From mboxrd@z Thu Jan 1 00:00:00 1970 From: Heiko Schocher Date: Wed, 11 Feb 2015 07:45:37 +0100 Subject: [U-Boot] [PATCH 2/5] cmd_nand: Verify writes to NAND In-Reply-To: <1422986296-26086-2-git-send-email-ptyser@xes-inc.com> References: <1422986296-26086-1-git-send-email-ptyser@xes-inc.com> <1422986296-26086-2-git-send-email-ptyser@xes-inc.com> Message-ID: <54DAFA91.9040204@denx.de> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hello Peter, Am 03.02.2015 18:58, schrieb Peter Tyser: > Previously NAND writes were only verified when CONFIG_MTD_NAND_VERIFY_WRITE > was defined. On boards without this define writes could fail silently. > Boards with CONFIG_MTD_NAND_VERIFY_WRITE could prematurely report > failures which ECC could correct. > > Add a verification step after all "nand write[.x]" commands to ensure the > writes were successful. The verification uses ECC for for "normal" > writes, but does not for raw and yaffs writes. Some test cases which > inject fake bad bits on a 2K page flash are below. > > Test cases with CONFIG_MTD_NAND_VERIFY_WRITE defined: > Example of an ECC write which previously failed when > CONFIG_MTD_NAND_VERIFY_WRITE was defined, but now succeeds because ECC > is used during verification: > nand erase 0 0x10000 > dhcp /somefile > mw.b 0x10000 0xff 0x2000 > mw.b 0x10020 0xfe 1 > nand write.raw 0x10000 0x800 1 > mw.b 0x1000020 0x01 1 > nand write 0x1000000 0x800 0x1800 > > Test cases without CONFIG_MTD_NAND_VERIFY_WRITE defined: > Example of an ECC write which previously silently failed: > nand erase 0 0x10000 > dhcp /somefile > mw.b 0x10000 0xff 0x2000 > mw.b 0x10020 0x00 1 > nand write.raw 0x10000 0x800 1 > mw.b 0x1000020 0xff 1 > nand write 0x1000000 0x800 0x1800 > > Example of a raw write which previously failed silently due to stuck > data bit, but now errors out: > nand erase 0 0x10000 > dhcp /somefile > mw.b 0x10000 0xff 0x2000 > mw.b 0x10020 0xfe 1 > nand write.raw 0x10000 0x800 1 > mw.b 0x1000020 0x01 1 > nand write.raw 0x1000000 0x800 3 > > Example of a raw write which previously failed silently due to stuck OOB > bit, but now errors out: > nand erase 0 0x10000 > dhcp /somefile > mw.b 0x10000 0xff 0x2000 > mw.b 0x10810 0xfe 1 > nand write.raw 0x10000 0x800 1 > mw.b 0x1000810 0x01 1 > nand write.raw 0x1000000 0x800 3 > > Signed-off-by: Peter Tyser > --- > > common/cmd_nand.c | 14 +++++++++----- > 1 file changed, 9 insertions(+), 5 deletions(-) Tested on the am335x based dxr2 board with writing a ubifs image into a nand mtd partition. Tested-by: Heiko Schocher Acked-by: Heiko Schocher bye, Heiko > > diff --git a/common/cmd_nand.c b/common/cmd_nand.c > index 7f962dc..bada28c 100644 > --- a/common/cmd_nand.c > +++ b/common/cmd_nand.c > @@ -419,10 +419,13 @@ static int raw_access(nand_info_t *nand, ulong addr, loff_t off, ulong count, > .mode = MTD_OPS_RAW > }; > > - if (read) > + if (read) { > ret = mtd_read_oob(nand, off, &ops); > - else > + } else { > ret = mtd_write_oob(nand, off, &ops); > + if (!ret) > + ret = nand_verify_page_oob(nand, &ops, off); > + } > > if (ret) { > printf("%s: error at offset %llx, ret %d\n", > @@ -690,7 +693,8 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) > else > ret = nand_write_skip_bad(nand, off, &rwsize, > NULL, maxsize, > - (u_char *)addr, 0); > + (u_char *)addr, > + WITH_WR_VERIFY); > #ifdef CONFIG_CMD_NAND_TRIMFFS > } else if (!strcmp(s, ".trimffs")) { > if (read) { > @@ -699,7 +703,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) > } > ret = nand_write_skip_bad(nand, off, &rwsize, NULL, > maxsize, (u_char *)addr, > - WITH_DROP_FFS); > + WITH_DROP_FFS | WITH_WR_VERIFY); > #endif > #ifdef CONFIG_CMD_NAND_YAFFS > } else if (!strcmp(s, ".yaffs")) { > @@ -709,7 +713,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) > } > ret = nand_write_skip_bad(nand, off, &rwsize, NULL, > maxsize, (u_char *)addr, > - WITH_YAFFS_OOB); > + WITH_YAFFS_OOB | WITH_WR_VERIFY); > #endif > } else if (!strcmp(s, ".oob")) { > /* out-of-band data */ > -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany