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

          Line data    Source code
       1             : /*      $OpenBSD: ohci.c,v 1.153 2018/03/05 11:32:05 jmatthew Exp $ */
       2             : /*      $NetBSD: ohci.c,v 1.139 2003/02/22 05:24:16 tsutsui Exp $       */
       3             : /*      $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $       */
       4             : 
       5             : /*
       6             :  * Copyright (c) 1998 The NetBSD Foundation, Inc.
       7             :  * All rights reserved.
       8             :  *
       9             :  * This code is derived from software contributed to The NetBSD Foundation
      10             :  * by Lennart Augustsson (lennart@augustsson.net) at
      11             :  * Carlstedt Research & Technology.
      12             :  *
      13             :  * Redistribution and use in source and binary forms, with or without
      14             :  * modification, are permitted provided that the following conditions
      15             :  * are met:
      16             :  * 1. Redistributions of source code must retain the above copyright
      17             :  *    notice, this list of conditions and the following disclaimer.
      18             :  * 2. Redistributions in binary form must reproduce the above copyright
      19             :  *    notice, this list of conditions and the following disclaimer in the
      20             :  *    documentation and/or other materials provided with the distribution.
      21             :  *
      22             :  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
      23             :  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
      24             :  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      25             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
      26             :  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      27             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      28             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      29             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      30             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      31             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      32             :  * POSSIBILITY OF SUCH DAMAGE.
      33             :  */
      34             : 
      35             : #include <sys/param.h>
      36             : #include <sys/systm.h>
      37             : #include <sys/malloc.h>
      38             : #include <sys/device.h>
      39             : #include <sys/queue.h>
      40             : #include <sys/timeout.h>
      41             : #include <sys/pool.h>
      42             : #include <sys/endian.h>
      43             : 
      44             : #include <machine/bus.h>
      45             : 
      46             : #include <dev/usb/usb.h>
      47             : #include <dev/usb/usbdi.h>
      48             : #include <dev/usb/usbdivar.h>
      49             : #include <dev/usb/usb_mem.h>
      50             : 
      51             : #include <dev/usb/ohcireg.h>
      52             : #include <dev/usb/ohcivar.h>
      53             : 
      54             : struct cfdriver ohci_cd = {
      55             :         NULL, "ohci", DV_DULL
      56             : };
      57             : 
      58             : #ifdef OHCI_DEBUG
      59             : #define DPRINTF(x)      do { if (ohcidebug) printf x; } while (0)
      60             : #define DPRINTFN(n,x)   do { if (ohcidebug>(n)) printf x; } while (0)
      61             : int ohcidebug = 0;
      62             : #define bitmask_snprintf(q,f,b,l) snprintf((b), (l), "%b", (q), (f))
      63             : #else
      64             : #define DPRINTF(x)
      65             : #define DPRINTFN(n,x)
      66             : #endif
      67             : 
      68             : struct pool *ohcixfer;
      69             : 
      70             : struct ohci_pipe;
      71             : 
      72             : struct ohci_soft_ed *ohci_alloc_sed(struct ohci_softc *);
      73             : void            ohci_free_sed(struct ohci_softc *, struct ohci_soft_ed *);
      74             : 
      75             : struct ohci_soft_td *ohci_alloc_std(struct ohci_softc *);
      76             : void            ohci_free_std(struct ohci_softc *, struct ohci_soft_td *);
      77             : 
      78             : struct ohci_soft_itd *ohci_alloc_sitd(struct ohci_softc *);
      79             : void            ohci_free_sitd(struct ohci_softc *, struct ohci_soft_itd *);
      80             : 
      81             : #if 0
      82             : void            ohci_free_std_chain(struct ohci_softc *, struct ohci_soft_td *,
      83             :                     struct ohci_soft_td *);
      84             : #endif
      85             : usbd_status     ohci_alloc_std_chain(struct ohci_softc *, u_int,
      86             :                     struct usbd_xfer *, struct ohci_soft_td *,
      87             :                     struct ohci_soft_td **);
      88             : 
      89             : usbd_status     ohci_open(struct usbd_pipe *);
      90             : int             ohci_setaddr(struct usbd_device *, int);
      91             : void            ohci_poll(struct usbd_bus *);
      92             : void            ohci_softintr(void *);
      93             : void            ohci_add_done(struct ohci_softc *, ohci_physaddr_t);
      94             : void            ohci_rhsc(struct ohci_softc *, struct usbd_xfer *);
      95             : 
      96             : usbd_status     ohci_device_request(struct usbd_xfer *xfer);
      97             : void            ohci_add_ed(struct ohci_soft_ed *, struct ohci_soft_ed *);
      98             : void            ohci_rem_ed(struct ohci_soft_ed *, struct ohci_soft_ed *);
      99             : void            ohci_hash_add_td(struct ohci_softc *, struct ohci_soft_td *);
     100             : struct ohci_soft_td *ohci_hash_find_td(struct ohci_softc *, ohci_physaddr_t);
     101             : void            ohci_hash_add_itd(struct ohci_softc *, struct ohci_soft_itd *);
     102             : void            ohci_hash_rem_itd(struct ohci_softc *, struct ohci_soft_itd *);
     103             : struct ohci_soft_itd *ohci_hash_find_itd(struct ohci_softc *, ohci_physaddr_t);
     104             : 
     105             : usbd_status     ohci_setup_isoc(struct usbd_pipe *pipe);
     106             : void            ohci_device_isoc_enter(struct usbd_xfer *);
     107             : 
     108             : struct usbd_xfer *ohci_allocx(struct usbd_bus *);
     109             : void            ohci_freex(struct usbd_bus *, struct usbd_xfer *);
     110             : 
     111             : usbd_status     ohci_root_ctrl_transfer(struct usbd_xfer *);
     112             : usbd_status     ohci_root_ctrl_start(struct usbd_xfer *);
     113             : void            ohci_root_ctrl_abort(struct usbd_xfer *);
     114             : void            ohci_root_ctrl_close(struct usbd_pipe *);
     115             : void            ohci_root_ctrl_done(struct usbd_xfer *);
     116             : 
     117             : usbd_status     ohci_root_intr_transfer(struct usbd_xfer *);
     118             : usbd_status     ohci_root_intr_start(struct usbd_xfer *);
     119             : void            ohci_root_intr_abort(struct usbd_xfer *);
     120             : void            ohci_root_intr_close(struct usbd_pipe *);
     121             : void            ohci_root_intr_done(struct usbd_xfer *);
     122             : 
     123             : usbd_status     ohci_device_ctrl_transfer(struct usbd_xfer *);
     124             : usbd_status     ohci_device_ctrl_start(struct usbd_xfer *);
     125             : void            ohci_device_ctrl_abort(struct usbd_xfer *);
     126             : void            ohci_device_ctrl_close(struct usbd_pipe *);
     127             : void            ohci_device_ctrl_done(struct usbd_xfer *);
     128             : 
     129             : usbd_status     ohci_device_bulk_transfer(struct usbd_xfer *);
     130             : usbd_status     ohci_device_bulk_start(struct usbd_xfer *);
     131             : void            ohci_device_bulk_abort(struct usbd_xfer *);
     132             : void            ohci_device_bulk_close(struct usbd_pipe *);
     133             : void            ohci_device_bulk_done(struct usbd_xfer *);
     134             : 
     135             : usbd_status     ohci_device_intr_transfer(struct usbd_xfer *);
     136             : usbd_status     ohci_device_intr_start(struct usbd_xfer *);
     137             : void            ohci_device_intr_abort(struct usbd_xfer *);
     138             : void            ohci_device_intr_close(struct usbd_pipe *);
     139             : void            ohci_device_intr_done(struct usbd_xfer *);
     140             : 
     141             : usbd_status     ohci_device_isoc_transfer(struct usbd_xfer *);
     142             : usbd_status     ohci_device_isoc_start(struct usbd_xfer *);
     143             : void            ohci_device_isoc_abort(struct usbd_xfer *);
     144             : void            ohci_device_isoc_close(struct usbd_pipe *);
     145             : void            ohci_device_isoc_done(struct usbd_xfer *);
     146             : 
     147             : usbd_status     ohci_device_setintr(struct ohci_softc *sc,
     148             :                             struct ohci_pipe *pipe, int ival);
     149             : 
     150             : void            ohci_timeout(void *);
     151             : void            ohci_timeout_task(void *);
     152             : void            ohci_rhsc_able(struct ohci_softc *, int);
     153             : void            ohci_rhsc_enable(void *);
     154             : 
     155             : void            ohci_close_pipe(struct usbd_pipe *, struct ohci_soft_ed *);
     156             : void            ohci_abort_xfer(struct usbd_xfer *, usbd_status);
     157             : 
     158             : void            ohci_device_clear_toggle(struct usbd_pipe *pipe);
     159             : 
     160             : #ifdef OHCI_DEBUG
     161             : void            ohci_dumpregs(struct ohci_softc *);
     162             : void            ohci_dump_tds(struct ohci_soft_td *);
     163             : void            ohci_dump_td(struct ohci_soft_td *);
     164             : void            ohci_dump_ed(struct ohci_soft_ed *);
     165             : void            ohci_dump_itd(struct ohci_soft_itd *);
     166             : void            ohci_dump_itds(struct ohci_soft_itd *);
     167             : #endif
     168             : 
     169             : #define OBARR(sc) bus_space_barrier((sc)->iot, (sc)->ioh, 0, (sc)->sc_size, \
     170             :                         BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)
     171             : #define OWRITE1(sc, r, x) \
     172             :  do { OBARR(sc); bus_space_write_1((sc)->iot, (sc)->ioh, (r), (x)); } while (0)
     173             : #define OWRITE2(sc, r, x) \
     174             :  do { OBARR(sc); bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x)); } while (0)
     175             : #define OWRITE4(sc, r, x) \
     176             :  do { OBARR(sc); bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)); } while (0)
     177             : 
     178             : __unused static __inline u_int8_t
     179             : OREAD1(struct ohci_softc *sc, bus_size_t r)
     180             : {
     181             :         OBARR(sc);
     182             :         return bus_space_read_1(sc->iot, sc->ioh, r);
     183             : }
     184             : 
     185             : __unused static __inline u_int16_t
     186             : OREAD2(struct ohci_softc *sc, bus_size_t r)
     187             : {
     188             :         OBARR(sc);
     189             :         return bus_space_read_2(sc->iot, sc->ioh, r);
     190             : }
     191             : 
     192             : __unused static __inline u_int32_t
     193           0 : OREAD4(struct ohci_softc *sc, bus_size_t r)
     194             : {
     195           0 :         OBARR(sc);
     196           0 :         return bus_space_read_4(sc->iot, sc->ioh, r);
     197             : }
     198             : 
     199             : /* Reverse the bits in a value 0 .. 31 */
     200             : u_int8_t revbits[OHCI_NO_INTRS] =
     201             :   { 0x00, 0x10, 0x08, 0x18, 0x04, 0x14, 0x0c, 0x1c,
     202             :     0x02, 0x12, 0x0a, 0x1a, 0x06, 0x16, 0x0e, 0x1e,
     203             :     0x01, 0x11, 0x09, 0x19, 0x05, 0x15, 0x0d, 0x1d,
     204             :     0x03, 0x13, 0x0b, 0x1b, 0x07, 0x17, 0x0f, 0x1f };
     205             : 
     206             : struct ohci_pipe {
     207             :         struct usbd_pipe pipe;
     208             :         struct ohci_soft_ed *sed;
     209             :         union {
     210             :                 struct ohci_soft_td *td;
     211             :                 struct ohci_soft_itd *itd;
     212             :         } tail;
     213             :         union {
     214             :                 /* Control pipe */
     215             :                 struct {
     216             :                         struct usb_dma reqdma;
     217             :                 } ctl;
     218             :                 /* Interrupt pipe */
     219             :                 struct {
     220             :                         int nslots;
     221             :                         int pos;
     222             :                 } intr;
     223             :                 /* Iso pipe */
     224             :                 struct iso {
     225             :                         int next, inuse;
     226             :                 } iso;
     227             :         } u;
     228             : };
     229             : 
     230             : #define OHCI_INTR_ENDPT 1
     231             : 
     232             : struct usbd_bus_methods ohci_bus_methods = {
     233             :         .open_pipe = ohci_open,
     234             :         .dev_setaddr = ohci_setaddr,
     235             :         .soft_intr = ohci_softintr,
     236             :         .do_poll = ohci_poll,
     237             :         .allocx = ohci_allocx,
     238             :         .freex = ohci_freex,
     239             : };
     240             : 
     241             : struct usbd_pipe_methods ohci_root_ctrl_methods = {
     242             :         .transfer = ohci_root_ctrl_transfer,
     243             :         .start = ohci_root_ctrl_start,
     244             :         .abort = ohci_root_ctrl_abort,
     245             :         .close = ohci_root_ctrl_close,
     246             :         .done = ohci_root_ctrl_done,
     247             : };
     248             : 
     249             : struct usbd_pipe_methods ohci_root_intr_methods = {
     250             :         .transfer = ohci_root_intr_transfer,
     251             :         .start = ohci_root_intr_start,
     252             :         .abort = ohci_root_intr_abort,
     253             :         .close = ohci_root_intr_close,
     254             :         .done = ohci_root_intr_done,
     255             : };
     256             : 
     257             : struct usbd_pipe_methods ohci_device_ctrl_methods = {
     258             :         .transfer = ohci_device_ctrl_transfer,
     259             :         .start = ohci_device_ctrl_start,
     260             :         .abort = ohci_device_ctrl_abort,
     261             :         .close = ohci_device_ctrl_close,
     262             :         .done = ohci_device_ctrl_done,
     263             : };
     264             : 
     265             : struct usbd_pipe_methods ohci_device_intr_methods = {
     266             :         .transfer = ohci_device_intr_transfer,
     267             :         .start = ohci_device_intr_start,
     268             :         .abort = ohci_device_intr_abort,
     269             :         .close = ohci_device_intr_close,
     270             :         .cleartoggle = ohci_device_clear_toggle,
     271             :         .done = ohci_device_intr_done,
     272             : };
     273             : 
     274             : struct usbd_pipe_methods ohci_device_bulk_methods = {
     275             :         .transfer = ohci_device_bulk_transfer,
     276             :         .start = ohci_device_bulk_start,
     277             :         .abort = ohci_device_bulk_abort,
     278             :         .close = ohci_device_bulk_close,
     279             :         .cleartoggle = ohci_device_clear_toggle,
     280             :         .done = ohci_device_bulk_done,
     281             : };
     282             : 
     283             : struct usbd_pipe_methods ohci_device_isoc_methods = {
     284             :         .transfer = ohci_device_isoc_transfer,
     285             :         .start = ohci_device_isoc_start,
     286             :         .abort = ohci_device_isoc_abort,
     287             :         .close = ohci_device_isoc_close,
     288             :         .done = ohci_device_isoc_done,
     289             : };
     290             : 
     291             : int
     292           0 : ohci_activate(struct device *self, int act)
     293             : {
     294           0 :         struct ohci_softc *sc = (struct ohci_softc *)self;
     295             :         u_int32_t reg;
     296             :         int rv = 0;
     297             : 
     298           0 :         switch (act) {
     299             :         case DVACT_SUSPEND:
     300           0 :                 rv = config_activate_children(self, act);
     301           0 :                 sc->sc_bus.use_polling++;
     302           0 :                 reg = OREAD4(sc, OHCI_CONTROL) & ~OHCI_HCFS_MASK;
     303           0 :                 if (sc->sc_control == 0) {
     304             :                         /*
     305             :                          * Preserve register values, in case that APM BIOS
     306             :                          * does not recover them.
     307             :                          */
     308           0 :                         sc->sc_control = reg;
     309           0 :                         sc->sc_intre = OREAD4(sc, OHCI_INTERRUPT_ENABLE);
     310           0 :                         sc->sc_ival = OHCI_GET_IVAL(OREAD4(sc,
     311             :                             OHCI_FM_INTERVAL));
     312           0 :                 }
     313           0 :                 reg |= OHCI_HCFS_SUSPEND;
     314           0 :                 OWRITE4(sc, OHCI_CONTROL, reg);
     315           0 :                 usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
     316           0 :                 sc->sc_bus.use_polling--;
     317           0 :                 break;
     318             :         case DVACT_RESUME:
     319           0 :                 sc->sc_bus.use_polling++;
     320             : 
     321             :                 /* Some broken BIOSes do not recover these values */
     322           0 :                 OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma, 0));
     323           0 :                 OWRITE4(sc, OHCI_CONTROL_HEAD_ED, sc->sc_ctrl_head->physaddr);
     324           0 :                 OWRITE4(sc, OHCI_BULK_HEAD_ED, sc->sc_bulk_head->physaddr);
     325           0 :                 if (sc->sc_intre)
     326           0 :                         OWRITE4(sc, OHCI_INTERRUPT_ENABLE,
     327             :                             sc->sc_intre & (OHCI_ALL_INTRS | OHCI_MIE));
     328           0 :                 if (sc->sc_control)
     329           0 :                         reg = sc->sc_control;
     330             :                 else
     331           0 :                         reg = OREAD4(sc, OHCI_CONTROL);
     332           0 :                 reg |= OHCI_HCFS_RESUME;
     333           0 :                 OWRITE4(sc, OHCI_CONTROL, reg);
     334           0 :                 usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
     335           0 :                 reg = (reg & ~OHCI_HCFS_MASK) | OHCI_HCFS_OPERATIONAL;
     336           0 :                 OWRITE4(sc, OHCI_CONTROL, reg);
     337             : 
     338           0 :                 reg = (OREAD4(sc, OHCI_FM_REMAINING) & OHCI_FIT) ^ OHCI_FIT;
     339           0 :                 reg |= OHCI_FSMPS(sc->sc_ival) | sc->sc_ival;
     340           0 :                 OWRITE4(sc, OHCI_FM_INTERVAL, reg);
     341           0 :                 OWRITE4(sc, OHCI_PERIODIC_START, OHCI_PERIODIC(sc->sc_ival));
     342             : 
     343             :                 /* Fiddle the No OverCurrent Protection to avoid a chip bug */
     344           0 :                 reg = OREAD4(sc, OHCI_RH_DESCRIPTOR_A);
     345           0 :                 OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, reg | OHCI_NOCP);
     346           0 :                 OWRITE4(sc, OHCI_RH_STATUS, OHCI_LPSC); /* Enable port power */
     347           0 :                 usb_delay_ms(&sc->sc_bus, OHCI_ENABLE_POWER_DELAY);
     348           0 :                 OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, reg);
     349             : 
     350           0 :                 usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY);
     351           0 :                 sc->sc_control = sc->sc_intre = sc->sc_ival = 0;
     352           0 :                 sc->sc_bus.use_polling--;
     353           0 :                 rv = config_activate_children(self, act);
     354           0 :                 break;
     355             :         case DVACT_POWERDOWN:
     356           0 :                 rv = config_activate_children(self, act);
     357           0 :                 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
     358           0 :                 break;
     359             :         default:
     360           0 :                 rv = config_activate_children(self, act);
     361           0 :                 break;
     362             :         }
     363           0 :         return (rv);
     364             : }
     365             : 
     366             : int
     367           0 : ohci_detach(struct device *self, int flags)
     368             : {
     369           0 :         struct ohci_softc *sc = (struct ohci_softc *)self;
     370             :         int rv;
     371             : 
     372           0 :         rv = config_detach_children(self, flags);
     373           0 :         if (rv != 0)
     374           0 :                 return (rv);
     375             : 
     376           0 :         timeout_del(&sc->sc_tmo_rhsc);
     377             : 
     378           0 :         usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
     379             : 
     380             :         /* free data structures XXX */
     381             : 
     382           0 :         return (rv);
     383           0 : }
     384             : 
     385             : struct ohci_soft_ed *
     386           0 : ohci_alloc_sed(struct ohci_softc *sc)
     387             : {
     388             :         struct ohci_soft_ed *sed = NULL;
     389             :         usbd_status err;
     390             :         int i, offs;
     391           0 :         struct usb_dma dma;
     392             :         int s;
     393             : 
     394           0 :         s = splusb();
     395           0 :         if (sc->sc_freeeds == NULL) {
     396             :                 DPRINTFN(2, ("ohci_alloc_sed: allocating chunk\n"));
     397           0 :                 err = usb_allocmem(&sc->sc_bus, OHCI_SED_SIZE * OHCI_SED_CHUNK,
     398             :                           OHCI_ED_ALIGN, &dma);
     399           0 :                 if (err)
     400             :                         goto out;
     401           0 :                 for (i = 0; i < OHCI_SED_CHUNK; i++) {
     402           0 :                         offs = i * OHCI_SED_SIZE;
     403           0 :                         sed = KERNADDR(&dma, offs);
     404           0 :                         sed->physaddr = DMAADDR(&dma, offs);
     405           0 :                         sed->next = sc->sc_freeeds;
     406           0 :                         sc->sc_freeeds = sed;
     407             :                 }
     408             :         }
     409           0 :         sed = sc->sc_freeeds;
     410           0 :         sc->sc_freeeds = sed->next;
     411           0 :         memset(&sed->ed, 0, sizeof(struct ohci_ed));
     412           0 :         sed->next = NULL;
     413             : 
     414             : out:
     415           0 :         splx(s);
     416           0 :         return (sed);
     417           0 : }
     418             : 
     419             : void
     420           0 : ohci_free_sed(struct ohci_softc *sc, struct ohci_soft_ed *sed)
     421             : {
     422             :         int s;
     423             : 
     424           0 :         s = splusb();
     425           0 :         sed->next = sc->sc_freeeds;
     426           0 :         sc->sc_freeeds = sed;
     427           0 :         splx(s);
     428           0 : }
     429             : 
     430             : struct ohci_soft_td *
     431           0 : ohci_alloc_std(struct ohci_softc *sc)
     432             : {
     433             :         struct ohci_soft_td *std = NULL;
     434             :         usbd_status err;
     435             :         int i, offs;
     436           0 :         struct usb_dma dma;
     437             :         int s;
     438             : 
     439           0 :         s = splusb();
     440           0 :         if (sc->sc_freetds == NULL) {
     441             :                 DPRINTFN(2, ("ohci_alloc_std: allocating chunk\n"));
     442           0 :                 err = usb_allocmem(&sc->sc_bus, OHCI_STD_SIZE * OHCI_STD_CHUNK,
     443             :                           OHCI_TD_ALIGN, &dma);
     444           0 :                 if (err)
     445             :                         goto out;
     446           0 :                 for (i = 0; i < OHCI_STD_CHUNK; i++) {
     447           0 :                         offs = i * OHCI_STD_SIZE;
     448           0 :                         std = KERNADDR(&dma, offs);
     449           0 :                         std->physaddr = DMAADDR(&dma, offs);
     450           0 :                         std->nexttd = sc->sc_freetds;
     451           0 :                         sc->sc_freetds = std;
     452             :                 }
     453             :         }
     454             : 
     455           0 :         std = sc->sc_freetds;
     456           0 :         sc->sc_freetds = std->nexttd;
     457           0 :         memset(&std->td, 0, sizeof(struct ohci_td));
     458           0 :         std->nexttd = NULL;
     459           0 :         std->xfer = NULL;
     460           0 :         ohci_hash_add_td(sc, std);
     461             : 
     462             : out:
     463           0 :         splx(s);
     464           0 :         return (std);
     465           0 : }
     466             : 
     467             : void
     468           0 : ohci_free_std(struct ohci_softc *sc, struct ohci_soft_td *std)
     469             : {
     470             :         int s;
     471             : 
     472           0 :         s = splusb();
     473           0 :         LIST_REMOVE(std, hnext);
     474           0 :         std->nexttd = sc->sc_freetds;
     475           0 :         sc->sc_freetds = std;
     476           0 :         splx(s);
     477           0 : }
     478             : 
     479             : usbd_status
     480           0 : ohci_alloc_std_chain(struct ohci_softc *sc, u_int alen, struct usbd_xfer *xfer,
     481             :     struct ohci_soft_td *sp, struct ohci_soft_td **ep)
     482             : {
     483             :         struct ohci_soft_td *next, *cur, *end;
     484             :         ohci_physaddr_t dataphys, dataphysend;
     485             :         u_int32_t tdflags;
     486             :         u_int len, curlen;
     487             :         int mps;
     488           0 :         int rd = usbd_xfer_isread(xfer);
     489           0 :         struct usb_dma *dma = &xfer->dmabuf;
     490           0 :         u_int16_t flags = xfer->flags;
     491             : 
     492             :         DPRINTFN(alen < 4096,("ohci_alloc_std_chain: start len=%u\n", alen));
     493             : 
     494             :         len = alen;
     495             :         cur = sp;
     496             :         end = NULL;
     497             : 
     498           0 :         dataphys = DMAADDR(dma, 0);
     499           0 :         dataphysend = OHCI_PAGE(dataphys + len - 1);
     500           0 :         tdflags = htole32(
     501             :             (rd ? OHCI_TD_IN : OHCI_TD_OUT) |
     502             :             (flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0) |
     503             :             OHCI_TD_NOCC | OHCI_TD_TOGGLE_CARRY | OHCI_TD_NOINTR);
     504           0 :         mps = UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize);
     505             : 
     506           0 :         while (len > 0) {
     507           0 :                 next = ohci_alloc_std(sc);
     508           0 :                 if (next == NULL)
     509             :                         goto nomem;
     510             : 
     511             :                 /* The OHCI hardware can handle at most one page crossing. */
     512           0 :                 if (OHCI_PAGE(dataphys) == dataphysend ||
     513           0 :                     OHCI_PAGE(dataphys) + OHCI_PAGE_SIZE == dataphysend) {
     514             :                         /* we can handle it in this TD */
     515             :                         curlen = len;
     516           0 :                 } else {
     517             :                         /* must use multiple TDs, fill as much as possible. */
     518           0 :                         curlen = 2 * OHCI_PAGE_SIZE -
     519           0 :                                  (dataphys & (OHCI_PAGE_SIZE-1));
     520             :                         /* the length must be a multiple of the max size */
     521           0 :                         curlen -= curlen % mps;
     522             : #ifdef DIAGNOSTIC
     523           0 :                         if (curlen == 0)
     524           0 :                                 panic("ohci_alloc_std: curlen == 0");
     525             : #endif
     526             :                 }
     527             :                 DPRINTFN(4,("ohci_alloc_std_chain: dataphys=0x%08x "
     528             :                             "dataphysend=0x%08x len=%u curlen=%u\n",
     529             :                             dataphys, dataphysend,
     530             :                             len, curlen));
     531           0 :                 len -= curlen;
     532             : 
     533           0 :                 cur->td.td_flags = tdflags;
     534           0 :                 cur->td.td_cbp = htole32(dataphys);
     535           0 :                 cur->nexttd = next;
     536           0 :                 cur->td.td_nexttd = htole32(next->physaddr);
     537           0 :                 cur->td.td_be = htole32(dataphys + curlen - 1);
     538           0 :                 cur->len = curlen;
     539           0 :                 cur->flags = OHCI_ADD_LEN;
     540           0 :                 cur->xfer = xfer;
     541             :                 DPRINTFN(10,("ohci_alloc_std_chain: cbp=0x%08x be=0x%08x\n",
     542             :                             dataphys, dataphys + curlen - 1));
     543             :                 DPRINTFN(10,("ohci_alloc_std_chain: extend chain\n"));
     544             :                 dataphys += curlen;
     545             :                 end = cur;
     546             :                 cur = next;
     547             :         }
     548           0 :         if (!rd && ((flags & USBD_FORCE_SHORT_XFER) || alen == 0) &&
     549           0 :             alen % mps == 0) {
     550             :                 /* Force a 0 length transfer at the end. */
     551             : 
     552           0 :                 next = ohci_alloc_std(sc);
     553           0 :                 if (next == NULL)
     554             :                         goto nomem;
     555             : 
     556           0 :                 cur->td.td_flags = tdflags;
     557           0 :                 cur->td.td_cbp = 0; /* indicate 0 length packet */
     558           0 :                 cur->nexttd = next;
     559           0 :                 cur->td.td_nexttd = htole32(next->physaddr);
     560           0 :                 cur->td.td_be = ~0;
     561           0 :                 cur->len = 0;
     562           0 :                 cur->flags = 0;
     563           0 :                 cur->xfer = xfer;
     564             :                 DPRINTFN(2,("ohci_alloc_std_chain: add 0 xfer\n"));
     565             :                 end = cur;
     566           0 :         }
     567           0 :         *ep = end;
     568             : 
     569           0 :         return (USBD_NORMAL_COMPLETION);
     570             : 
     571             :  nomem:
     572             :         /* XXX free chain */
     573           0 :         return (USBD_NOMEM);
     574           0 : }
     575             : 
     576             : #if 0
     577             : void
     578             : ohci_free_std_chain(struct ohci_softc *sc, struct ohci_soft_td *std,
     579             :     struct ohci_soft_td *stdend)
     580             : {
     581             :         struct ohci_soft_td *p;
     582             : 
     583             :         for (; std != stdend; std = p) {
     584             :                 p = std->nexttd;
     585             :                 ohci_free_std(sc, std);
     586             :         }
     587             : }
     588             : #endif
     589             : 
     590             : struct ohci_soft_itd *
     591           0 : ohci_alloc_sitd(struct ohci_softc *sc)
     592             : {
     593             :         struct ohci_soft_itd *sitd;
     594             :         usbd_status err;
     595             :         int i, s, offs;
     596           0 :         struct usb_dma dma;
     597             : 
     598           0 :         if (sc->sc_freeitds == NULL) {
     599             :                 DPRINTFN(2, ("ohci_alloc_sitd: allocating chunk\n"));
     600           0 :                 err = usb_allocmem(&sc->sc_bus, OHCI_SITD_SIZE * OHCI_SITD_CHUNK,
     601             :                           OHCI_ITD_ALIGN, &dma);
     602           0 :                 if (err)
     603           0 :                         return (NULL);
     604           0 :                 s = splusb();
     605           0 :                 for(i = 0; i < OHCI_SITD_CHUNK; i++) {
     606           0 :                         offs = i * OHCI_SITD_SIZE;
     607           0 :                         sitd = KERNADDR(&dma, offs);
     608           0 :                         sitd->physaddr = DMAADDR(&dma, offs);
     609           0 :                         sitd->nextitd = sc->sc_freeitds;
     610           0 :                         sc->sc_freeitds = sitd;
     611             :                 }
     612           0 :                 splx(s);
     613           0 :         }
     614             : 
     615           0 :         s = splusb();
     616           0 :         sitd = sc->sc_freeitds;
     617           0 :         sc->sc_freeitds = sitd->nextitd;
     618           0 :         memset(&sitd->itd, 0, sizeof(struct ohci_itd));
     619           0 :         sitd->nextitd = NULL;
     620           0 :         sitd->xfer = NULL;
     621           0 :         ohci_hash_add_itd(sc, sitd);
     622           0 :         splx(s);
     623             : 
     624             : #ifdef DIAGNOSTIC
     625           0 :         sitd->isdone = 0;
     626             : #endif
     627             : 
     628           0 :         return (sitd);
     629           0 : }
     630             : 
     631             : void
     632           0 : ohci_free_sitd(struct ohci_softc *sc, struct ohci_soft_itd *sitd)
     633             : {
     634             :         int s;
     635             : 
     636             :         DPRINTFN(10,("ohci_free_sitd: sitd=%p\n", sitd));
     637             : 
     638             : #ifdef DIAGNOSTIC
     639           0 :         if (!sitd->isdone) {
     640           0 :                 panic("ohci_free_sitd: sitd=%p not done", sitd);
     641             :                 return;
     642             :         }
     643             :         /* Warn double free */
     644           0 :         sitd->isdone = 0;
     645             : #endif
     646             : 
     647           0 :         s = splusb();
     648           0 :         ohci_hash_rem_itd(sc, sitd);
     649           0 :         sitd->nextitd = sc->sc_freeitds;
     650           0 :         sc->sc_freeitds = sitd;
     651           0 :         splx(s);
     652           0 : }
     653             : 
     654             : usbd_status
     655           0 : ohci_checkrev(struct ohci_softc *sc)
     656             : {
     657             :         u_int32_t rev;
     658             : 
     659           0 :         printf(",");
     660           0 :         rev = OREAD4(sc, OHCI_REVISION);
     661           0 :         printf(" version %d.%d%s\n", OHCI_REV_HI(rev), OHCI_REV_LO(rev),
     662           0 :                OHCI_REV_LEGACY(rev) ? ", legacy support" : "");
     663             : 
     664           0 :         if (OHCI_REV_HI(rev) != 1 || OHCI_REV_LO(rev) != 0) {
     665           0 :                 printf("%s: unsupported OHCI revision\n",
     666           0 :                        sc->sc_bus.bdev.dv_xname);
     667           0 :                 sc->sc_bus.usbrev = USBREV_UNKNOWN;
     668           0 :                 return (USBD_INVAL);
     669             :         }
     670           0 :         sc->sc_bus.usbrev = USBREV_1_0;
     671             : 
     672           0 :         return (USBD_NORMAL_COMPLETION);
     673           0 : }
     674             : 
     675             : usbd_status
     676           0 : ohci_handover(struct ohci_softc *sc)
     677             : {
     678             :         u_int32_t s, ctl;
     679             :         int i;
     680             : 
     681           0 :         ctl = OREAD4(sc, OHCI_CONTROL);
     682           0 :         if (ctl & OHCI_IR) {
     683             :                 /* SMM active, request change */
     684             :                 DPRINTF(("ohci_handover: SMM active, request owner change\n"));
     685           0 :                 if ((sc->sc_intre & (OHCI_OC | OHCI_MIE)) == 
     686             :                     (OHCI_OC | OHCI_MIE))
     687           0 :                         OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_MIE);
     688           0 :                 s = OREAD4(sc, OHCI_COMMAND_STATUS);
     689           0 :                 OWRITE4(sc, OHCI_COMMAND_STATUS, s | OHCI_OCR);
     690           0 :                 for (i = 0; i < 100 && (ctl & OHCI_IR); i++) {
     691           0 :                         usb_delay_ms(&sc->sc_bus, 1);
     692           0 :                         ctl = OREAD4(sc, OHCI_CONTROL);
     693             :                 }
     694           0 :                 OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_MIE);
     695           0 :                 if (ctl & OHCI_IR) {
     696           0 :                         printf("%s: SMM does not respond, will reset\n",
     697           0 :                             sc->sc_bus.bdev.dv_xname);
     698           0 :                 }
     699             :         }
     700             : 
     701           0 :         return (USBD_NORMAL_COMPLETION);
     702             : }
     703             : 
     704             : usbd_status
     705           0 : ohci_init(struct ohci_softc *sc)
     706             : {
     707             :         struct ohci_soft_ed *sed, *psed;
     708             :         usbd_status err;
     709             :         int i;
     710             :         u_int32_t ctl, rwc, ival, hcr, fm, per, desca, descb;
     711             : 
     712             :         DPRINTF(("ohci_init: start\n"));
     713             : 
     714           0 :         for (i = 0; i < OHCI_HASH_SIZE; i++)
     715           0 :                 LIST_INIT(&sc->sc_hash_tds[i]);
     716           0 :         for (i = 0; i < OHCI_HASH_SIZE; i++)
     717           0 :                 LIST_INIT(&sc->sc_hash_itds[i]);
     718             : 
     719           0 :         if (ohcixfer == NULL) {
     720           0 :                 ohcixfer = malloc(sizeof(struct pool), M_DEVBUF, M_NOWAIT);
     721           0 :                 if (ohcixfer == NULL) {
     722           0 :                         printf("%s: unable to allocate pool descriptor\n",
     723           0 :                             sc->sc_bus.bdev.dv_xname);
     724           0 :                         return (ENOMEM);
     725             :                 }
     726           0 :                 pool_init(ohcixfer, sizeof(struct ohci_xfer), 0, IPL_SOFTUSB,
     727             :                     0, "ohcixfer", NULL);
     728           0 :         }
     729             : 
     730             :         /* XXX determine alignment by R/W */
     731             :         /* Allocate the HCCA area. */
     732           0 :         err = usb_allocmem(&sc->sc_bus, OHCI_HCCA_SIZE,
     733           0 :                          OHCI_HCCA_ALIGN, &sc->sc_hccadma);
     734           0 :         if (err)
     735           0 :                 return (err);
     736           0 :         sc->sc_hcca = KERNADDR(&sc->sc_hccadma, 0);
     737           0 :         memset(sc->sc_hcca, 0, OHCI_HCCA_SIZE);
     738             : 
     739           0 :         sc->sc_eintrs = OHCI_NORMAL_INTRS;
     740             : 
     741             :         /* Allocate dummy ED that starts the control list. */
     742           0 :         sc->sc_ctrl_head = ohci_alloc_sed(sc);
     743           0 :         if (sc->sc_ctrl_head == NULL) {
     744             :                 err = USBD_NOMEM;
     745           0 :                 goto bad1;
     746             :         }
     747           0 :         sc->sc_ctrl_head->ed.ed_flags |= htole32(OHCI_ED_SKIP);
     748             : 
     749             :         /* Allocate dummy ED that starts the bulk list. */
     750           0 :         sc->sc_bulk_head = ohci_alloc_sed(sc);
     751           0 :         if (sc->sc_bulk_head == NULL) {
     752             :                 err = USBD_NOMEM;
     753           0 :                 goto bad2;
     754             :         }
     755           0 :         sc->sc_bulk_head->ed.ed_flags |= htole32(OHCI_ED_SKIP);
     756             : 
     757             :         /* Allocate dummy ED that starts the isochronous list. */
     758           0 :         sc->sc_isoc_head = ohci_alloc_sed(sc);
     759           0 :         if (sc->sc_isoc_head == NULL) {
     760             :                 err = USBD_NOMEM;
     761           0 :                 goto bad3;
     762             :         }
     763           0 :         sc->sc_isoc_head->ed.ed_flags |= htole32(OHCI_ED_SKIP);
     764             : 
     765             :         /* Allocate all the dummy EDs that make up the interrupt tree. */
     766           0 :         for (i = 0; i < OHCI_NO_EDS; i++) {
     767           0 :                 sed = ohci_alloc_sed(sc);
     768           0 :                 if (sed == NULL) {
     769           0 :                         while (--i >= 0)
     770           0 :                                 ohci_free_sed(sc, sc->sc_eds[i]);
     771             :                         err = USBD_NOMEM;
     772           0 :                         goto bad4;
     773             :                 }
     774             :                 /* All ED fields are set to 0. */
     775           0 :                 sc->sc_eds[i] = sed;
     776           0 :                 sed->ed.ed_flags |= htole32(OHCI_ED_SKIP);
     777           0 :                 if (i != 0)
     778           0 :                         psed = sc->sc_eds[(i-1) / 2];
     779             :                 else
     780           0 :                         psed= sc->sc_isoc_head;
     781           0 :                 sed->next = psed;
     782           0 :                 sed->ed.ed_nexted = htole32(psed->physaddr);
     783             :         }
     784             :         /*
     785             :          * Fill HCCA interrupt table.  The bit reversal is to get
     786             :          * the tree set up properly to spread the interrupts.
     787             :          */
     788           0 :         for (i = 0; i < OHCI_NO_INTRS; i++)
     789           0 :                 sc->sc_hcca->hcca_interrupt_table[revbits[i]] =
     790           0 :                     htole32(sc->sc_eds[OHCI_NO_EDS-OHCI_NO_INTRS+i]->physaddr);
     791             : 
     792             : #ifdef OHCI_DEBUG
     793             :         if (ohcidebug > 15) {
     794             :                 for (i = 0; i < OHCI_NO_EDS; i++) {
     795             :                         printf("ed#%d ", i);
     796             :                         ohci_dump_ed(sc->sc_eds[i]);
     797             :                 }
     798             :                 printf("iso ");
     799             :                 ohci_dump_ed(sc->sc_isoc_head);
     800             :         }
     801             : #endif
     802             :         /* Preserve values programmed by SMM/BIOS but lost over reset. */
     803           0 :         ctl = OREAD4(sc, OHCI_CONTROL);
     804           0 :         rwc = ctl & OHCI_RWC;
     805           0 :         fm = OREAD4(sc, OHCI_FM_INTERVAL);
     806           0 :         desca = OREAD4(sc, OHCI_RH_DESCRIPTOR_A);
     807           0 :         descb = OREAD4(sc, OHCI_RH_DESCRIPTOR_B);
     808             : 
     809             :         /* Determine in what context we are running. */
     810           0 :         if (ctl & OHCI_IR) {
     811           0 :                 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET | rwc);
     812           0 :                 goto reset;
     813             : #if 0
     814             : /* Don't bother trying to reuse the BIOS init, we'll reset it anyway. */
     815             :         } else if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_RESET) {
     816             :                 /* BIOS started controller. */
     817             :                 DPRINTF(("ohci_init: BIOS active\n"));
     818             :                 if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_OPERATIONAL) {
     819             :                         OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_OPERATIONAL | rwc);
     820             :                         usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
     821             :                 }
     822             : #endif
     823             :         } else {
     824             :                 DPRINTF(("ohci_init: cold started\n"));
     825             :         reset:
     826             :                 /* Controller was cold started. */
     827           0 :                 usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY);
     828             :         }
     829             : 
     830             :         /*
     831             :          * This reset should not be necessary according to the OHCI spec, but
     832             :          * without it some controllers do not start.
     833             :          */
     834             :         DPRINTF(("%s: resetting\n", sc->sc_bus.bdev.dv_xname));
     835           0 :         OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET | rwc);
     836           0 :         usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY);
     837             : 
     838             :         /* We now own the host controller and the bus has been reset. */
     839             : 
     840           0 :         OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_HCR); /* Reset HC */
     841             :         /* Nominal time for a reset is 10 us. */
     842           0 :         for (i = 0; i < 10; i++) {
     843           0 :                 delay(10);
     844           0 :                 hcr = OREAD4(sc, OHCI_COMMAND_STATUS) & OHCI_HCR;
     845           0 :                 if (!hcr)
     846             :                         break;
     847             :         }
     848           0 :         if (hcr) {
     849           0 :                 printf("%s: reset timeout\n", sc->sc_bus.bdev.dv_xname);
     850             :                 err = USBD_IOERROR;
     851             :                 goto bad5;
     852             :         }
     853             : #ifdef OHCI_DEBUG
     854             :         if (ohcidebug > 15)
     855             :                 ohci_dumpregs(sc);
     856             : #endif
     857             : 
     858             :         /* The controller is now in SUSPEND state, we have 2ms to finish. */
     859             : 
     860             :         /* Set up HC registers. */
     861           0 :         OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma, 0));
     862           0 :         OWRITE4(sc, OHCI_CONTROL_HEAD_ED, sc->sc_ctrl_head->physaddr);
     863           0 :         OWRITE4(sc, OHCI_BULK_HEAD_ED, sc->sc_bulk_head->physaddr);
     864             :         /* disable all interrupts and then switch on all desired interrupts */
     865           0 :         OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
     866             :         /* switch on desired functional features */
     867           0 :         ctl = OREAD4(sc, OHCI_CONTROL);
     868           0 :         ctl &= ~(OHCI_CBSR_MASK | OHCI_LES | OHCI_HCFS_MASK | OHCI_IR);
     869           0 :         ctl |= OHCI_PLE | OHCI_IE | OHCI_CLE | OHCI_BLE |
     870           0 :                 OHCI_RATIO_1_4 | OHCI_HCFS_OPERATIONAL | rwc;
     871             :         /* And finally start it! */
     872           0 :         OWRITE4(sc, OHCI_CONTROL, ctl);
     873             : 
     874             :         /*
     875             :          * The controller is now OPERATIONAL.  Set a some final
     876             :          * registers that should be set earlier, but that the
     877             :          * controller ignores when in the SUSPEND state.
     878             :          */
     879           0 :         ival = OHCI_GET_IVAL(fm);
     880           0 :         fm = (OREAD4(sc, OHCI_FM_REMAINING) & OHCI_FIT) ^ OHCI_FIT;
     881           0 :         fm |= OHCI_FSMPS(ival) | ival;
     882           0 :         OWRITE4(sc, OHCI_FM_INTERVAL, fm);
     883           0 :         per = OHCI_PERIODIC(ival); /* 90% periodic */
     884           0 :         OWRITE4(sc, OHCI_PERIODIC_START, per);
     885             : 
     886             :         /* Fiddle the No OverCurrent Protection bit to avoid chip bug. */
     887           0 :         OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, desca | OHCI_NOCP);
     888           0 :         OWRITE4(sc, OHCI_RH_STATUS, OHCI_LPSC); /* Enable port power */
     889           0 :         usb_delay_ms(&sc->sc_bus, OHCI_ENABLE_POWER_DELAY);
     890           0 :         OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, desca);
     891           0 :         OWRITE4(sc, OHCI_RH_DESCRIPTOR_B, descb);
     892           0 :         usb_delay_ms(&sc->sc_bus, OHCI_GET_POTPGT(desca) * UHD_PWRON_FACTOR);
     893             : 
     894             :         /*
     895             :          * The AMD756 requires a delay before re-reading the register,
     896             :          * otherwise it will occasionally report 0 ports.
     897             :          */
     898           0 :         sc->sc_noport = 0;
     899           0 :         for (i = 0; i < 10 && sc->sc_noport == 0; i++) {
     900           0 :                 usb_delay_ms(&sc->sc_bus, OHCI_READ_DESC_DELAY);
     901           0 :                 sc->sc_noport = OHCI_GET_NDP(OREAD4(sc, OHCI_RH_DESCRIPTOR_A));
     902             :         }
     903             : 
     904             : #ifdef OHCI_DEBUG
     905             :         if (ohcidebug > 5)
     906             :                 ohci_dumpregs(sc);
     907             : #endif
     908             : 
     909             :         /* Set up the bus struct. */
     910           0 :         sc->sc_bus.methods = &ohci_bus_methods;
     911           0 :         sc->sc_bus.pipe_size = sizeof(struct ohci_pipe);
     912             : 
     913           0 :         sc->sc_control = sc->sc_intre = 0;
     914             : 
     915           0 :         timeout_set(&sc->sc_tmo_rhsc, ohci_rhsc_enable, sc);
     916             : 
     917             :         /* Finally, turn on interrupts. */
     918             :         DPRINTFN(1,("ohci_init: enabling\n"));
     919           0 :         OWRITE4(sc, OHCI_INTERRUPT_ENABLE, sc->sc_eintrs | OHCI_MIE);
     920             : 
     921           0 :         return (USBD_NORMAL_COMPLETION);
     922             : 
     923             :  bad5:
     924           0 :         for (i = 0; i < OHCI_NO_EDS; i++)
     925           0 :                 ohci_free_sed(sc, sc->sc_eds[i]);
     926             :  bad4:
     927           0 :         ohci_free_sed(sc, sc->sc_isoc_head);
     928             :  bad3:
     929           0 :         ohci_free_sed(sc, sc->sc_bulk_head);
     930             :  bad2:
     931           0 :         ohci_free_sed(sc, sc->sc_ctrl_head);
     932             :  bad1:
     933           0 :         usb_freemem(&sc->sc_bus, &sc->sc_hccadma);
     934           0 :         return (err);
     935           0 : }
     936             : 
     937             : struct usbd_xfer *
     938           0 : ohci_allocx(struct usbd_bus *bus)
     939             : {
     940           0 :         return (pool_get(ohcixfer, PR_NOWAIT | PR_ZERO));
     941             : }
     942             : 
     943             : void
     944           0 : ohci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer)
     945             : {
     946           0 :         pool_put(ohcixfer, xfer);
     947           0 : }
     948             : 
     949             : #ifdef OHCI_DEBUG
     950             : void
     951             : ohci_dumpregs(struct ohci_softc *sc)
     952             : {
     953             :         DPRINTF(("ohci_dumpregs: rev=0x%08x control=0x%08x command=0x%08x\n",
     954             :                  OREAD4(sc, OHCI_REVISION),
     955             :                  OREAD4(sc, OHCI_CONTROL),
     956             :                  OREAD4(sc, OHCI_COMMAND_STATUS)));
     957             :         DPRINTF(("               intrstat=0x%08x intre=0x%08x intrd=0x%08x\n",
     958             :                  OREAD4(sc, OHCI_INTERRUPT_STATUS),
     959             :                  OREAD4(sc, OHCI_INTERRUPT_ENABLE),
     960             :                  OREAD4(sc, OHCI_INTERRUPT_DISABLE)));
     961             :         DPRINTF(("               hcca=0x%08x percur=0x%08x ctrlhd=0x%08x\n",
     962             :                  OREAD4(sc, OHCI_HCCA),
     963             :                  OREAD4(sc, OHCI_PERIOD_CURRENT_ED),
     964             :                  OREAD4(sc, OHCI_CONTROL_HEAD_ED)));
     965             :         DPRINTF(("               ctrlcur=0x%08x bulkhd=0x%08x bulkcur=0x%08x\n",
     966             :                  OREAD4(sc, OHCI_CONTROL_CURRENT_ED),
     967             :                  OREAD4(sc, OHCI_BULK_HEAD_ED),
     968             :                  OREAD4(sc, OHCI_BULK_CURRENT_ED)));
     969             :         DPRINTF(("               done=0x%08x fmival=0x%08x fmrem=0x%08x\n",
     970             :                  OREAD4(sc, OHCI_DONE_HEAD),
     971             :                  OREAD4(sc, OHCI_FM_INTERVAL),
     972             :                  OREAD4(sc, OHCI_FM_REMAINING)));
     973             :         DPRINTF(("               fmnum=0x%08x perst=0x%08x lsthrs=0x%08x\n",
     974             :                  OREAD4(sc, OHCI_FM_NUMBER),
     975             :                  OREAD4(sc, OHCI_PERIODIC_START),
     976             :                  OREAD4(sc, OHCI_LS_THRESHOLD)));
     977             :         DPRINTF(("               desca=0x%08x descb=0x%08x stat=0x%08x\n",
     978             :                  OREAD4(sc, OHCI_RH_DESCRIPTOR_A),
     979             :                  OREAD4(sc, OHCI_RH_DESCRIPTOR_B),
     980             :                  OREAD4(sc, OHCI_RH_STATUS)));
     981             :         DPRINTF(("               port1=0x%08x port2=0x%08x\n",
     982             :                  OREAD4(sc, OHCI_RH_PORT_STATUS(1)),
     983             :                  OREAD4(sc, OHCI_RH_PORT_STATUS(2))));
     984             :         DPRINTF(("         HCCA: frame_number=0x%04x done_head=0x%08x\n",
     985             :                  letoh32(sc->sc_hcca->hcca_frame_number),
     986             :                  letoh32(sc->sc_hcca->hcca_done_head)));
     987             : }
     988             : #endif
     989             : 
     990             : int ohci_intr1(struct ohci_softc *);
     991             : 
     992             : int
     993           0 : ohci_intr(void *p)
     994             : {
     995           0 :         struct ohci_softc *sc = p;
     996             : 
     997           0 :         if (sc == NULL || sc->sc_bus.dying)
     998           0 :                 return (0);
     999             : 
    1000             :         /* If we get an interrupt while polling, then just ignore it. */
    1001           0 :         if (sc->sc_bus.use_polling) {
    1002             : #ifdef DIAGNOSTIC
    1003             :                 static struct timeval ohci_intr_tv;
    1004           0 :                 if ((OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs) &&
    1005           0 :                     usbd_ratecheck(&ohci_intr_tv))
    1006             :                         DPRINTFN(16,
    1007             :                             ("ohci_intr: ignored interrupt while polling\n"));
    1008             : #endif
    1009           0 :                 return (0);
    1010             :         }
    1011             : 
    1012           0 :         return (ohci_intr1(sc));
    1013           0 : }
    1014             : 
    1015             : int
    1016           0 : ohci_intr1(struct ohci_softc *sc)
    1017             : {
    1018             :         u_int32_t intrs, eintrs;
    1019             :         ohci_physaddr_t done;
    1020             : 
    1021             :         DPRINTFN(14,("ohci_intr1: enter\n"));
    1022             : 
    1023             :         /* In case the interrupt occurs before initialization has completed. */
    1024           0 :         if (sc == NULL || sc->sc_hcca == NULL) {
    1025             : #ifdef DIAGNOSTIC
    1026           0 :                 printf("ohci_intr: sc->sc_hcca == NULL\n");
    1027             : #endif
    1028           0 :                 return (0);
    1029             :         }
    1030             : 
    1031             :         intrs = 0;
    1032           0 :         done = letoh32(sc->sc_hcca->hcca_done_head);
    1033           0 :         if (done != 0) {
    1034           0 :                 if (done & ~OHCI_DONE_INTRS)
    1035           0 :                         intrs = OHCI_WDH;
    1036           0 :                 if (done & OHCI_DONE_INTRS)
    1037           0 :                         intrs |= OREAD4(sc, OHCI_INTERRUPT_STATUS);
    1038           0 :                 sc->sc_hcca->hcca_done_head = 0;
    1039           0 :         } else {
    1040           0 :                 intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS);
    1041             :                 /* If we've flushed out a WDH then reread */
    1042           0 :                 if (intrs & OHCI_WDH) {
    1043           0 :                         done = letoh32(sc->sc_hcca->hcca_done_head);
    1044           0 :                         sc->sc_hcca->hcca_done_head = 0;
    1045           0 :                 }
    1046             :         }
    1047             : 
    1048           0 :         if (intrs == 0xffffffff) {
    1049           0 :                 sc->sc_bus.dying = 1;
    1050           0 :                 return (0);
    1051             :         }
    1052             : 
    1053           0 :         if (!intrs)
    1054           0 :                 return (0);
    1055             : 
    1056           0 :         intrs &= ~OHCI_MIE;
    1057           0 :         OWRITE4(sc, OHCI_INTERRUPT_STATUS, intrs); /* Acknowledge */
    1058           0 :         eintrs = intrs & sc->sc_eintrs;
    1059           0 :         if (!eintrs)
    1060           0 :                 return (0);
    1061             : 
    1062           0 :         sc->sc_bus.intr_context++;
    1063           0 :         sc->sc_bus.no_intrs++;
    1064             :         DPRINTFN(7, ("ohci_intr: sc=%p intrs=0x%x(0x%x) eintrs=0x%x\n",
    1065             :                      sc, (u_int)intrs, OREAD4(sc, OHCI_INTERRUPT_STATUS),
    1066             :                      (u_int)eintrs));
    1067             : 
    1068           0 :         if (eintrs & OHCI_SO) {
    1069           0 :                 sc->sc_overrun_cnt++;
    1070           0 :                 if (usbd_ratecheck(&sc->sc_overrun_ntc)) {
    1071           0 :                         printf("%s: %u scheduling overruns\n",
    1072           0 :                             sc->sc_bus.bdev.dv_xname, sc->sc_overrun_cnt);
    1073           0 :                         sc->sc_overrun_cnt = 0;
    1074           0 :                 }
    1075             :                 /* XXX do what */
    1076           0 :                 eintrs &= ~OHCI_SO;
    1077           0 :         }
    1078           0 :         if (eintrs & OHCI_WDH) {
    1079           0 :                 ohci_add_done(sc, done &~ OHCI_DONE_INTRS);
    1080           0 :                 usb_schedsoftintr(&sc->sc_bus);
    1081           0 :                 eintrs &= ~OHCI_WDH;
    1082           0 :         }
    1083           0 :         if (eintrs & OHCI_RD) {
    1084           0 :                 printf("%s: resume detect\n", sc->sc_bus.bdev.dv_xname);
    1085             :                 /* XXX process resume detect */
    1086           0 :         }
    1087           0 :         if (eintrs & OHCI_UE) {
    1088           0 :                 printf("%s: unrecoverable error, controller halted\n",
    1089           0 :                        sc->sc_bus.bdev.dv_xname);
    1090           0 :                 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
    1091             :                 /* XXX what else */
    1092           0 :         }
    1093           0 :         if (eintrs & OHCI_RHSC) {
    1094           0 :                 ohci_rhsc(sc, sc->sc_intrxfer);
    1095             :                 /*
    1096             :                  * Disable RHSC interrupt for now, because it will be
    1097             :                  * on until the port has been reset.
    1098             :                  */
    1099           0 :                 ohci_rhsc_able(sc, 0);
    1100             :                 DPRINTFN(2, ("%s: rhsc interrupt disabled\n",
    1101             :                              sc->sc_bus.bdev.dv_xname));
    1102             : 
    1103             :                 /* Do not allow RHSC interrupts > 1 per second */
    1104           0 :                 timeout_add_sec(&sc->sc_tmo_rhsc, 1);
    1105           0 :                 eintrs &= ~OHCI_RHSC;
    1106           0 :         }
    1107             : 
    1108           0 :         sc->sc_bus.intr_context--;
    1109             : 
    1110           0 :         if (eintrs != 0) {
    1111             :                 /* Block unprocessed interrupts. XXX */
    1112           0 :                 OWRITE4(sc, OHCI_INTERRUPT_DISABLE, eintrs);
    1113           0 :                 sc->sc_eintrs &= ~eintrs;
    1114           0 :                 printf("%s: blocking intrs 0x%x\n",
    1115           0 :                        sc->sc_bus.bdev.dv_xname, eintrs);
    1116           0 :         }
    1117             : 
    1118           0 :         return (1);
    1119           0 : }
    1120             : 
    1121             : void
    1122           0 : ohci_rhsc_able(struct ohci_softc *sc, int on)
    1123             : {
    1124             :         DPRINTFN(4, ("ohci_rhsc_able: on=%d\n", on));
    1125           0 :         if (on) {
    1126           0 :                 sc->sc_eintrs |= OHCI_RHSC;
    1127           0 :                 OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_RHSC);
    1128           0 :         } else {
    1129           0 :                 sc->sc_eintrs &= ~OHCI_RHSC;
    1130           0 :                 OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_RHSC);
    1131             :         }
    1132           0 : }
    1133             : 
    1134             : void
    1135           0 : ohci_rhsc_enable(void *v_sc)
    1136             : {
    1137           0 :         struct ohci_softc *sc = v_sc;
    1138             :         int s;
    1139             : 
    1140           0 :         if (sc->sc_bus.dying)
    1141           0 :                 return;
    1142             : 
    1143           0 :         s = splhardusb();
    1144           0 :         ohci_rhsc(sc, sc->sc_intrxfer);
    1145             :         DPRINTFN(2, ("%s: rhsc interrupt enabled\n",
    1146             :                      sc->sc_bus.bdev.dv_xname));
    1147             : 
    1148           0 :         ohci_rhsc_able(sc, 1);
    1149           0 :         splx(s);
    1150           0 : }
    1151             : 
    1152             : #ifdef OHCI_DEBUG
    1153             : char *ohci_cc_strs[] = {
    1154             :         "NO_ERROR",
    1155             :         "CRC",
    1156             :         "BIT_STUFFING",
    1157             :         "DATA_TOGGLE_MISMATCH",
    1158             :         "STALL",
    1159             :         "DEVICE_NOT_RESPONDING",
    1160             :         "PID_CHECK_FAILURE",
    1161             :         "UNEXPECTED_PID",
    1162             :         "DATA_OVERRUN",
    1163             :         "DATA_UNDERRUN",
    1164             :         "BUFFER_OVERRUN",
    1165             :         "BUFFER_UNDERRUN",
    1166             :         "reserved",
    1167             :         "reserved",
    1168             :         "NOT_ACCESSED",
    1169             :         "NOT_ACCESSED",
    1170             : };
    1171             : #endif
    1172             : 
    1173             : void
    1174           0 : ohci_add_done(struct ohci_softc *sc, ohci_physaddr_t done)
    1175             : {
    1176             :         struct ohci_soft_itd *sitd, *sidone, **ip;
    1177             :         struct ohci_soft_td *std, *sdone, **p;
    1178             : 
    1179             :         /* Reverse the done list. */
    1180           0 :         for (sdone = NULL, sidone = NULL; done != 0; ) {
    1181           0 :                 std = ohci_hash_find_td(sc, done);
    1182           0 :                 if (std != NULL) {
    1183           0 :                         std->dnext = sdone;
    1184           0 :                         done = letoh32(std->td.td_nexttd);
    1185             :                         sdone = std;
    1186             :                         DPRINTFN(10,("add TD %p\n", std));
    1187           0 :                         continue;
    1188             :                 }
    1189           0 :                 sitd = ohci_hash_find_itd(sc, done);
    1190           0 :                 if (sitd != NULL) {
    1191           0 :                         sitd->dnext = sidone;
    1192           0 :                         done = letoh32(sitd->itd.itd_nextitd);
    1193             :                         sidone = sitd;
    1194             :                         DPRINTFN(5,("add ITD %p\n", sitd));
    1195           0 :                         continue;
    1196             :                 }
    1197           0 :                 panic("ohci_add_done: addr 0x%08lx not found", (u_long)done);
    1198             :         }
    1199             : 
    1200             :         /* sdone & sidone now hold the done lists. */
    1201             :         /* Put them on the already processed lists. */
    1202           0 :         for (p = &sc->sc_sdone; *p != NULL; p = &(*p)->dnext)
    1203             :                 ;
    1204           0 :         *p = sdone;
    1205           0 :         for (ip = &sc->sc_sidone; *ip != NULL; ip = &(*ip)->dnext)
    1206             :                 ;
    1207           0 :         *ip = sidone;
    1208           0 : }
    1209             : 
    1210             : void
    1211           0 : ohci_softintr(void *v)
    1212             : {
    1213           0 :         struct ohci_softc *sc = v;
    1214             :         struct ohci_soft_itd *sitd, *sidone, *sitdnext;
    1215             :         struct ohci_soft_td *std, *sdone, *stdnext;
    1216             :         struct usbd_xfer *xfer;
    1217             :         struct ohci_pipe *opipe;
    1218             :         int len, cc, s;
    1219             :         int i, j, actlen, iframes, uedir;
    1220             : 
    1221             :         DPRINTFN(10,("ohci_softintr: enter\n"));
    1222             : 
    1223           0 :         if (sc->sc_bus.dying)
    1224           0 :                 return;
    1225             : 
    1226           0 :         sc->sc_bus.intr_context++;
    1227             : 
    1228           0 :         s = splhardusb();
    1229           0 :         sdone = sc->sc_sdone;
    1230           0 :         sc->sc_sdone = NULL;
    1231           0 :         sidone = sc->sc_sidone;
    1232           0 :         sc->sc_sidone = NULL;
    1233           0 :         splx(s);
    1234             : 
    1235             :         DPRINTFN(10,("ohci_softintr: sdone=%p sidone=%p\n", sdone, sidone));
    1236             : 
    1237             : #ifdef OHCI_DEBUG
    1238             :         if (ohcidebug > 10) {
    1239             :                 DPRINTF(("ohci_process_done: TD done:\n"));
    1240             :                 ohci_dump_tds(sdone);
    1241             :         }
    1242             : #endif
    1243             : 
    1244           0 :         for (std = sdone; std; std = stdnext) {
    1245           0 :                 xfer = std->xfer;
    1246           0 :                 stdnext = std->dnext;
    1247             :                 DPRINTFN(10, ("ohci_process_done: std=%p xfer=%p hcpriv=%p\n",
    1248             :                                 std, xfer, xfer ? xfer->hcpriv : 0));
    1249           0 :                 if (xfer == NULL) {
    1250             :                         /*
    1251             :                          * xfer == NULL: There seems to be no xfer associated
    1252             :                          * with this TD. It is tailp that happened to end up on
    1253             :                          * the done queue.
    1254             :                          * Shouldn't happen, but some chips are broken(?).
    1255             :                          */
    1256             :                         continue;
    1257             :                 }
    1258           0 :                 if (xfer->status == USBD_CANCELLED ||
    1259           0 :                     xfer->status == USBD_TIMEOUT) {
    1260             :                         DPRINTF(("ohci_process_done: cancel/timeout %p\n",
    1261             :                                  xfer));
    1262             :                         /* Handled by abort routine. */
    1263             :                         continue;
    1264             :                 }
    1265           0 :                 timeout_del(&xfer->timeout_handle);
    1266           0 :                 usb_rem_task(xfer->device, &xfer->abort_task);
    1267             : 
    1268           0 :                 len = std->len;
    1269           0 :                 if (std->td.td_cbp != 0)
    1270           0 :                         len -= letoh32(std->td.td_be) -
    1271           0 :                             letoh32(std->td.td_cbp) + 1;
    1272             :                 DPRINTFN(10, ("ohci_process_done: len=%d, flags=0x%x\n", len,
    1273             :                     std->flags));
    1274           0 :                 if (std->flags & OHCI_ADD_LEN)
    1275           0 :                         xfer->actlen += len;
    1276             : 
    1277           0 :                 cc = OHCI_TD_GET_CC(letoh32(std->td.td_flags));
    1278           0 :                 if (cc == OHCI_CC_NO_ERROR) {
    1279           0 :                         int done = (std->flags & OHCI_CALL_DONE);
    1280             : 
    1281           0 :                         ohci_free_std(sc, std);
    1282           0 :                         if (done) {
    1283           0 :                                 xfer->status = USBD_NORMAL_COMPLETION;
    1284           0 :                                 s = splusb();
    1285           0 :                                 usb_transfer_complete(xfer);
    1286           0 :                                 splx(s);
    1287           0 :                         }
    1288           0 :                 } else {
    1289             :                         /*
    1290             :                          * Endpoint is halted.  First unlink all the TDs
    1291             :                          * belonging to the failed transfer, and then restart
    1292             :                          * the endpoint.
    1293             :                          */
    1294             :                         struct ohci_soft_td *p, *n;
    1295           0 :                         opipe = (struct ohci_pipe *)xfer->pipe;
    1296             : 
    1297             :                         DPRINTFN(15,("ohci_process_done: error cc=%d (%s)\n",
    1298             :                           OHCI_TD_GET_CC(letoh32(std->td.td_flags)),
    1299             :                           ohci_cc_strs[OHCI_TD_GET_CC(letoh32(std->td.td_flags))]));
    1300             : 
    1301             :                         /* remove TDs */
    1302           0 :                         for (p = std; p->xfer == xfer; p = n) {
    1303           0 :                                 n = p->nexttd;
    1304           0 :                                 ohci_free_std(sc, p);
    1305             :                         }
    1306             : 
    1307             :                         /* clear halt */
    1308           0 :                         opipe->sed->ed.ed_headp = htole32(p->physaddr);
    1309           0 :                         OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
    1310             : 
    1311           0 :                         if (cc == OHCI_CC_STALL)
    1312           0 :                                 xfer->status = USBD_STALLED;
    1313           0 :                         else if (cc == OHCI_CC_DATA_UNDERRUN)
    1314           0 :                                 xfer->status = USBD_NORMAL_COMPLETION;
    1315             :                         else
    1316           0 :                                 xfer->status = USBD_IOERROR;
    1317           0 :                         s = splusb();
    1318           0 :                         usb_transfer_complete(xfer);
    1319           0 :                         splx(s);
    1320             :                 }
    1321             :         }
    1322             : 
    1323             : #ifdef OHCI_DEBUG
    1324             :         if (ohcidebug > 10) {
    1325             :                 DPRINTF(("ohci_softintr: ITD done:\n"));
    1326             :                 ohci_dump_itds(sidone);
    1327             :         }
    1328             : #endif
    1329             : 
    1330           0 :         for (sitd = sidone; sitd != NULL; sitd = sitdnext) {
    1331           0 :                 xfer = sitd->xfer;
    1332           0 :                 sitdnext = sitd->dnext;
    1333             :                 DPRINTFN(1, ("ohci_process_done: sitd=%p xfer=%p hcpriv=%p\n",
    1334             :                              sitd, xfer, xfer ? xfer->hcpriv : 0));
    1335           0 :                 if (xfer == NULL)
    1336             :                         continue;
    1337           0 :                 if (xfer->status == USBD_CANCELLED ||
    1338           0 :                     xfer->status == USBD_TIMEOUT) {
    1339             :                         DPRINTF(("ohci_process_done: cancel/timeout %p\n",
    1340             :                                  xfer));
    1341             :                         /* Handled by abort routine. */
    1342             :                         continue;
    1343             :                 }
    1344             : #ifdef DIAGNOSTIC
    1345           0 :                 if (sitd->isdone)
    1346           0 :                         printf("ohci_softintr: sitd=%p is done\n", sitd);
    1347           0 :                 sitd->isdone = 1;
    1348             : #endif
    1349           0 :                 if (sitd->flags & OHCI_CALL_DONE) {
    1350             :                         struct ohci_soft_itd *next;
    1351             : 
    1352           0 :                         opipe = (struct ohci_pipe *)xfer->pipe;
    1353           0 :                         opipe->u.iso.inuse -= xfer->nframes;
    1354           0 :                         uedir = UE_GET_DIR(xfer->pipe->endpoint->edesc->
    1355             :                             bEndpointAddress);
    1356           0 :                         xfer->status = USBD_NORMAL_COMPLETION;
    1357             :                         actlen = 0;
    1358           0 :                         for (i = 0, sitd = xfer->hcpriv; ;
    1359             :                             sitd = next) {
    1360           0 :                                 next = sitd->nextitd;
    1361           0 :                                 if (OHCI_ITD_GET_CC(letoh32(sitd->
    1362           0 :                                     itd.itd_flags)) != OHCI_CC_NO_ERROR)
    1363           0 :                                         xfer->status = USBD_IOERROR;
    1364             :                                 /* For input, update frlengths with actual */
    1365             :                                 /* XXX anything necessary for output? */
    1366           0 :                                 if (uedir == UE_DIR_IN &&
    1367           0 :                                     xfer->status == USBD_NORMAL_COMPLETION) {
    1368           0 :                                         iframes = OHCI_ITD_GET_FC(letoh32(
    1369             :                                             sitd->itd.itd_flags));
    1370           0 :                                         for (j = 0; j < iframes; i++, j++) {
    1371           0 :                                                 len = letoh16(sitd->
    1372             :                                                     itd.itd_offset[j]);
    1373           0 :                                                 if ((OHCI_ITD_PSW_GET_CC(len) &
    1374             :                                                     OHCI_CC_NOT_ACCESSED_MASK)
    1375           0 :                                                     == OHCI_CC_NOT_ACCESSED)
    1376           0 :                                                         len = 0;
    1377             :                                                 else
    1378           0 :                                                         len = OHCI_ITD_PSW_LENGTH(len);
    1379           0 :                                                 xfer->frlengths[i] = len;
    1380           0 :                                                 actlen += len;
    1381             :                                         }
    1382             :                                 }
    1383           0 :                                 if (sitd->flags & OHCI_CALL_DONE)
    1384             :                                         break;
    1385             :                                 ohci_free_sitd(sc, sitd);
    1386             :                         }
    1387             :                         ohci_free_sitd(sc, sitd);
    1388           0 :                         if (uedir == UE_DIR_IN &&
    1389           0 :                             xfer->status == USBD_NORMAL_COMPLETION)
    1390           0 :                                 xfer->actlen = actlen;
    1391           0 :                         xfer->hcpriv = NULL;
    1392             : 
    1393           0 :                         s = splusb();
    1394           0 :                         usb_transfer_complete(xfer);
    1395           0 :                         splx(s);
    1396           0 :                 }
    1397             :         }
    1398             : 
    1399           0 :         if (sc->sc_softwake) {
    1400           0 :                 sc->sc_softwake = 0;
    1401           0 :                 wakeup(&sc->sc_softwake);
    1402           0 :         }
    1403             : 
    1404           0 :         sc->sc_bus.intr_context--;
    1405             :         DPRINTFN(10,("ohci_softintr: done:\n"));
    1406           0 : }
    1407             : 
    1408             : void
    1409           0 : ohci_device_ctrl_done(struct usbd_xfer *xfer)
    1410             : {
    1411             :         DPRINTFN(10,("ohci_device_ctrl_done: xfer=%p\n", xfer));
    1412             : 
    1413             : #ifdef DIAGNOSTIC
    1414           0 :         if (!(xfer->rqflags & URQ_REQUEST)) {
    1415           0 :                 panic("ohci_device_ctrl_done: not a request");
    1416             :         }
    1417             : #endif
    1418           0 : }
    1419             : 
    1420             : void
    1421           0 : ohci_device_intr_done(struct usbd_xfer *xfer)
    1422             : {
    1423           0 :         struct ohci_softc *sc = (struct ohci_softc *)xfer->device->bus;
    1424           0 :         struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
    1425           0 :         struct ohci_soft_ed *sed = opipe->sed;
    1426             :         struct ohci_soft_td *data, *tail;
    1427             : 
    1428             : 
    1429             :         DPRINTFN(10, ("ohci_device_intr_done: xfer=%p, actlen=%d\n", xfer,
    1430             :             xfer->actlen));
    1431             : 
    1432           0 :         if (xfer->pipe->repeat) {
    1433           0 :                 data = opipe->tail.td;
    1434           0 :                 tail = ohci_alloc_std(sc);
    1435           0 :                 if (tail == NULL) {
    1436           0 :                         xfer->status = USBD_NOMEM;
    1437           0 :                         return;
    1438             :                 }
    1439           0 :                 tail->xfer = NULL;
    1440             : 
    1441           0 :                 data->td.td_flags = htole32(
    1442             :                         OHCI_TD_IN | OHCI_TD_NOCC |
    1443             :                         OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY);
    1444           0 :                 if (xfer->flags & USBD_SHORT_XFER_OK)
    1445           0 :                         data->td.td_flags |= htole32(OHCI_TD_R);
    1446           0 :                 data->td.td_cbp = htole32(DMAADDR(&xfer->dmabuf, 0));
    1447           0 :                 data->nexttd = tail;
    1448           0 :                 data->td.td_nexttd = htole32(tail->physaddr);
    1449           0 :                 data->td.td_be = htole32(letoh32(data->td.td_cbp) +
    1450             :                         xfer->length - 1);
    1451           0 :                 data->len = xfer->length;
    1452           0 :                 data->xfer = xfer;
    1453           0 :                 data->flags = OHCI_CALL_DONE | OHCI_ADD_LEN;
    1454           0 :                 xfer->hcpriv = data;
    1455           0 :                 xfer->actlen = 0;
    1456             : 
    1457           0 :                 sed->ed.ed_tailp = htole32(tail->physaddr);
    1458           0 :                 opipe->tail.td = tail;
    1459           0 :         }
    1460           0 : }
    1461             : 
    1462             : void
    1463           0 : ohci_device_bulk_done(struct usbd_xfer *xfer)
    1464             : {
    1465             :         DPRINTFN(10, ("ohci_device_bulk_done: xfer=%p, actlen=%d\n", xfer,
    1466             :             xfer->actlen));
    1467           0 : }
    1468             : 
    1469             : void
    1470           0 : ohci_rhsc(struct ohci_softc *sc, struct usbd_xfer *xfer)
    1471             : {
    1472             :         u_char *p;
    1473             :         int i, m;
    1474             :         int hstatus;
    1475             : 
    1476           0 :         hstatus = OREAD4(sc, OHCI_RH_STATUS);
    1477             :         DPRINTF(("ohci_rhsc: sc=%p xfer=%p hstatus=0x%08x\n",
    1478             :                  sc, xfer, hstatus));
    1479             : 
    1480           0 :         if (xfer == NULL) {
    1481             :                 /* Just ignore the change. */
    1482           0 :                 return;
    1483             :         }
    1484             : 
    1485           0 :         p = KERNADDR(&xfer->dmabuf, 0);
    1486           0 :         m = min(sc->sc_noport, xfer->length * 8 - 1);
    1487           0 :         memset(p, 0, xfer->length);
    1488           0 :         for (i = 1; i <= m; i++) {
    1489             :                 /* Pick out CHANGE bits from the status reg. */
    1490           0 :                 if (OREAD4(sc, OHCI_RH_PORT_STATUS(i)) >> 16)
    1491           0 :                         p[i/8] |= 1 << (i%8);
    1492             :         }
    1493             :         DPRINTF(("ohci_rhsc: change=0x%02x\n", *p));
    1494           0 :         xfer->actlen = xfer->length;
    1495           0 :         xfer->status = USBD_NORMAL_COMPLETION;
    1496             : 
    1497           0 :         usb_transfer_complete(xfer);
    1498           0 : }
    1499             : 
    1500             : void
    1501           0 : ohci_root_intr_done(struct usbd_xfer *xfer)
    1502             : {
    1503           0 : }
    1504             : 
    1505             : void
    1506           0 : ohci_root_ctrl_done(struct usbd_xfer *xfer)
    1507             : {
    1508           0 : }
    1509             : 
    1510             : void
    1511           0 : ohci_poll(struct usbd_bus *bus)
    1512             : {
    1513           0 :         struct ohci_softc *sc = (struct ohci_softc *)bus;
    1514             : #ifdef OHCI_DEBUG
    1515             :         static int last;
    1516             :         int new;
    1517             :         new = OREAD4(sc, OHCI_INTERRUPT_STATUS);
    1518             :         if (new != last) {
    1519             :                 DPRINTFN(10,("ohci_poll: intrs=0x%04x\n", new));
    1520             :                 last = new;
    1521             :         }
    1522             : #endif
    1523             : 
    1524           0 :         if (OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs)
    1525           0 :                 ohci_intr1(sc);
    1526           0 : }
    1527             : 
    1528             : usbd_status
    1529           0 : ohci_device_request(struct usbd_xfer *xfer)
    1530             : {
    1531           0 :         struct ohci_softc *sc = (struct ohci_softc *)xfer->device->bus;
    1532           0 :         struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
    1533           0 :         usb_device_request_t *req = &xfer->request;
    1534           0 :         struct ohci_soft_td *setup, *stat, *next, *tail;
    1535             :         struct ohci_soft_ed *sed;
    1536             :         u_int len;
    1537             :         usbd_status err;
    1538             :         int s;
    1539             : 
    1540           0 :         len = UGETW(req->wLength);
    1541             : 
    1542             :         DPRINTFN(3,("ohci_device_control type=0x%02x, request=0x%02x, "
    1543             :                     "wValue=0x%04x, wIndex=0x%04x len=%u, addr=%d, endpt=%d\n",
    1544             :                     req->bmRequestType, req->bRequest, UGETW(req->wValue),
    1545             :                     UGETW(req->wIndex), len, xfer->device->address,
    1546             :                     xfer->pipe->endpoint->edesc->bEndpointAddress));
    1547             : 
    1548           0 :         setup = opipe->tail.td;
    1549           0 :         stat = ohci_alloc_std(sc);
    1550           0 :         if (stat == NULL) {
    1551             :                 err = USBD_NOMEM;
    1552           0 :                 goto bad1;
    1553             :         }
    1554           0 :         tail = ohci_alloc_std(sc);
    1555           0 :         if (tail == NULL) {
    1556             :                 err = USBD_NOMEM;
    1557           0 :                 goto bad2;
    1558             :         }
    1559           0 :         tail->xfer = NULL;
    1560             : 
    1561           0 :         sed = opipe->sed;
    1562             : 
    1563           0 :         next = stat;
    1564             : 
    1565             :         /* Set up data transaction */
    1566           0 :         if (len != 0) {
    1567             :                 struct ohci_soft_td *std = stat;
    1568             : 
    1569           0 :                 err = ohci_alloc_std_chain(sc, len, xfer, std, &stat);
    1570           0 :                 stat = stat->nexttd; /* point at free TD */
    1571           0 :                 if (err)
    1572           0 :                         goto bad3;
    1573             :                 /* Start toggle at 1 and then use the carried toggle. */
    1574           0 :                 std->td.td_flags &= htole32(~OHCI_TD_TOGGLE_MASK);
    1575           0 :                 std->td.td_flags |= htole32(OHCI_TD_TOGGLE_1);
    1576           0 :         }
    1577             : 
    1578           0 :         memcpy(KERNADDR(&opipe->u.ctl.reqdma, 0), req, sizeof *req);
    1579             : 
    1580           0 :         setup->td.td_flags = htole32(OHCI_TD_SETUP | OHCI_TD_NOCC |
    1581             :                                      OHCI_TD_TOGGLE_0 | OHCI_TD_NOINTR);
    1582           0 :         setup->td.td_cbp = htole32(DMAADDR(&opipe->u.ctl.reqdma, 0));
    1583           0 :         setup->nexttd = next;
    1584           0 :         setup->td.td_nexttd = htole32(next->physaddr);
    1585           0 :         setup->td.td_be = htole32(letoh32(setup->td.td_cbp) + sizeof *req - 1);
    1586           0 :         setup->len = 0;
    1587           0 :         setup->xfer = xfer;
    1588           0 :         setup->flags = 0;
    1589           0 :         xfer->hcpriv = setup;
    1590             : 
    1591           0 :         stat->td.td_flags = htole32(
    1592             :                 (usbd_xfer_isread(xfer) ? OHCI_TD_OUT : OHCI_TD_IN) |
    1593             :                 OHCI_TD_NOCC | OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DI(1));
    1594           0 :         stat->td.td_cbp = 0;
    1595           0 :         stat->nexttd = tail;
    1596           0 :         stat->td.td_nexttd = htole32(tail->physaddr);
    1597           0 :         stat->td.td_be = 0;
    1598           0 :         stat->flags = OHCI_CALL_DONE;
    1599           0 :         stat->len = 0;
    1600           0 :         stat->xfer = xfer;
    1601             : 
    1602             : #ifdef OHCI_DEBUG
    1603             :         if (ohcidebug > 5) {
    1604             :                 DPRINTF(("ohci_device_request:\n"));
    1605             :                 ohci_dump_ed(sed);
    1606             :                 ohci_dump_tds(setup);
    1607             :         }
    1608             : #endif
    1609             : 
    1610             :         /* Insert ED in schedule */
    1611           0 :         s = splusb();
    1612           0 :         sed->ed.ed_tailp = htole32(tail->physaddr);
    1613           0 :         opipe->tail.td = tail;
    1614           0 :         OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
    1615           0 :         if (xfer->timeout && !sc->sc_bus.use_polling) {
    1616           0 :                 timeout_del(&xfer->timeout_handle);
    1617           0 :                 timeout_set(&xfer->timeout_handle, ohci_timeout, xfer);
    1618           0 :                 timeout_add_msec(&xfer->timeout_handle, xfer->timeout);
    1619           0 :         }
    1620           0 :         splx(s);
    1621             : 
    1622             : #ifdef OHCI_DEBUG
    1623             :         if (ohcidebug > 20) {
    1624             :                 delay(10000);
    1625             :                 DPRINTF(("ohci_device_request: status=%x\n",
    1626             :                          OREAD4(sc, OHCI_COMMAND_STATUS)));
    1627             :                 ohci_dumpregs(sc);
    1628             :                 printf("ctrl head:\n");
    1629             :                 ohci_dump_ed(sc->sc_ctrl_head);
    1630             :                 printf("sed:\n");
    1631             :                 ohci_dump_ed(sed);
    1632             :                 ohci_dump_tds(setup);
    1633             :         }
    1634             : #endif
    1635             : 
    1636           0 :         return (USBD_NORMAL_COMPLETION);
    1637             : 
    1638             :  bad3:
    1639           0 :         ohci_free_std(sc, tail);
    1640             :  bad2:
    1641           0 :         ohci_free_std(sc, stat);
    1642             :  bad1:
    1643           0 :         return (err);
    1644           0 : }
    1645             : 
    1646             : /*
    1647             :  * Add an ED to the schedule.  Called at splusb().
    1648             :  */
    1649             : void
    1650           0 : ohci_add_ed(struct ohci_soft_ed *sed, struct ohci_soft_ed *head)
    1651             : {
    1652             :         DPRINTFN(8,("ohci_add_ed: sed=%p head=%p\n", sed, head));
    1653             : 
    1654           0 :         splsoftassert(IPL_SOFTUSB);
    1655           0 :         sed->next = head->next;
    1656           0 :         sed->ed.ed_nexted = head->ed.ed_nexted;
    1657           0 :         head->next = sed;
    1658           0 :         head->ed.ed_nexted = htole32(sed->physaddr);
    1659           0 : }
    1660             : 
    1661             : /*
    1662             :  * Remove an ED from the schedule.  Called at splusb().
    1663             :  */
    1664             : void
    1665           0 : ohci_rem_ed(struct ohci_soft_ed *sed, struct ohci_soft_ed *head)
    1666             : {
    1667             :         struct ohci_soft_ed *p;
    1668             : 
    1669           0 :         splsoftassert(IPL_SOFTUSB);
    1670             : 
    1671             :         /* XXX */
    1672           0 :         for (p = head; p != NULL && p->next != sed; p = p->next)
    1673             :                 ;
    1674           0 :         if (p == NULL)
    1675           0 :                 panic("ohci_rem_ed: ED not found");
    1676           0 :         p->next = sed->next;
    1677           0 :         p->ed.ed_nexted = sed->ed.ed_nexted;
    1678           0 : }
    1679             : 
    1680             : /*
    1681             :  * When a transfer is completed the TD is added to the done queue by
    1682             :  * the host controller.  This queue is the processed by software.
    1683             :  * Unfortunately the queue contains the physical address of the TD
    1684             :  * and we have no simple way to translate this back to a kernel address.
    1685             :  * To make the translation possible (and fast) we use a hash table of
    1686             :  * TDs currently in the schedule.  The physical address is used as the
    1687             :  * hash value.
    1688             :  */
    1689             : 
    1690             : #define HASH(a) (((a) >> 4) % OHCI_HASH_SIZE)
    1691             : /* Called at splusb() */
    1692             : void
    1693           0 : ohci_hash_add_td(struct ohci_softc *sc, struct ohci_soft_td *std)
    1694             : {
    1695           0 :         int h = HASH(std->physaddr);
    1696             : 
    1697           0 :         splsoftassert(IPL_SOFTUSB);
    1698             : 
    1699           0 :         LIST_INSERT_HEAD(&sc->sc_hash_tds[h], std, hnext);
    1700           0 : }
    1701             : 
    1702             : struct ohci_soft_td *
    1703           0 : ohci_hash_find_td(struct ohci_softc *sc, ohci_physaddr_t a)
    1704             : {
    1705           0 :         int h = HASH(a);
    1706             :         struct ohci_soft_td *std;
    1707             : 
    1708           0 :         for (std = LIST_FIRST(&sc->sc_hash_tds[h]);
    1709           0 :              std != NULL;
    1710           0 :              std = LIST_NEXT(std, hnext))
    1711           0 :                 if (std->physaddr == a)
    1712           0 :                         return (std);
    1713           0 :         return (NULL);
    1714           0 : }
    1715             : 
    1716             : /* Called at splusb() */
    1717             : void
    1718           0 : ohci_hash_add_itd(struct ohci_softc *sc, struct ohci_soft_itd *sitd)
    1719             : {
    1720           0 :         int h = HASH(sitd->physaddr);
    1721             : 
    1722           0 :         splsoftassert(IPL_SOFTUSB);
    1723             : 
    1724             :         DPRINTFN(10,("ohci_hash_add_itd: sitd=%p physaddr=0x%08lx\n",
    1725             :                     sitd, (u_long)sitd->physaddr));
    1726             : 
    1727           0 :         LIST_INSERT_HEAD(&sc->sc_hash_itds[h], sitd, hnext);
    1728           0 : }
    1729             : 
    1730             : /* Called at splusb() */
    1731             : void
    1732           0 : ohci_hash_rem_itd(struct ohci_softc *sc, struct ohci_soft_itd *sitd)
    1733             : {
    1734           0 :         splsoftassert(IPL_SOFTUSB);
    1735             : 
    1736             :         DPRINTFN(10,("ohci_hash_rem_itd: sitd=%p physaddr=0x%08lx\n",
    1737             :                     sitd, (u_long)sitd->physaddr));
    1738             : 
    1739           0 :         LIST_REMOVE(sitd, hnext);
    1740           0 : }
    1741             : 
    1742             : struct ohci_soft_itd *
    1743           0 : ohci_hash_find_itd(struct ohci_softc *sc, ohci_physaddr_t a)
    1744             : {
    1745           0 :         int h = HASH(a);
    1746             :         struct ohci_soft_itd *sitd;
    1747             : 
    1748           0 :         for (sitd = LIST_FIRST(&sc->sc_hash_itds[h]);
    1749           0 :              sitd != NULL;
    1750           0 :              sitd = LIST_NEXT(sitd, hnext))
    1751           0 :                 if (sitd->physaddr == a)
    1752           0 :                         return (sitd);
    1753           0 :         return (NULL);
    1754           0 : }
    1755             : 
    1756             : void
    1757           0 : ohci_timeout(void *addr)
    1758             : {
    1759           0 :         struct usbd_xfer *xfer = addr;
    1760           0 :         struct ohci_softc *sc = (struct ohci_softc *)xfer->device->bus;
    1761             : 
    1762           0 :         if (sc->sc_bus.dying) {
    1763           0 :                 ohci_timeout_task(addr);
    1764           0 :                 return;
    1765             :         }
    1766             : 
    1767           0 :         usb_init_task(&xfer->abort_task, ohci_timeout_task, addr,
    1768             :             USB_TASK_TYPE_ABORT);
    1769           0 :         usb_add_task(xfer->device, &xfer->abort_task);
    1770           0 : }
    1771             : 
    1772             : void
    1773           0 : ohci_timeout_task(void *addr)
    1774             : {
    1775           0 :         struct usbd_xfer *xfer = addr;
    1776             :         int s;
    1777             : 
    1778             :         DPRINTF(("%s: xfer=%p\n", __func__, xfer));
    1779             : 
    1780           0 :         s = splusb();
    1781           0 :         ohci_abort_xfer(xfer, USBD_TIMEOUT);
    1782           0 :         splx(s);
    1783           0 : }
    1784             : 
    1785             : #ifdef OHCI_DEBUG
    1786             : void
    1787             : ohci_dump_tds(struct ohci_soft_td *std)
    1788             : {
    1789             :         for (; std; std = std->nexttd)
    1790             :                 ohci_dump_td(std);
    1791             : }
    1792             : 
    1793             : void
    1794             : ohci_dump_td(struct ohci_soft_td *std)
    1795             : {
    1796             :         char sbuf[128];
    1797             : 
    1798             :         bitmask_snprintf((u_int32_t)letoh32(std->td.td_flags),
    1799             :                          "\20\23R\24OUT\25IN\31TOG1\32SETTOGGLE",
    1800             :                          sbuf, sizeof(sbuf));
    1801             : 
    1802             :         printf("TD(%p) at %08lx: %s delay=%d ec=%d cc=%d\ncbp=0x%08lx "
    1803             :                "nexttd=0x%08lx be=0x%08lx\n",
    1804             :                std, (u_long)std->physaddr, sbuf,
    1805             :                OHCI_TD_GET_DI(letoh32(std->td.td_flags)),
    1806             :                OHCI_TD_GET_EC(letoh32(std->td.td_flags)),
    1807             :                OHCI_TD_GET_CC(letoh32(std->td.td_flags)),
    1808             :                (u_long)letoh32(std->td.td_cbp),
    1809             :                (u_long)letoh32(std->td.td_nexttd),
    1810             :                (u_long)letoh32(std->td.td_be));
    1811             : }
    1812             : 
    1813             : void
    1814             : ohci_dump_itd(struct ohci_soft_itd *sitd)
    1815             : {
    1816             :         int i;
    1817             : 
    1818             :         printf("ITD(%p) at %08lx: sf=%d di=%d fc=%d cc=%d\n"
    1819             :                "bp0=0x%08lx next=0x%08lx be=0x%08lx\n",
    1820             :                sitd, (u_long)sitd->physaddr,
    1821             :                OHCI_ITD_GET_SF(letoh32(sitd->itd.itd_flags)),
    1822             :                OHCI_ITD_GET_DI(letoh32(sitd->itd.itd_flags)),
    1823             :                OHCI_ITD_GET_FC(letoh32(sitd->itd.itd_flags)),
    1824             :                OHCI_ITD_GET_CC(letoh32(sitd->itd.itd_flags)),
    1825             :                (u_long)letoh32(sitd->itd.itd_bp0),
    1826             :                (u_long)letoh32(sitd->itd.itd_nextitd),
    1827             :                (u_long)letoh32(sitd->itd.itd_be));
    1828             :         for (i = 0; i < OHCI_ITD_NOFFSET; i++)
    1829             :                 printf("offs[%d]=0x%04x ", i,
    1830             :                        (u_int)letoh16(sitd->itd.itd_offset[i]));
    1831             :         printf("\n");
    1832             : }
    1833             : 
    1834             : void
    1835             : ohci_dump_itds(struct ohci_soft_itd *sitd)
    1836             : {
    1837             :         for (; sitd; sitd = sitd->nextitd)
    1838             :                 ohci_dump_itd(sitd);
    1839             : }
    1840             : 
    1841             : void
    1842             : ohci_dump_ed(struct ohci_soft_ed *sed)
    1843             : {
    1844             :         char sbuf[128], sbuf2[128];
    1845             : 
    1846             :         bitmask_snprintf((u_int32_t)letoh32(sed->ed.ed_flags),
    1847             :                          "\20\14OUT\15IN\16LOWSPEED\17SKIP\20ISO",
    1848             :                          sbuf, sizeof(sbuf));
    1849             :         bitmask_snprintf((u_int32_t)letoh32(sed->ed.ed_headp),
    1850             :                          "\20\1HALT\2CARRY", sbuf2, sizeof(sbuf2));
    1851             : 
    1852             :         printf("ED(%p) at 0x%08lx: addr=%d endpt=%d maxp=%d flags=%s\n"
    1853             :                "tailp=0x%08lx headflags=%s headp=0x%08lx nexted=0x%08lx\n",
    1854             :                sed, (u_long)sed->physaddr,
    1855             :                OHCI_ED_GET_FA(letoh32(sed->ed.ed_flags)),
    1856             :                OHCI_ED_GET_EN(letoh32(sed->ed.ed_flags)),
    1857             :                OHCI_ED_GET_MAXP(letoh32(sed->ed.ed_flags)), sbuf,
    1858             :                (u_long)letoh32(sed->ed.ed_tailp), sbuf2,
    1859             :                (u_long)letoh32(sed->ed.ed_headp),
    1860             :                (u_long)letoh32(sed->ed.ed_nexted));
    1861             : }
    1862             : #endif
    1863             : 
    1864             : usbd_status
    1865           0 : ohci_open(struct usbd_pipe *pipe)
    1866             : {
    1867           0 :         struct ohci_softc *sc = (struct ohci_softc *)pipe->device->bus;
    1868           0 :         usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
    1869           0 :         struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
    1870           0 :         u_int8_t xfertype = ed->bmAttributes & UE_XFERTYPE;
    1871             :         struct ohci_soft_ed *sed = NULL;
    1872             :         struct ohci_soft_td *std = NULL;
    1873             :         struct ohci_soft_itd *sitd;
    1874             :         ohci_physaddr_t tdphys;
    1875             :         u_int32_t fmt;
    1876             :         usbd_status err;
    1877             :         int s;
    1878             :         int ival;
    1879             : 
    1880             :         DPRINTFN(1, ("ohci_open: pipe=%p, addr=%d, endpt=%d\n",
    1881             :                      pipe, pipe->device->address, ed->bEndpointAddress));
    1882             : 
    1883           0 :         if (sc->sc_bus.dying)
    1884           0 :                 return (USBD_IOERROR);
    1885             : 
    1886             :         /* Root Hub */
    1887           0 :         if (pipe->device->depth == 0) {
    1888           0 :                 switch (ed->bEndpointAddress) {
    1889             :                 case USB_CONTROL_ENDPOINT:
    1890           0 :                         pipe->methods = &ohci_root_ctrl_methods;
    1891           0 :                         break;
    1892             :                 case UE_DIR_IN | OHCI_INTR_ENDPT:
    1893           0 :                         pipe->methods = &ohci_root_intr_methods;
    1894           0 :                         break;
    1895             :                 default:
    1896           0 :                         return (USBD_INVAL);
    1897             :                 }
    1898             :         } else {
    1899           0 :                 sed = ohci_alloc_sed(sc);
    1900           0 :                 if (sed == NULL)
    1901             :                         goto bad0;
    1902           0 :                 opipe->sed = sed;
    1903           0 :                 if (xfertype == UE_ISOCHRONOUS) {
    1904           0 :                         sitd = ohci_alloc_sitd(sc);
    1905           0 :                         if (sitd == NULL)
    1906             :                                 goto bad1;
    1907           0 :                         opipe->tail.itd = sitd;
    1908           0 :                         tdphys = sitd->physaddr;
    1909             :                         fmt = OHCI_ED_FORMAT_ISO;
    1910           0 :                         if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
    1911           0 :                                 fmt |= OHCI_ED_DIR_IN;
    1912             :                         else
    1913             :                                 fmt |= OHCI_ED_DIR_OUT;
    1914             :                 } else {
    1915           0 :                         std = ohci_alloc_std(sc);
    1916           0 :                         if (std == NULL)
    1917             :                                 goto bad1;
    1918           0 :                         opipe->tail.td = std;
    1919           0 :                         tdphys = std->physaddr;
    1920             :                         fmt = OHCI_ED_FORMAT_GEN | OHCI_ED_DIR_TD;
    1921             :                 }
    1922           0 :                 sed->ed.ed_flags = htole32(
    1923             :                         OHCI_ED_SET_FA(pipe->device->address) |
    1924             :                         OHCI_ED_SET_EN(UE_GET_ADDR(ed->bEndpointAddress)) |
    1925             :                         (pipe->device->speed == USB_SPEED_LOW ?
    1926             :                              OHCI_ED_SPEED : 0) |
    1927             :                         fmt | OHCI_ED_SET_MAXP(UGETW(ed->wMaxPacketSize)));
    1928           0 :                 sed->ed.ed_headp = htole32(tdphys |
    1929             :                     (pipe->endpoint->savedtoggle ? OHCI_TOGGLECARRY : 0));
    1930           0 :                 sed->ed.ed_tailp = htole32(tdphys);
    1931             : 
    1932           0 :                 switch (xfertype) {
    1933             :                 case UE_CONTROL:
    1934           0 :                         pipe->methods = &ohci_device_ctrl_methods;
    1935           0 :                         err = usb_allocmem(&sc->sc_bus,
    1936             :                                   sizeof(usb_device_request_t),
    1937           0 :                                   0, &opipe->u.ctl.reqdma);
    1938           0 :                         if (err)
    1939             :                                 goto bad;
    1940           0 :                         s = splusb();
    1941           0 :                         ohci_add_ed(sed, sc->sc_ctrl_head);
    1942           0 :                         splx(s);
    1943           0 :                         break;
    1944             :                 case UE_INTERRUPT:
    1945           0 :                         pipe->methods = &ohci_device_intr_methods;
    1946           0 :                         ival = pipe->interval;
    1947           0 :                         if (ival == USBD_DEFAULT_INTERVAL)
    1948           0 :                                 ival = ed->bInterval;
    1949           0 :                         return (ohci_device_setintr(sc, opipe, ival));
    1950             :                 case UE_ISOCHRONOUS:
    1951           0 :                         pipe->methods = &ohci_device_isoc_methods;
    1952           0 :                         return (ohci_setup_isoc(pipe));
    1953             :                 case UE_BULK:
    1954           0 :                         pipe->methods = &ohci_device_bulk_methods;
    1955           0 :                         s = splusb();
    1956           0 :                         ohci_add_ed(sed, sc->sc_bulk_head);
    1957           0 :                         splx(s);
    1958           0 :                         break;
    1959             :                 }
    1960             :         }
    1961           0 :         return (USBD_NORMAL_COMPLETION);
    1962             : 
    1963             :  bad:
    1964           0 :         if (std != NULL)
    1965           0 :                 ohci_free_std(sc, std);
    1966             :  bad1:
    1967           0 :         if (sed != NULL)
    1968           0 :                 ohci_free_sed(sc, sed);
    1969             :  bad0:
    1970           0 :         return (USBD_NOMEM);
    1971             : 
    1972           0 : }
    1973             : 
    1974             : /*
    1975             :  * Work around the half configured control (default) pipe when setting
    1976             :  * the address of a device.
    1977             :  *
    1978             :  * Because a single ED is setup per endpoint in ohci_open(), and the
    1979             :  * control pipe is configured before we could have set the address
    1980             :  * of the device or read the wMaxPacketSize of the endpoint, we have
    1981             :  * to re-open the pipe twice here.
    1982             :  */
    1983             : int
    1984           0 : ohci_setaddr(struct usbd_device *dev, int addr)
    1985             : {
    1986             :         /* Root Hub */
    1987           0 :         if (dev->depth == 0)
    1988           0 :                 return (0);
    1989             : 
    1990             :         /* Re-establish the default pipe with the new max packet size. */
    1991           0 :         ohci_device_ctrl_close(dev->default_pipe);
    1992           0 :         if (ohci_open(dev->default_pipe))
    1993           0 :                 return (EINVAL);
    1994             : 
    1995           0 :         if (usbd_set_address(dev, addr))
    1996           0 :                 return (1);
    1997             : 
    1998           0 :         dev->address = addr;
    1999             : 
    2000             :         /* Re-establish the default pipe with the new address. */
    2001           0 :         ohci_device_ctrl_close(dev->default_pipe);
    2002           0 :         if (ohci_open(dev->default_pipe))
    2003           0 :                 return (EINVAL);
    2004             : 
    2005           0 :         return (0);
    2006           0 : }
    2007             : 
    2008             : /*
    2009             :  * Close a reqular pipe.
    2010             :  * Assumes that there are no pending transactions.
    2011             :  */
    2012             : void
    2013           0 : ohci_close_pipe(struct usbd_pipe *pipe, struct ohci_soft_ed *head)
    2014             : {
    2015           0 :         struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
    2016           0 :         struct ohci_softc *sc = (struct ohci_softc *)pipe->device->bus;
    2017           0 :         struct ohci_soft_ed *sed = opipe->sed;
    2018             :         int s;
    2019             : 
    2020           0 :         s = splusb();
    2021             : #ifdef DIAGNOSTIC
    2022           0 :         sed->ed.ed_flags |= htole32(OHCI_ED_SKIP);
    2023           0 :         if ((letoh32(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
    2024           0 :             (letoh32(sed->ed.ed_headp) & OHCI_HEADMASK)) {
    2025             :                 struct ohci_soft_td *std;
    2026           0 :                 std = ohci_hash_find_td(sc, letoh32(sed->ed.ed_headp));
    2027           0 :                 printf("ohci_close_pipe: pipe not empty sed=%p hd=0x%x "
    2028             :                        "tl=0x%x pipe=%p, std=%p\n", sed,
    2029           0 :                        (int)letoh32(sed->ed.ed_headp),
    2030           0 :                        (int)letoh32(sed->ed.ed_tailp),
    2031             :                        pipe, std);
    2032             : #ifdef USB_DEBUG
    2033             :                 usbd_dump_pipe(pipe);
    2034             : #endif
    2035             : #ifdef OHCI_DEBUG
    2036             :                 ohci_dump_ed(sed);
    2037             :                 if (std)
    2038             :                         ohci_dump_td(std);
    2039             : #endif
    2040           0 :                 usb_delay_ms(&sc->sc_bus, 2);
    2041           0 :                 if ((letoh32(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
    2042           0 :                     (letoh32(sed->ed.ed_headp) & OHCI_HEADMASK))
    2043           0 :                         printf("ohci_close_pipe: pipe still not empty\n");
    2044           0 :         }
    2045             : #endif
    2046           0 :         ohci_rem_ed(sed, head);
    2047             :         /* Make sure the host controller is not touching this ED */
    2048           0 :         usb_delay_ms(&sc->sc_bus, 1);
    2049           0 :         splx(s);
    2050           0 :         pipe->endpoint->savedtoggle =
    2051           0 :             (letoh32(sed->ed.ed_headp) & OHCI_TOGGLECARRY) ? 1 : 0;
    2052           0 :         ohci_free_sed(sc, opipe->sed);
    2053           0 : }
    2054             : 
    2055             : /*
    2056             :  * Abort a device request.
    2057             :  * If this routine is called at splusb() it guarantees that the request
    2058             :  * will be removed from the hardware scheduling and that the callback
    2059             :  * for it will be called with USBD_CANCELLED status.
    2060             :  * It's impossible to guarantee that the requested transfer will not
    2061             :  * have happened since the hardware runs concurrently.
    2062             :  * If the transaction has already happened we rely on the ordinary
    2063             :  * interrupt processing to process it.
    2064             :  */
    2065             : void
    2066           0 : ohci_abort_xfer(struct usbd_xfer *xfer, usbd_status status)
    2067             : {
    2068           0 :         struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
    2069           0 :         struct ohci_softc *sc = (struct ohci_softc *)xfer->device->bus;
    2070           0 :         struct ohci_soft_ed *sed = opipe->sed;
    2071             :         struct ohci_soft_td *p, *n;
    2072             :         ohci_physaddr_t headp;
    2073             :         int s, hit;
    2074             : 
    2075             :         DPRINTF(("ohci_abort_xfer: xfer=%p pipe=%p sed=%p\n", xfer, opipe,
    2076             :                  sed));
    2077             : 
    2078           0 :         if (sc->sc_bus.dying) {
    2079             :                 /* If we're dying, just do the software part. */
    2080           0 :                 s = splusb();
    2081           0 :                 xfer->status = status;       /* make software ignore it */
    2082           0 :                 timeout_del(&xfer->timeout_handle);
    2083           0 :                 usb_rem_task(xfer->device, &xfer->abort_task);
    2084           0 :                 usb_transfer_complete(xfer);
    2085           0 :                 splx(s);
    2086           0 :                 return;
    2087             :         }
    2088             : 
    2089           0 :         if (xfer->device->bus->intr_context || !curproc)
    2090           0 :                 panic("ohci_abort_xfer: not in process context");
    2091             : 
    2092             :         /*
    2093             :          * Step 1: Make interrupt routine and hardware ignore xfer.
    2094             :          */
    2095           0 :         s = splusb();
    2096           0 :         xfer->status = status;       /* make software ignore it */
    2097           0 :         timeout_del(&xfer->timeout_handle);
    2098           0 :         usb_rem_task(xfer->device, &xfer->abort_task);
    2099           0 :         splx(s);
    2100             :         DPRINTFN(1,("ohci_abort_xfer: stop ed=%p\n", sed));
    2101           0 :         sed->ed.ed_flags |= htole32(OHCI_ED_SKIP); /* force hardware skip */
    2102             : 
    2103             :         /*
    2104             :          * Step 2: Wait until we know hardware has finished any possible
    2105             :          * use of the xfer.  Also make sure the soft interrupt routine
    2106             :          * has run.
    2107             :          */
    2108           0 :         usb_delay_ms(xfer->device->bus, 20); /* Hardware finishes in 1ms */
    2109           0 :         s = splusb();
    2110           0 :         sc->sc_softwake = 1;
    2111           0 :         usb_schedsoftintr(&sc->sc_bus);
    2112           0 :         tsleep(&sc->sc_softwake, PZERO, "ohciab", 0);
    2113           0 :         splx(s);
    2114             : 
    2115             :         /*
    2116             :          * Step 3: Remove any vestiges of the xfer from the hardware.
    2117             :          * The complication here is that the hardware may have executed
    2118             :          * beyond the xfer we're trying to abort.  So as we're scanning
    2119             :          * the TDs of this xfer we check if the hardware points to
    2120             :          * any of them.
    2121             :          */
    2122           0 :         s = splusb();           /* XXX why? */
    2123           0 :         p = xfer->hcpriv;
    2124             : #ifdef DIAGNOSTIC
    2125           0 :         if (p == NULL) {
    2126           0 :                 splx(s);
    2127           0 :                 printf("ohci_abort_xfer: hcpriv is NULL\n");
    2128           0 :                 return;
    2129             :         }
    2130             : #endif
    2131             : #ifdef OHCI_DEBUG
    2132             :         if (ohcidebug > 1) {
    2133             :                 DPRINTF(("ohci_abort_xfer: sed=\n"));
    2134             :                 ohci_dump_ed(sed);
    2135             :                 ohci_dump_tds(p);
    2136             :         }
    2137             : #endif
    2138           0 :         headp = letoh32(sed->ed.ed_headp) & OHCI_HEADMASK;
    2139             :         hit = 0;
    2140           0 :         for (; p->xfer == xfer; p = n) {
    2141           0 :                 hit |= headp == p->physaddr;
    2142           0 :                 n = p->nexttd;
    2143           0 :                 if (OHCI_TD_GET_CC(letoh32(p->td.td_flags)) ==
    2144             :                     OHCI_CC_NOT_ACCESSED)
    2145           0 :                         ohci_free_std(sc, p);
    2146             :         }
    2147             :         /* Zap headp register if hardware pointed inside the xfer. */
    2148           0 :         if (hit) {
    2149             :                 DPRINTFN(1,("ohci_abort_xfer: set hd=0x%08x, tl=0x%08x\n",
    2150             :                             (int)p->physaddr, (int)letoh32(sed->ed.ed_tailp)));
    2151           0 :                 sed->ed.ed_headp = htole32(p->physaddr); /* unlink TDs */
    2152           0 :         } else {
    2153             :                 DPRINTFN(1,("ohci_abort_xfer: no hit\n"));
    2154             :         }
    2155             : 
    2156             :         /*
    2157             :          * Step 4: Turn on hardware again.
    2158             :          */
    2159           0 :         sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); /* remove hardware skip */
    2160             : 
    2161             :         /*
    2162             :          * Step 5: Execute callback.
    2163             :          */
    2164           0 :         usb_transfer_complete(xfer);
    2165             : 
    2166           0 :         splx(s);
    2167           0 : }
    2168             : 
    2169             : /*
    2170             :  * Data structures and routines to emulate the root hub.
    2171             :  */
    2172             : usb_device_descriptor_t ohci_devd = {
    2173             :         USB_DEVICE_DESCRIPTOR_SIZE,
    2174             :         UDESC_DEVICE,           /* type */
    2175             :         {0x00, 0x01},           /* USB version */
    2176             :         UDCLASS_HUB,            /* class */
    2177             :         UDSUBCLASS_HUB,         /* subclass */
    2178             :         UDPROTO_FSHUB,
    2179             :         64,                     /* max packet */
    2180             :         {0},{0},{0x00,0x01},    /* device id */
    2181             :         1,2,0,                  /* string indices */
    2182             :         1                       /* # of configurations */
    2183             : };
    2184             : 
    2185             : usb_config_descriptor_t ohci_confd = {
    2186             :         USB_CONFIG_DESCRIPTOR_SIZE,
    2187             :         UDESC_CONFIG,
    2188             :         {USB_CONFIG_DESCRIPTOR_SIZE +
    2189             :          USB_INTERFACE_DESCRIPTOR_SIZE +
    2190             :          USB_ENDPOINT_DESCRIPTOR_SIZE},
    2191             :         1,
    2192             :         1,
    2193             :         0,
    2194             :         UC_SELF_POWERED,
    2195             :         0                       /* max power */
    2196             : };
    2197             : 
    2198             : usb_interface_descriptor_t ohci_ifcd = {
    2199             :         USB_INTERFACE_DESCRIPTOR_SIZE,
    2200             :         UDESC_INTERFACE,
    2201             :         0,
    2202             :         0,
    2203             :         1,
    2204             :         UICLASS_HUB,
    2205             :         UISUBCLASS_HUB,
    2206             :         UIPROTO_FSHUB,
    2207             :         0
    2208             : };
    2209             : 
    2210             : usb_endpoint_descriptor_t ohci_endpd = {
    2211             :         USB_ENDPOINT_DESCRIPTOR_SIZE,
    2212             :         UDESC_ENDPOINT,
    2213             :         UE_DIR_IN | OHCI_INTR_ENDPT,
    2214             :         UE_INTERRUPT,
    2215             :         {8, 0},                 /* max packet */
    2216             :         255
    2217             : };
    2218             : 
    2219             : usb_hub_descriptor_t ohci_hubd = {
    2220             :         USB_HUB_DESCRIPTOR_SIZE,
    2221             :         UDESC_HUB,
    2222             :         0,
    2223             :         {0,0},
    2224             :         0,
    2225             :         0,
    2226             :         {0},
    2227             : };
    2228             : 
    2229             : /*
    2230             :  * Simulate a hardware hub by handling all the necessary requests.
    2231             :  */
    2232             : usbd_status
    2233           0 : ohci_root_ctrl_transfer(struct usbd_xfer *xfer)
    2234             : {
    2235             :         usbd_status err;
    2236             : 
    2237             :         /* Insert last in queue. */
    2238           0 :         err = usb_insert_transfer(xfer);
    2239           0 :         if (err)
    2240           0 :                 return (err);
    2241             : 
    2242             :         /* Pipe isn't running, start first */
    2243           0 :         return (ohci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
    2244           0 : }
    2245             : 
    2246             : usbd_status
    2247           0 : ohci_root_ctrl_start(struct usbd_xfer *xfer)
    2248             : {
    2249           0 :         struct ohci_softc *sc = (struct ohci_softc *)xfer->device->bus;
    2250             :         usb_device_request_t *req;
    2251             :         void *buf = NULL;
    2252             :         int port, i;
    2253             :         int s, len, value, index, l, totlen = 0;
    2254           0 :         usb_port_status_t ps;
    2255           0 :         usb_hub_descriptor_t hubd;
    2256             :         usbd_status err;
    2257             :         u_int32_t v;
    2258             : 
    2259           0 :         if (sc->sc_bus.dying)
    2260           0 :                 return (USBD_IOERROR);
    2261             : 
    2262             : #ifdef DIAGNOSTIC
    2263           0 :         if (!(xfer->rqflags & URQ_REQUEST))
    2264             :                 /* XXX panic */
    2265           0 :                 return (USBD_INVAL);
    2266             : #endif
    2267           0 :         req = &xfer->request;
    2268             : 
    2269             :         DPRINTFN(4,("ohci_root_ctrl_control type=0x%02x request=%02x\n",
    2270             :                     req->bmRequestType, req->bRequest));
    2271             : 
    2272           0 :         len = UGETW(req->wLength);
    2273           0 :         value = UGETW(req->wValue);
    2274           0 :         index = UGETW(req->wIndex);
    2275             : 
    2276           0 :         if (len != 0)
    2277           0 :                 buf = KERNADDR(&xfer->dmabuf, 0);
    2278             : 
    2279             : #define C(x,y) ((x) | ((y) << 8))
    2280           0 :         switch(C(req->bRequest, req->bmRequestType)) {
    2281             :         case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
    2282             :         case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
    2283             :         case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
    2284             :                 /*
    2285             :                  * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
    2286             :                  * for the integrated root hub.
    2287             :                  */
    2288             :                 break;
    2289             :         case C(UR_GET_CONFIG, UT_READ_DEVICE):
    2290           0 :                 if (len > 0) {
    2291           0 :                         *(u_int8_t *)buf = sc->sc_conf;
    2292             :                         totlen = 1;
    2293           0 :                 }
    2294             :                 break;
    2295             :         case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
    2296             :                 DPRINTFN(8,("ohci_root_ctrl_control wValue=0x%04x\n", value));
    2297           0 :                 switch(value >> 8) {
    2298             :                 case UDESC_DEVICE:
    2299           0 :                         if ((value & 0xff) != 0) {
    2300             :                                 err = USBD_IOERROR;
    2301           0 :                                 goto ret;
    2302             :                         }
    2303           0 :                         totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
    2304           0 :                         USETW(ohci_devd.idVendor, sc->sc_id_vendor);
    2305           0 :                         memcpy(buf, &ohci_devd, l);
    2306           0 :                         break;
    2307             :                 case UDESC_CONFIG:
    2308           0 :                         if ((value & 0xff) != 0) {
    2309             :                                 err = USBD_IOERROR;
    2310           0 :                                 goto ret;
    2311             :                         }
    2312           0 :                         totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
    2313           0 :                         memcpy(buf, &ohci_confd, l);
    2314           0 :                         buf = (char *)buf + l;
    2315           0 :                         len -= l;
    2316           0 :                         l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
    2317           0 :                         totlen += l;
    2318           0 :                         memcpy(buf, &ohci_ifcd, l);
    2319           0 :                         buf = (char *)buf + l;
    2320           0 :                         len -= l;
    2321           0 :                         l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
    2322           0 :                         totlen += l;
    2323           0 :                         memcpy(buf, &ohci_endpd, l);
    2324           0 :                         break;
    2325             :                 case UDESC_STRING:
    2326           0 :                         if (len == 0)
    2327             :                                 break;
    2328           0 :                         *(u_int8_t *)buf = 0;
    2329             :                         totlen = 1;
    2330           0 :                         switch (value & 0xff) {
    2331             :                         case 0: /* Language table */
    2332           0 :                                 totlen = usbd_str(buf, len, "\001");
    2333           0 :                                 break;
    2334             :                         case 1: /* Vendor */
    2335           0 :                                 totlen = usbd_str(buf, len, sc->sc_vendor);
    2336           0 :                                 break;
    2337             :                         case 2: /* Product */
    2338           0 :                                 totlen = usbd_str(buf, len, "OHCI root hub");
    2339           0 :                                 break;
    2340             :                         }
    2341             :                         break;
    2342             :                 default:
    2343             :                         err = USBD_IOERROR;
    2344           0 :                         goto ret;
    2345             :                 }
    2346             :                 break;
    2347             :         case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
    2348           0 :                 if (len > 0) {
    2349           0 :                         *(u_int8_t *)buf = 0;
    2350             :                         totlen = 1;
    2351           0 :                 }
    2352             :                 break;
    2353             :         case C(UR_GET_STATUS, UT_READ_DEVICE):
    2354           0 :                 if (len > 1) {
    2355           0 :                         USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
    2356             :                         totlen = 2;
    2357           0 :                 }
    2358             :                 break;
    2359             :         case C(UR_GET_STATUS, UT_READ_INTERFACE):
    2360             :         case C(UR_GET_STATUS, UT_READ_ENDPOINT):
    2361           0 :                 if (len > 1) {
    2362           0 :                         USETW(((usb_status_t *)buf)->wStatus, 0);
    2363             :                         totlen = 2;
    2364           0 :                 }
    2365             :                 break;
    2366             :         case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
    2367           0 :                 if (value >= USB_MAX_DEVICES) {
    2368             :                         err = USBD_IOERROR;
    2369           0 :                         goto ret;
    2370             :                 }
    2371             :                 break;
    2372             :         case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
    2373           0 :                 if (value != 0 && value != 1) {
    2374             :                         err = USBD_IOERROR;
    2375           0 :                         goto ret;
    2376             :                 }
    2377           0 :                 sc->sc_conf = value;
    2378           0 :                 break;
    2379             :         case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
    2380             :                 break;
    2381             :         case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
    2382             :         case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
    2383             :         case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
    2384             :                 err = USBD_IOERROR;
    2385           0 :                 goto ret;
    2386             :         case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
    2387             :                 break;
    2388             :         case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
    2389             :                 break;
    2390             :         /* Hub requests */
    2391             :         case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
    2392             :                 break;
    2393             :         case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
    2394             :                 DPRINTFN(8, ("ohci_root_ctrl_control: UR_CLEAR_PORT_FEATURE "
    2395             :                              "port=%d feature=%d\n",
    2396             :                              index, value));
    2397           0 :                 if (index < 1 || index > sc->sc_noport) {
    2398             :                         err = USBD_IOERROR;
    2399           0 :                         goto ret;
    2400             :                 }
    2401           0 :                 port = OHCI_RH_PORT_STATUS(index);
    2402           0 :                 switch(value) {
    2403             :                 case UHF_PORT_ENABLE:
    2404           0 :                         OWRITE4(sc, port, UPS_CURRENT_CONNECT_STATUS);
    2405           0 :                         break;
    2406             :                 case UHF_PORT_SUSPEND:
    2407           0 :                         OWRITE4(sc, port, UPS_OVERCURRENT_INDICATOR);
    2408           0 :                         break;
    2409             :                 case UHF_PORT_POWER:
    2410             :                         /* Yes, writing to the LOW_SPEED bit clears power. */
    2411           0 :                         OWRITE4(sc, port, UPS_LOW_SPEED);
    2412           0 :                         break;
    2413             :                 case UHF_C_PORT_CONNECTION:
    2414           0 :                         OWRITE4(sc, port, UPS_C_CONNECT_STATUS << 16);
    2415           0 :                         break;
    2416             :                 case UHF_C_PORT_ENABLE:
    2417           0 :                         OWRITE4(sc, port, UPS_C_PORT_ENABLED << 16);
    2418           0 :                         break;
    2419             :                 case UHF_C_PORT_SUSPEND:
    2420           0 :                         OWRITE4(sc, port, UPS_C_SUSPEND << 16);
    2421           0 :                         break;
    2422             :                 case UHF_C_PORT_OVER_CURRENT:
    2423           0 :                         OWRITE4(sc, port, UPS_C_OVERCURRENT_INDICATOR << 16);
    2424           0 :                         break;
    2425             :                 case UHF_C_PORT_RESET:
    2426           0 :                         OWRITE4(sc, port, UPS_C_PORT_RESET << 16);
    2427           0 :                         break;
    2428             :                 default:
    2429             :                         err = USBD_IOERROR;
    2430           0 :                         goto ret;
    2431             :                 }
    2432           0 :                 switch(value) {
    2433             :                 case UHF_C_PORT_CONNECTION:
    2434             :                 case UHF_C_PORT_ENABLE:
    2435             :                 case UHF_C_PORT_SUSPEND:
    2436             :                 case UHF_C_PORT_OVER_CURRENT:
    2437             :                 case UHF_C_PORT_RESET:
    2438             :                         /* Enable RHSC interrupt if condition is cleared. */
    2439           0 :                         if ((OREAD4(sc, port) >> 16) == 0)
    2440           0 :                                 ohci_rhsc_able(sc, 1);
    2441             :                         break;
    2442             :                 default:
    2443             :                         break;
    2444             :                 }
    2445             :                 break;
    2446             :         case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
    2447           0 :                 if ((value & 0xff) != 0) {
    2448             :                         err = USBD_IOERROR;
    2449           0 :                         goto ret;
    2450             :                 }
    2451           0 :                 v = OREAD4(sc, OHCI_RH_DESCRIPTOR_A);
    2452           0 :                 hubd = ohci_hubd;
    2453           0 :                 hubd.bNbrPorts = sc->sc_noport;
    2454           0 :                 USETW(hubd.wHubCharacteristics,
    2455             :                       (v & OHCI_NPS ? UHD_PWR_NO_SWITCH :
    2456             :                        v & OHCI_PSM ? UHD_PWR_GANGED : UHD_PWR_INDIVIDUAL)
    2457             :                       /* XXX overcurrent */
    2458             :                       );
    2459           0 :                 hubd.bPwrOn2PwrGood = OHCI_GET_POTPGT(v);
    2460           0 :                 v = OREAD4(sc, OHCI_RH_DESCRIPTOR_B);
    2461           0 :                 for (i = 0, l = sc->sc_noport; l > 0; i++, l -= 8, v >>= 8)
    2462           0 :                         hubd.DeviceRemovable[i++] = (u_int8_t)v;
    2463           0 :                 hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + i;
    2464           0 :                 l = min(len, hubd.bDescLength);
    2465             :                 totlen = l;
    2466           0 :                 memcpy(buf, &hubd, l);
    2467           0 :                 break;
    2468             :         case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
    2469           0 :                 if (len != 4) {
    2470             :                         err = USBD_IOERROR;
    2471           0 :                         goto ret;
    2472             :                 }
    2473           0 :                 memset(buf, 0, len); /* ? XXX */
    2474             :                 totlen = len;
    2475           0 :                 break;
    2476             :         case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
    2477             :                 DPRINTFN(8,("ohci_root_ctrl_transfer: get port status i=%d\n",
    2478             :                             index));
    2479           0 :                 if (index < 1 || index > sc->sc_noport) {
    2480             :                         err = USBD_IOERROR;
    2481           0 :                         goto ret;
    2482             :                 }
    2483           0 :                 if (len != 4) {
    2484             :                         err = USBD_IOERROR;
    2485           0 :                         goto ret;
    2486             :                 }
    2487           0 :                 v = OREAD4(sc, OHCI_RH_PORT_STATUS(index));
    2488             :                 DPRINTFN(8,("ohci_root_ctrl_transfer: port status=0x%04x\n",
    2489             :                             v));
    2490           0 :                 USETW(ps.wPortStatus, v);
    2491           0 :                 USETW(ps.wPortChange, v >> 16);
    2492           0 :                 l = min(len, sizeof ps);
    2493           0 :                 memcpy(buf, &ps, l);
    2494             :                 totlen = l;
    2495           0 :                 break;
    2496             :         case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
    2497             :                 err = USBD_IOERROR;
    2498           0 :                 goto ret;
    2499             :         case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
    2500             :                 break;
    2501             :         case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
    2502           0 :                 if (index < 1 || index > sc->sc_noport) {
    2503             :                         err = USBD_IOERROR;
    2504           0 :                         goto ret;
    2505             :                 }
    2506           0 :                 port = OHCI_RH_PORT_STATUS(index);
    2507           0 :                 switch(value) {
    2508             :                 case UHF_PORT_ENABLE:
    2509           0 :                         OWRITE4(sc, port, UPS_PORT_ENABLED);
    2510           0 :                         break;
    2511             :                 case UHF_PORT_SUSPEND:
    2512           0 :                         OWRITE4(sc, port, UPS_SUSPEND);
    2513           0 :                         break;
    2514             :                 case UHF_PORT_RESET:
    2515             :                         DPRINTFN(5,("ohci_root_ctrl_transfer: reset port %d\n",
    2516             :                                     index));
    2517           0 :                         OWRITE4(sc, port, UPS_RESET);
    2518           0 :                         for (i = 0; i < 5; i++) {
    2519           0 :                                 usb_delay_ms(&sc->sc_bus,
    2520             :                                              USB_PORT_ROOT_RESET_DELAY);
    2521           0 :                                 if (sc->sc_bus.dying) {
    2522             :                                         err = USBD_IOERROR;
    2523           0 :                                         goto ret;
    2524             :                                 }
    2525           0 :                                 if ((OREAD4(sc, port) & UPS_RESET) == 0)
    2526             :                                         break;
    2527             :                         }
    2528             :                         DPRINTFN(8,("ohci port %d reset, status = 0x%04x\n",
    2529             :                                     index, OREAD4(sc, port)));
    2530             :                         break;
    2531             :                 case UHF_PORT_POWER:
    2532             :                         DPRINTFN(2,("ohci_root_ctrl_transfer: set port power "
    2533             :                                     "%d\n", index));
    2534           0 :                         OWRITE4(sc, port, UPS_PORT_POWER);
    2535           0 :                         break;
    2536             :                 case UHF_PORT_DISOWN_TO_1_1:
    2537             :                         /* accept, but do nothing */
    2538             :                         break;
    2539             :                 default:
    2540             :                         err = USBD_IOERROR;
    2541           0 :                         goto ret;
    2542             :                 }
    2543             :                 break;
    2544             :         default:
    2545             :                 err = USBD_IOERROR;
    2546           0 :                 goto ret;
    2547             :         }
    2548           0 :         xfer->actlen = totlen;
    2549           0 :         err = USBD_NORMAL_COMPLETION;
    2550             :  ret:
    2551           0 :         xfer->status = err;
    2552           0 :         s = splusb();
    2553           0 :         usb_transfer_complete(xfer);
    2554           0 :         splx(s);
    2555           0 :         return (err);
    2556           0 : }
    2557             : 
    2558             : /* Abort a root control request. */
    2559             : void
    2560           0 : ohci_root_ctrl_abort(struct usbd_xfer *xfer)
    2561             : {
    2562             :         /* Nothing to do, all transfers are synchronous. */
    2563           0 : }
    2564             : 
    2565             : /* Close the root pipe. */
    2566             : void
    2567           0 : ohci_root_ctrl_close(struct usbd_pipe *pipe)
    2568             : {
    2569             :         DPRINTF(("ohci_root_ctrl_close\n"));
    2570             :         /* Nothing to do. */
    2571           0 : }
    2572             : 
    2573             : usbd_status
    2574           0 : ohci_root_intr_transfer(struct usbd_xfer *xfer)
    2575             : {
    2576             :         usbd_status err;
    2577             : 
    2578             :         /* Insert last in queue. */
    2579           0 :         err = usb_insert_transfer(xfer);
    2580           0 :         if (err)
    2581           0 :                 return (err);
    2582             : 
    2583             :         /* Pipe isn't running, start first */
    2584           0 :         return (ohci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
    2585           0 : }
    2586             : 
    2587             : usbd_status
    2588           0 : ohci_root_intr_start(struct usbd_xfer *xfer)
    2589             : {
    2590           0 :         struct ohci_softc *sc = (struct ohci_softc *)xfer->device->bus;
    2591             : 
    2592           0 :         if (sc->sc_bus.dying)
    2593           0 :                 return (USBD_IOERROR);
    2594             : 
    2595           0 :         sc->sc_intrxfer = xfer;
    2596             : 
    2597           0 :         return (USBD_IN_PROGRESS);
    2598           0 : }
    2599             : 
    2600             : void
    2601           0 : ohci_root_intr_abort(struct usbd_xfer *xfer)
    2602             : {
    2603           0 :         struct ohci_softc *sc = (struct ohci_softc *)xfer->device->bus;
    2604             :         int s;
    2605             : 
    2606           0 :         sc->sc_intrxfer = NULL;
    2607             : 
    2608           0 :         xfer->status = USBD_CANCELLED;
    2609           0 :         s = splusb();
    2610           0 :         usb_transfer_complete(xfer);
    2611           0 :         splx(s);
    2612           0 : }
    2613             : 
    2614             : void
    2615           0 : ohci_root_intr_close(struct usbd_pipe *pipe)
    2616             : {
    2617           0 : }
    2618             : 
    2619             : usbd_status
    2620           0 : ohci_device_ctrl_transfer(struct usbd_xfer *xfer)
    2621             : {
    2622             :         usbd_status err;
    2623             : 
    2624             :         /* Insert last in queue. */
    2625           0 :         err = usb_insert_transfer(xfer);
    2626           0 :         if (err)
    2627           0 :                 return (err);
    2628             : 
    2629             :         /* Pipe isn't running, start first */
    2630           0 :         return (ohci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
    2631           0 : }
    2632             : 
    2633             : usbd_status
    2634           0 : ohci_device_ctrl_start(struct usbd_xfer *xfer)
    2635             : {
    2636           0 :         struct ohci_softc *sc = (struct ohci_softc *)xfer->device->bus;
    2637             :         usbd_status err;
    2638             : 
    2639           0 :         if (sc->sc_bus.dying)
    2640           0 :                 return (USBD_IOERROR);
    2641             : 
    2642             : #ifdef DIAGNOSTIC
    2643           0 :         if (!(xfer->rqflags & URQ_REQUEST)) {
    2644             :                 /* XXX panic */
    2645           0 :                 printf("ohci_device_ctrl_transfer: not a request\n");
    2646           0 :                 return (USBD_INVAL);
    2647             :         }
    2648             : #endif
    2649             : 
    2650           0 :         err = ohci_device_request(xfer);
    2651           0 :         if (err)
    2652           0 :                 return (err);
    2653             : 
    2654           0 :         return (USBD_IN_PROGRESS);
    2655           0 : }
    2656             : 
    2657             : /* Abort a device control request. */
    2658             : void
    2659           0 : ohci_device_ctrl_abort(struct usbd_xfer *xfer)
    2660             : {
    2661             :         DPRINTF(("ohci_device_ctrl_abort: xfer=%p\n", xfer));
    2662           0 :         ohci_abort_xfer(xfer, USBD_CANCELLED);
    2663           0 : }
    2664             : 
    2665             : /* Close a device control pipe. */
    2666             : void
    2667           0 : ohci_device_ctrl_close(struct usbd_pipe *pipe)
    2668             : {
    2669           0 :         struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
    2670           0 :         struct ohci_softc *sc = (struct ohci_softc *)pipe->device->bus;
    2671             : 
    2672             :         DPRINTF(("ohci_device_ctrl_close: pipe=%p\n", pipe));
    2673           0 :         ohci_close_pipe(pipe, sc->sc_ctrl_head);
    2674           0 :         ohci_free_std(sc, opipe->tail.td);
    2675           0 : }
    2676             : 
    2677             : /************************/
    2678             : 
    2679             : void
    2680           0 : ohci_device_clear_toggle(struct usbd_pipe *pipe)
    2681             : {
    2682           0 :         struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
    2683             : 
    2684           0 :         opipe->sed->ed.ed_headp &= htole32(~OHCI_TOGGLECARRY);
    2685           0 : }
    2686             : 
    2687             : usbd_status
    2688           0 : ohci_device_bulk_transfer(struct usbd_xfer *xfer)
    2689             : {
    2690             :         usbd_status err;
    2691             : 
    2692             :         /* Insert last in queue. */
    2693           0 :         err = usb_insert_transfer(xfer);
    2694           0 :         if (err)
    2695           0 :                 return (err);
    2696             : 
    2697             :         /* Pipe isn't running, start first */
    2698           0 :         return (ohci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
    2699           0 : }
    2700             : 
    2701             : usbd_status
    2702           0 : ohci_device_bulk_start(struct usbd_xfer *xfer)
    2703             : {
    2704           0 :         struct ohci_softc *sc = (struct ohci_softc *)xfer->device->bus;
    2705           0 :         struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
    2706           0 :         struct ohci_soft_td *data, *tail, *tdp;
    2707             :         struct ohci_soft_ed *sed;
    2708             :         u_int len;
    2709             :         int s, endpt;
    2710             :         usbd_status err;
    2711             : 
    2712           0 :         if (sc->sc_bus.dying)
    2713           0 :                 return (USBD_IOERROR);
    2714             : 
    2715             : #ifdef DIAGNOSTIC
    2716           0 :         if (xfer->rqflags & URQ_REQUEST) {
    2717             :                 /* XXX panic */
    2718           0 :                 printf("ohci_device_bulk_start: a request\n");
    2719           0 :                 return (USBD_INVAL);
    2720             :         }
    2721             : #endif
    2722             : 
    2723           0 :         len = xfer->length;
    2724           0 :         endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
    2725           0 :         sed = opipe->sed;
    2726             : 
    2727             :         DPRINTFN(4,("ohci_device_bulk_start: xfer=%p len=%u "
    2728             :                     "flags=%d endpt=%d\n", xfer, len, xfer->flags, endpt));
    2729             : 
    2730             :         /* Update device address */
    2731           0 :         sed->ed.ed_flags = htole32(
    2732             :                 (letoh32(sed->ed.ed_flags) & ~OHCI_ED_ADDRMASK) |
    2733             :                 OHCI_ED_SET_FA(xfer->device->address));
    2734             : 
    2735             :         /* Allocate a chain of new TDs (including a new tail). */
    2736           0 :         data = opipe->tail.td;
    2737           0 :         err = ohci_alloc_std_chain(sc, len, xfer, data, &tail);
    2738             :         /* We want interrupt at the end of the transfer. */
    2739           0 :         tail->td.td_flags &= htole32(~OHCI_TD_INTR_MASK);
    2740           0 :         tail->td.td_flags |= htole32(OHCI_TD_SET_DI(1));
    2741           0 :         tail->flags |= OHCI_CALL_DONE;
    2742           0 :         tail = tail->nexttd; /* point at sentinel */
    2743           0 :         if (err)
    2744           0 :                 return (err);
    2745             : 
    2746           0 :         tail->xfer = NULL;
    2747           0 :         xfer->hcpriv = data;
    2748             : 
    2749             :         DPRINTFN(4,("ohci_device_bulk_start: ed_flags=0x%08x td_flags=0x%08x "
    2750             :                     "td_cbp=0x%08x td_be=0x%08x\n",
    2751             :                     (int)letoh32(sed->ed.ed_flags),
    2752             :                     (int)letoh32(data->td.td_flags),
    2753             :                     (int)letoh32(data->td.td_cbp),
    2754             :                     (int)letoh32(data->td.td_be)));
    2755             : 
    2756             : #ifdef OHCI_DEBUG
    2757             :         if (ohcidebug > 5) {
    2758             :                 ohci_dump_ed(sed);
    2759             :                 ohci_dump_tds(data);
    2760             :         }
    2761             : #endif
    2762             : 
    2763             :         /* Insert ED in schedule */
    2764           0 :         s = splusb();
    2765           0 :         for (tdp = data; tdp != tail; tdp = tdp->nexttd) {
    2766           0 :                 tdp->xfer = xfer;
    2767             :         }
    2768           0 :         sed->ed.ed_tailp = htole32(tail->physaddr);
    2769           0 :         opipe->tail.td = tail;
    2770           0 :         sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
    2771           0 :         OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF);
    2772           0 :         if (xfer->timeout && !sc->sc_bus.use_polling) {
    2773           0 :                 timeout_del(&xfer->timeout_handle);
    2774           0 :                 timeout_set(&xfer->timeout_handle, ohci_timeout, xfer);
    2775           0 :                 timeout_add_msec(&xfer->timeout_handle, xfer->timeout);
    2776           0 :         }
    2777             : 
    2778             : #if 0
    2779             : /* This goes wrong if we are too slow. */
    2780             :         if (ohcidebug > 10) {
    2781             :                 delay(10000);
    2782             :                 DPRINTF(("ohci_device_intr_transfer: status=%x\n",
    2783             :                          OREAD4(sc, OHCI_COMMAND_STATUS)));
    2784             :                 ohci_dump_ed(sed);
    2785             :                 ohci_dump_tds(data);
    2786             :         }
    2787             : #endif
    2788             : 
    2789           0 :         splx(s);
    2790             : 
    2791           0 :         return (USBD_IN_PROGRESS);
    2792           0 : }
    2793             : 
    2794             : void
    2795           0 : ohci_device_bulk_abort(struct usbd_xfer *xfer)
    2796             : {
    2797             :         DPRINTF(("ohci_device_bulk_abort: xfer=%p\n", xfer));
    2798           0 :         ohci_abort_xfer(xfer, USBD_CANCELLED);
    2799           0 : }
    2800             : 
    2801             : /*
    2802             :  * Close a device bulk pipe.
    2803             :  */
    2804             : void
    2805           0 : ohci_device_bulk_close(struct usbd_pipe *pipe)
    2806             : {
    2807           0 :         struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
    2808           0 :         struct ohci_softc *sc = (struct ohci_softc *)pipe->device->bus;
    2809             : 
    2810             :         DPRINTF(("ohci_device_bulk_close: pipe=%p\n", pipe));
    2811           0 :         ohci_close_pipe(pipe, sc->sc_bulk_head);
    2812           0 :         ohci_free_std(sc, opipe->tail.td);
    2813           0 : }
    2814             : 
    2815             : /************************/
    2816             : 
    2817             : usbd_status
    2818           0 : ohci_device_intr_transfer(struct usbd_xfer *xfer)
    2819             : {
    2820             :         usbd_status err;
    2821             : 
    2822             :         /* Insert last in queue. */
    2823           0 :         err = usb_insert_transfer(xfer);
    2824           0 :         if (err)
    2825           0 :                 return (err);
    2826             : 
    2827             :         /* Pipe isn't running, start first */
    2828           0 :         return (ohci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
    2829           0 : }
    2830             : 
    2831             : usbd_status
    2832           0 : ohci_device_intr_start(struct usbd_xfer *xfer)
    2833             : {
    2834           0 :         struct ohci_softc *sc = (struct ohci_softc *)xfer->device->bus;
    2835           0 :         struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
    2836           0 :         struct ohci_soft_ed *sed = opipe->sed;
    2837             :         struct ohci_soft_td *data, *tail;
    2838             :         int s, len, endpt;
    2839             : 
    2840           0 :         if (sc->sc_bus.dying)
    2841           0 :                 return (USBD_IOERROR);
    2842             : 
    2843             :         DPRINTFN(3, ("ohci_device_intr_transfer: xfer=%p len=%u "
    2844             :                      "flags=%d priv=%p\n",
    2845             :                      xfer, xfer->length, xfer->flags, xfer->priv));
    2846             : 
    2847             : #ifdef DIAGNOSTIC
    2848           0 :         if (xfer->rqflags & URQ_REQUEST)
    2849           0 :                 panic("ohci_device_intr_transfer: a request");
    2850             : #endif
    2851             : 
    2852           0 :         len = xfer->length;
    2853           0 :         endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
    2854             : 
    2855           0 :         data = opipe->tail.td;
    2856           0 :         tail = ohci_alloc_std(sc);
    2857           0 :         if (tail == NULL)
    2858           0 :                 return (USBD_NOMEM);
    2859           0 :         tail->xfer = NULL;
    2860             : 
    2861           0 :         data->td.td_flags = htole32(
    2862             :                 (usbd_xfer_isread(xfer) ? OHCI_TD_IN : OHCI_TD_OUT) |
    2863             :                 OHCI_TD_NOCC |
    2864             :                 OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY);
    2865           0 :         if (xfer->flags & USBD_SHORT_XFER_OK)
    2866           0 :                 data->td.td_flags |= htole32(OHCI_TD_R);
    2867           0 :         data->td.td_cbp = htole32(DMAADDR(&xfer->dmabuf, 0));
    2868           0 :         data->nexttd = tail;
    2869           0 :         data->td.td_nexttd = htole32(tail->physaddr);
    2870           0 :         data->td.td_be = htole32(letoh32(data->td.td_cbp) + len - 1);
    2871           0 :         data->len = len;
    2872           0 :         data->xfer = xfer;
    2873           0 :         data->flags = OHCI_CALL_DONE | OHCI_ADD_LEN;
    2874           0 :         xfer->hcpriv = data;
    2875             : 
    2876             : #ifdef OHCI_DEBUG
    2877             :         if (ohcidebug > 5) {
    2878             :                 DPRINTF(("ohci_device_intr_transfer:\n"));
    2879             :                 ohci_dump_ed(sed);
    2880             :                 ohci_dump_tds(data);
    2881             :         }
    2882             : #endif
    2883             : 
    2884             :         /* Insert ED in schedule */
    2885           0 :         s = splusb();
    2886           0 :         sed->ed.ed_tailp = htole32(tail->physaddr);
    2887           0 :         opipe->tail.td = tail;
    2888           0 :         sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
    2889             : 
    2890             : #if 0
    2891             : /*
    2892             :  * This goes horribly wrong, printing thousands of descriptors,
    2893             :  * because false references are followed due to the fact that the
    2894             :  * TD is gone.
    2895             :  */
    2896             :         if (ohcidebug > 5) {
    2897             :                 usb_delay_ms(&sc->sc_bus, 5);
    2898             :                 DPRINTF(("ohci_device_intr_transfer: status=%x\n",
    2899             :                          OREAD4(sc, OHCI_COMMAND_STATUS)));
    2900             :                 ohci_dump_ed(sed);
    2901             :                 ohci_dump_tds(data);
    2902             :         }
    2903             : #endif
    2904           0 :         splx(s);
    2905             : 
    2906           0 :         return (USBD_IN_PROGRESS);
    2907           0 : }
    2908             : 
    2909             : void
    2910           0 : ohci_device_intr_abort(struct usbd_xfer *xfer)
    2911             : {
    2912           0 :         KASSERT(!xfer->pipe->repeat || xfer->pipe->intrxfer == xfer);
    2913             : 
    2914           0 :         ohci_abort_xfer(xfer, USBD_CANCELLED);
    2915           0 : }
    2916             : 
    2917             : /* Close a device interrupt pipe. */
    2918             : void
    2919           0 : ohci_device_intr_close(struct usbd_pipe *pipe)
    2920             : {
    2921           0 :         struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
    2922           0 :         struct ohci_softc *sc = (struct ohci_softc *)pipe->device->bus;
    2923           0 :         int nslots = opipe->u.intr.nslots;
    2924           0 :         int pos = opipe->u.intr.pos;
    2925             :         int j;
    2926           0 :         struct ohci_soft_ed *p, *sed = opipe->sed;
    2927             :         int s;
    2928             : 
    2929             :         DPRINTFN(1,("ohci_device_intr_close: pipe=%p nslots=%d pos=%d\n",
    2930             :                     pipe, nslots, pos));
    2931           0 :         s = splusb();
    2932           0 :         sed->ed.ed_flags |= htole32(OHCI_ED_SKIP);
    2933           0 :         if ((letoh32(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
    2934           0 :             (letoh32(sed->ed.ed_headp) & OHCI_HEADMASK))
    2935           0 :                 usb_delay_ms(&sc->sc_bus, 2);
    2936             : 
    2937           0 :         for (p = sc->sc_eds[pos]; p && p->next != sed; p = p->next)
    2938             :                 ;
    2939             : #ifdef DIAGNOSTIC
    2940           0 :         if (p == NULL)
    2941           0 :                 panic("ohci_device_intr_close: ED not found");
    2942             : #endif
    2943           0 :         p->next = sed->next;
    2944           0 :         p->ed.ed_nexted = sed->ed.ed_nexted;
    2945           0 :         splx(s);
    2946             : 
    2947           0 :         for (j = 0; j < nslots; j++)
    2948           0 :                 --sc->sc_bws[(pos * nslots + j) % OHCI_NO_INTRS];
    2949             : 
    2950           0 :         ohci_free_std(sc, opipe->tail.td);
    2951           0 :         ohci_free_sed(sc, opipe->sed);
    2952           0 : }
    2953             : 
    2954             : usbd_status
    2955           0 : ohci_device_setintr(struct ohci_softc *sc, struct ohci_pipe *opipe, int ival)
    2956             : {
    2957             :         int i, j, s, best;
    2958             :         u_int npoll, slow, shigh, nslots;
    2959             :         u_int bestbw, bw;
    2960           0 :         struct ohci_soft_ed *hsed, *sed = opipe->sed;
    2961             : 
    2962             :         DPRINTFN(2, ("ohci_setintr: pipe=%p\n", opipe));
    2963           0 :         if (ival == 0) {
    2964           0 :                 printf("ohci_setintr: 0 interval\n");
    2965           0 :                 return (USBD_INVAL);
    2966             :         }
    2967             : 
    2968             :         npoll = OHCI_NO_INTRS;
    2969           0 :         while (npoll > ival)
    2970           0 :                 npoll /= 2;
    2971             :         DPRINTFN(2, ("ohci_setintr: ival=%d npoll=%d\n", ival, npoll));
    2972             : 
    2973             :         /*
    2974             :          * We now know which level in the tree the ED must go into.
    2975             :          * Figure out which slot has most bandwidth left over.
    2976             :          * Slots to examine:
    2977             :          * npoll
    2978             :          * 1    0
    2979             :          * 2    1 2
    2980             :          * 4    3 4 5 6
    2981             :          * 8    7 8 9 10 11 12 13 14
    2982             :          * N    (N-1) .. (N-1+N-1)
    2983             :          */
    2984           0 :         slow = npoll-1;
    2985           0 :         shigh = slow + npoll;
    2986           0 :         nslots = OHCI_NO_INTRS / npoll;
    2987           0 :         for (best = i = slow, bestbw = ~0; i < shigh; i++) {
    2988             :                 bw = 0;
    2989           0 :                 for (j = 0; j < nslots; j++)
    2990           0 :                         bw += sc->sc_bws[(i * nslots + j) % OHCI_NO_INTRS];
    2991           0 :                 if (bw < bestbw) {
    2992             :                         best = i;
    2993             :                         bestbw = bw;
    2994           0 :                 }
    2995             :         }
    2996             :         DPRINTFN(2, ("ohci_setintr: best=%d(%d..%d) bestbw=%d\n",
    2997             :                      best, slow, shigh, bestbw));
    2998             : 
    2999           0 :         s = splusb();
    3000           0 :         hsed = sc->sc_eds[best];
    3001           0 :         sed->next = hsed->next;
    3002           0 :         sed->ed.ed_nexted = hsed->ed.ed_nexted;
    3003           0 :         hsed->next = sed;
    3004           0 :         hsed->ed.ed_nexted = htole32(sed->physaddr);
    3005           0 :         splx(s);
    3006             : 
    3007           0 :         for (j = 0; j < nslots; j++)
    3008           0 :                 ++sc->sc_bws[(best * nslots + j) % OHCI_NO_INTRS];
    3009           0 :         opipe->u.intr.nslots = nslots;
    3010           0 :         opipe->u.intr.pos = best;
    3011             : 
    3012             :         DPRINTFN(5, ("ohci_setintr: returns %p\n", opipe));
    3013           0 :         return (USBD_NORMAL_COMPLETION);
    3014           0 : }
    3015             : 
    3016             : /***********************/
    3017             : 
    3018             : usbd_status
    3019           0 : ohci_device_isoc_transfer(struct usbd_xfer *xfer)
    3020             : {
    3021             :         usbd_status err;
    3022             : 
    3023             :         DPRINTFN(5,("ohci_device_isoc_transfer: xfer=%p\n", xfer));
    3024             : 
    3025             :         /* Put it on our queue, */
    3026           0 :         err = usb_insert_transfer(xfer);
    3027             : 
    3028             :         /* bail out on error, */
    3029           0 :         if (err && err != USBD_IN_PROGRESS)
    3030           0 :                 return (err);
    3031             : 
    3032             :         /* XXX should check inuse here */
    3033             : 
    3034             :         /* insert into schedule, */
    3035           0 :         ohci_device_isoc_enter(xfer);
    3036             : 
    3037             :         /* and start if the pipe wasn't running */
    3038           0 :         if (!err)
    3039           0 :                 ohci_device_isoc_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
    3040             : 
    3041           0 :         return (err);
    3042           0 : }
    3043             : 
    3044             : void
    3045           0 : ohci_device_isoc_enter(struct usbd_xfer *xfer)
    3046             : {
    3047           0 :         struct ohci_softc *sc = (struct ohci_softc *)xfer->device->bus;
    3048           0 :         struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
    3049           0 :         struct ohci_soft_ed *sed = opipe->sed;
    3050           0 :         struct iso *iso = &opipe->u.iso;
    3051             :         struct ohci_soft_itd *sitd, *nsitd;
    3052             :         ohci_physaddr_t buf, offs, noffs, bp0;
    3053             :         int i, ncur, nframes;
    3054             :         int s;
    3055             : 
    3056             :         DPRINTFN(1,("ohci_device_isoc_enter: used=%d next=%d xfer=%p "
    3057             :                     "nframes=%d\n",
    3058             :                     iso->inuse, iso->next, xfer, xfer->nframes));
    3059             : 
    3060           0 :         if (sc->sc_bus.dying)
    3061           0 :                 return;
    3062             : 
    3063           0 :         if (iso->next == -1) {
    3064             :                 /* Not in use yet, schedule it a few frames ahead. */
    3065           0 :                 iso->next = letoh32(sc->sc_hcca->hcca_frame_number) + 5;
    3066             :                 DPRINTFN(2,("ohci_device_isoc_enter: start next=%d\n",
    3067             :                             iso->next));
    3068           0 :         }
    3069             : 
    3070           0 :         sitd = opipe->tail.itd;
    3071           0 :         buf = DMAADDR(&xfer->dmabuf, 0);
    3072           0 :         bp0 = OHCI_PAGE(buf);
    3073           0 :         offs = OHCI_PAGE_OFFSET(buf);
    3074           0 :         nframes = xfer->nframes;
    3075           0 :         xfer->hcpriv = sitd;
    3076           0 :         for (i = ncur = 0; i < nframes; i++, ncur++) {
    3077           0 :                 noffs = offs + xfer->frlengths[i];
    3078           0 :                 if (ncur == OHCI_ITD_NOFFSET || /* all offsets used */
    3079           0 :                     OHCI_PAGE(buf + noffs) > bp0 + OHCI_PAGE_SIZE) { /* too many page crossings */
    3080             : 
    3081             :                         /* Allocate next ITD */
    3082           0 :                         nsitd = ohci_alloc_sitd(sc);
    3083           0 :                         if (nsitd == NULL) {
    3084             :                                 /* XXX what now? */
    3085           0 :                                 printf("%s: isoc TD alloc failed\n",
    3086           0 :                                        sc->sc_bus.bdev.dv_xname);
    3087           0 :                                 return;
    3088             :                         }
    3089             : 
    3090             :                         /* Fill current ITD */
    3091           0 :                         sitd->itd.itd_flags = htole32(
    3092             :                                 OHCI_ITD_NOCC |
    3093             :                                 OHCI_ITD_SET_SF(iso->next) |
    3094             :                                 OHCI_ITD_SET_DI(6) | /* delay intr a little */
    3095             :                                 OHCI_ITD_SET_FC(ncur));
    3096           0 :                         sitd->itd.itd_bp0 = htole32(bp0);
    3097           0 :                         sitd->nextitd = nsitd;
    3098           0 :                         sitd->itd.itd_nextitd = htole32(nsitd->physaddr);
    3099           0 :                         sitd->itd.itd_be = htole32(bp0 + offs - 1);
    3100           0 :                         sitd->xfer = xfer;
    3101           0 :                         sitd->flags = 0;
    3102             : 
    3103             :                         sitd = nsitd;
    3104           0 :                         iso->next = iso->next + ncur;
    3105           0 :                         bp0 = OHCI_PAGE(buf + offs);
    3106             :                         ncur = 0;
    3107           0 :                 }
    3108           0 :                 sitd->itd.itd_offset[ncur] = htole16(OHCI_ITD_MK_OFFS(offs));
    3109             :                 offs = noffs;
    3110             :         }
    3111           0 :         nsitd = ohci_alloc_sitd(sc);
    3112           0 :         if (nsitd == NULL) {
    3113             :                 /* XXX what now? */
    3114           0 :                 printf("%s: isoc TD alloc failed\n",
    3115           0 :                        sc->sc_bus.bdev.dv_xname);
    3116           0 :                 return;
    3117             :         }
    3118             :         /* Fixup last used ITD */
    3119           0 :         sitd->itd.itd_flags = htole32(
    3120             :                 OHCI_ITD_NOCC |
    3121             :                 OHCI_ITD_SET_SF(iso->next) |
    3122             :                 OHCI_ITD_SET_DI(0) |
    3123             :                 OHCI_ITD_SET_FC(ncur));
    3124           0 :         sitd->itd.itd_bp0 = htole32(bp0);
    3125           0 :         sitd->nextitd = nsitd;
    3126           0 :         sitd->itd.itd_nextitd = htole32(nsitd->physaddr);
    3127           0 :         sitd->itd.itd_be = htole32(bp0 + offs - 1);
    3128           0 :         sitd->xfer = xfer;
    3129           0 :         sitd->flags = OHCI_CALL_DONE;
    3130             : 
    3131           0 :         iso->next = iso->next + ncur;
    3132           0 :         iso->inuse += nframes;
    3133             : 
    3134           0 :         xfer->actlen = offs; /* XXX pretend we did it all */
    3135             : 
    3136           0 :         xfer->status = USBD_IN_PROGRESS;
    3137             : 
    3138             : #ifdef OHCI_DEBUG
    3139             :         if (ohcidebug > 5) {
    3140             :                 DPRINTF(("ohci_device_isoc_enter: frame=%d\n",
    3141             :                          letoh32(sc->sc_hcca->hcca_frame_number)));
    3142             :                 ohci_dump_itds(xfer->hcpriv);
    3143             :                 ohci_dump_ed(sed);
    3144             :         }
    3145             : #endif
    3146             : 
    3147           0 :         s = splusb();
    3148           0 :         sed->ed.ed_tailp = htole32(nsitd->physaddr);
    3149           0 :         opipe->tail.itd = nsitd;
    3150           0 :         sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
    3151           0 :         splx(s);
    3152             : 
    3153             : #ifdef OHCI_DEBUG
    3154             :         if (ohcidebug > 5) {
    3155             :                 delay(150000);
    3156             :                 DPRINTF(("ohci_device_isoc_enter: after frame=%d\n",
    3157             :                          letoh32(sc->sc_hcca->hcca_frame_number)));
    3158             :                 ohci_dump_itds(xfer->hcpriv);
    3159             :                 ohci_dump_ed(sed);
    3160             :         }
    3161             : #endif
    3162           0 : }
    3163             : 
    3164             : usbd_status
    3165           0 : ohci_device_isoc_start(struct usbd_xfer *xfer)
    3166             : {
    3167           0 :         struct ohci_softc *sc = (struct ohci_softc *)xfer->device->bus;
    3168             : 
    3169             :         DPRINTFN(5,("ohci_device_isoc_start: xfer=%p\n", xfer));
    3170             : 
    3171           0 :         if (sc->sc_bus.dying)
    3172           0 :                 return (USBD_IOERROR);
    3173             : 
    3174             : #ifdef DIAGNOSTIC
    3175           0 :         if (xfer->status != USBD_IN_PROGRESS)
    3176           0 :                 printf("ohci_device_isoc_start: not in progress %p\n", xfer);
    3177             : #endif
    3178             : 
    3179           0 :         return (USBD_IN_PROGRESS);
    3180           0 : }
    3181             : 
    3182             : void
    3183           0 : ohci_device_isoc_abort(struct usbd_xfer *xfer)
    3184             : {
    3185           0 :         struct ohci_softc *sc = (struct ohci_softc *)xfer->device->bus;
    3186           0 :         struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
    3187             :         struct ohci_soft_ed *sed;
    3188             :         struct ohci_soft_itd *sitd;
    3189             :         int s;
    3190             : 
    3191           0 :         s = splusb();
    3192             : 
    3193             :         DPRINTFN(1,("ohci_device_isoc_abort: xfer=%p\n", xfer));
    3194             : 
    3195             :         /* Transfer is already done. */
    3196           0 :         if (xfer->status != USBD_NOT_STARTED &&
    3197           0 :             xfer->status != USBD_IN_PROGRESS) {
    3198           0 :                 splx(s);
    3199           0 :                 printf("ohci_device_isoc_abort: early return\n");
    3200           0 :                 return;
    3201             :         }
    3202             : 
    3203             :         /* Give xfer the requested abort code. */
    3204           0 :         xfer->status = USBD_CANCELLED;
    3205             : 
    3206           0 :         sed = opipe->sed;
    3207           0 :         sed->ed.ed_flags |= htole32(OHCI_ED_SKIP); /* force hardware skip */
    3208             : 
    3209           0 :         sitd = xfer->hcpriv;
    3210             : #ifdef DIAGNOSTIC
    3211           0 :         if (sitd == NULL) {
    3212           0 :                 splx(s);
    3213           0 :                 printf("ohci_device_isoc_abort: hcpriv==0\n");
    3214           0 :                 return;
    3215             :         }
    3216             : #endif
    3217           0 :         for (; sitd->xfer == xfer; sitd = sitd->nextitd) {
    3218             : #ifdef DIAGNOSTIC
    3219             :                 DPRINTFN(1,("abort sets done sitd=%p\n", sitd));
    3220           0 :                 sitd->isdone = 1;
    3221             : #endif
    3222             :         }
    3223             : 
    3224           0 :         splx(s);
    3225             : 
    3226           0 :         usb_delay_ms(&sc->sc_bus, OHCI_ITD_NOFFSET);
    3227             : 
    3228           0 :         s = splusb();
    3229             : 
    3230             :         /* Run callback. */
    3231           0 :         usb_transfer_complete(xfer);
    3232             : 
    3233           0 :         sed->ed.ed_headp = htole32(sitd->physaddr); /* unlink TDs */
    3234           0 :         sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); /* remove hardware skip */
    3235             : 
    3236           0 :         splx(s);
    3237           0 : }
    3238             : 
    3239             : void
    3240           0 : ohci_device_isoc_done(struct usbd_xfer *xfer)
    3241             : {
    3242             :         DPRINTFN(1,("ohci_device_isoc_done: xfer=%p\n", xfer));
    3243           0 : }
    3244             : 
    3245             : usbd_status
    3246           0 : ohci_setup_isoc(struct usbd_pipe *pipe)
    3247             : {
    3248           0 :         struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
    3249           0 :         struct ohci_softc *sc = (struct ohci_softc *)pipe->device->bus;
    3250           0 :         struct iso *iso = &opipe->u.iso;
    3251             :         int s;
    3252             : 
    3253           0 :         iso->next = -1;
    3254           0 :         iso->inuse = 0;
    3255             : 
    3256           0 :         s = splusb();
    3257           0 :         ohci_add_ed(opipe->sed, sc->sc_isoc_head);
    3258           0 :         splx(s);
    3259             : 
    3260           0 :         return (USBD_NORMAL_COMPLETION);
    3261             : }
    3262             : 
    3263             : void
    3264           0 : ohci_device_isoc_close(struct usbd_pipe *pipe)
    3265             : {
    3266           0 :         struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
    3267           0 :         struct ohci_softc *sc = (struct ohci_softc *)pipe->device->bus;
    3268             : 
    3269             :         DPRINTF(("ohci_device_isoc_close: pipe=%p\n", pipe));
    3270           0 :         ohci_close_pipe(pipe, sc->sc_isoc_head);
    3271             : #ifdef DIAGNOSTIC
    3272           0 :         opipe->tail.itd->isdone = 1;
    3273             : #endif
    3274           0 :         ohci_free_sitd(sc, opipe->tail.itd);
    3275           0 : }

Generated by: LCOV version 1.13