[PATCH 3/4] MTD: euclean_threshold added to mtd_info and sysfs

Mike Dunn mikedunn at newsguy.com
Sun Mar 11 17:21:12 EDT 2012


The element 'euclean_threshold' is added to struct mtd_info.  If the driver
leaves this uninitialized, mtd sets it to ecc_strength when the device or
partition is registered.  This element is also exposed for reading and writing
from userspace through sysfs.

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

An afterthought... ecc_strength should probably also be exposed through syfs as
a r/o value.  Ioctls for querying both these values could also be added to
mtdchar.

 Documentation/ABI/testing/sysfs-class-mtd |   23 ++++++++++++++++++++
 drivers/mtd/mtdcore.c                     |   33 +++++++++++++++++++++++++++++
 include/linux/mtd/mtd.h                   |    7 ++++++
 3 files changed, 63 insertions(+), 0 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-class-mtd b/Documentation/ABI/testing/sysfs-class-mtd
index 4d55a18..896a671 100644
--- a/Documentation/ABI/testing/sysfs-class-mtd
+++ b/Documentation/ABI/testing/sysfs-class-mtd
@@ -123,3 +123,26 @@ Description:
 		half page, or a quarter page).
 
 		In the case of ECC NOR, it is the ECC block size.
+
+What:		/sys/class/mtd/mtdX/euclean_threshold
+Date:		March 2012
+KernelVersion:	3.3.1
+Contact:	linux-mtd at lists.infradead.org
+Description:
+		This allows the user to examine and adjust the criteria by which
+		mtd returns -EUCLEAN from mtd_read() and mtd_read_oob().  If the
+		maximum number of bit errors corrected on any single writesize
+		during the read operation (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 set by the flash device driver.  If
+		not, then it is equal to the maximum number of bit errors that
+		the device's ECC facility is capable of correcting per
+		writesize.  Users who wish to be more paranoid about data
+		integrity can lower the value.
+
+		This is generally applicable only to NAND flash devices with
+		ECC capability.
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index b274fdf..5bbd717 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -250,6 +250,34 @@ static ssize_t mtd_name_show(struct device *dev,
 }
 static DEVICE_ATTR(name, S_IRUGO, mtd_name_show, NULL);
 
+static ssize_t mtd_euclean_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->euclean_threshold);
+}
+
+static ssize_t mtd_euclean_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 euclean_threshold;
+	int retval;
+
+	retval = kstrtouint(buf, 0, &euclean_threshold);
+	if (retval)
+		return retval;
+
+	mtd->euclean_threshold = euclean_threshold;
+	return count;
+}
+static DEVICE_ATTR(euclean_threshold, S_IRUGO | S_IWUSR,
+		   mtd_euclean_threshold_show,
+		   mtd_euclean_threshold_store);
+
 static struct attribute *mtd_attrs[] = {
 	&dev_attr_type.attr,
 	&dev_attr_flags.attr,
@@ -260,6 +288,7 @@ static struct attribute *mtd_attrs[] = {
 	&dev_attr_oobsize.attr,
 	&dev_attr_numeraseregions.attr,
 	&dev_attr_name.attr,
+	&dev_attr_euclean_threshold.attr,
 	NULL,
 };
 
@@ -322,6 +351,10 @@ int add_mtd_device(struct mtd_info *mtd)
 	mtd->index = i;
 	mtd->usecount = 0;
 
+	/* default value if not set by driver */
+	if (mtd->euclean_threshold == 0)
+		mtd->euclean_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 cf5ea8c..20b5c40 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -157,6 +157,13 @@ struct mtd_info {
 	unsigned int erasesize_mask;
 	unsigned int writesize_mask;
 
+	/*
+	 * read ops return -EUCLEAN if max number of bitflips corrected on any
+	 * one writesize region equals or exceeds this value.  Settable by
+	 * driver, else defaults to ecc_strength.  User can override in sysfs.
+	 */
+	unsigned int euclean_threshold;
+
 	// Kernel-only stuff starts here.
 	const char *name;
 	int index;
-- 
1.7.3.4




More information about the linux-mtd mailing list