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