aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/nand_base.c
diff options
context:
space:
mode:
authorMike Dunn <mikedunn@newsguy.com>2012-04-25 15:06:11 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2012-05-14 00:14:23 -0400
commitedbc4540e02c201bdd4f4d498ebb6ed517fd36e2 (patch)
tree403ee7318cb1218a224885d048781e35f2128a22 /drivers/mtd/nand/nand_base.c
parente2788c98b98269a3131bffd2b57599280d7abd73 (diff)
mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN
The drivers' _read() method, absent an error, returns a non-negative integer indicating the maximum number of bit errors that were corrected in any one region comprising an ecc step. MTD returns -EUCLEAN if this is >= bitflip_threshold, 0 otherwise. If bitflip_threshold is zero, the comparison is not made since these devices lack ECC and always return zero in the non-error case (thanks Brian)¹. Note that this is a subtle change to the driver interface. This and the preceding patches in this set were tested with ubi on top of the nandsim and docg4 devices, running the ubi test io_basic from mtd-utils. ¹ http://lists.infradead.org/pipermail/linux-mtd/2012-March/040468.html Signed-off-by: Mike Dunn <mikedunn@newsguy.com> Acked-by: Robert Jarzmik <robert.jarzmik@free.fr> Acked-by: Brian Norris <computersforpeace@gmail.com> Ivan Djelic <ivan.djelic@parrot.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/nand/nand_base.c')
-rw-r--r--drivers/mtd/nand/nand_base.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 9f5d339a3610..640f1f8159e8 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1486,6 +1486,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1486 mtd->oobavail : mtd->oobsize; 1486 mtd->oobavail : mtd->oobsize;
1487 1487
1488 uint8_t *bufpoi, *oob, *buf; 1488 uint8_t *bufpoi, *oob, *buf;
1489 unsigned int max_bitflips = 0;
1489 1490
1490 stats = mtd->ecc_stats; 1491 stats = mtd->ecc_stats;
1491 1492
@@ -1513,7 +1514,10 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1513 sndcmd = 0; 1514 sndcmd = 0;
1514 } 1515 }
1515 1516
1516 /* Now read the page into the buffer */ 1517 /*
1518 * Now read the page into the buffer. Absent an error,
1519 * the read methods return max bitflips per ecc step.
1520 */
1517 if (unlikely(ops->mode == MTD_OPS_RAW)) 1521 if (unlikely(ops->mode == MTD_OPS_RAW))
1518 ret = chip->ecc.read_page_raw(mtd, chip, 1522 ret = chip->ecc.read_page_raw(mtd, chip,
1519 bufpoi, page); 1523 bufpoi, page);
@@ -1530,15 +1534,19 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1530 break; 1534 break;
1531 } 1535 }
1532 1536
1537 max_bitflips = max_t(unsigned int, max_bitflips, ret);
1538
1533 /* Transfer not aligned data */ 1539 /* Transfer not aligned data */
1534 if (!aligned) { 1540 if (!aligned) {
1535 if (!NAND_SUBPAGE_READ(chip) && !oob && 1541 if (!NAND_SUBPAGE_READ(chip) && !oob &&
1536 !(mtd->ecc_stats.failed - stats.failed) && 1542 !(mtd->ecc_stats.failed - stats.failed) &&
1537 (ops->mode != MTD_OPS_RAW)) 1543 (ops->mode != MTD_OPS_RAW)) {
1538 chip->pagebuf = realpage; 1544 chip->pagebuf = realpage;
1539 else 1545 chip->pagebuf_bitflips = ret;
1546 } else {
1540 /* Invalidate page cache */ 1547 /* Invalidate page cache */
1541 chip->pagebuf = -1; 1548 chip->pagebuf = -1;
1549 }
1542 memcpy(buf, chip->buffers->databuf + col, bytes); 1550 memcpy(buf, chip->buffers->databuf + col, bytes);
1543 } 1551 }
1544 1552
@@ -1571,6 +1579,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1571 } else { 1579 } else {
1572 memcpy(buf, chip->buffers->databuf + col, bytes); 1580 memcpy(buf, chip->buffers->databuf + col, bytes);
1573 buf += bytes; 1581 buf += bytes;
1582 max_bitflips = max_t(unsigned int, max_bitflips,
1583 chip->pagebuf_bitflips);
1574 } 1584 }
1575 1585
1576 readlen -= bytes; 1586 readlen -= bytes;
@@ -1609,7 +1619,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1609 if (mtd->ecc_stats.failed - stats.failed) 1619 if (mtd->ecc_stats.failed - stats.failed)
1610 return -EBADMSG; 1620 return -EBADMSG;
1611 1621
1612 return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0; 1622 return max_bitflips;
1613} 1623}
1614 1624
1615/** 1625/**