[U-Boot] U-boot nand bug, read.part should fail
Harvey Chapman
hchapman-uboot at 3gfp.com
Fri Feb 8 17:44:30 CET 2013
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 */
More information about the U-Boot
mailing list