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

Cache object: 8a971f1d16d95a32d1703b3b2e74408d


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