diff options
Diffstat (limited to 'drivers/mtd/onenand/onenand_base.c')
-rw-r--r-- | drivers/mtd/onenand/onenand_base.c | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index b6a73b72f600..e342ba04118a 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c | |||
@@ -759,6 +759,36 @@ out: | |||
759 | 759 | ||
760 | #ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE | 760 | #ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE |
761 | /** | 761 | /** |
762 | * onenand_verify_oob - [GENERIC] verify the oob contents after a write | ||
763 | * @param mtd MTD device structure | ||
764 | * @param buf the databuffer to verify | ||
765 | * @param to offset to read from | ||
766 | * @param len number of bytes to read and compare | ||
767 | * | ||
768 | */ | ||
769 | static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to, int len) | ||
770 | { | ||
771 | struct onenand_chip *this = mtd->priv; | ||
772 | char *readp = this->page_buf; | ||
773 | int column = to & (mtd->oobsize - 1); | ||
774 | int status, i; | ||
775 | |||
776 | this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize); | ||
777 | onenand_update_bufferram(mtd, to, 0); | ||
778 | status = this->wait(mtd, FL_READING); | ||
779 | if (status) | ||
780 | return status; | ||
781 | |||
782 | this->read_bufferram(mtd, ONENAND_SPARERAM, readp, column, len); | ||
783 | |||
784 | for(i = 0; i < len; i++) | ||
785 | if (buf[i] != 0xFF && buf[i] != readp[i]) | ||
786 | return -EBADMSG; | ||
787 | |||
788 | return 0; | ||
789 | } | ||
790 | |||
791 | /** | ||
762 | * onenand_verify_page - [GENERIC] verify the chip contents after a write | 792 | * onenand_verify_page - [GENERIC] verify the chip contents after a write |
763 | * @param mtd MTD device structure | 793 | * @param mtd MTD device structure |
764 | * @param buf the databuffer to verify | 794 | * @param buf the databuffer to verify |
@@ -790,6 +820,7 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr) | |||
790 | } | 820 | } |
791 | #else | 821 | #else |
792 | #define onenand_verify_page(...) (0) | 822 | #define onenand_verify_page(...) (0) |
823 | #define onenand_verify_oob(...) (0) | ||
793 | #endif | 824 | #endif |
794 | 825 | ||
795 | #define NOTALIGNED(x) ((x & (mtd->oobblock - 1)) != 0) | 826 | #define NOTALIGNED(x) ((x & (mtd->oobblock - 1)) != 0) |
@@ -909,7 +940,7 @@ static int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len, | |||
909 | size_t *retlen, const u_char *buf) | 940 | size_t *retlen, const u_char *buf) |
910 | { | 941 | { |
911 | struct onenand_chip *this = mtd->priv; | 942 | struct onenand_chip *this = mtd->priv; |
912 | int column, status; | 943 | int column, ret = 0; |
913 | int written = 0; | 944 | int written = 0; |
914 | 945 | ||
915 | DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); | 946 | DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); |
@@ -941,9 +972,17 @@ static int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len, | |||
941 | 972 | ||
942 | onenand_update_bufferram(mtd, to, 0); | 973 | onenand_update_bufferram(mtd, to, 0); |
943 | 974 | ||
944 | status = this->wait(mtd, FL_WRITING); | 975 | ret = this->wait(mtd, FL_WRITING); |
945 | if (status) | 976 | if (ret) { |
977 | DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: write filaed %d\n", ret); | ||
978 | goto out; | ||
979 | } | ||
980 | |||
981 | ret = onenand_verify_oob(mtd, buf, to, thislen); | ||
982 | if (ret) { | ||
983 | DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: verify failed %d\n", ret); | ||
946 | goto out; | 984 | goto out; |
985 | } | ||
947 | 986 | ||
948 | written += thislen; | 987 | written += thislen; |
949 | 988 | ||
@@ -960,7 +999,7 @@ out: | |||
960 | 999 | ||
961 | *retlen = written; | 1000 | *retlen = written; |
962 | 1001 | ||
963 | return 0; | 1002 | return ret; |
964 | } | 1003 | } |
965 | 1004 | ||
966 | /** | 1005 | /** |