summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2014-07-14 16:12:32 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-07-16 07:16:47 +0000
commit241cc626850175acac7a2e95cddbeb269f75c1ba (patch)
tree96f9ae3d712371c976286d574302aa8f78aa59e7
parent9ef82030e6a005df990f8f2924cf54076cd2e8da (diff)
downloadchrome-ec-241cc626850175acac7a2e95cddbeb269f75c1ba.tar.gz
samus: add options for device passthru and interface
This allows sending host commands to the PD chip through the EC. The --interface option allows forcing a particular host interface. This is necessary at present because the crosec device driver doesn't support host protocol v3 so only has 8-bit command numbers. BUG=chrome-os-partner:30079 BRANCH=none TEST=from EC console, ectool version -> prints EC version ectool --interface=lpc --dev=0 version -> prints EC version ectool --interface=lpc --dev=1 version -> prints PD version ectool --interface=lpc --dev=2 version -> prints error ectool --interface=i2c version -> can't find EC ectool --interface=dev version -> prints EC version Change-Id: I9dd10578dac77e3e104d19e2f37759814eec6ca2 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/207948
-rw-r--r--util/burn_my_ec.c2
-rw-r--r--util/comm-dev.c2
-rw-r--r--util/comm-host.c30
-rw-r--r--util/comm-host.h36
-rw-r--r--util/comm-i2c.c2
-rw-r--r--util/comm-lpc.c4
-rw-r--r--util/comm-mec1322.c4
-rw-r--r--util/ectool.c31
8 files changed, 84 insertions, 27 deletions
diff --git a/util/burn_my_ec.c b/util/burn_my_ec.c
index 622ab48243..720d89ed93 100644
--- a/util/burn_my_ec.c
+++ b/util/burn_my_ec.c
@@ -130,7 +130,7 @@ int main(int argc, char *argv[])
{
extern uint8_t data[] asm("_payload_start");
- if (comm_init() < 0)
+ if (comm_init(COMM_ALL) < 0)
return -3;
flash_partition(EC_IMAGE_RW, data + CONFIG_FW_RW_OFF,
diff --git a/util/comm-dev.c b/util/comm-dev.c
index eb3a4f9b47..ab4f9bca9e 100644
--- a/util/comm-dev.c
+++ b/util/comm-dev.c
@@ -102,7 +102,7 @@ int comm_init_dev(void)
return 3;
}
- ec_command = ec_command_dev;
+ ec_command_proto = ec_command_dev;
if (ec_readmem_dev(EC_MEMMAP_ID, 2, version) == 2 &&
version[0] == 'E' && version[1] == 'C')
ec_readmem = ec_readmem_dev;
diff --git a/util/comm-host.c b/util/comm-host.c
index d0ab376aa9..3f8c70a4e7 100644
--- a/util/comm-host.c
+++ b/util/comm-host.c
@@ -11,15 +11,16 @@
#include "comm-host.h"
#include "ec_commands.h"
-int (*ec_command)(int command, int version,
- const void *outdata, int outsize,
- void *indata, int insize);
+int (*ec_command_proto)(int command, int version,
+ const void *outdata, int outsize,
+ void *indata, int insize);
int (*ec_readmem)(int offset, int bytes, void *dest);
int ec_max_outsize, ec_max_insize;
void *ec_outbuf;
void *ec_inbuf;
+static int command_offset;
int comm_init_dev(void) __attribute__((weak));
int comm_init_lpc(void) __attribute__((weak));
@@ -58,21 +59,36 @@ static int fake_readmem(int offset, int bytes, void *dest)
return EC_MEMMAP_TEXT_MAX - 1;
}
-int comm_init(void)
+void set_command_offset(int offset)
+{
+ command_offset = offset;
+}
+
+int ec_command(int command, int version,
+ const void *outdata, int outsize,
+ void *indata, int insize)
+{
+ /* Offset command code to support sub-devices */
+ return ec_command_proto(command_offset + command, version,
+ outdata, outsize,
+ indata, insize);
+}
+
+int comm_init(int interfaces)
{
/* Default memmap access */
ec_readmem = fake_readmem;
/* Prefer new /dev method */
- if (comm_init_dev && !comm_init_dev())
+ if ((interfaces & COMM_DEV) && comm_init_dev && !comm_init_dev())
goto init_ok;
/* Fallback to direct LPC on x86 */
- if (comm_init_lpc && !comm_init_lpc())
+ if ((interfaces & COMM_LPC) && comm_init_lpc && !comm_init_lpc())
goto init_ok;
/* Fallback to direct i2c on ARM */
- if (comm_init_i2c && !comm_init_i2c())
+ if ((interfaces & COMM_I2C) && comm_init_i2c && !comm_init_i2c())
goto init_ok;
/* Give up */
diff --git a/util/comm-host.h b/util/comm-host.h
index 1e01d58e40..30c6acee67 100644
--- a/util/comm-host.h
+++ b/util/comm-host.h
@@ -25,19 +25,45 @@ extern int ec_max_outsize, ec_max_insize;
extern void *ec_outbuf;
extern void *ec_inbuf;
+/* Interfaces to allow for comm_init() */
+enum comm_interface {
+ COMM_DEV = (1 << 0),
+ COMM_LPC = (1 << 1),
+ COMM_I2C = (1 << 2),
+ COMM_ALL = -1
+};
+
/**
* Perform initializations needed for subsequent requests
*
- * returns 0 in case of success or error code. */
-int comm_init(void);
+ * @param interfaces Interfaces to try; use COMM_ALL to try all of them.
+ * @return 0 in case of success, or error code.
+ */
+int comm_init(int interfaces);
/**
* Send a command to the EC. Returns the length of output data returned (0 if
* none), or negative on error.
*/
-extern int (*ec_command)(int command, int version,
- const void *outdata, int outsize, /* to the EC */
- void *indata, int insize); /* from the EC */
+int ec_command(int command, int version,
+ const void *outdata, int outsize, /* to the EC */
+ void *indata, int insize); /* from the EC */
+
+/**
+ * Set the offset to be applied to the command number when ec_command() calls
+ * ec_command_proto().
+ */
+void set_command_offset(int offset);
+
+/**
+ * Send a command to the EC. Returns the length of output data returned (0 if
+ * none), or negative on error. This is the low-level interface implemented
+ * by the protocol-specific driver. DO NOT call this version directly from
+ * anywhere but ec_command(), or the --device option will not work.
+ */
+extern int (*ec_command_proto)(int command, int version,
+ const void *outdata, int outsize, /* to EC */
+ void *indata, int insize); /* from EC */
/**
* Return the content of the EC information area mapped as "memory".
diff --git a/util/comm-i2c.c b/util/comm-i2c.c
index b305823198..a6fc8691dd 100644
--- a/util/comm-i2c.c
+++ b/util/comm-i2c.c
@@ -206,7 +206,7 @@ int comm_init_i2c(void)
free(file_path);
- ec_command = ec_command_i2c;
+ ec_command_proto = ec_command_i2c;
ec_max_outsize = ec_max_insize = EC_PROTO2_MAX_PARAM_SIZE;
return 0;
diff --git a/util/comm-lpc.c b/util/comm-lpc.c
index 25f0bea4c6..06912af1f2 100644
--- a/util/comm-lpc.c
+++ b/util/comm-lpc.c
@@ -289,7 +289,7 @@ int comm_init_lpc(void)
if (i & EC_HOST_CMD_FLAG_VERSION_3) {
/* Protocol version 3 */
- ec_command = ec_command_lpc_3;
+ ec_command_proto = ec_command_lpc_3;
ec_max_outsize = EC_LPC_HOST_PACKET_SIZE -
sizeof(struct ec_host_request);
ec_max_insize = EC_LPC_HOST_PACKET_SIZE -
@@ -297,7 +297,7 @@ int comm_init_lpc(void)
} else if (i & EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED) {
/* Protocol version 2 */
- ec_command = ec_command_lpc;
+ ec_command_proto = ec_command_lpc;
ec_max_outsize = ec_max_insize = EC_PROTO2_MAX_PARAM_SIZE;
} else {
diff --git a/util/comm-mec1322.c b/util/comm-mec1322.c
index 02b8ee775c..70e4f3ff89 100644
--- a/util/comm-mec1322.c
+++ b/util/comm-mec1322.c
@@ -342,7 +342,7 @@ int comm_init_lpc(void)
if (i & EC_HOST_CMD_FLAG_VERSION_3) {
/* Protocol version 3 */
- ec_command = ec_command_lpc_3;
+ ec_command_proto = ec_command_lpc_3;
ec_max_outsize = EC_LPC_HOST_PACKET_SIZE -
sizeof(struct ec_host_request);
ec_max_insize = EC_LPC_HOST_PACKET_SIZE -
@@ -350,7 +350,7 @@ int comm_init_lpc(void)
} else if (i & EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED) {
/* Protocol version 2 */
- ec_command = ec_command_lpc;
+ ec_command_proto = ec_command_lpc;
ec_max_outsize = ec_max_insize = EC_PROTO2_MAX_PARAM_SIZE;
} else {
diff --git a/util/ectool.c b/util/ectool.c
index 36f612d5d8..89c88104a1 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -25,12 +25,13 @@
/* Command line options */
enum {
- OPT_HELP = '?',
OPT_DEV = 1000,
+ OPT_INTERFACE,
};
static struct option long_opts[] = {
{"dev", 1, 0, OPT_DEV},
+ {"interface", 1, 0, OPT_INTERFACE},
{NULL, 0, 0, 0}
};
@@ -216,7 +217,8 @@ int parse_bool(const char *s, int *dest)
void print_help(const char *prog, int print_cmds)
{
- printf("Usage: %s [--dev=n] <command> [params]\n\n",
+ printf("Usage: %s [--dev=n] [--interface=dev|lpc|i2c] <command> "
+ "[params]\n\n",
prog);
if (print_cmds)
puts(help_str);
@@ -4540,6 +4542,7 @@ int main(int argc, char *argv[])
{
const struct command *cmd;
int dev = 0;
+ int interfaces = COMM_ALL;
int rv = 1;
int parse_error = 0;
char *e;
@@ -4561,6 +4564,19 @@ int main(int argc, char *argv[])
parse_error = 1;
}
break;
+
+ case OPT_INTERFACE:
+ if (!strcasecmp(optarg, "dev")) {
+ interfaces = COMM_DEV;
+ } else if (!strcasecmp(optarg, "lpc")) {
+ interfaces = COMM_LPC;
+ } else if (!strcasecmp(optarg, "i2c")) {
+ interfaces = COMM_I2C;
+ } else {
+ fprintf(stderr, "Invalid --interface\n");
+ parse_error = 1;
+ }
+ break;
}
}
@@ -4574,11 +4590,10 @@ int main(int argc, char *argv[])
exit(1);
}
- /*
- * --dev support is coming in the next patch. For now this is a
- * placeholder used in testing getopt_long()
- */
- if (dev != 0) {
+ /* Handle sub-devices command offset */
+ if (dev > 0 && dev < 4) {
+ set_command_offset(EC_CMD_PASSTHRU_OFFSET(dev));
+ } else if (dev != 0) {
fprintf(stderr, "Bad device number %d\n", dev);
parse_error = 1;
}
@@ -4593,7 +4608,7 @@ int main(int argc, char *argv[])
exit(1);
}
- if (comm_init()) {
+ if (comm_init(interfaces)) {
fprintf(stderr, "Couldn't find EC\n");
goto out;
}