summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGwendal Grignou <gwendal@chromium.org>2015-03-24 17:11:09 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-05-30 01:04:29 +0000
commitc89ebdb66c839fb6ef7787d22c4492a4507fb727 (patch)
tree91576ccf12e34e6c16c25935ea353f898f14289e
parent1ade8e02a7379732683e34b5cd71acfb2f1685ce (diff)
downloadchrome-ec-c89ebdb66c839fb6ef7787d22c4492a4507fb727.tar.gz
ectool: query packet size and set them properly internally.
Allow to negotiate the packet command and responses to whatever values the EC can support. Set the buffer size including the necessary V3 header. If the EC run v3 protocol with large packet support, but the kernel does not have v3 support (3.10), we can not support sending or receiving large commands. Be aware that on 3.10, commands like ectool console will fail if the EC wants to send command larger than the kernel can handle. Copied kernel_version_ge from libusb-1.0.19/libusb/os/linux_usbfs.c. BUG=chrome-os-partner:31989,chrome-os-partner:31660,chromium:454324,chrome-os-partner:39265 BRANCH=none TEST=Build a special firmware to exchange 300 bytes. Check ectool console works with the righ size. Check that ectool is calling uname. Check on Nyan_big: without change, "ectool version" crashes kernel. With changes, "ectool version" works. In conseuqence, it reverts commit be0bd9b83538427cc350ad38d64b821dfcad82a0, "ectool: Do not increase buffer size after probe max size from ec" Change-Id: I54ffd43488ea81272f30789dc87a261085769fe0 Signed-off-by: Gwendal Grignou <gwendal@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/274086 Reviewed-by: Shawn N <shawnn@chromium.org>
-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