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