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