Commit 0651ed50 authored by Miquel Raynal's avatar Miquel Raynal

mtd: rawnand: Ensure the number of bitflips is consistent

The main NAND read page function can loop over "page reads" many times
in if the reading reports uncorrectable error(s) and if the chip
supports the read_retry feature.

In this case, the number of bitflips is summarized between
attempts. Fix this by re-initializing the entire mtd_ecc_stats object
each time we retry.
Suggested-by: default avatarBoris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: default avatarBoris Brezillon <boris.brezillon@collabora.com>
Link: https://lore.kernel.org/linux-mtd/20200519074549.23673-4-miquel.raynal@bootlin.com
parent 1759279a
...@@ -3295,7 +3295,7 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from, ...@@ -3295,7 +3295,7 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from,
oob_required = oob ? 1 : 0; oob_required = oob ? 1 : 0;
while (1) { while (1) {
unsigned int ecc_failures = mtd->ecc_stats.failed; struct mtd_ecc_stats ecc_stats = mtd->ecc_stats;
bytes = min(mtd->writesize - col, readlen); bytes = min(mtd->writesize - col, readlen);
aligned = (bytes == mtd->writesize); aligned = (bytes == mtd->writesize);
...@@ -3346,7 +3346,7 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from, ...@@ -3346,7 +3346,7 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from,
*/ */
if (use_bounce_buf) { if (use_bounce_buf) {
if (!NAND_HAS_SUBPAGE_READ(chip) && !oob && if (!NAND_HAS_SUBPAGE_READ(chip) && !oob &&
!(mtd->ecc_stats.failed - ecc_failures) && !(mtd->ecc_stats.failed - ecc_stats.failed) &&
(ops->mode != MTD_OPS_RAW)) { (ops->mode != MTD_OPS_RAW)) {
chip->pagecache.page = realpage; chip->pagecache.page = realpage;
chip->pagecache.bitflips = ret; chip->pagecache.bitflips = ret;
...@@ -3369,7 +3369,7 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from, ...@@ -3369,7 +3369,7 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from,
nand_wait_readrdy(chip); nand_wait_readrdy(chip);
if (mtd->ecc_stats.failed - ecc_failures) { if (mtd->ecc_stats.failed - ecc_stats.failed) {
if (retry_mode + 1 < chip->read_retries) { if (retry_mode + 1 < chip->read_retries) {
retry_mode++; retry_mode++;
ret = nand_setup_read_retry(chip, ret = nand_setup_read_retry(chip,
...@@ -3377,8 +3377,8 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from, ...@@ -3377,8 +3377,8 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from,
if (ret < 0) if (ret < 0)
break; break;
/* Reset failures; retry */ /* Reset ecc_stats; retry */
mtd->ecc_stats.failed = ecc_failures; mtd->ecc_stats = ecc_stats;
goto read_retry; goto read_retry;
} else { } else {
/* No more retry modes; real failure */ /* No more retry modes; real failure */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment