This can be used in various situations (including one in the upcoming SFDP patch) and removes one FIXME in current HEAD. Needed to move check_block_eraser (which checks a single eraser) up to avoid (upcoming) forward declaration(s).
Signed-off-by: Stefan Tauner stefan.tauner@student.tuwien.ac.at --- flashrom.c | 70 ++++++++++++++++++++++++++++++++++------------------------- 1 files changed, 40 insertions(+), 30 deletions(-)
diff --git a/flashrom.c b/flashrom.c index 6979d84..aed10aa 100644 --- a/flashrom.c +++ b/flashrom.c @@ -711,6 +711,43 @@ char *extract_programmer_param(char *param_name) return extract_param(&programmer_param, param_name, ","); }
+static int check_block_eraser(const struct flashchip *flash, int k, int log) +{ + struct block_eraser eraser = flash->block_erasers[k]; + + if (!eraser.block_erase && !eraser.eraseblocks[0].count) { + if (log) + msg_cdbg("not defined. "); + return 1; + } + if (!eraser.block_erase && eraser.eraseblocks[0].count) { + if (log) + msg_cdbg("eraseblock layout is known, but matching " + "block erase function is not implemented. "); + return 1; + } + if (eraser.block_erase && !eraser.eraseblocks[0].count) { + if (log) + msg_cdbg("block erase function found, but " + "eraseblock layout is not defined. "); + return 1; + } + return 0; +} + +/* Returns the number of well-defined erasers for a chip. + * The log parameter controls output. */ +static int check_block_erasers(const struct flashchip *flash, int log) +{ + int usable_erasefunctions = 0; + int k; + for (k = 0; k < NUM_ERASEFUNCTIONS; k++) { + if (!check_block_eraser(flash, k, 0)) + usable_erasefunctions++; + } + return usable_erasefunctions; +} + /* start is an offset to the base address of the flash chip */ int check_erased_range(struct flashchip *flash, int start, int len) { @@ -1462,40 +1499,13 @@ static int walk_eraseregions(struct flashchip *flash, int erasefunction, return 0; }
-static int check_block_eraser(struct flashchip *flash, int k, int log) -{ - struct block_eraser eraser = flash->block_erasers[k]; - - if (!eraser.block_erase && !eraser.eraseblocks[0].count) { - if (log) - msg_cdbg("not defined. "); - return 1; - } - if (!eraser.block_erase && eraser.eraseblocks[0].count) { - if (log) - msg_cdbg("eraseblock layout is known, but matching " - "block erase function is not implemented. "); - return 1; - } - if (eraser.block_erase && !eraser.eraseblocks[0].count) { - if (log) - msg_cdbg("block erase function found, but " - "eraseblock layout is not defined. "); - return 1; - } - return 0; -} - int erase_and_write_flash(struct flashchip *flash, uint8_t *oldcontents, uint8_t *newcontents) { int k, ret = 0; uint8_t *curcontents; unsigned long size = flash->total_size * 1024; - int usable_erasefunctions = 0; + int usable_erasefunctions = check_block_erasers(flash, 0);
- for (k = 0; k < NUM_ERASEFUNCTIONS; k++) - if (!check_block_eraser(flash, k, 0)) - usable_erasefunctions++; msg_cinfo("Erasing and writing flash chip... "); if (!usable_erasefunctions) { msg_cerr("ERROR: flashrom has no erase function for this flash " @@ -1814,13 +1824,13 @@ int chip_safety_check(struct flashchip *flash, int force, int read_it, int write } if (erase_it || write_it) { /* Write needs erase. */ - if (flash->tested & TEST_BAD_ERASE) { + if (flash->tested & TEST_BAD_ERASE && + !check_block_erasers(flash, 0)) { msg_cerr("Erase is not working on this chip. "); if (!force) return 1; msg_cerr("Continuing anyway.\n"); } - /* FIXME: Check if at least one erase function exists. */ } if (write_it) { if (flash->tested & TEST_BAD_WRITE) {