summaryrefslogtreecommitdiff
path: root/lib/libmtd.c
diff options
context:
space:
mode:
authorBrian Norris <computersforpeace@gmail.com>2011-08-31 13:00:34 -0700
committerArtem Bityutskiy <artem.bityutskiy@intel.com>2011-09-11 16:11:41 +0300
commit6a8889fbc0ea7a198628c9e3901fd88038e12d09 (patch)
tree9293d25f13f6f1d9effa61638353cb47896976ae /lib/libmtd.c
parentcd42aea270e84884e6bbac845414568f0febbedf (diff)
libmtd: support MEMWRITE ioctl
`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>
Diffstat (limited to 'lib/libmtd.c')
-rw-r--r--lib/libmtd.c39
1 files changed, 31 insertions, 8 deletions
diff --git a/lib/libmtd.c b/lib/libmtd.c
index 746ea69..d47b307 100644
--- a/lib/libmtd.c
+++ b/lib/libmtd.c
@@ -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;
}