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