diff options
author | Paul Mackerras <paulus@samba.org> | 2007-05-09 07:47:15 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-05-10 07:28:13 -0400 |
commit | 31e92e0a1f40ecbef415cd99dc886b14963dc594 (patch) | |
tree | 320a7a0cd390c75d5f23100366acef0790af47c9 | |
parent | 4cc81aac8bd2022d5365ad23b7ce6406676e0aa8 (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>
-rw-r--r-- | arch/powerpc/kernel/pci_64.c | 37 |
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, ®ion, 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; |