|
@@ -180,25 +180,31 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
|
|
|
res->flags |= pci_calc_resource_flags(l);
|
|
|
if ((l & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK))
|
|
|
== (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)) {
|
|
|
- pci_read_config_dword(dev, reg+4, &l);
|
|
|
+ u32 szhi, lhi;
|
|
|
+ pci_read_config_dword(dev, reg+4, &lhi);
|
|
|
+ pci_write_config_dword(dev, reg+4, ~0);
|
|
|
+ pci_read_config_dword(dev, reg+4, &szhi);
|
|
|
+ pci_write_config_dword(dev, reg+4, lhi);
|
|
|
+ szhi = pci_size(lhi, szhi, 0xffffffff);
|
|
|
next++;
|
|
|
#if BITS_PER_LONG == 64
|
|
|
- res->start |= ((unsigned long) l) << 32;
|
|
|
+ res->start |= ((unsigned long) lhi) << 32;
|
|
|
res->end = res->start + sz;
|
|
|
- pci_write_config_dword(dev, reg+4, ~0);
|
|
|
- pci_read_config_dword(dev, reg+4, &sz);
|
|
|
- pci_write_config_dword(dev, reg+4, l);
|
|
|
- sz = pci_size(l, sz, 0xffffffff);
|
|
|
- if (sz) {
|
|
|
+ if (szhi) {
|
|
|
/* This BAR needs > 4GB? Wow. */
|
|
|
- res->end |= (unsigned long)sz<<32;
|
|
|
+ res->end |= (unsigned long)szhi<<32;
|
|
|
}
|
|
|
#else
|
|
|
- if (l) {
|
|
|
- printk(KERN_ERR "PCI: Unable to handle 64-bit address for device %s\n", pci_name(dev));
|
|
|
+ if (szhi) {
|
|
|
+ printk(KERN_ERR "PCI: Unable to handle 64-bit BAR for device %s\n", pci_name(dev));
|
|
|
res->start = 0;
|
|
|
res->flags = 0;
|
|
|
- continue;
|
|
|
+ } else if (l) {
|
|
|
+ /* 64-bit wide address, treat as disabled */
|
|
|
+ pci_write_config_dword(dev, reg, l & ~(u32)PCI_BASE_ADDRESS_MEM_MASK);
|
|
|
+ pci_write_config_dword(dev, reg+4, 0);
|
|
|
+ res->start = 0;
|
|
|
+ res->end = sz;
|
|
|
}
|
|
|
#endif
|
|
|
}
|