diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2007-06-12 19:54:08 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-06-13 03:01:19 -0400 |
commit | 56f5c0bd50e948408ac0fd587b5c89fa7e2a1b6e (patch) | |
tree | 00257841fe799337dab51d5ad22429d3c6143ccd /arch | |
parent | 4a907dec9845001dc2b117a0ed2a2150384a4cea (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.c | 12 |
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; |