Module Name:    src
Committed By:   skrll
Date:           Sun Jan 10 10:33:43 UTC 2016

Modified Files:
        src/sys/dev/usb [nick-nhusb]: usb.c usb_subr.c usbdivar.h xhci.c

Log Message:
Bring the following change from HEAD

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.


To generate a diff of this commit:
cvs rdiff -u -r1.156.2.11 -r1.156.2.12 src/sys/dev/usb/usb.c
cvs rdiff -u -r1.198.2.22 -r1.198.2.23 src/sys/dev/usb/usb_subr.c
cvs rdiff -u -r1.109.2.21 -r1.109.2.22 src/sys/dev/usb/usbdivar.h
cvs rdiff -u -r1.28.2.48 -r1.28.2.49 src/sys/dev/usb/xhci.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/usb.c
diff -u src/sys/dev/usb/usb.c:1.156.2.11 src/sys/dev/usb/usb.c:1.156.2.12
--- src/sys/dev/usb/usb.c:1.156.2.11	Sun Dec 27 12:09:59 2015
+++ src/sys/dev/usb/usb.c	Sun Jan 10 10:33:43 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: usb.c,v 1.156.2.11 2015/12/27 12:09:59 skrll Exp $	*/
+/*	$NetBSD: usb.c,v 1.156.2.12 2016/01/10 10:33:43 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.156.2.11 2015/12/27 12:09:59 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.156.2.12 2016/01/10 10:33:43 skrll Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -960,7 +960,7 @@ usbd_add_dev_event(int type, struct usbd
 {
 	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);
 }
 

Index: src/sys/dev/usb/usb_subr.c
diff -u src/sys/dev/usb/usb_subr.c:1.198.2.22 src/sys/dev/usb/usb_subr.c:1.198.2.23
--- src/sys/dev/usb/usb_subr.c:1.198.2.22	Mon Dec 28 09:26:33 2015
+++ src/sys/dev/usb/usb_subr.c	Sun Jan 10 10:33:43 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: usb_subr.c,v 1.198.2.22 2015/12/28 09:26:33 skrll Exp $	*/
+/*	$NetBSD: usb_subr.c,v 1.198.2.23 2016/01/10 10:33:43 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.198.2.22 2015/12/28 09:26:33 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.198.2.23 2016/01/10 10:33:43 skrll Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -166,6 +166,33 @@ usbd_trim_spaces(char *p)
 	*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->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(struct usbd_device *dev, char *v, size_t vl, char *p,
     size_t pl, int usedev, int useencoded)
@@ -183,6 +210,13 @@ usbd_devinfo_vp(struct usbd_device *dev,
 		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));
@@ -215,7 +249,7 @@ usbd_devinfo(struct usbd_device *dev, in
 	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",
@@ -832,19 +866,10 @@ usbd_attach_roothub(device_t parent, str
 static void
 usbd_serialnumber(device_t dv, struct usbd_device *dev)
 {
-	usb_device_descriptor_t *dd = &dev->ud_ddesc;
-	char *serialnumber;
-
-	serialnumber = kmem_alloc(USB_MAX_ENCODED_STRING_LEN, KM_SLEEP);
-	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);
 	}
-	kmem_free(serialnumber, USB_MAX_ENCODED_STRING_LEN);
 }
 
 static usbd_status
@@ -1325,6 +1350,8 @@ usbd_new_device(device_t parent, struct 
 
 	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 */
@@ -1446,10 +1473,22 @@ usbd_fill_deviceinfo(struct usbd_device 
 	    di->udi_product, sizeof(di->udi_product), usedev, 1);
 	usbd_printBCD(di->udi_release, sizeof(di->udi_release),
 	    UGETW(dev->ud_ddesc.bcdDevice));
-	di->udi_serial[0] = 0;
-	if (usedev)
-		(void)usbd_get_string(dev, dev->ud_ddesc.iSerialNumber,
-				      di->udi_serial);
+	if (usedev) {
+		usbd_status uerr = usbd_get_string(dev,
+		    dev->ud_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->ud_ddesc.idVendor);
 	di->udi_productNo = UGETW(dev->ud_ddesc.idProduct);
 	di->udi_releaseNo = UGETW(dev->ud_ddesc.bcdDevice);
@@ -1602,6 +1641,15 @@ usb_free_device(struct usbd_device *dev)
 		    dev->ud_subdevlen * sizeof(device_t));
 		dev->ud_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);
+	}
 	kmem_free(dev, sizeof(*dev));
 }
 

Index: src/sys/dev/usb/usbdivar.h
diff -u src/sys/dev/usb/usbdivar.h:1.109.2.21 src/sys/dev/usb/usbdivar.h:1.109.2.22
--- src/sys/dev/usb/usbdivar.h:1.109.2.21	Mon Dec 28 09:26:33 2015
+++ src/sys/dev/usb/usbdivar.h	Sun Jan 10 10:33:43 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: usbdivar.h,v 1.109.2.21 2015/12/28 09:26:33 skrll Exp $	*/
+/*	$NetBSD: usbdivar.h,v 1.109.2.22 2016/01/10 10:33:43 skrll Exp $	*/
 
 /*
  * Copyright (c) 1998, 2012 The NetBSD Foundation, Inc.
@@ -204,6 +204,10 @@ struct usbd_device {
 	device_t	       *ud_subdevs;	/* sub-devices */
 	int			ud_nifaces_claimed; /* number of ifaces in use */
 	void		       *ud_hcpriv;
+
+	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 {
@@ -294,6 +298,7 @@ void usbd_dump_pipe(struct usbd_pipe *);
 
 /* Routines from usb_subr.c */
 int		usbctlprint(void *, const char *);
+void		usbd_get_device_strings(struct usbd_device *);
 void		usb_delay_ms_locked(struct usbd_bus *, u_int, kmutex_t *);
 void		usb_delay_ms(struct usbd_bus *, u_int);
 void		usbd_delay_ms_locked(struct usbd_device *, u_int, kmutex_t *);

Index: src/sys/dev/usb/xhci.c
diff -u src/sys/dev/usb/xhci.c:1.28.2.48 src/sys/dev/usb/xhci.c:1.28.2.49
--- src/sys/dev/usb/xhci.c:1.28.2.48	Wed Dec 23 08:07:40 2015
+++ src/sys/dev/usb/xhci.c	Sun Jan 10 10:33:43 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: xhci.c,v 1.28.2.48 2015/12/23 08:07:40 skrll Exp $	*/
+/*	$NetBSD: xhci.c,v 1.28.2.49 2016/01/10 10:33:43 skrll Exp $	*/
 
 /*
  * Copyright (c) 2013 Jonathan A. Kollasch
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.28.2.48 2015/12/23 08:07:40 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.28.2.49 2016/01/10 10:33:43 skrll Exp $");
 
 #include "opt_usb.h"
 
@@ -2319,6 +2319,8 @@ xhci_new_device(device_t parent, struct 
 		dd->bMaxPacketSize, dd->bLength, dd->bNumConfigurations,
 		dev->ud_speed);
 
+	usbd_get_device_strings(dev);
+
 	usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev);
 
 	if ((depth == 0) && (port == 0)) {

Reply via email to