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