aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergei Shtylyov <sshtylyov@ru.mvista.com>2008-04-18 15:39:03 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-04-24 10:09:52 -0400
commit8911c9e3343c647b59727b47b10feca7ee9ac9c3 (patch)
treeaf0aff3b05bf448e7b8189a44d8f9aa7502b1e16
parent448504130f18bc9d8d10ba045775c906abd01438 (diff)
[SCSI] aic79xx: 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>
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.h2
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm_pci.c29
2 files changed, 16 insertions, 15 deletions
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
index b252803e05f..08dd18229b4 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -360,7 +360,7 @@ struct ahd_platform_data {
360#define AHD_LINUX_NOIRQ ((uint32_t)~0) 360#define AHD_LINUX_NOIRQ ((uint32_t)~0)
361 uint32_t irq; /* IRQ for this adapter */ 361 uint32_t irq; /* IRQ for this adapter */
362 uint32_t bios_address; 362 uint32_t bios_address;
363 uint32_t mem_busaddr; /* Mem Base Addr */ 363 resource_size_t mem_busaddr; /* Mem Base Addr */
364}; 364};
365 365
366/************************** OS Utility Wrappers *******************************/ 366/************************** OS Utility Wrappers *******************************/
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
index dfaaae5e73a..9e0d7bdc889 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
@@ -249,8 +249,8 @@ ahd_linux_pci_exit(void)
249} 249}
250 250
251static int 251static int
252ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, u_long *base, 252ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, resource_size_t *base,
253 u_long *base2) 253 resource_size_t *base2)
254{ 254{
255 *base = pci_resource_start(ahd->dev_softc, 0); 255 *base = pci_resource_start(ahd->dev_softc, 0);
256 /* 256 /*
@@ -272,11 +272,11 @@ ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, u_long *base,
272 272
273static int 273static int
274ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd, 274ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd,
275 u_long *bus_addr, 275 resource_size_t *bus_addr,
276 uint8_t __iomem **maddr) 276 uint8_t __iomem **maddr)
277{ 277{
278 u_long start; 278 resource_size_t start;
279 u_long base_page; 279 resource_size_t base_page;
280 u_long base_offset; 280 u_long base_offset;
281 int error = 0; 281 int error = 0;
282 282
@@ -310,7 +310,7 @@ int
310ahd_pci_map_registers(struct ahd_softc *ahd) 310ahd_pci_map_registers(struct ahd_softc *ahd)
311{ 311{
312 uint32_t command; 312 uint32_t command;
313 u_long base; 313 resource_size_t base;
314 uint8_t __iomem *maddr; 314 uint8_t __iomem *maddr;
315 int error; 315 int error;
316 316
@@ -346,31 +346,32 @@ ahd_pci_map_registers(struct ahd_softc *ahd)
346 } else 346 } else
347 command |= PCIM_CMD_MEMEN; 347 command |= PCIM_CMD_MEMEN;
348 } else if (bootverbose) { 348 } else if (bootverbose) {
349 printf("aic79xx: PCI%d:%d:%d MEM region 0x%lx " 349 printf("aic79xx: PCI%d:%d:%d MEM region 0x%llx "
350 "unavailable. Cannot memory map device.\n", 350 "unavailable. Cannot memory map device.\n",
351 ahd_get_pci_bus(ahd->dev_softc), 351 ahd_get_pci_bus(ahd->dev_softc),
352 ahd_get_pci_slot(ahd->dev_softc), 352 ahd_get_pci_slot(ahd->dev_softc),
353 ahd_get_pci_function(ahd->dev_softc), 353 ahd_get_pci_function(ahd->dev_softc),
354 base); 354 (unsigned long long)base);
355 } 355 }
356 356
357 if (maddr == NULL) { 357 if (maddr == NULL) {
358 u_long base2; 358 resource_size_t base2;
359 359
360 error = ahd_linux_pci_reserve_io_regions(ahd, &base, &base2); 360 error = ahd_linux_pci_reserve_io_regions(ahd, &base, &base2);
361 if (error == 0) { 361 if (error == 0) {
362 ahd->tags[0] = BUS_SPACE_PIO; 362 ahd->tags[0] = BUS_SPACE_PIO;
363 ahd->tags[1] = BUS_SPACE_PIO; 363 ahd->tags[1] = BUS_SPACE_PIO;
364 ahd->bshs[0].ioport = base; 364 ahd->bshs[0].ioport = (u_long)base;
365 ahd->bshs[1].ioport = base2; 365 ahd->bshs[1].ioport = (u_long)base2;
366 command |= PCIM_CMD_PORTEN; 366 command |= PCIM_CMD_PORTEN;
367 } else { 367 } else {
368 printf("aic79xx: PCI%d:%d:%d IO regions 0x%lx and 0x%lx" 368 printf("aic79xx: PCI%d:%d:%d IO regions 0x%llx and "
369 "unavailable. Cannot map device.\n", 369 "0x%llx unavailable. Cannot map device.\n",
370 ahd_get_pci_bus(ahd->dev_softc), 370 ahd_get_pci_bus(ahd->dev_softc),
371 ahd_get_pci_slot(ahd->dev_softc), 371 ahd_get_pci_slot(ahd->dev_softc),
372 ahd_get_pci_function(ahd->dev_softc), 372 ahd_get_pci_function(ahd->dev_softc),
373 base, base2); 373 (unsigned long long)base,
374 (unsigned long long)base2);
374 } 375 }
375 } 376 }
376 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, 4); 377 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, 4);