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