firewire.c revision 110193
11573Srgrimes/*
21573Srgrimes * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
31573Srgrimes * All rights reserved.
41573Srgrimes *
51573Srgrimes * Redistribution and use in source and binary forms, with or without
61573Srgrimes * modification, are permitted provided that the following conditions
71573Srgrimes * are met:
81573Srgrimes * 1. Redistributions of source code must retain the above copyright
91573Srgrimes *    notice, this list of conditions and the following disclaimer.
101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111573Srgrimes *    notice, this list of conditions and the following disclaimer in the
121573Srgrimes *    documentation and/or other materials provided with the distribution.
131573Srgrimes * 3. All advertising materials mentioning features or use of this software
141573Srgrimes *    must display the acknowledgement as bellow:
151573Srgrimes *
161573Srgrimes *    This product includes software developed by K. Kobayashi and H. Shimokawa
171573Srgrimes *
181573Srgrimes * 4. The name of the author may not be used to endorse or promote products
191573Srgrimes *    derived from this software without specific prior written permission.
201573Srgrimes *
211573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
221573Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
231573Srgrimes * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
241573Srgrimes * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
251573Srgrimes * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
261573Srgrimes * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
271573Srgrimes * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
291573Srgrimes * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
301573Srgrimes * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
311573Srgrimes * POSSIBILITY OF SUCH DAMAGE.
321573Srgrimes *
3390045Sobrien * $FreeBSD: head/sys/dev/firewire/firewire.c 110193 2003-02-01 14:42:49Z simokawa $
3490045Sobrien *
351573Srgrimes */
3671579Sdeischen
3742232Sbde#include <sys/param.h>
3842232Sbde#include <sys/systm.h>
3942232Sbde#include <sys/types.h>
4042232Sbde#include <sys/mbuf.h>
411573Srgrimes#include <sys/socket.h>
421573Srgrimes#include <sys/socketvar.h>
4342232Sbde
441573Srgrimes#include <sys/kernel.h>
451573Srgrimes#include <sys/malloc.h>
461573Srgrimes#include <sys/conf.h>
471573Srgrimes#include <sys/uio.h>
48241440Sstefanf#include <sys/sysctl.h>
4971579Sdeischen
501573Srgrimes#include <machine/cpufunc.h>    /* for rdtsc proto for clock.h below */
511573Srgrimes#include <machine/clock.h>
521573Srgrimes
532569Sjkh#include <sys/bus.h>		/* used by smbus and newbus */
54113219Smdodd
55113219Smdodd#include <dev/firewire/firewire.h>
56113219Smdodd#include <dev/firewire/firewirereg.h>
571573Srgrimes#include <dev/firewire/fwmem.h>
5890045Sobrien#include <dev/firewire/iec13213.h>
5990045Sobrien#include <dev/firewire/iec68113.h>
6090045Sobrien
611573Srgrimesint firewire_debug=0, try_bmr=1;
62113219SmdoddSYSCTL_INT(_debug, OID_AUTO, firewire_debug, CTLFLAG_RW, &firewire_debug, 0,
63113219Smdodd	"FireWire driver debug flag");
64113219SmdoddSYSCTL_NODE(_hw, OID_AUTO, firewire, CTLFLAG_RD, 0, "FireWire Subsystem");
65113219SmdoddSYSCTL_INT(_hw_firewire, OID_AUTO, try_bmr, CTLFLAG_RW, &try_bmr, 0,
66113219Smdodd	"Try to be a bus manager");
67113219Smdodd
68113219Smdodd#define FW_MAXASYRTY 4
69113219Smdodd#define FW_MAXDEVRCNT 4
70113219Smdodd
71113219Smdodd#define XFER_TIMEOUT 0
72113219Smdodd
73113219Smdodddevclass_t firewire_devclass;
74113219Smdodd
75113219Smdoddstatic int firewire_match      __P((device_t));
76113219Smdoddstatic int firewire_attach      __P((device_t));
77113219Smdoddstatic int firewire_detach      __P((device_t));
78113219Smdodd#if 0
79241439Sstefanfstatic int firewire_shutdown    __P((device_t));
80113219Smdodd#endif
81113219Smdoddstatic device_t firewire_add_child   __P((device_t, int, const char *, int));
82113219Smdoddstatic void fw_try_bmr __P((void *));
83113219Smdoddstatic void fw_try_bmr_callback __P((struct fw_xfer *));
84113219Smdoddstatic void fw_asystart __P((struct fw_xfer *));
85113219Smdoddstatic int fw_get_tlabel __P((struct firewire_comm *, struct fw_xfer *));
86113219Smdoddstatic void fw_bus_probe __P((struct firewire_comm *));
87113219Smdoddstatic void fw_bus_explore __P((struct firewire_comm *));
8842232Sbdestatic void fw_bus_explore_callback __P((struct fw_xfer *));
89241439Sstefanfstatic void fw_attach_dev __P((struct firewire_comm *));
9042232Sbde#ifdef FW_VMACCESS
9142232Sbdestatic void fw_vmaccess __P((struct fw_xfer *));
9242232Sbde#endif
9342232Sbdestruct fw_xfer *asyreqq __P((struct firewire_comm *, u_int8_t, u_int8_t, u_int8_t,
9442232Sbde	u_int32_t, u_int32_t, void (*)__P((struct fw_xfer *))));
95233300Spluknetstatic int fw_bmr __P((struct firewire_comm *));
9642232Sbde
9742232Sbdestatic device_method_t firewire_methods[] = {
9842232Sbde	/* Device interface */
9942232Sbde	DEVMETHOD(device_probe,		firewire_match),
10042232Sbde	DEVMETHOD(device_attach,	firewire_attach),
10142232Sbde	DEVMETHOD(device_detach,	firewire_detach),
10242232Sbde	DEVMETHOD(device_suspend,	bus_generic_suspend),
10342232Sbde	DEVMETHOD(device_resume,	bus_generic_resume),
10455028Speter	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
10555028Speter
10642232Sbde	/* Bus interface */
10742232Sbde	DEVMETHOD(bus_add_child,	firewire_add_child),
10842232Sbde	DEVMETHOD(bus_print_child,	bus_generic_print_child),
10942232Sbde
11011659Sphk	{ 0, 0 }
111241439Sstefanf};
1121573Srgrimeschar linkspeed[7][0x10]={"S100","S200","S400","S800","S1600","S3200","Unknown"};
1137327Sache
1141573Srgrimes#define MAX_GAPHOP  16
1151573Srgrimesu_int gap_cnt[] = {1, 1, 4, 6, 9, 12, 14, 17,
1161573Srgrimes			20, 23, 25, 28, 31, 33, 36, 39, 42};
1171573Srgrimes
1181573Srgrimesextern struct cdevsw firewire_cdevsw;
1191573Srgrimes
1202569Sjkhstatic driver_t firewire_driver = {
1217327Sache	"firewire",
122241439Sstefanf	firewire_methods,
1231573Srgrimes	sizeof(struct firewire_softc),
1242569Sjkh};
1252569Sjkh
1262569Sjkh/*
1277327Sache * Lookup fwdev by node id.
1287327Sache */
1297327Sachestruct fw_device *
13042232Sbdefw_noderesolve_nodeid(struct firewire_comm *fc, int dst)
1317327Sache{
1321573Srgrimes	struct fw_device *fwdev;
1331573Srgrimes	int s;
1341573Srgrimes
1351573Srgrimes	s = splfw();
1361573Srgrimes	STAILQ_FOREACH(fwdev, &fc->devices, link)
1371573Srgrimes		if (fwdev->dst == dst)
1381573Srgrimes			break;
13911659Sphk	splx(s);
1401573Srgrimes
14111659Sphk	if(fwdev == NULL) return NULL;
1421573Srgrimes	if(fwdev->status == FWDEVINVAL) return NULL;
143241439Sstefanf	return fwdev;
1441573Srgrimes}
1451573Srgrimes
1461573Srgrimes/*
1471573Srgrimes * Lookup fwdev by EUI64.
1481573Srgrimes */
1491573Srgrimesstruct fw_device *
1507327Sachefw_noderesolve_eui64(struct firewire_comm *fc, struct fw_eui64 eui)
1517327Sache{
1527327Sache	struct fw_device *fwdev;
153241441Sstefanf	int s;
1541573Srgrimes
155241441Sstefanf	s = splfw();
156241441Sstefanf	STAILQ_FOREACH(fwdev, &fc->devices, link)
1577327Sache		if (FW_EUI64_EQUAL(fwdev->eui, eui))
1587327Sache			break;
159241441Sstefanf	splx(s);
160241441Sstefanf
161241440Sstefanf	if(fwdev == NULL) return NULL;
162241441Sstefanf	if(fwdev->status == FWDEVINVAL) return NULL;
163241441Sstefanf	return fwdev;
16442232Sbde}
1657327Sache
1667327Sache/*
1677327Sache * Async. request procedure for userland application.
1687327Sache */
1697327Sacheint
1707327Sachefw_asyreq(struct firewire_comm *fc, int sub, struct fw_xfer *xfer)
1711573Srgrimes{
1721573Srgrimes	int err = 0;
1731573Srgrimes	struct fw_xferq *xferq;
1741573Srgrimes	int tl = 0, len;
1757327Sache	struct fw_pkt *fp;
1767327Sache	int tcode;
1777327Sache	struct tcode_info *info;
1781573Srgrimes
1797327Sache	if(xfer == NULL) return EINVAL;
1807327Sache	if(xfer->send.len > MAXREC(fc->maxrec)){
1817327Sache		printf("send.len > maxrec\n");
1821573Srgrimes		return EINVAL;
1831573Srgrimes	}
1841573Srgrimes	if(xfer->act.hand == NULL){
1857327Sache		printf("act.hand == NULL\n");
1867327Sache		return EINVAL;
1877327Sache	}
1881573Srgrimes	fp = (struct fw_pkt *)xfer->send.buf;
1891573Srgrimes
1901573Srgrimes	tcode = fp->mode.common.tcode & 0xf;
1911573Srgrimes	info = &fc->tcode[tcode];
1921573Srgrimes	if (info->flag == 0) {
1931573Srgrimes		printf("invalid tcode=%d\n", tcode);
1941573Srgrimes		return EINVAL;
1951573Srgrimes	}
1961573Srgrimes	if (info->flag & FWTI_REQ)
1971573Srgrimes		xferq = fc->atq;
1981573Srgrimes	else
1991573Srgrimes		xferq = fc->ats;
2001573Srgrimes	len = info->hdr_len;
2011573Srgrimes	if (info->flag & FWTI_BLOCK_STR)
2021573Srgrimes		len += ntohs(fp->mode.stream.len);
2031573Srgrimes	else if (info->flag & FWTI_BLOCK_ASY)
2041573Srgrimes		len += ntohs(fp->mode.rresb.len);
2051573Srgrimes	if( len >  xfer->send.len ){
2061573Srgrimes		printf("len(%d) > send.len(%d) (tcode=%d)\n",
2071573Srgrimes				len, xfer->send.len, tcode);
2081573Srgrimes		return EINVAL;
2091573Srgrimes	}
2101573Srgrimes	xfer->send.len = len;
2111573Srgrimes
2121573Srgrimes	if(xferq->start == NULL){
2131573Srgrimes		printf("xferq->start == NULL\n");
2141573Srgrimes		return EINVAL;
215241439Sstefanf	}
2161573Srgrimes	if(!(xferq->queued < xferq->maxq)){
2171573Srgrimes		device_printf(fc->bdev, "Discard a packet (queued=%d)\n",
2181573Srgrimes			xferq->queued);
2191573Srgrimes		return EINVAL;
2201573Srgrimes	}
2211573Srgrimes
2221573Srgrimes
2231573Srgrimes	if (info->flag & FWTI_TLABEL) {
224241439Sstefanf		if((tl = fw_get_tlabel(fc, xfer)) == -1 )
2251573Srgrimes			return EIO;
226241439Sstefanf		fp->mode.hdr.tlrt = tl << 2;
22711659Sphk	}
228241439Sstefanf
229241439Sstefanf	xfer->tl = tl;
2301573Srgrimes	xfer->tcode = tcode;
2311573Srgrimes	xfer->resp = 0;
2321573Srgrimes	xfer->fc = fc;
233241439Sstefanf	xfer->q = xferq;
2341573Srgrimes	xfer->act_type = FWACT_XFER;
235241439Sstefanf	xfer->retry_req = fw_asybusy;
2361573Srgrimes
2371573Srgrimes	fw_asystart(xfer);
2381573Srgrimes	return err;
239241439Sstefanf}
240241439Sstefanf/*
2411573Srgrimes * Wakeup blocked process.
2421573Srgrimes */
2431573Srgrimesvoid
244241439Sstefanffw_asy_callback(struct fw_xfer *xfer){
2451573Srgrimes	wakeup(xfer);
246241439Sstefanf	return;
2471573Srgrimes}
2481573Srgrimes/*
2491573Srgrimes * Postpone to later retry.
250241439Sstefanf */
251241439Sstefanfvoid fw_asybusy(struct fw_xfer *xfer){
2521573Srgrimes#if 1
2531573Srgrimes	printf("fw_asybusy\n");
254241439Sstefanf#endif
255241439Sstefanf#if XFER_TIMEOUT
2561573Srgrimes	untimeout(fw_xfer_timeout, (void *)xfer, xfer->ch);
2571573Srgrimes#endif
2581573Srgrimes/*
2592569Sjkh	xfer->ch =  timeout((timeout_t *)fw_asystart, (void *)xfer, 20000);
260241439Sstefanf*/
2611573Srgrimes	DELAY(20000);
262113219Smdodd	fw_asystart(xfer);
263113219Smdodd	return;
264113219Smdodd}
265113219Smdodd#if XFER_TIMEOUT
266113219Smdodd/*
267113219Smdodd * Post timeout for async. request.
268243865Sjilles */
2692569Sjkhvoid
270241439Sstefanffw_xfer_timeout(void *arg)
2712569Sjkh{
2721573Srgrimes	int s;
273241439Sstefanf	struct fw_xfer *xfer;
2741573Srgrimes
2751573Srgrimes	xfer = (struct fw_xfer *)arg;
2761573Srgrimes	printf("fw_xfer_timeout status=%d resp=%d\n", xfer->state, xfer->resp);
277241439Sstefanf	/* XXX set error code */
2781573Srgrimes	s = splfw();
279241439Sstefanf	xfer->act.hand(xfer);
2801573Srgrimes	splx(s);
2811573Srgrimes}
2821573Srgrimes#endif
2831573Srgrimes/*
284113219Smdodd * Async. request with given xfer structure.
285113219Smdodd */
2861573Srgrimesstatic void
2871573Srgrimesfw_asystart(struct fw_xfer *xfer)
28811659Sphk{
289241439Sstefanf	struct firewire_comm *fc = xfer->fc;
2901573Srgrimes	int s;
2911573Srgrimes	if(xfer->retry++ >= fc->max_asyretry){
2922569Sjkh		xfer->resp = EBUSY;
2931573Srgrimes		xfer->state = FWXF_BUSY;
29456698Sjasone		xfer->act.hand(xfer);
295113219Smdodd		return;
29656698Sjasone	}
2972569Sjkh#if 0 /* XXX allow bus explore packets only after bus rest */
29856698Sjasone	if (fc->status < FWBUSEXPLORE) {
2991573Srgrimes		xfer->resp = EAGAIN;
30056698Sjasone		xfer->state = FWXF_BUSY;
30156698Sjasone		if (xfer->act.hand != NULL)
3021573Srgrimes			xfer->act.hand(xfer);
303		return;
304	}
305#endif
306	s = splfw();
307	xfer->state = FWXF_INQ;
308	STAILQ_INSERT_TAIL(&xfer->q->q, xfer, link);
309	xfer->q->queued ++;
310	splx(s);
311	/* XXX just queue for mbuf */
312	if (xfer->mbuf == NULL)
313		xfer->q->start(fc);
314#if XFER_TIMEOUT
315	if (xfer->act.hand != NULL)
316		xfer->ch = timeout(fw_xfer_timeout, (void *)xfer, hz);
317#endif
318	return;
319}
320
321static int
322firewire_match( device_t dev )
323{
324	device_set_desc(dev, "IEEE1394(FireWire) bus");
325	return -140;
326}
327
328/*
329 * The attach routine.
330 */
331static int
332firewire_attach( device_t dev )
333{
334	int i, unitmask, mn;
335	struct firewire_softc *sc = device_get_softc(dev);
336	device_t pa = device_get_parent(dev);
337	struct firewire_comm *fc;
338	dev_t d;
339
340	fc = (struct firewire_comm *)device_get_softc(pa);
341	sc->fc = fc;
342
343	unitmask = UNIT2MIN(device_get_unit(dev));
344
345	if( fc->nisodma > FWMAXNDMA) fc->nisodma = FWMAXNDMA;
346	for ( i = 0 ; i < fc->nisodma ; i++ ){
347		mn = unitmask | i;
348		/* XXX device name should be improved */
349		d = make_dev(&firewire_cdevsw, unit2minor(mn),
350			UID_ROOT, GID_OPERATOR, 0660,
351			"fw%x", mn);
352#if __FreeBSD_version >= 500000
353		if (i == 0)
354			sc->dev = d;
355		else
356			dev_depends(sc->dev, d);
357#else
358		sc->dev[i] = d;
359#endif
360	}
361	d = make_dev(&firewire_cdevsw, unit2minor(unitmask | FWMEM_FLAG),
362			UID_ROOT, GID_OPERATOR, 0660,
363			"fwmem%d", device_get_unit(dev));
364#if __FreeBSD_version >= 500000
365	dev_depends(sc->dev, d);
366#else
367	sc->dev[i] = d;
368#endif
369#if __FreeBSD_version >= 500000
370#define CALLOUT_INIT(x) callout_init(x, 0 /* mpsafe */)
371#else
372#define CALLOUT_INIT(x) callout_init(x)
373#endif
374	CALLOUT_INIT(&sc->fc->timeout_callout);
375	CALLOUT_INIT(&sc->fc->bmr_callout);
376	CALLOUT_INIT(&sc->fc->retry_probe_callout);
377	CALLOUT_INIT(&sc->fc->busprobe_callout);
378
379	callout_reset(&sc->fc->timeout_callout, hz * 10,
380			(void *)sc->fc->timeout, (void *)sc->fc);
381
382	/* Locate our children */
383	bus_generic_probe(dev);
384
385	/* launch attachement of the added children */
386	bus_generic_attach(dev);
387
388	/* bus_reset */
389	fc->ibr(fc);
390
391	return 0;
392}
393
394/*
395 * Attach it as child.
396 */
397static device_t
398firewire_add_child(device_t dev, int order, const char *name, int unit)
399{
400        device_t child;
401	struct firewire_softc *sc;
402
403	sc = (struct firewire_softc *)device_get_softc(dev);
404	child = device_add_child(dev, name, unit);
405	if (child) {
406		device_set_ivars(child, sc->fc);
407		device_probe_and_attach(child);
408	}
409
410	return child;
411}
412
413/*
414 * Dettach it.
415 */
416static int
417firewire_detach( device_t dev )
418{
419	struct firewire_softc *sc;
420
421	sc = (struct firewire_softc *)device_get_softc(dev);
422
423#if __FreeBSD_version >= 500000
424	destroy_dev(sc->dev);
425#else
426	{
427		int j;
428		for (j = 0 ; j < sc->fc->nisodma + 1; j++)
429			destroy_dev(sc->dev[j]);
430	}
431#endif
432	/* XXX xfree_free and untimeout on all xfers */
433	callout_stop(&sc->fc->timeout_callout);
434	callout_stop(&sc->fc->bmr_callout);
435	callout_stop(&sc->fc->retry_probe_callout);
436	callout_stop(&sc->fc->busprobe_callout);
437	free(sc->fc->topology_map, M_DEVBUF);
438	free(sc->fc->speed_map, M_DEVBUF);
439	bus_generic_detach(dev);
440	return(0);
441}
442#if 0
443static int
444firewire_shutdown( device_t dev )
445{
446	return 0;
447}
448#endif
449
450/*
451 * Called after bus reset.
452 */
453void
454fw_busreset(struct firewire_comm *fc)
455{
456	int i;
457	struct fw_xfer *xfer;
458
459	switch(fc->status){
460	case FWBUSMGRELECT:
461		callout_stop(&fc->bmr_callout);
462		break;
463	default:
464		break;
465	}
466	fc->status = FWBUSRESET;
467/* XXX: discard all queued packet */
468	while((xfer = STAILQ_FIRST(&fc->atq->q)) != NULL){
469		STAILQ_REMOVE_HEAD(&fc->atq->q, link);
470		xfer->resp = EAGAIN;
471		switch(xfer->act_type){
472		case FWACT_XFER:
473			fw_xfer_done(xfer);
474			break;
475		default:
476			break;
477		}
478		fw_xfer_free( xfer);
479	}
480	while((xfer = STAILQ_FIRST(&fc->ats->q)) != NULL){
481		STAILQ_REMOVE_HEAD(&fc->ats->q, link);
482		xfer->resp = EAGAIN;
483		switch(xfer->act_type){
484		case FWACT_XFER:
485			fw_xfer_done(xfer);
486		default:
487			break;
488		}
489		fw_xfer_free( xfer);
490	}
491	for(i = 0; i < fc->nisodma; i++)
492		while((xfer = STAILQ_FIRST(&fc->it[i]->q)) != NULL){
493			STAILQ_REMOVE_HEAD(&fc->it[i]->q, link);
494			xfer->resp = 0;
495			switch(xfer->act_type){
496			case FWACT_XFER:
497				fw_xfer_done(xfer);
498				break;
499			default:
500				break;
501			}
502			fw_xfer_free( xfer);
503		}
504
505	CSRARC(fc, STATE_CLEAR)
506			= 1 << 23 | 0 << 17 | 1 << 16 | 1 << 15 | 1 << 14 ;
507	CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
508	CSRARC(fc, NODE_IDS) = 0x3f;
509
510	CSRARC(fc, TOPO_MAP + 8) = 0;
511	fc->irm = -1;
512
513	fc->max_node = -1;
514
515	for(i = 2; i < 0x100/4 - 2 ; i++){
516		CSRARC(fc, SPED_MAP + i * 4) = 0;
517	}
518	CSRARC(fc, STATE_CLEAR) = 1 << 23 | 0 << 17 | 1 << 16 | 1 << 15 | 1 << 14 ;
519	CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
520	CSRARC(fc, RESET_START) = 0;
521	CSRARC(fc, SPLIT_TIMEOUT_HI) = 0;
522	CSRARC(fc, SPLIT_TIMEOUT_LO) = 800 << 19;
523	CSRARC(fc, CYCLE_TIME) = 0x0;
524	CSRARC(fc, BUS_TIME) = 0x0;
525	CSRARC(fc, BUS_MGR_ID) = 0x3f;
526	CSRARC(fc, BANDWIDTH_AV) = 4915;
527	CSRARC(fc, CHANNELS_AV_HI) = 0xffffffff;
528	CSRARC(fc, CHANNELS_AV_LO) = 0xffffffff;
529	CSRARC(fc, IP_CHANNELS) = (1 << 31);
530
531	CSRARC(fc, CONF_ROM) = 0x04 << 24;
532	CSRARC(fc, CONF_ROM + 4) = 0x31333934; /* means strings 1394 */
533	CSRARC(fc, CONF_ROM + 8) = 1 << 31 | 1 << 30 | 1 << 29 |
534				1 << 28 | 0xff << 16 | 0x09 << 8;
535	CSRARC(fc, CONF_ROM + 0xc) = 0;
536
537/* DV depend CSRs see blue book */
538	CSRARC(fc, oPCR) &= ~DV_BROADCAST_ON;
539	CSRARC(fc, iPCR) &= ~DV_BROADCAST_ON;
540
541	CSRARC(fc, STATE_CLEAR) &= ~(1 << 23 | 1 << 15 | 1 << 14 );
542	CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
543}
544
545/* Call once after reboot */
546void fw_init(struct firewire_comm *fc)
547{
548	int i;
549	struct csrdir *csrd;
550#ifdef FW_VMACCESS
551	struct fw_xfer *xfer;
552	struct fw_bind *fwb;
553#endif
554
555	fc->max_asyretry = FW_MAXASYRTY;
556
557	fc->arq->queued = 0;
558	fc->ars->queued = 0;
559	fc->atq->queued = 0;
560	fc->ats->queued = 0;
561
562	fc->arq->psize = PAGE_SIZE;
563	fc->ars->psize = PAGE_SIZE;
564	fc->atq->psize = 0;
565	fc->ats->psize = 0;
566
567
568	fc->arq->buf = NULL;
569	fc->ars->buf = NULL;
570	fc->atq->buf = NULL;
571	fc->ats->buf = NULL;
572
573	fc->arq->flag = FWXFERQ_PACKET;
574	fc->ars->flag = FWXFERQ_PACKET;
575	fc->atq->flag = FWXFERQ_PACKET;
576	fc->ats->flag = FWXFERQ_PACKET;
577
578	STAILQ_INIT(&fc->atq->q);
579	STAILQ_INIT(&fc->ats->q);
580
581	for( i = 0 ; i < fc->nisodma ; i ++ ){
582		fc->it[i]->queued = 0;
583		fc->ir[i]->queued = 0;
584
585		fc->it[i]->start = NULL;
586		fc->ir[i]->start = NULL;
587
588		fc->it[i]->buf = NULL;
589		fc->ir[i]->buf = NULL;
590
591		fc->it[i]->flag = FWXFERQ_STREAM;
592		fc->ir[i]->flag = FWXFERQ_STREAM;
593
594		STAILQ_INIT(&fc->it[i]->q);
595		STAILQ_INIT(&fc->ir[i]->q);
596
597		STAILQ_INIT(&fc->it[i]->binds);
598		STAILQ_INIT(&fc->ir[i]->binds);
599	}
600
601	fc->arq->maxq = FWMAXQUEUE;
602	fc->ars->maxq = FWMAXQUEUE;
603	fc->atq->maxq = FWMAXQUEUE;
604	fc->ats->maxq = FWMAXQUEUE;
605
606	for( i = 0 ; i < fc->nisodma ; i++){
607		fc->ir[i]->maxq = FWMAXQUEUE;
608		fc->it[i]->maxq = FWMAXQUEUE;
609	}
610/* Initialize csr registers */
611	fc->topology_map = (struct fw_topology_map *)malloc(
612				sizeof(struct fw_topology_map),
613				M_DEVBUF, M_NOWAIT | M_ZERO);
614	fc->speed_map = (struct fw_speed_map *)malloc(
615				sizeof(struct fw_speed_map),
616				M_DEVBUF, M_NOWAIT | M_ZERO);
617	CSRARC(fc, TOPO_MAP) = 0x3f1 << 16;
618	CSRARC(fc, TOPO_MAP + 4) = 1;
619	CSRARC(fc, SPED_MAP) = 0x3f1 << 16;
620	CSRARC(fc, SPED_MAP + 4) = 1;
621
622	STAILQ_INIT(&fc->devices);
623	STAILQ_INIT(&fc->pending);
624
625/* Initialize csr ROM work space */
626	SLIST_INIT(&fc->ongocsr);
627	SLIST_INIT(&fc->csrfree);
628	for( i = 0 ; i < FWMAXCSRDIR ; i++){
629		csrd = (struct csrdir *) malloc(sizeof(struct csrdir), M_DEVBUF,M_NOWAIT);
630		if(csrd == NULL) break;
631		SLIST_INSERT_HEAD(&fc->csrfree, csrd, link);
632	}
633
634/* Initialize Async handlers */
635	STAILQ_INIT(&fc->binds);
636	for( i = 0 ; i < 0x40 ; i++){
637		STAILQ_INIT(&fc->tlabels[i]);
638	}
639
640/* DV depend CSRs see blue book */
641#if 0
642	CSRARC(fc, oMPR) = 0x3fff0001; /* # output channel = 1 */
643	CSRARC(fc, oPCR) = 0x8000007a;
644	for(i = 4 ; i < 0x7c/4 ; i+=4){
645		CSRARC(fc, i + oPCR) = 0x8000007a;
646	}
647
648	CSRARC(fc, iMPR) = 0x00ff0001; /* # input channel = 1 */
649	CSRARC(fc, iPCR) = 0x803f0000;
650	for(i = 4 ; i < 0x7c/4 ; i+=4){
651		CSRARC(fc, i + iPCR) = 0x0;
652	}
653#endif
654
655
656#ifdef FW_VMACCESS
657	xfer = fw_xfer_alloc();
658	if(xfer == NULL) return;
659
660	fwb = (struct fw_bind *)malloc(sizeof (struct fw_bind), M_DEVBUF, M_NOWAIT);
661	if(fwb == NULL){
662		fw_xfer_free(xfer);
663	}
664	xfer->act.hand = fw_vmaccess;
665	xfer->act_type = FWACT_XFER;
666	xfer->fc = fc;
667	xfer->sc = NULL;
668
669	fwb->start_hi = 0x2;
670	fwb->start_lo = 0;
671	fwb->addrlen = 0xffffffff;
672	fwb->xfer = xfer;
673	fw_bindadd(fc, fwb);
674#endif
675}
676
677/*
678 * To lookup binded process from IEEE1394 address.
679 */
680struct fw_bind *
681fw_bindlookup(struct firewire_comm *fc, u_int32_t dest_hi, u_int32_t dest_lo)
682{
683	struct fw_bind *tfw;
684	for(tfw = STAILQ_FIRST(&fc->binds) ; tfw != NULL ;
685		tfw = STAILQ_NEXT(tfw, fclist)){
686		if(tfw->xfer->act_type != FWACT_NULL &&
687			tfw->start_hi == dest_hi &&
688			tfw->start_lo <= dest_lo &&
689			(tfw->start_lo + tfw->addrlen) > dest_lo){
690			return(tfw);
691		}
692	}
693	return(NULL);
694}
695
696/*
697 * To bind IEEE1394 address block to process.
698 */
699int
700fw_bindadd(struct firewire_comm *fc, struct fw_bind *fwb)
701{
702	struct fw_bind *tfw, *tfw2 = NULL;
703	int err = 0;
704	tfw = STAILQ_FIRST(&fc->binds);
705	if(tfw == NULL){
706		STAILQ_INSERT_HEAD(&fc->binds, fwb, fclist);
707		goto out;
708	}
709	if((tfw->start_hi > fwb->start_hi) ||
710		(tfw->start_hi == fwb->start_hi &&
711		(tfw->start_lo > (fwb->start_lo + fwb->addrlen)))){
712		STAILQ_INSERT_HEAD(&fc->binds, fwb, fclist);
713		goto out;
714	}
715	for(; tfw != NULL; tfw = STAILQ_NEXT(tfw, fclist)){
716		if((tfw->start_hi < fwb->start_hi) ||
717		   (tfw->start_hi == fwb->start_hi &&
718		    (tfw->start_lo + tfw->addrlen) < fwb->start_lo)){
719		   tfw2 = STAILQ_NEXT(tfw, fclist);
720			if(tfw2 == NULL)
721				break;
722			if((tfw2->start_hi > fwb->start_hi) ||
723			   (tfw2->start_hi == fwb->start_hi &&
724			    tfw2->start_lo > (fwb->start_lo + fwb->addrlen))){
725				break;
726			}else{
727				err = EBUSY;
728				goto out;
729			}
730		}
731	}
732	if(tfw != NULL){
733		STAILQ_INSERT_AFTER(&fc->binds, tfw, fwb, fclist);
734	}else{
735		STAILQ_INSERT_TAIL(&fc->binds, fwb, fclist);
736	}
737out:
738	if(!err && fwb->xfer->act_type == FWACT_CH){
739		STAILQ_INSERT_HEAD(&fc->ir[fwb->xfer->sub]->binds, fwb, chlist);
740	}
741	return err;
742}
743
744/*
745 * To free IEEE1394 address block.
746 */
747int
748fw_bindremove(struct firewire_comm *fc, struct fw_bind *fwb)
749{
750	int s;
751
752	s = splfw();
753	/* shall we check the existance? */
754	STAILQ_REMOVE(&fc->binds, fwb, fw_bind, fclist);
755	splx(s);
756	if (fwb->xfer)
757		fw_xfer_free(fwb->xfer);
758
759	return 0;
760}
761
762/*
763 * To free transaction label.
764 */
765static void
766fw_tl_free(struct firewire_comm *fc, struct fw_xfer *xfer)
767{
768	struct tlabel *tl;
769	int s = splfw();
770
771	for( tl = STAILQ_FIRST(&fc->tlabels[xfer->tl]); tl != NULL;
772		tl = STAILQ_NEXT(tl, link)){
773		if(tl->xfer == xfer){
774			STAILQ_REMOVE(&fc->tlabels[xfer->tl], tl, tlabel, link);
775			free(tl, M_DEVBUF);
776			splx(s);
777			return;
778		}
779	}
780	splx(s);
781	return;
782}
783
784/*
785 * To obtain XFER structure by transaction label.
786 */
787static struct fw_xfer *
788fw_tl2xfer(struct firewire_comm *fc, int node, int tlabel)
789{
790	struct fw_xfer *xfer;
791	struct tlabel *tl;
792	int s = splfw();
793
794	for( tl = STAILQ_FIRST(&fc->tlabels[tlabel]); tl != NULL;
795		tl = STAILQ_NEXT(tl, link)){
796		if(tl->xfer->dst == node){
797			xfer = tl->xfer;
798			splx(s);
799			return(xfer);
800		}
801	}
802	splx(s);
803	return(NULL);
804}
805
806/*
807 * To allocate IEEE1394 XFER structure.
808 */
809struct fw_xfer *
810fw_xfer_alloc()
811{
812	struct fw_xfer *xfer;
813
814	xfer = malloc(sizeof(struct fw_xfer), M_DEVBUF, M_NOWAIT | M_ZERO);
815	if (xfer == NULL)
816		return xfer;
817
818	xfer->time = time_second;
819	xfer->sub = -1;
820
821	return xfer;
822}
823
824/*
825 * IEEE1394 XFER post process.
826 */
827void
828fw_xfer_done(struct fw_xfer *xfer)
829{
830	if (xfer->act.hand == NULL)
831		return;
832
833#if XFER_TIMEOUT
834	untimeout(fw_xfer_timeout, (void *)xfer, xfer->ch);
835#endif
836
837	if (xfer->fc->status != FWBUSRESET)
838		xfer->act.hand(xfer);
839	else {
840		printf("fw_xfer_done: pending\n");
841		if (xfer->fc != NULL)
842			STAILQ_INSERT_TAIL(&xfer->fc->pending, xfer, link);
843		else
844			panic("fw_xfer_done: why xfer->fc is NULL?");
845	}
846}
847
848/*
849 * To free IEEE1394 XFER structure.
850 */
851void
852fw_xfer_free( struct fw_xfer* xfer)
853{
854	int s;
855	if(xfer == NULL ) return;
856	if(xfer->state == FWXF_INQ){
857		printf("fw_xfer_free FWXF_INQ\n");
858		s = splfw();
859		STAILQ_REMOVE(&xfer->q->q, xfer, fw_xfer, link);
860		xfer->q->queued --;
861		splx(s);
862	}
863	if(xfer->fc != NULL){
864		if(xfer->state == FWXF_START){
865#if 0 /* this could happen if we call fwohci_arcv() before fwohci_txd() */
866			printf("fw_xfer_free FWXF_START\n");
867#endif
868			s = splfw();
869			xfer->q->drain(xfer->fc, xfer);
870			splx(s);
871		}
872	}
873	if(xfer->send.buf != NULL){
874		free(xfer->send.buf, M_DEVBUF);
875	}
876	if(xfer->recv.buf != NULL){
877		free(xfer->recv.buf, M_DEVBUF);
878	}
879	if(xfer->fc != NULL){
880		fw_tl_free(xfer->fc, xfer);
881	}
882	free(xfer, M_DEVBUF);
883}
884
885static void
886fw_asy_callback_free(struct fw_xfer *xfer)
887{
888#if 0
889	printf("asyreq done state=%d resp=%d\n",
890				xfer->state, xfer->resp);
891#endif
892	fw_xfer_free(xfer);
893}
894
895/*
896 * To configure PHY.
897 */
898static void
899fw_phy_config(struct firewire_comm *fc, int root_node, int gap_count)
900{
901	struct fw_xfer *xfer;
902	struct fw_pkt *fp;
903
904	fc->status = FWBUSPHYCONF;
905
906#if 0
907	DELAY(100000);
908#endif
909	xfer = fw_xfer_alloc();
910	xfer->send.len = 12;
911	xfer->send.off = 0;
912	xfer->fc = fc;
913	xfer->retry_req = fw_asybusy;
914	xfer->act.hand = fw_asy_callback_free;
915
916	xfer->send.buf = malloc(sizeof(u_int32_t),
917					M_DEVBUF, M_NOWAIT | M_ZERO);
918	fp = (struct fw_pkt *)xfer->send.buf;
919	fp->mode.ld[1] = 0;
920	if (root_node >= 0)
921		fp->mode.ld[1] |= htonl((root_node & 0x3f) << 24 | 1 << 23);
922	if (gap_count >= 0)
923		fp->mode.ld[1] |= htonl(1 << 22 | (gap_count & 0x3f) << 16);
924	fp->mode.ld[2] = ~fp->mode.ld[1];
925/* XXX Dangerous, how to pass PHY packet to device driver */
926	fp->mode.common.tcode |= FWTCODE_PHY;
927
928	if (firewire_debug)
929		printf("send phy_config root_node=%d gap_count=%d\n",
930						root_node, gap_count);
931	fw_asyreq(fc, -1, xfer);
932}
933
934#if 0
935/*
936 * Dump self ID.
937 */
938static void
939fw_print_sid(u_int32_t sid)
940{
941	union fw_self_id *s;
942	s = (union fw_self_id *) &sid;
943	printf("node:%d link:%d gap:%d spd:%d del:%d con:%d pwr:%d"
944		" p0:%d p1:%d p2:%d i:%d m:%d\n",
945		s->p0.phy_id, s->p0.link_active, s->p0.gap_count,
946		s->p0.phy_speed, s->p0.phy_delay, s->p0.contender,
947		s->p0.power_class, s->p0.port0, s->p0.port1,
948		s->p0.port2, s->p0.initiated_reset, s->p0.more_packets);
949}
950#endif
951
952/*
953 * To receive self ID.
954 */
955void fw_sidrcv(struct firewire_comm* fc, caddr_t buf, u_int len, u_int off)
956{
957	u_int32_t *p, *sid = (u_int32_t *)(buf + off);
958	union fw_self_id *self_id;
959	u_int i, j, node, c_port = 0, i_branch = 0;
960
961	fc->sid_cnt = len /(sizeof(u_int32_t) * 2);
962	fc->status = FWBUSINIT;
963	fc->max_node = fc->nodeid & 0x3f;
964	CSRARC(fc, NODE_IDS) = ((u_int32_t)fc->nodeid) << 16;
965	fc->status = FWBUSCYMELECT;
966	fc->topology_map->crc_len = 2;
967	fc->topology_map->generation ++;
968	fc->topology_map->self_id_count = 0;
969	fc->topology_map->node_count = 0;
970	fc->speed_map->generation ++;
971	fc->speed_map->crc_len = 1 + (64*64 + 3) / 4;
972	self_id = &fc->topology_map->self_id[0];
973	for(i = 0; i < fc->sid_cnt; i ++){
974		if (sid[1] != ~sid[0]) {
975			printf("fw_sidrcv: invalid self-id packet\n");
976			sid += 2;
977			continue;
978		}
979		*self_id = *((union fw_self_id *)sid);
980		fc->topology_map->crc_len++;
981		if(self_id->p0.sequel == 0){
982			fc->topology_map->node_count ++;
983			c_port = 0;
984#if 0
985			fw_print_sid(sid[0]);
986#endif
987			node = self_id->p0.phy_id;
988			if(fc->max_node < node){
989				fc->max_node = self_id->p0.phy_id;
990			}
991			/* XXX I'm not sure this is the right speed_map */
992			fc->speed_map->speed[node][node]
993					= self_id->p0.phy_speed;
994			for (j = 0; j < node; j ++) {
995				fc->speed_map->speed[j][node]
996					= fc->speed_map->speed[node][j]
997					= min(fc->speed_map->speed[j][j],
998							self_id->p0.phy_speed);
999			}
1000			if ((fc->irm == -1 || self_id->p0.phy_id > fc->irm) &&
1001			  (self_id->p0.link_active && self_id->p0.contender)) {
1002				fc->irm = self_id->p0.phy_id;
1003			}
1004			if(self_id->p0.port0 >= 0x2){
1005				c_port++;
1006			}
1007			if(self_id->p0.port1 >= 0x2){
1008				c_port++;
1009			}
1010			if(self_id->p0.port2 >= 0x2){
1011				c_port++;
1012			}
1013		}
1014		if(c_port > 2){
1015			i_branch += (c_port - 2);
1016		}
1017		sid += 2;
1018		self_id++;
1019		fc->topology_map->self_id_count ++;
1020	}
1021	device_printf(fc->bdev, "%d nodes", fc->max_node + 1);
1022	/* CRC */
1023	fc->topology_map->crc = fw_crc16(
1024			(u_int32_t *)&fc->topology_map->generation,
1025			fc->topology_map->crc_len * 4);
1026	fc->speed_map->crc = fw_crc16(
1027			(u_int32_t *)&fc->speed_map->generation,
1028			fc->speed_map->crc_len * 4);
1029	/* byteswap and copy to CSR */
1030	p = (u_int32_t *)fc->topology_map;
1031	for (i = 0; i <= fc->topology_map->crc_len; i++)
1032		CSRARC(fc, TOPO_MAP + i * 4) = htonl(*p++);
1033	p = (u_int32_t *)fc->speed_map;
1034	CSRARC(fc, SPED_MAP) = htonl(*p++);
1035	CSRARC(fc, SPED_MAP + 4) = htonl(*p++);
1036	/* don't byte-swap u_int8_t array */
1037	bcopy(p, &CSRARC(fc, SPED_MAP + 8), (fc->speed_map->crc_len - 1)*4);
1038
1039	fc->max_hop = fc->max_node - i_branch;
1040#if 1
1041	printf(", maxhop <= %d", fc->max_hop);
1042#endif
1043
1044	if(fc->irm == -1 ){
1045		printf(", Not found IRM capable node");
1046	}else{
1047		printf(", cable IRM = %d", fc->irm);
1048		if (fc->irm == fc->nodeid)
1049			printf(" (me)");
1050	}
1051	printf("\n");
1052
1053	if (try_bmr && (fc->irm != -1) && (CSRARC(fc, BUS_MGR_ID) == 0x3f)) {
1054		if (fc->irm == ((CSRARC(fc, NODE_IDS) >> 16 ) & 0x3f)) {
1055			fc->status = FWBUSMGRDONE;
1056			CSRARC(fc, BUS_MGR_ID) = fc->set_bmr(fc, fc->irm);
1057		} else {
1058			fc->status = FWBUSMGRELECT;
1059			callout_reset(&fc->bmr_callout, hz/8,
1060				(void *)fw_try_bmr, (void *)fc);
1061		}
1062	} else {
1063		fc->status = FWBUSMGRDONE;
1064#if 0
1065		device_printf(fc->bdev, "BMR = %x\n",
1066				CSRARC(fc, BUS_MGR_ID));
1067#endif
1068	}
1069	free(buf, M_DEVBUF);
1070	if(fc->irm == ((CSRARC(fc, NODE_IDS) >> 16 ) & 0x3f)){
1071		/* I am BMGR */
1072		fw_bmr(fc);
1073	}
1074	callout_reset(&fc->busprobe_callout, hz/4,
1075			(void *)fw_bus_probe, (void *)fc);
1076}
1077
1078/*
1079 * To probe devices on the IEEE1394 bus.
1080 */
1081static void
1082fw_bus_probe(struct firewire_comm *fc)
1083{
1084	int s;
1085	struct fw_device *fwdev, *next;
1086
1087	s = splfw();
1088	fc->status = FWBUSEXPLORE;
1089	fc->retry_count = 0;
1090
1091/*
1092 * Invalidate all devices, just after bus reset. Devices
1093 * to be removed has not been seen longer time.
1094 */
1095	for (fwdev = STAILQ_FIRST(&fc->devices); fwdev != NULL; fwdev = next) {
1096		next = STAILQ_NEXT(fwdev, link);
1097		if (fwdev->status != FWDEVINVAL) {
1098			fwdev->status = FWDEVINVAL;
1099			fwdev->rcnt = 0;
1100		} else if(fwdev->rcnt < FW_MAXDEVRCNT) {
1101			fwdev->rcnt ++;
1102		} else {
1103			STAILQ_REMOVE(&fc->devices, fwdev, fw_device, link);
1104			free(fwdev, M_DEVBUF);
1105		}
1106	}
1107	fc->ongonode = 0;
1108	fc->ongoaddr = CSRROMOFF;
1109	fc->ongodev = NULL;
1110	fc->ongoeui.hi = 0xffffffff; fc->ongoeui.lo = 0xffffffff;
1111	fw_bus_explore(fc);
1112	splx(s);
1113}
1114
1115/*
1116 * To collect device informations on the IEEE1394 bus.
1117 */
1118static void
1119fw_bus_explore(struct firewire_comm *fc )
1120{
1121	int err = 0;
1122	struct fw_device *fwdev, *pfwdev, *tfwdev;
1123	u_int32_t addr;
1124	struct fw_xfer *xfer;
1125	struct fw_pkt *fp;
1126
1127	if(fc->status != FWBUSEXPLORE)
1128		return;
1129
1130loop:
1131	if(fc->ongonode == fc->nodeid) fc->ongonode++;
1132
1133	if(fc->ongonode > fc->max_node) goto done;
1134	if(fc->ongonode >= 0x3f) goto done;
1135
1136	/* check link */
1137	/* XXX we need to check phy_id first */
1138	if (!fc->topology_map->self_id[fc->ongonode].p0.link_active) {
1139		printf("fw_bus_explore: node %d link down\n", fc->ongonode);
1140		fc->ongonode++;
1141		goto loop;
1142	}
1143
1144	if(fc->ongoaddr <= CSRROMOFF &&
1145		fc->ongoeui.hi == 0xffffffff &&
1146		fc->ongoeui.lo == 0xffffffff ){
1147		fc->ongoaddr = CSRROMOFF;
1148		addr = 0xf0000000 | fc->ongoaddr;
1149	}else if(fc->ongoeui.hi == 0xffffffff ){
1150		fc->ongoaddr = CSRROMOFF + 0xc;
1151		addr = 0xf0000000 | fc->ongoaddr;
1152	}else if(fc->ongoeui.lo == 0xffffffff ){
1153		fc->ongoaddr = CSRROMOFF + 0x10;
1154		addr = 0xf0000000 | fc->ongoaddr;
1155	}else if(fc->ongodev == NULL){
1156		STAILQ_FOREACH(fwdev, &fc->devices, link)
1157			if (FW_EUI64_EQUAL(fwdev->eui, fc->ongoeui))
1158				break;
1159		if(fwdev != NULL){
1160			fwdev->dst = fc->ongonode;
1161			fwdev->status = FWDEVATTACHED;
1162			fc->ongonode++;
1163			fc->ongoaddr = CSRROMOFF;
1164			fc->ongodev = NULL;
1165			fc->ongoeui.hi = 0xffffffff; fc->ongoeui.lo = 0xffffffff;
1166			goto loop;
1167		}
1168		fwdev = malloc(sizeof(struct fw_device), M_DEVBUF, M_NOWAIT);
1169		if(fwdev == NULL)
1170			return;
1171		fwdev->fc = fc;
1172		fwdev->rommax = 0;
1173		fwdev->dst = fc->ongonode;
1174		fwdev->eui.hi = fc->ongoeui.hi; fwdev->eui.lo = fc->ongoeui.lo;
1175		fwdev->status = FWDEVINIT;
1176#if 0
1177		fwdev->speed = CSRARC(fc, SPED_MAP + 8 + fc->ongonode / 4)
1178			>> ((3 - (fc->ongonode % 4)) * 8);
1179#else
1180		fwdev->speed = fc->speed_map->speed[fc->nodeid][fc->ongonode];
1181#endif
1182
1183		pfwdev = NULL;
1184		STAILQ_FOREACH(tfwdev, &fc->devices, link) {
1185			if (tfwdev->eui.hi > fwdev->eui.hi ||
1186					(tfwdev->eui.hi == fwdev->eui.hi &&
1187					tfwdev->eui.lo > fwdev->eui.lo))
1188				break;
1189			pfwdev = tfwdev;
1190		}
1191		if (pfwdev == NULL)
1192			STAILQ_INSERT_HEAD(&fc->devices, fwdev, link);
1193		else
1194			STAILQ_INSERT_AFTER(&fc->devices, pfwdev, fwdev, link);
1195
1196		device_printf(fc->bdev, "New %s device ID:%08x%08x\n",
1197			linkspeed[fwdev->speed],
1198			fc->ongoeui.hi, fc->ongoeui.lo);
1199
1200		fc->ongodev = fwdev;
1201		fc->ongoaddr = CSRROMOFF;
1202		addr = 0xf0000000 | fc->ongoaddr;
1203	}else{
1204		addr = 0xf0000000 | fc->ongoaddr;
1205	}
1206#if 0
1207	xfer = asyreqq(fc, FWSPD_S100, 0, 0,
1208		((FWLOCALBUS | fc->ongonode) << 16) | 0xffff , addr,
1209		fw_bus_explore_callback);
1210	if(xfer == NULL) goto done;
1211#else
1212	xfer = fw_xfer_alloc();
1213	if(xfer == NULL){
1214		goto done;
1215	}
1216	xfer->send.len = 16;
1217	xfer->spd = 0;
1218	xfer->send.buf = malloc(16, M_DEVBUF, M_NOWAIT);
1219	if(xfer->send.buf == NULL){
1220		fw_xfer_free( xfer);
1221		return;
1222	}
1223
1224	xfer->send.off = 0;
1225	fp = (struct fw_pkt *)xfer->send.buf;
1226	fp->mode.rreqq.dest_hi = htons(0xffff);
1227	fp->mode.rreqq.tlrt = 0;
1228	fp->mode.rreqq.tcode = FWTCODE_RREQQ;
1229	fp->mode.rreqq.pri = 0;
1230	fp->mode.rreqq.src = 0;
1231	xfer->dst = FWLOCALBUS | fc->ongonode;
1232	fp->mode.rreqq.dst = htons(xfer->dst);
1233	fp->mode.rreqq.dest_lo = htonl(addr);
1234	xfer->act.hand = fw_bus_explore_callback;
1235
1236	err = fw_asyreq(fc, -1, xfer);
1237	if(err){
1238		fw_xfer_free( xfer);
1239		return;
1240	}
1241#endif
1242	return;
1243done:
1244	/* fw_attach_devs */
1245	fc->status = FWBUSEXPDONE;
1246	if (firewire_debug)
1247		printf("bus_explore done\n");
1248	fw_attach_dev(fc);
1249	return;
1250
1251}
1252
1253/* Portable Async. request read quad */
1254struct fw_xfer *
1255asyreqq(struct firewire_comm *fc, u_int8_t spd, u_int8_t tl, u_int8_t rt,
1256	u_int32_t addr_hi, u_int32_t addr_lo,
1257	void (*hand) __P((struct fw_xfer*)))
1258{
1259	struct fw_xfer *xfer;
1260	struct fw_pkt *fp;
1261	int err;
1262
1263	xfer = fw_xfer_alloc();
1264	if(xfer == NULL){
1265		return NULL;
1266	}
1267	xfer->send.len = 16;
1268	xfer->spd = spd; /* XXX:min(spd, fc->spd) */
1269	xfer->send.buf = malloc(16, M_DEVBUF, M_NOWAIT);
1270	if(xfer->send.buf == NULL){
1271		fw_xfer_free( xfer);
1272		return NULL;
1273	}
1274
1275	xfer->send.off = 0;
1276	fp = (struct fw_pkt *)xfer->send.buf;
1277	fp->mode.rreqq.dest_hi = htons(addr_hi & 0xffff);
1278	if(tl & FWP_TL_VALID){
1279		fp->mode.rreqq.tlrt = (tl & 0x3f) << 2;
1280	}else{
1281		fp->mode.rreqq.tlrt = 0;
1282	}
1283	fp->mode.rreqq.tlrt |= rt & 0x3;
1284	fp->mode.rreqq.tcode = FWTCODE_RREQQ;
1285	fp->mode.rreqq.pri = 0;
1286	fp->mode.rreqq.src = 0;
1287	xfer->dst = addr_hi >> 16;
1288	fp->mode.rreqq.dst = htons(xfer->dst);
1289	fp->mode.rreqq.dest_lo = htonl(addr_lo);
1290	xfer->act.hand = hand;
1291
1292	err = fw_asyreq(fc, -1, xfer);
1293	if(err){
1294		fw_xfer_free( xfer);
1295		return NULL;
1296	}
1297	return xfer;
1298}
1299
1300/*
1301 * Callback for the IEEE1394 bus information collection.
1302 */
1303static void
1304fw_bus_explore_callback(struct fw_xfer *xfer)
1305{
1306	struct firewire_comm *fc;
1307	struct fw_pkt *sfp,*rfp;
1308	struct csrhdr *chdr;
1309	struct csrdir *csrd;
1310	struct csrreg *csrreg;
1311	u_int32_t offset;
1312
1313
1314	if(xfer == NULL) return;
1315	fc = xfer->fc;
1316	if(xfer->resp != 0){
1317		printf("resp != 0: node=%d addr=0x%x\n",
1318			fc->ongonode, fc->ongoaddr);
1319		fc->retry_count++;
1320		goto nextnode;
1321	}
1322
1323	if(xfer->send.buf == NULL){
1324		printf("send.buf == NULL: node=%d addr=0x%x\n",
1325			fc->ongonode, fc->ongoaddr);
1326		printf("send.buf == NULL\n");
1327		fc->retry_count++;
1328		goto nextnode;
1329	}
1330	sfp = (struct fw_pkt *)xfer->send.buf;
1331
1332	if(xfer->recv.buf == NULL){
1333		printf("recv.buf == NULL: node=%d addr=0x%x\n",
1334			fc->ongonode, fc->ongoaddr);
1335		fc->retry_count++;
1336		goto nextnode;
1337	}
1338	rfp = (struct fw_pkt *)xfer->recv.buf;
1339#if 0
1340	{
1341		u_int32_t *qld;
1342		int i;
1343		qld = (u_int32_t *)xfer->recv.buf;
1344		printf("len:%d\n", xfer->recv.len);
1345		for( i = 0 ; i <= xfer->recv.len && i < 32; i+= 4){
1346			printf("0x%08x ", ntohl(rfp->mode.ld[i/4]));
1347			if((i % 16) == 15) printf("\n");
1348		}
1349		if((i % 16) != 15) printf("\n");
1350	}
1351#endif
1352	if(fc->ongodev == NULL){
1353		if(sfp->mode.rreqq.dest_lo == htonl((0xf0000000 | CSRROMOFF))){
1354			rfp->mode.rresq.data = ntohl(rfp->mode.rresq.data);
1355			chdr = (struct csrhdr *)(&rfp->mode.rresq.data);
1356/* If CSR is minimul confinguration, more investgation is not needed. */
1357			if(chdr->info_len == 1){
1358				goto nextnode;
1359			}else{
1360				fc->ongoaddr = CSRROMOFF + 0xc;
1361			}
1362		}else if(sfp->mode.rreqq.dest_lo == htonl((0xf0000000 |(CSRROMOFF + 0xc)))){
1363			fc->ongoeui.hi = ntohl(rfp->mode.rresq.data);
1364			fc->ongoaddr = CSRROMOFF + 0x10;
1365		}else if(sfp->mode.rreqq.dest_lo == htonl((0xf0000000 |(CSRROMOFF + 0x10)))){
1366			fc->ongoeui.lo = ntohl(rfp->mode.rresq.data);
1367			if (fc->ongoeui.hi == 0 && fc->ongoeui.lo == 0)
1368				goto nextnode;
1369			fc->ongoaddr = CSRROMOFF;
1370		}
1371	}else{
1372		fc->ongodev->csrrom[(fc->ongoaddr - CSRROMOFF)/4] = ntohl(rfp->mode.rresq.data);
1373		if(fc->ongoaddr > fc->ongodev->rommax){
1374			fc->ongodev->rommax = fc->ongoaddr;
1375		}
1376		csrd = SLIST_FIRST(&fc->ongocsr);
1377		if((csrd = SLIST_FIRST(&fc->ongocsr)) == NULL){
1378			chdr = (struct csrhdr *)(fc->ongodev->csrrom);
1379			offset = CSRROMOFF;
1380		}else{
1381			chdr = (struct csrhdr *)&fc->ongodev->csrrom[(csrd->off - CSRROMOFF)/4];
1382			offset = csrd->off;
1383		}
1384		if(fc->ongoaddr > (CSRROMOFF + 0x14) && fc->ongoaddr != offset){
1385			csrreg = (struct csrreg *)&fc->ongodev->csrrom[(fc->ongoaddr - CSRROMOFF)/4];
1386			if( csrreg->key == 0x81 || csrreg->key == 0xd1){
1387				csrd = SLIST_FIRST(&fc->csrfree);
1388				if(csrd == NULL){
1389					goto nextnode;
1390				}else{
1391					csrd->ongoaddr = fc->ongoaddr;
1392					fc->ongoaddr += csrreg->val * 4;
1393					csrd->off = fc->ongoaddr;
1394					SLIST_REMOVE_HEAD(&fc->csrfree, link);
1395					SLIST_INSERT_HEAD(&fc->ongocsr, csrd, link);
1396					goto nextaddr;
1397				}
1398			}
1399		}
1400		fc->ongoaddr += 4;
1401		if(((fc->ongoaddr - offset)/4 > chdr->crc_len) &&
1402				(fc->ongodev->rommax < 0x414)){
1403			if(fc->ongodev->rommax <= 0x414){
1404				csrd = SLIST_FIRST(&fc->csrfree);
1405				if(csrd == NULL) goto nextnode;
1406				csrd->off = fc->ongoaddr;
1407				csrd->ongoaddr = fc->ongoaddr;
1408				SLIST_REMOVE_HEAD(&fc->csrfree, link);
1409				SLIST_INSERT_HEAD(&fc->ongocsr, csrd, link);
1410			}
1411			goto nextaddr;
1412		}
1413
1414		while(((fc->ongoaddr - offset)/4 > chdr->crc_len)){
1415			if(csrd == NULL){
1416				goto nextnode;
1417			};
1418			fc->ongoaddr = csrd->ongoaddr + 4;
1419			SLIST_REMOVE_HEAD(&fc->ongocsr, link);
1420			SLIST_INSERT_HEAD(&fc->csrfree, csrd, link);
1421			csrd = SLIST_FIRST(&fc->ongocsr);
1422			if((csrd = SLIST_FIRST(&fc->ongocsr)) == NULL){
1423				chdr = (struct csrhdr *)(fc->ongodev->csrrom);
1424				offset = CSRROMOFF;
1425			}else{
1426				chdr = (struct csrhdr *)&(fc->ongodev->csrrom[(csrd->off - CSRROMOFF)/4]);
1427				offset = csrd->off;
1428			}
1429		}
1430		if((fc->ongoaddr - CSRROMOFF) > CSRROMSIZE){
1431			goto nextnode;
1432		}
1433	}
1434nextaddr:
1435	fw_xfer_free( xfer);
1436	fw_bus_explore(fc);
1437	return;
1438nextnode:
1439	fw_xfer_free( xfer);
1440	fc->ongonode++;
1441/* housekeeping work space */
1442	fc->ongoaddr = CSRROMOFF;
1443	fc->ongodev = NULL;
1444	fc->ongoeui.hi = 0xffffffff; fc->ongoeui.lo = 0xffffffff;
1445	while((csrd = SLIST_FIRST(&fc->ongocsr)) != NULL){
1446		SLIST_REMOVE_HEAD(&fc->ongocsr, link);
1447		SLIST_INSERT_HEAD(&fc->csrfree, csrd, link);
1448	}
1449	fw_bus_explore(fc);
1450	return;
1451}
1452
1453/*
1454 * To obtain CSR register values.
1455 */
1456u_int32_t
1457getcsrdata(struct fw_device *fwdev, u_int8_t key)
1458{
1459	int i;
1460	struct csrhdr *chdr;
1461	struct csrreg *creg;
1462	chdr = (struct csrhdr *)&fwdev->csrrom[0];
1463	for( i = chdr->info_len + 4; i <= fwdev->rommax - CSRROMOFF; i+=4){
1464		creg = (struct csrreg *)&fwdev->csrrom[i/4];
1465		if(creg->key == key){
1466			return (u_int32_t)creg->val;
1467		}
1468	}
1469	return 0;
1470}
1471
1472/*
1473 * To attach sub-devices layer onto IEEE1394 bus.
1474 */
1475static void
1476fw_attach_dev(struct firewire_comm *fc)
1477{
1478	struct fw_device *fwdev;
1479	struct fw_xfer *xfer;
1480	int i, err;
1481	device_t *devlistp;
1482	int devcnt;
1483	struct firewire_dev_comm *fdc;
1484	u_int32_t spec, ver;
1485
1486	STAILQ_FOREACH(fwdev, &fc->devices, link) {
1487		if(fwdev->status == FWDEVINIT){
1488			spec = getcsrdata(fwdev, CSRKEY_SPEC);
1489			if(spec == 0)
1490				continue;
1491			ver = getcsrdata(fwdev, CSRKEY_VER);
1492			if(ver == 0)
1493				continue;
1494			fwdev->maxrec = (fwdev->csrrom[2] >> 12) & 0xf;
1495
1496			device_printf(fc->bdev, "Device ");
1497			switch(spec){
1498			case CSRVAL_ANSIT10:
1499				switch(ver){
1500				case CSRVAL_T10SBP2:
1501					printf("SBP-II");
1502					break;
1503				default:
1504					break;
1505				}
1506				break;
1507			case CSRVAL_1394TA:
1508				switch(ver){
1509				case CSR_PROTAVC:
1510					printf("AV/C");
1511					break;
1512				case CSR_PROTCAL:
1513					printf("CAL");
1514					break;
1515				case CSR_PROTEHS:
1516					printf("EHS");
1517					break;
1518				case CSR_PROTHAVI:
1519					printf("HAVi");
1520					break;
1521				case CSR_PROTCAM104:
1522					printf("1394 Cam 1.04");
1523					break;
1524				case CSR_PROTCAM120:
1525					printf("1394 Cam 1.20");
1526					break;
1527				case CSR_PROTCAM130:
1528					printf("1394 Cam 1.30");
1529					break;
1530				case CSR_PROTDPP:
1531					printf("1394 Direct print");
1532					break;
1533				case CSR_PROTIICP:
1534					printf("Industrial & Instrument");
1535					break;
1536				default:
1537					printf("unknown 1394TA");
1538					break;
1539				}
1540				break;
1541			default:
1542				printf("unknown spec");
1543				break;
1544			}
1545			fwdev->status = FWDEVATTACHED;
1546			printf("\n");
1547		}
1548	}
1549	err = device_get_children(fc->bdev, &devlistp, &devcnt);
1550	if( err != 0 )
1551		return;
1552	for( i = 0 ; i < devcnt ; i++){
1553		if (device_get_state(devlistp[i]) >= DS_ATTACHED)  {
1554			fdc = device_get_softc(devlistp[i]);
1555			if (fdc->post_explore != NULL)
1556				fdc->post_explore(fdc);
1557		}
1558	}
1559	free(devlistp, M_TEMP);
1560
1561	/* call pending handlers */
1562	i = 0;
1563	while ((xfer = STAILQ_FIRST(&fc->pending))) {
1564		STAILQ_REMOVE_HEAD(&fc->pending, link);
1565		i++;
1566		if (xfer->act.hand)
1567			xfer->act.hand(xfer);
1568	}
1569	if (i > 0)
1570		printf("fw_attach_dev: %d pending handlers called\n", i);
1571	if (fc->retry_count > 0) {
1572		printf("retry_count = %d\n", fc->retry_count);
1573		callout_reset(&fc->retry_probe_callout, hz*2,
1574					(void *)fc->ibr, (void *)fc);
1575	}
1576	return;
1577}
1578
1579/*
1580 * To allocate uniq transaction label.
1581 */
1582static int
1583fw_get_tlabel(struct firewire_comm *fc, struct fw_xfer *xfer)
1584{
1585	u_int i;
1586	struct tlabel *tl, *tmptl;
1587	int s;
1588	static u_int32_t label = 0;
1589
1590	s = splfw();
1591	for( i = 0 ; i < 0x40 ; i ++){
1592		label = (label + 1) & 0x3f;
1593		for(tmptl = STAILQ_FIRST(&fc->tlabels[label]);
1594			tmptl != NULL; tmptl = STAILQ_NEXT(tmptl, link)){
1595			if(tmptl->xfer->dst == xfer->dst) break;
1596		}
1597		if(tmptl == NULL) {
1598			tl = malloc(sizeof(struct tlabel),M_DEVBUF,M_NOWAIT);
1599			if (tl == NULL) {
1600				splx(s);
1601				return (-1);
1602			}
1603			tl->xfer = xfer;
1604			STAILQ_INSERT_TAIL(&fc->tlabels[label], tl, link);
1605			splx(s);
1606			return(label);
1607		}
1608	}
1609	splx(s);
1610
1611	printf("fw_get_tlabel: no free tlabel\n");
1612	return(-1);
1613}
1614
1615/*
1616 * Generic packet receving process.
1617 */
1618void
1619fw_rcv(struct firewire_comm* fc, caddr_t buf, u_int len, u_int sub, u_int off, u_int spd)
1620{
1621	struct fw_pkt *fp, *resfp;
1622	struct fw_xfer *xfer;
1623	struct fw_bind *bind;
1624	struct firewire_softc *sc;
1625	int s;
1626#if 0
1627	{
1628		u_int32_t *qld;
1629		int i;
1630		qld = (u_int32_t *)buf;
1631		printf("spd %d len:%d\n", spd, len);
1632		for( i = 0 ; i <= len && i < 32; i+= 4){
1633			printf("0x%08x ", ntohl(qld[i/4]));
1634			if((i % 16) == 15) printf("\n");
1635		}
1636		if((i % 16) != 15) printf("\n");
1637	}
1638#endif
1639	fp = (struct fw_pkt *)(buf + off);
1640	switch(fp->mode.common.tcode){
1641	case FWTCODE_WRES:
1642	case FWTCODE_RRESQ:
1643	case FWTCODE_RRESB:
1644	case FWTCODE_LRES:
1645		xfer = fw_tl2xfer(fc, ntohs(fp->mode.hdr.src),
1646					fp->mode.hdr.tlrt >> 2);
1647		if(xfer == NULL) {
1648			printf("fw_rcv: unknown response "
1649					"tcode=%d src=0x%x tl=%x rt=%d data=0x%x\n",
1650					fp->mode.common.tcode,
1651					ntohs(fp->mode.hdr.src),
1652					fp->mode.hdr.tlrt >> 2,
1653					fp->mode.hdr.tlrt & 3,
1654					fp->mode.rresq.data);
1655#if 1
1656			printf("try ad-hoc work around!!\n");
1657			xfer = fw_tl2xfer(fc, ntohs(fp->mode.hdr.src),
1658					(fp->mode.hdr.tlrt >> 2)^3);
1659			if (xfer == NULL) {
1660				printf("no use...\n");
1661				goto err;
1662			}
1663#else
1664			goto err;
1665#endif
1666		}
1667		switch(xfer->act_type){
1668		case FWACT_XFER:
1669			if((xfer->sub >= 0) &&
1670				((fc->ir[xfer->sub]->flag & FWXFERQ_MODEMASK ) == 0)){
1671				xfer->resp = EINVAL;
1672				fw_xfer_done(xfer);
1673				goto err;
1674			}
1675			xfer->recv.len = len;
1676			xfer->recv.off = off;
1677			xfer->recv.buf = buf;
1678			xfer->resp = 0;
1679			fw_xfer_done(xfer);
1680			return;
1681			break;
1682		case FWACT_CH:
1683		default:
1684			goto err;
1685			break;
1686		}
1687		break;
1688	case FWTCODE_WREQQ:
1689	case FWTCODE_WREQB:
1690	case FWTCODE_RREQQ:
1691	case FWTCODE_RREQB:
1692	case FWTCODE_LREQ:
1693		bind = fw_bindlookup(fc, ntohs(fp->mode.rreqq.dest_hi),
1694			ntohl(fp->mode.rreqq.dest_lo));
1695		if(bind == NULL){
1696#if __FreeBSD_version >= 500000
1697			printf("Unknown service addr 0x%08x:0x%08x tcode=%x\n",
1698#else
1699			printf("Unknown service addr 0x%08x:0x%08lx tcode=%x\n",
1700#endif
1701				ntohs(fp->mode.rreqq.dest_hi),
1702				ntohl(fp->mode.rreqq.dest_lo),
1703				fp->mode.common.tcode);
1704			if (fc->status == FWBUSRESET) {
1705				printf("fw_rcv: cannot response(bus reset)!\n");
1706				goto err;
1707			}
1708			xfer = fw_xfer_alloc();
1709			if(xfer == NULL){
1710				return;
1711			}
1712			xfer->spd = spd;
1713			xfer->send.buf = malloc(16, M_DEVBUF, M_NOWAIT);
1714			resfp = (struct fw_pkt *)xfer->send.buf;
1715			switch(fp->mode.common.tcode){
1716			case FWTCODE_WREQQ:
1717			case FWTCODE_WREQB:
1718				resfp->mode.hdr.tcode = FWTCODE_WRES;
1719				xfer->send.len = 12;
1720				break;
1721			case FWTCODE_RREQQ:
1722				resfp->mode.hdr.tcode = FWTCODE_RRESQ;
1723				xfer->send.len = 16;
1724				break;
1725			case FWTCODE_RREQB:
1726				resfp->mode.hdr.tcode = FWTCODE_RRESB;
1727				xfer->send.len = 16;
1728				break;
1729			case FWTCODE_LREQ:
1730				resfp->mode.hdr.tcode = FWTCODE_LRES;
1731				xfer->send.len = 16;
1732				break;
1733			}
1734			resfp->mode.hdr.dst = fp->mode.hdr.src;
1735			resfp->mode.hdr.tlrt = fp->mode.hdr.tlrt;
1736			resfp->mode.hdr.pri = fp->mode.hdr.pri;
1737			resfp->mode.rresb.rtcode = 7;
1738			resfp->mode.rresb.extcode = 0;
1739			resfp->mode.rresb.len = 0;
1740/*
1741			xfer->act.hand = fw_asy_callback;
1742*/
1743			xfer->act.hand = fw_xfer_free;
1744			if(fw_asyreq(fc, -1, xfer)){
1745				fw_xfer_free( xfer);
1746				return;
1747			}
1748			goto err;
1749		}
1750		switch(bind->xfer->act_type){
1751		case FWACT_XFER:
1752			xfer = fw_xfer_alloc();
1753			if(xfer == NULL) goto err;
1754			xfer->fc = bind->xfer->fc;
1755			xfer->sc = bind->xfer->sc;
1756			xfer->recv.buf = buf;
1757			xfer->recv.len = len;
1758			xfer->recv.off = off;
1759			xfer->spd = spd;
1760			xfer->act.hand = bind->xfer->act.hand;
1761			if (fc->status != FWBUSRESET)
1762				xfer->act.hand(xfer);
1763			else
1764				STAILQ_INSERT_TAIL(&fc->pending, xfer, link);
1765			return;
1766			break;
1767		case FWACT_CH:
1768			if(fc->ir[bind->xfer->sub]->queued >=
1769				fc->ir[bind->xfer->sub]->maxq){
1770				device_printf(fc->bdev,
1771					"Discard a packet %x %d\n",
1772					bind->xfer->sub,
1773					fc->ir[bind->xfer->sub]->queued);
1774				goto err;
1775			}
1776			xfer = fw_xfer_alloc();
1777			if(xfer == NULL) goto err;
1778			xfer->recv.buf = buf;
1779			xfer->recv.len = len;
1780			xfer->recv.off = off;
1781			xfer->spd = spd;
1782			s = splfw();
1783			fc->ir[bind->xfer->sub]->queued++;
1784			STAILQ_INSERT_TAIL(&fc->ir[bind->xfer->sub]->q, xfer, link);
1785			splx(s);
1786
1787			wakeup((caddr_t)fc->ir[bind->xfer->sub]);
1788
1789			return;
1790			break;
1791		default:
1792			goto err;
1793			break;
1794		}
1795		break;
1796	case FWTCODE_STREAM:
1797	{
1798		struct fw_xferq *xferq;
1799
1800		xferq = fc->ir[sub];
1801#if 0
1802		printf("stream rcv dma %d len %d off %d spd %d\n",
1803			sub, len, off, spd);
1804#endif
1805		if(xferq->queued >= xferq->maxq) {
1806			printf("receive queue is full\n");
1807			goto err;
1808		}
1809		xfer = fw_xfer_alloc();
1810		if(xfer == NULL) goto err;
1811		xfer->recv.buf = buf;
1812		xfer->recv.len = len;
1813		xfer->recv.off = off;
1814		xfer->spd = spd;
1815		s = splfw();
1816		xferq->queued++;
1817		STAILQ_INSERT_TAIL(&xferq->q, xfer, link);
1818		splx(s);
1819		sc = device_get_softc(fc->bdev);
1820#if __FreeBSD_version >= 500000
1821		if (SEL_WAITING(&xferq->rsel))
1822#else
1823		if (&xferq->rsel.si_pid != 0)
1824#endif
1825			selwakeup(&xferq->rsel);
1826		if (xferq->flag & FWXFERQ_WAKEUP) {
1827			xferq->flag &= ~FWXFERQ_WAKEUP;
1828			wakeup((caddr_t)xferq);
1829		}
1830		if (xferq->flag & FWXFERQ_HANDLER) {
1831			xferq->hand(xferq);
1832		}
1833		return;
1834		break;
1835	}
1836	default:
1837		printf("fw_rcv: unknow tcode\n");
1838		break;
1839	}
1840err:
1841	free(buf, M_DEVBUF);
1842}
1843
1844/*
1845 * Post process for Bus Manager election process.
1846 */
1847static void
1848fw_try_bmr_callback(struct fw_xfer *xfer)
1849{
1850	struct fw_pkt *rfp;
1851	struct firewire_comm *fc;
1852	int bmr;
1853
1854	if (xfer == NULL)
1855		return;
1856	fc = xfer->fc;
1857	if (xfer->resp != 0)
1858		goto error;
1859	if (xfer->send.buf == NULL)
1860		goto error;
1861	if (xfer->recv.buf == NULL)
1862		goto error;
1863	rfp = (struct fw_pkt *)xfer->recv.buf;
1864	if (rfp->mode.lres.rtcode != FWRCODE_COMPLETE)
1865		goto error;
1866
1867	bmr = ntohl(rfp->mode.lres.payload[0]);
1868	if (bmr == 0x3f)
1869		bmr = fc->nodeid;
1870
1871	CSRARC(fc, BUS_MGR_ID) = fc->set_bmr(fc, bmr & 0x3f);
1872	device_printf(fc->bdev, "new bus manager %d ",
1873		CSRARC(fc, BUS_MGR_ID));
1874	if(bmr == fc->nodeid){
1875		printf("(me)\n");
1876		fw_bmr(fc);
1877	}else{
1878		printf("\n");
1879	}
1880error:
1881	fw_xfer_free(xfer);
1882}
1883
1884/*
1885 * To candidate Bus Manager election process.
1886 */
1887void
1888fw_try_bmr(void *arg)
1889{
1890	struct fw_xfer *xfer;
1891	struct firewire_comm *fc = (struct firewire_comm *)arg;
1892	struct fw_pkt *fp;
1893	int err = 0;
1894
1895	xfer = fw_xfer_alloc();
1896	if(xfer == NULL){
1897		return;
1898	}
1899	xfer->send.len = 24;
1900	xfer->spd = 0;
1901	xfer->send.buf = malloc(24, M_DEVBUF, M_NOWAIT);
1902	if(xfer->send.buf == NULL){
1903		fw_xfer_free( xfer);
1904		return;
1905	}
1906
1907	fc->status = FWBUSMGRELECT;
1908
1909	xfer->send.off = 0;
1910	fp = (struct fw_pkt *)xfer->send.buf;
1911	fp->mode.lreq.dest_hi = htons(0xffff);
1912	fp->mode.lreq.tlrt = 0;
1913	fp->mode.lreq.tcode = FWTCODE_LREQ;
1914	fp->mode.lreq.pri = 0;
1915	fp->mode.lreq.src = 0;
1916	fp->mode.lreq.len = htons(8);
1917	fp->mode.lreq.extcode = htons(FW_LREQ_CMPSWAP);
1918	xfer->dst = FWLOCALBUS | fc->irm;
1919	fp->mode.lreq.dst = htons(xfer->dst);
1920	fp->mode.lreq.dest_lo = htonl(0xf0000000 | BUS_MGR_ID);
1921	fp->mode.lreq.payload[0] = htonl(0x3f);
1922	fp->mode.lreq.payload[1] = htonl(fc->nodeid);
1923	xfer->act_type = FWACT_XFER;
1924	xfer->act.hand = fw_try_bmr_callback;
1925
1926	err = fw_asyreq(fc, -1, xfer);
1927	if(err){
1928		fw_xfer_free( xfer);
1929		return;
1930	}
1931	return;
1932}
1933
1934#ifdef FW_VMACCESS
1935/*
1936 * Software implementation for physical memory block access.
1937 * XXX:Too slow, usef for debug purpose only.
1938 */
1939static void
1940fw_vmaccess(struct fw_xfer *xfer){
1941	struct fw_pkt *rfp, *sfp = NULL;
1942	u_int32_t *ld = (u_int32_t *)(xfer->recv.buf + xfer->recv.off);
1943
1944	printf("vmaccess spd:%2x len:%03x %d data:%08x %08x %08x %08x\n",
1945			xfer->spd, xfer->recv.len, xfer->recv.off, ntohl(ld[0]), ntohl(ld[1]), ntohl(ld[2]), ntohl(ld[3]));
1946	printf("vmaccess          data:%08x %08x %08x %08x\n", ntohl(ld[4]), ntohl(ld[5]), ntohl(ld[6]), ntohl(ld[7]));
1947	if(xfer->resp != 0){
1948		fw_xfer_free( xfer);
1949		return;
1950	}
1951	if(xfer->recv.buf == NULL){
1952		fw_xfer_free( xfer);
1953		return;
1954	}
1955	rfp = (struct fw_pkt *)xfer->recv.buf;
1956	switch(rfp->mode.hdr.tcode){
1957		/* XXX need fix for 64bit arch */
1958		case FWTCODE_WREQB:
1959			xfer->send.buf = malloc(12, M_DEVBUF, M_NOWAIT);
1960			xfer->send.len = 12;
1961			sfp = (struct fw_pkt *)xfer->send.buf;
1962			bcopy(rfp->mode.wreqb.payload,
1963				(caddr_t)ntohl(rfp->mode.wreqb.dest_lo), ntohs(rfp->mode.wreqb.len));
1964			sfp->mode.wres.tcode = FWTCODE_WRES;
1965			sfp->mode.wres.rtcode = 0;
1966			break;
1967		case FWTCODE_WREQQ:
1968			xfer->send.buf = malloc(12, M_DEVBUF, M_NOWAIT);
1969			xfer->send.len = 12;
1970			sfp->mode.wres.tcode = FWTCODE_WRES;
1971			*((u_int32_t *)(ntohl(rfp->mode.wreqb.dest_lo))) = rfp->mode.wreqq.data;
1972			sfp->mode.wres.rtcode = 0;
1973			break;
1974		case FWTCODE_RREQB:
1975			xfer->send.buf = malloc(16 + rfp->mode.rreqb.len, M_DEVBUF, M_NOWAIT);
1976			xfer->send.len = 16 + ntohs(rfp->mode.rreqb.len);
1977			sfp = (struct fw_pkt *)xfer->send.buf;
1978			bcopy((caddr_t)ntohl(rfp->mode.rreqb.dest_lo),
1979				sfp->mode.rresb.payload, (u_int16_t)ntohs(rfp->mode.rreqb.len));
1980			sfp->mode.rresb.tcode = FWTCODE_RRESB;
1981			sfp->mode.rresb.len = rfp->mode.rreqb.len;
1982			sfp->mode.rresb.rtcode = 0;
1983			sfp->mode.rresb.extcode = 0;
1984			break;
1985		case FWTCODE_RREQQ:
1986			xfer->send.buf = malloc(16, M_DEVBUF, M_NOWAIT);
1987			xfer->send.len = 16;
1988			sfp = (struct fw_pkt *)xfer->send.buf;
1989			sfp->mode.rresq.data = *(u_int32_t *)(ntohl(rfp->mode.rreqq.dest_lo));
1990			sfp->mode.wres.tcode = FWTCODE_RRESQ;
1991			sfp->mode.rresb.rtcode = 0;
1992			break;
1993		default:
1994			fw_xfer_free( xfer);
1995			return;
1996	}
1997	xfer->send.off = 0;
1998	sfp->mode.hdr.dst = rfp->mode.hdr.src;
1999	xfer->dst = ntohs(rfp->mode.hdr.src);
2000	xfer->act.hand = fw_xfer_free;
2001	xfer->retry_req = fw_asybusy;
2002
2003	sfp->mode.hdr.tlrt = rfp->mode.hdr.tlrt;
2004	sfp->mode.hdr.pri = 0;
2005
2006	fw_asyreq(xfer->fc, -1, xfer);
2007/**/
2008	return;
2009}
2010#endif
2011
2012/*
2013 * CRC16 check-sum for IEEE1394 register blocks.
2014 */
2015u_int16_t
2016fw_crc16(u_int32_t *ptr, u_int32_t len){
2017	u_int32_t i, sum, crc = 0;
2018	int shift;
2019	len = (len + 3) & ~3;
2020	for(i = 0 ; i < len ; i+= 4){
2021		for( shift = 28 ; shift >= 0 ; shift -= 4){
2022			sum = ((crc >> 12) ^ (ptr[i/4] >> shift)) & 0xf;
2023			crc = (crc << 4) ^ ( sum << 12 ) ^ ( sum << 5) ^ sum;
2024		}
2025		crc &= 0xffff;
2026	}
2027	return((u_int16_t) crc);
2028}
2029
2030int
2031fw_bmr(struct firewire_comm *fc)
2032{
2033	struct fw_device fwdev;
2034	int cmstr;
2035
2036	/* XXX Assume that the current root node is cycle master capable */
2037	cmstr = fc->max_node;
2038	/* If I am the bus manager, optimize gapcount */
2039	if(fc->max_hop <= MAX_GAPHOP ){
2040		fw_phy_config(fc, (fc->max_node > 0)?cmstr:-1,
2041						gap_cnt[fc->max_hop]);
2042	}
2043	/* If we are the cycle master, nothing to do */
2044	if (cmstr == fc->nodeid)
2045		return 0;
2046	/* Bus probe has not finished, make dummy fwdev for cmstr */
2047	bzero(&fwdev, sizeof(fwdev));
2048	fwdev.fc = fc;
2049	fwdev.dst = cmstr;
2050	fwdev.speed = 0;
2051	fwdev.maxrec = 8; /* 512 */
2052	fwdev.status = FWDEVINIT;
2053	/* Set cmstr bit on the cycle master */
2054	fwmem_write_quad(&fwdev, NULL, 0/*spd*/,
2055		0xffff, 0xf0000000 | STATE_SET, 1 << 16,
2056		fw_asy_callback_free);
2057
2058	return 0;
2059}
2060
2061DRIVER_MODULE(firewire,fwohci,firewire_driver,firewire_devclass,0,0);
2062MODULE_VERSION(firewire, 1);
2063