mtd: nand: Warn the user if the selected ECC strength is too weak
Linux-MTD Mailing List
linux-mtd at lists.infradead.org
Tue Jun 10 23:59:09 PDT 2014
Gitweb: http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=67a9ad9b8a6f6ea76ef8fc484ae49970d72d5534
Commit: 67a9ad9b8a6f6ea76ef8fc484ae49970d72d5534
Parent: edf02fb248022c13b2c86f08177b99ce619e693a
Author: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
AuthorDate: Wed May 14 14:58:06 2014 -0300
Committer: Brian Norris <computersforpeace at gmail.com>
CommitDate: Wed May 21 12:55:08 2014 -0700
mtd: nand: Warn the user if the selected ECC strength is too weak
This commit makes use of the chip->ecc_strength_ds and chip->ecc_step_ds which
contain the datasheet minimum requested ECC strength to produce a noisy warning
if the configured ECC strength is weaker.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
drivers/mtd/nand/nand_base.c | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 0c1593b..41167e9 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3794,6 +3794,39 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
}
EXPORT_SYMBOL(nand_scan_ident);
+/*
+ * Check if the chip configuration meet the datasheet requirements.
+
+ * If our configuration corrects A bits per B bytes and the minimum
+ * required correction level is X bits per Y bytes, then we must ensure
+ * both of the following are true:
+ *
+ * (1) A / B >= X / Y
+ * (2) A >= X
+ *
+ * Requirement (1) ensures we can correct for the required bitflip density.
+ * Requirement (2) ensures we can correct even when all bitflips are clumped
+ * in the same sector.
+ */
+static bool nand_ecc_strength_good(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct nand_ecc_ctrl *ecc = &chip->ecc;
+ int corr, ds_corr;
+
+ if (ecc->size == 0 || chip->ecc_step_ds == 0)
+ /* Not enough information */
+ return true;
+
+ /*
+ * We get the number of corrected bits per page to compare
+ * the correction density.
+ */
+ corr = (mtd->writesize * ecc->strength) / ecc->size;
+ ds_corr = (mtd->writesize * chip->ecc_strength_ds) / chip->ecc_step_ds;
+
+ return corr >= ds_corr && ecc->strength >= chip->ecc_strength_ds;
+}
/**
* nand_scan_tail - [NAND Interface] Scan for the NAND device
@@ -4014,6 +4047,9 @@ int nand_scan_tail(struct mtd_info *mtd)
ecc->layout->oobavail += ecc->layout->oobfree[i].length;
mtd->oobavail = ecc->layout->oobavail;
+ /* ECC sanity check: warn noisily if it's too weak */
+ WARN_ON(!nand_ecc_strength_good(mtd));
+
/*
* Set the number of read / write steps for one page depending on ECC
* mode.
More information about the linux-mtd-cvs
mailing list