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/controller/uhci.c

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

    1 /* $FreeBSD$ */
    2 /*-
    3  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    4  *
    5  * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
    6  * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
    7  * Copyright (c) 1998 Lennart Augustsson. All rights reserved.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   28  * SUCH DAMAGE.
   29  */
   30 
   31 /*
   32  * USB Universal Host Controller driver.
   33  * Handles e.g. PIIX3 and PIIX4.
   34  *
   35  * UHCI spec: http://developer.intel.com/design/USB/UHCI11D.htm
   36  * USB spec:  http://www.usb.org/developers/docs/usbspec.zip
   37  * PIIXn spec: ftp://download.intel.com/design/intarch/datashts/29055002.pdf
   38  *             ftp://download.intel.com/design/intarch/datashts/29056201.pdf
   39  */
   40 
   41 #ifdef USB_GLOBAL_INCLUDE_FILE
   42 #include USB_GLOBAL_INCLUDE_FILE
   43 #else
   44 #include <sys/stdint.h>
   45 #include <sys/stddef.h>
   46 #include <sys/param.h>
   47 #include <sys/queue.h>
   48 #include <sys/types.h>
   49 #include <sys/systm.h>
   50 #include <sys/kernel.h>
   51 #include <sys/bus.h>
   52 #include <sys/module.h>
   53 #include <sys/lock.h>
   54 #include <sys/mutex.h>
   55 #include <sys/condvar.h>
   56 #include <sys/sysctl.h>
   57 #include <sys/sx.h>
   58 #include <sys/unistd.h>
   59 #include <sys/callout.h>
   60 #include <sys/malloc.h>
   61 #include <sys/priv.h>
   62 
   63 #include <dev/usb/usb.h>
   64 #include <dev/usb/usbdi.h>
   65 
   66 #define USB_DEBUG_VAR uhcidebug
   67 
   68 #include <dev/usb/usb_core.h>
   69 #include <dev/usb/usb_debug.h>
   70 #include <dev/usb/usb_busdma.h>
   71 #include <dev/usb/usb_process.h>
   72 #include <dev/usb/usb_transfer.h>
   73 #include <dev/usb/usb_device.h>
   74 #include <dev/usb/usb_hub.h>
   75 #include <dev/usb/usb_util.h>
   76 
   77 #include <dev/usb/usb_controller.h>
   78 #include <dev/usb/usb_bus.h>
   79 #endif                  /* USB_GLOBAL_INCLUDE_FILE */
   80 
   81 #include <dev/usb/controller/uhci.h>
   82 #include <dev/usb/controller/uhcireg.h>
   83 
   84 #define alt_next next
   85 #define UHCI_BUS2SC(bus) \
   86         __containerof(bus, uhci_softc_t, sc_bus)
   87 
   88 #ifdef USB_DEBUG
   89 static int uhcidebug = 0;
   90 static int uhcinoloop = 0;
   91 
   92 static SYSCTL_NODE(_hw_usb, OID_AUTO, uhci, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
   93     "USB uhci");
   94 SYSCTL_INT(_hw_usb_uhci, OID_AUTO, debug, CTLFLAG_RWTUN,
   95     &uhcidebug, 0, "uhci debug level");
   96 SYSCTL_INT(_hw_usb_uhci, OID_AUTO, loop, CTLFLAG_RWTUN,
   97     &uhcinoloop, 0, "uhci noloop");
   98 
   99 static void uhci_dumpregs(uhci_softc_t *sc);
  100 static void uhci_dump_tds(uhci_td_t *td);
  101 
  102 #endif
  103 
  104 #define UBARR(sc) bus_space_barrier((sc)->sc_io_tag, (sc)->sc_io_hdl, 0, (sc)->sc_io_size, \
  105                         BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)
  106 #define UWRITE1(sc, r, x) \
  107  do { UBARR(sc); bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_hdl, (r), (x)); \
  108  } while (/*CONSTCOND*/0)
  109 #define UWRITE2(sc, r, x) \
  110  do { UBARR(sc); bus_space_write_2((sc)->sc_io_tag, (sc)->sc_io_hdl, (r), (x)); \
  111  } while (/*CONSTCOND*/0)
  112 #define UWRITE4(sc, r, x) \
  113  do { UBARR(sc); bus_space_write_4((sc)->sc_io_tag, (sc)->sc_io_hdl, (r), (x)); \
  114  } while (/*CONSTCOND*/0)
  115 #define UREAD1(sc, r) (UBARR(sc), bus_space_read_1((sc)->sc_io_tag, (sc)->sc_io_hdl, (r)))
  116 #define UREAD2(sc, r) (UBARR(sc), bus_space_read_2((sc)->sc_io_tag, (sc)->sc_io_hdl, (r)))
  117 #define UREAD4(sc, r) (UBARR(sc), bus_space_read_4((sc)->sc_io_tag, (sc)->sc_io_hdl, (r)))
  118 
  119 #define UHCICMD(sc, cmd) UWRITE2(sc, UHCI_CMD, cmd)
  120 #define UHCISTS(sc) UREAD2(sc, UHCI_STS)
  121 
  122 #define UHCI_RESET_TIMEOUT 100          /* ms, reset timeout */
  123 
  124 #define UHCI_INTR_ENDPT 1
  125 
  126 struct uhci_mem_layout {
  127         struct usb_page_search buf_res;
  128         struct usb_page_search fix_res;
  129 
  130         struct usb_page_cache *buf_pc;
  131         struct usb_page_cache *fix_pc;
  132 
  133         uint32_t buf_offset;
  134 
  135         uint16_t max_frame_size;
  136 };
  137 
  138 struct uhci_std_temp {
  139         struct uhci_mem_layout ml;
  140         uhci_td_t *td;
  141         uhci_td_t *td_next;
  142         uint32_t average;
  143         uint32_t td_status;
  144         uint32_t td_token;
  145         uint32_t len;
  146         uint16_t max_frame_size;
  147         uint8_t shortpkt;
  148         uint8_t setup_alt_next;
  149         uint8_t last_frame;
  150 };
  151 
  152 static const struct usb_bus_methods uhci_bus_methods;
  153 static const struct usb_pipe_methods uhci_device_bulk_methods;
  154 static const struct usb_pipe_methods uhci_device_ctrl_methods;
  155 static const struct usb_pipe_methods uhci_device_intr_methods;
  156 static const struct usb_pipe_methods uhci_device_isoc_methods;
  157 
  158 static uint8_t  uhci_restart(uhci_softc_t *sc);
  159 static void     uhci_do_poll(struct usb_bus *);
  160 static void     uhci_device_done(struct usb_xfer *, usb_error_t);
  161 static void     uhci_transfer_intr_enqueue(struct usb_xfer *);
  162 static void     uhci_timeout(void *);
  163 static uint8_t  uhci_check_transfer(struct usb_xfer *);
  164 static void     uhci_root_intr(uhci_softc_t *sc);
  165 
  166 void
  167 uhci_iterate_hw_softc(struct usb_bus *bus, usb_bus_mem_sub_cb_t *cb)
  168 {
  169         struct uhci_softc *sc = UHCI_BUS2SC(bus);
  170         uint32_t i;
  171 
  172         cb(bus, &sc->sc_hw.pframes_pc, &sc->sc_hw.pframes_pg,
  173             sizeof(uint32_t) * UHCI_FRAMELIST_COUNT, UHCI_FRAMELIST_ALIGN);
  174 
  175         cb(bus, &sc->sc_hw.ls_ctl_start_pc, &sc->sc_hw.ls_ctl_start_pg,
  176             sizeof(uhci_qh_t), UHCI_QH_ALIGN);
  177 
  178         cb(bus, &sc->sc_hw.fs_ctl_start_pc, &sc->sc_hw.fs_ctl_start_pg,
  179             sizeof(uhci_qh_t), UHCI_QH_ALIGN);
  180 
  181         cb(bus, &sc->sc_hw.bulk_start_pc, &sc->sc_hw.bulk_start_pg,
  182             sizeof(uhci_qh_t), UHCI_QH_ALIGN);
  183 
  184         cb(bus, &sc->sc_hw.last_qh_pc, &sc->sc_hw.last_qh_pg,
  185             sizeof(uhci_qh_t), UHCI_QH_ALIGN);
  186 
  187         cb(bus, &sc->sc_hw.last_td_pc, &sc->sc_hw.last_td_pg,
  188             sizeof(uhci_td_t), UHCI_TD_ALIGN);
  189 
  190         for (i = 0; i != UHCI_VFRAMELIST_COUNT; i++) {
  191                 cb(bus, sc->sc_hw.isoc_start_pc + i,
  192                     sc->sc_hw.isoc_start_pg + i,
  193                     sizeof(uhci_td_t), UHCI_TD_ALIGN);
  194         }
  195 
  196         for (i = 0; i != UHCI_IFRAMELIST_COUNT; i++) {
  197                 cb(bus, sc->sc_hw.intr_start_pc + i,
  198                     sc->sc_hw.intr_start_pg + i,
  199                     sizeof(uhci_qh_t), UHCI_QH_ALIGN);
  200         }
  201 }
  202 
  203 static void
  204 uhci_mem_layout_init(struct uhci_mem_layout *ml, struct usb_xfer *xfer)
  205 {
  206         ml->buf_pc = xfer->frbuffers + 0;
  207         ml->fix_pc = xfer->buf_fixup;
  208 
  209         ml->buf_offset = 0;
  210 
  211         ml->max_frame_size = xfer->max_frame_size;
  212 }
  213 
  214 static void
  215 uhci_mem_layout_fixup(struct uhci_mem_layout *ml, struct uhci_td *td)
  216 {
  217         usbd_get_page(ml->buf_pc, ml->buf_offset, &ml->buf_res);
  218 
  219         if (ml->buf_res.length < td->len) {
  220                 /* need to do a fixup */
  221 
  222                 usbd_get_page(ml->fix_pc, 0, &ml->fix_res);
  223 
  224                 td->td_buffer = htole32(ml->fix_res.physaddr);
  225 
  226                 /*
  227                  * The UHCI driver cannot handle
  228                  * page crossings, so a fixup is
  229                  * needed:
  230                  *
  231                  *  +----+----+ - - -
  232                  *  | YYY|Y   |
  233                  *  +----+----+ - - -
  234                  *     \    \
  235                  *      \    \
  236                  *       +----+
  237                  *       |YYYY|  (fixup)
  238                  *       +----+
  239                  */
  240 
  241                 if ((td->td_token & htole32(UHCI_TD_PID)) ==
  242                     htole32(UHCI_TD_PID_IN)) {
  243                         td->fix_pc = ml->fix_pc;
  244                         usb_pc_cpu_invalidate(ml->fix_pc);
  245 
  246                 } else {
  247                         td->fix_pc = NULL;
  248 
  249                         /* copy data to fixup location */
  250 
  251                         usbd_copy_out(ml->buf_pc, ml->buf_offset,
  252                             ml->fix_res.buffer, td->len);
  253 
  254                         usb_pc_cpu_flush(ml->fix_pc);
  255                 }
  256 
  257                 /* prepare next fixup */
  258 
  259                 ml->fix_pc++;
  260 
  261         } else {
  262                 td->td_buffer = htole32(ml->buf_res.physaddr);
  263                 td->fix_pc = NULL;
  264         }
  265 
  266         /* prepare next data location */
  267 
  268         ml->buf_offset += td->len;
  269 }
  270 
  271 /*
  272  * Return values:
  273  * 0: Success
  274  * Else: Failure
  275  */
  276 static uint8_t
  277 uhci_restart(uhci_softc_t *sc)
  278 {
  279         struct usb_page_search buf_res;
  280 
  281         USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
  282 
  283         if (UREAD2(sc, UHCI_CMD) & UHCI_CMD_RS) {
  284                 DPRINTFN(2, "Already started\n");
  285                 return (0);
  286         }
  287 
  288         DPRINTFN(2, "Restarting\n");
  289 
  290         usbd_get_page(&sc->sc_hw.pframes_pc, 0, &buf_res);
  291 
  292         /* Reload fresh base address */
  293         UWRITE4(sc, UHCI_FLBASEADDR, buf_res.physaddr);
  294 
  295         /*
  296          * Assume 64 byte packets at frame end and start HC controller:
  297          */
  298         UHCICMD(sc, (UHCI_CMD_MAXP | UHCI_CMD_RS));
  299 
  300         /* wait 10 milliseconds */
  301 
  302         usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 100);
  303 
  304         /* check that controller has started */
  305 
  306         if (UREAD2(sc, UHCI_STS) & UHCI_STS_HCH) {
  307                 DPRINTFN(2, "Failed\n");
  308                 return (1);
  309         }
  310         return (0);
  311 }
  312 
  313 void
  314 uhci_reset(uhci_softc_t *sc)
  315 {
  316         uint16_t n;
  317 
  318         USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
  319 
  320         DPRINTF("resetting the HC\n");
  321 
  322         /* disable interrupts */
  323 
  324         UWRITE2(sc, UHCI_INTR, 0);
  325 
  326         /* global reset */
  327 
  328         UHCICMD(sc, UHCI_CMD_GRESET);
  329 
  330         /* wait */
  331 
  332         usb_pause_mtx(&sc->sc_bus.bus_mtx,
  333             USB_MS_TO_TICKS(USB_BUS_RESET_DELAY));
  334 
  335         /* terminate all transfers */
  336 
  337         UHCICMD(sc, UHCI_CMD_HCRESET);
  338 
  339         /* the reset bit goes low when the controller is done */
  340 
  341         n = UHCI_RESET_TIMEOUT;
  342         while (n--) {
  343                 /* wait one millisecond */
  344 
  345                 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
  346 
  347                 if (!(UREAD2(sc, UHCI_CMD) & UHCI_CMD_HCRESET)) {
  348                         goto done_1;
  349                 }
  350         }
  351 
  352         device_printf(sc->sc_bus.bdev,
  353             "controller did not reset\n");
  354 
  355 done_1:
  356 
  357         n = 10;
  358         while (n--) {
  359                 /* wait one millisecond */
  360 
  361                 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
  362 
  363                 /* check if HC is stopped */
  364                 if (UREAD2(sc, UHCI_STS) & UHCI_STS_HCH) {
  365                         goto done_2;
  366                 }
  367         }
  368 
  369         device_printf(sc->sc_bus.bdev,
  370             "controller did not stop\n");
  371 
  372 done_2:
  373 
  374         /* reset frame number */
  375         UWRITE2(sc, UHCI_FRNUM, 0);
  376         /* set default SOF value */
  377         UWRITE1(sc, UHCI_SOF, 0x40);
  378 
  379         USB_BUS_UNLOCK(&sc->sc_bus);
  380 
  381         /* stop root interrupt */
  382         usb_callout_drain(&sc->sc_root_intr);
  383 
  384         USB_BUS_LOCK(&sc->sc_bus);
  385 }
  386 
  387 static void
  388 uhci_start(uhci_softc_t *sc)
  389 {
  390         USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
  391 
  392         DPRINTFN(2, "enabling\n");
  393 
  394         /* enable interrupts */
  395 
  396         UWRITE2(sc, UHCI_INTR,
  397             (UHCI_INTR_TOCRCIE |
  398             UHCI_INTR_RIE |
  399             UHCI_INTR_IOCE |
  400             UHCI_INTR_SPIE));
  401 
  402         if (uhci_restart(sc)) {
  403                 device_printf(sc->sc_bus.bdev,
  404                     "cannot start HC controller\n");
  405         }
  406 
  407         /* start root interrupt */
  408         uhci_root_intr(sc);
  409 }
  410 
  411 static struct uhci_qh *
  412 uhci_init_qh(struct usb_page_cache *pc)
  413 {
  414         struct usb_page_search buf_res;
  415         struct uhci_qh *qh;
  416 
  417         usbd_get_page(pc, 0, &buf_res);
  418 
  419         qh = buf_res.buffer;
  420 
  421         qh->qh_self =
  422             htole32(buf_res.physaddr) |
  423             htole32(UHCI_PTR_QH);
  424 
  425         qh->page_cache = pc;
  426 
  427         return (qh);
  428 }
  429 
  430 static struct uhci_td *
  431 uhci_init_td(struct usb_page_cache *pc)
  432 {
  433         struct usb_page_search buf_res;
  434         struct uhci_td *td;
  435 
  436         usbd_get_page(pc, 0, &buf_res);
  437 
  438         td = buf_res.buffer;
  439 
  440         td->td_self =
  441             htole32(buf_res.physaddr) |
  442             htole32(UHCI_PTR_TD);
  443 
  444         td->page_cache = pc;
  445 
  446         return (td);
  447 }
  448 
  449 usb_error_t
  450 uhci_init(uhci_softc_t *sc)
  451 {
  452         uint16_t bit;
  453         uint16_t x;
  454         uint16_t y;
  455 
  456         DPRINTF("start\n");
  457 
  458         usb_callout_init_mtx(&sc->sc_root_intr, &sc->sc_bus.bus_mtx, 0);
  459 
  460 #ifdef USB_DEBUG
  461         if (uhcidebug > 2) {
  462                 uhci_dumpregs(sc);
  463         }
  464 #endif
  465         /*
  466          * Setup QH's
  467          */
  468         sc->sc_ls_ctl_p_last =
  469             uhci_init_qh(&sc->sc_hw.ls_ctl_start_pc);
  470 
  471         sc->sc_fs_ctl_p_last =
  472             uhci_init_qh(&sc->sc_hw.fs_ctl_start_pc);
  473 
  474         sc->sc_bulk_p_last =
  475             uhci_init_qh(&sc->sc_hw.bulk_start_pc);
  476 #if 0
  477         sc->sc_reclaim_qh_p =
  478             sc->sc_fs_ctl_p_last;
  479 #else
  480         /* setup reclaim looping point */
  481         sc->sc_reclaim_qh_p =
  482             sc->sc_bulk_p_last;
  483 #endif
  484 
  485         sc->sc_last_qh_p =
  486             uhci_init_qh(&sc->sc_hw.last_qh_pc);
  487 
  488         sc->sc_last_td_p =
  489             uhci_init_td(&sc->sc_hw.last_td_pc);
  490 
  491         for (x = 0; x != UHCI_VFRAMELIST_COUNT; x++) {
  492                 sc->sc_isoc_p_last[x] =
  493                     uhci_init_td(sc->sc_hw.isoc_start_pc + x);
  494         }
  495 
  496         for (x = 0; x != UHCI_IFRAMELIST_COUNT; x++) {
  497                 sc->sc_intr_p_last[x] =
  498                     uhci_init_qh(sc->sc_hw.intr_start_pc + x);
  499         }
  500 
  501         /*
  502          * the QHs are arranged to give poll intervals that are
  503          * powers of 2 times 1ms
  504          */
  505         bit = UHCI_IFRAMELIST_COUNT / 2;
  506         while (bit) {
  507                 x = bit;
  508                 while (x & bit) {
  509                         uhci_qh_t *qh_x;
  510                         uhci_qh_t *qh_y;
  511 
  512                         y = (x ^ bit) | (bit / 2);
  513 
  514                         /*
  515                          * the next QH has half the poll interval
  516                          */
  517                         qh_x = sc->sc_intr_p_last[x];
  518                         qh_y = sc->sc_intr_p_last[y];
  519 
  520                         qh_x->h_next = NULL;
  521                         qh_x->qh_h_next = qh_y->qh_self;
  522                         qh_x->e_next = NULL;
  523                         qh_x->qh_e_next = htole32(UHCI_PTR_T);
  524                         x++;
  525                 }
  526                 bit >>= 1;
  527         }
  528 
  529         if (1) {
  530                 uhci_qh_t *qh_ls;
  531                 uhci_qh_t *qh_intr;
  532 
  533                 qh_ls = sc->sc_ls_ctl_p_last;
  534                 qh_intr = sc->sc_intr_p_last[0];
  535 
  536                 /* start QH for interrupt traffic */
  537                 qh_intr->h_next = qh_ls;
  538                 qh_intr->qh_h_next = qh_ls->qh_self;
  539                 qh_intr->e_next = 0;
  540                 qh_intr->qh_e_next = htole32(UHCI_PTR_T);
  541         }
  542         for (x = 0; x != UHCI_VFRAMELIST_COUNT; x++) {
  543                 uhci_td_t *td_x;
  544                 uhci_qh_t *qh_intr;
  545 
  546                 td_x = sc->sc_isoc_p_last[x];
  547                 qh_intr = sc->sc_intr_p_last[x | (UHCI_IFRAMELIST_COUNT / 2)];
  548 
  549                 /* start TD for isochronous traffic */
  550                 td_x->next = NULL;
  551                 td_x->td_next = qh_intr->qh_self;
  552                 td_x->td_status = htole32(UHCI_TD_IOS);
  553                 td_x->td_token = htole32(0);
  554                 td_x->td_buffer = htole32(0);
  555         }
  556 
  557         if (1) {
  558                 uhci_qh_t *qh_ls;
  559                 uhci_qh_t *qh_fs;
  560 
  561                 qh_ls = sc->sc_ls_ctl_p_last;
  562                 qh_fs = sc->sc_fs_ctl_p_last;
  563 
  564                 /* start QH where low speed control traffic will be queued */
  565                 qh_ls->h_next = qh_fs;
  566                 qh_ls->qh_h_next = qh_fs->qh_self;
  567                 qh_ls->e_next = 0;
  568                 qh_ls->qh_e_next = htole32(UHCI_PTR_T);
  569         }
  570         if (1) {
  571                 uhci_qh_t *qh_ctl;
  572                 uhci_qh_t *qh_blk;
  573                 uhci_qh_t *qh_lst;
  574                 uhci_td_t *td_lst;
  575 
  576                 qh_ctl = sc->sc_fs_ctl_p_last;
  577                 qh_blk = sc->sc_bulk_p_last;
  578 
  579                 /* start QH where full speed control traffic will be queued */
  580                 qh_ctl->h_next = qh_blk;
  581                 qh_ctl->qh_h_next = qh_blk->qh_self;
  582                 qh_ctl->e_next = 0;
  583                 qh_ctl->qh_e_next = htole32(UHCI_PTR_T);
  584 
  585                 qh_lst = sc->sc_last_qh_p;
  586 
  587                 /* start QH where bulk traffic will be queued */
  588                 qh_blk->h_next = qh_lst;
  589                 qh_blk->qh_h_next = qh_lst->qh_self;
  590                 qh_blk->e_next = 0;
  591                 qh_blk->qh_e_next = htole32(UHCI_PTR_T);
  592 
  593                 td_lst = sc->sc_last_td_p;
  594 
  595                 /* end QH which is used for looping the QHs */
  596                 qh_lst->h_next = 0;
  597                 qh_lst->qh_h_next = htole32(UHCI_PTR_T);        /* end of QH chain */
  598                 qh_lst->e_next = td_lst;
  599                 qh_lst->qh_e_next = td_lst->td_self;
  600 
  601                 /*
  602                  * end TD which hangs from the last QH, to avoid a bug in the PIIX
  603                  * that makes it run berserk otherwise
  604                  */
  605                 td_lst->next = 0;
  606                 td_lst->td_next = htole32(UHCI_PTR_T);
  607                 td_lst->td_status = htole32(0); /* inactive */
  608                 td_lst->td_token = htole32(0);
  609                 td_lst->td_buffer = htole32(0);
  610         }
  611         if (1) {
  612                 struct usb_page_search buf_res;
  613                 uint32_t *pframes;
  614 
  615                 usbd_get_page(&sc->sc_hw.pframes_pc, 0, &buf_res);
  616 
  617                 pframes = buf_res.buffer;
  618 
  619                 /*
  620                  * Setup UHCI framelist
  621                  *
  622                  * Execution order:
  623                  *
  624                  * pframes -> full speed isochronous -> interrupt QH's -> low
  625                  * speed control -> full speed control -> bulk transfers
  626                  *
  627                  */
  628 
  629                 for (x = 0; x != UHCI_FRAMELIST_COUNT; x++) {
  630                         pframes[x] =
  631                             sc->sc_isoc_p_last[x % UHCI_VFRAMELIST_COUNT]->td_self;
  632                 }
  633         }
  634         /* flush all cache into memory */
  635 
  636         usb_bus_mem_flush_all(&sc->sc_bus, &uhci_iterate_hw_softc);
  637 
  638         /* set up the bus struct */
  639         sc->sc_bus.methods = &uhci_bus_methods;
  640 
  641         USB_BUS_LOCK(&sc->sc_bus);
  642         /* reset the controller */
  643         uhci_reset(sc);
  644 
  645         /* start the controller */
  646         uhci_start(sc);
  647         USB_BUS_UNLOCK(&sc->sc_bus);
  648 
  649         /* catch lost interrupts */
  650         uhci_do_poll(&sc->sc_bus);
  651 
  652         return (0);
  653 }
  654 
  655 static void
  656 uhci_suspend(uhci_softc_t *sc)
  657 {
  658 #ifdef USB_DEBUG
  659         if (uhcidebug > 2) {
  660                 uhci_dumpregs(sc);
  661         }
  662 #endif
  663 
  664         USB_BUS_LOCK(&sc->sc_bus);
  665 
  666         /* stop the controller */
  667 
  668         uhci_reset(sc);
  669 
  670         /* enter global suspend */
  671 
  672         UHCICMD(sc, UHCI_CMD_EGSM);
  673 
  674         USB_BUS_UNLOCK(&sc->sc_bus);
  675 }
  676 
  677 static void
  678 uhci_resume(uhci_softc_t *sc)
  679 {
  680         USB_BUS_LOCK(&sc->sc_bus);
  681 
  682         /* reset the controller */
  683 
  684         uhci_reset(sc);
  685 
  686         /* force global resume */
  687 
  688         UHCICMD(sc, UHCI_CMD_FGR);
  689 
  690         /* and start traffic again */
  691 
  692         uhci_start(sc);
  693 
  694         USB_BUS_UNLOCK(&sc->sc_bus);
  695 
  696 #ifdef USB_DEBUG
  697         if (uhcidebug > 2)
  698                 uhci_dumpregs(sc);
  699 #endif
  700 
  701         /* catch lost interrupts */
  702         uhci_do_poll(&sc->sc_bus);
  703 }
  704 
  705 #ifdef USB_DEBUG
  706 static void
  707 uhci_dumpregs(uhci_softc_t *sc)
  708 {
  709         DPRINTFN(0, "%s regs: cmd=%04x, sts=%04x, intr=%04x, frnum=%04x, "
  710             "flbase=%08x, sof=%04x, portsc1=%04x, portsc2=%04x\n",
  711             device_get_nameunit(sc->sc_bus.bdev),
  712             UREAD2(sc, UHCI_CMD),
  713             UREAD2(sc, UHCI_STS),
  714             UREAD2(sc, UHCI_INTR),
  715             UREAD2(sc, UHCI_FRNUM),
  716             UREAD4(sc, UHCI_FLBASEADDR),
  717             UREAD1(sc, UHCI_SOF),
  718             UREAD2(sc, UHCI_PORTSC1),
  719             UREAD2(sc, UHCI_PORTSC2));
  720 }
  721 
  722 static uint8_t
  723 uhci_dump_td(uhci_td_t *p)
  724 {
  725         uint32_t td_next;
  726         uint32_t td_status;
  727         uint32_t td_token;
  728         uint8_t temp;
  729 
  730         usb_pc_cpu_invalidate(p->page_cache);
  731 
  732         td_next = le32toh(p->td_next);
  733         td_status = le32toh(p->td_status);
  734         td_token = le32toh(p->td_token);
  735 
  736         /*
  737          * Check whether the link pointer in this TD marks the link pointer
  738          * as end of queue:
  739          */
  740         temp = ((td_next & UHCI_PTR_T) || (td_next == 0));
  741 
  742         printf("TD(%p) at 0x%08x = link=0x%08x status=0x%08x "
  743             "token=0x%08x buffer=0x%08x\n",
  744             p,
  745             le32toh(p->td_self),
  746             td_next,
  747             td_status,
  748             td_token,
  749             le32toh(p->td_buffer));
  750 
  751         printf("TD(%p) td_next=%s%s%s td_status=%s%s%s%s%s%s%s%s%s%s%s, errcnt=%d, actlen=%d pid=%02x,"
  752             "addr=%d,endpt=%d,D=%d,maxlen=%d\n",
  753             p,
  754             (td_next & 1) ? "-T" : "",
  755             (td_next & 2) ? "-Q" : "",
  756             (td_next & 4) ? "-VF" : "",
  757             (td_status & UHCI_TD_BITSTUFF) ? "-BITSTUFF" : "",
  758             (td_status & UHCI_TD_CRCTO) ? "-CRCTO" : "",
  759             (td_status & UHCI_TD_NAK) ? "-NAK" : "",
  760             (td_status & UHCI_TD_BABBLE) ? "-BABBLE" : "",
  761             (td_status & UHCI_TD_DBUFFER) ? "-DBUFFER" : "",
  762             (td_status & UHCI_TD_STALLED) ? "-STALLED" : "",
  763             (td_status & UHCI_TD_ACTIVE) ? "-ACTIVE" : "",
  764             (td_status & UHCI_TD_IOC) ? "-IOC" : "",
  765             (td_status & UHCI_TD_IOS) ? "-IOS" : "",
  766             (td_status & UHCI_TD_LS) ? "-LS" : "",
  767             (td_status & UHCI_TD_SPD) ? "-SPD" : "",
  768             UHCI_TD_GET_ERRCNT(td_status),
  769             UHCI_TD_GET_ACTLEN(td_status),
  770             UHCI_TD_GET_PID(td_token),
  771             UHCI_TD_GET_DEVADDR(td_token),
  772             UHCI_TD_GET_ENDPT(td_token),
  773             UHCI_TD_GET_DT(td_token),
  774             UHCI_TD_GET_MAXLEN(td_token));
  775 
  776         return (temp);
  777 }
  778 
  779 static uint8_t
  780 uhci_dump_qh(uhci_qh_t *sqh)
  781 {
  782         uint8_t temp;
  783         uint32_t qh_h_next;
  784         uint32_t qh_e_next;
  785 
  786         usb_pc_cpu_invalidate(sqh->page_cache);
  787 
  788         qh_h_next = le32toh(sqh->qh_h_next);
  789         qh_e_next = le32toh(sqh->qh_e_next);
  790 
  791         DPRINTFN(0, "QH(%p) at 0x%08x: h_next=0x%08x e_next=0x%08x\n", sqh,
  792             le32toh(sqh->qh_self), qh_h_next, qh_e_next);
  793 
  794         temp = ((((sqh->h_next != NULL) && !(qh_h_next & UHCI_PTR_T)) ? 1 : 0) |
  795             (((sqh->e_next != NULL) && !(qh_e_next & UHCI_PTR_T)) ? 2 : 0));
  796 
  797         return (temp);
  798 }
  799 
  800 static void
  801 uhci_dump_all(uhci_softc_t *sc)
  802 {
  803         uhci_dumpregs(sc);
  804         uhci_dump_qh(sc->sc_ls_ctl_p_last);
  805         uhci_dump_qh(sc->sc_fs_ctl_p_last);
  806         uhci_dump_qh(sc->sc_bulk_p_last);
  807         uhci_dump_qh(sc->sc_last_qh_p);
  808 }
  809 
  810 static void
  811 uhci_dump_tds(uhci_td_t *td)
  812 {
  813         for (;
  814             td != NULL;
  815             td = td->obj_next) {
  816                 if (uhci_dump_td(td)) {
  817                         break;
  818                 }
  819         }
  820 }
  821 
  822 #endif
  823 
  824 /*
  825  * Let the last QH loop back to the full speed control transfer QH.
  826  * This is what intel calls "bandwidth reclamation" and improves
  827  * USB performance a lot for some devices.
  828  * If we are already looping, just count it.
  829  */
  830 static void
  831 uhci_add_loop(uhci_softc_t *sc)
  832 {
  833         struct uhci_qh *qh_lst;
  834         struct uhci_qh *qh_rec;
  835 
  836 #ifdef USB_DEBUG
  837         if (uhcinoloop) {
  838                 return;
  839         }
  840 #endif
  841         if (++(sc->sc_loops) == 1) {
  842                 DPRINTFN(6, "add\n");
  843 
  844                 qh_lst = sc->sc_last_qh_p;
  845                 qh_rec = sc->sc_reclaim_qh_p;
  846 
  847                 /* NOTE: we don't loop back the soft pointer */
  848 
  849                 qh_lst->qh_h_next = qh_rec->qh_self;
  850                 usb_pc_cpu_flush(qh_lst->page_cache);
  851         }
  852 }
  853 
  854 static void
  855 uhci_rem_loop(uhci_softc_t *sc)
  856 {
  857         struct uhci_qh *qh_lst;
  858 
  859 #ifdef USB_DEBUG
  860         if (uhcinoloop) {
  861                 return;
  862         }
  863 #endif
  864         if (--(sc->sc_loops) == 0) {
  865                 DPRINTFN(6, "remove\n");
  866 
  867                 qh_lst = sc->sc_last_qh_p;
  868                 qh_lst->qh_h_next = htole32(UHCI_PTR_T);
  869                 usb_pc_cpu_flush(qh_lst->page_cache);
  870         }
  871 }
  872 
  873 static void
  874 uhci_transfer_intr_enqueue(struct usb_xfer *xfer)
  875 {
  876         /* check for early completion */
  877         if (uhci_check_transfer(xfer)) {
  878                 return;
  879         }
  880         /* put transfer on interrupt queue */
  881         usbd_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
  882 
  883         /* start timeout, if any */
  884         if (xfer->timeout != 0) {
  885                 usbd_transfer_timeout_ms(xfer, &uhci_timeout, xfer->timeout);
  886         }
  887 }
  888 
  889 #define UHCI_APPEND_TD(std,last) (last) = _uhci_append_td(std,last)
  890 static uhci_td_t *
  891 _uhci_append_td(uhci_td_t *std, uhci_td_t *last)
  892 {
  893         DPRINTFN(11, "%p to %p\n", std, last);
  894 
  895         /* (sc->sc_bus.mtx) must be locked */
  896 
  897         std->next = last->next;
  898         std->td_next = last->td_next;
  899 
  900         std->prev = last;
  901 
  902         usb_pc_cpu_flush(std->page_cache);
  903 
  904         /*
  905          * the last->next->prev is never followed: std->next->prev = std;
  906          */
  907         last->next = std;
  908         last->td_next = std->td_self;
  909 
  910         usb_pc_cpu_flush(last->page_cache);
  911 
  912         return (std);
  913 }
  914 
  915 #define UHCI_APPEND_QH(sqh,last) (last) = _uhci_append_qh(sqh,last)
  916 static uhci_qh_t *
  917 _uhci_append_qh(uhci_qh_t *sqh, uhci_qh_t *last)
  918 {
  919         DPRINTFN(11, "%p to %p\n", sqh, last);
  920 
  921         if (sqh->h_prev != NULL) {
  922                 /* should not happen */
  923                 DPRINTFN(0, "QH already linked!\n");
  924                 return (last);
  925         }
  926         /* (sc->sc_bus.mtx) must be locked */
  927 
  928         sqh->h_next = last->h_next;
  929         sqh->qh_h_next = last->qh_h_next;
  930 
  931         sqh->h_prev = last;
  932 
  933         usb_pc_cpu_flush(sqh->page_cache);
  934 
  935         /*
  936          * The "last->h_next->h_prev" is never followed:
  937          *
  938          * "sqh->h_next->h_prev" = sqh;
  939          */
  940 
  941         last->h_next = sqh;
  942         last->qh_h_next = sqh->qh_self;
  943 
  944         usb_pc_cpu_flush(last->page_cache);
  945 
  946         return (sqh);
  947 }
  948 
  949 /**/
  950 
  951 #define UHCI_REMOVE_TD(std,last) (last) = _uhci_remove_td(std,last)
  952 static uhci_td_t *
  953 _uhci_remove_td(uhci_td_t *std, uhci_td_t *last)
  954 {
  955         DPRINTFN(11, "%p from %p\n", std, last);
  956 
  957         /* (sc->sc_bus.mtx) must be locked */
  958 
  959         std->prev->next = std->next;
  960         std->prev->td_next = std->td_next;
  961 
  962         usb_pc_cpu_flush(std->prev->page_cache);
  963 
  964         if (std->next) {
  965                 std->next->prev = std->prev;
  966                 usb_pc_cpu_flush(std->next->page_cache);
  967         }
  968         return ((last == std) ? std->prev : last);
  969 }
  970 
  971 #define UHCI_REMOVE_QH(sqh,last) (last) = _uhci_remove_qh(sqh,last)
  972 static uhci_qh_t *
  973 _uhci_remove_qh(uhci_qh_t *sqh, uhci_qh_t *last)
  974 {
  975         DPRINTFN(11, "%p from %p\n", sqh, last);
  976 
  977         /* (sc->sc_bus.mtx) must be locked */
  978 
  979         /* only remove if not removed from a queue */
  980         if (sqh->h_prev) {
  981                 sqh->h_prev->h_next = sqh->h_next;
  982                 sqh->h_prev->qh_h_next = sqh->qh_h_next;
  983 
  984                 usb_pc_cpu_flush(sqh->h_prev->page_cache);
  985 
  986                 if (sqh->h_next) {
  987                         sqh->h_next->h_prev = sqh->h_prev;
  988                         usb_pc_cpu_flush(sqh->h_next->page_cache);
  989                 }
  990                 last = ((last == sqh) ? sqh->h_prev : last);
  991 
  992                 sqh->h_prev = 0;
  993 
  994                 usb_pc_cpu_flush(sqh->page_cache);
  995         }
  996         return (last);
  997 }
  998 
  999 static void
 1000 uhci_isoc_done(uhci_softc_t *sc, struct usb_xfer *xfer)
 1001 {
 1002         struct usb_page_search res;
 1003         uint32_t nframes = xfer->nframes;
 1004         uint32_t status;
 1005         uint32_t offset = 0;
 1006         uint32_t *plen = xfer->frlengths;
 1007         uint16_t len = 0;
 1008         uhci_td_t *td = xfer->td_transfer_first;
 1009         uhci_td_t **pp_last = &sc->sc_isoc_p_last[xfer->qh_pos];
 1010 
 1011         DPRINTFN(13, "xfer=%p endpoint=%p transfer done\n",
 1012             xfer, xfer->endpoint);
 1013 
 1014         /* sync any DMA memory before doing fixups */
 1015 
 1016         usb_bdma_post_sync(xfer);
 1017 
 1018         while (nframes--) {
 1019                 if (td == NULL) {
 1020                         panic("%s:%d: out of TD's\n",
 1021                             __FUNCTION__, __LINE__);
 1022                 }
 1023                 if (pp_last >= &sc->sc_isoc_p_last[UHCI_VFRAMELIST_COUNT]) {
 1024                         pp_last = &sc->sc_isoc_p_last[0];
 1025                 }
 1026 #ifdef USB_DEBUG
 1027                 if (uhcidebug > 5) {
 1028                         DPRINTF("isoc TD\n");
 1029                         uhci_dump_td(td);
 1030                 }
 1031 #endif
 1032                 usb_pc_cpu_invalidate(td->page_cache);
 1033                 status = le32toh(td->td_status);
 1034 
 1035                 len = UHCI_TD_GET_ACTLEN(status);
 1036 
 1037                 if (len > *plen) {
 1038                         len = *plen;
 1039                 }
 1040                 if (td->fix_pc) {
 1041                         usbd_get_page(td->fix_pc, 0, &res);
 1042 
 1043                         /* copy data from fixup location to real location */
 1044 
 1045                         usb_pc_cpu_invalidate(td->fix_pc);
 1046 
 1047                         usbd_copy_in(xfer->frbuffers, offset,
 1048                             res.buffer, len);
 1049                 }
 1050                 offset += *plen;
 1051 
 1052                 *plen = len;
 1053 
 1054                 /* remove TD from schedule */
 1055                 UHCI_REMOVE_TD(td, *pp_last);
 1056 
 1057                 pp_last++;
 1058                 plen++;
 1059                 td = td->obj_next;
 1060         }
 1061 
 1062         xfer->aframes = xfer->nframes;
 1063 }
 1064 
 1065 static usb_error_t
 1066 uhci_non_isoc_done_sub(struct usb_xfer *xfer)
 1067 {
 1068         struct usb_page_search res;
 1069         uhci_td_t *td;
 1070         uhci_td_t *td_alt_next;
 1071         uint32_t status;
 1072         uint32_t token;
 1073         uint16_t len;
 1074 
 1075         td = xfer->td_transfer_cache;
 1076         td_alt_next = td->alt_next;
 1077 
 1078         if (xfer->aframes != xfer->nframes) {
 1079                 usbd_xfer_set_frame_len(xfer, xfer->aframes, 0);
 1080         }
 1081         while (1) {
 1082                 usb_pc_cpu_invalidate(td->page_cache);
 1083                 status = le32toh(td->td_status);
 1084                 token = le32toh(td->td_token);
 1085 
 1086                 /*
 1087                  * Verify the status and add
 1088                  * up the actual length:
 1089                  */
 1090 
 1091                 len = UHCI_TD_GET_ACTLEN(status);
 1092                 if (len > td->len) {
 1093                         /* should not happen */
 1094                         DPRINTF("Invalid status length, "
 1095                             "0x%04x/0x%04x bytes\n", len, td->len);
 1096                         status |= UHCI_TD_STALLED;
 1097 
 1098                 } else if ((xfer->aframes != xfer->nframes) && (len > 0)) {
 1099                         if (td->fix_pc) {
 1100                                 usbd_get_page(td->fix_pc, 0, &res);
 1101 
 1102                                 /*
 1103                                  * copy data from fixup location to real
 1104                                  * location
 1105                                  */
 1106 
 1107                                 usb_pc_cpu_invalidate(td->fix_pc);
 1108 
 1109                                 usbd_copy_in(xfer->frbuffers + xfer->aframes,
 1110                                     xfer->frlengths[xfer->aframes], res.buffer, len);
 1111                         }
 1112                         /* update actual length */
 1113 
 1114                         xfer->frlengths[xfer->aframes] += len;
 1115                 }
 1116                 /* Check for last transfer */
 1117                 if (((void *)td) == xfer->td_transfer_last) {
 1118                         td = NULL;
 1119                         break;
 1120                 }
 1121                 if (status & UHCI_TD_STALLED) {
 1122                         /* the transfer is finished */
 1123                         td = NULL;
 1124                         break;
 1125                 }
 1126                 /* Check for short transfer */
 1127                 if (len != td->len) {
 1128                         if (xfer->flags_int.short_frames_ok) {
 1129                                 /* follow alt next */
 1130                                 td = td->alt_next;
 1131                         } else {
 1132                                 /* the transfer is finished */
 1133                                 td = NULL;
 1134                         }
 1135                         break;
 1136                 }
 1137                 td = td->obj_next;
 1138 
 1139                 if (td->alt_next != td_alt_next) {
 1140                         /* this USB frame is complete */
 1141                         break;
 1142                 }
 1143         }
 1144 
 1145         /* update transfer cache */
 1146 
 1147         xfer->td_transfer_cache = td;
 1148 
 1149         /* update data toggle */
 1150 
 1151         xfer->endpoint->toggle_next = (token & UHCI_TD_SET_DT(1)) ? 0 : 1;
 1152 
 1153 #ifdef USB_DEBUG
 1154         if (status & UHCI_TD_ERROR) {
 1155                 DPRINTFN(11, "error, addr=%d, endpt=0x%02x, frame=0x%02x "
 1156                     "status=%s%s%s%s%s%s%s%s%s%s%s\n",
 1157                     xfer->address, xfer->endpointno, xfer->aframes,
 1158                     (status & UHCI_TD_BITSTUFF) ? "[BITSTUFF]" : "",
 1159                     (status & UHCI_TD_CRCTO) ? "[CRCTO]" : "",
 1160                     (status & UHCI_TD_NAK) ? "[NAK]" : "",
 1161                     (status & UHCI_TD_BABBLE) ? "[BABBLE]" : "",
 1162                     (status & UHCI_TD_DBUFFER) ? "[DBUFFER]" : "",
 1163                     (status & UHCI_TD_STALLED) ? "[STALLED]" : "",
 1164                     (status & UHCI_TD_ACTIVE) ? "[ACTIVE]" : "[NOT_ACTIVE]",
 1165                     (status & UHCI_TD_IOC) ? "[IOC]" : "",
 1166                     (status & UHCI_TD_IOS) ? "[IOS]" : "",
 1167                     (status & UHCI_TD_LS) ? "[LS]" : "",
 1168                     (status & UHCI_TD_SPD) ? "[SPD]" : "");
 1169         }
 1170 #endif
 1171         if (status & UHCI_TD_STALLED) {
 1172                 /* try to separate I/O errors from STALL */
 1173                 if (UHCI_TD_GET_ERRCNT(status) == 0)
 1174                         return (USB_ERR_IOERROR);
 1175                 return (USB_ERR_STALLED);
 1176         }
 1177         return (USB_ERR_NORMAL_COMPLETION);
 1178 }
 1179 
 1180 static void
 1181 uhci_non_isoc_done(struct usb_xfer *xfer)
 1182 {
 1183         usb_error_t err = 0;
 1184 
 1185         DPRINTFN(13, "xfer=%p endpoint=%p transfer done\n",
 1186             xfer, xfer->endpoint);
 1187 
 1188 #ifdef USB_DEBUG
 1189         if (uhcidebug > 10) {
 1190                 uhci_dump_tds(xfer->td_transfer_first);
 1191         }
 1192 #endif
 1193 
 1194         /* sync any DMA memory before doing fixups */
 1195 
 1196         usb_bdma_post_sync(xfer);
 1197 
 1198         /* reset scanner */
 1199 
 1200         xfer->td_transfer_cache = xfer->td_transfer_first;
 1201 
 1202         if (xfer->flags_int.control_xfr) {
 1203                 if (xfer->flags_int.control_hdr) {
 1204                         err = uhci_non_isoc_done_sub(xfer);
 1205                 }
 1206                 xfer->aframes = 1;
 1207 
 1208                 if (xfer->td_transfer_cache == NULL) {
 1209                         goto done;
 1210                 }
 1211         }
 1212         while (xfer->aframes != xfer->nframes) {
 1213                 err = uhci_non_isoc_done_sub(xfer);
 1214                 xfer->aframes++;
 1215 
 1216                 if (xfer->td_transfer_cache == NULL) {
 1217                         goto done;
 1218                 }
 1219         }
 1220 
 1221         if (xfer->flags_int.control_xfr &&
 1222             !xfer->flags_int.control_act) {
 1223                 err = uhci_non_isoc_done_sub(xfer);
 1224         }
 1225 done:
 1226         uhci_device_done(xfer, err);
 1227 }
 1228 
 1229 /*------------------------------------------------------------------------*
 1230  *      uhci_check_transfer_sub
 1231  *
 1232  * The main purpose of this function is to update the data-toggle
 1233  * in case it is wrong.
 1234  *------------------------------------------------------------------------*/
 1235 static void
 1236 uhci_check_transfer_sub(struct usb_xfer *xfer)
 1237 {
 1238         uhci_qh_t *qh;
 1239         uhci_td_t *td;
 1240         uhci_td_t *td_alt_next;
 1241 
 1242         uint32_t td_token;
 1243         uint32_t td_self;
 1244 
 1245         td = xfer->td_transfer_cache;
 1246         qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
 1247 
 1248         td_token = td->obj_next->td_token;
 1249         td = td->alt_next;
 1250         xfer->td_transfer_cache = td;
 1251         td_self = td->td_self;
 1252         td_alt_next = td->alt_next;
 1253 
 1254         if (xfer->flags_int.control_xfr)
 1255                 goto skip;      /* don't touch the DT value! */
 1256 
 1257         if (!((td->td_token ^ td_token) & htole32(UHCI_TD_SET_DT(1))))
 1258                 goto skip;      /* data toggle has correct value */
 1259 
 1260         /*
 1261          * The data toggle is wrong and we need to toggle it !
 1262          */
 1263         while (1) {
 1264                 td->td_token ^= htole32(UHCI_TD_SET_DT(1));
 1265                 usb_pc_cpu_flush(td->page_cache);
 1266 
 1267                 if (td == xfer->td_transfer_last) {
 1268                         /* last transfer */
 1269                         break;
 1270                 }
 1271                 td = td->obj_next;
 1272 
 1273                 if (td->alt_next != td_alt_next) {
 1274                         /* next frame */
 1275                         break;
 1276                 }
 1277         }
 1278 skip:
 1279 
 1280         /* update the QH */
 1281         qh->qh_e_next = td_self;
 1282         usb_pc_cpu_flush(qh->page_cache);
 1283 
 1284         DPRINTFN(13, "xfer=%p following alt next\n", xfer);
 1285 }
 1286 
 1287 /*------------------------------------------------------------------------*
 1288  *      uhci_check_transfer
 1289  *
 1290  * Return values:
 1291  *    0: USB transfer is not finished
 1292  * Else: USB transfer is finished
 1293  *------------------------------------------------------------------------*/
 1294 static uint8_t
 1295 uhci_check_transfer(struct usb_xfer *xfer)
 1296 {
 1297         uint32_t status;
 1298         uhci_td_t *td;
 1299 
 1300         DPRINTFN(16, "xfer=%p checking transfer\n", xfer);
 1301 
 1302         if (xfer->endpoint->methods == &uhci_device_isoc_methods) {
 1303                 /* isochronous transfer */
 1304 
 1305                 td = xfer->td_transfer_last;
 1306 
 1307                 usb_pc_cpu_invalidate(td->page_cache);
 1308                 status = le32toh(td->td_status);
 1309 
 1310                 /* check also if the first is complete */
 1311 
 1312                 td = xfer->td_transfer_first;
 1313 
 1314                 usb_pc_cpu_invalidate(td->page_cache);
 1315                 status |= le32toh(td->td_status);
 1316 
 1317                 if (!(status & UHCI_TD_ACTIVE)) {
 1318                         uhci_device_done(xfer, USB_ERR_NORMAL_COMPLETION);
 1319                         goto transferred;
 1320                 }
 1321         } else {
 1322                 /* non-isochronous transfer */
 1323 
 1324                 /*
 1325                  * check whether there is an error somewhere
 1326                  * in the middle, or whether there was a short
 1327                  * packet (SPD and not ACTIVE)
 1328                  */
 1329                 td = xfer->td_transfer_cache;
 1330 
 1331                 while (1) {
 1332                         usb_pc_cpu_invalidate(td->page_cache);
 1333                         status = le32toh(td->td_status);
 1334 
 1335                         /*
 1336                          * if there is an active TD the transfer isn't done
 1337                          */
 1338                         if (status & UHCI_TD_ACTIVE) {
 1339                                 /* update cache */
 1340                                 xfer->td_transfer_cache = td;
 1341                                 goto done;
 1342                         }
 1343                         /*
 1344                          * last transfer descriptor makes the transfer done
 1345                          */
 1346                         if (((void *)td) == xfer->td_transfer_last) {
 1347                                 break;
 1348                         }
 1349                         /*
 1350                          * any kind of error makes the transfer done
 1351                          */
 1352                         if (status & UHCI_TD_STALLED) {
 1353                                 break;
 1354                         }
 1355                         /*
 1356                          * check if we reached the last packet
 1357                          * or if there is a short packet:
 1358                          */
 1359                         if ((td->td_next == htole32(UHCI_PTR_T)) ||
 1360                             (UHCI_TD_GET_ACTLEN(status) < td->len)) {
 1361                                 if (xfer->flags_int.short_frames_ok) {
 1362                                         /* follow alt next */
 1363                                         if (td->alt_next) {
 1364                                                 /* update cache */
 1365                                                 xfer->td_transfer_cache = td;
 1366                                                 uhci_check_transfer_sub(xfer);
 1367                                                 goto done;
 1368                                         }
 1369                                 }
 1370                                 /* transfer is done */
 1371                                 break;
 1372                         }
 1373                         td = td->obj_next;
 1374                 }
 1375                 uhci_non_isoc_done(xfer);
 1376                 goto transferred;
 1377         }
 1378 
 1379 done:
 1380         DPRINTFN(13, "xfer=%p is still active\n", xfer);
 1381         return (0);
 1382 
 1383 transferred:
 1384         return (1);
 1385 }
 1386 
 1387 static void
 1388 uhci_interrupt_poll(uhci_softc_t *sc)
 1389 {
 1390         struct usb_xfer *xfer;
 1391 
 1392 repeat:
 1393         TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
 1394                 /*
 1395                  * check if transfer is transferred
 1396                  */
 1397                 if (uhci_check_transfer(xfer)) {
 1398                         /* queue has been modified */
 1399                         goto repeat;
 1400                 }
 1401         }
 1402 }
 1403 
 1404 /*------------------------------------------------------------------------*
 1405  *      uhci_interrupt - UHCI interrupt handler
 1406  *
 1407  * NOTE: Do not access "sc->sc_bus.bdev" inside the interrupt handler,
 1408  * hence the interrupt handler will be setup before "sc->sc_bus.bdev"
 1409  * is present !
 1410  *------------------------------------------------------------------------*/
 1411 void
 1412 uhci_interrupt(uhci_softc_t *sc)
 1413 {
 1414         uint32_t status;
 1415 
 1416         USB_BUS_LOCK(&sc->sc_bus);
 1417 
 1418         DPRINTFN(16, "real interrupt\n");
 1419 
 1420 #ifdef USB_DEBUG
 1421         if (uhcidebug > 15) {
 1422                 uhci_dumpregs(sc);
 1423         }
 1424 #endif
 1425         status = UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS;
 1426         if (status == 0) {
 1427                 /* the interrupt was not for us */
 1428                 goto done;
 1429         }
 1430         if (status & (UHCI_STS_RD | UHCI_STS_HSE |
 1431             UHCI_STS_HCPE | UHCI_STS_HCH)) {
 1432                 if (status & UHCI_STS_RD) {
 1433 #ifdef USB_DEBUG
 1434                         printf("%s: resume detect\n",
 1435                             __FUNCTION__);
 1436 #endif
 1437                 }
 1438                 if (status & UHCI_STS_HSE) {
 1439                         printf("%s: host system error\n",
 1440                             __FUNCTION__);
 1441                 }
 1442                 if (status & UHCI_STS_HCPE) {
 1443                         printf("%s: host controller process error\n",
 1444                             __FUNCTION__);
 1445                 }
 1446                 if (status & UHCI_STS_HCH) {
 1447                         /* no acknowledge needed */
 1448                         DPRINTF("%s: host controller halted\n",
 1449                             __FUNCTION__);
 1450 #ifdef USB_DEBUG
 1451                         if (uhcidebug > 0) {
 1452                                 uhci_dump_all(sc);
 1453                         }
 1454 #endif
 1455                 }
 1456         }
 1457         /* get acknowledge bits */
 1458         status &= (UHCI_STS_USBINT |
 1459             UHCI_STS_USBEI |
 1460             UHCI_STS_RD |
 1461             UHCI_STS_HSE |
 1462             UHCI_STS_HCPE |
 1463             UHCI_STS_HCH);
 1464 
 1465         if (status == 0) {
 1466                 /* nothing to acknowledge */
 1467                 goto done;
 1468         }
 1469         /* acknowledge interrupts */
 1470         UWRITE2(sc, UHCI_STS, status);
 1471 
 1472         /* poll all the USB transfers */
 1473         uhci_interrupt_poll(sc);
 1474 
 1475 done:
 1476         USB_BUS_UNLOCK(&sc->sc_bus);
 1477 }
 1478 
 1479 /*
 1480  * called when a request does not complete
 1481  */
 1482 static void
 1483 uhci_timeout(void *arg)
 1484 {
 1485         struct usb_xfer *xfer = arg;
 1486 
 1487         DPRINTF("xfer=%p\n", xfer);
 1488 
 1489         USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
 1490 
 1491         /* transfer is transferred */
 1492         uhci_device_done(xfer, USB_ERR_TIMEOUT);
 1493 }
 1494 
 1495 static void
 1496 uhci_do_poll(struct usb_bus *bus)
 1497 {
 1498         struct uhci_softc *sc = UHCI_BUS2SC(bus);
 1499 
 1500         USB_BUS_LOCK(&sc->sc_bus);
 1501         uhci_interrupt_poll(sc);
 1502         USB_BUS_UNLOCK(&sc->sc_bus);
 1503 }
 1504 
 1505 static void
 1506 uhci_setup_standard_chain_sub(struct uhci_std_temp *temp)
 1507 {
 1508         uhci_td_t *td;
 1509         uhci_td_t *td_next;
 1510         uhci_td_t *td_alt_next;
 1511         uint32_t average;
 1512         uint32_t len_old;
 1513         uint8_t shortpkt_old;
 1514         uint8_t precompute;
 1515 
 1516         td_alt_next = NULL;
 1517         shortpkt_old = temp->shortpkt;
 1518         len_old = temp->len;
 1519         precompute = 1;
 1520 
 1521         /* software is used to detect short incoming transfers */
 1522 
 1523         if ((temp->td_token & htole32(UHCI_TD_PID)) == htole32(UHCI_TD_PID_IN)) {
 1524                 temp->td_status |= htole32(UHCI_TD_SPD);
 1525         } else {
 1526                 temp->td_status &= ~htole32(UHCI_TD_SPD);
 1527         }
 1528 
 1529         temp->ml.buf_offset = 0;
 1530 
 1531 restart:
 1532 
 1533         temp->td_token &= ~htole32(UHCI_TD_SET_MAXLEN(0));
 1534         temp->td_token |= htole32(UHCI_TD_SET_MAXLEN(temp->average));
 1535 
 1536         td = temp->td;
 1537         td_next = temp->td_next;
 1538 
 1539         while (1) {
 1540                 if (temp->len == 0) {
 1541                         if (temp->shortpkt) {
 1542                                 break;
 1543                         }
 1544                         /* send a Zero Length Packet, ZLP, last */
 1545 
 1546                         temp->shortpkt = 1;
 1547                         temp->td_token |= htole32(UHCI_TD_SET_MAXLEN(0));
 1548                         average = 0;
 1549 
 1550                 } else {
 1551                         average = temp->average;
 1552 
 1553                         if (temp->len < average) {
 1554                                 temp->shortpkt = 1;
 1555                                 temp->td_token &= ~htole32(UHCI_TD_SET_MAXLEN(0));
 1556                                 temp->td_token |= htole32(UHCI_TD_SET_MAXLEN(temp->len));
 1557                                 average = temp->len;
 1558                         }
 1559                 }
 1560 
 1561                 if (td_next == NULL) {
 1562                         panic("%s: out of UHCI transfer descriptors!", __FUNCTION__);
 1563                 }
 1564                 /* get next TD */
 1565 
 1566                 td = td_next;
 1567                 td_next = td->obj_next;
 1568 
 1569                 /* check if we are pre-computing */
 1570 
 1571                 if (precompute) {
 1572                         /* update remaining length */
 1573 
 1574                         temp->len -= average;
 1575 
 1576                         continue;
 1577                 }
 1578                 /* fill out current TD */
 1579 
 1580                 td->td_status = temp->td_status;
 1581                 td->td_token = temp->td_token;
 1582 
 1583                 /* update data toggle */
 1584 
 1585                 temp->td_token ^= htole32(UHCI_TD_SET_DT(1));
 1586 
 1587                 if (average == 0) {
 1588                         td->len = 0;
 1589                         td->td_buffer = 0;
 1590                         td->fix_pc = NULL;
 1591 
 1592                 } else {
 1593                         /* update remaining length */
 1594 
 1595                         temp->len -= average;
 1596 
 1597                         td->len = average;
 1598 
 1599                         /* fill out buffer pointer and do fixup, if any */
 1600 
 1601                         uhci_mem_layout_fixup(&temp->ml, td);
 1602                 }
 1603 
 1604                 td->alt_next = td_alt_next;
 1605 
 1606                 if ((td_next == td_alt_next) && temp->setup_alt_next) {
 1607                         /* we need to receive these frames one by one ! */
 1608                         td->td_status |= htole32(UHCI_TD_IOC);
 1609                         td->td_next = htole32(UHCI_PTR_T);
 1610                 } else {
 1611                         if (td_next) {
 1612                                 /* link the current TD with the next one */
 1613                                 td->td_next = td_next->td_self;
 1614                         }
 1615                 }
 1616 
 1617                 usb_pc_cpu_flush(td->page_cache);
 1618         }
 1619 
 1620         if (precompute) {
 1621                 precompute = 0;
 1622 
 1623                 /* setup alt next pointer, if any */
 1624                 if (temp->last_frame) {
 1625                         td_alt_next = NULL;
 1626                 } else {
 1627                         /* we use this field internally */
 1628                         td_alt_next = td_next;
 1629                 }
 1630 
 1631                 /* restore */
 1632                 temp->shortpkt = shortpkt_old;
 1633                 temp->len = len_old;
 1634                 goto restart;
 1635         }
 1636         temp->td = td;
 1637         temp->td_next = td_next;
 1638 }
 1639 
 1640 static uhci_td_t *
 1641 uhci_setup_standard_chain(struct usb_xfer *xfer)
 1642 {
 1643         struct uhci_std_temp temp;
 1644         uhci_td_t *td;
 1645         uint32_t x;
 1646 
 1647         DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n",
 1648             xfer->address, UE_GET_ADDR(xfer->endpointno),
 1649             xfer->sumlen, usbd_get_speed(xfer->xroot->udev));
 1650 
 1651         temp.average = xfer->max_frame_size;
 1652         temp.max_frame_size = xfer->max_frame_size;
 1653 
 1654         /* toggle the DMA set we are using */
 1655         xfer->flags_int.curr_dma_set ^= 1;
 1656 
 1657         /* get next DMA set */
 1658         td = xfer->td_start[xfer->flags_int.curr_dma_set];
 1659         xfer->td_transfer_first = td;
 1660         xfer->td_transfer_cache = td;
 1661 
 1662         temp.td = NULL;
 1663         temp.td_next = td;
 1664         temp.last_frame = 0;
 1665         temp.setup_alt_next = xfer->flags_int.short_frames_ok;
 1666 
 1667         uhci_mem_layout_init(&temp.ml, xfer);
 1668 
 1669         temp.td_status =
 1670             htole32(UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(3) |
 1671             UHCI_TD_ACTIVE));
 1672 
 1673         if (xfer->xroot->udev->speed == USB_SPEED_LOW) {
 1674                 temp.td_status |= htole32(UHCI_TD_LS);
 1675         }
 1676         temp.td_token =
 1677             htole32(UHCI_TD_SET_ENDPT(xfer->endpointno) |
 1678             UHCI_TD_SET_DEVADDR(xfer->address));
 1679 
 1680         if (xfer->endpoint->toggle_next) {
 1681                 /* DATA1 is next */
 1682                 temp.td_token |= htole32(UHCI_TD_SET_DT(1));
 1683         }
 1684         /* check if we should prepend a setup message */
 1685 
 1686         if (xfer->flags_int.control_xfr) {
 1687                 if (xfer->flags_int.control_hdr) {
 1688                         temp.td_token &= htole32(UHCI_TD_SET_DEVADDR(0x7F) |
 1689                             UHCI_TD_SET_ENDPT(0xF));
 1690                         temp.td_token |= htole32(UHCI_TD_PID_SETUP |
 1691                             UHCI_TD_SET_DT(0));
 1692 
 1693                         temp.len = xfer->frlengths[0];
 1694                         temp.ml.buf_pc = xfer->frbuffers + 0;
 1695                         temp.shortpkt = temp.len ? 1 : 0;
 1696                         /* check for last frame */
 1697                         if (xfer->nframes == 1) {
 1698                                 /* no STATUS stage yet, SETUP is last */
 1699                                 if (xfer->flags_int.control_act) {
 1700                                         temp.last_frame = 1;
 1701                                         temp.setup_alt_next = 0;
 1702                                 }
 1703                         }
 1704                         uhci_setup_standard_chain_sub(&temp);
 1705                 }
 1706                 x = 1;
 1707         } else {
 1708                 x = 0;
 1709         }
 1710 
 1711         while (x != xfer->nframes) {
 1712                 /* DATA0 / DATA1 message */
 1713 
 1714                 temp.len = xfer->frlengths[x];
 1715                 temp.ml.buf_pc = xfer->frbuffers + x;
 1716 
 1717                 x++;
 1718 
 1719                 if (x == xfer->nframes) {
 1720                         if (xfer->flags_int.control_xfr) {
 1721                                 /* no STATUS stage yet, DATA is last */
 1722                                 if (xfer->flags_int.control_act) {
 1723                                         temp.last_frame = 1;
 1724                                         temp.setup_alt_next = 0;
 1725                                 }
 1726                         } else {
 1727                                 temp.last_frame = 1;
 1728                                 temp.setup_alt_next = 0;
 1729                         }
 1730                 }
 1731                 /*
 1732                  * Keep previous data toggle,
 1733                  * device address and endpoint number:
 1734                  */
 1735 
 1736                 temp.td_token &= htole32(UHCI_TD_SET_DEVADDR(0x7F) |
 1737                     UHCI_TD_SET_ENDPT(0xF) |
 1738                     UHCI_TD_SET_DT(1));
 1739 
 1740                 if (temp.len == 0) {
 1741                         /* make sure that we send an USB packet */
 1742 
 1743                         temp.shortpkt = 0;
 1744 
 1745                 } else {
 1746                         /* regular data transfer */
 1747 
 1748                         temp.shortpkt = (xfer->flags.force_short_xfer) ? 0 : 1;
 1749                 }
 1750 
 1751                 /* set endpoint direction */
 1752 
 1753                 temp.td_token |=
 1754                     (UE_GET_DIR(xfer->endpointno) == UE_DIR_IN) ?
 1755                     htole32(UHCI_TD_PID_IN) :
 1756                     htole32(UHCI_TD_PID_OUT);
 1757 
 1758                 uhci_setup_standard_chain_sub(&temp);
 1759         }
 1760 
 1761         /* check if we should append a status stage */
 1762 
 1763         if (xfer->flags_int.control_xfr &&
 1764             !xfer->flags_int.control_act) {
 1765                 /*
 1766                  * send a DATA1 message and reverse the current endpoint
 1767                  * direction
 1768                  */
 1769 
 1770                 temp.td_token &= htole32(UHCI_TD_SET_DEVADDR(0x7F) |
 1771                     UHCI_TD_SET_ENDPT(0xF) |
 1772                     UHCI_TD_SET_DT(1));
 1773                 temp.td_token |=
 1774                     (UE_GET_DIR(xfer->endpointno) == UE_DIR_OUT) ?
 1775                     htole32(UHCI_TD_PID_IN | UHCI_TD_SET_DT(1)) :
 1776                     htole32(UHCI_TD_PID_OUT | UHCI_TD_SET_DT(1));
 1777 
 1778                 temp.len = 0;
 1779                 temp.ml.buf_pc = NULL;
 1780                 temp.shortpkt = 0;
 1781                 temp.last_frame = 1;
 1782                 temp.setup_alt_next = 0;
 1783 
 1784                 uhci_setup_standard_chain_sub(&temp);
 1785         }
 1786         td = temp.td;
 1787 
 1788         /* Ensure that last TD is terminating: */
 1789         td->td_next = htole32(UHCI_PTR_T);
 1790 
 1791         /* set interrupt bit */
 1792 
 1793         td->td_status |= htole32(UHCI_TD_IOC);
 1794 
 1795         usb_pc_cpu_flush(td->page_cache);
 1796 
 1797         /* must have at least one frame! */
 1798 
 1799         xfer->td_transfer_last = td;
 1800 
 1801 #ifdef USB_DEBUG
 1802         if (uhcidebug > 8) {
 1803                 DPRINTF("nexttog=%d; data before transfer:\n",
 1804                     xfer->endpoint->toggle_next);
 1805                 uhci_dump_tds(xfer->td_transfer_first);
 1806         }
 1807 #endif
 1808         return (xfer->td_transfer_first);
 1809 }
 1810 
 1811 /* NOTE: "done" can be run two times in a row,
 1812  * from close and from interrupt
 1813  */
 1814 
 1815 static void
 1816 uhci_device_done(struct usb_xfer *xfer, usb_error_t error)
 1817 {
 1818         const struct usb_pipe_methods *methods = xfer->endpoint->methods;
 1819         uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
 1820         uhci_qh_t *qh;
 1821 
 1822         USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
 1823 
 1824         DPRINTFN(2, "xfer=%p, endpoint=%p, error=%d\n",
 1825             xfer, xfer->endpoint, error);
 1826 
 1827         qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
 1828         if (qh) {
 1829                 usb_pc_cpu_invalidate(qh->page_cache);
 1830         }
 1831         if (xfer->flags_int.bandwidth_reclaimed) {
 1832                 xfer->flags_int.bandwidth_reclaimed = 0;
 1833                 uhci_rem_loop(sc);
 1834         }
 1835         if (methods == &uhci_device_bulk_methods) {
 1836                 UHCI_REMOVE_QH(qh, sc->sc_bulk_p_last);
 1837         }
 1838         if (methods == &uhci_device_ctrl_methods) {
 1839                 if (xfer->xroot->udev->speed == USB_SPEED_LOW) {
 1840                         UHCI_REMOVE_QH(qh, sc->sc_ls_ctl_p_last);
 1841                 } else {
 1842                         UHCI_REMOVE_QH(qh, sc->sc_fs_ctl_p_last);
 1843                 }
 1844         }
 1845         if (methods == &uhci_device_intr_methods) {
 1846                 UHCI_REMOVE_QH(qh, sc->sc_intr_p_last[xfer->qh_pos]);
 1847         }
 1848         /*
 1849          * Only finish isochronous transfers once
 1850          * which will update "xfer->frlengths".
 1851          */
 1852         if (xfer->td_transfer_first &&
 1853             xfer->td_transfer_last) {
 1854                 if (methods == &uhci_device_isoc_methods) {
 1855                         uhci_isoc_done(sc, xfer);
 1856                 }
 1857                 xfer->td_transfer_first = NULL;
 1858                 xfer->td_transfer_last = NULL;
 1859         }
 1860         /* dequeue transfer and start next transfer */
 1861         usbd_transfer_done(xfer, error);
 1862 }
 1863 
 1864 /*------------------------------------------------------------------------*
 1865  * uhci bulk support
 1866  *------------------------------------------------------------------------*/
 1867 static void
 1868 uhci_device_bulk_open(struct usb_xfer *xfer)
 1869 {
 1870         return;
 1871 }
 1872 
 1873 static void
 1874 uhci_device_bulk_close(struct usb_xfer *xfer)
 1875 {
 1876         uhci_device_done(xfer, USB_ERR_CANCELLED);
 1877 }
 1878 
 1879 static void
 1880 uhci_device_bulk_enter(struct usb_xfer *xfer)
 1881 {
 1882         return;
 1883 }
 1884 
 1885 static void
 1886 uhci_device_bulk_start(struct usb_xfer *xfer)
 1887 {
 1888         uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
 1889         uhci_td_t *td;
 1890         uhci_qh_t *qh;
 1891 
 1892         /* setup TD's */
 1893         td = uhci_setup_standard_chain(xfer);
 1894 
 1895         /* setup QH */
 1896         qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
 1897 
 1898         qh->e_next = td;
 1899         qh->qh_e_next = td->td_self;
 1900 
 1901         if (xfer->xroot->udev->flags.self_suspended == 0) {
 1902                 UHCI_APPEND_QH(qh, sc->sc_bulk_p_last);
 1903                 uhci_add_loop(sc);
 1904                 xfer->flags_int.bandwidth_reclaimed = 1;
 1905         } else {
 1906                 usb_pc_cpu_flush(qh->page_cache);
 1907         }
 1908 
 1909         /* put transfer on interrupt queue */
 1910         uhci_transfer_intr_enqueue(xfer);
 1911 }
 1912 
 1913 static const struct usb_pipe_methods uhci_device_bulk_methods =
 1914 {
 1915         .open = uhci_device_bulk_open,
 1916         .close = uhci_device_bulk_close,
 1917         .enter = uhci_device_bulk_enter,
 1918         .start = uhci_device_bulk_start,
 1919 };
 1920 
 1921 /*------------------------------------------------------------------------*
 1922  * uhci control support
 1923  *------------------------------------------------------------------------*/
 1924 static void
 1925 uhci_device_ctrl_open(struct usb_xfer *xfer)
 1926 {
 1927         return;
 1928 }
 1929 
 1930 static void
 1931 uhci_device_ctrl_close(struct usb_xfer *xfer)
 1932 {
 1933         uhci_device_done(xfer, USB_ERR_CANCELLED);
 1934 }
 1935 
 1936 static void
 1937 uhci_device_ctrl_enter(struct usb_xfer *xfer)
 1938 {
 1939         return;
 1940 }
 1941 
 1942 static void
 1943 uhci_device_ctrl_start(struct usb_xfer *xfer)
 1944 {
 1945         uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
 1946         uhci_qh_t *qh;
 1947         uhci_td_t *td;
 1948 
 1949         /* setup TD's */
 1950         td = uhci_setup_standard_chain(xfer);
 1951 
 1952         /* setup QH */
 1953         qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
 1954 
 1955         qh->e_next = td;
 1956         qh->qh_e_next = td->td_self;
 1957 
 1958         /*
 1959          * NOTE: some devices choke on bandwidth- reclamation for control
 1960          * transfers
 1961          */
 1962         if (xfer->xroot->udev->flags.self_suspended == 0) {
 1963                 if (xfer->xroot->udev->speed == USB_SPEED_LOW) {
 1964                         UHCI_APPEND_QH(qh, sc->sc_ls_ctl_p_last);
 1965                 } else {
 1966                         UHCI_APPEND_QH(qh, sc->sc_fs_ctl_p_last);
 1967                 }
 1968         } else {
 1969                 usb_pc_cpu_flush(qh->page_cache);
 1970         }
 1971         /* put transfer on interrupt queue */
 1972         uhci_transfer_intr_enqueue(xfer);
 1973 }
 1974 
 1975 static const struct usb_pipe_methods uhci_device_ctrl_methods =
 1976 {
 1977         .open = uhci_device_ctrl_open,
 1978         .close = uhci_device_ctrl_close,
 1979         .enter = uhci_device_ctrl_enter,
 1980         .start = uhci_device_ctrl_start,
 1981 };
 1982 
 1983 /*------------------------------------------------------------------------*
 1984  * uhci interrupt support
 1985  *------------------------------------------------------------------------*/
 1986 static void
 1987 uhci_device_intr_open(struct usb_xfer *xfer)
 1988 {
 1989         uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
 1990         uint16_t best;
 1991         uint16_t bit;
 1992         uint16_t x;
 1993 
 1994         best = 0;
 1995         bit = UHCI_IFRAMELIST_COUNT / 2;
 1996         while (bit) {
 1997                 if (xfer->interval >= bit) {
 1998                         x = bit;
 1999                         best = bit;
 2000                         while (x & bit) {
 2001                                 if (sc->sc_intr_stat[x] <
 2002                                     sc->sc_intr_stat[best]) {
 2003                                         best = x;
 2004                                 }
 2005                                 x++;
 2006                         }
 2007                         break;
 2008                 }
 2009                 bit >>= 1;
 2010         }
 2011 
 2012         sc->sc_intr_stat[best]++;
 2013         xfer->qh_pos = best;
 2014 
 2015         DPRINTFN(3, "best=%d interval=%d\n",
 2016             best, xfer->interval);
 2017 }
 2018 
 2019 static void
 2020 uhci_device_intr_close(struct usb_xfer *xfer)
 2021 {
 2022         uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
 2023 
 2024         sc->sc_intr_stat[xfer->qh_pos]--;
 2025 
 2026         uhci_device_done(xfer, USB_ERR_CANCELLED);
 2027 }
 2028 
 2029 static void
 2030 uhci_device_intr_enter(struct usb_xfer *xfer)
 2031 {
 2032         return;
 2033 }
 2034 
 2035 static void
 2036 uhci_device_intr_start(struct usb_xfer *xfer)
 2037 {
 2038         uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
 2039         uhci_qh_t *qh;
 2040         uhci_td_t *td;
 2041 
 2042         /* setup TD's */
 2043         td = uhci_setup_standard_chain(xfer);
 2044 
 2045         /* setup QH */
 2046         qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
 2047 
 2048         qh->e_next = td;
 2049         qh->qh_e_next = td->td_self;
 2050 
 2051         if (xfer->xroot->udev->flags.self_suspended == 0) {
 2052                 /* enter QHs into the controller data structures */
 2053                 UHCI_APPEND_QH(qh, sc->sc_intr_p_last[xfer->qh_pos]);
 2054         } else {
 2055                 usb_pc_cpu_flush(qh->page_cache);
 2056         }
 2057 
 2058         /* put transfer on interrupt queue */
 2059         uhci_transfer_intr_enqueue(xfer);
 2060 }
 2061 
 2062 static const struct usb_pipe_methods uhci_device_intr_methods =
 2063 {
 2064         .open = uhci_device_intr_open,
 2065         .close = uhci_device_intr_close,
 2066         .enter = uhci_device_intr_enter,
 2067         .start = uhci_device_intr_start,
 2068 };
 2069 
 2070 /*------------------------------------------------------------------------*
 2071  * uhci isochronous support
 2072  *------------------------------------------------------------------------*/
 2073 static void
 2074 uhci_device_isoc_open(struct usb_xfer *xfer)
 2075 {
 2076         uhci_td_t *td;
 2077         uint32_t td_token;
 2078         uint8_t ds;
 2079 
 2080         td_token =
 2081             (UE_GET_DIR(xfer->endpointno) == UE_DIR_IN) ?
 2082             UHCI_TD_IN(0, xfer->endpointno, xfer->address, 0) :
 2083             UHCI_TD_OUT(0, xfer->endpointno, xfer->address, 0);
 2084 
 2085         td_token = htole32(td_token);
 2086 
 2087         /* initialize all TD's */
 2088 
 2089         for (ds = 0; ds != 2; ds++) {
 2090                 for (td = xfer->td_start[ds]; td; td = td->obj_next) {
 2091                         /* mark TD as inactive */
 2092                         td->td_status = htole32(UHCI_TD_IOS);
 2093                         td->td_token = td_token;
 2094 
 2095                         usb_pc_cpu_flush(td->page_cache);
 2096                 }
 2097         }
 2098 }
 2099 
 2100 static void
 2101 uhci_device_isoc_close(struct usb_xfer *xfer)
 2102 {
 2103         uhci_device_done(xfer, USB_ERR_CANCELLED);
 2104 }
 2105 
 2106 static void
 2107 uhci_device_isoc_enter(struct usb_xfer *xfer)
 2108 {
 2109         struct uhci_mem_layout ml;
 2110         uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
 2111         uint32_t nframes;
 2112         uint32_t startframe;
 2113         uint32_t *plen;
 2114 
 2115 #ifdef USB_DEBUG
 2116         uint8_t once = 1;
 2117 
 2118 #endif
 2119         uhci_td_t *td;
 2120         uhci_td_t *td_last = NULL;
 2121         uhci_td_t **pp_last;
 2122 
 2123         DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
 2124             xfer, xfer->endpoint->isoc_next, xfer->nframes);
 2125 
 2126         nframes = UREAD2(sc, UHCI_FRNUM);
 2127 
 2128         if (usbd_xfer_get_isochronous_start_frame(
 2129             xfer, nframes, 0, 1, UHCI_VFRAMELIST_COUNT - 1, &startframe))
 2130                 DPRINTFN(3, "start next=%d\n", startframe);
 2131 
 2132         /* get the real number of frames */
 2133 
 2134         nframes = xfer->nframes;
 2135 
 2136         uhci_mem_layout_init(&ml, xfer);
 2137 
 2138         plen = xfer->frlengths;
 2139 
 2140         /* toggle the DMA set we are using */
 2141         xfer->flags_int.curr_dma_set ^= 1;
 2142 
 2143         /* get next DMA set */
 2144         td = xfer->td_start[xfer->flags_int.curr_dma_set];
 2145         xfer->td_transfer_first = td;
 2146 
 2147         pp_last = &sc->sc_isoc_p_last[startframe];
 2148 
 2149         /* store starting position */
 2150 
 2151         xfer->qh_pos = startframe;
 2152 
 2153         while (nframes--) {
 2154                 if (td == NULL) {
 2155                         panic("%s:%d: out of TD's\n",
 2156                             __FUNCTION__, __LINE__);
 2157                 }
 2158                 if (pp_last >= &sc->sc_isoc_p_last[UHCI_VFRAMELIST_COUNT]) {
 2159                         pp_last = &sc->sc_isoc_p_last[0];
 2160                 }
 2161                 if (*plen > xfer->max_frame_size) {
 2162 #ifdef USB_DEBUG
 2163                         if (once) {
 2164                                 once = 0;
 2165                                 printf("%s: frame length(%d) exceeds %d "
 2166                                     "bytes (frame truncated)\n",
 2167                                     __FUNCTION__, *plen,
 2168                                     xfer->max_frame_size);
 2169                         }
 2170 #endif
 2171                         *plen = xfer->max_frame_size;
 2172                 }
 2173                 /* reuse td_token from last transfer */
 2174 
 2175                 td->td_token &= htole32(~UHCI_TD_MAXLEN_MASK);
 2176                 td->td_token |= htole32(UHCI_TD_SET_MAXLEN(*plen));
 2177 
 2178                 td->len = *plen;
 2179 
 2180                 if (td->len == 0) {
 2181                         /*
 2182                          * Do not call "uhci_mem_layout_fixup()" when the
 2183                          * length is zero!
 2184                          */
 2185                         td->td_buffer = 0;
 2186                         td->fix_pc = NULL;
 2187 
 2188                 } else {
 2189                         /* fill out buffer pointer and do fixup, if any */
 2190 
 2191                         uhci_mem_layout_fixup(&ml, td);
 2192                 }
 2193 
 2194                 /* update status */
 2195                 if (nframes == 0) {
 2196                         td->td_status = htole32
 2197                             (UHCI_TD_ZERO_ACTLEN
 2198                             (UHCI_TD_SET_ERRCNT(0) |
 2199                             UHCI_TD_ACTIVE |
 2200                             UHCI_TD_IOS |
 2201                             UHCI_TD_IOC));
 2202                 } else {
 2203                         td->td_status = htole32
 2204                             (UHCI_TD_ZERO_ACTLEN
 2205                             (UHCI_TD_SET_ERRCNT(0) |
 2206                             UHCI_TD_ACTIVE |
 2207                             UHCI_TD_IOS));
 2208                 }
 2209 
 2210                 usb_pc_cpu_flush(td->page_cache);
 2211 
 2212 #ifdef USB_DEBUG
 2213                 if (uhcidebug > 5) {
 2214                         DPRINTF("TD %d\n", nframes);
 2215                         uhci_dump_td(td);
 2216                 }
 2217 #endif
 2218                 /* insert TD into schedule */
 2219                 UHCI_APPEND_TD(td, *pp_last);
 2220                 pp_last++;
 2221 
 2222                 plen++;
 2223                 td_last = td;
 2224                 td = td->obj_next;
 2225         }
 2226 
 2227         xfer->td_transfer_last = td_last;
 2228 }
 2229 
 2230 static void
 2231 uhci_device_isoc_start(struct usb_xfer *xfer)
 2232 {
 2233         /* put transfer on interrupt queue */
 2234         uhci_transfer_intr_enqueue(xfer);
 2235 }
 2236 
 2237 static const struct usb_pipe_methods uhci_device_isoc_methods =
 2238 {
 2239         .open = uhci_device_isoc_open,
 2240         .close = uhci_device_isoc_close,
 2241         .enter = uhci_device_isoc_enter,
 2242         .start = uhci_device_isoc_start,
 2243 };
 2244 
 2245 /*------------------------------------------------------------------------*
 2246  * uhci root control support
 2247  *------------------------------------------------------------------------*
 2248  * Simulate a hardware hub by handling all the necessary requests.
 2249  *------------------------------------------------------------------------*/
 2250 
 2251 static const
 2252 struct usb_device_descriptor uhci_devd =
 2253 {
 2254         sizeof(struct usb_device_descriptor),
 2255         UDESC_DEVICE,                   /* type */
 2256         {0x00, 0x01},                   /* USB version */
 2257         UDCLASS_HUB,                    /* class */
 2258         UDSUBCLASS_HUB,                 /* subclass */
 2259         UDPROTO_FSHUB,                  /* protocol */
 2260         64,                             /* max packet */
 2261         {0}, {0}, {0x00, 0x01},         /* device id */
 2262         1, 2, 0,                        /* string indexes */
 2263         1                               /* # of configurations */
 2264 };
 2265 
 2266 static const struct uhci_config_desc uhci_confd = {
 2267         .confd = {
 2268                 .bLength = sizeof(struct usb_config_descriptor),
 2269                 .bDescriptorType = UDESC_CONFIG,
 2270                 .wTotalLength[0] = sizeof(uhci_confd),
 2271                 .bNumInterface = 1,
 2272                 .bConfigurationValue = 1,
 2273                 .iConfiguration = 0,
 2274                 .bmAttributes = UC_SELF_POWERED,
 2275                 .bMaxPower = 0          /* max power */
 2276         },
 2277         .ifcd = {
 2278                 .bLength = sizeof(struct usb_interface_descriptor),
 2279                 .bDescriptorType = UDESC_INTERFACE,
 2280                 .bNumEndpoints = 1,
 2281                 .bInterfaceClass = UICLASS_HUB,
 2282                 .bInterfaceSubClass = UISUBCLASS_HUB,
 2283                 .bInterfaceProtocol = UIPROTO_FSHUB,
 2284         },
 2285         .endpd = {
 2286                 .bLength = sizeof(struct usb_endpoint_descriptor),
 2287                 .bDescriptorType = UDESC_ENDPOINT,
 2288                 .bEndpointAddress = UE_DIR_IN | UHCI_INTR_ENDPT,
 2289                 .bmAttributes = UE_INTERRUPT,
 2290                 .wMaxPacketSize[0] = 8, /* max packet (63 ports) */
 2291                 .bInterval = 255,
 2292         },
 2293 };
 2294 
 2295 static const
 2296 struct usb_hub_descriptor_min uhci_hubd_piix =
 2297 {
 2298         .bDescLength = sizeof(uhci_hubd_piix),
 2299         .bDescriptorType = UDESC_HUB,
 2300         .bNbrPorts = 2,
 2301         .wHubCharacteristics = {UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL, 0},
 2302         .bPwrOn2PwrGood = 50,
 2303 };
 2304 
 2305 /*
 2306  * The USB hub protocol requires that SET_FEATURE(PORT_RESET) also
 2307  * enables the port, and also states that SET_FEATURE(PORT_ENABLE)
 2308  * should not be used by the USB subsystem.  As we cannot issue a
 2309  * SET_FEATURE(PORT_ENABLE) externally, we must ensure that the port
 2310  * will be enabled as part of the reset.
 2311  *
 2312  * On the VT83C572, the port cannot be successfully enabled until the
 2313  * outstanding "port enable change" and "connection status change"
 2314  * events have been reset.
 2315  */
 2316 static usb_error_t
 2317 uhci_portreset(uhci_softc_t *sc, uint16_t index)
 2318 {
 2319         uint16_t port;
 2320         uint16_t x;
 2321         uint8_t lim;
 2322 
 2323         if (index == 1)
 2324                 port = UHCI_PORTSC1;
 2325         else if (index == 2)
 2326                 port = UHCI_PORTSC2;
 2327         else
 2328                 return (USB_ERR_IOERROR);
 2329 
 2330         /*
 2331          * Before we do anything, turn on SOF messages on the USB
 2332          * BUS. Some USB devices do not cope without them!
 2333          */
 2334         uhci_restart(sc);
 2335 
 2336         x = URWMASK(UREAD2(sc, port));
 2337         UWRITE2(sc, port, x | UHCI_PORTSC_PR);
 2338 
 2339         usb_pause_mtx(&sc->sc_bus.bus_mtx,
 2340             USB_MS_TO_TICKS(usb_port_root_reset_delay));
 2341 
 2342         DPRINTFN(4, "uhci port %d reset, status0 = 0x%04x\n",
 2343             index, UREAD2(sc, port));
 2344 
 2345         x = URWMASK(UREAD2(sc, port));
 2346         UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
 2347 
 2348         mtx_unlock(&sc->sc_bus.bus_mtx);
 2349 
 2350         /* 
 2351          * This delay needs to be exactly 100us, else some USB devices
 2352          * fail to attach!
 2353          */
 2354         DELAY(100);
 2355 
 2356         mtx_lock(&sc->sc_bus.bus_mtx);
 2357 
 2358         DPRINTFN(4, "uhci port %d reset, status1 = 0x%04x\n",
 2359             index, UREAD2(sc, port));
 2360 
 2361         x = URWMASK(UREAD2(sc, port));
 2362         UWRITE2(sc, port, x | UHCI_PORTSC_PE);
 2363 
 2364         for (lim = 0; lim < 12; lim++) {
 2365                 usb_pause_mtx(&sc->sc_bus.bus_mtx,
 2366                     USB_MS_TO_TICKS(usb_port_reset_delay));
 2367 
 2368                 x = UREAD2(sc, port);
 2369 
 2370                 DPRINTFN(4, "uhci port %d iteration %u, status = 0x%04x\n",
 2371                     index, lim, x);
 2372 
 2373                 if (!(x & UHCI_PORTSC_CCS)) {
 2374                         /*
 2375                          * No device is connected (or was disconnected
 2376                          * during reset).  Consider the port reset.
 2377                          * The delay must be long enough to ensure on
 2378                          * the initial iteration that the device
 2379                          * connection will have been registered.  50ms
 2380                          * appears to be sufficient, but 20ms is not.
 2381                          */
 2382                         DPRINTFN(4, "uhci port %d loop %u, device detached\n",
 2383                             index, lim);
 2384                         goto done;
 2385                 }
 2386                 if (x & (UHCI_PORTSC_POEDC | UHCI_PORTSC_CSC)) {
 2387                         /*
 2388                          * Port enabled changed and/or connection
 2389                          * status changed were set.  Reset either or
 2390                          * both raised flags (by writing a 1 to that
 2391                          * bit), and wait again for state to settle.
 2392                          */
 2393                         UWRITE2(sc, port, URWMASK(x) |
 2394                             (x & (UHCI_PORTSC_POEDC | UHCI_PORTSC_CSC)));
 2395                         continue;
 2396                 }
 2397                 if (x & UHCI_PORTSC_PE) {
 2398                         /* port is enabled */
 2399                         goto done;
 2400                 }
 2401                 UWRITE2(sc, port, URWMASK(x) | UHCI_PORTSC_PE);
 2402         }
 2403 
 2404         DPRINTFN(2, "uhci port %d reset timed out\n", index);
 2405         return (USB_ERR_TIMEOUT);
 2406 
 2407 done:
 2408         DPRINTFN(4, "uhci port %d reset, status2 = 0x%04x\n",
 2409             index, UREAD2(sc, port));
 2410 
 2411         sc->sc_isreset = 1;
 2412         return (USB_ERR_NORMAL_COMPLETION);
 2413 }
 2414 
 2415 static usb_error_t
 2416 uhci_roothub_exec(struct usb_device *udev,
 2417     struct usb_device_request *req, const void **pptr, uint16_t *plength)
 2418 {
 2419         uhci_softc_t *sc = UHCI_BUS2SC(udev->bus);
 2420         const void *ptr;
 2421         const char *str_ptr;
 2422         uint16_t x;
 2423         uint16_t port;
 2424         uint16_t value;
 2425         uint16_t index;
 2426         uint16_t status;
 2427         uint16_t change;
 2428         uint16_t len;
 2429         usb_error_t err;
 2430 
 2431         USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
 2432 
 2433         /* buffer reset */
 2434         ptr = (const void *)&sc->sc_hub_desc.temp;
 2435         len = 0;
 2436         err = 0;
 2437 
 2438         value = UGETW(req->wValue);
 2439         index = UGETW(req->wIndex);
 2440 
 2441         DPRINTFN(3, "type=0x%02x request=0x%02x wLen=0x%04x "
 2442             "wValue=0x%04x wIndex=0x%04x\n",
 2443             req->bmRequestType, req->bRequest,
 2444             UGETW(req->wLength), value, index);
 2445 
 2446 #define C(x,y) ((x) | ((y) << 8))
 2447         switch (C(req->bRequest, req->bmRequestType)) {
 2448         case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
 2449         case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
 2450         case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
 2451                 /*
 2452                  * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
 2453                  * for the integrated root hub.
 2454                  */
 2455                 break;
 2456         case C(UR_GET_CONFIG, UT_READ_DEVICE):
 2457                 len = 1;
 2458                 sc->sc_hub_desc.temp[0] = sc->sc_conf;
 2459                 break;
 2460         case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
 2461                 switch (value >> 8) {
 2462                 case UDESC_DEVICE:
 2463                         if ((value & 0xff) != 0) {
 2464                                 err = USB_ERR_IOERROR;
 2465                                 goto done;
 2466                         }
 2467                         len = sizeof(uhci_devd);
 2468                         ptr = (const void *)&uhci_devd;
 2469                         break;
 2470 
 2471                 case UDESC_CONFIG:
 2472                         if ((value & 0xff) != 0) {
 2473                                 err = USB_ERR_IOERROR;
 2474                                 goto done;
 2475                         }
 2476                         len = sizeof(uhci_confd);
 2477                         ptr = (const void *)&uhci_confd;
 2478                         break;
 2479 
 2480                 case UDESC_STRING:
 2481                         switch (value & 0xff) {
 2482                         case 0: /* Language table */
 2483                                 str_ptr = "\001";
 2484                                 break;
 2485 
 2486                         case 1: /* Vendor */
 2487                                 str_ptr = sc->sc_vendor;
 2488                                 break;
 2489 
 2490                         case 2: /* Product */
 2491                                 str_ptr = "UHCI root HUB";
 2492                                 break;
 2493 
 2494                         default:
 2495                                 str_ptr = "";
 2496                                 break;
 2497                         }
 2498 
 2499                         len = usb_make_str_desc
 2500                             (sc->sc_hub_desc.temp,
 2501                             sizeof(sc->sc_hub_desc.temp),
 2502                             str_ptr);
 2503                         break;
 2504 
 2505                 default:
 2506                         err = USB_ERR_IOERROR;
 2507                         goto done;
 2508                 }
 2509                 break;
 2510         case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
 2511                 len = 1;
 2512                 sc->sc_hub_desc.temp[0] = 0;
 2513                 break;
 2514         case C(UR_GET_STATUS, UT_READ_DEVICE):
 2515                 len = 2;
 2516                 USETW(sc->sc_hub_desc.stat.wStatus, UDS_SELF_POWERED);
 2517                 break;
 2518         case C(UR_GET_STATUS, UT_READ_INTERFACE):
 2519         case C(UR_GET_STATUS, UT_READ_ENDPOINT):
 2520                 len = 2;
 2521                 USETW(sc->sc_hub_desc.stat.wStatus, 0);
 2522                 break;
 2523         case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
 2524                 if (value >= UHCI_MAX_DEVICES) {
 2525                         err = USB_ERR_IOERROR;
 2526                         goto done;
 2527                 }
 2528                 sc->sc_addr = value;
 2529                 break;
 2530         case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
 2531                 if ((value != 0) && (value != 1)) {
 2532                         err = USB_ERR_IOERROR;
 2533                         goto done;
 2534                 }
 2535                 sc->sc_conf = value;
 2536                 break;
 2537         case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
 2538                 break;
 2539         case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
 2540         case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
 2541         case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
 2542                 err = USB_ERR_IOERROR;
 2543                 goto done;
 2544         case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
 2545                 break;
 2546         case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
 2547                 break;
 2548                 /* Hub requests */
 2549         case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
 2550                 break;
 2551         case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
 2552                 DPRINTFN(4, "UR_CLEAR_PORT_FEATURE "
 2553                     "port=%d feature=%d\n",
 2554                     index, value);
 2555                 if (index == 1)
 2556                         port = UHCI_PORTSC1;
 2557                 else if (index == 2)
 2558                         port = UHCI_PORTSC2;
 2559                 else {
 2560                         err = USB_ERR_IOERROR;
 2561                         goto done;
 2562                 }
 2563                 switch (value) {
 2564                 case UHF_PORT_ENABLE:
 2565                         x = URWMASK(UREAD2(sc, port));
 2566                         UWRITE2(sc, port, x & ~UHCI_PORTSC_PE);
 2567                         break;
 2568                 case UHF_PORT_SUSPEND:
 2569                         x = URWMASK(UREAD2(sc, port));
 2570                         UWRITE2(sc, port, x & ~(UHCI_PORTSC_SUSP));
 2571                         break;
 2572                 case UHF_PORT_RESET:
 2573                         x = URWMASK(UREAD2(sc, port));
 2574                         UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
 2575                         break;
 2576                 case UHF_C_PORT_CONNECTION:
 2577                         x = URWMASK(UREAD2(sc, port));
 2578                         UWRITE2(sc, port, x | UHCI_PORTSC_CSC);
 2579                         break;
 2580                 case UHF_C_PORT_ENABLE:
 2581                         x = URWMASK(UREAD2(sc, port));
 2582                         UWRITE2(sc, port, x | UHCI_PORTSC_POEDC);
 2583                         break;
 2584                 case UHF_C_PORT_OVER_CURRENT:
 2585                         x = URWMASK(UREAD2(sc, port));
 2586                         UWRITE2(sc, port, x | UHCI_PORTSC_OCIC);
 2587                         break;
 2588                 case UHF_C_PORT_RESET:
 2589                         sc->sc_isreset = 0;
 2590                         err = USB_ERR_NORMAL_COMPLETION;
 2591                         goto done;
 2592                 case UHF_C_PORT_SUSPEND:
 2593                         sc->sc_isresumed &= ~(1 << index);
 2594                         break;
 2595                 case UHF_PORT_CONNECTION:
 2596                 case UHF_PORT_OVER_CURRENT:
 2597                 case UHF_PORT_POWER:
 2598                 case UHF_PORT_LOW_SPEED:
 2599                 default:
 2600                         err = USB_ERR_IOERROR;
 2601                         goto done;
 2602                 }
 2603                 break;
 2604         case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER):
 2605                 if (index == 1)
 2606                         port = UHCI_PORTSC1;
 2607                 else if (index == 2)
 2608                         port = UHCI_PORTSC2;
 2609                 else {
 2610                         err = USB_ERR_IOERROR;
 2611                         goto done;
 2612                 }
 2613                 len = 1;
 2614                 sc->sc_hub_desc.temp[0] =
 2615                     ((UREAD2(sc, port) & UHCI_PORTSC_LS) >>
 2616                     UHCI_PORTSC_LS_SHIFT);
 2617                 break;
 2618         case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
 2619                 if ((value & 0xff) != 0) {
 2620                         err = USB_ERR_IOERROR;
 2621                         goto done;
 2622                 }
 2623                 len = sizeof(uhci_hubd_piix);
 2624                 ptr = (const void *)&uhci_hubd_piix;
 2625                 break;
 2626         case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
 2627                 len = 16;
 2628                 memset(sc->sc_hub_desc.temp, 0, 16);
 2629                 break;
 2630         case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
 2631                 if (index == 1)
 2632                         port = UHCI_PORTSC1;
 2633                 else if (index == 2)
 2634                         port = UHCI_PORTSC2;
 2635                 else {
 2636                         err = USB_ERR_IOERROR;
 2637                         goto done;
 2638                 }
 2639                 x = UREAD2(sc, port);
 2640                 status = change = 0;
 2641                 if (x & UHCI_PORTSC_CCS)
 2642                         status |= UPS_CURRENT_CONNECT_STATUS;
 2643                 if (x & UHCI_PORTSC_CSC)
 2644                         change |= UPS_C_CONNECT_STATUS;
 2645                 if (x & UHCI_PORTSC_PE)
 2646                         status |= UPS_PORT_ENABLED;
 2647                 if (x & UHCI_PORTSC_POEDC)
 2648                         change |= UPS_C_PORT_ENABLED;
 2649                 if (x & UHCI_PORTSC_OCI)
 2650                         status |= UPS_OVERCURRENT_INDICATOR;
 2651                 if (x & UHCI_PORTSC_OCIC)
 2652                         change |= UPS_C_OVERCURRENT_INDICATOR;
 2653                 if (x & UHCI_PORTSC_LSDA)
 2654                         status |= UPS_LOW_SPEED;
 2655                 if ((x & UHCI_PORTSC_PE) && (x & UHCI_PORTSC_RD)) {
 2656                         /* need to do a write back */
 2657                         UWRITE2(sc, port, URWMASK(x));
 2658 
 2659                         /* wait 20ms for resume sequence to complete */
 2660                         usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 50);
 2661 
 2662                         /* clear suspend and resume detect */
 2663                         UWRITE2(sc, port, URWMASK(x) & ~(UHCI_PORTSC_RD |
 2664                             UHCI_PORTSC_SUSP));
 2665 
 2666                         /* wait a little bit */
 2667                         usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 500);
 2668 
 2669                         sc->sc_isresumed |= (1 << index);
 2670 
 2671                 } else if (x & UHCI_PORTSC_SUSP) {
 2672                         status |= UPS_SUSPEND;
 2673                 }
 2674                 status |= UPS_PORT_POWER;
 2675                 if (sc->sc_isresumed & (1 << index))
 2676                         change |= UPS_C_SUSPEND;
 2677                 if (sc->sc_isreset)
 2678                         change |= UPS_C_PORT_RESET;
 2679                 USETW(sc->sc_hub_desc.ps.wPortStatus, status);
 2680                 USETW(sc->sc_hub_desc.ps.wPortChange, change);
 2681                 len = sizeof(sc->sc_hub_desc.ps);
 2682                 break;
 2683         case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
 2684                 err = USB_ERR_IOERROR;
 2685                 goto done;
 2686         case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
 2687                 break;
 2688         case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
 2689                 if (index == 1)
 2690                         port = UHCI_PORTSC1;
 2691                 else if (index == 2)
 2692                         port = UHCI_PORTSC2;
 2693                 else {
 2694                         err = USB_ERR_IOERROR;
 2695                         goto done;
 2696                 }
 2697                 switch (value) {
 2698                 case UHF_PORT_ENABLE:
 2699                         x = URWMASK(UREAD2(sc, port));
 2700                         UWRITE2(sc, port, x | UHCI_PORTSC_PE);
 2701                         break;
 2702                 case UHF_PORT_SUSPEND:
 2703                         x = URWMASK(UREAD2(sc, port));
 2704                         UWRITE2(sc, port, x | UHCI_PORTSC_SUSP);
 2705                         break;
 2706                 case UHF_PORT_RESET:
 2707                         err = uhci_portreset(sc, index);
 2708                         goto done;
 2709                 case UHF_PORT_POWER:
 2710                         /* pretend we turned on power */
 2711                         err = USB_ERR_NORMAL_COMPLETION;
 2712                         goto done;
 2713                 case UHF_C_PORT_CONNECTION:
 2714                 case UHF_C_PORT_ENABLE:
 2715                 case UHF_C_PORT_OVER_CURRENT:
 2716                 case UHF_PORT_CONNECTION:
 2717                 case UHF_PORT_OVER_CURRENT:
 2718                 case UHF_PORT_LOW_SPEED:
 2719                 case UHF_C_PORT_SUSPEND:
 2720                 case UHF_C_PORT_RESET:
 2721                 default:
 2722                         err = USB_ERR_IOERROR;
 2723                         goto done;
 2724                 }
 2725                 break;
 2726         default:
 2727                 err = USB_ERR_IOERROR;
 2728                 goto done;
 2729         }
 2730 done:
 2731         *plength = len;
 2732         *pptr = ptr;
 2733         return (err);
 2734 }
 2735 
 2736 /*
 2737  * This routine is executed periodically and simulates interrupts from
 2738  * the root controller interrupt pipe for port status change:
 2739  */
 2740 static void
 2741 uhci_root_intr(uhci_softc_t *sc)
 2742 {
 2743         DPRINTFN(21, "\n");
 2744 
 2745         USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
 2746 
 2747         sc->sc_hub_idata[0] = 0;
 2748 
 2749         if (UREAD2(sc, UHCI_PORTSC1) & (UHCI_PORTSC_CSC |
 2750             UHCI_PORTSC_OCIC | UHCI_PORTSC_RD)) {
 2751                 sc->sc_hub_idata[0] |= 1 << 1;
 2752         }
 2753         if (UREAD2(sc, UHCI_PORTSC2) & (UHCI_PORTSC_CSC |
 2754             UHCI_PORTSC_OCIC | UHCI_PORTSC_RD)) {
 2755                 sc->sc_hub_idata[0] |= 1 << 2;
 2756         }
 2757 
 2758         /* restart timer */
 2759         usb_callout_reset(&sc->sc_root_intr, hz,
 2760             (void *)&uhci_root_intr, sc);
 2761 
 2762         if (sc->sc_hub_idata[0] != 0) {
 2763                 uhub_root_intr(&sc->sc_bus, sc->sc_hub_idata,
 2764                     sizeof(sc->sc_hub_idata));
 2765         }
 2766 }
 2767 
 2768 static void
 2769 uhci_xfer_setup(struct usb_setup_params *parm)
 2770 {
 2771         struct usb_page_search page_info;
 2772         struct usb_page_cache *pc;
 2773         struct usb_xfer *xfer;
 2774         void *last_obj;
 2775         uint32_t ntd;
 2776         uint32_t nqh;
 2777         uint32_t nfixup;
 2778         uint32_t n;
 2779         uint16_t align;
 2780 
 2781         xfer = parm->curr_xfer;
 2782 
 2783         parm->hc_max_packet_size = 0x500;
 2784         parm->hc_max_packet_count = 1;
 2785         parm->hc_max_frame_size = 0x500;
 2786 
 2787         /*
 2788          * compute ntd and nqh
 2789          */
 2790         if (parm->methods == &uhci_device_ctrl_methods) {
 2791                 xfer->flags_int.bdma_enable = 1;
 2792                 xfer->flags_int.bdma_no_post_sync = 1;
 2793 
 2794                 usbd_transfer_setup_sub(parm);
 2795 
 2796                 /* see EHCI HC driver for proof of "ntd" formula */
 2797 
 2798                 nqh = 1;
 2799                 ntd = ((2 * xfer->nframes) + 1  /* STATUS */
 2800                     + (xfer->max_data_length / xfer->max_frame_size));
 2801 
 2802         } else if (parm->methods == &uhci_device_bulk_methods) {
 2803                 xfer->flags_int.bdma_enable = 1;
 2804                 xfer->flags_int.bdma_no_post_sync = 1;
 2805 
 2806                 usbd_transfer_setup_sub(parm);
 2807 
 2808                 nqh = 1;
 2809                 ntd = ((2 * xfer->nframes)
 2810                     + (xfer->max_data_length / xfer->max_frame_size));
 2811 
 2812         } else if (parm->methods == &uhci_device_intr_methods) {
 2813                 xfer->flags_int.bdma_enable = 1;
 2814                 xfer->flags_int.bdma_no_post_sync = 1;
 2815 
 2816                 usbd_transfer_setup_sub(parm);
 2817 
 2818                 nqh = 1;
 2819                 ntd = ((2 * xfer->nframes)
 2820                     + (xfer->max_data_length / xfer->max_frame_size));
 2821 
 2822         } else if (parm->methods == &uhci_device_isoc_methods) {
 2823                 xfer->flags_int.bdma_enable = 1;
 2824                 xfer->flags_int.bdma_no_post_sync = 1;
 2825 
 2826                 usbd_transfer_setup_sub(parm);
 2827 
 2828                 nqh = 0;
 2829                 ntd = xfer->nframes;
 2830 
 2831         } else {
 2832                 usbd_transfer_setup_sub(parm);
 2833 
 2834                 nqh = 0;
 2835                 ntd = 0;
 2836         }
 2837 
 2838         if (parm->err) {
 2839                 return;
 2840         }
 2841         /*
 2842          * NOTE: the UHCI controller requires that
 2843          * every packet must be contiguous on
 2844          * the same USB memory page !
 2845          */
 2846         nfixup = (parm->bufsize / USB_PAGE_SIZE) + 1;
 2847 
 2848         /*
 2849          * Compute a suitable power of two alignment
 2850          * for our "max_frame_size" fixup buffer(s):
 2851          */
 2852         align = xfer->max_frame_size;
 2853         n = 0;
 2854         while (align) {
 2855                 align >>= 1;
 2856                 n++;
 2857         }
 2858 
 2859         /* check for power of two */
 2860         if (!(xfer->max_frame_size &
 2861             (xfer->max_frame_size - 1))) {
 2862                 n--;
 2863         }
 2864         /*
 2865          * We don't allow alignments of
 2866          * less than 8 bytes:
 2867          *
 2868          * NOTE: Allocating using an alignment 
 2869          * of 1 byte has special meaning!
 2870          */
 2871         if (n < 3) {
 2872                 n = 3;
 2873         }
 2874         align = (1 << n);
 2875 
 2876         if (usbd_transfer_setup_sub_malloc(
 2877             parm, &pc, xfer->max_frame_size,
 2878             align, nfixup)) {
 2879                 parm->err = USB_ERR_NOMEM;
 2880                 return;
 2881         }
 2882         xfer->buf_fixup = pc;
 2883 
 2884 alloc_dma_set:
 2885 
 2886         if (parm->err) {
 2887                 return;
 2888         }
 2889         last_obj = NULL;
 2890 
 2891         if (usbd_transfer_setup_sub_malloc(
 2892             parm, &pc, sizeof(uhci_td_t),
 2893             UHCI_TD_ALIGN, ntd)) {
 2894                 parm->err = USB_ERR_NOMEM;
 2895                 return;
 2896         }
 2897         if (parm->buf) {
 2898                 for (n = 0; n != ntd; n++) {
 2899                         uhci_td_t *td;
 2900 
 2901                         usbd_get_page(pc + n, 0, &page_info);
 2902 
 2903                         td = page_info.buffer;
 2904 
 2905                         /* init TD */
 2906                         if ((parm->methods == &uhci_device_bulk_methods) ||
 2907                             (parm->methods == &uhci_device_ctrl_methods) ||
 2908                             (parm->methods == &uhci_device_intr_methods)) {
 2909                                 /* set depth first bit */
 2910                                 td->td_self = htole32(page_info.physaddr |
 2911                                     UHCI_PTR_TD | UHCI_PTR_VF);
 2912                         } else {
 2913                                 td->td_self = htole32(page_info.physaddr |
 2914                                     UHCI_PTR_TD);
 2915                         }
 2916 
 2917                         td->obj_next = last_obj;
 2918                         td->page_cache = pc + n;
 2919 
 2920                         last_obj = td;
 2921 
 2922                         usb_pc_cpu_flush(pc + n);
 2923                 }
 2924         }
 2925         xfer->td_start[xfer->flags_int.curr_dma_set] = last_obj;
 2926 
 2927         last_obj = NULL;
 2928 
 2929         if (usbd_transfer_setup_sub_malloc(
 2930             parm, &pc, sizeof(uhci_qh_t),
 2931             UHCI_QH_ALIGN, nqh)) {
 2932                 parm->err = USB_ERR_NOMEM;
 2933                 return;
 2934         }
 2935         if (parm->buf) {
 2936                 for (n = 0; n != nqh; n++) {
 2937                         uhci_qh_t *qh;
 2938 
 2939                         usbd_get_page(pc + n, 0, &page_info);
 2940 
 2941                         qh = page_info.buffer;
 2942 
 2943                         /* init QH */
 2944                         qh->qh_self = htole32(page_info.physaddr | UHCI_PTR_QH);
 2945                         qh->obj_next = last_obj;
 2946                         qh->page_cache = pc + n;
 2947 
 2948                         last_obj = qh;
 2949 
 2950                         usb_pc_cpu_flush(pc + n);
 2951                 }
 2952         }
 2953         xfer->qh_start[xfer->flags_int.curr_dma_set] = last_obj;
 2954 
 2955         if (!xfer->flags_int.curr_dma_set) {
 2956                 xfer->flags_int.curr_dma_set = 1;
 2957                 goto alloc_dma_set;
 2958         }
 2959 }
 2960 
 2961 static void
 2962 uhci_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc,
 2963     struct usb_endpoint *ep)
 2964 {
 2965         uhci_softc_t *sc = UHCI_BUS2SC(udev->bus);
 2966 
 2967         DPRINTFN(2, "endpoint=%p, addr=%d, endpt=%d, mode=%d (%d)\n",
 2968             ep, udev->address,
 2969             edesc->bEndpointAddress, udev->flags.usb_mode,
 2970             sc->sc_addr);
 2971 
 2972         if (udev->device_index != sc->sc_addr) {
 2973                 switch (edesc->bmAttributes & UE_XFERTYPE) {
 2974                 case UE_CONTROL:
 2975                         ep->methods = &uhci_device_ctrl_methods;
 2976                         break;
 2977                 case UE_INTERRUPT:
 2978                         ep->methods = &uhci_device_intr_methods;
 2979                         break;
 2980                 case UE_ISOCHRONOUS:
 2981                         if (udev->speed == USB_SPEED_FULL) {
 2982                                 ep->methods = &uhci_device_isoc_methods;
 2983                         }
 2984                         break;
 2985                 case UE_BULK:
 2986                         ep->methods = &uhci_device_bulk_methods;
 2987                         break;
 2988                 default:
 2989                         /* do nothing */
 2990                         break;
 2991                 }
 2992         }
 2993 }
 2994 
 2995 static void
 2996 uhci_xfer_unsetup(struct usb_xfer *xfer)
 2997 {
 2998         return;
 2999 }
 3000 
 3001 static void
 3002 uhci_get_dma_delay(struct usb_device *udev, uint32_t *pus)
 3003 {
 3004         /*
 3005          * Wait until hardware has finished any possible use of the
 3006          * transfer descriptor(s) and QH
 3007          */
 3008         *pus = (1125);                  /* microseconds */
 3009 }
 3010 
 3011 static void
 3012 uhci_device_resume(struct usb_device *udev)
 3013 {
 3014         struct uhci_softc *sc = UHCI_BUS2SC(udev->bus);
 3015         struct usb_xfer *xfer;
 3016         const struct usb_pipe_methods *methods;
 3017         uhci_qh_t *qh;
 3018 
 3019         DPRINTF("\n");
 3020 
 3021         USB_BUS_LOCK(udev->bus);
 3022 
 3023         TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
 3024                 if (xfer->xroot->udev == udev) {
 3025                         methods = xfer->endpoint->methods;
 3026                         qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
 3027 
 3028                         if (methods == &uhci_device_bulk_methods) {
 3029                                 UHCI_APPEND_QH(qh, sc->sc_bulk_p_last);
 3030                                 uhci_add_loop(sc);
 3031                                 xfer->flags_int.bandwidth_reclaimed = 1;
 3032                         }
 3033                         if (methods == &uhci_device_ctrl_methods) {
 3034                                 if (xfer->xroot->udev->speed == USB_SPEED_LOW) {
 3035                                         UHCI_APPEND_QH(qh, sc->sc_ls_ctl_p_last);
 3036                                 } else {
 3037                                         UHCI_APPEND_QH(qh, sc->sc_fs_ctl_p_last);
 3038                                 }
 3039                         }
 3040                         if (methods == &uhci_device_intr_methods) {
 3041                                 UHCI_APPEND_QH(qh, sc->sc_intr_p_last[xfer->qh_pos]);
 3042                         }
 3043                 }
 3044         }
 3045 
 3046         USB_BUS_UNLOCK(udev->bus);
 3047 
 3048         return;
 3049 }
 3050 
 3051 static void
 3052 uhci_device_suspend(struct usb_device *udev)
 3053 {
 3054         struct uhci_softc *sc = UHCI_BUS2SC(udev->bus);
 3055         struct usb_xfer *xfer;
 3056         const struct usb_pipe_methods *methods;
 3057         uhci_qh_t *qh;
 3058 
 3059         DPRINTF("\n");
 3060 
 3061         USB_BUS_LOCK(udev->bus);
 3062 
 3063         TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
 3064                 if (xfer->xroot->udev == udev) {
 3065                         methods = xfer->endpoint->methods;
 3066                         qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
 3067 
 3068                         if (xfer->flags_int.bandwidth_reclaimed) {
 3069                                 xfer->flags_int.bandwidth_reclaimed = 0;
 3070                                 uhci_rem_loop(sc);
 3071                         }
 3072                         if (methods == &uhci_device_bulk_methods) {
 3073                                 UHCI_REMOVE_QH(qh, sc->sc_bulk_p_last);
 3074                         }
 3075                         if (methods == &uhci_device_ctrl_methods) {
 3076                                 if (xfer->xroot->udev->speed == USB_SPEED_LOW) {
 3077                                         UHCI_REMOVE_QH(qh, sc->sc_ls_ctl_p_last);
 3078                                 } else {
 3079                                         UHCI_REMOVE_QH(qh, sc->sc_fs_ctl_p_last);
 3080                                 }
 3081                         }
 3082                         if (methods == &uhci_device_intr_methods) {
 3083                                 UHCI_REMOVE_QH(qh, sc->sc_intr_p_last[xfer->qh_pos]);
 3084                         }
 3085                 }
 3086         }
 3087 
 3088         USB_BUS_UNLOCK(udev->bus);
 3089 
 3090         return;
 3091 }
 3092 
 3093 static void
 3094 uhci_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
 3095 {
 3096         struct uhci_softc *sc = UHCI_BUS2SC(bus);
 3097 
 3098         switch (state) {
 3099         case USB_HW_POWER_SUSPEND:
 3100         case USB_HW_POWER_SHUTDOWN:
 3101                 uhci_suspend(sc);
 3102                 break;
 3103         case USB_HW_POWER_RESUME:
 3104                 uhci_resume(sc);
 3105                 break;
 3106         default:
 3107                 break;
 3108         }
 3109 }
 3110 
 3111 static void
 3112 uhci_set_hw_power(struct usb_bus *bus)
 3113 {
 3114         struct uhci_softc *sc = UHCI_BUS2SC(bus);
 3115         uint32_t flags;
 3116 
 3117         DPRINTF("\n");
 3118 
 3119         USB_BUS_LOCK(bus);
 3120 
 3121         flags = bus->hw_power_state;
 3122 
 3123         /*
 3124          * WARNING: Some FULL speed USB devices require periodic SOF
 3125          * messages! If any USB devices are connected through the
 3126          * UHCI, power save will be disabled!
 3127          */
 3128         if (flags & (USB_HW_POWER_CONTROL |
 3129             USB_HW_POWER_NON_ROOT_HUB |
 3130             USB_HW_POWER_BULK |
 3131             USB_HW_POWER_INTERRUPT |
 3132             USB_HW_POWER_ISOC)) {
 3133                 DPRINTF("Some USB transfer is "
 3134                     "active on unit %u.\n",
 3135                     device_get_unit(sc->sc_bus.bdev));
 3136                 uhci_restart(sc);
 3137         } else {
 3138                 DPRINTF("Power save on unit %u.\n",
 3139                     device_get_unit(sc->sc_bus.bdev));
 3140                 UHCICMD(sc, UHCI_CMD_MAXP);
 3141         }
 3142 
 3143         USB_BUS_UNLOCK(bus);
 3144 
 3145         return;
 3146 }
 3147 
 3148 static const struct usb_bus_methods uhci_bus_methods =
 3149 {
 3150         .endpoint_init = uhci_ep_init,
 3151         .xfer_setup = uhci_xfer_setup,
 3152         .xfer_unsetup = uhci_xfer_unsetup,
 3153         .get_dma_delay = uhci_get_dma_delay,
 3154         .device_resume = uhci_device_resume,
 3155         .device_suspend = uhci_device_suspend,
 3156         .set_hw_power = uhci_set_hw_power,
 3157         .set_hw_power_sleep = uhci_set_hw_power_sleep,
 3158         .roothub_exec = uhci_roothub_exec,
 3159         .xfer_poll = uhci_do_poll,
 3160 };

Cache object: 3f698350a46560f436cd75afd78c9b95


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