From c08a69faddd99e2fb9b6c791152c129241ba0e25 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 25 Jan 2010 17:09:30 +0200 Subject: [PATCH] --- yaml --- r: 186348 b: refs/heads/master c: 6e9065d756df5dac6dc02b94b82b4f5dbbf38caf h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/mtd/ubi/debug.h | 4 ++ trunk/drivers/mtd/ubi/io.c | 70 +++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index f4aabf5d9a78..bfdaee33d124 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: adbf05e3ec6ea380ba145b6fa89d9125ed76eb98 +refs/heads/master: 6e9065d756df5dac6dc02b94b82b4f5dbbf38caf diff --git a/trunk/drivers/mtd/ubi/debug.h b/trunk/drivers/mtd/ubi/debug.h index f30bcb372c05..17a107129726 100644 --- a/trunk/drivers/mtd/ubi/debug.h +++ b/trunk/drivers/mtd/ubi/debug.h @@ -96,8 +96,11 @@ void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len); #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); +int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, + int offset, int len); #else #define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0 +#define ubi_dbg_check_write(ubi, buf, pnum, offset, len) 0 #endif #ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT @@ -176,6 +179,7 @@ static inline int ubi_dbg_is_erase_failure(void) #define ubi_dbg_is_write_failure() 0 #define ubi_dbg_is_erase_failure() 0 #define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0 +#define ubi_dbg_check_write(ubi, buf, pnum, offset, len) 0 #endif /* !CONFIG_MTD_UBI_DEBUG */ #endif /* !__UBI_DEBUG_H__ */ diff --git a/trunk/drivers/mtd/ubi/io.c b/trunk/drivers/mtd/ubi/io.c index a2501299a67c..b4ecc84c7549 100644 --- a/trunk/drivers/mtd/ubi/io.c +++ b/trunk/drivers/mtd/ubi/io.c @@ -273,6 +273,21 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, } else ubi_assert(written == len); + if (!err) { + err = ubi_dbg_check_write(ubi, buf, pnum, offset, len); + if (err) + return err; + + /* + * Since we always write sequentially, the rest of the PEB has + * to contain only 0xFF bytes. + */ + offset += len; + len = ubi->peb_size - offset; + if (len) + err = ubi_dbg_check_all_ff(ubi, pnum, offset, len); + } + return err; } @@ -1281,6 +1296,61 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) return err; } +/** + * ubi_dbg_check_write - make sure write succeeded. + * @ubi: UBI device description object + * @buf: buffer with data which were written + * @pnum: physical eraseblock number the data were written to + * @offset: offset within the physical eraseblock the data were written to + * @len: how many bytes were written + * + * This functions reads data which were recently written and compares it with + * the original data buffer - the data have to match. Returns zero if the data + * match and a negative error code if not or in case of failure. + */ +int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, + int offset, int len) +{ + int err, i; + + mutex_lock(&ubi->dbg_buf_mutex); + err = ubi_io_read(ubi, ubi->dbg_peb_buf, pnum, offset, len); + if (err) + goto out_unlock; + + for (i = 0; i < len; i++) { + uint8_t c = ((uint8_t *)buf)[i]; + uint8_t c1 = ((uint8_t *)ubi->dbg_peb_buf)[i]; + int dump_len; + + if (c == c1) + continue; + + ubi_err("paranoid check failed for PEB %d:%d, len %d", + pnum, offset, len); + ubi_msg("data differ at position %d", i); + dump_len = max_t(int, 128, len - i); + ubi_msg("hex dump of the original buffer from %d to %d", + i, i + dump_len); + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, + buf + i, dump_len, 1); + ubi_msg("hex dump of the read buffer from %d to %d", + i, i + dump_len); + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, + ubi->dbg_peb_buf + i, dump_len, 1); + ubi_dbg_dump_stack(); + err = -EINVAL; + goto out_unlock; + } + mutex_unlock(&ubi->dbg_buf_mutex); + + return 0; + +out_unlock: + mutex_unlock(&ubi->dbg_buf_mutex); + return err; +} + /** * ubi_dbg_check_all_ff - check that a region of flash is empty. * @ubi: UBI device description object