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