* [PATCH v5 1/3] mtd-utils: update to latest mtd-abi.h from kernel.org
@ 2010-05-13 2:22 Kevin Cernekee
2010-05-13 2:23 ` [PATCH v5 2/3] mtd-utils: support >4GiB devices Kevin Cernekee
2010-05-13 2:24 ` [PATCH v5 3/3] mtd-utils: clean up compiler warnings Kevin Cernekee
0 siblings, 2 replies; 6+ messages in thread
From: Kevin Cernekee @ 2010-05-13 2:22 UTC (permalink / raw)
To: dedekind1, saeed.bishara, jwboyer; +Cc: linux-mtd
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
---
include/mtd/mtd-abi.h | 89 ++++++++++++++++++++++++++++--------------------
1 files changed, 52 insertions(+), 37 deletions(-)
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;
};
/*
--
1.6.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v5 2/3] mtd-utils: support >4GiB devices
2010-05-13 2:22 [PATCH v5 1/3] mtd-utils: update to latest mtd-abi.h from kernel.org Kevin Cernekee
@ 2010-05-13 2:23 ` Kevin Cernekee
2010-05-13 10:11 ` Artem Bityutskiy
2010-05-13 2:24 ` [PATCH v5 3/3] mtd-utils: clean up compiler warnings Kevin Cernekee
1 sibling, 1 reply; 6+ messages in thread
From: Kevin Cernekee @ 2010-05-13 2:23 UTC (permalink / raw)
To: dedekind1, saeed.bishara, jwboyer; +Cc: linux-mtd
This patch updates the following programs to handle >4GiB flash devices:
flash_erase
flash_eraseall
flashcp
mtd_debug
nanddump
nandtest
nandwrite
It also lays the groundwork for >4GiB support in:
flash_lock
flash_unlock
The latter two utilities would require MEMLOCK64 / MEMUNLOCK64
functionality on the kernel side (currently unimplemented). For now
they still use MEMLOCK / MEMUNLOCK and cannot access blocks above 4GiB.
By default, the compatibility layer (mtd_ioctl.c) will attempt to use
the MTD sysfs interface and MEM*64 ioctls in 2.6.31+. It will fall back
to the older ABI if it determines that the running kernel does not
support the new calls.
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
---
Makefile | 19 +++-
flash_erase.c | 59 ++++++----
flash_eraseall.c | 31 +++--
flash_lock.c | 21 ++--
flash_unlock.c | 9 +-
flashcp.c | 22 ++--
mtd_debug.c | 114 ++++++++++---------
mtd_ioctl.c | 307 +++++++++++++++++++++++++++++++++++++++++++++++++
mtd_ioctl.h | 39 ++++++
nanddump.c | 23 +++--
nandtest.c | 35 +++---
nandwrite.c | 60 +++++-----
13 files changed, 570 insertions(+), 171 deletions(-)
create mode 100644 mtd_ioctl.c
create mode 100644 mtd_ioctl.h
diff --git a/Makefile b/Makefile
index 577634f..5bf1292 100644
--- a/Makefile
+++ b/Makefile
@@ -41,7 +41,24 @@ $(BUILDDIR)/mkfs.jffs2: $(addprefix $(BUILDDIR)/,\
LDFLAGS_mkfs.jffs2 = $(ZLIBLDFLAGS) $(LZOLDFLAGS)
LDLIBS_mkfs.jffs2 = -lz -llzo2
-$(BUILDDIR)/flash_eraseall: $(BUILDDIR)/crc32.o $(BUILDDIR)/flash_eraseall.o
+$(BUILDDIR)/flash_eraseall: $(BUILDDIR)/crc32.o $(BUILDDIR)/flash_eraseall.o \
+ $(BUILDDIR)/mtd_ioctl.o
+
+$(BUILDDIR)/flash_erase: $(BUILDDIR)/flash_erase.o $(BUILDDIR)/mtd_ioctl.o
+
+$(BUILDDIR)/nandwrite: $(BUILDDIR)/nandwrite.o $(BUILDDIR)/mtd_ioctl.o
+
+$(BUILDDIR)/nandtest: $(BUILDDIR)/nandtest.o $(BUILDDIR)/mtd_ioctl.o
+
+$(BUILDDIR)/nanddump: $(BUILDDIR)/nanddump.o $(BUILDDIR)/mtd_ioctl.o
+
+$(BUILDDIR)/flashcp: $(BUILDDIR)/flashcp.o $(BUILDDIR)/mtd_ioctl.o
+
+$(BUILDDIR)/flash_lock: $(BUILDDIR)/flash_lock.o $(BUILDDIR)/mtd_ioctl.o
+
+$(BUILDDIR)/flash_unlock: $(BUILDDIR)/flash_unlock.o $(BUILDDIR)/mtd_ioctl.o
+
+$(BUILDDIR)/mtd_debug: $(BUILDDIR)/mtd_debug.o $(BUILDDIR)/mtd_ioctl.o
$(BUILDDIR)/jffs2reader: $(BUILDDIR)/jffs2reader.o
LDFLAGS_jffs2reader = $(ZLIBLDFLAGS) $(LZOLDFLAGS)
diff --git a/flash_erase.c b/flash_erase.c
index fdf9918..f689cf5 100644
--- a/flash_erase.c
+++ b/flash_erase.c
@@ -11,22 +11,25 @@
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <mtd/mtd-user.h>
+#include "mtd_ioctl.h"
-int region_erase(int Fd, int start, int count, int unlock, int regcount)
+int region_erase(int Fd, long long start, int count, int unlock, int regcount)
{
int i, j;
- region_info_t * reginfo;
+ region_info64_t * reginfo;
reginfo = calloc(regcount, sizeof(region_info_t));
for(i = 0; i < regcount; i++)
{
reginfo[i].regionindex = i;
- if(ioctl(Fd,MEMGETREGIONINFO,&(reginfo[i])) != 0)
+ if(mtd_ioctl_getregioninfo(Fd,&(reginfo[i])) != 0)
return 8;
else
- printf("Region %d is at %d of %d sector and with sector "
- "size %x\n", i, reginfo[i].offset, reginfo[i].numblocks,
+ printf("Region %d is at %lld of %d sector and with sector "
+ "size %x\n", i,
+ (unsigned long long)reginfo[i].offset,
+ reginfo[i].numblocks,
reginfo[i].erasesize);
}
@@ -34,7 +37,7 @@ int region_erase(int Fd, int start, int count, int unlock, int regcount)
for(i = 0; i < regcount; i++)
{ //Loop through the regions
- region_info_t * r = &(reginfo[i]);
+ region_info64_t * r = &(reginfo[i]);
if((start >= reginfo[i].offset) &&
(start < (r->offset + r->numblocks*r->erasesize)))
@@ -43,7 +46,7 @@ int region_erase(int Fd, int start, int count, int unlock, int regcount)
if(i >= regcount)
{
- printf("Starting offset %x not within chip.\n", start);
+ printf("Starting offset %llx not within chip.\n", start);
return 8;
}
@@ -52,25 +55,28 @@ int region_erase(int Fd, int start, int count, int unlock, int regcount)
for(j = 0; (j < count)&&(i < regcount); j++)
{
- erase_info_t erase;
- region_info_t * r = &(reginfo[i]);
+ erase_info64_t erase;
+ region_info64_t * r = &(reginfo[i]);
+
+ memset(&erase, 0, sizeof(erase));
erase.start = start;
erase.length = r->erasesize;
if(unlock != 0)
{ //Unlock the sector first.
- if(ioctl(Fd, MEMUNLOCK, &erase) != 0)
+ if(mtd_ioctl_unlock(Fd, &erase) != 0)
{
perror("\nMTD Unlock failure");
close(Fd);
return 8;
}
}
- printf("\rPerforming Flash Erase of length %u at offset 0x%x",
- erase.length, erase.start);
+ printf("\rPerforming Flash Erase of length %llu at offset 0x%llx",
+ (unsigned long long)erase.length,
+ (unsigned long long)erase.start);
fflush(stdout);
- if(ioctl(Fd, MEMERASE, &erase) != 0)
+ if(mtd_ioctl_erase(Fd, &erase) != 0)
{
perror("\nMTD Erase failure");
close(Fd);
@@ -91,28 +97,31 @@ int region_erase(int Fd, int start, int count, int unlock, int regcount)
return 0;
}
-int non_region_erase(int Fd, int start, int count, int unlock)
+int non_region_erase(int Fd, long long start, int count, int unlock)
{
- mtd_info_t meminfo;
+ mtd_info64_t meminfo;
- if (ioctl(Fd,MEMGETINFO,&meminfo) == 0)
+ if (mtd_ioctl_getinfo(Fd,&meminfo) == 0)
{
- erase_info_t erase;
+ erase_info64_t erase;
- erase.start = start;
+ memset(&erase, 0, sizeof(erase));
+ erase.start = start;
erase.length = meminfo.erasesize;
for (; count > 0; count--) {
- printf("\rPerforming Flash Erase of length %u at offset 0x%x",
- erase.length, erase.start);
+ printf("\rPerforming Flash Erase of length %llu at offset 0x%llx",
+ (unsigned long long)erase.length,
+ (unsigned long long)erase.start);
fflush(stdout);
if(unlock != 0)
{
//Unlock the sector first.
- printf("\rPerforming Flash unlock at offset 0x%x",erase.start);
- if(ioctl(Fd, MEMUNLOCK, &erase) != 0)
+ printf("\rPerforming Flash unlock at offset 0x%llx",
+ (unsigned long long)erase.start);
+ if(mtd_ioctl_unlock(Fd, &erase) != 0)
{
perror("\nMTD Unlock failure");
close(Fd);
@@ -120,7 +129,7 @@ int non_region_erase(int Fd, int start, int count, int unlock)
}
}
- if (ioctl(Fd,MEMERASE,&erase) != 0)
+ if (mtd_ioctl_erase(Fd,&erase) != 0)
{
perror("\nMTD Erase failure");
close(Fd);
@@ -137,7 +146,7 @@ int main(int argc,char *argv[])
{
int regcount;
int Fd;
- int start;
+ long long start;
int count;
int unlock;
int res = 0;
@@ -149,7 +158,7 @@ int main(int argc,char *argv[])
}
if (argc > 2)
- start = strtol(argv[2], NULL, 0);
+ start = strtoll(argv[2], NULL, 0);
else
start = 0;
diff --git a/flash_eraseall.c b/flash_eraseall.c
index a22fc49..8f44570 100644
--- a/flash_eraseall.c
+++ b/flash_eraseall.c
@@ -36,6 +36,7 @@
#include <sys/ioctl.h>
#include <sys/mount.h>
#include "crc32.h"
+#include "mtd_ioctl.h"
#include <mtd/mtd-user.h>
#include <mtd/jffs2-user.h>
@@ -49,7 +50,7 @@ static int quiet; /* true -- don't output progress */
static int jffs2; // format for jffs2 usage
static void process_options (int argc, char *argv[]);
-void show_progress (mtd_info_t *meminfo, erase_info_t *erase);
+void show_progress (mtd_info64_t *meminfo, erase_info64_t *erase);
static void display_help (void);
static void display_version (void);
static struct jffs2_unknown_node cleanmarker;
@@ -57,9 +58,9 @@ int target_endian = __BYTE_ORDER;
int main (int argc, char *argv[])
{
- mtd_info_t meminfo;
+ mtd_info64_t meminfo;
int fd, clmpos = 0, clmlen = 8;
- erase_info_t erase;
+ erase_info64_t erase;
int isNAND, bbtest = 1;
process_options(argc, argv);
@@ -70,11 +71,12 @@ int main (int argc, char *argv[])
}
- if (ioctl(fd, MEMGETINFO, &meminfo) != 0) {
+ if (mtd_ioctl_getinfo(fd, &meminfo) != 0) {
fprintf(stderr, "%s: %s: unable to get MTD device info\n", exe_name, mtd_device);
return 1;
}
+ memset(&erase, 0, sizeof(erase));
erase.length = meminfo.erasesize;
isNAND = meminfo.type == MTD_NANDFLASH ? 1 : 0;
@@ -130,7 +132,8 @@ 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",
+ (unsigned long long)erase.start);
continue;
} else if (ret < 0) {
if (errno == EOPNOTSUPP) {
@@ -149,7 +152,7 @@ int main (int argc, char *argv[])
if (!quiet)
show_progress(&meminfo, &erase);
- if (ioctl(fd, MEMERASE, &erase) != 0) {
+ if (mtd_ioctl_erase(fd, &erase) != 0) {
fprintf(stderr, "\n%s: %s: MTD Erase failure: %s\n", exe_name, mtd_device, strerror(errno));
continue;
}
@@ -160,11 +163,12 @@ int main (int argc, char *argv[])
/* write cleanmarker */
if (isNAND) {
- struct mtd_oob_buf oob;
- oob.ptr = (unsigned char *) &cleanmarker;
+ struct mtd_oob_buf64 oob;
+ memset(&oob, 0, sizeof(oob));
+ oob.usr_ptr = (uintptr_t) &cleanmarker;
oob.start = erase.start + clmpos;
oob.length = clmlen;
- if (ioctl (fd, MEMWRITEOOB, &oob) != 0) {
+ if (mtd_ioctl_writeoob(fd, &oob) != 0) {
fprintf(stderr, "\n%s: %s: MTD writeoob failure: %s\n", exe_name, mtd_device, strerror(errno));
continue;
}
@@ -179,7 +183,8 @@ int main (int argc, char *argv[])
}
}
if (!quiet)
- printf (" Cleanmarker written at %x.", erase.start);
+ printf (" Cleanmarker written at %llx.",
+ (unsigned long long)erase.start);
}
if (!quiet) {
show_progress(&meminfo, &erase);
@@ -250,10 +255,10 @@ 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 (mtd_info64_t *meminfo, erase_info64_t *erase)
{
- printf("\rErasing %d Kibyte @ %x -- %2llu %% complete.",
- meminfo->erasesize / 1024, erase->start,
+ printf("\rErasing %d Kibyte @ %llx -- %2llu %% complete.",
+ meminfo->erasesize / 1024, (unsigned long long)erase->start,
(unsigned long long) erase->start * 100 / meminfo->size);
fflush(stdout);
}
diff --git a/flash_lock.c b/flash_lock.c
index 37f2ad3..a8a8241 100644
--- a/flash_lock.c
+++ b/flash_lock.c
@@ -15,14 +15,15 @@
#include <string.h>
#include <mtd/mtd-user.h>
+#include "mtd_ioctl.h"
int main(int argc, char *argv[])
{
int fd;
- struct mtd_info_user mtdInfo;
- struct erase_info_user mtdLockInfo;
- int num_sectors;
- int ofs;
+ struct mtd_info_user64 mtdInfo;
+ struct erase_info_user64 mtdLockInfo;
+ long long num_sectors;
+ long long ofs;
/*
* Parse command line options
@@ -45,17 +46,17 @@ int main(int argc, char *argv[])
exit(1);
}
- if(ioctl(fd, MEMGETINFO, &mtdInfo))
+ if(mtd_ioctl_getinfo(fd, &mtdInfo))
{
fprintf(stderr, "Could not get MTD device info from %s\n", argv[1]);
close(fd);
exit(1);
}
- sscanf(argv[2], "%x",&ofs);
- sscanf(argv[3], "%d",&num_sectors);
+ sscanf(argv[2], "%llx",&ofs);
+ sscanf(argv[3], "%lld",&num_sectors);
if(ofs > mtdInfo.size - mtdInfo.erasesize)
{
- fprintf(stderr, "%x is beyond device size %x\n",ofs,(unsigned int)(mtdInfo.size - mtdInfo.erasesize));
+ fprintf(stderr, "%llx is beyond device size %llx\n",ofs,(unsigned long long)(mtdInfo.size - mtdInfo.erasesize));
exit(1);
}
@@ -65,14 +66,14 @@ int main(int argc, char *argv[])
else {
if(num_sectors > mtdInfo.size/mtdInfo.erasesize)
{
- fprintf(stderr, "%d are too many sectors, device only has %d\n",num_sectors,(int)(mtdInfo.size/mtdInfo.erasesize));
+ fprintf(stderr, "%lld are too many sectors, device only has %lld\n",num_sectors,(long long)(mtdInfo.size/mtdInfo.erasesize));
exit(1);
}
}
mtdLockInfo.start = ofs;
mtdLockInfo.length = (num_sectors - 1) * mtdInfo.erasesize;
- if(ioctl(fd, MEMLOCK, &mtdLockInfo))
+ if(mtd_ioctl_lock(fd, &mtdLockInfo))
{
fprintf(stderr, "Could not lock MTD device: %s\n", argv[1]);
close(fd);
diff --git a/flash_unlock.c b/flash_unlock.c
index 3969453..9921996 100644
--- a/flash_unlock.c
+++ b/flash_unlock.c
@@ -15,12 +15,13 @@
#include <string.h>
#include <mtd/mtd-user.h>
+#include "mtd_ioctl.h"
int main(int argc, char *argv[])
{
int fd;
- struct mtd_info_user mtdInfo;
- struct erase_info_user mtdLockInfo;
+ struct mtd_info_user64 mtdInfo;
+ struct erase_info_user64 mtdLockInfo;
int count;
/*
@@ -44,7 +45,7 @@ int main(int argc, char *argv[])
exit(1);
}
- if(ioctl(fd, MEMGETINFO, &mtdInfo))
+ if(mtd_ioctl_getinfo(fd, &mtdInfo))
{
fprintf(stderr, "Could not get MTD device info from %s\n", argv[1]);
close(fd);
@@ -63,7 +64,7 @@ int main(int argc, char *argv[])
mtdLockInfo.length = mtdInfo.size - mtdInfo.erasesize;
}
- if(ioctl(fd, MEMUNLOCK, &mtdLockInfo))
+ if(mtd_ioctl_unlock(fd, &mtdLockInfo))
{
fprintf(stderr, "Could not unlock MTD device: %s\n", argv[1]);
close(fd);
diff --git a/flashcp.c b/flashcp.c
index 8775022..d9bab84 100644
--- a/flashcp.c
+++ b/flashcp.c
@@ -40,6 +40,7 @@
#include <unistd.h>
#include <mtd/mtd-user.h>
#include <getopt.h>
+#include "mtd_ioctl.h"
typedef int bool;
#define true 1
@@ -169,8 +170,8 @@ int main (int argc,char *argv[])
int i,flags = FLAG_NONE;
ssize_t result;
size_t size,written;
- struct mtd_info_user mtd;
- struct erase_info_user erase;
+ struct mtd_info_user64 mtd;
+ struct erase_info_user64 erase;
struct stat filestat;
unsigned char src[BUFSIZE],dest[BUFSIZE];
@@ -226,7 +227,7 @@ int main (int argc,char *argv[])
/* get some info about the flash device */
dev_fd = safe_open (device,O_SYNC | O_RDWR);
- if (ioctl (dev_fd,MEMGETINFO,&mtd) < 0)
+ if (mtd_ioctl_getinfo (dev_fd,&mtd) < 0)
{
DEBUG("ioctl(): %m\n");
log_printf (LOG_ERROR,"This doesn't seem to be a valid MTD flash device!\n");
@@ -254,6 +255,7 @@ int main (int argc,char *argv[])
#warning "Check for smaller erase regions"
+ memset(&erase, 0, sizeof(erase));
erase.start = 0;
erase.length = (filestat.st_size + mtd.erasesize - 1) / mtd.erasesize;
erase.length *= mtd.erasesize;
@@ -261,18 +263,18 @@ int main (int argc,char *argv[])
if (flags & FLAG_VERBOSE)
{
/* if the user wants verbose output, erase 1 block at a time and show him/her what's going on */
- int blocks = erase.length / mtd.erasesize;
+ long long blocks = erase.length / mtd.erasesize;
erase.length = mtd.erasesize;
log_printf (LOG_NORMAL,"Erasing blocks: 0/%d (0%%)",blocks);
for (i = 1; i <= blocks; i++)
{
log_printf (LOG_NORMAL,"\rErasing blocks: %d/%d (%d%%)",i,blocks,PERCENTAGE (i,blocks));
- if (ioctl (dev_fd,MEMERASE,&erase) < 0)
+ if (mtd_ioctl_erase (dev_fd, &erase) < 0)
{
log_printf (LOG_NORMAL,"\n");
log_printf (LOG_ERROR,
- "While erasing blocks 0x%.8x-0x%.8x on %s: %m\n",
- (unsigned int) erase.start,(unsigned int) (erase.start + erase.length),device);
+ "While erasing blocks 0x%.8llx-0x%.8llx on %s: %m\n",
+ erase.start, (erase.start + erase.length),device);
exit (EXIT_FAILURE);
}
erase.start += mtd.erasesize;
@@ -282,11 +284,11 @@ int main (int argc,char *argv[])
else
{
/* if not, erase the whole chunk in one shot */
- if (ioctl (dev_fd,MEMERASE,&erase) < 0)
+ if (mtd_ioctl_erase (dev_fd, &erase) < 0)
{
log_printf (LOG_ERROR,
- "While erasing blocks from 0x%.8x-0x%.8x on %s: %m\n",
- (unsigned int) erase.start,(unsigned int) (erase.start + erase.length),device);
+ "While erasing blocks from 0x%.8llx-0x%.8llx on %s: %m\n",
+ erase.start, (erase.start + erase.length),device);
exit (EXIT_FAILURE);
}
}
diff --git a/mtd_debug.c b/mtd_debug.c
index 49a4567..1020fe2 100644
--- a/mtd_debug.c
+++ b/mtd_debug.c
@@ -37,28 +37,13 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <mtd/mtd-user.h>
-
-/*
- * MEMGETINFO
- */
-static int getmeminfo (int fd,struct mtd_info_user *mtd)
-{
- return (ioctl (fd,MEMGETINFO,mtd));
-}
-
-/*
- * MEMERASE
- */
-static int memerase (int fd,struct erase_info_user *erase)
-{
- return (ioctl (fd,MEMERASE,erase));
-}
+#include "mtd_ioctl.h"
/*
* MEMGETREGIONCOUNT
- * MEMGETREGIONINFO
+ * MEMGETREGIONINFO64
*/
-static int getregions (int fd,struct region_info_user *regions,int *n)
+static int getregions (int fd,struct region_info_user64 *regions,int *n)
{
int i,err;
err = ioctl (fd,MEMGETREGIONCOUNT,n);
@@ -66,44 +51,48 @@ static int getregions (int fd,struct region_info_user *regions,int *n)
for (i = 0; i < *n; i++)
{
regions[i].regionindex = i;
- err = ioctl (fd,MEMGETREGIONINFO,®ions[i]);
+ err = mtd_ioctl_getregioninfo (fd,®ions[i]);
if (err) return (err);
}
return (0);
}
-int erase_flash (int fd,u_int32_t offset,u_int32_t bytes)
+int erase_flash (int fd,u_int64_t offset,u_int64_t bytes)
{
int err;
- struct erase_info_user erase;
+ struct erase_info_user64 erase;
+
+ memset(&erase, 0, sizeof(erase));
erase.start = offset;
erase.length = bytes;
- err = memerase (fd,&erase);
+
+ err = mtd_ioctl_erase (fd,&erase);
if (err < 0)
{
perror ("MEMERASE");
return (1);
}
- fprintf (stderr,"Erased %d bytes from address 0x%.8x in flash\n",bytes,offset);
+ fprintf (stderr,"Erased %lld bytes from address 0x%.8llx in flash\n",
+ (unsigned long long)bytes, (unsigned long long)offset);
return (0);
}
-void printsize (u_int32_t x)
+void printsize (u_int64_t x)
{
int i;
static const char *flags = "KMGT";
- printf ("%u ",x);
+ printf ("%llu ", (unsigned long long)x);
for (i = 0; x >= 1024 && flags[i] != '\0'; i++) x /= 1024;
i--;
- if (i >= 0) printf ("(%u%c)",x,flags[i]);
+ if (i >= 0) printf ("(%llu%c)",(unsigned long long)x,flags[i]);
}
-int flash_to_file (int fd,u_int32_t offset,size_t len,const char *filename)
+int flash_to_file (int fd, off_t offset,size_t len,const char *filename)
{
u_int8_t *buf = NULL;
int outfd,err;
- int size = len * sizeof (u_int8_t);
- int n = len;
+ size_t size = len * sizeof (u_int8_t);
+ size_t n = len;
if (offset != lseek (fd,offset,SEEK_SET))
{
@@ -121,10 +110,12 @@ retry:
if ((buf = (u_int8_t *) malloc (size)) == NULL)
{
#define BUF_SIZE (64 * 1024 * sizeof (u_int8_t))
- fprintf (stderr, "%s: malloc(%#x)\n", __FUNCTION__, size);
+ fprintf (stderr, "%s: malloc(%#x)\n", __FUNCTION__,
+ (unsigned int)size);
if (size != BUF_SIZE) {
size = BUF_SIZE;
- fprintf (stderr, "%s: trying buffer size %#x\n", __FUNCTION__, size);
+ fprintf (stderr, "%s: trying buffer size %#x\n",
+ __FUNCTION__, (unsigned int)size);
goto retry;
}
perror ("malloc()");
@@ -136,20 +127,25 @@ retry:
err = read (fd,buf,size);
if (err < 0)
{
- fprintf (stderr, "%s: read, size %#x, n %#x\n", __FUNCTION__, size, n);
+ fprintf (stderr, "%s: read, size %#x, n %#x\n",
+ __FUNCTION__, (unsigned int)size,
+ (unsigned int)n);
perror ("read()");
goto err2;
}
err = write (outfd,buf,size);
if (err < 0)
{
- fprintf (stderr, "%s: write, size %#x, n %#x\n", __FUNCTION__, size, n);
+ fprintf (stderr, "%s: write, size %#x, n %#x\n",
+ __FUNCTION__, (unsigned int)size,
+ (unsigned int)n);
perror ("write()");
goto err2;
}
if (err != size)
{
- fprintf (stderr,"Couldn't copy entire buffer to %s. (%d/%d bytes copied)\n",filename,err,size);
+ fprintf (stderr,"Couldn't copy entire buffer to %s. (%d/%d bytes copied)\n",
+ filename,err,(int)size);
goto err2;
}
n -= size;
@@ -158,7 +154,8 @@ retry:
if (buf != NULL)
free (buf);
close (outfd);
- printf ("Copied %d bytes from address 0x%.8x in flash to %s\n",len,offset,filename);
+ printf ("Copied %d bytes from address 0x%.8llx in flash to %s\n",
+ (int)len,(unsigned long long)offset,filename);
return (0);
err2:
@@ -170,13 +167,13 @@ err0:
return (1);
}
-int file_to_flash (int fd,u_int32_t offset,u_int32_t len,const char *filename)
+int file_to_flash (int fd, off_t offset, size_t len,const char *filename)
{
u_int8_t *buf = NULL;
FILE *fp;
int err;
- int size = len * sizeof (u_int8_t);
- int n = len;
+ size_t size = len * sizeof (u_int8_t);
+ size_t n = len;
if (offset != lseek (fd,offset,SEEK_SET))
{
@@ -191,10 +188,12 @@ int file_to_flash (int fd,u_int32_t offset,u_int32_t len,const char *filename)
retry:
if ((buf = (u_int8_t *) malloc (size)) == NULL)
{
- fprintf (stderr, "%s: malloc(%#x) failed\n", __FUNCTION__, size);
+ fprintf (stderr, "%s: malloc(%#x) failed\n",
+ __FUNCTION__, (int)size);
if (size != BUF_SIZE) {
size = BUF_SIZE;
- fprintf (stderr, "%s: trying buffer size %#x\n", __FUNCTION__, size);
+ fprintf (stderr, "%s: trying buffer size %#x\n",
+ __FUNCTION__, (int)size);
goto retry;
}
perror ("malloc()");
@@ -206,7 +205,9 @@ retry:
size = n;
if (fread (buf,size,1,fp) != 1 || ferror (fp))
{
- fprintf (stderr, "%s: fread, size %#x, n %#x\n", __FUNCTION__, size, n);
+ fprintf (stderr, "%s: fread, size %#x, n %#x\n",
+ __FUNCTION__, (unsigned int)size,
+ (unsigned int)n);
perror ("fread()");
free (buf);
fclose (fp);
@@ -215,7 +216,9 @@ retry:
err = write (fd,buf,size);
if (err < 0)
{
- fprintf (stderr, "%s: write, size %#x, n %#x\n", __FUNCTION__, size, n);
+ fprintf (stderr, "%s: write, size %#x, n %#x\n",
+ __FUNCTION__, (unsigned int)size,
+ (unsigned int)n);
perror ("write()");
free (buf);
fclose (fp);
@@ -227,23 +230,26 @@ retry:
if (buf != NULL)
free (buf);
fclose (fp);
- printf ("Copied %d bytes from %s to address 0x%.8x in flash\n",len,filename,offset);
+ printf ("Copied %d bytes from %s to address 0x%.8llx in flash\n",
+ (int)len,filename,(unsigned long long)offset);
return (0);
}
int showinfo (int fd)
{
int i,err,n;
- struct mtd_info_user mtd;
- static struct region_info_user region[1024];
+ struct mtd_info_user64 mtd;
+ static struct region_info_user64 region[1024];
- err = getmeminfo (fd,&mtd);
+ err = mtd_ioctl_getinfo (fd,&mtd);
if (err < 0)
{
- perror ("MEMGETINFO");
+ perror ("MEMGETINFO64");
return (1);
}
+ memset(region, 0, sizeof(region));
+
err = getregions (fd,region,&n);
if (err < 0)
{
@@ -301,7 +307,7 @@ int showinfo (int fd)
{ "MTD_WRITEABLE", MTD_WRITEABLE },
{ "MTD_BIT_WRITEABLE", MTD_BIT_WRITEABLE },
{ "MTD_NO_ERASE", MTD_NO_ERASE },
- { "MTD_STUPID_LOCK", MTD_STUPID_LOCK },
+ { "MTD_POWERUP_LOCK", MTD_POWERUP_LOCK },
{ NULL, -1 }
};
for (i = 0; flags[i].name != NULL; i++)
@@ -309,7 +315,7 @@ int showinfo (int fd)
{
if (first)
{
- printf (flags[i].name);
+ printf ("%s", flags[i].name);
first = 0;
}
else printf (" | %s",flags[i].name);
@@ -335,9 +341,9 @@ int showinfo (int fd)
for (i = 0; i < n; i++)
{
- printf ("region[%d].offset = 0x%.8x\n"
+ printf ("region[%d].offset = 0x%.8llx\n"
"region[%d].erasesize = ",
- i,region[i].offset,i);
+ i,(unsigned long long)region[i].offset,i);
printsize (region[i].erasesize);
printf ("\nregion[%d].numblocks = %d\n"
"region[%d].regionindex = %d\n",
@@ -399,13 +405,13 @@ int main (int argc,char *argv[])
showinfo (fd);
break;
case OPT_READ:
- err = flash_to_file (fd,strtol (argv[3],NULL,0),strtol (argv[4],NULL,0),argv[5]);
+ err = flash_to_file (fd,strtoll (argv[3],NULL,0),strtoll (argv[4],NULL,0),argv[5]);
break;
case OPT_WRITE:
- err = file_to_flash (fd,strtol (argv[3],NULL,0),strtol (argv[4],NULL,0),argv[5]);
+ err = file_to_flash (fd,strtoll (argv[3],NULL,0),strtoll (argv[4],NULL,0),argv[5]);
break;
case OPT_ERASE:
- err = erase_flash (fd,strtol (argv[3],NULL,0),strtol (argv[4],NULL,0));
+ err = erase_flash (fd,strtoll (argv[3],NULL,0),strtoll (argv[4],NULL,0));
break;
}
diff --git a/mtd_ioctl.c b/mtd_ioctl.c
new file mode 100644
index 0000000..d19dcd3
--- /dev/null
+++ b/mtd_ioctl.c
@@ -0,0 +1,307 @@
+/*
+ * mtd_ioctl.c - backward compatibility wrappers for MTD ioctls
+ */
+
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <mtd/mtd-user.h>
+#include "mtd_ioctl.h"
+
+#define BUF_LEN 64
+
+static int use_old_abi = 0;
+
+static int try_new_ioctl(int fd, unsigned int cmd, unsigned long arg, int *retp)
+{
+ int ret;
+
+ if(use_old_abi)
+ return(0);
+ ret = ioctl(fd, cmd, arg);
+ if((ret < 0) && (errno == ENOTTY)) {
+ use_old_abi = 1;
+ return(0);
+ }
+ *retp = ret;
+ return(1);
+}
+
+/**
+ * mkpath - compose full path from 2 given components.
+ * @path: the first component
+ * @name: the second component
+ *
+ * This function returns the resulting path in case of success and %NULL in
+ * case of failure.
+ */
+static char *mkpath(const char *path, const char *name)
+{
+ char *n;
+ int len1 = strlen(path);
+ int len2 = strlen(name);
+
+ n = malloc(len1 + len2 + 2);
+ if (!n) {
+ return NULL;
+ }
+
+ memcpy(n, path, len1);
+ if (n[len1 - 1] != '/')
+ n[len1++] = '/';
+
+ memcpy(n + len1, name, len2 + 1);
+ return n;
+}
+
+/**
+ * read_data - read data from a file.
+ * @file: the file to read from
+ * @buf: the buffer to read to
+ * @buf_len: buffer length
+ *
+ * This function returns number of read bytes in case of success and %-1 in
+ * case of failure. Note, if the file contains more then @buf_len bytes of
+ * date, this function fails with %EINVAL error code.
+ */
+static int sysfs_get_str(const char *prefix, const char *element,
+ char *buf, int buf_len)
+{
+ int fd, rd, tmp, tmp1;
+ char *file = mkpath(prefix, element), *sep;
+
+ if(! file)
+ return -1;
+
+ fd = open(file, O_RDONLY);
+ if (fd == -1) {
+ free(file);
+ return -1;
+ }
+
+ rd = read(fd, buf, buf_len);
+ if (rd == -1) {
+ goto out_error;
+ }
+
+ /* Make sure all data is read */
+ tmp1 = read(fd, &tmp, 1);
+ if (tmp1 == 1) {
+ goto out_error;
+ }
+ if (tmp1) {
+ errno = EINVAL;
+ goto out_error;
+ }
+
+ if (close(fd)) {
+ rd = -1;
+ }
+
+ sep = index(buf, '\n');
+ if(sep)
+ *sep = 0;
+ else
+ buf[buf_len - 1] = 0;
+
+ free(file);
+ return rd;
+
+out_error:
+ close(fd);
+ free(file);
+ return -1;
+}
+
+static int sysfs_get_ull(const char *prefix, const char *element,
+ unsigned long long *out)
+{
+ int ret;
+ char buf[BUF_LEN];
+
+ ret = sysfs_get_str(prefix, element, buf, BUF_LEN);
+ if(ret <= 0)
+ return(ret);
+
+ if(sscanf(buf, "0x%llx", out) == 1)
+ return(0);
+
+ if(sscanf(buf, "%llu", out) == 1)
+ return(0);
+
+ return(-1);
+}
+
+int mtd_ioctl_getinfo(int fd, struct mtd_info_user64 *arg)
+{
+ int ret;
+ struct mtd_info_user oldarg;
+ struct stat st;
+ char prefix[BUF_LEN], str[BUF_LEN];
+ unsigned long long tmp;
+
+ if((fstat(fd, &st) < 0) || !S_ISCHR(st.st_mode))
+ return(-1);
+
+ snprintf(prefix, BUF_LEN, "/sys/class/mtd/mtd%d/",
+ minor(st.st_rdev) >> 1);
+
+ if(sysfs_get_str(prefix, "type", str, BUF_LEN) > 0) {
+ if(strcasecmp(str, "absent") == 0)
+ arg->type = MTD_ABSENT;
+ else if(strcasecmp(str, "ram") == 0)
+ arg->type = MTD_RAM;
+ else if(strcasecmp(str, "rom") == 0)
+ arg->type = MTD_ROM;
+ else if(strcasecmp(str, "nor") == 0)
+ arg->type = MTD_NORFLASH;
+ else if(strcasecmp(str, "nand") == 0)
+ arg->type = MTD_NANDFLASH;
+ else if(strcasecmp(str, "dataflash") == 0)
+ arg->type = MTD_DATAFLASH;
+ else if(strcasecmp(str, "ubi") == 0)
+ arg->type = MTD_UBIVOLUME;
+ else
+ return(-1);
+
+ if(sysfs_get_ull(prefix, "flags", &tmp) != 0)
+ return(-1);
+ arg->flags = tmp;
+
+ if(sysfs_get_ull(prefix, "size", &tmp) != 0)
+ return(-1);
+ arg->size = tmp;
+
+ if(sysfs_get_ull(prefix, "erasesize", &tmp) != 0)
+ return(-1);
+ arg->erasesize = tmp;
+
+ if(sysfs_get_ull(prefix, "writesize", &tmp) != 0)
+ return(-1);
+ arg->writesize = tmp;
+
+ if(sysfs_get_ull(prefix, "oobsize", &tmp) != 0)
+ return(-1);
+ arg->oobsize = tmp;
+
+ return(0);
+ }
+
+ ret = ioctl(fd, MEMGETINFO, (unsigned long)&oldarg);
+ if(ret < 0)
+ return(ret);
+
+ arg->type = oldarg.type;
+ arg->flags = oldarg.flags;
+ arg->size = oldarg.size;
+ arg->erasesize = oldarg.erasesize;
+ arg->writesize = oldarg.writesize;
+ arg->oobsize = oldarg.oobsize;
+
+ return(ret);
+}
+
+int mtd_ioctl_erase(int fd, struct erase_info_user64 *arg)
+{
+ int ret;
+ struct erase_info_user oldarg;
+
+ if(try_new_ioctl(fd, MEMERASE64, (unsigned long)arg, &ret) != 0)
+ return(ret);
+
+ oldarg.start = arg->start;
+ oldarg.length = arg->length;
+
+ return(ioctl(fd, MEMERASE, (unsigned long)&oldarg));
+}
+
+int mtd_ioctl_writeoob(int fd, struct mtd_oob_buf64 *arg)
+{
+ int ret;
+ struct mtd_oob_buf oldarg;
+
+ if(try_new_ioctl(fd, MEMWRITEOOB64, (unsigned long)arg, &ret) != 0)
+ return(ret);
+
+ oldarg.start = arg->start;
+ oldarg.length = arg->length;
+ oldarg.ptr = (void *)(uintptr_t)arg->usr_ptr;
+
+ ret = ioctl(fd, MEMWRITEOOB, (unsigned long)&oldarg);
+
+ arg->length = oldarg.length;
+ return(ret);
+}
+
+int mtd_ioctl_readoob(int fd, struct mtd_oob_buf64 *arg)
+{
+ int ret;
+ struct mtd_oob_buf oldarg;
+
+ if(try_new_ioctl(fd, MEMREADOOB64, (unsigned long)arg, &ret) != 0)
+ return(ret);
+
+ oldarg.start = arg->start;
+ oldarg.length = arg->length;
+ oldarg.ptr = (void *)(uintptr_t)arg->usr_ptr;
+
+ ret = ioctl(fd, MEMREADOOB, (unsigned long)&oldarg);
+
+ /* old ABI puts returned length in "start" */
+ arg->length = oldarg.start;
+ return(ret);
+}
+
+int mtd_ioctl_lock(int fd, struct erase_info_user64 *arg)
+{
+ struct erase_info_user oldarg;
+#ifdef MEMLOCK64
+ int ret;
+
+ if(try_new_ioctl(fd, MEMLOCK64, (unsigned long)arg, &ret) != 0)
+ return(ret);
+#endif
+
+ oldarg.start = arg->start;
+ oldarg.length = arg->length;
+
+ return(ioctl(fd, MEMLOCK, (unsigned long)&oldarg));
+}
+
+int mtd_ioctl_unlock(int fd, struct erase_info_user64 *arg)
+{
+ struct erase_info_user oldarg;
+#ifdef MEMUNLOCK64
+ int ret;
+
+ if(try_new_ioctl(fd, MEMUNLOCK64, (unsigned long)arg, &ret) != 0)
+ return(ret);
+#endif
+
+ oldarg.start = arg->start;
+ oldarg.length = arg->length;
+
+ return(ioctl(fd, MEMUNLOCK, (unsigned long)&oldarg));
+}
+
+int mtd_ioctl_getregioninfo(int fd, struct region_info_user64 *arg)
+{
+ int ret;
+ struct region_info_user oldarg;
+
+ oldarg.regionindex = arg->regionindex;
+
+ ret = ioctl(fd, MEMGETREGIONINFO, (unsigned long)&oldarg);
+
+ arg->offset = oldarg.offset;
+ arg->erasesize = oldarg.erasesize;
+ arg->numblocks = oldarg.numblocks;
+
+ return(ret);
+}
diff --git a/mtd_ioctl.h b/mtd_ioctl.h
new file mode 100644
index 0000000..a479793
--- /dev/null
+++ b/mtd_ioctl.h
@@ -0,0 +1,39 @@
+/*
+ * mtd_ioctl.h - backward compatibility wrappers for MTD ioctls
+ */
+
+#ifndef _MTD_IOCTL_H
+#define _MTD_IOCTL_H
+
+#include <mtd/mtd-user.h>
+
+struct region_info_user64 {
+ uint64_t 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;
+};
+
+struct mtd_info_user64 {
+ uint32_t type;
+ uint32_t flags;
+ uint64_t size; /* Total size of the MTD */
+ uint32_t erasesize;
+ uint32_t writesize;
+ uint32_t oobsize; /* OOB bytes per page (e.g. 16) */
+};
+
+typedef struct mtd_info_user64 mtd_info64_t;
+typedef struct region_info_user64 region_info64_t;
+typedef struct erase_info_user64 erase_info64_t;
+
+int mtd_ioctl_getinfo(int fd, struct mtd_info_user64 *arg);
+int mtd_ioctl_erase(int fd, struct erase_info_user64 *arg);
+int mtd_ioctl_writeoob(int fd, struct mtd_oob_buf64 *arg);
+int mtd_ioctl_readoob(int fd, struct mtd_oob_buf64 *arg);
+int mtd_ioctl_lock(int fd, struct erase_info_user64 *arg);
+int mtd_ioctl_unlock(int fd, struct erase_info_user64 *arg);
+int mtd_ioctl_getregioninfo(int fd, struct region_info_user64 *arg);
+
+#endif /* !_MTD_IOCTL_H */
diff --git a/nanddump.c b/nanddump.c
index ae0e425..6f101d2 100644
--- a/nanddump.c
+++ b/nanddump.c
@@ -29,6 +29,7 @@
#include <asm/types.h>
#include <mtd/mtd-user.h>
+#include "mtd_ioctl.h"
#define PROGRAM "nanddump"
#define VERSION "$Revision: 1.29 $"
@@ -182,11 +183,15 @@ static unsigned char oobbuf[128];
*/
int main(int argc, char * const argv[])
{
- unsigned long ofs, end_addr = 0;
+ unsigned long long ofs, end_addr = 0;
unsigned long long blockstart = 1;
int ret, i, fd, ofd, bs, badblock = 0;
- struct mtd_oob_buf oob = {0, 16, oobbuf};
- mtd_info_t meminfo;
+ struct mtd_oob_buf64 oob = {
+ .start = 0,
+ .length = 16,
+ .usr_ptr = (uintptr_t)oobbuf,
+ };
+ mtd_info64_t meminfo;
char pretty_buf[80];
int oobinfochanged = 0 ;
struct nand_oobinfo old_oobinfo;
@@ -202,8 +207,8 @@ int main(int argc, char * const argv[])
}
/* Fill in MTD device capability structure */
- if (ioctl(fd, MEMGETINFO, &meminfo) != 0) {
- perror("MEMGETINFO");
+ if (mtd_ioctl_getinfo(fd, &meminfo) != 0) {
+ perror("MEMGETINFO64");
close(fd);
exit (EXIT_FAILURE);
}
@@ -322,11 +327,11 @@ int main(int argc, char * const argv[])
}
if (stat1.failed != stat2.failed)
fprintf(stderr, "ECC: %d uncorrectable bitflip(s)"
- " at offset 0x%08lx\n",
+ " at offset 0x%08llx\n",
stat2.failed - stat1.failed, ofs);
if (stat1.corrected != stat2.corrected)
fprintf(stderr, "ECC: %d corrected bitflip(s) at"
- " offset 0x%08lx\n",
+ " offset 0x%08llx\n",
stat2.corrected - stat1.corrected, ofs);
stat1 = stat2;
}
@@ -361,8 +366,8 @@ int main(int argc, char * const argv[])
} else {
/* Read OOB data and exit on failure */
oob.start = ofs;
- if (ioctl(fd, MEMREADOOB, &oob) != 0) {
- perror("ioctl(MEMREADOOB)");
+ if (mtd_ioctl_readoob(fd, &oob) != 0) {
+ perror("ioctl(MEMREADOOB64)");
goto closeall;
}
}
diff --git a/nandtest.c b/nandtest.c
index e31e28a..ef31130 100644
--- a/nandtest.c
+++ b/nandtest.c
@@ -14,6 +14,7 @@
#include <asm/types.h>
#include "mtd/mtd-user.h"
+#include "mtd_ioctl.h"
void usage(void)
{
@@ -28,7 +29,7 @@ void usage(void)
exit(1);
}
-struct mtd_info_user meminfo;
+struct mtd_info_user64 meminfo;
struct mtd_ecc_stats oldstats, newstats;
int fd;
int markbad=0;
@@ -36,26 +37,28 @@ int seed;
int erase_and_write(loff_t ofs, unsigned char *data, unsigned char *rbuf)
{
- struct erase_info_user er;
+ struct erase_info_user64 er;
ssize_t len;
int i;
- printf("\r%08x: erasing... ", (unsigned)ofs);
+ printf("\r%08llx: erasing... ", ofs);
fflush(stdout);
+ memset(&er, 0, sizeof(er));
+
er.start = ofs;
er.length = meminfo.erasesize;
- if (ioctl(fd, MEMERASE, &er)) {
- perror("MEMERASE");
+ if (mtd_ioctl_erase(fd, &er)) {
+ perror("MEMERASE64");
if (markbad) {
- printf("Mark block bad at %08lx\n", (long)ofs);
+ printf("Mark block bad at %08llx\n", ofs);
ioctl(fd, MEMSETBADBLOCK, &ofs);
}
return 1;
}
- printf("\r%08x: writing...", (unsigned)ofs);
+ printf("\r%08llx: writing...", ofs);
fflush(stdout);
len = pwrite(fd, data, meminfo.erasesize, ofs);
@@ -132,8 +135,8 @@ int main(int argc, char **argv)
int pass;
int nr_passes = 1;
int keep_contents = 0;
- uint32_t offset = 0;
- uint32_t length = -1;
+ uint64_t offset = 0;
+ uint64_t length = -1;
for (;;) {
static const char *short_options="hkl:mo:p:s:";
@@ -175,11 +178,11 @@ int main(int argc, char **argv)
break;
case 'o':
- offset = atol(optarg);
+ offset = atoll(optarg);
break;
case 'l':
- length = strtol(optarg, NULL, 0);
+ length = strtoll(optarg, NULL, 0);
break;
}
@@ -193,8 +196,8 @@ int main(int argc, char **argv)
exit(1);
}
- if (ioctl(fd, MEMGETINFO, &meminfo)) {
- perror("MEMGETINFO");
+ if (mtd_ioctl_getinfo(fd, &meminfo)) {
+ perror("MEMGETINFO64");
close(fd);
exit(1);
}
@@ -203,17 +206,17 @@ int main(int argc, char **argv)
length = meminfo.size;
if (offset % meminfo.erasesize) {
- fprintf(stderr, "Offset %x not multiple of erase size %x\n",
+ fprintf(stderr, "Offset %llx not multiple of erase size %x\n",
offset, meminfo.erasesize);
exit(1);
}
if (length % meminfo.erasesize) {
- fprintf(stderr, "Length %x not multiple of erase size %x\n",
+ fprintf(stderr, "Length %llx not multiple of erase size %x\n",
length, meminfo.erasesize);
exit(1);
}
if (length + offset > meminfo.size) {
- fprintf(stderr, "Length %x + offset %x exceeds device size %x\n",
+ fprintf(stderr, "Length %llx + offset %llx exceeds device size %llx\n",
length, offset, meminfo.size);
exit(1);
}
diff --git a/nandwrite.c b/nandwrite.c
index b77edd6..9684b95 100644
--- a/nandwrite.c
+++ b/nandwrite.c
@@ -38,6 +38,7 @@
#include <asm/types.h>
#include "mtd/mtd-user.h"
+#include "mtd_ioctl.h"
#define PROGRAM "nandwrite"
#define VERSION "$Revision: 1.32 $"
@@ -107,7 +108,7 @@ static void display_version (void)
static const char *standard_input = "-";
static const char *mtd_device, *img;
-static int mtdoffset = 0;
+static long long mtdoffset = 0;
static bool quiet = false;
static bool writeoob = false;
static bool autoplace = false;
@@ -188,7 +189,7 @@ static void process_options (int argc, char * const argv[])
pad = true;
break;
case 's':
- mtdoffset = strtol (optarg, NULL, 0);
+ mtdoffset = strtoll (optarg, NULL, 0);
break;
case 'b':
blockalign = atoi (optarg);
@@ -200,7 +201,7 @@ static void process_options (int argc, char * const argv[])
}
if (mtdoffset < 0) {
- fprintf(stderr, "Can't specify a negative device offset `%d'\n",
+ fprintf(stderr, "Can't specify a negative device offset `%lld'\n",
mtdoffset);
exit (EXIT_FAILURE);
}
@@ -246,9 +247,9 @@ int main(int argc, char * const argv[])
int ifd = -1;
int imglen = 0, pagelen;
bool baderaseblock = false;
- int blockstart = -1;
- struct mtd_info_user meminfo;
- struct mtd_oob_buf oob;
+ long long blockstart = -1;
+ struct mtd_info_user64 meminfo;
+ struct mtd_oob_buf64 oob;
loff_t offs;
int ret;
int oobinfochanged = 0;
@@ -280,8 +281,8 @@ int main(int argc, char * const argv[])
}
/* Fill in MTD device capability structure */
- if (ioctl(fd, MEMGETINFO, &meminfo) != 0) {
- perror("MEMGETINFO");
+ if (mtd_ioctl_getinfo(fd, &meminfo) != 0) {
+ perror("MEMGETINFO64");
close(fd);
exit (EXIT_FAILURE);
}
@@ -377,8 +378,9 @@ int main(int argc, char * const argv[])
}
}
+ memset(&oob, 0, sizeof(oob));
oob.length = meminfo.oobsize;
- oob.ptr = noecc ? oobreadbuf : oobbuf;
+ oob.usr_ptr = (uintptr_t)(noecc ? oobreadbuf : oobbuf);
/* Determine if we are reading from standard input or from a file. */
if (strcmp(img, standard_input) == 0) {
@@ -421,8 +423,9 @@ int main(int argc, char * const argv[])
// Check, if length fits into device
if ( ((imglen / pagelen) * meminfo.writesize) > (meminfo.size - mtdoffset)) {
- fprintf (stderr, "Image %d bytes, NAND page %d bytes, OOB area %u bytes, device size %u bytes\n",
- imglen, pagelen, meminfo.writesize, meminfo.size);
+ fprintf (stderr, "Image %d bytes, NAND page %d bytes, OOB area %u bytes, device size %llu bytes\n",
+ imglen, pagelen, meminfo.writesize,
+ (unsigned long long)meminfo.size);
perror ("Input file does not fit into device");
goto closeall;
}
@@ -467,7 +470,7 @@ int main(int argc, char * const argv[])
baderaseblock = false;
if (!quiet)
- fprintf (stdout, "Writing data to block %d at offset 0x%x\n",
+ fprintf (stdout, "Writing data to block %lld at offset 0x%llx\n",
blockstart / meminfo.erasesize, blockstart);
/* Check all the blocks in an erase block for bad blocks */
@@ -479,9 +482,10 @@ int main(int argc, char * const argv[])
if (ret == 1) {
baderaseblock = true;
if (!quiet)
- fprintf (stderr, "Bad block at %x, %u block(s) "
- "from %x will be skipped\n",
- (int) offs, blockalign, blockstart);
+ fprintf (stderr, "Bad block at %llx, %u block(s) "
+ "from %llx will be skipped\n",
+ (unsigned long long)offs,
+ blockalign, blockstart);
}
if (baderaseblock) {
@@ -580,7 +584,7 @@ int main(int argc, char * const argv[])
}
if (noecc) {
- oob.ptr = oobreadbuf;
+ oob.usr_ptr = (uintptr_t)oobreadbuf;
} else {
int i, start, len;
/*
@@ -610,15 +614,15 @@ int main(int argc, char * const argv[])
}
/* Write OOB data first, as ecc will be placed in there*/
oob.start = mtdoffset;
- if (ioctl(fd, MEMWRITEOOB, &oob) != 0) {
- perror ("ioctl(MEMWRITEOOB)");
+ if (mtd_ioctl_writeoob(fd, &oob) != 0) {
+ perror ("ioctl(MEMWRITEOOB64)");
goto closeall;
}
}
/* Write out the Page data */
if (pwrite(fd, writebuf, meminfo.writesize, mtdoffset) != meminfo.writesize) {
- erase_info_t erase;
+ erase_info64_t erase;
if (errno != EIO) {
perror("pwrite");
@@ -628,21 +632,21 @@ int main(int argc, char * const argv[])
/* Must rewind to blockstart if we can */
writebuf = filebuf;
+ memset(&erase, 0, sizeof(erase));
erase.start = blockstart;
erase.length = meminfo.erasesize;
- fprintf(stderr, "Erasing failed write from %08lx-%08lx\n",
- (long)erase.start, (long)erase.start+erase.length-1);
- if (ioctl(fd, MEMERASE, &erase) != 0) {
- int errno_tmp = errno;
- perror("MEMERASE");
- if (errno_tmp != EIO) {
- goto closeall;
- }
+ fprintf(stderr, "Erasing failed write from %08llx-%08llx\n",
+ (unsigned long long)erase.start,
+ (unsigned long long)(erase.start+erase.length-1));
+ if (mtd_ioctl_erase(fd, &erase) != 0) {
+ perror("MEMERASE64");
+ goto closeall;
}
if (markbad) {
loff_t bad_addr = mtdoffset & (~(meminfo.erasesize / blockalign) + 1);
- fprintf(stderr, "Marking block at %08lx bad\n", (long)bad_addr);
+ fprintf(stderr, "Marking block at %08llx bad\n",
+ (unsigned long long)bad_addr);
if (ioctl(fd, MEMSETBADBLOCK, &bad_addr)) {
perror("MEMSETBADBLOCK");
goto closeall;
--
1.6.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v5 3/3] mtd-utils: clean up compiler warnings
2010-05-13 2:22 [PATCH v5 1/3] mtd-utils: update to latest mtd-abi.h from kernel.org Kevin Cernekee
2010-05-13 2:23 ` [PATCH v5 2/3] mtd-utils: support >4GiB devices Kevin Cernekee
@ 2010-05-13 2:24 ` Kevin Cernekee
1 sibling, 0 replies; 6+ messages in thread
From: Kevin Cernekee @ 2010-05-13 2:24 UTC (permalink / raw)
To: dedekind1, saeed.bishara, jwboyer; +Cc: linux-mtd
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=us-ascii, Size: 5643 bytes --]
Seen on gcc 4.2.4 IA32:
flashcp.c:255:2: warning: #warning "Check for smaller erase regions"
nftl_format.c:214: warning: assignment discards qualifiers from pointer target type
nftl_format.c:219: warning: assignment discards qualifiers from pointer target type
serve_image.c:129: warning: format ‘%ld’ expects type ‘long int’, but argument 3 has type ‘__off64_t’
fec.c:120: warning: initialization discards qualifiers from pointer target type
<many more of these>
fec.c:417: warning: passing argument 2 of ‘my_malloc’ discards qualifiers from pointer target type
<many more of these>
recv_image.c:164: warning: comparison of unsigned expression < 0 is always false
recv_image.c:59: warning: ‘start_seq’ may be used uninitialized in this function
recv_image.c:56: warning: ‘fec’ may be used uninitialized in this function
recv_image.c:49: warning: ‘image_crc’ may be used uninitialized in this function
sumtool.c:112: warning: initialization discards qualifiers from pointer target type
sumtool.c:115: warning: initialization discards qualifiers from pointer target type
mkfs.ubifs.c:1171: warning: format ‘%lu’ expects type ‘long unsigned int’, but argument 4 has type ‘ino_t’
mkfs.ubifs.c:1171: warning: format ‘%lu’ expects type ‘long unsigned int’, but argument 6 has type ‘ino_t’
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
---
fec.c | 6 +++---
mkfs.ubifs/mkfs.ubifs.c | 4 ++--
nftl_format.c | 3 ++-
recv_image.c | 8 ++++----
serve_image.c | 5 +++--
sumtool.c | 4 ++--
6 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/fec.c b/fec.c
index 6d9020f..bee371e 100644
--- a/fec.c
+++ b/fec.c
@@ -114,7 +114,7 @@ typedef unsigned short gf;
* Primitive polynomials - see Lin & Costello, Appendix A,
* and Lee & Messerschmitt, p. 453.
*/
-static char *allPp[] = { /* GF_BITS polynomial */
+static const char *allPp[] = { /* GF_BITS polynomial */
NULL, /* 0 no code */
NULL, /* 1 no code */
"111", /* 2 1+x+x^2 */
@@ -226,7 +226,7 @@ gf_mul(x,y)
* one place.
*/
static void *
-my_malloc(int sz, char *err_string)
+my_malloc(int sz, const char *err_string)
{
void *p = malloc( sz );
if (p == NULL) {
@@ -247,7 +247,7 @@ generate_gf(void)
{
int i;
gf mask;
- char *Pp = allPp[GF_BITS] ;
+ const char *Pp = allPp[GF_BITS] ;
mask = 1; /* x ** 0 = 1 */
gf_exp[GF_BITS] = 0; /* will be updated at the end of the 1st loop */
diff --git a/mkfs.ubifs/mkfs.ubifs.c b/mkfs.ubifs/mkfs.ubifs.c
index e4b4e3c..4d1971c 100644
--- a/mkfs.ubifs/mkfs.ubifs.c
+++ b/mkfs.ubifs/mkfs.ubifs.c
@@ -1168,8 +1168,8 @@ static int add_dent_node(ino_t dir_inum, const char *name, ino_t inum,
char *kname;
int len;
- dbg_msg(3, "%s ino %lu type %u dir ino %lu", name, inum,
- (unsigned)type, dir_inum);
+ dbg_msg(3, "%s ino %lu type %u dir ino %lu", name, (unsigned long)inum,
+ (unsigned)type, (unsigned long)dir_inum);
memset(dent, 0, UBIFS_DENT_NODE_SZ);
dname.name = (void *)name;
diff --git a/nftl_format.c b/nftl_format.c
index 42949a0..167098a 100644
--- a/nftl_format.c
+++ b/nftl_format.c
@@ -202,7 +202,8 @@ int main(int argc, char **argv)
long MediaUnitOff1 = 0, MediaUnitOff2 = 0;
unsigned char oobbuf[16];
struct mtd_oob_buf oob = {0, 16, oobbuf};
- char *mtddevice, *nftl;
+ char *mtddevice;
+ const char *nftl;
int c, do_inftl = 0, do_bbt = 0;
diff --git a/recv_image.c b/recv_image.c
index d65aa2a..6ff0bce 100644
--- a/recv_image.c
+++ b/recv_image.c
@@ -39,24 +39,24 @@ int main(int argc, char **argv)
struct addrinfo *runp;
int ret;
int sock;
- size_t len;
+ ssize_t len;
int flfd;
struct mtd_info_user meminfo;
unsigned char *eb_buf, *decode_buf, **src_pkts;
int nr_blocks = 0;
int pkts_per_block;
int block_nr = -1;
- uint32_t image_crc;
+ uint32_t image_crc = 0;
int total_pkts = 0;
int ignored_pkts = 0;
loff_t mtdoffset = 0;
int badcrcs = 0;
int duplicates = 0;
int file_mode = 0;
- struct fec_parms *fec;
+ struct fec_parms *fec = NULL;
int i;
struct eraseblock *eraseblocks = NULL;
- uint32_t start_seq;
+ uint32_t start_seq = 0;
struct timeval start, now;
unsigned long fec_time = 0, flash_time = 0, crc_time = 0,
rflash_time = 0, erase_time = 0, net_time = 0;
diff --git a/serve_image.c b/serve_image.c
index adb4869..292e7f6 100644
--- a/serve_image.c
+++ b/serve_image.c
@@ -125,8 +125,9 @@ int main(int argc, char **argv)
}
if (st.st_size % erasesize) {
- fprintf(stderr, "Image size %ld bytes is not a multiple of erasesize %d bytes\n",
- st.st_size, erasesize);
+ fprintf(stderr, "Image size %lld bytes is not a multiple "
+ "of erasesize %d bytes\n",
+ (long long)st.st_size, erasesize);
exit(1);
}
image = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, rfd, 0);
diff --git a/sumtool.c b/sumtool.c
index 6bb7168..9a2029f 100644
--- a/sumtool.c
+++ b/sumtool.c
@@ -88,7 +88,7 @@ static struct option long_options[] = {
{NULL, 0, NULL, 0}
};
-static char *helptext =
+static const char *helptext =
"Usage: sumtool [OPTIONS] -i inputfile -o outputfile\n\n"
"Convert the input JFFS2 image to a summarized JFFS2 image\n"
"Summary makes mounting faster - if summary support enabled in your kernel\n\n"
@@ -112,7 +112,7 @@ static char *helptext =
" eraseblock\n\n";
-static char *revtext = "$Revision: 1.9 $";
+static const char *revtext = "$Revision: 1.9 $";
static unsigned char ffbuf[16] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--
1.6.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v5 2/3] mtd-utils: support >4GiB devices
2010-05-13 2:23 ` [PATCH v5 2/3] mtd-utils: support >4GiB devices Kevin Cernekee
@ 2010-05-13 10:11 ` Artem Bityutskiy
2010-06-12 11:36 ` Artem Bityutskiy
0 siblings, 1 reply; 6+ messages in thread
From: Artem Bityutskiy @ 2010-05-13 10:11 UTC (permalink / raw)
To: Kevin Cernekee; +Cc: linux-mtd, jwboyer, saeed.bishara
On Wed, 2010-05-12 at 19:23 -0700, Kevin Cernekee wrote:
> This patch updates the following programs to handle >4GiB flash devices:
>
> flash_erase
> flash_eraseall
> flashcp
> mtd_debug
> nanddump
> nandtest
> nandwrite
>
> It also lays the groundwork for >4GiB support in:
>
> flash_lock
> flash_unlock
>
> The latter two utilities would require MEMLOCK64 / MEMUNLOCK64
> functionality on the kernel side (currently unimplemented). For now
> they still use MEMLOCK / MEMUNLOCK and cannot access blocks above 4GiB.
>
> By default, the compatibility layer (mtd_ioctl.c) will attempt to use
> the MTD sysfs interface and MEM*64 ioctls in 2.6.31+. It will fall back
> to the older ABI if it determines that the running kernel does not
> support the new calls.
>
> Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
> ---
> Makefile | 19 +++-
> flash_erase.c | 59 ++++++----
> flash_eraseall.c | 31 +++--
> flash_lock.c | 21 ++--
> flash_unlock.c | 9 +-
> flashcp.c | 22 ++--
> mtd_debug.c | 114 ++++++++++---------
> mtd_ioctl.c | 307 +++++++++++++++++++++++++++++++++++++++++++++++++
> mtd_ioctl.h | 39 ++++++
> nanddump.c | 23 +++--
> nandtest.c | 35 +++---
> nandwrite.c | 60 +++++-----
> 13 files changed, 570 insertions(+), 171 deletions(-)
> create mode 100644 mtd_ioctl.c
> create mode 100644 mtd_ioctl.h
Any chance to extend and use mtd-utils/ubi-utils/src/libmtd.c instead of
mtd_ioctl.c?
--
Best Regards,
Artem Bityutskiy (Артём Битюцкий)
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v5 2/3] mtd-utils: support >4GiB devices
2010-05-13 10:11 ` Artem Bityutskiy
@ 2010-06-12 11:36 ` Artem Bityutskiy
2010-06-29 6:35 ` Artem Bityutskiy
0 siblings, 1 reply; 6+ messages in thread
From: Artem Bityutskiy @ 2010-06-12 11:36 UTC (permalink / raw)
To: Kevin Cernekee; +Cc: saeed.bishara, jwboyer, linux-mtd
On Thu, 2010-05-13 at 13:11 +0300, Artem Bityutskiy wrote:
> > nandwrite.c | 60 +++++-----
> > 13 files changed, 570 insertions(+), 171 deletions(-)
> > create mode 100644 mtd_ioctl.c
> > create mode 100644 mtd_ioctl.h
>
> Any chance to extend and use mtd-utils/ubi-utils/src/libmtd.c instead of
> mtd_ioctl.c?
Does silence mean that that answer is "no"? :-)
--
Best Regards,
Artem Bityutskiy (Артём Битюцкий)
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v5 2/3] mtd-utils: support >4GiB devices
2010-06-12 11:36 ` Artem Bityutskiy
@ 2010-06-29 6:35 ` Artem Bityutskiy
0 siblings, 0 replies; 6+ messages in thread
From: Artem Bityutskiy @ 2010-06-29 6:35 UTC (permalink / raw)
To: Kevin Cernekee; +Cc: linux-mtd, jwboyer, saeed.bishara
On Sat, 2010-06-12 at 14:36 +0300, Artem Bityutskiy wrote:
> On Thu, 2010-05-13 at 13:11 +0300, Artem Bityutskiy wrote:
> > > nandwrite.c | 60 +++++-----
> > > 13 files changed, 570 insertions(+), 171 deletions(-)
> > > create mode 100644 mtd_ioctl.c
> > > create mode 100644 mtd_ioctl.h
> >
> > Any chance to extend and use mtd-utils/ubi-utils/src/libmtd.c instead of
> > mtd_ioctl.c?
>
> Does silence mean that that answer is "no"? :-)
I have a dilemma whether to take your patches as they are or not :-) On
the one hand, they are needed, on the other hand, if we re-use libmtd.c,
we do not have duplicated code. libmtd.c is tested and it distinguish
beween old kernels (no sysfs support in mtd) and new kernels (expose
stuff via sysfs). It would be nice to share more code...
I guess I do not take your patches so far.
--
Best Regards,
Artem Bityutskiy (Артём Битюцкий)
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2010-06-29 6:38 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-13 2:22 [PATCH v5 1/3] mtd-utils: update to latest mtd-abi.h from kernel.org Kevin Cernekee
2010-05-13 2:23 ` [PATCH v5 2/3] mtd-utils: support >4GiB devices Kevin Cernekee
2010-05-13 10:11 ` Artem Bityutskiy
2010-06-12 11:36 ` Artem Bityutskiy
2010-06-29 6:35 ` Artem Bityutskiy
2010-05-13 2:24 ` [PATCH v5 3/3] mtd-utils: clean up compiler warnings Kevin Cernekee
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).