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