diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/nand/atmel_nand.c | 9 | ||||
-rw-r--r-- | drivers/mtd/nand/bcm_umi_bch.c | 4 | ||||
-rw-r--r-- | drivers/mtd/nand/cafe_nand.c | 4 | ||||
-rw-r--r-- | drivers/mtd/nand/denali.c | 10 | ||||
-rw-r--r-- | drivers/mtd/nand/docg4.c | 5 | ||||
-rw-r--r-- | drivers/mtd/nand/fsl_elbc_nand.c | 21 | ||||
-rw-r--r-- | drivers/mtd/nand/fsl_ifc_nand.c | 9 | ||||
-rw-r--r-- | drivers/mtd/nand/fsmc_nand.c | 9 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 47 | ||||
-rw-r--r-- | drivers/mtd/nand/sh_flctl.c | 2 |
10 files changed, 82 insertions, 38 deletions
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 2165576a1c67..9a7876e8de42 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c | |||
@@ -335,6 +335,7 @@ static int atmel_nand_read_page(struct mtd_info *mtd, | |||
335 | uint8_t *oob = chip->oob_poi; | 335 | uint8_t *oob = chip->oob_poi; |
336 | uint8_t *ecc_pos; | 336 | uint8_t *ecc_pos; |
337 | int stat; | 337 | int stat; |
338 | unsigned int max_bitflips = 0; | ||
338 | 339 | ||
339 | /* | 340 | /* |
340 | * Errata: ALE is incorrectly wired up to the ECC controller | 341 | * Errata: ALE is incorrectly wired up to the ECC controller |
@@ -371,10 +372,12 @@ static int atmel_nand_read_page(struct mtd_info *mtd, | |||
371 | /* check if there's an error */ | 372 | /* check if there's an error */ |
372 | stat = chip->ecc.correct(mtd, p, oob, NULL); | 373 | stat = chip->ecc.correct(mtd, p, oob, NULL); |
373 | 374 | ||
374 | if (stat < 0) | 375 | if (stat < 0) { |
375 | mtd->ecc_stats.failed++; | 376 | mtd->ecc_stats.failed++; |
376 | else | 377 | } else { |
377 | mtd->ecc_stats.corrected += stat; | 378 | mtd->ecc_stats.corrected += stat; |
379 | max_bitflips = max_t(unsigned int, max_bitflips, stat); | ||
380 | } | ||
378 | 381 | ||
379 | /* get back to oob start (end of page) */ | 382 | /* get back to oob start (end of page) */ |
380 | chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1); | 383 | chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1); |
@@ -382,7 +385,7 @@ static int atmel_nand_read_page(struct mtd_info *mtd, | |||
382 | /* read the oob */ | 385 | /* read the oob */ |
383 | chip->read_buf(mtd, oob, mtd->oobsize); | 386 | chip->read_buf(mtd, oob, mtd->oobsize); |
384 | 387 | ||
385 | return 0; | 388 | return max_bitflips; |
386 | } | 389 | } |
387 | 390 | ||
388 | /* | 391 | /* |
diff --git a/drivers/mtd/nand/bcm_umi_bch.c b/drivers/mtd/nand/bcm_umi_bch.c index a930666d0687..f8472b49567a 100644 --- a/drivers/mtd/nand/bcm_umi_bch.c +++ b/drivers/mtd/nand/bcm_umi_bch.c | |||
@@ -116,6 +116,7 @@ static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd, | |||
116 | uint8_t eccCalc[NAND_ECC_NUM_BYTES]; | 116 | uint8_t eccCalc[NAND_ECC_NUM_BYTES]; |
117 | int sectorOobSize = mtd->oobsize / eccsteps; | 117 | int sectorOobSize = mtd->oobsize / eccsteps; |
118 | int stat; | 118 | int stat; |
119 | unsigned int max_bitflips = 0; | ||
119 | 120 | ||
120 | for (sectorIdx = 0; sectorIdx < eccsteps; | 121 | for (sectorIdx = 0; sectorIdx < eccsteps; |
121 | sectorIdx++, datap += eccsize) { | 122 | sectorIdx++, datap += eccsize) { |
@@ -177,9 +178,10 @@ static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd, | |||
177 | } | 178 | } |
178 | #endif | 179 | #endif |
179 | mtd->ecc_stats.corrected += stat; | 180 | mtd->ecc_stats.corrected += stat; |
181 | max_bitflips = max_t(unsigned int, max_bitflips, stat); | ||
180 | } | 182 | } |
181 | } | 183 | } |
182 | return 0; | 184 | return max_bitflips; |
183 | } | 185 | } |
184 | 186 | ||
185 | /**************************************************************************** | 187 | /**************************************************************************** |
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index 2973d97bd529..886ff3a064c2 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c | |||
@@ -383,6 +383,7 @@ static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
383 | uint8_t *buf, int page) | 383 | uint8_t *buf, int page) |
384 | { | 384 | { |
385 | struct cafe_priv *cafe = mtd->priv; | 385 | struct cafe_priv *cafe = mtd->priv; |
386 | unsigned int max_bitflips = 0; | ||
386 | 387 | ||
387 | cafe_dev_dbg(&cafe->pdev->dev, "ECC result %08x SYN1,2 %08x\n", | 388 | cafe_dev_dbg(&cafe->pdev->dev, "ECC result %08x SYN1,2 %08x\n", |
388 | cafe_readl(cafe, NAND_ECC_RESULT), | 389 | cafe_readl(cafe, NAND_ECC_RESULT), |
@@ -449,10 +450,11 @@ static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
449 | } else { | 450 | } else { |
450 | dev_dbg(&cafe->pdev->dev, "Corrected %d symbol errors\n", n); | 451 | dev_dbg(&cafe->pdev->dev, "Corrected %d symbol errors\n", n); |
451 | mtd->ecc_stats.corrected += n; | 452 | mtd->ecc_stats.corrected += n; |
453 | max_bitflips = max_t(unsigned int, max_bitflips, n); | ||
452 | } | 454 | } |
453 | } | 455 | } |
454 | 456 | ||
455 | return 0; | 457 | return max_bitflips; |
456 | } | 458 | } |
457 | 459 | ||
458 | static struct nand_ecclayout cafe_oobinfo_2048 = { | 460 | static struct nand_ecclayout cafe_oobinfo_2048 = { |
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index a1048c7c5d2c..1b346474dba8 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c | |||
@@ -924,9 +924,10 @@ bool is_erased(uint8_t *buf, int len) | |||
924 | #define ECC_LAST_ERR(x) ((x) & ERR_CORRECTION_INFO__LAST_ERR_INFO) | 924 | #define ECC_LAST_ERR(x) ((x) & ERR_CORRECTION_INFO__LAST_ERR_INFO) |
925 | 925 | ||
926 | static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf, | 926 | static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf, |
927 | uint32_t irq_status) | 927 | uint32_t irq_status, unsigned int *max_bitflips) |
928 | { | 928 | { |
929 | bool check_erased_page = false; | 929 | bool check_erased_page = false; |
930 | unsigned int bitflips = 0; | ||
930 | 931 | ||
931 | if (irq_status & INTR_STATUS__ECC_ERR) { | 932 | if (irq_status & INTR_STATUS__ECC_ERR) { |
932 | /* read the ECC errors. we'll ignore them for now */ | 933 | /* read the ECC errors. we'll ignore them for now */ |
@@ -965,6 +966,7 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf, | |||
965 | /* correct the ECC error */ | 966 | /* correct the ECC error */ |
966 | buf[offset] ^= err_correction_value; | 967 | buf[offset] ^= err_correction_value; |
967 | denali->mtd.ecc_stats.corrected++; | 968 | denali->mtd.ecc_stats.corrected++; |
969 | bitflips++; | ||
968 | } | 970 | } |
969 | } else { | 971 | } else { |
970 | /* if the error is not correctable, need to | 972 | /* if the error is not correctable, need to |
@@ -984,6 +986,7 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf, | |||
984 | clear_interrupts(denali); | 986 | clear_interrupts(denali); |
985 | denali_set_intr_modes(denali, true); | 987 | denali_set_intr_modes(denali, true); |
986 | } | 988 | } |
989 | *max_bitflips = bitflips; | ||
987 | return check_erased_page; | 990 | return check_erased_page; |
988 | } | 991 | } |
989 | 992 | ||
@@ -1121,6 +1124,7 @@ static int denali_read_oob(struct mtd_info *mtd, struct nand_chip *chip, | |||
1121 | static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, | 1124 | static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, |
1122 | uint8_t *buf, int page) | 1125 | uint8_t *buf, int page) |
1123 | { | 1126 | { |
1127 | unsigned int max_bitflips; | ||
1124 | struct denali_nand_info *denali = mtd_to_denali(mtd); | 1128 | struct denali_nand_info *denali = mtd_to_denali(mtd); |
1125 | 1129 | ||
1126 | dma_addr_t addr = denali->buf.dma_buf; | 1130 | dma_addr_t addr = denali->buf.dma_buf; |
@@ -1153,7 +1157,7 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1153 | 1157 | ||
1154 | memcpy(buf, denali->buf.buf, mtd->writesize); | 1158 | memcpy(buf, denali->buf.buf, mtd->writesize); |
1155 | 1159 | ||
1156 | check_erased_page = handle_ecc(denali, buf, irq_status); | 1160 | check_erased_page = handle_ecc(denali, buf, irq_status, &max_bitflips); |
1157 | denali_enable_dma(denali, false); | 1161 | denali_enable_dma(denali, false); |
1158 | 1162 | ||
1159 | if (check_erased_page) { | 1163 | if (check_erased_page) { |
@@ -1167,7 +1171,7 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1167 | denali->mtd.ecc_stats.failed++; | 1171 | denali->mtd.ecc_stats.failed++; |
1168 | } | 1172 | } |
1169 | } | 1173 | } |
1170 | return 0; | 1174 | return max_bitflips; |
1171 | } | 1175 | } |
1172 | 1176 | ||
1173 | static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | 1177 | static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, |
diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c index b08202664543..8e7da0170a2b 100644 --- a/drivers/mtd/nand/docg4.c +++ b/drivers/mtd/nand/docg4.c | |||
@@ -720,6 +720,7 @@ static int read_page(struct mtd_info *mtd, struct nand_chip *nand, | |||
720 | struct docg4_priv *doc = nand->priv; | 720 | struct docg4_priv *doc = nand->priv; |
721 | void __iomem *docptr = doc->virtadr; | 721 | void __iomem *docptr = doc->virtadr; |
722 | uint16_t status, edc_err, *buf16; | 722 | uint16_t status, edc_err, *buf16; |
723 | int bits_corrected = 0; | ||
723 | 724 | ||
724 | dev_dbg(doc->dev, "%s: page %08x\n", __func__, page); | 725 | dev_dbg(doc->dev, "%s: page %08x\n", __func__, page); |
725 | 726 | ||
@@ -772,7 +773,7 @@ static int read_page(struct mtd_info *mtd, struct nand_chip *nand, | |||
772 | 773 | ||
773 | /* If bitflips are reported, attempt to correct with ecc */ | 774 | /* If bitflips are reported, attempt to correct with ecc */ |
774 | if (edc_err & DOC_ECCCONF1_BCH_SYNDROM_ERR) { | 775 | if (edc_err & DOC_ECCCONF1_BCH_SYNDROM_ERR) { |
775 | int bits_corrected = correct_data(mtd, buf, page); | 776 | bits_corrected = correct_data(mtd, buf, page); |
776 | if (bits_corrected == -EBADMSG) | 777 | if (bits_corrected == -EBADMSG) |
777 | mtd->ecc_stats.failed++; | 778 | mtd->ecc_stats.failed++; |
778 | else | 779 | else |
@@ -781,7 +782,7 @@ static int read_page(struct mtd_info *mtd, struct nand_chip *nand, | |||
781 | } | 782 | } |
782 | 783 | ||
783 | writew(0, docptr + DOC_DATAEND); | 784 | writew(0, docptr + DOC_DATAEND); |
784 | return 0; | 785 | return bits_corrected; |
785 | } | 786 | } |
786 | 787 | ||
787 | 788 | ||
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 80b5264f0a32..8638b5e734cc 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c | |||
@@ -75,6 +75,7 @@ struct fsl_elbc_fcm_ctrl { | |||
75 | unsigned int use_mdr; /* Non zero if the MDR is to be set */ | 75 | unsigned int use_mdr; /* Non zero if the MDR is to be set */ |
76 | unsigned int oob; /* Non zero if operating on OOB data */ | 76 | unsigned int oob; /* Non zero if operating on OOB data */ |
77 | unsigned int counter; /* counter for the initializations */ | 77 | unsigned int counter; /* counter for the initializations */ |
78 | unsigned int max_bitflips; /* Saved during READ0 cmd */ | ||
78 | }; | 79 | }; |
79 | 80 | ||
80 | /* These map to the positions used by the FCM hardware ECC generator */ | 81 | /* These map to the positions used by the FCM hardware ECC generator */ |
@@ -253,6 +254,8 @@ static int fsl_elbc_run_command(struct mtd_info *mtd) | |||
253 | if (chip->ecc.mode != NAND_ECC_HW) | 254 | if (chip->ecc.mode != NAND_ECC_HW) |
254 | return 0; | 255 | return 0; |
255 | 256 | ||
257 | elbc_fcm_ctrl->max_bitflips = 0; | ||
258 | |||
256 | if (elbc_fcm_ctrl->read_bytes == mtd->writesize + mtd->oobsize) { | 259 | if (elbc_fcm_ctrl->read_bytes == mtd->writesize + mtd->oobsize) { |
257 | uint32_t lteccr = in_be32(&lbc->lteccr); | 260 | uint32_t lteccr = in_be32(&lbc->lteccr); |
258 | /* | 261 | /* |
@@ -262,11 +265,16 @@ static int fsl_elbc_run_command(struct mtd_info *mtd) | |||
262 | * bits 28-31 are uncorrectable errors, marked elsewhere. | 265 | * bits 28-31 are uncorrectable errors, marked elsewhere. |
263 | * for small page nand only 1 bit is used. | 266 | * for small page nand only 1 bit is used. |
264 | * if the ELBC doesn't have the lteccr register it reads 0 | 267 | * if the ELBC doesn't have the lteccr register it reads 0 |
268 | * FIXME: 4 bits can be corrected on NANDs with 2k pages, so | ||
269 | * count the number of sub-pages with bitflips and update | ||
270 | * ecc_stats.corrected accordingly. | ||
265 | */ | 271 | */ |
266 | if (lteccr & 0x000F000F) | 272 | if (lteccr & 0x000F000F) |
267 | out_be32(&lbc->lteccr, 0x000F000F); /* clear lteccr */ | 273 | out_be32(&lbc->lteccr, 0x000F000F); /* clear lteccr */ |
268 | if (lteccr & 0x000F0000) | 274 | if (lteccr & 0x000F0000) { |
269 | mtd->ecc_stats.corrected++; | 275 | mtd->ecc_stats.corrected++; |
276 | elbc_fcm_ctrl->max_bitflips = 1; | ||
277 | } | ||
270 | } | 278 | } |
271 | 279 | ||
272 | return 0; | 280 | return 0; |
@@ -743,13 +751,17 @@ static int fsl_elbc_read_page(struct mtd_info *mtd, | |||
743 | uint8_t *buf, | 751 | uint8_t *buf, |
744 | int page) | 752 | int page) |
745 | { | 753 | { |
754 | struct fsl_elbc_mtd *priv = chip->priv; | ||
755 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; | ||
756 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; | ||
757 | |||
746 | fsl_elbc_read_buf(mtd, buf, mtd->writesize); | 758 | fsl_elbc_read_buf(mtd, buf, mtd->writesize); |
747 | fsl_elbc_read_buf(mtd, chip->oob_poi, mtd->oobsize); | 759 | fsl_elbc_read_buf(mtd, chip->oob_poi, mtd->oobsize); |
748 | 760 | ||
749 | if (fsl_elbc_wait(mtd, chip) & NAND_STATUS_FAIL) | 761 | if (fsl_elbc_wait(mtd, chip) & NAND_STATUS_FAIL) |
750 | mtd->ecc_stats.failed++; | 762 | mtd->ecc_stats.failed++; |
751 | 763 | ||
752 | return 0; | 764 | return elbc_fcm_ctrl->max_bitflips; |
753 | } | 765 | } |
754 | 766 | ||
755 | /* ECC will be calculated automatically, and errors will be detected in | 767 | /* ECC will be calculated automatically, and errors will be detected in |
@@ -814,11 +826,6 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) | |||
814 | chip->ecc.size = 512; | 826 | chip->ecc.size = 512; |
815 | chip->ecc.bytes = 3; | 827 | chip->ecc.bytes = 3; |
816 | chip->ecc.strength = 1; | 828 | chip->ecc.strength = 1; |
817 | /* | ||
818 | * FIXME: can hardware ecc correct 4 bitflips if page size is | ||
819 | * 2k? Then does hardware report number of corrections for this | ||
820 | * case? If so, ecc_stats reporting needs to be fixed as well. | ||
821 | */ | ||
822 | } else { | 829 | } else { |
823 | /* otherwise fall back to default software ECC */ | 830 | /* otherwise fall back to default software ECC */ |
824 | chip->ecc.mode = NAND_ECC_SOFT; | 831 | chip->ecc.mode = NAND_ECC_SOFT; |
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index 872cc9605291..0adde9670418 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c | |||
@@ -63,6 +63,7 @@ struct fsl_ifc_nand_ctrl { | |||
63 | unsigned int oob; /* Non zero if operating on OOB data */ | 63 | unsigned int oob; /* Non zero if operating on OOB data */ |
64 | unsigned int eccread; /* Non zero for a full-page ECC read */ | 64 | unsigned int eccread; /* Non zero for a full-page ECC read */ |
65 | unsigned int counter; /* counter for the initializations */ | 65 | unsigned int counter; /* counter for the initializations */ |
66 | unsigned int max_bitflips; /* Saved during READ0 cmd */ | ||
66 | }; | 67 | }; |
67 | 68 | ||
68 | static struct fsl_ifc_nand_ctrl *ifc_nand_ctrl; | 69 | static struct fsl_ifc_nand_ctrl *ifc_nand_ctrl; |
@@ -262,6 +263,8 @@ static void fsl_ifc_run_command(struct mtd_info *mtd) | |||
262 | if (ctrl->nand_stat & IFC_NAND_EVTER_STAT_WPER) | 263 | if (ctrl->nand_stat & IFC_NAND_EVTER_STAT_WPER) |
263 | dev_err(priv->dev, "NAND Flash Write Protect Error\n"); | 264 | dev_err(priv->dev, "NAND Flash Write Protect Error\n"); |
264 | 265 | ||
266 | nctrl->max_bitflips = 0; | ||
267 | |||
265 | if (nctrl->eccread) { | 268 | if (nctrl->eccread) { |
266 | int errors; | 269 | int errors; |
267 | int bufnum = nctrl->page & priv->bufnum_mask; | 270 | int bufnum = nctrl->page & priv->bufnum_mask; |
@@ -290,6 +293,9 @@ static void fsl_ifc_run_command(struct mtd_info *mtd) | |||
290 | } | 293 | } |
291 | 294 | ||
292 | mtd->ecc_stats.corrected += errors; | 295 | mtd->ecc_stats.corrected += errors; |
296 | nctrl->max_bitflips = max_t(unsigned int, | ||
297 | nctrl->max_bitflips, | ||
298 | errors); | ||
293 | } | 299 | } |
294 | 300 | ||
295 | nctrl->eccread = 0; | 301 | nctrl->eccread = 0; |
@@ -698,6 +704,7 @@ static int fsl_ifc_read_page(struct mtd_info *mtd, | |||
698 | { | 704 | { |
699 | struct fsl_ifc_mtd *priv = chip->priv; | 705 | struct fsl_ifc_mtd *priv = chip->priv; |
700 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; | 706 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; |
707 | struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl; | ||
701 | 708 | ||
702 | fsl_ifc_read_buf(mtd, buf, mtd->writesize); | 709 | fsl_ifc_read_buf(mtd, buf, mtd->writesize); |
703 | fsl_ifc_read_buf(mtd, chip->oob_poi, mtd->oobsize); | 710 | fsl_ifc_read_buf(mtd, chip->oob_poi, mtd->oobsize); |
@@ -708,7 +715,7 @@ static int fsl_ifc_read_page(struct mtd_info *mtd, | |||
708 | if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC) | 715 | if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC) |
709 | mtd->ecc_stats.failed++; | 716 | mtd->ecc_stats.failed++; |
710 | 717 | ||
711 | return 0; | 718 | return nctrl->max_bitflips; |
712 | } | 719 | } |
713 | 720 | ||
714 | /* ECC will be calculated automatically, and errors will be detected in | 721 | /* ECC will be calculated automatically, and errors will be detected in |
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 9d7f4171e077..6bf59fdde263 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c | |||
@@ -720,6 +720,7 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
720 | */ | 720 | */ |
721 | uint16_t ecc_oob[7]; | 721 | uint16_t ecc_oob[7]; |
722 | uint8_t *oob = (uint8_t *)&ecc_oob[0]; | 722 | uint8_t *oob = (uint8_t *)&ecc_oob[0]; |
723 | unsigned int max_bitflips = 0; | ||
723 | 724 | ||
724 | for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, p += eccsize) { | 725 | for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, p += eccsize) { |
725 | chip->cmdfunc(mtd, NAND_CMD_READ0, s * eccsize, page); | 726 | chip->cmdfunc(mtd, NAND_CMD_READ0, s * eccsize, page); |
@@ -748,13 +749,15 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
748 | chip->ecc.calculate(mtd, p, &ecc_calc[i]); | 749 | chip->ecc.calculate(mtd, p, &ecc_calc[i]); |
749 | 750 | ||
750 | stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); | 751 | stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); |
751 | if (stat < 0) | 752 | if (stat < 0) { |
752 | mtd->ecc_stats.failed++; | 753 | mtd->ecc_stats.failed++; |
753 | else | 754 | } else { |
754 | mtd->ecc_stats.corrected += stat; | 755 | mtd->ecc_stats.corrected += stat; |
756 | max_bitflips = max_t(unsigned int, max_bitflips, stat); | ||
757 | } | ||
755 | } | 758 | } |
756 | 759 | ||
757 | return 0; | 760 | return max_bitflips; |
758 | } | 761 | } |
759 | 762 | ||
760 | /* | 763 | /* |
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 671f228d4c7c..8718eaf8269f 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -1138,6 +1138,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
1138 | uint8_t *ecc_calc = chip->buffers->ecccalc; | 1138 | uint8_t *ecc_calc = chip->buffers->ecccalc; |
1139 | uint8_t *ecc_code = chip->buffers->ecccode; | 1139 | uint8_t *ecc_code = chip->buffers->ecccode; |
1140 | uint32_t *eccpos = chip->ecc.layout->eccpos; | 1140 | uint32_t *eccpos = chip->ecc.layout->eccpos; |
1141 | unsigned int max_bitflips = 0; | ||
1141 | 1142 | ||
1142 | chip->ecc.read_page_raw(mtd, chip, buf, page); | 1143 | chip->ecc.read_page_raw(mtd, chip, buf, page); |
1143 | 1144 | ||
@@ -1154,12 +1155,14 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
1154 | int stat; | 1155 | int stat; |
1155 | 1156 | ||
1156 | stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); | 1157 | stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); |
1157 | if (stat < 0) | 1158 | if (stat < 0) { |
1158 | mtd->ecc_stats.failed++; | 1159 | mtd->ecc_stats.failed++; |
1159 | else | 1160 | } else { |
1160 | mtd->ecc_stats.corrected += stat; | 1161 | mtd->ecc_stats.corrected += stat; |
1162 | max_bitflips = max_t(unsigned int, max_bitflips, stat); | ||
1163 | } | ||
1161 | } | 1164 | } |
1162 | return 0; | 1165 | return max_bitflips; |
1163 | } | 1166 | } |
1164 | 1167 | ||
1165 | /** | 1168 | /** |
@@ -1180,6 +1183,7 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, | |||
1180 | int datafrag_len, eccfrag_len, aligned_len, aligned_pos; | 1183 | int datafrag_len, eccfrag_len, aligned_len, aligned_pos; |
1181 | int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1; | 1184 | int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1; |
1182 | int index = 0; | 1185 | int index = 0; |
1186 | unsigned int max_bitflips = 0; | ||
1183 | 1187 | ||
1184 | /* Column address within the page aligned to ECC size (256bytes) */ | 1188 | /* Column address within the page aligned to ECC size (256bytes) */ |
1185 | start_step = data_offs / chip->ecc.size; | 1189 | start_step = data_offs / chip->ecc.size; |
@@ -1244,12 +1248,14 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, | |||
1244 | 1248 | ||
1245 | stat = chip->ecc.correct(mtd, p, | 1249 | stat = chip->ecc.correct(mtd, p, |
1246 | &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]); | 1250 | &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]); |
1247 | if (stat < 0) | 1251 | if (stat < 0) { |
1248 | mtd->ecc_stats.failed++; | 1252 | mtd->ecc_stats.failed++; |
1249 | else | 1253 | } else { |
1250 | mtd->ecc_stats.corrected += stat; | 1254 | mtd->ecc_stats.corrected += stat; |
1255 | max_bitflips = max_t(unsigned int, max_bitflips, stat); | ||
1256 | } | ||
1251 | } | 1257 | } |
1252 | return 0; | 1258 | return max_bitflips; |
1253 | } | 1259 | } |
1254 | 1260 | ||
1255 | /** | 1261 | /** |
@@ -1271,6 +1277,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
1271 | uint8_t *ecc_calc = chip->buffers->ecccalc; | 1277 | uint8_t *ecc_calc = chip->buffers->ecccalc; |
1272 | uint8_t *ecc_code = chip->buffers->ecccode; | 1278 | uint8_t *ecc_code = chip->buffers->ecccode; |
1273 | uint32_t *eccpos = chip->ecc.layout->eccpos; | 1279 | uint32_t *eccpos = chip->ecc.layout->eccpos; |
1280 | unsigned int max_bitflips = 0; | ||
1274 | 1281 | ||
1275 | for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { | 1282 | for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { |
1276 | chip->ecc.hwctl(mtd, NAND_ECC_READ); | 1283 | chip->ecc.hwctl(mtd, NAND_ECC_READ); |
@@ -1289,12 +1296,14 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
1289 | int stat; | 1296 | int stat; |
1290 | 1297 | ||
1291 | stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); | 1298 | stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); |
1292 | if (stat < 0) | 1299 | if (stat < 0) { |
1293 | mtd->ecc_stats.failed++; | 1300 | mtd->ecc_stats.failed++; |
1294 | else | 1301 | } else { |
1295 | mtd->ecc_stats.corrected += stat; | 1302 | mtd->ecc_stats.corrected += stat; |
1303 | max_bitflips = max_t(unsigned int, max_bitflips, stat); | ||
1304 | } | ||
1296 | } | 1305 | } |
1297 | return 0; | 1306 | return max_bitflips; |
1298 | } | 1307 | } |
1299 | 1308 | ||
1300 | /** | 1309 | /** |
@@ -1320,6 +1329,7 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd, | |||
1320 | uint8_t *ecc_code = chip->buffers->ecccode; | 1329 | uint8_t *ecc_code = chip->buffers->ecccode; |
1321 | uint32_t *eccpos = chip->ecc.layout->eccpos; | 1330 | uint32_t *eccpos = chip->ecc.layout->eccpos; |
1322 | uint8_t *ecc_calc = chip->buffers->ecccalc; | 1331 | uint8_t *ecc_calc = chip->buffers->ecccalc; |
1332 | unsigned int max_bitflips = 0; | ||
1323 | 1333 | ||
1324 | /* Read the OOB area first */ | 1334 | /* Read the OOB area first */ |
1325 | chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); | 1335 | chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); |
@@ -1337,12 +1347,14 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd, | |||
1337 | chip->ecc.calculate(mtd, p, &ecc_calc[i]); | 1347 | chip->ecc.calculate(mtd, p, &ecc_calc[i]); |
1338 | 1348 | ||
1339 | stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL); | 1349 | stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL); |
1340 | if (stat < 0) | 1350 | if (stat < 0) { |
1341 | mtd->ecc_stats.failed++; | 1351 | mtd->ecc_stats.failed++; |
1342 | else | 1352 | } else { |
1343 | mtd->ecc_stats.corrected += stat; | 1353 | mtd->ecc_stats.corrected += stat; |
1354 | max_bitflips = max_t(unsigned int, max_bitflips, stat); | ||
1355 | } | ||
1344 | } | 1356 | } |
1345 | return 0; | 1357 | return max_bitflips; |
1346 | } | 1358 | } |
1347 | 1359 | ||
1348 | /** | 1360 | /** |
@@ -1363,6 +1375,7 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip, | |||
1363 | int eccsteps = chip->ecc.steps; | 1375 | int eccsteps = chip->ecc.steps; |
1364 | uint8_t *p = buf; | 1376 | uint8_t *p = buf; |
1365 | uint8_t *oob = chip->oob_poi; | 1377 | uint8_t *oob = chip->oob_poi; |
1378 | unsigned int max_bitflips = 0; | ||
1366 | 1379 | ||
1367 | for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { | 1380 | for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { |
1368 | int stat; | 1381 | int stat; |
@@ -1379,10 +1392,12 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip, | |||
1379 | chip->read_buf(mtd, oob, eccbytes); | 1392 | chip->read_buf(mtd, oob, eccbytes); |
1380 | stat = chip->ecc.correct(mtd, p, oob, NULL); | 1393 | stat = chip->ecc.correct(mtd, p, oob, NULL); |
1381 | 1394 | ||
1382 | if (stat < 0) | 1395 | if (stat < 0) { |
1383 | mtd->ecc_stats.failed++; | 1396 | mtd->ecc_stats.failed++; |
1384 | else | 1397 | } else { |
1385 | mtd->ecc_stats.corrected += stat; | 1398 | mtd->ecc_stats.corrected += stat; |
1399 | max_bitflips = max_t(unsigned int, max_bitflips, stat); | ||
1400 | } | ||
1386 | 1401 | ||
1387 | oob += eccbytes; | 1402 | oob += eccbytes; |
1388 | 1403 | ||
@@ -1397,7 +1412,7 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip, | |||
1397 | if (i) | 1412 | if (i) |
1398 | chip->read_buf(mtd, oob, i); | 1413 | chip->read_buf(mtd, oob, i); |
1399 | 1414 | ||
1400 | return 0; | 1415 | return max_bitflips; |
1401 | } | 1416 | } |
1402 | 1417 | ||
1403 | /** | 1418 | /** |
@@ -1588,7 +1603,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
1588 | if (oob) | 1603 | if (oob) |
1589 | ops->oobretlen = ops->ooblen - oobreadlen; | 1604 | ops->oobretlen = ops->ooblen - oobreadlen; |
1590 | 1605 | ||
1591 | if (ret) | 1606 | if (ret < 0) |
1592 | return ret; | 1607 | return ret; |
1593 | 1608 | ||
1594 | if (mtd->ecc_stats.failed - stats.failed) | 1609 | if (mtd->ecc_stats.failed - stats.failed) |
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c index e9b2b260de3a..4ea3e20169ba 100644 --- a/drivers/mtd/nand/sh_flctl.c +++ b/drivers/mtd/nand/sh_flctl.c | |||
@@ -359,7 +359,7 @@ static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
359 | if (flctl->hwecc_cant_correct[i]) | 359 | if (flctl->hwecc_cant_correct[i]) |
360 | mtd->ecc_stats.failed++; | 360 | mtd->ecc_stats.failed++; |
361 | else | 361 | else |
362 | mtd->ecc_stats.corrected += 0; | 362 | mtd->ecc_stats.corrected += 0; /* FIXME */ |
363 | } | 363 | } |
364 | 364 | ||
365 | return 0; | 365 | return 0; |