From patchwork Mon Sep 27 06:50:58 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Frysinger X-Patchwork-Id: 65813 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [18.85.46.34]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id CE4FEB70E2 for ; Mon, 27 Sep 2010 16:51:42 +1000 (EST) Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.72 #1 (Red Hat Linux)) id 1P07XS-0000Pp-FE; Mon, 27 Sep 2010 06:50:14 +0000 Received: from smtp.gentoo.org ([140.211.166.183]) by bombadil.infradead.org with esmtps (Exim 4.72 #1 (Red Hat Linux)) id 1P07XN-0000Lz-TC for linux-mtd@lists.infradead.org; Mon, 27 Sep 2010 06:50:12 +0000 Received: from localhost.localdomain (localhost [127.0.0.1]) by smtp.gentoo.org (Postfix) with ESMTP id 4B6A01B40B2 for ; Mon, 27 Sep 2010 06:50:04 +0000 (UTC) From: Mike Frysinger To: linux-mtd@lists.infradead.org Subject: [PATCH v3] mtd-utils: unify flash_erase and flash_eraseall Date: Mon, 27 Sep 2010 02:50:58 -0400 Message-Id: <1285570258-17068-1-git-send-email-vapier@gentoo.org> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <1285394847-29844-1-git-send-email-vapier@gentoo.org> References: <1285394847-29844-1-git-send-email-vapier@gentoo.org> X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20100927_025010_311106_30CCC3D8 X-CRM114-Status: GOOD ( 31.81 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.3.1 on bombadil.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [140.211.166.183 listed in list.dnswl.org] X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org These have overlapping functionality, and while flash_eraseall supports newer 64bit ioctls, flash_erase does not. So rather than graft support onto flash_erase, merge the functionality of two into flash_erase so we only have to support one util from now on. A simple wrapper is provided to ease old flash_eraseall users into the new combined flash_erase util. Signed-off-by: Mike Frysinger --- v3 - rebase after recent common.h changes .gitignore | 1 - Makefile | 7 +- flash_erase.c | 418 ++++++++++++++++++++++++++++++++++-------------------- flash_eraseall | 4 + flash_eraseall.c | 276 ----------------------------------- 5 files changed, 269 insertions(+), 437 deletions(-) create mode 100755 flash_eraseall delete mode 100644 flash_eraseall.c diff --git a/.gitignore b/.gitignore index defbd57..2dbf198 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,6 @@ /doc_loadbios /docfdisk /flash_erase -/flash_eraseall /flash_info /flash_lock /flash_otp_dump diff --git a/Makefile b/Makefile index d315f39..93661cb 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ endif SUBDIRS = lib ubi-utils mkfs.ubifs -TARGETS = ftl_format flash_erase flash_eraseall nanddump doc_loadbios \ +TARGETS = ftl_format flash_erase nanddump doc_loadbios \ ftl_check mkfs.jffs2 flash_lock flash_unlock flash_info \ flash_otp_info flash_otp_dump mtd_debug flashcp nandwrite nandtest \ jffs2dump \ @@ -17,6 +17,7 @@ TARGETS = ftl_format flash_erase flash_eraseall nanddump doc_loadbios \ rfddump rfdformat \ serve_image recv_image \ sumtool #jffs2reader +SCRIPTS = flash_eraseall SYMLINKS = @@ -53,8 +54,8 @@ LDLIBS_jffs2reader = -lz -llzo2 $(BUILDDIR)/lib/libmtd.a: subdirs_lib_all ; -install:: ${TARGETS} +install:: ${TARGETS} ${SCRIPTS} mkdir -p ${DESTDIR}/${SBINDIR} - install -m 0755 ${TARGETS} ${DESTDIR}/${SBINDIR}/ + install -m 0755 ${TARGETS} ${SCRIPTS} ${DESTDIR}/${SBINDIR}/ mkdir -p ${DESTDIR}/${MANDIR}/man1 gzip -9c mkfs.jffs2.1 > ${DESTDIR}/${MANDIR}/man1/mkfs.jffs2.1.gz diff --git a/flash_erase.c b/flash_erase.c index fdf9918..8929054 100644 --- a/flash_erase.c +++ b/flash_erase.c @@ -1,189 +1,293 @@ -/* - * flash_erase.c -- erase parts of a MTD device - */ +/* flash_erase.c -- erase MTD devices -#include -#include -#include -#include -#include -#include -#include -#include -#include + Copyright (C) 2000 Arcom Control System Ltd + Copyright (C) 2010 Mike Frysinger -int region_erase(int Fd, int start, int count, int unlock, int regcount) -{ - int i, j; - region_info_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) - 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, - reginfo[i].erasesize); - } + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - // We have all the information about the chip we need. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - for(i = 0; i < regcount; i++) - { //Loop through the regions - region_info_t * r = &(reginfo[i]); + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ - if((start >= reginfo[i].offset) && - (start < (r->offset + r->numblocks*r->erasesize))) - break; - } +#define PROGRAM_NAME "flash_erase" +#define VERSION "2" - if(i >= regcount) - { - printf("Starting offset %x not within chip.\n", start); - return 8; - } +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include - //We are now positioned within region i of the chip, so start erasing - //count sectors from there. +#include +#include +#include - for(j = 0; (j < count)&&(i < regcount); j++) - { - erase_info_t erase; - region_info_t * r = &(reginfo[i]); +#include +#include - erase.start = start; - erase.length = r->erasesize; +static const char *mtd_device; - if(unlock != 0) - { //Unlock the sector first. - if(ioctl(Fd, MEMUNLOCK, &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); - fflush(stdout); - if(ioctl(Fd, MEMERASE, &erase) != 0) - { - perror("\nMTD Erase failure"); - close(Fd); - return 8; - } +static int quiet; /* true -- don't output progress */ +static int jffs2; /* format for jffs2 usage */ +static int noskipbad; /* do not skip bad blocks */ +static int unlock; /* unlock sectors before erasing */ +static struct jffs2_unknown_node cleanmarker; +int target_endian = __BYTE_ORDER; - start += erase.length; - if(start >= (r->offset + r->numblocks*r->erasesize)) - { //We finished region i so move to region i+1 - printf("\nMoving to region %d\n", i+1); - i++; - } - } +static void show_progress(struct mtd_dev_info *mtd, uint64_t start, int eb, + int eb_start, int eb_cnt) +{ + bareverbose(!quiet, "\rErasing %d Kibyte @ %"PRIx64" -- %2i %% complete ", + mtd->eb_size / 1024, start, ((eb - eb_start) * 100) / eb_cnt); + fflush(stdout); +} - printf(" done\n"); +static void display_help (void) +{ + printf("Usage: %s [options] MTD_DEVICE \n" + "Erase blocks of the specified MTD device.\n" + "Specify a count of 0 to erase to end of device.\n" + "\n" + " -j, --jffs2 format the device for jffs2\n" + " -N, --noskipbad don't skip bad blocks\n" + " -u, --unlock unlock sectors before erasing\n" + " -q, --quiet display progress messages\n" + " --silent same as --quiet\n" + " --help display this help and exit\n" + " --version output version information and exit\n", + PROGRAM_NAME); +} - return 0; +static void display_version (void) +{ + printf("%1$s version " VERSION "\n" + "\n" + "Copyright (C) 2000 Arcom Control Systems Ltd\n" + "\n" + "%1$s comes with NO WARRANTY\n" + "to the extent permitted by law.\n" + "\n" + "You may redistribute copies of %1$s\n" + "under the terms of the GNU General Public Licence.\n" + "See the file `COPYING' for more information.\n", + PROGRAM_NAME); } -int non_region_erase(int Fd, int start, int count, int unlock) +int main(int argc, char *argv[]) { - mtd_info_t meminfo; - - if (ioctl(Fd,MEMGETINFO,&meminfo) == 0) - { - erase_info_t 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); - 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) - { - perror("\nMTD Unlock failure"); - close(Fd); - return 8; - } - } + libmtd_t mtd_desc; + struct mtd_dev_info mtd; + int fd, clmpos = 0, clmlen = 8, eb, eb_start, eb_cnt; + int isNAND; + int error = 0; + uint64_t offset = 0; + + /* + * Process user arguments + */ + for (;;) { + int option_index = 0; + static const char *short_options = "jNqu"; + static const struct option long_options[] = { + {"help", no_argument, 0, 0}, + {"version", no_argument, 0, 0}, + {"jffs2", no_argument, 0, 'j'}, + {"noskipbad", no_argument, 0, 'N'}, + {"quiet", no_argument, 0, 'q'}, + {"silent", no_argument, 0, 'q'}, + {"unlock", no_argument, 0, 'u'}, + + {0, 0, 0, 0}, + }; + + int c = getopt_long(argc, argv, short_options, + long_options, &option_index); + if (c == EOF) + break; - if (ioctl(Fd,MEMERASE,&erase) != 0) - { - perror("\nMTD Erase failure"); - close(Fd); - return 8; + switch (c) { + case 0: + switch (option_index) { + case 0: + display_help(); + return 0; + case 1: + display_version(); + return 0; } - erase.start += meminfo.erasesize; + break; + case 'j': + jffs2 = 1; + break; + case 'N': + noskipbad = 1; + break; + case 'q': + quiet = 1; + break; + case 'u': + unlock = 1; + break; + case '?': + error = 1; + break; } - printf(" done\n"); } - return 0; -} - -int main(int argc,char *argv[]) -{ - int regcount; - int Fd; - int start; - int count; - int unlock; - int res = 0; - - if (1 >= argc || !strcmp(argv[1], "-h") || !strcmp (argv[1], "--help") ) { - printf("Usage: flash_erase MTD-device [start] [cnt (# erase blocks)] [lock]\n" - " flash_erase -h | --help\n") ; - return 16 ; + switch (argc - optind) { + case 3: + mtd_device = argv[optind]; + eb_start = simple_strtoul(argv[optind + 1], &error); + eb_cnt = simple_strtoul(argv[optind + 2], &error); + break; + default: + case 0: + errmsg("no MTD device specified"); + case 1: + errmsg("no start erase block specified"); + case 2: + errmsg("no erase block count specified"); + error = 1; + break; + } + if (error) + return errmsg("Try `--help' for more information"); + + /* + * Locate MTD and prepare for erasure + */ + mtd_desc = libmtd_open(); + if (mtd_desc == NULL) + return errmsg("can't initialize libmtd"); + + if ((fd = open(mtd_device, O_RDWR)) < 0) + return sys_errmsg("%s", mtd_device); + + if (mtd_get_dev_info(mtd_desc, mtd_device, &mtd) < 0) + return errmsg("mtd_get_dev_info failed"); + + isNAND = mtd.type == MTD_NANDFLASH ? 1 : 0; + + if (jffs2) { + cleanmarker.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK); + cleanmarker.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER); + if (!isNAND) + cleanmarker.totlen = cpu_to_je32(sizeof(cleanmarker)); + else { + struct nand_oobinfo oobinfo; + + if (ioctl(fd, MEMGETOOBSEL, &oobinfo) != 0) + return sys_errmsg("%s: unable to get NAND oobinfo", mtd_device); + + /* Check for autoplacement */ + if (oobinfo.useecc == MTD_NANDECC_AUTOPLACE) { + /* Get the position of the free bytes */ + if (!oobinfo.oobfree[0][1]) + return errmsg(" Eeep. Autoplacement selected and no empty space in oob"); + clmpos = oobinfo.oobfree[0][0]; + clmlen = oobinfo.oobfree[0][1]; + if (clmlen > 8) + clmlen = 8; + } else { + /* Legacy mode */ + switch (mtd.oob_size) { + case 8: + clmpos = 6; + clmlen = 2; + break; + case 16: + clmpos = 8; + clmlen = 8; + break; + case 64: + clmpos = 16; + clmlen = 8; + break; + } + } + cleanmarker.totlen = cpu_to_je32(8); + } + cleanmarker.hdr_crc = cpu_to_je32(mtd_crc32(0, &cleanmarker, sizeof(cleanmarker) - 4)); } - if (argc > 2) - start = strtol(argv[2], NULL, 0); - else - start = 0; - - if (argc > 3) - count = strtol(argv[3], NULL, 0); - else - count = 1; + /* + * Now do the actual erasing of the MTD device + */ + if (eb_cnt == 0) + eb_cnt = (mtd.size / mtd.eb_size) - eb_start; + + for (eb = eb_start; eb < eb_start + eb_cnt; eb++) { + offset = eb * mtd.eb_size; + + if (!noskipbad) { + int ret = mtd_is_bad(&mtd, fd, eb); + if (ret > 0) { + verbose(!quiet, "Skipping bad block at %08"PRIx64, offset); + continue; + } else if (ret < 0) { + if (errno == EOPNOTSUPP) { + noskipbad = 1; + if (isNAND) + return errmsg("%s: Bad block check not available", mtd_device); + } else + return sys_errmsg("%s: MTD get bad block failed", mtd_device); + } + } - if(argc > 4) - unlock = strtol(argv[4], NULL, 0); - else - unlock = 0; + show_progress(&mtd, offset, eb, eb_start, eb_cnt); + if (unlock) { + if (mtd_unlock(&mtd, fd, eb) != 0) { + sys_errmsg("%s: MTD unlock failure", mtd_device); + continue; + } + } - // Open and size the device - if ((Fd = open(argv[1],O_RDWR)) < 0) - { - fprintf(stderr,"File open error\n"); - return 8; - } + if (mtd_erase(mtd_desc, &mtd, fd, eb) != 0) { + sys_errmsg("%s: MTD Erase failure", mtd_device); + continue; + } - printf("Erase Total %d Units\n", count); + /* format for JFFS2 ? */ + if (!jffs2) + continue; - if (ioctl(Fd,MEMGETREGIONCOUNT,®count) == 0) - { - if(regcount == 0) - { - res = non_region_erase(Fd, start, count, unlock); - } - else - { - res = region_erase(Fd, start, count, unlock, regcount); + /* write cleanmarker */ + if (isNAND) { + if (mtd_write_oob(mtd_desc, &mtd, fd, offset + clmpos, clmlen, &cleanmarker) != 0) { + sys_errmsg("%s: MTD writeoob failure", mtd_device); + continue; + } + } else { + if (lseek(fd, (loff_t)offset, SEEK_SET) < 0) { + sys_errmsg("%s: MTD lseek failure", mtd_device); + continue; + } + if (write(fd, &cleanmarker, sizeof(cleanmarker)) != sizeof(cleanmarker)) { + sys_errmsg("%s: MTD write failure", mtd_device); + continue; + } } + verbose(!quiet, " Cleanmarker written at %"PRIx64, offset); } + offset += mtd.eb_size; + show_progress(&mtd, offset, eb, eb_start, eb_cnt); + bareverbose(!quiet, "\n"); - return res; + return 0; } diff --git a/flash_eraseall b/flash_eraseall new file mode 100755 index 0000000..c5539b3 --- /dev/null +++ b/flash_eraseall @@ -0,0 +1,4 @@ +#!/bin/sh +echo "${0##*/} has been replaced by \`flash_erase 0 0\`; please use it" 1>&2 +[ $# -ne 0 ] && set -- "$@" 0 0 +exec flash_erase "$@" diff --git a/flash_eraseall.c b/flash_eraseall.c deleted file mode 100644 index cb6f632..0000000 --- a/flash_eraseall.c +++ /dev/null @@ -1,276 +0,0 @@ -/* eraseall.c -- erase the whole of a MTD device - - Copyright (C) 2000 Arcom Control System Ltd - - Renamed to flash_eraseall.c - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define PROGRAM "flash_eraseall" -#define VERSION "$Revision: 1.22 $" - -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 struct jffs2_unknown_node cleanmarker; -int target_endian = __BYTE_ORDER; - -static void show_progress (struct mtd_dev_info *mtd, uint64_t start) -{ - printf("\rErasing %d Kibyte @ %llx -- %2llu %% complete.", - mtd->eb_size / 1024, (unsigned long long)start, - (unsigned long long) start * 100 / mtd->size); - fflush(stdout); -} - -static void display_help (void) -{ - printf("Usage: %s [OPTION] MTD_DEVICE\n" - "Erases all of the specified MTD device.\n" - "\n" - " -j, --jffs2 format the device for jffs2\n" - " -q, --quiet don't display progress messages\n" - " --silent same as --quiet\n" - " --help display this help and exit\n" - " --version output version information and exit\n", - exe_name); -} - - -static void display_version (void) -{ - printf(PROGRAM " " VERSION "\n" - "\n" - "Copyright (C) 2000 Arcom Control Systems Ltd\n" - "\n" - PROGRAM " comes with NO WARRANTY\n" - "to the extent permitted by law.\n" - "\n" - "You may redistribute copies of " PROGRAM "\n" - "under the terms of the GNU General Public Licence.\n" - "See the file `COPYING' for more information.\n"); -} - -int main (int argc, char *argv[]) -{ - libmtd_t mtd_desc; - struct mtd_dev_info mtd; - int fd, clmpos = 0, clmlen = 8, eb; - int isNAND, bbtest = 1; - int error = 0; - uint64_t offset = 0; - - exe_name = argv[0]; - for (;;) { - int option_index = 0; - static const char *short_options = "jq"; - static const struct option long_options[] = { - {"help", no_argument, 0, 0}, - {"version", no_argument, 0, 0}, - {"jffs2", no_argument, 0, 'j'}, - {"quiet", no_argument, 0, 'q'}, - {"silent", no_argument, 0, 'q'}, - - {0, 0, 0, 0}, - }; - - int c = getopt_long(argc, argv, short_options, - long_options, &option_index); - if (c == EOF) - break; - - switch (c) { - case 0: - switch (option_index) { - case 0: - display_help(); - return 0; - case 1: - display_version(); - return 0; - } - break; - case 'q': - quiet = 1; - break; - case 'j': - jffs2 = 1; - break; - case '?': - error = 1; - break; - } - } - if (optind == argc) { - fprintf(stderr, "%s: no MTD device specified\n", exe_name); - error = 1; - } - if (error) { - fprintf(stderr, "Try `%s --help' for more information.\n", - exe_name); - return 1; - } - mtd_device = argv[optind]; - - mtd_desc = libmtd_open(); - if (mtd_desc == NULL) { - fprintf(stderr, "%s: can't initialize libmtd\n", exe_name); - 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 (mtd_get_dev_info(mtd_desc, mtd_device, &mtd) < 0) { - fprintf(stderr, "%s: mtd_get_dev_info failed\n", exe_name); - return 1; - } - - isNAND = mtd.type == MTD_NANDFLASH ? 1 : 0; - - if (jffs2) { - cleanmarker.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK); - cleanmarker.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER); - if (!isNAND) - cleanmarker.totlen = cpu_to_je32 (sizeof (struct jffs2_unknown_node)); - else { - struct nand_oobinfo oobinfo; - - if (ioctl(fd, MEMGETOOBSEL, &oobinfo) != 0) { - fprintf(stderr, "%s: %s: unable to get NAND oobinfo\n", exe_name, mtd_device); - return 1; - } - - /* Check for autoplacement */ - if (oobinfo.useecc == MTD_NANDECC_AUTOPLACE) { - /* Get the position of the free bytes */ - if (!oobinfo.oobfree[0][1]) { - fprintf (stderr, " Eeep. Autoplacement selected and no empty space in oob\n"); - return 1; - } - clmpos = oobinfo.oobfree[0][0]; - clmlen = oobinfo.oobfree[0][1]; - if (clmlen > 8) - clmlen = 8; - } else { - /* Legacy mode */ - switch (mtd.oob_size) { - case 8: - clmpos = 6; - clmlen = 2; - break; - case 16: - clmpos = 8; - clmlen = 8; - break; - case 64: - clmpos = 16; - clmlen = 8; - break; - } - } - cleanmarker.totlen = cpu_to_je32(8); - } - cleanmarker.hdr_crc = cpu_to_je32 (mtd_crc32 (0, &cleanmarker, sizeof (struct jffs2_unknown_node) - 4)); - } - - for (eb = 0; eb < (mtd.size / mtd.eb_size); eb++) { - offset = eb * mtd.eb_size; - if (bbtest) { - int ret = mtd_is_bad(&mtd, fd, eb); - if (ret > 0) { - if (!quiet) - printf ("\nSkipping bad block at 0x%08llx\n", (unsigned long long)offset); - continue; - } else if (ret < 0) { - if (errno == EOPNOTSUPP) { - bbtest = 0; - if (isNAND) { - fprintf(stderr, "%s: %s: Bad block check not available\n", exe_name, mtd_device); - return 1; - } - } else { - fprintf(stderr, "\n%s: %s: MTD get bad block failed: %s\n", exe_name, mtd_device, strerror(errno)); - return 1; - } - } - } - - if (!quiet) - show_progress(&mtd, offset); - - if (mtd_erase(mtd_desc, &mtd, fd, eb) != 0) { - fprintf(stderr, "\n%s: %s: MTD Erase failure: %s\n", exe_name, mtd_device, strerror(errno)); - continue; - } - - /* format for JFFS2 ? */ - if (!jffs2) - continue; - - /* write cleanmarker */ - if (isNAND) { - if (mtd_write_oob(mtd_desc, &mtd, fd, offset + clmpos, clmlen, &cleanmarker) != 0) { - fprintf(stderr, "\n%s: %s: MTD writeoob failure: %s\n", exe_name, mtd_device, strerror(errno)); - continue; - } - } else { - if (lseek (fd, (loff_t)offset, SEEK_SET) < 0) { - fprintf(stderr, "\n%s: %s: MTD lseek failure: %s\n", exe_name, mtd_device, strerror(errno)); - continue; - } - if (write (fd , &cleanmarker, sizeof (cleanmarker)) != sizeof (cleanmarker)) { - fprintf(stderr, "\n%s: %s: MTD write failure: %s\n", exe_name, mtd_device, strerror(errno)); - continue; - } - } - if (!quiet) - printf (" Cleanmarker written at %llx.", (unsigned long long)offset); - } - if (!quiet) { - show_progress(&mtd, offset); - printf("\n"); - } - - return 0; -} -