]> git.sur5r.net Git - u-boot/blobdiff - drivers/mtd/onenand/onenand_bbt.c
mtd, ubi, ubifs: resync with Linux-3.14
[u-boot] / drivers / mtd / onenand / onenand_bbt.c
index 5a610ee5ea8b3fc381da19104112f227ce82e176..52509f1ae9ab4747a80f14304b05231c9466ced1 100644 (file)
@@ -3,7 +3,7 @@
  *
  *  Bad Block Table support for the OneNAND driver
  *
- *  Copyright(c) 2005-2007 Samsung Electronics
+ *  Copyright(c) 2005-2008 Samsung Electronics
  *  Kyungmin Park <kyungmin.park@samsung.com>
  *
  *  TODO:
  */
 
 #include <common.h>
-
-#ifdef CONFIG_CMD_ONENAND
-
-#include <linux/mtd/compat.h>
+#include <linux/compat.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/onenand.h>
 #include <malloc.h>
@@ -71,6 +68,8 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf,
        int startblock;
        loff_t from;
        size_t readlen, ooblen;
+       struct mtd_oob_ops ops;
+       int rgn;
 
        printk(KERN_INFO "Scanning device for bad blocks\n");
 
@@ -84,30 +83,31 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf,
        /* Note that numblocks is 2 * (real numblocks) here;
         * see i += 2 below as it makses shifting and masking less painful
         */
-       numblocks = mtd->size >> (bbm->bbt_erase_shift - 1);
+       numblocks = this->chipsize >> (bbm->bbt_erase_shift - 1);
        startblock = 0;
        from = 0;
 
+       ops.mode = MTD_OPS_PLACE_OOB;
+       ops.ooblen = readlen;
+       ops.oobbuf = buf;
+       ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
+
        for (i = startblock; i < numblocks;) {
                int ret;
 
                for (j = 0; j < len; j++) {
-                       size_t retlen;
-
                        /* No need to read pages fully,
                         * just read required OOB bytes */
-                       ret = onenand_read_oob(mtd,
-                                            from + j * mtd->oobblock +
-                                            bd->offs, readlen, &retlen,
-                                            &buf[0]);
-
-                       if (ret && ret != -EAGAIN) {
-                               printk("ret = %d\n", ret);
-                               return ret;
-                       }
+                       ret = onenand_bbt_read_oob(mtd,
+                                            from + j * mtd->writesize +
+                                            bd->offs, &ops);
 
-                       if (check_short_pattern
-                           (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
+                       /* If it is a initial bad block, just ignore it */
+                       if (ret == ONENAND_BBT_READ_FATAL_ERROR)
+                               return -EIO;
+
+                       if (ret || check_short_pattern
+                           (&buf[j * scanlen], scanlen, mtd->writesize, bd)) {
                                bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
                                printk(KERN_WARNING
                                       "Bad eraseblock %d at 0x%08x\n", i >> 1,
@@ -116,7 +116,12 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf,
                        }
                }
                i += 2;
-               from += (1 << bbm->bbt_erase_shift);
+
+               if (FLEXONENAND(this)) {
+                       rgn = flexonenand_region(mtd, from);
+                       from += mtd->eraseregions[rgn].erasesize;
+               } else
+                       from += (1 << bbm->bbt_erase_shift);
        }
 
        return 0;
@@ -135,7 +140,6 @@ static inline int onenand_memory_bbt(struct mtd_info *mtd,
 {
        unsigned char data_buf[MAX_ONENAND_PAGESIZE];
 
-       bd->options &= ~NAND_BBT_SCANEMPTY;
        return create_bbt(mtd, data_buf, bd, -1);
 }
 
@@ -153,12 +157,12 @@ static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
        uint8_t res;
 
        /* Get block number * 2 */
-       block = (int)(offs >> (bbm->bbt_erase_shift - 1));
+       block = (int) (onenand_block(this, offs) << 1);
        res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03;
 
-       DEBUG(MTD_DEBUG_LEVEL2,
-             "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n",
-             (unsigned int)offs, block >> 1, res);
+       MTDDEBUG (MTD_DEBUG_LEVEL2,
+               "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n",
+               (unsigned int)offs, block >> 1, res);
 
        switch ((int)res) {
        case 0x00:
@@ -192,13 +196,11 @@ int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
        struct bbm_info *bbm = this->bbm;
        int len, ret = 0;
 
-       len = mtd->size >> (this->erase_shift + 2);
+       len = this->chipsize >> (this->erase_shift + 2);
        /* Allocate memory (2bit per block) */
        bbm->bbt = malloc(len);
-       if (!bbm->bbt) {
-               printk(KERN_ERR "onenand_scan_bbt: Out of memory\n");
+       if (!bbm->bbt)
                return -ENOMEM;
-       }
        /* Clear the memory bad block table */
        memset(bbm->bbt, 0x00, len);
 
@@ -261,5 +263,3 @@ int onenand_default_bbt(struct mtd_info *mtd)
 
        return onenand_scan_bbt(mtd, bbm->badblock_pattern);
 }
-
-#endif /* CFG_CMD_ONENAND */