Commit 25f0c659 authored by Amol Lad's avatar Amol Lad Committed by David Woodhouse

ioremap balanced with iounmap for drivers/mtd subsystem

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/mtd/maps/Kconfig and drivers/mtd/nand/Kconfig to
make sure that the changed file is compiling without warning
Signed-off-by: default avatarAmol Lad <amol@verismonetworks.com>
Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
parent dd8e9ed6
...@@ -96,6 +96,8 @@ static struct mtd_partition arctic_partitions[PARTITIONS] = { ...@@ -96,6 +96,8 @@ static struct mtd_partition arctic_partitions[PARTITIONS] = {
static int __init static int __init
init_arctic_mtd(void) init_arctic_mtd(void)
{ {
int err = 0;
printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR); printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR);
arctic_mtd_map.virt = ioremap(PADDR, SIZE); arctic_mtd_map.virt = ioremap(PADDR, SIZE);
...@@ -109,12 +111,20 @@ init_arctic_mtd(void) ...@@ -109,12 +111,20 @@ init_arctic_mtd(void)
printk("%s: probing %d-bit flash bus\n", NAME, BUSWIDTH * 8); printk("%s: probing %d-bit flash bus\n", NAME, BUSWIDTH * 8);
arctic_mtd = do_map_probe("cfi_probe", &arctic_mtd_map); arctic_mtd = do_map_probe("cfi_probe", &arctic_mtd_map);
if (!arctic_mtd) if (!arctic_mtd) {
iounmap((void *) arctic_mtd_map.virt);
return -ENXIO; return -ENXIO;
}
arctic_mtd->owner = THIS_MODULE; arctic_mtd->owner = THIS_MODULE;
return add_mtd_partitions(arctic_mtd, arctic_partitions, PARTITIONS); err = add_mtd_partitions(arctic_mtd, arctic_partitions, PARTITIONS);
if (err) {
printk("%s: add_mtd_partitions failed\n", NAME);
iounmap((void *) arctic_mtd_map.virt);
}
return err;
} }
static void __exit static void __exit
......
...@@ -72,6 +72,8 @@ static struct mtd_partition beech_partitions[2] = { ...@@ -72,6 +72,8 @@ static struct mtd_partition beech_partitions[2] = {
static int __init static int __init
init_beech_mtd(void) init_beech_mtd(void)
{ {
int err = 0;
printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR); printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR);
beech_mtd_map.virt = ioremap(PADDR, SIZE); beech_mtd_map.virt = ioremap(PADDR, SIZE);
...@@ -86,12 +88,20 @@ init_beech_mtd(void) ...@@ -86,12 +88,20 @@ init_beech_mtd(void)
printk("%s: probing %d-bit flash bus\n", NAME, BUSWIDTH * 8); printk("%s: probing %d-bit flash bus\n", NAME, BUSWIDTH * 8);
beech_mtd = do_map_probe("cfi_probe", &beech_mtd_map); beech_mtd = do_map_probe("cfi_probe", &beech_mtd_map);
if (!beech_mtd) if (!beech_mtd) {
iounmap((void *) beech_mtd_map.virt);
return -ENXIO; return -ENXIO;
}
beech_mtd->owner = THIS_MODULE; beech_mtd->owner = THIS_MODULE;
return add_mtd_partitions(beech_mtd, beech_partitions, 2); err = add_mtd_partitions(beech_mtd, beech_partitions, 2);
if (err) {
printk("%s: add_mtd_partitions failed\n", NAME);
iounmap((void *) beech_mtd_map.virt);
}
return err;
} }
static void __exit static void __exit
......
...@@ -171,7 +171,14 @@ int __init init_cstm_mips_ixx(void) ...@@ -171,7 +171,14 @@ int __init init_cstm_mips_ixx(void)
cstm_mips_ixx_map[i].phys = cstm_mips_ixx_board_desc[i].window_addr; cstm_mips_ixx_map[i].phys = cstm_mips_ixx_board_desc[i].window_addr;
cstm_mips_ixx_map[i].virt = ioremap(cstm_mips_ixx_board_desc[i].window_addr, cstm_mips_ixx_board_desc[i].window_size); cstm_mips_ixx_map[i].virt = ioremap(cstm_mips_ixx_board_desc[i].window_addr, cstm_mips_ixx_board_desc[i].window_size);
if (!cstm_mips_ixx_map[i].virt) { if (!cstm_mips_ixx_map[i].virt) {
int j = 0;
printk(KERN_WARNING "Failed to ioremap\n"); printk(KERN_WARNING "Failed to ioremap\n");
for (j = 0; j < i; j++) {
if (cstm_mips_ixx_map[j].virt) {
iounmap((void *)cstm_mips_ixx_map[j].virt);
cstm_mips_ixx_map[j].virt = 0;
}
}
return -EIO; return -EIO;
} }
cstm_mips_ixx_map[i].name = cstm_mips_ixx_board_desc[i].name; cstm_mips_ixx_map[i].name = cstm_mips_ixx_board_desc[i].name;
...@@ -204,8 +211,15 @@ int __init init_cstm_mips_ixx(void) ...@@ -204,8 +211,15 @@ int __init init_cstm_mips_ixx(void)
cstm_mips_ixx_map[i].map_priv_2 = (unsigned long)mymtd; cstm_mips_ixx_map[i].map_priv_2 = (unsigned long)mymtd;
add_mtd_partitions(mymtd, parts, cstm_mips_ixx_board_desc[i].num_partitions); add_mtd_partitions(mymtd, parts, cstm_mips_ixx_board_desc[i].num_partitions);
} }
else else {
return -ENXIO; for (i = 0; i < PHYSMAP_NUMBER; i++) {
if (cstm_mips_ixx_map[i].virt) {
iounmap((void *)cstm_mips_ixx_map[i].virt);
cstm_mips_ixx_map[i].virt = 0;
}
}
return -ENXIO;
}
} }
return 0; return 0;
} }
......
...@@ -108,6 +108,7 @@ int __init init_ebony(void) ...@@ -108,6 +108,7 @@ int __init init_ebony(void)
ARRAY_SIZE(ebony_small_partitions)); ARRAY_SIZE(ebony_small_partitions));
} else { } else {
printk("map probe failed for flash\n"); printk("map probe failed for flash\n");
iounmap(ebony_small_map.virt);
return -ENXIO; return -ENXIO;
} }
...@@ -117,6 +118,7 @@ int __init init_ebony(void) ...@@ -117,6 +118,7 @@ int __init init_ebony(void)
if (!ebony_large_map.virt) { if (!ebony_large_map.virt) {
printk("Failed to ioremap flash\n"); printk("Failed to ioremap flash\n");
iounmap(ebony_small_map.virt);
return -EIO; return -EIO;
} }
...@@ -129,6 +131,8 @@ int __init init_ebony(void) ...@@ -129,6 +131,8 @@ int __init init_ebony(void)
ARRAY_SIZE(ebony_large_partitions)); ARRAY_SIZE(ebony_large_partitions));
} else { } else {
printk("map probe failed for flash\n"); printk("map probe failed for flash\n");
iounmap(ebony_small_map.virt);
iounmap(ebony_large_map.virt);
return -ENXIO; return -ENXIO;
} }
......
...@@ -218,8 +218,11 @@ int __init init_fortunet(void) ...@@ -218,8 +218,11 @@ int __init init_fortunet(void)
map_regions[ix].map_info.size); map_regions[ix].map_info.size);
if(!map_regions[ix].map_info.virt) if(!map_regions[ix].map_info.virt)
{ {
int j = 0;
printk(MTD_FORTUNET_PK "%s flash failed to ioremap!\n", printk(MTD_FORTUNET_PK "%s flash failed to ioremap!\n",
map_regions[ix].map_info.name); map_regions[ix].map_info.name);
for (j = 0 ; j < ix; j++)
iounmap(map_regions[j].map_info.virt);
return -ENXIO; return -ENXIO;
} }
simple_map_init(&map_regions[ix].map_info); simple_map_init(&map_regions[ix].map_info);
......
...@@ -79,6 +79,7 @@ static int __init init_lasat(void) ...@@ -79,6 +79,7 @@ static int __init init_lasat(void)
return 0; return 0;
} }
iounmap(lasat_map.virt);
return -ENXIO; return -ENXIO;
} }
...@@ -89,6 +90,7 @@ static void __exit cleanup_lasat(void) ...@@ -89,6 +90,7 @@ static void __exit cleanup_lasat(void)
map_destroy(lasat_mtd); map_destroy(lasat_mtd);
} }
if (lasat_map.virt) { if (lasat_map.virt) {
iounmap(lasat_map.virt);
lasat_map.virt = 0; lasat_map.virt = 0;
} }
} }
......
...@@ -277,6 +277,7 @@ int __init nettel_init(void) ...@@ -277,6 +277,7 @@ int __init nettel_init(void)
nettel_amd_map.virt = ioremap_nocache(amdaddr, maxsize); nettel_amd_map.virt = ioremap_nocache(amdaddr, maxsize);
if (!nettel_amd_map.virt) { if (!nettel_amd_map.virt) {
printk("SNAPGEAR: failed to ioremap() BOOTCS\n"); printk("SNAPGEAR: failed to ioremap() BOOTCS\n");
iounmap(nettel_mmcrp);
return(-EIO); return(-EIO);
} }
simple_map_init(&nettel_amd_map); simple_map_init(&nettel_amd_map);
...@@ -337,7 +338,8 @@ int __init nettel_init(void) ...@@ -337,7 +338,8 @@ int __init nettel_init(void)
nettel_amd_map.virt = NULL; nettel_amd_map.virt = NULL;
#else #else
/* Only AMD flash supported */ /* Only AMD flash supported */
return(-ENXIO); rc = -ENXIO;
goto out_unmap2;
#endif #endif
} }
...@@ -361,14 +363,15 @@ int __init nettel_init(void) ...@@ -361,14 +363,15 @@ int __init nettel_init(void)
nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize); nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize);
if (!nettel_intel_map.virt) { if (!nettel_intel_map.virt) {
printk("SNAPGEAR: failed to ioremap() ROMCS1\n"); printk("SNAPGEAR: failed to ioremap() ROMCS1\n");
return(-EIO); rc = -EIO;
goto out_unmap2;
} }
simple_map_init(&nettel_intel_map); simple_map_init(&nettel_intel_map);
intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map); intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map);
if (!intel_mtd) { if (!intel_mtd) {
iounmap(nettel_intel_map.virt); rc = -ENXIO;
return(-ENXIO); goto out_unmap1;
} }
/* Set PAR to the detected size */ /* Set PAR to the detected size */
...@@ -394,13 +397,14 @@ int __init nettel_init(void) ...@@ -394,13 +397,14 @@ int __init nettel_init(void)
nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize); nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize);
if (!nettel_intel_map.virt) { if (!nettel_intel_map.virt) {
printk("SNAPGEAR: failed to ioremap() ROMCS1/2\n"); printk("SNAPGEAR: failed to ioremap() ROMCS1/2\n");
return(-EIO); rc = -EIO;
goto out_unmap2;
} }
intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map); intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map);
if (! intel_mtd) { if (! intel_mtd) {
iounmap((void *) nettel_intel_map.virt); rc = -ENXIO;
return(-ENXIO); goto out_unmap1;
} }
intel1size = intel_mtd->size - intel0size; intel1size = intel_mtd->size - intel0size;
...@@ -456,6 +460,18 @@ int __init nettel_init(void) ...@@ -456,6 +460,18 @@ int __init nettel_init(void)
#endif #endif
return(rc); return(rc);
#ifdef CONFIG_MTD_CFI_INTELEXT
out_unmap1:
iounmap((void *) nettel_intel_map.virt);
#endif
out_unmap2:
iounmap(nettel_mmcrp);
iounmap(nettel_amd_map.virt);
return(rc);
} }
/****************************************************************************/ /****************************************************************************/
...@@ -469,6 +485,10 @@ void __exit nettel_cleanup(void) ...@@ -469,6 +485,10 @@ void __exit nettel_cleanup(void)
del_mtd_partitions(amd_mtd); del_mtd_partitions(amd_mtd);
map_destroy(amd_mtd); map_destroy(amd_mtd);
} }
if (nettel_mmcrp) {
iounmap(nettel_mmcrp);
nettel_mmcrp = NULL;
}
if (nettel_amd_map.virt) { if (nettel_amd_map.virt) {
iounmap(nettel_amd_map.virt); iounmap(nettel_amd_map.virt);
nettel_amd_map.virt = NULL; nettel_amd_map.virt = NULL;
......
...@@ -97,6 +97,7 @@ int __init init_ocotea(void) ...@@ -97,6 +97,7 @@ int __init init_ocotea(void)
ARRAY_SIZE(ocotea_small_partitions)); ARRAY_SIZE(ocotea_small_partitions));
} else { } else {
printk("map probe failed for flash\n"); printk("map probe failed for flash\n");
iounmap(ocotea_small_map.virt);
return -ENXIO; return -ENXIO;
} }
...@@ -106,6 +107,7 @@ int __init init_ocotea(void) ...@@ -106,6 +107,7 @@ int __init init_ocotea(void)
if (!ocotea_large_map.virt) { if (!ocotea_large_map.virt) {
printk("Failed to ioremap flash\n"); printk("Failed to ioremap flash\n");
iounmap(ocotea_small_map.virt);
return -EIO; return -EIO;
} }
...@@ -118,6 +120,8 @@ int __init init_ocotea(void) ...@@ -118,6 +120,8 @@ int __init init_ocotea(void)
ARRAY_SIZE(ocotea_large_partitions)); ARRAY_SIZE(ocotea_large_partitions));
} else { } else {
printk("map probe failed for flash\n"); printk("map probe failed for flash\n");
iounmap(ocotea_small_map.virt);
iounmap(ocotea_large_map.virt);
return -ENXIO; return -ENXIO;
} }
......
...@@ -602,6 +602,10 @@ static int pcmciamtd_config(struct pcmcia_device *link) ...@@ -602,6 +602,10 @@ static int pcmciamtd_config(struct pcmcia_device *link)
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_request_configuration(link, &link->conf);
if(ret != CS_SUCCESS) { if(ret != CS_SUCCESS) {
cs_error(link, RequestConfiguration, ret); cs_error(link, RequestConfiguration, ret);
if (dev->win_base) {
iounmap(dev->win_base);
dev->win_base = NULL;
}
return -ENODEV; return -ENODEV;
} }
......
...@@ -126,6 +126,8 @@ static struct mtd_info *redwood_mtd; ...@@ -126,6 +126,8 @@ static struct mtd_info *redwood_mtd;
int __init init_redwood_flash(void) int __init init_redwood_flash(void)
{ {
int err = 0;
printk(KERN_NOTICE "redwood: flash mapping: %x at %x\n", printk(KERN_NOTICE "redwood: flash mapping: %x at %x\n",
WINDOW_SIZE, WINDOW_ADDR); WINDOW_SIZE, WINDOW_ADDR);
...@@ -141,11 +143,18 @@ int __init init_redwood_flash(void) ...@@ -141,11 +143,18 @@ int __init init_redwood_flash(void)
if (redwood_mtd) { if (redwood_mtd) {
redwood_mtd->owner = THIS_MODULE; redwood_mtd->owner = THIS_MODULE;
return add_mtd_partitions(redwood_mtd, err = add_mtd_partitions(redwood_mtd,
redwood_flash_partitions, redwood_flash_partitions,
NUM_REDWOOD_FLASH_PARTITIONS); NUM_REDWOOD_FLASH_PARTITIONS);
if (err) {
printk("init_redwood_flash: add_mtd_partitions failed\n");
iounmap(redwood_flash_map.virt);
}
return err;
} }
iounmap(redwood_flash_map.virt);
return -ENXIO; return -ENXIO;
} }
......
...@@ -156,7 +156,7 @@ int __init init_sbc8240_mtd (void) ...@@ -156,7 +156,7 @@ int __init init_sbc8240_mtd (void)
}; };
int devicesfound = 0; int devicesfound = 0;
int i; int i,j;
for (i = 0; i < NUM_FLASH_BANKS; i++) { for (i = 0; i < NUM_FLASH_BANKS; i++) {
printk (KERN_NOTICE MSG_PREFIX printk (KERN_NOTICE MSG_PREFIX
...@@ -166,6 +166,10 @@ int __init init_sbc8240_mtd (void) ...@@ -166,6 +166,10 @@ int __init init_sbc8240_mtd (void)
(unsigned long) ioremap (pt[i].addr, pt[i].size); (unsigned long) ioremap (pt[i].addr, pt[i].size);
if (!sbc8240_map[i].map_priv_1) { if (!sbc8240_map[i].map_priv_1) {
printk (MSG_PREFIX "failed to ioremap\n"); printk (MSG_PREFIX "failed to ioremap\n");
for (j = 0; j < i; j++) {
iounmap((void *) sbc8240_map[j].map_priv_1);
sbc8240_map[j].map_priv_1 = 0;
}
return -EIO; return -EIO;
} }
simple_map_init(&sbc8240_mtd[i]); simple_map_init(&sbc8240_mtd[i]);
...@@ -175,6 +179,11 @@ int __init init_sbc8240_mtd (void) ...@@ -175,6 +179,11 @@ int __init init_sbc8240_mtd (void)
if (sbc8240_mtd[i]) { if (sbc8240_mtd[i]) {
sbc8240_mtd[i]->module = THIS_MODULE; sbc8240_mtd[i]->module = THIS_MODULE;
devicesfound++; devicesfound++;
} else {
if (sbc8240_map[i].map_priv_1) {
iounmap((void *) sbc8240_map[i].map_priv_1);
sbc8240_map[i].map_priv_1 = 0;
}
} }
} }
......
...@@ -68,6 +68,7 @@ int __init init_walnut(void) ...@@ -68,6 +68,7 @@ int __init init_walnut(void)
if (WALNUT_FLASH_ONBD_N(fpga_brds1)) { if (WALNUT_FLASH_ONBD_N(fpga_brds1)) {
printk("The on-board flash is disabled (U79 sw 5)!"); printk("The on-board flash is disabled (U79 sw 5)!");
iounmap(fpga_status_adr);
return -EIO; return -EIO;
} }
if (WALNUT_FLASH_SRAM_SEL(fpga_brds1)) if (WALNUT_FLASH_SRAM_SEL(fpga_brds1))
...@@ -81,6 +82,7 @@ int __init init_walnut(void) ...@@ -81,6 +82,7 @@ int __init init_walnut(void)
if (!walnut_map.virt) { if (!walnut_map.virt) {
printk("Failed to ioremap flash.\n"); printk("Failed to ioremap flash.\n");
iounmap(fpga_status_adr);
return -EIO; return -EIO;
} }
...@@ -93,9 +95,11 @@ int __init init_walnut(void) ...@@ -93,9 +95,11 @@ int __init init_walnut(void)
ARRAY_SIZE(walnut_partitions)); ARRAY_SIZE(walnut_partitions));
} else { } else {
printk("map probe failed for flash\n"); printk("map probe failed for flash\n");
iounmap(fpga_status_adr);
return -ENXIO; return -ENXIO;
} }
iounmap(fpga_status_adr);
return 0; return 0;
} }
......
...@@ -198,6 +198,9 @@ static void __exit ep7312_cleanup(void) ...@@ -198,6 +198,9 @@ static void __exit ep7312_cleanup(void)
/* Release resources, unregister device */ /* Release resources, unregister device */
nand_release(ap7312_mtd); nand_release(ap7312_mtd);
/* Release io resource */
iounmap((void *)this->IO_ADDR_R);
/* Free the MTD device structure */ /* Free the MTD device structure */
kfree(ep7312_mtd); kfree(ep7312_mtd);
} }
......
...@@ -276,6 +276,7 @@ static int __init ppchameleonevb_init(void) ...@@ -276,6 +276,7 @@ static int __init ppchameleonevb_init(void)
/* Scan to find existence of the device (it could not be mounted) */ /* Scan to find existence of the device (it could not be mounted) */
if (nand_scan(ppchameleon_mtd, 1)) { if (nand_scan(ppchameleon_mtd, 1)) {
iounmap((void *)ppchameleon_fio_base); iounmap((void *)ppchameleon_fio_base);
ppchameleon_fio_base = NULL;
kfree(ppchameleon_mtd); kfree(ppchameleon_mtd);
goto nand_evb_init; goto nand_evb_init;
} }
...@@ -314,6 +315,8 @@ static int __init ppchameleonevb_init(void) ...@@ -314,6 +315,8 @@ static int __init ppchameleonevb_init(void)
ppchameleonevb_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); ppchameleonevb_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
if (!ppchameleonevb_mtd) { if (!ppchameleonevb_mtd) {
printk("Unable to allocate PPChameleonEVB NAND MTD device structure.\n"); printk("Unable to allocate PPChameleonEVB NAND MTD device structure.\n");
if (ppchameleon_fio_base)
iounmap(ppchameleon_fio_base);
return -ENOMEM; return -ENOMEM;
} }
...@@ -322,6 +325,8 @@ static int __init ppchameleonevb_init(void) ...@@ -322,6 +325,8 @@ static int __init ppchameleonevb_init(void)
if (!ppchameleonevb_fio_base) { if (!ppchameleonevb_fio_base) {
printk("ioremap PPChameleonEVB NAND flash failed\n"); printk("ioremap PPChameleonEVB NAND flash failed\n");
kfree(ppchameleonevb_mtd); kfree(ppchameleonevb_mtd);
if (ppchameleon_fio_base)
iounmap(ppchameleon_fio_base);
return -EIO; return -EIO;
} }
...@@ -378,6 +383,8 @@ static int __init ppchameleonevb_init(void) ...@@ -378,6 +383,8 @@ static int __init ppchameleonevb_init(void)
if (nand_scan(ppchameleonevb_mtd, 1)) { if (nand_scan(ppchameleonevb_mtd, 1)) {
iounmap((void *)ppchameleonevb_fio_base); iounmap((void *)ppchameleonevb_fio_base);
kfree(ppchameleonevb_mtd); kfree(ppchameleonevb_mtd);
if (ppchameleon_fio_base)
iounmap(ppchameleon_fio_base);
return -ENXIO; return -ENXIO;
} }
#ifdef CONFIG_MTD_PARTITIONS #ifdef CONFIG_MTD_PARTITIONS
......
#define UTS_RELEASE "2.6.18"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment