aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
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;