mtd: nand: add ->badblockbits for minimum number of set bits in bad block byte
authorMaxim Levitsky <maximlevitsky@gmail.com>
Mon, 22 Feb 2010 18:39:38 +0000 (20:39 +0200)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Fri, 26 Feb 2010 18:02:07 +0000 (18:02 +0000)
This can be used to protect against bitflips in that field, but now mostly
for smartmedia.

Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
drivers/mtd/nand/nand_base.c
include/linux/mtd/nand.h

index 51dfea1..ba29a29 100644 (file)
@@ -364,14 +364,18 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
                bad = cpu_to_le16(chip->read_word(mtd));
                if (chip->badblockpos & 0x1)
                        bad >>= 8;
-               if ((bad & 0xFF) != 0xff)
-                       res = 1;
+               else
+                       bad &= 0xFF;
        } else {
                chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos, page);
-               if (chip->read_byte(mtd) != 0xff)
-                       res = 1;
+               bad = chip->read_byte(mtd);
        }
 
+       if (likely(chip->badblockbits == 8))
+               res = bad != 0xFF;
+       else
+               res = hweight8(bad) < chip->badblockbits;
+
        if (getchip)
                nand_release_device(mtd);
 
@@ -2884,6 +2888,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
        /* Set the bad block position */
        chip->badblockpos = mtd->writesize > 512 ?
                NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
+       chip->badblockbits = 8;
 
        /* Get chip options, preserve non chip based options */
        chip->options &= ~NAND_CHIPOPTIONS_MSK;
index 48bc2c5..f2d4a1a 100644 (file)
@@ -401,6 +401,7 @@ struct nand_chip {
        int             subpagesize;
        uint8_t         cellinfo;
        int             badblockpos;
+       int             badblockbits;
 
        flstate_t       state;