summaryrefslogtreecommitdiffstats
path: root/drivers/pci/pcie/aer/aerdrv_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/pcie/aer/aerdrv_core.c')
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c76
1 files changed, 37 insertions, 39 deletions
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 9f5ccbeb4fa5..c843a799814d 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -35,11 +35,14 @@ int pci_enable_pcie_error_reporting(struct pci_dev *dev)
u16 reg16 = 0;
int pos;
+ if (dev->aer_firmware_first)
+ return -EIO;
+
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
if (!pos)
return -EIO;
- pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+ pos = pci_pcie_cap(dev);
if (!pos)
return -EIO;
@@ -60,7 +63,10 @@ int pci_disable_pcie_error_reporting(struct pci_dev *dev)
u16 reg16 = 0;
int pos;
- pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+ if (dev->aer_firmware_first)
+ return -EIO;
+
+ pos = pci_pcie_cap(dev);
if (!pos)
return -EIO;
@@ -78,48 +84,27 @@ EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting);
int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
{
int pos;
- u32 status, mask;
+ u32 status;
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
if (!pos)
return -EIO;
pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
- pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask);
- if (dev->error_state == pci_channel_io_normal)
- status &= ~mask; /* Clear corresponding nonfatal bits */
- else
- status &= mask; /* Clear corresponding fatal bits */
- pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status);
+ if (status)
+ pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status);
return 0;
}
EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status);
-#if 0
-int pci_cleanup_aer_correct_error_status(struct pci_dev *dev)
-{
- int pos;
- u32 status;
-
- pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
- if (!pos)
- return -EIO;
-
- pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &status);
- pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, status);
-
- return 0;
-}
-#endif /* 0 */
-
static int 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) {
+ if ((dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) ||
+ (dev->pcie_type == PCI_EXP_TYPE_UPSTREAM) ||
+ (dev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)) {
if (enable)
pci_enable_pcie_error_reporting(dev);
else
@@ -218,7 +203,7 @@ static int find_device_iter(struct pci_dev *dev, void *data)
*/
if (atomic_read(&dev->enable_cnt) == 0)
return 0;
- pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+ pos = pci_pcie_cap(dev);
if (!pos)
return 0;
/* Check if AER is enabled */
@@ -431,10 +416,9 @@ static int find_aer_service_iter(struct device *device, void *data)
result = (struct find_aer_service_data *) data;
if (device->bus == &pcie_port_bus_type) {
- struct pcie_port_data *port_data;
+ struct pcie_device *pcie = to_pcie_device(device);
- port_data = pci_get_drvdata(to_pcie_device(device)->port);
- if (port_data->port_type == PCIE_SW_DOWNSTREAM_PORT)
+ if (pcie->port->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)
result->is_downstream = 1;
driver = device->driver;
@@ -603,7 +587,7 @@ static void handle_error_source(struct pcie_device *aerdev,
* aer_enable_rootport - enable Root Port's interrupts when receiving messages
* @rpc: pointer to a Root Port data structure
*
- * Invoked when PCIE bus loads AER service driver.
+ * Invoked when PCIe bus loads AER service driver.
*/
void aer_enable_rootport(struct aer_rpc *rpc)
{
@@ -612,8 +596,8 @@ void aer_enable_rootport(struct aer_rpc *rpc)
u16 reg16;
u32 reg32;
- pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
- /* Clear PCIE Capability's Device Status */
+ pos = pci_pcie_cap(pdev);
+ /* Clear PCIe Capability's Device Status */
pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, &reg16);
pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16);
@@ -647,7 +631,7 @@ void aer_enable_rootport(struct aer_rpc *rpc)
* disable_root_aer - disable Root Port's interrupts when receiving messages
* @rpc: pointer to a Root Port data structure
*
- * Invoked when PCIE bus unloads AER service driver.
+ * Invoked when PCIe bus unloads AER service driver.
*/
static void disable_root_aer(struct aer_rpc *rpc)
{
@@ -874,8 +858,22 @@ void aer_delete_rootport(struct aer_rpc *rpc)
*/
int aer_init(struct pcie_device *dev)
{
- if (aer_osc_setup(dev) && !forceload)
- return -ENXIO;
+ if (dev->port->aer_firmware_first) {
+ dev_printk(KERN_DEBUG, &dev->device,
+ "PCIe errors handled by platform firmware.\n");
+ goto out;
+ }
+
+ if (aer_osc_setup(dev))
+ goto out;
return 0;
+out:
+ if (forceload) {
+ dev_printk(KERN_DEBUG, &dev->device,
+ "aerdrv forceload requested.\n");
+ dev->port->aer_firmware_first = 0;
+ return 0;
+ }
+ return -ENXIO;
}