Hello Brian Norris,
I'd like you to do a code review. Please visit
https://review.coreboot.org/22511
to review the following change.
Change subject: linux_mtd: Support for NO_ERASE type devices ......................................................................
linux_mtd: Support for NO_ERASE type devices
Some mtd devices have the MTD_NO_ERASE flag set. This means these devices don't require an erase to write and might not have implemented an erase function. We should be conservative and skip erasing altogether, falling back to performing writes over the whole flash.
BUG=b:35104688 TESTED=Zaius flash is now written correctly for the 0xff regions.
Change-Id: I4c2fc769a8e0865edf8507f6bd796dc3344b4226 Signed-off-by: William A. Kennington III wak@google.com Reviewed-on: https://chromium-review.googlesource.com/472128 Commit-Ready: William Kennington wak@google.com Tested-by: William Kennington wak@google.com Reviewed-by: Brian Norris briannorris@chromium.org --- M flash.h M flashrom.c M linux_mtd.c 3 files changed, 16 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/11/22511/1
diff --git a/flash.h b/flash.h index 62f2e34..d16751b 100644 --- a/flash.h +++ b/flash.h @@ -120,6 +120,7 @@ #define FEATURE_OTP (1 << 8) #define FEATURE_QPI (1 << 9) #define FEATURE_4BA_SUPPORT (1 << 10) +#define FEATURE_NO_ERASE (1 << 11)
enum test_state { OK = 0, diff --git a/flashrom.c b/flashrom.c index 6329041..d7cafc2 100644 --- a/flashrom.c +++ b/flashrom.c @@ -1779,7 +1779,8 @@ ret = 1; bool skipped = true; uint8_t *const curcontents = info->curcontents + info->erase_start; - if (need_erase(curcontents, newcontents, erase_len, flashctx->chip->gran)) { + if (!(flashctx->chip->feature_bits & FEATURE_NO_ERASE) && + need_erase(curcontents, newcontents, erase_len, flashctx->chip->gran)) { if (erase_block(flashctx, info, erasefn)) goto _free_ret; /* Erase was successful. Adjust curcontents. */ diff --git a/linux_mtd.c b/linux_mtd.c index 99a7ec0..9320bd1 100644 --- a/linux_mtd.c +++ b/linux_mtd.c @@ -48,6 +48,8 @@
static int mtd_device_is_writeable;
+static int mtd_no_erase; + /* Size info is presented in bytes in sysfs. */ static unsigned long int mtd_total_size; static unsigned long int mtd_numeraseregions; @@ -131,6 +133,9 @@ /* cache for later use by write function */ mtd_device_is_writeable = 1; } + if (tmp & MTD_NO_ERASE) { + mtd_no_erase = 1; + }
/* Device name */ if (read_sysfs_string("name", mtd_device_name, sizeof(mtd_device_name))) @@ -174,10 +179,8 @@ flash->chip->tested.read = OK; flash->chip->tested.erase = OK; flash->chip->tested.write = OK; - flash->chip->total_size = mtd_total_size / 1024; /* bytes -> kB */ - flash->chip->block_erasers[0].eraseblocks[0].size = mtd_erasesize; - flash->chip->block_erasers[0].eraseblocks[0].count = - mtd_total_size / mtd_erasesize; + if (mtd_no_erase) + flash->chip->feature_bits |= FEATURE_NO_ERASE; #if 0 flash->chip->wp = &wp_mtd; #endif @@ -255,6 +258,12 @@ { uint32_t u;
+ if (mtd_no_erase) { + msg_perr("%s: device does not support erasing. Please file a " + "bug report at flashrom@flashrom.org\n", __func__); + return 1; + } + if (mtd_numeraseregions != 0) { /* TODO: Support non-uniform eraseblock size using use MEMGETREGIONCOUNT/MEMGETREGIONINFO ioctls */