summaryrefslogtreecommitdiffstats
path: root/drivers/pci/pcie
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2013-06-07 22:24:00 +0200
committerBjorn Helgaas <bhelgaas@google.com>2013-06-07 22:24:00 +0200
commit5899309c90971d5418abc4bf370bee871ff6072c (patch)
tree331b7922d0f3995110e130aa731dd7b2fbfea135 /drivers/pci/pcie
parentMerge branch 'pci/jiang-iov-fixes' into next (diff)
parentPCI/AER: Reset link for devices below Root Port or Downstream Port (diff)
downloadlinux-5899309c90971d5418abc4bf370bee871ff6072c.tar.xz
linux-5899309c90971d5418abc4bf370bee871ff6072c.zip
Merge branch 'pci/betty-aer-v3' into next
* pci/betty-aer-v3: PCI/AER: Reset link for devices below Root Port or Downstream Port ACPI / APEI: Force fatal AER severity when component has been reset PCI/AER: Remove "extern" from function declarations PCI/AER: Move AER severity defines to aer.h PCI/AER: Set dev->__aer_firmware_first only for matching devices PCI/AER: Factor out HEST device type matching PCI/AER: Don't parse HEST table for non-PCIe devices
Diffstat (limited to 'drivers/pci/pcie')
-rw-r--r--drivers/pci/pcie/aer/aerdrv.h4
-rw-r--r--drivers/pci/pcie/aer/aerdrv_acpi.c47
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c17
3 files changed, 33 insertions, 35 deletions
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h
index d12c77cd6991..90ea3e88041f 100644
--- a/drivers/pci/pcie/aer/aerdrv.h
+++ b/drivers/pci/pcie/aer/aerdrv.h
@@ -13,10 +13,6 @@
#include <linux/aer.h>
#include <linux/interrupt.h>
-#define AER_NONFATAL 0
-#define AER_FATAL 1
-#define AER_CORRECTABLE 2
-
#define SYSTEM_ERROR_INTR_ON_MESG_MASK (PCI_EXP_RTCTL_SECEE| \
PCI_EXP_RTCTL_SENFEE| \
PCI_EXP_RTCTL_SEFEE)
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c
index 5194a7d41730..cf611ab2193a 100644
--- a/drivers/pci/pcie/aer/aerdrv_acpi.c
+++ b/drivers/pci/pcie/aer/aerdrv_acpi.c
@@ -29,6 +29,22 @@ static inline int hest_match_pci(struct acpi_hest_aer_common *p,
p->function == PCI_FUNC(pci->devfn));
}
+static inline bool hest_match_type(struct acpi_hest_header *hest_hdr,
+ struct pci_dev *dev)
+{
+ u16 hest_type = hest_hdr->type;
+ u8 pcie_type = pci_pcie_type(dev);
+
+ if ((hest_type == ACPI_HEST_TYPE_AER_ROOT_PORT &&
+ pcie_type == PCI_EXP_TYPE_ROOT_PORT) ||
+ (hest_type == ACPI_HEST_TYPE_AER_ENDPOINT &&
+ pcie_type == PCI_EXP_TYPE_ENDPOINT) ||
+ (hest_type == ACPI_HEST_TYPE_AER_BRIDGE &&
+ (dev->class >> 16) == PCI_BASE_CLASS_BRIDGE))
+ return true;
+ return false;
+}
+
struct aer_hest_parse_info {
struct pci_dev *pci_dev;
int firmware_first;
@@ -38,34 +54,16 @@ static int aer_hest_parse(struct acpi_hest_header *hest_hdr, void *data)
{
struct aer_hest_parse_info *info = data;
struct acpi_hest_aer_common *p;
- u8 pcie_type = 0;
- u8 bridge = 0;
- int ff = 0;
-
- switch (hest_hdr->type) {
- case ACPI_HEST_TYPE_AER_ROOT_PORT:
- pcie_type = PCI_EXP_TYPE_ROOT_PORT;
- break;
- case ACPI_HEST_TYPE_AER_ENDPOINT:
- pcie_type = PCI_EXP_TYPE_ENDPOINT;
- break;
- case ACPI_HEST_TYPE_AER_BRIDGE:
- if ((info->pci_dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
- bridge = 1;
- break;
- default:
- return 0;
- }
+ int ff;
p = (struct acpi_hest_aer_common *)(hest_hdr + 1);
+ ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
if (p->flags & ACPI_HEST_GLOBAL) {
- if ((pci_is_pcie(info->pci_dev) &&
- pci_pcie_type(info->pci_dev) == pcie_type) || bridge)
- ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
+ if (hest_match_type(hest_hdr, info->pci_dev))
+ info->firmware_first = ff;
} else
if (hest_match_pci(p, info->pci_dev))
- ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
- info->firmware_first = ff;
+ info->firmware_first = ff;
return 0;
}
@@ -89,6 +87,9 @@ static void aer_set_firmware_first(struct pci_dev *pci_dev)
int pcie_aer_get_firmware_first(struct pci_dev *dev)
{
+ if (!pci_is_pcie(dev))
+ return 0;
+
if (!dev->__aer_firmware_first_valid)
aer_set_firmware_first(dev);
return dev->__aer_firmware_first;
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 8ec8b4f48560..d9e776e69fe8 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -400,16 +400,16 @@ void aer_do_secondary_bus_reset(struct pci_dev *dev)
}
/**
- * default_downstream_reset_link - default reset function for Downstream Port
- * @dev: pointer to downstream port's pci_dev data structure
+ * default_reset_link - default reset function
+ * @dev: pointer to pci_dev data structure
*
- * Invoked when performing link reset at Downstream Port w/ no aer driver.
+ * Invoked when performing link reset on a Downstream Port or a
+ * Root Port with no aer driver.
*/
-static pci_ers_result_t default_downstream_reset_link(struct pci_dev *dev)
+static pci_ers_result_t default_reset_link(struct pci_dev *dev)
{
aer_do_secondary_bus_reset(dev);
- dev_printk(KERN_DEBUG, &dev->dev,
- "Downstream Port link has been reset\n");
+ dev_printk(KERN_DEBUG, &dev->dev, "downstream link has been reset\n");
return PCI_ERS_RESULT_RECOVERED;
}
@@ -458,8 +458,9 @@ static pci_ers_result_t reset_link(struct pci_dev *dev)
if (driver && driver->reset_link) {
status = driver->reset_link(udev);
- } else if (pci_pcie_type(udev) == PCI_EXP_TYPE_DOWNSTREAM) {
- status = default_downstream_reset_link(udev);
+ } else if (pci_pcie_type(udev) == PCI_EXP_TYPE_DOWNSTREAM ||
+ pci_pcie_type(udev) == PCI_EXP_TYPE_ROOT_PORT) {
+ status = default_reset_link(udev);
} else {
dev_printk(KERN_DEBUG, &dev->dev,
"no link-reset support at upstream device %s\n",