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