LCOV - code coverage report
Current view: top level - dev/usb - ehci.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 1540 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 74 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: ehci.c,v 1.200 2017/05/15 10:52:08 mpi Exp $ */
       2             : /*      $NetBSD: ehci.c,v 1.66 2004/06/30 03:11:56 mycroft Exp $        */
       3             : 
       4             : /*
       5             :  * Copyright (c) 2014-2015 Martin Pieuchot
       6             :  *
       7             :  * Permission to use, copy, modify, and distribute this software for any
       8             :  * purpose with or without fee is hereby granted, provided that the above
       9             :  * copyright notice and this permission notice appear in all copies.
      10             :  *
      11             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      12             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      13             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      14             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      15             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      16             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      17             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      18             :  */
      19             : /*
      20             :  * Copyright (c) 2004-2008 The NetBSD Foundation, Inc.
      21             :  * All rights reserved.
      22             :  *
      23             :  * This code is derived from software contributed to The NetBSD Foundation
      24             :  * by Lennart Augustsson (lennart@augustsson.net), Charles M. Hannum and
      25             :  * Jeremy Morse (jeremy.morse@gmail.com).
      26             :  *
      27             :  * Redistribution and use in source and binary forms, with or without
      28             :  * modification, are permitted provided that the following conditions
      29             :  * are met:
      30             :  * 1. Redistributions of source code must retain the above copyright
      31             :  *    notice, this list of conditions and the following disclaimer.
      32             :  * 2. Redistributions in binary form must reproduce the above copyright
      33             :  *    notice, this list of conditions and the following disclaimer in the
      34             :  *    documentation and/or other materials provided with the distribution.
      35             :  *
      36             :  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
      37             :  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
      38             :  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      39             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
      40             :  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      41             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      42             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      43             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      44             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      45             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             :  * POSSIBILITY OF SUCH DAMAGE.
      47             :  */
      48             : 
      49             : /*
      50             :  * TODO:
      51             :  * 1) The hub driver needs to handle and schedule the transaction translator,
      52             :  *    to assign place in frame where different devices get to go. See chapter
      53             :  *    on hubs in USB 2.0 for details.
      54             :  *
      55             :  * 2) Command failures are not recovered correctly.
      56             :  */
      57             : 
      58             : #include <sys/param.h>
      59             : #include <sys/systm.h>
      60             : #include <sys/kernel.h>
      61             : #include <sys/rwlock.h>
      62             : #include <sys/malloc.h>
      63             : #include <sys/device.h>
      64             : #include <sys/queue.h>
      65             : #include <sys/timeout.h>
      66             : #include <sys/pool.h>
      67             : #include <sys/endian.h>
      68             : #include <sys/atomic.h>
      69             : 
      70             : #include <machine/bus.h>
      71             : 
      72             : #include <dev/usb/usb.h>
      73             : #include <dev/usb/usbdi.h>
      74             : #include <dev/usb/usbdivar.h>
      75             : #include <dev/usb/usb_mem.h>
      76             : 
      77             : #include <dev/usb/ehcireg.h>
      78             : #include <dev/usb/ehcivar.h>
      79             : 
      80             : struct cfdriver ehci_cd = {
      81             :         NULL, "ehci", DV_DULL
      82             : };
      83             : 
      84             : #ifdef EHCI_DEBUG
      85             : #define DPRINTF(x)      do { if (ehcidebug) printf x; } while(0)
      86             : #define DPRINTFN(n,x)   do { if (ehcidebug>(n)) printf x; } while (0)
      87             : int ehcidebug = 0;
      88             : #define bitmask_snprintf(q,f,b,l) snprintf((b), (l), "%b", (q), (f))
      89             : #else
      90             : #define DPRINTF(x)
      91             : #define DPRINTFN(n,x)
      92             : #endif
      93             : 
      94             : struct pool *ehcixfer;
      95             : 
      96             : struct ehci_pipe {
      97             :         struct usbd_pipe pipe;
      98             : 
      99             :         struct ehci_soft_qh *sqh;
     100             :         union {
     101             :                 /* Control pipe */
     102             :                 struct {
     103             :                         struct usb_dma reqdma;
     104             :                 } ctl;
     105             :                 /* Iso pipe */
     106             :                 struct {
     107             :                         u_int next_frame;
     108             :                         u_int cur_xfers;
     109             :                 } isoc;
     110             :         } u;
     111             : };
     112             : 
     113             : u_int8_t                ehci_reverse_bits(u_int8_t, int);
     114             : 
     115             : usbd_status     ehci_open(struct usbd_pipe *);
     116             : int             ehci_setaddr(struct usbd_device *, int);
     117             : void            ehci_poll(struct usbd_bus *);
     118             : void            ehci_softintr(void *);
     119             : int             ehci_intr1(struct ehci_softc *);
     120             : void            ehci_check_intr(struct ehci_softc *, struct usbd_xfer *);
     121             : void            ehci_check_qh_intr(struct ehci_softc *, struct usbd_xfer *);
     122             : void            ehci_check_itd_intr(struct ehci_softc *, struct usbd_xfer *);
     123             : void            ehci_idone(struct usbd_xfer *);
     124             : void            ehci_isoc_idone(struct usbd_xfer *);
     125             : void            ehci_timeout(void *);
     126             : void            ehci_timeout_task(void *);
     127             : void            ehci_intrlist_timeout(void *);
     128             : 
     129             : struct usbd_xfer *ehci_allocx(struct usbd_bus *);
     130             : void            ehci_freex(struct usbd_bus *, struct usbd_xfer *);
     131             : 
     132             : usbd_status     ehci_root_ctrl_transfer(struct usbd_xfer *);
     133             : usbd_status     ehci_root_ctrl_start(struct usbd_xfer *);
     134             : void            ehci_root_ctrl_abort(struct usbd_xfer *);
     135             : void            ehci_root_ctrl_close(struct usbd_pipe *);
     136             : void            ehci_root_ctrl_done(struct usbd_xfer *);
     137             : 
     138             : usbd_status     ehci_root_intr_transfer(struct usbd_xfer *);
     139             : usbd_status     ehci_root_intr_start(struct usbd_xfer *);
     140             : void            ehci_root_intr_abort(struct usbd_xfer *);
     141             : void            ehci_root_intr_close(struct usbd_pipe *);
     142             : void            ehci_root_intr_done(struct usbd_xfer *);
     143             : 
     144             : usbd_status     ehci_device_ctrl_transfer(struct usbd_xfer *);
     145             : usbd_status     ehci_device_ctrl_start(struct usbd_xfer *);
     146             : void            ehci_device_ctrl_abort(struct usbd_xfer *);
     147             : void            ehci_device_ctrl_close(struct usbd_pipe *);
     148             : void            ehci_device_ctrl_done(struct usbd_xfer *);
     149             : 
     150             : usbd_status     ehci_device_bulk_transfer(struct usbd_xfer *);
     151             : usbd_status     ehci_device_bulk_start(struct usbd_xfer *);
     152             : void            ehci_device_bulk_abort(struct usbd_xfer *);
     153             : void            ehci_device_bulk_close(struct usbd_pipe *);
     154             : void            ehci_device_bulk_done(struct usbd_xfer *);
     155             : 
     156             : usbd_status     ehci_device_intr_transfer(struct usbd_xfer *);
     157             : usbd_status     ehci_device_intr_start(struct usbd_xfer *);
     158             : void            ehci_device_intr_abort(struct usbd_xfer *);
     159             : void            ehci_device_intr_close(struct usbd_pipe *);
     160             : void            ehci_device_intr_done(struct usbd_xfer *);
     161             : 
     162             : usbd_status     ehci_device_isoc_transfer(struct usbd_xfer *);
     163             : usbd_status     ehci_device_isoc_start(struct usbd_xfer *);
     164             : void            ehci_device_isoc_abort(struct usbd_xfer *);
     165             : void            ehci_device_isoc_close(struct usbd_pipe *);
     166             : void            ehci_device_isoc_done(struct usbd_xfer *);
     167             : 
     168             : void            ehci_device_clear_toggle(struct usbd_pipe *pipe);
     169             : 
     170             : void            ehci_pcd(struct ehci_softc *, struct usbd_xfer *);
     171             : void            ehci_disown(struct ehci_softc *, int, int);
     172             : 
     173             : struct ehci_soft_qh *ehci_alloc_sqh(struct ehci_softc *);
     174             : void            ehci_free_sqh(struct ehci_softc *, struct ehci_soft_qh *);
     175             : 
     176             : struct ehci_soft_qtd *ehci_alloc_sqtd(struct ehci_softc *);
     177             : void            ehci_free_sqtd(struct ehci_softc *, struct ehci_soft_qtd *);
     178             : usbd_status     ehci_alloc_sqtd_chain(struct ehci_softc *, u_int,
     179             :                     struct usbd_xfer *, struct ehci_soft_qtd **, struct ehci_soft_qtd **);
     180             : void            ehci_free_sqtd_chain(struct ehci_softc *, struct ehci_xfer *);
     181             : 
     182             : struct ehci_soft_itd *ehci_alloc_itd(struct ehci_softc *);
     183             : void            ehci_free_itd(struct ehci_softc *, struct ehci_soft_itd *);
     184             : void            ehci_rem_itd_chain(struct ehci_softc *, struct ehci_xfer *);
     185             : void            ehci_free_itd_chain(struct ehci_softc *, struct ehci_xfer *);
     186             : int             ehci_alloc_itd_chain(struct ehci_softc *, struct usbd_xfer *);
     187             : int             ehci_alloc_sitd_chain(struct ehci_softc *, struct usbd_xfer *);
     188             : void            ehci_abort_isoc_xfer(struct usbd_xfer *xfer,
     189             :                     usbd_status status);
     190             : 
     191             : usbd_status     ehci_device_setintr(struct ehci_softc *, struct ehci_soft_qh *,
     192             :                             int ival);
     193             : 
     194             : void            ehci_add_qh(struct ehci_soft_qh *, struct ehci_soft_qh *);
     195             : void            ehci_rem_qh(struct ehci_softc *, struct ehci_soft_qh *);
     196             : void            ehci_set_qh_qtd(struct ehci_soft_qh *, struct ehci_soft_qtd *);
     197             : void            ehci_sync_hc(struct ehci_softc *);
     198             : 
     199             : void            ehci_close_pipe(struct usbd_pipe *);
     200             : void            ehci_abort_xfer(struct usbd_xfer *, usbd_status);
     201             : 
     202             : #ifdef EHCI_DEBUG
     203             : void            ehci_dump_regs(struct ehci_softc *);
     204             : void            ehci_dump(void);
     205             : struct ehci_softc *theehci;
     206             : void            ehci_dump_link(ehci_link_t, int);
     207             : void            ehci_dump_sqtds(struct ehci_soft_qtd *);
     208             : void            ehci_dump_sqtd(struct ehci_soft_qtd *);
     209             : void            ehci_dump_qtd(struct ehci_qtd *);
     210             : void            ehci_dump_sqh(struct ehci_soft_qh *);
     211             : #if notyet
     212             : void            ehci_dump_itd(struct ehci_soft_itd *);
     213             : #endif
     214             : #ifdef DIAGNOSTIC
     215             : void            ehci_dump_exfer(struct ehci_xfer *);
     216             : #endif
     217             : #endif
     218             : 
     219             : #define EHCI_INTR_ENDPT 1
     220             : 
     221             : struct usbd_bus_methods ehci_bus_methods = {
     222             :         .open_pipe = ehci_open,
     223             :         .dev_setaddr = ehci_setaddr,
     224             :         .soft_intr = ehci_softintr,
     225             :         .do_poll = ehci_poll,
     226             :         .allocx = ehci_allocx,
     227             :         .freex = ehci_freex,
     228             : };
     229             : 
     230             : struct usbd_pipe_methods ehci_root_ctrl_methods = {
     231             :         .transfer = ehci_root_ctrl_transfer,
     232             :         .start = ehci_root_ctrl_start,
     233             :         .abort = ehci_root_ctrl_abort,
     234             :         .close = ehci_root_ctrl_close,
     235             :         .done = ehci_root_ctrl_done,
     236             : };
     237             : 
     238             : struct usbd_pipe_methods ehci_root_intr_methods = {
     239             :         .transfer = ehci_root_intr_transfer,
     240             :         .start = ehci_root_intr_start,
     241             :         .abort = ehci_root_intr_abort,
     242             :         .close = ehci_root_intr_close,
     243             :         .done = ehci_root_intr_done,
     244             : };
     245             : 
     246             : struct usbd_pipe_methods ehci_device_ctrl_methods = {
     247             :         .transfer = ehci_device_ctrl_transfer,
     248             :         .start = ehci_device_ctrl_start,
     249             :         .abort = ehci_device_ctrl_abort,
     250             :         .close = ehci_device_ctrl_close,
     251             :         .done = ehci_device_ctrl_done,
     252             : };
     253             : 
     254             : struct usbd_pipe_methods ehci_device_intr_methods = {
     255             :         .transfer = ehci_device_intr_transfer,
     256             :         .start = ehci_device_intr_start,
     257             :         .abort = ehci_device_intr_abort,
     258             :         .close = ehci_device_intr_close,
     259             :         .cleartoggle = ehci_device_clear_toggle,
     260             :         .done = ehci_device_intr_done,
     261             : };
     262             : 
     263             : struct usbd_pipe_methods ehci_device_bulk_methods = {
     264             :         .transfer = ehci_device_bulk_transfer,
     265             :         .start = ehci_device_bulk_start,
     266             :         .abort = ehci_device_bulk_abort,
     267             :         .close = ehci_device_bulk_close,
     268             :         .cleartoggle = ehci_device_clear_toggle,
     269             :         .done = ehci_device_bulk_done,
     270             : };
     271             : 
     272             : struct usbd_pipe_methods ehci_device_isoc_methods = {
     273             :         .transfer = ehci_device_isoc_transfer,
     274             :         .start = ehci_device_isoc_start,
     275             :         .abort = ehci_device_isoc_abort,
     276             :         .close = ehci_device_isoc_close,
     277             :         .done = ehci_device_isoc_done,
     278             : };
     279             : 
     280             : /*
     281             :  * Reverse a number with nbits bits.  Used to evenly distribute lower-level
     282             :  * interrupt heads in the periodic schedule.
     283             :  * Suitable for use with EHCI_IPOLLRATES <= 9.
     284             :  */
     285             : u_int8_t
     286           0 : ehci_reverse_bits(u_int8_t c, int nbits)
     287             : {
     288           0 :         c = ((c >> 1) & 0x55) | ((c << 1) & 0xaa);
     289           0 :         c = ((c >> 2) & 0x33) | ((c << 2) & 0xcc);
     290           0 :         c = ((c >> 4) & 0x0f) | ((c << 4) & 0xf0);
     291             : 
     292           0 :         return c >> (8 - nbits);
     293             : }
     294             : 
     295             : usbd_status
     296           0 : ehci_init(struct ehci_softc *sc)
     297             : {
     298             :         u_int32_t sparams, cparams, hcr;
     299             :         u_int i, j;
     300             :         usbd_status err;
     301             :         struct ehci_soft_qh *sqh;
     302             : 
     303             : #ifdef EHCI_DEBUG
     304             :         u_int32_t vers;
     305             :         theehci = sc;
     306             : 
     307             :         DPRINTF(("ehci_init: start\n"));
     308             : 
     309             :         vers = EREAD2(sc, EHCI_HCIVERSION);
     310             :         DPRINTF(("%s: EHCI version %x.%x\n", sc->sc_bus.bdev.dv_xname,
     311             :             vers >> 8, vers & 0xff));
     312             : #endif
     313             : 
     314           0 :         sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH);
     315             : 
     316           0 :         sparams = EREAD4(sc, EHCI_HCSPARAMS);
     317             :         DPRINTF(("ehci_init: sparams=0x%x\n", sparams));
     318           0 :         sc->sc_noport = EHCI_HCS_N_PORTS(sparams);
     319           0 :         cparams = EREAD4(sc, EHCI_HCCPARAMS);
     320             :         DPRINTF(("ehci_init: cparams=0x%x\n", cparams));
     321             : 
     322             :         /* MUST clear segment register if 64 bit capable. */
     323           0 :         if (EHCI_HCC_64BIT(cparams))
     324           0 :                 EWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
     325             : 
     326           0 :         sc->sc_bus.usbrev = USBREV_2_0;
     327             : 
     328             :         DPRINTF(("%s: resetting\n", sc->sc_bus.bdev.dv_xname));
     329           0 :         err = ehci_reset(sc);
     330           0 :         if (err)
     331           0 :                 return (err);
     332             : 
     333           0 :         if (ehcixfer == NULL) {
     334           0 :                 ehcixfer = malloc(sizeof(struct pool), M_DEVBUF, M_NOWAIT);
     335           0 :                 if (ehcixfer == NULL) {
     336           0 :                         printf("%s: unable to allocate pool descriptor\n",
     337           0 :                             sc->sc_bus.bdev.dv_xname);
     338           0 :                         return (ENOMEM);
     339             :                 }
     340           0 :                 pool_init(ehcixfer, sizeof(struct ehci_xfer), 0, IPL_SOFTUSB,
     341             :                     0, "ehcixfer", NULL);
     342           0 :         }
     343             : 
     344             :         /* frame list size at default, read back what we got and use that */
     345           0 :         switch (EHCI_CMD_FLS(EOREAD4(sc, EHCI_USBCMD))) {
     346             :         case 0:
     347           0 :                 sc->sc_flsize = 1024;
     348           0 :                 break;
     349             :         case 1:
     350           0 :                 sc->sc_flsize = 512;
     351           0 :                 break;
     352             :         case 2:
     353           0 :                 sc->sc_flsize = 256;
     354           0 :                 break;
     355             :         case 3:
     356           0 :                 return (USBD_IOERROR);
     357             :         }
     358           0 :         err = usb_allocmem(&sc->sc_bus, sc->sc_flsize * sizeof(ehci_link_t),
     359           0 :             EHCI_FLALIGN_ALIGN, &sc->sc_fldma);
     360           0 :         if (err)
     361           0 :                 return (err);
     362             :         DPRINTF(("%s: flsize=%d\n", sc->sc_bus.bdev.dv_xname,sc->sc_flsize));
     363           0 :         sc->sc_flist = KERNADDR(&sc->sc_fldma, 0);
     364             : 
     365           0 :         for (i = 0; i < sc->sc_flsize; i++)
     366           0 :                 sc->sc_flist[i] = htole32(EHCI_LINK_TERMINATE);
     367             : 
     368           0 :         EOWRITE4(sc, EHCI_PERIODICLISTBASE, DMAADDR(&sc->sc_fldma, 0));
     369             : 
     370           0 :         sc->sc_softitds = mallocarray(sc->sc_flsize,
     371             :             sizeof(struct ehci_soft_itd *), M_USB, M_NOWAIT | M_ZERO);
     372           0 :         if (sc->sc_softitds == NULL) {
     373           0 :                 usb_freemem(&sc->sc_bus, &sc->sc_fldma);
     374           0 :                 return (ENOMEM);
     375             :         }
     376           0 :         LIST_INIT(&sc->sc_freeitds);
     377           0 :         TAILQ_INIT(&sc->sc_intrhead);
     378             : 
     379             :         /* Set up the bus struct. */
     380           0 :         sc->sc_bus.methods = &ehci_bus_methods;
     381           0 :         sc->sc_bus.pipe_size = sizeof(struct ehci_pipe);
     382             : 
     383           0 :         sc->sc_eintrs = EHCI_NORMAL_INTRS;
     384             : 
     385             :         /*
     386             :          * Allocate the interrupt dummy QHs. These are arranged to give poll
     387             :          * intervals that are powers of 2 times 1ms.
     388             :          */
     389           0 :         for (i = 0; i < EHCI_INTRQHS; i++) {
     390           0 :                 sqh = ehci_alloc_sqh(sc);
     391           0 :                 if (sqh == NULL) {
     392             :                         err = USBD_NOMEM;
     393           0 :                         goto bad1;
     394             :                 }
     395           0 :                 sc->sc_islots[i].sqh = sqh;
     396             :         }
     397           0 :         for (i = 0; i < EHCI_INTRQHS; i++) {
     398           0 :                 sqh = sc->sc_islots[i].sqh;
     399           0 :                 if (i == 0) {
     400             :                         /* The last (1ms) QH terminates. */
     401           0 :                         sqh->qh.qh_link = htole32(EHCI_LINK_TERMINATE);
     402           0 :                         sqh->next = NULL;
     403           0 :                 } else {
     404             :                         /* Otherwise the next QH has half the poll interval */
     405           0 :                         sqh->next = sc->sc_islots[(i + 1) / 2 - 1].sqh;
     406           0 :                         sqh->qh.qh_link = htole32(sqh->next->physaddr |
     407             :                             EHCI_LINK_QH);
     408             :                 }
     409           0 :                 sqh->qh.qh_endp = htole32(EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH));
     410           0 :                 sqh->qh.qh_endphub = htole32(EHCI_QH_SET_MULT(1));
     411           0 :                 sqh->qh.qh_curqtd = htole32(EHCI_LINK_TERMINATE);
     412           0 :                 sqh->qh.qh_qtd.qtd_next = htole32(EHCI_LINK_TERMINATE);
     413           0 :                 sqh->qh.qh_qtd.qtd_altnext = htole32(EHCI_LINK_TERMINATE);
     414           0 :                 sqh->qh.qh_qtd.qtd_status = htole32(EHCI_QTD_HALTED);
     415           0 :                 sqh->sqtd = NULL;
     416           0 :                 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
     417             :                     BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
     418             :         }
     419             :         /* Point the frame list at the last level (128ms). */
     420           0 :         for (i = 0; i < (1 << (EHCI_IPOLLRATES - 1)); i++)
     421           0 :                 for (j = i; j < sc->sc_flsize; j += 1 << (EHCI_IPOLLRATES - 1))
     422           0 :                         sc->sc_flist[j] = htole32(EHCI_LINK_QH | sc->sc_islots[
     423             :                             EHCI_IQHIDX(EHCI_IPOLLRATES - 1, ehci_reverse_bits(
     424             :                             i, EHCI_IPOLLRATES - 1))].sqh->physaddr);
     425           0 :         usb_syncmem(&sc->sc_fldma, 0, sc->sc_flsize * sizeof(ehci_link_t),
     426             :             BUS_DMASYNC_PREWRITE);
     427             : 
     428             :         /* Allocate dummy QH that starts the async list. */
     429           0 :         sqh = ehci_alloc_sqh(sc);
     430           0 :         if (sqh == NULL) {
     431             :                 err = USBD_NOMEM;
     432           0 :                 goto bad1;
     433             :         }
     434             :         /* Fill the QH */
     435           0 :         sqh->qh.qh_endp =
     436             :             htole32(EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH) | EHCI_QH_HRECL);
     437           0 :         sqh->qh.qh_link =
     438           0 :             htole32(sqh->physaddr | EHCI_LINK_QH);
     439           0 :         sqh->qh.qh_curqtd = htole32(EHCI_LINK_TERMINATE);
     440           0 :         sqh->prev = sqh; /*It's a circular list.. */
     441           0 :         sqh->next = sqh;
     442             :         /* Fill the overlay qTD */
     443           0 :         sqh->qh.qh_qtd.qtd_next = htole32(EHCI_LINK_TERMINATE);
     444           0 :         sqh->qh.qh_qtd.qtd_altnext = htole32(EHCI_LINK_TERMINATE);
     445           0 :         sqh->qh.qh_qtd.qtd_status = htole32(EHCI_QTD_HALTED);
     446           0 :         sqh->sqtd = NULL;
     447           0 :         usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
     448             :             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
     449             : 
     450             :         /* Point to async list */
     451           0 :         sc->sc_async_head = sqh;
     452           0 :         EOWRITE4(sc, EHCI_ASYNCLISTADDR, sqh->physaddr | EHCI_LINK_QH);
     453             : 
     454           0 :         timeout_set(&sc->sc_tmo_intrlist, ehci_intrlist_timeout, sc);
     455             : 
     456           0 :         rw_init(&sc->sc_doorbell_lock, "ehcidb");
     457             : 
     458             :         /* Turn on controller */
     459           0 :         EOWRITE4(sc, EHCI_USBCMD,
     460             :             EHCI_CMD_ITC_2 | /* 2 microframes interrupt delay */
     461             :             (EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_FLS_M) |
     462             :             EHCI_CMD_ASE |
     463             :             EHCI_CMD_PSE |
     464             :             EHCI_CMD_RS);
     465             : 
     466             :         /* Take over port ownership */
     467           0 :         EOWRITE4(sc, EHCI_CONFIGFLAG, EHCI_CONF_CF);
     468             : 
     469           0 :         for (i = 0; i < 100; i++) {
     470           0 :                 usb_delay_ms(&sc->sc_bus, 1);
     471           0 :                 hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
     472           0 :                 if (!hcr)
     473             :                         break;
     474             :         }
     475           0 :         if (hcr) {
     476           0 :                 printf("%s: run timeout\n", sc->sc_bus.bdev.dv_xname);
     477           0 :                 return (USBD_IOERROR);
     478             :         }
     479             : 
     480             :         /* Enable interrupts */
     481           0 :         EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
     482             : 
     483           0 :         return (USBD_NORMAL_COMPLETION);
     484             : 
     485             : #if 0
     486             :  bad2:
     487             :         ehci_free_sqh(sc, sc->sc_async_head);
     488             : #endif
     489             :  bad1:
     490           0 :         free(sc->sc_softitds, M_USB,
     491           0 :             sc->sc_flsize * sizeof(struct ehci_soft_itd *));
     492           0 :         usb_freemem(&sc->sc_bus, &sc->sc_fldma);
     493           0 :         return (err);
     494           0 : }
     495             : 
     496             : int
     497           0 : ehci_intr(void *v)
     498             : {
     499           0 :         struct ehci_softc *sc = v;
     500             : 
     501           0 :         if (sc == NULL || sc->sc_bus.dying)
     502           0 :                 return (0);
     503             : 
     504             :         /* If we get an interrupt while polling, then just ignore it. */
     505           0 :         if (sc->sc_bus.use_polling) {
     506           0 :                 u_int32_t intrs = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS));
     507             : 
     508           0 :                 if (intrs)
     509           0 :                         EOWRITE4(sc, EHCI_USBSTS, intrs); /* Acknowledge */
     510             :                 return (0);
     511             :         }
     512             : 
     513           0 :         return (ehci_intr1(sc));
     514           0 : }
     515             : 
     516             : int
     517           0 : ehci_intr1(struct ehci_softc *sc)
     518             : {
     519             :         u_int32_t intrs, eintrs;
     520             : 
     521             :         /* In case the interrupt occurs before initialization has completed. */
     522           0 :         if (sc == NULL) {
     523             : #ifdef DIAGNOSTIC
     524           0 :                 printf("ehci_intr1: sc == NULL\n");
     525             : #endif
     526           0 :                 return (0);
     527             :         }
     528             : 
     529           0 :         intrs = EOREAD4(sc, EHCI_USBSTS);
     530           0 :         if (intrs == 0xffffffff) {
     531           0 :                 sc->sc_bus.dying = 1;
     532           0 :                 return (0);
     533             :         }
     534           0 :         intrs = EHCI_STS_INTRS(intrs);
     535           0 :         if (!intrs)
     536           0 :                 return (0);
     537             : 
     538           0 :         eintrs = intrs & sc->sc_eintrs;
     539           0 :         if (!eintrs)
     540           0 :                 return (0);
     541             : 
     542           0 :         EOWRITE4(sc, EHCI_USBSTS, intrs); /* Acknowledge */
     543           0 :         sc->sc_bus.no_intrs++;
     544             : 
     545           0 :         if (eintrs & EHCI_STS_HSE) {
     546           0 :                 printf("%s: unrecoverable error, controller halted\n",
     547           0 :                        sc->sc_bus.bdev.dv_xname);
     548           0 :                 sc->sc_bus.dying = 1;
     549           0 :                 return (1);
     550             :         }
     551           0 :         if (eintrs & EHCI_STS_IAA) {
     552           0 :                 wakeup(&sc->sc_async_head);
     553           0 :                 eintrs &= ~EHCI_STS_IAA;
     554           0 :         }
     555           0 :         if (eintrs & (EHCI_STS_INT | EHCI_STS_ERRINT)) {
     556           0 :                 usb_schedsoftintr(&sc->sc_bus);
     557           0 :                 eintrs &= ~(EHCI_STS_INT | EHCI_STS_ERRINT);
     558           0 :         }
     559           0 :         if (eintrs & EHCI_STS_PCD) {
     560           0 :                 atomic_setbits_int(&sc->sc_flags, EHCIF_PCB_INTR);
     561           0 :                 usb_schedsoftintr(&sc->sc_bus);
     562           0 :                 eintrs &= ~EHCI_STS_PCD;
     563           0 :         }
     564             : 
     565           0 :         if (eintrs != 0) {
     566             :                 /* Block unprocessed interrupts. */
     567           0 :                 sc->sc_eintrs &= ~eintrs;
     568           0 :                 EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
     569           0 :                 printf("%s: blocking intrs 0x%x\n",
     570           0 :                        sc->sc_bus.bdev.dv_xname, eintrs);
     571           0 :         }
     572             : 
     573           0 :         return (1);
     574           0 : }
     575             : 
     576             : void
     577           0 : ehci_pcd(struct ehci_softc *sc, struct usbd_xfer *xfer)
     578             : {
     579             :         u_char *p;
     580             :         int i, m;
     581             : 
     582           0 :         if (xfer == NULL) {
     583             :                 /* Just ignore the change. */
     584           0 :                 return;
     585             :         }
     586             : 
     587           0 :         p = KERNADDR(&xfer->dmabuf, 0);
     588           0 :         m = min(sc->sc_noport, xfer->length * 8 - 1);
     589           0 :         memset(p, 0, xfer->length);
     590           0 :         for (i = 1; i <= m; i++) {
     591             :                 /* Pick out CHANGE bits from the status reg. */
     592           0 :                 if (EOREAD4(sc, EHCI_PORTSC(i)) & EHCI_PS_CLEAR)
     593           0 :                         p[i / 8] |= 1 << (i % 8);
     594             :         }
     595           0 :         xfer->actlen = xfer->length;
     596           0 :         xfer->status = USBD_NORMAL_COMPLETION;
     597             : 
     598           0 :         usb_transfer_complete(xfer);
     599           0 : }
     600             : 
     601             : /*
     602             :  * Work around the half configured control (default) pipe when setting
     603             :  * the address of a device.
     604             :  *
     605             :  * Because a single QH is setup per endpoint in ehci_open(), and the
     606             :  * control pipe is configured before we could have set the address
     607             :  * of the device or read the wMaxPacketSize of the endpoint, we have
     608             :  * to re-open the pipe twice here.
     609             :  */
     610             : int
     611           0 : ehci_setaddr(struct usbd_device *dev, int addr)
     612             : {
     613             :         /* Root Hub */
     614           0 :         if (dev->depth == 0)
     615           0 :                 return (0);
     616             : 
     617             :         /* Re-establish the default pipe with the new max packet size. */
     618           0 :         ehci_close_pipe(dev->default_pipe);
     619           0 :         if (ehci_open(dev->default_pipe))
     620           0 :                 return (EINVAL);
     621             : 
     622           0 :         if (usbd_set_address(dev, addr))
     623           0 :                 return (1);
     624             : 
     625           0 :         dev->address = addr;
     626             : 
     627             :         /* Re-establish the default pipe with the new address. */
     628           0 :         ehci_close_pipe(dev->default_pipe);
     629           0 :         if (ehci_open(dev->default_pipe))
     630           0 :                 return (EINVAL);
     631             : 
     632           0 :         return (0);
     633           0 : }
     634             : 
     635             : void
     636           0 : ehci_softintr(void *v)
     637             : {
     638           0 :         struct ehci_softc *sc = v;
     639             :         struct ehci_xfer *ex, *nextex;
     640             : 
     641           0 :         if (sc->sc_bus.dying)
     642           0 :                 return;
     643             : 
     644           0 :         sc->sc_bus.intr_context++;
     645             : 
     646           0 :         if (sc->sc_flags & EHCIF_PCB_INTR) {
     647           0 :                 atomic_clearbits_int(&sc->sc_flags, EHCIF_PCB_INTR);
     648           0 :                 ehci_pcd(sc, sc->sc_intrxfer);
     649           0 :         }
     650             : 
     651             :         /*
     652             :          * The only explanation I can think of for why EHCI is as brain dead
     653             :          * as UHCI interrupt-wise is that Intel was involved in both.
     654             :          * An interrupt just tells us that something is done, we have no
     655             :          * clue what, so we need to scan through all active transfers. :-(
     656             :          */
     657           0 :         for (ex = TAILQ_FIRST(&sc->sc_intrhead); ex; ex = nextex) {
     658           0 :                 nextex = TAILQ_NEXT(ex, inext);
     659           0 :                 ehci_check_intr(sc, &ex->xfer);
     660             :         }
     661             : 
     662             :         /* Schedule a callout to catch any dropped transactions. */
     663           0 :         if ((sc->sc_flags & EHCIF_DROPPED_INTR_WORKAROUND) &&
     664           0 :             !TAILQ_EMPTY(&sc->sc_intrhead)) {
     665           0 :                 timeout_add_sec(&sc->sc_tmo_intrlist, 1);
     666           0 :         }
     667             : 
     668           0 :         if (sc->sc_softwake) {
     669           0 :                 sc->sc_softwake = 0;
     670           0 :                 wakeup(&sc->sc_softwake);
     671           0 :         }
     672             : 
     673           0 :         sc->sc_bus.intr_context--;
     674           0 : }
     675             : 
     676             : void
     677           0 : ehci_check_intr(struct ehci_softc *sc, struct usbd_xfer *xfer)
     678             : {
     679           0 :         int attr = xfer->pipe->endpoint->edesc->bmAttributes;
     680             : 
     681           0 :         if (UE_GET_XFERTYPE(attr) == UE_ISOCHRONOUS)
     682           0 :                 ehci_check_itd_intr(sc, xfer);
     683             :         else
     684           0 :                 ehci_check_qh_intr(sc, xfer);
     685           0 : }
     686             : 
     687             : void
     688           0 : ehci_check_qh_intr(struct ehci_softc *sc, struct usbd_xfer *xfer)
     689             : {
     690           0 :         struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
     691           0 :         struct ehci_soft_qtd *sqtd, *lsqtd = ex->sqtdend;
     692             :         uint32_t status;
     693             : 
     694           0 :         KASSERT(ex->sqtdstart != NULL && ex->sqtdend != NULL);
     695             : 
     696           0 :         usb_syncmem(&lsqtd->dma,
     697           0 :             lsqtd->offs + offsetof(struct ehci_qtd, qtd_status),
     698             :             sizeof(lsqtd->qtd.qtd_status),
     699             :             BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
     700             : 
     701             :         /*
     702             :          * If the last TD is still active we need to check whether there
     703             :          * is a an error somewhere in the middle, or whether there was a
     704             :          * short packet (SPD and not ACTIVE).
     705             :          */
     706           0 :         if (letoh32(lsqtd->qtd.qtd_status) & EHCI_QTD_ACTIVE) {
     707             :                 DPRINTFN(12, ("ehci_check_intr: active ex=%p\n", ex));
     708           0 :                 for (sqtd = ex->sqtdstart; sqtd != lsqtd; sqtd=sqtd->nextqtd) {
     709           0 :                         usb_syncmem(&sqtd->dma,
     710           0 :                             sqtd->offs + offsetof(struct ehci_qtd, qtd_status),
     711             :                             sizeof(sqtd->qtd.qtd_status),
     712             :                             BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
     713           0 :                         status = letoh32(sqtd->qtd.qtd_status);
     714           0 :                         usb_syncmem(&sqtd->dma,
     715           0 :                             sqtd->offs + offsetof(struct ehci_qtd, qtd_status),
     716             :                             sizeof(sqtd->qtd.qtd_status), BUS_DMASYNC_PREREAD);
     717             :                         /* If there's an active QTD the xfer isn't done. */
     718           0 :                         if (status & EHCI_QTD_ACTIVE)
     719             :                                 break;
     720             :                         /* Any kind of error makes the xfer done. */
     721           0 :                         if (status & EHCI_QTD_HALTED)
     722             :                                 goto done;
     723             :                         /* We want short packets, and it is short: it's done */
     724           0 :                         if (EHCI_QTD_GET_BYTES(status) != 0)
     725             :                                 goto done;
     726             :                 }
     727             :                 DPRINTFN(12, ("ehci_check_intr: ex=%p std=%p still active\n",
     728             :                               ex, ex->sqtdstart));
     729           0 :                 usb_syncmem(&lsqtd->dma,
     730           0 :                     lsqtd->offs + offsetof(struct ehci_qtd, qtd_status),
     731             :                     sizeof(lsqtd->qtd.qtd_status), BUS_DMASYNC_PREREAD);
     732           0 :                 return;
     733             :         }
     734             :  done:
     735           0 :         TAILQ_REMOVE(&sc->sc_intrhead, ex, inext);
     736           0 :         timeout_del(&xfer->timeout_handle);
     737           0 :         usb_rem_task(xfer->pipe->device, &xfer->abort_task);
     738           0 :         ehci_idone(xfer);
     739           0 : }
     740             : 
     741             : void
     742           0 : ehci_check_itd_intr(struct ehci_softc *sc, struct usbd_xfer *xfer)
     743             : {
     744           0 :         struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
     745           0 :         struct ehci_soft_itd *itd = ex->itdend;
     746             :         int i;
     747             : 
     748           0 :         if (xfer != SIMPLEQ_FIRST(&xfer->pipe->queue))
     749           0 :                 return;
     750             : 
     751           0 :         KASSERT(ex->itdstart != NULL && ex->itdend != NULL);
     752             : 
     753             :         /* Check no active transfers in last itd, meaning we're finished */
     754           0 :         if (xfer->device->speed == USB_SPEED_HIGH) {
     755           0 :                 usb_syncmem(&itd->dma,
     756           0 :                     itd->offs + offsetof(struct ehci_itd, itd_ctl),
     757             :                     sizeof(itd->itd.itd_ctl),
     758             :                     BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
     759             : 
     760           0 :                 for (i = 0; i < 8; i++) {
     761           0 :                         if (letoh32(itd->itd.itd_ctl[i]) & EHCI_ITD_ACTIVE)
     762           0 :                                 return;
     763             :                 }
     764             :         } else {
     765           0 :                 usb_syncmem(&itd->dma,
     766           0 :                     itd->offs + offsetof(struct ehci_sitd, sitd_trans),
     767             :                     sizeof(itd->sitd.sitd_trans),
     768             :                     BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
     769             : 
     770           0 :                 if (le32toh(itd->sitd.sitd_trans) & EHCI_SITD_ACTIVE)
     771           0 :                         return;
     772             :         }
     773             : 
     774             :         /* All descriptor(s) inactive, it's done */
     775           0 :         TAILQ_REMOVE(&sc->sc_intrhead, ex, inext);
     776           0 :         timeout_del(&xfer->timeout_handle);
     777           0 :         usb_rem_task(xfer->pipe->device, &xfer->abort_task);
     778           0 :         ehci_isoc_idone(xfer);
     779           0 : }
     780             : 
     781             : void
     782           0 : ehci_isoc_idone(struct usbd_xfer *xfer)
     783             : {
     784           0 :         struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
     785             :         struct ehci_soft_itd *itd;
     786             :         int i, len, uframes, nframes = 0, actlen = 0;
     787             :         uint32_t status = 0;
     788             : 
     789           0 :         if (xfer->status == USBD_CANCELLED || xfer->status == USBD_TIMEOUT)
     790           0 :                 return;
     791             : 
     792           0 :         if (xfer->device->speed == USB_SPEED_HIGH) {
     793           0 :                 switch (xfer->pipe->endpoint->edesc->bInterval) {
     794             :                 case 0:
     795           0 :                         panic("isoc xfer suddenly has 0 bInterval, invalid");
     796             :                 case 1:
     797             :                         uframes = 1;
     798           0 :                         break;
     799             :                 case 2:
     800             :                         uframes = 2;
     801           0 :                         break;
     802             :                 case 3:
     803             :                         uframes = 4;
     804           0 :                         break;
     805             :                 default:
     806             :                         uframes = 8;
     807           0 :                         break;
     808             :                 }
     809             : 
     810           0 :                 for (itd = ex->itdstart; itd != NULL; itd = itd->xfer_next) {
     811           0 :                         usb_syncmem(&itd->dma,
     812           0 :                             itd->offs + offsetof(struct ehci_itd, itd_ctl),
     813             :                             sizeof(itd->itd.itd_ctl), BUS_DMASYNC_POSTWRITE |
     814             :                             BUS_DMASYNC_POSTREAD);
     815             : 
     816           0 :                         for (i = 0; i < 8; i += uframes) {
     817             :                                 /* XXX - driver didn't fill in the frame full
     818             :                                  *   of uframes. This leads to scheduling
     819             :                                  *   inefficiencies, but working around
     820             :                                  *   this doubles complexity of tracking
     821             :                                  *   an xfer.
     822             :                                  */
     823           0 :                                 if (nframes >= xfer->nframes)
     824             :                                         break;
     825             : 
     826           0 :                                 status = letoh32(itd->itd.itd_ctl[i]);
     827           0 :                                 len = EHCI_ITD_GET_LEN(status);
     828           0 :                                 if (EHCI_ITD_GET_STATUS(status) != 0)
     829             :                                         len = 0; /*No valid data on error*/
     830             : 
     831           0 :                                 xfer->frlengths[nframes++] = len;
     832           0 :                                 actlen += len;
     833             :                         }
     834             :                 }
     835             :         } else {
     836           0 :                 for (itd = ex->itdstart; itd != NULL; itd = itd->xfer_next) {
     837           0 :                         usb_syncmem(&itd->dma,
     838           0 :                             itd->offs + offsetof(struct ehci_sitd, sitd_trans),
     839             :                             sizeof(itd->sitd.sitd_trans),
     840             :                             BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
     841             : 
     842           0 :                         status = le32toh(itd->sitd.sitd_trans);
     843           0 :                         len = EHCI_SITD_GET_LEN(status);
     844           0 :                         if (xfer->frlengths[nframes] >= len)
     845           0 :                                 len = xfer->frlengths[nframes] - len;
     846             :                         else
     847             :                                 len = 0;
     848             : 
     849           0 :                         xfer->frlengths[nframes++] = len;
     850           0 :                         actlen += len;
     851             :                 }
     852             :         }
     853             : 
     854             : #ifdef DIAGNOSTIC
     855           0 :         ex->isdone = 1;
     856             : #endif
     857           0 :         xfer->actlen = actlen;
     858           0 :         xfer->status = USBD_NORMAL_COMPLETION;
     859           0 :         usb_transfer_complete(xfer);
     860           0 : }
     861             : 
     862             : void
     863           0 : ehci_idone(struct usbd_xfer *xfer)
     864             : {
     865           0 :         struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
     866             :         struct ehci_soft_qtd *sqtd;
     867             :         u_int32_t status = 0, nstatus = 0;
     868             :         int actlen, cerr;
     869             : 
     870             : #ifdef DIAGNOSTIC
     871             :         {
     872           0 :                 int s = splhigh();
     873           0 :                 if (ex->isdone) {
     874           0 :                         splx(s);
     875           0 :                         printf("ehci_idone: ex=%p is done!\n", ex);
     876           0 :                         return;
     877             :                 }
     878           0 :                 ex->isdone = 1;
     879           0 :                 splx(s);
     880           0 :         }
     881             : #endif
     882           0 :         if (xfer->status == USBD_CANCELLED || xfer->status == USBD_TIMEOUT)
     883           0 :                 return;
     884             : 
     885             :         actlen = 0;
     886           0 :         for (sqtd = ex->sqtdstart; sqtd != NULL; sqtd = sqtd->nextqtd) {
     887           0 :                 usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(sqtd->qtd),
     888             :                     BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
     889           0 :                 nstatus = letoh32(sqtd->qtd.qtd_status);
     890           0 :                 if (nstatus & EHCI_QTD_ACTIVE)
     891             :                         break;
     892             : 
     893             :                 status = nstatus;
     894             :                 /* halt is ok if descriptor is last, and complete */
     895           0 :                 if (sqtd->qtd.qtd_next == htole32(EHCI_LINK_TERMINATE) &&
     896           0 :                     EHCI_QTD_GET_BYTES(status) == 0)
     897           0 :                         status &= ~EHCI_QTD_HALTED;
     898           0 :                 if (EHCI_QTD_GET_PID(status) != EHCI_QTD_PID_SETUP)
     899           0 :                         actlen += sqtd->len - EHCI_QTD_GET_BYTES(status);
     900             :         }
     901             : 
     902           0 :         cerr = EHCI_QTD_GET_CERR(status);
     903             :         DPRINTFN(/*10*/2, ("ehci_idone: len=%d, actlen=%d, cerr=%d, "
     904             :             "status=0x%x\n", xfer->length, actlen, cerr, status));
     905           0 :         xfer->actlen = actlen;
     906           0 :         if ((status & EHCI_QTD_HALTED) != 0) {
     907           0 :                 if ((status & EHCI_QTD_BABBLE) == 0 && cerr > 0)
     908           0 :                         xfer->status = USBD_STALLED;
     909             :                 else
     910           0 :                         xfer->status = USBD_IOERROR; /* more info XXX */
     911             :         } else
     912           0 :                 xfer->status = USBD_NORMAL_COMPLETION;
     913             : 
     914             :         /* XXX transfer_complete memcpys out transfer data (for in endpoints)
     915             :          * during this call, before methods->done is called: dma sync required
     916             :          * beforehand? */
     917           0 :         usb_transfer_complete(xfer);
     918             :         DPRINTFN(/*12*/2, ("ehci_idone: ex=%p done\n", ex));
     919           0 : }
     920             : 
     921             : void
     922           0 : ehci_poll(struct usbd_bus *bus)
     923             : {
     924           0 :         struct ehci_softc *sc = (struct ehci_softc *)bus;
     925             : 
     926           0 :         if (EOREAD4(sc, EHCI_USBSTS) & sc->sc_eintrs)
     927           0 :                 ehci_intr1(sc);
     928           0 : }
     929             : 
     930             : int
     931           0 : ehci_detach(struct device *self, int flags)
     932             : {
     933           0 :         struct ehci_softc *sc = (struct ehci_softc *)self;
     934             :         int rv;
     935             : 
     936           0 :         rv = config_detach_children(self, flags);
     937           0 :         if (rv != 0)
     938           0 :                 return (rv);
     939             : 
     940           0 :         timeout_del(&sc->sc_tmo_intrlist);
     941             : 
     942           0 :         ehci_reset(sc);
     943             : 
     944           0 :         usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
     945             : 
     946           0 :         free(sc->sc_softitds, M_USB,
     947           0 :             sc->sc_flsize * sizeof(struct ehci_soft_itd *));
     948           0 :         usb_freemem(&sc->sc_bus, &sc->sc_fldma);
     949             :         /* XXX free other data structures XXX */
     950             : 
     951           0 :         return (rv);
     952           0 : }
     953             : 
     954             : 
     955             : int
     956           0 : ehci_activate(struct device *self, int act)
     957             : {
     958           0 :         struct ehci_softc *sc = (struct ehci_softc *)self;
     959             :         u_int32_t cmd, hcr, cparams;
     960             :         int i, rv = 0;
     961             : 
     962           0 :         switch (act) {
     963             :         case DVACT_SUSPEND:
     964           0 :                 rv = config_activate_children(self, act);
     965             : 
     966             : #ifdef DIAGNOSTIC
     967           0 :                 if (!TAILQ_EMPTY(&sc->sc_intrhead)) {
     968           0 :                         printf("%s: interrupt list not empty\n",
     969           0 :                             sc->sc_bus.bdev.dv_xname);
     970           0 :                         return (-1);
     971             :                 }
     972             : #endif
     973             : 
     974           0 :                 sc->sc_bus.use_polling++;
     975             : 
     976           0 :                 for (i = 1; i <= sc->sc_noport; i++) {
     977           0 :                         cmd = EOREAD4(sc, EHCI_PORTSC(i));
     978           0 :                         if ((cmd & (EHCI_PS_PO|EHCI_PS_PE)) == EHCI_PS_PE)
     979           0 :                                 EOWRITE4(sc, EHCI_PORTSC(i),
     980             :                                     cmd | EHCI_PS_SUSP);
     981             :                 }
     982             : 
     983             :                 /*
     984             :                  * First tell the host to stop processing Asynchronous
     985             :                  * and Periodic schedules.
     986             :                  */
     987           0 :                 cmd = EOREAD4(sc, EHCI_USBCMD) & ~(EHCI_CMD_ASE | EHCI_CMD_PSE);
     988           0 :                 EOWRITE4(sc, EHCI_USBCMD, cmd);
     989           0 :                 for (i = 0; i < 100; i++) {
     990           0 :                         usb_delay_ms(&sc->sc_bus, 1);
     991           0 :                         hcr = EOREAD4(sc, EHCI_USBSTS) &
     992             :                             (EHCI_STS_ASS | EHCI_STS_PSS);
     993           0 :                         if (hcr == 0)
     994             :                                 break;
     995             :                 }
     996           0 :                 if (hcr != 0)
     997           0 :                         printf("%s: disable schedules timeout\n",
     998           0 :                             sc->sc_bus.bdev.dv_xname);
     999             : 
    1000             :                 /*
    1001             :                  * Then reset the host as if it was a shutdown.
    1002             :                  *
    1003             :                  * All USB devices are disconnected/reconnected during
    1004             :                  * a suspend/resume cycle so keep it simple.
    1005             :                  */
    1006           0 :                 ehci_reset(sc);
    1007             : 
    1008           0 :                 sc->sc_bus.use_polling--;
    1009           0 :                 break;
    1010             :         case DVACT_RESUME:
    1011           0 :                 sc->sc_bus.use_polling++;
    1012             : 
    1013           0 :                 ehci_reset(sc);
    1014             : 
    1015           0 :                 cparams = EREAD4(sc, EHCI_HCCPARAMS);
    1016             :                 /* MUST clear segment register if 64 bit capable. */
    1017           0 :                 if (EHCI_HCC_64BIT(cparams))
    1018           0 :                         EWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
    1019             : 
    1020           0 :                 EOWRITE4(sc, EHCI_PERIODICLISTBASE, DMAADDR(&sc->sc_fldma, 0));
    1021           0 :                 EOWRITE4(sc, EHCI_ASYNCLISTADDR,
    1022             :                     sc->sc_async_head->physaddr | EHCI_LINK_QH);
    1023             : 
    1024             :                 hcr = 0;
    1025           0 :                 for (i = 1; i <= sc->sc_noport; i++) {
    1026           0 :                         cmd = EOREAD4(sc, EHCI_PORTSC(i));
    1027           0 :                         if ((cmd & (EHCI_PS_PO|EHCI_PS_SUSP)) == EHCI_PS_SUSP) {
    1028           0 :                                 EOWRITE4(sc, EHCI_PORTSC(i), cmd | EHCI_PS_FPR);
    1029             :                                 hcr = 1;
    1030           0 :                         }
    1031             :                 }
    1032             : 
    1033           0 :                 if (hcr) {
    1034           0 :                         usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
    1035           0 :                         for (i = 1; i <= sc->sc_noport; i++) {
    1036           0 :                                 cmd = EOREAD4(sc, EHCI_PORTSC(i));
    1037           0 :                                 if ((cmd & (EHCI_PS_PO|EHCI_PS_SUSP)) ==
    1038             :                                    EHCI_PS_SUSP)
    1039           0 :                                         EOWRITE4(sc, EHCI_PORTSC(i),
    1040             :                                            cmd & ~EHCI_PS_FPR);
    1041             :                         }
    1042             :                 }
    1043             : 
    1044             :                 /* Turn on controller */
    1045           0 :                 EOWRITE4(sc, EHCI_USBCMD,
    1046             :                     EHCI_CMD_ITC_2 | /* 2 microframes interrupt delay */
    1047             :                     (EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_FLS_M) |
    1048             :                     EHCI_CMD_ASE |
    1049             :                     EHCI_CMD_PSE |
    1050             :                     EHCI_CMD_RS);
    1051             : 
    1052             :                 /* Take over port ownership */
    1053           0 :                 EOWRITE4(sc, EHCI_CONFIGFLAG, EHCI_CONF_CF);
    1054           0 :                 for (i = 0; i < 100; i++) {
    1055           0 :                         usb_delay_ms(&sc->sc_bus, 1);
    1056           0 :                         hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
    1057           0 :                         if (!hcr)
    1058             :                                 break;
    1059             :                 }
    1060             : 
    1061           0 :                 if (hcr) {
    1062           0 :                         printf("%s: run timeout\n", sc->sc_bus.bdev.dv_xname);
    1063             :                         /* XXX should we bail here? */
    1064           0 :                 }
    1065             : 
    1066           0 :                 EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
    1067             : 
    1068           0 :                 usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
    1069             : 
    1070           0 :                 sc->sc_bus.use_polling--;
    1071           0 :                 rv = config_activate_children(self, act);
    1072           0 :                 break;
    1073             :         case DVACT_POWERDOWN:
    1074           0 :                 rv = config_activate_children(self, act);
    1075           0 :                 ehci_reset(sc);
    1076           0 :                 break;
    1077             :         default:
    1078           0 :                 rv = config_activate_children(self, act);
    1079           0 :                 break;
    1080             :         }
    1081           0 :         return (rv);
    1082           0 : }
    1083             : 
    1084             : usbd_status
    1085           0 : ehci_reset(struct ehci_softc *sc)
    1086             : {
    1087             :         u_int32_t hcr, usbmode;
    1088             :         int i;
    1089             : 
    1090           0 :         EOWRITE4(sc, EHCI_USBCMD, 0);   /* Halt controller */
    1091           0 :         for (i = 0; i < 100; i++) {
    1092           0 :                 usb_delay_ms(&sc->sc_bus, 1);
    1093           0 :                 hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
    1094           0 :                 if (hcr)
    1095             :                         break;
    1096             :         }
    1097             : 
    1098           0 :         if (!hcr)
    1099           0 :                 printf("%s: halt timeout\n", sc->sc_bus.bdev.dv_xname);
    1100             : 
    1101           0 :         if (sc->sc_flags & EHCIF_USBMODE)
    1102           0 :                 usbmode = EOREAD4(sc, EHCI_USBMODE);
    1103             : 
    1104           0 :         EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET);
    1105           0 :         for (i = 0; i < 100; i++) {
    1106           0 :                 usb_delay_ms(&sc->sc_bus, 1);
    1107           0 :                 hcr = EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_HCRESET;
    1108           0 :                 if (!hcr)
    1109             :                         break;
    1110             :         }
    1111             : 
    1112           0 :         if (hcr) {
    1113           0 :                 printf("%s: reset timeout\n", sc->sc_bus.bdev.dv_xname);
    1114           0 :                 return (USBD_IOERROR);
    1115             :         }
    1116             : 
    1117           0 :         if (sc->sc_flags & EHCIF_USBMODE)
    1118           0 :                 EOWRITE4(sc, EHCI_USBMODE, usbmode);
    1119             : 
    1120           0 :         return (USBD_NORMAL_COMPLETION);
    1121           0 : }
    1122             : 
    1123             : struct usbd_xfer *
    1124           0 : ehci_allocx(struct usbd_bus *bus)
    1125             : {
    1126             :         struct ehci_xfer *ex;
    1127             : 
    1128           0 :         ex = pool_get(ehcixfer, PR_NOWAIT | PR_ZERO);
    1129             : #ifdef DIAGNOSTIC
    1130           0 :         if (ex != NULL)
    1131           0 :                 ex->isdone = 1;
    1132             : #endif
    1133           0 :         return ((struct usbd_xfer *)ex);
    1134             : }
    1135             : 
    1136             : void
    1137           0 : ehci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer)
    1138             : {
    1139           0 :         struct ehci_xfer *ex = (struct ehci_xfer*)xfer;
    1140             : 
    1141             : #ifdef DIAGNOSTIC
    1142           0 :         if (!ex->isdone) {
    1143           0 :                 printf("%s: !isdone\n", __func__);
    1144           0 :                 return;
    1145             :         }
    1146             : #endif
    1147           0 :         pool_put(ehcixfer, ex);
    1148           0 : }
    1149             : 
    1150             : void
    1151           0 : ehci_device_clear_toggle(struct usbd_pipe *pipe)
    1152             : {
    1153           0 :         struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
    1154             : 
    1155             : #ifdef DIAGNOSTIC
    1156           0 :         if ((epipe->sqh->qh.qh_qtd.qtd_status & htole32(EHCI_QTD_ACTIVE)) != 0)
    1157           0 :                 panic("ehci_device_clear_toggle: queue active");
    1158             : #endif
    1159           0 :         epipe->sqh->qh.qh_qtd.qtd_status &= htole32(~EHCI_QTD_TOGGLE_MASK);
    1160           0 : }
    1161             : 
    1162             : #ifdef EHCI_DEBUG
    1163             : void
    1164             : ehci_dump_regs(struct ehci_softc *sc)
    1165             : {
    1166             :         int i;
    1167             : 
    1168             :         printf("cmd=0x%08x, sts=0x%08x, ien=0x%08x\n",
    1169             :             EOREAD4(sc, EHCI_USBCMD),
    1170             :             EOREAD4(sc, EHCI_USBSTS),
    1171             :             EOREAD4(sc, EHCI_USBINTR));
    1172             :         printf("frindex=0x%08x ctrdsegm=0x%08x periodic=0x%08x async=0x%08x\n",
    1173             :             EOREAD4(sc, EHCI_FRINDEX),
    1174             :             EOREAD4(sc, EHCI_CTRLDSSEGMENT),
    1175             :             EOREAD4(sc, EHCI_PERIODICLISTBASE),
    1176             :             EOREAD4(sc, EHCI_ASYNCLISTADDR));
    1177             :         for (i = 1; i <= sc->sc_noport; i++)
    1178             :                 printf("port %d status=0x%08x\n", i,
    1179             :                     EOREAD4(sc, EHCI_PORTSC(i)));
    1180             : }
    1181             : 
    1182             : /*
    1183             :  * Unused function - this is meant to be called from a kernel
    1184             :  * debugger.
    1185             :  */
    1186             : void
    1187             : ehci_dump(void)
    1188             : {
    1189             :         ehci_dump_regs(theehci);
    1190             : }
    1191             : 
    1192             : void
    1193             : ehci_dump_link(ehci_link_t link, int type)
    1194             : {
    1195             :         link = letoh32(link);
    1196             :         printf("0x%08x", link);
    1197             :         if (link & EHCI_LINK_TERMINATE)
    1198             :                 printf("<T>");
    1199             :         else {
    1200             :                 printf("<");
    1201             :                 if (type) {
    1202             :                         switch (EHCI_LINK_TYPE(link)) {
    1203             :                         case EHCI_LINK_ITD:
    1204             :                                 printf("ITD");
    1205             :                                 break;
    1206             :                         case EHCI_LINK_QH:
    1207             :                                 printf("QH");
    1208             :                                 break;
    1209             :                         case EHCI_LINK_SITD:
    1210             :                                 printf("SITD");
    1211             :                                 break;
    1212             :                         case EHCI_LINK_FSTN:
    1213             :                                 printf("FSTN");
    1214             :                                 break;
    1215             :                         }
    1216             :                 }
    1217             :                 printf(">");
    1218             :         }
    1219             : }
    1220             : 
    1221             : void
    1222             : ehci_dump_sqtds(struct ehci_soft_qtd *sqtd)
    1223             : {
    1224             :         int i;
    1225             :         u_int32_t stop;
    1226             : 
    1227             :         stop = 0;
    1228             :         for (i = 0; sqtd && i < 20 && !stop; sqtd = sqtd->nextqtd, i++) {
    1229             :                 ehci_dump_sqtd(sqtd);
    1230             :                 usb_syncmem(&sqtd->dma,
    1231             :                     sqtd->offs + offsetof(struct ehci_qtd, qtd_next),
    1232             :                     sizeof(sqtd->qtd),
    1233             :                     BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
    1234             :                 stop = sqtd->qtd.qtd_next & htole32(EHCI_LINK_TERMINATE);
    1235             :                 usb_syncmem(&sqtd->dma,
    1236             :                     sqtd->offs + offsetof(struct ehci_qtd, qtd_next),
    1237             :                     sizeof(sqtd->qtd), BUS_DMASYNC_PREREAD);
    1238             :         }
    1239             :         if (!stop)
    1240             :                 printf("dump aborted, too many TDs\n");
    1241             : }
    1242             : 
    1243             : void
    1244             : ehci_dump_sqtd(struct ehci_soft_qtd *sqtd)
    1245             : {
    1246             :         usb_syncmem(&sqtd->dma, sqtd->offs, 
    1247             :             sizeof(sqtd->qtd), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
    1248             :         printf("QTD(%p) at 0x%08x:\n", sqtd, sqtd->physaddr);
    1249             :         ehci_dump_qtd(&sqtd->qtd);
    1250             :         usb_syncmem(&sqtd->dma, sqtd->offs, 
    1251             :             sizeof(sqtd->qtd), BUS_DMASYNC_PREREAD);
    1252             : }
    1253             : 
    1254             : void
    1255             : ehci_dump_qtd(struct ehci_qtd *qtd)
    1256             : {
    1257             :         u_int32_t s;
    1258             :         char sbuf[128];
    1259             : 
    1260             :         printf("  next="); ehci_dump_link(qtd->qtd_next, 0);
    1261             :         printf(" altnext="); ehci_dump_link(qtd->qtd_altnext, 0);
    1262             :         printf("\n");
    1263             :         s = letoh32(qtd->qtd_status);
    1264             :         bitmask_snprintf(EHCI_QTD_GET_STATUS(s), "\20\10ACTIVE\7HALTED"
    1265             :             "\6BUFERR\5BABBLE\4XACTERR\3MISSED\2SPLIT\1PING",
    1266             :             sbuf, sizeof(sbuf));
    1267             :         printf("  status=0x%08x: toggle=%d bytes=0x%x ioc=%d c_page=0x%x\n",
    1268             :             s, EHCI_QTD_GET_TOGGLE(s), EHCI_QTD_GET_BYTES(s),
    1269             :             EHCI_QTD_GET_IOC(s), EHCI_QTD_GET_C_PAGE(s));
    1270             :         printf("    cerr=%d pid=%d stat=0x%s\n", EHCI_QTD_GET_CERR(s),
    1271             :             EHCI_QTD_GET_PID(s), sbuf);
    1272             :         for (s = 0; s < 5; s++)
    1273             :                 printf("  buffer[%d]=0x%08x\n", s, letoh32(qtd->qtd_buffer[s]));
    1274             : }
    1275             : 
    1276             : void
    1277             : ehci_dump_sqh(struct ehci_soft_qh *sqh)
    1278             : {
    1279             :         struct ehci_qh *qh = &sqh->qh;
    1280             :         u_int32_t endp, endphub;
    1281             : 
    1282             :         usb_syncmem(&sqh->dma, sqh->offs,
    1283             :             sizeof(sqh->qh), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
    1284             :         printf("QH(%p) at 0x%08x:\n", sqh, sqh->physaddr);
    1285             :         printf("  link="); ehci_dump_link(qh->qh_link, 1); printf("\n");
    1286             :         endp = letoh32(qh->qh_endp);
    1287             :         printf("  endp=0x%08x\n", endp);
    1288             :         printf("    addr=0x%02x inact=%d endpt=%d eps=%d dtc=%d hrecl=%d\n",
    1289             :             EHCI_QH_GET_ADDR(endp), EHCI_QH_GET_INACT(endp),
    1290             :             EHCI_QH_GET_ENDPT(endp),  EHCI_QH_GET_EPS(endp),
    1291             :             EHCI_QH_GET_DTC(endp), EHCI_QH_GET_HRECL(endp));
    1292             :         printf("    mpl=0x%x ctl=%d nrl=%d\n",
    1293             :             EHCI_QH_GET_MPL(endp), EHCI_QH_GET_CTL(endp),
    1294             :             EHCI_QH_GET_NRL(endp));
    1295             :         endphub = letoh32(qh->qh_endphub);
    1296             :         printf("  endphub=0x%08x\n", endphub);
    1297             :         printf("    smask=0x%02x cmask=0x%02x huba=0x%02x port=%d mult=%d\n",
    1298             :             EHCI_QH_GET_SMASK(endphub), EHCI_QH_GET_CMASK(endphub),
    1299             :             EHCI_QH_GET_HUBA(endphub), EHCI_QH_GET_PORT(endphub),
    1300             :             EHCI_QH_GET_MULT(endphub));
    1301             :         printf("  curqtd="); ehci_dump_link(qh->qh_curqtd, 0); printf("\n");
    1302             :         printf("Overlay qTD:\n");
    1303             :         ehci_dump_qtd(&qh->qh_qtd);
    1304             :         usb_syncmem(&sqh->dma, sqh->offs,
    1305             :             sizeof(sqh->qh), BUS_DMASYNC_PREREAD);
    1306             : }
    1307             : 
    1308             : #if notyet
    1309             : void
    1310             : ehci_dump_itd(struct ehci_soft_itd *itd)
    1311             : {
    1312             :         ehci_isoc_trans_t t;
    1313             :         ehci_isoc_bufr_ptr_t b, b2, b3;
    1314             :         int i;
    1315             : 
    1316             :         printf("ITD: next phys=%X\n", itd->itd.itd_next);
    1317             : 
    1318             :         for (i = 0; i < 8; i++) {
    1319             :                 t = letoh32(itd->itd.itd_ctl[i]);
    1320             :                 printf("ITDctl %d: stat=%X len=%X ioc=%X pg=%X offs=%X\n", i,
    1321             :                     EHCI_ITD_GET_STATUS(t), EHCI_ITD_GET_LEN(t),
    1322             :                     EHCI_ITD_GET_IOC(t), EHCI_ITD_GET_PG(t),
    1323             :                     EHCI_ITD_GET_OFFS(t));
    1324             :         }
    1325             :         printf("ITDbufr: ");
    1326             :         for (i = 0; i < 7; i++)
    1327             :                 printf("%X,", EHCI_ITD_GET_BPTR(letoh32(itd->itd.itd_bufr[i])));
    1328             : 
    1329             :         b = letoh32(itd->itd.itd_bufr[0]);
    1330             :         b2 = letoh32(itd->itd.itd_bufr[1]);
    1331             :         b3 = letoh32(itd->itd.itd_bufr[2]);
    1332             :         printf("\nep=%X daddr=%X dir=%d maxpkt=%X multi=%X\n",
    1333             :             EHCI_ITD_GET_EP(b), EHCI_ITD_GET_DADDR(b), EHCI_ITD_GET_DIR(b2),
    1334             :             EHCI_ITD_GET_MAXPKT(b2), EHCI_ITD_GET_MULTI(b3));
    1335             : }
    1336             : #endif
    1337             : 
    1338             : #ifdef DIAGNOSTIC
    1339             : void
    1340             : ehci_dump_exfer(struct ehci_xfer *ex)
    1341             : {
    1342             :         printf("ehci_dump_exfer: ex=%p sqtdstart=%p end=%p itdstart=%p end=%p "
    1343             :             "isdone=%d\n", ex, ex->sqtdstart, ex->sqtdend, ex->itdstart,
    1344             :             ex->itdend, ex->isdone);
    1345             : }
    1346             : #endif
    1347             : 
    1348             : #endif /* EHCI_DEBUG */
    1349             : 
    1350             : usbd_status
    1351           0 : ehci_open(struct usbd_pipe *pipe)
    1352             : {
    1353           0 :         struct usbd_device *dev = pipe->device;
    1354           0 :         struct ehci_softc *sc = (struct ehci_softc *)dev->bus;
    1355           0 :         usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
    1356           0 :         u_int8_t addr = dev->address;
    1357           0 :         u_int8_t xfertype = ed->bmAttributes & UE_XFERTYPE;
    1358           0 :         struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
    1359             :         struct ehci_soft_qh *sqh;
    1360             :         usbd_status err;
    1361             :         int s;
    1362             :         int ival, speed, naks;
    1363             :         int hshubaddr, hshubport;
    1364             : 
    1365             :         DPRINTFN(1, ("ehci_open: pipe=%p, addr=%d, endpt=%d\n",
    1366             :             pipe, addr, ed->bEndpointAddress));
    1367             : 
    1368           0 :         if (sc->sc_bus.dying)
    1369           0 :                 return (USBD_IOERROR);
    1370             : 
    1371           0 :         if (dev->myhsport) {
    1372           0 :                 hshubaddr = dev->myhsport->parent->address;
    1373           0 :                 hshubport = dev->myhsport->portno;
    1374           0 :         } else {
    1375             :                 hshubaddr = 0;
    1376             :                 hshubport = 0;
    1377             :         }
    1378             : 
    1379             :         /* Root Hub */
    1380           0 :         if (pipe->device->depth == 0) {
    1381           0 :                 switch (ed->bEndpointAddress) {
    1382             :                 case USB_CONTROL_ENDPOINT:
    1383           0 :                         pipe->methods = &ehci_root_ctrl_methods;
    1384           0 :                         break;
    1385             :                 case UE_DIR_IN | EHCI_INTR_ENDPT:
    1386           0 :                         pipe->methods = &ehci_root_intr_methods;
    1387           0 :                         break;
    1388             :                 default:
    1389           0 :                         return (USBD_INVAL);
    1390             :                 }
    1391           0 :                 return (USBD_NORMAL_COMPLETION);
    1392             :         }
    1393             : 
    1394             :         /* XXX All this stuff is only valid for async. */
    1395           0 :         switch (dev->speed) {
    1396             :         case USB_SPEED_LOW:
    1397             :                 speed = EHCI_QH_SPEED_LOW;
    1398           0 :                 break;
    1399             :         case USB_SPEED_FULL:
    1400             :                 speed = EHCI_QH_SPEED_FULL;
    1401           0 :                 break;
    1402             :         case USB_SPEED_HIGH:
    1403             :                 speed = EHCI_QH_SPEED_HIGH;
    1404           0 :                 break;
    1405             :         default:
    1406           0 :                 panic("ehci_open: bad device speed %d", dev->speed);
    1407             :         }
    1408             : 
    1409             :         naks = 8;               /* XXX */
    1410             : 
    1411             :         /* Allocate sqh for everything, save isoc xfers */
    1412           0 :         if (xfertype != UE_ISOCHRONOUS) {
    1413           0 :                 sqh = ehci_alloc_sqh(sc);
    1414           0 :                 if (sqh == NULL)
    1415           0 :                         return (USBD_NOMEM);
    1416             :                 /* qh_link filled when the QH is added */
    1417           0 :                 sqh->qh.qh_endp = htole32(
    1418             :                     EHCI_QH_SET_ADDR(addr) |
    1419             :                     EHCI_QH_SET_ENDPT(UE_GET_ADDR(ed->bEndpointAddress)) |
    1420             :                     EHCI_QH_SET_EPS(speed) |
    1421             :                     (xfertype == UE_CONTROL ? EHCI_QH_DTC : 0) |
    1422             :                     EHCI_QH_SET_MPL(UGETW(ed->wMaxPacketSize)) |
    1423             :                     (speed != EHCI_QH_SPEED_HIGH && xfertype == UE_CONTROL ?
    1424             :                     EHCI_QH_CTL : 0) |
    1425             :                     EHCI_QH_SET_NRL(naks)
    1426             :                 );
    1427           0 :                 sqh->qh.qh_endphub = htole32(
    1428             :                     EHCI_QH_SET_MULT(1) |
    1429             :                     EHCI_QH_SET_SMASK(xfertype == UE_INTERRUPT ? 0x01 : 0)
    1430             :                 );
    1431           0 :                 if (speed != EHCI_QH_SPEED_HIGH) {
    1432           0 :                         sqh->qh.qh_endphub |= htole32(
    1433             :                             EHCI_QH_SET_HUBA(hshubaddr) |
    1434             :                             EHCI_QH_SET_PORT(hshubport) |
    1435             :                             EHCI_QH_SET_CMASK(0x1c) /* XXX */
    1436             :                         );
    1437           0 :                 }
    1438           0 :                 sqh->qh.qh_curqtd = htole32(EHCI_LINK_TERMINATE);
    1439             :                 /* Fill the overlay qTD */
    1440           0 :                 sqh->qh.qh_qtd.qtd_next = htole32(EHCI_LINK_TERMINATE);
    1441           0 :                 sqh->qh.qh_qtd.qtd_altnext = htole32(EHCI_LINK_TERMINATE);
    1442           0 :                 sqh->qh.qh_qtd.qtd_status =
    1443           0 :                     htole32(EHCI_QTD_SET_TOGGLE(pipe->endpoint->savedtoggle));
    1444             : 
    1445           0 :                 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
    1446             :                     BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
    1447           0 :                 epipe->sqh = sqh;
    1448           0 :         } /*xfertype == UE_ISOC*/
    1449             : 
    1450           0 :         switch (xfertype) {
    1451             :         case UE_CONTROL:
    1452           0 :                 err = usb_allocmem(&sc->sc_bus, sizeof(usb_device_request_t),
    1453           0 :                     0, &epipe->u.ctl.reqdma);
    1454           0 :                 if (err) {
    1455           0 :                         ehci_free_sqh(sc, sqh);
    1456           0 :                         return (err);
    1457             :                 }
    1458           0 :                 pipe->methods = &ehci_device_ctrl_methods;
    1459           0 :                 s = splusb();
    1460           0 :                 ehci_add_qh(sqh, sc->sc_async_head);
    1461           0 :                 splx(s);
    1462           0 :                 break;
    1463             :         case UE_BULK:
    1464           0 :                 pipe->methods = &ehci_device_bulk_methods;
    1465           0 :                 s = splusb();
    1466           0 :                 ehci_add_qh(sqh, sc->sc_async_head);
    1467           0 :                 splx(s);
    1468           0 :                 break;
    1469             :         case UE_INTERRUPT:
    1470           0 :                 pipe->methods = &ehci_device_intr_methods;
    1471           0 :                 ival = pipe->interval;
    1472           0 :                 if (ival == USBD_DEFAULT_INTERVAL)
    1473           0 :                         ival = ed->bInterval;
    1474           0 :                 s = splusb();
    1475           0 :                 err = ehci_device_setintr(sc, sqh, ival);
    1476           0 :                 splx(s);
    1477           0 :                 return (err);
    1478             :         case UE_ISOCHRONOUS:
    1479           0 :                 switch (speed) {
    1480             :                 case EHCI_QH_SPEED_HIGH:
    1481             :                 case EHCI_QH_SPEED_FULL:
    1482           0 :                         pipe->methods = &ehci_device_isoc_methods;
    1483             :                         break;
    1484             :                 case EHCI_QH_SPEED_LOW:
    1485             :                 default:
    1486           0 :                         return (USBD_INVAL);
    1487             :                 }
    1488             :                 /* Spec page 271 says intervals > 16 are invalid */
    1489           0 :                 if (ed->bInterval == 0 || ed->bInterval > 16) {
    1490           0 :                         printf("ehci: opening pipe with invalid bInterval\n");
    1491           0 :                         return (USBD_INVAL);
    1492             :                 }
    1493           0 :                 if (UGETW(ed->wMaxPacketSize) == 0) {
    1494           0 :                         printf("ehci: zero length endpoint open request\n");
    1495           0 :                         return (USBD_INVAL);
    1496             :                 }
    1497           0 :                 epipe->u.isoc.next_frame = 0;
    1498           0 :                 epipe->u.isoc.cur_xfers = 0;
    1499           0 :                 break;
    1500             :         default:
    1501             :                 DPRINTF(("ehci: bad xfer type %d\n", xfertype));
    1502           0 :                 return (USBD_INVAL);
    1503             :         }
    1504           0 :         return (USBD_NORMAL_COMPLETION);
    1505           0 : }
    1506             : 
    1507             : /*
    1508             :  * Add an ED to the schedule.  Called at splusb().
    1509             :  * If in the async schedule, it will always have a next.
    1510             :  * If in the intr schedule it may not.
    1511             :  */
    1512             : void
    1513           0 : ehci_add_qh(struct ehci_soft_qh *sqh, struct ehci_soft_qh *head)
    1514             : {
    1515           0 :         splsoftassert(IPL_SOFTUSB);
    1516             : 
    1517           0 :         usb_syncmem(&head->dma, head->offs + offsetof(struct ehci_qh, qh_link),
    1518             :             sizeof(head->qh.qh_link), BUS_DMASYNC_POSTWRITE);
    1519           0 :         sqh->next = head->next;
    1520           0 :         sqh->prev = head;
    1521           0 :         sqh->qh.qh_link = head->qh.qh_link;
    1522           0 :         usb_syncmem(&sqh->dma, sqh->offs + offsetof(struct ehci_qh, qh_link),
    1523             :             sizeof(sqh->qh.qh_link), BUS_DMASYNC_PREWRITE);
    1524           0 :         head->next = sqh;
    1525           0 :         if (sqh->next)
    1526           0 :                 sqh->next->prev = sqh;
    1527           0 :         head->qh.qh_link = htole32(sqh->physaddr | EHCI_LINK_QH);
    1528           0 :         usb_syncmem(&head->dma, head->offs + offsetof(struct ehci_qh, qh_link),
    1529             :             sizeof(head->qh.qh_link), BUS_DMASYNC_PREWRITE);
    1530           0 : }
    1531             : 
    1532             : /*
    1533             :  * Remove an ED from the schedule.  Called at splusb().
    1534             :  * Will always have a 'next' if it's in the async list as it's circular.
    1535             :  */
    1536             : void
    1537           0 : ehci_rem_qh(struct ehci_softc *sc, struct ehci_soft_qh *sqh)
    1538             : {
    1539           0 :         splsoftassert(IPL_SOFTUSB);
    1540             :         /* XXX */
    1541           0 :         usb_syncmem(&sqh->dma, sqh->offs + offsetof(struct ehci_qh, qh_link),
    1542             :             sizeof(sqh->qh.qh_link), BUS_DMASYNC_POSTWRITE);
    1543           0 :         sqh->prev->qh.qh_link = sqh->qh.qh_link;
    1544           0 :         sqh->prev->next = sqh->next;
    1545           0 :         if (sqh->next)
    1546           0 :                 sqh->next->prev = sqh->prev;
    1547           0 :         usb_syncmem(&sqh->prev->dma,
    1548           0 :             sqh->prev->offs + offsetof(struct ehci_qh, qh_link),
    1549             :             sizeof(sqh->prev->qh.qh_link), BUS_DMASYNC_PREWRITE);
    1550             : 
    1551           0 :         ehci_sync_hc(sc);
    1552           0 : }
    1553             : 
    1554             : void
    1555           0 : ehci_set_qh_qtd(struct ehci_soft_qh *sqh, struct ehci_soft_qtd *sqtd)
    1556             : {
    1557             :         int i;
    1558             :         u_int32_t status;
    1559             : 
    1560             :         /* Save toggle bit and ping status. */
    1561           0 :         usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
    1562             :             BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
    1563           0 :         status = sqh->qh.qh_qtd.qtd_status &
    1564             :             htole32(EHCI_QTD_TOGGLE_MASK |
    1565             :                 EHCI_QTD_SET_STATUS(EHCI_QTD_PINGSTATE));
    1566             :         /* Set HALTED to make hw leave it alone. */
    1567           0 :         sqh->qh.qh_qtd.qtd_status =
    1568             :             htole32(EHCI_QTD_SET_STATUS(EHCI_QTD_HALTED));
    1569           0 :         usb_syncmem(&sqh->dma,
    1570           0 :             sqh->offs + offsetof(struct ehci_qh, qh_qtd.qtd_status),
    1571             :             sizeof(sqh->qh.qh_qtd.qtd_status),
    1572             :             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
    1573           0 :         sqh->qh.qh_curqtd = 0;
    1574           0 :         sqh->qh.qh_qtd.qtd_next = htole32(sqtd->physaddr);
    1575           0 :         sqh->qh.qh_qtd.qtd_altnext = htole32(EHCI_LINK_TERMINATE);
    1576           0 :         for (i = 0; i < EHCI_QTD_NBUFFERS; i++)
    1577           0 :                 sqh->qh.qh_qtd.qtd_buffer[i] = 0;
    1578           0 :         sqh->sqtd = sqtd;
    1579           0 :         usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
    1580             :             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
    1581             :         /* Set !HALTED && !ACTIVE to start execution, preserve some fields */
    1582           0 :         sqh->qh.qh_qtd.qtd_status = status;
    1583           0 :         usb_syncmem(&sqh->dma,
    1584           0 :             sqh->offs + offsetof(struct ehci_qh, qh_qtd.qtd_status),
    1585             :             sizeof(sqh->qh.qh_qtd.qtd_status),
    1586             :             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
    1587           0 : }
    1588             : 
    1589             : /*
    1590             :  * Ensure that the HC has released all references to the QH.  We do this
    1591             :  * by asking for a Async Advance Doorbell interrupt and then we wait for
    1592             :  * the interrupt.
    1593             :  * To make this easier we first obtain exclusive use of the doorbell.
    1594             :  */
    1595             : void
    1596           0 : ehci_sync_hc(struct ehci_softc *sc)
    1597             : {
    1598             :         int s, error;
    1599             :         int tries = 0;
    1600             : 
    1601           0 :         if (sc->sc_bus.dying) {
    1602           0 :                 return;
    1603             :         }
    1604             : 
    1605             :         /* get doorbell */
    1606           0 :         rw_enter_write(&sc->sc_doorbell_lock);
    1607           0 :         s = splhardusb();
    1608           0 :         do {
    1609           0 :                 EOWRITE4(sc, EHCI_USBCMD, EOREAD4(sc, EHCI_USBCMD) |
    1610             :                     EHCI_CMD_IAAD);
    1611           0 :                 error = tsleep(&sc->sc_async_head, PZERO, "ehcidi", hz / 2);
    1612           0 :         } while (error && ++tries < 10);
    1613           0 :         splx(s);
    1614             :         /* release doorbell */
    1615           0 :         rw_exit_write(&sc->sc_doorbell_lock);
    1616             : #ifdef DIAGNOSTIC
    1617           0 :         if (error)
    1618           0 :                 printf("ehci_sync_hc: tsleep() = %d\n", error);
    1619             : #endif
    1620           0 : }
    1621             : 
    1622             : void
    1623           0 : ehci_rem_itd_chain(struct ehci_softc *sc, struct ehci_xfer *ex)
    1624             : {
    1625             :         struct ehci_soft_itd *itd, *prev = NULL;
    1626             : 
    1627           0 :         splsoftassert(IPL_SOFTUSB);
    1628             : 
    1629           0 :         KASSERT(ex->itdstart != NULL && ex->itdend != NULL);
    1630             : 
    1631           0 :         for (itd = ex->itdstart; itd != NULL; itd = itd->xfer_next) {
    1632           0 :                 prev = itd->u.frame_list.prev;
    1633             :                 /* Unlink itd from hardware chain, or frame array */
    1634           0 :                 if (prev == NULL) { /* We're at the table head */
    1635           0 :                         sc->sc_softitds[itd->slot] = itd->u.frame_list.next;
    1636           0 :                         sc->sc_flist[itd->slot] = itd->itd.itd_next;
    1637           0 :                         usb_syncmem(&sc->sc_fldma,
    1638           0 :                             sizeof(uint32_t) * itd->slot, sizeof(uint32_t),
    1639             :                             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
    1640             : 
    1641           0 :                         if (itd->u.frame_list.next != NULL)
    1642           0 :                                 itd->u.frame_list.next->u.frame_list.prev =
    1643             :                                     NULL;
    1644             :                 } else {
    1645             :                         /* XXX this part is untested... */
    1646           0 :                         prev->itd.itd_next = itd->itd.itd_next;
    1647           0 :                         usb_syncmem(&itd->dma,
    1648           0 :                             itd->offs + offsetof(struct ehci_itd, itd_next),
    1649             :                             sizeof(itd->itd.itd_next), BUS_DMASYNC_PREWRITE);
    1650             : 
    1651           0 :                         prev->u.frame_list.next = itd->u.frame_list.next;
    1652           0 :                         if (itd->u.frame_list.next != NULL)
    1653           0 :                                 itd->u.frame_list.next->u.frame_list.prev =
    1654             :                                     prev;
    1655             :                 }
    1656             :         }
    1657           0 : }
    1658             : 
    1659             : void
    1660           0 : ehci_free_itd_chain(struct ehci_softc *sc, struct ehci_xfer *ex)
    1661             : {
    1662             :         struct ehci_soft_itd *itd, *prev = NULL;
    1663             : 
    1664           0 :         splsoftassert(IPL_SOFTUSB);
    1665             : 
    1666           0 :         KASSERT(ex->itdstart != NULL && ex->itdend != NULL);
    1667             : 
    1668           0 :         for (itd = ex->itdstart; itd != NULL; itd = itd->xfer_next) {
    1669           0 :                 if (prev != NULL)
    1670           0 :                         ehci_free_itd(sc, prev);
    1671             :                 prev = itd;
    1672             :         }
    1673           0 :         if (prev)
    1674           0 :                 ehci_free_itd(sc, prev);
    1675           0 :         ex->itdstart = NULL;
    1676           0 :         ex->itdend = NULL;
    1677           0 : }
    1678             : 
    1679             : /*
    1680             :  * Data structures and routines to emulate the root hub.
    1681             :  */
    1682             : usb_device_descriptor_t ehci_devd = {
    1683             :         USB_DEVICE_DESCRIPTOR_SIZE,
    1684             :         UDESC_DEVICE,           /* type */
    1685             :         {0x00, 0x02},           /* USB version */
    1686             :         UDCLASS_HUB,            /* class */
    1687             :         UDSUBCLASS_HUB,         /* subclass */
    1688             :         UDPROTO_HSHUBSTT,       /* protocol */
    1689             :         64,                     /* max packet */
    1690             :         {0},{0},{0x00,0x01},    /* device id */
    1691             :         1,2,0,                  /* string indicies */
    1692             :         1                       /* # of configurations */
    1693             : };
    1694             : 
    1695             : usb_device_qualifier_t ehci_odevd = {
    1696             :         USB_DEVICE_DESCRIPTOR_SIZE,
    1697             :         UDESC_DEVICE_QUALIFIER, /* type */
    1698             :         {0x00, 0x02},           /* USB version */
    1699             :         UDCLASS_HUB,            /* class */
    1700             :         UDSUBCLASS_HUB,         /* subclass */
    1701             :         UDPROTO_FSHUB,          /* protocol */
    1702             :         64,                     /* max packet */
    1703             :         1,                      /* # of configurations */
    1704             :         0
    1705             : };
    1706             : 
    1707             : usb_config_descriptor_t ehci_confd = {
    1708             :         USB_CONFIG_DESCRIPTOR_SIZE,
    1709             :         UDESC_CONFIG,
    1710             :         {USB_CONFIG_DESCRIPTOR_SIZE +
    1711             :          USB_INTERFACE_DESCRIPTOR_SIZE +
    1712             :          USB_ENDPOINT_DESCRIPTOR_SIZE},
    1713             :         1,
    1714             :         1,
    1715             :         0,
    1716             :         UC_SELF_POWERED,
    1717             :         0                       /* max power */
    1718             : };
    1719             : 
    1720             : usb_interface_descriptor_t ehci_ifcd = {
    1721             :         USB_INTERFACE_DESCRIPTOR_SIZE,
    1722             :         UDESC_INTERFACE,
    1723             :         0,
    1724             :         0,
    1725             :         1,
    1726             :         UICLASS_HUB,
    1727             :         UISUBCLASS_HUB,
    1728             :         UIPROTO_HSHUBSTT,
    1729             :         0
    1730             : };
    1731             : 
    1732             : usb_endpoint_descriptor_t ehci_endpd = {
    1733             :         USB_ENDPOINT_DESCRIPTOR_SIZE,
    1734             :         UDESC_ENDPOINT,
    1735             :         UE_DIR_IN | EHCI_INTR_ENDPT,
    1736             :         UE_INTERRUPT,
    1737             :         {8, 0},                 /* max packet */
    1738             :         12
    1739             : };
    1740             : 
    1741             : usb_hub_descriptor_t ehci_hubd = {
    1742             :         USB_HUB_DESCRIPTOR_SIZE,
    1743             :         UDESC_HUB,
    1744             :         0,
    1745             :         {0,0},
    1746             :         0,
    1747             :         0,
    1748             :         {0},
    1749             : };
    1750             : 
    1751             : /*
    1752             :  * Simulate a hardware hub by handling all the necessary requests.
    1753             :  */
    1754             : usbd_status
    1755           0 : ehci_root_ctrl_transfer(struct usbd_xfer *xfer)
    1756             : {
    1757             :         usbd_status err;
    1758             : 
    1759             :         /* Insert last in queue. */
    1760           0 :         err = usb_insert_transfer(xfer);
    1761           0 :         if (err)
    1762           0 :                 return (err);
    1763             : 
    1764             :         /* Pipe isn't running, start first */
    1765           0 :         return (ehci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
    1766           0 : }
    1767             : 
    1768             : usbd_status
    1769           0 : ehci_root_ctrl_start(struct usbd_xfer *xfer)
    1770             : {
    1771           0 :         struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
    1772             :         usb_device_request_t *req;
    1773             :         void *buf = NULL;
    1774             :         int port, i;
    1775             :         int s, len, value, index, l, totlen = 0;
    1776           0 :         usb_port_status_t ps;
    1777           0 :         usb_hub_descriptor_t hubd;
    1778             :         usbd_status err;
    1779             :         u_int32_t v;
    1780             : 
    1781           0 :         if (sc->sc_bus.dying)
    1782           0 :                 return (USBD_IOERROR);
    1783             : 
    1784             : #ifdef DIAGNOSTIC
    1785           0 :         if (!(xfer->rqflags & URQ_REQUEST))
    1786             :                 /* XXX panic */
    1787           0 :                 return (USBD_INVAL);
    1788             : #endif
    1789           0 :         req = &xfer->request;
    1790             : 
    1791             :         DPRINTFN(4,("ehci_root_ctrl_start: type=0x%02x request=%02x\n",
    1792             :                     req->bmRequestType, req->bRequest));
    1793             : 
    1794           0 :         len = UGETW(req->wLength);
    1795           0 :         value = UGETW(req->wValue);
    1796           0 :         index = UGETW(req->wIndex);
    1797             : 
    1798           0 :         if (len != 0)
    1799           0 :                 buf = KERNADDR(&xfer->dmabuf, 0);
    1800             : 
    1801             : #define C(x,y) ((x) | ((y) << 8))
    1802           0 :         switch(C(req->bRequest, req->bmRequestType)) {
    1803             :         case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
    1804             :         case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
    1805             :         case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
    1806             :                 /*
    1807             :                  * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
    1808             :                  * for the integrated root hub.
    1809             :                  */
    1810             :                 break;
    1811             :         case C(UR_GET_CONFIG, UT_READ_DEVICE):
    1812           0 :                 if (len > 0) {
    1813           0 :                         *(u_int8_t *)buf = sc->sc_conf;
    1814             :                         totlen = 1;
    1815           0 :                 }
    1816             :                 break;
    1817             :         case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
    1818             :                 DPRINTFN(8,("ehci_root_ctrl_start: wValue=0x%04x\n", value));
    1819           0 :                 switch(value >> 8) {
    1820             :                 case UDESC_DEVICE:
    1821           0 :                         if ((value & 0xff) != 0) {
    1822             :                                 err = USBD_IOERROR;
    1823           0 :                                 goto ret;
    1824             :                         }
    1825           0 :                         totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
    1826           0 :                         USETW(ehci_devd.idVendor, sc->sc_id_vendor);
    1827           0 :                         memcpy(buf, &ehci_devd, l);
    1828           0 :                         break;
    1829             :                 /*
    1830             :                  * We can't really operate at another speed, but the spec says
    1831             :                  * we need this descriptor.
    1832             :                  */
    1833             :                 case UDESC_DEVICE_QUALIFIER:
    1834           0 :                         if ((value & 0xff) != 0) {
    1835             :                                 err = USBD_IOERROR;
    1836           0 :                                 goto ret;
    1837             :                         }
    1838           0 :                         totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
    1839           0 :                         memcpy(buf, &ehci_odevd, l);
    1840           0 :                         break;
    1841             :                 /*
    1842             :                  * We can't really operate at another speed, but the spec says
    1843             :                  * we need this descriptor.
    1844             :                  */
    1845             :                 case UDESC_OTHER_SPEED_CONFIGURATION:
    1846             :                 case UDESC_CONFIG:
    1847           0 :                         if ((value & 0xff) != 0) {
    1848             :                                 err = USBD_IOERROR;
    1849           0 :                                 goto ret;
    1850             :                         }
    1851           0 :                         totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
    1852           0 :                         memcpy(buf, &ehci_confd, l);
    1853           0 :                         ((usb_config_descriptor_t *)buf)->bDescriptorType =
    1854           0 :                             value >> 8;
    1855           0 :                         buf = (char *)buf + l;
    1856           0 :                         len -= l;
    1857           0 :                         l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
    1858           0 :                         totlen += l;
    1859           0 :                         memcpy(buf, &ehci_ifcd, l);
    1860           0 :                         buf = (char *)buf + l;
    1861           0 :                         len -= l;
    1862           0 :                         l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
    1863           0 :                         totlen += l;
    1864           0 :                         memcpy(buf, &ehci_endpd, l);
    1865           0 :                         break;
    1866             :                 case UDESC_STRING:
    1867           0 :                         if (len == 0)
    1868             :                                 break;
    1869           0 :                         *(u_int8_t *)buf = 0;
    1870             :                         totlen = 1;
    1871           0 :                         switch (value & 0xff) {
    1872             :                         case 0: /* Language table */
    1873           0 :                                 totlen = usbd_str(buf, len, "\001");
    1874           0 :                                 break;
    1875             :                         case 1: /* Vendor */
    1876           0 :                                 totlen = usbd_str(buf, len, sc->sc_vendor);
    1877           0 :                                 break;
    1878             :                         case 2: /* Product */
    1879           0 :                                 totlen = usbd_str(buf, len, "EHCI root hub");
    1880           0 :                                 break;
    1881             :                         }
    1882             :                         break;
    1883             :                 default:
    1884             :                         err = USBD_IOERROR;
    1885           0 :                         goto ret;
    1886             :                 }
    1887             :                 break;
    1888             :         case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
    1889           0 :                 if (len > 0) {
    1890           0 :                         *(u_int8_t *)buf = 0;
    1891             :                         totlen = 1;
    1892           0 :                 }
    1893             :                 break;
    1894             :         case C(UR_GET_STATUS, UT_READ_DEVICE):
    1895           0 :                 if (len > 1) {
    1896           0 :                         USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
    1897             :                         totlen = 2;
    1898           0 :                 }
    1899             :                 break;
    1900             :         case C(UR_GET_STATUS, UT_READ_INTERFACE):
    1901             :         case C(UR_GET_STATUS, UT_READ_ENDPOINT):
    1902           0 :                 if (len > 1) {
    1903           0 :                         USETW(((usb_status_t *)buf)->wStatus, 0);
    1904             :                         totlen = 2;
    1905           0 :                 }
    1906             :                 break;
    1907             :         case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
    1908           0 :                 if (value >= USB_MAX_DEVICES) {
    1909             :                         err = USBD_IOERROR;
    1910           0 :                         goto ret;
    1911             :                 }
    1912             :                 break;
    1913             :         case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
    1914           0 :                 if (value != 0 && value != 1) {
    1915             :                         err = USBD_IOERROR;
    1916           0 :                         goto ret;
    1917             :                 }
    1918           0 :                 sc->sc_conf = value;
    1919           0 :                 break;
    1920             :         case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
    1921             :                 break;
    1922             :         case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
    1923             :         case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
    1924             :         case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
    1925             :                 err = USBD_IOERROR;
    1926           0 :                 goto ret;
    1927             :         case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
    1928             :                 break;
    1929             :         case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
    1930             :                 break;
    1931             :         /* Hub requests */
    1932             :         case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
    1933             :                 break;
    1934             :         case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
    1935             :                 DPRINTFN(8, ("ehci_root_ctrl_start: UR_CLEAR_PORT_FEATURE "
    1936             :                     "port=%d feature=%d\n", index, value));
    1937           0 :                 if (index < 1 || index > sc->sc_noport) {
    1938             :                         err = USBD_IOERROR;
    1939           0 :                         goto ret;
    1940             :                 }
    1941           0 :                 port = EHCI_PORTSC(index);
    1942           0 :                 v = EOREAD4(sc, port) &~ EHCI_PS_CLEAR;
    1943           0 :                 switch(value) {
    1944             :                 case UHF_PORT_ENABLE:
    1945           0 :                         EOWRITE4(sc, port, v &~ EHCI_PS_PE);
    1946           0 :                         break;
    1947             :                 case UHF_PORT_SUSPEND:
    1948           0 :                         EOWRITE4(sc, port, v &~ EHCI_PS_SUSP);
    1949           0 :                         break;
    1950             :                 case UHF_PORT_POWER:
    1951           0 :                         EOWRITE4(sc, port, v &~ EHCI_PS_PP);
    1952           0 :                         break;
    1953             :                 case UHF_PORT_TEST:
    1954             :                         DPRINTFN(2,("ehci_root_ctrl_start: "
    1955             :                             "clear port test %d\n", index));
    1956             :                         break;
    1957             :                 case UHF_PORT_INDICATOR:
    1958             :                         DPRINTFN(2,("ehci_root_ctrl_start: "
    1959             :                             "clear port index %d\n", index));
    1960           0 :                         EOWRITE4(sc, port, v &~ EHCI_PS_PIC);
    1961           0 :                         break;
    1962             :                 case UHF_C_PORT_CONNECTION:
    1963           0 :                         EOWRITE4(sc, port, v | EHCI_PS_CSC);
    1964           0 :                         break;
    1965             :                 case UHF_C_PORT_ENABLE:
    1966           0 :                         EOWRITE4(sc, port, v | EHCI_PS_PEC);
    1967           0 :                         break;
    1968             :                 case UHF_C_PORT_SUSPEND:
    1969             :                         /* how? */
    1970             :                         break;
    1971             :                 case UHF_C_PORT_OVER_CURRENT:
    1972           0 :                         EOWRITE4(sc, port, v | EHCI_PS_OCC);
    1973           0 :                         break;
    1974             :                 case UHF_C_PORT_RESET:
    1975           0 :                         sc->sc_isreset = 0;
    1976           0 :                         break;
    1977             :                 default:
    1978             :                         err = USBD_IOERROR;
    1979           0 :                         goto ret;
    1980             :                 }
    1981             :                 break;
    1982             :         case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
    1983           0 :                 if ((value & 0xff) != 0) {
    1984             :                         err = USBD_IOERROR;
    1985           0 :                         goto ret;
    1986             :                 }
    1987           0 :                 hubd = ehci_hubd;
    1988           0 :                 hubd.bNbrPorts = sc->sc_noport;
    1989           0 :                 v = EREAD4(sc, EHCI_HCSPARAMS);
    1990           0 :                 USETW(hubd.wHubCharacteristics,
    1991             :                     (EHCI_HCS_PPC(v) ? UHD_PWR_INDIVIDUAL : UHD_PWR_NO_SWITCH) |
    1992             :                     (EHCI_HCS_P_INDICATOR(v) ? UHD_PORT_IND : 0));
    1993           0 :                 hubd.bPwrOn2PwrGood = 200; /* XXX can't find out? */
    1994           0 :                 for (i = 0, l = sc->sc_noport; l > 0; i++, l -= 8, v >>= 8)
    1995           0 :                         hubd.DeviceRemovable[i++] = 0; /* XXX can't find out? */
    1996           0 :                 hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + i;
    1997           0 :                 l = min(len, hubd.bDescLength);
    1998             :                 totlen = l;
    1999           0 :                 memcpy(buf, &hubd, l);
    2000           0 :                 break;
    2001             :         case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
    2002           0 :                 if (len != 4) {
    2003             :                         err = USBD_IOERROR;
    2004           0 :                         goto ret;
    2005             :                 }
    2006           0 :                 memset(buf, 0, len); /* ? XXX */
    2007             :                 totlen = len;
    2008           0 :                 break;
    2009             :         case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
    2010             :                 DPRINTFN(8,("ehci_root_ctrl_start: get port status i=%d\n",
    2011             :                     index));
    2012           0 :                 if (index < 1 || index > sc->sc_noport) {
    2013             :                         err = USBD_IOERROR;
    2014           0 :                         goto ret;
    2015             :                 }
    2016           0 :                 if (len != 4) {
    2017             :                         err = USBD_IOERROR;
    2018           0 :                         goto ret;
    2019             :                 }
    2020           0 :                 v = EOREAD4(sc, EHCI_PORTSC(index));
    2021             :                 DPRINTFN(8,("ehci_root_ctrl_start: port status=0x%04x\n", v));
    2022             :                 i = UPS_HIGH_SPEED;
    2023           0 :                 if (v & EHCI_PS_CS) i |= UPS_CURRENT_CONNECT_STATUS;
    2024           0 :                 if (v & EHCI_PS_PE) i |= UPS_PORT_ENABLED;
    2025           0 :                 if (v & EHCI_PS_SUSP)       i |= UPS_SUSPEND;
    2026           0 :                 if (v & EHCI_PS_OCA)        i |= UPS_OVERCURRENT_INDICATOR;
    2027           0 :                 if (v & EHCI_PS_PR) i |= UPS_RESET;
    2028           0 :                 if (v & EHCI_PS_PP) i |= UPS_PORT_POWER;
    2029           0 :                 USETW(ps.wPortStatus, i);
    2030             :                 i = 0;
    2031           0 :                 if (v & EHCI_PS_CSC)        i |= UPS_C_CONNECT_STATUS;
    2032           0 :                 if (v & EHCI_PS_PEC)        i |= UPS_C_PORT_ENABLED;
    2033           0 :                 if (v & EHCI_PS_OCC)        i |= UPS_C_OVERCURRENT_INDICATOR;
    2034           0 :                 if (sc->sc_isreset)  i |= UPS_C_PORT_RESET;
    2035           0 :                 USETW(ps.wPortChange, i);
    2036           0 :                 l = min(len, sizeof(ps));
    2037           0 :                 memcpy(buf, &ps, l);
    2038             :                 totlen = l;
    2039           0 :                 break;
    2040             :         case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
    2041             :                 err = USBD_IOERROR;
    2042           0 :                 goto ret;
    2043             :         case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
    2044             :                 break;
    2045             :         case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
    2046           0 :                 if (index < 1 || index > sc->sc_noport) {
    2047             :                         err = USBD_IOERROR;
    2048           0 :                         goto ret;
    2049             :                 }
    2050           0 :                 port = EHCI_PORTSC(index);
    2051           0 :                 v = EOREAD4(sc, port) &~ EHCI_PS_CLEAR;
    2052           0 :                 switch(value) {
    2053             :                 case UHF_PORT_ENABLE:
    2054           0 :                         EOWRITE4(sc, port, v | EHCI_PS_PE);
    2055           0 :                         break;
    2056             :                 case UHF_PORT_SUSPEND:
    2057           0 :                         EOWRITE4(sc, port, v | EHCI_PS_SUSP);
    2058           0 :                         break;
    2059             :                 case UHF_PORT_DISOWN_TO_1_1:
    2060             :                         /* enter to Port Reset State */
    2061           0 :                         v &= ~EHCI_PS_PE;
    2062           0 :                         EOWRITE4(sc, port, v | EHCI_PS_PR);
    2063           0 :                         ehci_disown(sc, index, 0);
    2064           0 :                         break;
    2065             :                 case UHF_PORT_RESET:
    2066             :                         DPRINTFN(5,("ehci_root_ctrl_start: reset port %d\n",
    2067             :                             index));
    2068           0 :                         if (EHCI_PS_IS_LOWSPEED(v)) {
    2069             :                                 /* Low speed device, give up ownership. */
    2070           0 :                                 ehci_disown(sc, index, 1);
    2071           0 :                                 break;
    2072             :                         }
    2073             :                         /* Start reset sequence. */
    2074           0 :                         v &= ~ (EHCI_PS_PE | EHCI_PS_PR);
    2075           0 :                         EOWRITE4(sc, port, v | EHCI_PS_PR);
    2076             :                         /* Wait for reset to complete. */
    2077           0 :                         usb_delay_ms(&sc->sc_bus, USB_PORT_ROOT_RESET_DELAY);
    2078           0 :                         if (sc->sc_bus.dying) {
    2079             :                                 err = USBD_IOERROR;
    2080           0 :                                 goto ret;
    2081             :                         }
    2082             :                         /* Terminate reset sequence. */
    2083           0 :                         v = EOREAD4(sc, port);
    2084           0 :                         EOWRITE4(sc, port, v & ~EHCI_PS_PR);
    2085             :                         /* Wait for HC to complete reset. */
    2086           0 :                         usb_delay_ms(&sc->sc_bus, EHCI_PORT_RESET_COMPLETE);
    2087           0 :                         if (sc->sc_bus.dying) {
    2088             :                                 err = USBD_IOERROR;
    2089           0 :                                 goto ret;
    2090             :                         }
    2091           0 :                         v = EOREAD4(sc, port);
    2092             :                         DPRINTF(("ehci after reset, status=0x%08x\n", v));
    2093           0 :                         if (v & EHCI_PS_PR) {
    2094           0 :                                 printf("%s: port reset timeout\n",
    2095           0 :                                     sc->sc_bus.bdev.dv_xname);
    2096             :                                 err = USBD_IOERROR;
    2097           0 :                                 goto ret;
    2098             :                         }
    2099           0 :                         if (!(v & EHCI_PS_PE)) {
    2100             :                                 /* Not a high speed device, give up ownership.*/
    2101           0 :                                 ehci_disown(sc, index, 0);
    2102           0 :                                 break;
    2103             :                         }
    2104           0 :                         sc->sc_isreset = 1;
    2105             :                         DPRINTF(("ehci port %d reset, status = 0x%08x\n",
    2106             :                             index, v));
    2107           0 :                         break;
    2108             :                 case UHF_PORT_POWER:
    2109             :                         DPRINTFN(2,("ehci_root_ctrl_start: "
    2110             :                             "set port power %d\n", index));
    2111           0 :                         EOWRITE4(sc, port, v | EHCI_PS_PP);
    2112           0 :                         break;
    2113             :                 case UHF_PORT_TEST:
    2114             :                         DPRINTFN(2,("ehci_root_ctrl_start: "
    2115             :                             "set port test %d\n", index));
    2116             :                         break;
    2117             :                 case UHF_PORT_INDICATOR:
    2118             :                         DPRINTFN(2,("ehci_root_ctrl_start: "
    2119             :                             "set port ind %d\n", index));
    2120           0 :                         EOWRITE4(sc, port, v | EHCI_PS_PIC);
    2121           0 :                         break;
    2122             :                 default:
    2123             :                         err = USBD_IOERROR;
    2124           0 :                         goto ret;
    2125             :                 }
    2126             :                 break;
    2127             :         case C(UR_CLEAR_TT_BUFFER, UT_WRITE_CLASS_OTHER):
    2128             :         case C(UR_RESET_TT, UT_WRITE_CLASS_OTHER):
    2129             :         case C(UR_GET_TT_STATE, UT_READ_CLASS_OTHER):
    2130             :         case C(UR_STOP_TT, UT_WRITE_CLASS_OTHER):
    2131             :                 break;
    2132             :         default:
    2133             :                 err = USBD_IOERROR;
    2134           0 :                 goto ret;
    2135             :         }
    2136           0 :         xfer->actlen = totlen;
    2137           0 :         err = USBD_NORMAL_COMPLETION;
    2138             :  ret:
    2139           0 :         xfer->status = err;
    2140           0 :         s = splusb();
    2141           0 :         usb_transfer_complete(xfer);
    2142           0 :         splx(s);
    2143           0 :         return (err);
    2144           0 : }
    2145             : 
    2146             : void
    2147           0 : ehci_disown(struct ehci_softc *sc, int index, int lowspeed)
    2148             : {
    2149             :         int port;
    2150             :         u_int32_t v;
    2151             : 
    2152           0 :         port = EHCI_PORTSC(index);
    2153           0 :         v = EOREAD4(sc, port) &~ EHCI_PS_CLEAR;
    2154           0 :         EOWRITE4(sc, port, v | EHCI_PS_PO);
    2155           0 : }
    2156             : 
    2157             : /* Abort a root control request. */
    2158             : void
    2159           0 : ehci_root_ctrl_abort(struct usbd_xfer *xfer)
    2160             : {
    2161             :         /* Nothing to do, all transfers are synchronous. */
    2162           0 : }
    2163             : 
    2164             : /* Close the root pipe. */
    2165             : void
    2166           0 : ehci_root_ctrl_close(struct usbd_pipe *pipe)
    2167             : {
    2168             :         /* Nothing to do. */
    2169           0 : }
    2170             : 
    2171             : void
    2172           0 : ehci_root_intr_done(struct usbd_xfer *xfer)
    2173             : {
    2174           0 : }
    2175             : 
    2176             : usbd_status
    2177           0 : ehci_root_intr_transfer(struct usbd_xfer *xfer)
    2178             : {
    2179             :         usbd_status err;
    2180             : 
    2181             :         /* Insert last in queue. */
    2182           0 :         err = usb_insert_transfer(xfer);
    2183           0 :         if (err)
    2184           0 :                 return (err);
    2185             : 
    2186             :         /* Pipe isn't running, start first */
    2187           0 :         return (ehci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
    2188           0 : }
    2189             : 
    2190             : usbd_status
    2191           0 : ehci_root_intr_start(struct usbd_xfer *xfer)
    2192             : {
    2193           0 :         struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
    2194             : 
    2195           0 :         if (sc->sc_bus.dying)
    2196           0 :                 return (USBD_IOERROR);
    2197             : 
    2198           0 :         sc->sc_intrxfer = xfer;
    2199             : 
    2200           0 :         return (USBD_IN_PROGRESS);
    2201           0 : }
    2202             : 
    2203             : void
    2204           0 : ehci_root_intr_abort(struct usbd_xfer *xfer)
    2205             : {
    2206           0 :         struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
    2207             :         int s;
    2208             : 
    2209           0 :         sc->sc_intrxfer = NULL;
    2210             : 
    2211           0 :         xfer->status = USBD_CANCELLED;
    2212           0 :         s = splusb();
    2213           0 :         usb_transfer_complete(xfer);
    2214           0 :         splx(s);
    2215           0 : }
    2216             : 
    2217             : void
    2218           0 : ehci_root_intr_close(struct usbd_pipe *pipe)
    2219             : {
    2220           0 : }
    2221             : 
    2222             : void
    2223           0 : ehci_root_ctrl_done(struct usbd_xfer *xfer)
    2224             : {
    2225           0 : }
    2226             : 
    2227             : struct ehci_soft_qh *
    2228           0 : ehci_alloc_sqh(struct ehci_softc *sc)
    2229             : {
    2230             :         struct ehci_soft_qh *sqh = NULL;
    2231             :         usbd_status err;
    2232             :         int i, offs;
    2233           0 :         struct usb_dma dma;
    2234             :         int s;
    2235             : 
    2236           0 :         s = splusb();
    2237           0 :         if (sc->sc_freeqhs == NULL) {
    2238             :                 DPRINTFN(2, ("ehci_alloc_sqh: allocating chunk\n"));
    2239           0 :                 err = usb_allocmem(&sc->sc_bus, EHCI_SQH_SIZE * EHCI_SQH_CHUNK,
    2240             :                     EHCI_PAGE_SIZE, &dma);
    2241           0 :                 if (err)
    2242             :                         goto out;
    2243           0 :                 for (i = 0; i < EHCI_SQH_CHUNK; i++) {
    2244           0 :                         offs = i * EHCI_SQH_SIZE;
    2245           0 :                         sqh = KERNADDR(&dma, offs);
    2246           0 :                         sqh->physaddr = DMAADDR(&dma, offs);
    2247           0 :                         sqh->dma = dma;
    2248           0 :                         sqh->offs = offs;
    2249           0 :                         sqh->next = sc->sc_freeqhs;
    2250           0 :                         sc->sc_freeqhs = sqh;
    2251             :                 }
    2252             :         }
    2253           0 :         sqh = sc->sc_freeqhs;
    2254           0 :         sc->sc_freeqhs = sqh->next;
    2255           0 :         memset(&sqh->qh, 0, sizeof(struct ehci_qh));
    2256           0 :         sqh->next = NULL;
    2257           0 :         sqh->prev = NULL;
    2258             : 
    2259             : out:
    2260           0 :         splx(s);
    2261           0 :         return (sqh);
    2262           0 : }
    2263             : 
    2264             : void
    2265           0 : ehci_free_sqh(struct ehci_softc *sc, struct ehci_soft_qh *sqh)
    2266             : {
    2267             :         int s;
    2268             : 
    2269           0 :         s = splusb();
    2270           0 :         sqh->next = sc->sc_freeqhs;
    2271           0 :         sc->sc_freeqhs = sqh;
    2272           0 :         splx(s);
    2273           0 : }
    2274             : 
    2275             : struct ehci_soft_qtd *
    2276           0 : ehci_alloc_sqtd(struct ehci_softc *sc)
    2277             : {
    2278             :         struct ehci_soft_qtd *sqtd = NULL;
    2279             :         usbd_status err;
    2280             :         int i, offs;
    2281           0 :         struct usb_dma dma;
    2282             :         int s;
    2283             : 
    2284           0 :         s = splusb();
    2285           0 :         if (sc->sc_freeqtds == NULL) {
    2286             :                 DPRINTFN(2, ("ehci_alloc_sqtd: allocating chunk\n"));
    2287           0 :                 err = usb_allocmem(&sc->sc_bus, EHCI_SQTD_SIZE*EHCI_SQTD_CHUNK,
    2288             :                     EHCI_PAGE_SIZE, &dma);
    2289           0 :                 if (err)
    2290             :                         goto out;
    2291           0 :                 for(i = 0; i < EHCI_SQTD_CHUNK; i++) {
    2292           0 :                         offs = i * EHCI_SQTD_SIZE;
    2293           0 :                         sqtd = KERNADDR(&dma, offs);
    2294           0 :                         sqtd->physaddr = DMAADDR(&dma, offs);
    2295           0 :                         sqtd->dma = dma;
    2296           0 :                         sqtd->offs = offs;
    2297           0 :                         sqtd->nextqtd = sc->sc_freeqtds;
    2298           0 :                         sc->sc_freeqtds = sqtd;
    2299             :                 }
    2300             :         }
    2301             : 
    2302           0 :         sqtd = sc->sc_freeqtds;
    2303           0 :         sc->sc_freeqtds = sqtd->nextqtd;
    2304           0 :         memset(&sqtd->qtd, 0, sizeof(struct ehci_qtd));
    2305           0 :         sqtd->nextqtd = NULL;
    2306             : 
    2307             : out:
    2308           0 :         splx(s);
    2309           0 :         return (sqtd);
    2310           0 : }
    2311             : 
    2312             : void
    2313           0 : ehci_free_sqtd(struct ehci_softc *sc, struct ehci_soft_qtd *sqtd)
    2314             : {
    2315             :         int s;
    2316             : 
    2317           0 :         s = splusb();
    2318           0 :         sqtd->nextqtd = sc->sc_freeqtds;
    2319           0 :         sc->sc_freeqtds = sqtd;
    2320           0 :         splx(s);
    2321           0 : }
    2322             : 
    2323             : usbd_status
    2324           0 : ehci_alloc_sqtd_chain(struct ehci_softc *sc, u_int alen, struct usbd_xfer *xfer,
    2325             :     struct ehci_soft_qtd **sp, struct ehci_soft_qtd **ep)
    2326             : {
    2327             :         struct ehci_soft_qtd *next, *cur;
    2328             :         ehci_physaddr_t dataphys, dataphyspage, dataphyslastpage, nextphys;
    2329             :         u_int32_t qtdstatus;
    2330             :         u_int len, curlen;
    2331             :         int mps, i, iscontrol, forceshort;
    2332           0 :         int rd = usbd_xfer_isread(xfer);
    2333           0 :         struct usb_dma *dma = &xfer->dmabuf;
    2334             : 
    2335             :         DPRINTFN(alen<4*4096,("ehci_alloc_sqtd_chain: start len=%d\n", alen));
    2336             : 
    2337             :         len = alen;
    2338           0 :         iscontrol = (xfer->pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE) ==
    2339             :             UE_CONTROL;
    2340             : 
    2341           0 :         dataphys = DMAADDR(dma, 0);
    2342           0 :         dataphyslastpage = EHCI_PAGE(dataphys + len - 1);
    2343           0 :         qtdstatus = EHCI_QTD_ACTIVE |
    2344           0 :             EHCI_QTD_SET_PID(rd ? EHCI_QTD_PID_IN : EHCI_QTD_PID_OUT) |
    2345             :             EHCI_QTD_SET_CERR(3); /* IOC and BYTES set below */
    2346           0 :         mps = UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize);
    2347           0 :         forceshort = ((xfer->flags & USBD_FORCE_SHORT_XFER) || len == 0) &&
    2348           0 :             len % mps == 0;
    2349             :         /*
    2350             :          * The control transfer data stage always starts with a toggle of 1.
    2351             :          * For other transfers we let the hardware track the toggle state.
    2352             :          */
    2353           0 :         if (iscontrol)
    2354           0 :                 qtdstatus |= EHCI_QTD_SET_TOGGLE(1);
    2355             : 
    2356           0 :         cur = ehci_alloc_sqtd(sc);
    2357           0 :         *sp = cur;
    2358           0 :         if (cur == NULL)
    2359             :                 goto nomem;
    2360             : 
    2361           0 :         usb_syncmem(dma, 0, alen,
    2362           0 :             rd ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
    2363           0 :         for (;;) {
    2364           0 :                 dataphyspage = EHCI_PAGE(dataphys);
    2365             :                 /* The EHCI hardware can handle at most 5 pages. */
    2366           0 :                 if (dataphyslastpage - dataphyspage <
    2367             :                     EHCI_QTD_NBUFFERS * EHCI_PAGE_SIZE) {
    2368             :                         /* we can handle it in this QTD */
    2369             :                         curlen = len;
    2370           0 :                 } else {
    2371             :                         /* must use multiple TDs, fill as much as possible. */
    2372           0 :                         curlen = EHCI_QTD_NBUFFERS * EHCI_PAGE_SIZE -
    2373           0 :                                  EHCI_PAGE_OFFSET(dataphys);
    2374             : #ifdef DIAGNOSTIC
    2375           0 :                         if (curlen > len) {
    2376           0 :                                 printf("ehci_alloc_sqtd_chain: curlen=%u "
    2377             :                                     "len=%u offs=0x%x\n", curlen, len,
    2378             :                                     EHCI_PAGE_OFFSET(dataphys));
    2379           0 :                                 printf("lastpage=0x%x page=0x%x phys=0x%x\n",
    2380             :                                     dataphyslastpage, dataphyspage, dataphys);
    2381             :                                 curlen = len;
    2382           0 :                         }
    2383             : #endif
    2384             :                         /* the length must be a multiple of the max size */
    2385           0 :                         curlen -= curlen % mps;
    2386             :                         DPRINTFN(1,("ehci_alloc_sqtd_chain: multiple QTDs, "
    2387             :                             "curlen=%u\n", curlen));
    2388             : #ifdef DIAGNOSTIC
    2389           0 :                         if (curlen == 0)
    2390           0 :                                 panic("ehci_alloc_std: curlen == 0");
    2391             : #endif
    2392             :                 }
    2393             : 
    2394             :                 DPRINTFN(4,("ehci_alloc_sqtd_chain: dataphys=0x%08x "
    2395             :                     "dataphyslastpage=0x%08x len=%u curlen=%u\n",
    2396             :                     dataphys, dataphyslastpage, len, curlen));
    2397           0 :                 len -= curlen;
    2398             : 
    2399             :                 /*
    2400             :                  * Allocate another transfer if there's more data left,
    2401             :                  * or if force last short transfer flag is set and we're
    2402             :                  * allocating a multiple of the max packet size.
    2403             :                  */
    2404           0 :                 if (len != 0 || forceshort) {
    2405           0 :                         next = ehci_alloc_sqtd(sc);
    2406           0 :                         if (next == NULL)
    2407             :                                 goto nomem;
    2408           0 :                         nextphys = htole32(next->physaddr);
    2409           0 :                 } else {
    2410             :                         next = NULL;
    2411             :                         nextphys = htole32(EHCI_LINK_TERMINATE);
    2412             :                 }
    2413             : 
    2414           0 :                 for (i = 0; i * EHCI_PAGE_SIZE <
    2415           0 :                     curlen + EHCI_PAGE_OFFSET(dataphys); i++) {
    2416           0 :                         ehci_physaddr_t a = dataphys + i * EHCI_PAGE_SIZE;
    2417           0 :                         if (i != 0) /* use offset only in first buffer */
    2418           0 :                                 a = EHCI_PAGE(a);
    2419             : #ifdef DIAGNOSTIC
    2420           0 :                         if (i >= EHCI_QTD_NBUFFERS) {
    2421           0 :                                 printf("ehci_alloc_sqtd_chain: i=%d\n", i);
    2422           0 :                                 goto nomem;
    2423             :                         }
    2424             : #endif
    2425           0 :                         cur->qtd.qtd_buffer[i] = htole32(a);
    2426           0 :                         cur->qtd.qtd_buffer_hi[i] = 0;
    2427           0 :                 }
    2428           0 :                 cur->nextqtd = next;
    2429           0 :                 cur->qtd.qtd_next = cur->qtd.qtd_altnext = nextphys;
    2430           0 :                 cur->qtd.qtd_status = htole32(qtdstatus |
    2431             :                     EHCI_QTD_SET_BYTES(curlen));
    2432           0 :                 cur->len = curlen;
    2433             :                 DPRINTFN(10,("ehci_alloc_sqtd_chain: cbp=0x%08x end=0x%08x\n",
    2434             :                     dataphys, dataphys + curlen));
    2435             :                 DPRINTFN(10,("ehci_alloc_sqtd_chain: curlen=%u\n", curlen));
    2436           0 :                 if (iscontrol) {
    2437             :                         /*
    2438             :                          * adjust the toggle based on the number of packets
    2439             :                          * in this qtd
    2440             :                          */
    2441           0 :                         if ((((curlen + mps - 1) / mps) & 1) || curlen == 0)
    2442           0 :                                 qtdstatus ^= EHCI_QTD_TOGGLE_MASK;
    2443             :                 }
    2444           0 :                 if (len == 0) {
    2445           0 :                         if (! forceshort)
    2446             :                                 break;
    2447             :                         forceshort = 0;
    2448           0 :                 }
    2449           0 :                 usb_syncmem(&cur->dma, cur->offs, sizeof(cur->qtd),
    2450             :                     BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
    2451             :                 DPRINTFN(10,("ehci_alloc_sqtd_chain: extend chain\n"));
    2452           0 :                 dataphys += curlen;
    2453             :                 cur = next;
    2454             :         }
    2455           0 :         cur->qtd.qtd_status |= htole32(EHCI_QTD_IOC);
    2456           0 :         usb_syncmem(&cur->dma, cur->offs, sizeof(cur->qtd),
    2457             :             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
    2458           0 :         *ep = cur;
    2459             : 
    2460             :         DPRINTFN(10,("ehci_alloc_sqtd_chain: return sqtd=%p sqtdend=%p\n",
    2461             :             *sp, *ep));
    2462             : 
    2463           0 :         return (USBD_NORMAL_COMPLETION);
    2464             : 
    2465             :  nomem:
    2466             :         /* XXX free chain */
    2467             :         DPRINTFN(-1,("ehci_alloc_sqtd_chain: no memory\n"));
    2468           0 :         return (USBD_NOMEM);
    2469           0 : }
    2470             : 
    2471             : void
    2472           0 : ehci_free_sqtd_chain(struct ehci_softc *sc, struct ehci_xfer *ex)
    2473             : {
    2474           0 :         struct ehci_pipe *epipe = (struct ehci_pipe *)ex->xfer.pipe;
    2475             :         struct ehci_soft_qtd *sqtd, *next;
    2476             : 
    2477             :         DPRINTFN(10,("ehci_free_sqtd_chain: sqtd=%p\n", ex->sqtdstart));
    2478             : 
    2479           0 :         for (sqtd = ex->sqtdstart; sqtd != NULL; sqtd = next) {
    2480           0 :                 next = sqtd->nextqtd;
    2481           0 :                 ehci_free_sqtd(sc, sqtd);
    2482             :         }
    2483           0 :         ex->sqtdstart = ex->sqtdend = NULL;
    2484           0 :         epipe->sqh->sqtd = NULL;
    2485           0 : }
    2486             : 
    2487             : struct ehci_soft_itd *
    2488           0 : ehci_alloc_itd(struct ehci_softc *sc)
    2489             : {
    2490             :         struct ehci_soft_itd *itd, *freeitd;
    2491             :         usbd_status err;
    2492             :         int i, s, offs, frindex, previndex;
    2493           0 :         struct usb_dma dma;
    2494             : 
    2495           0 :         s = splusb();
    2496             : 
    2497             :         /* Find an itd that wasn't freed this frame or last frame. This can
    2498             :          * discard itds that were freed before frindex wrapped around
    2499             :          * XXX - can this lead to thrashing? Could fix by enabling wrap-around
    2500             :          *       interrupt and fiddling with list when that happens */
    2501           0 :         frindex = (EOREAD4(sc, EHCI_FRINDEX) + 1) >> 3;
    2502           0 :         previndex = (frindex != 0) ? frindex - 1 : sc->sc_flsize;
    2503             : 
    2504             :         freeitd = NULL;
    2505           0 :         LIST_FOREACH(itd, &sc->sc_freeitds, u.free_list) {
    2506             :                 if (itd == NULL)
    2507             :                         break;
    2508           0 :                 if (itd->slot != frindex && itd->slot != previndex) {
    2509             :                         freeitd = itd;
    2510           0 :                         break;
    2511             :                 }
    2512             :         }
    2513             : 
    2514           0 :         if (freeitd == NULL) {
    2515           0 :                 err = usb_allocmem(&sc->sc_bus, EHCI_ITD_SIZE * EHCI_ITD_CHUNK,
    2516             :                     EHCI_PAGE_SIZE, &dma);
    2517           0 :                 if (err) {
    2518           0 :                         splx(s);
    2519           0 :                         return (NULL);
    2520             :                 }
    2521             : 
    2522           0 :                 for (i = 0; i < EHCI_ITD_CHUNK; i++) {
    2523           0 :                         offs = i * EHCI_ITD_SIZE;
    2524           0 :                         itd = KERNADDR(&dma, offs);
    2525           0 :                         itd->physaddr = DMAADDR(&dma, offs);
    2526           0 :                         itd->dma = dma;
    2527           0 :                         itd->offs = offs;
    2528           0 :                         LIST_INSERT_HEAD(&sc->sc_freeitds, itd, u.free_list);
    2529             :                 }
    2530           0 :                 freeitd = LIST_FIRST(&sc->sc_freeitds);
    2531           0 :         }
    2532             : 
    2533             :         itd = freeitd;
    2534           0 :         LIST_REMOVE(itd, u.free_list);
    2535           0 :         memset(&itd->itd, 0, sizeof(struct ehci_itd));
    2536           0 :         usb_syncmem(&itd->dma, itd->offs + offsetof(struct ehci_itd, itd_next),
    2537             :             sizeof(itd->itd.itd_next), BUS_DMASYNC_PREWRITE |
    2538             :             BUS_DMASYNC_PREREAD);
    2539             : 
    2540           0 :         itd->u.frame_list.next = NULL;
    2541           0 :         itd->u.frame_list.prev = NULL;
    2542           0 :         itd->xfer_next = NULL;
    2543           0 :         itd->slot = 0;
    2544           0 :         splx(s);
    2545             : 
    2546           0 :         return (itd);
    2547           0 : }
    2548             : 
    2549             : void
    2550           0 : ehci_free_itd(struct ehci_softc *sc, struct ehci_soft_itd *itd)
    2551             : {
    2552             :         int s;
    2553             : 
    2554           0 :         s = splusb();
    2555           0 :         LIST_INSERT_HEAD(&sc->sc_freeitds, itd, u.free_list);
    2556           0 :         splx(s);
    2557           0 : }
    2558             : 
    2559             : /*
    2560             :  * Close a reqular pipe.
    2561             :  * Assumes that there are no pending transactions.
    2562             :  */
    2563             : void
    2564           0 : ehci_close_pipe(struct usbd_pipe *pipe)
    2565             : {
    2566           0 :         struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
    2567           0 :         struct ehci_softc *sc = (struct ehci_softc *)pipe->device->bus;
    2568           0 :         struct ehci_soft_qh *sqh = epipe->sqh;
    2569             :         int s;
    2570             : 
    2571           0 :         s = splusb();
    2572           0 :         ehci_rem_qh(sc, sqh);
    2573           0 :         splx(s);
    2574           0 :         pipe->endpoint->savedtoggle =
    2575           0 :             EHCI_QTD_GET_TOGGLE(letoh32(sqh->qh.qh_qtd.qtd_status));
    2576           0 :         ehci_free_sqh(sc, epipe->sqh);
    2577           0 : }
    2578             : 
    2579             : /*
    2580             :  * Abort a device request.
    2581             :  * If this routine is called at splusb() it guarantees that the request
    2582             :  * will be removed from the hardware scheduling and that the callback
    2583             :  * for it will be called with USBD_CANCELLED status.
    2584             :  * It's impossible to guarantee that the requested transfer will not
    2585             :  * have happened since the hardware runs concurrently.
    2586             :  * If the transaction has already happened we rely on the ordinary
    2587             :  * interrupt processing to process it.
    2588             :  */
    2589             : void
    2590           0 : ehci_abort_xfer(struct usbd_xfer *xfer, usbd_status status)
    2591             : {
    2592           0 :         struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
    2593           0 :         struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
    2594           0 :         struct ehci_xfer *ex = (struct ehci_xfer*)xfer;
    2595           0 :         struct ehci_soft_qh *sqh = epipe->sqh;
    2596             :         struct ehci_soft_qtd *sqtd;
    2597             :         int s;
    2598             : 
    2599           0 :         if (sc->sc_bus.dying || xfer->status == USBD_NOT_STARTED) {
    2600           0 :                 s = splusb();
    2601           0 :                 if (xfer->status != USBD_NOT_STARTED)
    2602           0 :                         TAILQ_REMOVE(&sc->sc_intrhead, ex, inext);
    2603           0 :                 xfer->status = status;       /* make software ignore it */
    2604           0 :                 timeout_del(&xfer->timeout_handle);
    2605           0 :                 usb_rem_task(xfer->device, &xfer->abort_task);
    2606             : #ifdef DIAGNOSTIC
    2607           0 :                 ex->isdone = 1;
    2608             : #endif
    2609           0 :                 usb_transfer_complete(xfer);
    2610           0 :                 splx(s);
    2611           0 :                 return;
    2612             :         }
    2613             : 
    2614           0 :         if (xfer->device->bus->intr_context)
    2615           0 :                 panic("ehci_abort_xfer: not in process context");
    2616             : 
    2617             :         /*
    2618             :          * If an abort is already in progress then just wait for it to
    2619             :          * complete and return.
    2620             :          */
    2621           0 :         if (ex->ehci_xfer_flags & EHCI_XFER_ABORTING) {
    2622             :                 DPRINTFN(2, ("ehci_abort_xfer: already aborting\n"));
    2623             :                 /* No need to wait if we're aborting from a timeout. */
    2624           0 :                 if (status == USBD_TIMEOUT)
    2625           0 :                         return;
    2626             :                 /* Override the status which might be USBD_TIMEOUT. */
    2627           0 :                 xfer->status = status;
    2628             :                 DPRINTFN(2, ("ehci_abort_xfer: waiting for abort to finish\n"));
    2629           0 :                 ex->ehci_xfer_flags |= EHCI_XFER_ABORTWAIT;
    2630           0 :                 while (ex->ehci_xfer_flags & EHCI_XFER_ABORTING)
    2631           0 :                         tsleep(&ex->ehci_xfer_flags, PZERO, "ehciaw", 0);
    2632           0 :                 return;
    2633             :         }
    2634             : 
    2635             :         /*
    2636             :          * Step 1: Make interrupt routine and timeouts ignore xfer.
    2637             :          */
    2638           0 :         s = splusb();
    2639           0 :         ex->ehci_xfer_flags |= EHCI_XFER_ABORTING;
    2640           0 :         xfer->status = status;       /* make software ignore it */
    2641           0 :         TAILQ_REMOVE(&sc->sc_intrhead, ex, inext);
    2642           0 :         timeout_del(&xfer->timeout_handle);
    2643           0 :         usb_rem_task(xfer->device, &xfer->abort_task);
    2644           0 :         splx(s);
    2645             : 
    2646             :         /*
    2647             :          * Step 2: Deactivate all of the qTDs that we will be removing,
    2648             :          * otherwise the queue head may go active again.
    2649             :          */
    2650           0 :         usb_syncmem(&sqh->dma,
    2651           0 :             sqh->offs + offsetof(struct ehci_qh, qh_qtd.qtd_status),
    2652             :             sizeof(sqh->qh.qh_qtd.qtd_status),
    2653             :             BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
    2654           0 :         sqh->qh.qh_qtd.qtd_status = htole32(EHCI_QTD_HALTED);
    2655           0 :         usb_syncmem(&sqh->dma,
    2656           0 :             sqh->offs + offsetof(struct ehci_qh, qh_qtd.qtd_status),
    2657             :             sizeof(sqh->qh.qh_qtd.qtd_status),
    2658             :             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
    2659             : 
    2660           0 :         for (sqtd = ex->sqtdstart; sqtd != NULL; sqtd = sqtd->nextqtd) {
    2661           0 :                 usb_syncmem(&sqtd->dma,
    2662           0 :                     sqtd->offs + offsetof(struct ehci_qtd, qtd_status),
    2663             :                     sizeof(sqtd->qtd.qtd_status),
    2664             :                     BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
    2665           0 :                 sqtd->qtd.qtd_status = htole32(EHCI_QTD_HALTED);
    2666           0 :                 usb_syncmem(&sqtd->dma,
    2667           0 :                     sqtd->offs + offsetof(struct ehci_qtd, qtd_status),
    2668             :                     sizeof(sqtd->qtd.qtd_status),
    2669             :                     BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
    2670             :         }
    2671           0 :         ehci_sync_hc(sc);
    2672             : 
    2673             :         /*
    2674             :          * Step 3: Make sure the soft interrupt routine has run. This
    2675             :          * should remove any completed items off the queue.
    2676             :          * The hardware has no reference to completed items (TDs).
    2677             :          * It's safe to remove them at any time.
    2678             :          */
    2679           0 :         s = splusb();
    2680           0 :         sc->sc_softwake = 1;
    2681           0 :         usb_schedsoftintr(&sc->sc_bus);
    2682           0 :         tsleep(&sc->sc_softwake, PZERO, "ehciab", 0);
    2683             : 
    2684             : #ifdef DIAGNOSTIC
    2685           0 :         ex->isdone = 1;
    2686             : #endif
    2687             :         /* Do the wakeup first to avoid touching the xfer after the callback. */
    2688           0 :         ex->ehci_xfer_flags &= ~EHCI_XFER_ABORTING;
    2689           0 :         if (ex->ehci_xfer_flags & EHCI_XFER_ABORTWAIT) {
    2690           0 :                 ex->ehci_xfer_flags &= ~EHCI_XFER_ABORTWAIT;
    2691           0 :                 wakeup(&ex->ehci_xfer_flags);
    2692           0 :         }
    2693           0 :         usb_transfer_complete(xfer);
    2694             : 
    2695           0 :         splx(s);
    2696           0 : }
    2697             : 
    2698             : void
    2699           0 : ehci_abort_isoc_xfer(struct usbd_xfer *xfer, usbd_status status)
    2700             : {
    2701           0 :         struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
    2702           0 :         struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
    2703             :         ehci_isoc_trans_t trans_status;
    2704             :         struct ehci_soft_itd *itd;
    2705             :         int i;
    2706             : 
    2707           0 :         splsoftassert(IPL_SOFTUSB);
    2708             : 
    2709           0 :         if (sc->sc_bus.dying || xfer->status == USBD_NOT_STARTED) {
    2710           0 :                 if (xfer->status != USBD_NOT_STARTED)
    2711           0 :                         TAILQ_REMOVE(&sc->sc_intrhead, ex, inext);
    2712           0 :                 xfer->status = status;
    2713           0 :                 timeout_del(&xfer->timeout_handle);
    2714           0 :                 usb_rem_task(xfer->device, &xfer->abort_task);
    2715           0 :                 usb_transfer_complete(xfer);
    2716           0 :                 return;
    2717             :         }
    2718             : 
    2719             :         /* Transfer is already done. */
    2720           0 :         if (xfer->status != USBD_IN_PROGRESS) {
    2721             :                 DPRINTF(("%s: already done \n", __func__));
    2722           0 :                 return;
    2723             :         }
    2724             : 
    2725             : 
    2726             : #ifdef DIAGNOSTIC
    2727           0 :         ex->isdone = 1;
    2728             : #endif
    2729           0 :         xfer->status = status;
    2730           0 :         TAILQ_REMOVE(&sc->sc_intrhead, ex, inext);
    2731           0 :         timeout_del(&xfer->timeout_handle);
    2732           0 :         usb_rem_task(xfer->device, &xfer->abort_task);
    2733             : 
    2734           0 :         if (xfer->device->speed == USB_SPEED_HIGH) {
    2735           0 :                 for (itd = ex->itdstart; itd != NULL; itd = itd->xfer_next) {
    2736           0 :                         usb_syncmem(&itd->dma,
    2737           0 :                             itd->offs + offsetof(struct ehci_itd, itd_ctl),
    2738             :                             sizeof(itd->itd.itd_ctl),
    2739             :                             BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
    2740             : 
    2741           0 :                         for (i = 0; i < 8; i++) {
    2742           0 :                                 trans_status = le32toh(itd->itd.itd_ctl[i]);
    2743           0 :                                 trans_status &= ~EHCI_ITD_ACTIVE;
    2744           0 :                                 itd->itd.itd_ctl[i] = htole32(trans_status);
    2745             :                         }
    2746             : 
    2747           0 :                         usb_syncmem(&itd->dma,
    2748           0 :                             itd->offs + offsetof(struct ehci_itd, itd_ctl),
    2749             :                             sizeof(itd->itd.itd_ctl),
    2750             :                             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
    2751             :                 }
    2752             :         } else {
    2753           0 :                 for (itd = ex->itdstart; itd != NULL; itd = itd->xfer_next) {
    2754           0 :                         usb_syncmem(&itd->dma,
    2755           0 :                             itd->offs + offsetof(struct ehci_sitd, sitd_trans),
    2756             :                             sizeof(itd->sitd.sitd_trans),
    2757             :                             BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
    2758             : 
    2759           0 :                         trans_status = le32toh(itd->sitd.sitd_trans);
    2760           0 :                         trans_status &= ~EHCI_SITD_ACTIVE;
    2761           0 :                         itd->sitd.sitd_trans = htole32(trans_status);
    2762             : 
    2763           0 :                         usb_syncmem(&itd->dma,
    2764           0 :                             itd->offs + offsetof(struct ehci_sitd, sitd_trans),
    2765             :                             sizeof(itd->sitd.sitd_trans),
    2766             :                             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
    2767             :                 }
    2768             :         }
    2769             : 
    2770           0 :         sc->sc_softwake = 1;
    2771           0 :         usb_schedsoftintr(&sc->sc_bus);
    2772           0 :         tsleep(&sc->sc_softwake, PZERO, "ehciab", 0);
    2773             : 
    2774           0 :         usb_transfer_complete(xfer);
    2775           0 : }
    2776             : 
    2777             : void
    2778           0 : ehci_timeout(void *addr)
    2779             : {
    2780           0 :         struct usbd_xfer *xfer = addr;
    2781           0 :         struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
    2782             : 
    2783           0 :         if (sc->sc_bus.dying) {
    2784           0 :                 ehci_timeout_task(addr);
    2785           0 :                 return;
    2786             :         }
    2787             : 
    2788           0 :         usb_init_task(&xfer->abort_task, ehci_timeout_task, addr,
    2789             :             USB_TASK_TYPE_ABORT);
    2790           0 :         usb_add_task(xfer->device, &xfer->abort_task);
    2791           0 : }
    2792             : 
    2793             : void
    2794           0 : ehci_timeout_task(void *addr)
    2795             : {
    2796           0 :         struct usbd_xfer *xfer = addr;
    2797             :         int s;
    2798             : 
    2799           0 :         s = splusb();
    2800           0 :         ehci_abort_xfer(xfer, USBD_TIMEOUT);
    2801           0 :         splx(s);
    2802           0 : }
    2803             : 
    2804             : /*
    2805             :  * Some EHCI chips from VIA / ATI seem to trigger interrupts before writing
    2806             :  * back the qTD status, or miss signalling occasionally under heavy load.
    2807             :  * If the host machine is too fast, we can miss transaction completion - when
    2808             :  * we scan the active list the transaction still seems to be active. This
    2809             :  * generally exhibits itself as a umass stall that never recovers.
    2810             :  *
    2811             :  * We work around this behaviour by setting up this callback after any softintr
    2812             :  * that completes with transactions still pending, giving us another chance to
    2813             :  * check for completion after the writeback has taken place.
    2814             :  */
    2815             : void
    2816           0 : ehci_intrlist_timeout(void *arg)
    2817             : {
    2818           0 :         struct ehci_softc *sc = arg;
    2819             :         int s;
    2820             : 
    2821           0 :         if (sc->sc_bus.dying)
    2822           0 :                 return;
    2823             : 
    2824           0 :         s = splusb();
    2825             :         DPRINTFN(1, ("ehci_intrlist_timeout\n"));
    2826           0 :         usb_schedsoftintr(&sc->sc_bus);
    2827           0 :         splx(s);
    2828           0 : }
    2829             : 
    2830             : usbd_status
    2831           0 : ehci_device_ctrl_transfer(struct usbd_xfer *xfer)
    2832             : {
    2833             :         usbd_status err;
    2834             : 
    2835             :         /* Insert last in queue. */
    2836           0 :         err = usb_insert_transfer(xfer);
    2837           0 :         if (err)
    2838           0 :                 return (err);
    2839             : 
    2840             :         /* Pipe isn't running, start first */
    2841           0 :         return (ehci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
    2842           0 : }
    2843             : 
    2844             : usbd_status
    2845           0 : ehci_device_ctrl_start(struct usbd_xfer *xfer)
    2846             : {
    2847           0 :         struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
    2848           0 :         struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
    2849           0 :         struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
    2850           0 :         usb_device_request_t *req = &xfer->request;
    2851           0 :         struct ehci_soft_qtd *setup, *stat, *next;
    2852             :         struct ehci_soft_qh *sqh;
    2853           0 :         u_int len = UGETW(req->wLength);
    2854             :         usbd_status err;
    2855             :         int s;
    2856             : 
    2857           0 :         KASSERT(xfer->rqflags & URQ_REQUEST);
    2858             : 
    2859           0 :         if (sc->sc_bus.dying)
    2860           0 :                 return (USBD_IOERROR);
    2861             : 
    2862           0 :         setup = ehci_alloc_sqtd(sc);
    2863           0 :         if (setup == NULL) {
    2864             :                 err = USBD_NOMEM;
    2865           0 :                 goto bad1;
    2866             :         }
    2867           0 :         stat = ehci_alloc_sqtd(sc);
    2868           0 :         if (stat == NULL) {
    2869             :                 err = USBD_NOMEM;
    2870           0 :                 goto bad2;
    2871             :         }
    2872             : 
    2873           0 :         sqh = epipe->sqh;
    2874             : 
    2875             :         /* Set up data transaction */
    2876           0 :         if (len != 0) {
    2877           0 :                 struct ehci_soft_qtd *end;
    2878             : 
    2879           0 :                 err = ehci_alloc_sqtd_chain(sc, len, xfer, &next, &end);
    2880           0 :                 if (err)
    2881           0 :                         goto bad3;
    2882           0 :                 end->qtd.qtd_status &= htole32(~EHCI_QTD_IOC);
    2883           0 :                 end->nextqtd = stat;
    2884           0 :                 end->qtd.qtd_next =
    2885           0 :                     end->qtd.qtd_altnext = htole32(stat->physaddr);
    2886           0 :                 usb_syncmem(&end->dma, end->offs, sizeof(end->qtd),
    2887             :                     BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
    2888           0 :         } else {
    2889           0 :                 next = stat;
    2890             :         }
    2891             : 
    2892           0 :         memcpy(KERNADDR(&epipe->u.ctl.reqdma, 0), req, sizeof(*req));
    2893           0 :         usb_syncmem(&epipe->u.ctl.reqdma, 0, sizeof *req, BUS_DMASYNC_PREWRITE);
    2894             : 
    2895             :         /* Clear toggle */
    2896           0 :         setup->qtd.qtd_status = htole32(
    2897             :             EHCI_QTD_ACTIVE |
    2898             :             EHCI_QTD_SET_PID(EHCI_QTD_PID_SETUP) |
    2899             :             EHCI_QTD_SET_CERR(3) |
    2900             :             EHCI_QTD_SET_TOGGLE(0) |
    2901             :             EHCI_QTD_SET_BYTES(sizeof(*req)));
    2902           0 :         setup->qtd.qtd_buffer[0] = htole32(DMAADDR(&epipe->u.ctl.reqdma, 0));
    2903           0 :         setup->qtd.qtd_buffer_hi[0] = 0;
    2904           0 :         setup->nextqtd = next;
    2905           0 :         setup->qtd.qtd_next = setup->qtd.qtd_altnext = htole32(next->physaddr);
    2906           0 :         setup->len = sizeof(*req);
    2907           0 :         usb_syncmem(&setup->dma, setup->offs, sizeof(setup->qtd),
    2908             :             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
    2909             : 
    2910           0 :         stat->qtd.qtd_status = htole32(
    2911             :             EHCI_QTD_ACTIVE |
    2912             :             EHCI_QTD_SET_PID(usbd_xfer_isread(xfer) ?
    2913             :                 EHCI_QTD_PID_OUT : EHCI_QTD_PID_IN) |
    2914             :             EHCI_QTD_SET_CERR(3) |
    2915             :             EHCI_QTD_SET_TOGGLE(1) |
    2916             :             EHCI_QTD_IOC);
    2917           0 :         stat->qtd.qtd_buffer[0] = 0; /* XXX not needed? */
    2918           0 :         stat->qtd.qtd_buffer_hi[0] = 0; /* XXX not needed? */
    2919           0 :         stat->nextqtd = NULL;
    2920           0 :         stat->qtd.qtd_next = stat->qtd.qtd_altnext = htole32(EHCI_LINK_TERMINATE);
    2921           0 :         stat->len = 0;
    2922           0 :         usb_syncmem(&stat->dma, stat->offs, sizeof(stat->qtd),
    2923             :             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
    2924             : 
    2925           0 :         ex->sqtdstart = setup;
    2926           0 :         ex->sqtdend = stat;
    2927             : #ifdef DIAGNOSTIC
    2928           0 :         if (!ex->isdone) {
    2929           0 :                 printf("%s: not done, ex=%p\n", __func__, ex);
    2930           0 :         }
    2931           0 :         ex->isdone = 0;
    2932             : #endif
    2933             : 
    2934             :         /* Insert qTD in QH list. */
    2935           0 :         s = splusb();
    2936           0 :         ehci_set_qh_qtd(sqh, setup);
    2937           0 :         if (xfer->timeout && !sc->sc_bus.use_polling) {
    2938           0 :                 timeout_del(&xfer->timeout_handle);
    2939           0 :                 timeout_set(&xfer->timeout_handle, ehci_timeout, xfer);
    2940           0 :                 timeout_add_msec(&xfer->timeout_handle, xfer->timeout);
    2941           0 :         }
    2942           0 :         TAILQ_INSERT_TAIL(&sc->sc_intrhead, ex, inext);
    2943           0 :         xfer->status = USBD_IN_PROGRESS;
    2944           0 :         splx(s);
    2945             : 
    2946           0 :         return (USBD_IN_PROGRESS);
    2947             : 
    2948             :  bad3:
    2949           0 :         ehci_free_sqtd(sc, stat);
    2950             :  bad2:
    2951           0 :         ehci_free_sqtd(sc, setup);
    2952             :  bad1:
    2953           0 :         xfer->status = err;
    2954           0 :         usb_transfer_complete(xfer);
    2955           0 :         return (err);
    2956           0 : }
    2957             : 
    2958             : void
    2959           0 : ehci_device_ctrl_done(struct usbd_xfer *xfer)
    2960             : {
    2961           0 :         struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
    2962           0 :         struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
    2963             : 
    2964           0 :         KASSERT(xfer->rqflags & URQ_REQUEST);
    2965             : 
    2966           0 :         if (xfer->status != USBD_NOMEM) {
    2967           0 :                 ehci_free_sqtd_chain(sc, ex);
    2968           0 :         }
    2969           0 : }
    2970             : 
    2971             : void
    2972           0 : ehci_device_ctrl_abort(struct usbd_xfer *xfer)
    2973             : {
    2974           0 :         ehci_abort_xfer(xfer, USBD_CANCELLED);
    2975           0 : }
    2976             : 
    2977             : void
    2978           0 : ehci_device_ctrl_close(struct usbd_pipe *pipe)
    2979             : {
    2980           0 :         ehci_close_pipe(pipe);
    2981           0 : }
    2982             : 
    2983             : usbd_status
    2984           0 : ehci_device_bulk_transfer(struct usbd_xfer *xfer)
    2985             : {
    2986             :         usbd_status err;
    2987             : 
    2988             :         /* Insert last in queue. */
    2989           0 :         err = usb_insert_transfer(xfer);
    2990           0 :         if (err)
    2991           0 :                 return (err);
    2992             : 
    2993             :         /* Pipe isn't running, start first */
    2994           0 :         return (ehci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
    2995           0 : }
    2996             : 
    2997             : usbd_status
    2998           0 : ehci_device_bulk_start(struct usbd_xfer *xfer)
    2999             : {
    3000           0 :         struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
    3001           0 :         struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
    3002           0 :         struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
    3003           0 :         struct ehci_soft_qtd *data, *dataend;
    3004             :         struct ehci_soft_qh *sqh;
    3005             :         usbd_status err;
    3006             :         int s;
    3007             : 
    3008           0 :         KASSERT(!(xfer->rqflags & URQ_REQUEST));
    3009             : 
    3010           0 :         if (sc->sc_bus.dying)
    3011           0 :                 return (USBD_IOERROR);
    3012             : 
    3013           0 :         sqh = epipe->sqh;
    3014             : 
    3015           0 :         err = ehci_alloc_sqtd_chain(sc, xfer->length, xfer, &data, &dataend);
    3016           0 :         if (err) {
    3017           0 :                 xfer->status = err;
    3018           0 :                 usb_transfer_complete(xfer);
    3019           0 :                 return (err);
    3020             :         }
    3021             : 
    3022             :         /* Set up interrupt info. */
    3023           0 :         ex->sqtdstart = data;
    3024           0 :         ex->sqtdend = dataend;
    3025             : #ifdef DIAGNOSTIC
    3026           0 :         if (!ex->isdone) {
    3027           0 :                 printf("ehci_device_bulk_start: not done, ex=%p\n", ex);
    3028           0 :         }
    3029           0 :         ex->isdone = 0;
    3030             : #endif
    3031             : 
    3032           0 :         s = splusb();
    3033           0 :         ehci_set_qh_qtd(sqh, data);
    3034           0 :         if (xfer->timeout && !sc->sc_bus.use_polling) {
    3035           0 :                 timeout_del(&xfer->timeout_handle);
    3036           0 :                 timeout_set(&xfer->timeout_handle, ehci_timeout, xfer);
    3037           0 :                 timeout_add_msec(&xfer->timeout_handle, xfer->timeout);
    3038           0 :         }
    3039           0 :         TAILQ_INSERT_TAIL(&sc->sc_intrhead, ex, inext);
    3040           0 :         xfer->status = USBD_IN_PROGRESS;
    3041           0 :         splx(s);
    3042             : 
    3043           0 :         return (USBD_IN_PROGRESS);
    3044           0 : }
    3045             : 
    3046             : void
    3047           0 : ehci_device_bulk_abort(struct usbd_xfer *xfer)
    3048             : {
    3049           0 :         ehci_abort_xfer(xfer, USBD_CANCELLED);
    3050           0 : }
    3051             : 
    3052             : /*
    3053             :  * Close a device bulk pipe.
    3054             :  */
    3055             : void
    3056           0 : ehci_device_bulk_close(struct usbd_pipe *pipe)
    3057             : {
    3058           0 :         ehci_close_pipe(pipe);
    3059           0 : }
    3060             : 
    3061             : void
    3062           0 : ehci_device_bulk_done(struct usbd_xfer *xfer)
    3063             : {
    3064           0 :         struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
    3065           0 :         struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
    3066             : 
    3067           0 :         if (xfer->status != USBD_NOMEM) {
    3068           0 :                 ehci_free_sqtd_chain(sc, ex);
    3069           0 :         }
    3070           0 : }
    3071             : 
    3072             : usbd_status
    3073           0 : ehci_device_setintr(struct ehci_softc *sc, struct ehci_soft_qh *sqh, int ival)
    3074             : {
    3075             :         struct ehci_soft_islot *isp;
    3076             :         int islot, lev;
    3077             : 
    3078             :         /* Find a poll rate that is large enough. */
    3079           0 :         for (lev = EHCI_IPOLLRATES - 1; lev > 0; lev--)
    3080           0 :                 if (EHCI_ILEV_IVAL(lev) <= ival)
    3081             :                         break;
    3082             : 
    3083             :         /* Pick an interrupt slot at the right level. */
    3084             :         /* XXX could do better than picking at random */
    3085           0 :         islot = EHCI_IQHIDX(lev, arc4random());
    3086             : 
    3087           0 :         sqh->islot = islot;
    3088           0 :         isp = &sc->sc_islots[islot];
    3089           0 :         ehci_add_qh(sqh, isp->sqh);
    3090             : 
    3091           0 :         return (USBD_NORMAL_COMPLETION);
    3092             : }
    3093             : 
    3094             : usbd_status
    3095           0 : ehci_device_intr_transfer(struct usbd_xfer *xfer)
    3096             : {
    3097             :         usbd_status err;
    3098             : 
    3099             :         /* Insert last in queue. */
    3100           0 :         err = usb_insert_transfer(xfer);
    3101           0 :         if (err)
    3102           0 :                 return (err);
    3103             : 
    3104             :         /*
    3105             :          * Pipe isn't running (otherwise err would be USBD_INPROG),
    3106             :          * so start it first.
    3107             :          */
    3108           0 :         return (ehci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
    3109           0 : }
    3110             : 
    3111             : usbd_status
    3112           0 : ehci_device_intr_start(struct usbd_xfer *xfer)
    3113             : {
    3114           0 :         struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
    3115           0 :         struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
    3116           0 :         struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
    3117           0 :         struct ehci_soft_qtd *data, *dataend;
    3118             :         struct ehci_soft_qh *sqh;
    3119             :         usbd_status err;
    3120             :         int s;
    3121             : 
    3122           0 :         KASSERT(!(xfer->rqflags & URQ_REQUEST));
    3123             : 
    3124           0 :         if (sc->sc_bus.dying)
    3125           0 :                 return (USBD_IOERROR);
    3126             : 
    3127           0 :         sqh = epipe->sqh;
    3128             : 
    3129           0 :         err = ehci_alloc_sqtd_chain(sc, xfer->length, xfer, &data, &dataend);
    3130           0 :         if (err) {
    3131           0 :                 xfer->status = err;
    3132           0 :                 usb_transfer_complete(xfer);
    3133           0 :                 return (err);
    3134             :         }
    3135             : 
    3136             :         /* Set up interrupt info. */
    3137           0 :         ex->sqtdstart = data;
    3138           0 :         ex->sqtdend = dataend;
    3139             : #ifdef DIAGNOSTIC
    3140           0 :         if (!ex->isdone)
    3141           0 :                 printf("ehci_device_intr_start: not done, ex=%p\n", ex);
    3142           0 :         ex->isdone = 0;
    3143             : #endif
    3144             : 
    3145           0 :         s = splusb();
    3146           0 :         ehci_set_qh_qtd(sqh, data);
    3147           0 :         if (xfer->timeout && !sc->sc_bus.use_polling) {
    3148           0 :                 timeout_del(&xfer->timeout_handle);
    3149           0 :                 timeout_set(&xfer->timeout_handle, ehci_timeout, xfer);
    3150           0 :                 timeout_add_msec(&xfer->timeout_handle, xfer->timeout);
    3151           0 :         }
    3152           0 :         TAILQ_INSERT_TAIL(&sc->sc_intrhead, ex, inext);
    3153           0 :         xfer->status = USBD_IN_PROGRESS;
    3154           0 :         splx(s);
    3155             : 
    3156           0 :         return (USBD_IN_PROGRESS);
    3157           0 : }
    3158             : 
    3159             : void
    3160           0 : ehci_device_intr_abort(struct usbd_xfer *xfer)
    3161             : {
    3162           0 :         KASSERT(!xfer->pipe->repeat || xfer->pipe->intrxfer == xfer);
    3163             : 
    3164             :         /*
    3165             :          * XXX - abort_xfer uses ehci_sync_hc, which syncs via the advance
    3166             :          *       async doorbell. That's dependant on the async list, wheras
    3167             :          *       intr xfers are periodic, should not use this?
    3168             :          */
    3169           0 :         ehci_abort_xfer(xfer, USBD_CANCELLED);
    3170           0 : }
    3171             : 
    3172             : void
    3173           0 : ehci_device_intr_close(struct usbd_pipe *pipe)
    3174             : {
    3175           0 :         ehci_close_pipe(pipe);
    3176           0 : }
    3177             : 
    3178             : void
    3179           0 : ehci_device_intr_done(struct usbd_xfer *xfer)
    3180             : {
    3181           0 :         struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
    3182           0 :         struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
    3183           0 :         struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
    3184           0 :         struct ehci_soft_qtd *data, *dataend;
    3185             :         struct ehci_soft_qh *sqh;
    3186             :         usbd_status err;
    3187             :         int s;
    3188             : 
    3189           0 :         if (xfer->pipe->repeat) {
    3190           0 :                 ehci_free_sqtd_chain(sc, ex);
    3191             : 
    3192           0 :                 usb_syncmem(&xfer->dmabuf, 0, xfer->length,
    3193           0 :                     usbd_xfer_isread(xfer) ?
    3194             :                     BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
    3195           0 :                 sqh = epipe->sqh;
    3196             : 
    3197           0 :                 err = ehci_alloc_sqtd_chain(sc, xfer->length, xfer, &data, &dataend);
    3198           0 :                 if (err) {
    3199           0 :                         xfer->status = err;
    3200           0 :                         return;
    3201             :                 }
    3202             : 
    3203             :                 /* Set up interrupt info. */
    3204           0 :                 ex->sqtdstart = data;
    3205           0 :                 ex->sqtdend = dataend;
    3206             : #ifdef DIAGNOSTIC
    3207           0 :                 if (!ex->isdone) {
    3208           0 :                         printf("ehci_device_intr_done: not done, ex=%p\n",
    3209             :                                         ex);
    3210           0 :                 }
    3211           0 :                 ex->isdone = 0;
    3212             : #endif
    3213             : 
    3214           0 :                 s = splusb();
    3215           0 :                 ehci_set_qh_qtd(sqh, data);
    3216           0 :                 if (xfer->timeout && !sc->sc_bus.use_polling) {
    3217           0 :                         timeout_del(&xfer->timeout_handle);
    3218           0 :                         timeout_set(&xfer->timeout_handle, ehci_timeout, xfer);
    3219           0 :                         timeout_add_msec(&xfer->timeout_handle, xfer->timeout);
    3220           0 :                 }
    3221           0 :                 TAILQ_INSERT_TAIL(&sc->sc_intrhead, ex, inext);
    3222           0 :                 xfer->status = USBD_IN_PROGRESS;
    3223           0 :                 splx(s);
    3224           0 :         } else if (xfer->status != USBD_NOMEM) {
    3225           0 :                 ehci_free_sqtd_chain(sc, ex);
    3226           0 :         }
    3227           0 : }
    3228             : 
    3229             : usbd_status
    3230           0 : ehci_device_isoc_transfer(struct usbd_xfer *xfer)
    3231             : {
    3232             :         usbd_status err;
    3233             : 
    3234           0 :         err = usb_insert_transfer(xfer);
    3235           0 :         if (err && err != USBD_IN_PROGRESS)
    3236           0 :                 return (err);
    3237             : 
    3238           0 :         return (ehci_device_isoc_start(xfer));
    3239           0 : }
    3240             : 
    3241             : usbd_status
    3242           0 : ehci_device_isoc_start(struct usbd_xfer *xfer)
    3243             : {
    3244           0 :         struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
    3245           0 :         struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
    3246           0 :         struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
    3247           0 :         usb_endpoint_descriptor_t *ed = xfer->pipe->endpoint->edesc;
    3248           0 :         uint8_t ival = ed->bInterval;
    3249             :         struct ehci_soft_itd *itd;
    3250             :         int s, frindex;
    3251             :         uint32_t link;
    3252             : 
    3253           0 :         KASSERT(!(xfer->rqflags & URQ_REQUEST));
    3254           0 :         KASSERT(ival > 0 && ival <= 16);
    3255             : 
    3256             :         /*
    3257             :          * To allow continuous transfers, above we start all transfers
    3258             :          * immediately. However, we're still going to get usbd_start_next call
    3259             :          * this when another xfer completes. So, check if this is already
    3260             :          * in progress or not
    3261             :          */
    3262           0 :         if (ex->itdstart != NULL)
    3263           0 :                 return (USBD_IN_PROGRESS);
    3264             : 
    3265           0 :         if (sc->sc_bus.dying)
    3266           0 :                 return (USBD_IOERROR);
    3267             : 
    3268             :         /* Why would you do that anyway? */
    3269           0 :         if (sc->sc_bus.use_polling)
    3270           0 :                 return (USBD_INVAL);
    3271             : 
    3272             :         /*
    3273             :          * To avoid complication, don't allow a request right now that'll span
    3274             :          * the entire frame table. To within 4 frames, to allow some leeway
    3275             :          * on either side of where the hc currently is.
    3276             :          */
    3277           0 :         if ((1 << (ival - 1)) * xfer->nframes >= (sc->sc_flsize - 4) * 8)
    3278           0 :                 return (USBD_INVAL);
    3279             : 
    3280             :         /*
    3281             :          * Step 1: Allocate and initialize itds.
    3282             :          */
    3283           0 :         if (xfer->device->speed == USB_SPEED_HIGH) {
    3284           0 :                 if (ehci_alloc_itd_chain(sc, xfer))
    3285           0 :                         return (USBD_INVAL);
    3286             : 
    3287             :                 link = EHCI_LINK_ITD;
    3288           0 :         } else {
    3289           0 :                 if (ehci_alloc_sitd_chain(sc, xfer))
    3290           0 :                         return (USBD_INVAL);
    3291             : 
    3292             :                 link = EHCI_LINK_SITD;
    3293             :         }
    3294             : 
    3295             : #ifdef DIAGNOSTIC
    3296           0 :         if (!ex->isdone) {
    3297           0 :                 printf("%s: not done, ex=%p\n", __func__, ex);
    3298           0 :         }
    3299           0 :         ex->isdone = 0;
    3300             : #endif
    3301             : 
    3302             :         /*
    3303             :          * Part 2: Transfer descriptors have now been set up, now they must
    3304             :          * be scheduled into the period frame list. Erk. Not wanting to
    3305             :          * complicate matters, transfer is denied if the transfer spans
    3306             :          * more than the period frame list.
    3307             :          */
    3308           0 :         s = splusb();
    3309             : 
    3310             :         /* Start inserting frames */
    3311           0 :         if (epipe->u.isoc.cur_xfers > 0) {
    3312           0 :                 frindex = epipe->u.isoc.next_frame;
    3313           0 :         } else {
    3314           0 :                 frindex = EOREAD4(sc, EHCI_FRINDEX);
    3315           0 :                 frindex = frindex >> 3; /* Erase microframe index */
    3316           0 :                 frindex += 2;
    3317             :         }
    3318             : 
    3319           0 :         if (frindex >= sc->sc_flsize)
    3320           0 :                 frindex &= (sc->sc_flsize - 1);
    3321             : 
    3322             :         /* What's the frame interval? */
    3323           0 :         ival = (1 << (ival - 1));
    3324           0 :         if (ival / 8 == 0)
    3325           0 :                 ival = 1;
    3326             :         else
    3327           0 :                 ival /= 8;
    3328             : 
    3329             :         /* Abuse the fact that itd_next == sitd_next. */
    3330           0 :         for (itd = ex->itdstart; itd != NULL; itd = itd->xfer_next) {
    3331           0 :                 itd->itd.itd_next = sc->sc_flist[frindex];
    3332           0 :                 if (itd->itd.itd_next == 0)
    3333           0 :                         itd->itd.itd_next = htole32(EHCI_LINK_TERMINATE);
    3334             : 
    3335           0 :                 sc->sc_flist[frindex] = htole32(link | itd->physaddr);
    3336           0 :                 itd->u.frame_list.next = sc->sc_softitds[frindex];
    3337           0 :                 sc->sc_softitds[frindex] = itd;
    3338           0 :                 if (itd->u.frame_list.next != NULL)
    3339           0 :                         itd->u.frame_list.next->u.frame_list.prev = itd;
    3340           0 :                 itd->slot = frindex;
    3341           0 :                 itd->u.frame_list.prev = NULL;
    3342             : 
    3343           0 :                 frindex += ival;
    3344           0 :                 if (frindex >= sc->sc_flsize)
    3345           0 :                         frindex -= sc->sc_flsize;
    3346             :         }
    3347             : 
    3348           0 :         epipe->u.isoc.cur_xfers++;
    3349           0 :         epipe->u.isoc.next_frame = frindex;
    3350             : 
    3351           0 :         TAILQ_INSERT_TAIL(&sc->sc_intrhead, ex, inext);
    3352           0 :         xfer->status = USBD_IN_PROGRESS;
    3353           0 :         xfer->done = 0;
    3354           0 :         splx(s);
    3355             : 
    3356           0 :         return (USBD_IN_PROGRESS);
    3357           0 : }
    3358             : 
    3359             : int
    3360           0 : ehci_alloc_itd_chain(struct ehci_softc *sc, struct usbd_xfer *xfer)
    3361             : {
    3362           0 :         struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
    3363           0 :         usb_endpoint_descriptor_t *ed = xfer->pipe->endpoint->edesc;
    3364           0 :         const uint32_t mps = UGETW(ed->wMaxPacketSize);
    3365             :         struct ehci_soft_itd *itd = NULL, *pitd = NULL;
    3366             :         int i, j, nframes, uframes, ufrperframe;
    3367             :         int offs = 0, trans_count = 0;
    3368             : 
    3369             :         /*
    3370             :          * How many itds do we need?  One per transfer if interval >= 8
    3371             :          * microframes, fewer if we use multiple microframes per frame.
    3372             :          */
    3373           0 :         switch (ed->bInterval) {
    3374             :         case 1:
    3375             :                 ufrperframe = 8;
    3376           0 :                 break;
    3377             :         case 2:
    3378             :                 ufrperframe = 4;
    3379           0 :                 break;
    3380             :         case 3:
    3381             :                 ufrperframe = 2;
    3382           0 :                 break;
    3383             :         default:
    3384             :                 ufrperframe = 1;
    3385           0 :                 break;
    3386             :         }
    3387           0 :         nframes = (xfer->nframes + (ufrperframe - 1)) / ufrperframe;
    3388           0 :         uframes = 8 / ufrperframe;
    3389           0 :         if (nframes == 0)
    3390           0 :                 return (1);
    3391             : 
    3392           0 :         for (i = 0; i < nframes; i++) {
    3393             :                 uint32_t froffs = offs;
    3394             : 
    3395           0 :                 itd = ehci_alloc_itd(sc);
    3396           0 :                 if (itd == NULL) {
    3397           0 :                         ehci_free_itd_chain(sc, ex);
    3398           0 :                         return (1);
    3399             :                 }
    3400             : 
    3401           0 :                 if (pitd != NULL)
    3402           0 :                         pitd->xfer_next = itd;
    3403             :                 else
    3404           0 :                         ex->itdstart = itd;
    3405             : 
    3406             :                 /*
    3407             :                  * Step 1.5, initialize uframes
    3408             :                  */
    3409           0 :                 for (j = 0; j < 8; j += uframes) {
    3410             :                         /* Calculate which page in the list this starts in */
    3411           0 :                         int addr = DMAADDR(&xfer->dmabuf, froffs);
    3412           0 :                         addr = EHCI_PAGE_OFFSET(addr) + (offs - froffs);
    3413           0 :                         addr = EHCI_PAGE(addr) / EHCI_PAGE_SIZE;
    3414             : 
    3415             :                         /* This gets the initial offset into the first page,
    3416             :                          * looks how far further along the current uframe
    3417             :                          * offset is. Works out how many pages that is.
    3418             :                          */
    3419           0 :                         itd->itd.itd_ctl[j] = htole32(
    3420             :                             EHCI_ITD_ACTIVE |
    3421             :                             EHCI_ITD_SET_LEN(xfer->frlengths[trans_count]) |
    3422             :                             EHCI_ITD_SET_PG(addr) |
    3423             :                             EHCI_ITD_SET_OFFS(DMAADDR(&xfer->dmabuf, offs))
    3424             :                         );
    3425             : 
    3426           0 :                         offs += xfer->frlengths[trans_count];
    3427           0 :                         trans_count++;
    3428             : 
    3429           0 :                         if (trans_count >= xfer->nframes) { /*Set IOC*/
    3430           0 :                                 itd->itd.itd_ctl[j] |= htole32(EHCI_ITD_IOC);
    3431           0 :                                 break;
    3432             :                         }
    3433           0 :                 }
    3434             : 
    3435             :                 /* Step 1.75, set buffer pointers. To simplify matters, all
    3436             :                  * pointers are filled out for the next 7 hardware pages in
    3437             :                  * the dma block, so no need to worry what pages to cover
    3438             :                  * and what to not.
    3439             :                  */
    3440             : 
    3441           0 :                 for (j = 0; j < 7; j++) {
    3442             :                         /*
    3443             :                          * Don't try to lookup a page that's past the end
    3444             :                          * of buffer
    3445             :                          */
    3446           0 :                         int page_offs = EHCI_PAGE(froffs +
    3447             :                             (EHCI_PAGE_SIZE * j));
    3448             : 
    3449           0 :                         if (page_offs >= xfer->dmabuf.block->size)
    3450           0 :                                 break;
    3451             : 
    3452           0 :                         long long page = DMAADDR(&xfer->dmabuf, page_offs);
    3453           0 :                         page = EHCI_PAGE(page);
    3454           0 :                         itd->itd.itd_bufr[j] = htole32(page);
    3455           0 :                         itd->itd.itd_bufr_hi[j] = htole32(page >> 32);
    3456           0 :                 }
    3457             : 
    3458             :                 /*
    3459             :                  * Other special values
    3460             :                  */
    3461           0 :                 itd->itd.itd_bufr[0] |= htole32(
    3462             :                     EHCI_ITD_SET_ENDPT(UE_GET_ADDR(ed->bEndpointAddress)) |
    3463             :                     EHCI_ITD_SET_DADDR(xfer->pipe->device->address)
    3464             :                 );
    3465             : 
    3466           0 :                 itd->itd.itd_bufr[1] |= htole32(
    3467             :                     (usbd_xfer_isread(xfer) ? EHCI_ITD_SET_DIR(1) : 0) |
    3468             :                     EHCI_ITD_SET_MAXPKT(UE_GET_SIZE(mps))
    3469             :                 );
    3470             :                 /* FIXME: handle invalid trans */
    3471           0 :                 itd->itd.itd_bufr[2] |= htole32(
    3472             :                     EHCI_ITD_SET_MULTI(UE_GET_TRANS(mps)+1)
    3473             :                 );
    3474             : 
    3475             :                 pitd = itd;
    3476           0 :         }
    3477             : 
    3478           0 :         ex->itdend = itd;
    3479             : 
    3480           0 :         return (0);
    3481           0 : }
    3482             : 
    3483             : int
    3484           0 : ehci_alloc_sitd_chain(struct ehci_softc *sc, struct usbd_xfer *xfer)
    3485             : {
    3486           0 :         struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
    3487           0 :         struct usbd_device *hshub = xfer->device->myhsport->parent;
    3488           0 :         usb_endpoint_descriptor_t *ed = xfer->pipe->endpoint->edesc;
    3489             :         struct ehci_soft_itd *itd = NULL, *pitd = NULL;
    3490             :         uint8_t smask, cmask, tp, uf;
    3491             :         int i, nframes, offs = 0;
    3492             :         uint32_t endp;
    3493             : 
    3494           0 :         nframes = xfer->nframes;
    3495           0 :         if (nframes == 0)
    3496           0 :                 return (1);
    3497             : 
    3498           0 :         endp = EHCI_SITD_SET_ENDPT(UE_GET_ADDR(ed->bEndpointAddress)) |
    3499           0 :             EHCI_SITD_SET_ADDR(xfer->device->address) |
    3500           0 :             EHCI_SITD_SET_PORT(xfer->device->myhsport->portno) |
    3501           0 :             EHCI_SITD_SET_HUBA(hshub->address);
    3502             : 
    3503           0 :         if (usbd_xfer_isread(xfer))
    3504           0 :                 endp |= EHCI_SITD_SET_DIR(1);
    3505             : 
    3506           0 :         for (i = 0; i < nframes; i++) {
    3507           0 :                 uint32_t addr = DMAADDR(&xfer->dmabuf, offs);
    3508           0 :                 uint32_t page = EHCI_PAGE(addr + xfer->frlengths[i] - 1);
    3509             : 
    3510           0 :                 itd = ehci_alloc_itd(sc);
    3511           0 :                 if (itd == NULL) {
    3512           0 :                         ehci_free_itd_chain(sc, ex);
    3513           0 :                         return (1);
    3514             :                 }
    3515           0 :                 if (pitd)
    3516           0 :                         pitd->xfer_next = itd;
    3517             :                 else
    3518           0 :                         ex->itdstart = itd;
    3519             : 
    3520           0 :                 itd->sitd.sitd_endp = htole32(endp);
    3521           0 :                 itd->sitd.sitd_back = htole32(EHCI_LINK_TERMINATE);
    3522           0 :                 itd->sitd.sitd_trans = htole32(
    3523             :                     EHCI_SITD_ACTIVE |
    3524             :                     EHCI_SITD_SET_LEN(xfer->frlengths[i]) |
    3525             :                     ((i == nframes - 1) ? EHCI_SITD_IOC : 0)
    3526             :                 );
    3527             : 
    3528           0 :                 uf = max(1, ((xfer->frlengths[i] + 187) / 188));
    3529             : 
    3530             :                 /*
    3531             :                  * Since we do not yet budget and schedule micro-frames
    3532             :                  * we assume there is no other transfer using the same
    3533             :                  * TT.
    3534             :                  */
    3535           0 :                 if (usbd_xfer_isread(xfer)) {
    3536             :                         smask = 0x01;
    3537           0 :                         cmask = ((1 << (uf + 2)) - 1) << 2;
    3538           0 :                 } else {
    3539             :                         /* Is the payload is greater than 188 bytes? */
    3540           0 :                         if (uf == 1)
    3541           0 :                                 tp = EHCI_SITD_TP_ALL;
    3542             :                         else
    3543             :                                 tp = EHCI_SITD_TP_BEGIN;
    3544             : 
    3545           0 :                         page |= EHCI_SITD_SET_TCOUNT(uf) | EHCI_SITD_SET_TP(tp);
    3546           0 :                         smask = (1 << uf) - 1;
    3547             :                         cmask = 0x00;
    3548             :                 }
    3549             : 
    3550           0 :                 itd->sitd.sitd_sched = htole32(
    3551             :                     EHCI_SITD_SET_SMASK(smask) | EHCI_SITD_SET_CMASK(cmask)
    3552             :                 );
    3553           0 :                 itd->sitd.sitd_bufr[0] = htole32(addr);
    3554           0 :                 itd->sitd.sitd_bufr[1] = htole32(page);
    3555             : 
    3556           0 :                 offs += xfer->frlengths[i];
    3557             :                 pitd = itd;
    3558           0 :         }
    3559             : 
    3560           0 :         ex->itdend = itd;
    3561             : 
    3562           0 :         return (0);
    3563           0 : }
    3564             : 
    3565             : void
    3566           0 : ehci_device_isoc_abort(struct usbd_xfer *xfer)
    3567             : {
    3568             :         int s;
    3569             : 
    3570           0 :         s = splusb();
    3571           0 :         ehci_abort_isoc_xfer(xfer, USBD_CANCELLED);
    3572           0 :         splx(s);
    3573           0 : }
    3574             : 
    3575             : void
    3576           0 : ehci_device_isoc_close(struct usbd_pipe *pipe)
    3577             : {
    3578           0 : }
    3579             : 
    3580             : void
    3581           0 : ehci_device_isoc_done(struct usbd_xfer *xfer)
    3582             : {
    3583           0 :         struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
    3584           0 :         struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
    3585           0 :         struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
    3586             :         int s;
    3587             : 
    3588           0 :         s = splusb();
    3589           0 :         epipe->u.isoc.cur_xfers--;
    3590           0 :         if (xfer->status != USBD_NOMEM) {
    3591           0 :                 ehci_rem_itd_chain(sc, ex);
    3592           0 :                 ehci_free_itd_chain(sc, ex);
    3593           0 :         }
    3594           0 :         splx(s);
    3595           0 : }

Generated by: LCOV version 1.13