diff options
author | Brian Norris <computersforpeace@gmail.com> | 2011-09-20 18:35:08 -0700 |
---|---|---|
committer | Artem Bityutskiy <artem.bityutskiy@intel.com> | 2011-09-21 09:19:07 +0300 |
commit | 167a8d52509a0f7d6728a79e2588b800e866c147 (patch) | |
tree | 7ae622e68cbed19680cd3954259f1616d3d868bd /drivers/mtd | |
parent | d57f40544a41fdfe90fd863b6865138c5a82f1cc (diff) | |
download | kernel-common-167a8d52509a0f7d6728a79e2588b800e866c147.tar.gz kernel-common-167a8d52509a0f7d6728a79e2588b800e866c147.tar.bz2 kernel-common-167a8d52509a0f7d6728a79e2588b800e866c147.zip |
mtd: nand: report ECC errors properly when reading BBT
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>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@intel.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/nand_bbt.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 584bdcb3c61a..0ed8591dbd26 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; } /** |