diff options
author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2008-04-18 15:30:45 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-04-24 10:09:49 -0400 |
commit | 448504130f18bc9d8d10ba045775c906abd01438 (patch) | |
tree | 1c8ca2c200f9c1706eb3494cb7d8e09acff716fa /drivers/scsi/aic7xxx | |
parent | be0d67680d524981dd65c661efe3c9cbd52a684f (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/scsi/aic7xxx')
-rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx_osm.h | 2 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx_osm_pci.c | 18 |
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 | ||
346 | static int | 346 | static int |
347 | ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc, u_long *base) | 347 | ahc_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 | ||
360 | static int | 360 | static int |
361 | ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc, | 361 | ahc_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 | |||
387 | ahc_pci_map_registers(struct ahc_softc *ahc) | 387 | ahc_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); |