aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mvebu/patches-3.14/008-nand_warn_weak_ecc_strength.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/mvebu/patches-3.14/008-nand_warn_weak_ecc_strength.patch')
-rw-r--r--target/linux/mvebu/patches-3.14/008-nand_warn_weak_ecc_strength.patch64
1 files changed, 64 insertions, 0 deletions
diff --git a/target/linux/mvebu/patches-3.14/008-nand_warn_weak_ecc_strength.patch b/target/linux/mvebu/patches-3.14/008-nand_warn_weak_ecc_strength.patch
new file mode 100644
index 0000000000..09bb72cf4e
--- /dev/null
+++ b/target/linux/mvebu/patches-3.14/008-nand_warn_weak_ecc_strength.patch
@@ -0,0 +1,64 @@
+From 67a9ad9b8a6f6ea76ef8fc484ae49970d72d5534 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Wed, 14 May 2014 14:58:06 -0300
+Subject: 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@free-electrons.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+
+--- a/drivers/mtd/nand/nand_base.c
++++ b/drivers/mtd/nand/nand_base.c
+@@ -3682,6 +3682,39 @@ int nand_scan_ident(struct mtd_info *mtd
+ }
+ 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
+@@ -3891,6 +3924,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.