summaryrefslogtreecommitdiffstats
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
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
-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