mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-27 18:25:05 +00:00
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:
@@ -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
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 \
|
||||
|
||||
Reference in New Issue
Block a user