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