xref: /netbsd-src/sys/dev/ieee1394/fwohci.c (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 /*	$NetBSD: fwohci.c,v 1.145 2021/04/24 23:36:55 thorpej 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.145 2021/04/24 23:36:55 thorpej 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
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
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 	    CFARG_EOL);
508 
509 	return 0;
510 }
511 
512 int
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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. responce */
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 			 * transcation 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 bounary. */
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 happend\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 	uint32_t ld0;
2647 	int hlen;
2648 #if BYTE_ORDER == BIG_ENDIAN
2649 	int slen, i;
2650 #endif
2651 
2652 	ld0 = FWOHCI_DMA_READ(fp->mode.ld[0]);
2653 #if 0
2654 	printf("ld0: x%08x\n", ld0);
2655 #endif
2656 	fp0 = (struct fw_pkt *)&ld0;
2657 	/* determine length to swap */
2658 	switch (fp0->mode.common.tcode) {
2659 	case FWTCODE_WRES:
2660 	case FWTCODE_RREQQ:
2661 	case FWTCODE_WREQQ:
2662 	case FWTCODE_RRESQ:
2663 	case FWOHCITCODE_PHY:
2664 #if BYTE_ORDER == BIG_ENDIAN
2665 		slen = 12;
2666 #endif
2667 		break;
2668 
2669 	case FWTCODE_RREQB:
2670 	case FWTCODE_WREQB:
2671 	case FWTCODE_LREQ:
2672 	case FWTCODE_RRESB:
2673 	case FWTCODE_LRES:
2674 #if BYTE_ORDER == BIG_ENDIAN
2675 		slen = 16;
2676 #endif
2677 		break;
2678 
2679 	default:
2680 		aprint_error("Unknown tcode %d\n", fp0->mode.common.tcode);
2681 		return 0;
2682 	}
2683 	hlen = tinfo[fp0->mode.common.tcode].hdr_len;
2684 	if (hlen > len) {
2685 		if (firewire_debug)
2686 			printf("splitted header\n");
2687 		return len - hlen;
2688 	}
2689 #if BYTE_ORDER == BIG_ENDIAN
2690 	for (i = 0; i < slen / 4; i++)
2691 		fp->mode.ld[i] = FWOHCI_DMA_READ(fp->mode.ld[i]);
2692 #endif
2693 	return hlen;
2694 }
2695 
2696 static int
2697 fwohci_get_plen(struct fwohci_softc *sc, struct fwohci_dbch *dbch,
2698 		struct fw_pkt *fp)
2699 {
2700 	const struct tcode_info *info;
2701 	int r;
2702 
2703 	info = &tinfo[fp->mode.common.tcode];
2704 	r = info->hdr_len + sizeof(uint32_t);
2705 	if (info->flag & FWTI_BLOCK_ASY)
2706 		r += roundup2(fp->mode.wreqb.len, sizeof(uint32_t));
2707 
2708 	if (r == sizeof(uint32_t)) {
2709 		/* XXX */
2710 		aprint_error_dev(sc->fc.dev, "Unknown tcode %d\n",
2711 		    fp->mode.common.tcode);
2712 		return -1;
2713 	}
2714 
2715 	if (r > dbch->xferq.psize) {
2716 		aprint_error_dev(sc->fc.dev, "Invalid packet length %d\n", r);
2717 		return -1;
2718 		/* panic ? */
2719 	}
2720 
2721 	return r;
2722 }
2723 
2724 static void
2725 fwohci_arcv_free_buf(struct fwohci_softc *sc, struct fwohci_dbch *dbch,
2726 		     struct fwohcidb_tr *db_tr, int wake)
2727 {
2728 	struct fwohcidb *db = db_tr->db;
2729 	struct fwohcidb_tr *bdb_tr = dbch->bottom;
2730 
2731 	FWOHCI_DMA_CLEAR(db->db.desc.depend, 0xf);
2732 	FWOHCI_DMA_WRITE(db->db.desc.res, dbch->xferq.psize);
2733 
2734 	fwdma_sync_multiseg(dbch->am, bdb_tr->idx, bdb_tr->idx,
2735 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
2736 	FWOHCI_DMA_SET(bdb_tr->db[0].db.desc.depend, dbch->ndesc);
2737 
2738 	fwdma_sync_multiseg(dbch->am, bdb_tr->idx, db_tr->idx,
2739 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2740 	dbch->bottom = db_tr;
2741 
2742 	if (wake)
2743 		OWRITE(sc, OHCI_DMACTL(dbch->off), OHCI_CNTL_DMA_WAKE);
2744 }
2745 
2746 static void
2747 fwohci_arcv(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
2748 {
2749 	struct fwohcidb_tr *db_tr;
2750 	struct fw_pkt pktbuf, *fp;
2751 	struct iovec vec[2];
2752 	bus_addr_t m;
2753 	bus_size_t n;
2754 	u_int spd;
2755 	uint32_t stat, status, event;
2756 	uint8_t *ld;
2757 	int nvec, resCount, len, plen, hlen, offset;
2758 	const int psize = dbch->xferq.psize;
2759 
2760 #if DIAGNOSTIC
2761 	if (dbch->off != OHCI_ARQOFF &&
2762 	    dbch->off != OHCI_ARSOFF)
2763 		panic("not async rx");
2764 #endif
2765 
2766 	mutex_enter(&dbch->xferq.q_mtx);
2767 	db_tr = dbch->top;
2768 	/* XXX we cannot handle a packet which lies in more than two buf */
2769 	fwdma_sync_multiseg(dbch->am, db_tr->idx, db_tr->idx,
2770 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
2771 	status = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res) >> OHCI_STATUS_SHIFT;
2772 	resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res) & OHCI_COUNT_MASK;
2773 	while (status & OHCI_CNTL_DMA_ACTIVE) {
2774 #if 0
2775 		if (dbch->off == OHCI_ARQOFF)
2776 			aprint_normal_dev(sc->fc.dev,
2777 			    "buf 0x%08x, status 0x%04x, resCount 0x%04x\n",
2778 			    db_tr->bus_addr, status, resCount);
2779 #endif
2780 		n = 0;
2781 		len = psize - resCount;
2782 		ld = (uint8_t *)db_tr->buf;
2783 		if (dbch->pdb_tr == NULL) {
2784 			len -= dbch->buf_offset;
2785 			ld += dbch->buf_offset;
2786 			m = dbch->buf_offset;
2787 		} else
2788 			m = 0;
2789 		if (len > 0)
2790 			bus_dmamap_sync(sc->fc.dmat, db_tr->dma_map,
2791 			    m, len, BUS_DMASYNC_POSTREAD);
2792 		while (len > 0) {
2793 			if (dbch->pdb_tr != NULL) {
2794 				/* we have a fragment in previous buffer */
2795 				int rlen = 0;
2796 				void *buf;
2797 
2798 				if (dbch->buf_offset < 0) {
2799 					/* splitted in header, pull up */
2800 					char *p;
2801 
2802 					rlen -= dbch->buf_offset;
2803 					buf = (char *)dbch->pdb_tr->buf +
2804 					    psize - rlen;
2805 
2806 					KASSERT(rlen <= sizeof(pktbuf));
2807 
2808 					p = (char *)&pktbuf;
2809 					memcpy(p, buf, rlen);
2810 					p += rlen;
2811 					/* this must be too long but harmless */
2812 					rlen = sizeof(pktbuf) - rlen;
2813 					memcpy(p, db_tr->buf, rlen);
2814 					ld += rlen;
2815 					len -= rlen;
2816 					hlen = fwohci_arcv_swap(&pktbuf,
2817 					    sizeof(pktbuf));
2818 					if (hlen <= 0) {
2819 						aprint_error_dev(sc->fc.dev,
2820 						    "hlen should be positive.");
2821 						goto err;
2822 					}
2823 					offset = sizeof(pktbuf);
2824 					vec[0].iov_base = (char *)&pktbuf;
2825 					vec[0].iov_len = offset;
2826 				} else {
2827 					/* splitted in payload */
2828 					buf = (char *)dbch->pdb_tr->buf +
2829 					    dbch->buf_offset;
2830 					rlen = psize - dbch->buf_offset;
2831 					if (firewire_debug)
2832 						printf("rlen=%d, offset=%d\n",
2833 						    rlen, dbch->buf_offset);
2834 					offset = rlen;
2835 					vec[0].iov_base = buf;
2836 					vec[0].iov_len = rlen;
2837 				}
2838 				fp = (struct fw_pkt *)vec[0].iov_base;
2839 				nvec = 1;
2840 			} else {
2841 				/* no fragment in previous buffer */
2842 				fp = (struct fw_pkt *)ld;
2843 				hlen = fwohci_arcv_swap(fp, len);
2844 				if (hlen == 0)
2845 					goto err;
2846 				if (hlen < 0) {
2847 					dbch->pdb_tr = db_tr;
2848 					dbch->buf_offset -= psize;
2849 					/* sanity check */
2850 					if (resCount != 0)  {
2851 						aprint_error_dev(sc->fc.dev,
2852 						    "resCount=%d hlen=%d\n",
2853 						    resCount, hlen);
2854 						goto err;
2855 					}
2856 					goto out;
2857 				}
2858 				offset = 0;
2859 				nvec = 0;
2860 			}
2861 			plen = fwohci_get_plen(sc, dbch, fp) - offset;
2862 			if (plen < 0) {
2863 				/*
2864 				 * minimum header size + trailer =
2865 				 *     sizeof(fw_pkt) so this shouldn't happens
2866 				 */
2867 				aprint_error_dev(sc->fc.dev,
2868 				    "plen(%d) is negative! offset=%d\n",
2869 				    plen, offset);
2870 				goto err;
2871 			}
2872 			if (plen > 0) {
2873 				len -= plen;
2874 				if (len < 0) {
2875 					dbch->pdb_tr = db_tr;
2876 					if (firewire_debug)
2877 						printf("splitted payload\n");
2878 					/* sanity check */
2879 					if (resCount != 0) {
2880 						aprint_error_dev(sc->fc.dev,
2881 						    "resCount=%d plen=%d"
2882 						    " len=%d\n",
2883 						    resCount, plen, len);
2884 						goto err;
2885 					}
2886 					goto out;
2887 				}
2888 				vec[nvec].iov_base = ld;
2889 				vec[nvec].iov_len = plen;
2890 				nvec++;
2891 				ld += plen;
2892 			}
2893 			if (nvec == 0)
2894 				aprint_error_dev(sc->fc.dev, "nvec == 0\n");
2895 
2896 /* DMA result-code will be written at the tail of packet */
2897 			stat = FWOHCI_DMA_READ(*(uint32_t *)(ld -
2898 						sizeof(struct fwohci_trailer)));
2899 #if 0
2900 			aprint_normal("plen: %d, stat %x\n", plen, stat);
2901 #endif
2902 			spd = (stat >> 21) & 0x3;
2903 			event = (stat >> 16) & 0x1f;
2904 			switch (event) {
2905 			case FWOHCIEV_ACKPEND:
2906 #if 0
2907 				aprint_normal(sc->fc.dev,
2908 				    "ack pending tcode=0x%x..\n",
2909 				    fp->mode.common.tcode);
2910 #endif
2911 				/* fall through */
2912 			case FWOHCIEV_ACKCOMPL:
2913 			{
2914 				struct fw_rcv_buf rb;
2915 
2916 				vec[nvec - 1].iov_len -=
2917 				    sizeof(struct fwohci_trailer);
2918 				if (vec[nvec - 1].iov_len == 0)
2919 					nvec--;
2920 				rb.fc = &sc->fc;
2921 				rb.vec = vec;
2922 				rb.nvec = nvec;
2923 				rb.spd = spd;
2924 				fw_rcv(&rb);
2925 				break;
2926 			}
2927 			case FWOHCIEV_BUSRST:
2928 				if ((sc->fc.status != FWBUSRESET) &&
2929 				    (sc->fc.status != FWBUSINIT))
2930 					aprint_error_dev(sc->fc.dev,
2931 					    "got BUSRST packet!?\n");
2932 				break;
2933 			default:
2934 				aprint_error_dev(sc->fc.dev,
2935 				    "Async DMA Receive error err=%02x %s"
2936 				    " plen=%d offset=%d len=%d status=0x%08x"
2937 				    " tcode=0x%x, stat=0x%08x\n",
2938 				    event, fwohcicode[event], plen,
2939 				    (int)(ld - (uint8_t *)db_tr->buf - plen),
2940 				    len, OREAD(sc, OHCI_DMACTL(dbch->off)),
2941 				    fp->mode.common.tcode, stat);
2942 #if 1 /* XXX */
2943 				goto err;
2944 #endif
2945 				break;
2946 			}
2947 			if (dbch->pdb_tr != NULL) {
2948 				if (dbch->buf_offset < 0)
2949 					bus_dmamap_sync(sc->fc.dmat,
2950 					    dbch->pdb_tr->dma_map,
2951 					    psize + dbch->buf_offset,
2952 					    0 - dbch->buf_offset,
2953 					    BUS_DMASYNC_PREREAD);
2954 				else
2955 					bus_dmamap_sync(sc->fc.dmat,
2956 					    dbch->pdb_tr->dma_map,
2957 					    dbch->buf_offset,
2958 					    psize - dbch->buf_offset,
2959 					    BUS_DMASYNC_PREREAD);
2960 				fwohci_arcv_free_buf(sc, dbch, dbch->pdb_tr, 1);
2961 				dbch->pdb_tr = NULL;
2962 			}
2963 			dbch->buf_offset = ld - (uint8_t *)db_tr->buf;
2964 			n += (plen + offset);
2965 		}
2966 out:
2967 		if (n > 0)
2968 			bus_dmamap_sync(sc->fc.dmat, db_tr->dma_map, m, n,
2969 			    BUS_DMASYNC_PREREAD);
2970 
2971 		if (resCount != 0) {
2972 			dbch->buf_offset = psize - resCount;
2973 			break;
2974 		}
2975 
2976 		/* done on this buffer */
2977 
2978 		if (dbch->pdb_tr == NULL) {
2979 			fwohci_arcv_free_buf(sc, dbch, db_tr, 1);
2980 			dbch->buf_offset = 0;
2981 		} else
2982 			if (dbch->pdb_tr != db_tr)
2983 				aprint_error_dev(sc->fc.dev,
2984 				    "pdb_tr != db_tr\n");
2985 		dbch->top = STAILQ_NEXT(db_tr, link);
2986 
2987 		db_tr = dbch->top;
2988 		fwdma_sync_multiseg(dbch->am, db_tr->idx, db_tr->idx,
2989 		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
2990 		status = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res) >>
2991 		    OHCI_STATUS_SHIFT;
2992 		resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
2993 		    & OHCI_COUNT_MASK;
2994 
2995 		/* XXX check buffer overrun */
2996 
2997 		/* XXX make sure DMA is not dead */
2998 	}
2999 	fwdma_sync_multiseg(dbch->am, db_tr->idx, db_tr->idx,
3000 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3001 	mutex_exit(&dbch->xferq.q_mtx);
3002 	return;
3003 
3004 err:
3005 	aprint_error_dev(sc->fc.dev, "AR DMA status=%x, ",
3006 	    OREAD(sc, OHCI_DMACTL(dbch->off)));
3007 	if (dbch->pdb_tr != NULL) {
3008 		if (dbch->buf_offset < 0)
3009 			bus_dmamap_sync(sc->fc.dmat, dbch->pdb_tr->dma_map,
3010 			    psize + dbch->buf_offset, 0 - dbch->buf_offset,
3011 			    BUS_DMASYNC_PREREAD);
3012 		else
3013 			bus_dmamap_sync(sc->fc.dmat, dbch->pdb_tr->dma_map,
3014 			    dbch->buf_offset, psize - dbch->buf_offset,
3015 			    BUS_DMASYNC_PREREAD);
3016 		fwohci_arcv_free_buf(sc, dbch, dbch->pdb_tr, 1);
3017 		dbch->pdb_tr = NULL;
3018 	}
3019 	/* skip until resCount != 0 */
3020 	aprint_error(" skip buffer");
3021 	while (resCount == 0) {
3022 		aprint_error(" #");
3023 		fwohci_arcv_free_buf(sc, dbch, db_tr, 0);
3024 		db_tr = STAILQ_NEXT(db_tr, link);
3025 		resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
3026 		    & OHCI_COUNT_MASK;
3027 	}
3028 	aprint_error(" done\n");
3029 	dbch->top = db_tr;
3030 	dbch->buf_offset = psize - resCount;
3031 	OWRITE(sc, OHCI_DMACTL(dbch->off), OHCI_CNTL_DMA_WAKE);
3032 	fwdma_sync_multiseg(dbch->am, db_tr->idx, db_tr->idx,
3033 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3034 	bus_dmamap_sync(sc->fc.dmat, db_tr->dma_map,
3035 	    0, db_tr->dma_map->dm_mapsize, BUS_DMASYNC_PREREAD);
3036 	mutex_exit(&dbch->xferq.q_mtx);
3037 }
3038