aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoris BREZILLON <boris.brezillon@free-electrons.com>2015-12-30 14:32:04 -0500
committerBrian Norris <computersforpeace@gmail.com>2016-01-06 21:48:20 -0500
commit40cbe6eee97b706f27bcc4c6aa1018bbe4f1e577 (patch)
tree6f35750b4b83b5e709569d3e6fbbae74fb19352b
parent6e9411923b8f4c0e568cbae0f35b7ee4eb989914 (diff)
mtd: nand: use nand_check_erased_ecc_chunk in default ECC read functions
The default NAND read functions are relying on the underlying controller driver to correct bitflips, but some of those controllers cannot properly fix bitflips in erased pages. Check for bitflips in erased pages in default core functions if the driver delegated the this check by setting the NAND_ECC_GENERIC_ERASED_CHECK flag. Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> Tested-by: Franklin S Cooper Jr. <fcooper@ti.com> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
-rw-r--r--drivers/mtd/nand/nand_base.c53
-rw-r--r--include/linux/mtd/nand.h10
2 files changed, 56 insertions, 7 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 50514f2501bb..f2c8ff398d6c 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1426,6 +1426,16 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
1426 1426
1427 stat = chip->ecc.correct(mtd, p, 1427 stat = chip->ecc.correct(mtd, p,
1428 &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]); 1428 &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]);
1429 if (stat == -EBADMSG &&
1430 (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) {
1431 /* check for empty pages with bitflips */
1432 stat = nand_check_erased_ecc_chunk(p, chip->ecc.size,
1433 &chip->buffers->ecccode[i],
1434 chip->ecc.bytes,
1435 NULL, 0,
1436 chip->ecc.strength);
1437 }
1438
1429 if (stat < 0) { 1439 if (stat < 0) {
1430 mtd->ecc_stats.failed++; 1440 mtd->ecc_stats.failed++;
1431 } else { 1441 } else {
@@ -1475,6 +1485,15 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
1475 int stat; 1485 int stat;
1476 1486
1477 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); 1487 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
1488 if (stat == -EBADMSG &&
1489 (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) {
1490 /* check for empty pages with bitflips */
1491 stat = nand_check_erased_ecc_chunk(p, eccsize,
1492 &ecc_code[i], eccbytes,
1493 NULL, 0,
1494 chip->ecc.strength);
1495 }
1496
1478 if (stat < 0) { 1497 if (stat < 0) {
1479 mtd->ecc_stats.failed++; 1498 mtd->ecc_stats.failed++;
1480 } else { 1499 } else {
@@ -1527,6 +1546,15 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
1527 chip->ecc.calculate(mtd, p, &ecc_calc[i]); 1546 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
1528 1547
1529 stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL); 1548 stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL);
1549 if (stat == -EBADMSG &&
1550 (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) {
1551 /* check for empty pages with bitflips */
1552 stat = nand_check_erased_ecc_chunk(p, eccsize,
1553 &ecc_code[i], eccbytes,
1554 NULL, 0,
1555 chip->ecc.strength);
1556 }
1557
1530 if (stat < 0) { 1558 if (stat < 0) {
1531 mtd->ecc_stats.failed++; 1559 mtd->ecc_stats.failed++;
1532 } else { 1560 } else {
@@ -1554,6 +1582,7 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
1554 int i, eccsize = chip->ecc.size; 1582 int i, eccsize = chip->ecc.size;
1555 int eccbytes = chip->ecc.bytes; 1583 int eccbytes = chip->ecc.bytes;
1556 int eccsteps = chip->ecc.steps; 1584 int eccsteps = chip->ecc.steps;
1585 int eccpadbytes = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
1557 uint8_t *p = buf; 1586 uint8_t *p = buf;
1558 uint8_t *oob = chip->oob_poi; 1587 uint8_t *oob = chip->oob_poi;
1559 unsigned int max_bitflips = 0; 1588 unsigned int max_bitflips = 0;
@@ -1573,19 +1602,29 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
1573 chip->read_buf(mtd, oob, eccbytes); 1602 chip->read_buf(mtd, oob, eccbytes);
1574 stat = chip->ecc.correct(mtd, p, oob, NULL); 1603 stat = chip->ecc.correct(mtd, p, oob, NULL);
1575 1604
1576 if (stat < 0) {
1577 mtd->ecc_stats.failed++;
1578 } else {
1579 mtd->ecc_stats.corrected += stat;
1580 max_bitflips = max_t(unsigned int, max_bitflips, stat);
1581 }
1582
1583 oob += eccbytes; 1605 oob += eccbytes;
1584 1606
1585 if (chip->ecc.postpad) { 1607 if (chip->ecc.postpad) {
1586 chip->read_buf(mtd, oob, chip->ecc.postpad); 1608 chip->read_buf(mtd, oob, chip->ecc.postpad);
1587 oob += chip->ecc.postpad; 1609 oob += chip->ecc.postpad;
1588 } 1610 }
1611
1612 if (stat == -EBADMSG &&
1613 (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) {
1614 /* check for empty pages with bitflips */
1615 stat = nand_check_erased_ecc_chunk(p, chip->ecc.size,
1616 oob - eccpadbytes,
1617 eccpadbytes,
1618 NULL, 0,
1619 chip->ecc.strength);
1620 }
1621
1622 if (stat < 0) {
1623 mtd->ecc_stats.failed++;
1624 } else {
1625 mtd->ecc_stats.corrected += stat;
1626 max_bitflips = max_t(unsigned int, max_bitflips, stat);
1627 }
1589 } 1628 }
1590 1629
1591 /* Calculate remaining oob bytes */ 1630 /* Calculate remaining oob bytes */
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 518958115182..86487dbe7358 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -129,6 +129,14 @@ typedef enum {
129/* Enable Hardware ECC before syndrome is read back from flash */ 129/* Enable Hardware ECC before syndrome is read back from flash */
130#define NAND_ECC_READSYN 2 130#define NAND_ECC_READSYN 2
131 131
132/*
133 * Enable generic NAND 'page erased' check. This check is only done when
134 * ecc.correct() returns -EBADMSG.
135 * Set this flag if your implementation does not fix bitflips in erased
136 * pages and you want to rely on the default implementation.
137 */
138#define NAND_ECC_GENERIC_ERASED_CHECK BIT(0)
139
132/* Bit mask for flags passed to do_nand_read_ecc */ 140/* Bit mask for flags passed to do_nand_read_ecc */
133#define NAND_GET_DEVICE 0x80 141#define NAND_GET_DEVICE 0x80
134 142
@@ -451,6 +459,7 @@ struct nand_hw_control {
451 * @total: total number of ECC bytes per page 459 * @total: total number of ECC bytes per page
452 * @prepad: padding information for syndrome based ECC generators 460 * @prepad: padding information for syndrome based ECC generators
453 * @postpad: padding information for syndrome based ECC generators 461 * @postpad: padding information for syndrome based ECC generators
462 * @options: ECC specific options (see NAND_ECC_XXX flags defined above)
454 * @layout: ECC layout control struct pointer 463 * @layout: ECC layout control struct pointer
455 * @priv: pointer to private ECC control data 464 * @priv: pointer to private ECC control data
456 * @hwctl: function to control hardware ECC generator. Must only 465 * @hwctl: function to control hardware ECC generator. Must only
@@ -500,6 +509,7 @@ struct nand_ecc_ctrl {
500 int strength; 509 int strength;
501 int prepad; 510 int prepad;
502 int postpad; 511 int postpad;
512 unsigned int options;
503 struct nand_ecclayout *layout; 513 struct nand_ecclayout *layout;
504 void *priv; 514 void *priv;
505 void (*hwctl)(struct mtd_info *mtd, int mode); 515 void (*hwctl)(struct mtd_info *mtd, int mode);