All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Jörn Engel" <joern@logfs.org>
To: Josh Boyer <jwboyer@gmail.com>, linux-mtd@lists.infradead.org
Subject: [Patch] Support large devices for flash_eraseaal
Date: Tue, 7 Jul 2009 18:22:32 +0200	[thread overview]
Message-ID: <20090707162231.GA26579@logfs.org> (raw)
In-Reply-To: <20090707140337.GA24749@logfs.org>

The mtd-abi.h bits may be wrong, not sure.  Otherwise it allows me to
erase a large device.  No guarantees beyond that.

Signed-off-by: Joern Engel <joern@logfs.org>

Jörn

-- 
Happiness isn't having what you want, it's wanting what you have.
-- unknown

 flash_eraseall.c      |   88 +++++++++++++++++++++++++++++++++++++++++--------
 include/mtd/mtd-abi.h |   89 +++++++++++++++++++++++++++++---------------------
 2 files changed, 126 insertions(+), 51 deletions(-)

diff --git a/flash_eraseall.c b/flash_eraseall.c
index a22fc49..d865cbc 100644
--- a/flash_eraseall.c
+++ b/flash_eraseall.c
@@ -48,33 +48,93 @@ static const char *mtd_device;
 static int quiet;		/* true -- don't output progress */
 static int jffs2;		// format for jffs2 usage
 
+struct mtd_info_user64 {
+	uint8_t type;
+	uint32_t flags;
+	uint64_t size;	 // Total size of the MTD
+	uint32_t erasesize;
+	uint32_t writesize;
+	uint32_t oobsize;   // Amount of OOB data per block (e.g. 16)
+	/* The below two fields are obsolete and broken, do not use them
+	 * (TODO: remove at some point) */
+	uint32_t ecctype;
+	uint32_t eccsize;
+};
+
 static void process_options (int argc, char *argv[]);
-void show_progress (mtd_info_t *meminfo, erase_info_t *erase);
+void show_progress(struct mtd_info_user64 *meminfo, struct erase_info_user64 *erase);
 static void display_help (void);
 static void display_version (void);
 static struct jffs2_unknown_node cleanmarker;
 int target_endian = __BYTE_ORDER;
 
+static int get_info(const char *devname, struct mtd_info_user64 *mtd64)
+{
+	struct mtd_info_user mtd;
+	char buf[256];
+	int fd;
+
+	if ((fd = open(devname, O_RDWR)) < 0) {
+		fprintf(stderr, "%s: %s: %s\n", exe_name, devname, strerror(errno));
+		return 1;
+	}
+
+
+	if (ioctl(fd, MEMGETINFO, &mtd) != 0) {
+		fprintf(stderr, "%s: %s: unable to get MTD device info\n", exe_name, devname);
+		return 1;
+	}
+	close(fd);
+
+	mtd64->type = mtd.type;
+	mtd64->flags = mtd.flags;
+	mtd64->size = mtd.size;
+	mtd64->erasesize = mtd.erasesize;
+	mtd64->writesize = mtd.writesize;
+	mtd64->oobsize = mtd.oobsize;
+	mtd64->ecctype = mtd.ecctype;
+	mtd64->eccsize = mtd.eccsize;
+
+	/* I'm glad I only have to do this for one parameter. */
+	sprintf(buf, "/sys/class/mtd/%s/size", basename((char *)devname));
+	fd = open(buf, O_RDONLY);
+	if (fd < 0)
+		return 0;
+	read(fd, buf, 256);
+	mtd64->size = strtoull(buf, NULL, 0);
+	close(fd);
+	return 0;
+}
+
+static int do_erase(int fd, struct erase_info_user64 *ei64, struct mtd_info_user64 *mtd64)
+{
+	struct erase_info_user ei;
+
+	if (mtd64->size >= 0x100000000ull)
+		return ioctl(fd, MEMERASE64, ei64);
+	else {
+		ei.start = ei64->start;
+		ei.length = ei64->length;
+		return ioctl(fd, MEMERASE, &ei);
+	}
+}
+
 int main (int argc, char *argv[])
 {
-	mtd_info_t meminfo;
+	struct mtd_info_user64 meminfo;
 	int fd, clmpos = 0, clmlen = 8;
-	erase_info_t erase;
+	struct erase_info_user64 erase;
 	int isNAND, bbtest = 1;
 
 	process_options(argc, argv);
 
+	if (get_info(mtd_device, &meminfo))
+		return 1;
 	if ((fd = open(mtd_device, O_RDWR)) < 0) {
 		fprintf(stderr, "%s: %s: %s\n", exe_name, mtd_device, strerror(errno));
 		return 1;
 	}
 
-
-	if (ioctl(fd, MEMGETINFO, &meminfo) != 0) {
-		fprintf(stderr, "%s: %s: unable to get MTD device info\n", exe_name, mtd_device);
-		return 1;
-	}
-
 	erase.length = meminfo.erasesize;
 	isNAND = meminfo.type == MTD_NANDFLASH ? 1 : 0;
 
@@ -130,7 +190,7 @@ int main (int argc, char *argv[])
 			int ret = ioctl(fd, MEMGETBADBLOCK, &offset);
 			if (ret > 0) {
 				if (!quiet)
-					printf ("\nSkipping bad block at 0x%08x\n", erase.start);
+					printf ("\nSkipping bad block at 0x%08llx\n", erase.start);
 				continue;
 			} else if (ret < 0) {
 				if (errno == EOPNOTSUPP) {
@@ -149,7 +209,7 @@ int main (int argc, char *argv[])
 		if (!quiet)
 			show_progress(&meminfo, &erase);
 
-		if (ioctl(fd, MEMERASE, &erase) != 0) {
+		if (do_erase(fd, &erase, &meminfo) != 0) {
 			fprintf(stderr, "\n%s: %s: MTD Erase failure: %s\n", exe_name, mtd_device, strerror(errno));
 			continue;
 		}
@@ -179,7 +239,7 @@ int main (int argc, char *argv[])
 			}
 		}
 		if (!quiet)
-			printf (" Cleanmarker written at %x.", erase.start);
+			printf (" Cleanmarker written at %llx.", erase.start);
 	}
 	if (!quiet) {
 		show_progress(&meminfo, &erase);
@@ -250,9 +310,9 @@ void process_options (int argc, char *argv[])
 	mtd_device = argv[optind];
 }
 
-void show_progress (mtd_info_t *meminfo, erase_info_t *erase)
+void show_progress(struct mtd_info_user64 *meminfo, struct erase_info_user64 *erase)
 {
-	printf("\rErasing %d Kibyte @ %x -- %2llu %% complete.",
+	printf("\rErasing %d Kibyte @ %llx -- %2llu %% complete.",
 		meminfo->erasesize / 1024, erase->start,
 		(unsigned long long) erase->start * 100 / meminfo->size);
 	fflush(stdout);
diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
index 86defe1..c6954ed 100644
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -1,23 +1,35 @@
 /*
- * $Id: mtd-abi.h,v 1.13 2005/11/07 11:14:56 gleixner Exp $
- *
  * Portions of MTD ABI definition which are shared by kernel and user space
  */
 
 #ifndef __MTD_ABI_H__
 #define __MTD_ABI_H__
 
+#include <linux/types.h>
+
 struct erase_info_user {
-	uint32_t start;
-	uint32_t length;
+	__u32 start;
+	__u32 length;
+};
+
+struct erase_info_user64 {
+	__u64 start;
+	__u64 length;
 };
 
 struct mtd_oob_buf {
-	uint32_t start;
-	uint32_t length;
+	__u32 start;
+	__u32 length;
 	unsigned char *ptr;
 };
 
+struct mtd_oob_buf64 {
+	__u64 start;
+	__u32 pad;
+	__u32 length;
+	__u64 usr_ptr;
+};
+
 #define MTD_ABSENT		0
 #define MTD_RAM			1
 #define MTD_ROM			2
@@ -29,7 +41,7 @@ struct mtd_oob_buf {
 #define MTD_WRITEABLE		0x400	/* Device is writeable */
 #define MTD_BIT_WRITEABLE	0x800	/* Single bits can be flipped */
 #define MTD_NO_ERASE		0x1000	/* No erase necessary */
-#define MTD_STUPID_LOCK		0x2000	/* Always locked after reset */
+#define MTD_POWERUP_LOCK	0x2000	/* Always locked after reset */
 
 // Some common devices / combinations of capabilities
 #define MTD_CAP_ROM		0
@@ -50,30 +62,30 @@ struct mtd_oob_buf {
 #define MTD_OTP_USER		2
 
 struct mtd_info_user {
-	uint8_t type;
-	uint32_t flags;
-	uint32_t size;	 // Total size of the MTD
-	uint32_t erasesize;
-	uint32_t writesize;
-	uint32_t oobsize;   // Amount of OOB data per block (e.g. 16)
+	__u8 type;
+	__u32 flags;
+	__u32 size;	 // Total size of the MTD
+	__u32 erasesize;
+	__u32 writesize;
+	__u32 oobsize;   // Amount of OOB data per block (e.g. 16)
 	/* The below two fields are obsolete and broken, do not use them
 	 * (TODO: remove at some point) */
-	uint32_t ecctype;
-	uint32_t eccsize;
+	__u32 ecctype;
+	__u32 eccsize;
 };
 
 struct region_info_user {
-	uint32_t offset;		/* At which this region starts,
+	__u32 offset;		/* At which this region starts,
 					 * from the beginning of the MTD */
-	uint32_t erasesize;		/* For this region */
-	uint32_t numblocks;		/* Number of blocks in this region */
-	uint32_t regionindex;
+	__u32 erasesize;		/* For this region */
+	__u32 numblocks;		/* Number of blocks in this region */
+	__u32 regionindex;
 };
 
 struct otp_info {
-	uint32_t start;
-	uint32_t length;
-	uint32_t locked;
+	__u32 start;
+	__u32 length;
+	__u32 locked;
 };
 
 #define MEMGETINFO		_IOR('M', 1, struct mtd_info_user)
@@ -86,8 +98,8 @@ struct otp_info {
 #define MEMGETREGIONINFO	_IOWR('M', 8, struct region_info_user)
 #define MEMSETOOBSEL		_IOW('M', 9, struct nand_oobinfo)
 #define MEMGETOOBSEL		_IOR('M', 10, struct nand_oobinfo)
-#define MEMGETBADBLOCK		_IOW('M', 11, loff_t)
-#define MEMSETBADBLOCK		_IOW('M', 12, loff_t)
+#define MEMGETBADBLOCK		_IOW('M', 11, __kernel_loff_t)
+#define MEMSETBADBLOCK		_IOW('M', 12, __kernel_loff_t)
 #define OTPSELECT		_IOR('M', 13, int)
 #define OTPGETREGIONCOUNT	_IOW('M', 14, int)
 #define OTPGETREGIONINFO	_IOW('M', 15, struct otp_info)
@@ -95,21 +107,24 @@ struct otp_info {
 #define ECCGETLAYOUT		_IOR('M', 17, struct nand_ecclayout)
 #define ECCGETSTATS		_IOR('M', 18, struct mtd_ecc_stats)
 #define MTDFILEMODE		_IO('M', 19)
+#define MEMERASE64		_IOW('M', 20, struct erase_info_user64)
+#define MEMWRITEOOB64		_IOWR('M', 21, struct mtd_oob_buf64)
+#define MEMREADOOB64		_IOWR('M', 22, struct mtd_oob_buf64)
 
 /*
  * Obsolete legacy interface. Keep it in order not to break userspace
  * interfaces
  */
 struct nand_oobinfo {
-	uint32_t useecc;
-	uint32_t eccbytes;
-	uint32_t oobfree[8][2];
-	uint32_t eccpos[32];
+	__u32 useecc;
+	__u32 eccbytes;
+	__u32 oobfree[8][2];
+	__u32 eccpos[32];
 };
 
 struct nand_oobfree {
-	uint32_t offset;
-	uint32_t length;
+	__u32 offset;
+	__u32 length;
 };
 
 #define MTD_MAX_OOBFREE_ENTRIES	8
@@ -118,9 +133,9 @@ struct nand_oobfree {
  * diagnosis and to allow creation of raw images
  */
 struct nand_ecclayout {
-	uint32_t eccbytes;
-	uint32_t eccpos[64];
-	uint32_t oobavail;
+	__u32 eccbytes;
+	__u32 eccpos[64];
+	__u32 oobavail;
 	struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES];
 };
 
@@ -133,10 +148,10 @@ struct nand_ecclayout {
  * @bbtblocks:	number of blocks reserved for bad block tables
  */
 struct mtd_ecc_stats {
-	uint32_t corrected;
-	uint32_t failed;
-	uint32_t badblocks;
-	uint32_t bbtblocks;
+	__u32 corrected;
+	__u32 failed;
+	__u32 badblocks;
+	__u32 bbtblocks;
 };
 
 /*

  reply	other threads:[~2009-07-07 16:22 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-07 14:03 mtd-utils warnings Jörn Engel
2009-07-07 16:22 ` Jörn Engel [this message]
2009-07-07 16:25   ` [Patch] Support large devices for flash_eraseaal Jörn Engel
2009-07-07 16:29     ` 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=20090707162231.GA26579@logfs.org \
    --to=joern@logfs.org \
    --cc=jwboyer@gmail.com \
    --cc=linux-mtd@lists.infradead.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.