ectool: use poll interface

Test polling for MKBP events through the kernel cros_ec/pd/fp/.. driver
node.

Signed-off-by: Vincent Palatin <vpalatin@chromium.org>

BRANCH=none
BUG=b:69460856
TEST=run on Eve EVT:
ectool --name=cros_fp fpmode fingerdown && \
ectool --name=cros_fp waitevent 5 10000

Change-Id: Ibdec137a3b646cf017a29afcf24ff5bbfb731198
Reviewed-on: https://chromium-review.googlesource.com/806167
Commit-Ready: Vincent Palatin <vpalatin@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Shawn N <shawnn@chromium.org>
This commit is contained in:
Vincent Palatin
2017-11-24 16:45:34 +01:00
committed by chrome-bot
parent 96a7e9fe81
commit b16f759652
5 changed files with 87 additions and 1 deletions

View File

@@ -6,6 +6,7 @@
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -219,6 +220,24 @@ static int ec_dev_is_v2(void)
return 0;
}
static int ec_pollevent_dev(unsigned long mask, void *buffer, size_t buf_size,
int timeout)
{
int rv;
struct pollfd pf = { .fd = fd, .events = POLLIN };
ioctl(fd, CROS_EC_DEV_IOCEVENTMASK_V2, mask);
rv = poll(&pf, 1, timeout);
if (rv != 1)
return rv;
if (pf.revents != POLLIN)
return -pf.revents;
return read(fd, buffer, buf_size);
}
int comm_init_dev(const char *device_name)
{
int (*ec_cmd_readmem)(int offset, int bytes, void *dest);
@@ -257,6 +276,7 @@ int comm_init_dev(const char *device_name)
if (ec_cmd_readmem(EC_MEMMAP_ID, 2, version) == 2 &&
version[0] == 'E' && version[1] == 'C')
ec_readmem = ec_cmd_readmem;
ec_pollevent = ec_pollevent_dev;
/*
* Set temporary size, will be updated later.

View File

@@ -21,6 +21,9 @@ int (*ec_command_proto)(int command, int version,
int (*ec_readmem)(int offset, int bytes, void *dest);
int (*ec_pollevent)(unsigned long mask, void *buffer, size_t buf_size,
int timeout);
int ec_max_outsize, ec_max_insize;
void *ec_outbuf;
void *ec_inbuf;

View File

@@ -75,4 +75,14 @@ extern int (*ec_command_proto)(int command, int version,
*/
extern int (*ec_readmem)(int offset, int bytes, void *dest);
/**
* Wait for a MKBP event matching 'mask' for at most 'timeout' milliseconds.
* Then read the incoming event content in 'buffer' (or at most
* 'buf_size' bytes of it).
* Return the size of the event read on success, 0 in case of timeout,
* or a negative value in case of error.
*/
extern int (*ec_pollevent)(unsigned long mask, void *buffer, size_t buf_size,
int timeout);
#endif /* __UTIL_COMM_HOST_H */

View File

@@ -85,5 +85,6 @@ struct cros_ec_readmem_v2 {
struct cros_ec_command_v2)
#define CROS_EC_DEV_IOCRDMEM_V2 _IOWR(CROS_EC_DEV_IOC_V2, 1, \
struct cros_ec_readmem_v2)
#define CROS_EC_DEV_IOCEVENTMASK_V2 _IO(CROS_EC_DEV_IOC_V2, 2)
#endif /* __UTIL_CROS_EC_DEV_H */

View File

@@ -258,6 +258,8 @@ const char help_str[] =
" Get USB PD power information\n"
" version\n"
" Prints EC version\n"
" waitevent <type> [<timeout>]\n"
" Wait for the MKBP event of type and display it\n"
" wireless <flags> [<mask> [<suspend_flags> <suspend_mask>]]\n"
" Enable/disable WLAN/Bluetooth radio\n"
"";
@@ -1264,7 +1266,7 @@ int cmd_fp_mode(int argc, char *argv[])
if (r.mode & FP_MODE_CAPTURE)
printf("capture ");
printf("\n");
return rv;
return 0;
}
int cmd_fp_info(int argc, char *argv[])
@@ -7592,6 +7594,55 @@ err:
return rv < 0;
}
int cmd_wait_event(int argc, char *argv[])
{
int rv, i;
struct ec_response_get_next_event buffer;
long timeout = 5000;
long event_type;
char *e;
if (!ec_pollevent) {
fprintf(stderr, "Polling for MKBP event not supported\n");
return -EINVAL;
}
if (argc < 2) {
fprintf(stderr, "Usage: %s <type> [<timeout>]\n",
argv[0]);
return -1;
}
event_type = strtol(argv[1], &e, 0);
if ((e && *e) || event_type < 0 || event_type >= EC_MKBP_EVENT_COUNT) {
fprintf(stderr, "Bad event type '%s'.\n", argv[1]);
return -1;
}
if (argc >= 3) {
timeout = strtol(argv[2], &e, 0);
if (e && *e) {
fprintf(stderr, "Bad timeout value '%s'.\n", argv[2]);
return -1;
}
}
rv = ec_pollevent(1 << event_type, &buffer, sizeof(buffer), timeout);
if (rv == 0) {
fprintf(stderr, "Timeout waitout for MKBP event\n");
return -ETIMEDOUT;
} else if (rv < 0) {
perror("Error polling for MKBP event\n");
return -EIO;
}
printf("MKBP event %d data: ", buffer.event_type);
for (i = 0; i < rv - 1; ++i)
printf("%02x ", buffer.data.key_matrix[i]);
printf("\n");
return 0;
}
/* NULL-terminated list of commands */
const struct command commands[] = {
{"autofanctrl", cmd_thermal_auto_fan_ctrl},
@@ -7701,6 +7752,7 @@ const struct command commands[] = {
{"usbpdmuxinfo", cmd_usb_pd_mux_info},
{"usbpdpower", cmd_usb_pd_power},
{"version", cmd_version},
{"waitevent", cmd_wait_event},
{"wireless", cmd_wireless},
{NULL, NULL}
};