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