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