Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
PCI: Enable PCIe AER only after checking firmware support
The PCIe port driver currently sets the PCIe AER error reporting bits for
any root or switch port without first checking to see if firmware will grant
control. This patch moves setting these bits to the AER service driver
aer_enable_port routine.  The bits are then set for the root port and any
downstream switch ports after the check for firmware support (aer_osc_setup)
is made. The patch also unsets the bits in a similar fashion when the AER
service driver is unloaded.

Reviewed-by: Alex Chiang <achiang@hp.com>
Signed-off-by: Andrew Patterson <andrew.patterson@hp.com>
Signed-off-by: Jesse Barnes <jbarnes@hobbes.lan>
  • Loading branch information
Andrew Patterson authored and Jesse Barnes committed Feb 24, 2009
1 parent 1c99a9e commit 47a8b0c
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 11 deletions.
48 changes: 39 additions & 9 deletions drivers/pci/pcie/aer/aerdrv_core.c
Expand Up @@ -108,6 +108,34 @@ int pci_cleanup_aer_correct_error_status(struct pci_dev *dev)
}
#endif /* 0 */


static void set_device_error_reporting(struct pci_dev *dev, void *data)
{
bool enable = *((bool *)data);

if (dev->pcie_type != PCIE_RC_PORT &&
dev->pcie_type != PCIE_SW_UPSTREAM_PORT &&
dev->pcie_type != PCIE_SW_DOWNSTREAM_PORT)
return;

if (enable)
pci_enable_pcie_error_reporting(dev);
else
pci_disable_pcie_error_reporting(dev);
}

/**
* set_downstream_devices_error_reporting - enable/disable the error reporting bits on the root port and its downstream ports.
* @dev: pointer to root port's pci_dev data structure
* @enable: true = enable error reporting, false = disable error reporting.
*/
static void set_downstream_devices_error_reporting(struct pci_dev *dev,
bool enable)
{
set_device_error_reporting(dev, &enable);
pci_walk_bus(dev->subordinate, set_device_error_reporting, &enable);
}

static int find_device_iter(struct device *device, void *data)
{
struct pci_dev *dev;
Expand Down Expand Up @@ -525,15 +553,11 @@ void aer_enable_rootport(struct aer_rpc *rpc)
pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, &reg32);
pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32);

/* Enable Root Port device reporting error itself */
pci_read_config_word(pdev, pos+PCI_EXP_DEVCTL, &reg16);
reg16 = reg16 |
PCI_EXP_DEVCTL_CERE |
PCI_EXP_DEVCTL_NFERE |
PCI_EXP_DEVCTL_FERE |
PCI_EXP_DEVCTL_URRE;
pci_write_config_word(pdev, pos+PCI_EXP_DEVCTL,
reg16);
/*
* Enable error reporting for the root port device and downstream port
* devices.
*/
set_downstream_devices_error_reporting(pdev, true);

/* Enable Root Port's interrupt in response to error messages */
pci_write_config_dword(pdev,
Expand All @@ -553,6 +577,12 @@ static void disable_root_aer(struct aer_rpc *rpc)
u32 reg32;
int pos;

/*
* Disable error reporting for the root port device and downstream port
* devices.
*/
set_downstream_devices_error_reporting(pdev, false);

pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
/* Disable Root's interrupt in response to error messages */
pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0);
Expand Down
2 changes: 0 additions & 2 deletions drivers/pci/pcie/portdrv_pci.c
Expand Up @@ -87,8 +87,6 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev,

pci_save_state(dev);

pci_enable_pcie_error_reporting(dev);

return 0;
}

Expand Down

0 comments on commit 47a8b0c

Please sign in to comment.