From 2ca0bbf296d6f7ce51b8255347c7fd08afa33651 Mon Sep 17 00:00:00 2001 From: Larisa Ileana Grigore Date: Fri, 23 Apr 2021 18:07:04 +0300 Subject: mtd-utils: flash_erase: Add flash erase chip Some flash types support full erase chip command which can reduce the flash erase time. Try first to erase the entire flash and fall back to the old method if the operation fails. Signed-off-by: Larisa Ileana Grigore Signed-off-by: David Oberhollenzer --- misc-utils/flash_erase.c | 95 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 71 insertions(+), 24 deletions(-) (limited to 'misc-utils') diff --git a/misc-utils/flash_erase.c b/misc-utils/flash_erase.c index a7fc6a6..49a880f 100644 --- a/misc-utils/flash_erase.c +++ b/misc-utils/flash_erase.c @@ -2,6 +2,7 @@ Copyright (C) 2000 Arcom Control System Ltd Copyright (C) 2010 Mike Frysinger + Copyright 2021 NXP 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 @@ -50,11 +51,10 @@ static int unlock; /* unlock sectors before erasing */ static struct jffs2_unknown_node cleanmarker; int target_endian = __BYTE_ORDER; -static void show_progress(struct mtd_dev_info *mtd, off_t start, int eb, - int eb_start, int eb_cnt) +static void show_progress(off_t start, int eb, int eb_start, int eb_cnt, int step) { bareverbose(!quiet, "\rErasing %d Kibyte @ %llx -- %2i %% complete ", - mtd->eb_size / 1024, (unsigned long long)start, ((eb - eb_start) * 100) / eb_cnt); + step / 1024, (unsigned long long)start, ((eb - eb_start) * 100) / eb_cnt); fflush(stdout); } @@ -88,6 +88,27 @@ static void display_version (void) PROGRAM_NAME); } +static void clear_marker(libmtd_t mtd_desc, struct mtd_dev_info *mtd, int fd, + unsigned int eb, int cmlen, bool isNAND) +{ + off_t offset = (off_t)eb * mtd->eb_size; + + /* write cleanmarker */ + if (isNAND) { + if (mtd_write(mtd_desc, mtd, fd, eb, 0, NULL, 0, &cleanmarker, cmlen, + MTD_OPS_AUTO_OOB) != 0) { + sys_errmsg("%s: MTD writeoob failure", mtd_device); + return; + } + } else { + if (pwrite(fd, &cleanmarker, sizeof(cleanmarker), (loff_t)offset) != sizeof(cleanmarker)) { + sys_errmsg("%s: MTD write failure", mtd_device); + return; + } + } + verbose(!quiet, "%llx : Cleanmarker Updated.", (unsigned long long)offset); +} + int main(int argc, char *argv[]) { libmtd_t mtd_desc; @@ -95,7 +116,7 @@ int main(int argc, char *argv[]) int fd, cmlen = 8; unsigned long long start; unsigned int eb, eb_start, eb_cnt; - bool isNAND; + bool isNAND, erase_chip = false; int error = 0; off_t offset = 0; @@ -205,6 +226,47 @@ int main(int argc, char *argv[]) if (eb_cnt == 0) eb_cnt = (mtd.size / mtd.eb_size) - eb_start; + if (eb_start == 0 && mtd.size == eb_cnt * mtd.eb_size) + erase_chip = true; + + /* If MTD device may have bad eraseblocks, + * erase one by one each sector + */ + if (noskipbad && mtd.bb_allowed) + erase_chip = false; + + if (erase_chip) { + show_progress(0, eb_start, eb_start, eb_cnt, mtd.size); + + if (unlock) { + if (mtd_unlock_multi(&mtd, fd, eb_start, eb_cnt) != 0) { + sys_errmsg("%s: MTD unlock entire chip failure." \ + "Trying one by one each sector.", + mtd_device); + goto erase_each_sector; + } + } + + if (mtd_erase_multi(mtd_desc, &mtd, fd, eb_start, eb_cnt) != 0) { + sys_errmsg("%s: MTD Erase entire chip failure" \ + "Trying one by one each sector.", + mtd_device); + goto erase_each_sector; + } + + show_progress(0, eb_start + eb_cnt, eb_start, + eb_cnt, mtd.size); + + if (!jffs2) + goto out; + + /* write cleanmarker */ + for (eb = eb_start; eb < eb_start + eb_cnt; eb++) + clear_marker(mtd_desc, &mtd, fd, eb, cmlen, isNAND); + goto out; + } + +erase_each_sector: for (eb = eb_start; eb < eb_start + eb_cnt; eb++) { offset = (off_t)eb * mtd.eb_size; @@ -223,7 +285,7 @@ int main(int argc, char *argv[]) } } - show_progress(&mtd, offset, eb, eb_start, eb_cnt); + show_progress(offset, eb, eb_start, eb_cnt, mtd.eb_size); if (unlock) { if (mtd_unlock(&mtd, fd, eb) != 0) { @@ -237,26 +299,11 @@ int main(int argc, char *argv[]) continue; } - /* format for JFFS2 ? */ - if (!jffs2) - continue; - - /* write cleanmarker */ - if (isNAND) { - if (mtd_write(mtd_desc, &mtd, fd, eb, 0, NULL, 0, &cleanmarker, cmlen, - MTD_OPS_AUTO_OOB) != 0) { - sys_errmsg("%s: MTD writeoob failure", mtd_device); - continue; - } - } else { - if (pwrite(fd, &cleanmarker, sizeof(cleanmarker), (loff_t)offset) != sizeof(cleanmarker)) { - sys_errmsg("%s: MTD write failure", mtd_device); - continue; - } - } - verbose(!quiet, " Cleanmarker Updated."); + if (jffs2) + clear_marker(mtd_desc, &mtd, fd, eb, cmlen, isNAND); } - show_progress(&mtd, offset, eb, eb_start, eb_cnt); + show_progress(offset, eb, eb_start, eb_cnt, mtd.eb_size); +out: bareverbose(!quiet, "\n"); return 0; -- cgit v1.2.3