aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSergei Shtylyov <sshtylyov@ru.mvista.com>2008-04-18 15:30:45 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-04-24 10:09:49 -0400
commit448504130f18bc9d8d10ba045775c906abd01438 (patch)
tree1c8ca2c200f9c1706eb3494cb7d8e09acff716fa /drivers
parentbe0d67680d524981dd65c661efe3c9cbd52a684f (diff)
[SCSI] aic7xxx: fix MMIO for PPC 44x platforms
The driver stores the PCI resource address into 'u_long' variable before calling ioremap_nocache() on it. This warrants kernel oops when the registers are accessed on PPC 44x platforms which (being 32-bit) have PCI memory space mapped beyond 4 GB. The arch/ppc/ kernel has a fixup in ioremap() that helps create an illusion that the PCI memory resources are mapped below 4 GB, but arch/powerpc/ code got rid of this trick, having instead CONFIG_RESOURCES_64BIT enabled. Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h2
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm_pci.c18
2 files changed, 10 insertions, 10 deletions
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index 9d6e0660ddbc..c2a9ad76d35d 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -365,7 +365,7 @@ struct ahc_platform_data {
365#define AHC_LINUX_NOIRQ ((uint32_t)~0) 365#define AHC_LINUX_NOIRQ ((uint32_t)~0)
366 uint32_t irq; /* IRQ for this adapter */ 366 uint32_t irq; /* IRQ for this adapter */
367 uint32_t bios_address; 367 uint32_t bios_address;
368 uint32_t mem_busaddr; /* Mem Base Addr */ 368 resource_size_t mem_busaddr; /* Mem Base Addr */
369}; 369};
370 370
371/************************** OS Utility Wrappers *******************************/ 371/************************** OS Utility Wrappers *******************************/
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
index bd422a80e9d5..950a046788f0 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
@@ -344,7 +344,7 @@ ahc_linux_pci_exit(void)
344} 344}
345 345
346static int 346static int
347ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc, u_long *base) 347ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc, resource_size_t *base)
348{ 348{
349 if (aic7xxx_allow_memio == 0) 349 if (aic7xxx_allow_memio == 0)
350 return (ENOMEM); 350 return (ENOMEM);
@@ -359,10 +359,10 @@ ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc, u_long *base)
359 359
360static int 360static int
361ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc, 361ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc,
362 u_long *bus_addr, 362 resource_size_t *bus_addr,
363 uint8_t __iomem **maddr) 363 uint8_t __iomem **maddr)
364{ 364{
365 u_long start; 365 resource_size_t start;
366 int error; 366 int error;
367 367
368 error = 0; 368 error = 0;
@@ -387,7 +387,7 @@ int
387ahc_pci_map_registers(struct ahc_softc *ahc) 387ahc_pci_map_registers(struct ahc_softc *ahc)
388{ 388{
389 uint32_t command; 389 uint32_t command;
390 u_long base; 390 resource_size_t base;
391 uint8_t __iomem *maddr; 391 uint8_t __iomem *maddr;
392 int error; 392 int error;
393 393
@@ -425,12 +425,12 @@ ahc_pci_map_registers(struct ahc_softc *ahc)
425 } else 425 } else
426 command |= PCIM_CMD_MEMEN; 426 command |= PCIM_CMD_MEMEN;
427 } else { 427 } else {
428 printf("aic7xxx: PCI%d:%d:%d MEM region 0x%lx " 428 printf("aic7xxx: PCI%d:%d:%d MEM region 0x%llx "
429 "unavailable. Cannot memory map device.\n", 429 "unavailable. Cannot memory map device.\n",
430 ahc_get_pci_bus(ahc->dev_softc), 430 ahc_get_pci_bus(ahc->dev_softc),
431 ahc_get_pci_slot(ahc->dev_softc), 431 ahc_get_pci_slot(ahc->dev_softc),
432 ahc_get_pci_function(ahc->dev_softc), 432 ahc_get_pci_function(ahc->dev_softc),
433 base); 433 (unsigned long long)base);
434 } 434 }
435 435
436 /* 436 /*
@@ -441,15 +441,15 @@ ahc_pci_map_registers(struct ahc_softc *ahc)
441 error = ahc_linux_pci_reserve_io_region(ahc, &base); 441 error = ahc_linux_pci_reserve_io_region(ahc, &base);
442 if (error == 0) { 442 if (error == 0) {
443 ahc->tag = BUS_SPACE_PIO; 443 ahc->tag = BUS_SPACE_PIO;
444 ahc->bsh.ioport = base; 444 ahc->bsh.ioport = (u_long)base;
445 command |= PCIM_CMD_PORTEN; 445 command |= PCIM_CMD_PORTEN;
446 } else { 446 } else {
447 printf("aic7xxx: PCI%d:%d:%d IO region 0x%lx[0..255] " 447 printf("aic7xxx: PCI%d:%d:%d IO region 0x%llx[0..255] "
448 "unavailable. Cannot map device.\n", 448 "unavailable. Cannot map device.\n",
449 ahc_get_pci_bus(ahc->dev_softc), 449 ahc_get_pci_bus(ahc->dev_softc),
450 ahc_get_pci_slot(ahc->dev_softc), 450 ahc_get_pci_slot(ahc->dev_softc),
451 ahc_get_pci_function(ahc->dev_softc), 451 ahc_get_pci_function(ahc->dev_softc),
452 base); 452 (unsigned long long)base);
453 } 453 }
454 } 454 }
455 ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, 4); 455 ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, 4);