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