summaryrefslogtreecommitdiffstats
path: root/usr.sbin/usbdevs
diff options
context:
space:
mode:
authorckuethe <ckuethe@openbsd.org>2007-12-04 05:05:46 +0000
committerckuethe <ckuethe@openbsd.org>2007-12-04 05:05:46 +0000
commit1c95a3ebd9fd58842a8dfc46ae55364baac4fd0b (patch)
treebc50d2e4bc8aea439bc1fd363c2767fe82bfdfec /usr.sbin/usbdevs
parentCheck for G channels before B when setting the (eeprom) mode. (diff)
downloadwireguard-openbsd-1c95a3ebd9fd58842a8dfc46ae55364baac4fd0b.tar.xz
wireguard-openbsd-1c95a3ebd9fd58842a8dfc46ae55364baac4fd0b.zip
allow the usb serial number to be printed in verbose mode. this is
useful for people writing custom hotplugd(8) scripts, as well as ipod users. ok deraadt
Diffstat (limited to 'usr.sbin/usbdevs')
-rw-r--r--usr.sbin/usbdevs/usbdevs.c77
1 files changed, 74 insertions, 3 deletions
diff --git a/usr.sbin/usbdevs/usbdevs.c b/usr.sbin/usbdevs/usbdevs.c
index 8fc2e361eb5..a3441b3a288 100644
--- a/usr.sbin/usbdevs/usbdevs.c
+++ b/usr.sbin/usbdevs/usbdevs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: usbdevs.c,v 1.11 2004/04/03 21:01:25 jmc Exp $ */
+/* $OpenBSD: usbdevs.c,v 1.12 2007/12/04 05:05:46 ckuethe Exp $ */
/* $NetBSD: usbdevs.c,v 1.19 2002/02/21 00:34:31 christos Exp $ */
/*
@@ -54,6 +54,8 @@ int showdevs = 0;
void usage(void);
void usbdev(int f, int a, int rec);
+int getdevicedesc(int, int, usb_device_descriptor_t *);
+void getstring(int, int, int, char *);
void usbdump(int f);
void dumpone(char *name, int f, int addr);
int main(int, char **);
@@ -75,6 +77,8 @@ void
usbdev(int f, int a, int rec)
{
struct usb_device_info di;
+ usb_device_descriptor_t dd;
+ char serialnum[USB_MAX_STRING_LEN];
int e, p, i;
di.udi_addr = a;
@@ -84,6 +88,9 @@ usbdev(int f, int a, int rec)
printf("addr %d: I/O error\n", a);
return;
}
+ if (getdevicedesc(f, a, &dd))
+ getstring(f, a, dd.iSerialNumber, serialnum);
+
printf("addr %d: ", a);
done[a] = 1;
if (verbose) {
@@ -114,6 +121,8 @@ usbdev(int f, int a, int rec)
printf("%s(0x%04x), %s(0x%04x), rev %s",
di.udi_product, di.udi_productNo,
di.udi_vendor, di.udi_vendorNo, di.udi_release);
+ if (strlen(serialnum))
+ printf(", iSerialNumber %s", serialnum);
} else
printf("%s, %s", di.udi_product, di.udi_vendor);
printf("\n");
@@ -151,6 +160,68 @@ usbdev(int f, int a, int rec)
}
}
+int
+getdevicedesc(int f, int addr, usb_device_descriptor_t *d)
+{
+ struct usb_ctl_request req;
+ int r;
+
+ req.ucr_addr = addr;
+ req.ucr_request.bmRequestType = UT_READ_DEVICE;
+ req.ucr_request.bRequest = UR_GET_DESCRIPTOR;
+ USETW2(req.ucr_request.wValue, UDESC_DEVICE, 0);
+ USETW(req.ucr_request.wIndex, 0);
+ USETW(req.ucr_request.wLength, USB_DEVICE_DESCRIPTOR_SIZE);
+ req.ucr_data = d;
+ req.ucr_flags = 0;
+ if (r = ioctl(f, USB_REQUEST, &req))
+ perror("getdevicedesc: ioctl");
+ return 1;
+ return (r == 0);
+}
+
+void
+getstring(int f, int addr, int si, char *s)
+{
+ struct usb_ctl_request req;
+ usb_string_descriptor_t us;
+ int r, i, n;
+ u_int16_t c;
+
+ if (si == 0) {
+ *s = 0;
+ return;
+ }
+ req.ucr_addr = addr;
+ req.ucr_request.bmRequestType = UT_READ_DEVICE;
+ req.ucr_request.bRequest = UR_GET_DESCRIPTOR;
+ req.ucr_data = &us;
+ USETW2(req.ucr_request.wValue, UDESC_STRING, si);
+ USETW(req.ucr_request.wIndex, 0);
+ USETW(req.ucr_request.wLength, sizeof(usb_string_descriptor_t));
+ req.ucr_flags = USBD_SHORT_XFER_OK;
+
+ if (ioctl(f, USB_REQUEST, &req) == -1){
+ perror("getstring: ioctl");
+ *s = 0;
+ return;
+ }
+
+ n = us.bLength / 2 - 1;
+ for (i = 0; i < n; i++) {
+ c = UGETW(us.bString[i]);
+ if ((c & 0xff00) == 0)
+ *s++ = c;
+ else if ((c & 0x00ff) == 0)
+ *s++ = c >> 8;
+ else {
+ snprintf(s, 6, "\\u%04x", c);
+ s += 6;
+ }
+ }
+ *s++ = 0;
+}
+
void
usbdump(int f)
{
@@ -208,7 +279,7 @@ main(int argc, char **argv)
if (dev == 0) {
for (ncont = 0, i = 0; i < 10; i++) {
snprintf(buf, sizeof buf, "%s%d", USBDEV, i);
- f = open(buf, O_RDONLY);
+ f = open(buf, O_RDWR);
if (f >= 0) {
dumpone(buf, f, addr);
close(f);
@@ -223,7 +294,7 @@ main(int argc, char **argv)
printf("%s: no USB controllers found\n",
__progname);
} else {
- f = open(dev, O_RDONLY);
+ f = open(dev, O_RDWR);
if (f >= 0)
dumpone(dev, f, addr);
else