summaryrefslogtreecommitdiff
path: root/drivers/pci/pcie/aer/aerdrv_acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/pcie/aer/aerdrv_acpi.c')
-rw-r--r--drivers/pci/pcie/aer/aerdrv_acpi.c48
1 files changed, 29 insertions, 19 deletions
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c
index cf611ab2193a..4d6991794fa2 100644
--- a/drivers/pci/pcie/aer/aerdrv_acpi.c
+++ b/drivers/pci/pcie/aer/aerdrv_acpi.c
@@ -50,14 +50,37 @@ struct aer_hest_parse_info {
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;
@@ -97,33 +120,20 @@ int pcie_aer_get_firmware_first(struct pci_dev *dev)
static bool aer_firmware_first;
-static int aer_hest_parse_aff(struct acpi_hest_header *hest_hdr, void *data)
-{
- struct acpi_hest_aer_common *p;
-
- if (aer_firmware_first)
- return 0;
-
- switch (hest_hdr->type) {
- case ACPI_HEST_TYPE_AER_ROOT_PORT:
- case ACPI_HEST_TYPE_AER_ENDPOINT:
- case ACPI_HEST_TYPE_AER_BRIDGE:
- p = (struct acpi_hest_aer_common *)(hest_hdr + 1);
- aer_firmware_first = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
- default:
- return 0;
- }
-}
-
/**
* aer_acpi_firmware_first - Check if APEI should control AER.
*/
bool aer_acpi_firmware_first(void)
{
static bool parsed = false;
+ struct aer_hest_parse_info info = {
+ .pci_dev = NULL, /* Check all PCIe devices */
+ .firmware_first = 0,
+ };
if (!parsed) {
- apei_hest_parse(aer_hest_parse_aff, NULL);
+ apei_hest_parse(aer_hest_parse, &info);
+ aer_firmware_first = info.firmware_first;
parsed = true;
}
return aer_firmware_first;