mirror of
https://github.com/torvalds/linux
synced 2024-10-19 09:49:29 +00:00
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: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Link: https://lore.kernel.org/linux-mtd/20200519074549.23673-4-miquel.raynal@bootlin.com
This commit is contained in:
parent
1759279ad1
commit
0651ed5082
|
@ -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,
|
||||||
*/
|
*/
|
||||||
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,
|
||||||
|
|
||||||
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,
|
||||||
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 */
|
||||||
|
|
Loading…
Reference in a new issue