Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mtd: nand: tango: Update ecc_stats.corrected

According to Boris, some user-space tools expect MTD drivers to
update ecc_stats.corrected, and it's better to provide a lower
bound than to provide no information at all.

Fixes: 6956e2385a16 ("mtd: nand: add tango NAND flash controller support")
Cc: stable@vger.kernel.org
Reported-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Marc Gonzalez <marc_gonzalez@sigmadesigns.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>

authored by

Marc Gonzalez and committed by
Boris Brezillon
60cf0ce1 2761b4f1

+15 -7
+15 -7
drivers/mtd/nand/tango_nand.c
··· 55 55 * byte 1 for other packets in the page (PKT_N, for N > 0) 56 56 * ERR_COUNT_PKT_N is the max error count over all but the first packet. 57 57 */ 58 - #define DECODE_OK_PKT_0(v) ((v) & BIT(7)) 59 - #define DECODE_OK_PKT_N(v) ((v) & BIT(15)) 60 58 #define ERR_COUNT_PKT_0(v) (((v) >> 0) & 0x3f) 61 59 #define ERR_COUNT_PKT_N(v) (((v) >> 8) & 0x3f) 60 + #define DECODE_FAIL_PKT_0(v) (((v) & BIT(7)) == 0) 61 + #define DECODE_FAIL_PKT_N(v) (((v) & BIT(15)) == 0) 62 62 63 63 /* Offsets relative to pbus_base */ 64 64 #define PBUS_CS_CTRL 0x83c ··· 193 193 chip->ecc.strength); 194 194 if (res < 0) 195 195 mtd->ecc_stats.failed++; 196 + else 197 + mtd->ecc_stats.corrected += res; 196 198 197 199 bitflips = max(res, bitflips); 198 200 buf += pkt_size; ··· 204 202 return bitflips; 205 203 } 206 204 207 - static int decode_error_report(struct tango_nfc *nfc) 205 + static int decode_error_report(struct nand_chip *chip) 208 206 { 209 207 u32 status, res; 208 + struct mtd_info *mtd = nand_to_mtd(chip); 209 + struct tango_nfc *nfc = to_tango_nfc(chip->controller); 210 210 211 211 status = readl_relaxed(nfc->reg_base + NFC_XFER_STATUS); 212 212 if (status & PAGE_IS_EMPTY) ··· 216 212 217 213 res = readl_relaxed(nfc->mem_base + ERROR_REPORT); 218 214 219 - if (DECODE_OK_PKT_0(res) && DECODE_OK_PKT_N(res)) 220 - return max(ERR_COUNT_PKT_0(res), ERR_COUNT_PKT_N(res)); 215 + if (DECODE_FAIL_PKT_0(res) || DECODE_FAIL_PKT_N(res)) 216 + return -EBADMSG; 221 217 222 - return -EBADMSG; 218 + /* ERR_COUNT_PKT_N is max, not sum, but that's all we have */ 219 + mtd->ecc_stats.corrected += 220 + ERR_COUNT_PKT_0(res) + ERR_COUNT_PKT_N(res); 221 + 222 + return max(ERR_COUNT_PKT_0(res), ERR_COUNT_PKT_N(res)); 223 223 } 224 224 225 225 static void tango_dma_callback(void *arg) ··· 290 282 if (err) 291 283 return err; 292 284 293 - res = decode_error_report(nfc); 285 + res = decode_error_report(chip); 294 286 if (res < 0) { 295 287 chip->ecc.read_oob_raw(mtd, chip, page); 296 288 res = check_erased_page(chip, buf);