mtd: nand: scrub BBT on ECC errors

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Mon Nov 7 11:59:35 EST 2011


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=623978de362a5faeb18d8395fa86089650642626
Commit:     623978de362a5faeb18d8395fa86089650642626
Parent:     167a8d52509a0f7d6728a79e2588b800e866c147
Author:     Brian Norris <computersforpeace at gmail.com>
AuthorDate: Tue Sep 20 18:35:34 2011 -0700
Committer:  Artem Bityutskiy <artem.bityutskiy at intel.com>
CommitDate: Wed Sep 21 09:19:07 2011 +0300

    mtd: nand: scrub BBT on ECC errors
    
    Now that `read_bbt()' returns ECC error codes properly, we handle those
    codes when checking the integrity of our flash-based BBT.
    
    The modifications can be described by this new policy:
    
    *) On any uncorrected ECC error, we invalidate the corresponding table
       and retry our version-checking integrity logic.
    *) On corrected bitflips, we mark both tables for re-writing to flash
       (a.k.a. scrubbing).
    
    Current integrity checks (i.e., comparing version numbers, etc.) should
    take care of all the cases that result in rescanning the device for bad
    blocks or falling back to the BBT as found in the mirror descriptor.
    
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
    Signed-off-by: Artem Bityutskiy <artem.bityutskiy at intel.com>
---
 drivers/mtd/nand/nand_bbt.c |   29 ++++++++++++++++++++++++-----
 1 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 0ed8591..11185aa 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -882,7 +882,7 @@ static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *b
  */
 static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
 {
-	int i, chips, writeops, create, chipsel, res;
+	int i, chips, writeops, create, chipsel, res, res2;
 	struct nand_chip *this = mtd->priv;
 	struct nand_bbt_descr *td = this->bbt_td;
 	struct nand_bbt_descr *md = this->bbt_md;
@@ -899,6 +899,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
 		create = 0;
 		rd = NULL;
 		rd2 = NULL;
+		res = res2 = 0;
 		/* Per chip or per device? */
 		chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1;
 		/* Mirrored table available? */
@@ -951,11 +952,29 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
 		}
 
 		/* Read back first? */
-		if (rd)
-			read_abs_bbt(mtd, buf, rd, chipsel);
+		if (rd) {
+			res = read_abs_bbt(mtd, buf, rd, chipsel);
+			if (mtd_is_eccerr(res)) {
+				/* Mark table as invalid */
+				rd->pages[i] = -1;
+				i--;
+				continue;
+			}
+		}
 		/* If they weren't versioned, read both */
-		if (rd2)
-			read_abs_bbt(mtd, buf, rd2, chipsel);
+		if (rd2) {
+			res2 = read_abs_bbt(mtd, buf, rd2, chipsel);
+			if (mtd_is_eccerr(res2)) {
+				/* Mark table as invalid */
+				rd2->pages[i] = -1;
+				i--;
+				continue;
+			}
+		}
+
+		/* Scrub the flash table(s)? */
+		if (mtd_is_bitflip(res) || mtd_is_bitflip(res2))
+			writeops = 0x03;
 
 		/* Write the bad block table to the device? */
 		if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {



More information about the linux-mtd-cvs mailing list