summaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorMiquel Raynal <miquel.raynal@bootlin.com>2020-05-25 10:58:49 +0200
committerMiquel Raynal <miquel.raynal@bootlin.com>2020-05-31 10:53:40 +0200
commit73f2b68c51f4f6c3dbe621d263d6fd32526f2faf (patch)
tree9d2061c218a122ff1894052cfa64f7d83a392f36 /drivers/mtd
parentdc2733dea2be78e03df1fbb5816b59d852b2291c (diff)
downloadlinux-stable-73f2b68c51f4f6c3dbe621d263d6fd32526f2faf.tar.gz
linux-stable-73f2b68c51f4f6c3dbe621d263d6fd32526f2faf.tar.bz2
linux-stable-73f2b68c51f4f6c3dbe621d263d6fd32526f2faf.zip
mtd: rawnand: nandsim: Manage lists on error in ns_init_module()
Lists are filled with calls to ns_parse_weakblocks(), ns_parse_weakpages() and ns_parse_gravepages(). Handle them in the error path, all at the same time. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/linux-mtd/20200525085851.17682-16-miquel.raynal@bootlin.com
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/raw/nandsim.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/mtd/nand/raw/nandsim.c b/drivers/mtd/nand/raw/nandsim.c
index 8ffd68321175..4492b9a9962e 100644
--- a/drivers/mtd/nand/raw/nandsim.c
+++ b/drivers/mtd/nand/raw/nandsim.c
@@ -2273,6 +2273,7 @@ static const struct nand_controller_ops ns_controller_ops = {
*/
static int __init ns_init_module(void)
{
+ struct list_head *pos, *n;
struct nand_chip *chip;
struct nandsim *ns;
int ret;
@@ -2340,11 +2341,11 @@ static int __init ns_init_module(void)
ret = ns_parse_weakpages();
if (ret)
- goto error;
+ goto free_wb_list;
ret = ns_parse_gravepages();
if (ret)
- goto error;
+ goto free_wp_list;
nand_controller_init(&ns->base);
ns->base.ops = &ns_controller_ops;
@@ -2353,7 +2354,7 @@ static int __init ns_init_module(void)
ret = nand_scan(chip, 1);
if (ret) {
NS_ERR("Could not scan NAND Simulator device\n");
- goto error;
+ goto free_gp_list;
}
if (overridesize) {
@@ -2412,9 +2413,23 @@ free_ebw:
kfree(erase_block_wear);
cleanup_nand:
nand_cleanup(chip);
+free_gp_list:
+ list_for_each_safe(pos, n, &grave_pages) {
+ list_del(pos);
+ kfree(list_entry(pos, struct grave_page, list));
+ }
+free_wp_list:
+ list_for_each_safe(pos, n, &weak_pages) {
+ list_del(pos);
+ kfree(list_entry(pos, struct weak_page, list));
+ }
+free_wb_list:
+ list_for_each_safe(pos, n, &weak_blocks) {
+ list_del(pos);
+ kfree(list_entry(pos, struct weak_block, list));
+ }
error:
kfree(ns);
- ns_free_lists();
return ret;
}