aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorBrian Norris <computersforpeace@gmail.com>2011-09-20 21:35:34 -0400
committerArtem Bityutskiy <artem.bityutskiy@intel.com>2011-09-21 02:19:07 -0400
commit623978de362a5faeb18d8395fa86089650642626 (patch)
treef5f6b3b77b5a25f438f0b1b90bf591986a1fa489 /drivers/mtd
parent167a8d52509a0f7d6728a79e2588b800e866c147 (diff)
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@gmail.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@intel.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/nand_bbt.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 0ed8591dbd26..11185aa6273c 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
882 */ 882 */
883static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd) 883static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
884{ 884{
885 int i, chips, writeops, create, chipsel, res; 885 int i, chips, writeops, create, chipsel, res, res2;
886 struct nand_chip *this = mtd->priv; 886 struct nand_chip *this = mtd->priv;
887 struct nand_bbt_descr *td = this->bbt_td; 887 struct nand_bbt_descr *td = this->bbt_td;
888 struct nand_bbt_descr *md = this->bbt_md; 888 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
899 create = 0; 899 create = 0;
900 rd = NULL; 900 rd = NULL;
901 rd2 = NULL; 901 rd2 = NULL;
902 res = res2 = 0;
902 /* Per chip or per device? */ 903 /* Per chip or per device? */
903 chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1; 904 chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1;
904 /* Mirrored table available? */ 905 /* Mirrored table available? */
@@ -951,11 +952,29 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
951 } 952 }
952 953
953 /* Read back first? */ 954 /* Read back first? */
954 if (rd) 955 if (rd) {
955 read_abs_bbt(mtd, buf, rd, chipsel); 956 res = read_abs_bbt(mtd, buf, rd, chipsel);
957 if (mtd_is_eccerr(res)) {
958 /* Mark table as invalid */
959 rd->pages[i] = -1;
960 i--;
961 continue;
962 }
963 }
956 /* If they weren't versioned, read both */ 964 /* If they weren't versioned, read both */
957 if (rd2) 965 if (rd2) {
958 read_abs_bbt(mtd, buf, rd2, chipsel); 966 res2 = read_abs_bbt(mtd, buf, rd2, chipsel);
967 if (mtd_is_eccerr(res2)) {
968 /* Mark table as invalid */
969 rd2->pages[i] = -1;
970 i--;
971 continue;
972 }
973 }
974
975 /* Scrub the flash table(s)? */
976 if (mtd_is_bitflip(res) || mtd_is_bitflip(res2))
977 writeops = 0x03;
959 978
960 /* Write the bad block table to the device? */ 979 /* Write the bad block table to the device? */
961 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { 980 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {