From: Kevin Cernekee <cernekee@gmail.com>
To: <dedekind1@gmail.com>, <saeed.bishara@gmail.com>,
<jwboyer@gmail.com>, <vapier.adi@gmail.com>
Cc: linux-mtd@lists.infradead.org
Subject: [PATCHv2 4/5] libmtd: add support for 64-bit offsets, OOB
Date: Wed, 7 Jul 2010 17:30:13 -0700 [thread overview]
Message-ID: <c65631c48fb5d2de8d25f65bffa5e22d@localhost> (raw)
In-Reply-To: <eb53f5a0215250d7e523de47d15b0d12@localhost>
Change mtd_erase() so that it attempts to use MEMERASE64 first, then falls
back to the old <2.6.31 MEMERASE if MEMERASE64 is unsupported.
Add mtd_read_oob(), mtd_write_oob() functions to wrap the OOB ioctls.
Similar ioctl fallback logic is used in these functions as well.
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
---
include/libmtd.h | 36 ++++++++++++++++++++++-
lib/libmtd.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 111 insertions(+), 7 deletions(-)
diff --git a/include/libmtd.h b/include/libmtd.h
index 0aea966..292d8c3 100644
--- a/include/libmtd.h
+++ b/include/libmtd.h
@@ -66,6 +66,7 @@ struct mtd_info
* @region_cnt: count of additional erase regions
* @writable: zero if the device is read-only
* @bb_allowed: non-zero if the MTD device may have bad eraseblocks
+ * @legacy_ioctls: non-zero if the kernel lacks MEMERASE64, MEM*OOB64
*/
struct mtd_dev_info
{
@@ -84,6 +85,7 @@ struct mtd_dev_info
int region_cnt;
unsigned int writable:1;
unsigned int bb_allowed:1;
+ unsigned int legacy_ioctls:1;
};
/**
@@ -146,7 +148,37 @@ int mtd_get_dev_info1(libmtd_t desc, int mtd_num, struct mtd_dev_info *mtd);
* This function erases eraseblock @eb of MTD device described by @fd. Returns
* %0 in case of success and %-1 in case of failure.
*/
-int mtd_erase(const struct mtd_dev_info *mtd, int fd, int eb);
+int mtd_erase(struct mtd_dev_info *mtd, int fd, int eb);
+
+/**
+ * mtd_read_oob - read OOB bytes
+ * @mtd: MTD device description object
+ * @fd: MTD device node file descriptor
+ * @start: page-aligned start address
+ * @length: number of OOB bytes to read
+ * @data: read buffer
+ *
+ * This function reads @length OOB bytes starting from address @start on
+ * MTD device described by @fd. Returns %0 in case of success and %-1 in
+ * case of failure.
+ */
+int mtd_read_oob(struct mtd_dev_info *mtd, int fd, uint64_t start,
+ uint64_t length, void *data);
+
+/**
+ * mtd_write_oob - write OOB bytes
+ * @mtd: MTD device description object
+ * @fd: MTD device node file descriptor
+ * @start: page-aligned start address
+ * @length: number of OOB bytes to write
+ * @data: write buffer
+ *
+ * This function writes @length OOB bytes starting from address @start on
+ * MTD device described by @fd. Returns %0 in case of success and %-1 in
+ * case of failure.
+ */
+int mtd_write_oob(struct mtd_dev_info *mtd, int fd, uint64_t start,
+ uint64_t length, void *data);
/**
* mtd_torture - torture an eraseblock.
@@ -157,7 +189,7 @@ int mtd_erase(const struct mtd_dev_info *mtd, int fd, int eb);
* This function tortures eraseblock @eb. Returns %0 in case of success and %-1
* in case of failure.
*/
-int mtd_torture(const struct mtd_dev_info *mtd, int fd, int eb);
+int mtd_torture(struct mtd_dev_info *mtd, int fd, int eb);
/**
* mtd_is_bad - check if eraseblock is bad.
diff --git a/lib/libmtd.c b/lib/libmtd.c
index 3ff031c..66e794a 100644
--- a/lib/libmtd.c
+++ b/lib/libmtd.c
@@ -32,6 +32,7 @@
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <mtd/mtd-user.h>
+#include <mtd/mtd-abi.h>
#include <libmtd.h>
#include "libmtd_int.h"
@@ -789,13 +790,84 @@ int mtd_get_dev_info(libmtd_t desc, const char *node, struct mtd_dev_info *mtd)
return mtd_get_dev_info1(desc, mtd_num, mtd);
}
-int mtd_erase(const struct mtd_dev_info *mtd, int fd, int eb)
+int mtd_erase(struct mtd_dev_info *mtd, int fd, int eb)
{
- struct erase_info_user ei;
+ int ret;
+ struct erase_info_user64 ei;
- ei.start = eb * mtd->eb_size;;
+ ei.start = (__u64)eb * mtd->eb_size;
ei.length = mtd->eb_size;
- return ioctl(fd, MEMERASE, &ei);
+
+ if (!mtd->legacy_ioctls) {
+ ret = ioctl(fd, MEMERASE64, &ei);
+ if (ret < 0 && errno == ENOTTY)
+ mtd->legacy_ioctls = 1;
+ }
+
+ if (mtd->legacy_ioctls) {
+ struct erase_info_user ei_old;
+
+ ei_old.start = ei.start;
+ ei_old.length = ei.length;
+
+ if (ei_old.start != ei.start) {
+ errno = EOVERFLOW;
+ return -1;
+ }
+
+ ret = ioctl(fd, MEMERASE, &ei_old);
+ }
+
+ return ret;
+}
+
+static int mtd_oob_op(int cmd, int cmd_old, struct mtd_dev_info *mtd, int fd,
+ uint64_t start, uint64_t length, void *data)
+{
+ int ret;
+ struct mtd_oob_buf64 oob;
+
+ oob.start = start;
+ oob.length = length;
+ oob.usr_ptr = (__u64)(unsigned long)data;
+
+ if (!mtd->legacy_ioctls) {
+ ret = ioctl(fd, cmd, &oob);
+ if (ret < 0 && errno == ENOTTY)
+ mtd->legacy_ioctls = 1;
+ }
+
+ if (mtd->legacy_ioctls) {
+ struct mtd_oob_buf oob_old;
+
+ oob_old.start = oob.start;
+ oob_old.length = oob.length;
+ oob_old.ptr = data;
+
+ if (oob_old.start != oob.start ||
+ oob_old.length != oob.length) {
+ errno = EOVERFLOW;
+ return -1;
+ }
+
+ ret = ioctl(fd, cmd_old, &oob_old);
+ }
+
+ return ret;
+}
+
+int mtd_read_oob(struct mtd_dev_info *mtd, int fd, uint64_t start,
+ uint64_t length, void *data)
+{
+ return mtd_oob_op(MEMREADOOB64, MEMREADOOB, mtd, fd, start, length,
+ data);
+}
+
+int mtd_write_oob(struct mtd_dev_info *mtd, int fd, uint64_t start,
+ uint64_t length, void *data)
+{
+ return mtd_oob_op(MEMWRITEOOB64, MEMWRITEOOB, mtd, fd, start, length,
+ data);
}
/* Patterns to write to a physical eraseblock when torturing it */
@@ -820,7 +892,7 @@ static int check_pattern(const void *buf, uint8_t patt, int size)
return 1;
}
-int mtd_torture(const struct mtd_dev_info *mtd, int fd, int eb)
+int mtd_torture(struct mtd_dev_info *mtd, int fd, int eb)
{
int err, i, patt_count;
void *buf;
--
1.7.0.4
next prev parent reply other threads:[~2010-07-08 0:42 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-08 0:30 [PATCHv2 1/5] mtd-utils: move libmtd source files to lib/ subdirectory Kevin Cernekee
2010-07-08 0:30 ` [PATCHv2 2/5] mtd-utils: update Makefiles, source files to use common libmtd.a Kevin Cernekee
2010-07-08 0:30 ` [PATCHv2 3/5] mtd-utils: update to latest mtd-abi.h from kernel.org Kevin Cernekee
2010-07-13 10:38 ` Artem Bityutskiy
2010-07-08 0:30 ` Kevin Cernekee [this message]
2010-07-13 10:49 ` [PATCHv2 4/5] libmtd: add support for 64-bit offsets, OOB Artem Bityutskiy
2010-07-14 0:09 ` Kevin Cernekee
2010-07-14 2:51 ` Artem Bityutskiy
2010-07-17 7:35 ` Artem Bityutskiy
2010-07-13 10:50 ` Artem Bityutskiy
2010-07-17 17:08 ` Artem Bityutskiy
2010-07-18 4:26 ` Artem Bityutskiy
2010-07-24 1:07 ` Kevin Cernekee
2010-07-26 5:57 ` Artem Bityutskiy
2010-07-24 2:43 ` Kevin Cernekee
2010-07-26 5:36 ` Artem Bityutskiy
2010-07-08 0:30 ` [PATCHv2 5/5] mtd-utils: change flash_eraseall to use libmtd-wrapped ioctls Kevin Cernekee
2010-07-13 10:35 ` [PATCHv2 1/5] mtd-utils: move libmtd source files to lib/ subdirectory Artem Bityutskiy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c65631c48fb5d2de8d25f65bffa5e22d@localhost \
--to=cernekee@gmail.com \
--cc=dedekind1@gmail.com \
--cc=jwboyer@gmail.com \
--cc=linux-mtd@lists.infradead.org \
--cc=saeed.bishara@gmail.com \
--cc=vapier.adi@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).