All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] mtd: Change meaning of -EUCLEAN return code on reads
@ 2012-04-24 19:18 Mike Dunn
  2012-04-24 19:18 ` [PATCH 1/7] mtd: ecc_strength is at ecc step granularity Mike Dunn
                   ` (7 more replies)
  0 siblings, 8 replies; 26+ messages in thread
From: Mike Dunn @ 2012-04-24 19:18 UTC (permalink / raw)
  To: linux-mtd; +Cc: Mike Dunn

This is the latest attempt to address this issue (full description below).  I
didn't give it a version number because the approach has changed and these are
more than just reworked earlier patches.  The fundamental change is that
bitflips are now considered at the finer granularity of one region comprising an
ecc step, instead of a full page (writesize region).  Less significant issues
that were brought up in the course of discussion are also addressed.

This patchset addresses the problem of insufficient information being returned
by mtd_read() with regard to bit error corrections.  Currently -EUCLEAN is
returned if one or more bit errors were corrected during the course of the read
operation.  Higher layers like UBI use this return code as an indication that
the erase block may be degrading and should be considered as a candidate for
being marked as a bad block.  The problem is that high bit error rates are
common on more recent NAND flash devices with strong ecc algorithms.  Frequent
(but entirely normal) bit error corrections on these devices result in blocks
being incorrectly marked as bad.  On some devices, ubi/ubifs can not be reliably
used because of this.

This problem was discussed a while back [1][2][3], and a consensus of sorts was
reached for a solution, which these patches implement.  The recent addition of
the mtd api entry functions now make this solution practical (thanks Artem!).  A
quick description of each patch will provide a synopsis of the set:

(1) Fix how mtd->ecc_strength is calculated from nand->ecc.strength to reflect
    the fact that granularity is now at ecc step level (the two values are now
    the same).
(2) Fix a couple incorrect nand->ecc.strength values.
(3) Expose mtd->ecc_strength through sysfs (read-only).
(4) mtd->bitflip_threshold is added and exposed as read/write through sysfs.
    The drivers can initialize it, otherwise mtd initializes it to the default
    value of ecc_strength.  Users can change it through sysfs.
(5) The nand driver method _read_page() returns max_bitflips to the nand
    infrastructure code.  This is the maximum number of bitflip corrections that
    were made on any one region comprising an ecc step.
(6) Sanity checks added to nand_scan_tail() to ensure that drivers needing to
    set ecc strength do so.  (This includes all drivers using hardware ecc.)
(7) Absent a hard error, all drivers' mtd->_read() methods now return
    max_bitflips to mtd, and mtd_read() makes the decision of whether to return
    -EUCLEAN or 0. If max_bitflips >= bitflip_threshold, -EUCLEAN is returned.
    If bitflip_threshold == 0 (no ecc), make no comparison and return 0.

Of course reviews greatly appreciated.  Thanks!

P.S. It looks like some of these patches may conflict with others that may be
queued up, so let me know if they need to be reworked.

[1] http://lists.infradead.org/pipermail/linux-mtd/2011-December/038755.html
[2] http://lists.infradead.org/pipermail/linux-mtd/2011-December/038688.html
[3] http://lists.infradead.org/pipermail/linux-mtd/2011-December/038828.html

Mike Dunn (7):
  mtd; ecc_strength is at ecc step granularity
  mtd: nand: fix incorrect ecc strength values
  mtd: expose ecc_strength through sysfs
  mtd: bitflip threshold added to mtd_info and sysfs
  mtd: nand: read_page() returns max_bitflips
  mtd: nand: sanity checks of ecc strength in nand_scan_tail()
  mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN

 Documentation/ABI/testing/sysfs-class-mtd |   48 +++++++++++++++
 drivers/mtd/devices/docg3.c               |    4 +-
 drivers/mtd/mtdcore.c                     |   57 +++++++++++++++++-
 drivers/mtd/mtdpart.c                     |   12 ++--
 drivers/mtd/nand/alauda.c                 |    4 +-
 drivers/mtd/nand/atmel_nand.c             |    9 ++-
 drivers/mtd/nand/bcm_umi_bch.c            |    4 +-
 drivers/mtd/nand/bcm_umi_nand.c           |    7 +--
 drivers/mtd/nand/cafe_nand.c              |    4 +-
 drivers/mtd/nand/denali.c                 |   10 ++-
 drivers/mtd/nand/docg4.c                  |    5 +-
 drivers/mtd/nand/fsl_elbc_nand.c          |   21 ++++--
 drivers/mtd/nand/fsl_ifc_nand.c           |   10 +++-
 drivers/mtd/nand/fsmc_nand.c              |    9 ++-
 drivers/mtd/nand/jz4740_nand.c            |    6 +--
 drivers/mtd/nand/nand_base.c              |   95 ++++++++++++++++++++--------
 drivers/mtd/nand/sh_flctl.c               |    2 +-
 drivers/mtd/onenand/onenand_base.c        |    6 +-
 include/linux/mtd/mtd.h                   |   11 +++-
 include/linux/mtd/nand.h                  |    3 +
 20 files changed, 254 insertions(+), 73 deletions(-)

-- 
1.7.3.4

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 1/7] mtd: ecc_strength is at ecc step granularity
  2012-04-24 19:18 [PATCH 0/7] mtd: Change meaning of -EUCLEAN return code on reads Mike Dunn
@ 2012-04-24 19:18 ` Mike Dunn
  2012-04-24 19:18 ` [PATCH 2/7] mtd: nand: fix incorrect ecc strength values Mike Dunn
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 26+ messages in thread
From: Mike Dunn @ 2012-04-24 19:18 UTC (permalink / raw)
  To: linux-mtd; +Cc: Mike Dunn

ecc_strength element of mtd_info will be the strength of one ecc step, not of
the entire writesize, as was previously planned.  This is the appropriate way
because, as was pointed out [1], bit errors in excess of the strength of one
step can cause a hard error if they all occur within the same ecc region.

[1] http://lists.infradead.org/pipermail/linux-mtd/2012-March/040313.html

Signed-off-by: Mike Dunn <mikedunn@newsguy.com>
---
 drivers/mtd/nand/nand_base.c |    2 +-
 include/linux/mtd/mtd.h      |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index eb88d8b..c2d2e93 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3484,7 +3484,7 @@ int nand_scan_tail(struct mtd_info *mtd)
 
 	/* propagate ecc info to mtd_info */
 	mtd->ecclayout = chip->ecc.layout;
-	mtd->ecc_strength = chip->ecc.strength * chip->ecc.steps;
+	mtd->ecc_strength = chip->ecc.strength;
 
 	/* Check, if we should skip the bad block table scan */
 	if (chip->options & NAND_SKIP_BBTSCAN)
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index cf5ea8c..cd0119d 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -164,7 +164,7 @@ struct mtd_info {
 	/* ECC layout structure pointer - read only! */
 	struct nand_ecclayout *ecclayout;
 
-	/* max number of correctible bit errors per writesize */
+	/* max number of correctible bit errors per ecc step */
 	unsigned int ecc_strength;
 
 	/* Data for variable erase regions. If numeraseregions is zero,
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 2/7] mtd: nand: fix incorrect ecc strength values
  2012-04-24 19:18 [PATCH 0/7] mtd: Change meaning of -EUCLEAN return code on reads Mike Dunn
  2012-04-24 19:18 ` [PATCH 1/7] mtd: ecc_strength is at ecc step granularity Mike Dunn
@ 2012-04-24 19:18 ` Mike Dunn
  2012-05-01 19:07   ` Jiandong Zheng
  2012-04-24 19:18 ` [PATCH 3/7] mtd: expose ecc_strength through sysfs Mike Dunn
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 26+ messages in thread
From: Mike Dunn @ 2012-04-24 19:18 UTC (permalink / raw)
  To: linux-mtd
  Cc: Scott Branden, Mike Dunn, Jiandong Zheng, Prabhakar Kushwaha,
	Lars-Peter Clausen

This fixes a couple of ecc strength values for which I earlier made conservative
guesses, but whose correct values were later determined [1] (thanks Ivan).  Also
sets strength for fsl_ifc_nand, which was merged to mainline after the original
patch that set the strength for all drivers.

[1] http://lists.infradead.org/pipermail/linux-mtd/2012-March/040325.html

Signed-off-by: Mike Dunn <mikedunn@newsguy.com>
---
 drivers/mtd/nand/bcm_umi_nand.c |    7 +------
 drivers/mtd/nand/fsl_ifc_nand.c |    1 +
 drivers/mtd/nand/jz4740_nand.c  |    6 +-----
 3 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/nand/bcm_umi_nand.c b/drivers/mtd/nand/bcm_umi_nand.c
index 6908cdd..7134adf 100644
--- a/drivers/mtd/nand/bcm_umi_nand.c
+++ b/drivers/mtd/nand/bcm_umi_nand.c
@@ -476,12 +476,7 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev)
 		this->badblock_pattern = &largepage_bbt;
 	}
 
-	/*
-	 * FIXME: ecc strength value of 6 bits per 512 bytes of data is a
-	 * conservative guess, given 13 ecc bytes and using bch alg.
-	 * (Assume Galois field order m=15 to allow a margin of error.)
-	 */
-	this->ecc.strength = 6;
+	this->ecc.strength = 8;
 
 #endif
 
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index 5387cec..872cc96 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -821,6 +821,7 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)
 	/* Hardware generates ECC per 512 Bytes */
 	chip->ecc.size = 512;
 	chip->ecc.bytes = 8;
+	chip->ecc.strength = 4;
 
 	switch (csor & CSOR_NAND_PGS_MASK) {
 	case CSOR_NAND_PGS_512:
diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c
index e4147e8..a6fa884 100644
--- a/drivers/mtd/nand/jz4740_nand.c
+++ b/drivers/mtd/nand/jz4740_nand.c
@@ -332,11 +332,7 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
 	chip->ecc.mode		= NAND_ECC_HW_OOB_FIRST;
 	chip->ecc.size		= 512;
 	chip->ecc.bytes		= 9;
-	chip->ecc.strength	= 2;
-	/*
-	 * FIXME: ecc_strength value of 2 bits per 512 bytes of data is a
-	 * conservative guess, given 9 ecc bytes and reed-solomon alg.
-	 */
+	chip->ecc.strength	= 4;
 
 	if (pdata)
 		chip->ecc.layout = pdata->ecc_layout;
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 3/7] mtd: expose ecc_strength through sysfs
  2012-04-24 19:18 [PATCH 0/7] mtd: Change meaning of -EUCLEAN return code on reads Mike Dunn
  2012-04-24 19:18 ` [PATCH 1/7] mtd: ecc_strength is at ecc step granularity Mike Dunn
  2012-04-24 19:18 ` [PATCH 2/7] mtd: nand: fix incorrect ecc strength values Mike Dunn
@ 2012-04-24 19:18 ` Mike Dunn
  2012-04-24 19:18 ` [PATCH 4/7] mtd: bitflip threshold added to mtd_info and sysfs Mike Dunn
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 26+ messages in thread
From: Mike Dunn @ 2012-04-24 19:18 UTC (permalink / raw)
  To: linux-mtd; +Cc: Mike Dunn

ecc_strength element of struct mtd_info is exposed as a read-only variable in
sysfs.  

This patch is unchanged from its earlier version, except for the wording in the
documentation to reflect the fact that it now applies to each ecc step.

Signed-off-by: Mike Dunn <mikedunn@newsguy.com>
---
 Documentation/ABI/testing/sysfs-class-mtd |   12 ++++++++++++
 drivers/mtd/mtdcore.c                     |   10 ++++++++++
 2 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-class-mtd b/Documentation/ABI/testing/sysfs-class-mtd
index 4d55a18..43d1818 100644
--- a/Documentation/ABI/testing/sysfs-class-mtd
+++ b/Documentation/ABI/testing/sysfs-class-mtd
@@ -123,3 +123,15 @@ Description:
 		half page, or a quarter page).
 
 		In the case of ECC NOR, it is the ECC block size.
+
+What:		/sys/class/mtd/mtdX/ecc_strength
+Date:		April 2012
+KernelVersion:	3.4
+Contact:	linux-mtd@lists.infradead.org
+Description:
+		Maximum number of bit errors that the device is capable of
+		correcting within each region covering an ecc step.  This will
+		always be a non-negative integer.  Note that some devices will
+		have multiple ecc steps within each writesize region.
+
+		In the case of devices lacking any ECC capability, it is 0.
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index c837507..090e849 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -250,6 +250,15 @@ static ssize_t mtd_name_show(struct device *dev,
 }
 static DEVICE_ATTR(name, S_IRUGO, mtd_name_show, NULL);
 
+static ssize_t mtd_ecc_strength_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct mtd_info *mtd = dev_get_drvdata(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%u\n", mtd->ecc_strength);
+}
+static DEVICE_ATTR(ecc_strength, S_IRUGO, mtd_ecc_strength_show, NULL);
+
 static struct attribute *mtd_attrs[] = {
 	&dev_attr_type.attr,
 	&dev_attr_flags.attr,
@@ -260,6 +269,7 @@ static struct attribute *mtd_attrs[] = {
 	&dev_attr_oobsize.attr,
 	&dev_attr_numeraseregions.attr,
 	&dev_attr_name.attr,
+	&dev_attr_ecc_strength.attr,
 	NULL,
 };
 
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 4/7] mtd: bitflip threshold added to mtd_info and sysfs
  2012-04-24 19:18 [PATCH 0/7] mtd: Change meaning of -EUCLEAN return code on reads Mike Dunn
                   ` (2 preceding siblings ...)
  2012-04-24 19:18 ` [PATCH 3/7] mtd: expose ecc_strength through sysfs Mike Dunn
@ 2012-04-24 19:18 ` Mike Dunn
  2012-04-24 19:18 ` [PATCH 5/7] mtd: nand: read_page() returns max_bitflips Mike Dunn
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 26+ messages in thread
From: Mike Dunn @ 2012-04-24 19:18 UTC (permalink / raw)
  To: linux-mtd; +Cc: Mike Dunn

An element 'bitflip_threshold' is added to struct mtd_info, and also exposed as
a read/write variable in sysfs.  This will be used to determine whether or not
mtd_read() returns -EUCLEAN or 0 (absent a hard error).  If the driver leaves it
as zero, mtd will set it to a default value of ecc_strength.  

This patch is unchanged from its earlier version, except for the wording in the
documentation to reflect the fact that it now applies to each ecc step, as well
as changes suggested during discussion [1].

[1] http://lists.infradead.org/pipermail/linux-mtd/2012-March/040331.html

Signed-off-by: Mike Dunn <mikedunn@newsguy.com>
---
 Documentation/ABI/testing/sysfs-class-mtd |   36 +++++++++++++++++++++++++++++
 drivers/mtd/mtdcore.c                     |   33 ++++++++++++++++++++++++++
 include/linux/mtd/mtd.h                   |    9 +++++++
 3 files changed, 78 insertions(+), 0 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-class-mtd b/Documentation/ABI/testing/sysfs-class-mtd
index 43d1818..7883508 100644
--- a/Documentation/ABI/testing/sysfs-class-mtd
+++ b/Documentation/ABI/testing/sysfs-class-mtd
@@ -135,3 +135,39 @@ Description:
 		have multiple ecc steps within each writesize region.
 
 		In the case of devices lacking any ECC capability, it is 0.
+
+What:		/sys/class/mtd/mtdX/bitflip_threshold
+Date:		April 2012
+KernelVersion:	3.4
+Contact:	linux-mtd@lists.infradead.org
+Description:
+		This allows the user to examine and adjust the criteria by which
+		mtd returns -EUCLEAN from mtd_read().  If the maximum number of
+		bit errors that were corrected on any single region comprising
+		an ecc step (as reported by the driver) equals or exceeds this
+		value, -EUCLEAN is returned.  Otherwise, absent an error, 0 is
+		returned.  Higher layers (e.g., UBI) use this return code as an
+		indication that an erase block may be degrading and should be
+		scrutinized as a candidate for being marked as bad.
+
+		The initial value may be specified by the flash device driver.
+		If not, then the default value is ecc_strength.
+
+		The introduction of this feature brings a subtle change to the
+		meaning of the -EUCLEAN return code.  Previously, it was
+		interpreted to mean simply "one or more bit errors were
+		corrected".  Its new interpretation can be phrased as "a
+		dangerously high number of bit errors were corrected on one or
+		more regions comprising an ecc step".  The precise definition of
+		"dangerously high" can be adjusted by the user with
+		bitflip_threshold.  Users are discouraged from doing this,
+		however, unless they know what they are doing and have intimate
+		knowledge of the properties of their device.  Broadly speaking,
+		bitflip_threshold should be low enough to detect genuine erase
+		block degradation, but high enough to avoid the consequences of
+		a persistent return value of -EUCLEAN on devices where sticky
+		bitflips occur.  Note that if bitflip_threshold exceeds
+		ecc_strength, -EUCLEAN is never returned by the read functions.
+
+		This is generally applicable only to NAND flash devices with ECC
+		capability.  It is ignored on devices lacking ECC capability.
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 090e849..6a7cba1 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -259,6 +259,34 @@ static ssize_t mtd_ecc_strength_show(struct device *dev,
 }
 static DEVICE_ATTR(ecc_strength, S_IRUGO, mtd_ecc_strength_show, NULL);
 
+static ssize_t mtd_bitflip_threshold_show(struct device *dev,
+					  struct device_attribute *attr,
+					  char *buf)
+{
+	struct mtd_info *mtd = dev_get_drvdata(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%u\n", mtd->bitflip_threshold);
+}
+
+static ssize_t mtd_bitflip_threshold_store(struct device *dev,
+					   struct device_attribute *attr,
+					   const char *buf, size_t count)
+{
+	struct mtd_info *mtd = dev_get_drvdata(dev);
+	unsigned int bitflip_threshold;
+	int retval;
+
+	retval = kstrtouint(buf, 0, &bitflip_threshold);
+	if (retval)
+		return retval;
+
+	mtd->bitflip_threshold = bitflip_threshold;
+	return count;
+}
+static DEVICE_ATTR(bitflip_threshold, S_IRUGO | S_IWUSR,
+		   mtd_bitflip_threshold_show,
+		   mtd_bitflip_threshold_store);
+
 static struct attribute *mtd_attrs[] = {
 	&dev_attr_type.attr,
 	&dev_attr_flags.attr,
@@ -270,6 +298,7 @@ static struct attribute *mtd_attrs[] = {
 	&dev_attr_numeraseregions.attr,
 	&dev_attr_name.attr,
 	&dev_attr_ecc_strength.attr,
+	&dev_attr_bitflip_threshold.attr,
 	NULL,
 };
 
@@ -332,6 +361,10 @@ int add_mtd_device(struct mtd_info *mtd)
 	mtd->index = i;
 	mtd->usecount = 0;
 
+	/* default value if not set by driver */
+	if (mtd->bitflip_threshold == 0)
+		mtd->bitflip_threshold = mtd->ecc_strength;
+
 	if (is_power_of_2(mtd->erasesize))
 		mtd->erasesize_shift = ffs(mtd->erasesize) - 1;
 	else
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index cd0119d..63dadc0 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -157,6 +157,15 @@ struct mtd_info {
 	unsigned int erasesize_mask;
 	unsigned int writesize_mask;
 
+	/*
+	 * read ops return -EUCLEAN if max number of bitflips corrected on any
+	 * one region comprising an ecc step equals or exceeds this value.
+	 * Settable by driver, else defaults to ecc_strength.  User can override
+	 * in sysfs.  N.B. The meaning of the -EUCLEAN return code has changed;
+	 * see Documentation/ABI/testing/sysfs-class-mtd for more detail.
+	 */
+	unsigned int bitflip_threshold;
+
 	// Kernel-only stuff starts here.
 	const char *name;
 	int index;
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 5/7] mtd: nand: read_page() returns max_bitflips
  2012-04-24 19:18 [PATCH 0/7] mtd: Change meaning of -EUCLEAN return code on reads Mike Dunn
                   ` (3 preceding siblings ...)
  2012-04-24 19:18 ` [PATCH 4/7] mtd: bitflip threshold added to mtd_info and sysfs Mike Dunn
@ 2012-04-24 19:18 ` Mike Dunn
  2012-04-24 19:45   ` Scott Wood
  2012-04-25  9:20   ` Shmulik Ladkani
  2012-04-24 19:18 ` [PATCH 6/7] mtd: nand: sanity checks of ecc strength in nand_scan_tail() Mike Dunn
                   ` (2 subsequent siblings)
  7 siblings, 2 replies; 26+ messages in thread
From: Mike Dunn @ 2012-04-24 19:18 UTC (permalink / raw)
  To: linux-mtd
  Cc: Jack Lan, Mike Dunn, Nick Spence, Chuanxiao Dong, Scott Wood,
	Jamie Iles, Axel Lin, Roy Zang, Prabhakar Kushwaha

The ecc.read_page() method for nand drivers is changed to return the maximum
number of bitflips that were corrected on any one region covering an ecc step,
This patch doesn't change what the nand code returns to mtd.

This patch wasn't necessary in the earlier attempt at this effort because when
max_bitflips referred to the entire page, the number of corrected bitflips could
be obtained from the ecc_stats by the nand infrastructure code.

This basically follows Schmulik's suggested approach [1].  It was tested only on
the docg4, but all drivers were compile-tested with the appropriate
cross-compiler.

[1] http://lists.infradead.org/pipermail/linux-mtd/2012-March/040343.html

Signed-off-by: Mike Dunn <mikedunn@newsguy.com>
---

Most of the changes to the drivers are straightforward, but a few really need
review.  The changes to the freescale controllers (fsl_elbc_nand and
fsl_ifc_nand) are a little more involved.  I am least confident about the denali
driver... I confess I am totally confused by the "multi connected nand support"
patch (commit 08b9ab9996c7e582f86da319f43d2dcb8ff55993).

 drivers/mtd/nand/atmel_nand.c    |    9 +++++--
 drivers/mtd/nand/bcm_umi_bch.c   |    4 ++-
 drivers/mtd/nand/cafe_nand.c     |    4 ++-
 drivers/mtd/nand/denali.c        |   10 +++++--
 drivers/mtd/nand/docg4.c         |    5 ++-
 drivers/mtd/nand/fsl_elbc_nand.c |   21 +++++++++++-----
 drivers/mtd/nand/fsl_ifc_nand.c  |    9 ++++++-
 drivers/mtd/nand/fsmc_nand.c     |    9 +++++--
 drivers/mtd/nand/nand_base.c     |   47 +++++++++++++++++++++++++-------------
 drivers/mtd/nand/sh_flctl.c      |    2 +-
 10 files changed, 82 insertions(+), 38 deletions(-)

diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 2165576..9a7876e 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -335,6 +335,7 @@ static int atmel_nand_read_page(struct mtd_info *mtd,
 	uint8_t *oob = chip->oob_poi;
 	uint8_t *ecc_pos;
 	int stat;
+	unsigned int max_bitflips = 0;
 
 	/*
 	 * Errata: ALE is incorrectly wired up to the ECC controller
@@ -371,10 +372,12 @@ static int atmel_nand_read_page(struct mtd_info *mtd,
 	/* check if there's an error */
 	stat = chip->ecc.correct(mtd, p, oob, NULL);
 
-	if (stat < 0)
+	if (stat < 0) {
 		mtd->ecc_stats.failed++;
-	else
+	} else {
 		mtd->ecc_stats.corrected += stat;
+		max_bitflips = max_t(unsigned int, max_bitflips, stat);
+	}
 
 	/* get back to oob start (end of page) */
 	chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1);
@@ -382,7 +385,7 @@ static int atmel_nand_read_page(struct mtd_info *mtd,
 	/* read the oob */
 	chip->read_buf(mtd, oob, mtd->oobsize);
 
-	return 0;
+	return max_bitflips;
 }
 
 /*
diff --git a/drivers/mtd/nand/bcm_umi_bch.c b/drivers/mtd/nand/bcm_umi_bch.c
index a930666..f8472b4 100644
--- a/drivers/mtd/nand/bcm_umi_bch.c
+++ b/drivers/mtd/nand/bcm_umi_bch.c
@@ -116,6 +116,7 @@ static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd,
 	uint8_t eccCalc[NAND_ECC_NUM_BYTES];
 	int sectorOobSize = mtd->oobsize / eccsteps;
 	int stat;
+	unsigned int max_bitflips = 0;
 
 	for (sectorIdx = 0; sectorIdx < eccsteps;
 			sectorIdx++, datap += eccsize) {
@@ -177,9 +178,10 @@ static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd,
 			}
 #endif
 			mtd->ecc_stats.corrected += stat;
+			max_bitflips = max_t(unsigned int, max_bitflips, stat);
 		}
 	}
-	return 0;
+	return max_bitflips;
 }
 
 /****************************************************************************
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c
index 2973d97..886ff3a 100644
--- a/drivers/mtd/nand/cafe_nand.c
+++ b/drivers/mtd/nand/cafe_nand.c
@@ -383,6 +383,7 @@ static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 			       uint8_t *buf, int page)
 {
 	struct cafe_priv *cafe = mtd->priv;
+	unsigned int max_bitflips = 0;
 
 	cafe_dev_dbg(&cafe->pdev->dev, "ECC result %08x SYN1,2 %08x\n",
 		     cafe_readl(cafe, NAND_ECC_RESULT),
@@ -449,10 +450,11 @@ static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 		} else {
 			dev_dbg(&cafe->pdev->dev, "Corrected %d symbol errors\n", n);
 			mtd->ecc_stats.corrected += n;
+			max_bitflips = max_t(unsigned int, max_bitflips, n);
 		}
 	}
 
-	return 0;
+	return max_bitflips;
 }
 
 static struct nand_ecclayout cafe_oobinfo_2048 = {
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index a1048c7..1b34647 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -924,9 +924,10 @@ bool is_erased(uint8_t *buf, int len)
 #define ECC_LAST_ERR(x)		((x) & ERR_CORRECTION_INFO__LAST_ERR_INFO)
 
 static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf,
-					uint32_t irq_status)
+		       uint32_t irq_status, unsigned int *max_bitflips)
 {
 	bool check_erased_page = false;
+	unsigned int bitflips = 0;
 
 	if (irq_status & INTR_STATUS__ECC_ERR) {
 		/* read the ECC errors. we'll ignore them for now */
@@ -965,6 +966,7 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf,
 					/* correct the ECC error */
 					buf[offset] ^= err_correction_value;
 					denali->mtd.ecc_stats.corrected++;
+					bitflips++;
 				}
 			} else {
 				/* if the error is not correctable, need to
@@ -984,6 +986,7 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf,
 		clear_interrupts(denali);
 		denali_set_intr_modes(denali, true);
 	}
+	*max_bitflips = bitflips;
 	return check_erased_page;
 }
 
@@ -1121,6 +1124,7 @@ static int denali_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
 static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 			    uint8_t *buf, int page)
 {
+	unsigned int max_bitflips;
 	struct denali_nand_info *denali = mtd_to_denali(mtd);
 
 	dma_addr_t addr = denali->buf.dma_buf;
@@ -1153,7 +1157,7 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 
 	memcpy(buf, denali->buf.buf, mtd->writesize);
 
-	check_erased_page = handle_ecc(denali, buf, irq_status);
+	check_erased_page = handle_ecc(denali, buf, irq_status, &max_bitflips);
 	denali_enable_dma(denali, false);
 
 	if (check_erased_page) {
@@ -1167,7 +1171,7 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 				denali->mtd.ecc_stats.failed++;
 		}
 	}
-	return 0;
+	return max_bitflips;
 }
 
 static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c
index b082026..8e7da01 100644
--- a/drivers/mtd/nand/docg4.c
+++ b/drivers/mtd/nand/docg4.c
@@ -720,6 +720,7 @@ static int read_page(struct mtd_info *mtd, struct nand_chip *nand,
 	struct docg4_priv *doc = nand->priv;
 	void __iomem *docptr = doc->virtadr;
 	uint16_t status, edc_err, *buf16;
+	int bits_corrected = 0;
 
 	dev_dbg(doc->dev, "%s: page %08x\n", __func__, page);
 
@@ -772,7 +773,7 @@ static int read_page(struct mtd_info *mtd, struct nand_chip *nand,
 
 		/* If bitflips are reported, attempt to correct with ecc */
 		if (edc_err & DOC_ECCCONF1_BCH_SYNDROM_ERR) {
-			int bits_corrected = correct_data(mtd, buf, page);
+			bits_corrected = correct_data(mtd, buf, page);
 			if (bits_corrected == -EBADMSG)
 				mtd->ecc_stats.failed++;
 			else
@@ -781,7 +782,7 @@ static int read_page(struct mtd_info *mtd, struct nand_chip *nand,
 	}
 
 	writew(0, docptr + DOC_DATAEND);
-	return 0;
+	return bits_corrected;
 }
 
 
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index 80b5264..8638b5e 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -75,6 +75,7 @@ struct fsl_elbc_fcm_ctrl {
 	unsigned int use_mdr;    /* Non zero if the MDR is to be set      */
 	unsigned int oob;        /* Non zero if operating on OOB data     */
 	unsigned int counter;	 /* counter for the initializations	  */
+	unsigned int max_bitflips;  /* Saved during READ0 cmd		  */
 };
 
 /* These map to the positions used by the FCM hardware ECC generator */
@@ -253,6 +254,8 @@ static int fsl_elbc_run_command(struct mtd_info *mtd)
 	if (chip->ecc.mode != NAND_ECC_HW)
 		return 0;
 
+	elbc_fcm_ctrl->max_bitflips = 0;
+
 	if (elbc_fcm_ctrl->read_bytes == mtd->writesize + mtd->oobsize) {
 		uint32_t lteccr = in_be32(&lbc->lteccr);
 		/*
@@ -262,11 +265,16 @@ static int fsl_elbc_run_command(struct mtd_info *mtd)
 		 * bits 28-31 are uncorrectable errors, marked elsewhere.
 		 * for small page nand only 1 bit is used.
 		 * if the ELBC doesn't have the lteccr register it reads 0
+		 * FIXME: 4 bits can be corrected on NANDs with 2k pages, so
+		 * count the number of sub-pages with bitflips and update
+		 * ecc_stats.corrected accordingly.
 		 */
 		if (lteccr & 0x000F000F)
 			out_be32(&lbc->lteccr, 0x000F000F); /* clear lteccr */
-		if (lteccr & 0x000F0000)
+		if (lteccr & 0x000F0000) {
 			mtd->ecc_stats.corrected++;
+			elbc_fcm_ctrl->max_bitflips = 1;
+		}
 	}
 
 	return 0;
@@ -743,13 +751,17 @@ static int fsl_elbc_read_page(struct mtd_info *mtd,
 			      uint8_t *buf,
 			      int page)
 {
+	struct fsl_elbc_mtd *priv = chip->priv;
+	struct fsl_lbc_ctrl *ctrl = priv->ctrl;
+	struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand;
+
 	fsl_elbc_read_buf(mtd, buf, mtd->writesize);
 	fsl_elbc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
 
 	if (fsl_elbc_wait(mtd, chip) & NAND_STATUS_FAIL)
 		mtd->ecc_stats.failed++;
 
-	return 0;
+	return elbc_fcm_ctrl->max_bitflips;
 }
 
 /* ECC will be calculated automatically, and errors will be detected in
@@ -814,11 +826,6 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
 		chip->ecc.size = 512;
 		chip->ecc.bytes = 3;
 		chip->ecc.strength = 1;
-		/*
-		 * FIXME: can hardware ecc correct 4 bitflips if page size is
-		 * 2k?  Then does hardware report number of corrections for this
-		 * case?  If so, ecc_stats reporting needs to be fixed as well.
-		 */
 	} else {
 		/* otherwise fall back to default software ECC */
 		chip->ecc.mode = NAND_ECC_SOFT;
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index 872cc96..df36037 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -63,6 +63,7 @@ struct fsl_ifc_nand_ctrl {
 	unsigned int oob;	/* Non zero if operating on OOB data	*/
 	unsigned int eccread;	/* Non zero for a full-page ECC read	*/
 	unsigned int counter;	/* counter for the initializations	*/
+	unsigned int max_bitflips;  /* Saved during READ0 cmd		*/
 };
 
 static struct fsl_ifc_nand_ctrl *ifc_nand_ctrl;
@@ -268,6 +269,8 @@ static void fsl_ifc_run_command(struct mtd_info *mtd)
 		int sector = bufnum * chip->ecc.steps;
 		int sector_end = sector + chip->ecc.steps - 1;
 
+		nctrl->max_bitflips = 0;
+
 		for (i = sector / 4; i <= sector_end / 4; i++)
 			eccstat[i] = in_be32(&ifc->ifc_nand.nand_eccstat[i]);
 
@@ -290,6 +293,9 @@ static void fsl_ifc_run_command(struct mtd_info *mtd)
 			}
 
 			mtd->ecc_stats.corrected += errors;
+			nctrl->max_bitflips = max_t(unsigned int,
+						    nctrl->max_bitflips,
+						    errors);
 		}
 
 		nctrl->eccread = 0;
@@ -698,6 +704,7 @@ static int fsl_ifc_read_page(struct mtd_info *mtd,
 {
 	struct fsl_ifc_mtd *priv = chip->priv;
 	struct fsl_ifc_ctrl *ctrl = priv->ctrl;
+	struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl;
 
 	fsl_ifc_read_buf(mtd, buf, mtd->writesize);
 	fsl_ifc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -708,7 +715,7 @@ static int fsl_ifc_read_page(struct mtd_info *mtd,
 	if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC)
 		mtd->ecc_stats.failed++;
 
-	return 0;
+	return nctrl->max_bitflips;
 }
 
 /* ECC will be calculated automatically, and errors will be detected in
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
index 1b8330e..1bf7f80 100644
--- a/drivers/mtd/nand/fsmc_nand.c
+++ b/drivers/mtd/nand/fsmc_nand.c
@@ -720,6 +720,7 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 	 */
 	uint16_t ecc_oob[7];
 	uint8_t *oob = (uint8_t *)&ecc_oob[0];
+	unsigned int max_bitflips = 0;
 
 	for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, p += eccsize) {
 		chip->cmdfunc(mtd, NAND_CMD_READ0, s * eccsize, page);
@@ -748,13 +749,15 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 
 		stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
-		if (stat < 0)
+		if (stat < 0) {
 			mtd->ecc_stats.failed++;
-		else
+		} else {
 			mtd->ecc_stats.corrected += stat;
+			max_bitflips = max_t(unsigned int, max_bitflips, stat);
+		}
 	}
 
-	return 0;
+	return max_bitflips;
 }
 
 /*
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index c2d2e93..3137abd 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1138,6 +1138,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	uint8_t *ecc_code = chip->buffers->ecccode;
 	uint32_t *eccpos = chip->ecc.layout->eccpos;
+	unsigned int max_bitflips = 0;
 
 	chip->ecc.read_page_raw(mtd, chip, buf, page);
 
@@ -1154,12 +1155,14 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 		int stat;
 
 		stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
-		if (stat < 0)
+		if (stat < 0) {
 			mtd->ecc_stats.failed++;
-		else
+		} else {
 			mtd->ecc_stats.corrected += stat;
+			max_bitflips = max_t(unsigned int, max_bitflips, stat);
+		}
 	}
-	return 0;
+	return max_bitflips;
 }
 
 /**
@@ -1180,6 +1183,7 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 	int datafrag_len, eccfrag_len, aligned_len, aligned_pos;
 	int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1;
 	int index = 0;
+	unsigned int max_bitflips = 0;
 
 	/* Column address within the page aligned to ECC size (256bytes) */
 	start_step = data_offs / chip->ecc.size;
@@ -1244,12 +1248,14 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 
 		stat = chip->ecc.correct(mtd, p,
 			&chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]);
-		if (stat < 0)
+		if (stat < 0) {
 			mtd->ecc_stats.failed++;
-		else
+		} else {
 			mtd->ecc_stats.corrected += stat;
+			max_bitflips = max_t(unsigned int, max_bitflips, stat);
+		}
 	}
-	return 0;
+	return max_bitflips;
 }
 
 /**
@@ -1271,6 +1277,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	uint8_t *ecc_code = chip->buffers->ecccode;
 	uint32_t *eccpos = chip->ecc.layout->eccpos;
+	unsigned int max_bitflips = 0;
 
 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
 		chip->ecc.hwctl(mtd, NAND_ECC_READ);
@@ -1289,12 +1296,14 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 		int stat;
 
 		stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
-		if (stat < 0)
+		if (stat < 0) {
 			mtd->ecc_stats.failed++;
-		else
+		} else {
 			mtd->ecc_stats.corrected += stat;
+			max_bitflips = max_t(unsigned int, max_bitflips, stat);
+		}
 	}
-	return 0;
+	return max_bitflips;
 }
 
 /**
@@ -1320,6 +1329,7 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
 	uint8_t *ecc_code = chip->buffers->ecccode;
 	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
+	unsigned int max_bitflips = 0;
 
 	/* Read the OOB area first */
 	chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
@@ -1337,12 +1347,14 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
 		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 
 		stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL);
-		if (stat < 0)
+		if (stat < 0) {
 			mtd->ecc_stats.failed++;
-		else
+		} else {
 			mtd->ecc_stats.corrected += stat;
+			max_bitflips = max_t(unsigned int, max_bitflips, stat);
+		}
 	}
-	return 0;
+	return max_bitflips;
 }
 
 /**
@@ -1363,6 +1375,7 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
 	int eccsteps = chip->ecc.steps;
 	uint8_t *p = buf;
 	uint8_t *oob = chip->oob_poi;
+	unsigned int max_bitflips = 0;
 
 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
 		int stat;
@@ -1379,10 +1392,12 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
 		chip->read_buf(mtd, oob, eccbytes);
 		stat = chip->ecc.correct(mtd, p, oob, NULL);
 
-		if (stat < 0)
+		if (stat < 0) {
 			mtd->ecc_stats.failed++;
-		else
+		} else {
 			mtd->ecc_stats.corrected += stat;
+			max_bitflips = max_t(unsigned int, max_bitflips, stat);
+		}
 
 		oob += eccbytes;
 
@@ -1397,7 +1412,7 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
 	if (i)
 		chip->read_buf(mtd, oob, i);
 
-	return 0;
+	return max_bitflips;
 }
 
 /**
@@ -1588,7 +1603,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 	if (oob)
 		ops->oobretlen = ops->ooblen - oobreadlen;
 
-	if (ret)
+	if (ret < 0)
 		return ret;
 
 	if (mtd->ecc_stats.failed - stats.failed)
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index e9b2b26..4ea3e20 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -359,7 +359,7 @@ static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 		if (flctl->hwecc_cant_correct[i])
 			mtd->ecc_stats.failed++;
 		else
-			mtd->ecc_stats.corrected += 0;
+			mtd->ecc_stats.corrected += 0; /* FIXME */
 	}
 
 	return 0;
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 6/7] mtd: nand: sanity checks of ecc strength in nand_scan_tail()
  2012-04-24 19:18 [PATCH 0/7] mtd: Change meaning of -EUCLEAN return code on reads Mike Dunn
                   ` (4 preceding siblings ...)
  2012-04-24 19:18 ` [PATCH 5/7] mtd: nand: read_page() returns max_bitflips Mike Dunn
@ 2012-04-24 19:18 ` Mike Dunn
  2012-04-25  4:09   ` Brian Norris
  2012-04-24 19:18 ` [PATCH 7/7] mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN Mike Dunn
  2012-04-25 11:23 ` [PATCH 0/7] mtd: Change meaning of -EUCLEAN return code on reads Ivan Djelic
  7 siblings, 1 reply; 26+ messages in thread
From: Mike Dunn @ 2012-04-24 19:18 UTC (permalink / raw)
  To: linux-mtd; +Cc: Mike Dunn

This patch adds sanity checks that ensure that drivers for controllers with
hardware ECC set the 'strength' element in struct nand_ecc_ctrl.  Also stylistic
changes to the line that calculates strength for software ECC.  Both suggested
during discussion [1].

[1] http://lists.infradead.org/pipermail/linux-mtd/2012-March/040467.html

Signed-off-by: Mike Dunn <mikedunn@newsguy.com>
---
 drivers/mtd/nand/nand_base.c |   28 ++++++++++++++++++++++------
 1 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 3137abd..275c43f 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3302,10 +3302,21 @@ int nand_scan_tail(struct mtd_info *mtd)
 				   "hardware ECC not possible\n");
 			BUG();
 		}
+
+		if (!chip->ecc.strength) {
+			pr_warn("Driver must set ecc.strength when using hardware ECC\n");
+			BUG();
+		}
+
 		if (!chip->ecc.read_page)
 			chip->ecc.read_page = nand_read_page_hwecc_oob_first;
 
 	case NAND_ECC_HW:
+		if (!chip->ecc.strength) {
+			pr_warn("Driver must set ecc.strength when using hardware ECC\n");
+			BUG();
+		}
+
 		/* Use standard hwecc read page function? */
 		if (!chip->ecc.read_page)
 			chip->ecc.read_page = nand_read_page_hwecc;
@@ -3345,12 +3356,17 @@ int nand_scan_tail(struct mtd_info *mtd)
 		if (!chip->ecc.write_oob)
 			chip->ecc.write_oob = nand_write_oob_syndrome;
 
-		if (mtd->writesize >= chip->ecc.size)
-			break;
-		pr_warn("%d byte HW ECC not possible on "
-			   "%d byte page size, fallback to SW ECC\n",
-			   chip->ecc.size, mtd->writesize);
+		if (mtd->writesize >= chip->ecc.size) {
+			if (!chip->ecc.strength) {
+				pr_warn("Driver must set ecc.strength when using hardware ECC\n");
+				BUG();
+			}
+			break;	/* all's well */
+		}
+		pr_warn("%d byte HW ECC not possible on %d byte page size, fallback to SW ECC\n",
+			chip->ecc.size, mtd->writesize);
 		chip->ecc.mode = NAND_ECC_SOFT;
+		/* fall through */
 
 	case NAND_ECC_SOFT:
 		chip->ecc.calculate = nand_calculate_ecc;
@@ -3401,7 +3417,7 @@ int nand_scan_tail(struct mtd_info *mtd)
 			BUG();
 		}
 		chip->ecc.strength =
-			chip->ecc.bytes*8 / fls(8*chip->ecc.size);
+			chip->ecc.bytes * 8 / fls(8 * chip->ecc.size);
 		break;
 
 	case NAND_ECC_NONE:
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 7/7] mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN
  2012-04-24 19:18 [PATCH 0/7] mtd: Change meaning of -EUCLEAN return code on reads Mike Dunn
                   ` (5 preceding siblings ...)
  2012-04-24 19:18 ` [PATCH 6/7] mtd: nand: sanity checks of ecc strength in nand_scan_tail() Mike Dunn
@ 2012-04-24 19:18 ` Mike Dunn
  2012-04-25 10:14   ` Shmulik Ladkani
  2012-04-25 18:27   ` Robert Jarzmik
  2012-04-25 11:23 ` [PATCH 0/7] mtd: Change meaning of -EUCLEAN return code on reads Ivan Djelic
  7 siblings, 2 replies; 26+ messages in thread
From: Mike Dunn @ 2012-04-24 19:18 UTC (permalink / raw)
  To: linux-mtd; +Cc: Mike Dunn

The drivers _read() method, absent an error, return 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) [1].  Note that this is a subtle change to the driver
interface.

This and the preceeding 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.

[1] http://lists.infradead.org/pipermail/linux-mtd/2012-March/040468.html

Signed-off-by: Mike Dunn <mikedunn@newsguy.com>
---
 drivers/mtd/devices/docg3.c        |    4 +++-
 drivers/mtd/mtdcore.c              |   14 +++++++++++++-
 drivers/mtd/mtdpart.c              |   12 ++++++------
 drivers/mtd/nand/alauda.c          |    4 ++--
 drivers/mtd/nand/nand_base.c       |   18 ++++++++++++++----
 drivers/mtd/onenand/onenand_base.c |    6 ++++--
 include/linux/mtd/nand.h           |    3 +++
 7 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
index 3414031..7644d59 100644
--- a/drivers/mtd/devices/docg3.c
+++ b/drivers/mtd/devices/docg3.c
@@ -862,6 +862,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
 	u8 *buf = ops->datbuf;
 	size_t len, ooblen, nbdata, nboob;
 	u8 hwecc[DOC_ECC_BCH_SIZE], eccconf1;
+	int max_bitflips = 0;
 
 	if (buf)
 		len = ops->len;
@@ -948,7 +949,8 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
 			}
 			if (ret > 0) {
 				mtd->ecc_stats.corrected += ret;
-				ret = -EUCLEAN;
+				max_bitflips = max(max_bitflips, ret);
+				ret = max_bitflips;
 			}
 		}
 
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 6a7cba1..b5bb628 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -800,12 +800,24 @@ EXPORT_SYMBOL_GPL(mtd_get_unmapped_area);
 int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
 	     u_char *buf)
 {
+	int ret_code;
 	*retlen = 0;
 	if (from < 0 || from > mtd->size || len > mtd->size - from)
 		return -EINVAL;
 	if (!len)
 		return 0;
-	return mtd->_read(mtd, from, len, retlen, buf);
+
+	/*
+	 * In the absence of an error, drivers return a non-negative integer
+	 * representing the maximum number of bitflips that were corrected on
+	 * any one ecc region (if applicable; zero otherwise).
+	 */
+	ret_code = mtd->_read(mtd, from, len, retlen, buf);
+	if (unlikely(ret_code < 0))
+		return ret_code;
+	if (mtd->bitflip_threshold == 0)
+		return 0;	/* device lacks ecc */
+	return ret_code >= mtd->bitflip_threshold ? -EUCLEAN : 0;
 }
 EXPORT_SYMBOL_GPL(mtd_read);
 
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 9651c06..d6321f6 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -67,12 +67,12 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
 	stats = part->master->ecc_stats;
 	res = part->master->_read(part->master, from + part->offset, len,
 				  retlen, buf);
-	if (unlikely(res)) {
-		if (mtd_is_bitflip(res))
-			mtd->ecc_stats.corrected += part->master->ecc_stats.corrected - stats.corrected;
-		if (mtd_is_eccerr(res))
-			mtd->ecc_stats.failed += part->master->ecc_stats.failed - stats.failed;
-	}
+	if (unlikely(mtd_is_eccerr(res)))
+		mtd->ecc_stats.failed +=
+			part->master->ecc_stats.failed - stats.failed;
+	else
+		mtd->ecc_stats.corrected +=
+			part->master->ecc_stats.corrected - stats.corrected;
 	return res;
 }
 
diff --git a/drivers/mtd/nand/alauda.c b/drivers/mtd/nand/alauda.c
index 4f20e1d..60a0dfd 100644
--- a/drivers/mtd/nand/alauda.c
+++ b/drivers/mtd/nand/alauda.c
@@ -414,7 +414,7 @@ static int alauda_bounce_read(struct mtd_info *mtd, loff_t from, size_t len,
 	}
 	err = 0;
 	if (corrected)
-		err = -EUCLEAN;
+		err = 1;	/* return max_bitflips per ecc step */
 	if (uncorrected)
 		err = -EBADMSG;
 out:
@@ -446,7 +446,7 @@ static int alauda_read(struct mtd_info *mtd, loff_t from, size_t len,
 	}
 	err = 0;
 	if (corrected)
-		err = -EUCLEAN;
+		err = 1;	/* return max_bitflips per ecc step */
 	if (uncorrected)
 		err = -EBADMSG;
 	return err;
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 275c43f..9f1b202 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,
 		mtd->oobavail : mtd->oobsize;
 
 	uint8_t *bufpoi, *oob, *buf;
+	unsigned int max_bitflips = 0;
 
 	stats = mtd->ecc_stats;
 
@@ -1513,7 +1514,10 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 				sndcmd = 0;
 			}
 
-			/* Now read the page into the buffer */
+			/*
+			 * Now read the page into the buffer.  Absent an error,
+			 * the read methods return max bitflips per ecc step.
+			 */
 			if (unlikely(ops->mode == MTD_OPS_RAW))
 				ret = chip->ecc.read_page_raw(mtd, chip,
 							      bufpoi, page);
@@ -1530,15 +1534,19 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 				break;
 			}
 
+			max_bitflips = max_t(unsigned int, max_bitflips, ret);
+
 			/* Transfer not aligned data */
 			if (!aligned) {
 				if (!NAND_SUBPAGE_READ(chip) && !oob &&
 				    !(mtd->ecc_stats.failed - stats.failed) &&
-				    (ops->mode != MTD_OPS_RAW))
+				    (ops->mode != MTD_OPS_RAW)) {
 					chip->pagebuf = realpage;
-				else
+					chip->pagebuf_bitflips = ret;
+				} else {
 					/* Invalidate page cache */
 					chip->pagebuf = -1;
+				}
 				memcpy(buf, chip->buffers->databuf + col, bytes);
 			}
 
@@ -1571,6 +1579,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 		} else {
 			memcpy(buf, chip->buffers->databuf + col, bytes);
 			buf += bytes;
+			max_bitflips = max_t(unsigned int, max_bitflips,
+					     chip->pagebuf_bitflips);
 		}
 
 		readlen -= bytes;
@@ -1609,7 +1619,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 	if (mtd->ecc_stats.failed - stats.failed)
 		return -EBADMSG;
 
-	return  mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
+	return max_bitflips;
 }
 
 /**
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index b3ce12e..7153e0d 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1201,7 +1201,8 @@ static int onenand_mlc_read_ops_nolock(struct mtd_info *mtd, loff_t from,
 	if (mtd->ecc_stats.failed - stats.failed)
 		return -EBADMSG;
 
-	return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
+	/* return max bitflips per ecc step; ONENANDs correct 1 bit only */
+	return mtd->ecc_stats.corrected != stats.corrected ? 1 : 0;
 }
 
 /**
@@ -1333,7 +1334,8 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
 	if (mtd->ecc_stats.failed - stats.failed)
 		return -EBADMSG;
 
-	return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
+	/* return max bitflips per ecc step; ONENANDs correct 1 bit only */
+	return mtd->ecc_stats.corrected != stats.corrected ? 1 : 0;
 }
 
 /**
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 1482340..2829e8b 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -459,6 +459,8 @@ struct nand_buffers {
  * @pagemask:		[INTERN] page number mask = number of (pages / chip) - 1
  * @pagebuf:		[INTERN] holds the pagenumber which is currently in
  *			data_buf.
+ * @pagebuf_bitflips:	[INTERN] holds the bitflip count for the page which is
+ *			currently in data_buf.
  * @subpagesize:	[INTERN] holds the subpagesize
  * @onfi_version:	[INTERN] holds the chip ONFI version (BCD encoded),
  *			non 0 if ONFI supported.
@@ -519,6 +521,7 @@ struct nand_chip {
 	uint64_t chipsize;
 	int pagemask;
 	int pagebuf;
+	unsigned int pagebuf_bitflips;
 	int subpagesize;
 	uint8_t cellinfo;
 	int badblockpos;
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH 5/7] mtd: nand: read_page() returns max_bitflips
  2012-04-24 19:18 ` [PATCH 5/7] mtd: nand: read_page() returns max_bitflips Mike Dunn
@ 2012-04-24 19:45   ` Scott Wood
  2012-04-25 15:35     ` Mike Dunn
  2012-04-25  9:20   ` Shmulik Ladkani
  1 sibling, 1 reply; 26+ messages in thread
From: Scott Wood @ 2012-04-24 19:45 UTC (permalink / raw)
  To: Mike Dunn
  Cc: Nick Spence, linux-mtd, Chuanxiao Dong, Jamie Iles, Axel Lin,
	Roy Zang, Prabhakar Kushwaha

On 04/24/2012 02:18 PM, Mike Dunn wrote:
> diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
> index 872cc96..df36037 100644
> --- a/drivers/mtd/nand/fsl_ifc_nand.c
> +++ b/drivers/mtd/nand/fsl_ifc_nand.c
> @@ -63,6 +63,7 @@ struct fsl_ifc_nand_ctrl {
>  	unsigned int oob;	/* Non zero if operating on OOB data	*/
>  	unsigned int eccread;	/* Non zero for a full-page ECC read	*/
>  	unsigned int counter;	/* counter for the initializations	*/
> +	unsigned int max_bitflips;  /* Saved during READ0 cmd		*/
>  };
>  
>  static struct fsl_ifc_nand_ctrl *ifc_nand_ctrl;
> @@ -268,6 +269,8 @@ static void fsl_ifc_run_command(struct mtd_info *mtd)
>  		int sector = bufnum * chip->ecc.steps;
>  		int sector_end = sector + chip->ecc.steps - 1;
>  
> +		nctrl->max_bitflips = 0;
> +
>  		for (i = sector / 4; i <= sector_end / 4; i++)
>  			eccstat[i] = in_be32(&ifc->ifc_nand.nand_eccstat[i]);
>  

I'd prefer to clear max_bitflips before this if-block, so that we can
rely on max_bitflips being zero when ECC wasn't requested.

Otherwise ACK the eLBC and IFC changes.

-Scott

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 6/7] mtd: nand: sanity checks of ecc strength in nand_scan_tail()
  2012-04-24 19:18 ` [PATCH 6/7] mtd: nand: sanity checks of ecc strength in nand_scan_tail() Mike Dunn
@ 2012-04-25  4:09   ` Brian Norris
  2012-04-25 15:08     ` Mike Dunn
  0 siblings, 1 reply; 26+ messages in thread
From: Brian Norris @ 2012-04-25  4:09 UTC (permalink / raw)
  To: Mike Dunn; +Cc: linux-mtd

Hi Mike,

On Tue, Apr 24, 2012 at 12:18 PM, Mike Dunn <mikedunn@newsguy.com> wrote:
> This patch adds sanity checks that ensure that drivers for controllers with
> hardware ECC set the 'strength' element in struct nand_ecc_ctrl.  Also stylistic
> changes to the line that calculates strength for software ECC.  Both suggested
> during discussion [1].
>
> [1] http://lists.infradead.org/pipermail/linux-mtd/2012-March/040467.html

Thanks for addressing these issues! Note my comment below though.

> ---
>  drivers/mtd/nand/nand_base.c |   28 ++++++++++++++++++++++------
>  1 files changed, 22 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index 3137abd..275c43f 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -3302,10 +3302,21 @@ int nand_scan_tail(struct mtd_info *mtd)
>                                   "hardware ECC not possible\n");
>                        BUG();
>                }
> +
> +               if (!chip->ecc.strength) {
> +                       pr_warn("Driver must set ecc.strength when using hardware ECC\n");
> +                       BUG();
> +               }
> +
>                if (!chip->ecc.read_page)
>                        chip->ecc.read_page = nand_read_page_hwecc_oob_first;
>
>        case NAND_ECC_HW:
> +               if (!chip->ecc.strength) {
> +                       pr_warn("Driver must set ecc.strength when using hardware ECC\n");
> +                       BUG();
> +               }
> +
>                /* Use standard hwecc read page function? */
>                if (!chip->ecc.read_page)
>                        chip->ecc.read_page = nand_read_page_hwecc;
> @@ -3345,12 +3356,17 @@ int nand_scan_tail(struct mtd_info *mtd)
>                if (!chip->ecc.write_oob)
>                        chip->ecc.write_oob = nand_write_oob_syndrome;
>
> -               if (mtd->writesize >= chip->ecc.size)
> -                       break;
> -               pr_warn("%d byte HW ECC not possible on "
> -                          "%d byte page size, fallback to SW ECC\n",
> -                          chip->ecc.size, mtd->writesize);
> +               if (mtd->writesize >= chip->ecc.size) {
> +                       if (!chip->ecc.strength) {
> +                               pr_warn("Driver must set ecc.strength when using hardware ECC\n");
> +                               BUG();
> +                       }
> +                       break;  /* all's well */
> +               }
> +               pr_warn("%d byte HW ECC not possible on %d byte page size, fallback to SW ECC\n",
> +                       chip->ecc.size, mtd->writesize);
>                chip->ecc.mode = NAND_ECC_SOFT;
> +               /* fall through */
>
>        case NAND_ECC_SOFT:
>                chip->ecc.calculate = nand_calculate_ecc;

I think you only need this last check (under ECC_HW_SYNDROME), since
the ECC_HW and ECC_HW_OOB_FIRST cases necessarily fall through to
ECC_HW_SYNDROME case. (Note the lack of 'break;' statements in the
first two 'case's.)

Brian

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 5/7] mtd: nand: read_page() returns max_bitflips
  2012-04-24 19:18 ` [PATCH 5/7] mtd: nand: read_page() returns max_bitflips Mike Dunn
  2012-04-24 19:45   ` Scott Wood
@ 2012-04-25  9:20   ` Shmulik Ladkani
  1 sibling, 0 replies; 26+ messages in thread
From: Shmulik Ladkani @ 2012-04-25  9:20 UTC (permalink / raw)
  To: Mike Dunn
  Cc: Jack Lan, Nick Spence, linux-mtd, Chuanxiao Dong, Scott Wood,
	Jamie Iles, Axel Lin, Roy Zang, Prabhakar Kushwaha

Hi Mike,

On Tue, 24 Apr 2012 12:18:23 -0700 Mike Dunn <mikedunn@newsguy.com> wrote:
> The ecc.read_page() method for nand drivers is changed to return the maximum
> number of bitflips that were corrected on any one region covering an ecc step,
> This patch doesn't change what the nand code returns to mtd.
> 
> This patch wasn't necessary in the earlier attempt at this effort because when
> max_bitflips referred to the entire page, the number of corrected bitflips could
> be obtained from the ecc_stats by the nand infrastructure code.
> 
> This basically follows Schmulik's suggested approach [1].  It was tested only on
> the docg4, but all drivers were compile-tested with the appropriate
> cross-compiler.
> 
> [1] http://lists.infradead.org/pipermail/linux-mtd/2012-March/040343.html
> 
> Signed-off-by: Mike Dunn <mikedunn@newsguy.com>

Reviewed nand_base.c, looks okay.

(though I wish we could avoid the max_bitflips calculation code
repetition)

Regards,
Shmulik

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 7/7] mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN
  2012-04-24 19:18 ` [PATCH 7/7] mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN Mike Dunn
@ 2012-04-25 10:14   ` Shmulik Ladkani
  2012-04-25 18:27   ` Robert Jarzmik
  1 sibling, 0 replies; 26+ messages in thread
From: Shmulik Ladkani @ 2012-04-25 10:14 UTC (permalink / raw)
  To: Mike Dunn; +Cc: linux-mtd

Hi Mike,

Reviewed mtdcore.c, mtdpart.c and nand_base.c.
Looks very good.

Minor comments below.

On Tue, 24 Apr 2012 12:18:25 -0700 Mike Dunn <mikedunn@newsguy.com> wrote:
> diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
> index 9651c06..d6321f6 100644
> --- a/drivers/mtd/mtdpart.c
> +++ b/drivers/mtd/mtdpart.c
> @@ -67,12 +67,12 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
>  	stats = part->master->ecc_stats;
>  	res = part->master->_read(part->master, from + part->offset, len,
>  				  retlen, buf);
> -	if (unlikely(res)) {
> -		if (mtd_is_bitflip(res))
> -			mtd->ecc_stats.corrected += part->master->ecc_stats.corrected - stats.corrected;
> -		if (mtd_is_eccerr(res))
> -			mtd->ecc_stats.failed += part->master->ecc_stats.failed - stats.failed;
> -	}
> +	if (unlikely(mtd_is_eccerr(res)))
> +		mtd->ecc_stats.failed +=
> +			part->master->ecc_stats.failed - stats.failed;
> +	else
> +		mtd->ecc_stats.corrected +=
> +			part->master->ecc_stats.corrected - stats.corrected;
>  	return res;
>  }

Probably need {} around the statements within the conditions.

Also I think there's no reason to execute "corrected +=" in case 'res'
is zero (although no harm).

Regards,
Shmulik

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 0/7] mtd: Change meaning of -EUCLEAN return code on reads
  2012-04-24 19:18 [PATCH 0/7] mtd: Change meaning of -EUCLEAN return code on reads Mike Dunn
                   ` (6 preceding siblings ...)
  2012-04-24 19:18 ` [PATCH 7/7] mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN Mike Dunn
@ 2012-04-25 11:23 ` Ivan Djelic
  2012-04-25 15:56   ` Mike Dunn
  7 siblings, 1 reply; 26+ messages in thread
From: Ivan Djelic @ 2012-04-25 11:23 UTC (permalink / raw)
  To: Mike Dunn; +Cc: linux-mtd

On Tue, Apr 24, 2012 at 08:18:18PM +0100, Mike Dunn wrote:
> 
> This problem was discussed a while back [1][2][3], and a consensus of sorts was
> reached for a solution, which these patches implement.  The recent addition of
> the mtd api entry functions now make this solution practical (thanks Artem!).  A
> quick description of each patch will provide a synopsis of the set:
> 
> (1) Fix how mtd->ecc_strength is calculated from nand->ecc.strength to reflect
>     the fact that granularity is now at ecc step level (the two values are now
>     the same).
> (2) Fix a couple incorrect nand->ecc.strength values.
> (3) Expose mtd->ecc_strength through sysfs (read-only).
> (4) mtd->bitflip_threshold is added and exposed as read/write through sysfs.
>     The drivers can initialize it, otherwise mtd initializes it to the default
>     value of ecc_strength.  Users can change it through sysfs.
> (5) The nand driver method _read_page() returns max_bitflips to the nand
>     infrastructure code.  This is the maximum number of bitflip corrections that
>     were made on any one region comprising an ecc step.
> (6) Sanity checks added to nand_scan_tail() to ensure that drivers needing to
>     set ecc strength do so.  (This includes all drivers using hardware ecc.)
> (7) Absent a hard error, all drivers' mtd->_read() methods now return
>     max_bitflips to mtd, and mtd_read() makes the decision of whether to return
>     -EUCLEAN or 0. If max_bitflips >= bitflip_threshold, -EUCLEAN is returned.
>     If bitflip_threshold == 0 (no ecc), make no comparison and return 0.
> 
> Of course reviews greatly appreciated.  Thanks!

Hi Mike,

Thanks for this new version.
The whole series of patches looks OK to me, except for one small glitch:
'mtd->bitflip_threshold' can be customized by the driver, but in that case it is not
propagated to the slave partition devices (the same way 'ecc_strength' is propagated).
Something like this is missing:

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index d6321f6..d518e4d 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -517,6 +517,8 @@ static struct mtd_part *allocate_partition(struct mtd_info *master,
 
        slave->mtd.ecclayout = master->ecclayout;
        slave->mtd.ecc_strength = master->ecc_strength;
+       slave->mtd.bitflip_threshold = master->bitflip_threshold;
+
        if (master->_block_isbad) {
                uint64_t offs = 0;

Apart from that, I was able to run a few tests on a BeagleBoard revC3 with simulated
bitflips, dropping my own error concealment code in favor of your patch. I did the
following checks:
 - when errors_corrected < bitflip_threshold, check that mtd_read() returns 0
 - when errors_corrected >= bitflip_threshold, check that mtd_read() returns -EUCLEAN
 - check if driver customization of bitflip_threshold works
 - check if per-partition customization of bitflip_threshold through sysfs works
Everything worked as expected.

BR,
--
Ivan

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH 6/7] mtd: nand: sanity checks of ecc strength in nand_scan_tail()
  2012-04-25  4:09   ` Brian Norris
@ 2012-04-25 15:08     ` Mike Dunn
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Dunn @ 2012-04-25 15:08 UTC (permalink / raw)
  To: Brian Norris; +Cc: linux-mtd

On 04/24/2012 09:09 PM, Brian Norris wrote:
> 
> I think you only need this last check (under ECC_HW_SYNDROME), since
> the ECC_HW and ECC_HW_OOB_FIRST cases necessarily fall through to
> ECC_HW_SYNDROME case. (Note the lack of 'break;' statements in the
> first two 'case's.)


Oops... you're right, I did miss that.  This should have been a much simpler
patch.  Thanks!

Mike

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 5/7] mtd: nand: read_page() returns max_bitflips
  2012-04-24 19:45   ` Scott Wood
@ 2012-04-25 15:35     ` Mike Dunn
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Dunn @ 2012-04-25 15:35 UTC (permalink / raw)
  To: Scott Wood
  Cc: Nick Spence, linux-mtd, Chuanxiao Dong, Jamie Iles, Axel Lin,
	Roy Zang, Prabhakar Kushwaha

On 04/24/2012 12:45 PM, Scott Wood wrote:
> 
> I'd prefer to clear max_bitflips before this if-block, so that we can
> rely on max_bitflips being zero when ECC wasn't requested.
> 
> Otherwise ACK the eLBC and IFC changes.


Thanks for the ACK Scott.  I'll include your preference in the next version of
the patches.

Mike

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 0/7] mtd: Change meaning of -EUCLEAN return code on reads
  2012-04-25 11:23 ` [PATCH 0/7] mtd: Change meaning of -EUCLEAN return code on reads Ivan Djelic
@ 2012-04-25 15:56   ` Mike Dunn
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Dunn @ 2012-04-25 15:56 UTC (permalink / raw)
  To: Ivan Djelic; +Cc: linux-mtd

On 04/25/2012 04:23 AM, Ivan Djelic wrote:
> 
> Thanks for this new version.
> The whole series of patches looks OK to me, except for one small glitch:
> 'mtd->bitflip_threshold' can be customized by the driver, but in that case it is not
> propagated to the slave partition devices (the same way 'ecc_strength' is propagated).
> Something like this is missing:
> 
> diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
> index d6321f6..d518e4d 100644
> --- a/drivers/mtd/mtdpart.c
> +++ b/drivers/mtd/mtdpart.c
> @@ -517,6 +517,8 @@ static struct mtd_part *allocate_partition(struct mtd_info *master,
>  
>         slave->mtd.ecclayout = master->ecclayout;
>         slave->mtd.ecc_strength = master->ecc_strength;
> +       slave->mtd.bitflip_threshold = master->bitflip_threshold;
> +
>         if (master->_block_isbad) {
>                 uint64_t offs = 0;
> 


Yes, you're right.  Without this it breaks if the driver sets bitflip_threshold.


> Apart from that, I was able to run a few tests on a BeagleBoard revC3 with simulated
> bitflips, dropping my own error concealment code in favor of your patch. I did the
> following checks:
>  - when errors_corrected < bitflip_threshold, check that mtd_read() returns 0
>  - when errors_corrected >= bitflip_threshold, check that mtd_read() returns -EUCLEAN
>  - check if driver customization of bitflip_threshold works


I guess I should have performed this test too :)


>  - check if per-partition customization of bitflip_threshold through sysfs works
> Everything worked as expected.


Thanks once again Ivan.  I'll follow up with a new version of the patch set in a
day or too.

Mike

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 7/7] mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN
  2012-04-24 19:18 ` [PATCH 7/7] mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN Mike Dunn
  2012-04-25 10:14   ` Shmulik Ladkani
@ 2012-04-25 18:27   ` Robert Jarzmik
  2012-04-25 19:13     ` Mike Dunn
  1 sibling, 1 reply; 26+ messages in thread
From: Robert Jarzmik @ 2012-04-25 18:27 UTC (permalink / raw)
  To: Mike Dunn; +Cc: linux-mtd

Mike Dunn <mikedunn@newsguy.com> writes:

One little trick with docg3 patch part:
> diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
> index 3414031..7644d59 100644
> --- a/drivers/mtd/devices/docg3.c
> +++ b/drivers/mtd/devices/docg3.c
> @@ -948,7 +949,8 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
>  			}
>  			if (ret > 0) {
>  				mtd->ecc_stats.corrected += ret;
> -				ret = -EUCLEAN;
> +				max_bitflips = max(max_bitflips, ret);
> +				ret = max_bitflips;
>  			}
>  		}

If you do set ret here, the next loop you'll do in the following statement
"	while (!ret && (len > 0 || ooblen > 0)) {" will exit because ret is not
0.

I think you should change :
>- 	while (!ret && (len > 0 || ooblen > 0)) {" will exit because ret is not
into
>- 	while (ret >= 0 && (len > 0 || ooblen > 0)) {".

With that change, please add my:
Acked-by: Robert Jarzmik <robert.jarzmik@free.fr>

Cheers.

-- 
Robert

PS: It's really a great work that bitflip serie

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 7/7] mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN
  2012-04-25 18:27   ` Robert Jarzmik
@ 2012-04-25 19:13     ` Mike Dunn
  2012-04-29 19:24       ` Artem Bityutskiy
  0 siblings, 1 reply; 26+ messages in thread
From: Mike Dunn @ 2012-04-25 19:13 UTC (permalink / raw)
  To: Robert Jarzmik; +Cc: linux-mtd

Thanks for the review Robert.

On 04/25/2012 11:27 AM, Robert Jarzmik wrote:
> 
> I think you should change :
>> - 	while (!ret && (len > 0 || ooblen > 0)) {" will exit because ret is not
> into
>> - 	while (ret >= 0 && (len > 0 || ooblen > 0)) {".
> 
> With that change, please add my:
> Acked-by: Robert Jarzmik <robert.jarzmik@free.fr>


In my exuberance, I prematurely sent the next version of the whole set.  Artem,
Robert's requested change is in patch 7/7.  If no other problems come to light,
maybe you could consider merging the first 6?  Then I only need to prepare a
corrected version of patch 7.

Thanks,
Mike

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 7/7] mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN
  2012-04-25 19:13     ` Mike Dunn
@ 2012-04-29 19:24       ` Artem Bityutskiy
  2012-04-30 19:55         ` Mike Dunn
  0 siblings, 1 reply; 26+ messages in thread
From: Artem Bityutskiy @ 2012-04-29 19:24 UTC (permalink / raw)
  To: Mike Dunn; +Cc: linux-mtd, Robert Jarzmik

[-- Attachment #1: Type: text/plain, Size: 929 bytes --]

On Wed, 2012-04-25 at 12:13 -0700, Mike Dunn wrote:
> Thanks for the review Robert.
> 
> On 04/25/2012 11:27 AM, Robert Jarzmik wrote:
> > 
> > I think you should change :
> >> - 	while (!ret && (len > 0 || ooblen > 0)) {" will exit because ret is not
> > into
> >> - 	while (ret >= 0 && (len > 0 || ooblen > 0)) {".
> > 
> > With that change, please add my:
> > Acked-by: Robert Jarzmik <robert.jarzmik@free.fr>
> 
> 
> In my exuberance, I prematurely sent the next version of the whole set.  Artem,
> Robert's requested change is in patch 7/7.  If no other problems come to light,
> maybe you could consider merging the first 6?  Then I only need to prepare a
> corrected version of patch 7.

Pushed the series to l2-mtd.git, thanks! You can send the newer version
and I'll put it instead of the older one. Do not forget to add
Acked-by's when you re-send, please.

-- 
Best Regards,
Artem Bityutskiy

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 7/7] mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN
  2012-04-29 19:24       ` Artem Bityutskiy
@ 2012-04-30 19:55         ` Mike Dunn
  2012-04-30 20:31           ` Robert Jarzmik
  2012-05-01 12:20           ` Artem Bityutskiy
  0 siblings, 2 replies; 26+ messages in thread
From: Mike Dunn @ 2012-04-30 19:55 UTC (permalink / raw)
  To: Artem Bityutskiy; +Cc: linux-mtd, Robert Jarzmik

On 04/29/2012 12:24 PM, Artem Bityutskiy wrote:
> On Wed, 2012-04-25 at 12:13 -0700, Mike Dunn wrote:
>> Thanks for the review Robert.
>>
>> On 04/25/2012 11:27 AM, Robert Jarzmik wrote:
>>>
>>> I think you should change :
>>>> - 	while (!ret && (len > 0 || ooblen > 0)) {" will exit because ret is not
>>> into
>>>> - 	while (ret >= 0 && (len > 0 || ooblen > 0)) {".
>>>
>>> With that change, please add my:
>>> Acked-by: Robert Jarzmik <robert.jarzmik@free.fr>
>>
>>
>> In my exuberance, I prematurely sent the next version of the whole set.  Artem,
>> Robert's requested change is in patch 7/7.  If no other problems come to light,
>> maybe you could consider merging the first 6?  Then I only need to prepare a
>> corrected version of patch 7.
> 
> Pushed the series to l2-mtd.git, thanks! You can send the newer version
> and I'll put it instead of the older one. Do not forget to add
> Acked-by's when you re-send, please.
> 


Thanks Artem.  Since you merged all 7, the only thing remaining is the fix to
docg3 that Robert describes above.  Robert, if you would rather prepare that
patch, I defer to you.  Otherwise, I'll submit it no later than tomorrow.

Yeah, sorry Artem, I neglected to add the Acked-by's in the patches you just merged.

Mike

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 7/7] mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN
  2012-04-30 19:55         ` Mike Dunn
@ 2012-04-30 20:31           ` Robert Jarzmik
  2012-05-01 12:20           ` Artem Bityutskiy
  1 sibling, 0 replies; 26+ messages in thread
From: Robert Jarzmik @ 2012-04-30 20:31 UTC (permalink / raw)
  To: Mike Dunn; +Cc: linux-mtd, Artem Bityutskiy

Mike Dunn <mikedunn@newsguy.com> writes:

> Thanks Artem.  Since you merged all 7, the only thing remaining is the fix to
> docg3 that Robert describes above.  Robert, if you would rather prepare that
> patch, I defer to you.  Otherwise, I'll submit it no later than tomorrow.
Oh no, go ahead, you have my blessing.

> Yeah, sorry Artem, I neglected to add the Acked-by's in the patches you just
> merged.
That's your opportunity to add it :)

Cheers.

-- 
Robert

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 7/7] mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN
  2012-04-30 19:55         ` Mike Dunn
  2012-04-30 20:31           ` Robert Jarzmik
@ 2012-05-01 12:20           ` Artem Bityutskiy
  2012-05-01 17:27             ` Mike Dunn
  1 sibling, 1 reply; 26+ messages in thread
From: Artem Bityutskiy @ 2012-05-01 12:20 UTC (permalink / raw)
  To: Mike Dunn; +Cc: linux-mtd, Robert Jarzmik

[-- Attachment #1: Type: text/plain, Size: 656 bytes --]

On Mon, 2012-04-30 at 12:55 -0700, Mike Dunn wrote:
> Thanks Artem.  Since you merged all 7, the only thing remaining is the fix to
> docg3 that Robert describes above.  Robert, if you would rather prepare that
> patch, I defer to you.  Otherwise, I'll submit it no later than tomorrow.
> 
> Yeah, sorry Artem, I neglected to add the Acked-by's in the patches you just merged.

If you know that an Acked-by or Reviewed-by was missed, let me know and
I'll add the tag(s) to the patch(es). I think it is important to be
careful about the tags because people spent their time helping to
improve the patches.

-- 
Best Regards,
Artem Bityutskiy

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 7/7] mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN
  2012-05-01 12:20           ` Artem Bityutskiy
@ 2012-05-01 17:27             ` Mike Dunn
  2012-05-01 18:51               ` Shmulik Ladkani
  2012-05-02  3:59               ` Artem Bityutskiy
  0 siblings, 2 replies; 26+ messages in thread
From: Mike Dunn @ 2012-05-01 17:27 UTC (permalink / raw)
  To: Artem Bityutskiy
  Cc: linux-mtd, Shmulik Ladkani, Scott Wood, Ivan Djelic,
	Brian Norris, Robert Jarzmik

On 05/01/2012 05:20 AM, Artem Bityutskiy wrote:
> On Mon, 2012-04-30 at 12:55 -0700, Mike Dunn wrote:
>>
>> Yeah, sorry Artem, I neglected to add the Acked-by's in the patches you just merged.
> 
> If you know that an Acked-by or Reviewed-by was missed, let me know and
> I'll add the tag(s) to the patch(es). I think it is important to be
> careful about the tags because people spent their time helping to
> improve the patches.


Well, I owe a debt to several reviewers, among them Brian Norris (caught the bug
that would cause all non-ecc devices to return -EUCLEAN), Shmulik Ladkani, Ivan
Djelic (reviews and tests), Scott Wood, Robert Jarzmik, yourself, ...

As far as formal tags... maybe these, if they don't object:

mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN
5568eb3c3bb2816281b6a7c04db92434b72b1495
Tested-by: Ivan Djelic <ivan.djelic@parrot.com>

mtd: nand: read_page() returns max_bitflips
6bf87bf989bfdfc78fb2c5cd55de4bab9b572992
Acked-by (freescale changes): Scott Wood <scottwood@freescale.com>

If the others feel a tag credit is appropriate, I certainly don't mind.

Thanks,
Mike

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 7/7] mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN
  2012-05-01 17:27             ` Mike Dunn
@ 2012-05-01 18:51               ` Shmulik Ladkani
  2012-05-02  3:59               ` Artem Bityutskiy
  1 sibling, 0 replies; 26+ messages in thread
From: Shmulik Ladkani @ 2012-05-01 18:51 UTC (permalink / raw)
  To: Artem Bityutskiy
  Cc: Mike Dunn, linux-mtd, Scott Wood, Ivan Djelic, Brian Norris,
	Robert Jarzmik

On Tue, 01 May 2012 10:27:14 -0700 Mike Dunn <mikedunn@newsguy.com> wrote:
> On 05/01/2012 05:20 AM, Artem Bityutskiy wrote:
> > On Mon, 2012-04-30 at 12:55 -0700, Mike Dunn wrote:
> >>
> >> Yeah, sorry Artem, I neglected to add the Acked-by's in the patches you just merged.
> > 
> > If you know that an Acked-by or Reviewed-by was missed, let me know and
> > I'll add the tag(s) to the patch(es). I think it is important to be
> > careful about the tags because people spent their time helping to
> > improve the patches.
> 
> 
> Well, I owe a debt to several reviewers, among them Brian Norris (caught the bug
> that would cause all non-ecc devices to return -EUCLEAN), Shmulik Ladkani, Ivan
> Djelic (reviews and tests), Scott Wood, Robert Jarzmik, yourself, ...
> 
> As far as formal tags... maybe these, if they don't object:
> 
> mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN
> 5568eb3c3bb2816281b6a7c04db92434b72b1495
> Tested-by: Ivan Djelic <ivan.djelic@parrot.com>
> 
> mtd: nand: read_page() returns max_bitflips
> 6bf87bf989bfdfc78fb2c5cd55de4bab9b572992
> Acked-by (freescale changes): Scott Wood <scottwood@freescale.com>
> 
> If the others feel a tag credit is appropriate, I certainly don't mind.

On a side note (sorry for the off-topic post):

It seems the use of the formal tags is somewhat limited.

AFAIU, Acked-by is supposed to be specified by the maintainer or major
contributor, the one in charge of the code affected, and it could
be specified to just a part of the patch.

OTOH Reviewed-by can be specified by any interested reviewer, as an
indication that the entire patch has been reviewed.

However when patches get partially reviewed by interested parties, no
formal tag is suitable.

Regards,
Shmulik

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2/7] mtd: nand: fix incorrect ecc strength values
  2012-04-24 19:18 ` [PATCH 2/7] mtd: nand: fix incorrect ecc strength values Mike Dunn
@ 2012-05-01 19:07   ` Jiandong Zheng
  0 siblings, 0 replies; 26+ messages in thread
From: Jiandong Zheng @ 2012-05-01 19:07 UTC (permalink / raw)
  To: Mike Dunn
  Cc: Lars-Peter Clausen, linux-mtd, Scott Branden, Prabhakar Kushwaha

On 4/24/2012 12:18 PM, Mike Dunn wrote:
> This fixes a couple of ecc strength values for which I earlier made conservative
> guesses, but whose correct values were later determined [1] (thanks Ivan).  Also
> sets strength for fsl_ifc_nand, which was merged to mainline after the original
> patch that set the strength for all drivers.
>
> [1] http://lists.infradead.org/pipermail/linux-mtd/2012-March/040325.html
>
> Signed-off-by: Mike Dunn<mikedunn@newsguy.com>
> ---
>   drivers/mtd/nand/bcm_umi_nand.c |    7 +------
>   drivers/mtd/nand/fsl_ifc_nand.c |    1 +
>   drivers/mtd/nand/jz4740_nand.c  |    6 +-----
>   3 files changed, 3 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/mtd/nand/bcm_umi_nand.c b/drivers/mtd/nand/bcm_umi_nand.c
> index 6908cdd..7134adf 100644
> --- a/drivers/mtd/nand/bcm_umi_nand.c
> +++ b/drivers/mtd/nand/bcm_umi_nand.c
> @@ -476,12 +476,7 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev)
>   		this->badblock_pattern =&largepage_bbt;
>   	}
>
> -	/*
> -	 * FIXME: ecc strength value of 6 bits per 512 bytes of data is a
> -	 * conservative guess, given 13 ecc bytes and using bch alg.
> -	 * (Assume Galois field order m=15 to allow a margin of error.)
> -	 */
> -	this->ecc.strength = 6;
> +	this->ecc.strength = 8;
>
>   #endif
>
>
Acked-by: Jiandong Zheng <jdzheng@broadcom.com>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 7/7] mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN
  2012-05-01 17:27             ` Mike Dunn
  2012-05-01 18:51               ` Shmulik Ladkani
@ 2012-05-02  3:59               ` Artem Bityutskiy
  1 sibling, 0 replies; 26+ messages in thread
From: Artem Bityutskiy @ 2012-05-02  3:59 UTC (permalink / raw)
  To: Mike Dunn
  Cc: linux-mtd, Shmulik Ladkani, Scott Wood, Ivan Djelic,
	Brian Norris, Robert Jarzmik

[-- Attachment #1: Type: text/plain, Size: 1759 bytes --]

On Tue, 2012-05-01 at 10:27 -0700, Mike Dunn wrote:
> On 05/01/2012 05:20 AM, Artem Bityutskiy wrote:
> > On Mon, 2012-04-30 at 12:55 -0700, Mike Dunn wrote:
> >>
> >> Yeah, sorry Artem, I neglected to add the Acked-by's in the patches you just merged.
> > 
> > If you know that an Acked-by or Reviewed-by was missed, let me know and
> > I'll add the tag(s) to the patch(es). I think it is important to be
> > careful about the tags because people spent their time helping to
> > improve the patches.
> 
> 
> Well, I owe a debt to several reviewers, among them Brian Norris (caught the bug
> that would cause all non-ecc devices to return -EUCLEAN), Shmulik Ladkani, Ivan
> Djelic (reviews and tests), Scott Wood, Robert Jarzmik, yourself, ...
> 
> As far as formal tags... maybe these, if they don't object:

How it usually goes - if the person sends a "formal" acked-by or some
other tag which can be copy-pasted, then he cares and wants the tag to
go in with the patch. But if the person just comments on the patch,
reviews, but does not send a "formal" tag, he does not care. In this
case you may give the person a credit in free form in the commit message
optionally, if you feel very grateful.

IOW, if we missed someone's "formal" tag - let's add it - I shamelessly
rebase my tree anyway, under excuse of "I am not the maintainer" :-)

> mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN
> 5568eb3c3bb2816281b6a7c04db92434b72b1495
> Tested-by: Ivan Djelic <ivan.djelic@parrot.com>
> 
> mtd: nand: read_page() returns max_bitflips
> 6bf87bf989bfdfc78fb2c5cd55de4bab9b572992
> Acked-by (freescale changes): Scott Wood <scottwood@freescale.com>

OK, thanks.

-- 
Best Regards,
Artem Bityutskiy

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2012-05-02  4:02 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-24 19:18 [PATCH 0/7] mtd: Change meaning of -EUCLEAN return code on reads Mike Dunn
2012-04-24 19:18 ` [PATCH 1/7] mtd: ecc_strength is at ecc step granularity Mike Dunn
2012-04-24 19:18 ` [PATCH 2/7] mtd: nand: fix incorrect ecc strength values Mike Dunn
2012-05-01 19:07   ` Jiandong Zheng
2012-04-24 19:18 ` [PATCH 3/7] mtd: expose ecc_strength through sysfs Mike Dunn
2012-04-24 19:18 ` [PATCH 4/7] mtd: bitflip threshold added to mtd_info and sysfs Mike Dunn
2012-04-24 19:18 ` [PATCH 5/7] mtd: nand: read_page() returns max_bitflips Mike Dunn
2012-04-24 19:45   ` Scott Wood
2012-04-25 15:35     ` Mike Dunn
2012-04-25  9:20   ` Shmulik Ladkani
2012-04-24 19:18 ` [PATCH 6/7] mtd: nand: sanity checks of ecc strength in nand_scan_tail() Mike Dunn
2012-04-25  4:09   ` Brian Norris
2012-04-25 15:08     ` Mike Dunn
2012-04-24 19:18 ` [PATCH 7/7] mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN Mike Dunn
2012-04-25 10:14   ` Shmulik Ladkani
2012-04-25 18:27   ` Robert Jarzmik
2012-04-25 19:13     ` Mike Dunn
2012-04-29 19:24       ` Artem Bityutskiy
2012-04-30 19:55         ` Mike Dunn
2012-04-30 20:31           ` Robert Jarzmik
2012-05-01 12:20           ` Artem Bityutskiy
2012-05-01 17:27             ` Mike Dunn
2012-05-01 18:51               ` Shmulik Ladkani
2012-05-02  3:59               ` Artem Bityutskiy
2012-04-25 11:23 ` [PATCH 0/7] mtd: Change meaning of -EUCLEAN return code on reads Ivan Djelic
2012-04-25 15:56   ` Mike Dunn

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.