
Eh, I shouldn't post code that quickly… Try 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,80 @@ 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 < 5) { + nand_info_t *nand = &nand_info[dev]; + int size = rwsize; + int maxoffset = off + rwsize; + int offset = off; + int badblocks = 0; + for (offset = off; offset < maxoffset; offset += nand->erasesize) + if (nand_block_isbad(nand, offset)) + badblocks++; + if (badblocks) { + rwsize -= badblocks * nand->erasesize; + printf("size adjusted to 0x%llx (%d bad blocks)\n", + (unsigned long long)rwsize, badblocks); + } + } + 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 */