summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util/build.mk4
-rw-r--r--util/comm-host.c19
-rw-r--r--util/misc_util.c37
-rw-r--r--util/misc_util.h5
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