xref: /freebsd/sys/dev/firewire/firewire.c (revision a3e8fd0b7f663db7eafff527d5c3ca3bcfa8a537)
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$
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 #include <sys/poll.h>
50 
51 #include <machine/cpufunc.h>    /* for rdtsc proto for clock.h below */
52 #include <machine/clock.h>
53 #include <pci/pcivar.h>
54 #include <pci/pcireg.h>
55 
56 #include <vm/vm.h>
57 #include <vm/pmap.h>            /* for vtophys proto */
58 #include <vm/vm_extern.h>
59 
60 #include <sys/bus.h>		/* used by smbus and newbus */
61 
62 #include <machine/bus.h>	/* used by newbus */
63 #include <sys/rman.h>		/* used by newbus */
64 #include <machine/resource.h>	/* used by newbus */
65 
66 #include <sys/signal.h>
67 #include <sys/mman.h>
68 #include <sys/ioccom.h>
69 
70 #include <dev/firewire/firewire.h>
71 #include <dev/firewire/firewirereg.h>
72 #include <dev/firewire/fwmem.h>
73 #include <dev/firewire/iec13213.h>
74 #include <dev/firewire/iec68113.h>
75 
76 int firewire_debug=0;
77 SYSCTL_NODE(_hw, OID_AUTO, firewire, CTLFLAG_RD, 0, "Firewire Subsystem");
78 SYSCTL_INT(_debug, OID_AUTO, firewire_debug, CTLFLAG_RW, &firewire_debug, 0,
79 	"Firewire driver debug flag");
80 
81 #define CDEV_MAJOR 127
82 #define FW_MAXASYRTY 4
83 #define FW_MAXDEVRCNT 4
84 #define	FWNODE_INVAL 0xffff
85 
86 #define XFER_TIMEOUT 0
87 
88 static	d_open_t	fw_open;
89 static	d_close_t	fw_close;
90 static	d_ioctl_t	fw_ioctl;
91 static	d_poll_t	fw_poll;
92 static	d_read_t	fw_read;	/* for Isochronous packet */
93 static	d_write_t	fw_write;
94 static	d_mmap_t	fw_mmap;
95 
96 devclass_t firewire_devclass;
97 
98 
99 static int firewire_match      __P((device_t));
100 static int firewire_attach      __P((device_t));
101 static int firewire_detach      __P((device_t));
102 #if 0
103 static int firewire_shutdown    __P((device_t));
104 #endif
105 static device_t firewire_add_child   __P((device_t, int, const char *, int));
106 static struct fw_bind *fw_bindlookup __P((struct firewire_comm *, u_int32_t, u_int32_t));
107 static void fw_try_bmr __P((void *));
108 static void fw_try_bmr_callback __P((struct fw_xfer *));
109 static u_int16_t fw_noderesolve __P((struct firewire_comm *, struct fw_eui64));
110 static void fw_asystart __P((struct fw_xfer *));
111 static int fw_get_tlabel __P((struct firewire_comm *, struct fw_xfer *));
112 static void fw_bus_probe __P((struct firewire_comm *));
113 static void fw_bus_explore __P((struct firewire_comm *));
114 static void fw_bus_explore_callback __P((struct fw_xfer *));
115 static void fw_attach_dev __P((struct firewire_comm *));
116 static void fw_vmaccess __P((struct fw_xfer *));
117 struct fw_xfer *asyreqq __P((struct firewire_comm *, u_int8_t, u_int8_t, u_int8_t,
118 	u_int32_t, u_int32_t, void (*)__P((struct fw_xfer *))));
119 
120 static device_method_t firewire_methods[] = {
121 	/* Device interface */
122 	DEVMETHOD(device_probe,		firewire_match),
123 	DEVMETHOD(device_attach,	firewire_attach),
124 	DEVMETHOD(device_detach,	firewire_detach),
125 	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
126 
127 	/* Bus interface */
128 	DEVMETHOD(bus_add_child,	firewire_add_child),
129 	DEVMETHOD(bus_print_child,	bus_generic_print_child),
130 
131 	{ 0, 0 }
132 };
133 char linkspeed[7][0x10]={"S100","S200","S400","S800","S1600","S3200","Unknown"};
134 u_int maxrec[6]={512,1024,2048,4096,8192,0};
135 
136 #define MAX_GAPHOP  16
137 u_int gap_cnt[] = {1, 1, 4, 6, 9, 12, 14, 17,
138 			20, 23, 25, 28, 31, 33, 36, 39, 42};
139 /*
140  * The probe routine.
141  */
142 struct cdevsw firewire_cdevsw =
143 {
144 	fw_open, fw_close, fw_read, fw_write, fw_ioctl,
145 	fw_poll, fw_mmap, nostrategy, "fw", CDEV_MAJOR, nodump, nopsize, D_MEM
146 };
147 static driver_t firewire_driver = {
148 	"firewire",
149 	firewire_methods,
150 	sizeof(struct firewire_softc),
151 };
152 
153 static int
154 fw_open (dev_t dev, int flags, int fmt, fw_proc *td)
155 {
156 	struct firewire_softc *sc;
157 	int unit = DEV2UNIT(dev);
158 	int sub = DEV2DMACH(dev);
159 
160 	int err = 0;
161 
162 	if (DEV_FWMEM(dev))
163 		return fwmem_open(dev, flags, fmt, td);
164 
165 	sc = devclass_get_softc(firewire_devclass, unit);
166 	if(sc->fc->ir[sub]->flag & FWXFERQ_OPEN){
167 		err = EBUSY;
168 		return err;
169 	}
170 	if(sc->fc->it[sub]->flag & FWXFERQ_OPEN){
171 		err = EBUSY;
172 		return err;
173 	}
174 	if(sc->fc->ir[sub]->flag & FWXFERQ_MODEMASK){
175 		err = EBUSY;
176 		return err;
177 	}
178 /* Default is per packet mode */
179 	sc->fc->ir[sub]->flag |= FWXFERQ_OPEN;
180 	sc->fc->it[sub]->flag |= FWXFERQ_OPEN;
181 	sc->fc->ir[sub]->flag |= FWXFERQ_PACKET;
182 	return err;
183 }
184 static int
185 fw_close (dev_t dev, int flags, int fmt, fw_proc *td)
186 {
187 	struct firewire_softc *sc;
188 	int unit = DEV2UNIT(dev);
189 	int sub = DEV2DMACH(dev);
190 	struct fw_xfer *xfer;
191 	struct fw_dvbuf *dvbuf;
192 	struct fw_bind *fwb;
193 	int err = 0;
194 
195 	if (DEV_FWMEM(dev))
196 		return fwmem_close(dev, flags, fmt, td);
197 
198 	sc = devclass_get_softc(firewire_devclass, unit);
199 	if(!(sc->fc->ir[sub]->flag & FWXFERQ_OPEN)){
200 		err = EINVAL;
201 		return err;
202 	}
203 	sc->fc->ir[sub]->flag &= ~FWXFERQ_OPEN;
204 	if(!(sc->fc->it[sub]->flag & FWXFERQ_OPEN)){
205 		err = EINVAL;
206 		return err;
207 	}
208 	sc->fc->it[sub]->flag &= ~FWXFERQ_OPEN;
209 
210 	if(sc->fc->ir[sub]->flag & FWXFERQ_RUNNING){
211 		sc->fc->irx_disable(sc->fc, sub);
212 	}
213 	if(sc->fc->it[sub]->flag & FWXFERQ_RUNNING){
214 		sc->fc->it[sub]->flag &= ~FWXFERQ_RUNNING;
215 		sc->fc->itx_disable(sc->fc, sub);
216 	}
217 	if(sc->fc->it[sub]->flag & FWXFERQ_DV){
218 		if((dvbuf = sc->fc->it[sub]->dvproc) != NULL){
219 			free(dvbuf->buf, M_DEVBUF);
220 			sc->fc->it[sub]->dvproc = NULL;
221 		}
222 		if((dvbuf = sc->fc->it[sub]->dvdma) != NULL){
223 			free(dvbuf->buf, M_DEVBUF);
224 			sc->fc->it[sub]->dvdma = NULL;
225 		}
226 		while((dvbuf = STAILQ_FIRST(&sc->fc->it[sub]->dvvalid)) != NULL){
227 			STAILQ_REMOVE_HEAD(&sc->fc->it[sub]->dvvalid, link);
228 			free(dvbuf->buf, M_DEVBUF);
229 		}
230 		while((dvbuf = STAILQ_FIRST(&sc->fc->it[sub]->dvfree)) != NULL){
231 			STAILQ_REMOVE_HEAD(&sc->fc->it[sub]->dvfree, link);
232 			free(dvbuf->buf, M_DEVBUF);
233 		}
234 		free(sc->fc->it[sub]->dvbuf, M_DEVBUF);
235 		sc->fc->it[sub]->dvbuf = NULL;
236 	}
237 	if(sc->fc->ir[sub]->flag & FWXFERQ_EXTBUF){
238 		free(sc->fc->ir[sub]->buf, M_DEVBUF);
239 		sc->fc->ir[sub]->buf = NULL;
240 		free(sc->fc->ir[sub]->bulkxfer, M_DEVBUF);
241 		sc->fc->ir[sub]->bulkxfer = NULL;
242 		sc->fc->ir[sub]->flag &= ~FWXFERQ_EXTBUF;
243 		sc->fc->ir[sub]->psize = FWPMAX_S400;
244 		sc->fc->ir[sub]->maxq = FWMAXQUEUE;
245 	}
246 	if(sc->fc->it[sub]->flag & FWXFERQ_EXTBUF){
247 		free(sc->fc->it[sub]->buf, M_DEVBUF);
248 		sc->fc->it[sub]->buf = NULL;
249 		free(sc->fc->it[sub]->bulkxfer, M_DEVBUF);
250 		sc->fc->it[sub]->bulkxfer = NULL;
251 		sc->fc->it[sub]->dvbuf = NULL;
252 		sc->fc->it[sub]->flag &= ~FWXFERQ_EXTBUF;
253 		sc->fc->it[sub]->psize = FWPMAX_S400;
254 		sc->fc->it[sub]->maxq = FWMAXQUEUE;
255 	}
256 	for(xfer = STAILQ_FIRST(&sc->fc->ir[sub]->q);
257 		xfer != NULL; xfer = STAILQ_FIRST(&sc->fc->ir[sub]->q)){
258 		sc->fc->ir[sub]->queued--;
259 		STAILQ_REMOVE_HEAD(&sc->fc->ir[sub]->q, link);
260 
261 		xfer->resp = 0;
262 		switch(xfer->act_type){
263 		case FWACT_XFER:
264 			fw_xfer_done(xfer);
265 			break;
266 		default:
267 			break;
268 		}
269 		fw_xfer_free(xfer);
270 	}
271 	for(fwb = STAILQ_FIRST(&sc->fc->ir[sub]->binds); fwb != NULL;
272 		fwb = STAILQ_FIRST(&sc->fc->ir[sub]->binds)){
273 		STAILQ_REMOVE(&sc->fc->binds, fwb, fw_bind, fclist);
274 		STAILQ_REMOVE_HEAD(&sc->fc->ir[sub]->binds, chlist);
275 		free(fwb, M_DEVBUF);
276 	}
277 	sc->fc->ir[sub]->flag &= ~FWXFERQ_MODEMASK;
278 	sc->fc->it[sub]->flag &= ~FWXFERQ_MODEMASK;
279 	return err;
280 }
281 /*
282  * read request.
283  */
284 static int
285 fw_read (dev_t dev, struct uio *uio, int ioflag)
286 {
287 	struct firewire_softc *sc;
288 	struct fw_xferq *ir;
289 	struct fw_xfer *xfer;
290 	int err = 0, s, slept = 0;
291 	int unit = DEV2UNIT(dev);
292 	int sub = DEV2DMACH(dev);
293 	struct fw_pkt *fp;
294 
295 	if (DEV_FWMEM(dev))
296 		return fwmem_read(dev, uio, ioflag);
297 
298 	sc = devclass_get_softc(firewire_devclass, unit);
299 
300 	ir = sc->fc->ir[sub];
301 
302 	if(ir->flag & FWXFERQ_PACKET){
303 		ir->stproc = NULL;
304 	}
305 readloop:
306 	xfer = STAILQ_FIRST(&ir->q);
307 	if(!(ir->flag & FWXFERQ_PACKET) && ir->stproc == NULL){
308 		ir->stproc = STAILQ_FIRST(&ir->stvalid);
309 		if(ir->stproc != NULL){
310 			s = splfw();
311 			STAILQ_REMOVE_HEAD(&ir->stvalid, link);
312 			splx(s);
313 			ir->queued = 0;
314 		}
315 	}
316 
317 	if(xfer == NULL && ir->stproc == NULL){
318 		if(slept == 0){
319 			slept = 1;
320 			if(!(ir->flag & FWXFERQ_RUNNING)
321 				&& (ir->flag & FWXFERQ_PACKET)){
322 				err = sc->fc->irx_enable(sc->fc, sub);
323 			}
324 			if(err){
325 				return err;
326 			}
327 			ir->flag |= FWXFERQ_WAKEUP;
328 			err = tsleep((caddr_t)ir, FWPRI, "fw_read", hz);
329 			if(err){
330 				ir->flag &= ~FWXFERQ_WAKEUP;
331 				return err;
332 			}
333 			goto readloop;
334 		}else{
335 			err = EIO;
336 			return err;
337 		}
338 	}else if(xfer != NULL){
339 		s = splfw();
340 		ir->queued --;
341 		STAILQ_REMOVE_HEAD(&ir->q, link);
342 		splx(s);
343 		fp = (struct fw_pkt *)(xfer->recv.buf + xfer->recv.off);
344 		if(sc->fc->irx_post != NULL)
345 			sc->fc->irx_post(sc->fc, fp->mode.ld);
346 		err = uiomove(xfer->recv.buf + xfer->recv.off, xfer->recv.len, uio);
347 		fw_xfer_free( xfer);
348 	}else if(ir->stproc != NULL){
349 		fp = (struct fw_pkt *)(ir->stproc->buf + ir->queued * ir->psize);
350 		if(sc->fc->irx_post != NULL)
351 			sc->fc->irx_post(sc->fc, fp->mode.ld);
352 		if(ntohs(fp->mode.stream.len) == 0){
353 			err = EIO;
354 			return err;
355 		}
356 		err = uiomove((caddr_t)fp, ntohs(fp->mode.stream.len) + sizeof(u_int32_t), uio);
357 		fp->mode.stream.len = 0;
358 		ir->queued ++;
359 		if(ir->queued >= ir->bnpacket){
360 			s = splfw();
361 			ir->stproc->flag = 0;
362 			STAILQ_INSERT_TAIL(&ir->stfree, ir->stproc, link);
363 			splx(s);
364 			ir->stproc = NULL;
365 		}
366 	}
367 #if 0
368 	if(STAILQ_FIRST(&ir->q) == NULL &&
369 		(ir->flag & FWXFERQ_RUNNING) && (ir->flag & FWXFERQ_PACKET)){
370 		err = sc->fc->irx_enable(sc->fc, sub);
371 	}
372 #endif
373 #if 0
374 	if(STAILQ_FIRST(&ir->stvalid) == NULL &&
375 		(ir->flag & FWXFERQ_RUNNING) && !(ir->flag & FWXFERQ_PACKET)){
376 		err = sc->fc->irx_enable(sc->fc, sub);
377 	}
378 #endif
379 	return err;
380 }
381 static int
382 fw_write (dev_t dev, struct uio *uio, int ioflag)
383 {
384 	int err = 0;
385 	struct firewire_softc *sc;
386 	int unit = DEV2UNIT(dev);
387 	int sub = DEV2DMACH(dev);
388 	int tl, s, slept = 0;
389 	struct fw_pkt *fp;
390 	struct fw_xfer *xfer;
391 	struct fw_xferq *xferq;
392 	struct firewire_comm *fc;
393 	struct fw_xferq *it;
394 
395 	if (DEV_FWMEM(dev))
396 		return fwmem_write(dev, uio, ioflag);
397 
398 	sc = devclass_get_softc(firewire_devclass, unit);
399 	fc = sc->fc;
400 	it = sc->fc->it[sub];
401 
402 	fp = (struct fw_pkt *)uio->uio_iov->iov_base;
403 	switch(fp->mode.common.tcode){
404 	case FWTCODE_RREQQ:
405 	case FWTCODE_RREQB:
406 	case FWTCODE_LREQ:
407 		err = EINVAL;
408 		return err;
409 	case FWTCODE_WREQQ:
410 	case FWTCODE_WREQB:
411 		xferq = fc->atq;
412 		break;
413 	case FWTCODE_STREAM:
414 		if(it->flag & FWXFERQ_PACKET){
415 			xferq = fc->atq;
416 		}else{
417 			xferq = NULL;
418 		}
419 		break;
420 	case FWTCODE_WRES:
421 	case FWTCODE_RRESQ:
422 	case FWTCODE_RRESB:
423 	case FWTCODE_LRES:
424 		xferq = fc->ats;
425 		break;
426 	default:
427 		err = EINVAL;
428 		return err;
429 	}
430 	/* Discard unsent buffered stream packet, when sending Asyrequrst */
431 	if(xferq != NULL && it->stproc != NULL){
432 		s = splfw();
433 		it->stproc->flag = 0;
434 		STAILQ_INSERT_TAIL(&it->stfree, it->stproc, link);
435 		splx(s);
436 		it->stproc = NULL;
437 	}
438 	if(xferq == NULL && !(it->flag & FWXFERQ_DV)){
439 isoloop:
440 		if(it->stproc == NULL){
441 			it->stproc = STAILQ_FIRST(&it->stfree);
442 			if(it->stproc != NULL){
443 				s = splfw();
444 				STAILQ_REMOVE_HEAD(&it->stfree, link);
445 				splx(s);
446 				it->queued = 0;
447 			}else if(slept == 0){
448 				slept = 1;
449 				err = sc->fc->itx_enable(sc->fc, sub);
450 				if(err){
451 					return err;
452 				}
453 				err = tsleep((caddr_t)it, FWPRI, "fw_write", hz);
454 				if(err){
455 					return err;
456 				}
457 				goto isoloop;
458 			}else{
459 				err = EIO;
460 				return err;
461 			}
462 		}
463 		fp = (struct fw_pkt *)(it->stproc->buf + it->queued * it->psize);
464 		fp->mode.stream.len = htons(uio->uio_resid - sizeof(u_int32_t));
465 		err = uiomove(it->stproc->buf + it->queued * it->psize,
466 							uio->uio_resid, uio);
467 		it->queued ++;
468 		if(it->queued >= it->btpacket){
469 			s = splfw();
470 			STAILQ_INSERT_TAIL(&it->stvalid, it->stproc, link);
471 			splx(s);
472 			it->stproc = NULL;
473 			fw_tbuf_update(sc->fc, sub, 0);
474 			err = sc->fc->itx_enable(sc->fc, sub);
475 		}
476 		return err;
477 	} if(xferq == NULL && it->flag & FWXFERQ_DV){
478 dvloop:
479 		if(it->dvproc == NULL){
480 			it->dvproc = STAILQ_FIRST(&it->dvfree);
481 			if(it->dvproc != NULL){
482 				s = splfw();
483 				STAILQ_REMOVE_HEAD(&it->dvfree, link);
484 				splx(s);
485 				it->dvptr = 0;
486 			}else if(slept == 0){
487 				slept = 1;
488 				err = sc->fc->itx_enable(sc->fc, sub);
489 				if(err){
490 					return err;
491 				}
492 				err = tsleep((caddr_t)it, FWPRI, "fw_write", hz);
493 				if(err){
494 					return err;
495 				}
496 				goto dvloop;
497 			}else{
498 				err = EIO;
499 				return err;
500 			}
501 		}
502 		fp = (struct fw_pkt *)(it->dvproc->buf + it->queued * it->psize);
503 		fp->mode.stream.len = htons(uio->uio_resid - sizeof(u_int32_t));
504 		err = uiomove(it->dvproc->buf + it->dvptr,
505 							uio->uio_resid, uio);
506 		it->dvptr += it->psize;
507 		if(err){
508 			return err;
509 		}
510 		if(it->dvptr >= it->psize * it->dvpacket){
511 			s = splfw();
512 			STAILQ_INSERT_TAIL(&it->dvvalid, it->dvproc, link);
513 			splx(s);
514 			it->dvproc = NULL;
515 			err = fw_tbuf_update(sc->fc, sub, 0);
516 			if(err){
517 				return err;
518 			}
519 			err = sc->fc->itx_enable(sc->fc, sub);
520 		}
521 		return err;
522 	}
523 	if(xferq != NULL){
524 		xfer = fw_xfer_alloc();
525 		if(xfer == NULL){
526 			err = ENOMEM;
527 			return err;
528 		}
529 		xfer->send.buf = malloc(uio->uio_resid, M_DEVBUF, M_NOWAIT);
530 		if(xfer->send.buf == NULL){
531 			fw_xfer_free( xfer);
532 			err = ENOBUFS;
533 			return err;
534 		}
535 		xfer->dst = ntohs(fp->mode.hdr.dst);
536 
537 		switch(fp->mode.common.tcode){
538 		case FWTCODE_WREQQ:
539 		case FWTCODE_WREQB:
540 			if((tl = fw_get_tlabel(fc, xfer)) == -1 ){
541 				fw_xfer_free( xfer);
542 				err = EAGAIN;
543 				return err;
544 			}
545 			fp->mode.hdr.tlrt = tl << 2;
546 		default:
547 			break;
548 		}
549 
550 		xfer->tl = fp->mode.hdr.tlrt >> 2;
551 		xfer->send.len = uio->uio_resid;
552 		xfer->send.off = 0;
553 		xfer->tcode = fp->mode.common.tcode;
554 		xfer->spd = 0;/* XXX: how to setup it */
555 		xfer->fc = fc;
556 		xfer->q = xferq;
557 		xfer->act_type = FWACT_XFER;
558 		xfer->act.hand = fw_asy_callback;
559 		xfer->retry_req = fw_asybusy;
560 
561 		err = uiomove(xfer->send.buf, uio->uio_resid, uio);
562 		if(err){
563 			return err;
564 		}
565 		fw_asystart(xfer);
566 		err = tsleep((caddr_t)xfer, FWPRI, "fw_write", hz);
567 		if(xfer->resp == EBUSY)
568 			return EBUSY;
569 		fw_xfer_free( xfer);
570 		return err;
571 	}
572 	return EINVAL;
573 }
574 /*
575  * transmitter buffer update.
576  */
577 int
578 fw_tbuf_update(struct firewire_comm *fc, int sub, int flag){
579 	struct fw_bulkxfer *bulkxfer, *bulkxfer2 = NULL;
580 	struct fw_dvbuf *dvbuf = NULL;
581 	struct fw_xferq *it;
582 	int s, err = 0, i, j, chtag;
583 	struct fw_pkt *fp;
584 	u_int64_t tmpsync, dvsync;
585 
586 	it = fc->it[sub];
587 
588 	s = splfw();
589 	if(it->stdma == NULL){
590 		bulkxfer = STAILQ_FIRST(&it->stvalid);
591 	}else if(flag != 0){
592 		bulkxfer = STAILQ_FIRST(&it->stvalid);
593 		if(bulkxfer == it->stdma){
594 			STAILQ_REMOVE_HEAD(&it->stvalid, link);
595 			it->stdma->flag = 0;
596 			STAILQ_INSERT_TAIL(&it->stfree, it->stdma, link);
597 			if(!(it->flag & FWXFERQ_DV))
598 				wakeup(it);
599 		}
600 		bulkxfer = STAILQ_FIRST(&it->stvalid);
601 	}else{
602 		bulkxfer = it->stdma;
603 	}
604 	splx(s);
605 	if(bulkxfer != NULL){
606 		s = splfw();
607 		bulkxfer2 = STAILQ_NEXT(bulkxfer, link);
608 #if 0
609 		if(it->flag & FWXFERQ_DV && bulkxfer2 == NULL){
610 			bulkxfer2 = STAILQ_FIRST(&it->stfree);
611 			STAILQ_REMOVE_HEAD(&it->stfree, link);
612 			splx(s);
613 			bcopy(bulkxfer->buf, bulkxfer2->buf,
614 					it->psize * it->btpacket);
615 			s = splfw();
616 			STAILQ_INSERT_TAIL(&it->stvalid, bulkxfer2, link);
617 		}
618 #endif
619 		splx(s);
620 	}
621 	it->stdma = bulkxfer;
622 	it->stdma2 = bulkxfer2;
623 
624 	if(it->flag & FWXFERQ_DV){
625 		chtag = it->flag & 0xff;
626 dvloop:
627 		if(it->dvdma == NULL){
628 			dvbuf = STAILQ_FIRST(&it->dvvalid);
629 			if(dvbuf != NULL){
630 				s = splfw();
631 				STAILQ_REMOVE_HEAD(&it->dvvalid, link);
632 				it->dvdma = dvbuf;
633 				splx(s);
634 				it->queued = 0;
635 			}
636 		}
637 		if(it->dvdma == NULL)
638 			return err;
639 
640 		it->stproc = STAILQ_FIRST(&it->stfree);
641 		if(it->stproc != NULL){
642 			s = splfw();
643 			STAILQ_REMOVE_HEAD(&it->stfree, link);
644 			splx(s);
645 		}else{
646 			return err;
647 		}
648 /*
649  * Insert least significant 12 bits timestamp value by computation.
650  * Highest significant 4 bits is insert at just before packet sending.
651  */
652 		fp = (struct fw_pkt *)(it->stproc->buf);
653 /* XXX: Parameter relies on NTSC type DV video */
654 		tmpsync = (u_int64_t)3072 * 8000 * 100 / 2997;
655 		tmpsync *= it->dvsync;
656 		dvsync = tmpsync;
657 		dvsync %= 0xc00;
658 		fp->mode.ld[2] = htonl(0x80000000 | (dvsync % 0xc00));
659 		it->dvsync ++;
660 		it->dvsync %= 2997;
661 
662 		for( i = 0, j = 0 ; i < it->dvpacket ; i++){
663 			bcopy(it->dvdma->buf + it->queued * it->psize,
664 				it->stproc->buf + j * it->psize, it->psize);
665 			fp = (struct fw_pkt *)(it->stproc->buf + j * it->psize);
666 			fp->mode.stream.len = htons(488);
667 			fp->mode.stream.chtag = chtag;
668 			fp->mode.stream.tcode = FWTCODE_STREAM;
669 			fp->mode.ld[1] = htonl((fc->nodeid << 24) | 0x00780000 | it->dvdbc);
670 			it->dvdbc++;
671 			it->dvdbc %= 256;
672 			it->queued ++;
673 			j++;
674 /* XXX: Parameter relies on NTSC type DV video */
675 #if 1
676 #define DVDIFF 203
677 #define DVFRAC 2997
678 #else
679 #define DVDIFF 127
680 #define DVFRAC 1875
681 #endif
682 			it->dvdiff += DVDIFF;
683 			if(it->dvdiff >= DVFRAC){
684 				it->dvdiff %= DVFRAC;
685 				fp = (struct fw_pkt *)(it->stproc->buf + j * it->psize);
686 
687 				fp->mode.stream.len = htons(0x8);
688 				fp->mode.stream.chtag = chtag;
689 				fp->mode.stream.tcode = FWTCODE_STREAM;
690 				fp->mode.ld[1] = htonl((fc->nodeid << 24) |
691 					 0x00780000 | it->dvdbc);
692 				j++;
693 			}
694 		}
695 		it->stproc->npacket = j;
696 		s = splfw();
697 		STAILQ_INSERT_TAIL(&it->stvalid, it->stproc, link);
698 		splx(s);
699 		if(it->queued >= it->dvpacket){
700 			s = splfw();
701 			STAILQ_INSERT_TAIL(&it->dvfree, it->dvdma, link);
702 			it->dvdma = NULL;
703 			splx(s);
704 			wakeup(it);
705 			goto dvloop;
706 		}
707 	}
708 	return err;
709 }
710 /*
711  * receving buffer update.
712  */
713 int
714 fw_rbuf_update(struct firewire_comm *fc, int sub, int flag){
715 	struct fw_bulkxfer *bulkxfer, *bulkxfer2 = NULL;
716 	struct fw_xferq *ir;
717 	int s, err = 0;
718 
719 	ir = fc->ir[sub];
720 	s = splfw();
721 	if(ir->stdma != NULL){
722 		if(flag != 0){
723 			STAILQ_INSERT_TAIL(&ir->stvalid, ir->stdma, link);
724 		}else{
725 			ir->stdma->flag = 0;
726 			STAILQ_INSERT_TAIL(&ir->stfree, ir->stdma, link);
727 		}
728 	}
729 	if(ir->stdma2 != NULL){
730 		bulkxfer = ir->stdma2;
731 		bulkxfer2 = STAILQ_FIRST(&ir->stfree);
732 		if(bulkxfer2 != NULL){
733 			STAILQ_REMOVE_HEAD(&ir->stfree, link);
734 		}
735 	}else{
736 		bulkxfer = STAILQ_FIRST(&ir->stfree);
737 		if(bulkxfer != NULL){
738 			STAILQ_REMOVE_HEAD(&ir->stfree, link);
739 			bulkxfer2 = STAILQ_FIRST(&ir->stfree);
740 			if(bulkxfer2 != NULL){
741 				STAILQ_REMOVE_HEAD(&ir->stfree, link);
742 			}
743 		}else{
744 			bulkxfer = STAILQ_FIRST(&ir->stvalid);
745 			STAILQ_REMOVE_HEAD(&ir->stvalid, link);
746 		}
747 	}
748 	splx(s);
749 	ir->stdma = bulkxfer;
750 	ir->stdma2 = bulkxfer2;
751 	return err;
752 }
753 /*
754  * ioctl support.
755  */
756 int
757 fw_ioctl (dev_t dev, u_long cmd, caddr_t data, int flag, fw_proc *td)
758 {
759 	struct firewire_softc *sc;
760 	int unit = DEV2UNIT(dev);
761 	int sub = DEV2DMACH(dev);
762 	int i, len, err = 0;
763 	struct fw_device *fwdev;
764 	struct fw_bind *fwb;
765 	struct fw_xferq *ir, *it;
766 	struct fw_xfer *xfer;
767 	struct fw_pkt *fp;
768 
769 	struct fw_devlstreq *fwdevlst = (struct fw_devlstreq *)data;
770 	struct fw_asyreq *asyreq = (struct fw_asyreq *)data;
771 	struct fw_isochreq *ichreq = (struct fw_isochreq *)data;
772 	struct fw_isobufreq *ibufreq = (struct fw_isobufreq *)data;
773 	struct fw_asybindreq *bindreq = (struct fw_asybindreq *)data;
774 #if 0
775 	struct fw_map_buf *map_buf = (struct fw_map_buf *)data;
776 #endif
777 	struct fw_crom_buf *crom_buf = (struct fw_crom_buf *)data;
778 
779 	if (DEV_FWMEM(dev))
780 		return fwmem_ioctl(dev, cmd, data, flag, td);
781 
782 	sc = devclass_get_softc(firewire_devclass, unit);
783 	if (!data)
784 		return(EINVAL);
785 
786 	switch (cmd) {
787 	case FW_STSTREAM:
788 		sc->fc->it[sub]->flag &= ~0xff;
789 		sc->fc->it[sub]->flag |= (0x3f & ichreq->ch);
790 		sc->fc->it[sub]->flag |= ((0x3 & ichreq->tag) << 6);
791 		err = 0;
792 		break;
793 	case FW_GTSTREAM:
794 		ichreq->ch = sc->fc->it[sub]->flag & 0x3f;
795 		ichreq->tag =(sc->fc->it[sub]->flag) >> 2 & 0x3;
796 		err = 0;
797 		break;
798 	case FW_SRSTREAM:
799 		sc->fc->ir[sub]->flag &= ~0xff;
800 		sc->fc->ir[sub]->flag |= (0x3f & ichreq->ch);
801 		sc->fc->ir[sub]->flag |= ((0x3 & ichreq->tag) << 6);
802 		err = sc->fc->irx_enable(sc->fc, sub);
803 		break;
804 	case FW_GRSTREAM:
805 		ichreq->ch = sc->fc->ir[sub]->flag & 0x3f;
806 		ichreq->tag =(sc->fc->ir[sub]->flag) >> 2 & 0x3;
807 		err = 0;
808 		break;
809 	case FW_SSTDV:
810 		ibufreq = (struct fw_isobufreq *)
811 			malloc(sizeof(struct fw_isobufreq), M_DEVBUF, M_NOWAIT);
812 		if(ibufreq == NULL){
813 			err = ENOMEM;
814 			break;
815 		}
816 #define FWDVPACKET 250
817 #define FWDVPMAX 512
818 		ibufreq->rx.nchunk = 8;
819 		ibufreq->rx.npacket = 50;
820 		ibufreq->rx.psize = FWDVPMAX;
821 
822 		ibufreq->tx.nchunk = 5;
823 		ibufreq->tx.npacket = 300;
824 		ibufreq->tx.psize = FWDVPMAX;
825 
826 		err = fw_ioctl(dev, FW_SSTBUF, (caddr_t)ibufreq, flag, td);
827 		sc->fc->it[sub]->dvpacket = FWDVPACKET;
828 		free(ibufreq, M_DEVBUF);
829 /* reserve a buffer space */
830 #define NDVCHUNK 8
831 		sc->fc->it[sub]->dvproc = NULL;
832 		sc->fc->it[sub]->dvdma = NULL;
833 		sc->fc->it[sub]->flag |= FWXFERQ_DV;
834 		sc->fc->it[sub]->dvbuf
835 			= (struct fw_dvbuf *)malloc(sizeof(struct fw_dvbuf) * NDVCHUNK, M_DEVBUF, M_DONTWAIT);
836 		STAILQ_INIT(&sc->fc->it[sub]->dvvalid);
837 		STAILQ_INIT(&sc->fc->it[sub]->dvfree);
838 		for( i = 0 ; i < NDVCHUNK ; i++){
839 			sc->fc->it[sub]->dvbuf[i].buf
840 				= malloc(FWDVPMAX * sc->fc->it[sub]->dvpacket, M_DEVBUF, M_DONTWAIT);
841 			STAILQ_INSERT_TAIL(&sc->fc->it[sub]->dvfree,
842 					&sc->fc->it[sub]->dvbuf[i], link);
843 		}
844 		break;
845 	case FW_SSTBUF:
846 		ir = sc->fc->ir[sub];
847 		it = sc->fc->it[sub];
848 
849 		if(ir->flag & FWXFERQ_RUNNING || it->flag & FWXFERQ_RUNNING){
850 			return(EBUSY);
851 		}
852 		if((ir->flag & FWXFERQ_EXTBUF) || (it->flag & FWXFERQ_EXTBUF)){
853 			return(EBUSY);
854 		}
855 		if((ibufreq->rx.nchunk *
856 			ibufreq->rx.psize * ibufreq->rx.npacket) +
857 		   (ibufreq->tx.nchunk *
858 			ibufreq->tx.psize * ibufreq->tx.npacket) <= 0){
859 				return(EINVAL);
860 		}
861 		if(ibufreq->rx.nchunk > FWSTMAXCHUNK ||
862 				ibufreq->tx.nchunk > FWSTMAXCHUNK){
863 			return(EINVAL);
864 		}
865 		ir->bulkxfer
866 			= (struct fw_bulkxfer *)malloc(sizeof(struct fw_bulkxfer) * ibufreq->rx.nchunk, M_DEVBUF, M_DONTWAIT);
867 		if(ir->bulkxfer == NULL){
868 			return(ENOMEM);
869 		}
870 		it->bulkxfer
871 			= (struct fw_bulkxfer *)malloc(sizeof(struct fw_bulkxfer) * ibufreq->tx.nchunk, M_DEVBUF, M_DONTWAIT);
872 		if(it->bulkxfer == NULL){
873 			return(ENOMEM);
874 		}
875 		ir->buf = malloc(
876 			ibufreq->rx.nchunk * ibufreq->rx.npacket
877 			* ((ibufreq->rx.psize + 3) &~3),
878 			M_DEVBUF, M_DONTWAIT);
879 		if(ir->buf == NULL){
880 			free(ir->bulkxfer, M_DEVBUF);
881 			free(it->bulkxfer, M_DEVBUF);
882 			ir->bulkxfer = NULL;
883 			it->bulkxfer = NULL;
884 			it->buf = NULL;
885 			return(ENOMEM);
886 		}
887 		it->buf = malloc(
888 			ibufreq->tx.nchunk * ibufreq->tx.npacket
889 			* ((ibufreq->tx.psize + 3) &~3),
890 			M_DEVBUF, M_DONTWAIT);
891 		if(it->buf == NULL){
892 			free(ir->bulkxfer, M_DEVBUF);
893 			free(it->bulkxfer, M_DEVBUF);
894 			free(ir->buf, M_DEVBUF);
895 			ir->bulkxfer = NULL;
896 			it->bulkxfer = NULL;
897 			it->buf = NULL;
898 			return(ENOMEM);
899 		}
900 
901 		ir->bnchunk = ibufreq->rx.nchunk;
902 		ir->bnpacket = ibufreq->rx.npacket;
903 		ir->btpacket = ibufreq->rx.npacket;
904 		ir->psize = (ibufreq->rx.psize + 3) & ~3;
905 		ir->queued = 0;
906 
907 		it->bnchunk = ibufreq->tx.nchunk;
908 		it->bnpacket = ibufreq->tx.npacket;
909 		it->btpacket = ibufreq->tx.npacket;
910 		it->psize = (ibufreq->tx.psize + 3) & ~3;
911 		ir->queued = 0;
912 		it->dvdbc = 0;
913 		it->dvdiff = 0;
914 		it->dvsync = 0;
915 
916 		STAILQ_INIT(&ir->stvalid);
917 		STAILQ_INIT(&ir->stfree);
918 		ir->stdma = NULL;
919 		ir->stdma2 = NULL;
920 		ir->stproc = NULL;
921 
922 		STAILQ_INIT(&it->stvalid);
923 		STAILQ_INIT(&it->stfree);
924 		it->stdma = NULL;
925 		it->stdma2 = NULL;
926 		it->stproc = NULL;
927 
928 		for(i = 0 ; i < sc->fc->ir[sub]->bnchunk; i++){
929 			ir->bulkxfer[i].buf =
930 				ir->buf +
931 				i * sc->fc->ir[sub]->bnpacket *
932 			  	sc->fc->ir[sub]->psize;
933 			ir->bulkxfer[i].flag = 0;
934 			STAILQ_INSERT_TAIL(&ir->stfree,
935 					&ir->bulkxfer[i], link);
936 			ir->bulkxfer[i].npacket = ir->bnpacket;
937 		}
938 		for(i = 0 ; i < sc->fc->it[sub]->bnchunk; i++){
939 			it->bulkxfer[i].buf =
940 				it->buf +
941 				i * sc->fc->it[sub]->bnpacket *
942 			  	sc->fc->it[sub]->psize;
943 			it->bulkxfer[i].flag = 0;
944 			STAILQ_INSERT_TAIL(&it->stfree,
945 					&it->bulkxfer[i], link);
946 			it->bulkxfer[i].npacket = it->bnpacket;
947 		}
948 		ir->flag &= ~FWXFERQ_MODEMASK;
949 		ir->flag |= FWXFERQ_STREAM;
950 		ir->flag |= FWXFERQ_EXTBUF;
951 
952 		it->flag &= ~FWXFERQ_MODEMASK;
953 		it->flag |= FWXFERQ_STREAM;
954 		it->flag |= FWXFERQ_EXTBUF;
955 		err = 0;
956 		break;
957 	case FW_GSTBUF:
958 		ibufreq->rx.nchunk = sc->fc->ir[sub]->bnchunk;
959 		ibufreq->rx.npacket = sc->fc->ir[sub]->bnpacket;
960 		ibufreq->rx.psize = sc->fc->ir[sub]->psize;
961 
962 		ibufreq->tx.nchunk = sc->fc->it[sub]->bnchunk;
963 		ibufreq->tx.npacket = sc->fc->it[sub]->bnpacket;
964 		ibufreq->tx.psize = sc->fc->it[sub]->psize;
965 		break;
966 	case FW_ASYREQ:
967 		xfer = fw_xfer_alloc();
968 		if(xfer == NULL){
969 			err = ENOMEM;
970 			return err;
971 		}
972 		fp = &asyreq->pkt;
973 		switch (asyreq->req.type) {
974 		case FWASREQNODE:
975 			xfer->dst = ntohs(fp->mode.hdr.dst);
976 			break;
977 		case FWASREQEUI:
978 			xfer->dst = fw_noderesolve(sc->fc, asyreq->req.dst.eui);
979 			if(xfer->dst == FWNODE_INVAL ){
980 				printf("%s:cannot found node\n",
981 					device_get_nameunit(sc->fc->dev));
982 				err = EINVAL;
983 				goto error;
984 			}
985 			fp->mode.hdr.dst = htons(FWLOCALBUS | xfer->dst);
986 			break;
987 		case FWASRESTL:
988 			/* XXX what's this? */
989 			break;
990 		case FWASREQSTREAM:
991 			/* nothing to do */
992 			break;
993 		}
994 		xfer->spd = asyreq->req.sped;
995 		xfer->send.len = asyreq->req.len;
996 		xfer->send.buf = malloc(xfer->send.len, M_DEVBUF, M_NOWAIT);
997 		if(xfer->send.buf == NULL){
998 			return ENOMEM;
999 		}
1000 		xfer->send.off = 0;
1001 		bcopy(fp, xfer->send.buf, xfer->send.len);
1002 		xfer->act.hand = fw_asy_callback;
1003 		err = fw_asyreq(sc->fc, sub, xfer);
1004 		if(err){
1005 			fw_xfer_free( xfer);
1006 			return err;
1007 		}
1008 		err = tsleep((caddr_t)xfer, FWPRI, "asyreq", hz);
1009 		if(err == 0){
1010 			if(asyreq->req.len >= xfer->recv.len){
1011 				asyreq->req.len = xfer->recv.len;
1012 			}else{
1013 				err = EINVAL;
1014 			}
1015 			bcopy(xfer->recv.buf + xfer->recv.off, fp, asyreq->req.len);
1016 		}
1017 error:
1018 		fw_xfer_free( xfer);
1019 		break;
1020 	case FW_IBUSRST:
1021 		sc->fc->ibr(sc->fc);
1022 		break;
1023 	case FW_CBINDADDR:
1024 		fwb = fw_bindlookup(sc->fc,
1025 				bindreq->start.hi, bindreq->start.lo);
1026 		if(fwb == NULL){
1027 			err = EINVAL;
1028 			break;
1029 		}
1030 		STAILQ_REMOVE(&sc->fc->binds, fwb, fw_bind, fclist);
1031 		STAILQ_REMOVE(&sc->fc->ir[sub]->binds, fwb, fw_bind, chlist);
1032 		free(fwb, M_DEVBUF);
1033 		break;
1034 	case FW_SBINDADDR:
1035 		if(bindreq->len <= 0 ){
1036 			err = EINVAL;
1037 			break;
1038 		}
1039 		if(bindreq->start.hi > 0xffff ){
1040 			err = EINVAL;
1041 			break;
1042 		}
1043 		fwb = (struct fw_bind *)malloc(sizeof (struct fw_bind), M_DEVBUF, M_DONTWAIT);
1044 		if(fwb == NULL){
1045 			err = ENOMEM;
1046 			break;
1047 		}
1048 		fwb->start_hi = bindreq->start.hi;
1049 		fwb->start_lo = bindreq->start.lo;
1050 		fwb->addrlen = bindreq->len;
1051 
1052 		xfer = fw_xfer_alloc();
1053 		if(xfer == NULL){
1054 			err = ENOMEM;
1055 			return err;
1056 		}
1057 		xfer->act_type = FWACT_CH;
1058 		xfer->sub = sub;
1059 		xfer->fc = sc->fc;
1060 
1061 		fwb->xfer = xfer;
1062 		err = fw_bindadd(sc->fc, fwb);
1063 		break;
1064 	case FW_GDEVLST:
1065 		i = 0;
1066 		for(fwdev = TAILQ_FIRST(&sc->fc->devices); fwdev != NULL;
1067 			fwdev = TAILQ_NEXT(fwdev, link)){
1068 			if(i < fwdevlst->n){
1069 				fwdevlst->dst[i] = fwdev->dst;
1070 				fwdevlst->status[i] =
1071 					(fwdev->status == FWDEVATTACHED)?1:0;
1072 				fwdevlst->eui[i].hi = fwdev->eui.hi;
1073 				fwdevlst->eui[i].lo = fwdev->eui.lo;
1074 			}
1075 			i++;
1076 		}
1077 		fwdevlst->n = i;
1078 		break;
1079 	case FW_GTPMAP:
1080 		bcopy(sc->fc->topology_map, data,
1081 				(sc->fc->topology_map->crc_len + 1) * 4);
1082 		break;
1083 	case FW_GSPMAP:
1084 		/* speed_map is larger than a page */
1085 		err = copyout(sc->fc->speed_map, *(void **)data,
1086 				(sc->fc->speed_map->crc_len + 1) * 4);
1087 		break;
1088 	case FW_GCROM:
1089 		for (fwdev = TAILQ_FIRST(&sc->fc->devices); fwdev != NULL;
1090 			fwdev = TAILQ_NEXT(fwdev, link)) {
1091 			if (fwdev->eui.hi == crom_buf->eui.hi &&
1092 					fwdev->eui.lo == crom_buf->eui.lo)
1093 				break;
1094 		}
1095 		if (fwdev == NULL) {
1096 			err = FWNODE_INVAL;
1097 			break;
1098 		}
1099 #if 0
1100 		if (fwdev->csrrom[0] >> 24 == 1)
1101 			len = 4;
1102 		else
1103 			len = (1 + ((fwdev->csrrom[0] >> 16) & 0xff)) * 4;
1104 #else
1105 		if (fwdev->rommax < CSRROMOFF)
1106 			len = 0;
1107 		else
1108 			len = fwdev->rommax - CSRROMOFF + 4;
1109 #endif
1110 		if (crom_buf->len < len)
1111 			len = crom_buf->len;
1112 		else
1113 			crom_buf->len = len;
1114 		err = copyout(&fwdev->csrrom[0], crom_buf->ptr, len);
1115 		break;
1116 	default:
1117 		sc->fc->ioctl (dev, cmd, data, flag, td);
1118 		break;
1119 	}
1120 	return err;
1121 }
1122 int
1123 fw_poll(dev_t dev, int events, fw_proc *td)
1124 {
1125 	int revents;
1126 	int tmp;
1127 	int unit = DEV2UNIT(dev);
1128 	int sub = DEV2DMACH(dev);
1129 	struct firewire_softc *sc;
1130 
1131 	if (DEV_FWMEM(dev))
1132 		return fwmem_poll(dev, events, td);
1133 
1134 	sc = devclass_get_softc(firewire_devclass, unit);
1135 	revents = 0;
1136 	tmp = POLLIN | POLLRDNORM;
1137 	if (events & tmp) {
1138 		if (STAILQ_FIRST(&sc->fc->ir[sub]->q) != NULL)
1139 			revents |= tmp;
1140 		else
1141 			selrecord(td, &sc->fc->ir[sub]->rsel);
1142 	}
1143 	tmp = POLLOUT | POLLWRNORM;
1144 	if (events & tmp) {
1145 		/* XXX should be fixed */
1146 		revents |= tmp;
1147 	}
1148 
1149 	return revents;
1150 }
1151 
1152 /*
1153  * To lookup node id. from EUI64.
1154  */
1155 u_int16_t fw_noderesolve(struct firewire_comm *fc, struct fw_eui64 eui)
1156 {
1157 	struct fw_device *fwdev;
1158 	for(fwdev = TAILQ_FIRST(&fc->devices); fwdev != NULL;
1159 		fwdev = TAILQ_NEXT(fwdev, link)){
1160 		if(fwdev->eui.hi == eui.hi && fwdev->eui.lo == eui.lo){
1161 			break;
1162 		}
1163 	}
1164 	if(fwdev == NULL) return FWNODE_INVAL;
1165 	if(fwdev->status != FWDEVATTACHED) return FWNODE_INVAL;
1166 	return fwdev->dst;
1167 }
1168 /*
1169  * Async. request procedure for userland application.
1170  */
1171 int
1172 fw_asyreq(struct firewire_comm *fc, int sub, struct fw_xfer *xfer)
1173 {
1174 	int err = 0;
1175 	struct fw_xferq *xferq;
1176 	int tl = 0, len;
1177 	struct fw_pkt *fp;
1178 	int tcode;
1179 	struct tcode_info *info;
1180 
1181 	if(xfer == NULL) return EINVAL;
1182 	if(xfer->send.len > fc->maxrec){
1183 		printf("send.len > maxrec\n");
1184 		return EINVAL;
1185 	}
1186 	if(xfer->act.hand == NULL){
1187 		printf("act.hand == NULL\n");
1188 		return EINVAL;
1189 	}
1190 	fp = (struct fw_pkt *)xfer->send.buf;
1191 
1192 #if 0
1193 	switch(fp->mode.common.tcode){
1194 	case FWTCODE_STREAM:
1195 		len = ntohs(fp->mode.stream.len) + 4;
1196 		break;
1197 	case FWTCODE_RREQQ:
1198 	case FWTCODE_WRES:
1199 	case FWTCODE_PHY:
1200 		len = 12;
1201 		break;
1202 	case FWTCODE_WREQQ:
1203 	case FWTCODE_RRESQ:
1204 		len = 16;
1205 		break;
1206 	default:
1207 		len = ntohs(fp->mode.rresb.len) + 16;
1208 		break;
1209 	}
1210 	if( len >  xfer->send.len ){
1211 		printf("len > send.len\n");
1212 		return EINVAL;
1213 	}
1214 	switch(fp->mode.common.tcode){
1215 	case FWTCODE_WREQQ:
1216 	case FWTCODE_WREQB:
1217 	case FWTCODE_RREQQ:
1218 	case FWTCODE_RREQB:
1219 	case FWTCODE_LREQ:
1220 	case FWTCODE_PHY:
1221 	case FWTCODE_STREAM:
1222 		xferq = fc->atq;
1223 		break;
1224 	case FWTCODE_WRES:
1225 	case FWTCODE_RRESQ:
1226 	case FWTCODE_RRESB:
1227 	case FWTCODE_LRES:
1228 		xferq = fc->ats;
1229 		break;
1230 	default:
1231 		return EINVAL;
1232 	}
1233 #else
1234 	tcode = fp->mode.common.tcode & 0xf;
1235 	info = &fc->tcode[tcode];
1236 	if (info->flag == 0) {
1237 		printf("invalid tcode=%d\n", tcode);
1238 		return EINVAL;
1239 	}
1240 	if (info->flag & FWTI_REQ)
1241 		xferq = fc->atq;
1242 	else
1243 		xferq = fc->ats;
1244 	len = info->hdr_len;
1245 	if (info->flag & FWTI_BLOCK_STR)
1246 		len += ntohs(fp->mode.stream.len);
1247 	else if (info->flag & FWTI_BLOCK_ASY)
1248 		len += ntohs(fp->mode.rresb.len);
1249 	if( len >  xfer->send.len ){
1250 		printf("len(%d) > send.len(%d) (tcode=%d)\n",
1251 				len, xfer->send.len, tcode);
1252 		return EINVAL;
1253 	}
1254 	xfer->send.len = len;
1255 #endif
1256 	if(xferq->start == NULL){
1257 		printf("xferq->start == NULL\n");
1258 		return EINVAL;
1259 	}
1260 	if(!(xferq->queued < xferq->maxq)){
1261 		printf("%s:Discard a packet (queued=%d)\n",
1262 			device_get_nameunit(fc->dev), xferq->queued);
1263 		return EINVAL;
1264 	}
1265 
1266 
1267 #if 0
1268 	switch(tcode){
1269 	case FWTCODE_WREQQ:
1270 	case FWTCODE_WREQB:
1271 	case FWTCODE_RREQQ:
1272 	case FWTCODE_RREQB:
1273 	case FWTCODE_LREQ:
1274 		if((tl = fw_get_tlabel(fc, xfer)) == -1 ){
1275 			return EIO;
1276 		}
1277 		fp->mode.hdr.tlrt = tl << 2;
1278 		break;
1279 	default:
1280 		break;
1281 	}
1282 #else
1283 	if (info->flag & FWTI_TLABEL) {
1284 		if((tl = fw_get_tlabel(fc, xfer)) == -1 )
1285 			return EIO;
1286 		fp->mode.hdr.tlrt = tl << 2;
1287 	}
1288 #endif
1289 
1290 	xfer->tl = tl;
1291 	xfer->tcode = tcode;
1292 	xfer->resp = 0;
1293 	xfer->fc = fc;
1294 	xfer->q = xferq;
1295 	xfer->act_type = FWACT_XFER;
1296 	xfer->retry_req = fw_asybusy;
1297 
1298 	fw_asystart(xfer);
1299 	return err;
1300 }
1301 /*
1302  * Wakeup blocked process.
1303  */
1304 void
1305 fw_asy_callback(struct fw_xfer *xfer){
1306 	wakeup(xfer);
1307 	return;
1308 }
1309 /*
1310  * Postpone to later retry.
1311  */
1312 void fw_asybusy(struct fw_xfer *xfer){
1313 #if 0
1314 	printf("fw_asybusy\n");
1315 #endif
1316 #if XFER_TIMEOUT
1317 	untimeout(fw_xfer_timeout, (void *)xfer, xfer->ch);
1318 #endif
1319 /*
1320 	xfer->ch =  timeout((timeout_t *)fw_asystart, (void *)xfer, 20000);
1321 */
1322 	DELAY(20000);
1323 	fw_asystart(xfer);
1324 	return;
1325 }
1326 #if XFER_TIMEOUT
1327 /*
1328  * Post timeout for async. request.
1329  */
1330 void
1331 fw_xfer_timeout(void *arg)
1332 {
1333 	int s;
1334 	struct fw_xfer *xfer;
1335 
1336 	xfer = (struct fw_xfer *)arg;
1337 	printf("fw_xfer_timeout status=%d resp=%d\n", xfer->state, xfer->resp);
1338 	/* XXX set error code */
1339 	s = splfw();
1340 	xfer->act.hand(xfer);
1341 	splx(s);
1342 }
1343 #endif
1344 /*
1345  * Async. request with given xfer structure.
1346  */
1347 static void fw_asystart(struct fw_xfer *xfer){
1348 	struct firewire_comm *fc = xfer->fc;
1349 	int s;
1350 	if(xfer->retry++ >= fc->max_asyretry){
1351 		xfer->resp = EBUSY;
1352 		xfer->state = FWXF_BUSY;
1353 		xfer->act.hand(xfer);
1354 		return;
1355 	}
1356 #if 0 /* XXX allow bus explore packets only after bus rest */
1357 	if (fc->status < FWBUSEXPLORE) {
1358 		xfer->resp = EAGAIN;
1359 		xfer->state = FWXF_BUSY;
1360 		if (xfer->act.hand != NULL)
1361 			xfer->act.hand(xfer);
1362 		return;
1363 	}
1364 #endif
1365 	s = splfw();
1366 	xfer->state = FWXF_INQ;
1367 	STAILQ_INSERT_TAIL(&xfer->q->q, xfer, link);
1368 	xfer->q->queued ++;
1369 	splx(s);
1370 	/* XXX just queue for mbuf */
1371 	if (xfer->mbuf == NULL)
1372 		xfer->q->start(fc);
1373 #if XFER_TIMEOUT
1374 	if (xfer->act.hand != NULL)
1375 		xfer->ch = timeout(fw_xfer_timeout, (void *)xfer, hz);
1376 #endif
1377 	return;
1378 }
1379 static int
1380 fw_mmap (dev_t dev, vm_offset_t offset, int nproto)
1381 {
1382 	struct firewire_softc *fc;
1383 	int unit = DEV2UNIT(dev);
1384 
1385 	if (DEV_FWMEM(dev))
1386 		return fwmem_mmap(dev, offset, nproto);
1387 
1388 	fc = devclass_get_softc(firewire_devclass, unit);
1389 
1390 	return EINVAL;
1391 }
1392 static int
1393 firewire_match( device_t dev )
1394 {
1395 	device_set_desc(dev, "IEEE1394(Firewire) bus");
1396 	return -140;
1397 }
1398 /*
1399  * The attach routine.
1400  */
1401 static int
1402 firewire_attach( device_t dev )
1403 {
1404 	int i, unitmask, mn;
1405 	struct firewire_softc *sc = device_get_softc(dev);
1406 	device_t pa = device_get_parent(dev);
1407 	struct firewire_comm *fc;
1408 	dev_t d;
1409 
1410 	fc = (struct firewire_comm *)device_get_softc(pa);
1411 	sc->fc = fc;
1412 	sc->fc->dev = dev;
1413 
1414 	unitmask = UNIT2MIN(device_get_unit(dev));
1415 
1416 	if( fc->nisodma > FWMAXNDMA) fc->nisodma = FWMAXNDMA;
1417 	for ( i = 0 ; i < fc->nisodma ; i++ ){
1418 		mn = unitmask | i;
1419 		/* XXX device name should be improved */
1420 		d = make_dev(&firewire_cdevsw, unit2minor(mn),
1421 			UID_ROOT, GID_OPERATOR, 0770,
1422 			"fw%x", mn);
1423 #if __FreeBSD_version >= 500000
1424 		if (i == 0)
1425 			sc->dev = d;
1426 		else
1427 			dev_depends(sc->dev, d);
1428 #else
1429 		sc->dev[i] = d;
1430 #endif
1431 	}
1432 	d = make_dev(&firewire_cdevsw, unit2minor(unitmask | FWMEM_FLAG),
1433 			UID_ROOT, GID_OPERATOR, 0770,
1434 			"fwmem%d", device_get_unit(dev));
1435 #if __FreeBSD_version >= 500000
1436 	dev_depends(sc->dev, d);
1437 #else
1438 	sc->dev[i] = d;
1439 #endif
1440 	printf("%s: firewire bus attach\n", device_get_nameunit(sc->fc->dev));
1441 	sc->fc->timeouthandle = timeout((timeout_t *)sc->fc->timeout, (void *)sc->fc, hz * 10);
1442 
1443 	/* Locate our children */
1444 	bus_generic_probe(dev);
1445 
1446 	/* launch attachement of the added children */
1447 	bus_generic_attach(dev);
1448 
1449 	/* bus_reset */
1450 	fc->ibr(fc);
1451 
1452 	return 0;
1453 }
1454 
1455 /*
1456  * Attach it as child.
1457  */
1458 static device_t
1459 firewire_add_child(device_t dev, int order, const char *name, int unit)
1460 {
1461         device_t child;
1462 	struct firewire_softc *sc;
1463 
1464 	sc = (struct firewire_softc *)device_get_softc(dev);
1465 	child = device_add_child(dev, name, unit);
1466 	if (child) {
1467 		device_set_ivars(child, sc->fc);
1468 		device_probe_and_attach(child);
1469 	}
1470 
1471 	return child;
1472 }
1473 /*
1474  * Dettach it.
1475  */
1476 static int
1477 firewire_detach( device_t dev )
1478 {
1479 	struct firewire_softc *sc;
1480 
1481 	sc = (struct firewire_softc *)device_get_softc(dev);
1482 #if 0
1483 	printf("%s:dettach prevented", device_get_nameunit(dev));
1484 	return(EINVAL);
1485 #endif
1486 #if __FreeBSD_version >= 500000
1487 	destroy_dev(sc->dev);
1488 #else
1489 	{
1490 		int j;
1491 		for (j = 0 ; j < sc->fc->nisodma + 1; j++)
1492 			destroy_dev(sc->dev[j]);
1493 	}
1494 #endif
1495 	/* XXX xfree_free and untimeout on all xfers */
1496 	untimeout((timeout_t *)sc->fc->timeout, sc->fc, sc->fc->timeouthandle);
1497 	free(sc->fc->topology_map, M_DEVBUF);
1498 	free(sc->fc->speed_map, M_DEVBUF);
1499 	bus_generic_detach(dev);
1500 	return(0);
1501 }
1502 #if 0
1503 static int
1504 firewire_shutdown( device_t dev )
1505 {
1506 	return 0;
1507 }
1508 #endif
1509 /*
1510  * Call ater bus reset.
1511  */
1512 void fw_busreset(struct firewire_comm *fc)
1513 {
1514 	int i;
1515 	struct fw_xfer *xfer;
1516 
1517 	switch(fc->status){
1518 	case FWBUSMGRELECT:
1519 		untimeout((timeout_t *)fw_try_bmr, (void *)fc, fc->bmrhandle);
1520 		break;
1521 	default:
1522 		break;
1523 	}
1524 	fc->status = FWBUSRESET;
1525 /* XXX: discard all queued packet */
1526 	while((xfer = STAILQ_FIRST(&fc->atq->q)) != NULL){
1527 		STAILQ_REMOVE_HEAD(&fc->atq->q, link);
1528 		xfer->resp = EAGAIN;
1529 		switch(xfer->act_type){
1530 		case FWACT_XFER:
1531 			fw_xfer_done(xfer);
1532 			break;
1533 		default:
1534 			break;
1535 		}
1536 		fw_xfer_free( xfer);
1537 	}
1538 	while((xfer = STAILQ_FIRST(&fc->ats->q)) != NULL){
1539 		STAILQ_REMOVE_HEAD(&fc->ats->q, link);
1540 		xfer->resp = EAGAIN;
1541 		switch(xfer->act_type){
1542 		case FWACT_XFER:
1543 			fw_xfer_done(xfer);
1544 		default:
1545 			break;
1546 		}
1547 		fw_xfer_free( xfer);
1548 	}
1549 	for(i = 0; i < fc->nisodma; i++)
1550 		while((xfer = STAILQ_FIRST(&fc->it[i]->q)) != NULL){
1551 			STAILQ_REMOVE_HEAD(&fc->it[i]->q, link);
1552 			xfer->resp = 0;
1553 			switch(xfer->act_type){
1554 			case FWACT_XFER:
1555 				fw_xfer_done(xfer);
1556 				break;
1557 			default:
1558 				break;
1559 			}
1560 			fw_xfer_free( xfer);
1561 		}
1562 
1563 	CSRARC(fc, STATE_CLEAR)
1564 			= 1 << 23 | 0 << 17 | 1 << 16 | 1 << 15 | 1 << 14 ;
1565 	CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
1566 	CSRARC(fc, NODE_IDS) = 0x3f;
1567 
1568 	CSRARC(fc, TOPO_MAP + 8) = 0;
1569 	fc->irm = -1;
1570 
1571 	fc->max_node = -1;
1572 
1573 	for(i = 2; i < 0x100/4 - 2 ; i++){
1574 		CSRARC(fc, SPED_MAP + i * 4) = 0;
1575 	}
1576 	CSRARC(fc, STATE_CLEAR) = 1 << 23 | 0 << 17 | 1 << 16 | 1 << 15 | 1 << 14 ;
1577 	CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
1578 	CSRARC(fc, RESET_START) = 0;
1579 	CSRARC(fc, SPLIT_TIMEOUT_HI) = 0;
1580 	CSRARC(fc, SPLIT_TIMEOUT_LO) = 800 << 19;
1581 	CSRARC(fc, CYCLE_TIME) = 0x0;
1582 	CSRARC(fc, BUS_TIME) = 0x0;
1583 	CSRARC(fc, BUS_MGR_ID) = 0x3f;
1584 	CSRARC(fc, BANDWIDTH_AV) = 4915;
1585 	CSRARC(fc, CHANNELS_AV_HI) = 0xffffffff;
1586 	CSRARC(fc, CHANNELS_AV_LO) = 0xffffffff;
1587 	CSRARC(fc, IP_CHANNELS) = (1 << 31);
1588 
1589 	CSRARC(fc, CONF_ROM) = 0x04 << 24;
1590 	CSRARC(fc, CONF_ROM + 4) = 0x31333934; /* means strings 1394 */
1591 	CSRARC(fc, CONF_ROM + 8) = 1 << 31 | 1 << 30 | 1 << 29 |
1592 				1 << 28 | 0xff << 16 | 0x09 << 8;
1593 	CSRARC(fc, CONF_ROM + 0xc) = 0;
1594 
1595 /* DV depend CSRs see blue book */
1596 	CSRARC(fc, oPCR) &= ~DV_BROADCAST_ON;
1597 	CSRARC(fc, iPCR) &= ~DV_BROADCAST_ON;
1598 
1599 	CSRARC(fc, STATE_CLEAR) &= ~(1 << 23 | 1 << 15 | 1 << 14 );
1600 	CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
1601 }
1602 /* Call once after reboot */
1603 void fw_init(fc)
1604 	struct firewire_comm *fc;
1605 {
1606 	int i;
1607 	struct fw_xfer *xfer;
1608 	struct fw_bind *fwb;
1609 	struct csrdir *csrd;
1610 
1611 	fc->max_asyretry = FW_MAXASYRTY;
1612 
1613 	fc->arq->queued = 0;
1614 	fc->ars->queued = 0;
1615 	fc->atq->queued = 0;
1616 	fc->ats->queued = 0;
1617 
1618 	fc->arq->psize = FWPMAX_S400;
1619 	fc->ars->psize = FWPMAX_S400;
1620 	fc->atq->psize = FWPMAX_S400;
1621 	fc->ats->psize = FWPMAX_S400;
1622 
1623 
1624 	fc->arq->buf = NULL;
1625 	fc->ars->buf = NULL;
1626 	fc->atq->buf = NULL;
1627 	fc->ats->buf = NULL;
1628 
1629 	fc->arq->flag = FWXFERQ_PACKET;
1630 	fc->ars->flag = FWXFERQ_PACKET;
1631 	fc->atq->flag = FWXFERQ_PACKET;
1632 	fc->ats->flag = FWXFERQ_PACKET;
1633 
1634 	STAILQ_INIT(&fc->atq->q);
1635 	STAILQ_INIT(&fc->ats->q);
1636 
1637 	for( i = 0 ; i < fc->nisodma ; i ++ ){
1638 		fc->it[i]->queued = 0;
1639 		fc->ir[i]->queued = 0;
1640 
1641 		fc->it[i]->start = NULL;
1642 		fc->ir[i]->start = NULL;
1643 
1644 		fc->it[i]->buf = NULL;
1645 		fc->ir[i]->buf = NULL;
1646 
1647 		fc->it[i]->flag = FWXFERQ_STREAM;
1648 		fc->ir[i]->flag = FWXFERQ_STREAM;
1649 
1650 		STAILQ_INIT(&fc->it[i]->q);
1651 		STAILQ_INIT(&fc->ir[i]->q);
1652 
1653 		STAILQ_INIT(&fc->it[i]->binds);
1654 		STAILQ_INIT(&fc->ir[i]->binds);
1655 	}
1656 
1657 	fc->arq->maxq = FWMAXQUEUE;
1658 	fc->ars->maxq = FWMAXQUEUE;
1659 	fc->atq->maxq = FWMAXQUEUE;
1660 	fc->ats->maxq = FWMAXQUEUE;
1661 
1662 	for( i = 0 ; i < fc->nisodma ; i++){
1663 		fc->ir[i]->maxq = FWMAXQUEUE;
1664 		fc->it[i]->maxq = FWMAXQUEUE;
1665 	}
1666 /* Initialize csr registers */
1667 	fc->topology_map = (struct fw_topology_map *)malloc(
1668 				sizeof(struct fw_topology_map),
1669 				M_DEVBUF, M_DONTWAIT | M_ZERO);
1670 	fc->speed_map = (struct fw_speed_map *)malloc(
1671 				sizeof(struct fw_speed_map),
1672 				M_DEVBUF, M_DONTWAIT | M_ZERO);
1673 	CSRARC(fc, TOPO_MAP) = 0x3f1 << 16;
1674 	CSRARC(fc, TOPO_MAP + 4) = 1;
1675 	CSRARC(fc, SPED_MAP) = 0x3f1 << 16;
1676 	CSRARC(fc, SPED_MAP + 4) = 1;
1677 
1678 	TAILQ_INIT(&fc->devices);
1679 	STAILQ_INIT(&fc->pending);
1680 
1681 /* Initialize csr ROM work space */
1682 	SLIST_INIT(&fc->ongocsr);
1683 	SLIST_INIT(&fc->csrfree);
1684 	for( i = 0 ; i < FWMAXCSRDIR ; i++){
1685 		csrd = (struct csrdir *) malloc(sizeof(struct csrdir), M_DEVBUF,M_DONTWAIT);
1686 		if(csrd == NULL) break;
1687 		SLIST_INSERT_HEAD(&fc->csrfree, csrd, link);
1688 	}
1689 
1690 /* Initialize Async handlers */
1691 	STAILQ_INIT(&fc->binds);
1692 	for( i = 0 ; i < 0x40 ; i++){
1693 		STAILQ_INIT(&fc->tlabels[i]);
1694 	}
1695 
1696 /* DV depend CSRs see blue book */
1697 #if 0
1698 	CSRARC(fc, oMPR) = 0x3fff0001; /* # output channel = 1 */
1699 	CSRARC(fc, oPCR) = 0x8000007a;
1700 	for(i = 4 ; i < 0x7c/4 ; i+=4){
1701 		CSRARC(fc, i + oPCR) = 0x8000007a;
1702 	}
1703 
1704 	CSRARC(fc, iMPR) = 0x00ff0001; /* # input channel = 1 */
1705 	CSRARC(fc, iPCR) = 0x803f0000;
1706 	for(i = 4 ; i < 0x7c/4 ; i+=4){
1707 		CSRARC(fc, i + iPCR) = 0x0;
1708 	}
1709 #endif
1710 
1711 
1712 	xfer = fw_xfer_alloc();
1713 	if(xfer == NULL) return;
1714 
1715 	fwb = (struct fw_bind *)malloc(sizeof (struct fw_bind), M_DEVBUF, M_DONTWAIT);
1716 	if(fwb == NULL){
1717 		fw_xfer_free(xfer);
1718 	}
1719 	xfer->act.hand = fw_vmaccess;
1720 	xfer->act_type = FWACT_XFER;
1721 	xfer->fc = fc;
1722 	xfer->sc = NULL;
1723 
1724 	fwb->start_hi = 0x2;
1725 	fwb->start_lo = 0;
1726 	fwb->addrlen = 0xffffffff;
1727 	fwb->xfer = xfer;
1728 	fw_bindadd(fc, fwb);
1729 }
1730 /*
1731  * To lookup binded process from IEEE1394 address.
1732  */
1733 static struct fw_bind *
1734 fw_bindlookup(fc, dest_hi, dest_lo)
1735 struct firewire_comm *fc;
1736 u_int32_t dest_lo, dest_hi;
1737 {
1738 	struct fw_bind *tfw;
1739 	for(tfw = STAILQ_FIRST(&fc->binds) ; tfw != NULL ;
1740 		tfw = STAILQ_NEXT(tfw, fclist)){
1741 		if(tfw->xfer->act_type != FWACT_NULL &&
1742 			tfw->start_hi == dest_hi &&
1743 			tfw->start_lo <= dest_lo &&
1744 			(tfw->start_lo + tfw->addrlen) > dest_lo){
1745 			return(tfw);
1746 		}
1747 	}
1748 	return(NULL);
1749 }
1750 /*
1751  * To bind IEEE1394 address block to process.
1752  */
1753 int fw_bindadd(struct firewire_comm *fc, struct fw_bind *fwb)
1754 {
1755 	struct fw_bind *tfw, *tfw2 = NULL;
1756 	int err = 0;
1757 	tfw = STAILQ_FIRST(&fc->binds);
1758 	if(tfw == NULL){
1759 		STAILQ_INSERT_HEAD(&fc->binds, fwb, fclist);
1760 		goto out;
1761 	}
1762 	if((tfw->start_hi > fwb->start_hi) ||
1763 		(tfw->start_hi == fwb->start_hi &&
1764 		(tfw->start_lo > (fwb->start_lo + fwb->addrlen)))){
1765 		STAILQ_INSERT_HEAD(&fc->binds, fwb, fclist);
1766 		goto out;
1767 	}
1768 	for(; tfw != NULL; tfw = STAILQ_NEXT(tfw, fclist)){
1769 		if((tfw->start_hi < fwb->start_hi) ||
1770 		   (tfw->start_hi == fwb->start_hi &&
1771 		    (tfw->start_lo + tfw->addrlen) < fwb->start_lo)){
1772 		   tfw2 = STAILQ_NEXT(tfw, fclist);
1773 			if(tfw2 == NULL)
1774 				break;
1775 			if((tfw2->start_hi > fwb->start_hi) ||
1776 			   (tfw2->start_hi == fwb->start_hi &&
1777 			    tfw2->start_lo > (fwb->start_lo + fwb->addrlen))){
1778 				break;
1779 			}else{
1780 				err = EBUSY;
1781 				goto out;
1782 			}
1783 		}
1784 	}
1785 	if(tfw != NULL){
1786 		STAILQ_INSERT_AFTER(&fc->binds, tfw, fwb, fclist);
1787 	}else{
1788 		STAILQ_INSERT_TAIL(&fc->binds, fwb, fclist);
1789 	}
1790 out:
1791 	if(!err && fwb->xfer->act_type == FWACT_CH){
1792 		STAILQ_INSERT_HEAD(&fc->ir[fwb->xfer->sub]->binds, fwb, chlist);
1793 	}
1794 	return err;
1795 }
1796 
1797 /*
1798  * To free IEEE1394 address block.
1799  */
1800 int fw_bindremove(struct firewire_comm *fc, struct fw_bind *fwb)
1801 {
1802 	int s;
1803 
1804 	s = splfw();
1805 	/* shall we check the existance? */
1806 	STAILQ_REMOVE(&fc->binds, fwb, fw_bind, fclist);
1807 	splx(s);
1808 	if (fwb->xfer)
1809 		fw_xfer_free(fwb->xfer);
1810 
1811 	return 0;
1812 }
1813 
1814 /*
1815  * To free transaction label.
1816  */
1817 static void fw_tl_free ( struct firewire_comm *fc, struct fw_xfer *xfer )
1818 {
1819 	struct tlabel *tl;
1820 	int s = splfw();
1821 
1822 	for( tl = STAILQ_FIRST(&fc->tlabels[xfer->tl]); tl != NULL;
1823 		tl = STAILQ_NEXT(tl, link)){
1824 		if(tl->xfer == xfer){
1825 			STAILQ_REMOVE(&fc->tlabels[xfer->tl], tl, tlabel, link);
1826 			free(tl, M_DEVBUF);
1827 			splx(s);
1828 			return;
1829 		}
1830 	}
1831 	splx(s);
1832 	return;
1833 }
1834 /*
1835  * To obtain XFER structure by transaction label.
1836  */
1837 static struct fw_xfer *fw_tl2xfer ( struct firewire_comm *fc, int node, int tlabel )
1838 {
1839 	struct fw_xfer *xfer;
1840 	struct tlabel *tl;
1841 	int s = splfw();
1842 
1843 	for( tl = STAILQ_FIRST(&fc->tlabels[tlabel]); tl != NULL;
1844 		tl = STAILQ_NEXT(tl, link)){
1845 		if(tl->xfer->dst == node){
1846 			xfer = tl->xfer;
1847 #if 0
1848 			STAILQ_REMOVE(&fc->tlabels[tlabel], tl, tlabel, link);
1849 			free(tl, M_DEVBUF);
1850 #endif
1851 			splx(s);
1852 			return(xfer);
1853 		}
1854 	}
1855 	splx(s);
1856 	return(NULL);
1857 }
1858 /*
1859  * To allocate IEEE1394 XFER structure.
1860  */
1861 struct fw_xfer *fw_xfer_alloc()
1862 {
1863 	struct fw_xfer *xfer;
1864 #if 0
1865 	xfer = malloc(sizeof(struct fw_xfer), M_DEVBUF, M_DONTWAIT);
1866 #else
1867 	xfer = malloc(sizeof(struct fw_xfer), M_DEVBUF, M_DONTWAIT | M_ZERO);
1868 #endif
1869 	if(xfer == NULL) return xfer;
1870 #if 0 /* xfer->tl = 0 was missing.. */
1871 	xfer->act_type = FWACT_NULL;
1872 	xfer->fc = NULL;
1873 	xfer->retry = 0;
1874 	xfer->resp = 0;
1875 	xfer->state = FWXF_INIT;
1876 	xfer->time = time_second;
1877 	xfer->sub = -1;
1878 	xfer->send.buf = NULL;
1879 	xfer->send.off = 0;
1880 	xfer->send.len = 0;
1881 	xfer->recv.buf = NULL;
1882 	xfer->recv.off = 0;
1883 	xfer->recv.len = 0;
1884 	xfer->retry_req = NULL;
1885 	xfer->act.hand = NULL;
1886 	xfer->sc = NULL;
1887 #else
1888 	xfer->time = time_second;
1889 	xfer->sub = -1;
1890 #endif
1891 	return xfer;
1892 }
1893 /*
1894  * IEEE1394 XFER post process.
1895  */
1896 void
1897 fw_xfer_done(struct fw_xfer *xfer)
1898 {
1899 	if (xfer->act.hand == NULL)
1900 		return;
1901 
1902 #if XFER_TIMEOUT
1903 	untimeout(fw_xfer_timeout, (void *)xfer, xfer->ch);
1904 #endif
1905 
1906 	if (xfer->fc->status != FWBUSRESET)
1907 		xfer->act.hand(xfer);
1908 	else {
1909 		printf("fw_xfer_done: pending\n");
1910 		if (xfer->fc != NULL)
1911 			STAILQ_INSERT_TAIL(&xfer->fc->pending, xfer, link);
1912 		else
1913 			panic("fw_xfer_done: why xfer->fc is NULL?");
1914 	}
1915 }
1916 
1917 /*
1918  * To free IEEE1394 XFER structure.
1919  */
1920 void fw_xfer_free( struct fw_xfer* xfer)
1921 {
1922 	int s;
1923 	if(xfer == NULL ) return;
1924 	if(xfer->state == FWXF_INQ){
1925 		printf("fw_xfer_free FWXF_INQ\n");
1926 		s = splfw();
1927 		STAILQ_REMOVE(&xfer->q->q, xfer, fw_xfer, link);
1928 		xfer->q->queued --;
1929 		splx(s);
1930 	}
1931 	if(xfer->fc != NULL){
1932 		if(xfer->state == FWXF_START){
1933 #if 0 /* this could happen if we call fwohci_arcv() before fwohci_txd() */
1934 			printf("fw_xfer_free FWXF_START\n");
1935 #endif
1936 			s = splfw();
1937 			xfer->q->drain(xfer->fc, xfer);
1938 			splx(s);
1939 		}
1940 	}
1941 	if(xfer->send.buf != NULL){
1942 		free(xfer->send.buf, M_DEVBUF);
1943 	}
1944 	if(xfer->recv.buf != NULL){
1945 		free(xfer->recv.buf, M_DEVBUF);
1946 	}
1947 	if(xfer->fc != NULL){
1948 		fw_tl_free(xfer->fc, xfer);
1949 	}
1950 	free(xfer, M_DEVBUF);
1951 }
1952 
1953 /*
1954  * Callback for PHY configuration.
1955  */
1956 static void
1957 fw_phy_config_callback(struct fw_xfer *xfer)
1958 {
1959 #if 0
1960 	printf("phy_config done state=%d resp=%d\n",
1961 				xfer->state, xfer->resp);
1962 #endif
1963 	fw_xfer_free(xfer);
1964 	/* XXX need bus reset ?? */
1965 	/* sc->fc->ibr(xfer->fc);  LOOP */
1966 }
1967 
1968 /*
1969  * To configure PHY.
1970  */
1971 static void
1972 fw_phy_config(struct firewire_comm *fc, int root_node, int gap_count)
1973 {
1974 	struct fw_xfer *xfer;
1975 	struct fw_pkt *fp;
1976 
1977 	fc->status = FWBUSPHYCONF;
1978 
1979 	DELAY(100000);
1980 	xfer = fw_xfer_alloc();
1981 	xfer->send.len = 12;
1982 	xfer->send.off = 0;
1983 	xfer->fc = fc;
1984 	xfer->retry_req = fw_asybusy;
1985 	xfer->act.hand = fw_phy_config_callback;
1986 
1987 	xfer->send.buf = malloc(sizeof(u_int32_t),
1988 					M_DEVBUF, M_DONTWAIT | M_ZERO);
1989 	fp = (struct fw_pkt *)xfer->send.buf;
1990 	fp->mode.ld[1] = 0;
1991 	if (root_node >= 0)
1992 		fp->mode.ld[1] |= htonl((root_node & 0x3f) << 24 | 1 << 23);
1993 	if (gap_count >= 0)
1994 		fp->mode.ld[1] |= htonl(1 << 22 | (gap_count & 0x3f) << 16);
1995 	fp->mode.ld[2] = ~fp->mode.ld[1];
1996 /* XXX Dangerous, how to pass PHY packet to device driver */
1997 	fp->mode.common.tcode |= FWTCODE_PHY;
1998 
1999 	printf("send phy_config root_node=%d gap_count=%d\n",
2000 						root_node, gap_count);
2001 	fw_asyreq(fc, -1, xfer);
2002 }
2003 
2004 #if 0
2005 /*
2006  * Dump self ID.
2007  */
2008 static void
2009 fw_print_sid(u_int32_t sid)
2010 {
2011 #if 0
2012 	printf("node:%d link:%d gap:%d spd:%d del:%d con:%d pwr:%d"
2013 		" p0:%d p1:%d p2:%d i:%d m:%d\n",
2014 		FWPHYSIDNODE(sid), FWPHYSIDLINK(sid), FWPHYSIDGAP(sid),
2015 		FWPHYSIDSPD(sid), FWPHYSIDDEL(sid), FWPHYSIDCON(sid),
2016 		FWPHYSIDPWR(sid), FWPHYSIDP0(sid), FWPHYSIDP1(sid),
2017 		FWPHYSIDP2(sid), FWPHYSIDIR(sid), FWPHYSIDMORE(sid));
2018 #else
2019 	union fw_self_id *s;
2020 	s = (union fw_self_id *) &sid;
2021 	printf("node:%d link:%d gap:%d spd:%d del:%d con:%d pwr:%d"
2022 		" p0:%d p1:%d p2:%d i:%d m:%d\n",
2023 		s->p0.phy_id, s->p0.link_active, s->p0.gap_count,
2024 		s->p0.phy_speed, s->p0.phy_delay, s->p0.contender,
2025 		s->p0.power_class, s->p0.port0, s->p0.port1,
2026 		s->p0.port2, s->p0.initiated_reset, s->p0.more_packets);
2027 #endif
2028 }
2029 #endif
2030 
2031 /*
2032  * To receive self ID.
2033  */
2034 void fw_sidrcv(struct firewire_comm* fc, caddr_t buf, u_int len, u_int off)
2035 {
2036 	u_int32_t *p, *sid = (u_int32_t *)(buf + off);
2037 	union fw_self_id *self_id;
2038 	u_int i, j, node, c_port = 0, i_branch = 0;
2039 
2040 	fc->sid_cnt = len /(sizeof(u_int32_t) * 2);
2041 	fc->status = FWBUSINIT;
2042 	fc->max_node = fc->nodeid & 0x3f;
2043 	CSRARC(fc, NODE_IDS) = ((u_int32_t)fc->nodeid) << 16;
2044 	fc->status = FWBUSCYMELECT;
2045 	fc->topology_map->crc_len = 2;
2046 	fc->topology_map->generation ++;
2047 	fc->topology_map->self_id_count = 0;
2048 	fc->topology_map->node_count = 0;
2049 	fc->speed_map->generation ++;
2050 	fc->speed_map->crc_len = 1 + (64*64 + 3) / 4;
2051 	self_id = &fc->topology_map->self_id[0];
2052 	for(i = 0; i < fc->sid_cnt; i ++){
2053 		if (sid[1] != ~sid[0]) {
2054 			printf("fw_sidrcv: invalid self-id packet\n");
2055 			sid += 2;
2056 			continue;
2057 		}
2058 		*self_id = *((union fw_self_id *)sid);
2059 		fc->topology_map->crc_len++;
2060 		if(self_id->p0.sequel == 0){
2061 			fc->topology_map->node_count ++;
2062 			c_port = 0;
2063 #if 0
2064 			fw_print_sid(sid[0]);
2065 #endif
2066 			node = self_id->p0.phy_id;
2067 			if(fc->max_node < node){
2068 				fc->max_node = self_id->p0.phy_id;
2069 			}
2070 			/* XXX I'm not sure this is the right speed_map */
2071 			fc->speed_map->speed[node][node]
2072 					= self_id->p0.phy_speed;
2073 			for (j = 0; j < node; j ++) {
2074 				fc->speed_map->speed[j][node]
2075 					= fc->speed_map->speed[node][j]
2076 					= min(fc->speed_map->speed[j][j],
2077 							self_id->p0.phy_speed);
2078 			}
2079 			if ((fc->irm == -1 || self_id->p0.phy_id > fc->irm) &&
2080 			  (self_id->p0.link_active && self_id->p0.contender)) {
2081 				fc->irm = self_id->p0.phy_id;
2082 			}
2083 			if(self_id->p0.port0 >= 0x2){
2084 				c_port++;
2085 			}
2086 			if(self_id->p0.port1 >= 0x2){
2087 				c_port++;
2088 			}
2089 			if(self_id->p0.port2 >= 0x2){
2090 				c_port++;
2091 			}
2092 		}
2093 		if(c_port > 2){
2094 			i_branch += (c_port - 2);
2095 		}
2096 		sid += 2;
2097 		self_id++;
2098 		fc->topology_map->self_id_count ++;
2099 	}
2100 	printf("%s: %d nodes", device_get_nameunit(fc->dev), fc->max_node + 1);
2101 	/* CRC */
2102 	fc->topology_map->crc = fw_crc16(
2103 			(u_int32_t *)&fc->topology_map->generation,
2104 			fc->topology_map->crc_len * 4);
2105 	fc->speed_map->crc = fw_crc16(
2106 			(u_int32_t *)&fc->speed_map->generation,
2107 			fc->speed_map->crc_len * 4);
2108 	/* byteswap and copy to CSR */
2109 	p = (u_int32_t *)fc->topology_map;
2110 	for (i = 0; i <= fc->topology_map->crc_len; i++)
2111 		CSRARC(fc, TOPO_MAP + i * 4) = htonl(*p++);
2112 	p = (u_int32_t *)fc->speed_map;
2113 	CSRARC(fc, SPED_MAP) = htonl(*p++);
2114 	CSRARC(fc, SPED_MAP + 4) = htonl(*p++);
2115 	/* don't byte-swap u_int8_t array */
2116 	bcopy(p, &CSRARC(fc, SPED_MAP + 8), (fc->speed_map->crc_len - 1)*4);
2117 
2118 	fc->max_hop = fc->max_node - i_branch;
2119 #if 1
2120 	printf(", maxhop <= %d", fc->max_hop);
2121 #endif
2122 
2123 	if(fc->irm == -1 ){
2124 		printf(", Not found IRM capable node");
2125 	}else{
2126 		printf(", cable IRM = %d", fc->irm);
2127 		if (fc->irm == fc->nodeid)
2128 			printf(" (me)\n");
2129 		else
2130 			printf("\n");
2131 	}
2132 
2133 	if((fc->irm != -1) && (CSRARC(fc, BUS_MGR_ID) == 0x3f) ){
2134 		if(fc->irm == ((CSRARC(fc, NODE_IDS) >> 16 ) & 0x3f)){
2135 			fc->status = FWBUSMGRDONE;
2136 			CSRARC(fc, BUS_MGR_ID) = fc->set_bmr(fc, fc->irm);
2137 		}else{
2138 			fc->status = FWBUSMGRELECT;
2139 			fc->bmrhandle = timeout((timeout_t *)fw_try_bmr,(void *)fc, hz / 8);
2140 		}
2141 	}else{
2142 		fc->status = FWBUSMGRDONE;
2143 		printf("%s: BMR = %x\n", device_get_nameunit(fc->dev), CSRARC(fc, BUS_MGR_ID));
2144 	}
2145 	free(buf, M_DEVBUF);
2146 #if 1
2147 	/* XXX optimize gap_count, if I am BMGR */
2148 	if(fc->irm == ((CSRARC(fc, NODE_IDS) >> 16 ) & 0x3f)){
2149 		fw_phy_config(fc, -1, gap_cnt[fc->max_hop]);
2150 	}
2151 #endif
2152 #if 1
2153 	timeout((timeout_t *)fw_bus_probe, (void *)fc, hz/4);
2154 #else
2155 	fw_bus_probe(fc);
2156 #endif
2157 }
2158 /*
2159  * To probe devices on the IEEE1394 bus.
2160  */
2161 static void fw_bus_probe(struct firewire_comm *fc)
2162 {
2163 	int s;
2164 	struct fw_device *fwdev, *next;
2165 
2166 	s = splfw();
2167 	fc->status = FWBUSEXPLORE;
2168 	fc->retry_count = 0;
2169 
2170 /*
2171  * Invalidate all devices, just after bus reset. Devices
2172  * to be removed has not been seen longer time.
2173  */
2174 	for(fwdev = TAILQ_FIRST(&fc->devices); fwdev != NULL; fwdev = next) {
2175 		next = TAILQ_NEXT(fwdev, link);
2176 		if(fwdev->status != FWDEVINVAL){
2177 			fwdev->status = FWDEVINVAL;
2178 			fwdev->rcnt = 0;
2179 		}else if(fwdev->rcnt < FW_MAXDEVRCNT){
2180 			fwdev->rcnt ++;
2181 		}else{
2182 			TAILQ_REMOVE(&fc->devices, fwdev, link);
2183 			free(fwdev, M_DEVBUF);
2184 		}
2185 	}
2186 	fc->ongonode = 0;
2187 	fc->ongoaddr = CSRROMOFF;
2188 	fc->ongodev = NULL;
2189 	fc->ongoeui.hi = 0xffffffff; fc->ongoeui.lo = 0xffffffff;
2190 	fw_bus_explore(fc);
2191 	splx(s);
2192 }
2193 /*
2194  * To collect device informations on the IEEE1394 bus.
2195  */
2196 static void fw_bus_explore(struct firewire_comm *fc )
2197 {
2198 	int err = 0;
2199 	struct fw_device *fwdev, *tfwdev;
2200 	u_int32_t addr;
2201 	struct fw_xfer *xfer;
2202 	struct fw_pkt *fp;
2203 
2204 	if(fc->status != FWBUSEXPLORE)
2205 		return;
2206 
2207 loop:
2208 	if(fc->ongonode == fc->nodeid) fc->ongonode++;
2209 
2210 	if(fc->ongonode > fc->max_node) goto done;
2211 	if(fc->ongonode >= 0x3f) goto done;
2212 
2213 	/* check link */
2214 	/* XXX we need to check phy_id first */
2215 	if (!fc->topology_map->self_id[fc->ongonode].p0.link_active) {
2216 		printf("fw_bus_explore: node %d link down\n", fc->ongonode);
2217 		fc->ongonode++;
2218 		goto loop;
2219 	}
2220 
2221 	if(fc->ongoaddr <= CSRROMOFF &&
2222 		fc->ongoeui.hi == 0xffffffff &&
2223 		fc->ongoeui.lo == 0xffffffff ){
2224 		fc->ongoaddr = CSRROMOFF;
2225 		addr = 0xf0000000 | fc->ongoaddr;
2226 	}else if(fc->ongoeui.hi == 0xffffffff ){
2227 		fc->ongoaddr = CSRROMOFF + 0xc;
2228 		addr = 0xf0000000 | fc->ongoaddr;
2229 	}else if(fc->ongoeui.lo == 0xffffffff ){
2230 		fc->ongoaddr = CSRROMOFF + 0x10;
2231 		addr = 0xf0000000 | fc->ongoaddr;
2232 	}else if(fc->ongodev == NULL){
2233 		for(fwdev = TAILQ_FIRST(&fc->devices); fwdev != NULL;
2234 			fwdev = TAILQ_NEXT(fwdev, link)){
2235 			if(fwdev->eui.hi == fc->ongoeui.hi && fwdev->eui.lo == fc->ongoeui.lo){
2236 				break;
2237 			}
2238 		}
2239 		if(fwdev != NULL){
2240 			fwdev->dst = fc->ongonode;
2241 			fwdev->status = FWDEVATTACHED;
2242 			fc->ongonode++;
2243 			fc->ongoaddr = CSRROMOFF;
2244 			fc->ongodev = NULL;
2245 			fc->ongoeui.hi = 0xffffffff; fc->ongoeui.lo = 0xffffffff;
2246 			goto loop;
2247 		}
2248 		fwdev = malloc(sizeof(struct fw_device), M_DEVBUF, M_DONTWAIT);
2249 		if(fwdev == NULL)
2250 			return;
2251 		fwdev->rommax = 0;
2252 		fwdev->dst = fc->ongonode;
2253 		fwdev->eui.hi = fc->ongoeui.hi; fwdev->eui.lo = fc->ongoeui.lo;
2254 		fwdev->status = FWDEVINIT;
2255 #if 0
2256 		fwdev->speed = CSRARC(fc, SPED_MAP + 8 + fc->ongonode / 4)
2257 			>> ((3 - (fc->ongonode % 4)) * 8);
2258 #else
2259 		fwdev->speed = fc->speed_map->speed[fc->nodeid][fc->ongonode];
2260 #endif
2261 
2262 #if 0
2263 		TAILQ_INSERT_TAIL(&fc->devices, fwdev, link);
2264 #else
2265 		tfwdev = TAILQ_FIRST(&fc->devices);
2266 		while( tfwdev != NULL &&
2267 			(tfwdev->eui.hi > fwdev->eui.hi) &&
2268 			((tfwdev->eui.hi == fwdev->eui.hi) &&
2269 				tfwdev->eui.lo > fwdev->eui.lo)){
2270 			tfwdev = TAILQ_NEXT( tfwdev, link);
2271 		}
2272 		if(tfwdev == NULL){
2273 			TAILQ_INSERT_TAIL(&fc->devices, fwdev, link);
2274 		}else{
2275 			TAILQ_INSERT_BEFORE(tfwdev, fwdev, link);
2276 		}
2277 #endif
2278 
2279 		printf("%s:Discover new %s device ID:%08x%08x\n", device_get_nameunit(fc->dev), linkspeed[fwdev->speed], fc->ongoeui.hi, fc->ongoeui.lo);
2280 
2281 		fc->ongodev = fwdev;
2282 		fc->ongoaddr = CSRROMOFF;
2283 		addr = 0xf0000000 | fc->ongoaddr;
2284 	}else{
2285 		addr = 0xf0000000 | fc->ongoaddr;
2286 	}
2287 #if 0
2288 	xfer = asyreqq(fc, FWSPD_S100, 0, 0,
2289 		((FWLOCALBUS | fc->ongonode) << 16) | 0xffff , addr,
2290 		fw_bus_explore_callback);
2291 	if(xfer == NULL) goto done;
2292 #else
2293 	xfer = fw_xfer_alloc();
2294 	if(xfer == NULL){
2295 		goto done;
2296 	}
2297 	xfer->send.len = 16;
2298 	xfer->spd = 0;
2299 	xfer->send.buf = malloc(16, M_DEVBUF, M_DONTWAIT);
2300 	if(xfer->send.buf == NULL){
2301 		fw_xfer_free( xfer);
2302 		return;
2303 	}
2304 
2305 	xfer->send.off = 0;
2306 	fp = (struct fw_pkt *)xfer->send.buf;
2307 	fp->mode.rreqq.dest_hi = htons(0xffff);
2308 	fp->mode.rreqq.tlrt = 0;
2309 	fp->mode.rreqq.tcode = FWTCODE_RREQQ;
2310 	fp->mode.rreqq.pri = 0;
2311 	fp->mode.rreqq.src = 0;
2312 	xfer->dst = FWLOCALBUS | fc->ongonode;
2313 	fp->mode.rreqq.dst = htons(xfer->dst);
2314 	fp->mode.rreqq.dest_lo = htonl(addr);
2315 	xfer->act.hand = fw_bus_explore_callback;
2316 
2317 	err = fw_asyreq(fc, -1, xfer);
2318 	if(err){
2319 		fw_xfer_free( xfer);
2320 		return;
2321 	}
2322 #endif
2323 	return;
2324 done:
2325 	/* fw_attach_devs */
2326 	fc->status = FWBUSEXPDONE;
2327 	printf("bus_explore done\n");
2328 	fw_attach_dev(fc);
2329 	return;
2330 
2331 }
2332 /* Portable Async. request read quad */
2333 struct fw_xfer *asyreqq(struct firewire_comm *fc,
2334 	u_int8_t spd, u_int8_t tl, u_int8_t rt,
2335 	u_int32_t addr_hi, u_int32_t addr_lo,
2336 	void (*hand) __P((struct fw_xfer*)))
2337 {
2338 	struct fw_xfer *xfer;
2339 	struct fw_pkt *fp;
2340 	int err;
2341 
2342 	xfer = fw_xfer_alloc();
2343 	if(xfer == NULL){
2344 		return NULL;
2345 	}
2346 	xfer->send.len = 16;
2347 	xfer->spd = spd; /* XXX:min(spd, fc->spd) */
2348 	xfer->send.buf = malloc(16, M_DEVBUF, M_DONTWAIT);
2349 	if(xfer->send.buf == NULL){
2350 		fw_xfer_free( xfer);
2351 		return NULL;
2352 	}
2353 
2354 	xfer->send.off = 0;
2355 	fp = (struct fw_pkt *)xfer->send.buf;
2356 	fp->mode.rreqq.dest_hi = htons(addr_hi & 0xffff);
2357 	if(tl & FWP_TL_VALID){
2358 		fp->mode.rreqq.tlrt = (tl & 0x3f) << 2;
2359 	}else{
2360 		fp->mode.rreqq.tlrt = 0;
2361 	}
2362 	fp->mode.rreqq.tlrt |= rt & 0x3;
2363 	fp->mode.rreqq.tcode = FWTCODE_RREQQ;
2364 	fp->mode.rreqq.pri = 0;
2365 	fp->mode.rreqq.src = 0;
2366 	xfer->dst = addr_hi >> 16;
2367 	fp->mode.rreqq.dst = htons(xfer->dst);
2368 	fp->mode.rreqq.dest_lo = htonl(addr_lo);
2369 	xfer->act.hand = hand;
2370 
2371 	err = fw_asyreq(fc, -1, xfer);
2372 	if(err){
2373 		fw_xfer_free( xfer);
2374 		return NULL;
2375 	}
2376 	return xfer;
2377 }
2378 /*
2379  * Callback for the IEEE1394 bus information collection.
2380  */
2381 static void fw_bus_explore_callback(struct fw_xfer *xfer){
2382 	struct firewire_comm *fc;
2383 	struct fw_pkt *sfp,*rfp;
2384 	struct csrhdr *chdr;
2385 	struct csrdir *csrd;
2386 	struct csrreg *csrreg;
2387 	u_int32_t offset;
2388 
2389 
2390 	if(xfer == NULL) return;
2391 	fc = xfer->fc;
2392 	if(xfer->resp != 0){
2393 		printf("resp != 0: node=%d addr=0x%x\n",
2394 			fc->ongonode, fc->ongoaddr);
2395 		fc->retry_count++;
2396 		goto nextnode;
2397 	}
2398 
2399 	if(xfer->send.buf == NULL){
2400 		printf("send.buf == NULL: node=%d addr=0x%x\n",
2401 			fc->ongonode, fc->ongoaddr);
2402 		printf("send.buf == NULL\n");
2403 		fc->retry_count++;
2404 		goto nextnode;
2405 	}
2406 	sfp = (struct fw_pkt *)xfer->send.buf;
2407 
2408 	if(xfer->recv.buf == NULL){
2409 		printf("recv.buf == NULL: node=%d addr=0x%x\n",
2410 			fc->ongonode, fc->ongoaddr);
2411 		fc->retry_count++;
2412 		goto nextnode;
2413 	}
2414 	rfp = (struct fw_pkt *)xfer->recv.buf;
2415 #if 0
2416 	{
2417 		u_int32_t *qld;
2418 		int i;
2419 		qld = (u_int32_t *)xfer->recv.buf;
2420 		printf("len:%d\n", xfer->recv.len);
2421 		for( i = 0 ; i <= xfer->recv.len && i < 32; i+= 4){
2422 			printf("0x%08x ", ntohl(rfp->mode.ld[i/4]));
2423 			if((i % 16) == 15) printf("\n");
2424 		}
2425 		if((i % 16) != 15) printf("\n");
2426 	}
2427 #endif
2428 	if(fc->ongodev == NULL){
2429 		if(sfp->mode.rreqq.dest_lo == htonl((0xf0000000 | CSRROMOFF))){
2430 			rfp->mode.rresq.data = ntohl(rfp->mode.rresq.data);
2431 			chdr = (struct csrhdr *)(&rfp->mode.rresq.data);
2432 /* If CSR is minimul confinguration, more investgation is not needed. */
2433 			if(chdr->info_len == 1){
2434 				goto nextnode;
2435 			}else{
2436 				fc->ongoaddr = CSRROMOFF + 0xc;
2437 			}
2438 		}else if(sfp->mode.rreqq.dest_lo == htonl((0xf0000000 |(CSRROMOFF + 0xc)))){
2439 			fc->ongoeui.hi = ntohl(rfp->mode.rresq.data);
2440 			fc->ongoaddr = CSRROMOFF + 0x10;
2441 		}else if(sfp->mode.rreqq.dest_lo == htonl((0xf0000000 |(CSRROMOFF + 0x10)))){
2442 			fc->ongoeui.lo = ntohl(rfp->mode.rresq.data);
2443 			if (fc->ongoeui.hi == 0 && fc->ongoeui.lo == 0)
2444 				goto nextnode;
2445 			fc->ongoaddr = CSRROMOFF;
2446 		}
2447 	}else{
2448 		fc->ongodev->csrrom[(fc->ongoaddr - CSRROMOFF)/4] = ntohl(rfp->mode.rresq.data);
2449 		if(fc->ongoaddr > fc->ongodev->rommax){
2450 			fc->ongodev->rommax = fc->ongoaddr;
2451 		}
2452 		csrd = SLIST_FIRST(&fc->ongocsr);
2453 		if((csrd = SLIST_FIRST(&fc->ongocsr)) == NULL){
2454 			chdr = (struct csrhdr *)(fc->ongodev->csrrom);
2455 			offset = CSRROMOFF;
2456 		}else{
2457 			chdr = (struct csrhdr *)&fc->ongodev->csrrom[(csrd->off - CSRROMOFF)/4];
2458 			offset = csrd->off;
2459 		}
2460 		if(fc->ongoaddr > (CSRROMOFF + 0x14) && fc->ongoaddr != offset){
2461 			csrreg = (struct csrreg *)&fc->ongodev->csrrom[(fc->ongoaddr - CSRROMOFF)/4];
2462 			if( csrreg->key == 0x81 || csrreg->key == 0xd1){
2463 				csrd = SLIST_FIRST(&fc->csrfree);
2464 				if(csrd == NULL){
2465 					goto nextnode;
2466 				}else{
2467 					csrd->ongoaddr = fc->ongoaddr;
2468 					fc->ongoaddr += csrreg->val * 4;
2469 					csrd->off = fc->ongoaddr;
2470 					SLIST_REMOVE_HEAD(&fc->csrfree, link);
2471 					SLIST_INSERT_HEAD(&fc->ongocsr, csrd, link);
2472 					goto nextaddr;
2473 				}
2474 			}
2475 		}
2476 		fc->ongoaddr += 4;
2477 		if(((fc->ongoaddr - offset)/4 > chdr->crc_len) &&
2478 				(fc->ongodev->rommax < 0x414)){
2479 			if(fc->ongodev->rommax <= 0x414){
2480 				csrd = SLIST_FIRST(&fc->csrfree);
2481 				if(csrd == NULL) goto nextnode;
2482 				csrd->off = fc->ongoaddr;
2483 				csrd->ongoaddr = fc->ongoaddr;
2484 				SLIST_REMOVE_HEAD(&fc->csrfree, link);
2485 				SLIST_INSERT_HEAD(&fc->ongocsr, csrd, link);
2486 			}
2487 			goto nextaddr;
2488 		}
2489 
2490 		while(((fc->ongoaddr - offset)/4 > chdr->crc_len)){
2491 			if(csrd == NULL){
2492 				goto nextnode;
2493 			};
2494 			fc->ongoaddr = csrd->ongoaddr + 4;
2495 			SLIST_REMOVE_HEAD(&fc->ongocsr, link);
2496 			SLIST_INSERT_HEAD(&fc->csrfree, csrd, link);
2497 			csrd = SLIST_FIRST(&fc->ongocsr);
2498 			if((csrd = SLIST_FIRST(&fc->ongocsr)) == NULL){
2499 				chdr = (struct csrhdr *)(fc->ongodev->csrrom);
2500 				offset = CSRROMOFF;
2501 			}else{
2502 				chdr = (struct csrhdr *)&(fc->ongodev->csrrom[(csrd->off - CSRROMOFF)/4]);
2503 				offset = csrd->off;
2504 			}
2505 		}
2506 		if((fc->ongoaddr - CSRROMOFF) > CSRROMSIZE){
2507 			goto nextnode;
2508 		}
2509 	}
2510 nextaddr:
2511 	fw_xfer_free( xfer);
2512 	fw_bus_explore(fc);
2513 	return;
2514 nextnode:
2515 	fw_xfer_free( xfer);
2516 	fc->ongonode++;
2517 /* housekeeping work space */
2518 	fc->ongoaddr = CSRROMOFF;
2519 	fc->ongodev = NULL;
2520 	fc->ongoeui.hi = 0xffffffff; fc->ongoeui.lo = 0xffffffff;
2521 	while((csrd = SLIST_FIRST(&fc->ongocsr)) != NULL){
2522 		SLIST_REMOVE_HEAD(&fc->ongocsr, link);
2523 		SLIST_INSERT_HEAD(&fc->csrfree, csrd, link);
2524 	}
2525 	fw_bus_explore(fc);
2526 	return;
2527 }
2528 /*
2529  * Async. write responce support for kernel internal use.
2530  */
2531 int fw_writeres(struct firewire_comm *fc, u_int32_t dst, u_int32_t tlrt){
2532 	int err = 0;
2533 	struct fw_xfer *xfer;
2534 	struct fw_pkt *fp;
2535 
2536 	xfer = fw_xfer_alloc();
2537 	if(xfer == NULL){
2538 		err = ENOMEM;
2539 		return err;
2540 	}
2541 	xfer->send.len = 12;
2542 	xfer->spd = 0;
2543 	xfer->send.buf = malloc(xfer->send.len, M_DEVBUF, M_NOWAIT);
2544 	if(xfer->send.buf == NULL){
2545 		return ENOMEM;
2546 	}
2547 	xfer->send.off = 0;
2548 	fp = (struct fw_pkt *)xfer->send.buf;
2549 
2550 	fp->mode.wres.tlrt = tlrt;
2551 	fp->mode.wres.tcode = FWTCODE_WRES;
2552 	fp->mode.wres.pri = 0;
2553 	fp->mode.wres.dst = htons(dst);
2554 
2555 	xfer->act.hand = fw_asy_callback;
2556 	err = fw_asyreq(fc, -1, xfer);
2557 	if(err){
2558 		fw_xfer_free( xfer);
2559 		return err;
2560 	}
2561 	err = tsleep((caddr_t)xfer, FWPRI, "asyreq", 0);
2562 	fw_xfer_free( xfer);
2563 
2564 	return err;
2565 }
2566 /*
2567  * Async. read responce block support for kernel internal use.
2568  */
2569 int fw_readresb(struct firewire_comm *fc, u_int32_t dst, u_int32_t tlrt, u_int32_t len, u_int32_t *buf){
2570 	int err = 0;
2571 	struct fw_xfer *xfer ;
2572 	struct fw_pkt *fp;
2573 
2574 	xfer = fw_xfer_alloc();
2575 	if(xfer == NULL){
2576 		err = ENOMEM;
2577 		return err;
2578 	}
2579 	xfer->send.len = sizeof(struct fw_pkt) + len;
2580 	xfer->spd = 0;
2581 	xfer->send.buf = malloc(sizeof(struct fw_pkt) + 1024, M_DEVBUF, M_DONTWAIT);
2582 	if(xfer->send.buf == NULL){
2583 		return ENOMEM;
2584 	}
2585 	xfer->send.off = 0;
2586 	fp = (struct fw_pkt *)xfer->send.buf;
2587 	fp->mode.rresb.tlrt = tlrt;
2588 	fp->mode.rresb.tcode = FWTCODE_RRESB;
2589 	fp->mode.rresb.pri = 0;
2590 	fp->mode.rresb.dst = htons(dst);
2591 	fp->mode.rresb.rtcode = 0;
2592 	fp->mode.rresb.extcode = 0;
2593 	fp->mode.rresb.len = htons(len);
2594 	bcopy(buf, fp->mode.rresb.payload, len);
2595 	xfer->act.hand = fw_asy_callback;
2596 	err = fw_asyreq(fc, -1, xfer);
2597 	if(err){
2598 		fw_xfer_free( xfer);
2599 		return err;
2600 	}
2601 	err = tsleep((caddr_t)xfer, FWPRI, "asyreq", 0);
2602 
2603 	fw_xfer_free( xfer);
2604 	return err;
2605 }
2606 /*
2607  * Async. write request block support for kernel internal use.
2608  */
2609 int fw_writereqb(struct firewire_comm *fc, u_int32_t addr_hi, u_int32_t addr_lo, u_int len, u_int32_t *buf){
2610 	int err = 0;
2611 	struct fw_xfer *xfer ;
2612 	struct fw_pkt *fp;
2613 
2614 	xfer = fw_xfer_alloc();
2615 	if(xfer == NULL){
2616 		err = ENOMEM;
2617 		return err;
2618 	}
2619 	xfer->send.len = sizeof(struct fw_pkt) + len;
2620 	xfer->spd = 0;
2621 	xfer->send.buf = malloc(sizeof(struct fw_pkt) + 1024, M_DEVBUF, M_DONTWAIT);
2622 	if(xfer->send.buf == NULL){
2623 		return ENOMEM;
2624 	}
2625 	xfer->send.off = 0;
2626 	fp = (struct fw_pkt *)xfer->send.buf;
2627 	fp->mode.wreqb.dest_hi = htonl(addr_hi & 0xffff);
2628 	fp->mode.wreqb.tlrt = 0;
2629 	fp->mode.wreqb.tcode = FWTCODE_WREQB;
2630 	fp->mode.wreqb.pri = 0;
2631 	fp->mode.wreqb.dst = htons(addr_hi >> 16);
2632 	fp->mode.wreqb.dest_lo = htonl(addr_lo);
2633 	fp->mode.wreqb.len = htons(len);
2634 	fp->mode.wreqb.extcode = 0;
2635 	bcopy(buf, fp->mode.wreqb.payload, len);
2636 	xfer->act.hand = fw_asy_callback;
2637 	err = fw_asyreq(fc, -1, xfer);
2638 	if(err){
2639 		fw_xfer_free( xfer);
2640 		return err;
2641 	}
2642 	err = tsleep((caddr_t)xfer, FWPRI, "asyreq", 0);
2643 
2644 	fw_xfer_free( xfer);
2645 	return err;
2646 }
2647 /*
2648  * Async. read request support for kernel internal use.
2649  */
2650 int fw_readreqq(struct firewire_comm *fc, u_int32_t addr_hi, u_int32_t addr_lo, u_int32_t *ret){
2651 	int err = 0;
2652 	struct fw_xfer *xfer ;
2653 	struct fw_pkt *fp, *rfp;
2654 
2655 	xfer = fw_xfer_alloc();
2656 	if(xfer == NULL){
2657 		err = ENOMEM;
2658 		return err;
2659 	}
2660 	xfer->send.len = 16;
2661 	xfer->spd = 0;
2662 	xfer->send.buf = malloc(16, M_DEVBUF, M_DONTWAIT);
2663 	if(xfer->send.buf == NULL){
2664 		return ENOMEM;
2665 	}
2666 	xfer->send.off = 0;
2667 	fp = (struct fw_pkt *)xfer->send.buf;
2668 	fp->mode.rreqq.dest_hi = htonl(addr_hi & 0xffff);
2669 	fp->mode.rreqq.tlrt = 0;
2670 	fp->mode.rreqq.tcode = FWTCODE_RREQQ;
2671 	fp->mode.rreqq.pri = 0;
2672 	xfer->dst = addr_hi >> 16;
2673 	fp->mode.rreqq.dst = htons(xfer->dst);
2674 	fp->mode.rreqq.dest_lo = htonl(addr_lo);
2675 	xfer->act.hand = fw_asy_callback;
2676 	err = fw_asyreq(fc, -1, xfer);
2677 	if(err){
2678 		fw_xfer_free( xfer);
2679 		return err;
2680 	}
2681 	err = tsleep((caddr_t)xfer, FWPRI, "asyreq", 0);
2682 
2683 	if(err == 0 && xfer->recv.buf != NULL){
2684 		rfp = (struct fw_pkt *)xfer->recv.buf;
2685 		*ret = ntohl(rfp->mode.rresq.data);
2686 	}
2687 	fw_xfer_free( xfer);
2688 	return err;
2689 }
2690 /*
2691  * To obtain CSR register values.
2692  */
2693 u_int32_t getcsrdata(struct fw_device *fwdev, u_int8_t key)
2694 {
2695 	int i;
2696 	struct csrhdr *chdr;
2697 	struct csrreg *creg;
2698 	chdr = (struct csrhdr *)&fwdev->csrrom[0];
2699 	for( i = chdr->info_len + 4; i <= fwdev->rommax - CSRROMOFF; i+=4){
2700 		creg = (struct csrreg *)&fwdev->csrrom[i/4];
2701 		if(creg->key == key){
2702 			return (u_int32_t)creg->val;
2703 		}
2704 	}
2705 	return 0;
2706 }
2707 /*
2708  * To attach sub-devices layer onto IEEE1394 bus.
2709  */
2710 static void fw_attach_dev(struct firewire_comm *fc)
2711 {
2712 	struct fw_device *fwdev;
2713 	struct fw_xfer *xfer;
2714 	int i, err;
2715 	device_t *devlistp;
2716 	int devcnt;
2717 	struct firewire_dev_comm *fdc;
2718 
2719 	for(fwdev = TAILQ_FIRST(&fc->devices); fwdev != NULL;
2720 			fwdev = TAILQ_NEXT(fwdev, link)){
2721 		if(fwdev->status == FWDEVINIT){
2722 			fwdev->spec = getcsrdata(fwdev, CSRKEY_SPEC);
2723 			if(fwdev->spec == 0)
2724 				continue;
2725 			fwdev->ver = getcsrdata(fwdev, CSRKEY_VER);
2726 			if(fwdev->ver == 0)
2727 				continue;
2728 			fwdev->maxrec = (fwdev->csrrom[2] >> 12) & 0xf;
2729 
2730 			switch(fwdev->spec){
2731 			case CSRVAL_ANSIT10:
2732 				switch(fwdev->ver){
2733 				case CSRVAL_T10SBP2:
2734 					printf("Device SBP-II");
2735 					break;
2736 				default:
2737 					break;
2738 				}
2739 				break;
2740 			case CSRVAL_1394TA:
2741 				switch(fwdev->ver){
2742 				case CSR_PROTAVC:
2743 					printf("Device AV/C");
2744 					break;
2745 				case CSR_PROTCAL:
2746 					printf("Device CAL");
2747 					break;
2748 				case CSR_PROTEHS:
2749 					printf("Device EHS");
2750 					break;
2751 				case CSR_PROTHAVI:
2752 					printf("Device HAVi");
2753 					break;
2754 				case CSR_PROTCAM104:
2755 					printf("Device 1394 Cam 1.04");
2756 					break;
2757 				case CSR_PROTCAM120:
2758 					printf("Device 1394 Cam 1.20");
2759 					break;
2760 				case CSR_PROTCAM130:
2761 					printf("Device 1394 Cam 1.30");
2762 					break;
2763 				case CSR_PROTDPP:
2764 					printf("Device 1394 Direct print");
2765 					break;
2766 				case CSR_PROTIICP:
2767 					printf("Device Industrial & Instrument");
2768 					break;
2769 				default:
2770 					printf("Device unkwon 1394TA");
2771 					break;
2772 				}
2773 				break;
2774 			default:
2775 				break;
2776 			}
2777 			fwdev->status = FWDEVATTACHED;
2778 			printf("\n");
2779 		}
2780 	}
2781 	err = device_get_children(fc->dev, &devlistp, &devcnt);
2782 	if( err != 0 )
2783 		return;
2784 	for( i = 0 ; i < devcnt ; i++){
2785 		if (device_get_state(devlistp[i]) >= DS_ATTACHED)  {
2786 			fdc = device_get_softc(devlistp[i]);
2787 			if (fdc->post_explore != NULL)
2788 				fdc->post_explore(fdc);
2789 		}
2790 	}
2791 	free(devlistp, M_TEMP);
2792 
2793 	/* call pending handlers */
2794 	i = 0;
2795 	while ((xfer = STAILQ_FIRST(&fc->pending))) {
2796 		STAILQ_REMOVE_HEAD(&fc->pending, link);
2797 		i++;
2798 		if (xfer->act.hand)
2799 			xfer->act.hand(xfer);
2800 	}
2801 	if (i > 0)
2802 		printf("fw_attach_dev: %d pending handlers called\n", i);
2803 	if (fc->retry_count > 0) {
2804 		printf("retry_count = %d\n", fc->retry_count);
2805 		fc->retry_probe_handle = timeout((timeout_t *)fc->ibr,
2806 							(void *)fc, hz*2);
2807 	}
2808 	return;
2809 }
2810 /*
2811  * To allocate uniq transaction label.
2812  */
2813 static int fw_get_tlabel(struct firewire_comm *fc, struct fw_xfer *xfer)
2814 {
2815 	u_int i;
2816 	struct tlabel *tl, *tmptl;
2817 	int s;
2818 	static u_int32_t label = 0;
2819 
2820 	s = splfw();
2821 	for( i = 0 ; i < 0x40 ; i ++){
2822 		label = (label + 1) & 0x3f;
2823 		for(tmptl = STAILQ_FIRST(&fc->tlabels[label]);
2824 			tmptl != NULL; tmptl = STAILQ_NEXT(tmptl, link)){
2825 			if(tmptl->xfer->dst == xfer->dst) break;
2826 		}
2827 		if(tmptl == NULL) {
2828 			tl = malloc(sizeof(struct tlabel),M_DEVBUF,M_DONTWAIT);
2829 			if (tl == NULL) {
2830 				splx(s);
2831 				return (-1);
2832 			}
2833 			tl->xfer = xfer;
2834 			STAILQ_INSERT_TAIL(&fc->tlabels[label], tl, link);
2835 			splx(s);
2836 			return(label);
2837 		}
2838 	}
2839 	splx(s);
2840 
2841 	printf("fw_get_tlabel: no free tlabel\n");
2842 	return(-1);
2843 }
2844 /*
2845  * Generic packet receving process.
2846  */
2847 void fw_rcv(struct firewire_comm* fc, caddr_t buf, u_int len, u_int sub, u_int off, u_int spd)
2848 {
2849 	struct fw_pkt *fp, *resfp;
2850 	struct fw_xfer *xfer;
2851 	struct fw_bind *bind;
2852 	struct firewire_softc *sc;
2853 	int s;
2854 #if 0
2855 	{
2856 		u_int32_t *qld;
2857 		int i;
2858 		qld = (u_int32_t *)buf;
2859 		printf("spd %d len:%d\n", spd, len);
2860 		for( i = 0 ; i <= len && i < 32; i+= 4){
2861 			printf("0x%08x ", ntohl(qld[i/4]));
2862 			if((i % 16) == 15) printf("\n");
2863 		}
2864 		if((i % 16) != 15) printf("\n");
2865 	}
2866 #endif
2867 	fp = (struct fw_pkt *)(buf + off);
2868 	switch(fp->mode.common.tcode){
2869 	case FWTCODE_WRES:
2870 	case FWTCODE_RRESQ:
2871 	case FWTCODE_RRESB:
2872 	case FWTCODE_LRES:
2873 		xfer = fw_tl2xfer(fc, ntohs(fp->mode.hdr.src),
2874 					fp->mode.hdr.tlrt >> 2);
2875 		if(xfer == NULL) {
2876 			printf("fw_rcv: unknown response "
2877 					"tcode=%d src=0x%x tl=%x rt=%d data=0x%x\n",
2878 					fp->mode.common.tcode,
2879 					ntohs(fp->mode.hdr.src),
2880 					fp->mode.hdr.tlrt >> 2,
2881 					fp->mode.hdr.tlrt & 3,
2882 					fp->mode.rresq.data);
2883 #if 1
2884 			printf("try ad-hoc work around!!\n");
2885 			xfer = fw_tl2xfer(fc, ntohs(fp->mode.hdr.src),
2886 					(fp->mode.hdr.tlrt >> 2)^3);
2887 			if (xfer == NULL) {
2888 				printf("no use...\n");
2889 				goto err;
2890 			}
2891 #else
2892 			goto err;
2893 #endif
2894 		}
2895 		switch(xfer->act_type){
2896 		case FWACT_XFER:
2897 			if((xfer->sub >= 0) &&
2898 				((fc->ir[xfer->sub]->flag & FWXFERQ_MODEMASK ) == 0)){
2899 				xfer->resp = EINVAL;
2900 				fw_xfer_done(xfer);
2901 				goto err;
2902 			}
2903 			xfer->recv.len = len;
2904 			xfer->recv.off = off;
2905 			xfer->recv.buf = buf;
2906 			xfer->resp = 0;
2907 			fw_xfer_done(xfer);
2908 			return;
2909 			break;
2910 		case FWACT_CH:
2911 		default:
2912 			goto err;
2913 			break;
2914 		}
2915 		break;
2916 	case FWTCODE_WREQQ:
2917 	case FWTCODE_WREQB:
2918 	case FWTCODE_RREQQ:
2919 	case FWTCODE_RREQB:
2920 	case FWTCODE_LREQ:
2921 		bind = fw_bindlookup(fc, ntohs(fp->mode.rreqq.dest_hi),
2922 			ntohl(fp->mode.rreqq.dest_lo));
2923 		if(bind == NULL){
2924 			printf("Unknown service addr 0x%08x:0x%08x tcode=%x\n",
2925 				ntohs(fp->mode.rreqq.dest_hi),
2926 				ntohl(fp->mode.rreqq.dest_lo),
2927 				fp->mode.common.tcode);
2928 			if (fc->status == FWBUSRESET) {
2929 				printf("fw_rcv: cannot response(bus reset)!\n");
2930 				goto err;
2931 			}
2932 			xfer = fw_xfer_alloc();
2933 			if(xfer == NULL){
2934 				return;
2935 			}
2936 			xfer->spd = spd;
2937 			xfer->send.buf = malloc(16, M_DEVBUF, M_DONTWAIT);
2938 			resfp = (struct fw_pkt *)xfer->send.buf;
2939 			switch(fp->mode.common.tcode){
2940 			case FWTCODE_WREQQ:
2941 			case FWTCODE_WREQB:
2942 				resfp->mode.hdr.tcode = FWTCODE_WRES;
2943 				xfer->send.len = 12;
2944 				break;
2945 			case FWTCODE_RREQQ:
2946 				resfp->mode.hdr.tcode = FWTCODE_RRESQ;
2947 				xfer->send.len = 16;
2948 				break;
2949 			case FWTCODE_RREQB:
2950 				resfp->mode.hdr.tcode = FWTCODE_RRESB;
2951 				xfer->send.len = 16;
2952 				break;
2953 			case FWTCODE_LREQ:
2954 				resfp->mode.hdr.tcode = FWTCODE_LRES;
2955 				xfer->send.len = 16;
2956 				break;
2957 			}
2958 			resfp->mode.hdr.dst = fp->mode.hdr.src;
2959 			resfp->mode.hdr.tlrt = fp->mode.hdr.tlrt;
2960 			resfp->mode.hdr.pri = fp->mode.hdr.pri;
2961 			resfp->mode.rresb.rtcode = 7;
2962 			resfp->mode.rresb.extcode = 0;
2963 			resfp->mode.rresb.len = 0;
2964 /*
2965 			xfer->act.hand = fw_asy_callback;
2966 */
2967 			xfer->act.hand = fw_xfer_free;
2968 			if(fw_asyreq(fc, -1, xfer)){
2969 				fw_xfer_free( xfer);
2970 				return;
2971 			}
2972 			goto err;
2973 		}
2974 		switch(bind->xfer->act_type){
2975 		case FWACT_XFER:
2976 			xfer = fw_xfer_alloc();
2977 			if(xfer == NULL) goto err;
2978 			xfer->fc = bind->xfer->fc;
2979 			xfer->sc = bind->xfer->sc;
2980 			xfer->recv.buf = buf;
2981 			xfer->recv.len = len;
2982 			xfer->recv.off = off;
2983 			xfer->spd = spd;
2984 			xfer->act.hand = bind->xfer->act.hand;
2985 			if (fc->status != FWBUSRESET)
2986 				xfer->act.hand(xfer);
2987 			else
2988 				STAILQ_INSERT_TAIL(&fc->pending, xfer, link);
2989 			return;
2990 			break;
2991 		case FWACT_CH:
2992 			if(fc->ir[bind->xfer->sub]->queued >=
2993 				fc->ir[bind->xfer->sub]->maxq){
2994 				printf("%s:Discard a packet %x %d\n",
2995 					device_get_nameunit(fc->dev),
2996 					bind->xfer->sub,
2997 					fc->ir[bind->xfer->sub]->queued);
2998 				goto err;
2999 			}
3000 			xfer = fw_xfer_alloc();
3001 			if(xfer == NULL) goto err;
3002 			xfer->recv.buf = buf;
3003 			xfer->recv.len = len;
3004 			xfer->recv.off = off;
3005 			xfer->spd = spd;
3006 			s = splfw();
3007 			fc->ir[bind->xfer->sub]->queued++;
3008 			STAILQ_INSERT_TAIL(&fc->ir[bind->xfer->sub]->q, xfer, link);
3009 			splx(s);
3010 
3011 			wakeup((caddr_t)fc->ir[bind->xfer->sub]);
3012 
3013 			return;
3014 			break;
3015 		default:
3016 			goto err;
3017 			break;
3018 		}
3019 		break;
3020 	case FWTCODE_STREAM:
3021 	{
3022 		struct fw_xferq *xferq;
3023 
3024 		xferq = fc->ir[sub];
3025 #if 0
3026 		printf("stream rcv dma %d len %d off %d spd %d\n",
3027 			sub, len, off, spd);
3028 #endif
3029 		if(xferq->queued >= xferq->maxq) {
3030 			printf("receive queue is full\n");
3031 			goto err;
3032 		}
3033 		xfer = fw_xfer_alloc();
3034 		if(xfer == NULL) goto err;
3035 		xfer->recv.buf = buf;
3036 		xfer->recv.len = len;
3037 		xfer->recv.off = off;
3038 		xfer->spd = spd;
3039 		s = splfw();
3040 		xferq->queued++;
3041 		STAILQ_INSERT_TAIL(&xferq->q, xfer, link);
3042 		splx(s);
3043 		sc = device_get_softc(fc->bdev);
3044 #if __FreeBSD_version >= 500000
3045 		if (SEL_WAITING(&xferq->rsel))
3046 #else
3047 		if (&xferq->rsel.si_pid != 0)
3048 #endif
3049 			selwakeup(&xferq->rsel);
3050 		if (xferq->flag & FWXFERQ_WAKEUP) {
3051 			xferq->flag &= ~FWXFERQ_WAKEUP;
3052 			wakeup((caddr_t)xferq);
3053 		}
3054 		if (xferq->flag & FWXFERQ_HANDLER) {
3055 			xferq->hand(xferq);
3056 		}
3057 		return;
3058 		break;
3059 	}
3060 	default:
3061 		printf("fw_rcv: unknow tcode\n");
3062 		break;
3063 	}
3064 err:
3065 	free(buf, M_DEVBUF);
3066 }
3067 /*
3068  * Post process for Bus Manager election process.
3069  */
3070 static void
3071 fw_try_bmr_callback(struct fw_xfer *xfer)
3072 {
3073 	struct fw_pkt *sfp,*rfp;
3074 	struct firewire_comm *fc;
3075 
3076 	if(xfer == NULL) return;
3077 	fc = xfer->fc;
3078 	if(xfer->resp != 0){
3079 		goto error;
3080 	}
3081 
3082 	if(xfer->send.buf == NULL){
3083 		goto error;
3084 	}
3085 	sfp = (struct fw_pkt *)xfer->send.buf;
3086 
3087 	if(xfer->recv.buf == NULL){
3088 		goto error;
3089 	}
3090 	rfp = (struct fw_pkt *)xfer->recv.buf;
3091 	CSRARC(fc, BUS_MGR_ID)
3092 		= fc->set_bmr(fc, ntohl(rfp->mode.lres.payload[0]) & 0x3f);
3093 	printf("%s: new bus manager %d ",
3094 		device_get_nameunit(fc->dev), CSRARC(fc, BUS_MGR_ID));
3095 	if((htonl(rfp->mode.lres.payload[0]) & 0x3f) == fc->nodeid){
3096 		printf("(me)\n");
3097 /* If I am bus manager, optimize gapcount */
3098 		if(fc->max_hop <= MAX_GAPHOP ){
3099 			fw_phy_config(fc, -1, gap_cnt[fc->max_hop]);
3100 		}
3101 	}else{
3102 		printf("\n");
3103 	}
3104 error:
3105 	fw_xfer_free(xfer);
3106 }
3107 /*
3108  * To candidate Bus Manager election process.
3109  */
3110 void fw_try_bmr(void *arg)
3111 {
3112 	struct fw_xfer *xfer;
3113 	struct firewire_comm *fc = (struct firewire_comm *)arg;
3114 	struct fw_pkt *fp;
3115 	int err = 0;
3116 
3117 	xfer = fw_xfer_alloc();
3118 	if(xfer == NULL){
3119 		return;
3120 	}
3121 	xfer->send.len = 24;
3122 	xfer->spd = 0;
3123 	xfer->send.buf = malloc(24, M_DEVBUF, M_DONTWAIT);
3124 	if(xfer->send.buf == NULL){
3125 		fw_xfer_free( xfer);
3126 		return;
3127 	}
3128 
3129 	fc->status = FWBUSMGRELECT;
3130 
3131 	xfer->send.off = 0;
3132 	fp = (struct fw_pkt *)xfer->send.buf;
3133 	fp->mode.lreq.dest_hi = htons(0xffff);
3134 	fp->mode.lreq.tlrt = 0;
3135 	fp->mode.lreq.tcode = FWTCODE_LREQ;
3136 	fp->mode.lreq.pri = 0;
3137 	fp->mode.lreq.src = 0;
3138 	fp->mode.lreq.len = htons(8);
3139 	fp->mode.lreq.extcode = htons(FW_LREQ_CMPSWAP);
3140 	xfer->dst = FWLOCALBUS | fc->irm;
3141 	fp->mode.lreq.dst = htons(xfer->dst);
3142 	fp->mode.lreq.dest_lo = htonl(0xf0000000 | BUS_MGR_ID);
3143 	fp->mode.lreq.payload[0] = 0x3f;
3144 	fp->mode.lreq.payload[1] = fc->nodeid;
3145 	xfer->act_type = FWACT_XFER;
3146 	xfer->act.hand = fw_try_bmr_callback;
3147 
3148 	err = fw_asyreq(fc, -1, xfer);
3149 	if(err){
3150 		fw_xfer_free( xfer);
3151 		return;
3152 	}
3153 	return;
3154 }
3155 /*
3156  * Software implementation for physical memory block access.
3157  * XXX:Too slow, usef for debug purpose only.
3158  */
3159 static void fw_vmaccess(struct fw_xfer *xfer){
3160 	struct fw_pkt *rfp, *sfp = NULL;
3161 	u_int32_t *ld = (u_int32_t *)(xfer->recv.buf + xfer->recv.off);
3162 
3163 	printf("vmaccess spd:%2x len:%03x %d data:%08x %08x %08x %08x\n",
3164 			xfer->spd, xfer->recv.len, xfer->recv.off, ntohl(ld[0]), ntohl(ld[1]), ntohl(ld[2]), ntohl(ld[3]));
3165 	printf("vmaccess          data:%08x %08x %08x %08x\n", ntohl(ld[4]), ntohl(ld[5]), ntohl(ld[6]), ntohl(ld[7]));
3166 	if(xfer->resp != 0){
3167 		fw_xfer_free( xfer);
3168 		return;
3169 	}
3170 	if(xfer->recv.buf == NULL){
3171 		fw_xfer_free( xfer);
3172 		return;
3173 	}
3174 	rfp = (struct fw_pkt *)xfer->recv.buf;
3175 	switch(rfp->mode.hdr.tcode){
3176 		/* XXX need fix for 64bit arch */
3177 		case FWTCODE_WREQB:
3178 			xfer->send.buf = malloc(12, M_DEVBUF, M_NOWAIT);
3179 			xfer->send.len = 12;
3180 			sfp = (struct fw_pkt *)xfer->send.buf;
3181 			bcopy(rfp->mode.wreqb.payload,
3182 				(caddr_t)ntohl(rfp->mode.wreqb.dest_lo), ntohs(rfp->mode.wreqb.len));
3183 			sfp->mode.wres.tcode = FWTCODE_WRES;
3184 			sfp->mode.wres.rtcode = 0;
3185 			break;
3186 		case FWTCODE_WREQQ:
3187 			xfer->send.buf = malloc(12, M_DEVBUF, M_NOWAIT);
3188 			xfer->send.len = 12;
3189 			sfp->mode.wres.tcode = FWTCODE_WRES;
3190 			*((u_int32_t *)(ntohl(rfp->mode.wreqb.dest_lo))) = rfp->mode.wreqq.data;
3191 			sfp->mode.wres.rtcode = 0;
3192 			break;
3193 		case FWTCODE_RREQB:
3194 			xfer->send.buf = malloc(16 + rfp->mode.rreqb.len, M_DEVBUF, M_NOWAIT);
3195 			xfer->send.len = 16 + ntohs(rfp->mode.rreqb.len);
3196 			sfp = (struct fw_pkt *)xfer->send.buf;
3197 			bcopy((caddr_t)ntohl(rfp->mode.rreqb.dest_lo),
3198 				sfp->mode.rresb.payload, (u_int16_t)ntohs(rfp->mode.rreqb.len));
3199 			sfp->mode.rresb.tcode = FWTCODE_RRESB;
3200 			sfp->mode.rresb.len = rfp->mode.rreqb.len;
3201 			sfp->mode.rresb.rtcode = 0;
3202 			sfp->mode.rresb.extcode = 0;
3203 			break;
3204 		case FWTCODE_RREQQ:
3205 			xfer->send.buf = malloc(16, M_DEVBUF, M_NOWAIT);
3206 			xfer->send.len = 16;
3207 			sfp = (struct fw_pkt *)xfer->send.buf;
3208 			sfp->mode.rresq.data = *(u_int32_t *)(ntohl(rfp->mode.rreqq.dest_lo));
3209 			sfp->mode.wres.tcode = FWTCODE_RRESQ;
3210 			sfp->mode.rresb.rtcode = 0;
3211 			break;
3212 		default:
3213 			fw_xfer_free( xfer);
3214 			return;
3215 	}
3216 	xfer->send.off = 0;
3217 	sfp->mode.hdr.dst = rfp->mode.hdr.src;
3218 	xfer->dst = ntohs(rfp->mode.hdr.src);
3219 	xfer->act.hand = fw_xfer_free;
3220 	xfer->retry_req = fw_asybusy;
3221 
3222 	sfp->mode.hdr.tlrt = rfp->mode.hdr.tlrt;
3223 	sfp->mode.hdr.pri = 0;
3224 
3225 	fw_asyreq(xfer->fc, -1, xfer);
3226 /**/
3227 	return;
3228 }
3229 /*
3230  * CRC16 check-sum for IEEE1394 register blocks.
3231  */
3232 u_int16_t fw_crc16(u_int32_t *ptr, u_int32_t len){
3233 	u_int32_t i, sum, crc = 0;
3234 	int shift;
3235 	len = (len + 3) & ~3;
3236 	for(i = 0 ; i < len ; i+= 4){
3237 		for( shift = 28 ; shift >= 0 ; shift -= 4){
3238 			sum = ((crc >> 12) ^ (ptr[i/4] >> shift)) & 0xf;
3239 			crc = (crc << 4) ^ ( sum << 12 ) ^ ( sum << 5) ^ sum;
3240 		}
3241 		crc &= 0xffff;
3242 	}
3243 	return((u_int16_t) crc);
3244 }
3245 DRIVER_MODULE(firewire,fwohci,firewire_driver,firewire_devclass,0,0);
3246 MODULE_VERSION(firewire, 1);
3247