]> git.baikalelectronics.ru Git - kernel.git/commit
mtd: nand: denali: fix bitflips calculation in handle_ecc()
authorMasahiro Yamada <yamada.masahiro@socionext.com>
Thu, 30 Mar 2017 06:45:50 +0000 (15:45 +0900)
committerBoris Brezillon <boris.brezillon@free-electrons.com>
Tue, 25 Apr 2017 12:18:33 +0000 (14:18 +0200)
commit4986e334ae3a4476725d6e2db93c3147e16bdb87
tree96548aa5cc8ca01c0dd597a88a37deca02df67c4
parent35bf0370db87f89617f87bee399249d610a3b46e
mtd: nand: denali: fix bitflips calculation in handle_ecc()

This function is wrong in multiple ways:

[1] Counting corrected bytes instead of corrected bits.

The following code is counting the number of corrected _bytes_.

    /* correct the ECC error */
    buf[offset] ^= err_cor_value;
    mtd->ecc_stats.corrected++;
    bitflips++;

What the core framework expects is the number of corrected _bits_.
They can be different if multiple bitflips occur within one byte.

[2] total number of errors instead of max of per-sector errors

The core framework expects that corrected errors are counted per
sector, then the max value should be taken.  The current code simply
iterates over the whole page, i.e. counts the total number of
correction in the page.  This means "too many bitflips" is triggered
earlier than it should be, i.e. the NAND device is worn out sooner.

Besides those bugs, this function is unreadable due to the deep
nesting.  Notice the whole code in this function is wrapped in
if (irq_status & INTR__ECC_ERR), so this conditional can be moved
out of the function.  Also, use shorter names for local variables.

Re-work the function to fix all the issues.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
drivers/mtd/nand/denali.c