From 066f501b253c84550e6959be527aa0aa75fff631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Harboe?= Date: Fri, 10 Dec 2010 10:05:43 +0100 Subject: [PATCH] mtd-utils: add fast NOR flash erase MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit do not erase sector (which can be 10x slower than write's on CFI's) if it is already erased. This includes a check for a cleanmarker. Signed-off-by: Øyvind Harboe --- .../flash_eraseall.c | 60 +++++++++++++++++++- 1 files changed, 59 insertions(+), 1 deletions(-) diff --git a/user/mtd-utils/606f38a2221648ca5c5fa292c9f71d2ddd59fa66/flash_eraseall.c b/user/mtd-utils/606f38a2221648ca5c5fa292c9f71d2ddd59fa66/flash_eraseall.c index a22fc49..f6da1ff 100644 --- a/user/mtd-utils/606f38a2221648ca5c5fa292c9f71d2ddd59fa66/flash_eraseall.c +++ b/user/mtd-utils/606f38a2221648ca5c5fa292c9f71d2ddd59fa66/flash_eraseall.c @@ -47,6 +47,7 @@ static const char *exe_name; static const char *mtd_device; static int quiet; /* true -- don't output progress */ static int jffs2; // format for jffs2 usage +static int fast; // Fast - check if the block is erased before erasing static void process_options (int argc, char *argv[]); void show_progress (mtd_info_t *meminfo, erase_info_t *erase); @@ -146,9 +147,61 @@ int main (int argc, char *argv[]) } } + /* Can we skip this one if it is already erased? + * Perhaps NAND performance could be improved by adding support for + * those cleanmarkers as well? + * + * Currently this only works with JFFS2 NOR clean markers + */ + int skip = 0; + if (fast && !isNAND) { + if (lseek (fd, erase.start, SEEK_SET) < 0) { + fprintf(stderr, "\n%s: %s: MTD lseek failure: %s\n", exe_name, mtd_device, strerror(errno)); + return 1; + } + uint8_t *tmp = malloc(meminfo.erasesize); + if (tmp == NULL) + { + fprintf(stderr, "Out of memory\n"); + return 1; + } + ssize_t actual = read(fd, tmp, meminfo.erasesize); + if (actual != meminfo.erasesize) { + fprintf(stderr, "\n%s: %s: MTD read failure: %s\n", exe_name, mtd_device, strerror(errno)); + return 1; + } + ssize_t i = 0; + int ok = 1; + + if (jffs2) { + ok = memcmp(tmp, &cleanmarker, sizeof (cleanmarker)) == 0; + i = sizeof (cleanmarker); + } + + if (ok) + { + for (; i < meminfo.erasesize; i++) + { + if (tmp[i] != 0xff) + break; + } + if (i == meminfo.erasesize) + { + /* Yup! we can skip! Here we could improve things by + * adding support for NAND cleanmarkers + */ + skip = 1; + } + } + free(tmp); + } + if (!quiet) show_progress(&meminfo, &erase); + if (skip) + continue; + if (ioctl(fd, MEMERASE, &erase) != 0) { fprintf(stderr, "\n%s: %s: MTD Erase failure: %s\n", exe_name, mtd_device, strerror(errno)); continue; @@ -198,11 +251,12 @@ void process_options (int argc, char *argv[]) for (;;) { int option_index = 0; - static const char *short_options = "jq"; + static const char *short_options = "jqf"; static const struct option long_options[] = { {"help", no_argument, 0, 0}, {"version", no_argument, 0, 0}, {"jffs2", no_argument, 0, 'j'}, + {"fast", no_argument, 0, 'f'}, {"quiet", no_argument, 0, 'q'}, {"silent", no_argument, 0, 'q'}, @@ -232,6 +286,9 @@ void process_options (int argc, char *argv[]) case 'j': jffs2 = 1; break; + case 'f': + fast = 1; + break; case '?': error = 1; break; @@ -265,6 +322,7 @@ void display_help (void) "\n" " -j, --jffs2 format the device for jffs2\n" " -q, --quiet don't display progress messages\n" + " -f, --fast do not re-erase sectors that are erased\n" " --silent same as --quiet\n" " --help display this help and exit\n" " --version output version information and exit\n", -- 1.7.0.4