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

Cache object: 5e49ee6072a83c0191e6bc6e595e7143


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