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