Alex found one system that one pci bridge pref mmio 64 is not set correctly. aka, the upper32 base/limit is not cleaned. he found that bridge is supporting 64 bit pref mmio, but device under that does not support that. so that IORESOURCE_MEM_64 get cleared in pbus_size_mem() the fix will be: make pci_bridge_check_ranges() to store the PCI_PREF_RANGE_TYPE_64 in addition to IORESOURCE_MEM_64. just like pci_read_bridge_bases() and later will use that bit in pci_setup_bridge_mmio_pref instead of IORESOURCE_MEM_64. also avoid touching upper32 regs if the bridge does not support 64bit pref. Reported-by: Alex Williamson <alex.williamson@xxxxxx> Signed-off-by: Yinghai Lu <yinghai@xxxxxxxxxx> --- drivers/pci/setup-bus.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) Index: linux-2.6/drivers/pci/setup-bus.c =================================================================== --- linux-2.6.orig/drivers/pci/setup-bus.c +++ linux-2.6/drivers/pci/setup-bus.c @@ -289,7 +289,6 @@ static void pci_setup_bridge_mmio_pref(s struct resource *res; struct pci_bus_region region; u32 l, bu, lu; - int pref_mem64; /* Clear out the upper 32 bits of PREF limit. If PCI_PREF_BASE_UPPER32 was non-zero, this temporarily @@ -297,7 +296,6 @@ static void pci_setup_bridge_mmio_pref(s pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0); /* Set up PREF base/limit. */ - pref_mem64 = 0; bu = lu = 0; res = bus->resource[2]; pcibios_resource_to_bus(bridge, ®ion, res); @@ -305,7 +303,6 @@ static void pci_setup_bridge_mmio_pref(s l = (region.start >> 16) & 0xfff0; l |= region.end & 0xfff00000; if (res->flags & IORESOURCE_MEM_64) { - pref_mem64 = 1; bu = upper_32_bits(region.start); lu = upper_32_bits(region.end); } @@ -317,7 +314,7 @@ static void pci_setup_bridge_mmio_pref(s } pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l); - if (pref_mem64) { + if (res->flags & PCI_PREF_RANGE_TYPE_64) { /* Set the upper 32 bits of PREF base & limit. */ pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu); pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu); @@ -385,8 +382,10 @@ static void pci_bridge_check_ranges(stru } if (pmem) { b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH; - if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) + if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) { b_res[2].flags |= IORESOURCE_MEM_64; + b_res[2].flags |= PCI_PREF_RANGE_TYPE_64; + } } /* double check if bridge does support 64 bit pref */ -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html