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