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>
This commit is contained in:
Alec Berg
2014-09-10 03:49:34 -07:00
committed by chrome-internal-fetch
parent fab7ac3b9a
commit 5bc3dc3bbe
3 changed files with 25 additions and 20 deletions

View File

@@ -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;
int tries = 0;
/* Acquire mutex */
mutex_lock(&pd_mutex);
/* 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);
/* 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;
}

View File

@@ -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");

View File

@@ -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 */
};
/*