The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/firewire/fwohci.c

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

    1 /*-
    2  * SPDX-License-Identifier: BSD-4-Clause
    3  *
    4  * Copyright (c) 2003 Hidetoshi Shimokawa
    5  * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the acknowledgement as bellow:
   18  *
   19  *    This product includes software developed by K. Kobayashi and H. Shimokawa
   20  *
   21  * 4. The name of the author may not be used to endorse or promote products
   22  *    derived from this software without specific prior written permission.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   26  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   27  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
   28  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   29  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   30  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   32  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   34  * POSSIBILITY OF SUCH DAMAGE.
   35  *
   36  * $FreeBSD$
   37  *
   38  */
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/lock.h>
   43 #include <sys/mbuf.h>
   44 #include <sys/malloc.h>
   45 #include <sys/sockio.h>
   46 #include <sys/sysctl.h>
   47 #include <sys/bus.h>
   48 #include <sys/kernel.h>
   49 #include <sys/conf.h>
   50 #include <sys/endian.h>
   51 #include <sys/kdb.h>
   52 
   53 #include <machine/bus.h>
   54 #include <machine/md_var.h>
   55 
   56 #include <dev/firewire/firewire.h>
   57 #include <dev/firewire/firewirereg.h>
   58 #include <dev/firewire/fwdma.h>
   59 #include <dev/firewire/fwohcireg.h>
   60 #include <dev/firewire/fwohcivar.h>
   61 #include <dev/firewire/firewire_phy.h>
   62 
   63 #undef OHCI_DEBUG
   64 
   65 static int nocyclemaster;
   66 int firewire_phydma_enable = 1;
   67 SYSCTL_DECL(_hw_firewire);
   68 SYSCTL_INT(_hw_firewire, OID_AUTO, nocyclemaster, CTLFLAG_RWTUN,
   69         &nocyclemaster, 0, "Do not send cycle start packets");
   70 SYSCTL_INT(_hw_firewire, OID_AUTO, phydma_enable, CTLFLAG_RWTUN,
   71         &firewire_phydma_enable, 0, "Allow physical request DMA from firewire");
   72 
   73 static char dbcode[16][0x10] = {"OUTM", "OUTL", "INPM", "INPL",
   74                                 "STOR", "LOAD", "NOP ", "STOP",};
   75 
   76 static char dbkey[8][0x10] = {"ST0", "ST1", "ST2", "ST3",
   77                               "UNDEF", "REG", "SYS", "DEV"};
   78 static char dbcond[4][0x10] = {"NEV", "C=1", "C=0", "ALL"};
   79 char fwohcicode[32][0x20]= {
   80         "No stat", "Undef", "long", "miss Ack err",
   81         "FIFO underrun", "FIFO overrun", "desc err", "data read err",
   82         "data write err", "bus reset", "timeout", "tcode err",
   83         "Undef", "Undef", "unknown event", "flushed",
   84         "Undef" ,"ack complete", "ack pend", "Undef",
   85         "ack busy_X", "ack busy_A", "ack busy_B", "Undef",
   86         "Undef", "Undef", "Undef", "ack tardy",
   87         "Undef", "ack data_err", "ack type_err", ""};
   88 
   89 #define MAX_SPEED 3
   90 extern char *linkspeed[];
   91 uint32_t tagbit[4] = {1 << 28, 1 << 29, 1 << 30, 1 << 31};
   92 
   93 static struct tcode_info tinfo[] = {
   94 /*              hdr_len block   flag    valid_response */
   95 /* 0 WREQQ  */ {16,     FWTI_REQ | FWTI_TLABEL, FWTCODE_WRES},
   96 /* 1 WREQB  */ {16,     FWTI_REQ | FWTI_TLABEL | FWTI_BLOCK_ASY, FWTCODE_WRES},
   97 /* 2 WRES   */ {12,     FWTI_RES, 0xff},
   98 /* 3 XXX    */ { 0,     0, 0xff},
   99 /* 4 RREQQ  */ {12,     FWTI_REQ | FWTI_TLABEL, FWTCODE_RRESQ},
  100 /* 5 RREQB  */ {16,     FWTI_REQ | FWTI_TLABEL, FWTCODE_RRESB},
  101 /* 6 RRESQ  */ {16,     FWTI_RES, 0xff},
  102 /* 7 RRESB  */ {16,     FWTI_RES | FWTI_BLOCK_ASY, 0xff},
  103 /* 8 CYCS   */ { 0,     0, 0xff},
  104 /* 9 LREQ   */ {16,     FWTI_REQ | FWTI_TLABEL | FWTI_BLOCK_ASY, FWTCODE_LRES},
  105 /* a STREAM */ { 4,     FWTI_REQ | FWTI_BLOCK_STR, 0xff},
  106 /* b LRES   */ {16,     FWTI_RES | FWTI_BLOCK_ASY, 0xff},
  107 /* c XXX    */ { 0,     0, 0xff},
  108 /* d XXX    */ { 0,     0, 0xff},
  109 /* e PHY    */ {12,     FWTI_REQ, 0xff},
  110 /* f XXX    */ { 0,     0, 0xff}
  111 };
  112 
  113 #define ATRQ_CH 0
  114 #define ATRS_CH 1
  115 #define ARRQ_CH 2
  116 #define ARRS_CH 3
  117 #define ITX_CH 4
  118 #define IRX_CH 0x24
  119 
  120 #define OHCI_WRITE_SIGMASK 0xffff0000
  121 #define OHCI_READ_SIGMASK 0xffff0000
  122 
  123 #define OWRITE(sc, r, x) bus_space_write_4((sc)->bst, (sc)->bsh, (r), (x))
  124 #define OREAD(sc, r) bus_space_read_4((sc)->bst, (sc)->bsh, (r))
  125 
  126 static void fwohci_ibr (struct firewire_comm *);
  127 static void fwohci_db_init (struct fwohci_softc *, struct fwohci_dbch *);
  128 static void fwohci_db_free (struct fwohci_dbch *);
  129 static void fwohci_arcv (struct fwohci_softc *, struct fwohci_dbch *, int);
  130 static void fwohci_txd (struct fwohci_softc *, struct fwohci_dbch *);
  131 static void fwohci_start_atq (struct firewire_comm *);
  132 static void fwohci_start_ats (struct firewire_comm *);
  133 static void fwohci_start (struct fwohci_softc *, struct fwohci_dbch *);
  134 static uint32_t fwphy_wrdata (struct fwohci_softc *, uint32_t, uint32_t);
  135 static uint32_t fwphy_rddata (struct fwohci_softc *, uint32_t);
  136 static int fwohci_rx_enable (struct fwohci_softc *, struct fwohci_dbch *);
  137 static int fwohci_tx_enable (struct fwohci_softc *, struct fwohci_dbch *);
  138 static int fwohci_irx_enable (struct firewire_comm *, int);
  139 static int fwohci_irx_disable (struct firewire_comm *, int);
  140 #if BYTE_ORDER == BIG_ENDIAN
  141 static void fwohci_irx_post (struct firewire_comm *, uint32_t *);
  142 #endif
  143 static int fwohci_itxbuf_enable (struct firewire_comm *, int);
  144 static int fwohci_itx_disable (struct firewire_comm *, int);
  145 static void fwohci_timeout (void *);
  146 static void fwohci_set_intr (struct firewire_comm *, int);
  147 
  148 static int fwohci_add_rx_buf (struct fwohci_dbch *, struct fwohcidb_tr *, int, struct fwdma_alloc *);
  149 static int fwohci_add_tx_buf (struct fwohci_dbch *, struct fwohcidb_tr *, int);
  150 static void dump_db (struct fwohci_softc *, uint32_t);
  151 static void print_db (struct fwohcidb_tr *, struct fwohcidb *, uint32_t , uint32_t);
  152 static void dump_dma (struct fwohci_softc *, uint32_t);
  153 static uint32_t fwohci_cyctimer (struct firewire_comm *);
  154 static void fwohci_rbuf_update (struct fwohci_softc *, int);
  155 static void fwohci_tbuf_update (struct fwohci_softc *, int);
  156 void fwohci_txbufdb (struct fwohci_softc *, int , struct fw_bulkxfer *);
  157 static void fwohci_task_busreset(void *, int);
  158 static void fwohci_task_sid(void *, int);
  159 static void fwohci_task_dma(void *, int);
  160 
  161 /*
  162  * memory allocated for DMA programs
  163  */
  164 #define DMA_PROG_ALLOC          (8 * PAGE_SIZE)
  165 
  166 #define NDB FWMAXQUEUE
  167 
  168 #define OHCI_VERSION            0x00
  169 #define OHCI_ATRETRY            0x08
  170 #define OHCI_CROMHDR            0x18
  171 #define OHCI_BUS_OPT            0x20
  172 #define OHCI_BUSIRMC            (1U << 31)
  173 #define OHCI_BUSCMC             (1 << 30)
  174 #define OHCI_BUSISC             (1 << 29)
  175 #define OHCI_BUSBMC             (1 << 28)
  176 #define OHCI_BUSPMC             (1 << 27)
  177 #define OHCI_BUSFNC             OHCI_BUSIRMC | OHCI_BUSCMC | OHCI_BUSISC |\
  178                                 OHCI_BUSBMC | OHCI_BUSPMC
  179 
  180 #define OHCI_EUID_HI            0x24
  181 #define OHCI_EUID_LO            0x28
  182 
  183 #define OHCI_CROMPTR            0x34
  184 #define OHCI_HCCCTL             0x50
  185 #define OHCI_HCCCTLCLR          0x54
  186 #define OHCI_AREQHI             0x100
  187 #define OHCI_AREQHICLR          0x104
  188 #define OHCI_AREQLO             0x108
  189 #define OHCI_AREQLOCLR          0x10c
  190 #define OHCI_PREQHI             0x110
  191 #define OHCI_PREQHICLR          0x114
  192 #define OHCI_PREQLO             0x118
  193 #define OHCI_PREQLOCLR          0x11c
  194 #define OHCI_PREQUPPER          0x120
  195 #define OHCI_PREQUPPER_MAX      0xffff0000
  196 
  197 #define OHCI_SID_BUF            0x64
  198 #define OHCI_SID_CNT            0x68
  199 #define OHCI_SID_ERR            (1U << 31)
  200 #define OHCI_SID_CNT_MASK       0xffc
  201 
  202 #define OHCI_IT_STAT            0x90
  203 #define OHCI_IT_STATCLR         0x94
  204 #define OHCI_IT_MASK            0x98
  205 #define OHCI_IT_MASKCLR         0x9c
  206 
  207 #define OHCI_IR_STAT            0xa0
  208 #define OHCI_IR_STATCLR         0xa4
  209 #define OHCI_IR_MASK            0xa8
  210 #define OHCI_IR_MASKCLR         0xac
  211 
  212 #define OHCI_LNKCTL             0xe0
  213 #define OHCI_LNKCTLCLR          0xe4
  214 
  215 #define OHCI_PHYACCESS          0xec
  216 #define OHCI_CYCLETIMER         0xf0
  217 
  218 #define OHCI_DMACTL(off)        (off)
  219 #define OHCI_DMACTLCLR(off)     (off + 4)
  220 #define OHCI_DMACMD(off)        (off + 0xc)
  221 #define OHCI_DMAMATCH(off)      (off + 0x10)
  222 
  223 #define OHCI_ATQOFF             0x180
  224 #define OHCI_ATQCTL             OHCI_ATQOFF
  225 #define OHCI_ATQCTLCLR          (OHCI_ATQOFF + 4)
  226 #define OHCI_ATQCMD             (OHCI_ATQOFF + 0xc)
  227 #define OHCI_ATQMATCH           (OHCI_ATQOFF + 0x10)
  228 
  229 #define OHCI_ATSOFF             0x1a0
  230 #define OHCI_ATSCTL             OHCI_ATSOFF
  231 #define OHCI_ATSCTLCLR          (OHCI_ATSOFF + 4)
  232 #define OHCI_ATSCMD             (OHCI_ATSOFF + 0xc)
  233 #define OHCI_ATSMATCH           (OHCI_ATSOFF + 0x10)
  234 
  235 #define OHCI_ARQOFF             0x1c0
  236 #define OHCI_ARQCTL             OHCI_ARQOFF
  237 #define OHCI_ARQCTLCLR          (OHCI_ARQOFF + 4)
  238 #define OHCI_ARQCMD             (OHCI_ARQOFF + 0xc)
  239 #define OHCI_ARQMATCH           (OHCI_ARQOFF + 0x10)
  240 
  241 #define OHCI_ARSOFF             0x1e0
  242 #define OHCI_ARSCTL             OHCI_ARSOFF
  243 #define OHCI_ARSCTLCLR          (OHCI_ARSOFF + 4)
  244 #define OHCI_ARSCMD             (OHCI_ARSOFF + 0xc)
  245 #define OHCI_ARSMATCH           (OHCI_ARSOFF + 0x10)
  246 
  247 #define OHCI_ITOFF(CH)          (0x200 + 0x10 * (CH))
  248 #define OHCI_ITCTL(CH)          (OHCI_ITOFF(CH))
  249 #define OHCI_ITCTLCLR(CH)       (OHCI_ITOFF(CH) + 4)
  250 #define OHCI_ITCMD(CH)          (OHCI_ITOFF(CH) + 0xc)
  251 
  252 #define OHCI_IROFF(CH)          (0x400 + 0x20 * (CH))
  253 #define OHCI_IRCTL(CH)          (OHCI_IROFF(CH))
  254 #define OHCI_IRCTLCLR(CH)       (OHCI_IROFF(CH) + 4)
  255 #define OHCI_IRCMD(CH)          (OHCI_IROFF(CH) + 0xc)
  256 #define OHCI_IRMATCH(CH)        (OHCI_IROFF(CH) + 0x10)
  257 
  258 d_ioctl_t fwohci_ioctl;
  259 
  260 /*
  261  * Communication with PHY device
  262  */
  263 /* XXX need lock for phy access */
  264 static uint32_t
  265 fwphy_wrdata(struct fwohci_softc *sc, uint32_t addr, uint32_t data)
  266 {
  267         uint32_t fun;
  268 
  269         addr &= 0xf;
  270         data &= 0xff;
  271 
  272         fun = (PHYDEV_WRCMD | (addr << PHYDEV_REGADDR) |
  273               (data << PHYDEV_WRDATA));
  274         OWRITE(sc, OHCI_PHYACCESS, fun);
  275         DELAY(100);
  276 
  277         return (fwphy_rddata(sc, addr));
  278 }
  279 
  280 static uint32_t
  281 fwohci_set_bus_manager(struct firewire_comm *fc, u_int node)
  282 {
  283         struct fwohci_softc *sc = (struct fwohci_softc *)fc;
  284         int i;
  285         uint32_t bm;
  286 
  287 #define OHCI_CSR_DATA   0x0c
  288 #define OHCI_CSR_COMP   0x10
  289 #define OHCI_CSR_CONT   0x14
  290 #define OHCI_BUS_MANAGER_ID     0
  291 
  292         OWRITE(sc, OHCI_CSR_DATA, node);
  293         OWRITE(sc, OHCI_CSR_COMP, 0x3f);
  294         OWRITE(sc, OHCI_CSR_CONT, OHCI_BUS_MANAGER_ID);
  295         for (i = 0; !(OREAD(sc, OHCI_CSR_CONT) & (1<<31)) && (i < 1000); i++)
  296                 DELAY(10);
  297         bm = OREAD(sc, OHCI_CSR_DATA);
  298         if ((bm & 0x3f) == 0x3f)
  299                 bm = node;
  300         if (firewire_debug)
  301                 device_printf(sc->fc.dev, "%s: %d->%d (loop=%d)\n",
  302                                 __func__, bm, node, i);
  303         return (bm);
  304 }
  305 
  306 static uint32_t
  307 fwphy_rddata(struct fwohci_softc *sc, u_int addr)
  308 {
  309         uint32_t fun, stat;
  310         u_int i, retry = 0;
  311 
  312         addr &= 0xf;
  313 #define MAX_RETRY 100
  314 again:
  315         OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_REG_FAIL);
  316         fun = PHYDEV_RDCMD | (addr << PHYDEV_REGADDR);
  317         OWRITE(sc, OHCI_PHYACCESS, fun);
  318         for (i = 0; i < MAX_RETRY; i++) {
  319                 fun = OREAD(sc, OHCI_PHYACCESS);
  320                 if ((fun & PHYDEV_RDCMD) == 0 && (fun & PHYDEV_RDDONE) != 0)
  321                         break;
  322                 DELAY(100);
  323         }
  324         if (i >= MAX_RETRY) {
  325                 if (firewire_debug)
  326                         device_printf(sc->fc.dev, "%s: failed(1).\n", __func__);
  327                 if (++retry < MAX_RETRY) {
  328                         DELAY(100);
  329                         goto again;
  330                 }
  331         }
  332         /* Make sure that SCLK is started */
  333         stat = OREAD(sc, FWOHCI_INTSTAT);
  334         if ((stat & OHCI_INT_REG_FAIL) != 0 ||
  335                         ((fun >> PHYDEV_REGADDR) & 0xf) != addr) {
  336                 if (firewire_debug)
  337                         device_printf(sc->fc.dev, "%s: failed(2).\n", __func__);
  338                 if (++retry < MAX_RETRY) {
  339                         DELAY(100);
  340                         goto again;
  341                 }
  342         }
  343         if (firewire_debug > 1 || retry >= MAX_RETRY)
  344                 device_printf(sc->fc.dev,
  345                     "%s:: 0x%x loop=%d, retry=%d\n",
  346                         __func__, addr, i, retry);
  347 #undef MAX_RETRY
  348         return ((fun >> PHYDEV_RDDATA) & 0xff);
  349 }
  350 
  351 /* Device specific ioctl. */
  352 int
  353 fwohci_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, fw_proc *td)
  354 {
  355         struct firewire_softc *sc;
  356         struct fwohci_softc *fc;
  357         int unit = DEV2UNIT(dev);
  358         int err = 0;
  359         struct fw_reg_req_t *reg = (struct fw_reg_req_t *) data;
  360         uint32_t *dmach = (uint32_t *) data;
  361 
  362         sc = devclass_get_softc(firewire_devclass, unit);
  363         if (sc == NULL)
  364                 return (EINVAL);
  365 
  366         fc = (struct fwohci_softc *)sc->fc;
  367 
  368         if (!data)
  369                 return (EINVAL);
  370 
  371         switch (cmd) {
  372         case FWOHCI_WRREG:
  373 #define OHCI_MAX_REG 0x800
  374                 if (reg->addr <= OHCI_MAX_REG) {
  375                         OWRITE(fc, reg->addr, reg->data);
  376                         reg->data = OREAD(fc, reg->addr);
  377                 } else {
  378                         err = EINVAL;
  379                 }
  380                 break;
  381         case FWOHCI_RDREG:
  382                 if (reg->addr <= OHCI_MAX_REG) {
  383                         reg->data = OREAD(fc, reg->addr);
  384                 } else {
  385                         err = EINVAL;
  386                 }
  387                 break;
  388 /* Read DMA descriptors for debug  */
  389         case DUMPDMA:
  390                 if (*dmach <= OHCI_MAX_DMA_CH) {
  391                         dump_dma(fc, *dmach);
  392                         dump_db(fc, *dmach);
  393                 } else {
  394                         err = EINVAL;
  395                 }
  396                 break;
  397 /* Read/Write Phy registers */
  398 #define OHCI_MAX_PHY_REG 0xf
  399         case FWOHCI_RDPHYREG:
  400                 if (reg->addr <= OHCI_MAX_PHY_REG)
  401                         reg->data = fwphy_rddata(fc, reg->addr);
  402                 else
  403                         err = EINVAL;
  404                 break;
  405         case FWOHCI_WRPHYREG:
  406                 if (reg->addr <= OHCI_MAX_PHY_REG)
  407                         reg->data = fwphy_wrdata(fc, reg->addr, reg->data);
  408                 else
  409                         err = EINVAL;
  410                 break;
  411         default:
  412                 err = EINVAL;
  413                 break;
  414         }
  415         return err;
  416 }
  417 
  418 static int
  419 fwohci_probe_phy(struct fwohci_softc *sc, device_t dev)
  420 {
  421         uint32_t reg, reg2;
  422         int e1394a = 1;
  423 
  424         /*
  425          * probe PHY parameters
  426          * 0. to prove PHY version, whether compliance of 1394a.
  427          * 1. to probe maximum speed supported by the PHY and
  428          *    number of port supported by core-logic.
  429          *    It is not actually available port on your PC .
  430          */
  431         OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LPS);
  432         DELAY(500);
  433 
  434         reg = fwphy_rddata(sc, FW_PHY_SPD_REG);
  435 
  436         if ((reg >> 5) != 7) {
  437                 sc->fc.mode &= ~FWPHYASYST;
  438                 sc->fc.nport = reg & FW_PHY_NP;
  439                 sc->fc.speed = reg & FW_PHY_SPD >> 6;
  440                 if (sc->fc.speed > MAX_SPEED) {
  441                         device_printf(dev, "invalid speed %d (fixed to %d).\n",
  442                                 sc->fc.speed, MAX_SPEED);
  443                         sc->fc.speed = MAX_SPEED;
  444                 }
  445                 device_printf(dev,
  446                         "Phy 1394 only %s, %d ports.\n",
  447                         linkspeed[sc->fc.speed], sc->fc.nport);
  448         } else {
  449                 reg2 = fwphy_rddata(sc, FW_PHY_ESPD_REG);
  450                 sc->fc.mode |= FWPHYASYST;
  451                 sc->fc.nport = reg & FW_PHY_NP;
  452                 sc->fc.speed = (reg2 & FW_PHY_ESPD) >> 5;
  453                 if (sc->fc.speed > MAX_SPEED) {
  454                         device_printf(dev, "invalid speed %d (fixed to %d).\n",
  455                                 sc->fc.speed, MAX_SPEED);
  456                         sc->fc.speed = MAX_SPEED;
  457                 }
  458                 device_printf(dev,
  459                         "Phy 1394a available %s, %d ports.\n",
  460                         linkspeed[sc->fc.speed], sc->fc.nport);
  461 
  462                 /* check programPhyEnable */
  463                 reg2 = fwphy_rddata(sc, 5);
  464 #if 0
  465                 if (e1394a && (OREAD(sc, OHCI_HCCCTL) & OHCI_HCC_PRPHY)) {
  466 #else   /* XXX force to enable 1394a */
  467                 if (e1394a) {
  468 #endif
  469                         if (firewire_debug)
  470                                 device_printf(dev,
  471                                         "Enable 1394a Enhancements\n");
  472                         /* enable EAA EMC */
  473                         reg2 |= 0x03;
  474                         /* set aPhyEnhanceEnable */
  475                         OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_PHYEN);
  476                         OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_PRPHY);
  477                 } else {
  478                         /* for safe */
  479                         reg2 &= ~0x83;
  480                 }
  481                 reg2 = fwphy_wrdata(sc, 5, reg2);
  482         }
  483 
  484         reg = fwphy_rddata(sc, FW_PHY_SPD_REG);
  485         if ((reg >> 5) == 7) {
  486                 reg = fwphy_rddata(sc, 4);
  487                 reg |= 1 << 6;
  488                 fwphy_wrdata(sc, 4, reg);
  489                 reg = fwphy_rddata(sc, 4);
  490         }
  491         return 0;
  492 }
  493 
  494 
  495 void
  496 fwohci_reset(struct fwohci_softc *sc, device_t dev)
  497 {
  498         int i, max_rec, speed;
  499         uint32_t reg, reg2;
  500         struct fwohcidb_tr *db_tr;
  501 
  502         /* Disable interrupts */
  503         OWRITE(sc, FWOHCI_INTMASKCLR, ~0);
  504 
  505         /* Now stopping all DMA channels */
  506         OWRITE(sc, OHCI_ARQCTLCLR, OHCI_CNTL_DMA_RUN);
  507         OWRITE(sc, OHCI_ARSCTLCLR, OHCI_CNTL_DMA_RUN);
  508         OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN);
  509         OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN);
  510 
  511         OWRITE(sc, OHCI_IR_MASKCLR, ~0);
  512         for (i = 0; i < sc->fc.nisodma; i++) {
  513                 OWRITE(sc, OHCI_IRCTLCLR(i), OHCI_CNTL_DMA_RUN);
  514                 OWRITE(sc, OHCI_ITCTLCLR(i), OHCI_CNTL_DMA_RUN);
  515         }
  516 
  517         /* FLUSH FIFO and reset Transmitter/Receiver */
  518         OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_RESET);
  519         if (firewire_debug)
  520                 device_printf(dev, "resetting OHCI...");
  521         i = 0;
  522         while (OREAD(sc, OHCI_HCCCTL) & OHCI_HCC_RESET) {
  523                 if (i++ > 100) break;
  524                 DELAY(1000);
  525         }
  526         if (firewire_debug)
  527                 printf("done (loop=%d)\n", i);
  528 
  529         /* Probe phy */
  530         fwohci_probe_phy(sc, dev);
  531 
  532         /* Probe link */
  533         reg = OREAD(sc, OHCI_BUS_OPT);
  534         reg2 = reg | OHCI_BUSFNC;
  535         max_rec = (reg & 0x0000f000) >> 12;
  536         speed = (reg & 0x00000007);
  537         device_printf(dev, "Link %s, max_rec %d bytes.\n",
  538                         linkspeed[speed], MAXREC(max_rec));
  539         /* XXX fix max_rec */
  540         sc->fc.maxrec = sc->fc.speed + 8;
  541         if (max_rec != sc->fc.maxrec) {
  542                 reg2 = (reg2 & 0xffff0fff) | (sc->fc.maxrec << 12);
  543                 device_printf(dev, "max_rec %d -> %d\n",
  544                                 MAXREC(max_rec), MAXREC(sc->fc.maxrec));
  545         }
  546         if (firewire_debug)
  547                 device_printf(dev, "BUS_OPT 0x%x -> 0x%x\n", reg, reg2);
  548         OWRITE(sc, OHCI_BUS_OPT, reg2);
  549 
  550         /* Initialize registers */
  551         OWRITE(sc, OHCI_CROMHDR, sc->fc.config_rom[0]);
  552         OWRITE(sc, OHCI_CROMPTR, sc->crom_dma.bus_addr);
  553         OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_BIGEND);
  554         OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_POSTWR);
  555         OWRITE(sc, OHCI_SID_BUF, sc->sid_dma.bus_addr);
  556         OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_SID);
  557 
  558         /* Enable link */
  559         OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LINKEN);
  560 
  561         /* Force to start async RX DMA */
  562         sc->arrq.xferq.flag &= ~FWXFERQ_RUNNING;
  563         sc->arrs.xferq.flag &= ~FWXFERQ_RUNNING;
  564         fwohci_rx_enable(sc, &sc->arrq);
  565         fwohci_rx_enable(sc, &sc->arrs);
  566 
  567         /* Initialize async TX */
  568         OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN | OHCI_CNTL_DMA_DEAD);
  569         OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN | OHCI_CNTL_DMA_DEAD);
  570 
  571         /* AT Retries */
  572         OWRITE(sc, FWOHCI_RETRY,
  573                 /* CycleLimit   PhyRespRetries ATRespRetries ATReqRetries */
  574                 (0xffff << 16) | (0x0f << 8) | (0x0f << 4) | 0x0f);
  575 
  576         sc->atrq.top = STAILQ_FIRST(&sc->atrq.db_trq);
  577         sc->atrs.top = STAILQ_FIRST(&sc->atrs.db_trq);
  578         sc->atrq.bottom = sc->atrq.top;
  579         sc->atrs.bottom = sc->atrs.top;
  580 
  581         for (i = 0, db_tr = sc->atrq.top; i < sc->atrq.ndb;
  582             i++, db_tr = STAILQ_NEXT(db_tr, link)) {
  583                 db_tr->xfer = NULL;
  584         }
  585         for (i = 0, db_tr = sc->atrs.top; i < sc->atrs.ndb;
  586             i++, db_tr = STAILQ_NEXT(db_tr, link)) {
  587                 db_tr->xfer = NULL;
  588         }
  589 
  590         /* Enable interrupts */
  591         sc->intmask =  (OHCI_INT_ERR  | OHCI_INT_PHY_SID
  592                         | OHCI_INT_DMA_ATRQ | OHCI_INT_DMA_ATRS
  593                         | OHCI_INT_DMA_PRRQ | OHCI_INT_DMA_PRRS
  594                         | OHCI_INT_PHY_BUS_R | OHCI_INT_PW_ERR);
  595         sc->intmask |=  OHCI_INT_DMA_IR | OHCI_INT_DMA_IT;
  596         sc->intmask |=  OHCI_INT_CYC_LOST | OHCI_INT_PHY_INT;
  597         OWRITE(sc, FWOHCI_INTMASK, sc->intmask);
  598         fwohci_set_intr(&sc->fc, 1);
  599 }
  600 
  601 int
  602 fwohci_init(struct fwohci_softc *sc, device_t dev)
  603 {
  604         int i, mver;
  605         uint32_t reg;
  606         uint8_t ui[8];
  607 
  608 /* OHCI version */
  609         reg = OREAD(sc, OHCI_VERSION);
  610         mver = (reg >> 16) & 0xff;
  611         device_printf(dev, "OHCI version %x.%x (ROM=%d)\n",
  612                         mver, reg & 0xff, (reg >> 24) & 1);
  613         if (mver < 1 || mver > 9) {
  614                 device_printf(dev, "invalid OHCI version\n");
  615                 return (ENXIO);
  616         }
  617 
  618 /* Available Isochronous DMA channel probe */
  619         OWRITE(sc, OHCI_IT_MASK, 0xffffffff);
  620         OWRITE(sc, OHCI_IR_MASK, 0xffffffff);
  621         reg = OREAD(sc, OHCI_IT_MASK) & OREAD(sc, OHCI_IR_MASK);
  622         OWRITE(sc, OHCI_IT_MASKCLR, 0xffffffff);
  623         OWRITE(sc, OHCI_IR_MASKCLR, 0xffffffff);
  624         for (i = 0; i < 0x20; i++)
  625                 if ((reg & (1 << i)) == 0)
  626                         break;
  627         sc->fc.nisodma = i;
  628         device_printf(dev, "No. of Isochronous channels is %d.\n", i);
  629         if (i == 0)
  630                 return (ENXIO);
  631 
  632         sc->fc.arq = &sc->arrq.xferq;
  633         sc->fc.ars = &sc->arrs.xferq;
  634         sc->fc.atq = &sc->atrq.xferq;
  635         sc->fc.ats = &sc->atrs.xferq;
  636 
  637         sc->arrq.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
  638         sc->arrs.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
  639         sc->atrq.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
  640         sc->atrs.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
  641 
  642         sc->arrq.xferq.start = NULL;
  643         sc->arrs.xferq.start = NULL;
  644         sc->atrq.xferq.start = fwohci_start_atq;
  645         sc->atrs.xferq.start = fwohci_start_ats;
  646 
  647         sc->arrq.xferq.buf = NULL;
  648         sc->arrs.xferq.buf = NULL;
  649         sc->atrq.xferq.buf = NULL;
  650         sc->atrs.xferq.buf = NULL;
  651 
  652         sc->arrq.xferq.dmach = -1;
  653         sc->arrs.xferq.dmach = -1;
  654         sc->atrq.xferq.dmach = -1;
  655         sc->atrs.xferq.dmach = -1;
  656 
  657         sc->arrq.ndesc = 1;
  658         sc->arrs.ndesc = 1;
  659         sc->atrq.ndesc = 8;     /* equal to maximum of mbuf chains */
  660         sc->atrs.ndesc = 2;
  661 
  662         sc->arrq.ndb = NDB;
  663         sc->arrs.ndb = NDB / 2;
  664         sc->atrq.ndb = NDB;
  665         sc->atrs.ndb = NDB / 2;
  666 
  667         for (i = 0; i < sc->fc.nisodma; i++) {
  668                 sc->fc.it[i] = &sc->it[i].xferq;
  669                 sc->fc.ir[i] = &sc->ir[i].xferq;
  670                 sc->it[i].xferq.dmach = i;
  671                 sc->ir[i].xferq.dmach = i;
  672                 sc->it[i].ndb = 0;
  673                 sc->ir[i].ndb = 0;
  674         }
  675 
  676         sc->fc.tcode = tinfo;
  677         sc->fc.dev = dev;
  678 
  679         sc->fc.config_rom = fwdma_malloc(&sc->fc, CROMSIZE, CROMSIZE,
  680             &sc->crom_dma, BUS_DMA_WAITOK | BUS_DMA_COHERENT);
  681         if (sc->fc.config_rom == NULL) {
  682                 device_printf(dev, "config_rom alloc failed.");
  683                 return ENOMEM;
  684         }
  685 
  686 #if 0
  687         bzero(&sc->fc.config_rom[0], CROMSIZE);
  688         sc->fc.config_rom[1] = 0x31333934;
  689         sc->fc.config_rom[2] = 0xf000a002;
  690         sc->fc.config_rom[3] = OREAD(sc, OHCI_EUID_HI);
  691         sc->fc.config_rom[4] = OREAD(sc, OHCI_EUID_LO);
  692         sc->fc.config_rom[5] = 0;
  693         sc->fc.config_rom[0] = (4 << 24) | (5 << 16);
  694 
  695         sc->fc.config_rom[0] |= fw_crc16(&sc->fc.config_rom[1], 5*4);
  696 #endif
  697 
  698 /* SID receive buffer must align 2^11 */
  699 #define OHCI_SIDSIZE    (1 << 11)
  700         sc->sid_buf = fwdma_malloc(&sc->fc, OHCI_SIDSIZE, OHCI_SIDSIZE,
  701             &sc->sid_dma, BUS_DMA_WAITOK | BUS_DMA_COHERENT);
  702         if (sc->sid_buf == NULL) {
  703                 device_printf(dev, "sid_buf alloc failed.");
  704                 return ENOMEM;
  705         }
  706 
  707         fwdma_malloc(&sc->fc, sizeof(uint32_t), sizeof(uint32_t),
  708             &sc->dummy_dma, BUS_DMA_WAITOK);
  709 
  710         if (sc->dummy_dma.v_addr == NULL) {
  711                 device_printf(dev, "dummy_dma alloc failed.");
  712                 return ENOMEM;
  713         }
  714 
  715         fwohci_db_init(sc, &sc->arrq);
  716         if ((sc->arrq.flags & FWOHCI_DBCH_INIT) == 0)
  717                 return ENOMEM;
  718 
  719         fwohci_db_init(sc, &sc->arrs);
  720         if ((sc->arrs.flags & FWOHCI_DBCH_INIT) == 0)
  721                 return ENOMEM;
  722 
  723         fwohci_db_init(sc, &sc->atrq);
  724         if ((sc->atrq.flags & FWOHCI_DBCH_INIT) == 0)
  725                 return ENOMEM;
  726 
  727         fwohci_db_init(sc, &sc->atrs);
  728         if ((sc->atrs.flags & FWOHCI_DBCH_INIT) == 0)
  729                 return ENOMEM;
  730 
  731         sc->fc.eui.hi = OREAD(sc, FWOHCIGUID_H);
  732         sc->fc.eui.lo = OREAD(sc, FWOHCIGUID_L);
  733         for (i = 0; i < 8; i++)
  734                 ui[i] = FW_EUI64_BYTE(&sc->fc.eui,i);
  735         device_printf(dev, "EUI64 %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
  736                 ui[0], ui[1], ui[2], ui[3], ui[4], ui[5], ui[6], ui[7]);
  737 
  738         sc->fc.ioctl = fwohci_ioctl;
  739         sc->fc.cyctimer = fwohci_cyctimer;
  740         sc->fc.set_bmr = fwohci_set_bus_manager;
  741         sc->fc.ibr = fwohci_ibr;
  742         sc->fc.irx_enable = fwohci_irx_enable;
  743         sc->fc.irx_disable = fwohci_irx_disable;
  744 
  745         sc->fc.itx_enable = fwohci_itxbuf_enable;
  746         sc->fc.itx_disable = fwohci_itx_disable;
  747 #if BYTE_ORDER == BIG_ENDIAN
  748         sc->fc.irx_post = fwohci_irx_post;
  749 #else
  750         sc->fc.irx_post = NULL;
  751 #endif
  752         sc->fc.itx_post = NULL;
  753         sc->fc.timeout = fwohci_timeout;
  754         sc->fc.poll = fwohci_poll;
  755         sc->fc.set_intr = fwohci_set_intr;
  756 
  757         sc->intmask = sc->irstat = sc->itstat = 0;
  758 
  759         /* Init task queue */
  760         sc->fc.taskqueue = taskqueue_create_fast("fw_taskq", M_WAITOK,
  761                 taskqueue_thread_enqueue, &sc->fc.taskqueue);
  762         taskqueue_start_threads(&sc->fc.taskqueue, 1, PI_NET, "fw%d_taskq",
  763                 device_get_unit(dev));
  764         TASK_INIT(&sc->fwohci_task_busreset, 2, fwohci_task_busreset, sc);
  765         TASK_INIT(&sc->fwohci_task_sid, 1, fwohci_task_sid, sc);
  766         TASK_INIT(&sc->fwohci_task_dma, 0, fwohci_task_dma, sc);
  767 
  768         fw_init(&sc->fc);
  769         fwohci_reset(sc, dev);
  770 
  771         return 0;
  772 }
  773 
  774 void
  775 fwohci_timeout(void *arg)
  776 {
  777         struct fwohci_softc *sc __unused;
  778 
  779         sc = (struct fwohci_softc *)arg;
  780 }
  781 
  782 uint32_t
  783 fwohci_cyctimer(struct firewire_comm *fc)
  784 {
  785         struct fwohci_softc *sc = (struct fwohci_softc *)fc;
  786         return (OREAD(sc, OHCI_CYCLETIMER));
  787 }
  788 
  789 int
  790 fwohci_detach(struct fwohci_softc *sc, device_t dev)
  791 {
  792         int i;
  793 
  794         if (sc->sid_buf != NULL)
  795                 fwdma_free(&sc->fc, &sc->sid_dma);
  796         if (sc->fc.config_rom != NULL)
  797                 fwdma_free(&sc->fc, &sc->crom_dma);
  798 
  799         fwohci_db_free(&sc->arrq);
  800         fwohci_db_free(&sc->arrs);
  801 
  802         fwohci_db_free(&sc->atrq);
  803         fwohci_db_free(&sc->atrs);
  804 
  805         for (i = 0; i < sc->fc.nisodma; i++) {
  806                 fwohci_db_free(&sc->it[i]);
  807                 fwohci_db_free(&sc->ir[i]);
  808         }
  809         if (sc->fc.taskqueue != NULL) {
  810                 taskqueue_drain(sc->fc.taskqueue, &sc->fwohci_task_busreset);
  811                 taskqueue_drain(sc->fc.taskqueue, &sc->fwohci_task_sid);
  812                 taskqueue_drain(sc->fc.taskqueue, &sc->fwohci_task_dma);
  813                 taskqueue_drain(sc->fc.taskqueue, &sc->fc.task_timeout);
  814                 taskqueue_free(sc->fc.taskqueue);
  815                 sc->fc.taskqueue = NULL;
  816         }
  817 
  818         return 0;
  819 }
  820 
  821 #define LAST_DB(dbtr, db) do {                                          \
  822         struct fwohcidb_tr *_dbtr = (dbtr);                             \
  823         int _cnt = _dbtr->dbcnt;                                        \
  824         db = &_dbtr->db[ (_cnt > 2) ? (_cnt -1) : 0];                   \
  825 } while (0)
  826 
  827 static void
  828 fwohci_execute_db(void *arg, bus_dma_segment_t *segs, int nseg, int error)
  829 {
  830         struct fwohcidb_tr *db_tr;
  831         struct fwohcidb *db;
  832         bus_dma_segment_t *s;
  833         int i;
  834 
  835         db_tr = (struct fwohcidb_tr *)arg;
  836         db = &db_tr->db[db_tr->dbcnt];
  837         if (error) {
  838                 if (firewire_debug || error != EFBIG)
  839                         printf("fwohci_execute_db: error=%d\n", error);
  840                 return;
  841         }
  842         for (i = 0; i < nseg; i++) {
  843                 s = &segs[i];
  844                 FWOHCI_DMA_WRITE(db->db.desc.addr, s->ds_addr);
  845                 FWOHCI_DMA_WRITE(db->db.desc.cmd, s->ds_len);
  846                 FWOHCI_DMA_WRITE(db->db.desc.res, 0);
  847                 db++;
  848                 db_tr->dbcnt++;
  849         }
  850 }
  851 
  852 static void
  853 fwohci_execute_db2(void *arg, bus_dma_segment_t *segs, int nseg,
  854     bus_size_t size, int error)
  855 {
  856         fwohci_execute_db(arg, segs, nseg, error);
  857 }
  858 
  859 static void
  860 fwohci_start(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
  861 {
  862         int i;
  863         int tcode, hdr_len, pl_off;
  864         int fsegment = -1;
  865         uint32_t off;
  866         struct fw_xfer *xfer;
  867         struct fw_pkt *fp;
  868         struct fwohci_txpkthdr *ohcifp;
  869         struct fwohcidb_tr *db_tr;
  870         struct fwohcidb *db;
  871         uint32_t *ld;
  872         struct tcode_info *info;
  873         static int maxdesc=0;
  874 
  875         FW_GLOCK_ASSERT(&sc->fc);
  876 
  877         if (&sc->atrq == dbch) {
  878                 off = OHCI_ATQOFF;
  879         } else if (&sc->atrs == dbch) {
  880                 off = OHCI_ATSOFF;
  881         } else {
  882                 return;
  883         }
  884 
  885         if (dbch->flags & FWOHCI_DBCH_FULL)
  886                 return;
  887 
  888         db_tr = dbch->top;
  889 txloop:
  890         xfer = STAILQ_FIRST(&dbch->xferq.q);
  891         if (xfer == NULL) {
  892                 goto kick;
  893         }
  894 #if 0
  895         if (dbch->xferq.queued == 0) {
  896                 device_printf(sc->fc.dev, "TX queue empty\n");
  897         }
  898 #endif
  899         STAILQ_REMOVE_HEAD(&dbch->xferq.q, link);
  900         db_tr->xfer = xfer;
  901         xfer->flag = FWXF_START;
  902 
  903         fp = &xfer->send.hdr;
  904         tcode = fp->mode.common.tcode;
  905 
  906         ohcifp = (struct fwohci_txpkthdr *) db_tr->db[1].db.immed;
  907         info = &tinfo[tcode];
  908         hdr_len = pl_off = info->hdr_len;
  909 
  910         ld = &ohcifp->mode.ld[0];
  911         ld[0] = ld[1] = ld[2] = ld[3] = 0;
  912         for (i = 0; i < pl_off; i+= 4)
  913                 ld[i/4] = fp->mode.ld[i/4];
  914 
  915         ohcifp->mode.common.spd = xfer->send.spd & 0x7;
  916         if (tcode == FWTCODE_STREAM) {
  917                 hdr_len = 8;
  918                 ohcifp->mode.stream.len = fp->mode.stream.len;
  919         } else if (tcode == FWTCODE_PHY) {
  920                 hdr_len = 12;
  921                 ld[1] = fp->mode.ld[1];
  922                 ld[2] = fp->mode.ld[2];
  923                 ohcifp->mode.common.spd = 0;
  924                 ohcifp->mode.common.tcode = FWOHCITCODE_PHY;
  925         } else {
  926                 ohcifp->mode.asycomm.dst = fp->mode.hdr.dst;
  927                 ohcifp->mode.asycomm.srcbus = OHCI_ASYSRCBUS;
  928                 ohcifp->mode.asycomm.tlrt |= FWRETRY_X;
  929         }
  930         db = &db_tr->db[0];
  931         FWOHCI_DMA_WRITE(db->db.desc.cmd,
  932                         OHCI_OUTPUT_MORE | OHCI_KEY_ST2 | hdr_len);
  933         FWOHCI_DMA_WRITE(db->db.desc.addr, 0);
  934         FWOHCI_DMA_WRITE(db->db.desc.res, 0);
  935 /* Specify bound timer of asy. response */
  936         if (&sc->atrs == dbch) {
  937                 FWOHCI_DMA_WRITE(db->db.desc.res,
  938                          (OREAD(sc, OHCI_CYCLETIMER) >> 12) + (1 << 13));
  939         }
  940 #if BYTE_ORDER == BIG_ENDIAN
  941         if (tcode == FWTCODE_WREQQ || tcode == FWTCODE_RRESQ)
  942                 hdr_len = 12;
  943         for (i = 0; i < hdr_len/4; i++)
  944                 FWOHCI_DMA_WRITE(ld[i], ld[i]);
  945 #endif
  946 
  947 again:
  948         db_tr->dbcnt = 2;
  949         db = &db_tr->db[db_tr->dbcnt];
  950         if (xfer->send.pay_len > 0) {
  951                 int err;
  952                 /* handle payload */
  953                 if (xfer->mbuf == NULL) {
  954                         err = bus_dmamap_load(dbch->dmat, db_tr->dma_map,
  955                                 &xfer->send.payload[0], xfer->send.pay_len,
  956                                 fwohci_execute_db, db_tr,
  957                                 /*flags*/0);
  958                 } else {
  959                         /* XXX we can handle only 6 (=8-2) mbuf chains */
  960                         err = bus_dmamap_load_mbuf(dbch->dmat, db_tr->dma_map,
  961                                 xfer->mbuf,
  962                                 fwohci_execute_db2, db_tr,
  963                                 /* flags */0);
  964                         if (err == EFBIG) {
  965                                 struct mbuf *m0;
  966 
  967                                 if (firewire_debug)
  968                                         device_printf(sc->fc.dev, "EFBIG.\n");
  969                                 m0 = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
  970                                 if (m0 != NULL) {
  971                                         m_copydata(xfer->mbuf, 0,
  972                                                 xfer->mbuf->m_pkthdr.len,
  973                                                 mtod(m0, caddr_t));
  974                                         m0->m_len = m0->m_pkthdr.len =
  975                                                 xfer->mbuf->m_pkthdr.len;
  976                                         m_freem(xfer->mbuf);
  977                                         xfer->mbuf = m0;
  978                                         goto again;
  979                                 }
  980                                 device_printf(sc->fc.dev, "m_getcl failed.\n");
  981                         }
  982                 }
  983                 if (err)
  984                         printf("dmamap_load: err=%d\n", err);
  985                 bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
  986                                                 BUS_DMASYNC_PREWRITE);
  987 #if 0 /* OHCI_OUTPUT_MODE == 0 */
  988                 for (i = 2; i < db_tr->dbcnt; i++)
  989                         FWOHCI_DMA_SET(db_tr->db[i].db.desc.cmd,
  990                                                 OHCI_OUTPUT_MORE);
  991 #endif
  992         }
  993         if (maxdesc < db_tr->dbcnt) {
  994                 maxdesc = db_tr->dbcnt;
  995                 if (firewire_debug)
  996                         device_printf(sc->fc.dev, "%s: maxdesc %d\n", __func__, maxdesc);
  997         }
  998         /* last db */
  999         LAST_DB(db_tr, db);
 1000         FWOHCI_DMA_SET(db->db.desc.cmd,
 1001                 OHCI_OUTPUT_LAST | OHCI_INTERRUPT_ALWAYS | OHCI_BRANCH_ALWAYS);
 1002         FWOHCI_DMA_WRITE(db->db.desc.depend,
 1003                         STAILQ_NEXT(db_tr, link)->bus_addr);
 1004 
 1005         if (fsegment == -1)
 1006                 fsegment = db_tr->dbcnt;
 1007         if (dbch->pdb_tr != NULL) {
 1008                 LAST_DB(dbch->pdb_tr, db);
 1009                 FWOHCI_DMA_SET(db->db.desc.depend, db_tr->dbcnt);
 1010         }
 1011         dbch->xferq.queued++;
 1012         dbch->pdb_tr = db_tr;
 1013         db_tr = STAILQ_NEXT(db_tr, link);
 1014         if (db_tr != dbch->bottom) {
 1015                 goto txloop;
 1016         } else {
 1017                 device_printf(sc->fc.dev, "fwohci_start: lack of db_trq\n");
 1018                 dbch->flags |= FWOHCI_DBCH_FULL;
 1019         }
 1020 kick:
 1021         /* kick asy q */
 1022         fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREREAD);
 1023         fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE);
 1024 
 1025         if (dbch->xferq.flag & FWXFERQ_RUNNING) {
 1026                 OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_WAKE);
 1027         } else {
 1028                 if (firewire_debug)
 1029                         device_printf(sc->fc.dev, "start AT DMA status=%x\n",
 1030                                         OREAD(sc, OHCI_DMACTL(off)));
 1031                 OWRITE(sc, OHCI_DMACMD(off), dbch->top->bus_addr | fsegment);
 1032                 OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_RUN);
 1033                 dbch->xferq.flag |= FWXFERQ_RUNNING;
 1034         }
 1035 
 1036         dbch->top = db_tr;
 1037         return;
 1038 }
 1039 
 1040 static void
 1041 fwohci_start_atq(struct firewire_comm *fc)
 1042 {
 1043         struct fwohci_softc *sc = (struct fwohci_softc *)fc;
 1044         FW_GLOCK(&sc->fc);
 1045         fwohci_start(sc, &(sc->atrq));
 1046         FW_GUNLOCK(&sc->fc);
 1047         return;
 1048 }
 1049 
 1050 static void
 1051 fwohci_start_ats(struct firewire_comm *fc)
 1052 {
 1053         struct fwohci_softc *sc = (struct fwohci_softc *)fc;
 1054         FW_GLOCK(&sc->fc);
 1055         fwohci_start(sc, &(sc->atrs));
 1056         FW_GUNLOCK(&sc->fc);
 1057         return;
 1058 }
 1059 
 1060 void
 1061 fwohci_txd(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
 1062 {
 1063         int s, ch, err = 0;
 1064         struct fwohcidb_tr *tr;
 1065         struct fwohcidb *db;
 1066         struct fw_xfer *xfer;
 1067         uint32_t off;
 1068         u_int stat, status;
 1069         int     packets;
 1070         struct firewire_comm *fc = (struct firewire_comm *)sc;
 1071 
 1072         if (&sc->atrq == dbch) {
 1073                 off = OHCI_ATQOFF;
 1074                 ch = ATRQ_CH;
 1075         } else if (&sc->atrs == dbch) {
 1076                 off = OHCI_ATSOFF;
 1077                 ch = ATRS_CH;
 1078         } else {
 1079                 return;
 1080         }
 1081         s = splfw();
 1082         tr = dbch->bottom;
 1083         packets = 0;
 1084         fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_POSTREAD);
 1085         fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_POSTWRITE);
 1086         while (dbch->xferq.queued > 0) {
 1087                 LAST_DB(tr, db);
 1088                 status = FWOHCI_DMA_READ(db->db.desc.res) >> OHCI_STATUS_SHIFT;
 1089                 if (!(status & OHCI_CNTL_DMA_ACTIVE)) {
 1090                         if (fc->status != FWBUSINIT)
 1091                                 /* maybe out of order?? */
 1092                                 goto out;
 1093                 }
 1094                 bus_dmamap_sync(dbch->dmat, tr->dma_map,
 1095                         BUS_DMASYNC_POSTWRITE);
 1096                 bus_dmamap_unload(dbch->dmat, tr->dma_map);
 1097 #if 1
 1098                 if (firewire_debug > 1)
 1099                         dump_db(sc, ch);
 1100 #endif
 1101                 if (status & OHCI_CNTL_DMA_DEAD) {
 1102                         /* Stop DMA */
 1103                         OWRITE(sc, OHCI_DMACTLCLR(off), OHCI_CNTL_DMA_RUN);
 1104                         device_printf(sc->fc.dev, "force reset AT FIFO\n");
 1105                         OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_LINKEN);
 1106                         OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LPS | OHCI_HCC_LINKEN);
 1107                         OWRITE(sc, OHCI_DMACTLCLR(off), OHCI_CNTL_DMA_RUN);
 1108                 }
 1109                 stat = status & FWOHCIEV_MASK;
 1110                 switch (stat) {
 1111                 case FWOHCIEV_ACKPEND:
 1112                 case FWOHCIEV_ACKCOMPL:
 1113                         err = 0;
 1114                         break;
 1115                 case FWOHCIEV_ACKBSA:
 1116                 case FWOHCIEV_ACKBSB:
 1117                 case FWOHCIEV_ACKBSX:
 1118                         err = EBUSY;
 1119                         break;
 1120                 case FWOHCIEV_FLUSHED:
 1121                 case FWOHCIEV_ACKTARD:
 1122                         err = EAGAIN;
 1123                         break;
 1124                 case FWOHCIEV_MISSACK:
 1125                 case FWOHCIEV_UNDRRUN:
 1126                 case FWOHCIEV_OVRRUN:
 1127                 case FWOHCIEV_DESCERR:
 1128                 case FWOHCIEV_DTRDERR:
 1129                 case FWOHCIEV_TIMEOUT:
 1130                 case FWOHCIEV_TCODERR:
 1131                 case FWOHCIEV_UNKNOWN:
 1132                 case FWOHCIEV_ACKDERR:
 1133                 case FWOHCIEV_ACKTERR:
 1134                 default:
 1135                         err = EINVAL;
 1136                         break;
 1137                 }
 1138                 if (tr->xfer != NULL) {
 1139                         xfer = tr->xfer;
 1140                         if (xfer->flag & FWXF_RCVD) {
 1141 #if 0
 1142                                 if (firewire_debug)
 1143                                         printf("already rcvd\n");
 1144 #endif
 1145                                 fw_xfer_done(xfer);
 1146                         } else {
 1147                                 microtime(&xfer->tv);
 1148                                 xfer->flag = FWXF_SENT;
 1149                                 if (err == EBUSY) {
 1150                                         xfer->flag = FWXF_BUSY;
 1151                                         xfer->resp = err;
 1152                                         xfer->recv.pay_len = 0;
 1153                                         fw_xfer_done(xfer);
 1154                                 } else if (stat != FWOHCIEV_ACKPEND) {
 1155                                         if (stat != FWOHCIEV_ACKCOMPL)
 1156                                                 xfer->flag = FWXF_SENTERR;
 1157                                         xfer->resp = err;
 1158                                         xfer->recv.pay_len = 0;
 1159                                         fw_xfer_done(xfer);
 1160                                 }
 1161                         }
 1162                         /*
 1163                          * The watchdog timer takes care of split
 1164                          * transaction timeout for ACKPEND case.
 1165                          */
 1166                 } else {
 1167                         printf("this shouldn't happen\n");
 1168                 }
 1169                 FW_GLOCK(fc);
 1170                 dbch->xferq.queued--;
 1171                 FW_GUNLOCK(fc);
 1172                 tr->xfer = NULL;
 1173 
 1174                 packets++;
 1175                 tr = STAILQ_NEXT(tr, link);
 1176                 dbch->bottom = tr;
 1177                 if (dbch->bottom == dbch->top) {
 1178                         /* we reaches the end of context program */
 1179                         if (firewire_debug && dbch->xferq.queued > 0)
 1180                                 printf("queued > 0\n");
 1181                         break;
 1182                 }
 1183         }
 1184 out:
 1185         if ((dbch->flags & FWOHCI_DBCH_FULL) && packets > 0) {
 1186                 printf("make free slot\n");
 1187                 dbch->flags &= ~FWOHCI_DBCH_FULL;
 1188                 FW_GLOCK(fc);
 1189                 fwohci_start(sc, dbch);
 1190                 FW_GUNLOCK(fc);
 1191         }
 1192         splx(s);
 1193 }
 1194 
 1195 static void
 1196 fwohci_db_free(struct fwohci_dbch *dbch)
 1197 {
 1198         struct fwohcidb_tr *db_tr;
 1199         int idb;
 1200 
 1201         if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
 1202                 return;
 1203 
 1204         for (db_tr = STAILQ_FIRST(&dbch->db_trq), idb = 0; idb < dbch->ndb;
 1205             db_tr = STAILQ_NEXT(db_tr, link), idb++) {
 1206                 if ((dbch->xferq.flag & FWXFERQ_EXTBUF) == 0 &&
 1207                     db_tr->buf != NULL) {
 1208                         fwdma_free_size(dbch->dmat, db_tr->dma_map,
 1209                                         db_tr->buf, dbch->xferq.psize);
 1210                         db_tr->buf = NULL;
 1211                 } else if (db_tr->dma_map != NULL)
 1212                         bus_dmamap_destroy(dbch->dmat, db_tr->dma_map);
 1213         }
 1214         dbch->ndb = 0;
 1215         db_tr = STAILQ_FIRST(&dbch->db_trq);
 1216         fwdma_free_multiseg(dbch->am);
 1217         free(db_tr, M_FW);
 1218         STAILQ_INIT(&dbch->db_trq);
 1219         dbch->flags &= ~FWOHCI_DBCH_INIT;
 1220 }
 1221 
 1222 static void
 1223 fwohci_db_init(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
 1224 {
 1225         int     idb;
 1226         struct fwohcidb_tr *db_tr;
 1227 
 1228         if ((dbch->flags & FWOHCI_DBCH_INIT) != 0)
 1229                 goto out;
 1230 
 1231         /* create dma_tag for buffers */
 1232 #define MAX_REQCOUNT    0xffff
 1233         if (bus_dma_tag_create(/*parent*/ sc->fc.dmat,
 1234                         /*alignment*/ 1, /*boundary*/ 0,
 1235                         /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
 1236                         /*highaddr*/ BUS_SPACE_MAXADDR,
 1237                         /*filter*/NULL, /*filterarg*/NULL,
 1238                         /*maxsize*/ dbch->xferq.psize,
 1239                         /*nsegments*/ dbch->ndesc > 3 ? dbch->ndesc - 2 : 1,
 1240                         /*maxsegsz*/ MAX_REQCOUNT,
 1241                         /*flags*/ 0,
 1242                         /*lockfunc*/busdma_lock_mutex,
 1243                         /*lockarg*/FW_GMTX(&sc->fc),
 1244                         &dbch->dmat))
 1245                 return;
 1246 
 1247         /* allocate DB entries and attach one to each DMA channels */
 1248         /* DB entry must start at 16 bytes bounary. */
 1249         STAILQ_INIT(&dbch->db_trq);
 1250         db_tr = (struct fwohcidb_tr *)
 1251                 malloc(sizeof(struct fwohcidb_tr) * dbch->ndb,
 1252                 M_FW, M_WAITOK | M_ZERO);
 1253 
 1254 #define DB_SIZE(x) (sizeof(struct fwohcidb) * (x)->ndesc)
 1255         dbch->am = fwdma_malloc_multiseg(&sc->fc, sizeof(struct fwohcidb),
 1256                 DB_SIZE(dbch), dbch->ndb, BUS_DMA_WAITOK);
 1257         if (dbch->am == NULL) {
 1258                 printf("fwohci_db_init: fwdma_malloc_multiseg failed\n");
 1259                 free(db_tr, M_FW);
 1260                 return;
 1261         }
 1262         /* Attach DB to DMA ch. */
 1263         for (idb = 0; idb < dbch->ndb; idb++) {
 1264                 db_tr->dbcnt = 0;
 1265                 db_tr->db = (struct fwohcidb *)fwdma_v_addr(dbch->am, idb);
 1266                 db_tr->bus_addr = fwdma_bus_addr(dbch->am, idb);
 1267                 /* create dmamap for buffers */
 1268                 /* XXX do we need 4bytes alignment tag? */
 1269                 /* XXX don't alloc dma_map for AR */
 1270                 if (bus_dmamap_create(dbch->dmat, 0, &db_tr->dma_map) != 0) {
 1271                         printf("bus_dmamap_create failed\n");
 1272                         dbch->flags = FWOHCI_DBCH_INIT; /* XXX fake */
 1273                         fwohci_db_free(dbch);
 1274                         return;
 1275                 }
 1276                 STAILQ_INSERT_TAIL(&dbch->db_trq, db_tr, link);
 1277                 if (dbch->xferq.flag & FWXFERQ_EXTBUF) {
 1278                         if (idb % dbch->xferq.bnpacket == 0)
 1279                                 dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket
 1280                                                 ].start = (caddr_t)db_tr;
 1281                         if ((idb + 1) % dbch->xferq.bnpacket == 0)
 1282                                 dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket
 1283                                                 ].end = (caddr_t)db_tr;
 1284                 }
 1285                 db_tr++;
 1286         }
 1287         STAILQ_LAST(&dbch->db_trq, fwohcidb_tr,link)->link.stqe_next
 1288                         = STAILQ_FIRST(&dbch->db_trq);
 1289 out:
 1290         dbch->xferq.queued = 0;
 1291         dbch->pdb_tr = NULL;
 1292         dbch->top = STAILQ_FIRST(&dbch->db_trq);
 1293         dbch->bottom = dbch->top;
 1294         dbch->flags = FWOHCI_DBCH_INIT;
 1295 }
 1296 
 1297 static int
 1298 fwohci_itx_disable(struct firewire_comm *fc, int dmach)
 1299 {
 1300         struct fwohci_softc *sc = (struct fwohci_softc *)fc;
 1301 
 1302         OWRITE(sc, OHCI_ITCTLCLR(dmach),
 1303                         OHCI_CNTL_DMA_RUN | OHCI_CNTL_CYCMATCH_S);
 1304         OWRITE(sc, OHCI_IT_MASKCLR, 1 << dmach);
 1305         OWRITE(sc, OHCI_IT_STATCLR, 1 << dmach);
 1306         /* XXX we cannot free buffers until the DMA really stops */
 1307         pause("fwitxd", hz);
 1308         fwohci_db_free(&sc->it[dmach]);
 1309         sc->it[dmach].xferq.flag &= ~FWXFERQ_RUNNING;
 1310         return 0;
 1311 }
 1312 
 1313 static int
 1314 fwohci_irx_disable(struct firewire_comm *fc, int dmach)
 1315 {
 1316         struct fwohci_softc *sc = (struct fwohci_softc *)fc;
 1317 
 1318         OWRITE(sc, OHCI_IRCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
 1319         OWRITE(sc, OHCI_IR_MASKCLR, 1 << dmach);
 1320         OWRITE(sc, OHCI_IR_STATCLR, 1 << dmach);
 1321         /* XXX we cannot free buffers until the DMA really stops */
 1322         pause("fwirxd", hz);
 1323         fwohci_db_free(&sc->ir[dmach]);
 1324         sc->ir[dmach].xferq.flag &= ~FWXFERQ_RUNNING;
 1325         return 0;
 1326 }
 1327 
 1328 #if BYTE_ORDER == BIG_ENDIAN
 1329 static void
 1330 fwohci_irx_post (struct firewire_comm *fc , uint32_t *qld)
 1331 {
 1332         qld[0] = FWOHCI_DMA_READ(qld[0]);
 1333         return;
 1334 }
 1335 #endif
 1336 
 1337 static int
 1338 fwohci_tx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
 1339 {
 1340         int err = 0;
 1341         int idb, z, i, dmach = 0, ldesc;
 1342         uint32_t off = 0;
 1343         struct fwohcidb_tr *db_tr;
 1344         struct fwohcidb *db;
 1345 
 1346         if (!(dbch->xferq.flag & FWXFERQ_EXTBUF)) {
 1347                 err = EINVAL;
 1348                 return err;
 1349         }
 1350         z = dbch->ndesc;
 1351         for (dmach = 0; dmach < sc->fc.nisodma; dmach++) {
 1352                 if (&sc->it[dmach] == dbch) {
 1353                         off = OHCI_ITOFF(dmach);
 1354                         break;
 1355                 }
 1356         }
 1357         if (off == 0) {
 1358                 err = EINVAL;
 1359                 return err;
 1360         }
 1361         if (dbch->xferq.flag & FWXFERQ_RUNNING)
 1362                 return err;
 1363         dbch->xferq.flag |= FWXFERQ_RUNNING;
 1364         for (i = 0, dbch->bottom = dbch->top; i < (dbch->ndb - 1); i++) {
 1365                 dbch->bottom = STAILQ_NEXT(dbch->bottom, link);
 1366         }
 1367         db_tr = dbch->top;
 1368         for (idb = 0; idb < dbch->ndb; idb++) {
 1369                 fwohci_add_tx_buf(dbch, db_tr, idb);
 1370                 if (STAILQ_NEXT(db_tr, link) == NULL) {
 1371                         break;
 1372                 }
 1373                 db = db_tr->db;
 1374                 ldesc = db_tr->dbcnt - 1;
 1375                 FWOHCI_DMA_WRITE(db[0].db.desc.depend,
 1376                                 STAILQ_NEXT(db_tr, link)->bus_addr | z);
 1377                 db[ldesc].db.desc.depend = db[0].db.desc.depend;
 1378                 if (dbch->xferq.flag & FWXFERQ_EXTBUF) {
 1379                         if (((idb + 1) % dbch->xferq.bnpacket) == 0) {
 1380                                 FWOHCI_DMA_SET(
 1381                                         db[ldesc].db.desc.cmd,
 1382                                         OHCI_INTERRUPT_ALWAYS);
 1383                                 /* OHCI 1.1 and above */
 1384                                 FWOHCI_DMA_SET(
 1385                                         db[0].db.desc.cmd,
 1386                                         OHCI_INTERRUPT_ALWAYS);
 1387                         }
 1388                 }
 1389                 db_tr = STAILQ_NEXT(db_tr, link);
 1390         }
 1391         FWOHCI_DMA_CLEAR(
 1392                 dbch->bottom->db[dbch->bottom->dbcnt - 1].db.desc.depend, 0xf);
 1393         return err;
 1394 }
 1395 
 1396 static int
 1397 fwohci_rx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
 1398 {
 1399         int err = 0;
 1400         int idb, z, i, dmach = 0, ldesc;
 1401         uint32_t off = 0;
 1402         struct fwohcidb_tr *db_tr;
 1403         struct fwohcidb *db;
 1404 
 1405         z = dbch->ndesc;
 1406         if (&sc->arrq == dbch) {
 1407                 off = OHCI_ARQOFF;
 1408         } else if (&sc->arrs == dbch) {
 1409                 off = OHCI_ARSOFF;
 1410         } else {
 1411                 for (dmach = 0; dmach < sc->fc.nisodma; dmach++) {
 1412                         if (&sc->ir[dmach] == dbch) {
 1413                                 off = OHCI_IROFF(dmach);
 1414                                 break;
 1415                         }
 1416                 }
 1417         }
 1418         if (off == 0) {
 1419                 err = EINVAL;
 1420                 return err;
 1421         }
 1422         if (dbch->xferq.flag & FWXFERQ_STREAM) {
 1423                 if (dbch->xferq.flag & FWXFERQ_RUNNING)
 1424                         return err;
 1425         } else {
 1426                 if (dbch->xferq.flag & FWXFERQ_RUNNING) {
 1427                         err = EBUSY;
 1428                         return err;
 1429                 }
 1430         }
 1431         dbch->xferq.flag |= FWXFERQ_RUNNING;
 1432         dbch->top = STAILQ_FIRST(&dbch->db_trq);
 1433         for (i = 0, dbch->bottom = dbch->top; i < (dbch->ndb - 1); i++) {
 1434                 dbch->bottom = STAILQ_NEXT(dbch->bottom, link);
 1435         }
 1436         db_tr = dbch->top;
 1437         for (idb = 0; idb < dbch->ndb; idb++) {
 1438                 fwohci_add_rx_buf(dbch, db_tr, idb, &sc->dummy_dma);
 1439                 if (STAILQ_NEXT(db_tr, link) == NULL)
 1440                         break;
 1441                 db = db_tr->db;
 1442                 ldesc = db_tr->dbcnt - 1;
 1443                 FWOHCI_DMA_WRITE(db[ldesc].db.desc.depend,
 1444                         STAILQ_NEXT(db_tr, link)->bus_addr | z);
 1445                 if (dbch->xferq.flag & FWXFERQ_EXTBUF) {
 1446                         if (((idb + 1) % dbch->xferq.bnpacket) == 0) {
 1447                                 FWOHCI_DMA_SET(
 1448                                         db[ldesc].db.desc.cmd,
 1449                                         OHCI_INTERRUPT_ALWAYS);
 1450                                 FWOHCI_DMA_CLEAR(
 1451                                         db[ldesc].db.desc.depend,
 1452                                         0xf);
 1453                         }
 1454                 }
 1455                 db_tr = STAILQ_NEXT(db_tr, link);
 1456         }
 1457         FWOHCI_DMA_CLEAR(
 1458                 dbch->bottom->db[db_tr->dbcnt - 1].db.desc.depend, 0xf);
 1459         dbch->buf_offset = 0;
 1460         fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREREAD);
 1461         fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE);
 1462         if (dbch->xferq.flag & FWXFERQ_STREAM) {
 1463                 return err;
 1464         } else {
 1465                 OWRITE(sc, OHCI_DMACMD(off), dbch->top->bus_addr | z);
 1466         }
 1467         OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_RUN);
 1468         return err;
 1469 }
 1470 
 1471 static int
 1472 fwohci_next_cycle(struct firewire_comm *fc, int cycle_now)
 1473 {
 1474         int sec, cycle, cycle_match;
 1475 
 1476         cycle = cycle_now & 0x1fff;
 1477         sec = cycle_now >> 13;
 1478 #define CYCLE_MOD       0x10
 1479 #if 1
 1480 #define CYCLE_DELAY     8       /* min delay to start DMA */
 1481 #else
 1482 #define CYCLE_DELAY     7000    /* min delay to start DMA */
 1483 #endif
 1484         cycle = cycle + CYCLE_DELAY;
 1485         if (cycle >= 8000) {
 1486                 sec++;
 1487                 cycle -= 8000;
 1488         }
 1489         cycle = roundup2(cycle, CYCLE_MOD);
 1490         if (cycle >= 8000) {
 1491                 sec++;
 1492                 if (cycle == 8000)
 1493                         cycle = 0;
 1494                 else
 1495                         cycle = CYCLE_MOD;
 1496         }
 1497         cycle_match = ((sec << 13) | cycle) & 0x7ffff;
 1498 
 1499         return (cycle_match);
 1500 }
 1501 
 1502 static int
 1503 fwohci_itxbuf_enable(struct firewire_comm *fc, int dmach)
 1504 {
 1505         struct fwohci_softc *sc = (struct fwohci_softc *)fc;
 1506         int err = 0;
 1507         struct fwohci_dbch *dbch;
 1508         int cycle_match, cycle_now, s, ldesc;
 1509         uint32_t stat;
 1510         struct fw_bulkxfer *first, *chunk, *prev;
 1511         struct fw_xferq *it;
 1512 
 1513         dbch = &sc->it[dmach];
 1514         it = &dbch->xferq;
 1515 
 1516         if ((dbch->flags & FWOHCI_DBCH_INIT) == 0) {
 1517                 dbch->ndb = it->bnpacket * it->bnchunk;
 1518                 dbch->ndesc = 3;
 1519                 fwohci_db_init(sc, dbch);
 1520                 if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
 1521                         return ENOMEM;
 1522 
 1523                 err = fwohci_tx_enable(sc, dbch);
 1524         }
 1525         if (err)
 1526                 return err;
 1527 
 1528         ldesc = dbch->ndesc - 1;
 1529         s = splfw();
 1530         FW_GLOCK(fc);
 1531         prev = STAILQ_LAST(&it->stdma, fw_bulkxfer, link);
 1532         while  ((chunk = STAILQ_FIRST(&it->stvalid)) != NULL) {
 1533                 struct fwohcidb *db;
 1534 
 1535                 fwdma_sync_multiseg(it->buf, chunk->poffset, it->bnpacket,
 1536                                         BUS_DMASYNC_PREWRITE);
 1537                 fwohci_txbufdb(sc, dmach, chunk);
 1538                 if (prev != NULL) {
 1539                         db = ((struct fwohcidb_tr *)(prev->end))->db;
 1540 #if 0 /* XXX necessary? */
 1541                         FWOHCI_DMA_SET(db[ldesc].db.desc.cmd,
 1542                                                 OHCI_BRANCH_ALWAYS);
 1543 #endif
 1544 #if 0 /* if bulkxfer->npacket changes */
 1545                         db[ldesc].db.desc.depend = db[0].db.desc.depend =
 1546                                 ((struct fwohcidb_tr *)
 1547                                 (chunk->start))->bus_addr | dbch->ndesc;
 1548 #else
 1549                         FWOHCI_DMA_SET(db[0].db.desc.depend, dbch->ndesc);
 1550                         FWOHCI_DMA_SET(db[ldesc].db.desc.depend, dbch->ndesc);
 1551 #endif
 1552                 }
 1553                 STAILQ_REMOVE_HEAD(&it->stvalid, link);
 1554                 STAILQ_INSERT_TAIL(&it->stdma, chunk, link);
 1555                 prev = chunk;
 1556         }
 1557         FW_GUNLOCK(fc);
 1558         fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE);
 1559         fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREREAD);
 1560         splx(s);
 1561         stat = OREAD(sc, OHCI_ITCTL(dmach));
 1562         if (firewire_debug && (stat & OHCI_CNTL_CYCMATCH_S))
 1563                 printf("stat 0x%x\n", stat);
 1564 
 1565         if (stat & (OHCI_CNTL_DMA_ACTIVE | OHCI_CNTL_CYCMATCH_S))
 1566                 return 0;
 1567 
 1568 #if 0
 1569         OWRITE(sc, OHCI_ITCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
 1570 #endif
 1571         OWRITE(sc, OHCI_IT_MASKCLR, 1 << dmach);
 1572         OWRITE(sc, OHCI_IT_STATCLR, 1 << dmach);
 1573         OWRITE(sc, OHCI_IT_MASK, 1 << dmach);
 1574         OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_DMA_IT);
 1575 
 1576         first = STAILQ_FIRST(&it->stdma);
 1577         OWRITE(sc, OHCI_ITCMD(dmach),
 1578                 ((struct fwohcidb_tr *)(first->start))->bus_addr | dbch->ndesc);
 1579         if (firewire_debug > 1) {
 1580                 printf("fwohci_itxbuf_enable: kick 0x%08x\n", stat);
 1581 #if 1
 1582                 dump_dma(sc, ITX_CH + dmach);
 1583 #endif
 1584         }
 1585         if ((stat & OHCI_CNTL_DMA_RUN) == 0) {
 1586 #if 1
 1587                 /* Don't start until all chunks are buffered */
 1588                 if (STAILQ_FIRST(&it->stfree) != NULL)
 1589                         goto out;
 1590 #endif
 1591 #if 1
 1592                 /* Clear cycle match counter bits */
 1593                 OWRITE(sc, OHCI_ITCTLCLR(dmach), 0xffff0000);
 1594 
 1595                 /* 2bit second + 13bit cycle */
 1596                 cycle_now = (fc->cyctimer(fc) >> 12) & 0x7fff;
 1597                 cycle_match = fwohci_next_cycle(fc, cycle_now);
 1598 
 1599                 OWRITE(sc, OHCI_ITCTL(dmach),
 1600                                 OHCI_CNTL_CYCMATCH_S | (cycle_match << 16)
 1601                                 | OHCI_CNTL_DMA_RUN);
 1602 #else
 1603                 OWRITE(sc, OHCI_ITCTL(dmach), OHCI_CNTL_DMA_RUN);
 1604 #endif
 1605                 if (firewire_debug > 1) {
 1606                         printf("cycle_match: 0x%04x->0x%04x\n",
 1607                                                 cycle_now, cycle_match);
 1608                         dump_dma(sc, ITX_CH + dmach);
 1609                         dump_db(sc, ITX_CH + dmach);
 1610                 }
 1611         } else if ((stat & OHCI_CNTL_CYCMATCH_S) == 0) {
 1612                 device_printf(sc->fc.dev,
 1613                         "IT DMA underrun (0x%08x)\n", stat);
 1614                 OWRITE(sc, OHCI_ITCTL(dmach), OHCI_CNTL_DMA_WAKE);
 1615         }
 1616 out:
 1617         return err;
 1618 }
 1619 
 1620 static int
 1621 fwohci_irx_enable(struct firewire_comm *fc, int dmach)
 1622 {
 1623         struct fwohci_softc *sc = (struct fwohci_softc *)fc;
 1624         int err = 0, s, ldesc;
 1625         unsigned short tag, ich;
 1626         uint32_t stat;
 1627         struct fwohci_dbch *dbch;
 1628         struct fwohcidb_tr *db_tr;
 1629         struct fw_bulkxfer *first, *prev, *chunk;
 1630         struct fw_xferq *ir;
 1631 
 1632         dbch = &sc->ir[dmach];
 1633         ir = &dbch->xferq;
 1634 
 1635         if ((ir->flag & FWXFERQ_RUNNING) == 0) {
 1636                 tag = (ir->flag >> 6) & 3;
 1637                 ich = ir->flag & 0x3f;
 1638                 OWRITE(sc, OHCI_IRMATCH(dmach), tagbit[tag] | ich);
 1639 
 1640                 ir->queued = 0;
 1641                 dbch->ndb = ir->bnpacket * ir->bnchunk;
 1642                 dbch->ndesc = 2;
 1643                 fwohci_db_init(sc, dbch);
 1644                 if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
 1645                         return ENOMEM;
 1646                 err = fwohci_rx_enable(sc, dbch);
 1647         }
 1648         if (err)
 1649                 return err;
 1650 
 1651         first = STAILQ_FIRST(&ir->stfree);
 1652         if (first == NULL) {
 1653                 device_printf(fc->dev, "IR DMA no free chunk\n");
 1654                 return 0;
 1655         }
 1656 
 1657         ldesc = dbch->ndesc - 1;
 1658         s = splfw();
 1659         if ((ir->flag & FWXFERQ_HANDLER) == 0)
 1660                 FW_GLOCK(fc);
 1661         prev = STAILQ_LAST(&ir->stdma, fw_bulkxfer, link);
 1662         while  ((chunk = STAILQ_FIRST(&ir->stfree)) != NULL) {
 1663                 struct fwohcidb *db;
 1664 
 1665 #if 1 /* XXX for if_fwe */
 1666                 if (chunk->mbuf != NULL) {
 1667                         db_tr = (struct fwohcidb_tr *)(chunk->start);
 1668                         db_tr->dbcnt = 1;
 1669                         err = bus_dmamap_load_mbuf(dbch->dmat, db_tr->dma_map,
 1670                                         chunk->mbuf, fwohci_execute_db2, db_tr,
 1671                                         /* flags */0);
 1672                         FWOHCI_DMA_SET(db_tr->db[1].db.desc.cmd,
 1673                                 OHCI_UPDATE | OHCI_INPUT_LAST |
 1674                                 OHCI_INTERRUPT_ALWAYS | OHCI_BRANCH_ALWAYS);
 1675                 }
 1676 #endif
 1677                 db = ((struct fwohcidb_tr *)(chunk->end))->db;
 1678                 FWOHCI_DMA_WRITE(db[ldesc].db.desc.res, 0);
 1679                 FWOHCI_DMA_CLEAR(db[ldesc].db.desc.depend, 0xf);
 1680                 if (prev != NULL) {
 1681                         db = ((struct fwohcidb_tr *)(prev->end))->db;
 1682                         FWOHCI_DMA_SET(db[ldesc].db.desc.depend, dbch->ndesc);
 1683                 }
 1684                 STAILQ_REMOVE_HEAD(&ir->stfree, link);
 1685                 STAILQ_INSERT_TAIL(&ir->stdma, chunk, link);
 1686                 prev = chunk;
 1687         }
 1688         if ((ir->flag & FWXFERQ_HANDLER) == 0)
 1689                 FW_GUNLOCK(fc);
 1690         fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE);
 1691         fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREREAD);
 1692         splx(s);
 1693         stat = OREAD(sc, OHCI_IRCTL(dmach));
 1694         if (stat & OHCI_CNTL_DMA_ACTIVE)
 1695                 return 0;
 1696         if (stat & OHCI_CNTL_DMA_RUN) {
 1697                 OWRITE(sc, OHCI_IRCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
 1698                 device_printf(sc->fc.dev, "IR DMA overrun (0x%08x)\n", stat);
 1699         }
 1700 
 1701         if (firewire_debug)
 1702                 printf("start IR DMA 0x%x\n", stat);
 1703         OWRITE(sc, OHCI_IR_MASKCLR, 1 << dmach);
 1704         OWRITE(sc, OHCI_IR_STATCLR, 1 << dmach);
 1705         OWRITE(sc, OHCI_IR_MASK, 1 << dmach);
 1706         OWRITE(sc, OHCI_IRCTLCLR(dmach), 0xf0000000);
 1707         OWRITE(sc, OHCI_IRCTL(dmach), OHCI_CNTL_ISOHDR);
 1708         OWRITE(sc, OHCI_IRCMD(dmach),
 1709                 ((struct fwohcidb_tr *)(first->start))->bus_addr
 1710                                                         | dbch->ndesc);
 1711         OWRITE(sc, OHCI_IRCTL(dmach), OHCI_CNTL_DMA_RUN);
 1712         OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_DMA_IR);
 1713 #if 0
 1714         dump_db(sc, IRX_CH + dmach);
 1715 #endif
 1716         return err;
 1717 }
 1718 
 1719 int
 1720 fwohci_stop(struct fwohci_softc *sc, device_t dev)
 1721 {
 1722         u_int i;
 1723 
 1724         fwohci_set_intr(&sc->fc, 0);
 1725 
 1726 /* Now stopping all DMA channel */
 1727         OWRITE(sc, OHCI_ARQCTLCLR, OHCI_CNTL_DMA_RUN);
 1728         OWRITE(sc, OHCI_ARSCTLCLR, OHCI_CNTL_DMA_RUN);
 1729         OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN);
 1730         OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN);
 1731 
 1732         for (i = 0; i < sc->fc.nisodma; i++) {
 1733                 OWRITE(sc, OHCI_IRCTLCLR(i), OHCI_CNTL_DMA_RUN);
 1734                 OWRITE(sc, OHCI_ITCTLCLR(i), OHCI_CNTL_DMA_RUN);
 1735         }
 1736 
 1737 #if 0 /* Let dcons(4) be accessed */
 1738 /* Stop interrupt */
 1739         OWRITE(sc, FWOHCI_INTMASKCLR,
 1740                         OHCI_INT_EN | OHCI_INT_ERR | OHCI_INT_PHY_SID
 1741                         | OHCI_INT_PHY_INT
 1742                         | OHCI_INT_DMA_ATRQ | OHCI_INT_DMA_ATRS
 1743                         | OHCI_INT_DMA_PRRQ | OHCI_INT_DMA_PRRS
 1744                         | OHCI_INT_DMA_ARRQ | OHCI_INT_DMA_ARRS
 1745                         | OHCI_INT_PHY_BUS_R);
 1746 
 1747 /* FLUSH FIFO and reset Transmitter/Receiver */
 1748         OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_RESET);
 1749 #endif
 1750 
 1751 /* XXX Link down?  Bus reset? */
 1752         return 0;
 1753 }
 1754 
 1755 int
 1756 fwohci_resume(struct fwohci_softc *sc, device_t dev)
 1757 {
 1758         int i;
 1759         struct fw_xferq *ir;
 1760         struct fw_bulkxfer *chunk;
 1761 
 1762         fwohci_reset(sc, dev);
 1763         /* XXX resume isochronous receive automatically. (how about TX?) */
 1764         for (i = 0; i < sc->fc.nisodma; i++) {
 1765                 ir = &sc->ir[i].xferq;
 1766                 if ((ir->flag & FWXFERQ_RUNNING) != 0) {
 1767                         device_printf(sc->fc.dev,
 1768                                 "resume iso receive ch: %d\n", i);
 1769                         ir->flag &= ~FWXFERQ_RUNNING;
 1770                         /* requeue stdma to stfree */
 1771                         while ((chunk = STAILQ_FIRST(&ir->stdma)) != NULL) {
 1772                                 STAILQ_REMOVE_HEAD(&ir->stdma, link);
 1773                                 STAILQ_INSERT_TAIL(&ir->stfree, chunk, link);
 1774                         }
 1775                         sc->fc.irx_enable(&sc->fc, i);
 1776                 }
 1777         }
 1778 
 1779         bus_generic_resume(dev);
 1780         sc->fc.ibr(&sc->fc);
 1781         return 0;
 1782 }
 1783 
 1784 #ifdef OHCI_DEBUG
 1785 static void
 1786 fwohci_dump_intr(struct fwohci_softc *sc, uint32_t stat)
 1787 {
 1788         if (stat & OREAD(sc, FWOHCI_INTMASK))
 1789                 device_printf(fc->dev, "INTERRUPT < %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s> 0x%08x, 0x%08x\n",
 1790                         stat & OHCI_INT_EN ? "DMA_EN ":"",
 1791                         stat & OHCI_INT_PHY_REG ? "PHY_REG ":"",
 1792                         stat & OHCI_INT_CYC_LONG ? "CYC_LONG ":"",
 1793                         stat & OHCI_INT_ERR ? "INT_ERR ":"",
 1794                         stat & OHCI_INT_CYC_ERR ? "CYC_ERR ":"",
 1795                         stat & OHCI_INT_CYC_LOST ? "CYC_LOST ":"",
 1796                         stat & OHCI_INT_CYC_64SECOND ? "CYC_64SECOND ":"",
 1797                         stat & OHCI_INT_CYC_START ? "CYC_START ":"",
 1798                         stat & OHCI_INT_PHY_INT ? "PHY_INT ":"",
 1799                         stat & OHCI_INT_PHY_BUS_R ? "BUS_RESET ":"",
 1800                         stat & OHCI_INT_PHY_SID ? "SID ":"",
 1801                         stat & OHCI_INT_LR_ERR ? "DMA_LR_ERR ":"",
 1802                         stat & OHCI_INT_PW_ERR ? "DMA_PW_ERR ":"",
 1803                         stat & OHCI_INT_DMA_IR ? "DMA_IR ":"",
 1804                         stat & OHCI_INT_DMA_IT  ? "DMA_IT " :"",
 1805                         stat & OHCI_INT_DMA_PRRS  ? "DMA_PRRS " :"",
 1806                         stat & OHCI_INT_DMA_PRRQ  ? "DMA_PRRQ " :"",
 1807                         stat & OHCI_INT_DMA_ARRS  ? "DMA_ARRS " :"",
 1808                         stat & OHCI_INT_DMA_ARRQ  ? "DMA_ARRQ " :"",
 1809                         stat & OHCI_INT_DMA_ATRS  ? "DMA_ATRS " :"",
 1810                         stat & OHCI_INT_DMA_ATRQ  ? "DMA_ATRQ " :"",
 1811                         stat, OREAD(sc, FWOHCI_INTMASK)
 1812                 );
 1813 }
 1814 #endif
 1815 
 1816 static void
 1817 fwohci_intr_core(struct fwohci_softc *sc, uint32_t stat, int count)
 1818 {
 1819         struct firewire_comm *fc = (struct firewire_comm *)sc;
 1820         uintmax_t prequpper;
 1821         uint32_t node_id, plen;
 1822 
 1823         FW_GLOCK_ASSERT(fc);
 1824         if ((stat & OHCI_INT_PHY_BUS_R) && (fc->status != FWBUSRESET)) {
 1825                 fc->status = FWBUSRESET;
 1826                 /* Disable bus reset interrupt until sid recv. */
 1827                 OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_PHY_BUS_R);
 1828 
 1829                 device_printf(fc->dev, "%s: BUS reset\n", __func__);
 1830                 OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_CYC_LOST);
 1831                 OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCSRC);
 1832 
 1833                 OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN);
 1834                 sc->atrq.xferq.flag &= ~FWXFERQ_RUNNING;
 1835                 OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN);
 1836                 sc->atrs.xferq.flag &= ~FWXFERQ_RUNNING;
 1837 
 1838                 if (!kdb_active)
 1839                         taskqueue_enqueue(sc->fc.taskqueue, &sc->fwohci_task_busreset);
 1840         }
 1841         if (stat & OHCI_INT_PHY_SID) {
 1842                 /* Enable bus reset interrupt */
 1843                 OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_PHY_BUS_R);
 1844                 OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_PHY_BUS_R);
 1845 
 1846                 /* Allow async. request to us */
 1847                 OWRITE(sc, OHCI_AREQHI, 1 << 31);
 1848                 if (firewire_phydma_enable) {
 1849                         /* allow from all nodes */
 1850                         OWRITE(sc, OHCI_PREQHI, 0x7fffffff);
 1851                         OWRITE(sc, OHCI_PREQLO, 0xffffffff);
 1852                         prequpper = ((uintmax_t)Maxmem << PAGE_SHIFT) >> 16;
 1853                         if (prequpper > OHCI_PREQUPPER_MAX) {
 1854                                 device_printf(fc->dev,
 1855                                     "Physical memory size of 0x%jx exceeds "
 1856                                     "fire wire address space.  Limiting dma "
 1857                                     "to memory below 0x%jx\n",
 1858                                     (uintmax_t)Maxmem << PAGE_SHIFT,
 1859                                     (uintmax_t)OHCI_PREQUPPER_MAX << 16);
 1860                                 prequpper = OHCI_PREQUPPER_MAX;
 1861                         }
 1862                         OWRITE(sc, OHCI_PREQUPPER, prequpper & 0xffffffff);
 1863                         if (OREAD(sc, OHCI_PREQUPPER) !=
 1864                             (prequpper & 0xffffffff)) {
 1865                                 device_printf(fc->dev,
 1866                                    "PhysicalUpperBound register is not "
 1867                                    "implemented.  Physical memory access "
 1868                                    "is limited to the first 4GB\n");
 1869                                 device_printf(fc->dev,
 1870                                    "PhysicalUpperBound = 0x%08x\n",
 1871                                     OREAD(sc, OHCI_PREQUPPER));
 1872                         }
 1873                 }
 1874                 /* Set ATRetries register */
 1875                 OWRITE(sc, OHCI_ATRETRY, 1<<(13 + 16) | 0xfff);
 1876 
 1877                 /*
 1878                  * Checking whether the node is root or not. If root, turn on
 1879                  * cycle master.
 1880                  */
 1881                 node_id = OREAD(sc, FWOHCI_NODEID);
 1882                 plen = OREAD(sc, OHCI_SID_CNT);
 1883 
 1884                 fc->nodeid = node_id & 0x3f;
 1885                 device_printf(fc->dev, "%s: node_id=0x%08x, SelfID Count=%d, ",
 1886                                 __func__, fc->nodeid, (plen >> 16) & 0xff);
 1887                 if (!(node_id & OHCI_NODE_VALID)) {
 1888                         device_printf(fc->dev, "%s: Bus reset failure\n",
 1889                                 __func__);
 1890                         goto sidout;
 1891                 }
 1892 
 1893                 /* cycle timer */
 1894                 sc->cycle_lost = 0;
 1895                 OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_CYC_LOST);
 1896                 if ((node_id & OHCI_NODE_ROOT) && !nocyclemaster) {
 1897                         printf("CYCLEMASTER mode\n");
 1898                         OWRITE(sc, OHCI_LNKCTL,
 1899                                 OHCI_CNTL_CYCMTR | OHCI_CNTL_CYCTIMER);
 1900                 } else {
 1901                         printf("non CYCLEMASTER mode\n");
 1902                         OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCMTR);
 1903                         OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_CYCTIMER);
 1904                 }
 1905 
 1906                 fc->status = FWBUSINIT;
 1907 
 1908                 if (!kdb_active)
 1909                         taskqueue_enqueue(sc->fc.taskqueue, &sc->fwohci_task_sid);
 1910         }
 1911 sidout:
 1912         if ((stat & ~(OHCI_INT_PHY_BUS_R | OHCI_INT_PHY_SID)) && (!kdb_active))
 1913                 taskqueue_enqueue(sc->fc.taskqueue, &sc->fwohci_task_dma);
 1914 }
 1915 
 1916 static void
 1917 fwohci_intr_dma(struct fwohci_softc *sc, uint32_t stat, int count)
 1918 {
 1919         uint32_t irstat, itstat;
 1920         u_int i;
 1921         struct firewire_comm *fc = (struct firewire_comm *)sc;
 1922 
 1923         if (stat & OHCI_INT_DMA_IR) {
 1924                 irstat = atomic_readandclear_int(&sc->irstat);
 1925                 for (i = 0; i < fc->nisodma; i++) {
 1926                         struct fwohci_dbch *dbch;
 1927 
 1928                         if ((irstat & (1 << i)) != 0) {
 1929                                 dbch = &sc->ir[i];
 1930                                 if ((dbch->xferq.flag & FWXFERQ_OPEN) == 0) {
 1931                                         device_printf(sc->fc.dev,
 1932                                                 "dma(%d) not active\n", i);
 1933                                         continue;
 1934                                 }
 1935                                 fwohci_rbuf_update(sc, i);
 1936                         }
 1937                 }
 1938         }
 1939         if (stat & OHCI_INT_DMA_IT) {
 1940                 itstat = atomic_readandclear_int(&sc->itstat);
 1941                 for (i = 0; i < fc->nisodma; i++) {
 1942                         if ((itstat & (1 << i)) != 0) {
 1943                                 fwohci_tbuf_update(sc, i);
 1944                         }
 1945                 }
 1946         }
 1947         if (stat & OHCI_INT_DMA_PRRS) {
 1948 #if 0
 1949                 dump_dma(sc, ARRS_CH);
 1950                 dump_db(sc, ARRS_CH);
 1951 #endif
 1952                 fwohci_arcv(sc, &sc->arrs, count);
 1953         }
 1954         if (stat & OHCI_INT_DMA_PRRQ) {
 1955 #if 0
 1956                 dump_dma(sc, ARRQ_CH);
 1957                 dump_db(sc, ARRQ_CH);
 1958 #endif
 1959                 fwohci_arcv(sc, &sc->arrq, count);
 1960         }
 1961         if (stat & OHCI_INT_CYC_LOST) {
 1962                 if (sc->cycle_lost >= 0)
 1963                         sc->cycle_lost++;
 1964                 if (sc->cycle_lost > 10) {
 1965                         sc->cycle_lost = -1;
 1966 #if 0
 1967                         OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCTIMER);
 1968 #endif
 1969                         OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_CYC_LOST);
 1970                         device_printf(fc->dev, "too many cycles lost, "
 1971                          "no cycle master present?\n");
 1972                 }
 1973         }
 1974         if (stat & OHCI_INT_DMA_ATRQ) {
 1975                 fwohci_txd(sc, &(sc->atrq));
 1976         }
 1977         if (stat & OHCI_INT_DMA_ATRS) {
 1978                 fwohci_txd(sc, &(sc->atrs));
 1979         }
 1980         if (stat & OHCI_INT_PW_ERR) {
 1981                 device_printf(fc->dev, "posted write error\n");
 1982         }
 1983         if (stat & OHCI_INT_ERR) {
 1984                 device_printf(fc->dev, "unrecoverable error\n");
 1985         }
 1986         if (stat & OHCI_INT_PHY_INT) {
 1987                 device_printf(fc->dev, "phy int\n");
 1988         }
 1989 }
 1990 
 1991 static void
 1992 fwohci_task_busreset(void *arg, int pending)
 1993 {
 1994         struct fwohci_softc *sc = (struct fwohci_softc *)arg;
 1995 
 1996         FW_GLOCK(&sc->fc);
 1997         fw_busreset(&sc->fc, FWBUSRESET);
 1998         OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0]));
 1999         OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2]));
 2000         FW_GUNLOCK(&sc->fc);
 2001 }
 2002 
 2003 static void
 2004 fwohci_task_sid(void *arg, int pending)
 2005 {
 2006         struct fwohci_softc *sc = (struct fwohci_softc *)arg;
 2007         struct firewire_comm *fc = &sc->fc;
 2008         uint32_t *buf;
 2009         int i, plen;
 2010 
 2011 
 2012         /*
 2013          * We really should have locking
 2014          * here.  Not sure why it's not
 2015          */
 2016         plen = OREAD(sc, OHCI_SID_CNT);
 2017 
 2018         if (plen & OHCI_SID_ERR) {
 2019                 device_printf(fc->dev, "SID Error\n");
 2020                 return;
 2021         }
 2022         plen &= OHCI_SID_CNT_MASK;
 2023         if (plen < 4 || plen > OHCI_SIDSIZE) {
 2024                 device_printf(fc->dev, "invalid SID len = %d\n", plen);
 2025                 return;
 2026         }
 2027         plen -= 4; /* chop control info */
 2028         buf = (uint32_t *)malloc(OHCI_SIDSIZE, M_FW, M_NOWAIT);
 2029         if (buf == NULL) {
 2030                 device_printf(fc->dev, "malloc failed\n");
 2031                 return;
 2032         }
 2033         for (i = 0; i < plen / 4; i++)
 2034                 buf[i] = FWOHCI_DMA_READ(sc->sid_buf[i + 1]);
 2035 
 2036         /* pending all pre-bus_reset packets */
 2037         fwohci_txd(sc, &sc->atrq);
 2038         fwohci_txd(sc, &sc->atrs);
 2039         fwohci_arcv(sc, &sc->arrs, -1);
 2040         fwohci_arcv(sc, &sc->arrq, -1);
 2041         fw_drain_txq(fc);
 2042         fw_sidrcv(fc, buf, plen);
 2043         free(buf, M_FW);
 2044 }
 2045 
 2046 static void
 2047 fwohci_task_dma(void *arg, int pending)
 2048 {
 2049         struct fwohci_softc *sc = (struct fwohci_softc *)arg;
 2050         uint32_t stat;
 2051 
 2052 again:
 2053         stat = atomic_readandclear_int(&sc->intstat);
 2054         if (stat)
 2055                 fwohci_intr_dma(sc, stat, -1);
 2056         else
 2057                 return;
 2058         goto again;
 2059 }
 2060 
 2061 static int
 2062 fwohci_check_stat(struct fwohci_softc *sc)
 2063 {
 2064         uint32_t stat, irstat, itstat;
 2065 
 2066         FW_GLOCK_ASSERT(&sc->fc);
 2067         stat = OREAD(sc, FWOHCI_INTSTAT);
 2068         if (stat == 0xffffffff) {
 2069                 if (!bus_child_present(sc->fc.dev))
 2070                         return (FILTER_HANDLED);
 2071                 device_printf(sc->fc.dev, "device physically ejected?\n");
 2072                 return (FILTER_STRAY);
 2073         }
 2074         if (stat)
 2075                 OWRITE(sc, FWOHCI_INTSTATCLR, stat & ~OHCI_INT_PHY_BUS_R);
 2076 
 2077         stat &= sc->intmask;
 2078         if (stat == 0)
 2079                 return (FILTER_STRAY);
 2080 
 2081         atomic_set_int(&sc->intstat, stat);
 2082         if (stat & OHCI_INT_DMA_IR) {
 2083                 irstat = OREAD(sc, OHCI_IR_STAT);
 2084                 OWRITE(sc, OHCI_IR_STATCLR, irstat);
 2085                 atomic_set_int(&sc->irstat, irstat);
 2086         }
 2087         if (stat & OHCI_INT_DMA_IT) {
 2088                 itstat = OREAD(sc, OHCI_IT_STAT);
 2089                 OWRITE(sc, OHCI_IT_STATCLR, itstat);
 2090                 atomic_set_int(&sc->itstat, itstat);
 2091         }
 2092 
 2093         fwohci_intr_core(sc, stat, -1);
 2094         return (FILTER_HANDLED);
 2095 }
 2096 
 2097 void
 2098 fwohci_intr(void *arg)
 2099 {
 2100         struct fwohci_softc *sc = (struct fwohci_softc *)arg;
 2101 
 2102         FW_GLOCK(&sc->fc);
 2103         fwohci_check_stat(sc);
 2104         FW_GUNLOCK(&sc->fc);
 2105 }
 2106 
 2107 void
 2108 fwohci_poll(struct firewire_comm *fc, int quick, int count)
 2109 {
 2110         struct fwohci_softc *sc = (struct fwohci_softc *)fc;
 2111 
 2112         FW_GLOCK(fc);
 2113         fwohci_check_stat(sc);
 2114         FW_GUNLOCK(fc);
 2115 }
 2116 
 2117 static void
 2118 fwohci_set_intr(struct firewire_comm *fc, int enable)
 2119 {
 2120         struct fwohci_softc *sc;
 2121 
 2122         sc = (struct fwohci_softc *)fc;
 2123         if (firewire_debug)
 2124                 device_printf(sc->fc.dev, "fwohci_set_intr: %d\n", enable);
 2125         if (enable) {
 2126                 sc->intmask |= OHCI_INT_EN;
 2127                 OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_EN);
 2128         } else {
 2129                 sc->intmask &= ~OHCI_INT_EN;
 2130                 OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_EN);
 2131         }
 2132 }
 2133 
 2134 static void
 2135 fwohci_tbuf_update(struct fwohci_softc *sc, int dmach)
 2136 {
 2137         struct firewire_comm *fc = &sc->fc;
 2138         struct fwohcidb *db;
 2139         struct fw_bulkxfer *chunk;
 2140         struct fw_xferq *it;
 2141         uint32_t stat, count __unused;
 2142         int s, w=0, ldesc;
 2143 
 2144         it = fc->it[dmach];
 2145         ldesc = sc->it[dmach].ndesc - 1;
 2146         s = splfw(); /* unnecessary ? */
 2147         FW_GLOCK(fc);
 2148         fwdma_sync_multiseg_all(sc->it[dmach].am, BUS_DMASYNC_POSTREAD);
 2149         if (firewire_debug)
 2150                 dump_db(sc, ITX_CH + dmach);
 2151         while ((chunk = STAILQ_FIRST(&it->stdma)) != NULL) {
 2152                 db = ((struct fwohcidb_tr *)(chunk->end))->db;
 2153                 stat = FWOHCI_DMA_READ(db[ldesc].db.desc.res)
 2154                                 >> OHCI_STATUS_SHIFT;
 2155                 db = ((struct fwohcidb_tr *)(chunk->start))->db;
 2156                 /* timestamp */
 2157                 count = FWOHCI_DMA_READ(db[ldesc].db.desc.res)
 2158                                 & OHCI_COUNT_MASK;
 2159                 if (stat == 0)
 2160                         break;
 2161                 STAILQ_REMOVE_HEAD(&it->stdma, link);
 2162                 switch (stat & FWOHCIEV_MASK) {
 2163                 case FWOHCIEV_ACKCOMPL:
 2164 #if 0
 2165                         device_printf(fc->dev, "0x%08x\n", count);
 2166 #endif
 2167                         break;
 2168                 default:
 2169                         device_printf(fc->dev,
 2170                                 "Isochronous transmit err %02x(%s)\n",
 2171                                         stat, fwohcicode[stat & 0x1f]);
 2172                 }
 2173                 STAILQ_INSERT_TAIL(&it->stfree, chunk, link);
 2174                 w++;
 2175         }
 2176         FW_GUNLOCK(fc);
 2177         splx(s);
 2178         if (w)
 2179                 wakeup(it);
 2180 }
 2181 
 2182 static void
 2183 fwohci_rbuf_update(struct fwohci_softc *sc, int dmach)
 2184 {
 2185         struct firewire_comm *fc = &sc->fc;
 2186         struct fwohcidb_tr *db_tr;
 2187         struct fw_bulkxfer *chunk;
 2188         struct fw_xferq *ir;
 2189         uint32_t stat;
 2190         int w = 0, ldesc;
 2191 
 2192         ir = fc->ir[dmach];
 2193         ldesc = sc->ir[dmach].ndesc - 1;
 2194 
 2195 #if 0
 2196         dump_db(sc, dmach);
 2197 #endif
 2198         if ((ir->flag & FWXFERQ_HANDLER) == 0)
 2199                 FW_GLOCK(fc);
 2200         fwdma_sync_multiseg_all(sc->ir[dmach].am, BUS_DMASYNC_POSTREAD);
 2201         while ((chunk = STAILQ_FIRST(&ir->stdma)) != NULL) {
 2202                 db_tr = (struct fwohcidb_tr *)chunk->end;
 2203                 stat = FWOHCI_DMA_READ(db_tr->db[ldesc].db.desc.res)
 2204                                 >> OHCI_STATUS_SHIFT;
 2205                 if (stat == 0)
 2206                         break;
 2207 
 2208                 if (chunk->mbuf != NULL) {
 2209                         bus_dmamap_sync(sc->ir[dmach].dmat, db_tr->dma_map,
 2210                                                 BUS_DMASYNC_POSTREAD);
 2211                         bus_dmamap_unload(sc->ir[dmach].dmat, db_tr->dma_map);
 2212                 } else if (ir->buf != NULL) {
 2213                         fwdma_sync_multiseg(ir->buf, chunk->poffset,
 2214                                 ir->bnpacket, BUS_DMASYNC_POSTREAD);
 2215                 } else {
 2216                         /* XXX */
 2217                         printf("fwohci_rbuf_update: this shouldn't happened\n");
 2218                 }
 2219 
 2220                 STAILQ_REMOVE_HEAD(&ir->stdma, link);
 2221                 STAILQ_INSERT_TAIL(&ir->stvalid, chunk, link);
 2222                 switch (stat & FWOHCIEV_MASK) {
 2223                 case FWOHCIEV_ACKCOMPL:
 2224                         chunk->resp = 0;
 2225                         break;
 2226                 default:
 2227                         chunk->resp = EINVAL;
 2228                         device_printf(fc->dev,
 2229                                 "Isochronous receive err %02x(%s)\n",
 2230                                         stat, fwohcicode[stat & 0x1f]);
 2231                 }
 2232                 w++;
 2233         }
 2234         if ((ir->flag & FWXFERQ_HANDLER) == 0)
 2235                 FW_GUNLOCK(fc);
 2236         if (w == 0)
 2237                 return;
 2238 
 2239         if (ir->flag & FWXFERQ_HANDLER)
 2240                 ir->hand(ir);
 2241         else
 2242                 wakeup(ir);
 2243 }
 2244 
 2245 void
 2246 dump_dma(struct fwohci_softc *sc, uint32_t ch)
 2247 {
 2248         uint32_t off, cntl, stat, cmd, match;
 2249 
 2250         if (ch == 0) {
 2251                 off = OHCI_ATQOFF;
 2252         } else if (ch == 1) {
 2253                 off = OHCI_ATSOFF;
 2254         } else if (ch == 2) {
 2255                 off = OHCI_ARQOFF;
 2256         } else if (ch == 3) {
 2257                 off = OHCI_ARSOFF;
 2258         } else if (ch < IRX_CH) {
 2259                 off = OHCI_ITCTL(ch - ITX_CH);
 2260         } else {
 2261                 off = OHCI_IRCTL(ch - IRX_CH);
 2262         }
 2263         cntl = stat = OREAD(sc, off);
 2264         cmd = OREAD(sc, off + 0xc);
 2265         match = OREAD(sc, off + 0x10);
 2266 
 2267         device_printf(sc->fc.dev, "ch %1x cntl:0x%08x cmd:0x%08x match:0x%08x\n",
 2268                 ch,
 2269                 cntl,
 2270                 cmd,
 2271                 match);
 2272         stat &= 0xffff;
 2273         if (stat) {
 2274                 device_printf(sc->fc.dev, "dma %d ch:%s%s%s%s%s%s %s(%x)\n",
 2275                         ch,
 2276                         stat & OHCI_CNTL_DMA_RUN ? "RUN," : "",
 2277                         stat & OHCI_CNTL_DMA_WAKE ? "WAKE," : "",
 2278                         stat & OHCI_CNTL_DMA_DEAD ? "DEAD," : "",
 2279                         stat & OHCI_CNTL_DMA_ACTIVE ? "ACTIVE," : "",
 2280                         stat & OHCI_CNTL_DMA_BT ? "BRANCH," : "",
 2281                         stat & OHCI_CNTL_DMA_BAD ? "BADDMA," : "",
 2282                         fwohcicode[stat & 0x1f],
 2283                         stat & 0x1f
 2284                 );
 2285         } else {
 2286                 device_printf(sc->fc.dev, "dma %d ch: Nostat\n", ch);
 2287         }
 2288 }
 2289 
 2290 void
 2291 dump_db(struct fwohci_softc *sc, uint32_t ch)
 2292 {
 2293         struct fwohci_dbch *dbch;
 2294         struct fwohcidb_tr *cp = NULL, *pp;
 2295         struct fwohcidb *curr = NULL;
 2296 #if 0
 2297         struct fwohcidb *prev
 2298         struct fwohcidb *next = NULL;
 2299         struct fwohcidb_tr *np = NULL;
 2300 #endif
 2301         int idb, jdb;
 2302         uint32_t cmd, off;
 2303 
 2304         if (ch == 0) {
 2305                 off = OHCI_ATQOFF;
 2306                 dbch = &sc->atrq;
 2307         } else if (ch == 1) {
 2308                 off = OHCI_ATSOFF;
 2309                 dbch = &sc->atrs;
 2310         } else if (ch == 2) {
 2311                 off = OHCI_ARQOFF;
 2312                 dbch = &sc->arrq;
 2313         } else if (ch == 3) {
 2314                 off = OHCI_ARSOFF;
 2315                 dbch = &sc->arrs;
 2316         } else if (ch < IRX_CH) {
 2317                 off = OHCI_ITCTL(ch - ITX_CH);
 2318                 dbch = &sc->it[ch - ITX_CH];
 2319         } else {
 2320                 off = OHCI_IRCTL(ch - IRX_CH);
 2321                 dbch = &sc->ir[ch - IRX_CH];
 2322         }
 2323         cmd = OREAD(sc, off + 0xc);
 2324 
 2325         if (dbch->ndb == 0) {
 2326                 device_printf(sc->fc.dev, "No DB is attached ch=%d\n", ch);
 2327                 return;
 2328         }
 2329         pp = dbch->top;
 2330 #if 0
 2331         prev = pp->db;
 2332 #endif
 2333         for (idb = 0; idb < dbch->ndb; idb++) {
 2334                 cp = STAILQ_NEXT(pp, link);
 2335                 if (cp == NULL) {
 2336                         curr = NULL;
 2337                         goto outdb;
 2338                 }
 2339 #if 0
 2340                 np = STAILQ_NEXT(cp, link);
 2341 #endif
 2342                 for (jdb = 0; jdb < dbch->ndesc; jdb++) {
 2343                         if ((cmd  & 0xfffffff0) == cp->bus_addr) {
 2344                                 curr = cp->db;
 2345 #if 0
 2346                                 if (np != NULL) {
 2347                                         next = np->db;
 2348                                 } else {
 2349                                         next = NULL;
 2350                                 }
 2351 #endif
 2352                                 goto outdb;
 2353                         }
 2354                 }
 2355                 pp = STAILQ_NEXT(pp, link);
 2356                 if (pp == NULL) {
 2357                         curr = NULL;
 2358                         goto outdb;
 2359                 }
 2360 #if 0
 2361                 prev = pp->db;
 2362 #endif
 2363         }
 2364 outdb:
 2365         if (curr != NULL) {
 2366 #if 0
 2367                 printf("Prev DB %d\n", ch);
 2368                 print_db(pp, prev, ch, dbch->ndesc);
 2369 #endif
 2370                 printf("Current DB %d\n", ch);
 2371                 print_db(cp, curr, ch, dbch->ndesc);
 2372 #if 0
 2373                 printf("Next DB %d\n", ch);
 2374                 print_db(np, next, ch, dbch->ndesc);
 2375 #endif
 2376         } else {
 2377                 printf("dbdump err ch = %d cmd = 0x%08x\n", ch, cmd);
 2378         }
 2379         return;
 2380 }
 2381 
 2382 void
 2383 print_db(struct fwohcidb_tr *db_tr, struct fwohcidb *db,
 2384                 uint32_t ch, uint32_t max)
 2385 {
 2386         fwohcireg_t stat;
 2387         int i, key;
 2388         uint32_t cmd, res;
 2389 
 2390         if (db == NULL) {
 2391                 printf("No Descriptor is found\n");
 2392                 return;
 2393         }
 2394 
 2395         printf("ch = %d\n%8s %s %s %s %s %4s %8s %8s %4s:%4s\n",
 2396                 ch,
 2397                 "Current",
 2398                 "OP  ",
 2399                 "KEY",
 2400                 "INT",
 2401                 "BR ",
 2402                 "len",
 2403                 "Addr",
 2404                 "Depend",
 2405                 "Stat",
 2406                 "Cnt");
 2407         for (i = 0; i <= max; i++) {
 2408                 cmd = FWOHCI_DMA_READ(db[i].db.desc.cmd);
 2409                 res = FWOHCI_DMA_READ(db[i].db.desc.res);
 2410                 key = cmd & OHCI_KEY_MASK;
 2411                 stat = res >> OHCI_STATUS_SHIFT;
 2412                 printf("%08jx %s %s %s %s %5d %08x %08x %04x:%04x",
 2413                                 (uintmax_t)db_tr->bus_addr,
 2414                                 dbcode[(cmd >> 28) & 0xf],
 2415                                 dbkey[(cmd >> 24) & 0x7],
 2416                                 dbcond[(cmd >> 20) & 0x3],
 2417                                 dbcond[(cmd >> 18) & 0x3],
 2418                                 cmd & OHCI_COUNT_MASK,
 2419                                 FWOHCI_DMA_READ(db[i].db.desc.addr),
 2420                                 FWOHCI_DMA_READ(db[i].db.desc.depend),
 2421                                 stat,
 2422                                 res & OHCI_COUNT_MASK);
 2423                 if (stat & 0xff00) {
 2424                         printf(" %s%s%s%s%s%s %s(%x)\n",
 2425                                 stat & OHCI_CNTL_DMA_RUN ? "RUN," : "",
 2426                                 stat & OHCI_CNTL_DMA_WAKE ? "WAKE," : "",
 2427                                 stat & OHCI_CNTL_DMA_DEAD ? "DEAD," : "",
 2428                                 stat & OHCI_CNTL_DMA_ACTIVE ? "ACTIVE," : "",
 2429                                 stat & OHCI_CNTL_DMA_BT ? "BRANCH," : "",
 2430                                 stat & OHCI_CNTL_DMA_BAD ? "BADDMA," : "",
 2431                                 fwohcicode[stat & 0x1f],
 2432                                 stat & 0x1f
 2433                         );
 2434                 } else {
 2435                         printf(" Nostat\n");
 2436                 }
 2437                 if (key == OHCI_KEY_ST2) {
 2438                         printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
 2439                                 FWOHCI_DMA_READ(db[i + 1].db.immed[0]),
 2440                                 FWOHCI_DMA_READ(db[i + 1].db.immed[1]),
 2441                                 FWOHCI_DMA_READ(db[i + 1].db.immed[2]),
 2442                                 FWOHCI_DMA_READ(db[i + 1].db.immed[3]));
 2443                 }
 2444                 if (key == OHCI_KEY_DEVICE) {
 2445                         return;
 2446                 }
 2447                 if ((cmd & OHCI_BRANCH_MASK)
 2448                                 == OHCI_BRANCH_ALWAYS) {
 2449                         return;
 2450                 }
 2451                 if ((cmd & OHCI_CMD_MASK)
 2452                                 == OHCI_OUTPUT_LAST) {
 2453                         return;
 2454                 }
 2455                 if ((cmd & OHCI_CMD_MASK)
 2456                                 == OHCI_INPUT_LAST) {
 2457                         return;
 2458                 }
 2459                 if (key == OHCI_KEY_ST2) {
 2460                         i++;
 2461                 }
 2462         }
 2463         return;
 2464 }
 2465 
 2466 void
 2467 fwohci_ibr(struct firewire_comm *fc)
 2468 {
 2469         struct fwohci_softc *sc;
 2470         uint32_t fun;
 2471 
 2472         device_printf(fc->dev, "Initiate bus reset\n");
 2473         sc = (struct fwohci_softc *)fc;
 2474 
 2475         FW_GLOCK(fc);
 2476         /*
 2477          * Make sure our cached values from the config rom are
 2478          * initialised.
 2479          */
 2480         OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0]));
 2481         OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2]));
 2482 
 2483         /*
 2484          * Set root hold-off bit so that non cyclemaster capable node
 2485          * shouldn't became the root node.
 2486          */
 2487 #if 1
 2488         fun = fwphy_rddata(sc, FW_PHY_IBR_REG);
 2489         fun |= FW_PHY_IBR | FW_PHY_RHB;
 2490         fun = fwphy_wrdata(sc, FW_PHY_IBR_REG, fun);
 2491 #else   /* Short bus reset */
 2492         fun = fwphy_rddata(sc, FW_PHY_ISBR_REG);
 2493         fun |= FW_PHY_ISBR | FW_PHY_RHB;
 2494         fun = fwphy_wrdata(sc, FW_PHY_ISBR_REG, fun);
 2495 #endif
 2496         FW_GUNLOCK(fc);
 2497 }
 2498 
 2499 void
 2500 fwohci_txbufdb(struct fwohci_softc *sc, int dmach, struct fw_bulkxfer *bulkxfer)
 2501 {
 2502         struct fwohcidb_tr *db_tr;
 2503 #if 0
 2504         struct fwohcidb_tr *fdb_tr;
 2505 #endif
 2506         struct fwohci_dbch *dbch;
 2507         struct fwohcidb *db;
 2508         struct fw_pkt *fp;
 2509         struct fwohci_txpkthdr *ohcifp;
 2510         unsigned short chtag;
 2511         int idb;
 2512 
 2513         FW_GLOCK_ASSERT(&sc->fc);
 2514 
 2515         dbch = &sc->it[dmach];
 2516         chtag = sc->it[dmach].xferq.flag & 0xff;
 2517 
 2518         db_tr = (struct fwohcidb_tr *)(bulkxfer->start);
 2519 #if 0
 2520         fdb_tr = (struct fwohcidb_tr *)(bulkxfer->end);
 2521 device_printf(sc->fc.dev, "DB %08x %08x %08x\n", bulkxfer, db_tr->bus_addr, fdb_tr->bus_addr);
 2522 #endif
 2523         for (idb = 0; idb < dbch->xferq.bnpacket; idb++) {
 2524                 db = db_tr->db;
 2525                 fp = (struct fw_pkt *)db_tr->buf;
 2526                 ohcifp = (struct fwohci_txpkthdr *) db[1].db.immed;
 2527                 ohcifp->mode.ld[0] = fp->mode.ld[0];
 2528                 ohcifp->mode.common.spd = 0 & 0x7;
 2529                 ohcifp->mode.stream.len = fp->mode.stream.len;
 2530                 ohcifp->mode.stream.chtag = chtag;
 2531                 ohcifp->mode.stream.tcode = 0xa;
 2532 #if BYTE_ORDER == BIG_ENDIAN
 2533                 FWOHCI_DMA_WRITE(db[1].db.immed[0], db[1].db.immed[0]);
 2534                 FWOHCI_DMA_WRITE(db[1].db.immed[1], db[1].db.immed[1]);
 2535 #endif
 2536 
 2537                 FWOHCI_DMA_CLEAR(db[2].db.desc.cmd, OHCI_COUNT_MASK);
 2538                 FWOHCI_DMA_SET(db[2].db.desc.cmd, fp->mode.stream.len);
 2539                 FWOHCI_DMA_WRITE(db[2].db.desc.res, 0);
 2540 #if 0 /* if bulkxfer->npackets changes */
 2541                 db[2].db.desc.cmd = OHCI_OUTPUT_LAST
 2542                         | OHCI_UPDATE
 2543                         | OHCI_BRANCH_ALWAYS;
 2544                 db[0].db.desc.depend =
 2545                         = db[dbch->ndesc - 1].db.desc.depend
 2546                         = STAILQ_NEXT(db_tr, link)->bus_addr | dbch->ndesc;
 2547 #else
 2548                 FWOHCI_DMA_SET(db[0].db.desc.depend, dbch->ndesc);
 2549                 FWOHCI_DMA_SET(db[dbch->ndesc - 1].db.desc.depend, dbch->ndesc);
 2550 #endif
 2551                 bulkxfer->end = (caddr_t)db_tr;
 2552                 db_tr = STAILQ_NEXT(db_tr, link);
 2553         }
 2554         db = ((struct fwohcidb_tr *)bulkxfer->end)->db;
 2555         FWOHCI_DMA_CLEAR(db[0].db.desc.depend, 0xf);
 2556         FWOHCI_DMA_CLEAR(db[dbch->ndesc - 1].db.desc.depend, 0xf);
 2557 #if 0 /* if bulkxfer->npackets changes */
 2558         db[dbch->ndesc - 1].db.desc.control |= OHCI_INTERRUPT_ALWAYS;
 2559         /* OHCI 1.1 and above */
 2560         db[0].db.desc.control |= OHCI_INTERRUPT_ALWAYS;
 2561 #endif
 2562 #if 0
 2563         db_tr = (struct fwohcidb_tr *)bulkxfer->start;
 2564         fdb_tr = (struct fwohcidb_tr *)bulkxfer->end;
 2565 device_printf(sc->fc.dev, "DB %08x %3d %08x %08x\n", bulkxfer, bulkxfer->npacket, db_tr->bus_addr, fdb_tr->bus_addr);
 2566 #endif
 2567         return;
 2568 }
 2569 
 2570 static int
 2571 fwohci_add_tx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr,
 2572                                                                 int poffset)
 2573 {
 2574         struct fwohcidb *db = db_tr->db;
 2575         struct fw_xferq *it;
 2576         int err = 0;
 2577 
 2578         it = &dbch->xferq;
 2579         if (it->buf == 0) {
 2580                 err = EINVAL;
 2581                 return err;
 2582         }
 2583         db_tr->buf = fwdma_v_addr(it->buf, poffset);
 2584         db_tr->dbcnt = 3;
 2585 
 2586         FWOHCI_DMA_WRITE(db[0].db.desc.cmd,
 2587                 OHCI_OUTPUT_MORE | OHCI_KEY_ST2 | 8);
 2588         FWOHCI_DMA_WRITE(db[0].db.desc.addr, 0);
 2589         bzero((void *)&db[1].db.immed[0], sizeof(db[1].db.immed));
 2590         FWOHCI_DMA_WRITE(db[2].db.desc.addr,
 2591         fwdma_bus_addr(it->buf, poffset) + sizeof(uint32_t));
 2592 
 2593         FWOHCI_DMA_WRITE(db[2].db.desc.cmd,
 2594                 OHCI_OUTPUT_LAST | OHCI_UPDATE | OHCI_BRANCH_ALWAYS);
 2595 #if 1
 2596         FWOHCI_DMA_WRITE(db[0].db.desc.res, 0);
 2597         FWOHCI_DMA_WRITE(db[2].db.desc.res, 0);
 2598 #endif
 2599         return 0;
 2600 }
 2601 
 2602 int
 2603 fwohci_add_rx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr,
 2604                 int poffset, struct fwdma_alloc *dummy_dma)
 2605 {
 2606         struct fwohcidb *db = db_tr->db;
 2607         struct fw_xferq *ir;
 2608         int i, ldesc;
 2609         bus_addr_t dbuf[2];
 2610         int dsiz[2];
 2611 
 2612         ir = &dbch->xferq;
 2613         if (ir->buf == NULL && (dbch->xferq.flag & FWXFERQ_EXTBUF) == 0) {
 2614                 if (db_tr->buf == NULL) {
 2615                         db_tr->buf = fwdma_malloc_size(dbch->dmat,
 2616                             &db_tr->dma_map, ir->psize, &dbuf[0],
 2617                             BUS_DMA_NOWAIT);
 2618                         if (db_tr->buf == NULL)
 2619                                 return (ENOMEM);
 2620                 }
 2621                 db_tr->dbcnt = 1;
 2622                 dsiz[0] = ir->psize;
 2623                 bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
 2624                         BUS_DMASYNC_PREREAD);
 2625         } else {
 2626                 db_tr->dbcnt = 0;
 2627                 if (dummy_dma != NULL) {
 2628                         dsiz[db_tr->dbcnt] = sizeof(uint32_t);
 2629                         dbuf[db_tr->dbcnt++] = dummy_dma->bus_addr;
 2630                 }
 2631                 dsiz[db_tr->dbcnt] = ir->psize;
 2632                 if (ir->buf != NULL) {
 2633                         db_tr->buf = fwdma_v_addr(ir->buf, poffset);
 2634                         dbuf[db_tr->dbcnt] = fwdma_bus_addr(ir->buf, poffset);
 2635                 }
 2636                 db_tr->dbcnt++;
 2637         }
 2638         for (i = 0; i < db_tr->dbcnt; i++) {
 2639                 FWOHCI_DMA_WRITE(db[i].db.desc.addr, dbuf[i]);
 2640                 FWOHCI_DMA_WRITE(db[i].db.desc.cmd, OHCI_INPUT_MORE | dsiz[i]);
 2641                 if (ir->flag & FWXFERQ_STREAM) {
 2642                         FWOHCI_DMA_SET(db[i].db.desc.cmd, OHCI_UPDATE);
 2643                 }
 2644                 FWOHCI_DMA_WRITE(db[i].db.desc.res, dsiz[i]);
 2645         }
 2646         ldesc = db_tr->dbcnt - 1;
 2647         if (ir->flag & FWXFERQ_STREAM) {
 2648                 FWOHCI_DMA_SET(db[ldesc].db.desc.cmd, OHCI_INPUT_LAST);
 2649         }
 2650         FWOHCI_DMA_SET(db[ldesc].db.desc.cmd, OHCI_BRANCH_ALWAYS);
 2651         return 0;
 2652 }
 2653 
 2654 
 2655 static int
 2656 fwohci_arcv_swap(struct fw_pkt *fp, int len)
 2657 {
 2658         struct fw_pkt *fp0;
 2659         uint32_t ld0;
 2660         int hlen;
 2661 #if BYTE_ORDER == BIG_ENDIAN
 2662         int slen;
 2663         int i;
 2664 #endif
 2665 
 2666         ld0 = FWOHCI_DMA_READ(fp->mode.ld[0]);
 2667 #if 0
 2668         printf("ld0: x%08x\n", ld0);
 2669 #endif
 2670         fp0 = (struct fw_pkt *)&ld0;
 2671         /* determine length to swap */
 2672         switch (fp0->mode.common.tcode) {
 2673         case FWTCODE_RREQQ:
 2674         case FWTCODE_WRES:
 2675         case FWTCODE_WREQQ:
 2676         case FWTCODE_RRESQ:
 2677         case FWOHCITCODE_PHY:
 2678 #if BYTE_ORDER == BIG_ENDIAN
 2679                 slen = 12;
 2680 #endif
 2681                 break;
 2682         case FWTCODE_RREQB:
 2683         case FWTCODE_WREQB:
 2684         case FWTCODE_LREQ:
 2685         case FWTCODE_RRESB:
 2686         case FWTCODE_LRES:
 2687 #if BYTE_ORDER == BIG_ENDIAN
 2688                 slen = 16;
 2689 #endif
 2690                 break;
 2691         default:
 2692                 printf("Unknown tcode %d\n", fp0->mode.common.tcode);
 2693                 return (0);
 2694         }
 2695         hlen = tinfo[fp0->mode.common.tcode].hdr_len;
 2696         if (hlen > len) {
 2697                 if (firewire_debug)
 2698                         printf("splitted header\n");
 2699                 return (-hlen);
 2700         }
 2701 #if BYTE_ORDER == BIG_ENDIAN
 2702         for (i = 0; i < slen/4; i++)
 2703                 fp->mode.ld[i] = FWOHCI_DMA_READ(fp->mode.ld[i]);
 2704 #endif
 2705         return (hlen);
 2706 }
 2707 
 2708 static int
 2709 fwohci_get_plen(struct fwohci_softc *sc, struct fwohci_dbch *dbch, struct fw_pkt *fp)
 2710 {
 2711         struct tcode_info *info;
 2712         int r;
 2713 
 2714         info = &tinfo[fp->mode.common.tcode];
 2715         r = info->hdr_len + sizeof(uint32_t);
 2716         if ((info->flag & FWTI_BLOCK_ASY) != 0)
 2717                 r += roundup2((uint32_t)fp->mode.wreqb.len, sizeof(uint32_t));
 2718 
 2719         if (r == sizeof(uint32_t)) {
 2720                 /* XXX */
 2721                 device_printf(sc->fc.dev, "Unknown tcode %d\n",
 2722                                                 fp->mode.common.tcode);
 2723                 return (-1);
 2724         }
 2725 
 2726         if (r > dbch->xferq.psize) {
 2727                 device_printf(sc->fc.dev, "Invalid packet length %d\n", r);
 2728                 return (-1);
 2729                 /* panic ? */
 2730         }
 2731 
 2732         return r;
 2733 }
 2734 
 2735 static void
 2736 fwohci_arcv_free_buf(struct fwohci_softc *sc, struct fwohci_dbch *dbch,
 2737     struct fwohcidb_tr *db_tr, uint32_t off, int wake)
 2738 {
 2739         struct fwohcidb *db = &db_tr->db[0];
 2740 
 2741         FWOHCI_DMA_CLEAR(db->db.desc.depend, 0xf);
 2742         FWOHCI_DMA_WRITE(db->db.desc.res, dbch->xferq.psize);
 2743         FWOHCI_DMA_SET(dbch->bottom->db[0].db.desc.depend, 1);
 2744         fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE);
 2745         dbch->bottom = db_tr;
 2746 
 2747         if (wake)
 2748                 OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_WAKE);
 2749 }
 2750 
 2751 static void
 2752 fwohci_arcv(struct fwohci_softc *sc, struct fwohci_dbch *dbch, int count)
 2753 {
 2754         struct fwohcidb_tr *db_tr;
 2755         struct iovec vec[2];
 2756         struct fw_pkt pktbuf;
 2757         int nvec;
 2758         struct fw_pkt *fp;
 2759         uint8_t *ld;
 2760         uint32_t stat, off, status, event;
 2761         u_int spd;
 2762 #ifdef COUNT_PACKETS
 2763         int pcnt;
 2764 #endif
 2765         int len, plen, hlen, offset;
 2766         int s;
 2767         caddr_t buf;
 2768         int resCount;
 2769 
 2770         if (&sc->arrq == dbch) {
 2771                 off = OHCI_ARQOFF;
 2772         } else if (&sc->arrs == dbch) {
 2773                 off = OHCI_ARSOFF;
 2774         } else {
 2775                 return;
 2776         }
 2777 
 2778         s = splfw();
 2779         db_tr = dbch->top;
 2780 #ifdef COUNT_PACKETS
 2781         pcnt = 0;
 2782 #endif
 2783         /* XXX we cannot handle a packet which lies in more than two buf */
 2784         fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_POSTREAD);
 2785         fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_POSTWRITE);
 2786         status = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res) >> OHCI_STATUS_SHIFT;
 2787         resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res) & OHCI_COUNT_MASK;
 2788         while (status & OHCI_CNTL_DMA_ACTIVE) {
 2789 #if 0
 2790 
 2791                 if (off == OHCI_ARQOFF)
 2792                         printf("buf 0x%08x, status 0x%04x, resCount 0x%04x\n",
 2793                             db_tr->bus_addr, status, resCount);
 2794 #endif
 2795                 len = dbch->xferq.psize - resCount;
 2796                 ld = (uint8_t *)db_tr->buf;
 2797                 if (dbch->pdb_tr == NULL) {
 2798                         len -= dbch->buf_offset;
 2799                         ld += dbch->buf_offset;
 2800                 }
 2801                 if (len > 0)
 2802                         bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
 2803                                         BUS_DMASYNC_POSTREAD);
 2804                 while (len > 0) {
 2805                         if (count >= 0 && count-- == 0)
 2806                                 goto out;
 2807                         if (dbch->pdb_tr != NULL) {
 2808                                 /* we have a fragment in previous buffer */
 2809                                 int rlen;
 2810 
 2811                                 offset = dbch->buf_offset;
 2812                                 if (offset < 0)
 2813                                         offset = - offset;
 2814                                 buf = dbch->pdb_tr->buf + offset;
 2815                                 rlen = dbch->xferq.psize - offset;
 2816                                 if (firewire_debug)
 2817                                         printf("rlen=%d, offset=%d\n",
 2818                                                 rlen, dbch->buf_offset);
 2819                                 if (dbch->buf_offset < 0) {
 2820                                         /* splitted in header, pull up */
 2821                                         char *p;
 2822 
 2823                                         p = (char *)&pktbuf;
 2824                                         bcopy(buf, p, rlen);
 2825                                         p += rlen;
 2826                                         /* this must be too long but harmless */
 2827                                         rlen = sizeof(pktbuf) - rlen;
 2828                                         if (rlen < 0)
 2829                                                 printf("why rlen < 0\n");
 2830                                         bcopy(db_tr->buf, p, rlen);
 2831                                         ld += rlen;
 2832                                         len -= rlen;
 2833                                         hlen = fwohci_arcv_swap(&pktbuf, sizeof(pktbuf));
 2834                                         if (hlen <= 0) {
 2835                                                 printf("hlen should be positive.");
 2836                                                 goto err;
 2837                                         }
 2838                                         offset = sizeof(pktbuf);
 2839                                         vec[0].iov_base = (char *)&pktbuf;
 2840                                         vec[0].iov_len = offset;
 2841                                 } else {
 2842                                         /* splitted in payload */
 2843                                         offset = rlen;
 2844                                         vec[0].iov_base = buf;
 2845                                         vec[0].iov_len = rlen;
 2846                                 }
 2847                                 fp=(struct fw_pkt *)vec[0].iov_base;
 2848                                 nvec = 1;
 2849                         } else {
 2850                                 /* no fragment in previous buffer */
 2851                                 fp=(struct fw_pkt *)ld;
 2852                                 hlen = fwohci_arcv_swap(fp, len);
 2853                                 if (hlen == 0)
 2854                                         goto err;
 2855                                 if (hlen < 0) {
 2856                                         dbch->pdb_tr = db_tr;
 2857                                         dbch->buf_offset = - dbch->buf_offset;
 2858                                         /* sanity check */
 2859                                         if (resCount != 0) {
 2860                                                 printf("resCount=%d hlen=%d\n",
 2861                                                     resCount, hlen);
 2862                                                     goto err;
 2863                                         }
 2864                                         goto out;
 2865                                 }
 2866                                 offset = 0;
 2867                                 nvec = 0;
 2868                         }
 2869                         plen = fwohci_get_plen(sc, dbch, fp) - offset;
 2870                         if (plen < 0) {
 2871                                 /* minimum header size + trailer
 2872                                 = sizeof(fw_pkt) so this shouldn't happens */
 2873                                 printf("plen(%d) is negative! offset=%d\n",
 2874                                     plen, offset);
 2875                                 goto err;
 2876                         }
 2877                         if (plen > 0) {
 2878                                 len -= plen;
 2879                                 if (len < 0) {
 2880                                         dbch->pdb_tr = db_tr;
 2881                                         if (firewire_debug)
 2882                                                 printf("splitted payload\n");
 2883                                         /* sanity check */
 2884                                         if (resCount != 0) {
 2885                                                 printf("resCount=%d plen=%d"
 2886                                                     " len=%d\n",
 2887                                                     resCount, plen, len);
 2888                                                 goto err;
 2889                                         }
 2890                                         goto out;
 2891                                 }
 2892                                 vec[nvec].iov_base = ld;
 2893                                 vec[nvec].iov_len = plen;
 2894                                 nvec++;
 2895                                 ld += plen;
 2896                         }
 2897                         dbch->buf_offset = ld - (uint8_t *)db_tr->buf;
 2898                         if (nvec == 0)
 2899                                 printf("nvec == 0\n");
 2900 
 2901 /* DMA result-code will be written at the tail of packet */
 2902                         stat = FWOHCI_DMA_READ(*(uint32_t *)(ld - sizeof(struct fwohci_trailer)));
 2903 #if 0
 2904                         printf("plen: %d, stat %x\n",
 2905                             plen ,stat);
 2906 #endif
 2907                         spd = (stat >> 21) & 0x3;
 2908                         event = (stat >> 16) & 0x1f;
 2909                         switch (event) {
 2910                         case FWOHCIEV_ACKPEND:
 2911 #if 0
 2912                                 printf("fwohci_arcv: ack pending tcode=0x%x..\n", fp->mode.common.tcode);
 2913 #endif
 2914                                 /* fall through */
 2915                         case FWOHCIEV_ACKCOMPL:
 2916                         {
 2917                                 struct fw_rcv_buf rb;
 2918 
 2919                                 if ((vec[nvec-1].iov_len -=
 2920                                         sizeof(struct fwohci_trailer)) == 0)
 2921                                         nvec--;
 2922                                 rb.fc = &sc->fc;
 2923                                 rb.vec = vec;
 2924                                 rb.nvec = nvec;
 2925                                 rb.spd = spd;
 2926                                 fw_rcv(&rb);
 2927                                 break;
 2928                         }
 2929                         case FWOHCIEV_BUSRST:
 2930                                 if ((sc->fc.status != FWBUSRESET) &&
 2931                                     (sc->fc.status != FWBUSINIT))
 2932                                         printf("got BUSRST packet!?\n");
 2933                                 break;
 2934                         default:
 2935                                 device_printf(sc->fc.dev,
 2936                                     "Async DMA Receive error err=%02x %s"
 2937                                     " plen=%d offset=%d len=%d status=0x%08x"
 2938                                     " tcode=0x%x, stat=0x%08x\n",
 2939                                     event, fwohcicode[event], plen,
 2940                                     dbch->buf_offset, len,
 2941                                     OREAD(sc, OHCI_DMACTL(off)),
 2942                                     fp->mode.common.tcode, stat);
 2943 #if 1 /* XXX */
 2944                                 goto err;
 2945 #endif
 2946                                 break;
 2947                         }
 2948 #ifdef COUNT_PACKETS
 2949                         pcnt++;
 2950 #endif
 2951                         if (dbch->pdb_tr != NULL) {
 2952                                 fwohci_arcv_free_buf(sc, dbch, dbch->pdb_tr,
 2953                                     off, 1);
 2954                                 dbch->pdb_tr = NULL;
 2955                         }
 2956 
 2957                 }
 2958 out:
 2959                 if (resCount == 0) {
 2960                         /* done on this buffer */
 2961                         if (dbch->pdb_tr == NULL) {
 2962                                 fwohci_arcv_free_buf(sc, dbch, db_tr, off, 1);
 2963                                 dbch->buf_offset = 0;
 2964                         } else
 2965                                 if (dbch->pdb_tr != db_tr)
 2966                                         printf("pdb_tr != db_tr\n");
 2967                         db_tr = STAILQ_NEXT(db_tr, link);
 2968                         status = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
 2969                                                 >> OHCI_STATUS_SHIFT;
 2970                         resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
 2971                                                 & OHCI_COUNT_MASK;
 2972                         /* XXX check buffer overrun */
 2973                         dbch->top = db_tr;
 2974                 } else {
 2975                         dbch->buf_offset = dbch->xferq.psize - resCount;
 2976                         break;
 2977                 }
 2978                 /* XXX make sure DMA is not dead */
 2979         }
 2980 #ifdef COUNT_PACKETS
 2981         if (pcnt < 1)
 2982                 printf("fwohci_arcv: no packets\n");
 2983 #endif
 2984         splx(s);
 2985         return;
 2986 
 2987 err:
 2988         device_printf(sc->fc.dev, "AR DMA status=%x, ",
 2989                                         OREAD(sc, OHCI_DMACTL(off)));
 2990         dbch->pdb_tr = NULL;
 2991         /* skip until resCount != 0 */
 2992         printf(" skip buffer");
 2993         while (resCount == 0) {
 2994                 printf(" #");
 2995                 fwohci_arcv_free_buf(sc, dbch, db_tr, off, 0);
 2996                 db_tr = STAILQ_NEXT(db_tr, link);
 2997                 resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
 2998                                                 & OHCI_COUNT_MASK;
 2999         }
 3000         printf(" done\n");
 3001         dbch->top = db_tr;
 3002         dbch->buf_offset = dbch->xferq.psize - resCount;
 3003         OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_WAKE);
 3004         splx(s);
 3005 }

Cache object: 9b6d1cb6e503ed5e144d5c416e26a92a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.