aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2007-05-09 07:47:15 -0400
committerPaul Mackerras <paulus@samba.org>2007-05-10 07:28:13 -0400
commit31e92e0a1f40ecbef415cd99dc886b14963dc594 (patch)
tree320a7a0cd390c75d5f23100366acef0790af47c9 /arch
parent4cc81aac8bd2022d5365ad23b7ce6406676e0aa8 (diff)
[POWERPC] Fix incorrect calculation of I/O window addresses
My patch "Cope with PCI host bridge I/O window not starting at 0" introduced a bug in the calculation of the virtual addresses for the I/O windows of PCI host bridges other than the first, because it didn't account for the fact that hose->io_resource gets offset so that it reflects the range of global I/O port numbers assigned to the bridge. This fixes it and simplifies get_bus_io_range() in the process. Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kernel/pci_64.c37
1 files changed, 13 insertions, 24 deletions
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 6d05a1f377b5..b0409e19b1c1 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -1098,35 +1098,24 @@ static int get_bus_io_range(struct pci_bus *bus, unsigned long *start_phys,
1098 unsigned long *start_virt, unsigned long *size) 1098 unsigned long *start_virt, unsigned long *size)
1099{ 1099{
1100 struct pci_controller *hose = pci_bus_to_host(bus); 1100 struct pci_controller *hose = pci_bus_to_host(bus);
1101 struct pci_bus_region region;
1102 struct resource *res; 1101 struct resource *res;
1103 1102
1104 if (bus->self) { 1103 if (bus->self)
1105 res = bus->resource[0]; 1104 res = bus->resource[0];
1106 pcibios_resource_to_bus(bus->self, &region, res); 1105 else
1107 *start_phys = hose->io_base_phys + region.start;
1108 *start_virt = (unsigned long) hose->io_base_virt +
1109 region.start;
1110 if (region.end > region.start)
1111 *size = region.end - region.start + 1;
1112 else {
1113 printk("%s(): unexpected region 0x%lx->0x%lx\n",
1114 __FUNCTION__, region.start, region.end);
1115 return 1;
1116 }
1117
1118 } else {
1119 /* Root Bus */ 1106 /* Root Bus */
1120 res = &hose->io_resource; 1107 res = &hose->io_resource;
1121 *start_phys = hose->io_base_phys + res->start; 1108
1122 *start_virt = (unsigned long) hose->io_base_virt + res->start; 1109 *start_virt = pci_io_base + res->start;
1123 if (res->end > res->start) 1110 *start_phys = *start_virt + hose->io_base_phys
1124 *size = res->end - res->start + 1; 1111 - (unsigned long) hose->io_base_virt;
1125 else { 1112
1126 printk("%s(): unexpected region 0x%lx->0x%lx\n", 1113 if (res->end > res->start)
1127 __FUNCTION__, res->start, res->end); 1114 *size = res->end - res->start + 1;
1128 return 1; 1115 else {
1129 } 1116 printk("%s(): unexpected region 0x%lx->0x%lx\n",
1117 __FUNCTION__, res->start, res->end);
1118 return 1;
1130 } 1119 }
1131 1120
1132 return 0; 1121 return 0;