cmd_nand: Verify writes to NAND

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 <ptyser@xes-inc.com>
Tested-by: Heiko Schocher <hs@denx.de>
Acked-by: Heiko Schocher <hs@denx.de>
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 @@
 			.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 @@
 			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 @@
 			}
 			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 @@
 			}
 			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 */