On Feb 7, 2013, at 5:22 PM, Scott Wood <[email protected]> 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 */


_______________________________________________
U-Boot mailing list
[email protected]
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to