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


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

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

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

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

Cache object: 8ee6efdddcc0584dc3c026090577afdb


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