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