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