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