diff options
author | Boris Brezillon <boris.brezillon@bootlin.com> | 2018-12-20 15:13:20 +0100 |
---|---|---|
committer | Boris Brezillon <bbrezillon@kernel.org> | 2019-01-16 20:32:17 +0100 |
commit | 2431c4f5b46c32c4ac495456b1ef4ce59c0bb85d (patch) | |
tree | b886405413cd01f3ea774d02fde9a2be3820fb8c | |
parent | mtd: lpddr: Use struct_size() in kzalloc() (diff) | |
download | linux-2431c4f5b46c32c4ac495456b1ef4ce59c0bb85d.tar.xz linux-2431c4f5b46c32c4ac495456b1ef4ce59c0bb85d.zip |
mtd: Implement mtd_{read,write}() as wrappers around mtd_{read,write}_oob()
mtd_{read,write}_oob() already take care of checking the params and
calling ->_{read,write}() or ->_{read,write}_oob() based on the
request and the operations supported by the MTD device.
No need to duplicate the logic, we can simply implement
mtd_{read,write}() as wrappers around mtd_{read,write}_oob().
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Boris Brezillon <bbrezillon@kernel.org>
-rw-r--r-- | drivers/mtd/mtdcore.c | 75 |
1 files changed, 24 insertions, 51 deletions
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 21e3cdc04036..d5a7fc6ea3f3 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -559,6 +559,14 @@ int add_mtd_device(struct mtd_info *mtd) BUG_ON(mtd->writesize == 0); + /* + * MTD drivers should implement ->_{write,read}() or + * ->_{write,read}_oob(), but not both. + */ + if (WARN_ON((mtd->_write && mtd->_write_oob) || + (mtd->_read && mtd->_read_oob))) + return -EINVAL; + if (WARN_ON((!mtd->erasesize || !mtd->_erase) && !(mtd->flags & MTD_NO_ERASE))) return -EINVAL; @@ -1089,67 +1097,32 @@ 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; + struct mtd_oob_ops ops = { + .len = len, + .datbuf = buf, + }; + int ret; - ledtrig_mtd_activity(); - /* - * 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). - */ - if (mtd->_read) { - ret_code = mtd->_read(mtd, from, len, retlen, buf); - } else if (mtd->_read_oob) { - struct mtd_oob_ops ops = { - .len = len, - .datbuf = buf, - }; - - ret_code = mtd->_read_oob(mtd, from, &ops); - *retlen = ops.retlen; - } else { - return -ENOTSUPP; - } + ret = mtd_read_oob(mtd, from, &ops); + *retlen = ops.retlen; - if (unlikely(ret_code < 0)) - return ret_code; - if (mtd->ecc_strength == 0) - return 0; /* device lacks ecc */ - return ret_code >= mtd->bitflip_threshold ? -EUCLEAN : 0; + return ret; } EXPORT_SYMBOL_GPL(mtd_read); int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { - *retlen = 0; - if (to < 0 || to >= mtd->size || len > mtd->size - to) - return -EINVAL; - if ((!mtd->_write && !mtd->_write_oob) || - !(mtd->flags & MTD_WRITEABLE)) - return -EROFS; - if (!len) - return 0; - ledtrig_mtd_activity(); - - if (!mtd->_write) { - struct mtd_oob_ops ops = { - .len = len, - .datbuf = (u8 *)buf, - }; - int ret; + struct mtd_oob_ops ops = { + .len = len, + .datbuf = (u8 *)buf, + }; + int ret; - ret = mtd->_write_oob(mtd, to, &ops); - *retlen = ops.retlen; - return ret; - } + ret = mtd_write_oob(mtd, to, &ops); + *retlen = ops.retlen; - return mtd->_write(mtd, to, len, retlen, buf); + return ret; } EXPORT_SYMBOL_GPL(mtd_write); |