[PATCH] mtd: nand: write bad block marker even with BBT

Brian Norris computersforpeace at gmail.com
Wed Dec 7 16:08:20 EST 2011


Add and option (NAND_BBT_WRITE_BBM) for writing bad block markers to
proper OOB area on each block in addition to flash-based BBT. This is
useful when:

 * bootloader cannot read the flash-based BBT format
 * BBT is corrupted and the flash must be rescanned for bad
   blocks; we want to remember bad blocks that were marked from Linux

Adapted from code by Matthieu CASTET.

Cc: Matthieu CASTET <matthieu.castet at parrot.com>
Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
Last year's discussion thread:
    http://lists.infradead.org/pipermail/linux-mtd/2010-October/032942.html

I'll address the criticisms:

"add a BUG_ON to catch misuse cases when NAND_WRITE_BB [now named
NAND_BBT_WRITE_BBM] is used without NAND_USE_FLASH_BBT - they should go
in pair"

NAND_BBT_WRITE_BBM has no special effect when used without
NAND_BBT_USE_FLASH; it's already the default behavior. So I don't expect
it to be an issue.

"And also, how about cases when BBT is updated, but OOB did not because
of a power cut"

Not a very likely case as bad blocks are written infrequently, plus for
the situations where we're writing BBM simply because the bootloader
doesn't understand our BBT, having 99% of blocks marked properly is
better than none.

 drivers/mtd/nand/nand_base.c |   11 +++++++++--
 include/linux/mtd/bbm.h      |    9 +++++++++
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 35b4565..6d619f7 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -392,7 +392,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
 	struct nand_chip *chip = mtd->priv;
 	uint8_t buf[2] = { 0, 0 };
-	int block, ret, i = 0;
+	int block, ret = 0, i = 0;
 
 	if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
 		ofs += mtd->erasesize - mtd->writesize;
@@ -405,7 +405,14 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
 	/* Do we have a flash based bad block table? */
 	if (chip->bbt_options & NAND_BBT_USE_FLASH)
 		ret = nand_update_bbt(mtd, ofs);
-	else {
+	/*
+	 * Write bad block marker to OOB, in one of two cases:
+	 *  (1) we don't have flash-based BBT
+	 *  (2) we have flash-based BBT but also want to keep markers in OOB in
+	 *      each block
+	 */
+	if (!(chip->bbt_options & NAND_BBT_USE_FLASH) ||
+			(chip->bbt_options & NAND_BBT_WRITE_BBM)) {
 		struct mtd_oob_ops ops;
 
 		nand_get_device(chip, mtd, FL_WRITING);
diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h
index c4eec22..61fcb30 100644
--- a/include/linux/mtd/bbm.h
+++ b/include/linux/mtd/bbm.h
@@ -112,6 +112,15 @@ struct nand_bbt_descr {
 #define NAND_BBT_USE_FLASH	0x00020000
 /* Do not store flash based bad block table in OOB area; store it in-band */
 #define NAND_BBT_NO_OOB		0x00040000
+/*
+ * Write bad block marker to OOB when marking new bad blocks. This is the
+ * default behavior without NAND_USE_FLASH_BBT, so this is only useful in
+ * conjunction with NAND_USE_FLASH_BBT.
+ * One might need bad blocks marked in each block as well as in BBT when
+ * bootloader cannot read the flash-based BBT format or when the BBT is
+ * corrupted and the flash must be rescanned for bad blocks.
+ */
+#define NAND_BBT_WRITE_BBM	0x00080000
 
 /*
  * Flag set by nand_create_default_bbt_descr(), marking that the nand_bbt_descr
-- 
1.7.5.4




More information about the linux-mtd mailing list