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