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