Commit 789e7dc8 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6: (30 commits)
  [PATCH] PCI Hotplug: Fix recovery path from errors during pcie_init()
  [PATCH] PCI Hotplug: fake NULL pointer dereferences in IBM Hot Plug Controller Driver
  [PATCH] shpchp: Cleanup improper info messages
  [PATCH] shpchp: Remove Unused hpc_evelnt_lock
  [PATCH] shpchp: Cleanup interrupt polling timer
  [PATCH] shpchp: Cleanup SHPC commands
  [PATCH] shpchp: Cleanup interrupt handler
  [PATCH] shpchp: Remove unnecessary hpc_ctlr_handle check
  [PATCH] pciehp: Implement get_address callback
  [PATCH] pciehp: Add missing pci_dev_put
  [PATCH] pciehp: Replace pci_find_slot() with pci_get_slot()
  [PATCH] SGI Hotplug: Incorrect power status
  [PATCH] shpchp: Create shpchpd at controller probe time
  [PATCH] shpchp: Mask Global SERR and Intr at controller release time
  [PATCH] SHPC: Fix SHPC Contoller SERR-INT Register bits access
  [PATCH] SHPC: Fix SHPC Logical Slot Register bits access
  [PATCH] SHPC: Cleanup SHPC Logical Slot Register bits access
  [PATCH] SHPC: Cleanup SHPC Logical Slot Register access
  [PATCH] SHPC: Cleanup SHPC register access
  [PATCH] pciehp: Fix programming hotplug parameters
  ...
parents 28e4b224 9c64f977
This diff is collapsed.
...@@ -75,6 +75,10 @@ struct acpiphp_bridge { ...@@ -75,6 +75,10 @@ struct acpiphp_bridge {
struct list_head list; struct list_head list;
acpi_handle handle; acpi_handle handle;
struct acpiphp_slot *slots; struct acpiphp_slot *slots;
/* Ejectable PCI-to-PCI bridge (PCI bridge and PCI function) */
struct acpiphp_func *func;
int type; int type;
int nr_slots; int nr_slots;
...@@ -122,6 +126,7 @@ struct acpiphp_slot { ...@@ -122,6 +126,7 @@ struct acpiphp_slot {
*/ */
struct acpiphp_func { struct acpiphp_func {
struct acpiphp_slot *slot; /* parent */ struct acpiphp_slot *slot; /* parent */
struct acpiphp_bridge *bridge; /* Ejectable PCI-to-PCI bridge */
struct list_head sibling; struct list_head sibling;
struct pci_dev *pci_dev; struct pci_dev *pci_dev;
......
This diff is collapsed.
...@@ -285,7 +285,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value) ...@@ -285,7 +285,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)
(ulong) hotplug_slot, (ulong) value); (ulong) hotplug_slot, (ulong) value);
ibmphp_lock_operations(); ibmphp_lock_operations();
if (hotplug_slot && value) { if (hotplug_slot) {
pslot = hotplug_slot->private; pslot = hotplug_slot->private;
if (pslot) { if (pslot) {
memcpy(&myslot, pslot, sizeof(struct slot)); memcpy(&myslot, pslot, sizeof(struct slot));
...@@ -315,7 +315,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value) ...@@ -315,7 +315,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value)
debug("get_latch_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", debug("get_latch_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
(ulong) hotplug_slot, (ulong) value); (ulong) hotplug_slot, (ulong) value);
ibmphp_lock_operations(); ibmphp_lock_operations();
if (hotplug_slot && value) { if (hotplug_slot) {
pslot = hotplug_slot->private; pslot = hotplug_slot->private;
if (pslot) { if (pslot) {
memcpy(&myslot, pslot, sizeof(struct slot)); memcpy(&myslot, pslot, sizeof(struct slot));
...@@ -342,7 +342,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value) ...@@ -342,7 +342,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)
debug("get_power_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", debug("get_power_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
(ulong) hotplug_slot, (ulong) value); (ulong) hotplug_slot, (ulong) value);
ibmphp_lock_operations(); ibmphp_lock_operations();
if (hotplug_slot && value) { if (hotplug_slot) {
pslot = hotplug_slot->private; pslot = hotplug_slot->private;
if (pslot) { if (pslot) {
memcpy(&myslot, pslot, sizeof(struct slot)); memcpy(&myslot, pslot, sizeof(struct slot));
...@@ -369,7 +369,7 @@ static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 * value) ...@@ -369,7 +369,7 @@ static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 * value)
debug("get_adapter_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", debug("get_adapter_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
(ulong) hotplug_slot, (ulong) value); (ulong) hotplug_slot, (ulong) value);
ibmphp_lock_operations(); ibmphp_lock_operations();
if (hotplug_slot && value) { if (hotplug_slot) {
pslot = hotplug_slot->private; pslot = hotplug_slot->private;
if (pslot) { if (pslot) {
memcpy(&myslot, pslot, sizeof(struct slot)); memcpy(&myslot, pslot, sizeof(struct slot));
...@@ -401,7 +401,7 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe ...@@ -401,7 +401,7 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe
ibmphp_lock_operations(); ibmphp_lock_operations();
if (hotplug_slot && value) { if (hotplug_slot) {
pslot = hotplug_slot->private; pslot = hotplug_slot->private;
if (pslot) { if (pslot) {
rc = 0; rc = 0;
...@@ -441,7 +441,7 @@ static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe ...@@ -441,7 +441,7 @@ static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe
ibmphp_lock_operations(); ibmphp_lock_operations();
if (hotplug_slot && value) { if (hotplug_slot) {
pslot = hotplug_slot->private; pslot = hotplug_slot->private;
if (pslot) { if (pslot) {
rc = get_cur_bus_info(&pslot); rc = get_cur_bus_info(&pslot);
......
...@@ -176,19 +176,59 @@ extern int pci_hp_change_slot_info (struct hotplug_slot *slot, ...@@ -176,19 +176,59 @@ extern int pci_hp_change_slot_info (struct hotplug_slot *slot,
struct hotplug_slot_info *info); struct hotplug_slot_info *info);
extern struct subsystem pci_hotplug_slots_subsys; extern struct subsystem pci_hotplug_slots_subsys;
struct hotplug_params { /* PCI Setting Record (Type 0) */
struct hpp_type0 {
u32 revision;
u8 cache_line_size; u8 cache_line_size;
u8 latency_timer; u8 latency_timer;
u8 enable_serr; u8 enable_serr;
u8 enable_perr; u8 enable_perr;
}; };
/* PCI-X Setting Record (Type 1) */
struct hpp_type1 {
u32 revision;
u8 max_mem_read;
u8 avg_max_split;
u16 tot_max_split;
};
/* PCI Express Setting Record (Type 2) */
struct hpp_type2 {
u32 revision;
u32 unc_err_mask_and;
u32 unc_err_mask_or;
u32 unc_err_sever_and;
u32 unc_err_sever_or;
u32 cor_err_mask_and;
u32 cor_err_mask_or;
u32 adv_err_cap_and;
u32 adv_err_cap_or;
u16 pci_exp_devctl_and;
u16 pci_exp_devctl_or;
u16 pci_exp_lnkctl_and;
u16 pci_exp_lnkctl_or;
u32 sec_unc_err_sever_and;
u32 sec_unc_err_sever_or;
u32 sec_unc_err_mask_and;
u32 sec_unc_err_mask_or;
};
struct hotplug_params {
struct hpp_type0 *t0; /* Type0: NULL if not available */
struct hpp_type1 *t1; /* Type1: NULL if not available */
struct hpp_type2 *t2; /* Type2: NULL if not available */
struct hpp_type0 type0_data;
struct hpp_type1 type1_data;
struct hpp_type2 type2_data;
};
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
#include <acpi/acpi.h> #include <acpi/acpi.h>
#include <acpi/acpi_bus.h> #include <acpi/acpi_bus.h>
#include <acpi/actypes.h> #include <acpi/actypes.h>
extern acpi_status acpi_run_oshp(acpi_handle handle); extern acpi_status acpi_run_oshp(acpi_handle handle);
extern acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev, extern acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
struct hotplug_params *hpp); struct hotplug_params *hpp);
int acpi_root_bridge(acpi_handle handle); int acpi_root_bridge(acpi_handle handle);
#endif #endif
......
...@@ -284,7 +284,7 @@ struct hpc_ops { ...@@ -284,7 +284,7 @@ struct hpc_ops {
static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev, static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
struct hotplug_params *hpp) struct hotplug_params *hpp)
{ {
if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev, hpp))) if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev->bus, hpp)))
return -ENODEV; return -ENODEV;
return 0; return 0;
} }
......
...@@ -69,6 +69,7 @@ static int get_power_status (struct hotplug_slot *slot, u8 *value); ...@@ -69,6 +69,7 @@ static int get_power_status (struct hotplug_slot *slot, u8 *value);
static int get_attention_status (struct hotplug_slot *slot, u8 *value); static int get_attention_status (struct hotplug_slot *slot, u8 *value);
static int get_latch_status (struct hotplug_slot *slot, u8 *value); static int get_latch_status (struct hotplug_slot *slot, u8 *value);
static int get_adapter_status (struct hotplug_slot *slot, u8 *value); static int get_adapter_status (struct hotplug_slot *slot, u8 *value);
static int get_address (struct hotplug_slot *slot, u32 *value);
static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
...@@ -81,6 +82,7 @@ static struct hotplug_slot_ops pciehp_hotplug_slot_ops = { ...@@ -81,6 +82,7 @@ static struct hotplug_slot_ops pciehp_hotplug_slot_ops = {
.get_attention_status = get_attention_status, .get_attention_status = get_attention_status,
.get_latch_status = get_latch_status, .get_latch_status = get_latch_status,
.get_adapter_status = get_adapter_status, .get_adapter_status = get_adapter_status,
.get_address = get_address,
.get_max_bus_speed = get_max_bus_speed, .get_max_bus_speed = get_max_bus_speed,
.get_cur_bus_speed = get_cur_bus_speed, .get_cur_bus_speed = get_cur_bus_speed,
}; };
...@@ -331,6 +333,18 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) ...@@ -331,6 +333,18 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
return 0; return 0;
} }
static int get_address(struct hotplug_slot *hotplug_slot, u32 *value)
{
struct slot *slot = hotplug_slot->private;
struct pci_bus *bus = slot->ctrl->pci_dev->subordinate;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
*value = (pci_domain_nr(bus) << 16) | (slot->bus << 8) | slot->device;
return 0;
}
static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
{ {
struct slot *slot = hotplug_slot->private; struct slot *slot = hotplug_slot->private;
......
...@@ -1288,7 +1288,7 @@ int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev) ...@@ -1288,7 +1288,7 @@ int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev)
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status)) {
dbg("Gained control for hotplug HW for pci %s (%s)\n", dbg("Gained control for hotplug HW for pci %s (%s)\n",
pci_name(dev), (char *)string.pointer); pci_name(dev), (char *)string.pointer);
acpi_os_free(string.pointer); kfree(string.pointer);
return 0; return 0;
} }
if (acpi_root_bridge(handle)) if (acpi_root_bridge(handle))
...@@ -1302,7 +1302,7 @@ int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev) ...@@ -1302,7 +1302,7 @@ int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev)
err("Cannot get control of hotplug hardware for pci %s\n", err("Cannot get control of hotplug hardware for pci %s\n",
pci_name(dev)); pci_name(dev));
acpi_os_free(string.pointer); kfree(string.pointer);
return -1; return -1;
} }
#endif #endif
...@@ -1404,9 +1404,6 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) ...@@ -1404,9 +1404,6 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device,
pdev->subsystem_vendor, pdev->subsystem_device); pdev->subsystem_vendor, pdev->subsystem_device);
if (pci_enable_device(pdev))
goto abort_free_ctlr;
mutex_init(&ctrl->crit_sect); mutex_init(&ctrl->crit_sect);
/* setup wait queue */ /* setup wait queue */
init_waitqueue_head(&ctrl->queue); init_waitqueue_head(&ctrl->queue);
...@@ -1474,7 +1471,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) ...@@ -1474,7 +1471,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_irq;
} }
intr_enable = intr_enable | PRSN_DETECT_ENABLE; intr_enable = intr_enable | PRSN_DETECT_ENABLE;
...@@ -1500,19 +1497,19 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) ...@@ -1500,19 +1497,19 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
if (rc) { if (rc) {
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_irq;
} }
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_disable_intr;
} }
temp_word = 0x1F; /* Clear all events */ temp_word = 0x1F; /* Clear all events */
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
if (rc) { if (rc) {
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_disable_intr;
} }
if (pciehp_force) { if (pciehp_force) {
...@@ -1521,7 +1518,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) ...@@ -1521,7 +1518,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
} else { } else {
rc = pciehp_get_hp_hw_control_from_firmware(ctrl->pci_dev); rc = pciehp_get_hp_hw_control_from_firmware(ctrl->pci_dev);
if (rc) if (rc)
goto abort_free_ctlr; goto abort_disable_intr;
} }
/* Add this HPC instance into the HPC list */ /* Add this HPC instance into the HPC list */
...@@ -1548,6 +1545,21 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) ...@@ -1548,6 +1545,21 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
return 0; return 0;
/* We end up here for the many possible ways to fail this API. */ /* We end up here for the many possible ways to fail this API. */
abort_disable_intr:
rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
if (!rc) {
temp_word &= ~(intr_enable | HP_INTR_ENABLE);
rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
}
if (rc)
err("%s : disabling interrupts failed\n", __FUNCTION__);
abort_free_irq:
if (pciehp_poll_mode)
del_timer_sync(&php_ctlr->int_poll_timer);
else
free_irq(php_ctlr->irq, ctrl);
abort_free_ctlr: abort_free_ctlr:
pcie_cap_base = saved_cap_base; pcie_cap_base = saved_cap_base;
kfree(php_ctlr); kfree(php_ctlr);
......
...@@ -34,6 +34,144 @@ ...@@ -34,6 +34,144 @@
#include "../pci.h" #include "../pci.h"
#include "pciehp.h" #include "pciehp.h"
static void program_hpp_type0(struct pci_dev *dev, struct hpp_type0 *hpp)
{
u16 pci_cmd, pci_bctl;
if (hpp->revision > 1) {
printk(KERN_WARNING "%s: Rev.%d type0 record not supported\n",
__FUNCTION__, hpp->revision);
return;
}
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp->cache_line_size);
pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp->latency_timer);
pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
if (hpp->enable_serr)
pci_cmd |= PCI_COMMAND_SERR;
else
pci_cmd &= ~PCI_COMMAND_SERR;
if (hpp->enable_perr)
pci_cmd |= PCI_COMMAND_PARITY;
else
pci_cmd &= ~PCI_COMMAND_PARITY;
pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
/* Program bridge control value */
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
hpp->latency_timer);
pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
if (hpp->enable_serr)
pci_bctl |= PCI_BRIDGE_CTL_SERR;
else
pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
if (hpp->enable_perr)
pci_bctl |= PCI_BRIDGE_CTL_PARITY;
else
pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
}
}
static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
{
int pos;
u16 reg16;
u32 reg32;
if (hpp->revision > 1) {
printk(KERN_WARNING "%s: Rev.%d type2 record not supported\n",
__FUNCTION__, hpp->revision);
return;
}
/* Find PCI Express capability */
pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
if (!pos)
return;
/* Initialize Device Control Register */
pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &reg16);
reg16 = (reg16 & hpp->pci_exp_devctl_and) | hpp->pci_exp_devctl_or;
pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16);
/* Initialize Link Control Register */
if (dev->subordinate) {
pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &reg16);
reg16 = (reg16 & hpp->pci_exp_lnkctl_and)
| hpp->pci_exp_lnkctl_or;
pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, reg16);
}
/* Find Advanced Error Reporting Enhanced Capability */
pos = 256;
do {
pci_read_config_dword(dev, pos, &reg32);
if (PCI_EXT_CAP_ID(reg32) == PCI_EXT_CAP_ID_ERR)
break;
} while ((pos = PCI_EXT_CAP_NEXT(reg32)));
if (!pos)
return;
/* Initialize Uncorrectable Error Mask Register */
pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, &reg32);
reg32 = (reg32 & hpp->unc_err_mask_and) | hpp->unc_err_mask_or;
pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, reg32);
/* Initialize Uncorrectable Error Severity Register */
pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &reg32);
reg32 = (reg32 & hpp->unc_err_sever_and) | hpp->unc_err_sever_or;
pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, reg32);
/* Initialize Correctable Error Mask Register */
pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &reg32);
reg32 = (reg32 & hpp->cor_err_mask_and) | hpp->cor_err_mask_or;
pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg32);
/* Initialize Advanced Error Capabilities and Control Register */
pci_read_config_dword(dev, pos + PCI_ERR_CAP, &reg32);
reg32 = (reg32 & hpp->adv_err_cap_and) | hpp->adv_err_cap_or;
pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32);
/*
* FIXME: The following two registers are not supported yet.
*
* o Secondary Uncorrectable Error Severity Register
* o Secondary Uncorrectable Error Mask Register
*/
}
static void program_fw_provided_values(struct pci_dev *dev)
{
struct pci_dev *cdev;
struct hotplug_params hpp;
/* Program hpp values for this device */
if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
return;
if (pciehp_get_hp_params_from_firmware(dev, &hpp)) {
printk(KERN_WARNING "%s: Could not get hotplug parameters\n",
__FUNCTION__);
return;
}
if (hpp.t2)
program_hpp_type2(dev, hpp.t2);
if (hpp.t0)
program_hpp_type0(dev, hpp.t0);
/* Program child devices */
if (dev->subordinate) {
list_for_each_entry(cdev, &dev->subordinate->devices,
bus_list)
program_fw_provided_values(cdev);
}
}
static int pciehp_add_bridge(struct pci_dev *dev) static int pciehp_add_bridge(struct pci_dev *dev)
{ {
struct pci_bus *parent = dev->bus; struct pci_bus *parent = dev->bus;
...@@ -66,10 +204,11 @@ int pciehp_configure_device(struct slot *p_slot) ...@@ -66,10 +204,11 @@ int pciehp_configure_device(struct slot *p_slot)
struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
int num, fn; int num, fn;
dev = pci_find_slot(p_slot->bus, PCI_DEVFN(p_slot->device, 0)); dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0));
if (dev) { if (dev) {
err("Device %s already exists at %x:%x, cannot hot-add\n", err("Device %s already exists at %x:%x, cannot hot-add\n",
pci_name(dev), p_slot->bus, p_slot->device); pci_name(dev), p_slot->bus, p_slot->device);
pci_dev_put(dev);
return -EINVAL; return -EINVAL;
} }
...@@ -86,14 +225,15 @@ int pciehp_configure_device(struct slot *p_slot) ...@@ -86,14 +225,15 @@ int pciehp_configure_device(struct slot *p_slot)
if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
err("Cannot hot-add display device %s\n", err("Cannot hot-add display device %s\n",
pci_name(dev)); pci_name(dev));
pci_dev_put(dev);
continue; continue;
} }
if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
pciehp_add_bridge(dev); pciehp_add_bridge(dev);
} }
/* TBD: program firmware provided _HPP values */ program_fw_provided_values(dev);
/* program_fw_provided_values(dev); */ pci_dev_put(dev);
} }
pci_bus_assign_resources(parent); pci_bus_assign_resources(parent);
...@@ -106,18 +246,20 @@ int pciehp_unconfigure_device(struct slot *p_slot) ...@@ -106,18 +246,20 @@ int pciehp_unconfigure_device(struct slot *p_slot)
int rc = 0; int rc = 0;
int j; int j;
u8 bctl = 0; u8 bctl = 0;
struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus, dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus,
p_slot->device); p_slot->device);
for (j=0; j<8 ; j++) { for (j=0; j<8 ; j++) {
struct pci_dev* temp = pci_find_slot(p_slot->bus, struct pci_dev* temp = pci_get_slot(parent,
(p_slot->device << 3) | j); (p_slot->device << 3) | j);
if (!temp) if (!temp)
continue; continue;
if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) { if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
err("Cannot remove display device %s\n", err("Cannot remove display device %s\n",
pci_name(temp)); pci_name(temp));
pci_dev_put(temp);
continue; continue;
} }
if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) { if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
...@@ -125,10 +267,12 @@ int pciehp_unconfigure_device(struct slot *p_slot) ...@@ -125,10 +267,12 @@ int pciehp_unconfigure_device(struct slot *p_slot)
if (bctl & PCI_BRIDGE_CTL_VGA) { if (bctl & PCI_BRIDGE_CTL_VGA) {
err("Cannot remove display device %s\n", err("Cannot remove display device %s\n",
pci_name(temp)); pci_name(temp));
pci_dev_put(temp);
continue; continue;
} }
} }
pci_remove_bus_device(temp); pci_remove_bus_device(temp);
pci_dev_put(temp);
} }
/* /*
* Some PCI Express root ports require fixup after hot-plug operation. * Some PCI Express root ports require fixup after hot-plug operation.
......
...@@ -18,11 +18,13 @@ ...@@ -18,11 +18,13 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include <asm/sn/addrs.h> #include <asm/sn/addrs.h>
#include <asm/sn/geo.h>
#include <asm/sn/l1.h> #include <asm/sn/l1.h>
#include <asm/sn/module.h> #include <asm/sn/module.h>
#include <asm/sn/pcibr_provider.h> #include <asm/sn/pcibr_provider.h>
#include <asm/sn/pcibus_provider_defs.h> #include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/pcidev.h> #include <asm/sn/pcidev.h>
#include <asm/sn/sn_feature_sets.h>
#include <asm/sn/sn_sal.h> #include <asm/sn/sn_sal.h>
#include <asm/sn/types.h> #include <asm/sn/types.h>
...@@ -102,8 +104,7 @@ static struct hotplug_slot_attribute sn_slot_path_attr = __ATTR_RO(path); ...@@ -102,8 +104,7 @@ static struct hotplug_slot_attribute sn_slot_path_attr = __ATTR_RO(path);
static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device) static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device)
{ {
struct pcibus_info *pcibus_info; struct pcibus_info *pcibus_info;
int bricktype; u16 busnum, segment, ioboard_type;
int bus_num;
pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus); pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
...@@ -111,12 +112,14 @@ static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device) ...@@ -111,12 +112,14 @@ static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device)
if (!(pcibus_info->pbi_valid_devices & (1 << device))) if (!(pcibus_info->pbi_valid_devices & (1 << device)))
return -EPERM; return -EPERM;
bricktype = MODULE_GET_BTYPE(pcibus_info->pbi_moduleid); ioboard_type = sn_ioboard_to_pci_bus(pci_bus);
bus_num = pcibus_info->pbi_buscommon.bs_persist_busnum & 0xf; busnum = pcibus_info->pbi_buscommon.bs_persist_busnum;
segment = pci_domain_nr(pci_bus) & 0xf;
/* Do not allow hotplug operations on base I/O cards */ /* Do not allow hotplug operations on base I/O cards */
if ((bricktype == L1_BRICKTYPE_IX || bricktype == L1_BRICKTYPE_IA) && if ((ioboard_type == L1_BRICKTYPE_IX ||
(bus_num == 1 && device != 1)) ioboard_type == L1_BRICKTYPE_IA) &&
(segment == 1 && busnum == 0 && device != 1))
return -EPERM; return -EPERM;
return 1; return 1;
...@@ -125,23 +128,23 @@ static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device) ...@@ -125,23 +128,23 @@ static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device)
static int sn_pci_bus_valid(struct pci_bus *pci_bus) static int sn_pci_bus_valid(struct pci_bus *pci_bus)
{ {
struct pcibus_info *pcibus_info; struct pcibus_info *pcibus_info;
int asic_type; u32 asic_type;
int bricktype; u16 ioboard_type;
pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
/* Don't register slots hanging off the TIOCA bus */ /* Don't register slots hanging off the TIOCA bus */
pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
asic_type = pcibus_info->pbi_buscommon.bs_asic_type; asic_type = pcibus_info->pbi_buscommon.bs_asic_type;
if (asic_type == PCIIO_ASIC_TYPE_TIOCA) if (asic_type == PCIIO_ASIC_TYPE_TIOCA)
return -EPERM; return -EPERM;
/* Only register slots in I/O Bricks that support hotplug */ /* Only register slots in I/O Bricks that support hotplug */
bricktype = MODULE_GET_BTYPE(pcibus_info->pbi_moduleid); ioboard_type = sn_ioboard_to_pci_bus(pci_bus);
switch (bricktype) { switch (ioboard_type) {
case L1_BRICKTYPE_IX: case L1_BRICKTYPE_IX:
case L1_BRICKTYPE_PX: case L1_BRICKTYPE_PX:
case L1_BRICKTYPE_IA: case L1_BRICKTYPE_IA:
case L1_BRICKTYPE_PA: case L1_BRICKTYPE_PA:
case L1_BOARDTYPE_PCIX3SLOT:
return 1; return 1;
break; break;
default: default:
...@@ -175,14 +178,11 @@ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot, ...@@ -175,14 +178,11 @@ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
slot->pci_bus = pci_bus; slot->pci_bus = pci_bus;
sprintf(bss_hotplug_slot->name, "%04x:%02x:%02x", sprintf(bss_hotplug_slot->name, "%04x:%02x:%02x",
pci_domain_nr(pci_bus), pci_domain_nr(pci_bus),
((int)pcibus_info->pbi_buscommon.bs_persist_busnum) & 0xf, ((u16)pcibus_info->pbi_buscommon.bs_persist_busnum),
device + 1); device + 1);
sprintf(slot->physical_path, "module_%c%c%c%c%.2d",
'0'+RACK_GET_CLASS(MODULE_GET_RACK(pcibus_info->pbi_moduleid)), sn_generate_path(pci_bus, slot->physical_path);
'0'+RACK_GET_GROUP(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
'0'+RACK_GET_NUM(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
MODULE_GET_BTCHAR(pcibus_info->pbi_moduleid),
MODULE_GET_BPOS(pcibus_info->pbi_moduleid));
slot->hotplug_slot = bss_hotplug_slot; slot->hotplug_slot = bss_hotplug_slot;
list_add(&slot->hp_list, &sn_hp_list); list_add(&slot->hp_list, &sn_hp_list);
...@@ -461,10 +461,12 @@ static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot, ...@@ -461,10 +461,12 @@ static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot,
{ {
struct slot *slot = bss_hotplug_slot->private; struct slot *slot = bss_hotplug_slot->private;
struct pcibus_info *pcibus_info; struct pcibus_info *pcibus_info;
u32 power;
pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus); pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
mutex_lock(&sn_hotplug_mutex); mutex_lock(&sn_hotplug_mutex);
*value = pcibus_info->pbi_enabled_devices & (1 << slot->device_num); power = pcibus_info->pbi_enabled_devices & (1 << slot->device_num);
*value = power ? 1 : 0;
mutex_unlock(&sn_hotplug_mutex); mutex_unlock(&sn_hotplug_mutex);
return 0; return 0;
} }
...@@ -553,8 +555,8 @@ static int sn_pci_hotplug_init(void) ...@@ -553,8 +555,8 @@ static int sn_pci_hotplug_init(void)
int rc; int rc;
int registered = 0; int registered = 0;
if (sn_sal_rev() < SGI_HOTPLUG_PROM_REV) { if (!sn_prom_feature_available(PRF_HOTPLUG_SUPPORT)) {
printk(KERN_ERR "%s: PROM version must be greater than 4.30\n", printk(KERN_ERR "%s: PROM version does not support hotplug.\n",
__FUNCTION__); __FUNCTION__);
return -EPERM; return -EPERM;
} }
......
...@@ -168,9 +168,9 @@ struct controller { ...@@ -168,9 +168,9 @@ struct controller {
* error Messages * error Messages
*/ */
#define msg_initialization_err "Initialization failure, error=%d\n" #define msg_initialization_err "Initialization failure, error=%d\n"
#define msg_button_on "PCI slot #%d - powering on due to button press.\n" #define msg_button_on "PCI slot #%s - powering on due to button press.\n"
#define msg_button_off "PCI slot #%d - powering off due to button press.\n" #define msg_button_off "PCI slot #%s - powering off due to button press.\n"
#define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n" #define msg_button_cancel "PCI slot #%s - action canceled due to button press.\n"
/* sysfs functions for the hotplug controller info */ /* sysfs functions for the hotplug controller info */
extern void shpchp_create_ctrl_files (struct controller *ctrl); extern void shpchp_create_ctrl_files (struct controller *ctrl);
...@@ -196,7 +196,7 @@ extern void queue_pushbutton_work(void *data); ...@@ -196,7 +196,7 @@ extern void queue_pushbutton_work(void *data);
static inline int get_hp_params_from_firmware(struct pci_dev *dev, static inline int get_hp_params_from_firmware(struct pci_dev *dev,
struct hotplug_params *hpp) struct hotplug_params *hpp)
{ {
if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev, hpp))) if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev->bus, hpp)))
return -ENODEV; return -ENODEV;
return 0; return 0;
} }
......
...@@ -491,16 +491,9 @@ static int __init shpcd_init(void) ...@@ -491,16 +491,9 @@ static int __init shpcd_init(void)
shpchp_poll_mode = 1; shpchp_poll_mode = 1;
#endif #endif
shpchp_wq = create_singlethread_workqueue("shpchpd");
if (!shpchp_wq)
return -ENOMEM;
retval = pci_register_driver(&shpc_driver); retval = pci_register_driver(&shpc_driver);
dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval); dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval);
info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
if (retval) {
destroy_workqueue(shpchp_wq);
}
return retval; return retval;
} }
...@@ -508,7 +501,6 @@ static void __exit shpcd_cleanup(void) ...@@ -508,7 +501,6 @@ static void __exit shpcd_cleanup(void)
{ {
dbg("unload_shpchpd()\n"); dbg("unload_shpchpd()\n");
pci_unregister_driver(&shpc_driver); pci_unregister_driver(&shpc_driver);
destroy_workqueue(shpchp_wq);
info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
} }
......
...@@ -72,7 +72,7 @@ u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id) ...@@ -72,7 +72,7 @@ u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id)
/* /*
* Button pressed - See if need to TAKE ACTION!!! * Button pressed - See if need to TAKE ACTION!!!
*/ */
info("Button pressed on Slot(%d)\n", ctrl->first_slot + hp_slot); info("Button pressed on Slot(%s)\n", p_slot->name);
event_type = INT_BUTTON_PRESS; event_type = INT_BUTTON_PRESS;
queue_interrupt_event(p_slot, event_type); queue_interrupt_event(p_slot, event_type);
...@@ -101,7 +101,7 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) ...@@ -101,7 +101,7 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
/* /*
* Switch opened * Switch opened
*/ */
info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot); info("Latch open on Slot(%s)\n", p_slot->name);
event_type = INT_SWITCH_OPEN; event_type = INT_SWITCH_OPEN;
if (p_slot->pwr_save && p_slot->presence_save) { if (p_slot->pwr_save && p_slot->presence_save) {
event_type = INT_POWER_FAULT; event_type = INT_POWER_FAULT;
...@@ -111,7 +111,7 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) ...@@ -111,7 +111,7 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
/* /*
* Switch closed * Switch closed
*/ */
info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot); info("Latch close on Slot(%s)\n", p_slot->name);
event_type = INT_SWITCH_CLOSE; event_type = INT_SWITCH_CLOSE;
} }
...@@ -139,13 +139,13 @@ u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id) ...@@ -139,13 +139,13 @@ u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id)
/* /*
* Card Present * Card Present
*/ */
info("Card present on Slot(%d)\n", ctrl->first_slot + hp_slot); info("Card present on Slot(%s)\n", p_slot->name);
event_type = INT_PRESENCE_ON; event_type = INT_PRESENCE_ON;
} else { } else {
/* /*
* Not Present * Not Present
*/ */
info("Card not present on Slot(%d)\n", ctrl->first_slot + hp_slot); info("Card not present on Slot(%s)\n", p_slot->name);
event_type = INT_PRESENCE_OFF; event_type = INT_PRESENCE_OFF;
} }
...@@ -169,14 +169,14 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id) ...@@ -169,14 +169,14 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id)
/* /*
* Power fault Cleared * Power fault Cleared
*/ */
info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot); info("Power fault cleared on Slot(%s)\n", p_slot->name);
p_slot->status = 0x00; p_slot->status = 0x00;
event_type = INT_POWER_FAULT_CLEAR; event_type = INT_POWER_FAULT_CLEAR;
} else { } else {
/* /*
* Power fault * Power fault
*/ */
info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot); info("Power fault on Slot(%s)\n", p_slot->name);
event_type = INT_POWER_FAULT; event_type = INT_POWER_FAULT;
/* set power fault status for this board */ /* set power fault status for this board */
p_slot->status = 0xFF; p_slot->status = 0xFF;
...@@ -496,10 +496,10 @@ static void handle_button_press_event(struct slot *p_slot) ...@@ -496,10 +496,10 @@ static void handle_button_press_event(struct slot *p_slot)
p_slot->hpc_ops->get_power_status(p_slot, &getstatus); p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (getstatus) { if (getstatus) {
p_slot->state = BLINKINGOFF_STATE; p_slot->state = BLINKINGOFF_STATE;
info(msg_button_off, p_slot->number); info(msg_button_off, p_slot->name);
} else { } else {
p_slot->state = BLINKINGON_STATE; p_slot->state = BLINKINGON_STATE;
info(msg_button_on, p_slot->number); info(msg_button_on, p_slot->name);
} }
/* blink green LED and turn off amber */ /* blink green LED and turn off amber */
p_slot->hpc_ops->green_led_blink(p_slot); p_slot->hpc_ops->green_led_blink(p_slot);
...@@ -522,7 +522,7 @@ static void handle_button_press_event(struct slot *p_slot) ...@@ -522,7 +522,7 @@ static void handle_button_press_event(struct slot *p_slot)
else else
p_slot->hpc_ops->green_led_off(p_slot); p_slot->hpc_ops->green_led_off(p_slot);
p_slot->hpc_ops->set_attention_status(p_slot, 0); p_slot->hpc_ops->set_attention_status(p_slot, 0);
info(msg_button_cancel, p_slot->number); info(msg_button_cancel, p_slot->name);
p_slot->state = STATIC_STATE; p_slot->state = STATIC_STATE;
break; break;
case POWEROFF_STATE: case POWEROFF_STATE:
...@@ -575,17 +575,17 @@ static int shpchp_enable_slot (struct slot *p_slot) ...@@ -575,17 +575,17 @@ static int shpchp_enable_slot (struct slot *p_slot)
mutex_lock(&p_slot->ctrl->crit_sect); mutex_lock(&p_slot->ctrl->crit_sect);
rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
if (rc || !getstatus) { if (rc || !getstatus) {
info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); info("No adapter on slot(%s)\n", p_slot->name);
goto out; goto out;
} }
rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
if (rc || getstatus) { if (rc || getstatus) {
info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); info("Latch open on slot(%s)\n", p_slot->name);
goto out; goto out;
} }
rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (rc || getstatus) { if (rc || getstatus) {
info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); info("Already enabled on slot(%s)\n", p_slot->name);
goto out; goto out;
} }
...@@ -634,17 +634,17 @@ static int shpchp_disable_slot (struct slot *p_slot) ...@@ -634,17 +634,17 @@ static int shpchp_disable_slot (struct slot *p_slot)
rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
if (rc || !getstatus) { if (rc || !getstatus) {
info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); info("No adapter on slot(%s)\n", p_slot->name);
goto out; goto out;
} }
rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
if (rc || getstatus) { if (rc || getstatus) {
info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); info("Latch open on slot(%s)\n", p_slot->name);
goto out; goto out;
} }
rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (rc || !getstatus) { if (rc || !getstatus) {
info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); info("Already disabled slot(%s)\n", p_slot->name);
goto out; goto out;
} }
......
This diff is collapsed.
...@@ -47,21 +47,28 @@ static void program_fw_provided_values(struct pci_dev *dev) ...@@ -47,21 +47,28 @@ static void program_fw_provided_values(struct pci_dev *dev)
return; return;
/* use default values if we can't get them from firmware */ /* use default values if we can't get them from firmware */
if (get_hp_params_from_firmware(dev, &hpp)) { if (get_hp_params_from_firmware(dev, &hpp) ||
hpp.cache_line_size = 8; !hpp.t0 || (hpp.t0->revision > 1)) {
hpp.latency_timer = 0x40; printk(KERN_WARNING
hpp.enable_serr = 0; "%s: Could not get hotplug parameters. Use defaults\n",
hpp.enable_perr = 0; __FUNCTION__);
hpp.t0 = &hpp.type0_data;
hpp.t0->revision = 0;
hpp.t0->cache_line_size = 8;
hpp.t0->latency_timer = 0x40;
hpp.t0->enable_serr = 0;
hpp.t0->enable_perr = 0;
} }
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp.cache_line_size); pci_write_config_byte(dev,
pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp.latency_timer); PCI_CACHE_LINE_SIZE, hpp.t0->cache_line_size);
pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp.t0->latency_timer);
pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
if (hpp.enable_serr) if (hpp.t0->enable_serr)
pci_cmd |= PCI_COMMAND_SERR; pci_cmd |= PCI_COMMAND_SERR;
else else
pci_cmd &= ~PCI_COMMAND_SERR; pci_cmd &= ~PCI_COMMAND_SERR;
if (hpp.enable_perr) if (hpp.t0->enable_perr)
pci_cmd |= PCI_COMMAND_PARITY; pci_cmd |= PCI_COMMAND_PARITY;
else else
pci_cmd &= ~PCI_COMMAND_PARITY; pci_cmd &= ~PCI_COMMAND_PARITY;
...@@ -70,13 +77,13 @@ static void program_fw_provided_values(struct pci_dev *dev) ...@@ -70,13 +77,13 @@ static void program_fw_provided_values(struct pci_dev *dev)
/* Program bridge control value and child devices */ /* Program bridge control value and child devices */
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
hpp.latency_timer); hpp.t0->latency_timer);
pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl); pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
if (hpp.enable_serr) if (hpp.t0->enable_serr)
pci_bctl |= PCI_BRIDGE_CTL_SERR; pci_bctl |= PCI_BRIDGE_CTL_SERR;
else else
pci_bctl &= ~PCI_BRIDGE_CTL_SERR; pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
if (hpp.enable_perr) if (hpp.t0->enable_perr)
pci_bctl |= PCI_BRIDGE_CTL_PARITY; pci_bctl |= PCI_BRIDGE_CTL_PARITY;
else else
pci_bctl &= ~PCI_BRIDGE_CTL_PARITY; pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment