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.
This commit is contained in:
skrll 2016-01-06 22:12:49 +00:00
parent 96bedaec9a
commit 5d519ff7b6
4 changed files with 78 additions and 24 deletions

View File

@ -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 @@ usbd_add_dev_event(int type, usbd_device_handle udev)
{
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);
}

View File

@ -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 @@ 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->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 @@ usbd_devinfo_vp(usbd_device_handle dev, char *v, size_t vl, char *p,
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 @@ usbd_devinfo(usbd_device_handle dev, int showclass, char *cp, size_t l)
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 @@ usbd_attach_roothub(device_t parent, usbd_device_handle dev)
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 @@ usbd_new_device(device_t parent, usbd_bus_handle bus, int depth,
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 @@ usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di,
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 @@ usb_free_device(usbd_device_handle dev)
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);
}

View File

@ -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 @@ struct usbd_device {
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 @@ void usbd_dump_pipe(usbd_pipe_handle pipe);
/* 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 *);

View File

@ -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 @@ xhci_new_device(device_t parent, usbd_bus_handle bus, int depth,
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)) {