From 1c95a3ebd9fd58842a8dfc46ae55364baac4fd0b Mon Sep 17 00:00:00 2001 From: ckuethe Date: Tue, 4 Dec 2007 05:05:46 +0000 Subject: 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 --- usr.sbin/usbdevs/usbdevs.c | 77 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 3 deletions(-) (limited to 'usr.sbin/usbdevs') 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 -- cgit v1.2.3-59-g8ed1b