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-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

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

Cache object: 88280954950e74f15967a8eb92dcc90d


[ 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.