]> www.infradead.org Git - mtd-utils.git/commitdiff
libmtd: support MEMWRITE ioctl
authorBrian Norris <computersforpeace@gmail.com>
Wed, 31 Aug 2011 20:00:34 +0000 (13:00 -0700)
committerArtem Bityutskiy <artem.bityutskiy@intel.com>
Sun, 11 Sep 2011 13:11:41 +0000 (16:11 +0300)
`mtd_write()' now will first attempt to use MEMWRITE. Then, if that
doesn't exist, it will attempt to fall back to old methods for writing
OOB and/or page data.

Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@intel.com>
lib/libmtd.c

index 746ea693a6c3aa6e52df3df9b4ac765da423c44e..d47b3073872fcf6cc7a85586829b82adc6ea2c11 100644 (file)
@@ -1077,6 +1077,7 @@ int mtd_write(libmtd_t desc, const struct mtd_dev_info *mtd, int fd, int eb,
 {
        int ret;
        off_t seek;
+       struct mtd_write_req ops;
 
        ret = mtd_valid_erase_block(mtd, eb);
        if (ret)
@@ -1101,16 +1102,38 @@ int mtd_write(libmtd_t desc, const struct mtd_dev_info *mtd, int fd, int eb,
                return -1;
        }
 
-       /* Seek to the beginning of the eraseblock */
+       /* Calculate seek address */
        seek = (off_t)eb * mtd->eb_size + offs;
-       if (lseek(fd, seek, SEEK_SET) != seek)
-               return sys_errmsg("cannot seek mtd%d to offset %llu",
-                                 mtd->mtd_num, (unsigned long long)seek);
 
-       ret = write(fd, data, len);
-       if (ret != len)
-               return sys_errmsg("cannot write %d bytes to mtd%d (eraseblock %d, offset %d)",
-                                 len, mtd->mtd_num, eb, offs);
+       ops.start = seek;
+       ops.len = len;
+       ops.ooblen = ooblen;
+       ops.usr_data = (uint64_t)(unsigned long)data;
+       ops.usr_oob = (uint64_t)(unsigned long)oob;
+       ops.mode = mode;
+
+       ret = ioctl(fd, MEMWRITE, &ops);
+       if (ret == 0)
+               return 0;
+       else if (errno != ENOTTY)
+               return mtd_ioctl_error(mtd, eb, "MEMWRITE");
+
+       /* Fall back to old methods if necessary */
+       if (oob) {
+               if (mtd_write_oob(desc, mtd, fd, seek, ooblen, oob) < 0)
+                       return sys_errmsg("cannot write to OOB");
+       }
+       if (data) {
+               /* Seek to the beginning of the eraseblock */
+               if (lseek(fd, seek, SEEK_SET) != seek)
+                       return sys_errmsg("cannot seek mtd%d to offset %llu",
+                                       mtd->mtd_num, (unsigned long long)seek);
+               ret = write(fd, data, len);
+               if (ret != len)
+                       return sys_errmsg("cannot write %d bytes to mtd%d "
+                                         "(eraseblock %d, offset %d)",
+                                         len, mtd->mtd_num, eb, offs);
+       }
 
        return 0;
 }