aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/bus.c
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2009-04-23 23:48:32 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-06-11 15:04:06 -0400
commit1f82de10d6b1d845155363c895c552e61b36b51a (patch)
tree3e93b9d1c97ae48509133fbbec9c81b4823816a5 /drivers/pci/bus.c
parent67b5db6502ddd27d65dea43bf036abbd82d0dfc9 (diff)
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.c7
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,
41 void *alignf_data) 41 void *alignf_data)
42{ 42{
43 int i, ret = -ENOMEM; 43 int i, ret = -ENOMEM;
44 resource_size_t max = -1;
44 45
45 type_mask |= IORESOURCE_IO | IORESOURCE_MEM; 46 type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
46 47
48 /* don't allocate too high if the pref mem doesn't support 64bit*/
49 if (!(res->flags & IORESOURCE_MEM_64))
50 max = PCIBIOS_MAX_MEM_32;
51
47 for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { 52 for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
48 struct resource *r = bus->resource[i]; 53 struct resource *r = bus->resource[i];
49 if (!r) 54 if (!r)
@@ -62,7 +67,7 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
62 /* Ok, try it out.. */ 67 /* Ok, try it out.. */
63 ret = allocate_resource(r, res, size, 68 ret = allocate_resource(r, res, size,
64 r->start ? : min, 69 r->start ? : min,
65 -1, align, 70 max, align,
66 alignf, alignf_data); 71 alignf, alignf_data);
67 if (ret == 0) 72 if (ret == 0)
68 break; 73 break;