ioremap must be balanced by an iounmap and failing to do so can result in a memory leak. Tested (compilation only) with: - allmodconfig - Modifying drivers/scsi/Kconfig to make sure that the changed file is compiling without warning Signed-off-by: Amol Lad <amol@xxxxxxxxxxxxxxxxxxx> --- Please CC me as I'm not subscribed to linux-scsi --- 3w-9xxx.c | 5 +++++ amiga7xx.c | 2 ++ fdomain.c | 6 +++++- ncr53c8xx.c | 2 ++ nsp32.c | 5 +++++ qlogicpti.c | 1 + seagate.c | 13 ++++++++++++- sun3_scsi.c | 7 ++++++- sun3_scsi_vme.c | 5 ++++- zalon.c | 2 ++ 10 files changed, 44 insertions(+), 4 deletions(-) --- diff -uprN -X linux-2.6.18-orig/Documentation/dontdiff linux-2.6.18-orig/drivers/scsi/3w-9xxx.c linux-2.6.18/drivers/scsi/3w-9xxx.c --- linux-2.6.18-orig/drivers/scsi/3w-9xxx.c 2006-09-21 10:15:38.000000000 +0530 +++ linux-2.6.18/drivers/scsi/3w-9xxx.c 2006-09-25 18:14:51.000000000 +0530 @@ -2147,6 +2147,8 @@ out_remove_host: scsi_remove_host(host); out_release_mem_region: pci_release_regions(pdev); + if (tw_dev->base_addr) + iounmap(tw_dev->base_addr); out_free_device_extension: twa_free_device_extension(tw_dev); scsi_host_put(host); @@ -2173,6 +2175,9 @@ static void twa_remove(struct pci_dev *p /* Free up the IRQ */ free_irq(tw_dev->tw_pci_dev->irq, tw_dev); + /* Free IO mem */ + iounmap(tw_dev->base_addr); + /* Shutdown the card */ __twa_shutdown(tw_dev); diff -uprN -X linux-2.6.18-orig/Documentation/dontdiff linux-2.6.18-orig/drivers/scsi/amiga7xx.c linux-2.6.18/drivers/scsi/amiga7xx.c --- linux-2.6.18-orig/drivers/scsi/amiga7xx.c 2006-09-21 10:15:39.000000000 +0530 +++ linux-2.6.18/drivers/scsi/amiga7xx.c 2006-09-26 10:37:34.000000000 +0530 @@ -115,6 +115,8 @@ static int amiga7xx_release(struct Scsi_ free_irq(shost->irq, NULL); if (shost->dma_channel != 0xff) free_dma(shost->dma_channel); + if (shost->base) + z_iounmap((void *)shost->base); if (shost->io_port && shost->n_io_port) release_region(shost->io_port, shost->n_io_port); scsi_unregister(shost); diff -uprN -X linux-2.6.18-orig/Documentation/dontdiff linux-2.6.18-orig/drivers/scsi/fdomain.c linux-2.6.18/drivers/scsi/fdomain.c --- linux-2.6.18-orig/drivers/scsi/fdomain.c 2006-09-21 10:15:39.000000000 +0530 +++ linux-2.6.18/drivers/scsi/fdomain.c 2006-09-25 18:15:26.000000000 +0530 @@ -780,7 +780,11 @@ found: else printk( " FAILURE\n" ); #endif - if (!flag) return 0; /* iobase not found */ + if (!flag) { + if (bios_mem) + iounmap(bios_mem); + return 0; /* iobase not found */ + } *irq = fdomain_get_irq( base ); *iobase = base; diff -uprN -X linux-2.6.18-orig/Documentation/dontdiff linux-2.6.18-orig/drivers/scsi/ncr53c8xx.c linux-2.6.18/drivers/scsi/ncr53c8xx.c --- linux-2.6.18-orig/drivers/scsi/ncr53c8xx.c 2006-09-21 10:15:40.000000000 +0530 +++ linux-2.6.18/drivers/scsi/ncr53c8xx.c 2006-09-25 18:15:26.000000000 +0530 @@ -8563,6 +8563,8 @@ struct Scsi_Host * __init ncr_attach(str m_free_dma(np->script0, sizeof(struct script), "SCRIPT"); if (np->ccb) m_free_dma(np->ccb, sizeof(struct ccb), "CCB"); + if (!device->slot.base_v && np->vaddr) + iounmap(np->vaddr); m_free_dma(np, sizeof(struct ncb), "NCB"); host_data->ncb = NULL; diff -uprN -X linux-2.6.18-orig/Documentation/dontdiff linux-2.6.18-orig/drivers/scsi/nsp32.c linux-2.6.18/drivers/scsi/nsp32.c --- linux-2.6.18-orig/drivers/scsi/nsp32.c 2006-09-21 10:15:40.000000000 +0530 +++ linux-2.6.18/drivers/scsi/nsp32.c 2006-09-25 18:15:26.000000000 +0530 @@ -3540,6 +3540,11 @@ static int __devinit nsp32_probe(struct nsp32_dbg(NSP32_DEBUG_REGISTER, "exit %d", ret); + if (ret) { + iounmap(data->MmioAddress); + data->MmioAddress = NULL; + } + return ret; } diff -uprN -X linux-2.6.18-orig/Documentation/dontdiff linux-2.6.18-orig/drivers/scsi/qlogicpti.c linux-2.6.18/drivers/scsi/qlogicpti.c --- linux-2.6.18-orig/drivers/scsi/qlogicpti.c 2006-09-21 10:15:40.000000000 +0530 +++ linux-2.6.18/drivers/scsi/qlogicpti.c 2006-09-25 18:15:26.000000000 +0530 @@ -699,6 +699,7 @@ static int __init qpti_map_regs(struct q "PTI Qlogic/ISP statreg"); if (!qpti->sreg) { printk("PTI: Qlogic/ISP status register is unmappable\n"); + sbus_iounmap(qpti->qregs, qpti->sdev->reg_addrs[0].reg_size); return -1; } } diff -uprN -X linux-2.6.18-orig/Documentation/dontdiff linux-2.6.18-orig/drivers/scsi/seagate.c linux-2.6.18/drivers/scsi/seagate.c --- linux-2.6.18-orig/drivers/scsi/seagate.c 2006-09-21 10:15:40.000000000 +0530 +++ linux-2.6.18/drivers/scsi/seagate.c 2006-09-25 18:15:26.000000000 +0530 @@ -493,12 +493,19 @@ int __init seagate_st0x_detect (struct s * if we lose our first interrupt. */ instance = scsi_register (tpnt, 0); - if (instance == NULL) + if (instance == NULL) { + iounmap(st0x_cr_sr); + iounmap(st0x_dr); + st0x_cr_sr = st0x_dr = NULL; return 0; + } hostno = instance->host_no; if (request_irq (irq, do_seagate_reconnect_intr, IRQF_DISABLED, (controller_type == SEAGATE) ? "seagate" : "tmc-8xx", instance)) { printk(KERN_ERR "scsi%d : unable to allocate IRQ%d\n", hostno, irq); + iounmap(st0x_cr_sr); + iounmap(st0x_dr); + st0x_cr_sr = st0x_dr = NULL; return 0; } instance->irq = irq; @@ -1645,6 +1652,10 @@ static int seagate_st0x_release(struct S { if (shost->irq) free_irq(shost->irq, shost); + if (st0x_cr_sr) + iounmap(st0x_cr_sr); + if (st0x_dr) + iounmap(st0x_dr); release_region(shost->io_port, shost->n_io_port); return 0; } diff -uprN -X linux-2.6.18-orig/Documentation/dontdiff linux-2.6.18-orig/drivers/scsi/sun3_scsi.c linux-2.6.18/drivers/scsi/sun3_scsi.c --- linux-2.6.18-orig/drivers/scsi/sun3_scsi.c 2006-08-24 02:46:33.000000000 +0530 +++ linux-2.6.18/drivers/scsi/sun3_scsi.c 2006-09-25 17:39:53.000000000 +0530 @@ -240,11 +240,13 @@ int sun3scsi_detect(struct scsi_host_tem if((udc_regs = dvma_malloc(sizeof(struct sun3_udc_regs))) == NULL) { printk("SUN3 Scsi couldn't allocate DVMA memory!\n"); + iounmap((void*)ioaddr); return 0; } #ifdef OLDDMA if((dmabuf = dvma_malloc_align(SUN3_DVMA_BUFSIZE, 0x10000)) == NULL) { printk("SUN3 Scsi couldn't allocate DVMA memory!\n"); + iounmap((void*)ioaddr); return 0; } #endif @@ -254,8 +256,10 @@ int sun3scsi_detect(struct scsi_host_tem #endif instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); - if(instance == NULL) + if(instance == NULL) { + iounmap((void*)ioaddr); return 0; + } default_instance = instance; @@ -277,6 +281,7 @@ int sun3scsi_detect(struct scsi_host_tem #else printk("scsi%d: IRQ%d not free, bailing out\n", instance->host_no, instance->irq); + iounmap((void*)ioaddr); return 0; #endif } diff -uprN -X linux-2.6.18-orig/Documentation/dontdiff linux-2.6.18-orig/drivers/scsi/sun3_scsi_vme.c linux-2.6.18/drivers/scsi/sun3_scsi_vme.c --- linux-2.6.18-orig/drivers/scsi/sun3_scsi_vme.c 2006-08-24 02:46:33.000000000 +0530 +++ linux-2.6.18/drivers/scsi/sun3_scsi_vme.c 2006-09-25 18:15:26.000000000 +0530 @@ -216,8 +216,10 @@ static int sun3scsi_detect(struct scsi_h #endif instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); - if(instance == NULL) + if(instance == NULL) { + iounmap((void *)ioaddr); return 0; + } default_instance = instance; @@ -239,6 +241,7 @@ static int sun3scsi_detect(struct scsi_h #else printk("scsi%d: IRQ%d not free, bailing out\n", instance->host_no, instance->irq); + iounmap((void *)ioaddr); return 0; #endif } diff -uprN -X linux-2.6.18-orig/Documentation/dontdiff linux-2.6.18-orig/drivers/scsi/zalon.c linux-2.6.18/drivers/scsi/zalon.c --- linux-2.6.18-orig/drivers/scsi/zalon.c 2006-09-21 10:15:41.000000000 +0530 +++ linux-2.6.18/drivers/scsi/zalon.c 2006-09-26 10:43:35.000000000 +0530 @@ -156,6 +156,8 @@ zalon_probe(struct parisc_device *dev) fail_free_irq: free_irq(dev->irq, host); fail: + if (zalon) + iounmap(zalon); ncr53c8xx_release(host); return error; } - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html