Commit e0d317fd authored by Tim Hockin's avatar Tim Hockin Committed by Greg Kroah-Hartman

[PATCH] PCI: small PCI probe patch for odd 64 bit BARs

On Thu, Nov 11, 2004 at 09:54:19AM -0800, Greg KH wrote:
> I'll wait till you test this on 2.6 before applying it.

OK.  Tested now on real hardware in 32 bit and 64 bit kernels.  32 bit
found another dumbness, that we can fix up.

Some PCI bridges default their UPPER prefetch windows to an unused state
of base > limit.  We should not use those values if we find that.  It
might be nice to reprogram them to 0, in fact.

Yes, BIOS should fix that up, but apparently, some do not.
Signed-Off-By: default avatarTim Hockin <thockin@google.com>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent b48838a9
......@@ -144,9 +144,11 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
pci_write_config_dword(dev, reg+4, ~0);
pci_read_config_dword(dev, reg+4, &sz);
pci_write_config_dword(dev, reg+4, l);
if (~sz)
res->end = res->start + 0xffffffff +
(((unsigned long) ~sz) << 32);
sz = pci_size(l, sz, 0xffffffff);
if (sz) {
/* This BAR needs > 4GB? Wow. */
res->end |= (unsigned long)sz<<32;
}
#else
if (l) {
printk(KERN_ERR "PCI: Unable to handle 64-bit address for device %s\n", pci_name(dev));
......@@ -243,16 +245,24 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
u32 mem_base_hi, mem_limit_hi;
pci_read_config_dword(dev, PCI_PREF_BASE_UPPER32, &mem_base_hi);
pci_read_config_dword(dev, PCI_PREF_LIMIT_UPPER32, &mem_limit_hi);
/*
* Some bridges set the base > limit by default, and some
* (broken) BIOSes do not initialize them. If we find
* this, just assume they are not being used.
*/
if (mem_base_hi <= mem_limit_hi) {
#if BITS_PER_LONG == 64
base |= ((long) mem_base_hi) << 32;
limit |= ((long) mem_limit_hi) << 32;
#else
if (mem_base_hi || mem_limit_hi) {
printk(KERN_ERR "PCI: Unable to handle 64-bit address space for %s\n", child->name);
printk(KERN_ERR "PCI: Unable to handle 64-bit address space for bridge %s\n", pci_name(dev));
return;
}
#endif
}
}
if (base <= limit) {
res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
res->start = base;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment