firewire.c revision 109890
1/*
2 * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the acknowledgement as bellow:
15 *
16 *    This product includes software developed by K. Kobayashi and H. Shimokawa
17 *
18 * 4. The name of the author may not be used to endorse or promote products
19 *    derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 * $FreeBSD: head/sys/dev/firewire/firewire.c 109890 2003-01-26 15:39:04Z simokawa $
34 *
35 */
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/types.h>
40#include <sys/mbuf.h>
41#include <sys/socket.h>
42#include <sys/socketvar.h>
43
44#include <sys/kernel.h>
45#include <sys/malloc.h>
46#include <sys/conf.h>
47#include <sys/uio.h>
48#include <sys/sysctl.h>
49
50#include <machine/cpufunc.h>    /* for rdtsc proto for clock.h below */
51#include <machine/clock.h>
52
53#include <sys/bus.h>		/* used by smbus and newbus */
54
55#include <dev/firewire/firewire.h>
56#include <dev/firewire/firewirereg.h>
57#include <dev/firewire/iec13213.h>
58#include <dev/firewire/iec68113.h>
59
60int firewire_debug=0, try_bmr=1;
61SYSCTL_INT(_debug, OID_AUTO, firewire_debug, CTLFLAG_RW, &firewire_debug, 0,
62	"FireWire driver debug flag");
63SYSCTL_NODE(_hw, OID_AUTO, firewire, CTLFLAG_RD, 0, "FireWire Subsystem");
64SYSCTL_INT(_hw_firewire, OID_AUTO, try_bmr, CTLFLAG_RW, &try_bmr, 0,
65	"Try to be a bus manager");
66
67#define FW_MAXASYRTY 4
68#define FW_MAXDEVRCNT 4
69
70#define XFER_TIMEOUT 0
71
72devclass_t firewire_devclass;
73
74static int firewire_match      __P((device_t));
75static int firewire_attach      __P((device_t));
76static int firewire_detach      __P((device_t));
77#if 0
78static int firewire_shutdown    __P((device_t));
79#endif
80static device_t firewire_add_child   __P((device_t, int, const char *, int));
81static void fw_try_bmr __P((void *));
82static void fw_try_bmr_callback __P((struct fw_xfer *));
83static void fw_asystart __P((struct fw_xfer *));
84static int fw_get_tlabel __P((struct firewire_comm *, struct fw_xfer *));
85static void fw_bus_probe __P((struct firewire_comm *));
86static void fw_bus_explore __P((struct firewire_comm *));
87static void fw_bus_explore_callback __P((struct fw_xfer *));
88static void fw_attach_dev __P((struct firewire_comm *));
89#ifdef FW_VMACCESS
90static void fw_vmaccess __P((struct fw_xfer *));
91#endif
92struct fw_xfer *asyreqq __P((struct firewire_comm *, u_int8_t, u_int8_t, u_int8_t,
93	u_int32_t, u_int32_t, void (*)__P((struct fw_xfer *))));
94
95static device_method_t firewire_methods[] = {
96	/* Device interface */
97	DEVMETHOD(device_probe,		firewire_match),
98	DEVMETHOD(device_attach,	firewire_attach),
99	DEVMETHOD(device_detach,	firewire_detach),
100	DEVMETHOD(device_suspend,	bus_generic_suspend),
101	DEVMETHOD(device_resume,	bus_generic_resume),
102	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
103
104	/* Bus interface */
105	DEVMETHOD(bus_add_child,	firewire_add_child),
106	DEVMETHOD(bus_print_child,	bus_generic_print_child),
107
108	{ 0, 0 }
109};
110char linkspeed[7][0x10]={"S100","S200","S400","S800","S1600","S3200","Unknown"};
111
112#define MAX_GAPHOP  16
113u_int gap_cnt[] = {1, 1, 4, 6, 9, 12, 14, 17,
114			20, 23, 25, 28, 31, 33, 36, 39, 42};
115
116extern struct cdevsw firewire_cdevsw;
117
118static driver_t firewire_driver = {
119	"firewire",
120	firewire_methods,
121	sizeof(struct firewire_softc),
122};
123
124/*
125 * To lookup node id. from EUI64.
126 */
127struct fw_device *
128fw_noderesolve(struct firewire_comm *fc, struct fw_eui64 eui)
129{
130	struct fw_device *fwdev;
131	for(fwdev = TAILQ_FIRST(&fc->devices); fwdev != NULL;
132		fwdev = TAILQ_NEXT(fwdev, link)){
133		if(fwdev->eui.hi == eui.hi && fwdev->eui.lo == eui.lo){
134			break;
135		}
136	}
137	if(fwdev == NULL) return NULL;
138	if(fwdev->status == FWDEVINVAL) return NULL;
139	return fwdev;
140}
141
142/*
143 * Async. request procedure for userland application.
144 */
145int
146fw_asyreq(struct firewire_comm *fc, int sub, struct fw_xfer *xfer)
147{
148	int err = 0;
149	struct fw_xferq *xferq;
150	int tl = 0, len;
151	struct fw_pkt *fp;
152	int tcode;
153	struct tcode_info *info;
154
155	if(xfer == NULL) return EINVAL;
156	if(xfer->send.len > MAXREC(fc->maxrec)){
157		printf("send.len > maxrec\n");
158		return EINVAL;
159	}
160	if(xfer->act.hand == NULL){
161		printf("act.hand == NULL\n");
162		return EINVAL;
163	}
164	fp = (struct fw_pkt *)xfer->send.buf;
165
166	tcode = fp->mode.common.tcode & 0xf;
167	info = &fc->tcode[tcode];
168	if (info->flag == 0) {
169		printf("invalid tcode=%d\n", tcode);
170		return EINVAL;
171	}
172	if (info->flag & FWTI_REQ)
173		xferq = fc->atq;
174	else
175		xferq = fc->ats;
176	len = info->hdr_len;
177	if (info->flag & FWTI_BLOCK_STR)
178		len += ntohs(fp->mode.stream.len);
179	else if (info->flag & FWTI_BLOCK_ASY)
180		len += ntohs(fp->mode.rresb.len);
181	if( len >  xfer->send.len ){
182		printf("len(%d) > send.len(%d) (tcode=%d)\n",
183				len, xfer->send.len, tcode);
184		return EINVAL;
185	}
186	xfer->send.len = len;
187
188	if(xferq->start == NULL){
189		printf("xferq->start == NULL\n");
190		return EINVAL;
191	}
192	if(!(xferq->queued < xferq->maxq)){
193		device_printf(fc->bdev, "Discard a packet (queued=%d)\n",
194			xferq->queued);
195		return EINVAL;
196	}
197
198
199	if (info->flag & FWTI_TLABEL) {
200		if((tl = fw_get_tlabel(fc, xfer)) == -1 )
201			return EIO;
202		fp->mode.hdr.tlrt = tl << 2;
203	}
204
205	xfer->tl = tl;
206	xfer->tcode = tcode;
207	xfer->resp = 0;
208	xfer->fc = fc;
209	xfer->q = xferq;
210	xfer->act_type = FWACT_XFER;
211	xfer->retry_req = fw_asybusy;
212
213	fw_asystart(xfer);
214	return err;
215}
216/*
217 * Wakeup blocked process.
218 */
219void
220fw_asy_callback(struct fw_xfer *xfer){
221	wakeup(xfer);
222	return;
223}
224/*
225 * Postpone to later retry.
226 */
227void fw_asybusy(struct fw_xfer *xfer){
228#if 1
229	printf("fw_asybusy\n");
230#endif
231#if XFER_TIMEOUT
232	untimeout(fw_xfer_timeout, (void *)xfer, xfer->ch);
233#endif
234/*
235	xfer->ch =  timeout((timeout_t *)fw_asystart, (void *)xfer, 20000);
236*/
237	DELAY(20000);
238	fw_asystart(xfer);
239	return;
240}
241#if XFER_TIMEOUT
242/*
243 * Post timeout for async. request.
244 */
245void
246fw_xfer_timeout(void *arg)
247{
248	int s;
249	struct fw_xfer *xfer;
250
251	xfer = (struct fw_xfer *)arg;
252	printf("fw_xfer_timeout status=%d resp=%d\n", xfer->state, xfer->resp);
253	/* XXX set error code */
254	s = splfw();
255	xfer->act.hand(xfer);
256	splx(s);
257}
258#endif
259/*
260 * Async. request with given xfer structure.
261 */
262static void
263fw_asystart(struct fw_xfer *xfer)
264{
265	struct firewire_comm *fc = xfer->fc;
266	int s;
267	if(xfer->retry++ >= fc->max_asyretry){
268		xfer->resp = EBUSY;
269		xfer->state = FWXF_BUSY;
270		xfer->act.hand(xfer);
271		return;
272	}
273#if 0 /* XXX allow bus explore packets only after bus rest */
274	if (fc->status < FWBUSEXPLORE) {
275		xfer->resp = EAGAIN;
276		xfer->state = FWXF_BUSY;
277		if (xfer->act.hand != NULL)
278			xfer->act.hand(xfer);
279		return;
280	}
281#endif
282	s = splfw();
283	xfer->state = FWXF_INQ;
284	STAILQ_INSERT_TAIL(&xfer->q->q, xfer, link);
285	xfer->q->queued ++;
286	splx(s);
287	/* XXX just queue for mbuf */
288	if (xfer->mbuf == NULL)
289		xfer->q->start(fc);
290#if XFER_TIMEOUT
291	if (xfer->act.hand != NULL)
292		xfer->ch = timeout(fw_xfer_timeout, (void *)xfer, hz);
293#endif
294	return;
295}
296
297static int
298firewire_match( device_t dev )
299{
300	device_set_desc(dev, "IEEE1394(FireWire) bus");
301	return -140;
302}
303
304/*
305 * The attach routine.
306 */
307static int
308firewire_attach( device_t dev )
309{
310	int i, unitmask, mn;
311	struct firewire_softc *sc = device_get_softc(dev);
312	device_t pa = device_get_parent(dev);
313	struct firewire_comm *fc;
314	dev_t d;
315
316	fc = (struct firewire_comm *)device_get_softc(pa);
317	sc->fc = fc;
318
319	unitmask = UNIT2MIN(device_get_unit(dev));
320
321	if( fc->nisodma > FWMAXNDMA) fc->nisodma = FWMAXNDMA;
322	for ( i = 0 ; i < fc->nisodma ; i++ ){
323		mn = unitmask | i;
324		/* XXX device name should be improved */
325		d = make_dev(&firewire_cdevsw, unit2minor(mn),
326			UID_ROOT, GID_OPERATOR, 0660,
327			"fw%x", mn);
328#if __FreeBSD_version >= 500000
329		if (i == 0)
330			sc->dev = d;
331		else
332			dev_depends(sc->dev, d);
333#else
334		sc->dev[i] = d;
335#endif
336	}
337	d = make_dev(&firewire_cdevsw, unit2minor(unitmask | FWMEM_FLAG),
338			UID_ROOT, GID_OPERATOR, 0660,
339			"fwmem%d", device_get_unit(dev));
340#if __FreeBSD_version >= 500000
341	dev_depends(sc->dev, d);
342#else
343	sc->dev[i] = d;
344#endif
345	sc->fc->timeouthandle = timeout((timeout_t *)sc->fc->timeout, (void *)sc->fc, hz * 10);
346
347	callout_init(&sc->fc->busprobe_callout
348#if __FreeBSD_version >= 500000
349						, /* mpsafe? */ 0);
350#else
351						);
352#endif
353
354	/* Locate our children */
355	bus_generic_probe(dev);
356
357	/* launch attachement of the added children */
358	bus_generic_attach(dev);
359
360	/* bus_reset */
361	fc->ibr(fc);
362
363	return 0;
364}
365
366/*
367 * Attach it as child.
368 */
369static device_t
370firewire_add_child(device_t dev, int order, const char *name, int unit)
371{
372        device_t child;
373	struct firewire_softc *sc;
374
375	sc = (struct firewire_softc *)device_get_softc(dev);
376	child = device_add_child(dev, name, unit);
377	if (child) {
378		device_set_ivars(child, sc->fc);
379		device_probe_and_attach(child);
380	}
381
382	return child;
383}
384
385/*
386 * Dettach it.
387 */
388static int
389firewire_detach( device_t dev )
390{
391	struct firewire_softc *sc;
392
393	sc = (struct firewire_softc *)device_get_softc(dev);
394
395#if __FreeBSD_version >= 500000
396	destroy_dev(sc->dev);
397#else
398	{
399		int j;
400		for (j = 0 ; j < sc->fc->nisodma + 1; j++)
401			destroy_dev(sc->dev[j]);
402	}
403#endif
404	/* XXX xfree_free and untimeout on all xfers */
405	untimeout((timeout_t *)sc->fc->timeout, sc->fc, sc->fc->timeouthandle);
406	free(sc->fc->topology_map, M_DEVBUF);
407	free(sc->fc->speed_map, M_DEVBUF);
408	bus_generic_detach(dev);
409	return(0);
410}
411#if 0
412static int
413firewire_shutdown( device_t dev )
414{
415	return 0;
416}
417#endif
418
419/*
420 * Called after bus reset.
421 */
422void
423fw_busreset(struct firewire_comm *fc)
424{
425	int i;
426	struct fw_xfer *xfer;
427
428	switch(fc->status){
429	case FWBUSMGRELECT:
430		untimeout((timeout_t *)fw_try_bmr, (void *)fc, fc->bmrhandle);
431		break;
432	default:
433		break;
434	}
435	fc->status = FWBUSRESET;
436/* XXX: discard all queued packet */
437	while((xfer = STAILQ_FIRST(&fc->atq->q)) != NULL){
438		STAILQ_REMOVE_HEAD(&fc->atq->q, link);
439		xfer->resp = EAGAIN;
440		switch(xfer->act_type){
441		case FWACT_XFER:
442			fw_xfer_done(xfer);
443			break;
444		default:
445			break;
446		}
447		fw_xfer_free( xfer);
448	}
449	while((xfer = STAILQ_FIRST(&fc->ats->q)) != NULL){
450		STAILQ_REMOVE_HEAD(&fc->ats->q, link);
451		xfer->resp = EAGAIN;
452		switch(xfer->act_type){
453		case FWACT_XFER:
454			fw_xfer_done(xfer);
455		default:
456			break;
457		}
458		fw_xfer_free( xfer);
459	}
460	for(i = 0; i < fc->nisodma; i++)
461		while((xfer = STAILQ_FIRST(&fc->it[i]->q)) != NULL){
462			STAILQ_REMOVE_HEAD(&fc->it[i]->q, link);
463			xfer->resp = 0;
464			switch(xfer->act_type){
465			case FWACT_XFER:
466				fw_xfer_done(xfer);
467				break;
468			default:
469				break;
470			}
471			fw_xfer_free( xfer);
472		}
473
474	CSRARC(fc, STATE_CLEAR)
475			= 1 << 23 | 0 << 17 | 1 << 16 | 1 << 15 | 1 << 14 ;
476	CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
477	CSRARC(fc, NODE_IDS) = 0x3f;
478
479	CSRARC(fc, TOPO_MAP + 8) = 0;
480	fc->irm = -1;
481
482	fc->max_node = -1;
483
484	for(i = 2; i < 0x100/4 - 2 ; i++){
485		CSRARC(fc, SPED_MAP + i * 4) = 0;
486	}
487	CSRARC(fc, STATE_CLEAR) = 1 << 23 | 0 << 17 | 1 << 16 | 1 << 15 | 1 << 14 ;
488	CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
489	CSRARC(fc, RESET_START) = 0;
490	CSRARC(fc, SPLIT_TIMEOUT_HI) = 0;
491	CSRARC(fc, SPLIT_TIMEOUT_LO) = 800 << 19;
492	CSRARC(fc, CYCLE_TIME) = 0x0;
493	CSRARC(fc, BUS_TIME) = 0x0;
494	CSRARC(fc, BUS_MGR_ID) = 0x3f;
495	CSRARC(fc, BANDWIDTH_AV) = 4915;
496	CSRARC(fc, CHANNELS_AV_HI) = 0xffffffff;
497	CSRARC(fc, CHANNELS_AV_LO) = 0xffffffff;
498	CSRARC(fc, IP_CHANNELS) = (1 << 31);
499
500	CSRARC(fc, CONF_ROM) = 0x04 << 24;
501	CSRARC(fc, CONF_ROM + 4) = 0x31333934; /* means strings 1394 */
502	CSRARC(fc, CONF_ROM + 8) = 1 << 31 | 1 << 30 | 1 << 29 |
503				1 << 28 | 0xff << 16 | 0x09 << 8;
504	CSRARC(fc, CONF_ROM + 0xc) = 0;
505
506/* DV depend CSRs see blue book */
507	CSRARC(fc, oPCR) &= ~DV_BROADCAST_ON;
508	CSRARC(fc, iPCR) &= ~DV_BROADCAST_ON;
509
510	CSRARC(fc, STATE_CLEAR) &= ~(1 << 23 | 1 << 15 | 1 << 14 );
511	CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
512}
513
514/* Call once after reboot */
515void fw_init(struct firewire_comm *fc)
516{
517	int i;
518	struct csrdir *csrd;
519#ifdef FW_VMACCESS
520	struct fw_xfer *xfer;
521	struct fw_bind *fwb;
522#endif
523
524	fc->max_asyretry = FW_MAXASYRTY;
525
526	fc->arq->queued = 0;
527	fc->ars->queued = 0;
528	fc->atq->queued = 0;
529	fc->ats->queued = 0;
530
531	fc->arq->psize = PAGE_SIZE;
532	fc->ars->psize = PAGE_SIZE;
533	fc->atq->psize = 0;
534	fc->ats->psize = 0;
535
536
537	fc->arq->buf = NULL;
538	fc->ars->buf = NULL;
539	fc->atq->buf = NULL;
540	fc->ats->buf = NULL;
541
542	fc->arq->flag = FWXFERQ_PACKET;
543	fc->ars->flag = FWXFERQ_PACKET;
544	fc->atq->flag = FWXFERQ_PACKET;
545	fc->ats->flag = FWXFERQ_PACKET;
546
547	STAILQ_INIT(&fc->atq->q);
548	STAILQ_INIT(&fc->ats->q);
549
550	for( i = 0 ; i < fc->nisodma ; i ++ ){
551		fc->it[i]->queued = 0;
552		fc->ir[i]->queued = 0;
553
554		fc->it[i]->start = NULL;
555		fc->ir[i]->start = NULL;
556
557		fc->it[i]->buf = NULL;
558		fc->ir[i]->buf = NULL;
559
560		fc->it[i]->flag = FWXFERQ_STREAM;
561		fc->ir[i]->flag = FWXFERQ_STREAM;
562
563		STAILQ_INIT(&fc->it[i]->q);
564		STAILQ_INIT(&fc->ir[i]->q);
565
566		STAILQ_INIT(&fc->it[i]->binds);
567		STAILQ_INIT(&fc->ir[i]->binds);
568	}
569
570	fc->arq->maxq = FWMAXQUEUE;
571	fc->ars->maxq = FWMAXQUEUE;
572	fc->atq->maxq = FWMAXQUEUE;
573	fc->ats->maxq = FWMAXQUEUE;
574
575	for( i = 0 ; i < fc->nisodma ; i++){
576		fc->ir[i]->maxq = FWMAXQUEUE;
577		fc->it[i]->maxq = FWMAXQUEUE;
578	}
579/* Initialize csr registers */
580	fc->topology_map = (struct fw_topology_map *)malloc(
581				sizeof(struct fw_topology_map),
582				M_DEVBUF, M_NOWAIT | M_ZERO);
583	fc->speed_map = (struct fw_speed_map *)malloc(
584				sizeof(struct fw_speed_map),
585				M_DEVBUF, M_NOWAIT | M_ZERO);
586	CSRARC(fc, TOPO_MAP) = 0x3f1 << 16;
587	CSRARC(fc, TOPO_MAP + 4) = 1;
588	CSRARC(fc, SPED_MAP) = 0x3f1 << 16;
589	CSRARC(fc, SPED_MAP + 4) = 1;
590
591	TAILQ_INIT(&fc->devices);
592	STAILQ_INIT(&fc->pending);
593
594/* Initialize csr ROM work space */
595	SLIST_INIT(&fc->ongocsr);
596	SLIST_INIT(&fc->csrfree);
597	for( i = 0 ; i < FWMAXCSRDIR ; i++){
598		csrd = (struct csrdir *) malloc(sizeof(struct csrdir), M_DEVBUF,M_NOWAIT);
599		if(csrd == NULL) break;
600		SLIST_INSERT_HEAD(&fc->csrfree, csrd, link);
601	}
602
603/* Initialize Async handlers */
604	STAILQ_INIT(&fc->binds);
605	for( i = 0 ; i < 0x40 ; i++){
606		STAILQ_INIT(&fc->tlabels[i]);
607	}
608
609/* DV depend CSRs see blue book */
610#if 0
611	CSRARC(fc, oMPR) = 0x3fff0001; /* # output channel = 1 */
612	CSRARC(fc, oPCR) = 0x8000007a;
613	for(i = 4 ; i < 0x7c/4 ; i+=4){
614		CSRARC(fc, i + oPCR) = 0x8000007a;
615	}
616
617	CSRARC(fc, iMPR) = 0x00ff0001; /* # input channel = 1 */
618	CSRARC(fc, iPCR) = 0x803f0000;
619	for(i = 4 ; i < 0x7c/4 ; i+=4){
620		CSRARC(fc, i + iPCR) = 0x0;
621	}
622#endif
623
624
625#ifdef FW_VMACCESS
626	xfer = fw_xfer_alloc();
627	if(xfer == NULL) return;
628
629	fwb = (struct fw_bind *)malloc(sizeof (struct fw_bind), M_DEVBUF, M_NOWAIT);
630	if(fwb == NULL){
631		fw_xfer_free(xfer);
632	}
633	xfer->act.hand = fw_vmaccess;
634	xfer->act_type = FWACT_XFER;
635	xfer->fc = fc;
636	xfer->sc = NULL;
637
638	fwb->start_hi = 0x2;
639	fwb->start_lo = 0;
640	fwb->addrlen = 0xffffffff;
641	fwb->xfer = xfer;
642	fw_bindadd(fc, fwb);
643#endif
644}
645
646/*
647 * To lookup binded process from IEEE1394 address.
648 */
649struct fw_bind *
650fw_bindlookup(struct firewire_comm *fc, u_int32_t dest_hi, u_int32_t dest_lo)
651{
652	struct fw_bind *tfw;
653	for(tfw = STAILQ_FIRST(&fc->binds) ; tfw != NULL ;
654		tfw = STAILQ_NEXT(tfw, fclist)){
655		if(tfw->xfer->act_type != FWACT_NULL &&
656			tfw->start_hi == dest_hi &&
657			tfw->start_lo <= dest_lo &&
658			(tfw->start_lo + tfw->addrlen) > dest_lo){
659			return(tfw);
660		}
661	}
662	return(NULL);
663}
664
665/*
666 * To bind IEEE1394 address block to process.
667 */
668int
669fw_bindadd(struct firewire_comm *fc, struct fw_bind *fwb)
670{
671	struct fw_bind *tfw, *tfw2 = NULL;
672	int err = 0;
673	tfw = STAILQ_FIRST(&fc->binds);
674	if(tfw == NULL){
675		STAILQ_INSERT_HEAD(&fc->binds, fwb, fclist);
676		goto out;
677	}
678	if((tfw->start_hi > fwb->start_hi) ||
679		(tfw->start_hi == fwb->start_hi &&
680		(tfw->start_lo > (fwb->start_lo + fwb->addrlen)))){
681		STAILQ_INSERT_HEAD(&fc->binds, fwb, fclist);
682		goto out;
683	}
684	for(; tfw != NULL; tfw = STAILQ_NEXT(tfw, fclist)){
685		if((tfw->start_hi < fwb->start_hi) ||
686		   (tfw->start_hi == fwb->start_hi &&
687		    (tfw->start_lo + tfw->addrlen) < fwb->start_lo)){
688		   tfw2 = STAILQ_NEXT(tfw, fclist);
689			if(tfw2 == NULL)
690				break;
691			if((tfw2->start_hi > fwb->start_hi) ||
692			   (tfw2->start_hi == fwb->start_hi &&
693			    tfw2->start_lo > (fwb->start_lo + fwb->addrlen))){
694				break;
695			}else{
696				err = EBUSY;
697				goto out;
698			}
699		}
700	}
701	if(tfw != NULL){
702		STAILQ_INSERT_AFTER(&fc->binds, tfw, fwb, fclist);
703	}else{
704		STAILQ_INSERT_TAIL(&fc->binds, fwb, fclist);
705	}
706out:
707	if(!err && fwb->xfer->act_type == FWACT_CH){
708		STAILQ_INSERT_HEAD(&fc->ir[fwb->xfer->sub]->binds, fwb, chlist);
709	}
710	return err;
711}
712
713/*
714 * To free IEEE1394 address block.
715 */
716int
717fw_bindremove(struct firewire_comm *fc, struct fw_bind *fwb)
718{
719	int s;
720
721	s = splfw();
722	/* shall we check the existance? */
723	STAILQ_REMOVE(&fc->binds, fwb, fw_bind, fclist);
724	splx(s);
725	if (fwb->xfer)
726		fw_xfer_free(fwb->xfer);
727
728	return 0;
729}
730
731/*
732 * To free transaction label.
733 */
734static void
735fw_tl_free(struct firewire_comm *fc, struct fw_xfer *xfer)
736{
737	struct tlabel *tl;
738	int s = splfw();
739
740	for( tl = STAILQ_FIRST(&fc->tlabels[xfer->tl]); tl != NULL;
741		tl = STAILQ_NEXT(tl, link)){
742		if(tl->xfer == xfer){
743			STAILQ_REMOVE(&fc->tlabels[xfer->tl], tl, tlabel, link);
744			free(tl, M_DEVBUF);
745			splx(s);
746			return;
747		}
748	}
749	splx(s);
750	return;
751}
752
753/*
754 * To obtain XFER structure by transaction label.
755 */
756static struct fw_xfer *
757fw_tl2xfer(struct firewire_comm *fc, int node, int tlabel)
758{
759	struct fw_xfer *xfer;
760	struct tlabel *tl;
761	int s = splfw();
762
763	for( tl = STAILQ_FIRST(&fc->tlabels[tlabel]); tl != NULL;
764		tl = STAILQ_NEXT(tl, link)){
765		if(tl->xfer->dst == node){
766			xfer = tl->xfer;
767			splx(s);
768			return(xfer);
769		}
770	}
771	splx(s);
772	return(NULL);
773}
774
775/*
776 * To allocate IEEE1394 XFER structure.
777 */
778struct fw_xfer *
779fw_xfer_alloc()
780{
781	struct fw_xfer *xfer;
782
783	xfer = malloc(sizeof(struct fw_xfer), M_DEVBUF, M_NOWAIT | M_ZERO);
784	if (xfer == NULL)
785		return xfer;
786
787	xfer->time = time_second;
788	xfer->sub = -1;
789
790	return xfer;
791}
792
793/*
794 * IEEE1394 XFER post process.
795 */
796void
797fw_xfer_done(struct fw_xfer *xfer)
798{
799	if (xfer->act.hand == NULL)
800		return;
801
802#if XFER_TIMEOUT
803	untimeout(fw_xfer_timeout, (void *)xfer, xfer->ch);
804#endif
805
806	if (xfer->fc->status != FWBUSRESET)
807		xfer->act.hand(xfer);
808	else {
809		printf("fw_xfer_done: pending\n");
810		if (xfer->fc != NULL)
811			STAILQ_INSERT_TAIL(&xfer->fc->pending, xfer, link);
812		else
813			panic("fw_xfer_done: why xfer->fc is NULL?");
814	}
815}
816
817/*
818 * To free IEEE1394 XFER structure.
819 */
820void
821fw_xfer_free( struct fw_xfer* xfer)
822{
823	int s;
824	if(xfer == NULL ) return;
825	if(xfer->state == FWXF_INQ){
826		printf("fw_xfer_free FWXF_INQ\n");
827		s = splfw();
828		STAILQ_REMOVE(&xfer->q->q, xfer, fw_xfer, link);
829		xfer->q->queued --;
830		splx(s);
831	}
832	if(xfer->fc != NULL){
833		if(xfer->state == FWXF_START){
834#if 0 /* this could happen if we call fwohci_arcv() before fwohci_txd() */
835			printf("fw_xfer_free FWXF_START\n");
836#endif
837			s = splfw();
838			xfer->q->drain(xfer->fc, xfer);
839			splx(s);
840		}
841	}
842	if(xfer->send.buf != NULL){
843		free(xfer->send.buf, M_DEVBUF);
844	}
845	if(xfer->recv.buf != NULL){
846		free(xfer->recv.buf, M_DEVBUF);
847	}
848	if(xfer->fc != NULL){
849		fw_tl_free(xfer->fc, xfer);
850	}
851	free(xfer, M_DEVBUF);
852}
853
854/*
855 * Callback for PHY configuration.
856 */
857static void
858fw_phy_config_callback(struct fw_xfer *xfer)
859{
860#if 0
861	printf("phy_config done state=%d resp=%d\n",
862				xfer->state, xfer->resp);
863#endif
864	fw_xfer_free(xfer);
865	/* XXX need bus reset ?? */
866	/* sc->fc->ibr(xfer->fc);  LOOP */
867}
868
869/*
870 * To configure PHY.
871 */
872static void
873fw_phy_config(struct firewire_comm *fc, int root_node, int gap_count)
874{
875	struct fw_xfer *xfer;
876	struct fw_pkt *fp;
877
878	fc->status = FWBUSPHYCONF;
879
880#if 0
881	DELAY(100000);
882#endif
883	xfer = fw_xfer_alloc();
884	xfer->send.len = 12;
885	xfer->send.off = 0;
886	xfer->fc = fc;
887	xfer->retry_req = fw_asybusy;
888	xfer->act.hand = fw_phy_config_callback;
889
890	xfer->send.buf = malloc(sizeof(u_int32_t),
891					M_DEVBUF, M_NOWAIT | M_ZERO);
892	fp = (struct fw_pkt *)xfer->send.buf;
893	fp->mode.ld[1] = 0;
894	if (root_node >= 0)
895		fp->mode.ld[1] |= htonl((root_node & 0x3f) << 24 | 1 << 23);
896	if (gap_count >= 0)
897		fp->mode.ld[1] |= htonl(1 << 22 | (gap_count & 0x3f) << 16);
898	fp->mode.ld[2] = ~fp->mode.ld[1];
899/* XXX Dangerous, how to pass PHY packet to device driver */
900	fp->mode.common.tcode |= FWTCODE_PHY;
901
902	if (firewire_debug)
903		printf("send phy_config root_node=%d gap_count=%d\n",
904						root_node, gap_count);
905	fw_asyreq(fc, -1, xfer);
906}
907
908#if 0
909/*
910 * Dump self ID.
911 */
912static void
913fw_print_sid(u_int32_t sid)
914{
915	union fw_self_id *s;
916	s = (union fw_self_id *) &sid;
917	printf("node:%d link:%d gap:%d spd:%d del:%d con:%d pwr:%d"
918		" p0:%d p1:%d p2:%d i:%d m:%d\n",
919		s->p0.phy_id, s->p0.link_active, s->p0.gap_count,
920		s->p0.phy_speed, s->p0.phy_delay, s->p0.contender,
921		s->p0.power_class, s->p0.port0, s->p0.port1,
922		s->p0.port2, s->p0.initiated_reset, s->p0.more_packets);
923}
924#endif
925
926/*
927 * To receive self ID.
928 */
929void fw_sidrcv(struct firewire_comm* fc, caddr_t buf, u_int len, u_int off)
930{
931	u_int32_t *p, *sid = (u_int32_t *)(buf + off);
932	union fw_self_id *self_id;
933	u_int i, j, node, c_port = 0, i_branch = 0;
934
935	fc->sid_cnt = len /(sizeof(u_int32_t) * 2);
936	fc->status = FWBUSINIT;
937	fc->max_node = fc->nodeid & 0x3f;
938	CSRARC(fc, NODE_IDS) = ((u_int32_t)fc->nodeid) << 16;
939	fc->status = FWBUSCYMELECT;
940	fc->topology_map->crc_len = 2;
941	fc->topology_map->generation ++;
942	fc->topology_map->self_id_count = 0;
943	fc->topology_map->node_count = 0;
944	fc->speed_map->generation ++;
945	fc->speed_map->crc_len = 1 + (64*64 + 3) / 4;
946	self_id = &fc->topology_map->self_id[0];
947	for(i = 0; i < fc->sid_cnt; i ++){
948		if (sid[1] != ~sid[0]) {
949			printf("fw_sidrcv: invalid self-id packet\n");
950			sid += 2;
951			continue;
952		}
953		*self_id = *((union fw_self_id *)sid);
954		fc->topology_map->crc_len++;
955		if(self_id->p0.sequel == 0){
956			fc->topology_map->node_count ++;
957			c_port = 0;
958#if 0
959			fw_print_sid(sid[0]);
960#endif
961			node = self_id->p0.phy_id;
962			if(fc->max_node < node){
963				fc->max_node = self_id->p0.phy_id;
964			}
965			/* XXX I'm not sure this is the right speed_map */
966			fc->speed_map->speed[node][node]
967					= self_id->p0.phy_speed;
968			for (j = 0; j < node; j ++) {
969				fc->speed_map->speed[j][node]
970					= fc->speed_map->speed[node][j]
971					= min(fc->speed_map->speed[j][j],
972							self_id->p0.phy_speed);
973			}
974			if ((fc->irm == -1 || self_id->p0.phy_id > fc->irm) &&
975			  (self_id->p0.link_active && self_id->p0.contender)) {
976				fc->irm = self_id->p0.phy_id;
977			}
978			if(self_id->p0.port0 >= 0x2){
979				c_port++;
980			}
981			if(self_id->p0.port1 >= 0x2){
982				c_port++;
983			}
984			if(self_id->p0.port2 >= 0x2){
985				c_port++;
986			}
987		}
988		if(c_port > 2){
989			i_branch += (c_port - 2);
990		}
991		sid += 2;
992		self_id++;
993		fc->topology_map->self_id_count ++;
994	}
995	device_printf(fc->bdev, "%d nodes", fc->max_node + 1);
996	/* CRC */
997	fc->topology_map->crc = fw_crc16(
998			(u_int32_t *)&fc->topology_map->generation,
999			fc->topology_map->crc_len * 4);
1000	fc->speed_map->crc = fw_crc16(
1001			(u_int32_t *)&fc->speed_map->generation,
1002			fc->speed_map->crc_len * 4);
1003	/* byteswap and copy to CSR */
1004	p = (u_int32_t *)fc->topology_map;
1005	for (i = 0; i <= fc->topology_map->crc_len; i++)
1006		CSRARC(fc, TOPO_MAP + i * 4) = htonl(*p++);
1007	p = (u_int32_t *)fc->speed_map;
1008	CSRARC(fc, SPED_MAP) = htonl(*p++);
1009	CSRARC(fc, SPED_MAP + 4) = htonl(*p++);
1010	/* don't byte-swap u_int8_t array */
1011	bcopy(p, &CSRARC(fc, SPED_MAP + 8), (fc->speed_map->crc_len - 1)*4);
1012
1013	fc->max_hop = fc->max_node - i_branch;
1014#if 1
1015	printf(", maxhop <= %d", fc->max_hop);
1016#endif
1017
1018	if(fc->irm == -1 ){
1019		printf(", Not found IRM capable node");
1020	}else{
1021		printf(", cable IRM = %d", fc->irm);
1022		if (fc->irm == fc->nodeid)
1023			printf(" (me)\n");
1024		else
1025			printf("\n");
1026	}
1027
1028	if (try_bmr && (fc->irm != -1) && (CSRARC(fc, BUS_MGR_ID) == 0x3f)) {
1029		if (fc->irm == ((CSRARC(fc, NODE_IDS) >> 16 ) & 0x3f)) {
1030			fc->status = FWBUSMGRDONE;
1031			CSRARC(fc, BUS_MGR_ID) = fc->set_bmr(fc, fc->irm);
1032		} else {
1033			fc->status = FWBUSMGRELECT;
1034			fc->bmrhandle = timeout((timeout_t *)fw_try_bmr,
1035							(void *)fc, hz / 8);
1036		}
1037	} else {
1038		fc->status = FWBUSMGRDONE;
1039#if 0
1040		device_printf(fc->bdev, "BMR = %x\n",
1041				CSRARC(fc, BUS_MGR_ID));
1042#endif
1043	}
1044	free(buf, M_DEVBUF);
1045	/* Optimize gap_count, if I am BMGR */
1046	if(fc->irm == ((CSRARC(fc, NODE_IDS) >> 16 ) & 0x3f)){
1047		fw_phy_config(fc, -1, gap_cnt[fc->max_hop]);
1048	}
1049	callout_reset(&fc->busprobe_callout, hz/4,
1050			(void *)fw_bus_probe, (void *)fc);
1051}
1052
1053/*
1054 * To probe devices on the IEEE1394 bus.
1055 */
1056static void
1057fw_bus_probe(struct firewire_comm *fc)
1058{
1059	int s;
1060	struct fw_device *fwdev, *next;
1061
1062	s = splfw();
1063	fc->status = FWBUSEXPLORE;
1064	fc->retry_count = 0;
1065
1066/*
1067 * Invalidate all devices, just after bus reset. Devices
1068 * to be removed has not been seen longer time.
1069 */
1070	for(fwdev = TAILQ_FIRST(&fc->devices); fwdev != NULL; fwdev = next) {
1071		next = TAILQ_NEXT(fwdev, link);
1072		if(fwdev->status != FWDEVINVAL){
1073			fwdev->status = FWDEVINVAL;
1074			fwdev->rcnt = 0;
1075		}else if(fwdev->rcnt < FW_MAXDEVRCNT){
1076			fwdev->rcnt ++;
1077		}else{
1078			TAILQ_REMOVE(&fc->devices, fwdev, link);
1079			free(fwdev, M_DEVBUF);
1080		}
1081	}
1082	fc->ongonode = 0;
1083	fc->ongoaddr = CSRROMOFF;
1084	fc->ongodev = NULL;
1085	fc->ongoeui.hi = 0xffffffff; fc->ongoeui.lo = 0xffffffff;
1086	fw_bus_explore(fc);
1087	splx(s);
1088}
1089
1090/*
1091 * To collect device informations on the IEEE1394 bus.
1092 */
1093static void
1094fw_bus_explore(struct firewire_comm *fc )
1095{
1096	int err = 0;
1097	struct fw_device *fwdev, *tfwdev;
1098	u_int32_t addr;
1099	struct fw_xfer *xfer;
1100	struct fw_pkt *fp;
1101
1102	if(fc->status != FWBUSEXPLORE)
1103		return;
1104
1105loop:
1106	if(fc->ongonode == fc->nodeid) fc->ongonode++;
1107
1108	if(fc->ongonode > fc->max_node) goto done;
1109	if(fc->ongonode >= 0x3f) goto done;
1110
1111	/* check link */
1112	/* XXX we need to check phy_id first */
1113	if (!fc->topology_map->self_id[fc->ongonode].p0.link_active) {
1114		printf("fw_bus_explore: node %d link down\n", fc->ongonode);
1115		fc->ongonode++;
1116		goto loop;
1117	}
1118
1119	if(fc->ongoaddr <= CSRROMOFF &&
1120		fc->ongoeui.hi == 0xffffffff &&
1121		fc->ongoeui.lo == 0xffffffff ){
1122		fc->ongoaddr = CSRROMOFF;
1123		addr = 0xf0000000 | fc->ongoaddr;
1124	}else if(fc->ongoeui.hi == 0xffffffff ){
1125		fc->ongoaddr = CSRROMOFF + 0xc;
1126		addr = 0xf0000000 | fc->ongoaddr;
1127	}else if(fc->ongoeui.lo == 0xffffffff ){
1128		fc->ongoaddr = CSRROMOFF + 0x10;
1129		addr = 0xf0000000 | fc->ongoaddr;
1130	}else if(fc->ongodev == NULL){
1131		for(fwdev = TAILQ_FIRST(&fc->devices); fwdev != NULL;
1132			fwdev = TAILQ_NEXT(fwdev, link)){
1133			if(fwdev->eui.hi == fc->ongoeui.hi && fwdev->eui.lo == fc->ongoeui.lo){
1134				break;
1135			}
1136		}
1137		if(fwdev != NULL){
1138			fwdev->dst = fc->ongonode;
1139			fwdev->status = FWDEVATTACHED;
1140			fc->ongonode++;
1141			fc->ongoaddr = CSRROMOFF;
1142			fc->ongodev = NULL;
1143			fc->ongoeui.hi = 0xffffffff; fc->ongoeui.lo = 0xffffffff;
1144			goto loop;
1145		}
1146		fwdev = malloc(sizeof(struct fw_device), M_DEVBUF, M_NOWAIT);
1147		if(fwdev == NULL)
1148			return;
1149		fwdev->fc = fc;
1150		fwdev->rommax = 0;
1151		fwdev->dst = fc->ongonode;
1152		fwdev->eui.hi = fc->ongoeui.hi; fwdev->eui.lo = fc->ongoeui.lo;
1153		fwdev->status = FWDEVINIT;
1154#if 0
1155		fwdev->speed = CSRARC(fc, SPED_MAP + 8 + fc->ongonode / 4)
1156			>> ((3 - (fc->ongonode % 4)) * 8);
1157#else
1158		fwdev->speed = fc->speed_map->speed[fc->nodeid][fc->ongonode];
1159#endif
1160
1161		tfwdev = TAILQ_FIRST(&fc->devices);
1162		while( tfwdev != NULL &&
1163			(tfwdev->eui.hi > fwdev->eui.hi) &&
1164			((tfwdev->eui.hi == fwdev->eui.hi) &&
1165				tfwdev->eui.lo > fwdev->eui.lo)){
1166			tfwdev = TAILQ_NEXT( tfwdev, link);
1167		}
1168		if(tfwdev == NULL){
1169			TAILQ_INSERT_TAIL(&fc->devices, fwdev, link);
1170		}else{
1171			TAILQ_INSERT_BEFORE(tfwdev, fwdev, link);
1172		}
1173
1174		device_printf(fc->bdev, "New %s device ID:%08x%08x\n",
1175			linkspeed[fwdev->speed],
1176			fc->ongoeui.hi, fc->ongoeui.lo);
1177
1178		fc->ongodev = fwdev;
1179		fc->ongoaddr = CSRROMOFF;
1180		addr = 0xf0000000 | fc->ongoaddr;
1181	}else{
1182		addr = 0xf0000000 | fc->ongoaddr;
1183	}
1184#if 0
1185	xfer = asyreqq(fc, FWSPD_S100, 0, 0,
1186		((FWLOCALBUS | fc->ongonode) << 16) | 0xffff , addr,
1187		fw_bus_explore_callback);
1188	if(xfer == NULL) goto done;
1189#else
1190	xfer = fw_xfer_alloc();
1191	if(xfer == NULL){
1192		goto done;
1193	}
1194	xfer->send.len = 16;
1195	xfer->spd = 0;
1196	xfer->send.buf = malloc(16, M_DEVBUF, M_NOWAIT);
1197	if(xfer->send.buf == NULL){
1198		fw_xfer_free( xfer);
1199		return;
1200	}
1201
1202	xfer->send.off = 0;
1203	fp = (struct fw_pkt *)xfer->send.buf;
1204	fp->mode.rreqq.dest_hi = htons(0xffff);
1205	fp->mode.rreqq.tlrt = 0;
1206	fp->mode.rreqq.tcode = FWTCODE_RREQQ;
1207	fp->mode.rreqq.pri = 0;
1208	fp->mode.rreqq.src = 0;
1209	xfer->dst = FWLOCALBUS | fc->ongonode;
1210	fp->mode.rreqq.dst = htons(xfer->dst);
1211	fp->mode.rreqq.dest_lo = htonl(addr);
1212	xfer->act.hand = fw_bus_explore_callback;
1213
1214	err = fw_asyreq(fc, -1, xfer);
1215	if(err){
1216		fw_xfer_free( xfer);
1217		return;
1218	}
1219#endif
1220	return;
1221done:
1222	/* fw_attach_devs */
1223	fc->status = FWBUSEXPDONE;
1224	if (firewire_debug)
1225		printf("bus_explore done\n");
1226	fw_attach_dev(fc);
1227	return;
1228
1229}
1230
1231/* Portable Async. request read quad */
1232struct fw_xfer *
1233asyreqq(struct firewire_comm *fc, u_int8_t spd, u_int8_t tl, u_int8_t rt,
1234	u_int32_t addr_hi, u_int32_t addr_lo,
1235	void (*hand) __P((struct fw_xfer*)))
1236{
1237	struct fw_xfer *xfer;
1238	struct fw_pkt *fp;
1239	int err;
1240
1241	xfer = fw_xfer_alloc();
1242	if(xfer == NULL){
1243		return NULL;
1244	}
1245	xfer->send.len = 16;
1246	xfer->spd = spd; /* XXX:min(spd, fc->spd) */
1247	xfer->send.buf = malloc(16, M_DEVBUF, M_NOWAIT);
1248	if(xfer->send.buf == NULL){
1249		fw_xfer_free( xfer);
1250		return NULL;
1251	}
1252
1253	xfer->send.off = 0;
1254	fp = (struct fw_pkt *)xfer->send.buf;
1255	fp->mode.rreqq.dest_hi = htons(addr_hi & 0xffff);
1256	if(tl & FWP_TL_VALID){
1257		fp->mode.rreqq.tlrt = (tl & 0x3f) << 2;
1258	}else{
1259		fp->mode.rreqq.tlrt = 0;
1260	}
1261	fp->mode.rreqq.tlrt |= rt & 0x3;
1262	fp->mode.rreqq.tcode = FWTCODE_RREQQ;
1263	fp->mode.rreqq.pri = 0;
1264	fp->mode.rreqq.src = 0;
1265	xfer->dst = addr_hi >> 16;
1266	fp->mode.rreqq.dst = htons(xfer->dst);
1267	fp->mode.rreqq.dest_lo = htonl(addr_lo);
1268	xfer->act.hand = hand;
1269
1270	err = fw_asyreq(fc, -1, xfer);
1271	if(err){
1272		fw_xfer_free( xfer);
1273		return NULL;
1274	}
1275	return xfer;
1276}
1277
1278/*
1279 * Callback for the IEEE1394 bus information collection.
1280 */
1281static void
1282fw_bus_explore_callback(struct fw_xfer *xfer)
1283{
1284	struct firewire_comm *fc;
1285	struct fw_pkt *sfp,*rfp;
1286	struct csrhdr *chdr;
1287	struct csrdir *csrd;
1288	struct csrreg *csrreg;
1289	u_int32_t offset;
1290
1291
1292	if(xfer == NULL) return;
1293	fc = xfer->fc;
1294	if(xfer->resp != 0){
1295		printf("resp != 0: node=%d addr=0x%x\n",
1296			fc->ongonode, fc->ongoaddr);
1297		fc->retry_count++;
1298		goto nextnode;
1299	}
1300
1301	if(xfer->send.buf == NULL){
1302		printf("send.buf == NULL: node=%d addr=0x%x\n",
1303			fc->ongonode, fc->ongoaddr);
1304		printf("send.buf == NULL\n");
1305		fc->retry_count++;
1306		goto nextnode;
1307	}
1308	sfp = (struct fw_pkt *)xfer->send.buf;
1309
1310	if(xfer->recv.buf == NULL){
1311		printf("recv.buf == NULL: node=%d addr=0x%x\n",
1312			fc->ongonode, fc->ongoaddr);
1313		fc->retry_count++;
1314		goto nextnode;
1315	}
1316	rfp = (struct fw_pkt *)xfer->recv.buf;
1317#if 0
1318	{
1319		u_int32_t *qld;
1320		int i;
1321		qld = (u_int32_t *)xfer->recv.buf;
1322		printf("len:%d\n", xfer->recv.len);
1323		for( i = 0 ; i <= xfer->recv.len && i < 32; i+= 4){
1324			printf("0x%08x ", ntohl(rfp->mode.ld[i/4]));
1325			if((i % 16) == 15) printf("\n");
1326		}
1327		if((i % 16) != 15) printf("\n");
1328	}
1329#endif
1330	if(fc->ongodev == NULL){
1331		if(sfp->mode.rreqq.dest_lo == htonl((0xf0000000 | CSRROMOFF))){
1332			rfp->mode.rresq.data = ntohl(rfp->mode.rresq.data);
1333			chdr = (struct csrhdr *)(&rfp->mode.rresq.data);
1334/* If CSR is minimul confinguration, more investgation is not needed. */
1335			if(chdr->info_len == 1){
1336				goto nextnode;
1337			}else{
1338				fc->ongoaddr = CSRROMOFF + 0xc;
1339			}
1340		}else if(sfp->mode.rreqq.dest_lo == htonl((0xf0000000 |(CSRROMOFF + 0xc)))){
1341			fc->ongoeui.hi = ntohl(rfp->mode.rresq.data);
1342			fc->ongoaddr = CSRROMOFF + 0x10;
1343		}else if(sfp->mode.rreqq.dest_lo == htonl((0xf0000000 |(CSRROMOFF + 0x10)))){
1344			fc->ongoeui.lo = ntohl(rfp->mode.rresq.data);
1345			if (fc->ongoeui.hi == 0 && fc->ongoeui.lo == 0)
1346				goto nextnode;
1347			fc->ongoaddr = CSRROMOFF;
1348		}
1349	}else{
1350		fc->ongodev->csrrom[(fc->ongoaddr - CSRROMOFF)/4] = ntohl(rfp->mode.rresq.data);
1351		if(fc->ongoaddr > fc->ongodev->rommax){
1352			fc->ongodev->rommax = fc->ongoaddr;
1353		}
1354		csrd = SLIST_FIRST(&fc->ongocsr);
1355		if((csrd = SLIST_FIRST(&fc->ongocsr)) == NULL){
1356			chdr = (struct csrhdr *)(fc->ongodev->csrrom);
1357			offset = CSRROMOFF;
1358		}else{
1359			chdr = (struct csrhdr *)&fc->ongodev->csrrom[(csrd->off - CSRROMOFF)/4];
1360			offset = csrd->off;
1361		}
1362		if(fc->ongoaddr > (CSRROMOFF + 0x14) && fc->ongoaddr != offset){
1363			csrreg = (struct csrreg *)&fc->ongodev->csrrom[(fc->ongoaddr - CSRROMOFF)/4];
1364			if( csrreg->key == 0x81 || csrreg->key == 0xd1){
1365				csrd = SLIST_FIRST(&fc->csrfree);
1366				if(csrd == NULL){
1367					goto nextnode;
1368				}else{
1369					csrd->ongoaddr = fc->ongoaddr;
1370					fc->ongoaddr += csrreg->val * 4;
1371					csrd->off = fc->ongoaddr;
1372					SLIST_REMOVE_HEAD(&fc->csrfree, link);
1373					SLIST_INSERT_HEAD(&fc->ongocsr, csrd, link);
1374					goto nextaddr;
1375				}
1376			}
1377		}
1378		fc->ongoaddr += 4;
1379		if(((fc->ongoaddr - offset)/4 > chdr->crc_len) &&
1380				(fc->ongodev->rommax < 0x414)){
1381			if(fc->ongodev->rommax <= 0x414){
1382				csrd = SLIST_FIRST(&fc->csrfree);
1383				if(csrd == NULL) goto nextnode;
1384				csrd->off = fc->ongoaddr;
1385				csrd->ongoaddr = fc->ongoaddr;
1386				SLIST_REMOVE_HEAD(&fc->csrfree, link);
1387				SLIST_INSERT_HEAD(&fc->ongocsr, csrd, link);
1388			}
1389			goto nextaddr;
1390		}
1391
1392		while(((fc->ongoaddr - offset)/4 > chdr->crc_len)){
1393			if(csrd == NULL){
1394				goto nextnode;
1395			};
1396			fc->ongoaddr = csrd->ongoaddr + 4;
1397			SLIST_REMOVE_HEAD(&fc->ongocsr, link);
1398			SLIST_INSERT_HEAD(&fc->csrfree, csrd, link);
1399			csrd = SLIST_FIRST(&fc->ongocsr);
1400			if((csrd = SLIST_FIRST(&fc->ongocsr)) == NULL){
1401				chdr = (struct csrhdr *)(fc->ongodev->csrrom);
1402				offset = CSRROMOFF;
1403			}else{
1404				chdr = (struct csrhdr *)&(fc->ongodev->csrrom[(csrd->off - CSRROMOFF)/4]);
1405				offset = csrd->off;
1406			}
1407		}
1408		if((fc->ongoaddr - CSRROMOFF) > CSRROMSIZE){
1409			goto nextnode;
1410		}
1411	}
1412nextaddr:
1413	fw_xfer_free( xfer);
1414	fw_bus_explore(fc);
1415	return;
1416nextnode:
1417	fw_xfer_free( xfer);
1418	fc->ongonode++;
1419/* housekeeping work space */
1420	fc->ongoaddr = CSRROMOFF;
1421	fc->ongodev = NULL;
1422	fc->ongoeui.hi = 0xffffffff; fc->ongoeui.lo = 0xffffffff;
1423	while((csrd = SLIST_FIRST(&fc->ongocsr)) != NULL){
1424		SLIST_REMOVE_HEAD(&fc->ongocsr, link);
1425		SLIST_INSERT_HEAD(&fc->csrfree, csrd, link);
1426	}
1427	fw_bus_explore(fc);
1428	return;
1429}
1430
1431/*
1432 * To obtain CSR register values.
1433 */
1434u_int32_t
1435getcsrdata(struct fw_device *fwdev, u_int8_t key)
1436{
1437	int i;
1438	struct csrhdr *chdr;
1439	struct csrreg *creg;
1440	chdr = (struct csrhdr *)&fwdev->csrrom[0];
1441	for( i = chdr->info_len + 4; i <= fwdev->rommax - CSRROMOFF; i+=4){
1442		creg = (struct csrreg *)&fwdev->csrrom[i/4];
1443		if(creg->key == key){
1444			return (u_int32_t)creg->val;
1445		}
1446	}
1447	return 0;
1448}
1449
1450/*
1451 * To attach sub-devices layer onto IEEE1394 bus.
1452 */
1453static void
1454fw_attach_dev(struct firewire_comm *fc)
1455{
1456	struct fw_device *fwdev;
1457	struct fw_xfer *xfer;
1458	int i, err;
1459	device_t *devlistp;
1460	int devcnt;
1461	struct firewire_dev_comm *fdc;
1462	u_int32_t spec, ver;
1463
1464	for(fwdev = TAILQ_FIRST(&fc->devices); fwdev != NULL;
1465			fwdev = TAILQ_NEXT(fwdev, link)){
1466		if(fwdev->status == FWDEVINIT){
1467			spec = getcsrdata(fwdev, CSRKEY_SPEC);
1468			if(spec == 0)
1469				continue;
1470			ver = getcsrdata(fwdev, CSRKEY_VER);
1471			if(ver == 0)
1472				continue;
1473			fwdev->maxrec = (fwdev->csrrom[2] >> 12) & 0xf;
1474
1475			device_printf(fc->bdev, "Device ");
1476			switch(spec){
1477			case CSRVAL_ANSIT10:
1478				switch(ver){
1479				case CSRVAL_T10SBP2:
1480					printf("SBP-II");
1481					break;
1482				default:
1483					break;
1484				}
1485				break;
1486			case CSRVAL_1394TA:
1487				switch(ver){
1488				case CSR_PROTAVC:
1489					printf("AV/C");
1490					break;
1491				case CSR_PROTCAL:
1492					printf("CAL");
1493					break;
1494				case CSR_PROTEHS:
1495					printf("EHS");
1496					break;
1497				case CSR_PROTHAVI:
1498					printf("HAVi");
1499					break;
1500				case CSR_PROTCAM104:
1501					printf("1394 Cam 1.04");
1502					break;
1503				case CSR_PROTCAM120:
1504					printf("1394 Cam 1.20");
1505					break;
1506				case CSR_PROTCAM130:
1507					printf("1394 Cam 1.30");
1508					break;
1509				case CSR_PROTDPP:
1510					printf("1394 Direct print");
1511					break;
1512				case CSR_PROTIICP:
1513					printf("Industrial & Instrument");
1514					break;
1515				default:
1516					printf("unknown 1394TA");
1517					break;
1518				}
1519				break;
1520			default:
1521				printf("unknown spec");
1522				break;
1523			}
1524			fwdev->status = FWDEVATTACHED;
1525			printf("\n");
1526		}
1527	}
1528	err = device_get_children(fc->bdev, &devlistp, &devcnt);
1529	if( err != 0 )
1530		return;
1531	for( i = 0 ; i < devcnt ; i++){
1532		if (device_get_state(devlistp[i]) >= DS_ATTACHED)  {
1533			fdc = device_get_softc(devlistp[i]);
1534			if (fdc->post_explore != NULL)
1535				fdc->post_explore(fdc);
1536		}
1537	}
1538	free(devlistp, M_TEMP);
1539
1540	/* call pending handlers */
1541	i = 0;
1542	while ((xfer = STAILQ_FIRST(&fc->pending))) {
1543		STAILQ_REMOVE_HEAD(&fc->pending, link);
1544		i++;
1545		if (xfer->act.hand)
1546			xfer->act.hand(xfer);
1547	}
1548	if (i > 0)
1549		printf("fw_attach_dev: %d pending handlers called\n", i);
1550	if (fc->retry_count > 0) {
1551		printf("retry_count = %d\n", fc->retry_count);
1552		fc->retry_probe_handle = timeout((timeout_t *)fc->ibr,
1553							(void *)fc, hz*2);
1554	}
1555	return;
1556}
1557
1558/*
1559 * To allocate uniq transaction label.
1560 */
1561static int
1562fw_get_tlabel(struct firewire_comm *fc, struct fw_xfer *xfer)
1563{
1564	u_int i;
1565	struct tlabel *tl, *tmptl;
1566	int s;
1567	static u_int32_t label = 0;
1568
1569	s = splfw();
1570	for( i = 0 ; i < 0x40 ; i ++){
1571		label = (label + 1) & 0x3f;
1572		for(tmptl = STAILQ_FIRST(&fc->tlabels[label]);
1573			tmptl != NULL; tmptl = STAILQ_NEXT(tmptl, link)){
1574			if(tmptl->xfer->dst == xfer->dst) break;
1575		}
1576		if(tmptl == NULL) {
1577			tl = malloc(sizeof(struct tlabel),M_DEVBUF,M_NOWAIT);
1578			if (tl == NULL) {
1579				splx(s);
1580				return (-1);
1581			}
1582			tl->xfer = xfer;
1583			STAILQ_INSERT_TAIL(&fc->tlabels[label], tl, link);
1584			splx(s);
1585			return(label);
1586		}
1587	}
1588	splx(s);
1589
1590	printf("fw_get_tlabel: no free tlabel\n");
1591	return(-1);
1592}
1593
1594/*
1595 * Generic packet receving process.
1596 */
1597void
1598fw_rcv(struct firewire_comm* fc, caddr_t buf, u_int len, u_int sub, u_int off, u_int spd)
1599{
1600	struct fw_pkt *fp, *resfp;
1601	struct fw_xfer *xfer;
1602	struct fw_bind *bind;
1603	struct firewire_softc *sc;
1604	int s;
1605#if 0
1606	{
1607		u_int32_t *qld;
1608		int i;
1609		qld = (u_int32_t *)buf;
1610		printf("spd %d len:%d\n", spd, len);
1611		for( i = 0 ; i <= len && i < 32; i+= 4){
1612			printf("0x%08x ", ntohl(qld[i/4]));
1613			if((i % 16) == 15) printf("\n");
1614		}
1615		if((i % 16) != 15) printf("\n");
1616	}
1617#endif
1618	fp = (struct fw_pkt *)(buf + off);
1619	switch(fp->mode.common.tcode){
1620	case FWTCODE_WRES:
1621	case FWTCODE_RRESQ:
1622	case FWTCODE_RRESB:
1623	case FWTCODE_LRES:
1624		xfer = fw_tl2xfer(fc, ntohs(fp->mode.hdr.src),
1625					fp->mode.hdr.tlrt >> 2);
1626		if(xfer == NULL) {
1627			printf("fw_rcv: unknown response "
1628					"tcode=%d src=0x%x tl=%x rt=%d data=0x%x\n",
1629					fp->mode.common.tcode,
1630					ntohs(fp->mode.hdr.src),
1631					fp->mode.hdr.tlrt >> 2,
1632					fp->mode.hdr.tlrt & 3,
1633					fp->mode.rresq.data);
1634#if 1
1635			printf("try ad-hoc work around!!\n");
1636			xfer = fw_tl2xfer(fc, ntohs(fp->mode.hdr.src),
1637					(fp->mode.hdr.tlrt >> 2)^3);
1638			if (xfer == NULL) {
1639				printf("no use...\n");
1640				goto err;
1641			}
1642#else
1643			goto err;
1644#endif
1645		}
1646		switch(xfer->act_type){
1647		case FWACT_XFER:
1648			if((xfer->sub >= 0) &&
1649				((fc->ir[xfer->sub]->flag & FWXFERQ_MODEMASK ) == 0)){
1650				xfer->resp = EINVAL;
1651				fw_xfer_done(xfer);
1652				goto err;
1653			}
1654			xfer->recv.len = len;
1655			xfer->recv.off = off;
1656			xfer->recv.buf = buf;
1657			xfer->resp = 0;
1658			fw_xfer_done(xfer);
1659			return;
1660			break;
1661		case FWACT_CH:
1662		default:
1663			goto err;
1664			break;
1665		}
1666		break;
1667	case FWTCODE_WREQQ:
1668	case FWTCODE_WREQB:
1669	case FWTCODE_RREQQ:
1670	case FWTCODE_RREQB:
1671	case FWTCODE_LREQ:
1672		bind = fw_bindlookup(fc, ntohs(fp->mode.rreqq.dest_hi),
1673			ntohl(fp->mode.rreqq.dest_lo));
1674		if(bind == NULL){
1675#if __FreeBSD_version >= 500000
1676			printf("Unknown service addr 0x%08x:0x%08x tcode=%x\n",
1677#else
1678			printf("Unknown service addr 0x%08x:0x%08lx tcode=%x\n",
1679#endif
1680				ntohs(fp->mode.rreqq.dest_hi),
1681				ntohl(fp->mode.rreqq.dest_lo),
1682				fp->mode.common.tcode);
1683			if (fc->status == FWBUSRESET) {
1684				printf("fw_rcv: cannot response(bus reset)!\n");
1685				goto err;
1686			}
1687			xfer = fw_xfer_alloc();
1688			if(xfer == NULL){
1689				return;
1690			}
1691			xfer->spd = spd;
1692			xfer->send.buf = malloc(16, M_DEVBUF, M_NOWAIT);
1693			resfp = (struct fw_pkt *)xfer->send.buf;
1694			switch(fp->mode.common.tcode){
1695			case FWTCODE_WREQQ:
1696			case FWTCODE_WREQB:
1697				resfp->mode.hdr.tcode = FWTCODE_WRES;
1698				xfer->send.len = 12;
1699				break;
1700			case FWTCODE_RREQQ:
1701				resfp->mode.hdr.tcode = FWTCODE_RRESQ;
1702				xfer->send.len = 16;
1703				break;
1704			case FWTCODE_RREQB:
1705				resfp->mode.hdr.tcode = FWTCODE_RRESB;
1706				xfer->send.len = 16;
1707				break;
1708			case FWTCODE_LREQ:
1709				resfp->mode.hdr.tcode = FWTCODE_LRES;
1710				xfer->send.len = 16;
1711				break;
1712			}
1713			resfp->mode.hdr.dst = fp->mode.hdr.src;
1714			resfp->mode.hdr.tlrt = fp->mode.hdr.tlrt;
1715			resfp->mode.hdr.pri = fp->mode.hdr.pri;
1716			resfp->mode.rresb.rtcode = 7;
1717			resfp->mode.rresb.extcode = 0;
1718			resfp->mode.rresb.len = 0;
1719/*
1720			xfer->act.hand = fw_asy_callback;
1721*/
1722			xfer->act.hand = fw_xfer_free;
1723			if(fw_asyreq(fc, -1, xfer)){
1724				fw_xfer_free( xfer);
1725				return;
1726			}
1727			goto err;
1728		}
1729		switch(bind->xfer->act_type){
1730		case FWACT_XFER:
1731			xfer = fw_xfer_alloc();
1732			if(xfer == NULL) goto err;
1733			xfer->fc = bind->xfer->fc;
1734			xfer->sc = bind->xfer->sc;
1735			xfer->recv.buf = buf;
1736			xfer->recv.len = len;
1737			xfer->recv.off = off;
1738			xfer->spd = spd;
1739			xfer->act.hand = bind->xfer->act.hand;
1740			if (fc->status != FWBUSRESET)
1741				xfer->act.hand(xfer);
1742			else
1743				STAILQ_INSERT_TAIL(&fc->pending, xfer, link);
1744			return;
1745			break;
1746		case FWACT_CH:
1747			if(fc->ir[bind->xfer->sub]->queued >=
1748				fc->ir[bind->xfer->sub]->maxq){
1749				device_printf(fc->bdev,
1750					"Discard a packet %x %d\n",
1751					bind->xfer->sub,
1752					fc->ir[bind->xfer->sub]->queued);
1753				goto err;
1754			}
1755			xfer = fw_xfer_alloc();
1756			if(xfer == NULL) goto err;
1757			xfer->recv.buf = buf;
1758			xfer->recv.len = len;
1759			xfer->recv.off = off;
1760			xfer->spd = spd;
1761			s = splfw();
1762			fc->ir[bind->xfer->sub]->queued++;
1763			STAILQ_INSERT_TAIL(&fc->ir[bind->xfer->sub]->q, xfer, link);
1764			splx(s);
1765
1766			wakeup((caddr_t)fc->ir[bind->xfer->sub]);
1767
1768			return;
1769			break;
1770		default:
1771			goto err;
1772			break;
1773		}
1774		break;
1775	case FWTCODE_STREAM:
1776	{
1777		struct fw_xferq *xferq;
1778
1779		xferq = fc->ir[sub];
1780#if 0
1781		printf("stream rcv dma %d len %d off %d spd %d\n",
1782			sub, len, off, spd);
1783#endif
1784		if(xferq->queued >= xferq->maxq) {
1785			printf("receive queue is full\n");
1786			goto err;
1787		}
1788		xfer = fw_xfer_alloc();
1789		if(xfer == NULL) goto err;
1790		xfer->recv.buf = buf;
1791		xfer->recv.len = len;
1792		xfer->recv.off = off;
1793		xfer->spd = spd;
1794		s = splfw();
1795		xferq->queued++;
1796		STAILQ_INSERT_TAIL(&xferq->q, xfer, link);
1797		splx(s);
1798		sc = device_get_softc(fc->bdev);
1799#if __FreeBSD_version >= 500000
1800		if (SEL_WAITING(&xferq->rsel))
1801#else
1802		if (&xferq->rsel.si_pid != 0)
1803#endif
1804			selwakeup(&xferq->rsel);
1805		if (xferq->flag & FWXFERQ_WAKEUP) {
1806			xferq->flag &= ~FWXFERQ_WAKEUP;
1807			wakeup((caddr_t)xferq);
1808		}
1809		if (xferq->flag & FWXFERQ_HANDLER) {
1810			xferq->hand(xferq);
1811		}
1812		return;
1813		break;
1814	}
1815	default:
1816		printf("fw_rcv: unknow tcode\n");
1817		break;
1818	}
1819err:
1820	free(buf, M_DEVBUF);
1821}
1822
1823/*
1824 * Post process for Bus Manager election process.
1825 */
1826static void
1827fw_try_bmr_callback(struct fw_xfer *xfer)
1828{
1829	struct fw_pkt *rfp;
1830	struct firewire_comm *fc;
1831	int bmr;
1832
1833	if (xfer == NULL)
1834		return;
1835	fc = xfer->fc;
1836	if (xfer->resp != 0)
1837		goto error;
1838	if (xfer->send.buf == NULL)
1839		goto error;
1840	if (xfer->recv.buf == NULL)
1841		goto error;
1842	rfp = (struct fw_pkt *)xfer->recv.buf;
1843	if (rfp->mode.lres.rtcode != FWRCODE_COMPLETE)
1844		goto error;
1845
1846	bmr = ntohl(rfp->mode.lres.payload[0]);
1847	if (bmr == 0x3f)
1848		bmr = fc->nodeid;
1849
1850	CSRARC(fc, BUS_MGR_ID) = fc->set_bmr(fc, bmr & 0x3f);
1851	device_printf(fc->bdev, "new bus manager %d ",
1852		CSRARC(fc, BUS_MGR_ID));
1853	if(bmr == fc->nodeid){
1854		printf("(me)\n");
1855/* If I am bus manager, optimize gapcount */
1856		if(fc->max_hop <= MAX_GAPHOP ){
1857			fw_phy_config(fc, -1, gap_cnt[fc->max_hop]);
1858		}
1859	}else{
1860		printf("\n");
1861	}
1862error:
1863	fw_xfer_free(xfer);
1864}
1865
1866/*
1867 * To candidate Bus Manager election process.
1868 */
1869void
1870fw_try_bmr(void *arg)
1871{
1872	struct fw_xfer *xfer;
1873	struct firewire_comm *fc = (struct firewire_comm *)arg;
1874	struct fw_pkt *fp;
1875	int err = 0;
1876
1877	xfer = fw_xfer_alloc();
1878	if(xfer == NULL){
1879		return;
1880	}
1881	xfer->send.len = 24;
1882	xfer->spd = 0;
1883	xfer->send.buf = malloc(24, M_DEVBUF, M_NOWAIT);
1884	if(xfer->send.buf == NULL){
1885		fw_xfer_free( xfer);
1886		return;
1887	}
1888
1889	fc->status = FWBUSMGRELECT;
1890
1891	xfer->send.off = 0;
1892	fp = (struct fw_pkt *)xfer->send.buf;
1893	fp->mode.lreq.dest_hi = htons(0xffff);
1894	fp->mode.lreq.tlrt = 0;
1895	fp->mode.lreq.tcode = FWTCODE_LREQ;
1896	fp->mode.lreq.pri = 0;
1897	fp->mode.lreq.src = 0;
1898	fp->mode.lreq.len = htons(8);
1899	fp->mode.lreq.extcode = htons(FW_LREQ_CMPSWAP);
1900	xfer->dst = FWLOCALBUS | fc->irm;
1901	fp->mode.lreq.dst = htons(xfer->dst);
1902	fp->mode.lreq.dest_lo = htonl(0xf0000000 | BUS_MGR_ID);
1903	fp->mode.lreq.payload[0] = htonl(0x3f);
1904	fp->mode.lreq.payload[1] = htonl(fc->nodeid);
1905	xfer->act_type = FWACT_XFER;
1906	xfer->act.hand = fw_try_bmr_callback;
1907
1908	err = fw_asyreq(fc, -1, xfer);
1909	if(err){
1910		fw_xfer_free( xfer);
1911		return;
1912	}
1913	return;
1914}
1915
1916#ifdef FW_VMACCESS
1917/*
1918 * Software implementation for physical memory block access.
1919 * XXX:Too slow, usef for debug purpose only.
1920 */
1921static void
1922fw_vmaccess(struct fw_xfer *xfer){
1923	struct fw_pkt *rfp, *sfp = NULL;
1924	u_int32_t *ld = (u_int32_t *)(xfer->recv.buf + xfer->recv.off);
1925
1926	printf("vmaccess spd:%2x len:%03x %d data:%08x %08x %08x %08x\n",
1927			xfer->spd, xfer->recv.len, xfer->recv.off, ntohl(ld[0]), ntohl(ld[1]), ntohl(ld[2]), ntohl(ld[3]));
1928	printf("vmaccess          data:%08x %08x %08x %08x\n", ntohl(ld[4]), ntohl(ld[5]), ntohl(ld[6]), ntohl(ld[7]));
1929	if(xfer->resp != 0){
1930		fw_xfer_free( xfer);
1931		return;
1932	}
1933	if(xfer->recv.buf == NULL){
1934		fw_xfer_free( xfer);
1935		return;
1936	}
1937	rfp = (struct fw_pkt *)xfer->recv.buf;
1938	switch(rfp->mode.hdr.tcode){
1939		/* XXX need fix for 64bit arch */
1940		case FWTCODE_WREQB:
1941			xfer->send.buf = malloc(12, M_DEVBUF, M_NOWAIT);
1942			xfer->send.len = 12;
1943			sfp = (struct fw_pkt *)xfer->send.buf;
1944			bcopy(rfp->mode.wreqb.payload,
1945				(caddr_t)ntohl(rfp->mode.wreqb.dest_lo), ntohs(rfp->mode.wreqb.len));
1946			sfp->mode.wres.tcode = FWTCODE_WRES;
1947			sfp->mode.wres.rtcode = 0;
1948			break;
1949		case FWTCODE_WREQQ:
1950			xfer->send.buf = malloc(12, M_DEVBUF, M_NOWAIT);
1951			xfer->send.len = 12;
1952			sfp->mode.wres.tcode = FWTCODE_WRES;
1953			*((u_int32_t *)(ntohl(rfp->mode.wreqb.dest_lo))) = rfp->mode.wreqq.data;
1954			sfp->mode.wres.rtcode = 0;
1955			break;
1956		case FWTCODE_RREQB:
1957			xfer->send.buf = malloc(16 + rfp->mode.rreqb.len, M_DEVBUF, M_NOWAIT);
1958			xfer->send.len = 16 + ntohs(rfp->mode.rreqb.len);
1959			sfp = (struct fw_pkt *)xfer->send.buf;
1960			bcopy((caddr_t)ntohl(rfp->mode.rreqb.dest_lo),
1961				sfp->mode.rresb.payload, (u_int16_t)ntohs(rfp->mode.rreqb.len));
1962			sfp->mode.rresb.tcode = FWTCODE_RRESB;
1963			sfp->mode.rresb.len = rfp->mode.rreqb.len;
1964			sfp->mode.rresb.rtcode = 0;
1965			sfp->mode.rresb.extcode = 0;
1966			break;
1967		case FWTCODE_RREQQ:
1968			xfer->send.buf = malloc(16, M_DEVBUF, M_NOWAIT);
1969			xfer->send.len = 16;
1970			sfp = (struct fw_pkt *)xfer->send.buf;
1971			sfp->mode.rresq.data = *(u_int32_t *)(ntohl(rfp->mode.rreqq.dest_lo));
1972			sfp->mode.wres.tcode = FWTCODE_RRESQ;
1973			sfp->mode.rresb.rtcode = 0;
1974			break;
1975		default:
1976			fw_xfer_free( xfer);
1977			return;
1978	}
1979	xfer->send.off = 0;
1980	sfp->mode.hdr.dst = rfp->mode.hdr.src;
1981	xfer->dst = ntohs(rfp->mode.hdr.src);
1982	xfer->act.hand = fw_xfer_free;
1983	xfer->retry_req = fw_asybusy;
1984
1985	sfp->mode.hdr.tlrt = rfp->mode.hdr.tlrt;
1986	sfp->mode.hdr.pri = 0;
1987
1988	fw_asyreq(xfer->fc, -1, xfer);
1989/**/
1990	return;
1991}
1992#endif
1993
1994/*
1995 * CRC16 check-sum for IEEE1394 register blocks.
1996 */
1997u_int16_t
1998fw_crc16(u_int32_t *ptr, u_int32_t len){
1999	u_int32_t i, sum, crc = 0;
2000	int shift;
2001	len = (len + 3) & ~3;
2002	for(i = 0 ; i < len ; i+= 4){
2003		for( shift = 28 ; shift >= 0 ; shift -= 4){
2004			sum = ((crc >> 12) ^ (ptr[i/4] >> shift)) & 0xf;
2005			crc = (crc << 4) ^ ( sum << 12 ) ^ ( sum << 5) ^ sum;
2006		}
2007		crc &= 0xffff;
2008	}
2009	return((u_int16_t) crc);
2010}
2011
2012DRIVER_MODULE(firewire,fwohci,firewire_driver,firewire_devclass,0,0);
2013MODULE_VERSION(firewire, 1);
2014