cros_ec: Retry failed VBNV transactions

This patch adds a few retries to NVRAM read/write transactions with the
EC. Failing to read the NVRAM is not fatal to the boot, but it's still
pretty bad... especially since a single initial read failure will cause
vboot to blindly reinitialize the whole NVRAM with zeroes, destroying
important configuration bits like dev_boot_usb. The current EC
transaction timeout is one second, so the three retries added here can
potentially increase boot time by three seconds per transaction... but
this shouldn't happen in any normal case anyway, and if there are errors
a little extra wait is probably preferrable to nuking your NVRAM.

(Also, added a missing newline to an error message in the EC code.)

BRANCH=veyron
BUG=chrome-os-partner:36924
TEST=Booted a Jerry with the power button bug with a 2 second press,
noticed that the first two transactions failed but the third one
succeeded.

Change-Id: I6267cdda2be2bad34541b687404c2434d3be345b
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/251694
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
(cherry picked from commit 894a8a0b4a9805e92544b5e3dfa90baf6d36649a)
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/251813
This commit is contained in:
Julius Werner 2015-02-20 13:36:11 -08:00 committed by ChromeOS Commit Bot
commit 9192c1a32e
2 changed files with 10 additions and 3 deletions

View file

@ -235,7 +235,7 @@ static int send_command_proto3(struct chromeec_command *cec_command,
rv = crosec_io(out_bytes, in_bytes, context);
if (rv != 0) {
printk(BIOS_ERR, "%s: failed to complete I/O: Err = %#x.",
printk(BIOS_ERR, "%s: failed to complete I/O: Err = %#x.\n",
__func__, rv >= 0 ? rv : -rv);
return -EC_RES_ERROR;
}

View file

@ -233,11 +233,12 @@ int google_chromeec_vbnv_context(int is_read, uint8_t *data, int len)
struct chromeec_command cec_cmd;
struct ec_params_vbnvcontext cmd_vbnvcontext;
struct ec_response_vbnvcontext rsp_vbnvcontext;
int retries = 3;
if (len != EC_VBNV_BLOCK_SIZE)
return -1;
retry:
cec_cmd.cmd_code = EC_CMD_VBNV_CONTEXT;
cec_cmd.cmd_version = EC_VER_VBNV_CONTEXT;
cec_cmd.cmd_data_in = &cmd_vbnvcontext;
@ -252,7 +253,13 @@ int google_chromeec_vbnv_context(int is_read, uint8_t *data, int len)
if (!is_read)
memcpy(&cmd_vbnvcontext.block, data, EC_VBNV_BLOCK_SIZE);
google_chromeec_command(&cec_cmd);
if (google_chromeec_command(&cec_cmd)) {
printk(BIOS_ERR, "ERROR: failed to %s vbnv_ec context: %d\n",
is_read ? "read" : "write", (int)cec_cmd.cmd_code);
mdelay(10); /* just in case */
if (--retries)
goto retry;
}
if (is_read)
memcpy(data, &rsp_vbnvcontext.block, EC_VBNV_BLOCK_SIZE);