Merge branch 'master' of git://git.denx.de/u-boot-usb
[oweals/u-boot.git] / drivers / mtd / nand / nand_bbt.c
index 00f28a41571a6b0a0bc1454ecd832bf31032722a..74c4c9a3c802f679955bfb55be367f2803fa6a5b 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  drivers/mtd/nand_bbt.c
- *
  *  Overview:
  *   Bad block table support for the NAND driver
  *
@@ -65,7 +63,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/bbm.h>
 #include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
 #include <linux/bitops.h>
 #include <linux/string.h>
 
@@ -173,7 +170,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
                struct nand_bbt_descr *td, int offs)
 {
        int res, ret = 0, i, j, act = 0;
-       struct nand_chip *this = mtd->priv;
+       struct nand_chip *this = mtd_to_nand(mtd);
        size_t retlen, len, totlen;
        loff_t from;
        int bits = td->options & NAND_BBT_NRBITS_MSK;
@@ -264,7 +261,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
  */
 static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip)
 {
-       struct nand_chip *this = mtd->priv;
+       struct nand_chip *this = mtd_to_nand(mtd);
        int res = 0, i;
 
        if (td->options & NAND_BBT_PERCHIP) {
@@ -389,7 +386,7 @@ static u32 bbt_get_ver_offs(struct mtd_info *mtd, struct nand_bbt_descr *td)
 static void read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
                          struct nand_bbt_descr *td, struct nand_bbt_descr *md)
 {
-       struct nand_chip *this = mtd->priv;
+       struct nand_chip *this = mtd_to_nand(mtd);
 
        /* Read the primary version, if available */
        if (td->options & NAND_BBT_VERSION) {
@@ -455,7 +452,7 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
 static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
        struct nand_bbt_descr *bd, int chip)
 {
-       struct nand_chip *this = mtd->priv;
+       struct nand_chip *this = mtd_to_nand(mtd);
        int i, numblocks, numpages;
        int startblock;
        loff_t from;
@@ -524,7 +521,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
  */
 static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
 {
-       struct nand_chip *this = mtd->priv;
+       struct nand_chip *this = mtd_to_nand(mtd);
        int i, chips;
        int startblock, block, dir;
        int scanlen = mtd->writesize + mtd->oobsize;
@@ -619,7 +616,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                     struct nand_bbt_descr *td, struct nand_bbt_descr *md,
                     int chipsel)
 {
-       struct nand_chip *this = mtd->priv;
+       struct nand_chip *this = mtd_to_nand(mtd);
        struct erase_info einfo;
        int i, res, chip = 0;
        int bits, startblock, dir, page, offs, numblocks, sft, sftmsk;
@@ -718,7 +715,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                /* Must we save the block contents? */
                if (td->options & NAND_BBT_SAVECONTENT) {
                        /* Make it block aligned */
-                       to &= ~((loff_t)((1 << this->bbt_erase_shift) - 1));
+                       to &= ~(((loff_t)1 << this->bbt_erase_shift) - 1);
                        len = 1 << this->bbt_erase_shift;
                        res = mtd_read(mtd, to, len, &retlen, buf);
                        if (res < 0) {
@@ -820,7 +817,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
  */
 static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 {
-       struct nand_chip *this = mtd->priv;
+       struct nand_chip *this = mtd_to_nand(mtd);
 
        return create_bbt(mtd, this->buffers->databuf, bd, -1);
 }
@@ -839,7 +836,7 @@ static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *b
 static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
 {
        int i, chips, writeops, create, chipsel, res, res2;
-       struct nand_chip *this = mtd->priv;
+       struct nand_chip *this = mtd_to_nand(mtd);
        struct nand_bbt_descr *td = this->bbt_td;
        struct nand_bbt_descr *md = this->bbt_md;
        struct nand_bbt_descr *rd, *rd2;
@@ -963,7 +960,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
  */
 static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
 {
-       struct nand_chip *this = mtd->priv;
+       struct nand_chip *this = mtd_to_nand(mtd);
        int i, j, chips, block, nrblocks, update;
        uint8_t oldval;
 
@@ -1023,7 +1020,7 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
  */
 static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 {
-       struct nand_chip *this = mtd->priv;
+       struct nand_chip *this = mtd_to_nand(mtd);
        u32 pattern_len;
        u32 bits;
        u32 table_size;
@@ -1073,15 +1070,15 @@ static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
  * The bad block table memory is allocated here. It must be freed by calling
  * the nand_free_bbt function.
  */
-int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
+static int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 {
-       struct nand_chip *this = mtd->priv;
-       int len, res = 0;
+       struct nand_chip *this = mtd_to_nand(mtd);
+       int len, res;
        uint8_t *buf;
        struct nand_bbt_descr *td = this->bbt_td;
        struct nand_bbt_descr *md = this->bbt_md;
 
-       len = mtd->size >> (this->bbt_erase_shift + 2);
+       len = (mtd->size >> (this->bbt_erase_shift + 2)) ? : 1;
        /*
         * Allocate memory (2bit per block) and clear the memory bad block
         * table.
@@ -1097,10 +1094,9 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
        if (!td) {
                if ((res = nand_memory_bbt(mtd, bd))) {
                        pr_err("nand_bbt: can't scan flash and build the RAM-based BBT\n");
-                       kfree(this->bbt);
-                       this->bbt = NULL;
+                       goto err;
                }
-               return res;
+               return 0;
        }
        verify_bbt_descr(mtd, td);
        verify_bbt_descr(mtd, md);
@@ -1110,9 +1106,8 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
        len += (len >> this->page_shift) * mtd->oobsize;
        buf = vmalloc(len);
        if (!buf) {
-               kfree(this->bbt);
-               this->bbt = NULL;
-               return -ENOMEM;
+               res = -ENOMEM;
+               goto err;
        }
 
        /* Is the bbt at a given page? */
@@ -1124,6 +1119,8 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
        }
 
        res = check_create(mtd, buf, bd);
+       if (res)
+               goto err;
 
        /* Prevent the bbt regions from erasing / writing */
        mark_bbt_region(mtd, td);
@@ -1131,6 +1128,11 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
                mark_bbt_region(mtd, md);
 
        vfree(buf);
+       return 0;
+
+err:
+       kfree(this->bbt);
+       this->bbt = NULL;
        return res;
 }
 
@@ -1143,7 +1145,7 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
  */
 static int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
 {
-       struct nand_chip *this = mtd->priv;
+       struct nand_chip *this = mtd_to_nand(mtd);
        int len, res = 0;
        int chip, chipsel;
        uint8_t *buf;
@@ -1277,7 +1279,7 @@ static int nand_create_badblock_pattern(struct nand_chip *this)
  */
 int nand_default_bbt(struct mtd_info *mtd)
 {
-       struct nand_chip *this = mtd->priv;
+       struct nand_chip *this = mtd_to_nand(mtd);
        int ret;
 
        /* Is a flash based bad block table requested? */
@@ -1313,7 +1315,7 @@ int nand_default_bbt(struct mtd_info *mtd)
  */
 int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs)
 {
-       struct nand_chip *this = mtd->priv;
+       struct nand_chip *this = mtd_to_nand(mtd);
        int block;
 
        block = (int)(offs >> this->bbt_erase_shift);
@@ -1328,7 +1330,7 @@ int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs)
  */
 int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
 {
-       struct nand_chip *this = mtd->priv;
+       struct nand_chip *this = mtd_to_nand(mtd);
        int block, res;
 
        block = (int)(offs >> this->bbt_erase_shift);
@@ -1355,7 +1357,7 @@ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
  */
 int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
 {
-       struct nand_chip *this = mtd->priv;
+       struct nand_chip *this = mtd_to_nand(mtd);
        int block, ret = 0;
 
        block = (int)(offs >> this->bbt_erase_shift);
@@ -1369,5 +1371,3 @@ int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
 
        return ret;
 }
-
-EXPORT_SYMBOL(nand_scan_bbt);