Skip to content

Commit 3c9c6d6

Browse files
mike-dunndedekind
authored andcommitted
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>
1 parent 440b1d7 commit 3c9c6d6

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

drivers/mtd/nand/docg4.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ struct docg4_priv {
212212
#define DOCG4_T 4 /* BCH alg corrects up to 4 bit errors */
213213

214214
#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 */
215216

216217
/*
217218
* Bytes 0, 1 are used as badblock marker.
@@ -1020,16 +1021,15 @@ static int __init read_factory_bbt(struct mtd_info *mtd)
10201021
struct docg4_priv *doc = nand->priv;
10211022
uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0);
10221023
uint8_t *buf;
1023-
int i, block, status;
1024+
int i, block;
1025+
__u32 eccfailed_stats = mtd->ecc_stats.failed;
10241026

10251027
buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL);
10261028
if (buf == NULL)
10271029
return -ENOMEM;
10281030

10291031
read_page_prologue(mtd, g4_addr);
1030-
status = docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE);
1031-
if (status)
1032-
goto exit;
1032+
docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE);
10331033

10341034
/*
10351035
* 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)
10411041
if (nand->bbt == NULL) /* no memory-based bbt */
10421042
goto exit;
10431043

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+
10441058
/*
10451059
* Parse factory bbt and update memory-based bbt. Factory bbt format is
10461060
* 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)
10601074
}
10611075
exit:
10621076
kfree(buf);
1063-
return status;
1077+
return 0;
10641078
}
10651079

10661080
static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs)

0 commit comments

Comments
 (0)