summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlec Berg <alecaberg@chromium.org>2014-09-10 03:49:34 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-09-17 01:24:05 +0000
commit5bc3dc3bbe8f062b39065678638b820de330dee2 (patch)
tree28144048e475ba5b4d47cb6b24a19db08e02ab9f
parentfab7ac3b9a5cc26927b8a40bbbba8049d64b323b (diff)
downloadchrome-ec-5bc3dc3bbe8f062b39065678638b820de330dee2.tar.gz
samus: add automatic retries for host commands from EC to PD
Add three retries for EC to PD host commands. With this change, removed retry mechanism in host_command_pd.c which was a retry only for the specific EC_CMD_PD_EXCHANGE_STATUS host command. BUG=chrome-os-partner:32006 BRANCH=none TEST=Loaded EC code onto samus. Added the following code for testing failed host commands to samus_pd common/host_command.c host_command_task(): if ((evt & TASK_EVENT_CMD_PENDING) && pending_args) { if (i++ != 4) pending_args->result = host_command_process(pending_args); else { pending_args->result = -7; i = 0; } host_send_response(pending_args); } This test code on samus_pd drops one in every five host commands. With this code, from the EC, I send "pdcmd 0 0", and verified that 1 out of 5 times the EC prints a host command failed code, but then retries successfully. Change-Id: Ibf43feefbfc7d791c45c6689b82c66f5d71046ab Signed-off-by: Alec Berg <alecaberg@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/217461 Reviewed-by: Todd Broch <tbroch@chromium.org>
-rw-r--r--common/host_command_master.c36
-rw-r--r--common/host_command_pd.c10
-rw-r--r--include/ec_commands.h3
3 files changed, 27 insertions, 22 deletions
diff --git a/common/host_command_master.c b/common/host_command_master.c
index 38acd9a560..11d0dbca06 100644
--- a/common/host_command_master.c
+++ b/common/host_command_master.c
@@ -20,6 +20,9 @@
/* Host command timeout */
#define HOST_COMMAND_TIMEOUT_US SECOND
+/* Number of attempts for each PD host command */
+#define PD_HOST_COMMAND_ATTEMPTS 3
+
static struct mutex pd_mutex;
/**
@@ -86,7 +89,7 @@ static int pd_host_command_internal(int command, int version,
if (ret) {
i2c_lock(I2C_PORT_PD_MCU, 0);
CPRINTF("[%T i2c transaction 1 failed: %d]\n", ret);
- return -ret;
+ return -EC_RES_BUS_ERROR;
}
resp_len = resp_buf[1];
@@ -107,7 +110,7 @@ static int pd_host_command_internal(int command, int version,
i2c_lock(I2C_PORT_PD_MCU, 0);
if (ret) {
CPRINTF("[%T i2c transaction 2 failed: %d]\n", ret);
- return -ret;
+ return -EC_RES_BUS_ERROR;
}
/* Check for host command error code */
@@ -151,7 +154,7 @@ static int pd_host_command_internal(int command, int version,
if ((uint8_t)sum) {
CPRINTF("[%T command 0x%02x bad checksum returned: "
"%d]\n", command, sum);
- return -EC_RES_ERROR;
+ return -EC_RES_INVALID_CHECKSUM;
}
/* Return output buffer size */
@@ -163,16 +166,23 @@ int pd_host_command(int command, int version,
void *indata, int insize)
{
int rv;
-
- /* Acquire mutex */
- mutex_lock(&pd_mutex);
-
- /* Call internal version of host command */
- rv = pd_host_command_internal(command, version, outdata, outsize,
- indata, insize);
-
- /* Release mutex */
- mutex_unlock(&pd_mutex);
+ int tries = 0;
+
+ /* Try multiple times to send host command. */
+ for (tries = 0; tries < PD_HOST_COMMAND_ATTEMPTS; tries++) {
+ /* Acquire mutex */
+ mutex_lock(&pd_mutex);
+ /* Call internal version of host command */
+ rv = pd_host_command_internal(command, version, outdata,
+ outsize, indata, insize);
+ /* Release mutex */
+ mutex_unlock(&pd_mutex);
+
+ /* If host command error due to i2c bus error, try again. */
+ if (rv != -EC_RES_BUS_ERROR)
+ break;
+ task_wait_event(50*MSEC);
+ }
return rv;
}
diff --git a/common/host_command_pd.c b/common/host_command_pd.c
index ecd5e07cf5..444e9e3288 100644
--- a/common/host_command_pd.c
+++ b/common/host_command_pd.c
@@ -26,7 +26,7 @@ static void pd_exchange_status(void)
{
struct ec_params_pd_status ec_status;
struct ec_response_pd_status pd_status;
- int rv = 0, tries = 0;
+ int rv = 0;
/* Send battery state of charge */
if (charge_get_flags() & CHARGE_FLAG_BATT_RESPONSIVE)
@@ -34,15 +34,9 @@ static void pd_exchange_status(void)
else
ec_status.batt_soc = -1;
- /* Try 3 times to get the PD MCU status. */
- while (tries++ < 3) {
- rv = pd_host_command(EC_CMD_PD_EXCHANGE_STATUS, 0, &ec_status,
+ rv = pd_host_command(EC_CMD_PD_EXCHANGE_STATUS, 0, &ec_status,
sizeof(struct ec_params_pd_status), &pd_status,
sizeof(struct ec_response_pd_status));
- if (rv >= 0)
- break;
- task_wait_event(500*MSEC);
- }
if (rv < 0) {
CPRINTS("Host command to PD MCU failed");
diff --git a/include/ec_commands.h b/include/ec_commands.h
index 4428648511..951551769b 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -224,7 +224,8 @@ enum ec_status {
EC_RES_OVERFLOW = 11, /* Table / data overflow */
EC_RES_INVALID_HEADER = 12, /* Header contains invalid data */
EC_RES_REQUEST_TRUNCATED = 13, /* Didn't get the entire request */
- EC_RES_RESPONSE_TOO_BIG = 14 /* Response was too big to handle */
+ EC_RES_RESPONSE_TOO_BIG = 14, /* Response was too big to handle */
+ EC_RES_BUS_ERROR = 15 /* Communications bus error */
};
/*