mtd: introduce mtd_read_oob interface
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
This commit is contained in:
parent
7ae79d7ff1
commit
fd2819bbc9
|
@ -158,7 +158,7 @@ int inftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
|
||||||
ops.oobbuf = buf;
|
ops.oobbuf = buf;
|
||||||
ops.datbuf = NULL;
|
ops.datbuf = NULL;
|
||||||
|
|
||||||
res = mtd->read_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
|
res = mtd_read_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
|
||||||
*retlen = ops.oobretlen;
|
*retlen = ops.oobretlen;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,7 +227,7 @@ static ssize_t mtdchar_read(struct file *file, char __user *buf, size_t count,
|
||||||
ops.oobbuf = NULL;
|
ops.oobbuf = NULL;
|
||||||
ops.len = len;
|
ops.len = len;
|
||||||
|
|
||||||
ret = mtd->read_oob(mtd, *ppos, &ops);
|
ret = mtd_read_oob(mtd, *ppos, &ops);
|
||||||
retlen = ops.retlen;
|
retlen = ops.retlen;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -471,7 +471,7 @@ static int mtdchar_readoob(struct file *file, struct mtd_info *mtd,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
start &= ~((uint64_t)mtd->writesize - 1);
|
start &= ~((uint64_t)mtd->writesize - 1);
|
||||||
ret = mtd->read_oob(mtd, start, &ops);
|
ret = mtd_read_oob(mtd, start, &ops);
|
||||||
|
|
||||||
if (put_user(ops.oobretlen, retp))
|
if (put_user(ops.oobretlen, retp))
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
|
|
|
@ -273,7 +273,7 @@ concat_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
|
||||||
if (from + devops.len > subdev->size)
|
if (from + devops.len > subdev->size)
|
||||||
devops.len = subdev->size - from;
|
devops.len = subdev->size - from;
|
||||||
|
|
||||||
err = subdev->read_oob(subdev, from, &devops);
|
err = mtd_read_oob(subdev, from, &devops);
|
||||||
ops->retlen += devops.retlen;
|
ops->retlen += devops.retlen;
|
||||||
ops->oobretlen += devops.oobretlen;
|
ops->oobretlen += devops.oobretlen;
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,7 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = part->master->read_oob(part->master, from + part->offset, ops);
|
res = mtd_read_oob(part->master, from + part->offset, ops);
|
||||||
if (unlikely(res)) {
|
if (unlikely(res)) {
|
||||||
if (mtd_is_bitflip(res))
|
if (mtd_is_bitflip(res))
|
||||||
mtd->ecc_stats.corrected++;
|
mtd->ecc_stats.corrected++;
|
||||||
|
|
|
@ -312,7 +312,7 @@ static int mtdswap_handle_write_error(struct mtdswap_dev *d, struct swap_eb *eb)
|
||||||
static int mtdswap_read_oob(struct mtdswap_dev *d, loff_t from,
|
static int mtdswap_read_oob(struct mtdswap_dev *d, loff_t from,
|
||||||
struct mtd_oob_ops *ops)
|
struct mtd_oob_ops *ops)
|
||||||
{
|
{
|
||||||
int ret = d->mtd->read_oob(d->mtd, from, ops);
|
int ret = mtd_read_oob(d->mtd, from, ops);
|
||||||
|
|
||||||
if (mtd_is_bitflip(ret))
|
if (mtd_is_bitflip(ret))
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -955,7 +955,7 @@ static unsigned int mtdswap_eblk_passes(struct mtdswap_dev *d,
|
||||||
|
|
||||||
pos = base;
|
pos = base;
|
||||||
for (i = 0; i < mtd_pages; i++) {
|
for (i = 0; i < mtd_pages; i++) {
|
||||||
ret = mtd->read_oob(mtd, pos, &ops);
|
ret = mtd_read_oob(mtd, pos, &ops);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
|
|
@ -317,7 +317,7 @@ static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
|
||||||
ops.len = min(len, (size_t)mtd->writesize);
|
ops.len = min(len, (size_t)mtd->writesize);
|
||||||
ops.oobbuf = buf + ops.len;
|
ops.oobbuf = buf + ops.len;
|
||||||
|
|
||||||
res = mtd->read_oob(mtd, offs, &ops);
|
res = mtd_read_oob(mtd, offs, &ops);
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
|
@ -434,7 +434,7 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
|
||||||
* Read the full oob until read_oob is fixed to handle single
|
* Read the full oob until read_oob is fixed to handle single
|
||||||
* byte reads for 16 bit buswidth.
|
* byte reads for 16 bit buswidth.
|
||||||
*/
|
*/
|
||||||
ret = mtd->read_oob(mtd, offs, &ops);
|
ret = mtd_read_oob(mtd, offs, &ops);
|
||||||
/* Ignore ECC errors when checking for BBM */
|
/* Ignore ECC errors when checking for BBM */
|
||||||
if (ret && !mtd_is_bitflip_or_eccerr(ret))
|
if (ret && !mtd_is_bitflip_or_eccerr(ret))
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -769,7 +769,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
|
||||||
/* Read oob data */
|
/* Read oob data */
|
||||||
ops.ooblen = (len >> this->page_shift) * mtd->oobsize;
|
ops.ooblen = (len >> this->page_shift) * mtd->oobsize;
|
||||||
ops.oobbuf = &buf[len];
|
ops.oobbuf = &buf[len];
|
||||||
res = mtd->read_oob(mtd, to + mtd->writesize, &ops);
|
res = mtd_read_oob(mtd, to + mtd->writesize, &ops);
|
||||||
if (res < 0 || ops.oobretlen != ops.ooblen)
|
if (res < 0 || ops.oobretlen != ops.ooblen)
|
||||||
goto outerr;
|
goto outerr;
|
||||||
|
|
||||||
|
|
|
@ -153,7 +153,7 @@ int nftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
|
||||||
ops.oobbuf = buf;
|
ops.oobbuf = buf;
|
||||||
ops.datbuf = NULL;
|
ops.datbuf = NULL;
|
||||||
|
|
||||||
res = mtd->read_oob(mtd, offs & ~mask, &ops);
|
res = mtd_read_oob(mtd, offs & ~mask, &ops);
|
||||||
*retlen = ops.oobretlen;
|
*retlen = ops.oobretlen;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -278,7 +278,7 @@ again:
|
||||||
|
|
||||||
/* Unfortunately, oob read will _always_ succeed,
|
/* Unfortunately, oob read will _always_ succeed,
|
||||||
despite card removal..... */
|
despite card removal..... */
|
||||||
ret = mtd->read_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);
|
ret = mtd_read_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);
|
||||||
|
|
||||||
/* Test for unknown errors */
|
/* Test for unknown errors */
|
||||||
if (ret != 0 && !mtd_is_bitflip_or_eccerr(ret)) {
|
if (ret != 0 && !mtd_is_bitflip_or_eccerr(ret)) {
|
||||||
|
|
|
@ -175,7 +175,7 @@ static int read_raw_oob(struct mtd_info *mtd, loff_t offs, uint8_t *buf)
|
||||||
ops.oobbuf = buf;
|
ops.oobbuf = buf;
|
||||||
ops.datbuf = NULL;
|
ops.datbuf = NULL;
|
||||||
|
|
||||||
ret = mtd->read_oob(mtd, offs, &ops);
|
ret = mtd_read_oob(mtd, offs, &ops);
|
||||||
if (ret < 0 || ops.oobretlen != OOB_SIZE)
|
if (ret < 0 || ops.oobretlen != OOB_SIZE)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
|
@ -192,7 +192,7 @@ static int verify_eraseblock(int ebnum)
|
||||||
ops.ooboffs = use_offset;
|
ops.ooboffs = use_offset;
|
||||||
ops.datbuf = NULL;
|
ops.datbuf = NULL;
|
||||||
ops.oobbuf = readbuf;
|
ops.oobbuf = readbuf;
|
||||||
err = mtd->read_oob(mtd, addr, &ops);
|
err = mtd_read_oob(mtd, addr, &ops);
|
||||||
if (err || ops.oobretlen != use_len) {
|
if (err || ops.oobretlen != use_len) {
|
||||||
printk(PRINT_PREF "error: readoob failed at %#llx\n",
|
printk(PRINT_PREF "error: readoob failed at %#llx\n",
|
||||||
(long long)addr);
|
(long long)addr);
|
||||||
|
@ -219,7 +219,7 @@ static int verify_eraseblock(int ebnum)
|
||||||
ops.ooboffs = 0;
|
ops.ooboffs = 0;
|
||||||
ops.datbuf = NULL;
|
ops.datbuf = NULL;
|
||||||
ops.oobbuf = readbuf;
|
ops.oobbuf = readbuf;
|
||||||
err = mtd->read_oob(mtd, addr, &ops);
|
err = mtd_read_oob(mtd, addr, &ops);
|
||||||
if (err || ops.oobretlen != mtd->ecclayout->oobavail) {
|
if (err || ops.oobretlen != mtd->ecclayout->oobavail) {
|
||||||
printk(PRINT_PREF "error: readoob failed at "
|
printk(PRINT_PREF "error: readoob failed at "
|
||||||
"%#llx\n", (long long)addr);
|
"%#llx\n", (long long)addr);
|
||||||
|
@ -284,7 +284,7 @@ static int verify_eraseblock_in_one_go(int ebnum)
|
||||||
ops.ooboffs = 0;
|
ops.ooboffs = 0;
|
||||||
ops.datbuf = NULL;
|
ops.datbuf = NULL;
|
||||||
ops.oobbuf = readbuf;
|
ops.oobbuf = readbuf;
|
||||||
err = mtd->read_oob(mtd, addr, &ops);
|
err = mtd_read_oob(mtd, addr, &ops);
|
||||||
if (err || ops.oobretlen != len) {
|
if (err || ops.oobretlen != len) {
|
||||||
printk(PRINT_PREF "error: readoob failed at %#llx\n",
|
printk(PRINT_PREF "error: readoob failed at %#llx\n",
|
||||||
(long long)addr);
|
(long long)addr);
|
||||||
|
@ -544,7 +544,7 @@ static int __init mtd_oobtest_init(void)
|
||||||
ops.oobbuf = readbuf;
|
ops.oobbuf = readbuf;
|
||||||
printk(PRINT_PREF "attempting to start read past end of OOB\n");
|
printk(PRINT_PREF "attempting to start read past end of OOB\n");
|
||||||
printk(PRINT_PREF "an error is expected...\n");
|
printk(PRINT_PREF "an error is expected...\n");
|
||||||
err = mtd->read_oob(mtd, addr0, &ops);
|
err = mtd_read_oob(mtd, addr0, &ops);
|
||||||
if (err) {
|
if (err) {
|
||||||
printk(PRINT_PREF "error occurred as expected\n");
|
printk(PRINT_PREF "error occurred as expected\n");
|
||||||
err = 0;
|
err = 0;
|
||||||
|
@ -588,7 +588,7 @@ static int __init mtd_oobtest_init(void)
|
||||||
ops.oobbuf = readbuf;
|
ops.oobbuf = readbuf;
|
||||||
printk(PRINT_PREF "attempting to read past end of device\n");
|
printk(PRINT_PREF "attempting to read past end of device\n");
|
||||||
printk(PRINT_PREF "an error is expected...\n");
|
printk(PRINT_PREF "an error is expected...\n");
|
||||||
err = mtd->read_oob(mtd, mtd->size - mtd->writesize, &ops);
|
err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops);
|
||||||
if (err) {
|
if (err) {
|
||||||
printk(PRINT_PREF "error occurred as expected\n");
|
printk(PRINT_PREF "error occurred as expected\n");
|
||||||
err = 0;
|
err = 0;
|
||||||
|
@ -632,7 +632,7 @@ static int __init mtd_oobtest_init(void)
|
||||||
ops.oobbuf = readbuf;
|
ops.oobbuf = readbuf;
|
||||||
printk(PRINT_PREF "attempting to read past end of device\n");
|
printk(PRINT_PREF "attempting to read past end of device\n");
|
||||||
printk(PRINT_PREF "an error is expected...\n");
|
printk(PRINT_PREF "an error is expected...\n");
|
||||||
err = mtd->read_oob(mtd, mtd->size - mtd->writesize, &ops);
|
err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops);
|
||||||
if (err) {
|
if (err) {
|
||||||
printk(PRINT_PREF "error occurred as expected\n");
|
printk(PRINT_PREF "error occurred as expected\n");
|
||||||
err = 0;
|
err = 0;
|
||||||
|
@ -698,7 +698,7 @@ static int __init mtd_oobtest_init(void)
|
||||||
ops.ooboffs = 0;
|
ops.ooboffs = 0;
|
||||||
ops.datbuf = NULL;
|
ops.datbuf = NULL;
|
||||||
ops.oobbuf = readbuf;
|
ops.oobbuf = readbuf;
|
||||||
err = mtd->read_oob(mtd, addr, &ops);
|
err = mtd_read_oob(mtd, addr, &ops);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
if (memcmp(readbuf, writebuf, mtd->ecclayout->oobavail * 2)) {
|
if (memcmp(readbuf, writebuf, mtd->ecclayout->oobavail * 2)) {
|
||||||
|
|
|
@ -74,7 +74,7 @@ static int read_eraseblock_by_page(int ebnum)
|
||||||
ops.ooboffs = 0;
|
ops.ooboffs = 0;
|
||||||
ops.datbuf = NULL;
|
ops.datbuf = NULL;
|
||||||
ops.oobbuf = oobbuf;
|
ops.oobbuf = oobbuf;
|
||||||
ret = mtd->read_oob(mtd, addr, &ops);
|
ret = mtd_read_oob(mtd, addr, &ops);
|
||||||
if ((ret && !mtd_is_bitflip(ret)) ||
|
if ((ret && !mtd_is_bitflip(ret)) ||
|
||||||
ops.oobretlen != mtd->oobsize) {
|
ops.oobretlen != mtd->oobsize) {
|
||||||
printk(PRINT_PREF "error: read oob failed at "
|
printk(PRINT_PREF "error: read oob failed at "
|
||||||
|
|
|
@ -351,9 +351,9 @@ u16 mtd_Read_Page_Main_Spare(u8 *read_data, u32 Block,
|
||||||
ops.ooblen = BTSIG_BYTES;
|
ops.ooblen = BTSIG_BYTES;
|
||||||
ops.ooboffs = 0;
|
ops.ooboffs = 0;
|
||||||
|
|
||||||
ret = spectra_mtd->read_oob(spectra_mtd,
|
ret = mtd_read_oob(spectra_mtd,
|
||||||
(Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
|
(Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
|
||||||
&ops);
|
&ops);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printk(KERN_ERR "%s failed %d\n", __func__, ret);
|
printk(KERN_ERR "%s failed %d\n", __func__, ret);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
@ -484,9 +484,9 @@ u16 mtd_Read_Page_Spare(u8 *read_data, u32 Block,
|
||||||
ops.ooblen = BTSIG_BYTES;
|
ops.ooblen = BTSIG_BYTES;
|
||||||
ops.ooboffs = 0;
|
ops.ooboffs = 0;
|
||||||
|
|
||||||
ret = spectra_mtd->read_oob(spectra_mtd,
|
ret = mtd_read_oob(spectra_mtd,
|
||||||
(Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
|
(Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
|
||||||
&ops);
|
&ops);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printk(KERN_ERR "%s failed %d\n", __func__, ret);
|
printk(KERN_ERR "%s failed %d\n", __func__, ret);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
|
|
@ -1032,7 +1032,7 @@ int jffs2_check_oob_empty(struct jffs2_sb_info *c,
|
||||||
ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
|
ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
|
||||||
ops.datbuf = NULL;
|
ops.datbuf = NULL;
|
||||||
|
|
||||||
ret = c->mtd->read_oob(c->mtd, jeb->offset, &ops);
|
ret = mtd_read_oob(c->mtd, jeb->offset, &ops);
|
||||||
if (ret || ops.oobretlen != ops.ooblen) {
|
if (ret || ops.oobretlen != ops.ooblen) {
|
||||||
printk(KERN_ERR "cannot read OOB for EB at %08x, requested %zd"
|
printk(KERN_ERR "cannot read OOB for EB at %08x, requested %zd"
|
||||||
" bytes, read %zd bytes, error %d\n",
|
" bytes, read %zd bytes, error %d\n",
|
||||||
|
@ -1075,7 +1075,7 @@ int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c,
|
||||||
ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
|
ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
|
||||||
ops.datbuf = NULL;
|
ops.datbuf = NULL;
|
||||||
|
|
||||||
ret = c->mtd->read_oob(c->mtd, jeb->offset, &ops);
|
ret = mtd_read_oob(c->mtd, jeb->offset, &ops);
|
||||||
if (ret || ops.oobretlen != ops.ooblen) {
|
if (ret || ops.oobretlen != ops.ooblen) {
|
||||||
printk(KERN_ERR "cannot read OOB for EB at %08x, requested %zd"
|
printk(KERN_ERR "cannot read OOB for EB at %08x, requested %zd"
|
||||||
" bytes, read %zd bytes, error %d\n",
|
" bytes, read %zd bytes, error %d\n",
|
||||||
|
|
|
@ -188,6 +188,8 @@ struct mtd_info {
|
||||||
size_t *retlen, const u_char *buf);
|
size_t *retlen, const u_char *buf);
|
||||||
int (*panic_write) (struct mtd_info *mtd, loff_t to, size_t len,
|
int (*panic_write) (struct mtd_info *mtd, loff_t to, size_t len,
|
||||||
size_t *retlen, const u_char *buf);
|
size_t *retlen, const u_char *buf);
|
||||||
|
int (*read_oob) (struct mtd_info *mtd, loff_t from,
|
||||||
|
struct mtd_oob_ops *ops);
|
||||||
|
|
||||||
/* Backing device capabilities for this device
|
/* Backing device capabilities for this device
|
||||||
* - provides mmap capabilities
|
* - provides mmap capabilities
|
||||||
|
@ -195,8 +197,6 @@ struct mtd_info {
|
||||||
struct backing_dev_info *backing_dev_info;
|
struct backing_dev_info *backing_dev_info;
|
||||||
|
|
||||||
|
|
||||||
int (*read_oob) (struct mtd_info *mtd, loff_t from,
|
|
||||||
struct mtd_oob_ops *ops);
|
|
||||||
int (*write_oob) (struct mtd_info *mtd, loff_t to,
|
int (*write_oob) (struct mtd_info *mtd, loff_t to,
|
||||||
struct mtd_oob_ops *ops);
|
struct mtd_oob_ops *ops);
|
||||||
|
|
||||||
|
@ -320,6 +320,12 @@ static inline int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||||
return mtd->panic_write(mtd, to, len, retlen, buf);
|
return mtd->panic_write(mtd, to, len, retlen, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int mtd_read_oob(struct mtd_info *mtd, loff_t from,
|
||||||
|
struct mtd_oob_ops *ops)
|
||||||
|
{
|
||||||
|
return mtd->read_oob(mtd, from, ops);
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct mtd_info *dev_to_mtd(struct device *dev)
|
static inline struct mtd_info *dev_to_mtd(struct device *dev)
|
||||||
{
|
{
|
||||||
return dev ? dev_get_drvdata(dev) : NULL;
|
return dev ? dev_get_drvdata(dev) : NULL;
|
||||||
|
|
Loading…
Reference in New Issue