mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-02-25 06:53:40 +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
@ -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);
|
this->command(mtd, ONENAND_CMD_READ, from, writesize);
|
||||||
ret = this->wait(mtd, FL_READING);
|
ret = this->wait(mtd, FL_READING);
|
||||||
onenand_update_bufferram(mtd, from, !ret);
|
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 */
|
/* Now wait for load */
|
||||||
ret = this->wait(mtd, FL_READING);
|
ret = this->wait(mtd, FL_READING);
|
||||||
onenand_update_bufferram(mtd, from, !ret);
|
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->retlen = read;
|
||||||
ops->oobretlen = oobread;
|
ops->oobretlen = oobread;
|
||||||
|
|
||||||
if (mtd->ecc_stats.failed - stats.failed)
|
|
||||||
return -EBADMSG;
|
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
if (mtd->ecc_stats.failed - stats.failed)
|
||||||
|
return -EBADMSG;
|
||||||
|
|
||||||
return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
|
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 mtd_oob_ops *ops)
|
||||||
{
|
{
|
||||||
struct onenand_chip *this = mtd->priv;
|
struct onenand_chip *this = mtd->priv;
|
||||||
|
struct mtd_ecc_stats stats;
|
||||||
int read = 0, thislen, column, oobsize;
|
int read = 0, thislen, column, oobsize;
|
||||||
size_t len = ops->ooblen;
|
size_t len = ops->ooblen;
|
||||||
mtd_oob_mode_t mode = ops->mode;
|
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;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stats = mtd->ecc_stats;
|
||||||
|
|
||||||
while (read < len) {
|
while (read < len) {
|
||||||
cond_resched();
|
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);
|
onenand_update_bufferram(mtd, from, 0);
|
||||||
|
|
||||||
ret = this->wait(mtd, FL_READING);
|
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)
|
if (mode == MTD_OOB_AUTO)
|
||||||
onenand_transfer_auto_oob(mtd, buf, column, thislen);
|
onenand_transfer_auto_oob(mtd, buf, column, thislen);
|
||||||
else
|
else
|
||||||
this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
|
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;
|
read += thislen;
|
||||||
|
|
||||||
if (read == len)
|
if (read == len)
|
||||||
@ -1016,7 +1021,14 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ops->oobretlen = read;
|
ops->oobretlen = read;
|
||||||
return ret;
|
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (mtd->ecc_stats.failed - stats.failed)
|
||||||
|
return -EBADMSG;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user