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>
This commit is contained in:
Randall Spangler
2012-07-11 13:37:20 -07:00
committed by Gerrit
parent fe5c01cb6e
commit bdf3ba5ded
5 changed files with 63 additions and 65 deletions

View File

@@ -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

View File

@@ -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 {

View File

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

View File

@@ -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;
if (!(EC_VER_MASK(args->version) & cmd->version_mask))
return EC_RES_INVALID_VERSION;
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;
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);
}
}
}

View File

@@ -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 \