summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--futility/updater.c17
-rw-r--r--futility/updater.h1
-rw-r--r--futility/updater_quirks.c5
-rw-r--r--futility/updater_utils.c24
-rw-r--r--futility/updater_utils.h5
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
@@ -384,6 +384,14 @@ static int emulate_write_firmware(const char *filename,
}
/*
+ * 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.
* Returns 0 if success, non-zero if error.
@@ -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;