diff options
author | Brian Norris <computersforpeace@gmail.com> | 2012-06-22 19:35:39 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2012-09-29 09:50:50 -0400 |
commit | e47f68587b8255410e79166cbdecae290ca8a84e (patch) | |
tree | 6339788ba16b9fe05b0ce7dfcece57748aed4e07 | |
parent | 8bb8b85f6732ed579222a465d0749f66a3cace4d (diff) |
mtd: check for max_bitflips in mtd_read_oob()
mtd_read_oob() has some unexpected similarities to mtd_read(). For
instance, when ops->datbuf != NULL, nand_base.c might return max_bitflips;
however, when ops->datbuf == NULL, nand_base's code potentially could
return -EUCLEAN (no in-tree drivers do this yet). In any case where the
driver might return max_bitflips, we should translate this into an
appropriate return code using the bitflip_threshold.
Essentially, mtd_read_oob() duplicates the logic from mtd_read().
This prevents users of mtd_read_oob() from receiving a positive return
value (i.e., from max_bitflips) and interpreting it as an unknown error.
Artem: amend comments.
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Reviewed-by: Mike Dunn <mikedunn@newsguy.com>
Reviewed-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
-rw-r--r-- | drivers/mtd/mtdcore.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index fcfce24f87d1..ec794a72975d 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c | |||
@@ -860,10 +860,22 @@ EXPORT_SYMBOL_GPL(mtd_panic_write); | |||
860 | 860 | ||
861 | int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) | 861 | int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) |
862 | { | 862 | { |
863 | int ret_code; | ||
863 | ops->retlen = ops->oobretlen = 0; | 864 | ops->retlen = ops->oobretlen = 0; |
864 | if (!mtd->_read_oob) | 865 | if (!mtd->_read_oob) |
865 | return -EOPNOTSUPP; | 866 | return -EOPNOTSUPP; |
866 | return mtd->_read_oob(mtd, from, ops); | 867 | /* |
868 | * In cases where ops->datbuf != NULL, mtd->_read_oob() has semantics | ||
869 | * similar to mtd->_read(), returning a non-negative integer | ||
870 | * representing max bitflips. In other cases, mtd->_read_oob() may | ||
871 | * return -EUCLEAN. In all cases, perform similar logic to mtd_read(). | ||
872 | */ | ||
873 | ret_code = mtd->_read_oob(mtd, from, ops); | ||
874 | if (unlikely(ret_code < 0)) | ||
875 | return ret_code; | ||
876 | if (mtd->ecc_strength == 0) | ||
877 | return 0; /* device lacks ecc */ | ||
878 | return ret_code >= mtd->bitflip_threshold ? -EUCLEAN : 0; | ||
867 | } | 879 | } |
868 | EXPORT_SYMBOL_GPL(mtd_read_oob); | 880 | EXPORT_SYMBOL_GPL(mtd_read_oob); |
869 | 881 | ||