mtd: nand: fix SCAN2NDPAGE check for BBM
authorBrian Norris <computersforpeace@gmail.com>
Sat, 14 Jan 2012 02:11:48 +0000 (18:11 -0800)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Mon, 26 Mar 2012 23:11:50 +0000 (00:11 +0100)
nand_block_bad() doesn't check the correct pages when
NAND_BBT_SCAN2NDPAGE is enabled. It should scan both the OOB region of
both the 1st and 2nd page of each block.

Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
drivers/mtd/nand/nand_base.c

index cd827d5..7855fd2 100644 (file)
@@ -338,7 +338,7 @@ static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
  */
 static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
 {
-       int page, chipnr, res = 0;
+       int page, chipnr, res = 0, i = 0;
        struct nand_chip *chip = mtd->priv;
        u16 bad;
 
@@ -356,23 +356,29 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
                chip->select_chip(mtd, chipnr);
        }
 
-       if (chip->options & NAND_BUSWIDTH_16) {
-               chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos & 0xFE,
-                             page);
-               bad = cpu_to_le16(chip->read_word(mtd));
-               if (chip->badblockpos & 0x1)
-                       bad >>= 8;
-               else
-                       bad &= 0xFF;
-       } else {
-               chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos, page);
-               bad = chip->read_byte(mtd);
-       }
+       do {
+               if (chip->options & NAND_BUSWIDTH_16) {
+                       chip->cmdfunc(mtd, NAND_CMD_READOOB,
+                                       chip->badblockpos & 0xFE, page);
+                       bad = cpu_to_le16(chip->read_word(mtd));
+                       if (chip->badblockpos & 0x1)
+                               bad >>= 8;
+                       else
+                               bad &= 0xFF;
+               } else {
+                       chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos,
+                                       page);
+                       bad = chip->read_byte(mtd);
+               }
 
-       if (likely(chip->badblockbits == 8))
-               res = bad != 0xFF;
-       else
-               res = hweight8(bad) < chip->badblockbits;
+               if (likely(chip->badblockbits == 8))
+                       res = bad != 0xFF;
+               else
+                       res = hweight8(bad) < chip->badblockbits;
+               ofs += mtd->writesize;
+               page = (int)(ofs >> chip->page_shift) & chip->pagemask;
+               i++;
+       } while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE));
 
        if (getchip)
                nand_release_device(mtd);