diff options
author | Randall Spangler <rspangler@chromium.org> | 2012-07-11 13:37:20 -0700 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2012-07-11 17:22:57 -0700 |
commit | bdf3ba5ded28e0686452cedfd5fe83e4b1bef84e (patch) | |
tree | 5d2abf191aeabf4cfb6015e353142a5302aa3582 | |
parent | fe5c01cb6e9426c81af39605ddcb2adbac1d8a1c (diff) | |
download | chrome-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.c | 18 | ||||
-rw-r--r-- | chip/stm32/i2c.c | 15 | ||||
-rw-r--r-- | chip/stm32/spi.c | 29 | ||||
-rw-r--r-- | common/host_command.c | 53 | ||||
-rw-r--r-- | include/host_command.h | 15 |
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 \ |