From 801273617d2feb754253f715a3ade1b23eeafefc Mon Sep 17 00:00:00 2001 From: Vincent Palatin Date: Fri, 24 Nov 2017 16:45:34 +0100 Subject: ectool: use poll interface Test polling for MKBP events through the kernel cros_ec/pd/fp/.. driver node. Signed-off-by: Vincent Palatin BRANCH=none BUG=b:69460856 TEST=run on Eve EVT: ectool --name=cros_fp fpmode fingerdown && \ ectool --name=cros_fp waitevent 5 10000 Reviewed-on: https://chromium-review.googlesource.com/806167 Reviewed-by: Shawn N (cherry picked from commit b16f759652f074ee597fc4db8c403a46eab32c50) Change-Id: Ibdec137a3b646cf017a29afcf24ff5bbfb731198 Reviewed-on: https://chromium-review.googlesource.com/1063872 Tested-by: Stefan Adolfsson Reviewed-by: Daisuke Nojiri Commit-Queue: Stefan Adolfsson --- util/comm-dev.c | 20 ++++++++++++++++++++ util/comm-host.c | 3 +++ util/comm-host.h | 10 ++++++++++ util/cros_ec_dev.h | 1 + util/ectool.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 87 insertions(+), 1 deletion(-) diff --git a/util/comm-dev.c b/util/comm-dev.c index 96356a6177..33a69f9d6f 100644 --- a/util/comm-dev.c +++ b/util/comm-dev.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -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. diff --git a/util/comm-host.c b/util/comm-host.c index 9fc65ab634..cc7da3296a 100644 --- a/util/comm-host.c +++ b/util/comm-host.c @@ -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; diff --git a/util/comm-host.h b/util/comm-host.h index 1d3cb9e36d..7a71cb6e34 100644 --- a/util/comm-host.h +++ b/util/comm-host.h @@ -74,4 +74,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 */ diff --git a/util/cros_ec_dev.h b/util/cros_ec_dev.h index 65c112c3b2..7ff87aed9a 100644 --- a/util/cros_ec_dev.h +++ b/util/cros_ec_dev.h @@ -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 */ diff --git a/util/ectool.c b/util/ectool.c index 97f86eb5c2..b0dc08f996 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -253,6 +253,8 @@ const char help_str[] = " Get USB PD power information\n" " version\n" " Prints EC version\n" + " waitevent []\n" + " Wait for the MKBP event of type and display it\n" " wireless [ [ ]]\n" " Enable/disable WLAN/Bluetooth radio\n" ""; @@ -1109,7 +1111,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[]) @@ -7222,6 +7224,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 []\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}, @@ -7329,6 +7380,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} }; -- cgit v1.2.1