From 02e847b919b4807440ddb02bdfa7c8ac74edd7f2 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Fri, 20 Feb 2015 13:36:11 -0800 Subject: [PATCH] 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: I5d1cf29ac1c555ea2336ebb0b0e0a3f7cbb9c3fd Signed-off-by: Stefan Reinauer Original-Commit-Id: 894a8a0b4a9805e92544b5e3dfa90baf6d36649a Original-Change-Id: I6267cdda2be2bad34541b687404c2434d3be345b Original-Signed-off-by: Julius Werner Original-Reviewed-on: https://chromium-review.googlesource.com/251694 Original-Reviewed-by: Aaron Durbin Reviewed-on: http://review.coreboot.org/9507 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- src/ec/google/chromeec/crosec_proto.c | 2 +- src/ec/google/chromeec/ec.c | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/ec/google/chromeec/crosec_proto.c b/src/ec/google/chromeec/crosec_proto.c index 55a707db17..1183e827f1 100644 --- a/src/ec/google/chromeec/crosec_proto.c +++ b/src/ec/google/chromeec/crosec_proto.c @@ -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; } diff --git a/src/ec/google/chromeec/ec.c b/src/ec/google/chromeec/ec.c index 83c22d3a35..bda88e462f 100644 --- a/src/ec/google/chromeec/ec.c +++ b/src/ec/google/chromeec/ec.c @@ -232,11 +232,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; @@ -251,7 +252,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);