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