diff options
author | Yinghai Lu <yinghai@kernel.org> | 2009-04-23 23:48:32 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-06-11 15:04:06 -0400 |
commit | 1f82de10d6b1d845155363c895c552e61b36b51a (patch) | |
tree | 3e93b9d1c97ae48509133fbbec9c81b4823816a5 /drivers/pci/probe.c | |
parent | 67b5db6502ddd27d65dea43bf036abbd82d0dfc9 (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/probe.c')
-rw-r--r-- | drivers/pci/probe.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index f1ae2475ffff..b962326e3d95 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -193,7 +193,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
193 | res->flags |= pci_calc_resource_flags(l) | IORESOURCE_SIZEALIGN; | 193 | res->flags |= pci_calc_resource_flags(l) | IORESOURCE_SIZEALIGN; |
194 | if (type == pci_bar_io) { | 194 | if (type == pci_bar_io) { |
195 | l &= PCI_BASE_ADDRESS_IO_MASK; | 195 | l &= PCI_BASE_ADDRESS_IO_MASK; |
196 | mask = PCI_BASE_ADDRESS_IO_MASK & 0xffff; | 196 | mask = PCI_BASE_ADDRESS_IO_MASK & IO_SPACE_LIMIT; |
197 | } else { | 197 | } else { |
198 | l &= PCI_BASE_ADDRESS_MEM_MASK; | 198 | l &= PCI_BASE_ADDRESS_MEM_MASK; |
199 | mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; | 199 | mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; |
@@ -237,6 +237,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
237 | dev_printk(KERN_DEBUG, &dev->dev, | 237 | dev_printk(KERN_DEBUG, &dev->dev, |
238 | "reg %x 64bit mmio: %pR\n", pos, res); | 238 | "reg %x 64bit mmio: %pR\n", pos, res); |
239 | } | 239 | } |
240 | |||
241 | res->flags |= IORESOURCE_MEM_64; | ||
240 | } else { | 242 | } else { |
241 | sz = pci_size(l, sz, mask); | 243 | sz = pci_size(l, sz, mask); |
242 | 244 | ||
@@ -362,7 +364,10 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) | |||
362 | } | 364 | } |
363 | } | 365 | } |
364 | if (base <= limit) { | 366 | if (base <= limit) { |
365 | res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH; | 367 | res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) | |
368 | IORESOURCE_MEM | IORESOURCE_PREFETCH; | ||
369 | if (res->flags & PCI_PREF_RANGE_TYPE_64) | ||
370 | res->flags |= IORESOURCE_MEM_64; | ||
366 | res->start = base; | 371 | res->start = base; |
367 | res->end = limit + 0xfffff; | 372 | res->end = limit + 0xfffff; |
368 | dev_printk(KERN_DEBUG, &dev->dev, "bridge %sbit mmio pref: %pR\n", | 373 | dev_printk(KERN_DEBUG, &dev->dev, "bridge %sbit mmio pref: %pR\n", |