summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2012-07-11 13:37:20 -0700
committerGerrit <chrome-bot@google.com>2012-07-11 17:22:57 -0700
commitbdf3ba5ded28e0686452cedfd5fe83e4b1bef84e (patch)
tree5d2abf191aeabf4cfb6015e353142a5302aa3582
parentfe5c01cb6e9426c81af39605ddcb2adbac1d8a1c (diff)
downloadchrome-ec-bdf3ba5ded28e0686452cedfd5fe83e4b1bef84e.tar.gz
Move host_cmd_handler_args farther up the call chain
This is necessary for an imminent change which passes version data from the host bus (LPC/I2C/SPI) into the host command handler. BUG=chrome-os-partner:11275 TEST=from u-boot prompt, 'mkbp hash' Change-Id: If34d0d7c6dc320ad5632becf512c30900fd61aca Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/27190 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r--chip/lm4/lpc.c18
-rw-r--r--chip/stm32/i2c.c15
-rw-r--r--chip/stm32/spi.c29
-rw-r--r--common/host_command.c53
-rw-r--r--include/host_command.h15
5 files changed, 64 insertions, 66 deletions
diff --git a/chip/lm4/lpc.c b/chip/lm4/lpc.c
index 28b4d91867..c5c4627b16 100644
--- a/chip/lm4/lpc.c
+++ b/chip/lm4/lpc.c
@@ -32,9 +32,9 @@
static uint32_t host_events; /* Currently pending SCI/SMI events */
static uint32_t event_mask[3]; /* Event masks for each type */
+static struct host_cmd_handler_args host_cmd_args;
-
-/* Configures GPIOs for module. */
+/* Configure GPIOs for module */
static void configure_gpio(void)
{
/* Set digital alternate function 15 for PL0:5, PM0:2, PM4:5 pins. */
@@ -113,8 +113,8 @@ static void lpc_generate_sci(void)
host_events & event_mask[LPC_HOST_EVENT_SCI]);
}
-
-uint8_t *host_get_buffer(void)
+/* Return buffer for host command params/response. */
+static uint8_t *host_get_buffer(void)
{
return (uint8_t *)LPC_POOL_CMD_DATA;
}
@@ -131,7 +131,7 @@ void host_send_response(enum ec_status result, const uint8_t *data, int size)
/* Fail if response doesn't fit in the param buffer */
if (size < 0 || size > EC_PARAM_SIZE)
- result = EC_RES_ERROR;
+ result = EC_RES_INVALID_RESPONSE;
else if (data != out)
memcpy(out, data, size);
@@ -369,7 +369,13 @@ static void lpc_interrupt(void)
* Read the command byte and pass to the host command handler.
* This clears the FRMH bit in the status byte.
*/
- host_command_received(LPC_POOL_USER[0]);
+ host_cmd_args.command = LPC_POOL_USER[0];
+ host_cmd_args.version = 0;
+ host_cmd_args.params = host_get_buffer();
+ host_cmd_args.params_size = EC_PARAM_SIZE;
+ host_cmd_args.response = host_get_buffer();
+ host_cmd_args.response_size = 0;
+ host_command_received(&host_cmd_args);
}
#endif
diff --git a/chip/stm32/i2c.c b/chip/stm32/i2c.c
index 5c343c9bc4..51ed3ae1dd 100644
--- a/chip/stm32/i2c.c
+++ b/chip/stm32/i2c.c
@@ -43,6 +43,7 @@ static struct mutex i2c_mutex;
/* buffer for host commands (including error code and checksum) */
static uint8_t host_buffer[EC_PARAM_SIZE + 2];
+static struct host_cmd_handler_args host_cmd_args;
/* current position in host buffer for reception */
static int rx_index;
@@ -138,11 +139,6 @@ void host_send_response(enum ec_status result, const uint8_t *data, int size)
i2c_write_raw(I2C2, host_buffer, out - host_buffer);
}
-uint8_t *host_get_buffer(void)
-{
- return host_buffer + 1 /* skip room for error code */;
-}
-
static void i2c_event_handler(int port)
{
@@ -177,7 +173,14 @@ static void i2c_event_handler(int port)
if (port == I2C2) { /* AP is waiting for EC response */
if (rx_index) {
/* we have an available command : execute it */
- host_command_received(host_buffer[0]);
+ host_cmd_args.command = host_buffer[0];
+ host_cmd_args.version = 0;
+ host_cmd_args.params = host_buffer + 1;
+ host_cmd_args.params_size = EC_PARAM_SIZE;
+ /* skip room for error code */
+ host_cmd_args.response = host_buffer + 1;
+ host_cmd_args.response_size = 0;
+ host_command_received(&host_cmd_args);
/* reset host buffer after end of transfer */
rx_index = 0;
} else {
diff --git a/chip/stm32/spi.c b/chip/stm32/spi.c
index 09ba7c909c..43386cbe0a 100644
--- a/chip/stm32/spi.c
+++ b/chip/stm32/spi.c
@@ -160,6 +160,7 @@ static void reply(int port, char *msg, int msg_len)
*/
static void spi_interrupt(int port)
{
+ struct host_cmd_handler_args args;
enum ec_status status;
int msg_len;
int dmac;
@@ -177,11 +178,31 @@ static void spi_interrupt(int port)
dma_start_rx(dmac, sizeof(in_msg), (void *)&STM32_SPI_DR(port),
in_msg);
- /* Process the command and send the reply */
- status = host_command_process(0, cmd,
- out_msg + SPI_MSG_HEADER_BYTES + 1, &msg_len);
+ /*
+ * Process the command and send the reply.
+ *
+ * This is kind of ugly, because the host command interface can
+ * only call host_send_response() for one host bus, but stm32 could
+ * potentially have both I2C and SPI active at the same time on the
+ * current devel board.
+ */
+ args.command = cmd;
+ args.version = 0;
+ args.params = out_msg + SPI_MSG_HEADER_BYTES + 1;
+ args.params_size = sizeof(out_msg) - SPI_MSG_PROTO_BYTES;
+ /* TODO: use a different initial buffer for params vs. response */
+ args.response = args.params;
+ args.response_size = 0;
+
+ status = host_command_process(&args);
+
+ if (args.response_size < 0 || args.response_size > EC_PARAM_SIZE)
+ status = EC_RES_INVALID_RESPONSE;
+ else if (args.response != args.params)
+ memcpy(args.response, args.params, args.response_size);
+
out_msg[SPI_MSG_HEADER_BYTES] = status;
- reply(port, out_msg, msg_len);
+ reply(port, out_msg, args.response_size);
/* Wake up the task that watches for end of the incoming message */
task_wake(TASK_ID_SPI);
diff --git a/common/host_command.c b/common/host_command.c
index 51647fe6d3..a5feb73653 100644
--- a/common/host_command.c
+++ b/common/host_command.c
@@ -22,7 +22,7 @@
#define TASK_EVENT_CMD_PENDING TASK_EVENT_CUSTOM(1)
-static int pending_cmd;
+static struct host_cmd_handler_args *pending_args;
#ifndef CONFIG_LPC
static uint8_t host_memmap[EC_MEMMAP_SIZE];
@@ -37,7 +37,7 @@ uint8_t *host_get_memmap(int offset)
#endif
}
-void host_command_received(int command)
+void host_command_received(struct host_cmd_handler_args *args)
{
/* TODO: should warn if we already think we're in a command */
@@ -46,7 +46,7 @@ void host_command_received(int command)
* host processor a way to unwedge the EC even if it's busy with some
* other command.
*/
- if (command == EC_CMD_REBOOT) {
+ if (args->command == EC_CMD_REBOOT) {
system_reset(1);
/* Reset should never return; if it does, post an error */
host_send_response(EC_RES_ERROR, NULL, 0);
@@ -54,7 +54,7 @@ void host_command_received(int command)
}
/* Save the command */
- pending_cmd = command;
+ pending_args = args;
/* Wake up the task to handle the command */
task_set_event(TASK_ID_HOSTCMD, TASK_EVENT_CMD_PENDING, 0);
@@ -182,38 +182,19 @@ DECLARE_HOST_COMMAND(EC_CMD_GET_CMD_VERSIONS,
host_command_get_cmd_versions,
EC_VER_MASK(0));
-enum ec_status host_command_process(int command, uint8_t *data,
- int *response_size)
+enum ec_status host_command_process(struct host_cmd_handler_args *args)
{
- const struct host_command *cmd = find_host_command(command);
- struct host_cmd_handler_args args;
- enum ec_status res;
+ const struct host_command *cmd = find_host_command(args->command);
- CPRINTF("[%T hostcmd 0x%02x]\n", command);
+ CPRINTF("[%T hostcmd 0x%02x]\n", args->command);
if (!cmd)
return EC_RES_INVALID_COMMAND;
- /* TODO: right now we assume the same data buffer for both params
- * and response. This isn't true for I2C/SPI; we should
- * propagate args farther up the call chain. */
- args.command = command;
- args.version = 0;
- args.params = data;
- args.params_size = EC_PARAM_SIZE;
- args.response = data;
- args.response_size = 0;
-
- res = cmd->handler(&args);
-
- /* Copy response data if necessary */
- *response_size = args.response_size;
- if (args.response_size > EC_PARAM_SIZE)
- return EC_RES_INVALID_RESPONSE;
- else if (args.response_size && args.response != data)
- memcpy(data, args.response, args.response_size);
-
- return res;
+ if (!(EC_VER_MASK(args->version) & cmd->version_mask))
+ return EC_RES_INVALID_VERSION;
+
+ return cmd->handler(args);
}
/*****************************************************************************/
@@ -221,7 +202,6 @@ enum ec_status host_command_process(int command, uint8_t *data,
static int host_command_init(void)
{
- pending_cmd = -1;
host_set_single_event(EC_HOST_EVENT_INTERFACE_READY);
CPRINTF("[%T hostcmd init 0x%x]\n", host_get_events());
@@ -236,13 +216,10 @@ void host_command_task(void)
/* wait for the next command event */
int evt = task_wait_event(-1);
/* process it */
- if (evt & TASK_EVENT_CMD_PENDING) {
- int size = 0; /* Default to no response data */
- int res = host_command_process(pending_cmd,
- host_get_buffer(),
- &size);
-
- host_send_response(res, host_get_buffer(), size);
+ if ((evt & TASK_EVENT_CMD_PENDING) && pending_args) {
+ enum ec_status res = host_command_process(pending_args);
+ host_send_response(res, pending_args->response,
+ pending_args->response_size);
}
}
}
diff --git a/include/host_command.h b/include/host_command.h
index b892a68ec8..566d90f190 100644
--- a/include/host_command.h
+++ b/include/host_command.h
@@ -54,14 +54,10 @@ uint8_t *host_get_memmap(int offset);
/**
* Process a host command and return its response
*
- * @param command The command code
- * @param data Buffer holding the command, and used for the
- * response payload.
- * @param response_size Returns the size of the response
+ * @param args Command handler args
* @return resulting status
*/
-enum ec_status host_command_process(int command, uint8_t *data,
- int *response_size);
+enum ec_status host_command_process(struct host_cmd_handler_args *args);
/**
* Set one or more host event bits.
@@ -96,7 +92,7 @@ uint32_t host_get_events(void);
/**
* Called by host interface module when a command is received.
*/
-void host_command_received(int command);
+void host_command_received(struct host_cmd_handler_args *args);
/**
* Send a successful result code along with response data to a host command.
@@ -107,11 +103,6 @@ void host_command_received(int command);
*/
void host_send_response(enum ec_status result, const uint8_t *data, int size);
-/* Return a pointer to the host command data buffer. This buffer must
- * only be accessed between a notification to host_command_received()
- * and a subsequent call to lpc_SendHostResponse(). */
-uint8_t *host_get_buffer(void);
-
/* Register a host command handler */
#define DECLARE_HOST_COMMAND(command, routine, version_mask) \
const struct host_command __host_cmd_##command \