diff options
author | Mike Dunn <mikedunn@newsguy.com> | 2012-12-07 15:07:23 -0500 |
---|---|---|
committer | Artem Bityutskiy <artem.bityutskiy@linux.intel.com> | 2012-12-12 10:03:42 -0500 |
commit | 3c9c6d657a94f9b9aae498cb5951659cc67fd6ad (patch) | |
tree | f4969efdec7109ca179865f5839242a952141cf9 /drivers/mtd | |
parent | 440b1d73b1b49bc08e1709ee6f6ef7ba2fc1f8ba (diff) |
mtd: nand/docg4: fix and improve read of factory bbt
This patch does two things related to reading the factory badblock table during
initialization: (1) fix error where a non-zero return code from
docg4_read_page() is assumed to be an error (it was later changed to be
max_bitflips; thanks to Brian Norris for bringing this to my attention a while
back), and (2) if there is an error reading the factory bbt, it tries reading
another (redundant) factory bbt table.
Signed-off-by: Mike Dunn <mikedunn@newsguy.com>
Acked-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/docg4.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c index 04e5fa93735e..18fa4489e52e 100644 --- a/drivers/mtd/nand/docg4.c +++ b/drivers/mtd/nand/docg4.c | |||
@@ -212,6 +212,7 @@ struct docg4_priv { | |||
212 | #define DOCG4_T 4 /* BCH alg corrects up to 4 bit errors */ | 212 | #define DOCG4_T 4 /* BCH alg corrects up to 4 bit errors */ |
213 | 213 | ||
214 | #define DOCG4_FACTORY_BBT_PAGE 16 /* page where read-only factory bbt lives */ | 214 | #define DOCG4_FACTORY_BBT_PAGE 16 /* page where read-only factory bbt lives */ |
215 | #define DOCG4_REDUNDANT_BBT_PAGE 24 /* page where redundant factory bbt lives */ | ||
215 | 216 | ||
216 | /* | 217 | /* |
217 | * Bytes 0, 1 are used as badblock marker. | 218 | * Bytes 0, 1 are used as badblock marker. |
@@ -1020,16 +1021,15 @@ static int __init read_factory_bbt(struct mtd_info *mtd) | |||
1020 | struct docg4_priv *doc = nand->priv; | 1021 | struct docg4_priv *doc = nand->priv; |
1021 | uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0); | 1022 | uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0); |
1022 | uint8_t *buf; | 1023 | uint8_t *buf; |
1023 | int i, block, status; | 1024 | int i, block; |
1025 | __u32 eccfailed_stats = mtd->ecc_stats.failed; | ||
1024 | 1026 | ||
1025 | buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL); | 1027 | buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL); |
1026 | if (buf == NULL) | 1028 | if (buf == NULL) |
1027 | return -ENOMEM; | 1029 | return -ENOMEM; |
1028 | 1030 | ||
1029 | read_page_prologue(mtd, g4_addr); | 1031 | read_page_prologue(mtd, g4_addr); |
1030 | status = docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE); | 1032 | docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE); |
1031 | if (status) | ||
1032 | goto exit; | ||
1033 | 1033 | ||
1034 | /* | 1034 | /* |
1035 | * If no memory-based bbt was created, exit. This will happen if module | 1035 | * If no memory-based bbt was created, exit. This will happen if module |
@@ -1041,6 +1041,20 @@ static int __init read_factory_bbt(struct mtd_info *mtd) | |||
1041 | if (nand->bbt == NULL) /* no memory-based bbt */ | 1041 | if (nand->bbt == NULL) /* no memory-based bbt */ |
1042 | goto exit; | 1042 | goto exit; |
1043 | 1043 | ||
1044 | if (mtd->ecc_stats.failed > eccfailed_stats) { | ||
1045 | /* | ||
1046 | * Whoops, an ecc failure ocurred reading the factory bbt. | ||
1047 | * It is stored redundantly, so we get another chance. | ||
1048 | */ | ||
1049 | eccfailed_stats = mtd->ecc_stats.failed; | ||
1050 | docg4_read_page(mtd, nand, buf, 0, DOCG4_REDUNDANT_BBT_PAGE); | ||
1051 | if (mtd->ecc_stats.failed > eccfailed_stats) { | ||
1052 | dev_warn(doc->dev, | ||
1053 | "The factory bbt could not be read!\n"); | ||
1054 | goto exit; | ||
1055 | } | ||
1056 | } | ||
1057 | |||
1044 | /* | 1058 | /* |
1045 | * Parse factory bbt and update memory-based bbt. Factory bbt format is | 1059 | * Parse factory bbt and update memory-based bbt. Factory bbt format is |
1046 | * simple: one bit per block, block numbers increase left to right (msb | 1060 | * simple: one bit per block, block numbers increase left to right (msb |
@@ -1060,7 +1074,7 @@ static int __init read_factory_bbt(struct mtd_info *mtd) | |||
1060 | } | 1074 | } |
1061 | exit: | 1075 | exit: |
1062 | kfree(buf); | 1076 | kfree(buf); |
1063 | return status; | 1077 | return 0; |
1064 | } | 1078 | } |
1065 | 1079 | ||
1066 | static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs) | 1080 | static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs) |