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

Cache object: 55853a6157f7b649f1290ffe49eaf86a


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