aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorAdrian Hunter <ext-adrian.hunter@nokia.com>2007-01-25 00:06:33 -0500
committerKyungmin Park <kyungmin.park@samsung.com>2007-01-25 00:06:33 -0500
commit8b29c0b6eb3a4952e7eae03038bbf6c1695dfe80 (patch)
treee6667249d596585dcf1b86d1639cdd47b13ab8c7 /drivers/mtd
parentec255e34061bbc48fc702875336c6db969df9461 (diff)
[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: Adrian Hunter <ext-adrian.hunter@nokia.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/onenand/onenand_base.c52
1 files changed, 31 insertions, 21 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 0249b4aa0976..65acb85830d3 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -909,41 +909,51 @@ static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to
909} 909}
910 910
911/** 911/**
912 * onenand_verify_page - [GENERIC] verify the chip contents after a write 912 * onenand_verify - [GENERIC] verify the chip contents after a write
913 * @param mtd MTD device structure 913 * @param mtd MTD device structure
914 * @param buf the databuffer to verify 914 * @param buf the databuffer to verify
915 * @param addr offset to read from
916 * @param len number of bytes to read and compare
915 * 917 *
916 * Check DataRAM area directly
917 */ 918 */
918static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr) 919static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr, size_t len)
919{ 920{
920 struct onenand_chip *this = mtd->priv; 921 struct onenand_chip *this = mtd->priv;
921 void __iomem *dataram0, *dataram1; 922 void __iomem *dataram;
922 int ret = 0; 923 int ret = 0;
924 int thislen, column;
923 925
924 /* In partial page write, just skip it */ 926 while (len != 0) {
925 if ((addr & (mtd->writesize - 1)) != 0) 927 thislen = min_t(int, mtd->writesize, len);
926 return 0; 928 column = addr & (mtd->writesize - 1);
929 if (column + thislen > mtd->writesize)
930 thislen = mtd->writesize - column;
927 931
928 this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize); 932 this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);
929 933
930 ret = this->wait(mtd, FL_READING); 934 onenand_update_bufferram(mtd, addr, 0);
931 if (ret) 935
932 return ret; 936 ret = this->wait(mtd, FL_READING);
937 if (ret)
938 return ret;
933 939
934 onenand_update_bufferram(mtd, addr, 1); 940 onenand_update_bufferram(mtd, addr, 1);
935 941
936 /* Check, if the two dataram areas are same */ 942 dataram = this->base + ONENAND_DATARAM;
937 dataram0 = this->base + ONENAND_DATARAM; 943 dataram += onenand_bufferram_offset(mtd, ONENAND_DATARAM);
938 dataram1 = dataram0 + mtd->writesize;
939 944
940 if (memcmp(dataram0, dataram1, mtd->writesize)) 945 if (memcmp(buf, dataram + column, thislen))
941 return -EBADMSG; 946 return -EBADMSG;
947
948 len -= thislen;
949 buf += thislen;
950 addr += thislen;
951 }
942 952
943 return 0; 953 return 0;
944} 954}
945#else 955#else
946#define onenand_verify_page(...) (0) 956#define onenand_verify(...) (0)
947#define onenand_verify_oob(...) (0) 957#define onenand_verify_oob(...) (0)
948#endif 958#endif
949 959
@@ -1025,7 +1035,7 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
1025 } 1035 }
1026 1036
1027 /* Only check verify write turn on */ 1037 /* Only check verify write turn on */
1028 ret = onenand_verify_page(mtd, (u_char *) wbuf, to); 1038 ret = onenand_verify(mtd, (u_char *) wbuf, to, thislen);
1029 if (ret) { 1039 if (ret) {
1030 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: verify failed %d\n", ret); 1040 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: verify failed %d\n", ret);
1031 break; 1041 break;