diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2010-02-16 18:16:39 +1100 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2010-02-16 18:16:39 +1100 |
commit | 4836d02cce0a6a54d8cac2211435d5a410fe4cce (patch) | |
tree | 0bf7cc735d3979570a26e434f2998dba1e4c804a /arch/x86/pci/acpi.c | |
parent | b766a27a403e5961d27febf13347bbf8ebed2b8d (diff) |
Revert "PCI: replace bus resource table with a list"
This reverts commit 94a8887c501b22a2818ee58197864e9eab983510.
Diffstat (limited to 'arch/x86/pci/acpi.c')
-rw-r--r-- | arch/x86/pci/acpi.c | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index a2f8cdb8c1d5..959e548a7039 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -45,6 +45,20 @@ count_resource(struct acpi_resource *acpi_res, void *data) return AE_OK; } +static int +bus_has_transparent_bridge(struct pci_bus *bus) +{ + struct pci_dev *dev; + + list_for_each_entry(dev, &bus->devices, bus_list) { + u16 class = dev->class >> 8; + + if (class == PCI_CLASS_BRIDGE_PCI && dev->transparent) + return true; + } + return false; +} + static void align_resource(struct acpi_device *bridge, struct resource *res) { @@ -78,8 +92,12 @@ setup_resource(struct acpi_resource *acpi_res, void *data) acpi_status status; unsigned long flags; struct resource *root; + int max_root_bus_resources = PCI_BUS_NUM_RESOURCES; u64 start, end; + if (bus_has_transparent_bridge(info->bus)) + max_root_bus_resources -= 3; + status = resource_to_addr(acpi_res, &addr); if (!ACPI_SUCCESS(status)) return AE_OK; @@ -97,6 +115,15 @@ setup_resource(struct acpi_resource *acpi_res, void *data) start = addr.minimum + addr.translation_offset; end = start + addr.address_length - 1; + if (info->res_num >= max_root_bus_resources) { + if (pci_probe & PCI_USE__CRS) + printk(KERN_WARNING "PCI: Failed to allocate " + "0x%lx-0x%lx from %s for %s due to _CRS " + "returning more than %d resource descriptors\n", + (unsigned long) start, (unsigned long) end, + root->name, info->name, max_root_bus_resources); + return AE_OK; + } res = &info->res[info->res_num]; res->name = info->name; @@ -116,7 +143,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data) dev_err(&info->bridge->dev, "can't allocate host bridge window %pR\n", res); } else { - pci_bus_add_resource(info->bus, res, 0); + info->bus->resource[info->res_num] = res; info->res_num++; if (addr.translation_offset) dev_info(&info->bridge->dev, "host bridge window %pR " @@ -137,9 +164,7 @@ get_current_resources(struct acpi_device *device, int busnum, struct pci_root_info info; size_t size; - if (pci_probe & PCI_USE__CRS) - pci_bus_remove_resources(bus); - else + if (!(pci_probe & PCI_USE__CRS)) dev_info(&device->dev, "ignoring host bridge windows from ACPI; " "boot with \"pci=use_crs\" to use them\n"); |