mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
[MTD] [OneNAND] Do not stop reading for ECC errors
When an ECC error occurs, the read should be completed anyway before returning -EBADMSG. Returning -EBADMSG straight away is incorrect. Signed-off-by: Adrian Hunter <ext-adrian.hunter@nokia.com> Acked-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: David Woodhouse <dwmw2@infradead.org>
This commit is contained in:
parent
b1c9c9be6d
commit
5f4d47d5d1
1 changed files with 22 additions and 10 deletions
|
@ -855,6 +855,8 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
|
|||
this->command(mtd, ONENAND_CMD_READ, from, writesize);
|
||||
ret = this->wait(mtd, FL_READING);
|
||||
onenand_update_bufferram(mtd, from, !ret);
|
||||
if (ret == -EBADMSG)
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -913,6 +915,8 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
|
|||
/* Now wait for load */
|
||||
ret = this->wait(mtd, FL_READING);
|
||||
onenand_update_bufferram(mtd, from, !ret);
|
||||
if (ret == -EBADMSG)
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -923,12 +927,12 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
|
|||
ops->retlen = read;
|
||||
ops->oobretlen = oobread;
|
||||
|
||||
if (mtd->ecc_stats.failed - stats.failed)
|
||||
return -EBADMSG;
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (mtd->ecc_stats.failed - stats.failed)
|
||||
return -EBADMSG;
|
||||
|
||||
return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
|
||||
}
|
||||
|
||||
|
@ -944,6 +948,7 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
|
|||
struct mtd_oob_ops *ops)
|
||||
{
|
||||
struct onenand_chip *this = mtd->priv;
|
||||
struct mtd_ecc_stats stats;
|
||||
int read = 0, thislen, column, oobsize;
|
||||
size_t len = ops->ooblen;
|
||||
mtd_oob_mode_t mode = ops->mode;
|
||||
|
@ -977,6 +982,8 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
stats = mtd->ecc_stats;
|
||||
|
||||
while (read < len) {
|
||||
cond_resched();
|
||||
|
||||
|
@ -988,18 +995,16 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
|
|||
onenand_update_bufferram(mtd, from, 0);
|
||||
|
||||
ret = this->wait(mtd, FL_READING);
|
||||
/* First copy data and check return value for ECC handling */
|
||||
if (ret && ret != -EBADMSG) {
|
||||
printk(KERN_ERR "onenand_read_oob_nolock: read failed = 0x%x\n", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
if (mode == MTD_OOB_AUTO)
|
||||
onenand_transfer_auto_oob(mtd, buf, column, thislen);
|
||||
else
|
||||
this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
|
||||
|
||||
if (ret) {
|
||||
printk(KERN_ERR "onenand_read_oob_nolock: read failed = 0x%x\n", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
read += thislen;
|
||||
|
||||
if (read == len)
|
||||
|
@ -1016,7 +1021,14 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
|
|||
}
|
||||
|
||||
ops->oobretlen = read;
|
||||
return ret;
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (mtd->ecc_stats.failed - stats.failed)
|
||||
return -EBADMSG;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue