[package] mtd: fix r24132
[openwrt/svn-archive/archive.git] / package / mtd / src / mtd.c
index ff75fcb8a93435ff02a1d407c01dab8fdc213e81..5ec79dce0f53ce1ab45ce36c0d432f7039bd336c 100644 (file)
@@ -74,6 +74,7 @@ static char *imagefile = NULL;
 static char *jffs2file = NULL, *jffs2dir = JFFS2_DEFAULT_DIR;
 static int buflen = 0;
 int quiet;
+int no_erase;
 int mtdsize = 0;
 int erasesize = 0;
 
@@ -367,6 +368,16 @@ mtd_refresh(const char *mtd)
        return 0;
 }
 
+static void
+indicate_writing(const char *mtd)
+{
+       if (quiet < 2)
+               fprintf(stderr, "\nWriting from %s to %s ... ", imagefile, mtd);
+
+       if (!quiet)
+               fprintf(stderr, " [ ]");
+}
+
 static int
 mtd_write(int imagefd, const char *mtd, char *fis_layout)
 {
@@ -374,6 +385,7 @@ mtd_write(int imagefd, const char *mtd, char *fis_layout)
        char *str = NULL;
        int fd, result;
        ssize_t r, w, e;
+       ssize_t skip = 0;
        uint32_t offset = 0;
 
 #ifdef FIS_SUPPORT
@@ -451,13 +463,9 @@ resume:
                exit(1);
        }
 
-       if (quiet < 2)
-               fprintf(stderr, "Writing from %s to %s ... ", imagefile, mtd);
+       indicate_writing(mtd);
 
        w = e = 0;
-       if (!quiet)
-               fprintf(stderr, " [ ]");
-
        for (;;) {
                /* buffer may contain data already (from trx check or last mtd partition write attempt) */
                while (buflen < erasesize) {
@@ -480,6 +488,15 @@ resume:
                if (buflen == 0)
                        break;
 
+               if (skip > 0) {
+                       skip -= buflen;
+                       buflen = 0;
+                       if (skip <= 0)
+                               indicate_writing(mtd);
+
+                       continue;
+               }
+
                if (jffs2file) {
                        if (memcmp(buf, JFFS2_EOF, sizeof(JFFS2_EOF) - 1) == 0) {
                                if (!quiet)
@@ -487,8 +504,14 @@ resume:
                                if (quiet < 2)
                                        fprintf(stderr, "\nAppending jffs2 data from %s to %s...", jffs2file, mtd);
                                /* got an EOF marker - this is the place to add some jffs2 data */
-                               mtd_replace_jffs2(mtd, fd, e, jffs2file);
-                               goto done;
+                               skip = mtd_replace_jffs2(mtd, fd, e, jffs2file);
+
+                               w += skip;
+                               e += skip;
+                               skip -= buflen;
+                               buflen = 0;
+                               offset = 0;
+                               continue;
                        }
                        /* no EOF marker, make sure we figure out the last inode number
                         * before appending some data */
@@ -496,32 +519,35 @@ resume:
                }
 
                /* need to erase the next block before writing data to it */
-               while (w + buflen > e) {
-                       if (!quiet)
-                               fprintf(stderr, "\b\b\b[e]");
-
-
-                       if (mtd_erase_block(fd, e) < 0) {
-                               if (next) {
-                                       if (w < e) {
-                                               write(fd, buf + offset, e - w);
-                                               offset = e - w;
+               if(!no_erase)
+               {
+                       while (w + buflen > e) {
+                               if (!quiet)
+                                       fprintf(stderr, "\b\b\b[e]");
+
+
+                               if (mtd_erase_block(fd, e) < 0) {
+                                       if (next) {
+                                               if (w < e) {
+                                                       write(fd, buf + offset, e - w);
+                                                       offset = e - w;
+                                               }
+                                               w = 0;
+                                               e = 0;
+                                               close(fd);
+                                               mtd = next;
+                                               fprintf(stderr, "\b\b\b   \n");
+                                               goto resume;
+                                       } else {
+                                               fprintf(stderr, "Failed to erase block\n");
+                                               exit(1);
                                        }
-                                       w = 0;
-                                       e = 0;
-                                       close(fd);
-                                       mtd = next;
-                                       fprintf(stderr, "\b\b\b   \n");
-                                       goto resume;
-                               } else {
-                                       fprintf(stderr, "Failed to erase block\n");
-                                       exit(1);
                                }
-                       }
 
-                       /* erase the chunk */
-                       e += erasesize;
-               }
+                               /* erase the chunk */
+                               e += erasesize;
+                       }
+           }
 
                if (!quiet)
                        fprintf(stderr, "\b\b\b[w]");
@@ -573,6 +599,7 @@ static void usage(void)
        "Following options are available:\n"
        "        -q                      quiet mode (once: no [w] on writing,\n"
        "                                           twice: no status messages)\n"
+       "        -n                      write without first erasing the blocks\n"
        "        -r                      reboot after successful command\n"
        "        -f                      force write without trx checks\n"
        "        -e <device>             erase <device> before executing the command\n"
@@ -624,12 +651,13 @@ int main (int argc, char **argv)
        force = 0;
        buflen = 0;
        quiet = 0;
+  no_erase = 0;
 
        while ((ch = getopt(argc, argv,
 #ifdef FIS_SUPPORT
                        "F:"
 #endif
-                       "frqe:d:j:o:")) != -1)
+                       "frnqe:d:j:o:")) != -1)
                switch (ch) {
                        case 'f':
                                force = 1;
@@ -637,6 +665,9 @@ int main (int argc, char **argv)
                        case 'r':
                                boot = 1;
                                break;
+                       case 'n':
+                               no_erase = 1;
+                               break;
                        case 'j':
                                jffs2file = optarg;
                                break;