Patchwork [v2,09/14] mtd: nand: report ECC errors properly when reading BBT

login
register
mail settings
Submitter Brian Norris
Date Sept. 21, 2011, 1:35 a.m.
Message ID <1316568908-21539-1-git-send-email-computersforpeace@gmail.com>
Download mbox | patch
Permalink /patch/115656/
State Accepted
Commit 167a8d52509a0f7d6728a79e2588b800e866c147
Headers show

Comments

Brian Norris - Sept. 21, 2011, 1:35 a.m.
Instead of just printing a warning when encountering ECC errors, we
should return a proper error status and print a more informative
warning. Later, we will handle these error messages in the upper layers
of the BBT scan.

Note that this patch makes our check for ECC error codes a little bit
more restrictive, leaving all unrecognized errors to the generic "else"
clause. This shouldn't cause problems and could even be a benefit.

This code is based on some findings reported by Matthieu Castet.

Reported-by: Matthieu CASTET <matthieu.castet@parrot.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
---
v2: change to `mtd_is_*' prefix

 drivers/mtd/nand/nand_bbt.c |   17 ++++++++++++-----
 1 files changed, 12 insertions(+), 5 deletions(-)

Patch

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 584bdcb..0ed8591 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -178,7 +178,7 @@  static u32 add_marker_len(struct nand_bbt_descr *td)
 static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
 		struct nand_bbt_descr *td, int offs)
 {
-	int res, i, j, act = 0;
+	int res, ret = 0, i, j, act = 0;
 	struct nand_chip *this = mtd->priv;
 	size_t retlen, len, totlen;
 	loff_t from;
@@ -204,11 +204,18 @@  static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
 		}
 		res = mtd->read(mtd, from, len, &retlen, buf);
 		if (res < 0) {
-			if (retlen != len) {
-				pr_info("nand_bbt: error reading bad block table\n");
+			if (mtd_is_eccerr(res)) {
+				pr_info("nand_bbt: ECC error in BBT at "
+					"0x%012llx\n", from & ~mtd->writesize);
+				return res;
+			} else if (mtd_is_bitflip(res)) {
+				pr_info("nand_bbt: corrected error in BBT at "
+					"0x%012llx\n", from & ~mtd->writesize);
+				ret = res;
+			} else {
+				pr_info("nand_bbt: error reading BBT\n");
 				return res;
 			}
-			pr_warn("nand_bbt: ECC error while reading bad block table\n");
 		}
 
 		/* Analyse data */
@@ -242,7 +249,7 @@  static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
 		totlen -= len;
 		from += len;
 	}
-	return 0;
+	return ret;
 }
 
 /**