
On Feb 7, 2013, at 5:22 PM, Scott Wood scottwood@freescale.com wrote:
It's fine until you get a bad block in the partition, and you end up accessing the first block of the next partition (or getting "Attempt to read/write outside the flash area" if it's the last partition).
Of course, fixing partition/chip accesses to account for this when determining size would be even better. :-)
Something like this?
diff --git a/common/cmd_nand.c b/common/cmd_nand.c --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -621,60 +621,78 @@ int do_nand(cmd_tbl_t * cmdtp, int flag,
nand = &nand_info[dev];
s = strchr(cmd, '.');
if (s && !strcmp(s, ".raw")) { raw = 1;
if (arg_off(argv[3], &dev, &off, &size)) return 1;
if (argc > 4 && !str2long(argv[4], &pagecount)) { printf("'%s' is not a number\n", argv[4]); return 1; }
if (pagecount * nand->writesize > size) { puts("Size exceeds partition or device limit\n"); return -1; }
rwsize = pagecount * (nand->writesize + nand->oobsize); } else { if (arg_off_size(argc - 3, argv + 3, &dev, &off, &size) != 0) return 1;
rwsize = size; }
+ /* If no size was given, it has been calculated for us as + * the remainder of the chip or partition from offset. Adjust + * down for bad blocks, if necessary. + */ + if (argc < 4) { + nand_info_t *nand = &nand_info[dev]; + int maxsize = rwsize; + int offset = off; + for (; offset < maxsize; offset += nand->erasesize) + if (nand_block_isbad(nand, offset)) + rwsize -= nand->erasesize; + + if (rwsize != maxsize) + printf("\nsize adjusted to %d (%d bad blocks)\n", + rwsize, + (maxsize - rwsize) / nand->erasesize); + } + if (!s || !strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i") || !strcmp(s, ".part")) { if (read) ret = nand_read_skip_bad(nand, off, &rwsize, (u_char *)addr); else ret = nand_write_skip_bad(nand, off, &rwsize, (u_char *)addr, 0); #ifdef CONFIG_CMD_NAND_TRIMFFS } else if (!strcmp(s, ".trimffs")) { if (read) { printf("Unknown nand command suffix '%s'\n", s); return 1; } ret = nand_write_skip_bad(nand, off, &rwsize, (u_char *)addr, WITH_DROP_FFS); #endif #ifdef CONFIG_CMD_NAND_YAFFS } else if (!strcmp(s, ".yaffs")) { if (read) { printf("Unknown nand command suffix '%s'.\n", s); return 1; } ret = nand_write_skip_bad(nand, off, &rwsize, (u_char *)addr, WITH_INLINE_OOB); #endif } else if (!strcmp(s, ".oob")) { /* out-of-band data */