From a113946f11ddd7e88c9316bd1654d929eacccca5 Mon Sep 17 00:00:00 2001 From: Hung-Te Lin Date: Fri, 11 Feb 2022 14:24:51 +0800 Subject: futility: updater: add new quirk 'extra_retries' In early bring up, some devices may have problem when flashrom is reading or writing to the system flash. To unblock dogfood process, we want to have a special quirk to retry flashing. BUG=b:213706510 TEST=make; build and run test BRANCH=None Change-Id: I58788f620fb32f7c886d1e5638f4a3605ea77953 Signed-off-by: Hung-Te Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/3452846 Reviewed-by: YH Lin Commit-Queue: YH Lin Reviewed-by: Yu-Ping Wu (cherry picked from commit 707b839fadfd600af4300bc451946f8e8ccf840e) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/3906634 Commit-Queue: Nick Vaccaro Tested-by: Nick Vaccaro --- futility/updater.c | 17 ++++++++++++++--- futility/updater.h | 1 + futility/updater_quirks.c | 5 +++++ futility/updater_utils.c | 24 ++++++++++++++++++------ futility/updater_utils.h | 5 +++-- 5 files changed, 41 insertions(+), 11 deletions(-) diff --git a/futility/updater.c b/futility/updater.c index 46f8878a..5790aceb 100644 --- a/futility/updater.c +++ b/futility/updater.c @@ -383,6 +383,14 @@ static int emulate_write_firmware(const char *filename, return errorcnt; } +/* + * Returns the number of retries when reading or writing to flash. + */ +static int get_io_retries(struct updater_config *cfg) +{ + return 1 + get_config_quirk(QUIRK_EXTRA_RETRIES, cfg); +} + /* * Writes a section from given firmware image to system firmware. * If section_name is NULL, write whole image. @@ -410,7 +418,7 @@ static int write_firmware(struct updater_config *cfg, return write_system_firmware(image, diff_image, section_name, &cfg->tempfiles, cfg->do_verify, - cfg->verbosity + 1); + get_io_retries(cfg), cfg->verbosity + 1); } /* @@ -1207,9 +1215,10 @@ enum updater_error_codes update_firmware(struct updater_config *cfg) } if (!image_from->data) { int ret; + INFO("Loading current system firmware...\n"); ret = load_system_firmware(image_from, &cfg->tempfiles, - cfg->verbosity); + get_io_retries(cfg), cfg->verbosity); if (ret == IMAGE_PARSE_FAILURE && cfg->force_update) { WARN("No compatible firmware in system.\n"); cfg->check_platform = 0; @@ -1392,7 +1401,9 @@ static int updater_apply_white_label(struct updater_config *cfg, if (!cfg->image_current.data) { INFO("Loading system firmware for white label...\n"); load_system_firmware(&cfg->image_current, - &cfg->tempfiles, cfg->verbosity); + &cfg->tempfiles, + get_io_retries(cfg), + cfg->verbosity); } tmp_image = get_firmware_image_temp_file( &cfg->image_current, &cfg->tempfiles); diff --git a/futility/updater.h b/futility/updater.h index 2562782b..6dda9283 100644 --- a/futility/updater.h +++ b/futility/updater.h @@ -48,6 +48,7 @@ enum quirk_types { QUIRK_PRESERVE_ME, QUIRK_NO_CHECK_PLATFORM, QUIRK_NO_VERIFY, + QUIRK_EXTRA_RETRIES, QUIRK_MAX, }; diff --git a/futility/updater_quirks.c b/futility/updater_quirks.c index 1f7fada9..6d6ccf86 100644 --- a/futility/updater_quirks.c +++ b/futility/updater_quirks.c @@ -512,6 +512,11 @@ void updater_register_quirks(struct updater_config *cfg) quirks->name = "no_verify"; quirks->help = "Do not verify when flashing."; quirks->apply = quirk_no_verify; + + quirks = &cfg->quirks[QUIRK_EXTRA_RETRIES]; + quirks->name = "extra_retries"; + quirks->help = "Extra retries when writing to system firmware."; + quirks->apply = NULL; /* Simple config. */ } /* diff --git a/futility/updater_utils.c b/futility/updater_utils.c index 2221a878..a846ef2b 100644 --- a/futility/updater_utils.c +++ b/futility/updater_utils.c @@ -523,11 +523,16 @@ char *host_detect_servo(int *need_prepare_ptr) * Returns 0 if success, non-zero if error. */ int load_system_firmware(struct firmware_image *image, - struct tempfile *tempfiles, int verbosity) + struct tempfile *tempfiles, + int retries, int verbosity) { - int r; + int r, i; - r = flashrom_read_image(image, NULL, (verbosity + 1)); + for (i = 1, r = -1; i <= retries && r != 0; i++) { + if (i > 1) + WARN("Retry reading firmware (%d/%d)...\n", i, retries); + r = flashrom_read_image(image, NULL, verbosity + 1); + } if (!r) r = parse_firmware_image(image); return r; @@ -542,10 +547,17 @@ int write_system_firmware(const struct firmware_image *image, const struct firmware_image *diff_image, const char *section_name, struct tempfile *tempfiles, - int do_verify, int verbosity) + int do_verify, int retries, int verbosity) { - return flashrom_write_image(image, section_name, diff_image, - do_verify, (verbosity + 1)); + int r, i; + + for (i = 1, r = -1; i <= retries && r != 0; i++) { + if (i > 1) + WARN("Retry writing firmware (%d/%d)...\n", i, retries); + r = flashrom_write_image(image, section_name, diff_image, + do_verify, verbosity + 1); + } + return r; } /* Helper function to return host software write protection status. */ diff --git a/futility/updater_utils.h b/futility/updater_utils.h index ae5574f2..8ac06831 100644 --- a/futility/updater_utils.h +++ b/futility/updater_utils.h @@ -85,7 +85,8 @@ int load_firmware_image(struct firmware_image *image, const char *file_name, * Returns 0 if success, non-zero if error. */ int load_system_firmware(struct firmware_image *image, - struct tempfile *tempfiles, int verbosity); + struct tempfile *tempfiles, + int retries, int verbosity); /* Frees the allocated resource from a firmware image object. */ void free_firmware_image(struct firmware_image *image); @@ -107,7 +108,7 @@ int write_system_firmware(const struct firmware_image *image, const struct firmware_image *diff_image, const char *section_name, struct tempfile *tempfiles, - int do_verify, int verbosity); + int do_verify, int retries, int verbosity); struct firmware_section { uint8_t *data; -- cgit v1.2.1