Commit 8b29c0b6 authored by Adrian Hunter's avatar Adrian Hunter Committed by Kyungmin Park

[MTD] OneNAND: Amend write-verify to compare to original buffer

When write-verify is enabled (CONFIG_MTD_ONENAND_VERIFY_WRITE),
the data written is read back and compared.  The comparison
was being made between dataRAM buffers, but this does not
verify that the data made it to the dataRAM correctly in
the first place.  This patch amends write-verify to
compare back to the original buffer.  It also now verifies
sub-page writes.
Signed-off-by: default avatarAdrian Hunter <ext-adrian.hunter@nokia.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
parent ec255e34
...@@ -909,41 +909,51 @@ static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to ...@@ -909,41 +909,51 @@ static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to
} }
/** /**
* onenand_verify_page - [GENERIC] verify the chip contents after a write * onenand_verify - [GENERIC] verify the chip contents after a write
* @param mtd MTD device structure * @param mtd MTD device structure
* @param buf the databuffer to verify * @param buf the databuffer to verify
* @param addr offset to read from
* @param len number of bytes to read and compare
* *
* Check DataRAM area directly
*/ */
static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr) static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr, size_t len)
{ {
struct onenand_chip *this = mtd->priv; struct onenand_chip *this = mtd->priv;
void __iomem *dataram0, *dataram1; void __iomem *dataram;
int ret = 0; int ret = 0;
int thislen, column;
/* In partial page write, just skip it */ while (len != 0) {
if ((addr & (mtd->writesize - 1)) != 0) thislen = min_t(int, mtd->writesize, len);
return 0; column = addr & (mtd->writesize - 1);
if (column + thislen > mtd->writesize)
thislen = mtd->writesize - column;
this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize); this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);
ret = this->wait(mtd, FL_READING); onenand_update_bufferram(mtd, addr, 0);
if (ret)
return ret; ret = this->wait(mtd, FL_READING);
if (ret)
return ret;
onenand_update_bufferram(mtd, addr, 1); onenand_update_bufferram(mtd, addr, 1);
/* Check, if the two dataram areas are same */ dataram = this->base + ONENAND_DATARAM;
dataram0 = this->base + ONENAND_DATARAM; dataram += onenand_bufferram_offset(mtd, ONENAND_DATARAM);
dataram1 = dataram0 + mtd->writesize;
if (memcmp(dataram0, dataram1, mtd->writesize)) if (memcmp(buf, dataram + column, thislen))
return -EBADMSG; return -EBADMSG;
len -= thislen;
buf += thislen;
addr += thislen;
}
return 0; return 0;
} }
#else #else
#define onenand_verify_page(...) (0) #define onenand_verify(...) (0)
#define onenand_verify_oob(...) (0) #define onenand_verify_oob(...) (0)
#endif #endif
...@@ -1025,7 +1035,7 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len, ...@@ -1025,7 +1035,7 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
} }
/* Only check verify write turn on */ /* Only check verify write turn on */
ret = onenand_verify_page(mtd, (u_char *) wbuf, to); ret = onenand_verify(mtd, (u_char *) wbuf, to, thislen);
if (ret) { if (ret) {
DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: verify failed %d\n", ret); DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: verify failed %d\n", ret);
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment