[PATCH v3] mtd: nand: add option to erase NAND blocks even if detected as bad.

Mario J. Rugiero mrugiero at gmail.com
Fri May 12 00:39:46 PDT 2017

Some chips used under a custom vendor driver can get their blocks
incorrectly detected as bad blocks, out of incompatibilities
between such drivers and MTD drivers.
When there are too many misdetected bad blocks, the device becomes
unusable because a bad block table can't be allocated, aside from
all the legitimately good blocks which become unusable under these
This adds a build option to workaround the issue by enabling the
user to free up space regardless of what the driver thinks about
the blocks. It still warns about it, since that's potentially

Example usage: recovering NAND chips on sunxi devices, as explained
here: http://linux-sunxi.org/Mainline_NAND_Howto#Known_issues

v3: Warn when erasing a bad block, as suggested by Andrea Scian.

v2: Fix a typo in the config description.

Signed-off-by: Mario J. Rugiero <mrugiero at gmail.com>
 drivers/mtd/nand/Kconfig     | 9 +++++++++
 drivers/mtd/nand/nand_base.c | 2 ++
 2 files changed, 11 insertions(+)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index c3029528063b..e0a32a34b6bf 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -36,6 +36,15 @@ config MTD_NAND_ECC_BCH
 	  ECC codes. They are used with NAND devices requiring more than 1 bit
 	  of error correction.
+	bool "Enable erasing of bad blocks (DANGEROUS)"
+	default n
+	help
+	  This enables support for attempting to erase bad blocks.
+	  It is needed to workaround too many badblocks issue on chips used
+	  under custom, incompatible vendor drivers.
+	  Say N if unsure.
 	default n
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index d474378ed810..282410813a9c 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3211,8 +3211,10 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 					chip->page_shift, allowbbt)) {
 			pr_warn("%s: attempt to erase a bad block at page 0x%08x\n",
 				    __func__, page);
 			instr->state = MTD_ERASE_FAILED;
 			goto erase_exit;
+			#endif

More information about the linux-mtd mailing list