summaryrefslogtreecommitdiffstats
path: root/usr.sbin/usbconfig
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2010-01-07 00:50:45 +0000
committerthompsa <thompsa@FreeBSD.org>2010-01-07 00:50:45 +0000
commit8399082d6d51d51e281d46f674bc47cb8cdcc08f (patch)
tree5e7c75c11de880b8d288f02782f128c57659a989 /usr.sbin/usbconfig
parent2e14be290b5b8c1dd99a985297642637367d2604 (diff)
downloadFreeBSD-src-8399082d6d51d51e281d46f674bc47cb8cdcc08f.zip
FreeBSD-src-8399082d6d51d51e281d46f674bc47cb8cdcc08f.tar.gz
Sync to p4
- Add new quirks commands and the '-d' option optionally to specify the ugen device. Submitted by: Hans Petter Selasky
Diffstat (limited to 'usr.sbin/usbconfig')
-rw-r--r--usr.sbin/usbconfig/dump.c37
-rw-r--r--usr.sbin/usbconfig/dump.h6
-rw-r--r--usr.sbin/usbconfig/usbconfig.839
-rw-r--r--usr.sbin/usbconfig/usbconfig.c155
4 files changed, 213 insertions, 24 deletions
diff --git a/usr.sbin/usbconfig/dump.c b/usr.sbin/usbconfig/dump.c
index 6dfc6ec..4e527ea 100644
--- a/usr.sbin/usbconfig/dump.c
+++ b/usr.sbin/usbconfig/dump.c
@@ -365,3 +365,40 @@ dump_config(struct libusb20_device *pdev, uint8_t all_cfg)
}
return;
}
+
+void
+dump_string_by_index(struct libusb20_device *pdev, uint8_t str_index)
+{
+ char *pbuf;
+ uint8_t n;
+ uint8_t len;
+
+ pbuf = malloc(256);
+ if (pbuf == NULL)
+ err(1, "out of memory");
+
+ if (str_index == 0) {
+ /* language table */
+ if (libusb20_dev_req_string_sync(pdev,
+ str_index, 0, pbuf, 256)) {
+ printf("STRING_0x%02x = <read error>\n", str_index);
+ } else {
+ printf("STRING_0x%02x = ", str_index);
+ len = (uint8_t)pbuf[0];
+ for (n = 0; n != len; n++) {
+ printf("0x%02x%s", (uint8_t)pbuf[n],
+ (n != (len-1)) ? ", " : "");
+ }
+ printf("\n");
+ }
+ } else {
+ /* ordinary string */
+ if (libusb20_dev_req_string_simple_sync(pdev,
+ str_index, pbuf, 256)) {
+ printf("STRING_0x%02x = <read error>\n", str_index);
+ } else {
+ printf("STRING_0x%02x = <%s>\n", str_index, pbuf);
+ }
+ }
+ free(pbuf);
+}
diff --git a/usr.sbin/usbconfig/dump.h b/usr.sbin/usbconfig/dump.h
index 7fafdfd..581684a 100644
--- a/usr.sbin/usbconfig/dump.h
+++ b/usr.sbin/usbconfig/dump.h
@@ -24,11 +24,17 @@
* SUCH DAMAGE.
*/
+#ifndef _DUMP_H_
+#define _DUMP_H_
+
const char *dump_mode(uint8_t value);
const char *dump_speed(uint8_t value);
const char *dump_power_mode(uint8_t value);
+void dump_string_by_index(struct libusb20_device *pdev, uint8_t index);
void dump_device_info(struct libusb20_device *pdev, uint8_t show_drv);
void dump_be_quirk_names(struct libusb20_backend *pbe);
void dump_be_dev_quirks(struct libusb20_backend *pbe);
void dump_device_desc(struct libusb20_device *pdev);
void dump_config(struct libusb20_device *pdev, uint8_t all_cfg);
+
+#endif /* _DUMP_H_ */
diff --git a/usr.sbin/usbconfig/usbconfig.8 b/usr.sbin/usbconfig/usbconfig.8
index 0914d9e..971367d 100644
--- a/usr.sbin/usbconfig/usbconfig.8
+++ b/usr.sbin/usbconfig/usbconfig.8
@@ -1,6 +1,6 @@
.\" $FreeBSD$
.\"
-.\" Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
+.\" Copyright (c) 2008-2010 Hans Petter Selasky. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd November 1, 2009
+.Dd January 6, 2010
.Dt USBCONFIG 8
.Os
.Sh NAME
@@ -34,6 +34,9 @@
.Op Fl u Ar unit
.Op Fl a Ar addr
.Op cmds...
+.Nm
+.Op Fl d Ar [ugen]<unit>.<addr>
+.Op cmds...
.Sh DESCRIPTION
The
.Nm
@@ -46,6 +49,9 @@ Limit device range to USB devices connected to the given USBUS unit.
.It Fl a Ar addr
Limit device range to the given USB device index.
Should only be used in conjunction with the unit argument.
+.It Fl d Ar [ugen]<unit>.<addr>
+Limit device range to USB devices connected to the given unit and address.
+The unit and address coordinates may be prefixed by the lowercased word "ugen".
.It Fl h
Show help and available commands.
.El
@@ -57,5 +63,34 @@ prints a list of all available USB devices.
Show information about the device on USB bus 1 at address 2:
.Pp
.Dl usbconfig -u 1 -a 2 dump_info
+.Pp
+Dump HID descriptor for device on USB bus 1 at address 2:
+.Pp
+.Dl usbconfig -u 1 -a 2 do_request 0x81 0x06 0x2200 0 0x100
+.Pp
+Dump string descriptor at index Z for device on USB bus 1 at address 2:
+.Pp
+.Dl usbconfig -u 1 -a 2 dump_string Z
+.Pp
+Dump current configuration descriptor for device on USB bus 1 at address 2:
+.Pp
+.Dl usbconfig -u 1 -a 2 dump_curr_config_desc
+.Pp
+Dump device descriptor for device on USB bus 1 at address 2:
+.Pp
+.Dl usbconfig -u 1 -a 2 dump_device_desc
+.Pp
+Program the device on USB bus 1 at address 2 to suspend, resume, power off, go into power save, or power on:
+.Pp
+.Dl usbconfig -u 1 -a 2 suspend
+.Dl usbconfig -u 1 -a 2 resume
+.Dl usbconfig -u 1 -a 2 power_off
+.Dl usbconfig -u 1 -a 2 power_save
+.Dl usbconfig -u 1 -a 2 power_on
+.Pp
+Display a list of available quirk names:
+.Pp
+.Dl usbconfig dump_quirk_names
+.Pp
.Sh SEE ALSO
.Xr usb 4
diff --git a/usr.sbin/usbconfig/usbconfig.c b/usr.sbin/usbconfig/usbconfig.c
index 810e183..fd701a7 100644
--- a/usr.sbin/usbconfig/usbconfig.c
+++ b/usr.sbin/usbconfig/usbconfig.c
@@ -1,6 +1,6 @@
/* $FreeBSD$ */
/*-
- * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
+ * Copyright (c) 2008-2009 Hans Petter Selasky. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -81,6 +81,8 @@ struct options {
uint8_t got_show_iface_driver:1;
uint8_t got_remove_device_quirk:1;
uint8_t got_add_device_quirk:1;
+ uint8_t got_remove_quirk:1;
+ uint8_t got_add_quirk:1;
uint8_t got_dump_string:1;
uint8_t got_do_request:1;
};
@@ -94,6 +96,7 @@ struct token {
enum {
T_UNIT,
T_ADDR,
+ T_UGEN,
T_IFACE,
T_SET_CONFIG,
T_SET_ALT,
@@ -101,6 +104,8 @@ enum {
T_GET_TEMPLATE,
T_ADD_DEVICE_QUIRK,
T_REMOVE_DEVICE_QUIRK,
+ T_ADD_QUIRK,
+ T_REMOVE_QUIRK,
T_SHOW_IFACE_DRIVER,
T_DUMP_QUIRK_NAMES,
T_DUMP_DEVICE_QUIRKS,
@@ -124,6 +129,7 @@ static struct options options;
static const struct token token[] = {
{"-u", T_UNIT, 1},
{"-a", T_ADDR, 1},
+ {"-d", T_UGEN, 1},
{"-i", T_IFACE, 1},
{"set_config", T_SET_CONFIG, 1},
{"set_alt", T_SET_ALT, 1},
@@ -131,6 +137,8 @@ static const struct token token[] = {
{"get_template", T_GET_TEMPLATE, 0},
{"add_dev_quirk_vplh", T_ADD_DEVICE_QUIRK, 5},
{"remove_dev_quirk_vplh", T_REMOVE_DEVICE_QUIRK, 5},
+ {"add_quirk", T_ADD_QUIRK, 1},
+ {"remove_quirk", T_REMOVE_QUIRK, 1},
{"dump_quirk_names", T_DUMP_QUIRK_NAMES, 0},
{"dump_device_quirks", T_DUMP_DEVICE_QUIRKS, 0},
{"dump_device_desc", T_DUMP_DEVICE_DESC, 0},
@@ -247,11 +255,20 @@ get_int(const char *s)
}
static void
+duplicate_option(const char *ptr)
+{
+ printf("Syntax error: "
+ "Duplicate option: '%s'\n", ptr);
+ exit(1);
+}
+
+static void
usage(void)
{
printf(""
"usbconfig - configure the USB subsystem" "\n"
"usage: usbconfig -u <busnum> -a <devaddr> -i <ifaceindex> [cmds...]" "\n"
+ "usage: usbconfig -d [ugen]<busnum>.<devaddr> -i <ifaceindex> [cmds...]" "\n"
"commands:" "\n"
" set_config <cfg_index>" "\n"
" set_alt <alt_index>" "\n"
@@ -259,6 +276,8 @@ usage(void)
" get_template" "\n"
" add_dev_quirk_vplh <vid> <pid> <lo_rev> <hi_rev> <quirk>" "\n"
" remove_dev_quirk_vplh <vid> <pid> <lo_rev> <hi_rev> <quirk>" "\n"
+ " add_quirk <quirk>" "\n"
+ " remove_quirk <quirk>" "\n"
" dump_quirk_names" "\n"
" dump_device_quirks" "\n"
" dump_device_desc" "\n"
@@ -360,25 +379,33 @@ flush_command(struct libusb20_backend *pbe, struct options *opt)
}
matches++;
+ if (opt->got_remove_quirk) {
+ struct LIBUSB20_DEVICE_DESC_DECODED *ddesc;
+
+ ddesc = libusb20_dev_get_device_desc(pdev);
+
+ be_dev_remove_quirk(pbe,
+ ddesc->idVendor, ddesc->idProduct,
+ ddesc->bcdDevice, ddesc->bcdDevice,
+ opt->quirkname);
+ }
+
+ if (opt->got_add_quirk) {
+ struct LIBUSB20_DEVICE_DESC_DECODED *ddesc;
+
+ ddesc = libusb20_dev_get_device_desc(pdev);
+
+ be_dev_add_quirk(pbe,
+ ddesc->idVendor, ddesc->idProduct,
+ ddesc->bcdDevice, ddesc->bcdDevice,
+ opt->quirkname);
+ }
+
if (libusb20_dev_open(pdev, 0)) {
err(1, "could not open device");
}
if (opt->got_dump_string) {
- char *pbuf;
-
- pbuf = malloc(256);
- if (pbuf == NULL) {
- err(1, "out of memory");
- }
- if (libusb20_dev_req_string_simple_sync(pdev,
- opt->string_index, pbuf, 256)) {
- printf("STRING_0x%02x = <read error>\n",
- opt->string_index);
- } else {
- printf("STRING_0x%02x = <%s>\n",
- opt->string_index, pbuf);
- }
- free(pbuf);
+ dump_string_by_index(pdev, opt->string_index);
}
if (opt->got_do_request) {
uint16_t actlen;
@@ -501,6 +528,9 @@ main(int argc, char **argv)
{
struct libusb20_backend *pbe;
struct options *opt = &options;
+ const char *ptr;
+ int unit;
+ int addr;
int n;
int t;
@@ -518,6 +548,28 @@ main(int argc, char **argv)
if (t > 255)
t = 255;
switch (get_token(argv[n], t)) {
+ case T_ADD_QUIRK:
+ if (opt->got_add_quirk) {
+ flush_command(pbe, opt);
+ }
+ opt->quirkname = argv[n + 1];
+ n++;
+
+ opt->got_add_quirk = 1;
+ opt->got_any++;
+ break;
+
+ case T_REMOVE_QUIRK:
+ if (opt->got_remove_quirk) {
+ flush_command(pbe, opt);
+ }
+ opt->quirkname = argv[n + 1];
+ n++;
+
+ opt->got_remove_quirk = 1;
+ opt->got_any++;
+ break;
+
case T_ADD_DEVICE_QUIRK:
if (opt->got_add_device_quirk) {
flush_command(pbe, opt);
@@ -548,11 +600,15 @@ main(int argc, char **argv)
break;
case T_DUMP_QUIRK_NAMES:
+ if (opt->got_dump_quirk_names)
+ duplicate_option(argv[n]);
opt->got_dump_quirk_names = 1;
opt->got_any++;
break;
case T_DUMP_DEVICE_QUIRKS:
+ if (opt->got_dump_device_quirks)
+ duplicate_option(argv[n]);
opt->got_dump_device_quirks = 1;
opt->got_any++;
break;
@@ -561,6 +617,33 @@ main(int argc, char **argv)
opt->got_show_iface_driver = 1;
break;
+ case T_UGEN:
+ if (opt->got_any) {
+ /* allow multiple commands on the same line */
+ flush_command(pbe, opt);
+ }
+ ptr = argv[n + 1];
+
+ if ((ptr[0] == 'u') &&
+ (ptr[1] == 'g') &&
+ (ptr[2] == 'e') &&
+ (ptr[3] == 'n'))
+ ptr += 4;
+
+ if ((sscanf(ptr, "%d.%d",
+ &unit, &addr) != 2) ||
+ (unit < 0) || (unit > 65535) ||
+ (addr < 0) || (addr > 65535)) {
+ errx(1, "cannot "
+ "parse '%s'", argv[n + 1]);
+ }
+ opt->bus = unit;
+ opt->addr = addr;
+ opt->got_bus = 1;
+; opt->got_addr = 1;
+ n++;
+ break;
+
case T_UNIT:
if (opt->got_any) {
/* allow multiple commands on the same line */
@@ -581,84 +664,112 @@ main(int argc, char **argv)
n++;
break;
case T_SET_CONFIG:
+ if (opt->got_set_config)
+ duplicate_option(argv[n]);
opt->config_index = num_id(argv[n + 1], "cfg_index");
opt->got_set_config = 1;
opt->got_any++;
n++;
break;
case T_SET_ALT:
+ if (opt->got_set_alt)
+ duplicate_option(argv[n]);
opt->alt_index = num_id(argv[n + 1], "cfg_index");
opt->got_set_alt = 1;
opt->got_any++;
n++;
break;
case T_SET_TEMPLATE:
+ if (opt->got_set_template)
+ duplicate_option(argv[n]);
opt->template = get_int(argv[n + 1]);
opt->got_set_template = 1;
opt->got_any++;
n++;
break;
case T_GET_TEMPLATE:
+ if (opt->got_get_template)
+ duplicate_option(argv[n]);
opt->got_get_template = 1;
opt->got_any++;
break;
case T_DUMP_DEVICE_DESC:
+ if (opt->got_dump_device_desc)
+ duplicate_option(argv[n]);
opt->got_dump_device_desc = 1;
opt->got_any++;
break;
case T_DUMP_CURR_CONFIG_DESC:
+ if (opt->got_dump_curr_config)
+ duplicate_option(argv[n]);
opt->got_dump_curr_config = 1;
opt->got_any++;
break;
case T_DUMP_ALL_CONFIG_DESC:
+ if (opt->got_dump_all_config)
+ duplicate_option(argv[n]);
opt->got_dump_all_config = 1;
opt->got_any++;
break;
case T_DUMP_INFO:
+ if (opt->got_dump_info)
+ duplicate_option(argv[n]);
opt->got_dump_info = 1;
opt->got_any++;
break;
case T_DUMP_STRING:
- if (opt->got_dump_string) {
- flush_command(pbe, opt);
- }
+ if (opt->got_dump_string)
+ duplicate_option(argv[n]);
opt->string_index = num_id(argv[n + 1], "str_index");
opt->got_dump_string = 1;
opt->got_any++;
n++;
break;
case T_SUSPEND:
+ if (opt->got_suspend)
+ duplicate_option(argv[n]);
opt->got_suspend = 1;
opt->got_any++;
break;
case T_RESUME:
+ if (opt->got_resume)
+ duplicate_option(argv[n]);
opt->got_resume = 1;
opt->got_any++;
break;
case T_POWER_OFF:
+ if (opt->got_power_off)
+ duplicate_option(argv[n]);
opt->got_power_off = 1;
opt->got_any++;
break;
case T_POWER_SAVE:
+ if (opt->got_power_save)
+ duplicate_option(argv[n]);
opt->got_power_save = 1;
opt->got_any++;
break;
case T_POWER_ON:
+ if (opt->got_power_on)
+ duplicate_option(argv[n]);
opt->got_power_on = 1;
opt->got_any++;
break;
case T_RESET:
+ if (opt->got_reset)
+ duplicate_option(argv[n]);
opt->got_reset = 1;
opt->got_any++;
break;
case T_LIST:
+ if (opt->got_list)
+ duplicate_option(argv[n]);
opt->got_list = 1;
opt->got_any++;
break;
case T_DO_REQUEST:
- if (opt->got_do_request) {
- flush_command(pbe, opt);
- }
+ if (opt->got_do_request)
+ duplicate_option(argv[n]);
LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &opt->setup);
opt->setup.bmRequestType = num_id(argv[n + 1], "bmReqTyp");
opt->setup.bRequest = num_id(argv[n + 2], "bReq");
OpenPOWER on IntegriCloud