]> CyberLeo.Net >> Repos - FreeBSD/stable/8.git/blob - sys/dev/usb/usb_hub.c
MFC r260588 and r260589:
[FreeBSD/stable/8.git] / sys / dev / usb / usb_hub.c
1 /* $FreeBSD$ */
2 /*-
3  * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
4  * Copyright (c) 1998 Lennart Augustsson. All rights reserved.
5  * Copyright (c) 2008-2010 Hans Petter Selasky. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 /*
30  * USB spec: http://www.usb.org/developers/docs/usbspec.zip 
31  */
32
33 #include <sys/stdint.h>
34 #include <sys/stddef.h>
35 #include <sys/param.h>
36 #include <sys/queue.h>
37 #include <sys/types.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
40 #include <sys/bus.h>
41 #include <sys/module.h>
42 #include <sys/lock.h>
43 #include <sys/mutex.h>
44 #include <sys/condvar.h>
45 #include <sys/sysctl.h>
46 #include <sys/sx.h>
47 #include <sys/unistd.h>
48 #include <sys/callout.h>
49 #include <sys/malloc.h>
50 #include <sys/priv.h>
51
52 #include <dev/usb/usb.h>
53 #include <dev/usb/usbdi.h>
54 #include <dev/usb/usbdi_util.h>
55
56 #define USB_DEBUG_VAR uhub_debug
57
58 #include <dev/usb/usb_core.h>
59 #include <dev/usb/usb_process.h>
60 #include <dev/usb/usb_device.h>
61 #include <dev/usb/usb_request.h>
62 #include <dev/usb/usb_debug.h>
63 #include <dev/usb/usb_hub.h>
64 #include <dev/usb/usb_util.h>
65 #include <dev/usb/usb_busdma.h>
66 #include <dev/usb/usb_transfer.h>
67 #include <dev/usb/usb_dynamic.h>
68
69 #include <dev/usb/usb_controller.h>
70 #include <dev/usb/usb_bus.h>
71
72 #define UHUB_INTR_INTERVAL 250          /* ms */
73 enum {
74         UHUB_INTR_TRANSFER,
75 #if USB_HAVE_TT_SUPPORT
76         UHUB_RESET_TT_TRANSFER,
77 #endif
78         UHUB_N_TRANSFER,
79 };
80
81 #ifdef USB_DEBUG
82 static int uhub_debug = 0;
83
84 SYSCTL_NODE(_hw_usb, OID_AUTO, uhub, CTLFLAG_RW, 0, "USB HUB");
85 SYSCTL_INT(_hw_usb_uhub, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_TUN, &uhub_debug, 0,
86     "Debug level");
87 TUNABLE_INT("hw.usb.uhub.debug", &uhub_debug);
88 #endif
89
90 #if USB_HAVE_POWERD
91 static int usb_power_timeout = 30;      /* seconds */
92
93 SYSCTL_INT(_hw_usb, OID_AUTO, power_timeout, CTLFLAG_RW,
94     &usb_power_timeout, 0, "USB power timeout");
95 #endif
96
97 struct uhub_current_state {
98         uint16_t port_change;
99         uint16_t port_status;
100 };
101
102 struct uhub_softc {
103         struct uhub_current_state sc_st;/* current state */
104         device_t sc_dev;                /* base device */
105         struct mtx sc_mtx;              /* our mutex */
106         struct usb_device *sc_udev;     /* USB device */
107         struct usb_xfer *sc_xfer[UHUB_N_TRANSFER];      /* interrupt xfer */
108         uint8_t sc_flags;
109 #define UHUB_FLAG_DID_EXPLORE 0x01
110         char    sc_name[32];
111 };
112
113 #define UHUB_PROTO(sc) ((sc)->sc_udev->ddesc.bDeviceProtocol)
114 #define UHUB_IS_HIGH_SPEED(sc) (UHUB_PROTO(sc) != UDPROTO_FSHUB)
115 #define UHUB_IS_SINGLE_TT(sc) (UHUB_PROTO(sc) == UDPROTO_HSHUBSTT)
116 #define UHUB_IS_MULTI_TT(sc) (UHUB_PROTO(sc) == UDPROTO_HSHUBMTT)
117 #define UHUB_IS_SUPER_SPEED(sc) (UHUB_PROTO(sc) == UDPROTO_SSHUB)
118
119 /* prototypes for type checking: */
120
121 static device_probe_t uhub_probe;
122 static device_attach_t uhub_attach;
123 static device_detach_t uhub_detach;
124 static device_suspend_t uhub_suspend;
125 static device_resume_t uhub_resume;
126
127 static bus_driver_added_t uhub_driver_added;
128 static bus_child_location_str_t uhub_child_location_string;
129 static bus_child_pnpinfo_str_t uhub_child_pnpinfo_string;
130
131 static usb_callback_t uhub_intr_callback;
132 #if USB_HAVE_TT_SUPPORT
133 static usb_callback_t uhub_reset_tt_callback;
134 #endif
135
136 static void usb_dev_resume_peer(struct usb_device *udev);
137 static void usb_dev_suspend_peer(struct usb_device *udev);
138 static uint8_t usb_peer_should_wakeup(struct usb_device *udev);
139
140 static const struct usb_config uhub_config[UHUB_N_TRANSFER] = {
141
142         [UHUB_INTR_TRANSFER] = {
143                 .type = UE_INTERRUPT,
144                 .endpoint = UE_ADDR_ANY,
145                 .direction = UE_DIR_ANY,
146                 .timeout = 0,
147                 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
148                 .bufsize = 0,   /* use wMaxPacketSize */
149                 .callback = &uhub_intr_callback,
150                 .interval = UHUB_INTR_INTERVAL,
151         },
152 #if USB_HAVE_TT_SUPPORT
153         [UHUB_RESET_TT_TRANSFER] = {
154                 .type = UE_CONTROL,
155                 .endpoint = 0x00,       /* Control pipe */
156                 .direction = UE_DIR_ANY,
157                 .bufsize = sizeof(struct usb_device_request),
158                 .callback = &uhub_reset_tt_callback,
159                 .timeout = 1000,        /* 1 second */
160                 .usb_mode = USB_MODE_HOST,
161         },
162 #endif
163 };
164
165 /*
166  * driver instance for "hub" connected to "usb"
167  * and "hub" connected to "hub"
168  */
169 static devclass_t uhub_devclass;
170
171 static device_method_t uhub_methods[] = {
172         DEVMETHOD(device_probe, uhub_probe),
173         DEVMETHOD(device_attach, uhub_attach),
174         DEVMETHOD(device_detach, uhub_detach),
175
176         DEVMETHOD(device_suspend, uhub_suspend),
177         DEVMETHOD(device_resume, uhub_resume),
178
179         DEVMETHOD(bus_child_location_str, uhub_child_location_string),
180         DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_string),
181         DEVMETHOD(bus_driver_added, uhub_driver_added),
182         {0, 0}
183 };
184
185 static driver_t uhub_driver = {
186         .name = "uhub",
187         .methods = uhub_methods,
188         .size = sizeof(struct uhub_softc)
189 };
190
191 DRIVER_MODULE(uhub, usbus, uhub_driver, uhub_devclass, 0, 0);
192 DRIVER_MODULE(uhub, uhub, uhub_driver, uhub_devclass, NULL, 0);
193 MODULE_VERSION(uhub, 1);
194
195 static void
196 uhub_intr_callback(struct usb_xfer *xfer, usb_error_t error)
197 {
198         struct uhub_softc *sc = usbd_xfer_softc(xfer);
199
200         switch (USB_GET_STATE(xfer)) {
201         case USB_ST_TRANSFERRED:
202                 DPRINTFN(2, "\n");
203                 /*
204                  * This is an indication that some port
205                  * has changed status. Notify the bus
206                  * event handler thread that we need
207                  * to be explored again:
208                  */
209                 usb_needs_explore(sc->sc_udev->bus, 0);
210
211         case USB_ST_SETUP:
212                 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
213                 usbd_transfer_submit(xfer);
214                 break;
215
216         default:                        /* Error */
217                 if (xfer->error != USB_ERR_CANCELLED) {
218                         /*
219                          * Do a clear-stall. The "stall_pipe" flag
220                          * will get cleared before next callback by
221                          * the USB stack.
222                          */
223                         usbd_xfer_set_stall(xfer);
224                         usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
225                         usbd_transfer_submit(xfer);
226                 }
227                 break;
228         }
229 }
230
231 /*------------------------------------------------------------------------*
232  *      uhub_reset_tt_proc
233  *
234  * This function starts the TT reset USB request
235  *------------------------------------------------------------------------*/
236 #if USB_HAVE_TT_SUPPORT
237 static void
238 uhub_reset_tt_proc(struct usb_proc_msg *_pm)
239 {
240         struct usb_udev_msg *pm = (void *)_pm;
241         struct usb_device *udev = pm->udev;
242         struct usb_hub *hub;
243         struct uhub_softc *sc;
244
245         hub = udev->hub;
246         if (hub == NULL)
247                 return;
248         sc = hub->hubsoftc;
249         if (sc == NULL)
250                 return;
251
252         /* Change lock */
253         USB_BUS_UNLOCK(udev->bus);
254         mtx_lock(&sc->sc_mtx);
255         /* Start transfer */
256         usbd_transfer_start(sc->sc_xfer[UHUB_RESET_TT_TRANSFER]);
257         /* Change lock */
258         mtx_unlock(&sc->sc_mtx);
259         USB_BUS_LOCK(udev->bus);
260 }
261 #endif
262
263 /*------------------------------------------------------------------------*
264  *      uhub_tt_buffer_reset_async_locked
265  *
266  * This function queues a TT reset for the given USB device and endpoint.
267  *------------------------------------------------------------------------*/
268 #if USB_HAVE_TT_SUPPORT
269 void
270 uhub_tt_buffer_reset_async_locked(struct usb_device *child, struct usb_endpoint *ep)
271 {
272         struct usb_device_request req;
273         struct usb_device *udev;
274         struct usb_hub *hub;
275         struct usb_port *up;
276         uint16_t wValue;
277         uint8_t port;
278
279         if (child == NULL || ep == NULL)
280                 return;
281
282         udev = child->parent_hs_hub;
283         port = child->hs_port_no;
284
285         if (udev == NULL)
286                 return;
287
288         hub = udev->hub;
289         if ((hub == NULL) ||
290             (udev->speed != USB_SPEED_HIGH) ||
291             (child->speed != USB_SPEED_LOW &&
292              child->speed != USB_SPEED_FULL) ||
293             (child->flags.usb_mode != USB_MODE_HOST) ||
294             (port == 0) || (ep->edesc == NULL)) {
295                 /* not applicable */
296                 return;
297         }
298
299         USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
300
301         up = hub->ports + port - 1;
302
303         if (udev->ddesc.bDeviceClass == UDCLASS_HUB &&
304             udev->ddesc.bDeviceProtocol == UDPROTO_HSHUBSTT)
305                 port = 1;
306
307         /* if we already received a clear buffer request, reset the whole TT */
308         if (up->req_reset_tt.bRequest != 0) {
309                 req.bmRequestType = UT_WRITE_CLASS_OTHER;
310                 req.bRequest = UR_RESET_TT;
311                 USETW(req.wValue, 0);
312                 req.wIndex[0] = port;
313                 req.wIndex[1] = 0;
314                 USETW(req.wLength, 0);
315         } else {
316                 wValue = (ep->edesc->bEndpointAddress & 0xF) |
317                       ((child->address & 0x7F) << 4) |
318                       ((ep->edesc->bEndpointAddress & 0x80) << 8) |
319                       ((ep->edesc->bmAttributes & 3) << 12);
320
321                 req.bmRequestType = UT_WRITE_CLASS_OTHER;
322                 req.bRequest = UR_CLEAR_TT_BUFFER;
323                 USETW(req.wValue, wValue);
324                 req.wIndex[0] = port;
325                 req.wIndex[1] = 0;
326                 USETW(req.wLength, 0);
327         }
328         up->req_reset_tt = req;
329         /* get reset transfer started */
330         usb_proc_msignal(&udev->bus->non_giant_callback_proc,
331             &hub->tt_msg[0], &hub->tt_msg[1]);
332 }
333 #endif
334
335 #if USB_HAVE_TT_SUPPORT
336 static void
337 uhub_reset_tt_callback(struct usb_xfer *xfer, usb_error_t error)
338 {
339         struct uhub_softc *sc;
340         struct usb_device *udev;
341         struct usb_port *up;
342         uint8_t x;
343
344         DPRINTF("TT buffer reset\n");
345
346         sc = usbd_xfer_softc(xfer);
347         udev = sc->sc_udev;
348
349         switch (USB_GET_STATE(xfer)) {
350         case USB_ST_TRANSFERRED:
351         case USB_ST_SETUP:
352 tr_setup:
353                 USB_BUS_LOCK(udev->bus);
354                 /* find first port which needs a TT reset */
355                 for (x = 0; x != udev->hub->nports; x++) {
356                         up = udev->hub->ports + x;
357
358                         if (up->req_reset_tt.bRequest == 0)
359                                 continue;
360
361                         /* copy in the transfer */
362                         usbd_copy_in(xfer->frbuffers, 0, &up->req_reset_tt,
363                             sizeof(up->req_reset_tt));
364                         /* reset buffer */
365                         memset(&up->req_reset_tt, 0, sizeof(up->req_reset_tt));
366
367                         /* set length */
368                         usbd_xfer_set_frame_len(xfer, 0, sizeof(up->req_reset_tt));
369                         xfer->nframes = 1;
370                         USB_BUS_UNLOCK(udev->bus);
371
372                         usbd_transfer_submit(xfer);
373                         return;
374                 }
375                 USB_BUS_UNLOCK(udev->bus);
376                 break;
377
378         default:
379                 if (error == USB_ERR_CANCELLED)
380                         break;
381
382                 DPRINTF("TT buffer reset failed (%s)\n", usbd_errstr(error));
383                 goto tr_setup;
384         }
385 }
386 #endif
387
388 /*------------------------------------------------------------------------*
389  *      uhub_count_active_host_ports
390  *
391  * This function counts the number of active ports at the given speed.
392  *------------------------------------------------------------------------*/
393 uint8_t
394 uhub_count_active_host_ports(struct usb_device *udev, enum usb_dev_speed speed)
395 {
396         struct uhub_softc *sc;
397         struct usb_device *child;
398         struct usb_hub *hub;
399         struct usb_port *up;
400         uint8_t retval = 0;
401         uint8_t x;
402
403         if (udev == NULL)
404                 goto done;
405         hub = udev->hub;
406         if (hub == NULL)
407                 goto done;
408         sc = hub->hubsoftc;
409         if (sc == NULL)
410                 goto done;
411
412         for (x = 0; x != hub->nports; x++) {
413                 up = hub->ports + x;
414                 child = usb_bus_port_get_device(udev->bus, up);
415                 if (child != NULL &&
416                     child->flags.usb_mode == USB_MODE_HOST &&
417                     child->speed == speed)
418                         retval++;
419         }
420 done:
421         return (retval);
422 }
423
424 /*------------------------------------------------------------------------*
425  *      uhub_explore_sub - subroutine
426  *
427  * Return values:
428  *    0: Success
429  * Else: A control transaction failed
430  *------------------------------------------------------------------------*/
431 static usb_error_t
432 uhub_explore_sub(struct uhub_softc *sc, struct usb_port *up)
433 {
434         struct usb_bus *bus;
435         struct usb_device *child;
436         uint8_t refcount;
437         usb_error_t err;
438
439         bus = sc->sc_udev->bus;
440         err = 0;
441
442         /* get driver added refcount from USB bus */
443         refcount = bus->driver_added_refcount;
444
445         /* get device assosiated with the given port */
446         child = usb_bus_port_get_device(bus, up);
447         if (child == NULL) {
448                 /* nothing to do */
449                 goto done;
450         }
451
452         /* check if device should be re-enumerated */
453
454         if (child->flags.usb_mode == USB_MODE_HOST) {
455                 uint8_t do_unlock;
456                 
457                 do_unlock = usbd_enum_lock(child);
458                 switch (child->re_enumerate_wait) {
459                 case USB_RE_ENUM_START:
460                         err = usbd_set_config_index(child,
461                             USB_UNCONFIG_INDEX);
462                         if (err != 0) {
463                                 DPRINTF("Unconfigure failed: "
464                                     "%s: Ignored.\n",
465                                     usbd_errstr(err));
466                         }
467                         err = usbd_req_re_enumerate(child, NULL);
468                         if (err == 0)
469                                 err = usbd_set_config_index(child, 0);
470                         if (err == 0) {
471                                 err = usb_probe_and_attach(child,
472                                     USB_IFACE_INDEX_ANY);
473                         }
474                         child->re_enumerate_wait = USB_RE_ENUM_DONE;
475                         err = 0;
476                         break;
477
478                 case USB_RE_ENUM_PWR_OFF:
479                         /* get the device unconfigured */
480                         err = usbd_set_config_index(child,
481                             USB_UNCONFIG_INDEX);
482                         if (err) {
483                                 DPRINTFN(0, "Could not unconfigure "
484                                     "device (ignored)\n");
485                         }
486
487                         /* clear port enable */
488                         err = usbd_req_clear_port_feature(child->parent_hub,
489                             NULL, child->port_no, UHF_PORT_ENABLE);
490                         if (err) {
491                                 DPRINTFN(0, "Could not disable port "
492                                     "(ignored)\n");
493                         }
494                         child->re_enumerate_wait = USB_RE_ENUM_DONE;
495                         err = 0;
496                         break;
497
498                 default:
499                         child->re_enumerate_wait = USB_RE_ENUM_DONE;
500                         break;
501                 }
502                 if (do_unlock)
503                         usbd_enum_unlock(child);
504         }
505
506         /* check if probe and attach should be done */
507
508         if (child->driver_added_refcount != refcount) {
509                 child->driver_added_refcount = refcount;
510                 err = usb_probe_and_attach(child,
511                     USB_IFACE_INDEX_ANY);
512                 if (err) {
513                         goto done;
514                 }
515         }
516         /* start control transfer, if device mode */
517
518         if (child->flags.usb_mode == USB_MODE_DEVICE)
519                 usbd_ctrl_transfer_setup(child);
520
521         /* if a HUB becomes present, do a recursive HUB explore */
522
523         if (child->hub)
524                 err = (child->hub->explore) (child);
525
526 done:
527         return (err);
528 }
529
530 /*------------------------------------------------------------------------*
531  *      uhub_read_port_status - factored out code
532  *------------------------------------------------------------------------*/
533 static usb_error_t
534 uhub_read_port_status(struct uhub_softc *sc, uint8_t portno)
535 {
536         struct usb_port_status ps;
537         usb_error_t err;
538
539         err = usbd_req_get_port_status(
540             sc->sc_udev, NULL, &ps, portno);
541
542         /* update status regardless of error */
543
544         sc->sc_st.port_status = UGETW(ps.wPortStatus);
545         sc->sc_st.port_change = UGETW(ps.wPortChange);
546
547         /* debugging print */
548
549         DPRINTFN(4, "port %d, wPortStatus=0x%04x, "
550             "wPortChange=0x%04x, err=%s\n",
551             portno, sc->sc_st.port_status,
552             sc->sc_st.port_change, usbd_errstr(err));
553         return (err);
554 }
555
556 /*------------------------------------------------------------------------*
557  *      uhub_reattach_port
558  *
559  * Returns:
560  *    0: Success
561  * Else: A control transaction failed
562  *------------------------------------------------------------------------*/
563 static usb_error_t
564 uhub_reattach_port(struct uhub_softc *sc, uint8_t portno)
565 {
566         struct usb_device *child;
567         struct usb_device *udev;
568         enum usb_dev_speed speed;
569         enum usb_hc_mode mode;
570         usb_error_t err;
571         uint16_t power_mask;
572         uint8_t timeout;
573
574         DPRINTF("reattaching port %d\n", portno);
575
576         err = 0;
577         timeout = 0;
578         udev = sc->sc_udev;
579         child = usb_bus_port_get_device(udev->bus,
580             udev->hub->ports + portno - 1);
581
582 repeat:
583
584         /* first clear the port connection change bit */
585
586         err = usbd_req_clear_port_feature(udev, NULL,
587             portno, UHF_C_PORT_CONNECTION);
588
589         if (err) {
590                 goto error;
591         }
592         /* check if there is a child */
593
594         if (child != NULL) {
595                 /*
596                  * Free USB device and all subdevices, if any.
597                  */
598                 usb_free_device(child, 0);
599                 child = NULL;
600         }
601         /* get fresh status */
602
603         err = uhub_read_port_status(sc, portno);
604         if (err) {
605                 goto error;
606         }
607         /* check if nothing is connected to the port */
608
609         if (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS)) {
610                 goto error;
611         }
612         /* check if there is no power on the port and print a warning */
613
614         switch (udev->speed) {
615         case USB_SPEED_HIGH:
616         case USB_SPEED_FULL:
617         case USB_SPEED_LOW:
618                 power_mask = UPS_PORT_POWER;
619                 break;
620         case USB_SPEED_SUPER:
621                 if (udev->parent_hub == NULL)
622                         power_mask = UPS_PORT_POWER;
623                 else
624                         power_mask = UPS_PORT_POWER_SS;
625                 break;
626         default:
627                 power_mask = 0;
628                 break;
629         }
630         if (!(sc->sc_st.port_status & power_mask)) {
631                 DPRINTF("WARNING: strange, connected port %d "
632                     "has no power\n", portno);
633         }
634
635         /* check if the device is in Host Mode */
636
637         if (!(sc->sc_st.port_status & UPS_PORT_MODE_DEVICE)) {
638
639                 DPRINTF("Port %d is in Host Mode\n", portno);
640
641                 if (sc->sc_st.port_status & UPS_SUSPEND) {
642                         /*
643                          * NOTE: Should not get here in SuperSpeed
644                          * mode, because the HUB should report this
645                          * bit as zero.
646                          */
647                         DPRINTF("Port %d was still "
648                             "suspended, clearing.\n", portno);
649                         err = usbd_req_clear_port_feature(udev,
650                             NULL, portno, UHF_PORT_SUSPEND);
651                 }
652
653                 /* USB Host Mode */
654
655                 /* wait for maximum device power up time */
656
657                 usb_pause_mtx(NULL, 
658                     USB_MS_TO_TICKS(usb_port_powerup_delay));
659
660                 /* reset port, which implies enabling it */
661
662                 err = usbd_req_reset_port(udev, NULL, portno);
663
664                 if (err) {
665                         DPRINTFN(0, "port %d reset "
666                             "failed, error=%s\n",
667                             portno, usbd_errstr(err));
668                         goto error;
669                 }
670                 /* get port status again, it might have changed during reset */
671
672                 err = uhub_read_port_status(sc, portno);
673                 if (err) {
674                         goto error;
675                 }
676                 /* check if something changed during port reset */
677
678                 if ((sc->sc_st.port_change & UPS_C_CONNECT_STATUS) ||
679                     (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS))) {
680                         if (timeout) {
681                                 DPRINTFN(0, "giving up port reset "
682                                     "- device vanished\n");
683                                 goto error;
684                         }
685                         timeout = 1;
686                         goto repeat;
687                 }
688         } else {
689                 DPRINTF("Port %d is in Device Mode\n", portno);
690         }
691
692         /*
693          * Figure out the device speed
694          */
695         switch (udev->speed) {
696         case USB_SPEED_HIGH:
697                 if (sc->sc_st.port_status & UPS_HIGH_SPEED)
698                         speed = USB_SPEED_HIGH;
699                 else if (sc->sc_st.port_status & UPS_LOW_SPEED)
700                         speed = USB_SPEED_LOW;
701                 else
702                         speed = USB_SPEED_FULL;
703                 break;
704         case USB_SPEED_FULL:
705                 if (sc->sc_st.port_status & UPS_LOW_SPEED)
706                         speed = USB_SPEED_LOW;
707                 else
708                         speed = USB_SPEED_FULL;
709                 break;
710         case USB_SPEED_LOW:
711                 speed = USB_SPEED_LOW;
712                 break;
713         case USB_SPEED_SUPER:
714                 if (udev->parent_hub == NULL) {
715                         /* Root HUB - special case */
716                         switch (sc->sc_st.port_status & UPS_OTHER_SPEED) {
717                         case 0:
718                                 speed = USB_SPEED_FULL;
719                                 break;
720                         case UPS_LOW_SPEED:
721                                 speed = USB_SPEED_LOW;
722                                 break;
723                         case UPS_HIGH_SPEED:
724                                 speed = USB_SPEED_HIGH;
725                                 break;
726                         default:
727                                 speed = USB_SPEED_SUPER;
728                                 break;
729                         }
730                 } else {
731                         speed = USB_SPEED_SUPER;
732                 }
733                 break;
734         default:
735                 /* same speed like parent */
736                 speed = udev->speed;
737                 break;
738         }
739         if (speed == USB_SPEED_SUPER) {
740                 err = usbd_req_set_hub_u1_timeout(udev, NULL,
741                     portno, 128 - (2 * udev->depth));
742                 if (err) {
743                         DPRINTFN(0, "port %d U1 timeout "
744                             "failed, error=%s\n",
745                             portno, usbd_errstr(err));
746                 }
747                 err = usbd_req_set_hub_u2_timeout(udev, NULL,
748                     portno, 128 - (2 * udev->depth));
749                 if (err) {
750                         DPRINTFN(0, "port %d U2 timeout "
751                             "failed, error=%s\n",
752                             portno, usbd_errstr(err));
753                 }
754         }
755
756         /*
757          * Figure out the device mode
758          *
759          * NOTE: This part is currently FreeBSD specific.
760          */
761         if (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE)
762                 mode = USB_MODE_DEVICE;
763         else
764                 mode = USB_MODE_HOST;
765
766         /* need to create a new child */
767         child = usb_alloc_device(sc->sc_dev, udev->bus, udev,
768             udev->depth + 1, portno - 1, portno, speed, mode);
769         if (child == NULL) {
770                 DPRINTFN(0, "could not allocate new device\n");
771                 goto error;
772         }
773         return (0);                     /* success */
774
775 error:
776         if (child != NULL) {
777                 /*
778                  * Free USB device and all subdevices, if any.
779                  */
780                 usb_free_device(child, 0);
781                 child = NULL;
782         }
783         if (err == 0) {
784                 if (sc->sc_st.port_status & UPS_PORT_ENABLED) {
785                         err = usbd_req_clear_port_feature(
786                             sc->sc_udev, NULL,
787                             portno, UHF_PORT_ENABLE);
788                 }
789         }
790         if (err) {
791                 DPRINTFN(0, "device problem (%s), "
792                     "disabling port %d\n", usbd_errstr(err), portno);
793         }
794         return (err);
795 }
796
797 /*------------------------------------------------------------------------*
798  *      usb_device_20_compatible
799  *
800  * Returns:
801  *    0: HUB does not support suspend and resume
802  * Else: HUB supports suspend and resume
803  *------------------------------------------------------------------------*/
804 static uint8_t
805 usb_device_20_compatible(struct usb_device *udev)
806 {
807         if (udev == NULL)
808                 return (0);
809         switch (udev->speed) {
810         case USB_SPEED_LOW:
811         case USB_SPEED_FULL:
812         case USB_SPEED_HIGH:
813                 return (1);
814         default:
815                 return (0);
816         }
817 }
818
819 /*------------------------------------------------------------------------*
820  *      uhub_suspend_resume_port
821  *
822  * Returns:
823  *    0: Success
824  * Else: A control transaction failed
825  *------------------------------------------------------------------------*/
826 static usb_error_t
827 uhub_suspend_resume_port(struct uhub_softc *sc, uint8_t portno)
828 {
829         struct usb_device *child;
830         struct usb_device *udev;
831         uint8_t is_suspend;
832         usb_error_t err;
833
834         DPRINTF("port %d\n", portno);
835
836         udev = sc->sc_udev;
837         child = usb_bus_port_get_device(udev->bus,
838             udev->hub->ports + portno - 1);
839
840         /* first clear the port suspend change bit */
841
842         if (usb_device_20_compatible(udev)) {
843                 err = usbd_req_clear_port_feature(udev, NULL,
844                     portno, UHF_C_PORT_SUSPEND);
845         } else {
846                 err = usbd_req_clear_port_feature(udev, NULL,
847                     portno, UHF_C_PORT_LINK_STATE);
848         }
849
850         if (err) {
851                 DPRINTF("clearing suspend failed.\n");
852                 goto done;
853         }
854         /* get fresh status */
855
856         err = uhub_read_port_status(sc, portno);
857         if (err) {
858                 DPRINTF("reading port status failed.\n");
859                 goto done;
860         }
861         /* convert current state */
862
863         if (usb_device_20_compatible(udev)) {
864                 if (sc->sc_st.port_status & UPS_SUSPEND) {
865                         is_suspend = 1;
866                 } else {
867                         is_suspend = 0;
868                 }
869         } else {
870                 switch (UPS_PORT_LINK_STATE_GET(sc->sc_st.port_status)) {
871                 case UPS_PORT_LS_U3:
872                         is_suspend = 1;
873                         break;
874                 case UPS_PORT_LS_SS_INA:
875                         usbd_req_warm_reset_port(udev, NULL, portno);
876                         is_suspend = 0;
877                         break;
878                 default:
879                         is_suspend = 0;
880                         break;
881                 }
882         }
883
884         DPRINTF("suspended=%u\n", is_suspend);
885
886         /* do the suspend or resume */
887
888         if (child) {
889                 /*
890                  * This code handle two cases: 1) Host Mode - we can only
891                  * receive resume here 2) Device Mode - we can receive
892                  * suspend and resume here
893                  */
894                 if (is_suspend == 0)
895                         usb_dev_resume_peer(child);
896                 else if (child->flags.usb_mode == USB_MODE_DEVICE)
897                         usb_dev_suspend_peer(child);
898         }
899 done:
900         return (err);
901 }
902
903 /*------------------------------------------------------------------------*
904  *      uhub_root_interrupt
905  *
906  * This function is called when a Root HUB interrupt has
907  * happened. "ptr" and "len" makes up the Root HUB interrupt
908  * packet. This function is called having the "bus_mtx" locked.
909  *------------------------------------------------------------------------*/
910 void
911 uhub_root_intr(struct usb_bus *bus, const uint8_t *ptr, uint8_t len)
912 {
913         USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
914
915         usb_needs_explore(bus, 0);
916 }
917
918 static uint8_t
919 uhub_is_too_deep(struct usb_device *udev)
920 {
921         switch (udev->speed) {
922         case USB_SPEED_FULL:
923         case USB_SPEED_LOW:
924         case USB_SPEED_HIGH:
925                 if (udev->depth > USB_HUB_MAX_DEPTH)
926                         return (1);
927                 break;
928         case USB_SPEED_SUPER:
929                 if (udev->depth > USB_SS_HUB_DEPTH_MAX)
930                         return (1);
931                 break;
932         default:
933                 break;
934         }
935         return (0);
936 }
937
938 /*------------------------------------------------------------------------*
939  *      uhub_explore
940  *
941  * Returns:
942  *     0: Success
943  *  Else: Failure
944  *------------------------------------------------------------------------*/
945 static usb_error_t
946 uhub_explore(struct usb_device *udev)
947 {
948         struct usb_hub *hub;
949         struct uhub_softc *sc;
950         struct usb_port *up;
951         usb_error_t err;
952         uint8_t portno;
953         uint8_t x;
954         uint8_t do_unlock;
955
956         hub = udev->hub;
957         sc = hub->hubsoftc;
958
959         DPRINTFN(11, "udev=%p addr=%d\n", udev, udev->address);
960
961         /* ignore devices that are too deep */
962         if (uhub_is_too_deep(udev))
963                 return (USB_ERR_TOO_DEEP);
964
965         /* check if device is suspended */
966         if (udev->flags.self_suspended) {
967                 /* need to wait until the child signals resume */
968                 DPRINTF("Device is suspended!\n");
969                 return (0);
970         }
971
972         /*
973          * Make sure we don't race against user-space applications
974          * like LibUSB:
975          */
976         do_unlock = usbd_enum_lock(udev);
977
978         for (x = 0; x != hub->nports; x++) {
979                 up = hub->ports + x;
980                 portno = x + 1;
981
982                 err = uhub_read_port_status(sc, portno);
983                 if (err) {
984                         /* most likely the HUB is gone */
985                         break;
986                 }
987                 if (sc->sc_st.port_change & UPS_C_OVERCURRENT_INDICATOR) {
988                         DPRINTF("Overcurrent on port %u.\n", portno);
989                         err = usbd_req_clear_port_feature(
990                             udev, NULL, portno, UHF_C_PORT_OVER_CURRENT);
991                         if (err) {
992                                 /* most likely the HUB is gone */
993                                 break;
994                         }
995                 }
996                 if (!(sc->sc_flags & UHUB_FLAG_DID_EXPLORE)) {
997                         /*
998                          * Fake a connect status change so that the
999                          * status gets checked initially!
1000                          */
1001                         sc->sc_st.port_change |=
1002                             UPS_C_CONNECT_STATUS;
1003                 }
1004                 if (sc->sc_st.port_change & UPS_C_PORT_ENABLED) {
1005                         err = usbd_req_clear_port_feature(
1006                             udev, NULL, portno, UHF_C_PORT_ENABLE);
1007                         if (err) {
1008                                 /* most likely the HUB is gone */
1009                                 break;
1010                         }
1011                         if (sc->sc_st.port_change & UPS_C_CONNECT_STATUS) {
1012                                 /*
1013                                  * Ignore the port error if the device
1014                                  * has vanished !
1015                                  */
1016                         } else if (sc->sc_st.port_status & UPS_PORT_ENABLED) {
1017                                 DPRINTFN(0, "illegal enable change, "
1018                                     "port %d\n", portno);
1019                         } else {
1020
1021                                 if (up->restartcnt == USB_RESTART_MAX) {
1022                                         /* XXX could try another speed ? */
1023                                         DPRINTFN(0, "port error, giving up "
1024                                             "port %d\n", portno);
1025                                 } else {
1026                                         sc->sc_st.port_change |=
1027                                             UPS_C_CONNECT_STATUS;
1028                                         up->restartcnt++;
1029                                 }
1030                         }
1031                 }
1032                 if (sc->sc_st.port_change & UPS_C_CONNECT_STATUS) {
1033                         err = uhub_reattach_port(sc, portno);
1034                         if (err) {
1035                                 /* most likely the HUB is gone */
1036                                 break;
1037                         }
1038                 }
1039                 if (sc->sc_st.port_change & (UPS_C_SUSPEND |
1040                     UPS_C_PORT_LINK_STATE)) {
1041                         err = uhub_suspend_resume_port(sc, portno);
1042                         if (err) {
1043                                 /* most likely the HUB is gone */
1044                                 break;
1045                         }
1046                 }
1047                 err = uhub_explore_sub(sc, up);
1048                 if (err) {
1049                         /* no device(s) present */
1050                         continue;
1051                 }
1052                 /* explore succeeded - reset restart counter */
1053                 up->restartcnt = 0;
1054         }
1055
1056         if (do_unlock)
1057                 usbd_enum_unlock(udev);
1058
1059         /* initial status checked */
1060         sc->sc_flags |= UHUB_FLAG_DID_EXPLORE;
1061
1062         /* return success */
1063         return (USB_ERR_NORMAL_COMPLETION);
1064 }
1065
1066 static int
1067 uhub_probe(device_t dev)
1068 {
1069         struct usb_attach_arg *uaa = device_get_ivars(dev);
1070
1071         if (uaa->usb_mode != USB_MODE_HOST)
1072                 return (ENXIO);
1073
1074         /*
1075          * The subclass for USB HUBs is currently ignored because it
1076          * is 0 for some and 1 for others.
1077          */
1078         if (uaa->info.bConfigIndex == 0 &&
1079             uaa->info.bDeviceClass == UDCLASS_HUB)
1080                 return (0);
1081
1082         return (ENXIO);
1083 }
1084
1085 /* NOTE: The information returned by this function can be wrong. */
1086 usb_error_t
1087 uhub_query_info(struct usb_device *udev, uint8_t *pnports, uint8_t *ptt)
1088 {
1089         struct usb_hub_descriptor hubdesc20;
1090         struct usb_hub_ss_descriptor hubdesc30;
1091         usb_error_t err;
1092         uint8_t nports;
1093         uint8_t tt;
1094
1095         if (udev->ddesc.bDeviceClass != UDCLASS_HUB)
1096                 return (USB_ERR_INVAL);
1097
1098         nports = 0;
1099         tt = 0;
1100
1101         switch (udev->speed) {
1102         case USB_SPEED_LOW:
1103         case USB_SPEED_FULL:
1104         case USB_SPEED_HIGH:
1105                 /* assuming that there is one port */
1106                 err = usbd_req_get_hub_descriptor(udev, NULL, &hubdesc20, 1);
1107                 if (err) {
1108                         DPRINTFN(0, "getting USB 2.0 HUB descriptor failed,"
1109                             "error=%s\n", usbd_errstr(err));
1110                         break;
1111                 }
1112                 nports = hubdesc20.bNbrPorts;
1113                 if (nports > 127)
1114                         nports = 127;
1115
1116                 if (udev->speed == USB_SPEED_HIGH)
1117                         tt = (UGETW(hubdesc20.wHubCharacteristics) >> 5) & 3;
1118                 break;
1119
1120         case USB_SPEED_SUPER:
1121                 err = usbd_req_get_ss_hub_descriptor(udev, NULL, &hubdesc30, 1);
1122                 if (err) {
1123                         DPRINTFN(0, "Getting USB 3.0 HUB descriptor failed,"
1124                             "error=%s\n", usbd_errstr(err));
1125                         break;
1126                 }
1127                 nports = hubdesc30.bNbrPorts;
1128                 if (nports > 16)
1129                         nports = 16;
1130                 break;
1131
1132         default:
1133                 err = USB_ERR_INVAL;
1134                 break;
1135         }
1136
1137         if (pnports != NULL)
1138                 *pnports = nports;
1139
1140         if (ptt != NULL)
1141                 *ptt = tt;
1142
1143         return (err);
1144 }
1145
1146 static int
1147 uhub_attach(device_t dev)
1148 {
1149         struct uhub_softc *sc = device_get_softc(dev);
1150         struct usb_attach_arg *uaa = device_get_ivars(dev);
1151         struct usb_device *udev = uaa->device;
1152         struct usb_device *parent_hub = udev->parent_hub;
1153         struct usb_hub *hub;
1154         struct usb_hub_descriptor hubdesc20;
1155         struct usb_hub_ss_descriptor hubdesc30;
1156         uint16_t pwrdly;
1157         uint8_t x;
1158         uint8_t nports;
1159         uint8_t portno;
1160         uint8_t removable;
1161         uint8_t iface_index;
1162         usb_error_t err;
1163
1164         sc->sc_udev = udev;
1165         sc->sc_dev = dev;
1166
1167         mtx_init(&sc->sc_mtx, "USB HUB mutex", NULL, MTX_DEF);
1168
1169         snprintf(sc->sc_name, sizeof(sc->sc_name), "%s",
1170             device_get_nameunit(dev));
1171
1172         device_set_usb_desc(dev);
1173
1174         DPRINTFN(2, "depth=%d selfpowered=%d, parent=%p, "
1175             "parent->selfpowered=%d\n",
1176             udev->depth,
1177             udev->flags.self_powered,
1178             parent_hub,
1179             parent_hub ?
1180             parent_hub->flags.self_powered : 0);
1181
1182         if (uhub_is_too_deep(udev)) {
1183                 DPRINTFN(0, "HUB at depth %d, "
1184                     "exceeds maximum. HUB ignored\n", (int)udev->depth);
1185                 goto error;
1186         }
1187
1188         if (!udev->flags.self_powered && parent_hub &&
1189             !parent_hub->flags.self_powered) {
1190                 DPRINTFN(0, "Bus powered HUB connected to "
1191                     "bus powered HUB. HUB ignored\n");
1192                 goto error;
1193         }
1194
1195         if (UHUB_IS_MULTI_TT(sc)) {
1196                 err = usbd_set_alt_interface_index(udev, 0, 1);
1197                 if (err) {
1198                         device_printf(dev, "MTT could not be enabled\n");
1199                         goto error;
1200                 }
1201                 device_printf(dev, "MTT enabled\n");
1202         }
1203
1204         /* get HUB descriptor */
1205
1206         DPRINTFN(2, "Getting HUB descriptor\n");
1207
1208         switch (udev->speed) {
1209         case USB_SPEED_LOW:
1210         case USB_SPEED_FULL:
1211         case USB_SPEED_HIGH:
1212                 /* assuming that there is one port */
1213                 err = usbd_req_get_hub_descriptor(udev, NULL, &hubdesc20, 1);
1214                 if (err) {
1215                         DPRINTFN(0, "getting USB 2.0 HUB descriptor failed,"
1216                             "error=%s\n", usbd_errstr(err));
1217                         goto error;
1218                 }
1219                 /* get number of ports */
1220                 nports = hubdesc20.bNbrPorts;
1221
1222                 /* get power delay */
1223                 pwrdly = ((hubdesc20.bPwrOn2PwrGood * UHD_PWRON_FACTOR) +
1224                     usb_extra_power_up_time);
1225
1226                 /* get complete HUB descriptor */
1227                 if (nports >= 8) {
1228                         /* check number of ports */
1229                         if (nports > 127) {
1230                                 DPRINTFN(0, "Invalid number of USB 2.0 ports,"
1231                                     "error=%s\n", usbd_errstr(err));
1232                                 goto error;
1233                         }
1234                         /* get complete HUB descriptor */
1235                         err = usbd_req_get_hub_descriptor(udev, NULL, &hubdesc20, nports);
1236
1237                         if (err) {
1238                                 DPRINTFN(0, "Getting USB 2.0 HUB descriptor failed,"
1239                                     "error=%s\n", usbd_errstr(err));
1240                                 goto error;
1241                         }
1242                         if (hubdesc20.bNbrPorts != nports) {
1243                                 DPRINTFN(0, "Number of ports changed\n");
1244                                 goto error;
1245                         }
1246                 }
1247                 break;
1248         case USB_SPEED_SUPER:
1249                 if (udev->parent_hub != NULL) {
1250                         err = usbd_req_set_hub_depth(udev, NULL,
1251                             udev->depth - 1);
1252                         if (err) {
1253                                 DPRINTFN(0, "Setting USB 3.0 HUB depth failed,"
1254                                     "error=%s\n", usbd_errstr(err));
1255                                 goto error;
1256                         }
1257                 }
1258                 err = usbd_req_get_ss_hub_descriptor(udev, NULL, &hubdesc30, 1);
1259                 if (err) {
1260                         DPRINTFN(0, "Getting USB 3.0 HUB descriptor failed,"
1261                             "error=%s\n", usbd_errstr(err));
1262                         goto error;
1263                 }
1264                 /* get number of ports */
1265                 nports = hubdesc30.bNbrPorts;
1266
1267                 /* get power delay */
1268                 pwrdly = ((hubdesc30.bPwrOn2PwrGood * UHD_PWRON_FACTOR) +
1269                     usb_extra_power_up_time);
1270
1271                 /* get complete HUB descriptor */
1272                 if (nports >= 8) {
1273                         /* check number of ports */
1274                         if (nports > ((udev->parent_hub != NULL) ? 15 : 127)) {
1275                                 DPRINTFN(0, "Invalid number of USB 3.0 ports,"
1276                                     "error=%s\n", usbd_errstr(err));
1277                                 goto error;
1278                         }
1279                         /* get complete HUB descriptor */
1280                         err = usbd_req_get_ss_hub_descriptor(udev, NULL, &hubdesc30, nports);
1281
1282                         if (err) {
1283                                 DPRINTFN(0, "Getting USB 2.0 HUB descriptor failed,"
1284                                     "error=%s\n", usbd_errstr(err));
1285                                 goto error;
1286                         }
1287                         if (hubdesc30.bNbrPorts != nports) {
1288                                 DPRINTFN(0, "Number of ports changed\n");
1289                                 goto error;
1290                         }
1291                 }
1292                 break;
1293         default:
1294                 DPRINTF("Assuming HUB has only one port\n");
1295                 /* default number of ports */
1296                 nports = 1;
1297                 /* default power delay */
1298                 pwrdly = ((10 * UHD_PWRON_FACTOR) + usb_extra_power_up_time);
1299                 break;
1300         }
1301         if (nports == 0) {
1302                 DPRINTFN(0, "portless HUB\n");
1303                 goto error;
1304         }
1305         hub = malloc(sizeof(hub[0]) + (sizeof(hub->ports[0]) * nports),
1306             M_USBDEV, M_WAITOK | M_ZERO);
1307
1308         if (hub == NULL) {
1309                 goto error;
1310         }
1311         udev->hub = hub;
1312
1313         /* initialize HUB structure */
1314         hub->hubsoftc = sc;
1315         hub->explore = &uhub_explore;
1316         hub->nports = nports;
1317         hub->hubudev = udev;
1318 #if USB_HAVE_TT_SUPPORT
1319         hub->tt_msg[0].hdr.pm_callback = &uhub_reset_tt_proc;
1320         hub->tt_msg[0].udev = udev;
1321         hub->tt_msg[1].hdr.pm_callback = &uhub_reset_tt_proc;
1322         hub->tt_msg[1].udev = udev;
1323 #endif
1324         /* if self powered hub, give ports maximum current */
1325         if (udev->flags.self_powered) {
1326                 hub->portpower = USB_MAX_POWER;
1327         } else {
1328                 hub->portpower = USB_MIN_POWER;
1329         }
1330
1331         /* set up interrupt pipe */
1332         iface_index = 0;
1333         if (udev->parent_hub == NULL) {
1334                 /* root HUB is special */
1335                 err = 0;
1336         } else {
1337                 /* normal HUB */
1338                 err = usbd_transfer_setup(udev, &iface_index, sc->sc_xfer,
1339                     uhub_config, UHUB_N_TRANSFER, sc, &sc->sc_mtx);
1340         }
1341         if (err) {
1342                 DPRINTFN(0, "cannot setup interrupt transfer, "
1343                     "errstr=%s\n", usbd_errstr(err));
1344                 goto error;
1345         }
1346         /* wait with power off for a while */
1347         usb_pause_mtx(NULL, USB_MS_TO_TICKS(USB_POWER_DOWN_TIME));
1348
1349         /*
1350          * To have the best chance of success we do things in the exact same
1351          * order as Windoze98.  This should not be necessary, but some
1352          * devices do not follow the USB specs to the letter.
1353          *
1354          * These are the events on the bus when a hub is attached:
1355          *  Get device and config descriptors (see attach code)
1356          *  Get hub descriptor (see above)
1357          *  For all ports
1358          *     turn on power
1359          *     wait for power to become stable
1360          * (all below happens in explore code)
1361          *  For all ports
1362          *     clear C_PORT_CONNECTION
1363          *  For all ports
1364          *     get port status
1365          *     if device connected
1366          *        wait 100 ms
1367          *        turn on reset
1368          *        wait
1369          *        clear C_PORT_RESET
1370          *        get port status
1371          *        proceed with device attachment
1372          */
1373
1374         /* XXX should check for none, individual, or ganged power? */
1375
1376         removable = 0;
1377
1378         for (x = 0; x != nports; x++) {
1379                 /* set up data structures */
1380                 struct usb_port *up = hub->ports + x;
1381
1382                 up->device_index = 0;
1383                 up->restartcnt = 0;
1384                 portno = x + 1;
1385
1386                 /* check if port is removable */
1387                 switch (udev->speed) {
1388                 case USB_SPEED_LOW:
1389                 case USB_SPEED_FULL:
1390                 case USB_SPEED_HIGH:
1391                         if (!UHD_NOT_REMOV(&hubdesc20, portno))
1392                                 removable++;
1393                         break;
1394                 case USB_SPEED_SUPER:
1395                         if (!UHD_NOT_REMOV(&hubdesc30, portno))
1396                                 removable++;
1397                         break;
1398                 default:
1399                         DPRINTF("Assuming removable port\n");
1400                         removable++;
1401                         break;
1402                 }
1403                 if (!err) {
1404                         /* turn the power on */
1405                         err = usbd_req_set_port_feature(udev, NULL,
1406                             portno, UHF_PORT_POWER);
1407                 }
1408                 if (err) {
1409                         DPRINTFN(0, "port %d power on failed, %s\n",
1410                             portno, usbd_errstr(err));
1411                 }
1412                 DPRINTF("turn on port %d power\n",
1413                     portno);
1414
1415                 /* wait for stable power */
1416                 usb_pause_mtx(NULL, USB_MS_TO_TICKS(pwrdly));
1417         }
1418
1419         device_printf(dev, "%d port%s with %d "
1420             "removable, %s powered\n", nports, (nports != 1) ? "s" : "",
1421             removable, udev->flags.self_powered ? "self" : "bus");
1422
1423         /* Start the interrupt endpoint, if any */
1424
1425         mtx_lock(&sc->sc_mtx);
1426         usbd_transfer_start(sc->sc_xfer[UHUB_INTR_TRANSFER]);
1427         mtx_unlock(&sc->sc_mtx);
1428
1429         /* Enable automatic power save on all USB HUBs */
1430
1431         usbd_set_power_mode(udev, USB_POWER_MODE_SAVE);
1432
1433         return (0);
1434
1435 error:
1436         usbd_transfer_unsetup(sc->sc_xfer, UHUB_N_TRANSFER);
1437
1438         if (udev->hub) {
1439                 free(udev->hub, M_USBDEV);
1440                 udev->hub = NULL;
1441         }
1442
1443         mtx_destroy(&sc->sc_mtx);
1444
1445         return (ENXIO);
1446 }
1447
1448 /*
1449  * Called from process context when the hub is gone.
1450  * Detach all devices on active ports.
1451  */
1452 static int
1453 uhub_detach(device_t dev)
1454 {
1455         struct uhub_softc *sc = device_get_softc(dev);
1456         struct usb_hub *hub = sc->sc_udev->hub;
1457         struct usb_bus *bus = sc->sc_udev->bus;
1458         struct usb_device *child;
1459         uint8_t x;
1460
1461         if (hub == NULL)                /* must be partially working */
1462                 return (0);
1463
1464         /* Make sure interrupt transfer is gone. */
1465         usbd_transfer_unsetup(sc->sc_xfer, UHUB_N_TRANSFER);
1466
1467         /* Detach all ports */
1468         for (x = 0; x != hub->nports; x++) {
1469
1470                 child = usb_bus_port_get_device(bus, hub->ports + x);
1471
1472                 if (child == NULL) {
1473                         continue;
1474                 }
1475
1476                 /*
1477                  * Free USB device and all subdevices, if any.
1478                  */
1479                 usb_free_device(child, 0);
1480         }
1481
1482 #if USB_HAVE_TT_SUPPORT
1483         /* Make sure our TT messages are not queued anywhere */
1484         USB_BUS_LOCK(bus);
1485         usb_proc_mwait(&bus->non_giant_callback_proc,
1486             &hub->tt_msg[0], &hub->tt_msg[1]);
1487         USB_BUS_UNLOCK(bus);
1488 #endif
1489
1490         free(hub, M_USBDEV);
1491         sc->sc_udev->hub = NULL;
1492
1493         mtx_destroy(&sc->sc_mtx);
1494
1495         return (0);
1496 }
1497
1498 static int
1499 uhub_suspend(device_t dev)
1500 {
1501         DPRINTF("\n");
1502         /* Sub-devices are not suspended here! */
1503         return (0);
1504 }
1505
1506 static int
1507 uhub_resume(device_t dev)
1508 {
1509         DPRINTF("\n");
1510         /* Sub-devices are not resumed here! */
1511         return (0);
1512 }
1513
1514 static void
1515 uhub_driver_added(device_t dev, driver_t *driver)
1516 {
1517         usb_needs_explore_all();
1518 }
1519
1520 struct hub_result {
1521         struct usb_device *udev;
1522         uint8_t portno;
1523         uint8_t iface_index;
1524 };
1525
1526 static void
1527 uhub_find_iface_index(struct usb_hub *hub, device_t child,
1528     struct hub_result *res)
1529 {
1530         struct usb_interface *iface;
1531         struct usb_device *udev;
1532         uint8_t nports;
1533         uint8_t x;
1534         uint8_t i;
1535
1536         nports = hub->nports;
1537         for (x = 0; x != nports; x++) {
1538                 udev = usb_bus_port_get_device(hub->hubudev->bus,
1539                     hub->ports + x);
1540                 if (!udev) {
1541                         continue;
1542                 }
1543                 for (i = 0; i != USB_IFACE_MAX; i++) {
1544                         iface = usbd_get_iface(udev, i);
1545                         if (iface &&
1546                             (iface->subdev == child)) {
1547                                 res->iface_index = i;
1548                                 res->udev = udev;
1549                                 res->portno = x + 1;
1550                                 return;
1551                         }
1552                 }
1553         }
1554         res->iface_index = 0;
1555         res->udev = NULL;
1556         res->portno = 0;
1557 }
1558
1559 static int
1560 uhub_child_location_string(device_t parent, device_t child,
1561     char *buf, size_t buflen)
1562 {
1563         struct uhub_softc *sc;
1564         struct usb_hub *hub;
1565         struct hub_result res;
1566
1567         if (!device_is_attached(parent)) {
1568                 if (buflen)
1569                         buf[0] = 0;
1570                 return (0);
1571         }
1572
1573         sc = device_get_softc(parent);
1574         hub = sc->sc_udev->hub;
1575
1576         mtx_lock(&Giant);
1577         uhub_find_iface_index(hub, child, &res);
1578         if (!res.udev) {
1579                 DPRINTF("device not on hub\n");
1580                 if (buflen) {
1581                         buf[0] = '\0';
1582                 }
1583                 goto done;
1584         }
1585         snprintf(buf, buflen, "bus=%u hubaddr=%u port=%u devaddr=%u interface=%u",
1586             (res.udev->parent_hub != NULL) ? res.udev->parent_hub->device_index : 0,
1587             res.portno, device_get_unit(res.udev->bus->bdev),
1588             res.udev->device_index, res.iface_index);
1589 done:
1590         mtx_unlock(&Giant);
1591
1592         return (0);
1593 }
1594
1595 static int
1596 uhub_child_pnpinfo_string(device_t parent, device_t child,
1597     char *buf, size_t buflen)
1598 {
1599         struct uhub_softc *sc;
1600         struct usb_hub *hub;
1601         struct usb_interface *iface;
1602         struct hub_result res;
1603
1604         if (!device_is_attached(parent)) {
1605                 if (buflen)
1606                         buf[0] = 0;
1607                 return (0);
1608         }
1609
1610         sc = device_get_softc(parent);
1611         hub = sc->sc_udev->hub;
1612
1613         mtx_lock(&Giant);
1614         uhub_find_iface_index(hub, child, &res);
1615         if (!res.udev) {
1616                 DPRINTF("device not on hub\n");
1617                 if (buflen) {
1618                         buf[0] = '\0';
1619                 }
1620                 goto done;
1621         }
1622         iface = usbd_get_iface(res.udev, res.iface_index);
1623         if (iface && iface->idesc) {
1624                 snprintf(buf, buflen, "vendor=0x%04x product=0x%04x "
1625                     "devclass=0x%02x devsubclass=0x%02x "
1626                     "sernum=\"%s\" "
1627                     "release=0x%04x "
1628                     "mode=%s "
1629                     "intclass=0x%02x intsubclass=0x%02x "
1630                     "intprotocol=0x%02x " "%s%s",
1631                     UGETW(res.udev->ddesc.idVendor),
1632                     UGETW(res.udev->ddesc.idProduct),
1633                     res.udev->ddesc.bDeviceClass,
1634                     res.udev->ddesc.bDeviceSubClass,
1635                     usb_get_serial(res.udev),
1636                     UGETW(res.udev->ddesc.bcdDevice),
1637                     (res.udev->flags.usb_mode == USB_MODE_HOST) ? "host" : "device",
1638                     iface->idesc->bInterfaceClass,
1639                     iface->idesc->bInterfaceSubClass,
1640                     iface->idesc->bInterfaceProtocol,
1641                     iface->pnpinfo ? " " : "",
1642                     iface->pnpinfo ? iface->pnpinfo : "");
1643         } else {
1644                 if (buflen) {
1645                         buf[0] = '\0';
1646                 }
1647                 goto done;
1648         }
1649 done:
1650         mtx_unlock(&Giant);
1651
1652         return (0);
1653 }
1654
1655 /*
1656  * The USB Transaction Translator:
1657  * ===============================
1658  *
1659  * When doing LOW- and FULL-speed USB transfers accross a HIGH-speed
1660  * USB HUB, bandwidth must be allocated for ISOCHRONOUS and INTERRUPT
1661  * USB transfers. To utilize bandwidth dynamically the "scatter and
1662  * gather" principle must be applied. This means that bandwidth must
1663  * be divided into equal parts of bandwidth. With regard to USB all
1664  * data is transferred in smaller packets with length
1665  * "wMaxPacketSize". The problem however is that "wMaxPacketSize" is
1666  * not a constant!
1667  *
1668  * The bandwidth scheduler which I have implemented will simply pack
1669  * the USB transfers back to back until there is no more space in the
1670  * schedule. Out of the 8 microframes which the USB 2.0 standard
1671  * provides, only 6 are available for non-HIGH-speed devices. I have
1672  * reserved the first 4 microframes for ISOCHRONOUS transfers. The
1673  * last 2 microframes I have reserved for INTERRUPT transfers. Without
1674  * this division, it is very difficult to allocate and free bandwidth
1675  * dynamically.
1676  *
1677  * NOTE about the Transaction Translator in USB HUBs:
1678  *
1679  * USB HUBs have a very simple Transaction Translator, that will
1680  * simply pipeline all the SPLIT transactions. That means that the
1681  * transactions will be executed in the order they are queued!
1682  *
1683  */
1684
1685 /*------------------------------------------------------------------------*
1686  *      usb_intr_find_best_slot
1687  *
1688  * Return value:
1689  *   The best Transaction Translation slot for an interrupt endpoint.
1690  *------------------------------------------------------------------------*/
1691 static uint8_t
1692 usb_intr_find_best_slot(usb_size_t *ptr, uint8_t start,
1693     uint8_t end, uint8_t mask)
1694 {
1695         usb_size_t min = (usb_size_t)-1;
1696         usb_size_t sum;
1697         uint8_t x;
1698         uint8_t y;
1699         uint8_t z;
1700
1701         y = 0;
1702
1703         /* find the last slot with lesser used bandwidth */
1704
1705         for (x = start; x < end; x++) {
1706
1707                 sum = 0;
1708
1709                 /* compute sum of bandwidth */
1710                 for (z = x; z < end; z++) {
1711                         if (mask & (1U << (z - x)))
1712                                 sum += ptr[z];
1713                 }
1714
1715                 /* check if the current multi-slot is more optimal */
1716                 if (min >= sum) {
1717                         min = sum;
1718                         y = x;
1719                 }
1720
1721                 /* check if the mask is about to be shifted out */
1722                 if (mask & (1U << (end - 1 - x)))
1723                         break;
1724         }
1725         return (y);
1726 }
1727
1728 /*------------------------------------------------------------------------*
1729  *      usb_hs_bandwidth_adjust
1730  *
1731  * This function will update the bandwith usage for the microframe
1732  * having index "slot" by "len" bytes. "len" can be negative.  If the
1733  * "slot" argument is greater or equal to "USB_HS_MICRO_FRAMES_MAX"
1734  * the "slot" argument will be replaced by the slot having least used
1735  * bandwidth. The "mask" argument is used for multi-slot allocations.
1736  *
1737  * Returns:
1738  *    The slot in which the bandwidth update was done: 0..7
1739  *------------------------------------------------------------------------*/
1740 static uint8_t
1741 usb_hs_bandwidth_adjust(struct usb_device *udev, int16_t len,
1742     uint8_t slot, uint8_t mask)
1743 {
1744         struct usb_bus *bus = udev->bus;
1745         struct usb_hub *hub;
1746         enum usb_dev_speed speed;
1747         uint8_t x;
1748
1749         USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
1750
1751         speed = usbd_get_speed(udev);
1752
1753         switch (speed) {
1754         case USB_SPEED_LOW:
1755         case USB_SPEED_FULL:
1756                 if (speed == USB_SPEED_LOW) {
1757                         len *= 8;
1758                 }
1759                 /*
1760                  * The Host Controller Driver should have
1761                  * performed checks so that the lookup
1762                  * below does not result in a NULL pointer
1763                  * access.
1764                  */
1765
1766                 hub = udev->parent_hs_hub->hub;
1767                 if (slot >= USB_HS_MICRO_FRAMES_MAX) {
1768                         slot = usb_intr_find_best_slot(hub->uframe_usage,
1769                             USB_FS_ISOC_UFRAME_MAX, 6, mask);
1770                 }
1771                 for (x = slot; x < 8; x++) {
1772                         if (mask & (1U << (x - slot))) {
1773                                 hub->uframe_usage[x] += len;
1774                                 bus->uframe_usage[x] += len;
1775                         }
1776                 }
1777                 break;
1778         default:
1779                 if (slot >= USB_HS_MICRO_FRAMES_MAX) {
1780                         slot = usb_intr_find_best_slot(bus->uframe_usage, 0,
1781                             USB_HS_MICRO_FRAMES_MAX, mask);
1782                 }
1783                 for (x = slot; x < 8; x++) {
1784                         if (mask & (1U << (x - slot))) {
1785                                 bus->uframe_usage[x] += len;
1786                         }
1787                 }
1788                 break;
1789         }
1790         return (slot);
1791 }
1792
1793 /*------------------------------------------------------------------------*
1794  *      usb_hs_bandwidth_alloc
1795  *
1796  * This function is a wrapper function for "usb_hs_bandwidth_adjust()".
1797  *------------------------------------------------------------------------*/
1798 void
1799 usb_hs_bandwidth_alloc(struct usb_xfer *xfer)
1800 {
1801         struct usb_device *udev;
1802         uint8_t slot;
1803         uint8_t mask;
1804         uint8_t speed;
1805
1806         udev = xfer->xroot->udev;
1807
1808         if (udev->flags.usb_mode != USB_MODE_HOST)
1809                 return;         /* not supported */
1810
1811         xfer->endpoint->refcount_bw++;
1812         if (xfer->endpoint->refcount_bw != 1)
1813                 return;         /* already allocated */
1814
1815         speed = usbd_get_speed(udev);
1816
1817         switch (xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE) {
1818         case UE_INTERRUPT:
1819                 /* allocate a microframe slot */
1820
1821                 mask = 0x01;
1822                 slot = usb_hs_bandwidth_adjust(udev,
1823                     xfer->max_frame_size, USB_HS_MICRO_FRAMES_MAX, mask);
1824
1825                 xfer->endpoint->usb_uframe = slot;
1826                 xfer->endpoint->usb_smask = mask << slot;
1827
1828                 if ((speed != USB_SPEED_FULL) &&
1829                     (speed != USB_SPEED_LOW)) {
1830                         xfer->endpoint->usb_cmask = 0x00 ;
1831                 } else {
1832                         xfer->endpoint->usb_cmask = (-(0x04 << slot)) & 0xFE;
1833                 }
1834                 break;
1835
1836         case UE_ISOCHRONOUS:
1837                 switch (usbd_xfer_get_fps_shift(xfer)) {
1838                 case 0:
1839                         mask = 0xFF;
1840                         break;
1841                 case 1:
1842                         mask = 0x55;
1843                         break;
1844                 case 2:
1845                         mask = 0x11;
1846                         break;
1847                 default:
1848                         mask = 0x01;
1849                         break;
1850                 }
1851
1852                 /* allocate a microframe multi-slot */
1853
1854                 slot = usb_hs_bandwidth_adjust(udev,
1855                     xfer->max_frame_size, USB_HS_MICRO_FRAMES_MAX, mask);
1856
1857                 xfer->endpoint->usb_uframe = slot;
1858                 xfer->endpoint->usb_cmask = 0;
1859                 xfer->endpoint->usb_smask = mask << slot;
1860                 break;
1861
1862         default:
1863                 xfer->endpoint->usb_uframe = 0;
1864                 xfer->endpoint->usb_cmask = 0;
1865                 xfer->endpoint->usb_smask = 0;
1866                 break;
1867         }
1868
1869         DPRINTFN(11, "slot=%d, mask=0x%02x\n", 
1870             xfer->endpoint->usb_uframe, 
1871             xfer->endpoint->usb_smask >> xfer->endpoint->usb_uframe);
1872 }
1873
1874 /*------------------------------------------------------------------------*
1875  *      usb_hs_bandwidth_free
1876  *
1877  * This function is a wrapper function for "usb_hs_bandwidth_adjust()".
1878  *------------------------------------------------------------------------*/
1879 void
1880 usb_hs_bandwidth_free(struct usb_xfer *xfer)
1881 {
1882         struct usb_device *udev;
1883         uint8_t slot;
1884         uint8_t mask;
1885
1886         udev = xfer->xroot->udev;
1887
1888         if (udev->flags.usb_mode != USB_MODE_HOST)
1889                 return;         /* not supported */
1890
1891         xfer->endpoint->refcount_bw--;
1892         if (xfer->endpoint->refcount_bw != 0)
1893                 return;         /* still allocated */
1894
1895         switch (xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE) {
1896         case UE_INTERRUPT:
1897         case UE_ISOCHRONOUS:
1898
1899                 slot = xfer->endpoint->usb_uframe;
1900                 mask = xfer->endpoint->usb_smask;
1901
1902                 /* free microframe slot(s): */    
1903                 usb_hs_bandwidth_adjust(udev,
1904                     -xfer->max_frame_size, slot, mask >> slot);
1905
1906                 DPRINTFN(11, "slot=%d, mask=0x%02x\n", 
1907                     slot, mask >> slot);
1908
1909                 xfer->endpoint->usb_uframe = 0;
1910                 xfer->endpoint->usb_cmask = 0;
1911                 xfer->endpoint->usb_smask = 0;
1912                 break;
1913
1914         default:
1915                 break;
1916         }
1917 }
1918
1919 /*------------------------------------------------------------------------*
1920  *      usb_isoc_time_expand
1921  *
1922  * This function will expand the time counter from 7-bit to 16-bit.
1923  *
1924  * Returns:
1925  *   16-bit isochronous time counter.
1926  *------------------------------------------------------------------------*/
1927 uint16_t
1928 usb_isoc_time_expand(struct usb_bus *bus, uint16_t isoc_time_curr)
1929 {
1930         uint16_t rem;
1931
1932         USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
1933
1934         rem = bus->isoc_time_last & (USB_ISOC_TIME_MAX - 1);
1935
1936         isoc_time_curr &= (USB_ISOC_TIME_MAX - 1);
1937
1938         if (isoc_time_curr < rem) {
1939                 /* the time counter wrapped around */
1940                 bus->isoc_time_last += USB_ISOC_TIME_MAX;
1941         }
1942         /* update the remainder */
1943
1944         bus->isoc_time_last &= ~(USB_ISOC_TIME_MAX - 1);
1945         bus->isoc_time_last |= isoc_time_curr;
1946
1947         return (bus->isoc_time_last);
1948 }
1949
1950 /*------------------------------------------------------------------------*
1951  *      usbd_fs_isoc_schedule_alloc_slot
1952  *
1953  * This function will allocate bandwidth for an isochronous FULL speed
1954  * transaction in the FULL speed schedule.
1955  *
1956  * Returns:
1957  *    <8: Success
1958  * Else: Error
1959  *------------------------------------------------------------------------*/
1960 #if USB_HAVE_TT_SUPPORT
1961 uint8_t
1962 usbd_fs_isoc_schedule_alloc_slot(struct usb_xfer *isoc_xfer, uint16_t isoc_time)
1963 {
1964         struct usb_xfer *xfer;
1965         struct usb_xfer *pipe_xfer;
1966         struct usb_bus *bus;
1967         usb_frlength_t len;
1968         usb_frlength_t data_len;
1969         uint16_t delta;
1970         uint16_t slot;
1971         uint8_t retval;
1972
1973         data_len = 0;
1974         slot = 0;
1975
1976         bus = isoc_xfer->xroot->bus;
1977
1978         TAILQ_FOREACH(xfer, &bus->intr_q.head, wait_entry) {
1979
1980                 /* skip self, if any */
1981
1982                 if (xfer == isoc_xfer)
1983                         continue;
1984
1985                 /* check if this USB transfer is going through the same TT */
1986
1987                 if (xfer->xroot->udev->parent_hs_hub !=
1988                     isoc_xfer->xroot->udev->parent_hs_hub) {
1989                         continue;
1990                 }
1991                 if ((isoc_xfer->xroot->udev->parent_hs_hub->
1992                     ddesc.bDeviceProtocol == UDPROTO_HSHUBMTT) &&
1993                     (xfer->xroot->udev->hs_port_no !=
1994                     isoc_xfer->xroot->udev->hs_port_no)) {
1995                         continue;
1996                 }
1997                 if (xfer->endpoint->methods != isoc_xfer->endpoint->methods)
1998                         continue;
1999
2000                 /* check if isoc_time is part of this transfer */
2001
2002                 delta = xfer->isoc_time_complete - isoc_time;
2003                 if (delta > 0 && delta <= xfer->nframes) {
2004                         delta = xfer->nframes - delta;
2005
2006                         len = xfer->frlengths[delta];
2007                         len += 8;
2008                         len *= 7;
2009                         len /= 6;
2010
2011                         data_len += len;
2012                 }
2013
2014                 /* check double buffered transfers */
2015
2016                 TAILQ_FOREACH(pipe_xfer, &xfer->endpoint->endpoint_q.head,
2017                     wait_entry) {
2018
2019                         /* skip self, if any */
2020
2021                         if (pipe_xfer == isoc_xfer)
2022                                 continue;
2023
2024                         /* check if isoc_time is part of this transfer */
2025
2026                         delta = pipe_xfer->isoc_time_complete - isoc_time;
2027                         if (delta > 0 && delta <= pipe_xfer->nframes) {
2028                                 delta = pipe_xfer->nframes - delta;
2029
2030                                 len = pipe_xfer->frlengths[delta];
2031                                 len += 8;
2032                                 len *= 7;
2033                                 len /= 6;
2034
2035                                 data_len += len;
2036                         }
2037                 }
2038         }
2039
2040         while (data_len >= USB_FS_BYTES_PER_HS_UFRAME) {
2041                 data_len -= USB_FS_BYTES_PER_HS_UFRAME;
2042                 slot++;
2043         }
2044
2045         /* check for overflow */
2046
2047         if (slot >= USB_FS_ISOC_UFRAME_MAX)
2048                 return (255);
2049
2050         retval = slot;
2051
2052         delta = isoc_xfer->isoc_time_complete - isoc_time;
2053         if (delta > 0 && delta <= isoc_xfer->nframes) {
2054                 delta = isoc_xfer->nframes - delta;
2055
2056                 len = isoc_xfer->frlengths[delta];
2057                 len += 8;
2058                 len *= 7;
2059                 len /= 6;
2060
2061                 data_len += len;
2062         }
2063
2064         while (data_len >= USB_FS_BYTES_PER_HS_UFRAME) {
2065                 data_len -= USB_FS_BYTES_PER_HS_UFRAME;
2066                 slot++;
2067         }
2068
2069         /* check for overflow */
2070
2071         if (slot >= USB_FS_ISOC_UFRAME_MAX)
2072                 return (255);
2073
2074         return (retval);
2075 }
2076 #endif
2077
2078 /*------------------------------------------------------------------------*
2079  *      usb_bus_port_get_device
2080  *
2081  * This function is NULL safe.
2082  *------------------------------------------------------------------------*/
2083 struct usb_device *
2084 usb_bus_port_get_device(struct usb_bus *bus, struct usb_port *up)
2085 {
2086         if ((bus == NULL) || (up == NULL)) {
2087                 /* be NULL safe */
2088                 return (NULL);
2089         }
2090         if (up->device_index == 0) {
2091                 /* nothing to do */
2092                 return (NULL);
2093         }
2094         return (bus->devices[up->device_index]);
2095 }
2096
2097 /*------------------------------------------------------------------------*
2098  *      usb_bus_port_set_device
2099  *
2100  * This function is NULL safe.
2101  *------------------------------------------------------------------------*/
2102 void
2103 usb_bus_port_set_device(struct usb_bus *bus, struct usb_port *up,
2104     struct usb_device *udev, uint8_t device_index)
2105 {
2106         if (bus == NULL) {
2107                 /* be NULL safe */
2108                 return;
2109         }
2110         /*
2111          * There is only one case where we don't
2112          * have an USB port, and that is the Root Hub!
2113          */
2114         if (up) {
2115                 if (udev) {
2116                         up->device_index = device_index;
2117                 } else {
2118                         device_index = up->device_index;
2119                         up->device_index = 0;
2120                 }
2121         }
2122         /*
2123          * Make relationships to our new device
2124          */
2125         if (device_index != 0) {
2126 #if USB_HAVE_UGEN
2127                 mtx_lock(&usb_ref_lock);
2128 #endif
2129                 bus->devices[device_index] = udev;
2130 #if USB_HAVE_UGEN
2131                 mtx_unlock(&usb_ref_lock);
2132 #endif
2133         }
2134         /*
2135          * Debug print
2136          */
2137         DPRINTFN(2, "bus %p devices[%u] = %p\n", bus, device_index, udev);
2138 }
2139
2140 /*------------------------------------------------------------------------*
2141  *      usb_needs_explore
2142  *
2143  * This functions is called when the USB event thread needs to run.
2144  *------------------------------------------------------------------------*/
2145 void
2146 usb_needs_explore(struct usb_bus *bus, uint8_t do_probe)
2147 {
2148         uint8_t do_unlock;
2149
2150         DPRINTF("\n");
2151
2152         if (bus == NULL) {
2153                 DPRINTF("No bus pointer!\n");
2154                 return;
2155         }
2156         if ((bus->devices == NULL) ||
2157             (bus->devices[USB_ROOT_HUB_ADDR] == NULL)) {
2158                 DPRINTF("No root HUB\n");
2159                 return;
2160         }
2161         if (mtx_owned(&bus->bus_mtx)) {
2162                 do_unlock = 0;
2163         } else {
2164                 USB_BUS_LOCK(bus);
2165                 do_unlock = 1;
2166         }
2167         if (do_probe) {
2168                 bus->do_probe = 1;
2169         }
2170         if (usb_proc_msignal(&bus->explore_proc,
2171             &bus->explore_msg[0], &bus->explore_msg[1])) {
2172                 /* ignore */
2173         }
2174         if (do_unlock) {
2175                 USB_BUS_UNLOCK(bus);
2176         }
2177 }
2178
2179 /*------------------------------------------------------------------------*
2180  *      usb_needs_explore_all
2181  *
2182  * This function is called whenever a new driver is loaded and will
2183  * cause that all USB busses are re-explored.
2184  *------------------------------------------------------------------------*/
2185 void
2186 usb_needs_explore_all(void)
2187 {
2188         struct usb_bus *bus;
2189         devclass_t dc;
2190         device_t dev;
2191         int max;
2192
2193         DPRINTFN(3, "\n");
2194
2195         dc = usb_devclass_ptr;
2196         if (dc == NULL) {
2197                 DPRINTFN(0, "no devclass\n");
2198                 return;
2199         }
2200         /*
2201          * Explore all USB busses in parallell.
2202          */
2203         max = devclass_get_maxunit(dc);
2204         while (max >= 0) {
2205                 dev = devclass_get_device(dc, max);
2206                 if (dev) {
2207                         bus = device_get_softc(dev);
2208                         if (bus) {
2209                                 usb_needs_explore(bus, 1);
2210                         }
2211                 }
2212                 max--;
2213         }
2214 }
2215
2216 /*------------------------------------------------------------------------*
2217  *      usb_bus_power_update
2218  *
2219  * This function will ensure that all USB devices on the given bus are
2220  * properly suspended or resumed according to the device transfer
2221  * state.
2222  *------------------------------------------------------------------------*/
2223 #if USB_HAVE_POWERD
2224 void
2225 usb_bus_power_update(struct usb_bus *bus)
2226 {
2227         usb_needs_explore(bus, 0 /* no probe */ );
2228 }
2229 #endif
2230
2231 /*------------------------------------------------------------------------*
2232  *      usbd_transfer_power_ref
2233  *
2234  * This function will modify the power save reference counts and
2235  * wakeup the USB device associated with the given USB transfer, if
2236  * needed.
2237  *------------------------------------------------------------------------*/
2238 #if USB_HAVE_POWERD
2239 void
2240 usbd_transfer_power_ref(struct usb_xfer *xfer, int val)
2241 {
2242         static const usb_power_mask_t power_mask[4] = {
2243                 [UE_CONTROL] = USB_HW_POWER_CONTROL,
2244                 [UE_BULK] = USB_HW_POWER_BULK,
2245                 [UE_INTERRUPT] = USB_HW_POWER_INTERRUPT,
2246                 [UE_ISOCHRONOUS] = USB_HW_POWER_ISOC,
2247         };
2248         struct usb_device *udev;
2249         uint8_t needs_explore;
2250         uint8_t needs_hw_power;
2251         uint8_t xfer_type;
2252
2253         udev = xfer->xroot->udev;
2254
2255         if (udev->device_index == USB_ROOT_HUB_ADDR) {
2256                 /* no power save for root HUB */
2257                 return;
2258         }
2259         USB_BUS_LOCK(udev->bus);
2260
2261         xfer_type = xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE;
2262
2263         udev->pwr_save.last_xfer_time = ticks;
2264         udev->pwr_save.type_refs[xfer_type] += val;
2265
2266         if (xfer->flags_int.control_xfr) {
2267                 udev->pwr_save.read_refs += val;
2268                 if (xfer->flags_int.usb_mode == USB_MODE_HOST) {
2269                         /*
2270                          * It is not allowed to suspend during a
2271                          * control transfer:
2272                          */
2273                         udev->pwr_save.write_refs += val;
2274                 }
2275         } else if (USB_GET_DATA_ISREAD(xfer)) {
2276                 udev->pwr_save.read_refs += val;
2277         } else {
2278                 udev->pwr_save.write_refs += val;
2279         }
2280
2281         if (val > 0) {
2282                 if (udev->flags.self_suspended)
2283                         needs_explore = usb_peer_should_wakeup(udev);
2284                 else
2285                         needs_explore = 0;
2286
2287                 if (!(udev->bus->hw_power_state & power_mask[xfer_type])) {
2288                         DPRINTF("Adding type %u to power state\n", xfer_type);
2289                         udev->bus->hw_power_state |= power_mask[xfer_type];
2290                         needs_hw_power = 1;
2291                 } else {
2292                         needs_hw_power = 0;
2293                 }
2294         } else {
2295                 needs_explore = 0;
2296                 needs_hw_power = 0;
2297         }
2298
2299         USB_BUS_UNLOCK(udev->bus);
2300
2301         if (needs_explore) {
2302                 DPRINTF("update\n");
2303                 usb_bus_power_update(udev->bus);
2304         } else if (needs_hw_power) {
2305                 DPRINTF("needs power\n");
2306                 if (udev->bus->methods->set_hw_power != NULL) {
2307                         (udev->bus->methods->set_hw_power) (udev->bus);
2308                 }
2309         }
2310 }
2311 #endif
2312
2313 /*------------------------------------------------------------------------*
2314  *      usb_peer_should_wakeup
2315  *
2316  * This function returns non-zero if the current device should wake up.
2317  *------------------------------------------------------------------------*/
2318 static uint8_t
2319 usb_peer_should_wakeup(struct usb_device *udev)
2320 {
2321         return (((udev->power_mode == USB_POWER_MODE_ON) &&
2322             (udev->flags.usb_mode == USB_MODE_HOST)) ||
2323             (udev->driver_added_refcount != udev->bus->driver_added_refcount) ||
2324             (udev->re_enumerate_wait != USB_RE_ENUM_DONE) ||
2325             (udev->pwr_save.type_refs[UE_ISOCHRONOUS] != 0) ||
2326             (udev->pwr_save.write_refs != 0) ||
2327             ((udev->pwr_save.read_refs != 0) &&
2328             (udev->flags.usb_mode == USB_MODE_HOST) &&
2329             (usb_peer_can_wakeup(udev) == 0)));
2330 }
2331
2332 /*------------------------------------------------------------------------*
2333  *      usb_bus_powerd
2334  *
2335  * This function implements the USB power daemon and is called
2336  * regularly from the USB explore thread.
2337  *------------------------------------------------------------------------*/
2338 #if USB_HAVE_POWERD
2339 void
2340 usb_bus_powerd(struct usb_bus *bus)
2341 {
2342         struct usb_device *udev;
2343         usb_ticks_t temp;
2344         usb_ticks_t limit;
2345         usb_ticks_t mintime;
2346         usb_size_t type_refs[5];
2347         uint8_t x;
2348
2349         limit = usb_power_timeout;
2350         if (limit == 0)
2351                 limit = hz;
2352         else if (limit > 255)
2353                 limit = 255 * hz;
2354         else
2355                 limit = limit * hz;
2356
2357         DPRINTF("bus=%p\n", bus);
2358
2359         USB_BUS_LOCK(bus);
2360
2361         /*
2362          * The root HUB device is never suspended
2363          * and we simply skip it.
2364          */
2365         for (x = USB_ROOT_HUB_ADDR + 1;
2366             x != bus->devices_max; x++) {
2367
2368                 udev = bus->devices[x];
2369                 if (udev == NULL)
2370                         continue;
2371
2372                 temp = ticks - udev->pwr_save.last_xfer_time;
2373
2374                 if (usb_peer_should_wakeup(udev)) {
2375                         /* check if we are suspended */
2376                         if (udev->flags.self_suspended != 0) {
2377                                 USB_BUS_UNLOCK(bus);
2378                                 usb_dev_resume_peer(udev);
2379                                 USB_BUS_LOCK(bus);
2380                         }
2381                 } else if ((temp >= limit) &&
2382                     (udev->flags.usb_mode == USB_MODE_HOST) &&
2383                     (udev->flags.self_suspended == 0)) {
2384                         /* try to do suspend */
2385
2386                         USB_BUS_UNLOCK(bus);
2387                         usb_dev_suspend_peer(udev);
2388                         USB_BUS_LOCK(bus);
2389                 }
2390         }
2391
2392         /* reset counters */
2393
2394         mintime = (usb_ticks_t)-1;
2395         type_refs[0] = 0;
2396         type_refs[1] = 0;
2397         type_refs[2] = 0;
2398         type_refs[3] = 0;
2399         type_refs[4] = 0;
2400
2401         /* Re-loop all the devices to get the actual state */
2402
2403         for (x = USB_ROOT_HUB_ADDR + 1;
2404             x != bus->devices_max; x++) {
2405
2406                 udev = bus->devices[x];
2407                 if (udev == NULL)
2408                         continue;
2409
2410                 /* we found a non-Root-Hub USB device */
2411                 type_refs[4] += 1;
2412
2413                 /* "last_xfer_time" can be updated by a resume */
2414                 temp = ticks - udev->pwr_save.last_xfer_time;
2415
2416                 /*
2417                  * Compute minimum time since last transfer for the complete
2418                  * bus:
2419                  */
2420                 if (temp < mintime)
2421                         mintime = temp;
2422
2423                 if (udev->flags.self_suspended == 0) {
2424                         type_refs[0] += udev->pwr_save.type_refs[0];
2425                         type_refs[1] += udev->pwr_save.type_refs[1];
2426                         type_refs[2] += udev->pwr_save.type_refs[2];
2427                         type_refs[3] += udev->pwr_save.type_refs[3];
2428                 }
2429         }
2430
2431         if (mintime >= (usb_ticks_t)(1 * hz)) {
2432                 /* recompute power masks */
2433                 DPRINTF("Recomputing power masks\n");
2434                 bus->hw_power_state = 0;
2435                 if (type_refs[UE_CONTROL] != 0)
2436                         bus->hw_power_state |= USB_HW_POWER_CONTROL;
2437                 if (type_refs[UE_BULK] != 0)
2438                         bus->hw_power_state |= USB_HW_POWER_BULK;
2439                 if (type_refs[UE_INTERRUPT] != 0)
2440                         bus->hw_power_state |= USB_HW_POWER_INTERRUPT;
2441                 if (type_refs[UE_ISOCHRONOUS] != 0)
2442                         bus->hw_power_state |= USB_HW_POWER_ISOC;
2443                 if (type_refs[4] != 0)
2444                         bus->hw_power_state |= USB_HW_POWER_NON_ROOT_HUB;
2445         }
2446         USB_BUS_UNLOCK(bus);
2447
2448         if (bus->methods->set_hw_power != NULL) {
2449                 /* always update hardware power! */
2450                 (bus->methods->set_hw_power) (bus);
2451         }
2452         return;
2453 }
2454 #endif
2455
2456 /*------------------------------------------------------------------------*
2457  *      usb_dev_resume_peer
2458  *
2459  * This function will resume an USB peer and do the required USB
2460  * signalling to get an USB device out of the suspended state.
2461  *------------------------------------------------------------------------*/
2462 static void
2463 usb_dev_resume_peer(struct usb_device *udev)
2464 {
2465         struct usb_bus *bus;
2466         int err;
2467
2468         /* be NULL safe */
2469         if (udev == NULL)
2470                 return;
2471
2472         /* check if already resumed */
2473         if (udev->flags.self_suspended == 0)
2474                 return;
2475
2476         /* we need a parent HUB to do resume */
2477         if (udev->parent_hub == NULL)
2478                 return;
2479
2480         DPRINTF("udev=%p\n", udev);
2481
2482         if ((udev->flags.usb_mode == USB_MODE_DEVICE) &&
2483             (udev->flags.remote_wakeup == 0)) {
2484                 /*
2485                  * If the host did not set the remote wakeup feature, we can
2486                  * not wake it up either!
2487                  */
2488                 DPRINTF("remote wakeup is not set!\n");
2489                 return;
2490         }
2491         /* get bus pointer */
2492         bus = udev->bus;
2493
2494         /* resume parent hub first */
2495         usb_dev_resume_peer(udev->parent_hub);
2496
2497         /* reduce chance of instant resume failure by waiting a little bit */
2498         usb_pause_mtx(NULL, USB_MS_TO_TICKS(20));
2499
2500         if (usb_device_20_compatible(udev)) {
2501                 /* resume current port (Valid in Host and Device Mode) */
2502                 err = usbd_req_clear_port_feature(udev->parent_hub,
2503                     NULL, udev->port_no, UHF_PORT_SUSPEND);
2504                 if (err) {
2505                         DPRINTFN(0, "Resuming port failed\n");
2506                         return;
2507                 }
2508         } else {
2509                 /* resume current port (Valid in Host and Device Mode) */
2510                 err = usbd_req_set_port_link_state(udev->parent_hub,
2511                     NULL, udev->port_no, UPS_PORT_LS_U0);
2512                 if (err) {
2513                         DPRINTFN(0, "Resuming port failed\n");
2514                         return;
2515                 }
2516         }
2517
2518         /* resume settle time */
2519         usb_pause_mtx(NULL, USB_MS_TO_TICKS(usb_port_resume_delay));
2520
2521         if (bus->methods->device_resume != NULL) {
2522                 /* resume USB device on the USB controller */
2523                 (bus->methods->device_resume) (udev);
2524         }
2525         USB_BUS_LOCK(bus);
2526         /* set that this device is now resumed */
2527         udev->flags.self_suspended = 0;
2528 #if USB_HAVE_POWERD
2529         /* make sure that we don't go into suspend right away */
2530         udev->pwr_save.last_xfer_time = ticks;
2531
2532         /* make sure the needed power masks are on */
2533         if (udev->pwr_save.type_refs[UE_CONTROL] != 0)
2534                 bus->hw_power_state |= USB_HW_POWER_CONTROL;
2535         if (udev->pwr_save.type_refs[UE_BULK] != 0)
2536                 bus->hw_power_state |= USB_HW_POWER_BULK;
2537         if (udev->pwr_save.type_refs[UE_INTERRUPT] != 0)
2538                 bus->hw_power_state |= USB_HW_POWER_INTERRUPT;
2539         if (udev->pwr_save.type_refs[UE_ISOCHRONOUS] != 0)
2540                 bus->hw_power_state |= USB_HW_POWER_ISOC;
2541 #endif
2542         USB_BUS_UNLOCK(bus);
2543
2544         if (bus->methods->set_hw_power != NULL) {
2545                 /* always update hardware power! */
2546                 (bus->methods->set_hw_power) (bus);
2547         }
2548
2549         usbd_sr_lock(udev);
2550
2551         /* notify all sub-devices about resume */
2552         err = usb_suspend_resume(udev, 0);
2553
2554         usbd_sr_unlock(udev);
2555
2556         /* check if peer has wakeup capability */
2557         if (usb_peer_can_wakeup(udev)) {
2558                 /* clear remote wakeup */
2559                 err = usbd_req_clear_device_feature(udev,
2560                     NULL, UF_DEVICE_REMOTE_WAKEUP);
2561                 if (err) {
2562                         DPRINTFN(0, "Clearing device "
2563                             "remote wakeup failed: %s\n",
2564                             usbd_errstr(err));
2565                 }
2566         }
2567 }
2568
2569 /*------------------------------------------------------------------------*
2570  *      usb_dev_suspend_peer
2571  *
2572  * This function will suspend an USB peer and do the required USB
2573  * signalling to get an USB device into the suspended state.
2574  *------------------------------------------------------------------------*/
2575 static void
2576 usb_dev_suspend_peer(struct usb_device *udev)
2577 {
2578         struct usb_device *child;
2579         int err;
2580         uint8_t x;
2581         uint8_t nports;
2582
2583 repeat:
2584         /* be NULL safe */
2585         if (udev == NULL)
2586                 return;
2587
2588         /* check if already suspended */
2589         if (udev->flags.self_suspended)
2590                 return;
2591
2592         /* we need a parent HUB to do suspend */
2593         if (udev->parent_hub == NULL)
2594                 return;
2595
2596         DPRINTF("udev=%p\n", udev);
2597
2598         /* check if the current device is a HUB */
2599         if (udev->hub != NULL) {
2600                 nports = udev->hub->nports;
2601
2602                 /* check if all devices on the HUB are suspended */
2603                 for (x = 0; x != nports; x++) {
2604                         child = usb_bus_port_get_device(udev->bus,
2605                             udev->hub->ports + x);
2606
2607                         if (child == NULL)
2608                                 continue;
2609
2610                         if (child->flags.self_suspended)
2611                                 continue;
2612
2613                         DPRINTFN(1, "Port %u is busy on the HUB!\n", x + 1);
2614                         return;
2615                 }
2616         }
2617
2618         if (usb_peer_can_wakeup(udev)) {
2619                 /*
2620                  * This request needs to be done before we set
2621                  * "udev->flags.self_suspended":
2622                  */
2623
2624                 /* allow device to do remote wakeup */
2625                 err = usbd_req_set_device_feature(udev,
2626                     NULL, UF_DEVICE_REMOTE_WAKEUP);
2627                 if (err) {
2628                         DPRINTFN(0, "Setting device "
2629                             "remote wakeup failed\n");
2630                 }
2631         }
2632
2633         USB_BUS_LOCK(udev->bus);
2634         /*
2635          * Checking for suspend condition and setting suspended bit
2636          * must be atomic!
2637          */
2638         err = usb_peer_should_wakeup(udev);
2639         if (err == 0) {
2640                 /*
2641                  * Set that this device is suspended. This variable
2642                  * must be set before calling USB controller suspend
2643                  * callbacks.
2644                  */
2645                 udev->flags.self_suspended = 1;
2646         }
2647         USB_BUS_UNLOCK(udev->bus);
2648
2649         if (err != 0) {
2650                 if (usb_peer_can_wakeup(udev)) {
2651                         /* allow device to do remote wakeup */
2652                         err = usbd_req_clear_device_feature(udev,
2653                             NULL, UF_DEVICE_REMOTE_WAKEUP);
2654                         if (err) {
2655                                 DPRINTFN(0, "Setting device "
2656                                     "remote wakeup failed\n");
2657                         }
2658                 }
2659
2660                 if (udev->flags.usb_mode == USB_MODE_DEVICE) {
2661                         /* resume parent HUB first */
2662                         usb_dev_resume_peer(udev->parent_hub);
2663
2664                         /* reduce chance of instant resume failure by waiting a little bit */
2665                         usb_pause_mtx(NULL, USB_MS_TO_TICKS(20));
2666
2667                         /* resume current port (Valid in Host and Device Mode) */
2668                         err = usbd_req_clear_port_feature(udev->parent_hub,
2669                             NULL, udev->port_no, UHF_PORT_SUSPEND);
2670
2671                         /* resume settle time */
2672                         usb_pause_mtx(NULL, USB_MS_TO_TICKS(usb_port_resume_delay));
2673                 }
2674                 DPRINTF("Suspend was cancelled!\n");
2675                 return;
2676         }
2677
2678         usbd_sr_lock(udev);
2679
2680         /* notify all sub-devices about suspend */
2681         err = usb_suspend_resume(udev, 1);
2682
2683         usbd_sr_unlock(udev);
2684
2685         if (udev->bus->methods->device_suspend != NULL) {
2686                 usb_timeout_t temp;
2687
2688                 /* suspend device on the USB controller */
2689                 (udev->bus->methods->device_suspend) (udev);
2690
2691                 /* do DMA delay */
2692                 temp = usbd_get_dma_delay(udev);
2693                 if (temp != 0)
2694                         usb_pause_mtx(NULL, USB_MS_TO_TICKS(temp));
2695
2696         }
2697
2698         if (usb_device_20_compatible(udev)) {
2699                 /* suspend current port */
2700                 err = usbd_req_set_port_feature(udev->parent_hub,
2701                     NULL, udev->port_no, UHF_PORT_SUSPEND);
2702                 if (err) {
2703                         DPRINTFN(0, "Suspending port failed\n");
2704                         return;
2705                 }
2706         } else {
2707                 /* suspend current port */
2708                 err = usbd_req_set_port_link_state(udev->parent_hub,
2709                     NULL, udev->port_no, UPS_PORT_LS_U3);
2710                 if (err) {
2711                         DPRINTFN(0, "Suspending port failed\n");
2712                         return;
2713                 }
2714         }
2715
2716         udev = udev->parent_hub;
2717         goto repeat;
2718 }
2719
2720 /*------------------------------------------------------------------------*
2721  *      usbd_set_power_mode
2722  *
2723  * This function will set the power mode, see USB_POWER_MODE_XXX for a
2724  * USB device.
2725  *------------------------------------------------------------------------*/
2726 void
2727 usbd_set_power_mode(struct usb_device *udev, uint8_t power_mode)
2728 {
2729         /* filter input argument */
2730         if ((power_mode != USB_POWER_MODE_ON) &&
2731             (power_mode != USB_POWER_MODE_OFF))
2732                 power_mode = USB_POWER_MODE_SAVE;
2733
2734         power_mode = usbd_filter_power_mode(udev, power_mode);  
2735
2736         udev->power_mode = power_mode;  /* update copy of power mode */
2737
2738 #if USB_HAVE_POWERD
2739         usb_bus_power_update(udev->bus);
2740 #else
2741         usb_needs_explore(udev->bus, 0 /* no probe */ );
2742 #endif
2743 }
2744
2745 /*------------------------------------------------------------------------*
2746  *      usbd_filter_power_mode
2747  *
2748  * This function filters the power mode based on hardware requirements.
2749  *------------------------------------------------------------------------*/
2750 uint8_t
2751 usbd_filter_power_mode(struct usb_device *udev, uint8_t power_mode)
2752 {
2753         struct usb_bus_methods *mtod;
2754         int8_t temp;
2755
2756         mtod = udev->bus->methods;
2757         temp = -1;
2758
2759         if (mtod->get_power_mode != NULL)
2760                 (mtod->get_power_mode) (udev, &temp);
2761
2762         /* check if we should not filter */
2763         if (temp < 0)
2764                 return (power_mode);
2765
2766         /* use fixed power mode given by hardware driver */
2767         return (temp);
2768 }
2769
2770 /*------------------------------------------------------------------------*
2771  *      usbd_start_re_enumerate
2772  *
2773  * This function starts re-enumeration of the given USB device. This
2774  * function does not need to be called BUS-locked. This function does
2775  * not wait until the re-enumeration is completed.
2776  *------------------------------------------------------------------------*/
2777 void
2778 usbd_start_re_enumerate(struct usb_device *udev)
2779 {
2780         if (udev->re_enumerate_wait == USB_RE_ENUM_DONE) {
2781                 udev->re_enumerate_wait = USB_RE_ENUM_START;
2782                 usb_needs_explore(udev->bus, 0);
2783         }
2784 }