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