summaryrefslogtreecommitdiffstats
path: root/drivers/pci/pcie/aer.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/pcie/aer.c')
-rw-r--r--drivers/pci/pcie/aer.c118
1 files changed, 11 insertions, 107 deletions
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index efc26773cc6d..803273ba30db 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -217,118 +217,22 @@ void pcie_ecrc_get_policy(char *str)
}
#endif /* CONFIG_PCIE_ECRC */
-#ifdef CONFIG_ACPI_APEI
-static inline int hest_match_pci(struct acpi_hest_aer_common *p,
- struct pci_dev *pci)
-{
- return ACPI_HEST_SEGMENT(p->bus) == pci_domain_nr(pci->bus) &&
- ACPI_HEST_BUS(p->bus) == pci->bus->number &&
- p->device == PCI_SLOT(pci->devfn) &&
- 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;
-};
-
-static int hest_source_is_pcie_aer(struct acpi_hest_header *hest_hdr)
-{
- if (hest_hdr->type == ACPI_HEST_TYPE_AER_ROOT_PORT ||
- hest_hdr->type == ACPI_HEST_TYPE_AER_ENDPOINT ||
- hest_hdr->type == ACPI_HEST_TYPE_AER_BRIDGE)
- return 1;
- return 0;
-}
-
-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;
- int ff;
-
- if (!hest_source_is_pcie_aer(hest_hdr))
- return 0;
-
- p = (struct acpi_hest_aer_common *)(hest_hdr + 1);
- ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
-
- /*
- * If no specific device is supplied, determine whether
- * FIRMWARE_FIRST is set for *any* PCIe device.
- */
- if (!info->pci_dev) {
- info->firmware_first |= ff;
- return 0;
- }
-
- /* Otherwise, check the specific device */
- if (p->flags & ACPI_HEST_GLOBAL) {
- if (hest_match_type(hest_hdr, info->pci_dev))
- info->firmware_first = ff;
- } else
- if (hest_match_pci(p, info->pci_dev))
- info->firmware_first = ff;
-
- return 0;
-}
-
-static void aer_set_firmware_first(struct pci_dev *pci_dev)
-{
- int rc;
- struct aer_hest_parse_info info = {
- .pci_dev = pci_dev,
- .firmware_first = 0,
- };
-
- rc = apei_hest_parse(aer_hest_parse, &info);
-
- if (rc)
- pci_dev->__aer_firmware_first = 0;
- else
- pci_dev->__aer_firmware_first = info.firmware_first;
- pci_dev->__aer_firmware_first_valid = 1;
-}
+#define PCI_EXP_AER_FLAGS (PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | \
+ PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE)
-int pcie_aer_get_firmware_first(struct pci_dev *dev)
+int pcie_aer_is_native(struct pci_dev *dev)
{
- if (!pci_is_pcie(dev))
- return 0;
+ struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
- if (pcie_ports_native)
+ if (!dev->aer_cap)
return 0;
- if (!dev->__aer_firmware_first_valid)
- aer_set_firmware_first(dev);
- return dev->__aer_firmware_first;
+ return pcie_ports_native || host->native_aer;
}
-#endif
-
-#define PCI_EXP_AER_FLAGS (PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | \
- PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE)
int pci_enable_pcie_error_reporting(struct pci_dev *dev)
{
- if (pcie_aer_get_firmware_first(dev))
- return -EIO;
-
- if (!dev->aer_cap)
+ if (!pcie_aer_is_native(dev))
return -EIO;
return pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_AER_FLAGS);
@@ -337,7 +241,7 @@ EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting);
int pci_disable_pcie_error_reporting(struct pci_dev *dev)
{
- if (pcie_aer_get_firmware_first(dev))
+ if (!pcie_aer_is_native(dev))
return -EIO;
return pcie_capability_clear_word(dev, PCI_EXP_DEVCTL,
@@ -362,7 +266,7 @@ int pci_aer_clear_nonfatal_status(struct pci_dev *dev)
if (!pos)
return -EIO;
- if (pcie_aer_get_firmware_first(dev))
+ if (!pcie_aer_is_native(dev))
return -EIO;
/* Clear status bits for ERR_NONFATAL errors only */
@@ -385,7 +289,7 @@ void pci_aer_clear_fatal_status(struct pci_dev *dev)
if (!pos)
return;
- if (pcie_aer_get_firmware_first(dev))
+ if (!pcie_aer_is_native(dev))
return;
/* Clear status bits for ERR_FATAL errors only */
@@ -435,7 +339,7 @@ int pci_aer_raw_clear_status(struct pci_dev *dev)
int pci_aer_clear_status(struct pci_dev *dev)
{
- if (pcie_aer_get_firmware_first(dev))
+ if (!pcie_aer_is_native(dev))
return -EIO;
return pci_aer_raw_clear_status(dev);