Sync to p4

- Add new quirks commands and the '-d' option optionally to specify the ugen device.

Submitted by:	Hans Petter Selasky
This commit is contained in:
Andrew Thompson 2010-01-07 00:50:45 +00:00
parent 9dbf7a62f4
commit cf109686d0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=201705
4 changed files with 213 additions and 24 deletions

View File

@ -365,3 +365,40 @@ dump_config(struct libusb20_device *pdev, uint8_t all_cfg)
} }
return; 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);
}

View File

@ -24,11 +24,17 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#ifndef _DUMP_H_
#define _DUMP_H_
const char *dump_mode(uint8_t value); const char *dump_mode(uint8_t value);
const char *dump_speed(uint8_t value); const char *dump_speed(uint8_t value);
const char *dump_power_mode(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_device_info(struct libusb20_device *pdev, uint8_t show_drv);
void dump_be_quirk_names(struct libusb20_backend *pbe); void dump_be_quirk_names(struct libusb20_backend *pbe);
void dump_be_dev_quirks(struct libusb20_backend *pbe); void dump_be_dev_quirks(struct libusb20_backend *pbe);
void dump_device_desc(struct libusb20_device *pdev); void dump_device_desc(struct libusb20_device *pdev);
void dump_config(struct libusb20_device *pdev, uint8_t all_cfg); void dump_config(struct libusb20_device *pdev, uint8_t all_cfg);
#endif /* _DUMP_H_ */

View File

@ -1,6 +1,6 @@
.\" $FreeBSD$ .\" $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 .\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions .\" 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 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.Dd November 1, 2009 .Dd January 6, 2010
.Dt USBCONFIG 8 .Dt USBCONFIG 8
.Os .Os
.Sh NAME .Sh NAME
@ -34,6 +34,9 @@
.Op Fl u Ar unit .Op Fl u Ar unit
.Op Fl a Ar addr .Op Fl a Ar addr
.Op cmds... .Op cmds...
.Nm
.Op Fl d Ar [ugen]<unit>.<addr>
.Op cmds...
.Sh DESCRIPTION .Sh DESCRIPTION
The The
.Nm .Nm
@ -46,6 +49,9 @@ Limit device range to USB devices connected to the given USBUS unit.
.It Fl a Ar addr .It Fl a Ar addr
Limit device range to the given USB device index. Limit device range to the given USB device index.
Should only be used in conjunction with the unit argument. 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 .It Fl h
Show help and available commands. Show help and available commands.
.El .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: Show information about the device on USB bus 1 at address 2:
.Pp .Pp
.Dl usbconfig -u 1 -a 2 dump_info .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 .Sh SEE ALSO
.Xr usb 4 .Xr usb 4

View File

@ -1,6 +1,6 @@
/* $FreeBSD$ */ /* $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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -81,6 +81,8 @@ struct options {
uint8_t got_show_iface_driver:1; uint8_t got_show_iface_driver:1;
uint8_t got_remove_device_quirk:1; uint8_t got_remove_device_quirk:1;
uint8_t got_add_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_dump_string:1;
uint8_t got_do_request:1; uint8_t got_do_request:1;
}; };
@ -94,6 +96,7 @@ struct token {
enum { enum {
T_UNIT, T_UNIT,
T_ADDR, T_ADDR,
T_UGEN,
T_IFACE, T_IFACE,
T_SET_CONFIG, T_SET_CONFIG,
T_SET_ALT, T_SET_ALT,
@ -101,6 +104,8 @@ enum {
T_GET_TEMPLATE, T_GET_TEMPLATE,
T_ADD_DEVICE_QUIRK, T_ADD_DEVICE_QUIRK,
T_REMOVE_DEVICE_QUIRK, T_REMOVE_DEVICE_QUIRK,
T_ADD_QUIRK,
T_REMOVE_QUIRK,
T_SHOW_IFACE_DRIVER, T_SHOW_IFACE_DRIVER,
T_DUMP_QUIRK_NAMES, T_DUMP_QUIRK_NAMES,
T_DUMP_DEVICE_QUIRKS, T_DUMP_DEVICE_QUIRKS,
@ -124,6 +129,7 @@ static struct options options;
static const struct token token[] = { static const struct token token[] = {
{"-u", T_UNIT, 1}, {"-u", T_UNIT, 1},
{"-a", T_ADDR, 1}, {"-a", T_ADDR, 1},
{"-d", T_UGEN, 1},
{"-i", T_IFACE, 1}, {"-i", T_IFACE, 1},
{"set_config", T_SET_CONFIG, 1}, {"set_config", T_SET_CONFIG, 1},
{"set_alt", T_SET_ALT, 1}, {"set_alt", T_SET_ALT, 1},
@ -131,6 +137,8 @@ static const struct token token[] = {
{"get_template", T_GET_TEMPLATE, 0}, {"get_template", T_GET_TEMPLATE, 0},
{"add_dev_quirk_vplh", T_ADD_DEVICE_QUIRK, 5}, {"add_dev_quirk_vplh", T_ADD_DEVICE_QUIRK, 5},
{"remove_dev_quirk_vplh", T_REMOVE_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_quirk_names", T_DUMP_QUIRK_NAMES, 0},
{"dump_device_quirks", T_DUMP_DEVICE_QUIRKS, 0}, {"dump_device_quirks", T_DUMP_DEVICE_QUIRKS, 0},
{"dump_device_desc", T_DUMP_DEVICE_DESC, 0}, {"dump_device_desc", T_DUMP_DEVICE_DESC, 0},
@ -246,12 +254,21 @@ get_int(const char *s)
return val; return val;
} }
static void
duplicate_option(const char *ptr)
{
printf("Syntax error: "
"Duplicate option: '%s'\n", ptr);
exit(1);
}
static void static void
usage(void) usage(void)
{ {
printf("" printf(""
"usbconfig - configure the USB subsystem" "\n" "usbconfig - configure the USB subsystem" "\n"
"usage: usbconfig -u <busnum> -a <devaddr> -i <ifaceindex> [cmds...]" "\n" "usage: usbconfig -u <busnum> -a <devaddr> -i <ifaceindex> [cmds...]" "\n"
"usage: usbconfig -d [ugen]<busnum>.<devaddr> -i <ifaceindex> [cmds...]" "\n"
"commands:" "\n" "commands:" "\n"
" set_config <cfg_index>" "\n" " set_config <cfg_index>" "\n"
" set_alt <alt_index>" "\n" " set_alt <alt_index>" "\n"
@ -259,6 +276,8 @@ usage(void)
" get_template" "\n" " get_template" "\n"
" add_dev_quirk_vplh <vid> <pid> <lo_rev> <hi_rev> <quirk>" "\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" " 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_quirk_names" "\n"
" dump_device_quirks" "\n" " dump_device_quirks" "\n"
" dump_device_desc" "\n" " dump_device_desc" "\n"
@ -360,25 +379,33 @@ flush_command(struct libusb20_backend *pbe, struct options *opt)
} }
matches++; 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)) { if (libusb20_dev_open(pdev, 0)) {
err(1, "could not open device"); err(1, "could not open device");
} }
if (opt->got_dump_string) { if (opt->got_dump_string) {
char *pbuf; dump_string_by_index(pdev, opt->string_index);
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);
} }
if (opt->got_do_request) { if (opt->got_do_request) {
uint16_t actlen; uint16_t actlen;
@ -501,6 +528,9 @@ main(int argc, char **argv)
{ {
struct libusb20_backend *pbe; struct libusb20_backend *pbe;
struct options *opt = &options; struct options *opt = &options;
const char *ptr;
int unit;
int addr;
int n; int n;
int t; int t;
@ -518,6 +548,28 @@ main(int argc, char **argv)
if (t > 255) if (t > 255)
t = 255; t = 255;
switch (get_token(argv[n], t)) { 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: case T_ADD_DEVICE_QUIRK:
if (opt->got_add_device_quirk) { if (opt->got_add_device_quirk) {
flush_command(pbe, opt); flush_command(pbe, opt);
@ -548,11 +600,15 @@ main(int argc, char **argv)
break; break;
case T_DUMP_QUIRK_NAMES: case T_DUMP_QUIRK_NAMES:
if (opt->got_dump_quirk_names)
duplicate_option(argv[n]);
opt->got_dump_quirk_names = 1; opt->got_dump_quirk_names = 1;
opt->got_any++; opt->got_any++;
break; break;
case T_DUMP_DEVICE_QUIRKS: case T_DUMP_DEVICE_QUIRKS:
if (opt->got_dump_device_quirks)
duplicate_option(argv[n]);
opt->got_dump_device_quirks = 1; opt->got_dump_device_quirks = 1;
opt->got_any++; opt->got_any++;
break; break;
@ -561,6 +617,33 @@ main(int argc, char **argv)
opt->got_show_iface_driver = 1; opt->got_show_iface_driver = 1;
break; 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: case T_UNIT:
if (opt->got_any) { if (opt->got_any) {
/* allow multiple commands on the same line */ /* allow multiple commands on the same line */
@ -581,84 +664,112 @@ main(int argc, char **argv)
n++; n++;
break; break;
case T_SET_CONFIG: case T_SET_CONFIG:
if (opt->got_set_config)
duplicate_option(argv[n]);
opt->config_index = num_id(argv[n + 1], "cfg_index"); opt->config_index = num_id(argv[n + 1], "cfg_index");
opt->got_set_config = 1; opt->got_set_config = 1;
opt->got_any++; opt->got_any++;
n++; n++;
break; break;
case T_SET_ALT: case T_SET_ALT:
if (opt->got_set_alt)
duplicate_option(argv[n]);
opt->alt_index = num_id(argv[n + 1], "cfg_index"); opt->alt_index = num_id(argv[n + 1], "cfg_index");
opt->got_set_alt = 1; opt->got_set_alt = 1;
opt->got_any++; opt->got_any++;
n++; n++;
break; break;
case T_SET_TEMPLATE: case T_SET_TEMPLATE:
if (opt->got_set_template)
duplicate_option(argv[n]);
opt->template = get_int(argv[n + 1]); opt->template = get_int(argv[n + 1]);
opt->got_set_template = 1; opt->got_set_template = 1;
opt->got_any++; opt->got_any++;
n++; n++;
break; break;
case T_GET_TEMPLATE: case T_GET_TEMPLATE:
if (opt->got_get_template)
duplicate_option(argv[n]);
opt->got_get_template = 1; opt->got_get_template = 1;
opt->got_any++; opt->got_any++;
break; break;
case T_DUMP_DEVICE_DESC: case T_DUMP_DEVICE_DESC:
if (opt->got_dump_device_desc)
duplicate_option(argv[n]);
opt->got_dump_device_desc = 1; opt->got_dump_device_desc = 1;
opt->got_any++; opt->got_any++;
break; break;
case T_DUMP_CURR_CONFIG_DESC: case T_DUMP_CURR_CONFIG_DESC:
if (opt->got_dump_curr_config)
duplicate_option(argv[n]);
opt->got_dump_curr_config = 1; opt->got_dump_curr_config = 1;
opt->got_any++; opt->got_any++;
break; break;
case T_DUMP_ALL_CONFIG_DESC: case T_DUMP_ALL_CONFIG_DESC:
if (opt->got_dump_all_config)
duplicate_option(argv[n]);
opt->got_dump_all_config = 1; opt->got_dump_all_config = 1;
opt->got_any++; opt->got_any++;
break; break;
case T_DUMP_INFO: case T_DUMP_INFO:
if (opt->got_dump_info)
duplicate_option(argv[n]);
opt->got_dump_info = 1; opt->got_dump_info = 1;
opt->got_any++; opt->got_any++;
break; break;
case T_DUMP_STRING: case T_DUMP_STRING:
if (opt->got_dump_string) { if (opt->got_dump_string)
flush_command(pbe, opt); duplicate_option(argv[n]);
}
opt->string_index = num_id(argv[n + 1], "str_index"); opt->string_index = num_id(argv[n + 1], "str_index");
opt->got_dump_string = 1; opt->got_dump_string = 1;
opt->got_any++; opt->got_any++;
n++; n++;
break; break;
case T_SUSPEND: case T_SUSPEND:
if (opt->got_suspend)
duplicate_option(argv[n]);
opt->got_suspend = 1; opt->got_suspend = 1;
opt->got_any++; opt->got_any++;
break; break;
case T_RESUME: case T_RESUME:
if (opt->got_resume)
duplicate_option(argv[n]);
opt->got_resume = 1; opt->got_resume = 1;
opt->got_any++; opt->got_any++;
break; break;
case T_POWER_OFF: case T_POWER_OFF:
if (opt->got_power_off)
duplicate_option(argv[n]);
opt->got_power_off = 1; opt->got_power_off = 1;
opt->got_any++; opt->got_any++;
break; break;
case T_POWER_SAVE: case T_POWER_SAVE:
if (opt->got_power_save)
duplicate_option(argv[n]);
opt->got_power_save = 1; opt->got_power_save = 1;
opt->got_any++; opt->got_any++;
break; break;
case T_POWER_ON: case T_POWER_ON:
if (opt->got_power_on)
duplicate_option(argv[n]);
opt->got_power_on = 1; opt->got_power_on = 1;
opt->got_any++; opt->got_any++;
break; break;
case T_RESET: case T_RESET:
if (opt->got_reset)
duplicate_option(argv[n]);
opt->got_reset = 1; opt->got_reset = 1;
opt->got_any++; opt->got_any++;
break; break;
case T_LIST: case T_LIST:
if (opt->got_list)
duplicate_option(argv[n]);
opt->got_list = 1; opt->got_list = 1;
opt->got_any++; opt->got_any++;
break; break;
case T_DO_REQUEST: case T_DO_REQUEST:
if (opt->got_do_request) { if (opt->got_do_request)
flush_command(pbe, opt); duplicate_option(argv[n]);
}
LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &opt->setup); LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &opt->setup);
opt->setup.bmRequestType = num_id(argv[n + 1], "bmReqTyp"); opt->setup.bmRequestType = num_id(argv[n + 1], "bmReqTyp");
opt->setup.bRequest = num_id(argv[n + 2], "bReq"); opt->setup.bRequest = num_id(argv[n + 2], "bReq");