Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 310207
b: refs/heads/master
c: d062d4e
h: refs/heads/master
i:
  310205: 25d8896
  310203: 513dc9e
  310199: bd1497a
  310191: 552082c
  310175: ce161ee
  310143: fa6aa7d
v: v3
  • Loading branch information
Mike Dunn authored and David Woodhouse committed May 14, 2012
1 parent c6216f4 commit d3a6959
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a9b672e82bca47bf2b37ee869b8095000cf3ca88
refs/heads/master: d062d4ede877fcd2ecc4c6262abad09a6f32950a
36 changes: 36 additions & 0 deletions trunk/Documentation/ABI/testing/sysfs-class-mtd
Original file line number Diff line number Diff line change
Expand Up @@ -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.
33 changes: 33 additions & 0 deletions trunk/drivers/mtd/mtdcore.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
};

Expand Down Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/mtd/mtdpart.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
9 changes: 9 additions & 0 deletions trunk/include/linux/mtd/mtd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit d3a6959

Please sign in to comment.