This change implements the suggestion from an earlier thread for
how to handle padding of non-page sized writes to NAND flashes.

See http://lists.denx.de/pipermail/u-boot/2009-February/047795.html
for the original discussion.  Note that validity of tail page's
memory is the reponsibility of the caller.

Signed-off-by: Josh Karabin <gkara...@vocollect.com>
---
 common/cmd_nand.c |   41 +++++++++++++++++++++++++++++++----------
 1 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index 1992531..f094101 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -102,9 +102,11 @@ static inline int str2long(char *p, ulong *num)
 }
 
 static int
-arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, size_t 
*size)
+arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off,
+             size_t *size, int *plussed)
 {
        int idx = nand_curr_device;
+       char *ps = argv[1];
 #if defined(CONFIG_CMD_MTDPARTS)
        struct mtd_device *dev;
        struct part_info *part;
@@ -119,8 +121,12 @@ arg_off_size(int argc, char *argv[], nand_info_t *nand, 
ulong *off, size_t *size
                        }
                        *off = part->offset;
                        if (argc >= 2) {
-                               if (!(str2long(argv[1], (ulong *)size))) {
-                                       printf("'%s' is not a number\n", 
argv[1]);
+                               if (plussed && *ps == '+') {
+                                       *plussed = 1;
+                                       ps++;
+                               }
+                               if (!(str2long(ps, (ulong *)size))) {
+                                       printf("'%s' is not a number\n", ps);
                                        return -1;
                                }
                                if (*size > part->size)
@@ -145,8 +151,12 @@ arg_off_size(int argc, char *argv[], nand_info_t *nand, 
ulong *off, size_t *size
        }
 
        if (argc >= 2) {
-               if (!(str2long(argv[1], (ulong *)size))) {
-                       printf("'%s' is not a number\n", argv[1]);
+               if (plussed && *ps == '+') {
+                       *plussed = 1;
+                       ps++;
+               }
+               if (!(str2long(ps, (ulong *)size))) {
+                       printf("'%s' is not a number\n", ps);
                        return -1;
                }
        } else {
@@ -317,7 +327,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char 
*argv[])
 
                printf("\nNAND %s: ", scrub ? "scrub" : "erase");
                /* skip first two or three arguments, look for offset and size 
*/
-               if (arg_off_size(argc - o, argv + o, nand, &off, &size) != 0)
+               if (arg_off_size(argc - o, argv + o, nand, &off, &size, NULL) 
!= 0)
                        return 1;
 
                memset(&opts, 0, sizeof(opts));
@@ -378,8 +388,18 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char 
*argv[])
 
                read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
                printf("\nNAND %s: ", read ? "read" : "write");
-               if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0)
+               if (read && arg_off_size(argc - 3, argv + 3, nand, &off, &size, 
NULL) != 0)
                        return 1;
+               else if (!read) {
+                       int plussed = 0;
+                       if (arg_off_size(argc - 3, argv + 3, nand, &off, &size, 
&plussed) != 0)
+                               return 1;
+                       if (plussed) {
+                               int tailsize = size & (nand->writesize - 1);
+                               memset ((u_char *)addr + size, 0xff, 
nand->writesize - tailsize);
+                               size += nand->writesize - tailsize;
+                       }
+               }
 
                s = strchr(cmd, '.');
                if (!s || !strcmp(s, ".jffs2") ||
@@ -457,7 +477,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char 
*argv[])
        }
 
        if (strcmp(cmd, "unlock") == 0) {
-               if (arg_off_size(argc - 2, argv + 2, nand, &off, &size) < 0)
+               if (arg_off_size(argc - 2, argv + 2, nand, &off, &size, NULL) < 
0)
                        return 1;
 
                if (!nand_unlock(nand, off, size)) {
@@ -481,9 +501,10 @@ U_BOOT_CMD(nand, 5, 1, do_nand,
           "info - show available NAND devices\n"
           "nand device [dev] - show or set current device\n"
           "nand read - addr off|partition size\n"
-          "nand write - addr off|partition size\n"
+          "nand write - addr off|partition [+]size\n"
           "    read/write 'size' bytes starting at offset 'off'\n"
-          "    to/from memory address 'addr', skipping bad blocks.\n"
+          "    to/from memory address 'addr', skipping bad blocks,\n"
+          "    rounding up to a page size if '+' is specified.\n"
           "nand erase [clean] [off size] - erase 'size' bytes from\n"
           "    offset 'off' (entire device if not specified)\n"
           "nand bad - show bad blocks\n"
-- 
1.6.0.6

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to