aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-06-12 19:54:08 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-06-13 03:01:19 -0400
commit56f5c0bd50e948408ac0fd587b5c89fa7e2a1b6e (patch)
tree00257841fe799337dab51d5ad22429d3c6143ccd /arch
parent4a907dec9845001dc2b117a0ed2a2150384a4cea (diff)
[SPARC64]: Fix IO/MEM space sizing for PCI.
In pci_determine_mem_io_space(), do not hard code the region sizes. Instead, use the values given to us in the ranges property. Thanks goes to Mikael Petterson for the original Xorg failure bug repoert, and strace dumps from Mikael and Dmitry Artamonow. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc64/kernel/pci_common.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c
index f974fefc3ebc..4249214608af 100644
--- a/arch/sparc64/kernel/pci_common.c
+++ b/arch/sparc64/kernel/pci_common.c
@@ -291,8 +291,9 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
291 291
292 for (i = 0; i < num_pbm_ranges; i++) { 292 for (i = 0; i < num_pbm_ranges; i++) {
293 const struct linux_prom_pci_ranges *pr = &pbm_ranges[i]; 293 const struct linux_prom_pci_ranges *pr = &pbm_ranges[i];
294 unsigned long a; 294 unsigned long a, size;
295 u32 parent_phys_hi, parent_phys_lo; 295 u32 parent_phys_hi, parent_phys_lo;
296 u32 size_hi, size_lo;
296 int type; 297 int type;
297 298
298 parent_phys_hi = pr->parent_phys_hi; 299 parent_phys_hi = pr->parent_phys_hi;
@@ -300,9 +301,14 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
300 if (tlb_type == hypervisor) 301 if (tlb_type == hypervisor)
301 parent_phys_hi &= 0x0fffffff; 302 parent_phys_hi &= 0x0fffffff;
302 303
304 size_hi = pr->size_hi;
305 size_lo = pr->size_lo;
306
303 type = (pr->child_phys_hi >> 24) & 0x3; 307 type = (pr->child_phys_hi >> 24) & 0x3;
304 a = (((unsigned long)parent_phys_hi << 32UL) | 308 a = (((unsigned long)parent_phys_hi << 32UL) |
305 ((unsigned long)parent_phys_lo << 0UL)); 309 ((unsigned long)parent_phys_lo << 0UL));
310 size = (((unsigned long)size_hi << 32UL) |
311 ((unsigned long)size_lo << 0UL));
306 312
307 switch (type) { 313 switch (type) {
308 case 0: 314 case 0:
@@ -313,7 +319,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
313 case 1: 319 case 1:
314 /* 16-bit IO space, 16MB */ 320 /* 16-bit IO space, 16MB */
315 pbm->io_space.start = a; 321 pbm->io_space.start = a;
316 pbm->io_space.end = a + ((16UL*1024UL*1024UL) - 1UL); 322 pbm->io_space.end = a + size - 1UL;
317 pbm->io_space.flags = IORESOURCE_IO; 323 pbm->io_space.flags = IORESOURCE_IO;
318 saw_io = 1; 324 saw_io = 1;
319 break; 325 break;
@@ -321,7 +327,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
321 case 2: 327 case 2:
322 /* 32-bit MEM space, 2GB */ 328 /* 32-bit MEM space, 2GB */
323 pbm->mem_space.start = a; 329 pbm->mem_space.start = a;
324 pbm->mem_space.end = a + (0x80000000UL - 1UL); 330 pbm->mem_space.end = a + size - 1UL;
325 pbm->mem_space.flags = IORESOURCE_MEM; 331 pbm->mem_space.flags = IORESOURCE_MEM;
326 saw_mem = 1; 332 saw_mem = 1;
327 break; 333 break;