diff options
| -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 04e5fa93735..18fa4489e52 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) |
