Host command interface has only one slot now

Now that ACPI events are handled directly in the LPC interrupt
handler, we can simplify the host event code.

BUG=chrome-os-partner:11240
TEST=boot system; should boot
close lid; should send SMI and suspend system

Change-Id: I8c73ea31a66e94310e4460a008635a103220413e
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/27100
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
This commit is contained in:
Randall Spangler
2012-07-10 16:48:19 -07:00
committed by Gerrit
parent f2400b869e
commit 29332907d4
7 changed files with 140 additions and 158 deletions

View File

@@ -43,7 +43,7 @@
/* TODO: these should really only be used inside lpc.c; once they are, remove
* from board header files. */
/* LPC channels */
#define LPC_CH_KERNEL 0 /* Kernel commands */
#define LPC_CH_ACPI 0 /* ACPI commands */
#define LPC_CH_PORT80 1 /* Port 80 debug output */
#define LPC_CH_CMD_DATA 2 /* Data for kernel/user-mode commands */
#define LPC_CH_KEYBOARD 3 /* 8042 keyboard emulation */
@@ -51,15 +51,15 @@
#define LPC_CH_MEMMAP 5 /* Data for kernel/user-mode commands */
#define LPC_CH_COMX 7 /* UART emulation */
/* LPC pool offsets */
#define LPC_POOL_OFFS_KERNEL 0 /* Kernel commands - 0=in, 1=out */
#define LPC_POOL_OFFS_ACPI 0 /* ACPI commands - 0=in, 1=out */
#define LPC_POOL_OFFS_PORT80 4 /* Port 80 - 4=in, 5=out */
#define LPC_POOL_OFFS_COMX 8 /* UART emulation range - 8-15 */
#define LPC_POOL_OFFS_KEYBOARD 16 /* Keyboard - 16=in, 17=out */
#define LPC_POOL_OFFS_USER 20 /* User commands - 20=in, 21=out */
#define LPC_POOL_OFFS_CMD_DATA 512 /* Data range for commands - 512-767 */
#define LPC_POOL_OFFS_MEMMAP 768 /* Data range for commands - 768-1023 */
#define LPC_POOL_OFFS_CMD_DATA 512 /* Data range for user commands - 512-639 */
#define LPC_POOL_OFFS_MEMMAP 768 /* Memory-mapped data - 768-1023 */
/* LPC pool data pointers */
#define LPC_POOL_KERNEL (LM4_LPC_LPCPOOL + LPC_POOL_OFFS_KERNEL)
#define LPC_POOL_ACPI (LM4_LPC_LPCPOOL + LPC_POOL_OFFS_ACPI)
#define LPC_POOL_PORT80 (LM4_LPC_LPCPOOL + LPC_POOL_OFFS_PORT80)
#define LPC_POOL_COMX (LM4_LPC_LPCPOOL + LPC_POOL_OFFS_COMX)
#define LPC_POOL_KEYBOARD (LM4_LPC_LPCPOOL + LPC_POOL_OFFS_KEYBOARD)

View File

@@ -5,14 +5,14 @@
/* LPC module for Chrome EC */
#include "board.h"
#include "common.h"
#include "console.h"
#include "ec_commands.h"
#include "gpio.h"
#include "hooks.h"
#include "host_command.h"
#include "i8042.h"
#include "lpc.h"
#include "ec_commands.h"
#include "port80.h"
#include "registers.h"
#include "system.h"
@@ -114,9 +114,9 @@ static void lpc_generate_sci(void)
}
uint8_t *host_get_buffer(int slot)
uint8_t *host_get_buffer(void)
{
return (uint8_t *)LPC_POOL_CMD_DATA + EC_PARAM_SIZE * slot;
return (uint8_t *)LPC_POOL_CMD_DATA;
}
@@ -125,36 +125,9 @@ uint8_t *lpc_get_memmap_range(void)
return (uint8_t *)LPC_POOL_MEMMAP;
}
static void send_result(int slot, enum ec_status result)
void host_send_response(enum ec_status result, const uint8_t *data, int size)
{
int ch = slot ? LPC_CH_USER : LPC_CH_KERNEL;
/* Write result to the data byte. This sets the TOH bit in the
* status byte and triggers an IRQ on the host so the host can read
* the result. */
/* TODO: (crosbug.com/p/7496) or it would, if we actually set up host
* IRQs */
if (slot)
LPC_POOL_USER[1] = result;
else
LPC_POOL_KERNEL[1] = result;
/* Clear the busy bit */
task_disable_irq(LM4_IRQ_LPC);
LM4_LPC_ST(ch) &= ~(1 << 12);
task_enable_irq(LM4_IRQ_LPC);
/* ACPI 5.0-12.6.1: Generate SCI for Output Buffer Full
* condition on the kernel channel. */
if (ch == LPC_CH_KERNEL)
lpc_generate_sci();
}
void host_send_response(int slot, enum ec_status result, const uint8_t *data,
int size)
{
uint8_t *out = host_get_buffer(slot);
uint8_t *out = host_get_buffer();
/* Fail if response doesn't fit in the param buffer */
if (size < 0 || size > EC_PARAM_SIZE)
@@ -162,17 +135,32 @@ void host_send_response(int slot, enum ec_status result, const uint8_t *data,
else if (data != out)
memcpy(out, data, size);
send_result(slot, result);
/*
* Write result to the data byte. This sets the TOH bit in the
* status byte and triggers an IRQ on the host so the host can read
* the result.
*
* TODO: (crosbug.com/p/7496) or it would, if we actually set up host
* IRQs
*/
LPC_POOL_USER[1] = result;
/* Clear the busy bit */
task_disable_irq(LM4_IRQ_LPC);
LM4_LPC_ST(LPC_CH_USER) &= ~(1 << 12);
task_enable_irq(LM4_IRQ_LPC);
}
/* Return true if the TOH is still set */
int lpc_keyboard_has_char(void) {
int lpc_keyboard_has_char(void)
{
return (LM4_LPC_ST(LPC_CH_KEYBOARD) & TOH) ? 1 : 0;
}
/* Put a char to host buffer and send IRQ if specified. */
void lpc_keyboard_put_char(uint8_t chr, int send_irq) {
void lpc_keyboard_put_char(uint8_t chr, int send_irq)
{
LPC_POOL_KEYBOARD[1] = chr;
if (send_irq) {
lpc_manual_irq(1); /* IRQ#1 */
@@ -237,25 +225,18 @@ static void update_host_event_status(void) {
if (host_events & event_mask[LPC_HOST_EVENT_SMI]) {
/* Only generate SMI for first event */
if (!(LM4_LPC_ST(LPC_CH_USER) & (1 << 10)) ||
!(LM4_LPC_ST(LPC_CH_KERNEL) & (1 << 10)))
if (!(LM4_LPC_ST(LPC_CH_ACPI) & (1 << 10)))
need_smi = 1;
LM4_LPC_ST(LPC_CH_USER) |= (1 << 10);
LM4_LPC_ST(LPC_CH_KERNEL) |= (1 << 10);
} else {
LM4_LPC_ST(LPC_CH_USER) &= ~(1 << 10);
LM4_LPC_ST(LPC_CH_KERNEL) &= ~(1 << 10);
}
LM4_LPC_ST(LPC_CH_ACPI) |= (1 << 10);
} else
LM4_LPC_ST(LPC_CH_ACPI) &= ~(1 << 10);
if (host_events & event_mask[LPC_HOST_EVENT_SCI]) {
/* Generate SCI for every event */
need_sci = 1;
LM4_LPC_ST(LPC_CH_USER) |= (1 << 9);
LM4_LPC_ST(LPC_CH_KERNEL) |= (1 << 9);
} else {
LM4_LPC_ST(LPC_CH_USER) &= ~(1 << 9);
LM4_LPC_ST(LPC_CH_KERNEL) &= ~(1 << 9);
}
LM4_LPC_ST(LPC_CH_ACPI) |= (1 << 9);
} else
LM4_LPC_ST(LPC_CH_ACPI) &= ~(1 << 9);
/* Copy host events to mapped memory */
*mapped_raw_events = host_events;
@@ -319,7 +300,7 @@ uint32_t lpc_get_host_event_mask(enum lpc_host_event_type type)
}
/* Handle an ACPI command on the kernel channel */
/* Handle an ACPI command */
static void handle_acpi_command(void)
{
int cmd;
@@ -327,13 +308,13 @@ static void handle_acpi_command(void)
int i;
/* Set the busy bit */
LM4_LPC_ST(LPC_CH_KERNEL) |= (1 << 12);
LM4_LPC_ST(LPC_CH_ACPI) |= (1 << 12);
/*
* Read the command byte and pass to the host command handler.
* This clears the FRMH bit in the status byte.
*/
cmd = LPC_POOL_KERNEL[0];
cmd = LPC_POOL_ACPI[0];
/* Process the command */
switch (cmd) {
@@ -353,10 +334,10 @@ static void handle_acpi_command(void)
}
/* Write the response */
LPC_POOL_KERNEL[1] = result;
LPC_POOL_ACPI[1] = result;
/* Clear the busy bit */
LM4_LPC_ST(LPC_CH_KERNEL) &= ~(1 << 12);
LM4_LPC_ST(LPC_CH_ACPI) &= ~(1 << 12);
/*
* ACPI 5.0-12.6.1: Generate SCI for Input Buffer Empty / Output Buffer
@@ -375,17 +356,20 @@ static void lpc_interrupt(void)
LM4_LPC_LPCIC = mis;
#ifdef CONFIG_TASK_HOSTCMD
/* Handle host kernel/user command writes */
if (mis & LM4_LPC_INT_MASK(LPC_CH_KERNEL, 4))
/* Handle ACPI command writes */
if (mis & LM4_LPC_INT_MASK(LPC_CH_ACPI, 4))
handle_acpi_command();
/* Handle user command writes */
if (mis & LM4_LPC_INT_MASK(LPC_CH_USER, 4)) {
/* Set the busy bit */
LM4_LPC_ST(LPC_CH_USER) |= (1 << 12);
/* Read the command byte and pass to the host command handler.
* This clears the FRMH bit in the status byte. */
host_command_received(1, LPC_POOL_USER[0]);
/*
* 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]);
}
#endif
@@ -472,35 +456,41 @@ static int lpc_init(void)
/* Configure GPIOs */
configure_gpio();
/* Set LPC channel 0 to I/O address 0x62 (data) / 0x66 (command),
/*
* Set LPC channel 0 to I/O address 0x62 (data) / 0x66 (command),
* single endpoint, offset 0 for host command/writes and 1 for EC
* data writes, pool bytes 0(data)/1(cmd) */
LM4_LPC_ADR(LPC_CH_KERNEL) = EC_LPC_ADDR_KERNEL_DATA;
LM4_LPC_CTL(LPC_CH_KERNEL) = (LPC_POOL_OFFS_KERNEL << (5 - 1));
* data writes, pool bytes 0(data)/1(cmd)
*/
LM4_LPC_ADR(LPC_CH_ACPI) = EC_LPC_ADDR_ACPI_DATA;
LM4_LPC_CTL(LPC_CH_ACPI) = (LPC_POOL_OFFS_ACPI << (5 - 1));
/* Unmask interrupt for host command writes */
LM4_LPC_LPCIM |= LM4_LPC_INT_MASK(LPC_CH_KERNEL, 4);
LM4_LPC_LPCIM |= LM4_LPC_INT_MASK(LPC_CH_ACPI, 4);
/* Set LPC channel 1 to I/O address 0x80 (data), single endpoint,
* pool bytes 4(data)/5(cmd). */
/*
* Set LPC channel 1 to I/O address 0x80 (data), single endpoint,
* pool bytes 4(data)/5(cmd).
*/
LM4_LPC_ADR(LPC_CH_PORT80) = 0x80;
LM4_LPC_CTL(LPC_CH_PORT80) = (LPC_POOL_OFFS_PORT80 << (5 - 1));
/* Unmask interrupt for host data writes */
LM4_LPC_LPCIM |= LM4_LPC_INT_MASK(LPC_CH_PORT80, 2);
/* Set LPC channel 2 to I/O address 0x800, range endpoint,
* arbitration disabled, pool bytes 512-767. To access this from
/*
* Set LPC channel 2 to I/O address 0x880, range endpoint,
* arbitration disabled, pool bytes 512-639. To access this from
* x86, use the following command to set GEN_LPC2:
*
* pci_write32 0 0x1f 0 0x88 0x007c0801
*/
LM4_LPC_ADR(LPC_CH_CMD_DATA) = EC_LPC_ADDR_KERNEL_PARAM;
LM4_LPC_CTL(LPC_CH_CMD_DATA) = 0x8019 |
LM4_LPC_ADR(LPC_CH_CMD_DATA) = EC_LPC_ADDR_USER_PARAM;
LM4_LPC_CTL(LPC_CH_CMD_DATA) = 0x8015 |
(LPC_POOL_OFFS_CMD_DATA << (5 - 1));
/* Set LPC channel 3 to I/O address 0x60 (data) / 0x64 (command),
/*
* Set LPC channel 3 to I/O address 0x60 (data) / 0x64 (command),
* single endpoint, offset 0 for host command/writes and 1 for EC
* data writes, pool bytes 0(data)/1(cmd) */
* data writes, pool bytes 0(data)/1(cmd)
*/
LM4_LPC_ADR(LPC_CH_KEYBOARD) = 0x60;
LM4_LPC_CTL(LPC_CH_KEYBOARD) = (1 << 24/* IRQSEL1 */) |
(0 << 18/* IRQEN1 */) | (LPC_POOL_OFFS_KEYBOARD << (5 - 1));
@@ -508,15 +498,18 @@ static int lpc_init(void)
/* Unmask interrupt for host command/data writes and data reads */
LM4_LPC_LPCIM |= LM4_LPC_INT_MASK(LPC_CH_KEYBOARD, 7);
/* Set LPC channel 4 to I/O address 0x200 (data) / 0x204 (command),
/*
* Set LPC channel 4 to I/O address 0x200 (data) / 0x204 (command),
* single endpoint, offset 0 for host command/writes and 1 for EC
* data writes, pool bytes 0(data)/1(cmd) */
* data writes, pool bytes 0(data)/1(cmd)
*/
LM4_LPC_ADR(LPC_CH_USER) = EC_LPC_ADDR_USER_DATA;
LM4_LPC_CTL(LPC_CH_USER) = (LPC_POOL_OFFS_USER << (5 - 1));
/* Unmask interrupt for host command writes */
LM4_LPC_LPCIM |= LM4_LPC_INT_MASK(LPC_CH_USER, 4);
/* Set LPC channel 5 to I/O address 0x900, range endpoint,
/*
* Set LPC channel 5 to I/O address 0x900, range endpoint,
* arbitration enabled, pool bytes 768-1023. To access this from
* x86, use the following command to set GEN_LPC3:
*
@@ -525,27 +518,35 @@ static int lpc_init(void)
LM4_LPC_ADR(LPC_CH_MEMMAP) = EC_LPC_ADDR_MEMMAP;
LM4_LPC_CTL(LPC_CH_MEMMAP) = 0x0019 | (LPC_POOL_OFFS_MEMMAP << (5 - 1));
/* Set LPC channel 7 to COM port I/O address. Note that channel 7
* ignores the TYPE bit and is always an 8-byte range. */
/*
* Set LPC channel 7 to COM port I/O address. Note that channel 7
* ignores the TYPE bit and is always an 8-byte range.
*/
LM4_LPC_ADR(LPC_CH_COMX) = LPC_COMX_ADDR;
/* TODO: could configure IRQSELs and set IRQEN2/CX, and then the host
* can enable IRQs on its own. */
/*
* TODO: could configure IRQSELs and set IRQEN2/CX, and then the host
* can enable IRQs on its own.
*/
LM4_LPC_CTL(LPC_CH_COMX) = 0x0004 | (LPC_POOL_OFFS_COMX << (5 - 1));
/* Enable COMx emulation for reads and writes. */
LM4_LPC_LPCDMACX = 0x00310000;
/* Unmask interrupt for host data writes. We don't need interrupts for
/*
* Unmask interrupt for host data writes. We don't need interrupts for
* reads, because there's no flow control in that direction; LPC is
* much faster than the UART, and the UART doesn't have anywhere
* sensible to buffer input anyway. */
* sensible to buffer input anyway.
*/
LM4_LPC_LPCIM |= LM4_LPC_INT_MASK(LPC_CH_COMX, 2);
/* Unmaksk LPC bus reset interrupt. This lets us monitor the PCH
* PLTRST# signal for debugging. */
/*
* Unmaksk LPC bus reset interrupt. This lets us monitor the PCH
* PLTRST# signal for debugging.
*/
LM4_LPC_LPCIM |= (1 << 31);
/* Enable LPC channels */
LM4_LPC_LPCCTL = LM4_LPC_SCI_CLK_1 |
(1 << LPC_CH_KERNEL) |
(1 << LPC_CH_ACPI) |
(1 << LPC_CH_PORT80) |
(1 << LPC_CH_CMD_DATA) |
(1 << LPC_CH_KEYBOARD) |

View File

@@ -121,13 +121,11 @@ static int i2c_write_raw(int port, void *buf, int len)
return len;
}
void host_send_response(int slot, enum ec_status result, const uint8_t *data,
int size)
void host_send_response(enum ec_status result, const uint8_t *data, int size)
{
uint8_t *out = host_buffer;
int sum, i;
ASSERT(slot == 0);
*out++ = result;
for (i = 0, sum = 0; i < size; i++, data++, out++) {
if (data != out)
@@ -140,9 +138,8 @@ void host_send_response(int slot, enum ec_status result, const uint8_t *data,
i2c_write_raw(I2C2, host_buffer, out - host_buffer);
}
uint8_t *host_get_buffer(int slot)
uint8_t *host_get_buffer(void)
{
ASSERT(slot == 0);
return host_buffer + 1 /* skip room for error code */;
}
@@ -180,7 +177,7 @@ 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(0, host_buffer[0]);
host_command_received(host_buffer[0]);
/* reset host buffer after end of transfer */
rx_index = 0;
} else {

View File

@@ -5,11 +5,12 @@
/* Host command module for Chrome EC */
#include "common.h"
#include "console.h"
#include "ec_commands.h"
#include "host_command.h"
#include "link_defs.h"
#include "lpc.h"
#include "ec_commands.h"
#include "system.h"
#include "task.h"
#include "timer.h"
@@ -19,9 +20,9 @@
#define CPUTS(outstr) cputs(CC_SYSTEM, outstr)
#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args)
#define TASK_EVENT_SLOT(n) TASK_EVENT_CUSTOM(1 << n)
#define TASK_EVENT_CMD_PENDING TASK_EVENT_CUSTOM(1)
static int host_command[2];
static int pending_cmd;
#ifndef CONFIG_LPC
static uint8_t host_memmap[EC_MEMMAP_SIZE];
@@ -36,25 +37,27 @@ uint8_t *host_get_memmap(int offset)
#endif
}
void host_command_received(int slot, int command)
void host_command_received(int command)
{
/* TODO: should warn if we already think we're in a command */
/* If this is the reboot command, reboot immediately. This gives
* the host processor a way to unwedge the EC even if it's busy with
* some other command. */
/*
* If this is the reboot command, reboot immediately. This gives the
* host processor a way to unwedge the EC even if it's busy with some
* other command.
*/
if (command == EC_CMD_REBOOT) {
system_reset(1);
/* Reset should never return; if it does, post an error */
host_send_response(slot, EC_RES_ERROR, NULL, 0);
host_send_response(EC_RES_ERROR, NULL, 0);
return;
}
/* Save the command */
host_command[slot] = command;
pending_cmd = command;
/* Wake up the task to handle the command for the slot */
task_set_event(TASK_ID_HOSTCMD, TASK_EVENT_SLOT(slot), 0);
/* Wake up the task to handle the command */
task_set_event(TASK_ID_HOSTCMD, TASK_EVENT_CMD_PENDING, 0);
}
@@ -146,14 +149,13 @@ static const struct host_command *find_host_command(int command)
return NULL;
}
enum ec_status host_command_process(int slot, int command, uint8_t *data,
enum ec_status host_command_process(int command, uint8_t *data,
int *response_size)
{
const struct host_command *cmd = find_host_command(command);
enum ec_status res = EC_RES_INVALID_COMMAND;
CPRINTF("[%T hostcmd%d 0x%02x]\n", slot, command);
CPRINTF("[%T hostcmd 0x%02x]\n", command);
*response_size = 0;
if (cmd)
@@ -162,24 +164,12 @@ enum ec_status host_command_process(int slot, int command, uint8_t *data,
return res;
}
/* Handle a host command */
static void command_process(int slot)
{
int size;
int res;
res = host_command_process(slot, host_command[slot],
host_get_buffer(slot), &size);
host_send_response(slot, res, host_get_buffer(slot), size);
}
/*****************************************************************************/
/* Initialization / task */
static int host_command_init(void)
{
host_command[0] = host_command[1] = -1;
pending_cmd = -1;
host_set_single_event(EC_HOST_EVENT_INTERFACE_READY);
CPRINTF("[%T hostcmd init 0x%x]\n", host_get_events());
@@ -194,9 +184,13 @@ void host_command_task(void)
/* wait for the next command event */
int evt = task_wait_event(-1);
/* process it */
if (evt & TASK_EVENT_SLOT(0))
command_process(0);
if (evt & TASK_EVENT_SLOT(1))
command_process(1);
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);
}
}
}

View File

@@ -782,13 +782,8 @@ int host_command_reboot(uint8_t *data, int *resp_size)
/* TODO: (crosbug.com/p/9040) handle EC_REBOOT_FLAG_POWER_ON */
#ifdef CONFIG_TASK_HOSTCMD
#ifdef CONFIG_LPC
/* Clean busy bits on host */
host_send_response(0, EC_RES_SUCCESS, NULL, 0);
host_send_response(1, EC_RES_SUCCESS, NULL, 0);
#elif defined CONFIG_I2C
host_send_response(0, EC_RES_SUCCESS, NULL, 0);
#endif
host_send_response(EC_RES_SUCCESS, NULL, 0);
#endif
CPUTS("[Executing host reboot command]\n");

View File

@@ -31,13 +31,12 @@
#define EC_PROTO_VERSION 0x00000002
/* I/O addresses for LPC commands */
#define EC_LPC_ADDR_KERNEL_DATA 0x62
#define EC_LPC_ADDR_KERNEL_CMD 0x66
#define EC_LPC_ADDR_KERNEL_PARAM 0x800
#define EC_LPC_ADDR_USER_DATA 0x200
#define EC_LPC_ADDR_USER_CMD 0x204
#define EC_LPC_ADDR_USER_PARAM 0x880
#define EC_PARAM_SIZE 128 /* Size of each param area in bytes */
#define EC_LPC_ADDR_ACPI_DATA 0x62
#define EC_LPC_ADDR_ACPI_CMD 0x66
#define EC_LPC_ADDR_USER_DATA 0x200
#define EC_LPC_ADDR_USER_CMD 0x204
#define EC_LPC_ADDR_USER_PARAM 0x880
#define EC_PARAM_SIZE 128 /* Size of param area in bytes */
/* EC command register bit functions */
#define EC_LPC_CMDR_DATA (1 << 0)

View File

@@ -35,15 +35,13 @@ uint8_t *host_get_memmap(int offset);
/**
* Process a host command and return its response
*
* @param slot is 0 for kernel-originated commands,
* 1 for usermode-originated commands.
* @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
* @return resulting status
*/
enum ec_status host_command_process(int slot, int command, uint8_t *data,
enum ec_status host_command_process(int command, uint8_t *data,
int *response_size);
/**
@@ -77,25 +75,23 @@ void host_clear_events(uint32_t mask);
uint32_t host_get_events(void);
/**
* Called by host interface module when a command is written to one of the
* command slots (0=kernel, 1=user).
* Called by host interface module when a command is received.
*/
void host_command_received(int slot, int command);
void host_command_received(int command);
/* Send a successful result code along with response data to a host command.
* <slot> is 0 for kernel-originated commands,
* 1 for usermode-originated commands.
* <result> is the result code for the command (EC_RES_...)
* <data> is the buffer with the response payload.
* <size> is the size of the response buffer. */
void host_send_response(int slot, enum ec_status result, const uint8_t *data,
int size);
/**
* Send a successful result code along with response data to a host command.
*
* @param result Result code for the command (EC_RES_...)
* @param data Buffer with the response payload.
* @param size Size of the response buffer.
*/
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(). <slot> is 0 for
* kernel-originated commands, 1 for usermode-originated commands. */
uint8_t *host_get_buffer(int slot);
* and a subsequent call to lpc_SendHostResponse(). */
uint8_t *host_get_buffer(void);
/* Register a host command handler */
#define DECLARE_HOST_COMMAND(command, routine) \