[MTD] [NAND] atmel_nand: Clean up and fix probe() error path
authorHåvard Skinnemoen <haavard.skinnemoen@atmel.com>
Fri, 6 Jun 2008 16:04:54 +0000 (18:04 +0200)
committerDavid Woodhouse <dwmw2@infradead.org>
Sat, 7 Jun 2008 07:43:11 +0000 (08:43 +0100)
This fixes several bugs in the atmel_nand_probe() error path, including
at least one memory leak.

Signed-off-by: Håvard Skinnemoen <haavard.skinnemoen@atmel.com>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
drivers/mtd/nand/atmel_nand.c

index 675a82ca77f587b8f85a841898f46f7c607aa9b9..325ce29f53fc3bc32fb86a96a45fc04efb135d07 100644 (file)
@@ -371,6 +371,12 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
        int num_partitions = 0;
 #endif
 
+       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!mem) {
+               printk(KERN_ERR "atmel_nand: can't get I/O resource mem\n");
+               return -ENXIO;
+       }
+
        /* Allocate memory for the device structure (and zero it) */
        host = kzalloc(sizeof(struct atmel_nand_host), GFP_KERNEL);
        if (!host) {
@@ -378,17 +384,11 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
-       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!mem) {
-               printk(KERN_ERR "atmel_nand: can't get I/O resource mem\n");
-               return -ENXIO;
-       }
-
        host->io_base = ioremap(mem->start, mem->end - mem->start + 1);
        if (host->io_base == NULL) {
                printk(KERN_ERR "atmel_nand: ioremap failed\n");
-               kfree(host);
-               return -EIO;
+               res = -EIO;
+               goto err_nand_ioremap;
        }
 
        mtd = &host->mtd;
@@ -446,14 +446,14 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
                if (gpio_get_value(host->board->det_pin)) {
                        printk ("No SmartMedia card inserted.\n");
                        res = ENXIO;
-                       goto out;
+                       goto err_no_card;
                }
        }
 
        /* first scan to find the device and get the page size */
        if (nand_scan_ident(mtd, 1)) {
                res = -ENXIO;
-               goto out;
+               goto err_scan_ident;
        }
 
        if (nand_chip->ecc.mode == NAND_ECC_HW_SYNDROME) {
@@ -498,7 +498,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
        /* second phase scan */
        if (nand_scan_tail(mtd)) {
                res = -ENXIO;
-               goto out;
+               goto err_scan_tail;
        }
 
 #ifdef CONFIG_MTD_PARTITIONS
@@ -514,7 +514,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
        if ((!partitions) || (num_partitions == 0)) {
                printk(KERN_ERR "atmel_nand: No parititions defined, or unsupported device.\n");
                res = ENXIO;
-               goto release;
+               goto err_no_partitions;
        }
 
        res = add_mtd_partitions(mtd, partitions, num_partitions);
@@ -526,17 +526,19 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
                return res;
 
 #ifdef CONFIG_MTD_PARTITIONS
-release:
+err_no_partitions:
 #endif
        nand_release(mtd);
-
-out:
-       iounmap(host->ecc);
-
-err_ecc_ioremap:
+err_scan_tail:
+err_scan_ident:
+err_no_card:
        atmel_nand_disable(host);
        platform_set_drvdata(pdev, NULL);
+       if (host->ecc)
+               iounmap(host->ecc);
+err_ecc_ioremap:
        iounmap(host->io_base);
+err_nand_ioremap:
        kfree(host);
        return res;
 }
@@ -553,8 +555,9 @@ static int __devexit atmel_nand_remove(struct platform_device *pdev)
 
        atmel_nand_disable(host);
 
+       if (host->ecc)
+               iounmap(host->ecc);
        iounmap(host->io_base);
-       iounmap(host->ecc);
        kfree(host);
 
        return 0;
This page took 0.026457 seconds and 5 git commands to generate.