9
0
Fork 0

mtd: introduce mtd_read_oob and mtd_write_oob

Directly copied from the Kernel as of 3.11-rc1

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
Sascha Hauer 2013-07-18 15:07:42 +02:00
parent d155610821
commit 69f3d6c93b
4 changed files with 38 additions and 4 deletions

View File

@ -327,6 +327,27 @@ int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
return mtd->erase(mtd, instr);
}
int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
{
int ret_code;
ops->retlen = ops->oobretlen = 0;
if (!mtd->read_oob)
return -EOPNOTSUPP;
/*
* In cases where ops->datbuf != NULL, mtd->_read_oob() has semantics
* similar to mtd->_read(), returning a non-negative integer
* representing max bitflips. In other cases, mtd->_read_oob() may
* return -EUCLEAN. In all cases, perform similar logic to mtd_read().
*/
ret_code = mtd->read_oob(mtd, from, ops);
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;
}
static struct file_operations mtd_ops = {
.read = mtd_op_read,
#ifdef CONFIG_MTD_WRITE

View File

@ -56,7 +56,7 @@ static ssize_t mtd_op_read_oob(struct cdev *cdev, void *buf, size_t count,
ops.len = mtd->oobsize;
offset /= mtd->oobsize;
ret = mtd->read_oob(mtd, offset * mtd->writesize, &ops);
ret = mtd_read_oob(mtd, offset * mtd->writesize, &ops);
if (ret)
return ret;

View File

@ -58,7 +58,7 @@
* - no actual mtd->write if done
* A second write of 512 bytes triggers:
* - copy of the 16 first bytes into writebuf
* - a mtd->write_oob() from writebuf
* - a mtd_write_oob() from writebuf
* - empty writebuf
* - copy the remaining 496 bytes into writebuf
* => write_fill = 496, write_ofs = offset + 528
@ -103,7 +103,7 @@ static ssize_t mtdraw_read_unaligned(struct mtd_info *mtd, void *dst,
ops.len = mtd->writesize;
ops.oobbuf = tmp + mtd->writesize;
ops.ooblen = mtd->oobsize;
ret = mtd->read_oob(mtd, offset, &ops);
ret = mtd_read_oob(mtd, offset, &ops);
if (ret)
goto err;
if (partial)
@ -158,7 +158,7 @@ static ssize_t mtdraw_blkwrite(struct mtd_info *mtd, const void *buf,
ops.len = mtd->writesize;
ops.oobbuf = (void *)buf + mtd->writesize;
ops.ooblen = mtd->oobsize;
ret = mtd->write_oob(mtd, offset, &ops);
ret = mtd_write_oob(mtd, offset, &ops);
if (!ret)
ret = ops.retlen + ops.oobretlen;
return ret;

View File

@ -213,6 +213,19 @@ int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
const u_char *buf);
int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops);
static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to,
struct mtd_oob_ops *ops)
{
ops->retlen = ops->oobretlen = 0;
if (!mtd->write_oob)
return -EOPNOTSUPP;
if (!(mtd->flags & MTD_WRITEABLE))
return -EROFS;
return mtd->write_oob(mtd, to, ops);
}
static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd)
{
do_div(sz, mtd->erasesize);