diff options
author | Yinghai Lu <yinghai@kernel.org> | 2009-04-23 20:48:32 -0700 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-06-11 12:04:06 -0700 |
commit | 1f82de10d6b1d845155363c895c552e61b36b51a (patch) | |
tree | 3e93b9d1c97ae48509133fbbec9c81b4823816a5 /drivers/pci/bus.c | |
parent | 67b5db6502ddd27d65dea43bf036abbd82d0dfc9 (diff) | |
download | linux-stable-1f82de10d6b1d845155363c895c552e61b36b51a.tar.gz linux-stable-1f82de10d6b1d845155363c895c552e61b36b51a.tar.bz2 linux-stable-1f82de10d6b1d845155363c895c552e61b36b51a.zip |
PCI/x86: don't assume prefetchable ranges are 64bit
We should not assign 64bit ranges to PCI devices that only take 32bit
prefetchable addresses.
Try to set IORESOURCE_MEM_64 in 64bit resource of pci_device/pci_bridge
and make the bus resource only have that bit set when all devices under
it support 64bit prefetchable memory. Use that flag to allocate
resources from that range.
Reported-by: Yannick <yannick.roehlly@free.fr>
Reviewed-by: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/bus.c')
-rw-r--r-- | drivers/pci/bus.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 97a8194063b5..40af27f31043 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -41,9 +41,14 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, void *alignf_data) { int i, ret = -ENOMEM; + resource_size_t max = -1; type_mask |= IORESOURCE_IO | IORESOURCE_MEM; + /* don't allocate too high if the pref mem doesn't support 64bit*/ + if (!(res->flags & IORESOURCE_MEM_64)) + max = PCIBIOS_MAX_MEM_32; + for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { struct resource *r = bus->resource[i]; if (!r) @@ -62,7 +67,7 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, /* Ok, try it out.. */ ret = allocate_resource(r, res, size, r->start ? : min, - -1, align, + max, align, alignf, alignf_data); if (ret == 0) break; |