diff options
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/onenand/onenand_base.c | 52 |
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 | */ |
918 | static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr) | 919 | static 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; |