summaryrefslogtreecommitdiffstats
path: root/usr.sbin/usbconfig
diff options
context:
space:
mode:
authoralfred <alfred@FreeBSD.org>2008-11-19 08:56:35 +0000
committeralfred <alfred@FreeBSD.org>2008-11-19 08:56:35 +0000
commit881f5acc93790d49318ffde65d52c6f45ca9c1f8 (patch)
tree563c2e235db65a3694986a6531a444241d882b23 /usr.sbin/usbconfig
parentf750559c3fe5d18392fa3f5969411eef4c84075c (diff)
downloadFreeBSD-src-881f5acc93790d49318ffde65d52c6f45ca9c1f8.zip
FreeBSD-src-881f5acc93790d49318ffde65d52c6f45ca9c1f8.tar.gz
src/sys/dev/usb2/controller/uss820dci_pccard.c
src/sys/dev/usb2/core/usbdevs src/sys/dev/usb2/include/urio2_ioctl.h src/sys/dev/usb2/storage/ustorage2_fs.h These files are not used any more. src/usr.sbin/Makefile src/etc/mtree/BSD.include.dist src/include/Makefile src/lib/Makefile src/share/man/man7/hier.7 src/share/mk/bsd.libnames.mk src/etc/mtree/BSD.include.dist Make "usbconfig" and "libusb20" a part of the default build. src/sys/dev/usb/rio500_usb.h src/sys/dev/usb2/storage/urio2.c Use common include file. src/sys/dev/usb2/bluetooth/ng_ubt2.c Make USB bluetooth depend on "ng_hci" module. src/sys/dev/usb2/controller/ehci2.c src/sys/dev/usb2/controller/ehci2.h Patches for Marvell EHCI. src/sys/dev/usb2/core/usb2_busdma.c Bugfix for 64-bit platforms. Need to unload the previously loaded DMA map and some cleanup regarding some corner cases. src/sys/dev/usb2/core/usb2_core.h src/sys/dev/usb2/core/usb2_dev.c src/sys/dev/usb2/core/usb2_dev.h Bugfix for libusb filesystem interface. New feature: Add support for filtering device data at the expense of the userland process. Add some more comments. Some minor code styling. Remove unused function, usb2_fifo_get_data_next(). Fix an issue about "fifo_index" being used instead of "ep_index". src/sys/dev/usb2/core/usb2_device.c src/sys/dev/usb2/core/usb2_generic.c Bugfix for Linux USB compat layer. Do not free non-generic FIFOs when doing an alternate setting. Cleanup USB IOCTL and USB reference handling. Fix a corner case where USB-FS was left initialised after setting a new configuration or alternate setting. src/sys/dev/usb2/core/usb2_hub.c Improvement: Check all USB HUB ports by default at least one time. src/sys/dev/usb2/core/usb2_request.c Bugfix: Make sure destination ASCII string is properly zero terminated in all cases. Improvement: Skip invalid characters instead of replacing with a dot. src/sys/dev/usb2/core/usb2_util.c src/sys/dev/usb2/image/uscanner2.c Spelling. src/sys/dev/usb2/include/Makefile Share "usbdevs" with the old USB stack. src/sys/dev/usb2/include/usb2_devid.h src/sys/dev/usb2/include/usb2_devtable.h Regenerate files. Alfred: Please fix the RCS tag at the top. src/sys/dev/usb2/include/usb2_ioctl.h Fix compilation of "kdump". src/sys/dev/usb2/serial/ubsa2.c src/sys/dev/usb2/serial/ugensa2.c Remove device ID's which will end up in a new 3G driver. src/sys/dev/usb2/sound/uaudio2.c Correct a debug printout. src/sys/dev/usb2/storage/umass2.c Sync with old USB stack. src/lib/libusb20/libusb20.3 Add more documentation. src/lib/libusb20/libusb20.c Various bugfixes and improvements. src/usr.sbin/usbconfig/dump.c src/usr.sbin/usbconfig/usbconfig.c New commands for dumping strings and doing custom USB requests from the command line. Remove keyword requirements from generated files: "head/sys/dev/usb2/include/usb2_devid.h" "head/sys/dev/usb2/include/usb2_devtable.h"
Diffstat (limited to 'usr.sbin/usbconfig')
-rw-r--r--usr.sbin/usbconfig/dump.c76
-rw-r--r--usr.sbin/usbconfig/usbconfig.c148
2 files changed, 142 insertions, 82 deletions
diff --git a/usr.sbin/usbconfig/dump.c b/usr.sbin/usbconfig/dump.c
index 89a47ac..ffa8b2c 100644
--- a/usr.sbin/usbconfig/dump.c
+++ b/usr.sbin/usbconfig/dump.c
@@ -96,9 +96,6 @@ static void
dump_field(struct libusb20_device *pdev, const char *plevel,
const char *field, uint32_t value)
{
- struct LIBUSB20_CONTROL_SETUP_DECODED req;
- uint16_t lang_id;
- uint8_t index;
uint8_t temp_string[256];
printf("%s%s = 0x%04x ", plevel, field, value);
@@ -108,64 +105,15 @@ dump_field(struct libusb20_device *pdev, const char *plevel,
return;
}
if (value == 0) {
- printf(" <no string> \n");
+ printf(" <no string>\n");
return;
}
- LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &req);
-
- lang_id = 0;
- index = 0;
-
- req.bmRequestType =
- LIBUSB20_REQUEST_TYPE_STANDARD |
- LIBUSB20_RECIPIENT_DEVICE |
- LIBUSB20_ENDPOINT_IN;
- req.bRequest = LIBUSB20_REQUEST_GET_DESCRIPTOR;
- req.wValue = (256 * LIBUSB20_DT_STRING) | index;
- req.wIndex = lang_id;
- req.wLength = 4; /* bytes */
-
- if (libusb20_dev_request_sync(pdev, &req,
- temp_string, NULL, 1000, 0)) {
- goto done;
- }
- lang_id = temp_string[2] | (temp_string[3] << 8);
-
- printf(" LangId:0x%04x <", lang_id);
-
- index = value;
-
- req.wValue = (256 * LIBUSB20_DT_STRING) | index;
- req.wIndex = lang_id;
- req.wLength = 4; /* bytes */
-
- if (libusb20_dev_request_sync(pdev, &req,
- temp_string, NULL, 1000, 0)) {
- printf("ERROR>\n");
- goto done;
- }
- req.wValue = (256 * LIBUSB20_DT_STRING) | index;
- req.wIndex = lang_id;
- req.wLength = temp_string[0]; /* bytes */
-
- if (libusb20_dev_request_sync(pdev, &req,
- temp_string, NULL, 1000, 0)) {
- printf("ERROR>\n");
- goto done;
- }
- req.wLength /= 2;
-
- for (index = 1; index != req.wLength; index++) {
- if (isprint(temp_string[(2 * index) + 0])) {
- printf("%c", temp_string[(2 * index) + 0]);
- } else if (isprint(temp_string[(2 * index) + 1])) {
- printf("%c", temp_string[(2 * index) + 1]);
- } else {
- printf("?");
- }
+ if (libusb20_dev_req_string_simple_sync(pdev, value,
+ temp_string, sizeof(temp_string))) {
+ printf(" <retrieving string failed>\n");
+ return;
}
- printf(">\n");
-done:
+ printf(" <%s>\n", temp_string);
return;
}
@@ -244,7 +192,7 @@ dump_be_quirk_names(struct libusb20_backend *pbe)
{
struct libusb20_quirk q;
uint16_t x;
- int err;
+ int error;
memset(&q, 0, sizeof(q));
@@ -252,8 +200,8 @@ dump_be_quirk_names(struct libusb20_backend *pbe)
for (x = 0; x != 0xFFFF; x++) {
- err = libusb20_be_get_quirk_name(pbe, x, &q);
- if (err) {
+ error = libusb20_be_get_quirk_name(pbe, x, &q);
+ if (error) {
if (x == 0) {
printf("No quirk names - maybe the USB quirk "
"module has not been loaded.\n");
@@ -272,7 +220,7 @@ dump_be_dev_quirks(struct libusb20_backend *pbe)
{
struct libusb20_quirk q;
uint16_t x;
- int err;
+ int error;
memset(&q, 0, sizeof(q));
@@ -280,8 +228,8 @@ dump_be_dev_quirks(struct libusb20_backend *pbe)
for (x = 0; x != 0xFFFF; x++) {
- err = libusb20_be_get_dev_quirk(pbe, x, &q);
- if (err) {
+ error = libusb20_be_get_dev_quirk(pbe, x, &q);
+ if (error) {
if (x == 0) {
printf("No device quirks - maybe the USB quirk "
"module has not been loaded.\n");
diff --git a/usr.sbin/usbconfig/usbconfig.c b/usr.sbin/usbconfig/usbconfig.c
index eb10b5f..5aa9102 100644
--- a/usr.sbin/usbconfig/usbconfig.c
+++ b/usr.sbin/usbconfig/usbconfig.c
@@ -32,6 +32,7 @@
#include <pwd.h>
#include <grp.h>
#include <errno.h>
+#include <ctype.h>
#include <libusb20_desc.h>
#include <libusb20.h>
@@ -40,10 +41,12 @@
struct options {
const char *quirkname;
+ void *buffer;
gid_t gid;
uid_t uid;
mode_t mode;
uint32_t got_any;
+ struct LIBUSB20_CONTROL_SETUP_DECODED setup;
uint16_t bus;
uint16_t addr;
uint16_t iface;
@@ -51,6 +54,7 @@ struct options {
uint16_t pid;
uint16_t lo_rev; /* inclusive */
uint16_t hi_rev; /* inclusive */
+ uint8_t string_index;
uint8_t config_index;
uint8_t alt_index;
uint8_t got_list:1;
@@ -76,6 +80,8 @@ struct options {
uint8_t got_dump_access:1;
uint8_t got_remove_device_quirk:1;
uint8_t got_add_device_quirk:1;
+ uint8_t got_dump_string:1;
+ uint8_t got_do_request:1;
};
struct token {
@@ -99,6 +105,7 @@ enum {
T_DUMP_DEVICE_DESC,
T_DUMP_CURR_CONFIG_DESC,
T_DUMP_ALL_CONFIG_DESC,
+ T_DUMP_STRING,
T_DUMP_ACCESS,
T_DUMP_INFO,
T_SUSPEND,
@@ -108,6 +115,7 @@ enum {
T_POWER_ON,
T_RESET,
T_LIST,
+ T_DO_REQUEST,
};
static struct options options;
@@ -127,6 +135,7 @@ static const struct token token[] = {
{"dump_device_desc", T_DUMP_DEVICE_DESC, 0},
{"dump_curr_config_desc", T_DUMP_CURR_CONFIG_DESC, 0},
{"dump_all_config_desc", T_DUMP_ALL_CONFIG_DESC, 0},
+ {"dump_string", T_DUMP_STRING, 1},
{"dump_access", T_DUMP_ACCESS, 0},
{"dump_info", T_DUMP_INFO, 0},
{"suspend", T_SUSPEND, 0},
@@ -136,6 +145,7 @@ static const struct token token[] = {
{"power_on", T_POWER_ON, 0},
{"reset", T_RESET, 0},
{"list", T_LIST, 0},
+ {"do_request", T_DO_REQUEST, 5},
};
static void
@@ -144,7 +154,7 @@ be_dev_remove_quirk(struct libusb20_backend *pbe,
const char *str)
{
struct libusb20_quirk q;
- int err;
+ int error;
memset(&q, 0, sizeof(q));
@@ -154,8 +164,8 @@ be_dev_remove_quirk(struct libusb20_backend *pbe,
q.bcdDeviceHigh = hirev;
strlcpy(q.quirkname, str, sizeof(q.quirkname));
- err = libusb20_be_remove_dev_quirk(pbe, &q);
- if (err) {
+ error = libusb20_be_remove_dev_quirk(pbe, &q);
+ if (error) {
printf("Removing quirk '%s' failed, continuing.\n", str);
}
return;
@@ -167,7 +177,7 @@ be_dev_add_quirk(struct libusb20_backend *pbe,
const char *str)
{
struct libusb20_quirk q;
- int err;
+ int error;
memset(&q, 0, sizeof(q));
@@ -177,8 +187,8 @@ be_dev_add_quirk(struct libusb20_backend *pbe,
q.bcdDeviceHigh = hirev;
strlcpy(q.quirkname, str, sizeof(q.quirkname));
- err = libusb20_be_add_dev_quirk(pbe, &q);
- if (err) {
+ error = libusb20_be_add_dev_quirk(pbe, &q);
+ if (error) {
printf("Adding quirk '%s' failed, continuing.\n", str);
}
return;
@@ -192,7 +202,7 @@ get_token(const char *str, uint8_t narg)
for (n = 0; n != (sizeof(token) / sizeof(token[0])); n++) {
if (strcasecmp(str, token[n].name) == 0) {
if (token[n].narg > narg) {
- /* to little arguments */
+ /* too few arguments */
break;
}
return (token[n].value);
@@ -266,8 +276,8 @@ usage(void)
"usbconfig - configure the USB subsystem" "\n"
"usage: usbconfig -u <busnum> -a <devaddr> -i <ifaceindex> [cmds...]" "\n"
"commands:" "\n"
- " set_config <num>" "\n"
- " set_alt <altno>" "\n"
+ " set_config <cfg_index>" "\n"
+ " set_alt <alt_index>" "\n"
" set_owner <user:group>" "\n"
" set_perm <mode>" "\n"
" add_dev_quirk_vplh <vid> <pid> <lo_rev> <hi_rev> <quirk>" "\n"
@@ -277,6 +287,7 @@ usage(void)
" dump_device_desc" "\n"
" dump_curr_config_desc" "\n"
" dump_all_config_desc" "\n"
+ " dump_string <index>" "\n"
" dump_access" "\n"
" dump_info" "\n"
" suspend" "\n"
@@ -286,6 +297,7 @@ usage(void)
" power_on" "\n"
" reset" "\n"
" list" "\n"
+ " do_request <bmReqTyp> <bReq> <wVal> <wIdx> <wLen> <data...>" "\n"
);
exit(1);
}
@@ -293,6 +305,8 @@ usage(void)
static void
reset_options(struct options *opt)
{
+ if (opt->buffer)
+ free(opt->buffer);
memset(opt, 0, sizeof(*opt));
return;
}
@@ -418,6 +432,54 @@ flush_command(struct libusb20_backend *pbe, struct options *opt)
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);
+ }
+ if (opt->got_do_request) {
+ uint16_t actlen;
+ uint16_t t;
+
+ if (libusb20_dev_request_sync(pdev, &opt->setup,
+ opt->buffer, &actlen, 5000 /* 5 seconds */ , 0)) {
+ printf("REQUEST = <ERROR>\n");
+ } else if (!(opt->setup.bmRequestType &
+ LIBUSB20_ENDPOINT_IN)) {
+ printf("REQUEST = <OK>\n");
+ } else {
+ t = actlen;
+ printf("REQUEST = <");
+ for (t = 0; t != actlen; t++) {
+ printf("0x%02x%s",
+ ((uint8_t *)opt->buffer)[t],
+ (t == (actlen - 1)) ? "" : " ");
+ }
+ printf("><");
+ for (t = 0; t != actlen; t++) {
+ char c;
+
+ c = ((uint8_t *)opt->buffer)[t];
+ if ((c != '<') &&
+ (c != '>') && isprint(c)) {
+ putchar(c);
+ }
+ }
+ printf(">\n");
+ }
+ }
if (opt->got_set_config) {
if (libusb20_dev_set_config_index(pdev,
opt->config_index)) {
@@ -425,7 +487,8 @@ flush_command(struct libusb20_backend *pbe, struct options *opt)
}
}
if (opt->got_set_alt) {
- if (libusb20_dev_set_alt_index(pdev, opt->iface, opt->alt_index)) {
+ if (libusb20_dev_set_alt_index(pdev, opt->iface,
+ opt->alt_index)) {
err(1, "could not set alternate setting");
}
}
@@ -435,27 +498,32 @@ flush_command(struct libusb20_backend *pbe, struct options *opt)
}
}
if (opt->got_suspend) {
- if (libusb20_dev_set_power_mode(pdev, LIBUSB20_POWER_SUSPEND)) {
+ if (libusb20_dev_set_power_mode(pdev,
+ LIBUSB20_POWER_SUSPEND)) {
err(1, "could not set suspend");
}
}
if (opt->got_resume) {
- if (libusb20_dev_set_power_mode(pdev, LIBUSB20_POWER_RESUME)) {
+ if (libusb20_dev_set_power_mode(pdev,
+ LIBUSB20_POWER_RESUME)) {
err(1, "could not set resume");
}
}
if (opt->got_power_off) {
- if (libusb20_dev_set_power_mode(pdev, LIBUSB20_POWER_OFF)) {
+ if (libusb20_dev_set_power_mode(pdev,
+ LIBUSB20_POWER_OFF)) {
err(1, "could not set power OFF");
}
}
if (opt->got_power_save) {
- if (libusb20_dev_set_power_mode(pdev, LIBUSB20_POWER_SAVE)) {
+ if (libusb20_dev_set_power_mode(pdev,
+ LIBUSB20_POWER_SAVE)) {
err(1, "could not set power SAVE");
}
}
if (opt->got_power_on) {
- if (libusb20_dev_set_power_mode(pdev, LIBUSB20_POWER_ON)) {
+ if (libusb20_dev_set_power_mode(pdev,
+ LIBUSB20_POWER_ON)) {
err(1, "could not set power ON");
}
}
@@ -584,13 +652,13 @@ main(int argc, char **argv)
n++;
break;
case T_SET_CONFIG:
- opt->config_index = num_id(argv[n + 1], "confindex");
+ opt->config_index = num_id(argv[n + 1], "cfg_index");
opt->got_set_config = 1;
opt->got_any++;
n++;
break;
case T_SET_ALT:
- opt->alt_index = num_id(argv[n + 1], "confindex");
+ opt->alt_index = num_id(argv[n + 1], "cfg_index");
opt->got_set_alt = 1;
opt->got_any++;
n++;
@@ -630,9 +698,18 @@ main(int argc, char **argv)
opt->got_dump_info = 1;
opt->got_any++;
break;
+ case T_DUMP_STRING:
+ if (opt->got_dump_string) {
+ flush_command(pbe, opt);
+ }
+ opt->string_index = num_id(argv[n + 1], "str_index");
+ opt->got_dump_string = 1;
+ opt->got_any++;
+ n++;
+ break;
case T_DUMP_ACCESS:
opt->got_dump_access = 1;
- opt->got_any++;
+ opt->got_any += 2;
break;
case T_SUSPEND:
opt->got_suspend = 1;
@@ -662,6 +739,41 @@ main(int argc, char **argv)
opt->got_list = 1;
opt->got_any++;
break;
+ case T_DO_REQUEST:
+ if (opt->got_do_request) {
+ flush_command(pbe, opt);
+ }
+ 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");
+ opt->setup.wValue = num_id(argv[n + 3], "wVal");
+ opt->setup.wIndex = num_id(argv[n + 4], "wIndex");
+ opt->setup.wLength = num_id(argv[n + 5], "wLen");
+ if (opt->setup.wLength != 0) {
+ opt->buffer = malloc(opt->setup.wLength);
+ } else {
+ opt->buffer = NULL;
+ }
+
+ n += 5;
+
+ if (!(opt->setup.bmRequestType &
+ LIBUSB20_ENDPOINT_IN)) {
+ /* copy in data */
+ t = (argc - n - 1);
+ if (t < opt->setup.wLength) {
+ err(1, "request data missing");
+ }
+ t = opt->setup.wLength;
+ while (t--) {
+ ((uint8_t *)opt->buffer)[t] =
+ num_id(argv[n + t + 1], "req_data");
+ }
+ n += opt->setup.wLength;
+ }
+ opt->got_do_request = 1;
+ opt->got_any++;
+ break;
default:
usage();
break;
OpenPOWER on IntegriCloud