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