Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/usb Get the iManufacturer, iProduct, and iSerialNumb...



details:   https://anonhg.NetBSD.org/src/rev/1a33c046210a
branches:  trunk
changeset: 342727:1a33c046210a
user:      skrll <skrll%NetBSD.org@localhost>
date:      Wed Jan 06 22:12:49 2016 +0000

description:
Get the iManufacturer, iProduct, and iSerialNumber strings before probing
for drivers and cache them for later use.  This reduces bus transactions
and fixes attachment for at least two of my umass(4)s.

diffstat:

 sys/dev/usb/usb.c      |   6 +-
 sys/dev/usb/usb_subr.c |  83 +++++++++++++++++++++++++++++++++++++++----------
 sys/dev/usb/usbdivar.h |   7 +++-
 sys/dev/usb/xhci.c     |   6 ++-
 4 files changed, 78 insertions(+), 24 deletions(-)

diffs (230 lines):

diff -r c7909fc66a70 -r 1a33c046210a sys/dev/usb/usb.c
--- a/sys/dev/usb/usb.c Wed Jan 06 18:06:38 2016 +0000
+++ b/sys/dev/usb/usb.c Wed Jan 06 22:12:49 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: usb.c,v 1.160 2015/10/29 00:15:48 mrg Exp $    */
+/*     $NetBSD: usb.c,v 1.161 2016/01/06 22:12:49 skrll Exp $  */
 
 /*
  * Copyright (c) 1998, 2002, 2008, 2012 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.160 2015/10/29 00:15:48 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.161 2016/01/06 22:12:49 skrll Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -947,7 +947,7 @@
 {
        struct usb_event *ue = usb_alloc_event();
 
-       usbd_fill_deviceinfo(udev, &ue->u.ue_device, USB_EVENT_IS_ATTACH(type));
+       usbd_fill_deviceinfo(udev, &ue->u.ue_device, false);
        usb_add_event(type, ue);
 }
 
diff -r c7909fc66a70 -r 1a33c046210a sys/dev/usb/usb_subr.c
--- a/sys/dev/usb/usb_subr.c    Wed Jan 06 18:06:38 2016 +0000
+++ b/sys/dev/usb/usb_subr.c    Wed Jan 06 22:12:49 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: usb_subr.c,v 1.206 2015/12/10 09:19:42 skrll Exp $     */
+/*     $NetBSD: usb_subr.c,v 1.207 2016/01/06 22:12:49 skrll Exp $     */
 /*     $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $   */
 
 /*
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.206 2015/12/10 09:19:42 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.207 2016/01/06 22:12:49 skrll Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -170,6 +170,33 @@
        *e = '\0';                      /* kill trailing spaces */
 }
 
+static void
+usbd_get_device_string(struct usbd_device *ud, uByte index, char **buf)
+{
+       char *b = kmem_alloc(USB_MAX_ENCODED_STRING_LEN, KM_SLEEP);
+       if (b) {
+               usbd_status err = usbd_get_string0(ud, index, b, true);
+               if (err != USBD_NORMAL_COMPLETION) {
+                       kmem_free(b, USB_MAX_ENCODED_STRING_LEN);
+                       b = NULL;
+               } else {
+                       usbd_trim_spaces(b);
+               }
+       }
+       *buf = b;
+}
+
+void
+usbd_get_device_strings(struct usbd_device *ud)
+{
+       usb_device_descriptor_t *udd = &ud->ddesc;
+
+       usbd_get_device_string(ud, udd->iManufacturer, &ud->ud_vendor);
+       usbd_get_device_string(ud, udd->iProduct, &ud->ud_product);
+       usbd_get_device_string(ud, udd->iSerialNumber, &ud->ud_serial);
+}
+
+
 Static void
 usbd_devinfo_vp(usbd_device_handle dev, char *v, size_t vl, char *p,
     size_t pl, int usedev, int useencoded)
@@ -187,6 +214,13 @@
                if (usbd_get_string0(dev, udd->iProduct, p, useencoded) ==
                    USBD_NORMAL_COMPLETION)
                        usbd_trim_spaces(p);
+       } else {
+               if (dev->ud_vendor) {
+                       strlcpy(v, dev->ud_vendor, vl);
+               }
+               if (dev->ud_product) {
+                       strlcpy(p, dev->ud_product, pl);
+               }
        }
        if (v[0] == '\0')
                usb_findvendor(v, vl, UGETW(udd->idVendor));
@@ -219,7 +253,7 @@
        ep = cp + l;
 
        usbd_devinfo_vp(dev, vendor, USB_MAX_ENCODED_STRING_LEN,
-           product, USB_MAX_ENCODED_STRING_LEN, 1, 1);
+           product, USB_MAX_ENCODED_STRING_LEN, 0, 1);
        cp += snprintf(cp, ep - cp, "%s %s", vendor, product);
        if (showclass)
                cp += snprintf(cp, ep - cp, ", class %d/%d",
@@ -793,19 +827,10 @@
 static void
 usbd_serialnumber(device_t dv, usbd_device_handle dev)
 {
-       usb_device_descriptor_t *dd = &dev->ddesc;
-       char *serialnumber;
-
-       serialnumber = malloc(USB_MAX_ENCODED_STRING_LEN, M_USB, M_NOWAIT);
-       if (serialnumber == NULL)
-               return;
-       serialnumber[0] = '\0';
-       (void)usbd_get_string(dev, dd->iSerialNumber, serialnumber);
-       if (serialnumber[0]) {
+       if (dev->ud_serial) {
                prop_dictionary_set_cstring(device_properties(dv),
-                   "serialnumber", serialnumber);
+                   "serialnumber", dev->ud_serial);
        }
-       free(serialnumber, M_USB);
 }
 
 static usbd_status
@@ -1281,6 +1306,8 @@
 
        DPRINTF("new dev (addr %d), dev=%p, parent=%p", addr, dev, parent, 0);
 
+       usbd_get_device_strings(dev);
+
        usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev);
 
        if (port == 0) { /* root hub */
@@ -1402,10 +1429,21 @@
            di->udi_product, sizeof(di->udi_product), usedev, 1);
        usbd_printBCD(di->udi_release, sizeof(di->udi_release),
            UGETW(dev->ddesc.bcdDevice));
-       di->udi_serial[0] = 0;
-       if (usedev)
-               (void)usbd_get_string(dev, dev->ddesc.iSerialNumber,
-                                     di->udi_serial);
+       if (usedev) {
+               usbd_status uerr = usbd_get_string(dev,
+                   dev->ddesc.iSerialNumber, di->udi_serial);
+               if (uerr != USBD_NORMAL_COMPLETION) {
+                       di->udi_serial[0] = '\0';
+               } else {
+                       usbd_trim_spaces(di->udi_serial);
+               }
+       } else {
+               di->udi_serial[0] = '\0';
+               if (dev->ud_serial) {
+                       strlcpy(di->udi_serial, dev->ud_serial,
+                           sizeof(di->udi_serial));
+               }
+       }
        di->udi_vendorNo = UGETW(dev->ddesc.idVendor);
        di->udi_productNo = UGETW(dev->ddesc.idProduct);
        di->udi_releaseNo = UGETW(dev->ddesc.bcdDevice);
@@ -1546,6 +1584,15 @@
                free(dev->subdevs, M_USB);
                dev->subdevlen = 0;
        }
+       if (dev->ud_vendor) {
+               kmem_free(dev->ud_vendor, USB_MAX_ENCODED_STRING_LEN);
+       }
+       if (dev->ud_product) {
+               kmem_free(dev->ud_product, USB_MAX_ENCODED_STRING_LEN);
+       }
+       if (dev->ud_serial) {
+               kmem_free(dev->ud_serial, USB_MAX_ENCODED_STRING_LEN);
+       }
        free(dev, M_USB);
 }
 
diff -r c7909fc66a70 -r 1a33c046210a sys/dev/usb/usbdivar.h
--- a/sys/dev/usb/usbdivar.h    Wed Jan 06 18:06:38 2016 +0000
+++ b/sys/dev/usb/usbdivar.h    Wed Jan 06 22:12:49 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: usbdivar.h,v 1.110 2015/08/23 11:12:01 skrll Exp $     */
+/*     $NetBSD: usbdivar.h,v 1.111 2016/01/06 22:12:49 skrll Exp $     */
 
 /*
  * Copyright (c) 1998, 2012 The NetBSD Foundation, Inc.
@@ -197,6 +197,10 @@
        device_t               *subdevs;       /* sub-devices */
        int                     nifaces_claimed; /* number of ifaces in use */
        void                   *hci_private;
+
+       char                   *ud_serial;      /* serial number, can be NULL */
+       char                   *ud_vendor;      /* vendor string, can be NULL */
+       char                   *ud_product;     /* product string can be NULL */
 };
 
 struct usbd_interface {
@@ -286,6 +290,7 @@
 
 /* Routines from usb_subr.c */
 int            usbctlprint(void *, const char *);
+void           usbd_get_device_strings(struct usbd_device *);
 void           usb_delay_ms_locked(usbd_bus_handle, u_int, kmutex_t *);
 void           usb_delay_ms(usbd_bus_handle, u_int);
 void           usbd_delay_ms_locked(usbd_device_handle, u_int, kmutex_t *);
diff -r c7909fc66a70 -r 1a33c046210a sys/dev/usb/xhci.c
--- a/sys/dev/usb/xhci.c        Wed Jan 06 18:06:38 2016 +0000
+++ b/sys/dev/usb/xhci.c        Wed Jan 06 22:12:49 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: xhci.c,v 1.32 2015/12/10 17:07:07 skrll Exp $  */
+/*     $NetBSD: xhci.c,v 1.33 2016/01/06 22:12:49 skrll Exp $  */
 
 /*
  * Copyright (c) 2013 Jonathan A. Kollasch
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.32 2015/12/10 17:07:07 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.33 2016/01/06 22:12:49 skrll Exp $");
 
 #include "opt_usb.h"
 
@@ -1614,6 +1614,8 @@
                dd->bMaxPacketSize, dd->bLength, dd->bNumConfigurations,
                dev->speed);
 
+       usbd_get_device_strings(dev);
+
        usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev);
 
        if ((depth == 0) && (port == 0)) {



Home | Main Index | Thread Index | Old Index