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