The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/usb_hub.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 0a6fcb6ee565b6c1a0200519f3a459c9


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.