xref: /netbsd-src/sys/dev/usb/usb_subr.c (revision 001c68bd94f75ce9270b69227c4199fbf34ee396)
1 /*	$NetBSD: usb_subr.c,v 1.104 2003/06/23 11:02:01 martin Exp $	*/
2 /*	$FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $	*/
3 
4 /*
5  * Copyright (c) 1998 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Lennart Augustsson (lennart@augustsson.net) at
10  * Carlstedt Research & Technology.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  *        This product includes software developed by the NetBSD
23  *        Foundation, Inc. and its contributors.
24  * 4. Neither the name of The NetBSD Foundation nor the names of its
25  *    contributors may be used to endorse or promote products derived
26  *    from this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 #include <sys/cdefs.h>
42 __KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.104 2003/06/23 11:02:01 martin Exp $");
43 
44 #include "opt_usbverbose.h"
45 
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/kernel.h>
49 #include <sys/malloc.h>
50 #if defined(__NetBSD__) || defined(__OpenBSD__)
51 #include <sys/device.h>
52 #include <sys/select.h>
53 #elif defined(__FreeBSD__)
54 #include <sys/module.h>
55 #include <sys/bus.h>
56 #endif
57 #include <sys/proc.h>
58 
59 #include <machine/bus.h>
60 
61 #include <dev/usb/usb.h>
62 
63 #include <dev/usb/usbdi.h>
64 #include <dev/usb/usbdi_util.h>
65 #include <dev/usb/usbdivar.h>
66 #include <dev/usb/usbdevs.h>
67 #include <dev/usb/usb_quirks.h>
68 
69 #if defined(__FreeBSD__)
70 #include <machine/clock.h>
71 #define delay(d)         DELAY(d)
72 #endif
73 
74 #ifdef USB_DEBUG
75 #define DPRINTF(x)	if (usbdebug) logprintf x
76 #define DPRINTFN(n,x)	if (usbdebug>(n)) logprintf x
77 extern int usbdebug;
78 #else
79 #define DPRINTF(x)
80 #define DPRINTFN(n,x)
81 #endif
82 
83 Static usbd_status usbd_set_config(usbd_device_handle, int);
84 Static void usbd_devinfo_vp(usbd_device_handle, char *, char *, int);
85 Static char *usbd_get_string(usbd_device_handle, int, char *);
86 Static int usbd_getnewaddr(usbd_bus_handle bus);
87 #if defined(__NetBSD__)
88 Static int usbd_print(void *aux, const char *pnp);
89 Static int usbd_submatch(device_ptr_t, struct cfdata *cf, void *);
90 #elif defined(__OpenBSD__)
91 Static int usbd_print(void *aux, const char *pnp);
92 Static int usbd_submatch(device_ptr_t, void *, void *);
93 #endif
94 Static void usbd_free_iface_data(usbd_device_handle dev, int ifcno);
95 Static void usbd_kill_pipe(usbd_pipe_handle);
96 Static usbd_status usbd_probe_and_attach(device_ptr_t parent,
97 				 usbd_device_handle dev, int port, int addr);
98 
99 Static u_int32_t usb_cookie_no = 0;
100 
101 #ifdef USBVERBOSE
102 typedef u_int16_t usb_vendor_id_t;
103 typedef u_int16_t usb_product_id_t;
104 
105 /*
106  * Descriptions of of known vendors and devices ("products").
107  */
108 struct usb_knowndev {
109 	usb_vendor_id_t		vendor;
110 	usb_product_id_t	product;
111 	int			flags;
112 	char			*vendorname, *productname;
113 };
114 #define	USB_KNOWNDEV_NOPROD	0x01		/* match on vendor only */
115 
116 #include <dev/usb/usbdevs_data.h>
117 #endif /* USBVERBOSE */
118 
119 Static const char * const usbd_error_strs[] = {
120 	"NORMAL_COMPLETION",
121 	"IN_PROGRESS",
122 	"PENDING_REQUESTS",
123 	"NOT_STARTED",
124 	"INVAL",
125 	"NOMEM",
126 	"CANCELLED",
127 	"BAD_ADDRESS",
128 	"IN_USE",
129 	"NO_ADDR",
130 	"SET_ADDR_FAILED",
131 	"NO_POWER",
132 	"TOO_DEEP",
133 	"IOERROR",
134 	"NOT_CONFIGURED",
135 	"TIMEOUT",
136 	"SHORT_XFER",
137 	"STALLED",
138 	"INTERRUPTED",
139 	"XXX",
140 };
141 
142 const char *
143 usbd_errstr(usbd_status err)
144 {
145 	static char buffer[5];
146 
147 	if (err < USBD_ERROR_MAX) {
148 		return usbd_error_strs[err];
149 	} else {
150 		snprintf(buffer, sizeof buffer, "%d", err);
151 		return buffer;
152 	}
153 }
154 
155 usbd_status
156 usbd_get_string_desc(usbd_device_handle dev, int sindex, int langid,
157 		     usb_string_descriptor_t *sdesc)
158 {
159 	usb_device_request_t req;
160 	usbd_status err;
161 	int actlen;
162 
163 	req.bmRequestType = UT_READ_DEVICE;
164 	req.bRequest = UR_GET_DESCRIPTOR;
165 	USETW2(req.wValue, UDESC_STRING, sindex);
166 	USETW(req.wIndex, langid);
167 	USETW(req.wLength, 2);	/* only size byte first */
168 	err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK,
169 		&actlen, USBD_DEFAULT_TIMEOUT);
170 	if (err)
171 		return (err);
172 
173 	if (actlen < 1)
174 		return (USBD_SHORT_XFER);
175 
176 	USETW(req.wLength, sdesc->bLength);	/* the whole string */
177 	return (usbd_do_request(dev, &req, sdesc));
178 }
179 
180 char *
181 usbd_get_string(usbd_device_handle dev, int si, char *buf)
182 {
183 	int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE;
184 	usb_string_descriptor_t us;
185 	char *s;
186 	int i, n;
187 	u_int16_t c;
188 	usbd_status err;
189 
190 	if (si == 0)
191 		return (0);
192 	if (dev->quirks->uq_flags & UQ_NO_STRINGS)
193 		return (0);
194 	if (dev->langid == USBD_NOLANG) {
195 		/* Set up default language */
196 		err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us);
197 		if (err || us.bLength < 4) {
198 			dev->langid = 0; /* Well, just pick something then */
199 		} else {
200 			/* Pick the first language as the default. */
201 			dev->langid = UGETW(us.bString[0]);
202 		}
203 	}
204 	err = usbd_get_string_desc(dev, si, dev->langid, &us);
205 	if (err)
206 		return (0);
207 	s = buf;
208 	n = us.bLength / 2 - 1;
209 	for (i = 0; i < n; i++) {
210 		c = UGETW(us.bString[i]);
211 		/* Convert from Unicode, handle buggy strings. */
212 		if ((c & 0xff00) == 0)
213 			*s++ = c;
214 		else if ((c & 0x00ff) == 0 && swap)
215 			*s++ = c >> 8;
216 		else
217 			*s++ = '?';
218 	}
219 	*s++ = 0;
220 	return (buf);
221 }
222 
223 static void
224 usbd_trim_spaces(char *p)
225 {
226 	char *q, *e;
227 
228 	if (p == NULL)
229 		return;
230 	q = e = p;
231 	while (*q == ' ')	/* skip leading spaces */
232 		q++;
233 	while ((*p = *q++))	/* copy string */
234 		if (*p++ != ' ') /* remember last non-space */
235 			e = p;
236 	*e = 0;			/* kill trailing spaces */
237 }
238 
239 void
240 usbd_devinfo_vp(usbd_device_handle dev, char *v, char *p, int usedev)
241 {
242 	usb_device_descriptor_t *udd = &dev->ddesc;
243 	char *vendor = 0, *product = 0;
244 #ifdef USBVERBOSE
245 	const struct usb_knowndev *kdp;
246 #endif
247 
248 	if (dev == NULL) {
249 		v[0] = p[0] = '\0';
250 		return;
251 	}
252 
253 	if (usedev) {
254 		vendor = usbd_get_string(dev, udd->iManufacturer, v);
255 		usbd_trim_spaces(vendor);
256 		product = usbd_get_string(dev, udd->iProduct, p);
257 		usbd_trim_spaces(product);
258 	} else {
259 		vendor = NULL;
260 		product = NULL;
261 	}
262 #ifdef USBVERBOSE
263 	if (vendor == NULL || product == NULL) {
264 		for(kdp = usb_knowndevs;
265 		    kdp->vendorname != NULL;
266 		    kdp++) {
267 			if (kdp->vendor == UGETW(udd->idVendor) &&
268 			    (kdp->product == UGETW(udd->idProduct) ||
269 			     (kdp->flags & USB_KNOWNDEV_NOPROD) != 0))
270 				break;
271 		}
272 		if (kdp->vendorname != NULL) {
273 			if (vendor == NULL)
274 			    vendor = kdp->vendorname;
275 			if (product == NULL)
276 			    product = (kdp->flags & USB_KNOWNDEV_NOPROD) == 0 ?
277 				kdp->productname : NULL;
278 		}
279 	}
280 #endif
281 	if (vendor != NULL && *vendor)
282 		strcpy(v, vendor);
283 	else
284 		sprintf(v, "vendor 0x%04x", UGETW(udd->idVendor));
285 	if (product != NULL && *product)
286 		strcpy(p, product);
287 	else
288 		sprintf(p, "product 0x%04x", UGETW(udd->idProduct));
289 }
290 
291 int
292 usbd_printBCD(char *cp, int bcd)
293 {
294 	return (sprintf(cp, "%x.%02x", bcd >> 8, bcd & 0xff));
295 }
296 
297 void
298 usbd_devinfo(usbd_device_handle dev, int showclass, char *cp)
299 {
300 	usb_device_descriptor_t *udd = &dev->ddesc;
301 	char vendor[USB_MAX_STRING_LEN];
302 	char product[USB_MAX_STRING_LEN];
303 	int bcdDevice, bcdUSB;
304 
305 	usbd_devinfo_vp(dev, vendor, product, 1);
306 	cp += sprintf(cp, "%s %s", vendor, product);
307 	if (showclass)
308 		cp += sprintf(cp, ", class %d/%d",
309 			      udd->bDeviceClass, udd->bDeviceSubClass);
310 	bcdUSB = UGETW(udd->bcdUSB);
311 	bcdDevice = UGETW(udd->bcdDevice);
312 	cp += sprintf(cp, ", rev ");
313 	cp += usbd_printBCD(cp, bcdUSB);
314 	*cp++ = '/';
315 	cp += usbd_printBCD(cp, bcdDevice);
316 	cp += sprintf(cp, ", addr %d", dev->address);
317 	*cp = 0;
318 }
319 
320 /* Delay for a certain number of ms */
321 void
322 usb_delay_ms(usbd_bus_handle bus, u_int ms)
323 {
324 	/* Wait at least two clock ticks so we know the time has passed. */
325 	if (bus->use_polling || cold)
326 		delay((ms+1) * 1000);
327 	else
328 		tsleep(&ms, PRIBIO, "usbdly", (ms*hz+999)/1000 + 1);
329 }
330 
331 /* Delay given a device handle. */
332 void
333 usbd_delay_ms(usbd_device_handle dev, u_int ms)
334 {
335 	usb_delay_ms(dev->bus, ms);
336 }
337 
338 usbd_status
339 usbd_reset_port(usbd_device_handle dev, int port, usb_port_status_t *ps)
340 {
341 	usb_device_request_t req;
342 	usbd_status err;
343 	int n;
344 
345 	req.bmRequestType = UT_WRITE_CLASS_OTHER;
346 	req.bRequest = UR_SET_FEATURE;
347 	USETW(req.wValue, UHF_PORT_RESET);
348 	USETW(req.wIndex, port);
349 	USETW(req.wLength, 0);
350 	err = usbd_do_request(dev, &req, 0);
351 	DPRINTFN(1,("usbd_reset_port: port %d reset done, error=%s\n",
352 		    port, usbd_errstr(err)));
353 	if (err)
354 		return (err);
355 	n = 10;
356 	do {
357 		/* Wait for device to recover from reset. */
358 		usbd_delay_ms(dev, USB_PORT_RESET_DELAY);
359 		err = usbd_get_port_status(dev, port, ps);
360 		if (err) {
361 			DPRINTF(("usbd_reset_port: get status failed %d\n",
362 				 err));
363 			return (err);
364 		}
365 		/* If the device disappeared, just give up. */
366 		if (!(UGETW(ps->wPortStatus) & UPS_CURRENT_CONNECT_STATUS))
367 			return (USBD_NORMAL_COMPLETION);
368 	} while ((UGETW(ps->wPortChange) & UPS_C_PORT_RESET) == 0 && --n > 0);
369 	if (n == 0)
370 		return (USBD_TIMEOUT);
371 	err = usbd_clear_port_feature(dev, port, UHF_C_PORT_RESET);
372 #ifdef USB_DEBUG
373 	if (err)
374 		DPRINTF(("usbd_reset_port: clear port feature failed %d\n",
375 			 err));
376 #endif
377 
378 	/* Wait for the device to recover from reset. */
379 	usbd_delay_ms(dev, USB_PORT_RESET_RECOVERY);
380 	return (err);
381 }
382 
383 usb_interface_descriptor_t *
384 usbd_find_idesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx)
385 {
386 	char *p = (char *)cd;
387 	char *end = p + UGETW(cd->wTotalLength);
388 	usb_interface_descriptor_t *d;
389 	int curidx, lastidx, curaidx = 0;
390 
391 	for (curidx = lastidx = -1; p < end; ) {
392 		d = (usb_interface_descriptor_t *)p;
393 		DPRINTFN(4,("usbd_find_idesc: idx=%d(%d) altidx=%d(%d) len=%d "
394 			    "type=%d\n",
395 			    ifaceidx, curidx, altidx, curaidx,
396 			    d->bLength, d->bDescriptorType));
397 		if (d->bLength == 0) /* bad descriptor */
398 			break;
399 		p += d->bLength;
400 		if (p <= end && d->bDescriptorType == UDESC_INTERFACE) {
401 			if (d->bInterfaceNumber != lastidx) {
402 				lastidx = d->bInterfaceNumber;
403 				curidx++;
404 				curaidx = 0;
405 			} else
406 				curaidx++;
407 			if (ifaceidx == curidx && altidx == curaidx)
408 				return (d);
409 		}
410 	}
411 	return (NULL);
412 }
413 
414 usb_endpoint_descriptor_t *
415 usbd_find_edesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx,
416 		int endptidx)
417 {
418 	char *p = (char *)cd;
419 	char *end = p + UGETW(cd->wTotalLength);
420 	usb_interface_descriptor_t *d;
421 	usb_endpoint_descriptor_t *e;
422 	int curidx;
423 
424 	d = usbd_find_idesc(cd, ifaceidx, altidx);
425 	if (d == NULL)
426 		return (NULL);
427 	if (endptidx >= d->bNumEndpoints) /* quick exit */
428 		return (NULL);
429 
430 	curidx = -1;
431 	for (p = (char *)d + d->bLength; p < end; ) {
432 		e = (usb_endpoint_descriptor_t *)p;
433 		if (e->bLength == 0) /* bad descriptor */
434 			break;
435 		p += e->bLength;
436 		if (p <= end && e->bDescriptorType == UDESC_INTERFACE)
437 			return (NULL);
438 		if (p <= end && e->bDescriptorType == UDESC_ENDPOINT) {
439 			curidx++;
440 			if (curidx == endptidx)
441 				return (e);
442 		}
443 	}
444 	return (NULL);
445 }
446 
447 usbd_status
448 usbd_fill_iface_data(usbd_device_handle dev, int ifaceidx, int altidx)
449 {
450 	usbd_interface_handle ifc = &dev->ifaces[ifaceidx];
451 	usb_interface_descriptor_t *idesc;
452 	char *p, *end;
453 	int endpt, nendpt;
454 
455 	DPRINTFN(4,("usbd_fill_iface_data: ifaceidx=%d altidx=%d\n",
456 		    ifaceidx, altidx));
457 	idesc = usbd_find_idesc(dev->cdesc, ifaceidx, altidx);
458 	if (idesc == NULL)
459 		return (USBD_INVAL);
460 	ifc->device = dev;
461 	ifc->idesc = idesc;
462 	ifc->index = ifaceidx;
463 	ifc->altindex = altidx;
464 	nendpt = ifc->idesc->bNumEndpoints;
465 	DPRINTFN(4,("usbd_fill_iface_data: found idesc nendpt=%d\n", nendpt));
466 	if (nendpt != 0) {
467 		ifc->endpoints = malloc(nendpt * sizeof(struct usbd_endpoint),
468 					M_USB, M_NOWAIT);
469 		if (ifc->endpoints == NULL)
470 			return (USBD_NOMEM);
471 	} else
472 		ifc->endpoints = NULL;
473 	ifc->priv = NULL;
474 	p = (char *)ifc->idesc + ifc->idesc->bLength;
475 	end = (char *)dev->cdesc + UGETW(dev->cdesc->wTotalLength);
476 #define ed ((usb_endpoint_descriptor_t *)p)
477 	for (endpt = 0; endpt < nendpt; endpt++) {
478 		DPRINTFN(10,("usbd_fill_iface_data: endpt=%d\n", endpt));
479 		for (; p < end; p += ed->bLength) {
480 			DPRINTFN(10,("usbd_fill_iface_data: p=%p end=%p "
481 				     "len=%d type=%d\n",
482 				 p, end, ed->bLength, ed->bDescriptorType));
483 			if (p + ed->bLength <= end && ed->bLength != 0 &&
484 			    ed->bDescriptorType == UDESC_ENDPOINT)
485 				goto found;
486 			if (ed->bLength == 0 ||
487 			    ed->bDescriptorType == UDESC_INTERFACE)
488 				break;
489 		}
490 		/* passed end, or bad desc */
491 		printf("usbd_fill_iface_data: bad descriptor(s): %s\n",
492 		       ed->bLength == 0 ? "0 length" :
493 		       ed->bDescriptorType == UDESC_INTERFACE ? "iface desc":
494 		       "out of data");
495 		goto bad;
496 	found:
497 		ifc->endpoints[endpt].edesc = ed;
498 		if (dev->speed == USB_SPEED_HIGH) {
499 			u_int mps;
500 			/* Control and bulk endpoints have max packet limits. */
501 			switch (UE_GET_XFERTYPE(ed->bmAttributes)) {
502 			case UE_CONTROL:
503 				mps = USB_2_MAX_CTRL_PACKET;
504 				goto check;
505 			case UE_BULK:
506 				mps = USB_2_MAX_BULK_PACKET;
507 			check:
508 				if (UGETW(ed->wMaxPacketSize) != mps) {
509 					USETW(ed->wMaxPacketSize, mps);
510 #ifdef DIAGNOSTIC
511 					printf("usbd_fill_iface_data: bad max "
512 					       "packet size\n");
513 #endif
514 				}
515 				break;
516 			default:
517 				break;
518 			}
519 		}
520 		ifc->endpoints[endpt].refcnt = 0;
521 		p += ed->bLength;
522 	}
523 #undef ed
524 	LIST_INIT(&ifc->pipes);
525 	return (USBD_NORMAL_COMPLETION);
526 
527  bad:
528 	if (ifc->endpoints != NULL) {
529 		free(ifc->endpoints, M_USB);
530 		ifc->endpoints = NULL;
531 	}
532 	return (USBD_INVAL);
533 }
534 
535 void
536 usbd_free_iface_data(usbd_device_handle dev, int ifcno)
537 {
538 	usbd_interface_handle ifc = &dev->ifaces[ifcno];
539 	if (ifc->endpoints)
540 		free(ifc->endpoints, M_USB);
541 }
542 
543 Static usbd_status
544 usbd_set_config(usbd_device_handle dev, int conf)
545 {
546 	usb_device_request_t req;
547 
548 	req.bmRequestType = UT_WRITE_DEVICE;
549 	req.bRequest = UR_SET_CONFIG;
550 	USETW(req.wValue, conf);
551 	USETW(req.wIndex, 0);
552 	USETW(req.wLength, 0);
553 	return (usbd_do_request(dev, &req, 0));
554 }
555 
556 usbd_status
557 usbd_set_config_no(usbd_device_handle dev, int no, int msg)
558 {
559 	int index;
560 	usb_config_descriptor_t cd;
561 	usbd_status err;
562 
563 	if (no == USB_UNCONFIG_NO)
564 		return (usbd_set_config_index(dev, USB_UNCONFIG_INDEX, msg));
565 
566 	DPRINTFN(5,("usbd_set_config_no: %d\n", no));
567 	/* Figure out what config index to use. */
568 	for (index = 0; index < dev->ddesc.bNumConfigurations; index++) {
569 		err = usbd_get_config_desc(dev, index, &cd);
570 		if (err)
571 			return (err);
572 		if (cd.bConfigurationValue == no)
573 			return (usbd_set_config_index(dev, index, msg));
574 	}
575 	return (USBD_INVAL);
576 }
577 
578 usbd_status
579 usbd_set_config_index(usbd_device_handle dev, int index, int msg)
580 {
581 	usb_status_t ds;
582 	usb_config_descriptor_t cd, *cdp;
583 	usbd_status err;
584 	int i, ifcidx, nifc, len, selfpowered, power;
585 
586 	DPRINTFN(5,("usbd_set_config_index: dev=%p index=%d\n", dev, index));
587 
588 	/* XXX check that all interfaces are idle */
589 	if (dev->config != USB_UNCONFIG_NO) {
590 		DPRINTF(("usbd_set_config_index: free old config\n"));
591 		/* Free all configuration data structures. */
592 		nifc = dev->cdesc->bNumInterface;
593 		for (ifcidx = 0; ifcidx < nifc; ifcidx++)
594 			usbd_free_iface_data(dev, ifcidx);
595 		free(dev->ifaces, M_USB);
596 		free(dev->cdesc, M_USB);
597 		dev->ifaces = NULL;
598 		dev->cdesc = NULL;
599 		dev->config = USB_UNCONFIG_NO;
600 	}
601 
602 	if (index == USB_UNCONFIG_INDEX) {
603 		/* We are unconfiguring the device, so leave unallocated. */
604 		DPRINTF(("usbd_set_config_index: set config 0\n"));
605 		err = usbd_set_config(dev, USB_UNCONFIG_NO);
606 		if (err)
607 			DPRINTF(("usbd_set_config_index: setting config=0 "
608 				 "failed, error=%s\n", usbd_errstr(err)));
609 		return (err);
610 	}
611 
612 	/* Get the short descriptor. */
613 	err = usbd_get_config_desc(dev, index, &cd);
614 	if (err)
615 		return (err);
616 	len = UGETW(cd.wTotalLength);
617 	cdp = malloc(len, M_USB, M_NOWAIT);
618 	if (cdp == NULL)
619 		return (USBD_NOMEM);
620 
621 	/* Get the full descriptor.  Try a few times for slow devices. */
622 	for (i = 0; i < 3; i++) {
623 		err = usbd_get_desc(dev, UDESC_CONFIG, index, len, cdp);
624 		if (!err)
625 			break;
626 		usbd_delay_ms(dev, 200);
627 	}
628 	if (err)
629 		goto bad;
630 
631 	if (cdp->bDescriptorType != UDESC_CONFIG) {
632 		DPRINTFN(-1,("usbd_set_config_index: bad desc %d\n",
633 			     cdp->bDescriptorType));
634 		err = USBD_INVAL;
635 		goto bad;
636 	}
637 
638 	/* Figure out if the device is self or bus powered. */
639 	selfpowered = 0;
640 	if (!(dev->quirks->uq_flags & UQ_BUS_POWERED) &&
641 	    (cdp->bmAttributes & UC_SELF_POWERED)) {
642 		/* May be self powered. */
643 		if (cdp->bmAttributes & UC_BUS_POWERED) {
644 			/* Must ask device. */
645 			if (dev->quirks->uq_flags & UQ_POWER_CLAIM) {
646 				/*
647 				 * Hub claims to be self powered, but isn't.
648 				 * It seems that the power status can be
649 				 * determined by the hub characteristics.
650 				 */
651 				usb_hub_descriptor_t hd;
652 				usb_device_request_t req;
653 				req.bmRequestType = UT_READ_CLASS_DEVICE;
654 				req.bRequest = UR_GET_DESCRIPTOR;
655 				USETW(req.wValue, 0);
656 				USETW(req.wIndex, 0);
657 				USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE);
658 				err = usbd_do_request(dev, &req, &hd);
659 				if (!err &&
660 				    (UGETW(hd.wHubCharacteristics) &
661 				     UHD_PWR_INDIVIDUAL))
662 					selfpowered = 1;
663 				DPRINTF(("usbd_set_config_index: charac=0x%04x"
664 				    ", error=%s\n",
665 				    UGETW(hd.wHubCharacteristics),
666 				    usbd_errstr(err)));
667 			} else {
668 				err = usbd_get_device_status(dev, &ds);
669 				if (!err &&
670 				    (UGETW(ds.wStatus) & UDS_SELF_POWERED))
671 					selfpowered = 1;
672 				DPRINTF(("usbd_set_config_index: status=0x%04x"
673 				    ", error=%s\n",
674 				    UGETW(ds.wStatus), usbd_errstr(err)));
675 			}
676 		} else
677 			selfpowered = 1;
678 	}
679 	DPRINTF(("usbd_set_config_index: (addr %d) cno=%d attr=0x%02x, "
680 		 "selfpowered=%d, power=%d\n",
681 		 cdp->bConfigurationValue, dev->address, cdp->bmAttributes,
682 		 selfpowered, cdp->bMaxPower * 2));
683 
684 	/* Check if we have enough power. */
685 #ifdef USB_DEBUG
686 	if (dev->powersrc == NULL) {
687 		DPRINTF(("usbd_set_config_index: No power source?\n"));
688 		return (USBD_IOERROR);
689 	}
690 #endif
691 	power = cdp->bMaxPower * 2;
692 	if (power > dev->powersrc->power) {
693 		DPRINTF(("power exceeded %d %d\n", power,dev->powersrc->power));
694 		/* XXX print nicer message. */
695 		if (msg)
696 			printf("%s: device addr %d (config %d) exceeds power "
697 				 "budget, %d mA > %d mA\n",
698 			       USBDEVNAME(dev->bus->bdev), dev->address,
699 			       cdp->bConfigurationValue,
700 			       power, dev->powersrc->power);
701 		err = USBD_NO_POWER;
702 		goto bad;
703 	}
704 	dev->power = power;
705 	dev->self_powered = selfpowered;
706 
707 	/* Set the actual configuration value. */
708 	DPRINTF(("usbd_set_config_index: set config %d\n",
709 		 cdp->bConfigurationValue));
710 	err = usbd_set_config(dev, cdp->bConfigurationValue);
711 	if (err) {
712 		DPRINTF(("usbd_set_config_index: setting config=%d failed, "
713 			 "error=%s\n",
714 			 cdp->bConfigurationValue, usbd_errstr(err)));
715 		goto bad;
716 	}
717 
718 	/* Allocate and fill interface data. */
719 	nifc = cdp->bNumInterface;
720 	dev->ifaces = malloc(nifc * sizeof(struct usbd_interface),
721 			     M_USB, M_NOWAIT);
722 	if (dev->ifaces == NULL) {
723 		err = USBD_NOMEM;
724 		goto bad;
725 	}
726 	DPRINTFN(5,("usbd_set_config_index: dev=%p cdesc=%p\n", dev, cdp));
727 	dev->cdesc = cdp;
728 	dev->config = cdp->bConfigurationValue;
729 	for (ifcidx = 0; ifcidx < nifc; ifcidx++) {
730 		err = usbd_fill_iface_data(dev, ifcidx, 0);
731 		if (err) {
732 			while (--ifcidx >= 0)
733 				usbd_free_iface_data(dev, ifcidx);
734 			goto bad;
735 		}
736 	}
737 
738 	return (USBD_NORMAL_COMPLETION);
739 
740  bad:
741 	free(cdp, M_USB);
742 	return (err);
743 }
744 
745 /* XXX add function for alternate settings */
746 
747 usbd_status
748 usbd_setup_pipe(usbd_device_handle dev, usbd_interface_handle iface,
749 		struct usbd_endpoint *ep, int ival, usbd_pipe_handle *pipe)
750 {
751 	usbd_pipe_handle p;
752 	usbd_status err;
753 
754 	DPRINTFN(1,("usbd_setup_pipe: dev=%p iface=%p ep=%p pipe=%p\n",
755 		    dev, iface, ep, pipe));
756 	p = malloc(dev->bus->pipe_size, M_USB, M_NOWAIT);
757 	if (p == NULL)
758 		return (USBD_NOMEM);
759 	p->device = dev;
760 	p->iface = iface;
761 	p->endpoint = ep;
762 	ep->refcnt++;
763 	p->refcnt = 1;
764 	p->intrxfer = 0;
765 	p->running = 0;
766 	p->aborting = 0;
767 	p->repeat = 0;
768 	p->interval = ival;
769 	SIMPLEQ_INIT(&p->queue);
770 	err = dev->bus->methods->open_pipe(p);
771 	if (err) {
772 		DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error="
773 			 "%s\n",
774 			 ep->edesc->bEndpointAddress, usbd_errstr(err)));
775 		free(p, M_USB);
776 		return (err);
777 	}
778 	/* Clear any stall and make sure DATA0 toggle will be used next. */
779 	if (UE_GET_ADDR(ep->edesc->bEndpointAddress) != USB_CONTROL_ENDPOINT)
780 		usbd_clear_endpoint_stall(p);
781 	*pipe = p;
782 	return (USBD_NORMAL_COMPLETION);
783 }
784 
785 /* Abort the device control pipe. */
786 void
787 usbd_kill_pipe(usbd_pipe_handle pipe)
788 {
789 	usbd_abort_pipe(pipe);
790 	pipe->methods->close(pipe);
791 	pipe->endpoint->refcnt--;
792 	free(pipe, M_USB);
793 }
794 
795 int
796 usbd_getnewaddr(usbd_bus_handle bus)
797 {
798 	int addr;
799 
800 	for (addr = 1; addr < USB_MAX_DEVICES; addr++)
801 		if (bus->devices[addr] == 0)
802 			return (addr);
803 	return (-1);
804 }
805 
806 
807 usbd_status
808 usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev,
809 		      int port, int addr)
810 {
811 	struct usb_attach_arg uaa;
812 	usb_device_descriptor_t *dd = &dev->ddesc;
813 	int found, i, confi, nifaces;
814 	usbd_status err;
815 	device_ptr_t dv;
816 	usbd_interface_handle ifaces[256]; /* 256 is the absolute max */
817 
818 #if defined(__FreeBSD__)
819 	/*
820 	 * XXX uaa is a static var. Not a problem as it _should_ be used only
821 	 * during probe and attach. Should be changed however.
822 	 */
823 	device_t bdev;
824 	bdev = device_add_child(parent, NULL, -1, &uaa);
825 	if (!bdev) {
826 	    printf("%s: Device creation failed\n", USBDEVNAME(dev->bus->bdev));
827 	    return (USBD_INVAL);
828 	}
829 	device_quiet(bdev);
830 #endif
831 
832 	uaa.device = dev;
833 	uaa.iface = NULL;
834 	uaa.ifaces = NULL;
835 	uaa.nifaces = 0;
836 	uaa.usegeneric = 0;
837 	uaa.port = port;
838 	uaa.configno = UHUB_UNK_CONFIGURATION;
839 	uaa.ifaceno = UHUB_UNK_INTERFACE;
840 	uaa.vendor = UGETW(dd->idVendor);
841 	uaa.product = UGETW(dd->idProduct);
842 	uaa.release = UGETW(dd->bcdDevice);
843 
844 	/* First try with device specific drivers. */
845 	DPRINTF(("usbd_probe_and_attach: trying device specific drivers\n"));
846 	dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch);
847 	if (dv) {
848 		dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT);
849 		if (dev->subdevs == NULL)
850 			return (USBD_NOMEM);
851 		dev->subdevs[0] = dv;
852 		dev->subdevs[1] = 0;
853 		return (USBD_NORMAL_COMPLETION);
854 	}
855 
856 	DPRINTF(("usbd_probe_and_attach: no device specific driver found\n"));
857 
858 	DPRINTF(("usbd_probe_and_attach: looping over %d configurations\n",
859 		 dd->bNumConfigurations));
860 	/* Next try with interface drivers. */
861 	for (confi = 0; confi < dd->bNumConfigurations; confi++) {
862 		DPRINTFN(1,("usbd_probe_and_attach: trying config idx=%d\n",
863 			    confi));
864 		err = usbd_set_config_index(dev, confi, 1);
865 		if (err) {
866 #ifdef USB_DEBUG
867 			DPRINTF(("%s: port %d, set config at addr %d failed, "
868 				 "error=%s\n", USBDEVPTRNAME(parent), port,
869 				 addr, usbd_errstr(err)));
870 #else
871 			printf("%s: port %d, set config at addr %d failed\n",
872 			       USBDEVPTRNAME(parent), port, addr);
873 #endif
874 #if defined(__FreeBSD__)
875 			device_delete_child(parent, bdev);
876 #endif
877 
878  			return (err);
879 		}
880 		nifaces = dev->cdesc->bNumInterface;
881 		uaa.configno = dev->cdesc->bConfigurationValue;
882 		for (i = 0; i < nifaces; i++)
883 			ifaces[i] = &dev->ifaces[i];
884 		uaa.ifaces = ifaces;
885 		uaa.nifaces = nifaces;
886 		dev->subdevs = malloc((nifaces+1) * sizeof dv, M_USB,M_NOWAIT);
887 		if (dev->subdevs == NULL) {
888 #if defined(__FreeBSD__)
889 			device_delete_child(parent, bdev);
890 #endif
891 			return (USBD_NOMEM);
892 		}
893 
894 		found = 0;
895 		for (i = 0; i < nifaces; i++) {
896 			if (ifaces[i] == NULL)
897 				continue; /* interface already claimed */
898 			uaa.iface = ifaces[i];
899 			uaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber;
900 			dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print,
901 					   usbd_submatch);
902 			if (dv != NULL) {
903 				dev->subdevs[found++] = dv;
904 				dev->subdevs[found] = 0;
905 				ifaces[i] = 0; /* consumed */
906 
907 #if defined(__FreeBSD__)
908 				/* create another child for the next iface */
909 				bdev = device_add_child(parent, NULL, -1,&uaa);
910 				if (!bdev) {
911 					printf("%s: Device creation failed\n",
912 					USBDEVNAME(dev->bus->bdev));
913 					return (USBD_NORMAL_COMPLETION);
914 				}
915 				device_quiet(bdev);
916 #endif
917 			}
918 		}
919 		if (found != 0) {
920 #if defined(__FreeBSD__)
921 			/* remove the last created child again; it is unused */
922 			device_delete_child(parent, bdev);
923 #endif
924 			return (USBD_NORMAL_COMPLETION);
925 		}
926 		free(dev->subdevs, M_USB);
927 		dev->subdevs = 0;
928 	}
929 	/* No interfaces were attached in any of the configurations. */
930 
931 	if (dd->bNumConfigurations > 1) /* don't change if only 1 config */
932 		usbd_set_config_index(dev, 0, 0);
933 
934 	DPRINTF(("usbd_probe_and_attach: no interface drivers found\n"));
935 
936 	/* Finally try the generic driver. */
937 	uaa.iface = NULL;
938 	uaa.usegeneric = 1;
939 	uaa.configno = UHUB_UNK_CONFIGURATION;
940 	uaa.ifaceno = UHUB_UNK_INTERFACE;
941 	dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch);
942 	if (dv != NULL) {
943 		dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT);
944 		if (dev->subdevs == 0)
945 			return (USBD_NOMEM);
946 		dev->subdevs[0] = dv;
947 		dev->subdevs[1] = 0;
948 		return (USBD_NORMAL_COMPLETION);
949 	}
950 
951 	/*
952 	 * The generic attach failed, but leave the device as it is.
953 	 * We just did not find any drivers, that's all.  The device is
954 	 * fully operational and not harming anyone.
955 	 */
956 	DPRINTF(("usbd_probe_and_attach: generic attach failed\n"));
957 #if defined(__FreeBSD__)
958 	device_delete_child(parent, bdev);
959 #endif
960  	return (USBD_NORMAL_COMPLETION);
961 }
962 
963 
964 /*
965  * Called when a new device has been put in the powered state,
966  * but not yet in the addressed state.
967  * Get initial descriptor, set the address, get full descriptor,
968  * and attach a driver.
969  */
970 usbd_status
971 usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
972 		int speed, int port, struct usbd_port *up)
973 {
974 	usbd_device_handle dev;
975 	struct usbd_device *hub;
976 	usb_device_descriptor_t *dd;
977 	usbd_status err;
978 	int addr;
979 	int i;
980 
981 	DPRINTF(("usbd_new_device bus=%p port=%d depth=%d speed=%d\n",
982 		 bus, port, depth, speed));
983 	addr = usbd_getnewaddr(bus);
984 	if (addr < 0) {
985 		printf("%s: No free USB addresses, new device ignored.\n",
986 		       USBDEVNAME(bus->bdev));
987 		return (USBD_NO_ADDR);
988 	}
989 
990 	dev = malloc(sizeof *dev, M_USB, M_NOWAIT|M_ZERO);
991 	if (dev == NULL)
992 		return (USBD_NOMEM);
993 
994 	dev->bus = bus;
995 
996 	/* Set up default endpoint handle. */
997 	dev->def_ep.edesc = &dev->def_ep_desc;
998 
999 	/* Set up default endpoint descriptor. */
1000 	dev->def_ep_desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE;
1001 	dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT;
1002 	dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT;
1003 	dev->def_ep_desc.bmAttributes = UE_CONTROL;
1004 	USETW(dev->def_ep_desc.wMaxPacketSize, USB_MAX_IPACKET);
1005 	dev->def_ep_desc.bInterval = 0;
1006 
1007 	dev->quirks = &usbd_no_quirk;
1008 	dev->address = USB_START_ADDR;
1009 	dev->ddesc.bMaxPacketSize = 0;
1010 	dev->depth = depth;
1011 	dev->powersrc = up;
1012 	dev->myhub = up->parent;
1013 	for (hub = up->parent;
1014 	     hub != NULL && hub->speed != USB_SPEED_HIGH;
1015 	     hub = hub->myhub)
1016 		;
1017 	dev->myhighhub = hub;
1018 	dev->speed = speed;
1019 	dev->langid = USBD_NOLANG;
1020 	dev->cookie.cookie = ++usb_cookie_no;
1021 
1022 	/* Establish the default pipe. */
1023 	err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL,
1024 			      &dev->default_pipe);
1025 	if (err) {
1026 		usbd_remove_device(dev, up);
1027 		return (err);
1028 	}
1029 
1030 	up->device = dev;
1031 	dd = &dev->ddesc;
1032 	/* Try a few times in case the device is slow (i.e. outside specs.) */
1033 	for (i = 0; i < 3; i++) {
1034 		/* Get the first 8 bytes of the device descriptor. */
1035 		err = usbd_get_desc(dev, UDESC_DEVICE, 0, USB_MAX_IPACKET, dd);
1036 		if (!err)
1037 			break;
1038 		usbd_delay_ms(dev, 200);
1039 	}
1040 	if (err) {
1041 		DPRINTFN(-1, ("usbd_new_device: addr=%d, getting first desc "
1042 			      "failed\n", addr));
1043 		usbd_remove_device(dev, up);
1044 		return (err);
1045 	}
1046 
1047 	if (speed == USB_SPEED_HIGH) {
1048 		/* Max packet size must be 64 (sec 5.5.3). */
1049 		if (dd->bMaxPacketSize != USB_2_MAX_CTRL_PACKET) {
1050 #ifdef DIAGNOSTIC
1051 			printf("usbd_new_device: addr=%d bad max packet size\n",
1052 			       addr);
1053 #endif
1054 			dd->bMaxPacketSize = USB_2_MAX_CTRL_PACKET;
1055 		}
1056 	}
1057 
1058 	DPRINTF(("usbd_new_device: adding unit addr=%d, rev=%02x, class=%d, "
1059 		 "subclass=%d, protocol=%d, maxpacket=%d, len=%d, speed=%d\n",
1060 		 addr,UGETW(dd->bcdUSB), dd->bDeviceClass, dd->bDeviceSubClass,
1061 		 dd->bDeviceProtocol, dd->bMaxPacketSize, dd->bLength,
1062 		 dev->speed));
1063 
1064 	if (dd->bDescriptorType != UDESC_DEVICE) {
1065 		/* Illegal device descriptor */
1066 		DPRINTFN(-1,("usbd_new_device: illegal descriptor %d\n",
1067 			     dd->bDescriptorType));
1068 		usbd_remove_device(dev, up);
1069 		return (USBD_INVAL);
1070 	}
1071 
1072 	if (dd->bLength < USB_DEVICE_DESCRIPTOR_SIZE) {
1073 		DPRINTFN(-1,("usbd_new_device: bad length %d\n", dd->bLength));
1074 		usbd_remove_device(dev, up);
1075 		return (USBD_INVAL);
1076 	}
1077 
1078 	USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize);
1079 
1080 	err = usbd_reload_device_desc(dev);
1081 	if (err) {
1082 		DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc "
1083 			      "failed\n", addr));
1084 		usbd_remove_device(dev, up);
1085 		return (err);
1086 	}
1087 
1088 	/* Set the address */
1089 	err = usbd_set_address(dev, addr);
1090 	DPRINTFN(5,("usbd_new_device: setting device address=%d\n", addr));
1091 	if (err) {
1092 		DPRINTFN(-1,("usb_new_device: set address %d failed\n", addr));
1093 		err = USBD_SET_ADDR_FAILED;
1094 		usbd_remove_device(dev, up);
1095 		return (err);
1096 	}
1097 	/* Allow device time to set new address */
1098 	usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE);
1099 
1100 	dev->address = addr;	/* New device address now */
1101 	bus->devices[addr] = dev;
1102 
1103 	/* Assume 100mA bus powered for now. Changed when configured. */
1104 	dev->power = USB_MIN_POWER;
1105 	dev->self_powered = 0;
1106 
1107 	DPRINTF(("usbd_new_device: new dev (addr %d), dev=%p, parent=%p\n",
1108 		 addr, dev, parent));
1109 
1110 	usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev);
1111 
1112 	err = usbd_probe_and_attach(parent, dev, port, addr);
1113 	if (err) {
1114 		usbd_remove_device(dev, up);
1115 		return (err);
1116   	}
1117 
1118   	return (USBD_NORMAL_COMPLETION);
1119 }
1120 
1121 usbd_status
1122 usbd_reload_device_desc(usbd_device_handle dev)
1123 {
1124 	usbd_status err;
1125 
1126 	/* Get the full device descriptor. */
1127 	err = usbd_get_device_desc(dev, &dev->ddesc);
1128 	if (err)
1129 		return (err);
1130 
1131 	/* Figure out what's wrong with this device. */
1132 	dev->quirks = usbd_find_quirk(&dev->ddesc);
1133 
1134 	return (USBD_NORMAL_COMPLETION);
1135 }
1136 
1137 void
1138 usbd_remove_device(usbd_device_handle dev, struct usbd_port *up)
1139 {
1140 	DPRINTF(("usbd_remove_device: %p\n", dev));
1141 
1142 	if (dev->default_pipe != NULL)
1143 		usbd_kill_pipe(dev->default_pipe);
1144 	up->device = 0;
1145 	dev->bus->devices[dev->address] = 0;
1146 
1147 	free(dev, M_USB);
1148 }
1149 
1150 #if defined(__NetBSD__) || defined(__OpenBSD__)
1151 int
1152 usbd_print(void *aux, const char *pnp)
1153 {
1154 	struct usb_attach_arg *uaa = aux;
1155 	char devinfo[1024];
1156 
1157 	DPRINTFN(15, ("usbd_print dev=%p\n", uaa->device));
1158 	if (pnp) {
1159 		if (!uaa->usegeneric)
1160 			return (QUIET);
1161 		usbd_devinfo(uaa->device, 1, devinfo);
1162 		aprint_normal("%s, %s", devinfo, pnp);
1163 	}
1164 	if (uaa->port != 0)
1165 		aprint_normal(" port %d", uaa->port);
1166 	if (uaa->configno != UHUB_UNK_CONFIGURATION)
1167 		aprint_normal(" configuration %d", uaa->configno);
1168 	if (uaa->ifaceno != UHUB_UNK_INTERFACE)
1169 		aprint_normal(" interface %d", uaa->ifaceno);
1170 #if 0
1171 	/*
1172 	 * It gets very crowded with these locators on the attach line.
1173 	 * They are not really needed since they are printed in the clear
1174 	 * by each driver.
1175 	 */
1176 	if (uaa->vendor != UHUB_UNK_VENDOR)
1177 		aprint_normal(" vendor 0x%04x", uaa->vendor);
1178 	if (uaa->product != UHUB_UNK_PRODUCT)
1179 		aprint_normal(" product 0x%04x", uaa->product);
1180 	if (uaa->release != UHUB_UNK_RELEASE)
1181 		aprint_normal(" release 0x%04x", uaa->release);
1182 #endif
1183 	return (UNCONF);
1184 }
1185 
1186 #if defined(__NetBSD__)
1187 int
1188 usbd_submatch(struct device *parent, struct cfdata *cf, void *aux)
1189 {
1190 #elif defined(__OpenBSD__)
1191 int
1192 usbd_submatch(struct device *parent, void *match, void *aux)
1193 {
1194 	struct cfdata *cf = match;
1195 #endif
1196 	struct usb_attach_arg *uaa = aux;
1197 
1198 	DPRINTFN(5,("usbd_submatch port=%d,%d configno=%d,%d "
1199 	    "ifaceno=%d,%d vendor=%d,%d product=%d,%d release=%d,%d\n",
1200 	    uaa->port, cf->uhubcf_port,
1201 	    uaa->configno, cf->uhubcf_configuration,
1202 	    uaa->ifaceno, cf->uhubcf_interface,
1203 	    uaa->vendor, cf->uhubcf_vendor,
1204 	    uaa->product, cf->uhubcf_product,
1205 	    uaa->release, cf->uhubcf_release));
1206 	if (uaa->port != 0 &&	/* root hub has port 0, it should match */
1207 	    ((uaa->port != 0 &&
1208 	      cf->uhubcf_port != UHUB_UNK_PORT &&
1209 	      cf->uhubcf_port != uaa->port) ||
1210 	     (uaa->configno != UHUB_UNK_CONFIGURATION &&
1211 	      cf->uhubcf_configuration != UHUB_UNK_CONFIGURATION &&
1212 	      cf->uhubcf_configuration != uaa->configno) ||
1213 	     (uaa->ifaceno != UHUB_UNK_INTERFACE &&
1214 	      cf->uhubcf_interface != UHUB_UNK_INTERFACE &&
1215 	      cf->uhubcf_interface != uaa->ifaceno) ||
1216 	     (uaa->vendor != UHUB_UNK_VENDOR &&
1217 	      cf->uhubcf_vendor != UHUB_UNK_VENDOR &&
1218 	      cf->uhubcf_vendor != uaa->vendor) ||
1219 	     (uaa->product != UHUB_UNK_PRODUCT &&
1220 	      cf->uhubcf_product != UHUB_UNK_PRODUCT &&
1221 	      cf->uhubcf_product != uaa->product) ||
1222 	     (uaa->release != UHUB_UNK_RELEASE &&
1223 	      cf->uhubcf_release != UHUB_UNK_RELEASE &&
1224 	      cf->uhubcf_release != uaa->release)
1225 	     )
1226 	   )
1227 		return 0;
1228 	if (cf->uhubcf_vendor != UHUB_UNK_VENDOR &&
1229 	    cf->uhubcf_vendor == uaa->vendor &&
1230 	    cf->uhubcf_product != UHUB_UNK_PRODUCT &&
1231 	    cf->uhubcf_product == uaa->product) {
1232 		/* We have a vendor&product locator match */
1233 		if (cf->uhubcf_release != UHUB_UNK_RELEASE &&
1234 		    cf->uhubcf_release == uaa->release)
1235 			uaa->matchlvl = UMATCH_VENDOR_PRODUCT_REV;
1236 		else
1237 			uaa->matchlvl = UMATCH_VENDOR_PRODUCT;
1238 	} else
1239 		uaa->matchlvl = 0;
1240 	return (config_match(parent, cf, aux));
1241 }
1242 
1243 #endif
1244 
1245 void
1246 usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di,
1247 		     int usedev)
1248 {
1249 	struct usbd_port *p;
1250 	int i, err, s;
1251 
1252 	di->udi_bus = USBDEVUNIT(dev->bus->bdev);
1253 	di->udi_addr = dev->address;
1254 	di->udi_cookie = dev->cookie;
1255 	usbd_devinfo_vp(dev, di->udi_vendor, di->udi_product, usedev);
1256 	usbd_printBCD(di->udi_release, UGETW(dev->ddesc.bcdDevice));
1257 	di->udi_vendorNo = UGETW(dev->ddesc.idVendor);
1258 	di->udi_productNo = UGETW(dev->ddesc.idProduct);
1259 	di->udi_releaseNo = UGETW(dev->ddesc.bcdDevice);
1260 	di->udi_class = dev->ddesc.bDeviceClass;
1261 	di->udi_subclass = dev->ddesc.bDeviceSubClass;
1262 	di->udi_protocol = dev->ddesc.bDeviceProtocol;
1263 	di->udi_config = dev->config;
1264 	di->udi_power = dev->self_powered ? 0 : dev->power;
1265 	di->udi_speed = dev->speed;
1266 
1267 	if (dev->subdevs != NULL) {
1268 		for (i = 0; dev->subdevs[i] &&
1269 			     i < USB_MAX_DEVNAMES; i++) {
1270 			strncpy(di->udi_devnames[i], USBDEVPTRNAME(dev->subdevs[i]),
1271 				USB_MAX_DEVNAMELEN);
1272 			di->udi_devnames[i][USB_MAX_DEVNAMELEN-1] = '\0';
1273                 }
1274         } else {
1275                 i = 0;
1276         }
1277         for (/*i is set */; i < USB_MAX_DEVNAMES; i++)
1278                 di->udi_devnames[i][0] = 0;                 /* empty */
1279 
1280 	if (dev->hub) {
1281 		for (i = 0;
1282 		     i < sizeof(di->udi_ports) / sizeof(di->udi_ports[0]) &&
1283 			     i < dev->hub->hubdesc.bNbrPorts;
1284 		     i++) {
1285 			p = &dev->hub->ports[i];
1286 			if (p->device)
1287 				err = p->device->address;
1288 			else {
1289 				s = UGETW(p->status.wPortStatus);
1290 				if (s & UPS_PORT_ENABLED)
1291 					err = USB_PORT_ENABLED;
1292 				else if (s & UPS_SUSPEND)
1293 					err = USB_PORT_SUSPENDED;
1294 				else if (s & UPS_PORT_POWER)
1295 					err = USB_PORT_POWERED;
1296 				else
1297 					err = USB_PORT_DISABLED;
1298 			}
1299 			di->udi_ports[i] = err;
1300 		}
1301 		di->udi_nports = dev->hub->hubdesc.bNbrPorts;
1302 	} else
1303 		di->udi_nports = 0;
1304 }
1305 
1306 void
1307 usb_free_device(usbd_device_handle dev)
1308 {
1309 	int ifcidx, nifc;
1310 
1311 	if (dev->default_pipe != NULL)
1312 		usbd_kill_pipe(dev->default_pipe);
1313 	if (dev->ifaces != NULL) {
1314 		nifc = dev->cdesc->bNumInterface;
1315 		for (ifcidx = 0; ifcidx < nifc; ifcidx++)
1316 			usbd_free_iface_data(dev, ifcidx);
1317 		free(dev->ifaces, M_USB);
1318 	}
1319 	if (dev->cdesc != NULL)
1320 		free(dev->cdesc, M_USB);
1321 	if (dev->subdevs != NULL)
1322 		free(dev->subdevs, M_USB);
1323 	free(dev, M_USB);
1324 }
1325 
1326 /*
1327  * The general mechanism for detaching drivers works as follows: Each
1328  * driver is responsible for maintaining a reference count on the
1329  * number of outstanding references to its softc (e.g.  from
1330  * processing hanging in a read or write).  The detach method of the
1331  * driver decrements this counter and flags in the softc that the
1332  * driver is dying and then wakes any sleepers.  It then sleeps on the
1333  * softc.  Each place that can sleep must maintain the reference
1334  * count.  When the reference count drops to -1 (0 is the normal value
1335  * of the reference count) the a wakeup on the softc is performed
1336  * signaling to the detach waiter that all references are gone.
1337  */
1338 
1339 /*
1340  * Called from process context when we discover that a port has
1341  * been disconnected.
1342  */
1343 void
1344 usb_disconnect_port(struct usbd_port *up, device_ptr_t parent)
1345 {
1346 	usbd_device_handle dev = up->device;
1347 	char *hubname = USBDEVPTRNAME(parent);
1348 	int i;
1349 
1350 	DPRINTFN(3,("uhub_disconnect: up=%p dev=%p port=%d\n",
1351 		    up, dev, up->portno));
1352 
1353 #ifdef DIAGNOSTIC
1354 	if (dev == NULL) {
1355 		printf("usb_disconnect_port: no device\n");
1356 		return;
1357 	}
1358 #endif
1359 
1360 	if (dev->subdevs != NULL) {
1361 		DPRINTFN(3,("usb_disconnect_port: disconnect subdevs\n"));
1362 		for (i = 0; dev->subdevs[i]; i++) {
1363 			printf("%s: at %s", USBDEVPTRNAME(dev->subdevs[i]),
1364 			       hubname);
1365 			if (up->portno != 0)
1366 				printf(" port %d", up->portno);
1367 			printf(" (addr %d) disconnected\n", dev->address);
1368 			config_detach(dev->subdevs[i], DETACH_FORCE);
1369 		}
1370 	}
1371 
1372 	usbd_add_dev_event(USB_EVENT_DEVICE_DETACH, dev);
1373 	dev->bus->devices[dev->address] = NULL;
1374 	up->device = NULL;
1375 	usb_free_device(dev);
1376 }
1377 
1378 #ifdef __OpenBSD__
1379 void *usb_realloc(void *p, u_int size, int pool, int flags)
1380 {
1381 	void *q;
1382 
1383 	q = malloc(size, pool, flags);
1384 	if (q == NULL)
1385 		return (NULL);
1386 	bcopy(p, q, size);
1387 	free(p, pool);
1388 	return (q);
1389 }
1390 #endif
1391