diff options
-rw-r--r-- | util/build.mk | 4 | ||||
-rw-r--r-- | util/comm-host.c | 19 | ||||
-rw-r--r-- | util/misc_util.c | 37 | ||||
-rw-r--r-- | util/misc_util.h | 5 |
4 files changed, 59 insertions, 6 deletions
diff --git a/util/build.mk b/util/build.mk index f9b0f87932..74466ba1f0 100644 --- a/util/build.mk +++ b/util/build.mk @@ -10,9 +10,9 @@ host-util-bin=ectool lbplay stm32mon ec_sb_firmware_update lbcc build-util-bin=ec_uartd iteflash comm-objs=$(util-lock-objs:%=lock/%) comm-host.o comm-dev.o -comm-objs+=comm-lpc.o comm-i2c.o +comm-objs+=comm-lpc.o comm-i2c.o misc_util.o -ectool-objs=ectool.o ectool_keyscan.o misc_util.o ec_flash.o $(comm-objs) +ectool-objs=ectool.o ectool_keyscan.o ec_flash.o $(comm-objs) ec_sb_firmware_update-objs=ec_sb_firmware_update.o $(comm-objs) misc_util.o ec_sb_firmware_update-objs+=powerd_lock.o lbplay-objs=lbplay.o $(comm-objs) diff --git a/util/comm-host.c b/util/comm-host.c index 7da86316fb..601411d74f 100644 --- a/util/comm-host.c +++ b/util/comm-host.c @@ -11,6 +11,8 @@ #include "comm-host.h" #include "ec_commands.h" +#include "misc_util.h" + int (*ec_command_proto)(int command, int version, const void *outdata, int outsize, @@ -78,10 +80,17 @@ int ec_command(int command, int version, int comm_init(int interfaces, const char *device_name) { struct ec_response_get_protocol_info info; + int allow_large_buffer; /* Default memmap access */ ec_readmem = fake_readmem; + allow_large_buffer = kernel_version_ge(3, 14, 0); + if (allow_large_buffer < 0) { + fprintf(stderr, "Unable to check linux version\n"); + return 1; + } + /* Prefer new /dev method */ if ((interfaces & COMM_DEV) && comm_init_dev && !comm_init_dev(device_name)) @@ -111,10 +120,12 @@ int comm_init(int interfaces, const char *device_name) /* read max request / response size from ec for protocol v3+ */ if (ec_command(EC_CMD_GET_PROTOCOL_INFO, 0, NULL, 0, &info, sizeof(info)) == sizeof(info)) { - ec_max_outsize = info.max_request_packet_size - - sizeof(struct ec_host_request); - ec_max_insize = info.max_response_packet_size - - sizeof(struct ec_host_response); + if ((allow_large_buffer) || + (info.max_request_packet_size < ec_max_outsize)) + ec_max_outsize = info.max_request_packet_size; + if ((allow_large_buffer) || + (info.max_request_packet_size < ec_max_insize)) + ec_max_insize = info.max_response_packet_size; ec_outbuf = realloc(ec_outbuf, ec_max_outsize); ec_inbuf = realloc(ec_inbuf, ec_max_insize); diff --git a/util/misc_util.c b/util/misc_util.c index 63c0fead2a..3e4ff71f0f 100644 --- a/util/misc_util.c +++ b/util/misc_util.c @@ -8,6 +8,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/utsname.h> #include "comm-host.h" #include "misc_util.h" @@ -133,3 +134,39 @@ int ec_cmd_version_supported(int cmd, int ver) return (mask & EC_VER_MASK(ver)) ? 1 : 0; } + +/** + * Return 1 is the current kernel version is greater or equal to + * <major>.<minor>.<sublevel> + */ +int kernel_version_ge(int major, int minor, int sublevel) +{ + struct utsname uts; + int atoms, kmajor, kminor, ksublevel; + + if (uname(&uts) < 0) + return -1; + atoms = sscanf(uts.release, "%d.%d.%d", &kmajor, &kminor, &ksublevel); + if (atoms < 1) + return -1; + + if (kmajor > major) + return 1; + if (kmajor < major) + return 0; + + /* kmajor == major */ + if (atoms < 2) + return 0 == minor && 0 == sublevel; + if (kminor > minor) + return 1; + if (kminor < minor) + return 0; + + /* kminor == minor */ + if (atoms < 3) + return 0 == sublevel; + + return ksublevel >= sublevel; +} + diff --git a/util/misc_util.h b/util/misc_util.h index c54d68fc96..c550a1baa1 100644 --- a/util/misc_util.h +++ b/util/misc_util.h @@ -56,4 +56,9 @@ int ec_get_cmd_versions(int cmd, uint32_t *pmask); */ int ec_cmd_version_supported(int cmd, int ver); +/** + * Return 1 is the current kernel version is greater or equal to + * <major>.<minor>.<sublevel> + */ +int kernel_version_ge(int major, int minor, int sublevel); #endif |