diff options
author | Bill Richardson <wfrichar@chromium.org> | 2016-03-24 19:33:31 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-03-30 17:10:17 -0700 |
commit | 20f5efafc8c02ad1ada7dd1ca5256af9dfc439ab (patch) | |
tree | 77f0481496f7cb50f8286d93b372a94dcc7c8cfd /test | |
parent | 06ea3b5b008206085b91b728f6fa61cc5edd7e28 (diff) | |
download | chrome-ec-20f5efafc8c02ad1ada7dd1ca5256af9dfc439ab.tar.gz |
Cr50: Support USB SETCFG/GETCFG control transfers
This adds USB support to Set and Get the Device Configuration.
These control transfers are standard device requests that need to
be added in order to behave properly for USB suspend/resume (and
in general). Before this CL, the Get command always failed and
the Set command had no effect internally. With this CL it works.
Note that this particular change only supports ONE configuration
for the Cr50. If/when we add additional configuration
descriptors, we'll need to update it again.
BUG=chrome-os-partner:50721
BRANCH=none
TEST=make buildall; manual tests on Cr50
This CL includes a test program. Connect the Cr50 to the build
host, and use that program to read and change the configuration.
cd test/usb_test
make
./device_configuration
./device_configuration 0
./device_configuration 1
./device_configuration 2
You may need to use sudo if your device permissions aren't sufficient.
Change-Id: Id65e70265f0760b1b374005dfcddc88e66a933f6
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/335878
Reviewed-by: Scott Collyer <scollyer@chromium.org>
Diffstat (limited to 'test')
-rw-r--r-- | test/usb_test/Makefile | 34 | ||||
-rw-r--r-- | test/usb_test/README | 2 | ||||
-rw-r--r-- | test/usb_test/device_configuration.c | 172 |
3 files changed, 208 insertions, 0 deletions
diff --git a/test/usb_test/Makefile b/test/usb_test/Makefile new file mode 100644 index 0000000000..e18e4a7c3b --- /dev/null +++ b/test/usb_test/Makefile @@ -0,0 +1,34 @@ +# Copyright 2015 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +PROGRAM := device_configuration +SOURCE := $(PROGRAM).c +LIBS := +LFLAGS := +CFLAGS := -std=gnu99 \ + -g3 \ + -O3 \ + -Wall \ + -Werror \ + -Wpointer-arith \ + -Wcast-align \ + -Wcast-qual \ + -Wundef \ + -Wsign-compare \ + -Wredundant-decls \ + -Wmissing-declarations + +# +# Add libusb-1.0 required flags +# +LIBS += $(shell pkg-config --libs libusb-1.0) +CFLAGS += $(shell pkg-config --cflags libusb-1.0) + +$(PROGRAM): $(SOURCE) Makefile + gcc $(CFLAGS) $(SOURCE) $(LFLAGS) $(LIBS) -o $@ + +.PHONY: clean + +clean: + rm -rf $(PROGRAM) *~ diff --git a/test/usb_test/README b/test/usb_test/README new file mode 100644 index 0000000000..5d7af93f7e --- /dev/null +++ b/test/usb_test/README @@ -0,0 +1,2 @@ +These tests need to be built and run by hand, unless/until we set up a lab +with known devices attached to a test host. diff --git a/test/usb_test/device_configuration.c b/test/usb_test/device_configuration.c new file mode 100644 index 0000000000..69f889c2d3 --- /dev/null +++ b/test/usb_test/device_configuration.c @@ -0,0 +1,172 @@ +/* + * Copyright 2016 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <errno.h> +#include <getopt.h> +#include <libusb.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* Options */ +static uint16_t vid = 0x18d1; /* Google */ +static uint16_t pid = 0x5014; /* Cr50 */ + +static char *progname; + +static void usage(int errs) +{ + printf("\nUsage: %s [vid:pid] [value]\n" + "\n" + "Set/Get the USB Device Configuration value\n" + "\n" + "The default vid:pid is %04x:%04x\n" + "\n", progname, vid, pid); + + exit(!!errs); +} + +/* Globals */ +struct libusb_device_handle *devh = 0; + +static void stupid_usb(const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + + if (devh) + libusb_close(devh); + + libusb_exit(NULL); + + exit(1); +} + + +int main(int argc, char *argv[]) +{ + int r = 1; + int errorcnt = 0; + int do_set = 0; + uint16_t setval = 0; + uint8_t buf[80]; /* Arbitrary size */ + int i; + + progname = strrchr(argv[0], '/'); + if (progname) + progname++; + else + progname = argv[0]; + + opterr = 0; /* quiet, you */ + while ((i = getopt(argc, argv, "")) != -1) { + switch (i) { + case 'h': + usage(errorcnt); + break; + case 0: /* auto-handled option */ + break; + case '?': + if (optopt) + printf("Unrecognized option: -%c\n", optopt); + else + printf("Unrecognized option: %s\n", + argv[optind - 1]); + errorcnt++; + break; + case ':': + printf("Missing argument to %s\n", argv[optind - 1]); + errorcnt++; + break; + default: + printf("Internal error at %s:%d\n", __FILE__, __LINE__); + exit(1); + } + } + + if (errorcnt) + usage(errorcnt); + + if (optind < argc) { + uint16_t v, p; + + if (2 == sscanf(argv[optind], "%hx:%hx", &v, &p)) { + vid = v; + pid = p; + optind++; + } + } + + if (optind < argc) { + do_set = 1; + setval = atoi(argv[optind]); + } + + r = libusb_init(NULL); + if (r) { + printf("libusb_init() returned 0x%x: %s\n", + r, libusb_error_name(r)); + return 1; + } + + devh = libusb_open_device_with_vid_pid(NULL, vid, pid); + if (!devh) { + perror(progname); + stupid_usb("Can't open device %04x:%04x\n", vid, pid); + } + + + /* Set config*/ + if (do_set) { + printf("SetCfg %d\n", setval); + r = libusb_control_transfer( + devh, + 0x00, /* bmRequestType */ + 0x09, /* bRequest */ + setval, /* wValue */ + 0x0000, /* wIndex */ + NULL, /* data */ + 0x0000, /* wLength */ + 1000); /* timeout (ms) */ + + if (r < 0) + printf("transfer returned 0x%x %s\n", + r, libusb_error_name(r)); + } + + /* Get config */ + memset(buf, 0, sizeof(buf)); + + r = libusb_control_transfer( + devh, + 0x80, /* bmRequestType */ + 0x08, /* bRequest */ + 0x0000, /* wValue */ + 0x0000, /* wIndex */ + buf, /* data */ + 0x0001, /* wLength */ + 1000); /* timeout (ms) */ + + if (r <= 0) + stupid_usb("GetCfg transfer() returned 0x%x %s\n", + r, libusb_error_name(r)); + + printf("GetCfg returned %d bytes:", r); + for (i = 0; i < r; i++) + printf(" 0x%02x", buf[i]); + printf("\n"); + + /* done */ + if (devh) + libusb_close(devh); + libusb_exit(NULL); + + return 0; +} |