Commit 6b94f118a213583ada80bab25fedacc08562392d

Authored by Peter Tyser
Committed by Scott Wood
1 parent 59b5a2ad83

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>

Showing 1 changed file with 9 additions and 5 deletions Side-by-side Diff

... ... @@ -419,10 +419,13 @@
419 419 .mode = MTD_OPS_RAW
420 420 };
421 421  
422   - if (read)
  422 + if (read) {
423 423 ret = mtd_read_oob(nand, off, &ops);
424   - else
  424 + } else {
425 425 ret = mtd_write_oob(nand, off, &ops);
  426 + if (!ret)
  427 + ret = nand_verify_page_oob(nand, &ops, off);
  428 + }
426 429  
427 430 if (ret) {
428 431 printf("%s: error at offset %llx, ret %d\n",
... ... @@ -690,7 +693,8 @@
690 693 else
691 694 ret = nand_write_skip_bad(nand, off, &rwsize,
692 695 NULL, maxsize,
693   - (u_char *)addr, 0);
  696 + (u_char *)addr,
  697 + WITH_WR_VERIFY);
694 698 #ifdef CONFIG_CMD_NAND_TRIMFFS
695 699 } else if (!strcmp(s, ".trimffs")) {
696 700 if (read) {
... ... @@ -699,7 +703,7 @@
699 703 }
700 704 ret = nand_write_skip_bad(nand, off, &rwsize, NULL,
701 705 maxsize, (u_char *)addr,
702   - WITH_DROP_FFS);
  706 + WITH_DROP_FFS | WITH_WR_VERIFY);
703 707 #endif
704 708 #ifdef CONFIG_CMD_NAND_YAFFS
705 709 } else if (!strcmp(s, ".yaffs")) {
... ... @@ -709,7 +713,7 @@
709 713 }
710 714 ret = nand_write_skip_bad(nand, off, &rwsize, NULL,
711 715 maxsize, (u_char *)addr,
712   - WITH_YAFFS_OOB);
  716 + WITH_YAFFS_OOB | WITH_WR_VERIFY);
713 717 #endif
714 718 } else if (!strcmp(s, ".oob")) {
715 719 /* out-of-band data */