aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-class-mtd36
-rw-r--r--drivers/mtd/mtdcore.c33
-rw-r--r--drivers/mtd/mtdpart.c2
-rw-r--r--include/linux/mtd/mtd.h9
4 files changed, 80 insertions, 0 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-mtd b/Documentation/ABI/testing/sysfs-class-mtd
index 43d18180b46e..78835080856a 100644
--- a/Documentation/ABI/testing/sysfs-class-mtd
+++ b/Documentation/ABI/testing/sysfs-class-mtd
@@ -135,3 +135,39 @@ Description:
135 have multiple ecc steps within each writesize region. 135 have multiple ecc steps within each writesize region.
136 136
137 In the case of devices lacking any ECC capability, it is 0. 137 In the case of devices lacking any ECC capability, it is 0.
138
139What: /sys/class/mtd/mtdX/bitflip_threshold
140Date: April 2012
141KernelVersion: 3.4
142Contact: linux-mtd@lists.infradead.org
143Description:
144 This allows the user to examine and adjust the criteria by which
145 mtd returns -EUCLEAN from mtd_read(). If the maximum number of
146 bit errors that were corrected on any single region comprising
147 an ecc step (as reported by the driver) equals or exceeds this
148 value, -EUCLEAN is returned. Otherwise, absent an error, 0 is
149 returned. Higher layers (e.g., UBI) use this return code as an
150 indication that an erase block may be degrading and should be
151 scrutinized as a candidate for being marked as bad.
152
153 The initial value may be specified by the flash device driver.
154 If not, then the default value is ecc_strength.
155
156 The introduction of this feature brings a subtle change to the
157 meaning of the -EUCLEAN return code. Previously, it was
158 interpreted to mean simply "one or more bit errors were
159 corrected". Its new interpretation can be phrased as "a
160 dangerously high number of bit errors were corrected on one or
161 more regions comprising an ecc step". The precise definition of
162 "dangerously high" can be adjusted by the user with
163 bitflip_threshold. Users are discouraged from doing this,
164 however, unless they know what they are doing and have intimate
165 knowledge of the properties of their device. Broadly speaking,
166 bitflip_threshold should be low enough to detect genuine erase
167 block degradation, but high enough to avoid the consequences of
168 a persistent return value of -EUCLEAN on devices where sticky
169 bitflips occur. Note that if bitflip_threshold exceeds
170 ecc_strength, -EUCLEAN is never returned by the read functions.
171
172 This is generally applicable only to NAND flash devices with ECC
173 capability. It is ignored on devices lacking ECC capability.
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 090e849d3dcd..6a7cba1e24e6 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,
259} 259}
260static DEVICE_ATTR(ecc_strength, S_IRUGO, mtd_ecc_strength_show, NULL); 260static DEVICE_ATTR(ecc_strength, S_IRUGO, mtd_ecc_strength_show, NULL);
261 261
262static ssize_t mtd_bitflip_threshold_show(struct device *dev,
263 struct device_attribute *attr,
264 char *buf)
265{
266 struct mtd_info *mtd = dev_get_drvdata(dev);
267
268 return snprintf(buf, PAGE_SIZE, "%u\n", mtd->bitflip_threshold);
269}
270
271static ssize_t mtd_bitflip_threshold_store(struct device *dev,
272 struct device_attribute *attr,
273 const char *buf, size_t count)
274{
275 struct mtd_info *mtd = dev_get_drvdata(dev);
276 unsigned int bitflip_threshold;
277 int retval;
278
279 retval = kstrtouint(buf, 0, &bitflip_threshold);
280 if (retval)
281 return retval;
282
283 mtd->bitflip_threshold = bitflip_threshold;
284 return count;
285}
286static DEVICE_ATTR(bitflip_threshold, S_IRUGO | S_IWUSR,
287 mtd_bitflip_threshold_show,
288 mtd_bitflip_threshold_store);
289
262static struct attribute *mtd_attrs[] = { 290static struct attribute *mtd_attrs[] = {
263 &dev_attr_type.attr, 291 &dev_attr_type.attr,
264 &dev_attr_flags.attr, 292 &dev_attr_flags.attr,
@@ -270,6 +298,7 @@ static struct attribute *mtd_attrs[] = {
270 &dev_attr_numeraseregions.attr, 298 &dev_attr_numeraseregions.attr,
271 &dev_attr_name.attr, 299 &dev_attr_name.attr,
272 &dev_attr_ecc_strength.attr, 300 &dev_attr_ecc_strength.attr,
301 &dev_attr_bitflip_threshold.attr,
273 NULL, 302 NULL,
274}; 303};
275 304
@@ -332,6 +361,10 @@ int add_mtd_device(struct mtd_info *mtd)
332 mtd->index = i; 361 mtd->index = i;
333 mtd->usecount = 0; 362 mtd->usecount = 0;
334 363
364 /* default value if not set by driver */
365 if (mtd->bitflip_threshold == 0)
366 mtd->bitflip_threshold = mtd->ecc_strength;
367
335 if (is_power_of_2(mtd->erasesize)) 368 if (is_power_of_2(mtd->erasesize))
336 mtd->erasesize_shift = ffs(mtd->erasesize) - 1; 369 mtd->erasesize_shift = ffs(mtd->erasesize) - 1;
337 else 370 else
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 9651c06de0a9..ec75d44e0253 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,
517 517
518 slave->mtd.ecclayout = master->ecclayout; 518 slave->mtd.ecclayout = master->ecclayout;
519 slave->mtd.ecc_strength = master->ecc_strength; 519 slave->mtd.ecc_strength = master->ecc_strength;
520 slave->mtd.bitflip_threshold = master->bitflip_threshold;
521
520 if (master->_block_isbad) { 522 if (master->_block_isbad) {
521 uint64_t offs = 0; 523 uint64_t offs = 0;
522 524
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index cd0119d19cd9..63dadc0dfb62 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -157,6 +157,15 @@ struct mtd_info {
157 unsigned int erasesize_mask; 157 unsigned int erasesize_mask;
158 unsigned int writesize_mask; 158 unsigned int writesize_mask;
159 159
160 /*
161 * read ops return -EUCLEAN if max number of bitflips corrected on any
162 * one region comprising an ecc step equals or exceeds this value.
163 * Settable by driver, else defaults to ecc_strength. User can override
164 * in sysfs. N.B. The meaning of the -EUCLEAN return code has changed;
165 * see Documentation/ABI/testing/sysfs-class-mtd for more detail.
166 */
167 unsigned int bitflip_threshold;
168
160 // Kernel-only stuff starts here. 169 // Kernel-only stuff starts here.
161 const char *name; 170 const char *name;
162 int index; 171 int index;