[patch 2/4] x86: pci: acpi: Respect ioresource flags

Thomas Gleixner
2014-12-11T19:48:27Z

[-- Attachment #1: x86-pci-respect-ioresource-flags.patch --]
[-- Type: text/plain, Size: 2756 bytes --]

setup_res() blindly clear all resource->flags except IO and MEM. So if
a resource is marked disabled by the acpi code, setup_res() will use
it nevertheless.

Preserve the flags and add proper checks to setup_res() and
__release_pci_root_info(). The latter is simplified while at it.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/pci/acpi.c | 35 ++++++++++++++++-------------------
1 file changed, 16 insertions(+), 19 deletions(-)

Index: tip/arch/x86/pci/acpi.c
===================================================================
--- tip.orig/arch/x86/pci/acpi.c
+++ tip/arch/x86/pci/acpi.c
@@ -218,6 +218,12 @@ static void teardown_mcfg_map(struct pci
}
#endif

+static bool is_valid_resource(struct resource *res)
+{
+ return (res->flags & (IORESOURCE_MEM | IORESOURCE_IO)) &&
+ !(res->flags & IORESOURCE_DISABLED);
+}
+
static acpi_status count_resource(struct acpi_resource *acpi_res, void *data)
{
struct pci_root_info *info = data;
@@ -228,7 +234,7 @@ static acpi_status count_resource(struct
!acpi_dev_resource_address_space(acpi_res, &r))
return AE_OK;

- if ((r.flags & (IORESOURCE_IO | IORESOURCE_MEM)) && resource_size(&r))
+ if (is_valid_resource(&r))
info->res_num++;

return AE_OK;
@@ -242,13 +248,10 @@ static acpi_status setup_resource(struct
u64 orig_end;

memset(&r, 0, sizeof(r));
- if (acpi_dev_resource_memory(acpi_res, &r)) {
- r.flags &= IORESOURCE_MEM;
- } else if (acpi_dev_resource_address_space(acpi_res, &r)) {
+ if (!acpi_dev_resource_memory(acpi_res, &r)) {
struct acpi_resource_address64 addr;

- r.flags &= IORESOURCE_MEM | IORESOURCE_IO;
- if (r.flags == 0)
+ if (!acpi_dev_resource_address_space(acpi_res, &r))
return AE_OK;

if (ACPI_FAILURE(acpi_resource_to_address64(acpi_res, &addr)))
@@ -264,10 +267,11 @@ static acpi_status setup_resource(struct
translation_offset = addr.translation_offset;
r.start += translation_offset;
r.end += translation_offset;
- } else {
- return AE_OK;
}

+ if (!is_valid_resource(&r))
+ return AE_OK;
+
/* Exclude non-addressable range or non-addressable portion of range */
orig_end = r.end;
r.end = min(r.end, iomem_resource.end);
@@ -367,19 +371,12 @@ static void free_pci_root_info_res(struc

static void __release_pci_root_info(struct pci_root_info *info)
{
+ struct resource *res = info->res;
int i;
- struct resource *res;
-
- for (i = 0; i < info->res_num; i++) {
- res = &info->res[i];
-
- if (!res->parent)
- continue;
-
- if (!(res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
- continue;

- release_resource(res);
+ for (i = 0; i < info->res_num; i++, res++) {
+ if (res->parent && is_valid_resource(res))
+ release_resource(res);
}

free_pci_root_info_res(info);