Commit 2c78c443 authored by Roel Kluin's avatar Roel Kluin Committed by David Woodhouse

mtd: pmcmsp-flash: fix error paths in init_msp_flash

Cleanin up after errors in init_msp_flash().

Also cleanup_msp_flash() attempts to determine the size of
msp_flash with `sizeof(msp_flash) / sizeof(struct mtd_info **)'
This will not work since msp_flash is not an array.
Signed-off-by: default avatarRoel Kluin <roel.kluin@gmail.com>
Signed-off-by: default avatarArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent fca91088
...@@ -50,7 +50,7 @@ static int fcnt; ...@@ -50,7 +50,7 @@ static int fcnt;
static int __init init_msp_flash(void) static int __init init_msp_flash(void)
{ {
int i, j; int i, j, ret = -ENOMEM;
int offset, coff; int offset, coff;
char *env; char *env;
int pcnt; int pcnt;
...@@ -75,14 +75,16 @@ static int __init init_msp_flash(void) ...@@ -75,14 +75,16 @@ static int __init init_msp_flash(void)
printk(KERN_NOTICE "Found %d PMC flash devices\n", fcnt); printk(KERN_NOTICE "Found %d PMC flash devices\n", fcnt);
msp_flash = kmalloc(fcnt * sizeof(struct map_info *), GFP_KERNEL); msp_flash = kmalloc(fcnt * sizeof(struct map_info *), GFP_KERNEL);
if (!msp_flash)
return -ENOMEM;
msp_parts = kmalloc(fcnt * sizeof(struct mtd_partition *), GFP_KERNEL); msp_parts = kmalloc(fcnt * sizeof(struct mtd_partition *), GFP_KERNEL);
if (!msp_parts)
goto free_msp_flash;
msp_maps = kcalloc(fcnt, sizeof(struct mtd_info), GFP_KERNEL); msp_maps = kcalloc(fcnt, sizeof(struct mtd_info), GFP_KERNEL);
if (!msp_flash || !msp_parts || !msp_maps) { if (!msp_maps)
kfree(msp_maps); goto free_msp_parts;
kfree(msp_parts);
kfree(msp_flash);
return -ENOMEM;
}
/* loop over the flash devices, initializing each */ /* loop over the flash devices, initializing each */
for (i = 0; i < fcnt; i++) { for (i = 0; i < fcnt; i++) {
...@@ -100,13 +102,18 @@ static int __init init_msp_flash(void) ...@@ -100,13 +102,18 @@ static int __init init_msp_flash(void)
msp_parts[i] = kcalloc(pcnt, sizeof(struct mtd_partition), msp_parts[i] = kcalloc(pcnt, sizeof(struct mtd_partition),
GFP_KERNEL); GFP_KERNEL);
if (!msp_parts[i])
goto cleanup_loop;
/* now initialize the devices proper */ /* now initialize the devices proper */
flash_name[5] = '0' + i; flash_name[5] = '0' + i;
env = prom_getenv(flash_name); env = prom_getenv(flash_name);
if (sscanf(env, "%x:%x", &addr, &size) < 2) if (sscanf(env, "%x:%x", &addr, &size) < 2) {
return -ENXIO; ret = -ENXIO;
kfree(msp_parts[i]);
goto cleanup_loop;
}
addr = CPHYSADDR(addr); addr = CPHYSADDR(addr);
printk(KERN_NOTICE printk(KERN_NOTICE
...@@ -122,13 +129,23 @@ static int __init init_msp_flash(void) ...@@ -122,13 +129,23 @@ static int __init init_msp_flash(void)
*/ */
if (size > CONFIG_MSP_FLASH_MAP_LIMIT) if (size > CONFIG_MSP_FLASH_MAP_LIMIT)
size = CONFIG_MSP_FLASH_MAP_LIMIT; size = CONFIG_MSP_FLASH_MAP_LIMIT;
msp_maps[i].virt = ioremap(addr, size); msp_maps[i].virt = ioremap(addr, size);
if (msp_maps[i].virt == NULL) {
ret = -ENXIO;
kfree(msp_parts[i]);
goto cleanup_loop;
}
msp_maps[i].bankwidth = 1; msp_maps[i].bankwidth = 1;
msp_maps[i].name = strncpy(kmalloc(7, GFP_KERNEL), msp_maps[i].name = kmalloc(7, GFP_KERNEL);
flash_name, 7); if (!msp_maps[i].name) {
iounmap(msp_maps[i].virt);
kfree(msp_parts[i]);
goto cleanup_loop;
}
if (msp_maps[i].virt == NULL) msp_maps[i].name = strncpy(msp_maps[i].name, flash_name, 7);
return -ENXIO;
for (j = 0; j < pcnt; j++) { for (j = 0; j < pcnt; j++) {
part_name[5] = '0' + i; part_name[5] = '0' + i;
...@@ -136,8 +153,14 @@ static int __init init_msp_flash(void) ...@@ -136,8 +153,14 @@ static int __init init_msp_flash(void)
env = prom_getenv(part_name); env = prom_getenv(part_name);
if (sscanf(env, "%x:%x:%n", &offset, &size, &coff) < 2) if (sscanf(env, "%x:%x:%n", &offset, &size,
return -ENXIO; &coff) < 2) {
ret = -ENXIO;
kfree(msp_maps[i].name);
iounmap(msp_maps[i].virt);
kfree(msp_parts[i]);
goto cleanup_loop;
}
msp_parts[i][j].size = size; msp_parts[i][j].size = size;
msp_parts[i][j].offset = offset; msp_parts[i][j].offset = offset;
...@@ -152,18 +175,37 @@ static int __init init_msp_flash(void) ...@@ -152,18 +175,37 @@ static int __init init_msp_flash(void)
add_mtd_partitions(msp_flash[i], msp_parts[i], pcnt); add_mtd_partitions(msp_flash[i], msp_parts[i], pcnt);
} else { } else {
printk(KERN_ERR "map probe failed for flash\n"); printk(KERN_ERR "map probe failed for flash\n");
return -ENXIO; ret = -ENXIO;
kfree(msp_maps[i].name);
iounmap(msp_maps[i].virt);
kfree(msp_parts[i]);
goto cleanup_loop;
} }
} }
return 0; return 0;
cleanup_loop:
while (i--) {
del_mtd_partitions(msp_flash[i]);
map_destroy(msp_flash[i]);
kfree(msp_maps[i].name);
iounmap(msp_maps[i].virt);
kfree(msp_parts[i]);
}
kfree(msp_maps);
free_msp_parts:
kfree(msp_parts);
free_msp_flash:
kfree(msp_flash);
return ret;
} }
static void __exit cleanup_msp_flash(void) static void __exit cleanup_msp_flash(void)
{ {
int i; int i;
for (i = 0; i < sizeof(msp_flash) / sizeof(struct mtd_info **); i++) { for (i = 0; i < fcnt; i++) {
del_mtd_partitions(msp_flash[i]); del_mtd_partitions(msp_flash[i]);
map_destroy(msp_flash[i]); map_destroy(msp_flash[i]);
iounmap((void *)msp_maps[i].virt); iounmap((void *)msp_maps[i].virt);
......
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