|
@@ -212,6 +212,7 @@ struct docg4_priv {
|
|
|
#define DOCG4_T 4 /* BCH alg corrects up to 4 bit errors */
|
|
|
|
|
|
#define DOCG4_FACTORY_BBT_PAGE 16 /* page where read-only factory bbt lives */
|
|
|
+#define DOCG4_REDUNDANT_BBT_PAGE 24 /* page where redundant factory bbt lives */
|
|
|
|
|
|
/*
|
|
|
* Bytes 0, 1 are used as badblock marker.
|
|
@@ -1020,16 +1021,15 @@ static int __init read_factory_bbt(struct mtd_info *mtd)
|
|
|
struct docg4_priv *doc = nand->priv;
|
|
|
uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0);
|
|
|
uint8_t *buf;
|
|
|
- int i, block, status;
|
|
|
+ int i, block;
|
|
|
+ __u32 eccfailed_stats = mtd->ecc_stats.failed;
|
|
|
|
|
|
buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL);
|
|
|
if (buf == NULL)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
read_page_prologue(mtd, g4_addr);
|
|
|
- status = docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE);
|
|
|
- if (status)
|
|
|
- goto exit;
|
|
|
+ docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE);
|
|
|
|
|
|
/*
|
|
|
* 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)
|
|
|
if (nand->bbt == NULL) /* no memory-based bbt */
|
|
|
goto exit;
|
|
|
|
|
|
+ if (mtd->ecc_stats.failed > eccfailed_stats) {
|
|
|
+ /*
|
|
|
+ * Whoops, an ecc failure ocurred reading the factory bbt.
|
|
|
+ * It is stored redundantly, so we get another chance.
|
|
|
+ */
|
|
|
+ eccfailed_stats = mtd->ecc_stats.failed;
|
|
|
+ docg4_read_page(mtd, nand, buf, 0, DOCG4_REDUNDANT_BBT_PAGE);
|
|
|
+ if (mtd->ecc_stats.failed > eccfailed_stats) {
|
|
|
+ dev_warn(doc->dev,
|
|
|
+ "The factory bbt could not be read!\n");
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/*
|
|
|
* Parse factory bbt and update memory-based bbt. Factory bbt format is
|
|
|
* 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)
|
|
|
}
|
|
|
exit:
|
|
|
kfree(buf);
|
|
|
- return status;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs)
|