Home | History | Annotate | Line # | Download | only in ieee1394
fwohci.c revision 1.88.2.5
      1  1.88.2.5   yamt /*	$NetBSD: fwohci.c,v 1.88.2.5 2007/11/15 11:44:12 yamt Exp $	*/
      2      1.14  enami 
      3       1.1   matt /*-
      4  1.88.2.1   yamt  * Copyright (c) 2003 Hidetoshi Shimokawa
      5  1.88.2.1   yamt  * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
      6       1.1   matt  * All rights reserved.
      7       1.1   matt  *
      8       1.1   matt  * Redistribution and use in source and binary forms, with or without
      9       1.1   matt  * modification, are permitted provided that the following conditions
     10       1.1   matt  * are met:
     11       1.1   matt  * 1. Redistributions of source code must retain the above copyright
     12       1.1   matt  *    notice, this list of conditions and the following disclaimer.
     13       1.1   matt  * 2. Redistributions in binary form must reproduce the above copyright
     14       1.1   matt  *    notice, this list of conditions and the following disclaimer in the
     15       1.1   matt  *    documentation and/or other materials provided with the distribution.
     16       1.1   matt  * 3. All advertising materials mentioning features or use of this software
     17  1.88.2.1   yamt  *    must display the acknowledgement as bellow:
     18  1.88.2.1   yamt  *
     19  1.88.2.1   yamt  *    This product includes software developed by K. Kobayashi and H. Shimokawa
     20       1.1   matt  *
     21  1.88.2.1   yamt  * 4. The name of the author may not be used to endorse or promote products
     22  1.88.2.1   yamt  *    derived from this software without specific prior written permission.
     23  1.88.2.1   yamt  *
     24  1.88.2.1   yamt  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     25  1.88.2.1   yamt  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     26  1.88.2.1   yamt  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     27  1.88.2.1   yamt  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     28  1.88.2.1   yamt  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     29  1.88.2.1   yamt  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     30  1.88.2.1   yamt  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     31  1.88.2.1   yamt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     32  1.88.2.1   yamt  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     33  1.88.2.1   yamt  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     34       1.1   matt  * POSSIBILITY OF SUCH DAMAGE.
     35  1.88.2.1   yamt  *
     36  1.88.2.5   yamt  * $FreeBSD: src/sys/dev/firewire/fwohci.c,v 1.93 2007/06/08 09:04:30 simokawa Exp $
     37  1.88.2.1   yamt  *
     38       1.1   matt  */
     39  1.88.2.5   yamt #include <sys/cdefs.h>
     40  1.88.2.5   yamt __KERNEL_RCSID(0, "$NetBSD: fwohci.c,v 1.88.2.5 2007/11/15 11:44:12 yamt Exp $");
     41       1.1   matt 
     42  1.88.2.1   yamt #define ATRQ_CH 0
     43  1.88.2.1   yamt #define ATRS_CH 1
     44  1.88.2.1   yamt #define ARRQ_CH 2
     45  1.88.2.1   yamt #define ARRS_CH 3
     46  1.88.2.1   yamt #define ITX_CH 4
     47  1.88.2.1   yamt #define IRX_CH 0x24
     48       1.3   onoe 
     49  1.88.2.1   yamt #if defined(__FreeBSD__)
     50  1.88.2.1   yamt #include <sys/param.h>
     51  1.88.2.1   yamt #include <sys/systm.h>
     52  1.88.2.1   yamt #include <sys/mbuf.h>
     53  1.88.2.1   yamt #include <sys/malloc.h>
     54  1.88.2.1   yamt #include <sys/sockio.h>
     55  1.88.2.1   yamt #include <sys/sysctl.h>
     56  1.88.2.1   yamt #include <sys/bus.h>
     57  1.88.2.1   yamt #include <sys/kernel.h>
     58  1.88.2.1   yamt #include <sys/conf.h>
     59  1.88.2.1   yamt #include <sys/endian.h>
     60  1.88.2.5   yamt #include <sys/kdb.h>
     61      1.45  lukem 
     62  1.88.2.5   yamt #include <machine/bus.h>
     63      1.40   haya 
     64  1.88.2.1   yamt #if defined(__DragonFly__) || __FreeBSD_version < 500000
     65  1.88.2.1   yamt #include <machine/clock.h>		/* for DELAY() */
     66  1.88.2.1   yamt #endif
     67       1.3   onoe 
     68  1.88.2.1   yamt #ifdef __DragonFly__
     69  1.88.2.1   yamt #include "fw_port.h"
     70  1.88.2.1   yamt #include "firewire.h"
     71  1.88.2.1   yamt #include "firewirereg.h"
     72  1.88.2.1   yamt #include "fwdma.h"
     73  1.88.2.1   yamt #include "fwohcireg.h"
     74  1.88.2.1   yamt #include "fwohcivar.h"
     75  1.88.2.1   yamt #include "firewire_phy.h"
     76  1.88.2.1   yamt #else
     77  1.88.2.1   yamt #include <dev/firewire/fw_port.h>
     78  1.88.2.1   yamt #include <dev/firewire/firewire.h>
     79  1.88.2.1   yamt #include <dev/firewire/firewirereg.h>
     80  1.88.2.1   yamt #include <dev/firewire/fwdma.h>
     81  1.88.2.1   yamt #include <dev/firewire/fwohcireg.h>
     82  1.88.2.1   yamt #include <dev/firewire/fwohcivar.h>
     83  1.88.2.1   yamt #include <dev/firewire/firewire_phy.h>
     84  1.88.2.1   yamt #endif
     85  1.88.2.1   yamt #elif defined(__NetBSD__)
     86       1.1   matt #include <sys/param.h>
     87       1.1   matt #include <sys/device.h>
     88  1.88.2.1   yamt #include <sys/errno.h>
     89  1.88.2.1   yamt #include <sys/conf.h>
     90       1.7   onoe #include <sys/kernel.h>
     91       1.3   onoe #include <sys/malloc.h>
     92       1.3   onoe #include <sys/mbuf.h>
     93  1.88.2.1   yamt #include <sys/proc.h>
     94  1.88.2.1   yamt #include <sys/reboot.h>
     95  1.88.2.1   yamt #include <sys/sysctl.h>
     96  1.88.2.1   yamt #include <sys/systm.h>
     97       1.7   onoe 
     98  1.88.2.4   yamt #include <sys/bus.h>
     99       1.1   matt 
    100  1.88.2.1   yamt #include <dev/ieee1394/fw_port.h>
    101  1.88.2.1   yamt #include <dev/ieee1394/firewire.h>
    102  1.88.2.1   yamt #include <dev/ieee1394/firewirereg.h>
    103  1.88.2.1   yamt #include <dev/ieee1394/fwdma.h>
    104       1.1   matt #include <dev/ieee1394/fwohcireg.h>
    105       1.1   matt #include <dev/ieee1394/fwohcivar.h>
    106  1.88.2.1   yamt #include <dev/ieee1394/firewire_phy.h>
    107  1.88.2.2   yamt 
    108  1.88.2.2   yamt #include "ioconf.h"
    109       1.5   matt #endif
    110      1.24    jmc 
    111  1.88.2.1   yamt #undef OHCI_DEBUG
    112       1.5   matt 
    113  1.88.2.1   yamt static int nocyclemaster = 0;
    114  1.88.2.5   yamt int firewire_phydma_enable = 1;
    115  1.88.2.1   yamt #if defined(__FreeBSD__)
    116  1.88.2.1   yamt SYSCTL_DECL(_hw_firewire);
    117  1.88.2.1   yamt SYSCTL_INT(_hw_firewire, OID_AUTO, nocyclemaster, CTLFLAG_RW, &nocyclemaster, 0,
    118  1.88.2.1   yamt 	"Do not send cycle start packets");
    119  1.88.2.5   yamt SYSCTL_INT(_hw_firewire, OID_AUTO, phydma_enable, CTLFLAG_RW,
    120  1.88.2.5   yamt 	&firewire_phydma_enable, 1, "Allow physical request DMA from firewire");
    121  1.88.2.5   yamt TUNABLE_INT("hw.firewire.phydma_enable", &firewire_phydma_enable);
    122  1.88.2.1   yamt #elif defined(__NetBSD__)
    123  1.88.2.1   yamt /*
    124  1.88.2.1   yamt  * Setup sysctl(3) MIB, hw.fwohci.*
    125  1.88.2.1   yamt  *
    126  1.88.2.1   yamt  * TBD condition CTLFLAG_PERMANENT on being an LKM or not
    127  1.88.2.1   yamt  */
    128  1.88.2.1   yamt SYSCTL_SETUP(sysctl_fwohci, "sysctl fwohci(4) subtree setup")
    129  1.88.2.1   yamt {
    130  1.88.2.5   yamt 	int rc, fwohci_node_num;
    131  1.88.2.1   yamt 	const struct sysctlnode *node;
    132  1.88.2.1   yamt 
    133  1.88.2.1   yamt 	if ((rc = sysctl_createv(clog, 0, NULL, NULL,
    134  1.88.2.1   yamt 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
    135  1.88.2.1   yamt 	    NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0) {
    136  1.88.2.1   yamt 		goto err;
    137  1.88.2.1   yamt 	}
    138  1.88.2.1   yamt 
    139  1.88.2.1   yamt 	if ((rc = sysctl_createv(clog, 0, NULL, &node,
    140  1.88.2.1   yamt 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "fwohci",
    141  1.88.2.1   yamt 	    SYSCTL_DESCR("fwohci controls"),
    142  1.88.2.1   yamt 	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0) {
    143  1.88.2.1   yamt 		goto err;
    144  1.88.2.1   yamt 	}
    145  1.88.2.5   yamt 	fwohci_node_num = node->sysctl_num;
    146  1.88.2.1   yamt 
    147  1.88.2.1   yamt 	/* fwohci no cyclemaster flag */
    148  1.88.2.1   yamt 	if ((rc = sysctl_createv(clog, 0, NULL, &node,
    149  1.88.2.1   yamt 	    CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
    150  1.88.2.1   yamt 	    "nocyclemaster", SYSCTL_DESCR("Do not send cycle start packets"),
    151  1.88.2.1   yamt 	    NULL, 0, &nocyclemaster,
    152  1.88.2.5   yamt 	    0, CTL_HW, fwohci_node_num, CTL_CREATE, CTL_EOL)) != 0) {
    153  1.88.2.5   yamt 		goto err;
    154  1.88.2.5   yamt 	}
    155  1.88.2.5   yamt 
    156  1.88.2.5   yamt 	/* fwohci physical request DMA enable */
    157  1.88.2.5   yamt 	if ((rc = sysctl_createv(clog, 0, NULL, &node,
    158  1.88.2.5   yamt 	    CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, "phydma_enable",
    159  1.88.2.5   yamt 	    SYSCTL_DESCR("Allow physical request DMA from firewire"),
    160  1.88.2.5   yamt 	    NULL, 0, &firewire_phydma_enable,
    161  1.88.2.5   yamt 	    0, CTL_HW, fwohci_node_num, CTL_CREATE, CTL_EOL)) != 0) {
    162  1.88.2.1   yamt 		goto err;
    163  1.88.2.1   yamt 	}
    164  1.88.2.1   yamt 	return;
    165  1.88.2.1   yamt 
    166  1.88.2.1   yamt err:
    167  1.88.2.1   yamt 	printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
    168  1.88.2.1   yamt }
    169  1.88.2.1   yamt #endif
    170  1.88.2.1   yamt 
    171  1.88.2.1   yamt static const char * const dbcode[16] = {"OUTM", "OUTL","INPM","INPL",
    172  1.88.2.1   yamt 		"STOR","LOAD","NOP ","STOP",
    173  1.88.2.1   yamt 		"", "", "", "", "", "", "", ""};
    174  1.88.2.1   yamt 
    175  1.88.2.1   yamt static const char * const dbkey[8] = {"ST0", "ST1","ST2","ST3",
    176  1.88.2.1   yamt 		"UNDEF","REG","SYS","DEV"};
    177  1.88.2.1   yamt static const char * const dbcond[4] = {"NEV","C=1", "C=0", "ALL"};
    178  1.88.2.1   yamt static const char * const fwohcicode[32] = {
    179  1.88.2.1   yamt 	"No stat","Undef","long","miss Ack err",
    180  1.88.2.5   yamt 	"FIFO underrun","FIFO overrun","desc err", "data read err",
    181  1.88.2.1   yamt 	"data write err","bus reset","timeout","tcode err",
    182  1.88.2.1   yamt 	"Undef","Undef","unknown event","flushed",
    183  1.88.2.1   yamt 	"Undef","ack complete","ack pend","Undef",
    184  1.88.2.1   yamt 	"ack busy_X","ack busy_A","ack busy_B","Undef",
    185  1.88.2.1   yamt 	"Undef","Undef","Undef","ack tardy",
    186  1.88.2.1   yamt 	"Undef","ack data_err","ack type_err",""};
    187  1.88.2.1   yamt 
    188  1.88.2.1   yamt #define MAX_SPEED 3
    189  1.88.2.1   yamt extern const char *fw_linkspeed[];
    190  1.88.2.1   yamt static uint32_t const tagbit[4] = { 1 << 28, 1 << 29, 1 << 30, 1 << 31};
    191  1.88.2.1   yamt 
    192  1.88.2.1   yamt static const struct tcode_info tinfo[] = {
    193  1.88.2.5   yamt /*		hdr_len block 	flag	valid_response*/
    194  1.88.2.5   yamt /* 0 WREQQ  */ {16,	FWTI_REQ | FWTI_TLABEL, FWTCODE_WRES},
    195  1.88.2.5   yamt /* 1 WREQB  */ {16,	FWTI_REQ | FWTI_TLABEL | FWTI_BLOCK_ASY, FWTCODE_WRES},
    196  1.88.2.5   yamt /* 2 WRES   */ {12,	FWTI_RES, 0xff},
    197  1.88.2.5   yamt /* 3 XXX    */ { 0,	0, 0xff},
    198  1.88.2.5   yamt /* 4 RREQQ  */ {12,	FWTI_REQ | FWTI_TLABEL, FWTCODE_RRESQ},
    199  1.88.2.5   yamt /* 5 RREQB  */ {16,	FWTI_REQ | FWTI_TLABEL, FWTCODE_RRESB},
    200  1.88.2.5   yamt /* 6 RRESQ  */ {16,	FWTI_RES, 0xff},
    201  1.88.2.5   yamt /* 7 RRESB  */ {16,	FWTI_RES | FWTI_BLOCK_ASY, 0xff},
    202  1.88.2.5   yamt /* 8 CYCS   */ { 0,	0, 0xff},
    203  1.88.2.5   yamt /* 9 LREQ   */ {16,	FWTI_REQ | FWTI_TLABEL | FWTI_BLOCK_ASY, FWTCODE_LRES},
    204  1.88.2.5   yamt /* a STREAM */ { 4,	FWTI_REQ | FWTI_BLOCK_STR, 0xff},
    205  1.88.2.5   yamt /* b LRES   */ {16,	FWTI_RES | FWTI_BLOCK_ASY, 0xff},
    206  1.88.2.5   yamt /* c XXX    */ { 0,	0, 0xff},
    207  1.88.2.5   yamt /* d XXX    */ { 0, 	0, 0xff},
    208  1.88.2.5   yamt /* e PHY    */ {12,	FWTI_REQ, 0xff},
    209  1.88.2.5   yamt /* f XXX    */ { 0,	0, 0xff}
    210  1.88.2.1   yamt };
    211       1.8   onoe 
    212  1.88.2.1   yamt #define OHCI_WRITE_SIGMASK 0xffff0000
    213  1.88.2.1   yamt #define OHCI_READ_SIGMASK 0xffff0000
    214      1.62   haya 
    215  1.88.2.1   yamt #define OWRITE(sc, r, x) bus_space_write_4((sc)->bst, (sc)->bsh, (r), (x))
    216  1.88.2.1   yamt #define OREAD(sc, r) bus_space_read_4((sc)->bst, (sc)->bsh, (r))
    217      1.62   haya 
    218  1.88.2.1   yamt static void fwohci_ibr (struct firewire_comm *);
    219  1.88.2.1   yamt static void fwohci_db_init (struct fwohci_softc *, struct fwohci_dbch *);
    220  1.88.2.1   yamt static void fwohci_db_free (struct fwohci_dbch *);
    221  1.88.2.1   yamt static void fwohci_arcv (struct fwohci_softc *, struct fwohci_dbch *, int);
    222  1.88.2.1   yamt static void fwohci_txd (struct fwohci_softc *, struct fwohci_dbch *);
    223  1.88.2.1   yamt static void fwohci_start_atq (struct firewire_comm *);
    224  1.88.2.1   yamt static void fwohci_start_ats (struct firewire_comm *);
    225  1.88.2.1   yamt static void fwohci_start (struct fwohci_softc *, struct fwohci_dbch *);
    226  1.88.2.1   yamt static uint32_t fwphy_wrdata ( struct fwohci_softc *, uint32_t, uint32_t);
    227  1.88.2.1   yamt static uint32_t fwphy_rddata ( struct fwohci_softc *, uint32_t);
    228  1.88.2.1   yamt static int fwohci_rx_enable (struct fwohci_softc *, struct fwohci_dbch *);
    229  1.88.2.1   yamt static int fwohci_tx_enable (struct fwohci_softc *, struct fwohci_dbch *);
    230  1.88.2.1   yamt static int fwohci_irx_enable (struct firewire_comm *, int);
    231  1.88.2.1   yamt static int fwohci_irx_disable (struct firewire_comm *, int);
    232  1.88.2.1   yamt #if BYTE_ORDER == BIG_ENDIAN
    233  1.88.2.1   yamt static void fwohci_irx_post (struct firewire_comm *, uint32_t *);
    234  1.88.2.1   yamt #endif
    235  1.88.2.1   yamt static int fwohci_itxbuf_enable (struct firewire_comm *, int);
    236  1.88.2.1   yamt static int fwohci_itx_disable (struct firewire_comm *, int);
    237  1.88.2.1   yamt static void fwohci_timeout (void *);
    238  1.88.2.1   yamt static void fwohci_set_intr (struct firewire_comm *, int);
    239  1.88.2.1   yamt 
    240  1.88.2.1   yamt static int fwohci_add_rx_buf (struct fwohci_dbch *, struct fwohcidb_tr *, int, struct fwdma_alloc *);
    241  1.88.2.1   yamt static int fwohci_add_tx_buf (struct fwohci_dbch *, struct fwohcidb_tr *, int);
    242  1.88.2.1   yamt static void	dump_db (struct fwohci_softc *, uint32_t);
    243  1.88.2.1   yamt static void 	print_db (struct fwohcidb_tr *, struct fwohcidb *, uint32_t , uint32_t);
    244  1.88.2.1   yamt static void	dump_dma (struct fwohci_softc *, uint32_t);
    245  1.88.2.1   yamt static uint32_t fwohci_cyctimer (struct firewire_comm *);
    246  1.88.2.1   yamt static void fwohci_rbuf_update (struct fwohci_softc *, int);
    247  1.88.2.1   yamt static void fwohci_tbuf_update (struct fwohci_softc *, int);
    248  1.88.2.1   yamt void fwohci_txbufdb (struct fwohci_softc *, int , struct fw_bulkxfer *);
    249  1.88.2.5   yamt static void fwohci_task_busreset(void *, int);
    250  1.88.2.5   yamt static void fwohci_task_sid(void *, int);
    251  1.88.2.5   yamt static void fwohci_task_dma(void *, int);
    252  1.88.2.1   yamt #if defined(__NetBSD__)
    253  1.88.2.1   yamt int fwohci_print(void *, const char *);
    254       1.5   matt #endif
    255       1.5   matt 
    256  1.88.2.1   yamt /*
    257  1.88.2.1   yamt  * memory allocated for DMA programs
    258  1.88.2.1   yamt  */
    259  1.88.2.1   yamt #define DMA_PROG_ALLOC		(8 * PAGE_SIZE)
    260      1.40   haya 
    261  1.88.2.1   yamt #define NDB FWMAXQUEUE
    262  1.88.2.1   yamt 
    263  1.88.2.1   yamt #define	OHCI_VERSION		0x00
    264  1.88.2.1   yamt #define	OHCI_ATRETRY		0x08
    265  1.88.2.1   yamt #define	OHCI_CROMHDR		0x18
    266  1.88.2.1   yamt #define	OHCI_BUS_OPT		0x20
    267  1.88.2.1   yamt #define	OHCI_BUSIRMC		(1 << 31)
    268  1.88.2.1   yamt #define	OHCI_BUSCMC		(1 << 30)
    269  1.88.2.1   yamt #define	OHCI_BUSISC		(1 << 29)
    270  1.88.2.1   yamt #define	OHCI_BUSBMC		(1 << 28)
    271  1.88.2.1   yamt #define	OHCI_BUSPMC		(1 << 27)
    272  1.88.2.1   yamt #define OHCI_BUSFNC		OHCI_BUSIRMC | OHCI_BUSCMC | OHCI_BUSISC |\
    273  1.88.2.1   yamt 				OHCI_BUSBMC | OHCI_BUSPMC
    274  1.88.2.1   yamt 
    275  1.88.2.1   yamt #define	OHCI_EUID_HI		0x24
    276  1.88.2.1   yamt #define	OHCI_EUID_LO		0x28
    277  1.88.2.1   yamt 
    278  1.88.2.1   yamt #define	OHCI_CROMPTR		0x34
    279  1.88.2.1   yamt #define	OHCI_HCCCTL		0x50
    280  1.88.2.1   yamt #define	OHCI_HCCCTLCLR		0x54
    281  1.88.2.1   yamt #define	OHCI_AREQHI		0x100
    282  1.88.2.1   yamt #define	OHCI_AREQHICLR		0x104
    283  1.88.2.1   yamt #define	OHCI_AREQLO		0x108
    284  1.88.2.1   yamt #define	OHCI_AREQLOCLR		0x10c
    285  1.88.2.1   yamt #define	OHCI_PREQHI		0x110
    286  1.88.2.1   yamt #define	OHCI_PREQHICLR		0x114
    287  1.88.2.1   yamt #define	OHCI_PREQLO		0x118
    288  1.88.2.1   yamt #define	OHCI_PREQLOCLR		0x11c
    289  1.88.2.1   yamt #define	OHCI_PREQUPPER		0x120
    290  1.88.2.1   yamt 
    291  1.88.2.1   yamt #define	OHCI_SID_BUF		0x64
    292  1.88.2.1   yamt #define	OHCI_SID_CNT		0x68
    293  1.88.2.1   yamt #define OHCI_SID_ERR		(1 << 31)
    294  1.88.2.1   yamt #define OHCI_SID_CNT_MASK	0xffc
    295  1.88.2.1   yamt 
    296  1.88.2.1   yamt #define	OHCI_IT_STAT		0x90
    297  1.88.2.1   yamt #define	OHCI_IT_STATCLR		0x94
    298  1.88.2.1   yamt #define	OHCI_IT_MASK		0x98
    299  1.88.2.1   yamt #define	OHCI_IT_MASKCLR		0x9c
    300  1.88.2.1   yamt 
    301  1.88.2.1   yamt #define	OHCI_IR_STAT		0xa0
    302  1.88.2.1   yamt #define	OHCI_IR_STATCLR		0xa4
    303  1.88.2.1   yamt #define	OHCI_IR_MASK		0xa8
    304  1.88.2.1   yamt #define	OHCI_IR_MASKCLR		0xac
    305  1.88.2.1   yamt 
    306  1.88.2.1   yamt #define	OHCI_LNKCTL		0xe0
    307  1.88.2.1   yamt #define	OHCI_LNKCTLCLR		0xe4
    308  1.88.2.1   yamt 
    309  1.88.2.1   yamt #define	OHCI_PHYACCESS		0xec
    310  1.88.2.1   yamt #define	OHCI_CYCLETIMER		0xf0
    311  1.88.2.1   yamt 
    312  1.88.2.1   yamt #define	OHCI_DMACTL(off)	(off)
    313  1.88.2.1   yamt #define	OHCI_DMACTLCLR(off)	(off + 4)
    314  1.88.2.1   yamt #define	OHCI_DMACMD(off)	(off + 0xc)
    315  1.88.2.1   yamt #define	OHCI_DMAMATCH(off)	(off + 0x10)
    316  1.88.2.1   yamt 
    317  1.88.2.1   yamt #define OHCI_ATQOFF		0x180
    318  1.88.2.1   yamt #define OHCI_ATQCTL		OHCI_ATQOFF
    319  1.88.2.1   yamt #define OHCI_ATQCTLCLR		(OHCI_ATQOFF + 4)
    320  1.88.2.1   yamt #define OHCI_ATQCMD		(OHCI_ATQOFF + 0xc)
    321  1.88.2.1   yamt #define OHCI_ATQMATCH		(OHCI_ATQOFF + 0x10)
    322  1.88.2.1   yamt 
    323  1.88.2.1   yamt #define OHCI_ATSOFF		0x1a0
    324  1.88.2.1   yamt #define OHCI_ATSCTL		OHCI_ATSOFF
    325  1.88.2.1   yamt #define OHCI_ATSCTLCLR		(OHCI_ATSOFF + 4)
    326  1.88.2.1   yamt #define OHCI_ATSCMD		(OHCI_ATSOFF + 0xc)
    327  1.88.2.1   yamt #define OHCI_ATSMATCH		(OHCI_ATSOFF + 0x10)
    328  1.88.2.1   yamt 
    329  1.88.2.1   yamt #define OHCI_ARQOFF		0x1c0
    330  1.88.2.1   yamt #define OHCI_ARQCTL		OHCI_ARQOFF
    331  1.88.2.1   yamt #define OHCI_ARQCTLCLR		(OHCI_ARQOFF + 4)
    332  1.88.2.1   yamt #define OHCI_ARQCMD		(OHCI_ARQOFF + 0xc)
    333  1.88.2.1   yamt #define OHCI_ARQMATCH		(OHCI_ARQOFF + 0x10)
    334  1.88.2.1   yamt 
    335  1.88.2.1   yamt #define OHCI_ARSOFF		0x1e0
    336  1.88.2.1   yamt #define OHCI_ARSCTL		OHCI_ARSOFF
    337  1.88.2.1   yamt #define OHCI_ARSCTLCLR		(OHCI_ARSOFF + 4)
    338  1.88.2.1   yamt #define OHCI_ARSCMD		(OHCI_ARSOFF + 0xc)
    339  1.88.2.1   yamt #define OHCI_ARSMATCH		(OHCI_ARSOFF + 0x10)
    340  1.88.2.1   yamt 
    341  1.88.2.1   yamt #define OHCI_ITOFF(CH)		(0x200 + 0x10 * (CH))
    342  1.88.2.1   yamt #define OHCI_ITCTL(CH)		(OHCI_ITOFF(CH))
    343  1.88.2.1   yamt #define OHCI_ITCTLCLR(CH)	(OHCI_ITOFF(CH) + 4)
    344  1.88.2.1   yamt #define OHCI_ITCMD(CH)		(OHCI_ITOFF(CH) + 0xc)
    345  1.88.2.1   yamt 
    346  1.88.2.1   yamt #define OHCI_IROFF(CH)		(0x400 + 0x20 * (CH))
    347  1.88.2.1   yamt #define OHCI_IRCTL(CH)		(OHCI_IROFF(CH))
    348  1.88.2.1   yamt #define OHCI_IRCTLCLR(CH)	(OHCI_IROFF(CH) + 4)
    349  1.88.2.1   yamt #define OHCI_IRCMD(CH)		(OHCI_IROFF(CH) + 0xc)
    350  1.88.2.1   yamt #define OHCI_IRMATCH(CH)	(OHCI_IROFF(CH) + 0x10)
    351  1.88.2.1   yamt 
    352  1.88.2.1   yamt #if defined(__FreeBSD__)
    353  1.88.2.1   yamt d_ioctl_t fwohci_ioctl;
    354  1.88.2.1   yamt #elif defined(__NetBSD__)
    355  1.88.2.1   yamt dev_type_ioctl(fwohci_ioctl);
    356  1.88.2.1   yamt #endif
    357  1.88.2.1   yamt 
    358  1.88.2.1   yamt /*
    359  1.88.2.1   yamt  * Communication with PHY device
    360  1.88.2.1   yamt  */
    361  1.88.2.5   yamt /* XXX need lock for phy access */
    362  1.88.2.1   yamt static uint32_t
    363  1.88.2.1   yamt fwphy_wrdata( struct fwohci_softc *sc, uint32_t addr, uint32_t data)
    364  1.88.2.1   yamt {
    365  1.88.2.1   yamt 	uint32_t fun;
    366  1.88.2.1   yamt 
    367  1.88.2.1   yamt 	addr &= 0xf;
    368  1.88.2.1   yamt 	data &= 0xff;
    369  1.88.2.1   yamt 
    370  1.88.2.1   yamt 	fun = (PHYDEV_WRCMD | (addr << PHYDEV_REGADDR) | (data << PHYDEV_WRDATA));
    371  1.88.2.1   yamt 	OWRITE(sc, OHCI_PHYACCESS, fun);
    372  1.88.2.1   yamt 	DELAY(100);
    373  1.88.2.1   yamt 
    374  1.88.2.1   yamt 	return(fwphy_rddata( sc, addr));
    375  1.88.2.1   yamt }
    376  1.88.2.1   yamt 
    377  1.88.2.1   yamt static uint32_t
    378  1.88.2.1   yamt fwohci_set_bus_manager(struct firewire_comm *fc, u_int node)
    379  1.88.2.1   yamt {
    380  1.88.2.1   yamt 	struct fwohci_softc *sc = (struct fwohci_softc *)fc;
    381  1.88.2.1   yamt 	int i;
    382  1.88.2.1   yamt 	uint32_t bm;
    383  1.88.2.1   yamt 
    384  1.88.2.1   yamt #define OHCI_CSR_DATA	0x0c
    385  1.88.2.1   yamt #define OHCI_CSR_COMP	0x10
    386  1.88.2.1   yamt #define OHCI_CSR_CONT	0x14
    387  1.88.2.1   yamt #define OHCI_BUS_MANAGER_ID	0
    388  1.88.2.1   yamt 
    389  1.88.2.1   yamt 	OWRITE(sc, OHCI_CSR_DATA, node);
    390  1.88.2.1   yamt 	OWRITE(sc, OHCI_CSR_COMP, 0x3f);
    391  1.88.2.1   yamt 	OWRITE(sc, OHCI_CSR_CONT, OHCI_BUS_MANAGER_ID);
    392  1.88.2.1   yamt  	for (i = 0; !(OREAD(sc, OHCI_CSR_CONT) & (1<<31)) && (i < 1000); i++)
    393      1.36   onoe 		DELAY(10);
    394  1.88.2.1   yamt 	bm = OREAD(sc, OHCI_CSR_DATA);
    395  1.88.2.1   yamt 	if((bm & 0x3f) == 0x3f)
    396  1.88.2.1   yamt 		bm = node;
    397  1.88.2.1   yamt 	if (firewire_debug)
    398  1.88.2.5   yamt 		fw_printf(sc->fc.dev,
    399  1.88.2.1   yamt 			"fw_set_bus_manager: %d->%d (loop=%d)\n", bm, node, i);
    400  1.88.2.1   yamt 
    401  1.88.2.1   yamt 	return(bm);
    402  1.88.2.1   yamt }
    403  1.88.2.1   yamt 
    404  1.88.2.1   yamt static uint32_t
    405  1.88.2.1   yamt fwphy_rddata(struct fwohci_softc *sc,  u_int addr)
    406  1.88.2.1   yamt {
    407  1.88.2.1   yamt 	uint32_t fun, stat;
    408  1.88.2.1   yamt 	u_int i, retry = 0;
    409  1.88.2.1   yamt 
    410  1.88.2.1   yamt 	addr &= 0xf;
    411  1.88.2.1   yamt #define MAX_RETRY 100
    412  1.88.2.1   yamt again:
    413  1.88.2.1   yamt 	OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_REG_FAIL);
    414  1.88.2.1   yamt 	fun = PHYDEV_RDCMD | (addr << PHYDEV_REGADDR);
    415  1.88.2.1   yamt 	OWRITE(sc, OHCI_PHYACCESS, fun);
    416  1.88.2.1   yamt 	for ( i = 0 ; i < MAX_RETRY ; i ++ ){
    417  1.88.2.1   yamt 		fun = OREAD(sc, OHCI_PHYACCESS);
    418  1.88.2.1   yamt 		if ((fun & PHYDEV_RDCMD) == 0 && (fun & PHYDEV_RDDONE) != 0)
    419  1.88.2.1   yamt 			break;
    420  1.88.2.1   yamt 		DELAY(100);
    421       1.3   onoe 	}
    422  1.88.2.1   yamt 	if(i >= MAX_RETRY) {
    423  1.88.2.1   yamt 		if (firewire_debug)
    424  1.88.2.5   yamt 			fw_printf(sc->fc.dev, "phy read failed(1).\n");
    425  1.88.2.1   yamt 		if (++retry < MAX_RETRY) {
    426  1.88.2.1   yamt 			DELAY(100);
    427  1.88.2.1   yamt 			goto again;
    428  1.88.2.1   yamt 		}
    429       1.1   matt 	}
    430  1.88.2.1   yamt 	/* Make sure that SCLK is started */
    431  1.88.2.1   yamt 	stat = OREAD(sc, FWOHCI_INTSTAT);
    432  1.88.2.1   yamt 	if ((stat & OHCI_INT_REG_FAIL) != 0 ||
    433  1.88.2.1   yamt 			((fun >> PHYDEV_REGADDR) & 0xf) != addr) {
    434  1.88.2.1   yamt 		if (firewire_debug)
    435  1.88.2.5   yamt 			fw_printf(sc->fc.dev, "phy read failed(2).\n");
    436  1.88.2.1   yamt 		if (++retry < MAX_RETRY) {
    437  1.88.2.1   yamt 			DELAY(100);
    438  1.88.2.1   yamt 			goto again;
    439  1.88.2.1   yamt 		}
    440  1.88.2.1   yamt 	}
    441  1.88.2.1   yamt 	if (firewire_debug || retry >= MAX_RETRY)
    442  1.88.2.5   yamt 		fw_printf(sc->fc.dev,
    443  1.88.2.1   yamt 		    "fwphy_rddata: 0x%x loop=%d, retry=%d\n", addr, i, retry);
    444  1.88.2.1   yamt #undef MAX_RETRY
    445  1.88.2.1   yamt 	return((fun >> PHYDEV_RDDATA )& 0xff);
    446  1.88.2.1   yamt }
    447  1.88.2.1   yamt /* Device specific ioctl. */
    448  1.88.2.1   yamt FW_IOCTL(fwohci)
    449  1.88.2.1   yamt {
    450  1.88.2.1   yamt 	FW_IOCTL_START;
    451  1.88.2.1   yamt 	struct fwohci_softc *fc;
    452  1.88.2.1   yamt 	int err = 0;
    453  1.88.2.1   yamt 	struct fw_reg_req_t *reg  = (struct fw_reg_req_t *) data;
    454  1.88.2.1   yamt 	uint32_t *dmach = (uint32_t *) data;
    455  1.88.2.1   yamt 
    456  1.88.2.1   yamt 	if(sc == NULL){
    457  1.88.2.1   yamt 		return(EINVAL);
    458  1.88.2.1   yamt 	}
    459  1.88.2.1   yamt 	fc = (struct fwohci_softc *)sc->fc;
    460  1.88.2.1   yamt 
    461  1.88.2.1   yamt 	if (!data)
    462  1.88.2.1   yamt 		return(EINVAL);
    463  1.88.2.1   yamt 
    464  1.88.2.1   yamt 	switch (cmd) {
    465  1.88.2.1   yamt 	case FWOHCI_WRREG:
    466  1.88.2.1   yamt #define OHCI_MAX_REG 0x800
    467  1.88.2.1   yamt 		if(reg->addr <= OHCI_MAX_REG){
    468  1.88.2.1   yamt 			OWRITE(fc, reg->addr, reg->data);
    469  1.88.2.1   yamt 			reg->data = OREAD(fc, reg->addr);
    470  1.88.2.1   yamt 		}else{
    471  1.88.2.1   yamt 			err = EINVAL;
    472  1.88.2.1   yamt 		}
    473  1.88.2.1   yamt 		break;
    474  1.88.2.1   yamt 	case FWOHCI_RDREG:
    475  1.88.2.1   yamt 		if(reg->addr <= OHCI_MAX_REG){
    476  1.88.2.1   yamt 			reg->data = OREAD(fc, reg->addr);
    477  1.88.2.1   yamt 		}else{
    478  1.88.2.1   yamt 			err = EINVAL;
    479  1.88.2.1   yamt 		}
    480  1.88.2.1   yamt 		break;
    481  1.88.2.1   yamt /* Read DMA descriptors for debug  */
    482  1.88.2.1   yamt 	case DUMPDMA:
    483  1.88.2.1   yamt 		if(*dmach <= OHCI_MAX_DMA_CH ){
    484  1.88.2.1   yamt 			dump_dma(fc, *dmach);
    485  1.88.2.1   yamt 			dump_db(fc, *dmach);
    486  1.88.2.1   yamt 		}else{
    487  1.88.2.1   yamt 			err = EINVAL;
    488  1.88.2.1   yamt 		}
    489  1.88.2.1   yamt 		break;
    490  1.88.2.1   yamt /* Read/Write Phy registers */
    491  1.88.2.1   yamt #define OHCI_MAX_PHY_REG 0xf
    492  1.88.2.1   yamt 	case FWOHCI_RDPHYREG:
    493  1.88.2.1   yamt 		if (reg->addr <= OHCI_MAX_PHY_REG)
    494  1.88.2.1   yamt 			reg->data = fwphy_rddata(fc, reg->addr);
    495  1.88.2.1   yamt 		else
    496  1.88.2.1   yamt 			err = EINVAL;
    497  1.88.2.1   yamt 		break;
    498  1.88.2.1   yamt 	case FWOHCI_WRPHYREG:
    499  1.88.2.1   yamt 		if (reg->addr <= OHCI_MAX_PHY_REG)
    500  1.88.2.1   yamt 			reg->data = fwphy_wrdata(fc, reg->addr, reg->data);
    501  1.88.2.1   yamt 		else
    502  1.88.2.1   yamt 			err = EINVAL;
    503  1.88.2.1   yamt 		break;
    504  1.88.2.1   yamt 	default:
    505  1.88.2.1   yamt 		err = EINVAL;
    506  1.88.2.1   yamt 		break;
    507       1.1   matt 	}
    508  1.88.2.1   yamt 	return err;
    509  1.88.2.1   yamt }
    510      1.84  perry 
    511  1.88.2.1   yamt static int
    512  1.88.2.1   yamt fwohci_probe_phy(struct fwohci_softc *sc, device_t dev)
    513  1.88.2.1   yamt {
    514  1.88.2.1   yamt 	uint32_t reg, reg2;
    515  1.88.2.1   yamt 	int e1394a = 1;
    516  1.88.2.1   yamt /*
    517  1.88.2.1   yamt  * probe PHY parameters
    518  1.88.2.1   yamt  * 0. to prove PHY version, whether compliance of 1394a.
    519  1.88.2.1   yamt  * 1. to probe maximum speed supported by the PHY and
    520  1.88.2.1   yamt  *    number of port supported by core-logic.
    521  1.88.2.1   yamt  *    It is not actually available port on your PC .
    522  1.88.2.1   yamt  */
    523  1.88.2.1   yamt 	OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LPS);
    524  1.88.2.3   yamt 	DELAY(500);
    525  1.88.2.3   yamt 
    526  1.88.2.1   yamt 	reg = fwphy_rddata(sc, FW_PHY_SPD_REG);
    527  1.88.2.1   yamt 
    528  1.88.2.1   yamt 	if((reg >> 5) != 7 ){
    529  1.88.2.1   yamt 		sc->fc.mode &= ~FWPHYASYST;
    530  1.88.2.1   yamt 		sc->fc.nport = reg & FW_PHY_NP;
    531  1.88.2.1   yamt 		sc->fc.speed = reg & FW_PHY_SPD >> 6;
    532  1.88.2.1   yamt 		if (sc->fc.speed > MAX_SPEED) {
    533  1.88.2.5   yamt 			fw_printf(dev, "invalid speed %d (fixed to %d).\n",
    534  1.88.2.1   yamt 				sc->fc.speed, MAX_SPEED);
    535  1.88.2.1   yamt 			sc->fc.speed = MAX_SPEED;
    536  1.88.2.1   yamt 		}
    537  1.88.2.5   yamt 		fw_printf(dev, "Phy 1394 only %s, %d ports.\n",
    538  1.88.2.1   yamt 			fw_linkspeed[sc->fc.speed], sc->fc.nport);
    539  1.88.2.1   yamt 	}else{
    540  1.88.2.1   yamt 		reg2 = fwphy_rddata(sc, FW_PHY_ESPD_REG);
    541  1.88.2.1   yamt 		sc->fc.mode |= FWPHYASYST;
    542  1.88.2.1   yamt 		sc->fc.nport = reg & FW_PHY_NP;
    543  1.88.2.1   yamt 		sc->fc.speed = (reg2 & FW_PHY_ESPD) >> 5;
    544  1.88.2.1   yamt 		if (sc->fc.speed > MAX_SPEED) {
    545  1.88.2.5   yamt 			fw_printf(dev, "invalid speed %d (fixed to %d).\n",
    546  1.88.2.1   yamt 				sc->fc.speed, MAX_SPEED);
    547  1.88.2.1   yamt 			sc->fc.speed = MAX_SPEED;
    548  1.88.2.1   yamt 		}
    549  1.88.2.5   yamt 		fw_printf(dev, "Phy 1394a available %s, %d ports.\n",
    550  1.88.2.1   yamt 			fw_linkspeed[sc->fc.speed], sc->fc.nport);
    551       1.3   onoe 
    552  1.88.2.1   yamt 		/* check programPhyEnable */
    553  1.88.2.1   yamt 		reg2 = fwphy_rddata(sc, 5);
    554  1.88.2.1   yamt #if 0
    555  1.88.2.1   yamt 		if (e1394a && (OREAD(sc, OHCI_HCCCTL) & OHCI_HCC_PRPHY)) {
    556  1.88.2.1   yamt #else	/* XXX force to enable 1394a */
    557  1.88.2.1   yamt 		if (e1394a) {
    558  1.88.2.1   yamt #endif
    559  1.88.2.1   yamt 			if (firewire_debug)
    560  1.88.2.5   yamt 				fw_printf(dev, "Enable 1394a Enhancements\n");
    561  1.88.2.1   yamt 			/* enable EAA EMC */
    562  1.88.2.1   yamt 			reg2 |= 0x03;
    563  1.88.2.1   yamt 			/* set aPhyEnhanceEnable */
    564  1.88.2.1   yamt 			OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_PHYEN);
    565  1.88.2.1   yamt 			OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_PRPHY);
    566  1.88.2.1   yamt 		}
    567  1.88.2.1   yamt #if 0
    568  1.88.2.1   yamt 		else {
    569  1.88.2.1   yamt 			/* for safe */
    570  1.88.2.1   yamt 			reg2 &= ~0x83;
    571  1.88.2.1   yamt 		}
    572  1.88.2.1   yamt #endif
    573  1.88.2.1   yamt 		reg2 = fwphy_wrdata(sc, 5, reg2);
    574       1.3   onoe 	}
    575      1.62   haya 
    576  1.88.2.1   yamt 	reg = fwphy_rddata(sc, FW_PHY_SPD_REG);
    577  1.88.2.1   yamt 	if((reg >> 5) == 7 ){
    578  1.88.2.1   yamt 		reg = fwphy_rddata(sc, 4);
    579  1.88.2.1   yamt 		reg |= 1 << 6;
    580  1.88.2.1   yamt 		fwphy_wrdata(sc, 4, reg);
    581  1.88.2.1   yamt 		reg = fwphy_rddata(sc, 4);
    582      1.62   haya 	}
    583  1.88.2.1   yamt 	return 0;
    584  1.88.2.1   yamt }
    585  1.88.2.1   yamt 
    586  1.88.2.1   yamt 
    587  1.88.2.1   yamt void
    588  1.88.2.1   yamt fwohci_reset(struct fwohci_softc *sc, device_t dev)
    589  1.88.2.1   yamt {
    590  1.88.2.1   yamt 	int i, max_rec, speed;
    591  1.88.2.1   yamt 	uint32_t reg, reg2;
    592  1.88.2.1   yamt 	struct fwohcidb_tr *db_tr;
    593  1.88.2.1   yamt 
    594  1.88.2.1   yamt 	/* Disable interrupts */
    595  1.88.2.1   yamt 	OWRITE(sc, FWOHCI_INTMASKCLR, ~0);
    596  1.88.2.1   yamt 
    597  1.88.2.1   yamt 	/* Now stopping all DMA channels */
    598  1.88.2.1   yamt 	OWRITE(sc,  OHCI_ARQCTLCLR, OHCI_CNTL_DMA_RUN);
    599  1.88.2.1   yamt 	OWRITE(sc,  OHCI_ARSCTLCLR, OHCI_CNTL_DMA_RUN);
    600  1.88.2.1   yamt 	OWRITE(sc,  OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN);
    601  1.88.2.1   yamt 	OWRITE(sc,  OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN);
    602  1.88.2.1   yamt 
    603  1.88.2.1   yamt 	OWRITE(sc,  OHCI_IR_MASKCLR, ~0);
    604  1.88.2.1   yamt 	for( i = 0 ; i < sc->fc.nisodma ; i ++ ){
    605  1.88.2.1   yamt 		OWRITE(sc,  OHCI_IRCTLCLR(i), OHCI_CNTL_DMA_RUN);
    606  1.88.2.1   yamt 		OWRITE(sc,  OHCI_ITCTLCLR(i), OHCI_CNTL_DMA_RUN);
    607  1.88.2.1   yamt 	}
    608  1.88.2.1   yamt 
    609  1.88.2.1   yamt 	/* FLUSH FIFO and reset Transmitter/Reciever */
    610  1.88.2.1   yamt 	OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_RESET);
    611  1.88.2.1   yamt 	if (firewire_debug)
    612  1.88.2.5   yamt 		fw_printf(dev, "resetting OHCI...");
    613  1.88.2.1   yamt 	i = 0;
    614  1.88.2.1   yamt 	while(OREAD(sc, OHCI_HCCCTL) & OHCI_HCC_RESET) {
    615  1.88.2.1   yamt 		if (i++ > 100) break;
    616  1.88.2.1   yamt 		DELAY(1000);
    617  1.88.2.1   yamt 	}
    618  1.88.2.1   yamt 	if (firewire_debug)
    619  1.88.2.1   yamt 		printf("done (loop=%d)\n", i);
    620  1.88.2.1   yamt 
    621  1.88.2.1   yamt 	/* Probe phy */
    622  1.88.2.1   yamt 	fwohci_probe_phy(sc, dev);
    623  1.88.2.1   yamt 
    624  1.88.2.1   yamt 	/* Probe link */
    625  1.88.2.1   yamt 	reg = OREAD(sc,  OHCI_BUS_OPT);
    626  1.88.2.1   yamt 	reg2 = reg | OHCI_BUSFNC;
    627  1.88.2.1   yamt 	max_rec = (reg & 0x0000f000) >> 12;
    628  1.88.2.1   yamt 	speed = (reg & 0x00000007);
    629  1.88.2.5   yamt 	fw_printf(dev, "Link %s, max_rec %d bytes.\n",
    630  1.88.2.1   yamt 			fw_linkspeed[speed], MAXREC(max_rec));
    631  1.88.2.1   yamt 	/* XXX fix max_rec */
    632  1.88.2.1   yamt 	sc->fc.maxrec = sc->fc.speed + 8;
    633  1.88.2.1   yamt 	if (max_rec != sc->fc.maxrec) {
    634  1.88.2.1   yamt 		reg2 = (reg2 & 0xffff0fff) | (sc->fc.maxrec << 12);
    635  1.88.2.5   yamt 		fw_printf(dev, "max_rec %d -> %d\n",
    636  1.88.2.1   yamt 				MAXREC(max_rec), MAXREC(sc->fc.maxrec));
    637  1.88.2.1   yamt 	}
    638  1.88.2.1   yamt 	if (firewire_debug)
    639  1.88.2.5   yamt 		fw_printf(dev, "BUS_OPT 0x%x -> 0x%x\n", reg, reg2);
    640  1.88.2.1   yamt 	OWRITE(sc,  OHCI_BUS_OPT, reg2);
    641  1.88.2.1   yamt 
    642  1.88.2.1   yamt 	/* Initialize registers */
    643  1.88.2.1   yamt 	OWRITE(sc, OHCI_CROMHDR, sc->fc.config_rom[0]);
    644  1.88.2.1   yamt 	OWRITE(sc, OHCI_CROMPTR, sc->crom_dma.bus_addr);
    645  1.88.2.1   yamt 	OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_BIGEND);
    646  1.88.2.1   yamt 	OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_POSTWR);
    647  1.88.2.1   yamt 	OWRITE(sc, OHCI_SID_BUF, sc->sid_dma.bus_addr);
    648  1.88.2.1   yamt 	OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_SID);
    649  1.88.2.1   yamt 
    650  1.88.2.1   yamt 	/* Enable link */
    651  1.88.2.1   yamt 	OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LINKEN);
    652  1.88.2.1   yamt 
    653  1.88.2.1   yamt 	/* Force to start async RX DMA */
    654  1.88.2.1   yamt 	sc->arrq.xferq.flag &= ~FWXFERQ_RUNNING;
    655  1.88.2.1   yamt 	sc->arrs.xferq.flag &= ~FWXFERQ_RUNNING;
    656  1.88.2.1   yamt 	fwohci_rx_enable(sc, &sc->arrq);
    657  1.88.2.1   yamt 	fwohci_rx_enable(sc, &sc->arrs);
    658  1.88.2.1   yamt 
    659  1.88.2.1   yamt 	/* Initialize async TX */
    660  1.88.2.1   yamt 	OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN | OHCI_CNTL_DMA_DEAD);
    661  1.88.2.1   yamt 	OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN | OHCI_CNTL_DMA_DEAD);
    662  1.88.2.1   yamt 
    663  1.88.2.1   yamt 	/* AT Retries */
    664  1.88.2.1   yamt 	OWRITE(sc, FWOHCI_RETRY,
    665  1.88.2.1   yamt 		/* CycleLimit   PhyRespRetries ATRespRetries ATReqRetries */
    666  1.88.2.1   yamt 		(0xffff << 16 ) | (0x0f << 8) | (0x0f << 4) | 0x0f) ;
    667  1.88.2.1   yamt 
    668  1.88.2.1   yamt 	sc->atrq.top = STAILQ_FIRST(&sc->atrq.db_trq);
    669  1.88.2.1   yamt 	sc->atrs.top = STAILQ_FIRST(&sc->atrs.db_trq);
    670  1.88.2.1   yamt 	sc->atrq.bottom = sc->atrq.top;
    671  1.88.2.1   yamt 	sc->atrs.bottom = sc->atrs.top;
    672  1.88.2.1   yamt 
    673  1.88.2.1   yamt 	for( i = 0, db_tr = sc->atrq.top; i < sc->atrq.ndb ;
    674  1.88.2.1   yamt 				i ++, db_tr = STAILQ_NEXT(db_tr, link)){
    675  1.88.2.1   yamt 		db_tr->xfer = NULL;
    676  1.88.2.1   yamt 	}
    677  1.88.2.1   yamt 	for( i = 0, db_tr = sc->atrs.top; i < sc->atrs.ndb ;
    678  1.88.2.1   yamt 				i ++, db_tr = STAILQ_NEXT(db_tr, link)){
    679  1.88.2.1   yamt 		db_tr->xfer = NULL;
    680  1.88.2.1   yamt 	}
    681  1.88.2.1   yamt 
    682  1.88.2.1   yamt 
    683  1.88.2.1   yamt 	/* Enable interrupts */
    684  1.88.2.5   yamt 	sc->intmask =  (OHCI_INT_ERR  | OHCI_INT_PHY_SID
    685  1.88.2.1   yamt 			| OHCI_INT_DMA_ATRQ | OHCI_INT_DMA_ATRS
    686  1.88.2.1   yamt 			| OHCI_INT_DMA_PRRQ | OHCI_INT_DMA_PRRS
    687  1.88.2.1   yamt 			| OHCI_INT_PHY_BUS_R | OHCI_INT_PW_ERR);
    688  1.88.2.5   yamt 	sc->intmask |=  OHCI_INT_DMA_IR | OHCI_INT_DMA_IT;
    689  1.88.2.5   yamt 	sc->intmask |=  OHCI_INT_CYC_LOST | OHCI_INT_PHY_INT;
    690  1.88.2.5   yamt 	OWRITE(sc, FWOHCI_INTMASK, sc->intmask);
    691  1.88.2.1   yamt 	fwohci_set_intr(&sc->fc, 1);
    692  1.88.2.1   yamt }
    693      1.62   haya 
    694  1.88.2.1   yamt int
    695  1.88.2.1   yamt fwohci_init(struct fwohci_softc *sc, device_t dev)
    696  1.88.2.1   yamt {
    697  1.88.2.1   yamt 	int i, mver;
    698  1.88.2.1   yamt 	uint32_t reg;
    699  1.88.2.1   yamt 	uint8_t ui[8];
    700  1.88.2.1   yamt 
    701  1.88.2.1   yamt /* OHCI version */
    702  1.88.2.1   yamt 	reg = OREAD(sc, OHCI_VERSION);
    703  1.88.2.1   yamt 	mver = (reg >> 16) & 0xff;
    704  1.88.2.5   yamt 	fw_printf(dev, "OHCI version %x.%x (ROM=%d)\n",
    705  1.88.2.1   yamt 			mver, reg & 0xff, (reg>>24) & 1);
    706  1.88.2.1   yamt 	if (mver < 1 || mver > 9) {
    707  1.88.2.5   yamt 		fw_printf(dev, "invalid OHCI version\n");
    708  1.88.2.1   yamt 		return (ENXIO);
    709  1.88.2.1   yamt 	}
    710  1.88.2.1   yamt 
    711  1.88.2.1   yamt /* Available Isochronous DMA channel probe */
    712  1.88.2.1   yamt 	OWRITE(sc, OHCI_IT_MASK, 0xffffffff);
    713  1.88.2.1   yamt 	OWRITE(sc, OHCI_IR_MASK, 0xffffffff);
    714  1.88.2.1   yamt 	reg = OREAD(sc, OHCI_IT_MASK) & OREAD(sc, OHCI_IR_MASK);
    715  1.88.2.1   yamt 	OWRITE(sc, OHCI_IT_MASKCLR, 0xffffffff);
    716  1.88.2.1   yamt 	OWRITE(sc, OHCI_IR_MASKCLR, 0xffffffff);
    717  1.88.2.1   yamt 	for (i = 0; i < 0x20; i++)
    718  1.88.2.1   yamt 		if ((reg & (1 << i)) == 0)
    719  1.88.2.1   yamt 			break;
    720  1.88.2.1   yamt 	sc->fc.nisodma = i;
    721  1.88.2.5   yamt 	fw_printf(dev, "No. of Isochronous channels is %d.\n", i);
    722  1.88.2.1   yamt 	if (i == 0)
    723  1.88.2.1   yamt 		return (ENXIO);
    724  1.88.2.1   yamt 
    725  1.88.2.1   yamt 	sc->fc.arq = &sc->arrq.xferq;
    726  1.88.2.1   yamt 	sc->fc.ars = &sc->arrs.xferq;
    727  1.88.2.1   yamt 	sc->fc.atq = &sc->atrq.xferq;
    728  1.88.2.1   yamt 	sc->fc.ats = &sc->atrs.xferq;
    729  1.88.2.1   yamt 
    730  1.88.2.1   yamt 	sc->arrq.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
    731  1.88.2.1   yamt 	sc->arrs.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
    732  1.88.2.1   yamt 	sc->atrq.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
    733  1.88.2.1   yamt 	sc->atrs.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
    734  1.88.2.1   yamt 
    735  1.88.2.1   yamt 	sc->arrq.xferq.start = NULL;
    736  1.88.2.1   yamt 	sc->arrs.xferq.start = NULL;
    737  1.88.2.1   yamt 	sc->atrq.xferq.start = fwohci_start_atq;
    738  1.88.2.1   yamt 	sc->atrs.xferq.start = fwohci_start_ats;
    739  1.88.2.1   yamt 
    740  1.88.2.1   yamt 	sc->arrq.xferq.buf = NULL;
    741  1.88.2.1   yamt 	sc->arrs.xferq.buf = NULL;
    742  1.88.2.1   yamt 	sc->atrq.xferq.buf = NULL;
    743  1.88.2.1   yamt 	sc->atrs.xferq.buf = NULL;
    744  1.88.2.1   yamt 
    745  1.88.2.1   yamt 	sc->arrq.xferq.dmach = -1;
    746  1.88.2.1   yamt 	sc->arrs.xferq.dmach = -1;
    747  1.88.2.1   yamt 	sc->atrq.xferq.dmach = -1;
    748  1.88.2.1   yamt 	sc->atrs.xferq.dmach = -1;
    749  1.88.2.1   yamt 
    750  1.88.2.1   yamt 	sc->arrq.ndesc = 1;
    751  1.88.2.1   yamt 	sc->arrs.ndesc = 1;
    752  1.88.2.1   yamt 	sc->atrq.ndesc = 8;	/* equal to maximum of mbuf chains */
    753  1.88.2.1   yamt 	sc->atrs.ndesc = 2;
    754  1.88.2.1   yamt 
    755  1.88.2.1   yamt 	sc->arrq.ndb = NDB;
    756  1.88.2.1   yamt 	sc->arrs.ndb = NDB / 2;
    757  1.88.2.1   yamt 	sc->atrq.ndb = NDB;
    758  1.88.2.1   yamt 	sc->atrs.ndb = NDB / 2;
    759  1.88.2.1   yamt 
    760  1.88.2.1   yamt 	for( i = 0 ; i < sc->fc.nisodma ; i ++ ){
    761  1.88.2.1   yamt 		sc->fc.it[i] = &sc->it[i].xferq;
    762  1.88.2.1   yamt 		sc->fc.ir[i] = &sc->ir[i].xferq;
    763  1.88.2.1   yamt 		sc->it[i].xferq.dmach = i;
    764  1.88.2.1   yamt 		sc->ir[i].xferq.dmach = i;
    765  1.88.2.1   yamt 		sc->it[i].ndb = 0;
    766  1.88.2.1   yamt 		sc->ir[i].ndb = 0;
    767  1.88.2.1   yamt 	}
    768  1.88.2.1   yamt 
    769  1.88.2.1   yamt 	sc->fc.tcode = tinfo;
    770  1.88.2.1   yamt 	sc->fc.dev = dev;
    771  1.88.2.1   yamt 
    772  1.88.2.1   yamt 	sc->fc.config_rom = fwdma_malloc(&sc->fc, CROMSIZE, CROMSIZE,
    773  1.88.2.1   yamt 						&sc->crom_dma, BUS_DMA_WAITOK);
    774  1.88.2.1   yamt 	if(sc->fc.config_rom == NULL){
    775  1.88.2.5   yamt 		fw_printf(dev, "config_rom alloc failed.");
    776  1.88.2.1   yamt 		return ENOMEM;
    777  1.88.2.1   yamt 	}
    778       1.3   onoe 
    779       1.5   matt #if 0
    780  1.88.2.1   yamt 	bzero(&sc->fc.config_rom[0], CROMSIZE);
    781  1.88.2.1   yamt 	sc->fc.config_rom[1] = 0x31333934;
    782  1.88.2.1   yamt 	sc->fc.config_rom[2] = 0xf000a002;
    783  1.88.2.1   yamt 	sc->fc.config_rom[3] = OREAD(sc, OHCI_EUID_HI);
    784  1.88.2.1   yamt 	sc->fc.config_rom[4] = OREAD(sc, OHCI_EUID_LO);
    785  1.88.2.1   yamt 	sc->fc.config_rom[5] = 0;
    786  1.88.2.1   yamt 	sc->fc.config_rom[0] = (4 << 24) | (5 << 16);
    787  1.88.2.1   yamt 
    788  1.88.2.1   yamt 	sc->fc.config_rom[0] |= fw_crc16(&sc->fc.config_rom[1], 5*4);
    789       1.5   matt #endif
    790       1.5   matt 
    791  1.88.2.1   yamt /* SID recieve buffer must align 2^11 */
    792  1.88.2.1   yamt #define	OHCI_SIDSIZE	(1 << 11)
    793  1.88.2.1   yamt 	sc->sid_buf = fwdma_malloc(&sc->fc, OHCI_SIDSIZE, OHCI_SIDSIZE,
    794  1.88.2.1   yamt 						&sc->sid_dma, BUS_DMA_WAITOK);
    795  1.88.2.1   yamt 	if (sc->sid_buf == NULL) {
    796  1.88.2.5   yamt 		fw_printf(dev, "sid_buf alloc failed.");
    797  1.88.2.1   yamt 		return ENOMEM;
    798  1.88.2.1   yamt 	}
    799  1.88.2.1   yamt 
    800  1.88.2.1   yamt 	fwdma_malloc(&sc->fc, sizeof(uint32_t), sizeof(uint32_t),
    801  1.88.2.1   yamt 					&sc->dummy_dma, BUS_DMA_WAITOK);
    802  1.88.2.1   yamt 
    803  1.88.2.1   yamt 	if (sc->dummy_dma.v_addr == NULL) {
    804  1.88.2.5   yamt 		fw_printf(dev, "dummy_dma alloc failed.");
    805  1.88.2.1   yamt 		return ENOMEM;
    806  1.88.2.1   yamt 	}
    807  1.88.2.1   yamt 
    808  1.88.2.1   yamt 	fwohci_db_init(sc, &sc->arrq);
    809  1.88.2.1   yamt 	if ((sc->arrq.flags & FWOHCI_DBCH_INIT) == 0)
    810  1.88.2.1   yamt 		return ENOMEM;
    811  1.88.2.1   yamt 
    812  1.88.2.1   yamt 	fwohci_db_init(sc, &sc->arrs);
    813  1.88.2.1   yamt 	if ((sc->arrs.flags & FWOHCI_DBCH_INIT) == 0)
    814  1.88.2.1   yamt 		return ENOMEM;
    815  1.88.2.1   yamt 
    816  1.88.2.1   yamt 	fwohci_db_init(sc, &sc->atrq);
    817  1.88.2.1   yamt 	if ((sc->atrq.flags & FWOHCI_DBCH_INIT) == 0)
    818  1.88.2.1   yamt 		return ENOMEM;
    819  1.88.2.1   yamt 
    820  1.88.2.1   yamt 	fwohci_db_init(sc, &sc->atrs);
    821  1.88.2.1   yamt 	if ((sc->atrs.flags & FWOHCI_DBCH_INIT) == 0)
    822  1.88.2.1   yamt 		return ENOMEM;
    823  1.88.2.1   yamt 
    824  1.88.2.1   yamt 	sc->fc.eui.hi = OREAD(sc, FWOHCIGUID_H);
    825  1.88.2.1   yamt 	sc->fc.eui.lo = OREAD(sc, FWOHCIGUID_L);
    826  1.88.2.1   yamt 	for( i = 0 ; i < 8 ; i ++)
    827  1.88.2.1   yamt 		ui[i] = FW_EUI64_BYTE(&sc->fc.eui,i);
    828  1.88.2.5   yamt 	fw_printf(dev, "EUI64 %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
    829  1.88.2.1   yamt 		ui[0], ui[1], ui[2], ui[3], ui[4], ui[5], ui[6], ui[7]);
    830  1.88.2.1   yamt 
    831  1.88.2.1   yamt 	sc->fc.ioctl = fwohci_ioctl;
    832  1.88.2.1   yamt 	sc->fc.cyctimer = fwohci_cyctimer;
    833  1.88.2.1   yamt 	sc->fc.set_bmr = fwohci_set_bus_manager;
    834  1.88.2.1   yamt 	sc->fc.ibr = fwohci_ibr;
    835  1.88.2.1   yamt 	sc->fc.irx_enable = fwohci_irx_enable;
    836  1.88.2.1   yamt 	sc->fc.irx_disable = fwohci_irx_disable;
    837  1.88.2.1   yamt 
    838  1.88.2.1   yamt 	sc->fc.itx_enable = fwohci_itxbuf_enable;
    839  1.88.2.1   yamt 	sc->fc.itx_disable = fwohci_itx_disable;
    840  1.88.2.1   yamt #if BYTE_ORDER == BIG_ENDIAN
    841  1.88.2.1   yamt 	sc->fc.irx_post = fwohci_irx_post;
    842  1.88.2.1   yamt #else
    843  1.88.2.1   yamt 	sc->fc.irx_post = NULL;
    844  1.88.2.1   yamt #endif
    845  1.88.2.1   yamt 	sc->fc.itx_post = NULL;
    846  1.88.2.1   yamt 	sc->fc.timeout = fwohci_timeout;
    847  1.88.2.1   yamt 	sc->fc.poll = fwohci_poll;
    848  1.88.2.1   yamt 	sc->fc.set_intr = fwohci_set_intr;
    849  1.88.2.1   yamt 
    850  1.88.2.1   yamt 	sc->intmask = sc->irstat = sc->itstat = 0;
    851  1.88.2.1   yamt 
    852  1.88.2.5   yamt 	/* Init task queue */
    853  1.88.2.5   yamt 	sc->fc.taskqueue = fw_taskqueue_create_fast("fw_taskq", M_WAITOK,
    854  1.88.2.5   yamt 		fw_taskqueue_thread_enqueue, &sc->fc.taskqueue);
    855  1.88.2.5   yamt 	fw_taskqueue_start_threads(&sc->fc.taskqueue, 1, PI_NET, "fw%d_taskq",
    856  1.88.2.5   yamt 		fw_get_unit(dev));
    857  1.88.2.5   yamt 	FW_TASK_INIT(&sc->fwohci_task_busreset, 2, fwohci_task_busreset, sc);
    858  1.88.2.5   yamt 	FW_TASK_INIT(&sc->fwohci_task_sid, 1, fwohci_task_sid, sc);
    859  1.88.2.5   yamt 	FW_TASK_INIT(&sc->fwohci_task_dma, 0, fwohci_task_dma, sc);
    860  1.88.2.5   yamt 
    861  1.88.2.1   yamt 	fw_init(&sc->fc);
    862  1.88.2.1   yamt 	fwohci_reset(sc, dev);
    863  1.88.2.1   yamt 	FWOHCI_INIT_END;
    864      1.84  perry 
    865       1.1   matt 	return 0;
    866       1.1   matt }
    867       1.1   matt 
    868  1.88.2.1   yamt void
    869  1.88.2.1   yamt fwohci_timeout(void *arg)
    870      1.40   haya {
    871  1.88.2.1   yamt 	struct fwohci_softc *sc;
    872      1.40   haya 
    873  1.88.2.1   yamt 	sc = (struct fwohci_softc *)arg;
    874      1.40   haya }
    875      1.40   haya 
    876  1.88.2.1   yamt uint32_t
    877  1.88.2.1   yamt fwohci_cyctimer(struct firewire_comm *fc)
    878       1.1   matt {
    879  1.88.2.1   yamt 	struct fwohci_softc *sc = (struct fwohci_softc *)fc;
    880  1.88.2.1   yamt 	return(OREAD(sc, OHCI_CYCLETIMER));
    881  1.88.2.1   yamt }
    882      1.62   haya 
    883  1.88.2.1   yamt FWOHCI_DETACH()
    884  1.88.2.1   yamt {
    885  1.88.2.1   yamt 	int i;
    886      1.40   haya 
    887  1.88.2.1   yamt 	FWOHCI_DETACH_START;
    888  1.88.2.1   yamt 	if (sc->sid_buf != NULL)
    889  1.88.2.1   yamt 		fwdma_free(&sc->fc, &sc->sid_dma);
    890  1.88.2.1   yamt 	if (sc->fc.config_rom != NULL)
    891  1.88.2.1   yamt 		fwdma_free(&sc->fc, &sc->crom_dma);
    892      1.62   haya 
    893  1.88.2.1   yamt 	fwohci_db_free(&sc->arrq);
    894  1.88.2.1   yamt 	fwohci_db_free(&sc->arrs);
    895      1.62   haya 
    896  1.88.2.1   yamt 	fwohci_db_free(&sc->atrq);
    897  1.88.2.1   yamt 	fwohci_db_free(&sc->atrs);
    898       1.3   onoe 
    899  1.88.2.1   yamt 	for( i = 0 ; i < sc->fc.nisodma ; i ++ ){
    900  1.88.2.1   yamt 		fwohci_db_free(&sc->it[i]);
    901  1.88.2.1   yamt 		fwohci_db_free(&sc->ir[i]);
    902       1.1   matt 	}
    903  1.88.2.1   yamt 	FWOHCI_DETACH_END;
    904  1.88.2.1   yamt 
    905  1.88.2.1   yamt 	return 0;
    906       1.3   onoe }
    907       1.3   onoe 
    908  1.88.2.1   yamt #define LAST_DB(dbtr, db) do {						\
    909  1.88.2.1   yamt 	struct fwohcidb_tr *_dbtr = (dbtr);				\
    910  1.88.2.1   yamt 	int _cnt = _dbtr->dbcnt;					\
    911  1.88.2.1   yamt 	db = &_dbtr->db[ (_cnt > 2) ? (_cnt -1) : 0];			\
    912  1.88.2.1   yamt } while (0)
    913  1.88.2.1   yamt 
    914      1.24    jmc static void
    915  1.88.2.1   yamt fwohci_execute_db(void *arg, bus_dma_segment_t *segs, int nseg, int error)
    916      1.24    jmc {
    917  1.88.2.1   yamt 	struct fwohcidb_tr *db_tr;
    918  1.88.2.1   yamt 	struct fwohcidb *db;
    919  1.88.2.1   yamt 	bus_dma_segment_t *s;
    920  1.88.2.1   yamt 	int i;
    921      1.24    jmc 
    922  1.88.2.1   yamt 	db_tr = (struct fwohcidb_tr *)arg;
    923  1.88.2.1   yamt 	db = &db_tr->db[db_tr->dbcnt];
    924  1.88.2.1   yamt 	if (error) {
    925  1.88.2.1   yamt 		if (firewire_debug || error != EFBIG)
    926  1.88.2.1   yamt 			printf("fwohci_execute_db: error=%d\n", error);
    927  1.88.2.1   yamt 		return;
    928  1.88.2.1   yamt 	}
    929  1.88.2.1   yamt 	for (i = 0; i < nseg; i++) {
    930  1.88.2.1   yamt 		s = &segs[i];
    931  1.88.2.1   yamt 		FWOHCI_DMA_WRITE(db->db.desc.addr, s->ds_addr);
    932  1.88.2.1   yamt 		FWOHCI_DMA_WRITE(db->db.desc.cmd, s->ds_len);
    933  1.88.2.1   yamt  		FWOHCI_DMA_WRITE(db->db.desc.res, 0);
    934  1.88.2.1   yamt 		db++;
    935  1.88.2.1   yamt 		db_tr->dbcnt++;
    936      1.26  enami 	}
    937      1.24    jmc }
    938      1.24    jmc 
    939      1.24    jmc static void
    940  1.88.2.1   yamt fwohci_execute_db2(void *arg, bus_dma_segment_t *segs, int nseg,
    941  1.88.2.2   yamt     bus_size_t size, int error)
    942      1.24    jmc {
    943  1.88.2.1   yamt 	fwohci_execute_db(arg, segs, nseg, error);
    944  1.88.2.1   yamt }
    945      1.26  enami 
    946  1.88.2.1   yamt static void
    947  1.88.2.1   yamt fwohci_start(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
    948  1.88.2.1   yamt {
    949  1.88.2.1   yamt 	int i, s;
    950  1.88.2.1   yamt 	int tcode, hdr_len, pl_off;
    951  1.88.2.1   yamt 	int fsegment = -1;
    952  1.88.2.1   yamt 	uint32_t off;
    953  1.88.2.1   yamt 	struct fw_xfer *xfer;
    954  1.88.2.1   yamt 	struct fw_pkt *fp;
    955  1.88.2.1   yamt 	struct fwohci_txpkthdr *ohcifp;
    956  1.88.2.1   yamt 	struct fwohcidb_tr *db_tr;
    957  1.88.2.1   yamt 	struct fwohcidb *db;
    958  1.88.2.1   yamt 	uint32_t *ld;
    959  1.88.2.1   yamt 	const struct tcode_info *info;
    960  1.88.2.1   yamt 	static int maxdesc=0;
    961  1.88.2.1   yamt 
    962  1.88.2.5   yamt 	FW_GLOCK_ASSERT(&sc->fc);
    963  1.88.2.5   yamt 
    964  1.88.2.1   yamt 	if(&sc->atrq == dbch){
    965  1.88.2.1   yamt 		off = OHCI_ATQOFF;
    966  1.88.2.1   yamt 	}else if(&sc->atrs == dbch){
    967  1.88.2.1   yamt 		off = OHCI_ATSOFF;
    968  1.88.2.1   yamt 	}else{
    969  1.88.2.1   yamt 		return;
    970      1.26  enami 	}
    971      1.24    jmc 
    972  1.88.2.1   yamt 	if (dbch->flags & FWOHCI_DBCH_FULL)
    973  1.88.2.1   yamt 		return;
    974      1.24    jmc 
    975  1.88.2.1   yamt 	s = splfw();
    976  1.88.2.1   yamt 	fwdma_sync_multiseg_all(dbch->am,
    977  1.88.2.1   yamt 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
    978  1.88.2.1   yamt 	db_tr = dbch->top;
    979  1.88.2.1   yamt txloop:
    980  1.88.2.1   yamt 	xfer = STAILQ_FIRST(&dbch->xferq.q);
    981  1.88.2.1   yamt 	if(xfer == NULL){
    982  1.88.2.1   yamt 		goto kick;
    983  1.88.2.1   yamt 	}
    984  1.88.2.5   yamt #if 0
    985  1.88.2.1   yamt 	if(dbch->xferq.queued == 0 ){
    986  1.88.2.5   yamt 		fw_printf(sc->fc.dev, "TX queue empty\n");
    987  1.88.2.1   yamt 	}
    988  1.88.2.5   yamt #endif
    989  1.88.2.1   yamt 	STAILQ_REMOVE_HEAD(&dbch->xferq.q, link);
    990  1.88.2.1   yamt 	db_tr->xfer = xfer;
    991  1.88.2.5   yamt 	xfer->flag = FWXF_START;
    992  1.88.2.1   yamt 
    993  1.88.2.1   yamt 	fp = &xfer->send.hdr;
    994  1.88.2.1   yamt 	tcode = fp->mode.common.tcode;
    995  1.88.2.1   yamt 
    996  1.88.2.1   yamt 	ohcifp = (struct fwohci_txpkthdr *) db_tr->db[1].db.immed;
    997  1.88.2.1   yamt 	info = &tinfo[tcode];
    998  1.88.2.1   yamt 	hdr_len = pl_off = info->hdr_len;
    999  1.88.2.1   yamt 
   1000  1.88.2.1   yamt 	ld = &ohcifp->mode.ld[0];
   1001  1.88.2.1   yamt 	ld[0] = ld[1] = ld[2] = ld[3] = 0;
   1002  1.88.2.1   yamt 	for( i = 0 ; i < pl_off ; i+= 4)
   1003  1.88.2.1   yamt 		ld[i/4] = fp->mode.ld[i/4];
   1004  1.88.2.1   yamt 
   1005  1.88.2.1   yamt 	ohcifp->mode.common.spd = xfer->send.spd & 0x7;
   1006  1.88.2.1   yamt 	if (tcode == FWTCODE_STREAM ){
   1007  1.88.2.1   yamt 		hdr_len = 8;
   1008  1.88.2.1   yamt 		ohcifp->mode.stream.len = fp->mode.stream.len;
   1009  1.88.2.1   yamt 	} else if (tcode == FWTCODE_PHY) {
   1010  1.88.2.1   yamt 		hdr_len = 12;
   1011  1.88.2.1   yamt 		ld[1] = fp->mode.ld[1];
   1012  1.88.2.1   yamt 		ld[2] = fp->mode.ld[2];
   1013  1.88.2.1   yamt 		ohcifp->mode.common.spd = 0;
   1014  1.88.2.1   yamt 		ohcifp->mode.common.tcode = FWOHCITCODE_PHY;
   1015  1.88.2.1   yamt 	} else {
   1016  1.88.2.1   yamt 		ohcifp->mode.asycomm.dst = fp->mode.hdr.dst;
   1017  1.88.2.1   yamt 		ohcifp->mode.asycomm.srcbus = OHCI_ASYSRCBUS;
   1018  1.88.2.1   yamt 		ohcifp->mode.asycomm.tlrt |= FWRETRY_X;
   1019  1.88.2.1   yamt 	}
   1020  1.88.2.1   yamt 	db = &db_tr->db[0];
   1021  1.88.2.1   yamt  	FWOHCI_DMA_WRITE(db->db.desc.cmd,
   1022  1.88.2.1   yamt 			OHCI_OUTPUT_MORE | OHCI_KEY_ST2 | hdr_len);
   1023  1.88.2.1   yamt  	FWOHCI_DMA_WRITE(db->db.desc.addr, 0);
   1024  1.88.2.1   yamt  	FWOHCI_DMA_WRITE(db->db.desc.res, 0);
   1025  1.88.2.1   yamt /* Specify bound timer of asy. responce */
   1026  1.88.2.1   yamt 	if(&sc->atrs == dbch){
   1027  1.88.2.1   yamt  		FWOHCI_DMA_WRITE(db->db.desc.res,
   1028  1.88.2.1   yamt 			 (OREAD(sc, OHCI_CYCLETIMER) >> 12) + (1 << 13));
   1029  1.88.2.1   yamt 	}
   1030  1.88.2.1   yamt #if BYTE_ORDER == BIG_ENDIAN
   1031  1.88.2.1   yamt 	if (tcode == FWTCODE_WREQQ || tcode == FWTCODE_RRESQ)
   1032  1.88.2.1   yamt 		hdr_len = 12;
   1033  1.88.2.1   yamt 	for (i = 0; i < hdr_len/4; i ++)
   1034  1.88.2.1   yamt 		FWOHCI_DMA_WRITE(ld[i], ld[i]);
   1035  1.88.2.1   yamt #endif
   1036  1.88.2.1   yamt 
   1037  1.88.2.1   yamt again:
   1038  1.88.2.1   yamt 	db_tr->dbcnt = 2;
   1039  1.88.2.1   yamt 	db = &db_tr->db[db_tr->dbcnt];
   1040  1.88.2.1   yamt 	if (xfer->send.pay_len > 0) {
   1041  1.88.2.1   yamt 		int err;
   1042  1.88.2.1   yamt 		/* handle payload */
   1043  1.88.2.1   yamt 		if (xfer->mbuf == NULL) {
   1044  1.88.2.1   yamt 			err = fw_bus_dmamap_load(dbch->dmat, db_tr->dma_map,
   1045  1.88.2.1   yamt 				&xfer->send.payload[0], xfer->send.pay_len,
   1046  1.88.2.1   yamt 				fwohci_execute_db, db_tr,
   1047  1.88.2.1   yamt 				BUS_DMA_WAITOK);
   1048  1.88.2.1   yamt 		} else {
   1049  1.88.2.1   yamt 			/* XXX we can handle only 6 (=8-2) mbuf chains */
   1050  1.88.2.1   yamt 			err = fw_bus_dmamap_load_mbuf(dbch->dmat,
   1051  1.88.2.1   yamt 				db_tr->dma_map, xfer->mbuf,
   1052  1.88.2.1   yamt 				fwohci_execute_db2, db_tr,
   1053  1.88.2.1   yamt 				BUS_DMA_WAITOK);
   1054  1.88.2.1   yamt 			if (err == EFBIG) {
   1055  1.88.2.1   yamt 				struct mbuf *m0;
   1056  1.88.2.1   yamt 
   1057  1.88.2.1   yamt 				if (firewire_debug)
   1058  1.88.2.5   yamt 					fw_printf(sc->fc.dev, "EFBIG.\n");
   1059  1.88.2.1   yamt 				m0 = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
   1060  1.88.2.1   yamt 				if (m0 != NULL) {
   1061  1.88.2.1   yamt 					m_copydata(xfer->mbuf, 0,
   1062  1.88.2.1   yamt 						xfer->mbuf->m_pkthdr.len,
   1063  1.88.2.3   yamt 						mtod(m0, void *));
   1064  1.88.2.1   yamt 					m0->m_len = m0->m_pkthdr.len =
   1065  1.88.2.1   yamt 						xfer->mbuf->m_pkthdr.len;
   1066  1.88.2.1   yamt 					m_freem(xfer->mbuf);
   1067  1.88.2.1   yamt 					xfer->mbuf = m0;
   1068  1.88.2.1   yamt 					goto again;
   1069  1.88.2.1   yamt 				}
   1070  1.88.2.5   yamt 				fw_printf(sc->fc.dev, "m_getcl failed.\n");
   1071  1.88.2.1   yamt 			}
   1072  1.88.2.1   yamt 		}
   1073  1.88.2.1   yamt 		if (err)
   1074  1.88.2.1   yamt 			printf("dmamap_load: err=%d\n", err);
   1075  1.88.2.1   yamt 		fw_bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
   1076  1.88.2.1   yamt 						BUS_DMASYNC_PREWRITE);
   1077  1.88.2.1   yamt #if 0 /* OHCI_OUTPUT_MODE == 0 */
   1078  1.88.2.1   yamt 		for (i = 2; i < db_tr->dbcnt; i++)
   1079  1.88.2.1   yamt 			FWOHCI_DMA_SET(db_tr->db[i].db.desc.cmd,
   1080  1.88.2.1   yamt 						OHCI_OUTPUT_MORE);
   1081  1.88.2.1   yamt #endif
   1082  1.88.2.1   yamt 	}
   1083  1.88.2.1   yamt 	if (maxdesc < db_tr->dbcnt) {
   1084  1.88.2.1   yamt 		maxdesc = db_tr->dbcnt;
   1085  1.88.2.1   yamt 		if (firewire_debug)
   1086  1.88.2.5   yamt 			fw_printf(sc->fc.dev, "maxdesc: %d\n", maxdesc);
   1087  1.88.2.1   yamt 	}
   1088  1.88.2.1   yamt 	/* last db */
   1089  1.88.2.1   yamt 	LAST_DB(db_tr, db);
   1090  1.88.2.1   yamt  	FWOHCI_DMA_SET(db->db.desc.cmd,
   1091  1.88.2.1   yamt 		OHCI_OUTPUT_LAST | OHCI_INTERRUPT_ALWAYS | OHCI_BRANCH_ALWAYS);
   1092  1.88.2.1   yamt  	FWOHCI_DMA_WRITE(db->db.desc.depend,
   1093  1.88.2.1   yamt 			STAILQ_NEXT(db_tr, link)->bus_addr);
   1094  1.88.2.1   yamt 
   1095  1.88.2.1   yamt 	if(fsegment == -1 )
   1096  1.88.2.1   yamt 		fsegment = db_tr->dbcnt;
   1097  1.88.2.1   yamt 	if (dbch->pdb_tr != NULL) {
   1098  1.88.2.1   yamt 		LAST_DB(dbch->pdb_tr, db);
   1099  1.88.2.1   yamt  		FWOHCI_DMA_SET(db->db.desc.depend, db_tr->dbcnt);
   1100  1.88.2.1   yamt 	}
   1101  1.88.2.5   yamt 	dbch->xferq.queued ++;
   1102  1.88.2.1   yamt 	dbch->pdb_tr = db_tr;
   1103  1.88.2.1   yamt 	db_tr = STAILQ_NEXT(db_tr, link);
   1104  1.88.2.1   yamt 	if(db_tr != dbch->bottom){
   1105  1.88.2.1   yamt 		goto txloop;
   1106  1.88.2.1   yamt 	} else {
   1107  1.88.2.5   yamt 		fw_printf(sc->fc.dev, "fwohci_start: lack of db_trq\n");
   1108  1.88.2.1   yamt 		dbch->flags |= FWOHCI_DBCH_FULL;
   1109  1.88.2.1   yamt 	}
   1110  1.88.2.1   yamt kick:
   1111  1.88.2.1   yamt 	/* kick asy q */
   1112  1.88.2.1   yamt 	fwdma_sync_multiseg_all(dbch->am,
   1113  1.88.2.1   yamt 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1114  1.88.2.1   yamt 
   1115  1.88.2.1   yamt 	if(dbch->xferq.flag & FWXFERQ_RUNNING) {
   1116  1.88.2.1   yamt 		OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_WAKE);
   1117  1.88.2.1   yamt 	} else {
   1118  1.88.2.1   yamt 		if (firewire_debug)
   1119  1.88.2.5   yamt 			fw_printf(sc->fc.dev, "start AT DMA status=%x\n",
   1120  1.88.2.1   yamt 					OREAD(sc, OHCI_DMACTL(off)));
   1121  1.88.2.1   yamt 		OWRITE(sc, OHCI_DMACMD(off), dbch->top->bus_addr | fsegment);
   1122  1.88.2.1   yamt 		OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_RUN);
   1123  1.88.2.1   yamt 		dbch->xferq.flag |= FWXFERQ_RUNNING;
   1124      1.62   haya 	}
   1125  1.88.2.1   yamt 	CTR0(KTR_DEV, "start kick done");
   1126  1.88.2.1   yamt 	CTR0(KTR_DEV, "start kick done2");
   1127      1.24    jmc 
   1128  1.88.2.1   yamt 	dbch->top = db_tr;
   1129  1.88.2.1   yamt 	splx(s);
   1130  1.88.2.1   yamt 	return;
   1131  1.88.2.1   yamt }
   1132      1.24    jmc 
   1133  1.88.2.1   yamt static void
   1134  1.88.2.1   yamt fwohci_start_atq(struct firewire_comm *fc)
   1135  1.88.2.1   yamt {
   1136  1.88.2.1   yamt 	struct fwohci_softc *sc = (struct fwohci_softc *)fc;
   1137  1.88.2.5   yamt 	FW_GLOCK(&sc->fc);
   1138  1.88.2.1   yamt 	fwohci_start( sc, &(sc->atrq));
   1139  1.88.2.5   yamt 	FW_GUNLOCK(&sc->fc);
   1140  1.88.2.1   yamt 	return;
   1141  1.88.2.1   yamt }
   1142      1.24    jmc 
   1143  1.88.2.1   yamt static void
   1144  1.88.2.1   yamt fwohci_start_ats(struct firewire_comm *fc)
   1145  1.88.2.1   yamt {
   1146  1.88.2.1   yamt 	struct fwohci_softc *sc = (struct fwohci_softc *)fc;
   1147  1.88.2.5   yamt 	FW_GLOCK(&sc->fc);
   1148  1.88.2.1   yamt 	fwohci_start( sc, &(sc->atrs));
   1149  1.88.2.5   yamt 	FW_GUNLOCK(&sc->fc);
   1150  1.88.2.1   yamt 	return;
   1151  1.88.2.1   yamt }
   1152      1.62   haya 
   1153  1.88.2.1   yamt void
   1154  1.88.2.1   yamt fwohci_txd(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
   1155  1.88.2.1   yamt {
   1156  1.88.2.1   yamt 	int s, ch, err = 0;
   1157  1.88.2.1   yamt 	struct fwohcidb_tr *tr;
   1158  1.88.2.1   yamt 	struct fwohcidb *db;
   1159  1.88.2.1   yamt 	struct fw_xfer *xfer;
   1160  1.88.2.1   yamt 	uint32_t off;
   1161  1.88.2.1   yamt 	u_int stat, status;
   1162  1.88.2.1   yamt 	int	packets;
   1163  1.88.2.1   yamt 	struct firewire_comm *fc = (struct firewire_comm *)sc;
   1164  1.88.2.1   yamt 
   1165  1.88.2.1   yamt 	if(&sc->atrq == dbch){
   1166  1.88.2.1   yamt 		off = OHCI_ATQOFF;
   1167  1.88.2.1   yamt 		ch = ATRQ_CH;
   1168  1.88.2.1   yamt 	}else if(&sc->atrs == dbch){
   1169  1.88.2.1   yamt 		off = OHCI_ATSOFF;
   1170  1.88.2.1   yamt 		ch = ATRS_CH;
   1171  1.88.2.1   yamt 	}else{
   1172  1.88.2.1   yamt 		return;
   1173  1.88.2.1   yamt 	}
   1174  1.88.2.1   yamt 	s = splfw();
   1175  1.88.2.1   yamt 	tr = dbch->bottom;
   1176  1.88.2.1   yamt 	packets = 0;
   1177  1.88.2.1   yamt 	fwdma_sync_multiseg_all(dbch->am,
   1178  1.88.2.1   yamt 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
   1179  1.88.2.1   yamt 	while(dbch->xferq.queued > 0){
   1180  1.88.2.1   yamt 		LAST_DB(tr, db);
   1181  1.88.2.1   yamt 		status = FWOHCI_DMA_READ(db->db.desc.res) >> OHCI_STATUS_SHIFT;
   1182  1.88.2.1   yamt 		if(!(status & OHCI_CNTL_DMA_ACTIVE)){
   1183  1.88.2.5   yamt 			if (fc->status != FWBUSINIT)
   1184  1.88.2.1   yamt 				/* maybe out of order?? */
   1185  1.88.2.1   yamt 				goto out;
   1186  1.88.2.1   yamt 		}
   1187  1.88.2.1   yamt 		if (tr->xfer->send.pay_len > 0) {
   1188  1.88.2.1   yamt 			fw_bus_dmamap_sync(dbch->dmat, tr->dma_map,
   1189  1.88.2.1   yamt 				BUS_DMASYNC_POSTWRITE);
   1190  1.88.2.1   yamt 			fw_bus_dmamap_unload(dbch->dmat, tr->dma_map);
   1191  1.88.2.1   yamt 		}
   1192  1.88.2.1   yamt #if 1
   1193  1.88.2.1   yamt 		if (firewire_debug > 1)
   1194  1.88.2.1   yamt 			dump_db(sc, ch);
   1195      1.62   haya #endif
   1196  1.88.2.1   yamt 		if(status & OHCI_CNTL_DMA_DEAD) {
   1197  1.88.2.1   yamt 			/* Stop DMA */
   1198  1.88.2.1   yamt 			OWRITE(sc, OHCI_DMACTLCLR(off), OHCI_CNTL_DMA_RUN);
   1199  1.88.2.5   yamt 			fw_printf(sc->fc.dev, "force reset AT FIFO\n");
   1200  1.88.2.1   yamt 			OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_LINKEN);
   1201  1.88.2.1   yamt 			OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LPS | OHCI_HCC_LINKEN);
   1202  1.88.2.1   yamt 			OWRITE(sc, OHCI_DMACTLCLR(off), OHCI_CNTL_DMA_RUN);
   1203  1.88.2.1   yamt 		}
   1204  1.88.2.1   yamt 		stat = status & FWOHCIEV_MASK;
   1205  1.88.2.1   yamt 		switch(stat){
   1206  1.88.2.1   yamt 		case FWOHCIEV_ACKPEND:
   1207  1.88.2.1   yamt 			CTR0(KTR_DEV, "txd: ack pending");
   1208  1.88.2.1   yamt 			/* fall through */
   1209  1.88.2.1   yamt 		case FWOHCIEV_ACKCOMPL:
   1210  1.88.2.1   yamt 			err = 0;
   1211  1.88.2.1   yamt 			break;
   1212  1.88.2.1   yamt 		case FWOHCIEV_ACKBSA:
   1213  1.88.2.1   yamt 		case FWOHCIEV_ACKBSB:
   1214  1.88.2.1   yamt 		case FWOHCIEV_ACKBSX:
   1215  1.88.2.5   yamt 			fw_printf(sc->fc.dev, "txd err=%2x %s\n", stat,
   1216  1.88.2.5   yamt 			    fwohcicode[stat]);
   1217  1.88.2.1   yamt 			err = EBUSY;
   1218  1.88.2.1   yamt 			break;
   1219  1.88.2.1   yamt 		case FWOHCIEV_FLUSHED:
   1220  1.88.2.1   yamt 		case FWOHCIEV_ACKTARD:
   1221  1.88.2.5   yamt 			fw_printf(sc->fc.dev, "txd err=%2x %s\n", stat,
   1222  1.88.2.5   yamt 			    fwohcicode[stat]);
   1223  1.88.2.1   yamt 			err = EAGAIN;
   1224  1.88.2.1   yamt 			break;
   1225  1.88.2.1   yamt 		case FWOHCIEV_MISSACK:
   1226  1.88.2.1   yamt 		case FWOHCIEV_UNDRRUN:
   1227  1.88.2.1   yamt 		case FWOHCIEV_OVRRUN:
   1228  1.88.2.1   yamt 		case FWOHCIEV_DESCERR:
   1229  1.88.2.1   yamt 		case FWOHCIEV_DTRDERR:
   1230  1.88.2.1   yamt 		case FWOHCIEV_TIMEOUT:
   1231  1.88.2.1   yamt 		case FWOHCIEV_TCODERR:
   1232  1.88.2.1   yamt 		case FWOHCIEV_UNKNOWN:
   1233  1.88.2.1   yamt 		case FWOHCIEV_ACKDERR:
   1234  1.88.2.1   yamt 		case FWOHCIEV_ACKTERR:
   1235  1.88.2.1   yamt 		default:
   1236  1.88.2.5   yamt 			fw_printf(sc->fc.dev, "txd err=%2x %s\n",
   1237  1.88.2.1   yamt 							stat, fwohcicode[stat]);
   1238  1.88.2.1   yamt 			err = EINVAL;
   1239  1.88.2.1   yamt 			break;
   1240  1.88.2.1   yamt 		}
   1241  1.88.2.1   yamt 		if (tr->xfer != NULL) {
   1242  1.88.2.1   yamt 			xfer = tr->xfer;
   1243  1.88.2.1   yamt 			CTR0(KTR_DEV, "txd");
   1244  1.88.2.5   yamt 			if (xfer->flag & FWXF_RCVD) {
   1245  1.88.2.1   yamt #if 0
   1246  1.88.2.1   yamt 				if (firewire_debug)
   1247  1.88.2.1   yamt 					printf("already rcvd\n");
   1248      1.62   haya #endif
   1249  1.88.2.1   yamt 				fw_xfer_done(xfer);
   1250  1.88.2.1   yamt 			} else {
   1251  1.88.2.5   yamt 				microtime(&xfer->tv);
   1252  1.88.2.5   yamt 				xfer->flag = FWXF_SENT;
   1253  1.88.2.5   yamt 				if (err == EBUSY) {
   1254  1.88.2.5   yamt 					xfer->flag = FWXF_BUSY;
   1255  1.88.2.1   yamt 					xfer->resp = err;
   1256  1.88.2.1   yamt 					xfer->recv.pay_len = 0;
   1257  1.88.2.1   yamt 					fw_xfer_done(xfer);
   1258  1.88.2.1   yamt 				} else if (stat != FWOHCIEV_ACKPEND) {
   1259  1.88.2.1   yamt 					if (stat != FWOHCIEV_ACKCOMPL)
   1260  1.88.2.5   yamt 						xfer->flag = FWXF_SENTERR;
   1261  1.88.2.1   yamt 					xfer->resp = err;
   1262  1.88.2.1   yamt 					xfer->recv.pay_len = 0;
   1263  1.88.2.1   yamt 					fw_xfer_done(xfer);
   1264  1.88.2.1   yamt 				}
   1265  1.88.2.1   yamt 			}
   1266  1.88.2.1   yamt 			/*
   1267  1.88.2.1   yamt 			 * The watchdog timer takes care of split
   1268  1.88.2.1   yamt 			 * transcation timeout for ACKPEND case.
   1269  1.88.2.1   yamt 			 */
   1270  1.88.2.1   yamt 		} else {
   1271  1.88.2.1   yamt 			printf("this shouldn't happen\n");
   1272  1.88.2.1   yamt 		}
   1273  1.88.2.5   yamt 		FW_GLOCK(fc);
   1274  1.88.2.1   yamt 		dbch->xferq.queued --;
   1275  1.88.2.5   yamt 		FW_GUNLOCK(fc);
   1276  1.88.2.1   yamt 		tr->xfer = NULL;
   1277      1.62   haya 
   1278  1.88.2.1   yamt 		fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREREAD);
   1279  1.88.2.1   yamt 		packets ++;
   1280  1.88.2.1   yamt 		tr = STAILQ_NEXT(tr, link);
   1281  1.88.2.1   yamt 		dbch->bottom = tr;
   1282  1.88.2.1   yamt 		if (dbch->bottom == dbch->top) {
   1283  1.88.2.1   yamt 			/* we reaches the end of context program */
   1284  1.88.2.1   yamt 			if (firewire_debug && dbch->xferq.queued > 0)
   1285  1.88.2.1   yamt 				printf("queued > 0\n");
   1286  1.88.2.1   yamt 			break;
   1287  1.88.2.1   yamt 		}
   1288  1.88.2.1   yamt 	}
   1289  1.88.2.1   yamt out:
   1290  1.88.2.1   yamt 	if ((dbch->flags & FWOHCI_DBCH_FULL) && packets > 0) {
   1291  1.88.2.1   yamt 		printf("make free slot\n");
   1292  1.88.2.1   yamt 		dbch->flags &= ~FWOHCI_DBCH_FULL;
   1293  1.88.2.5   yamt 		FW_GLOCK(fc);
   1294  1.88.2.1   yamt 		fwohci_start(sc, dbch);
   1295  1.88.2.5   yamt 		FW_GUNLOCK(fc);
   1296  1.88.2.1   yamt 	}
   1297  1.88.2.1   yamt 	fwdma_sync_multiseg_all(
   1298  1.88.2.1   yamt 	    dbch->am, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1299  1.88.2.1   yamt 	splx(s);
   1300      1.24    jmc }
   1301      1.24    jmc 
   1302      1.24    jmc static void
   1303  1.88.2.1   yamt fwohci_db_free(struct fwohci_dbch *dbch)
   1304      1.24    jmc {
   1305  1.88.2.1   yamt 	struct fwohcidb_tr *db_tr;
   1306  1.88.2.1   yamt 	int idb;
   1307      1.26  enami 
   1308  1.88.2.1   yamt 	if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
   1309  1.88.2.1   yamt 		return;
   1310      1.26  enami 
   1311  1.88.2.1   yamt 	for(db_tr = STAILQ_FIRST(&dbch->db_trq), idb = 0; idb < dbch->ndb;
   1312  1.88.2.1   yamt 			db_tr = STAILQ_NEXT(db_tr, link), idb++){
   1313  1.88.2.1   yamt 		if ((dbch->xferq.flag & FWXFERQ_EXTBUF) == 0 &&
   1314  1.88.2.1   yamt 					db_tr->buf != NULL) {
   1315  1.88.2.1   yamt 			fwdma_free_size(dbch->dmat, db_tr->dma_map,
   1316  1.88.2.1   yamt 					db_tr->buf, dbch->xferq.psize);
   1317  1.88.2.1   yamt 			db_tr->buf = NULL;
   1318  1.88.2.1   yamt 		} else if (db_tr->dma_map != NULL)
   1319  1.88.2.1   yamt 			fw_bus_dmamap_destroy(dbch->dmat, db_tr->dma_map);
   1320  1.88.2.1   yamt 	}
   1321  1.88.2.1   yamt 	dbch->ndb = 0;
   1322  1.88.2.1   yamt 	db_tr = STAILQ_FIRST(&dbch->db_trq);
   1323  1.88.2.1   yamt 	fwdma_free_multiseg(dbch->am);
   1324  1.88.2.1   yamt 	free(db_tr, M_FW);
   1325  1.88.2.1   yamt 	STAILQ_INIT(&dbch->db_trq);
   1326  1.88.2.1   yamt 	dbch->flags &= ~FWOHCI_DBCH_INIT;
   1327  1.88.2.4   yamt 	seldestroy(&dbch->xferq.rsel);
   1328  1.88.2.1   yamt }
   1329      1.26  enami 
   1330  1.88.2.1   yamt static void
   1331  1.88.2.1   yamt fwohci_db_init(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
   1332  1.88.2.1   yamt {
   1333  1.88.2.1   yamt 	int	idb;
   1334  1.88.2.1   yamt 	struct fwohcidb_tr *db_tr;
   1335  1.88.2.1   yamt 
   1336  1.88.2.1   yamt 	if ((dbch->flags & FWOHCI_DBCH_INIT) != 0)
   1337  1.88.2.1   yamt 		goto out;
   1338  1.88.2.1   yamt 
   1339  1.88.2.1   yamt 	/* create dma_tag for buffers */
   1340  1.88.2.1   yamt #define MAX_REQCOUNT	0xffff
   1341  1.88.2.1   yamt 	if (fw_bus_dma_tag_create(/*parent*/ sc->fc.dmat,
   1342  1.88.2.1   yamt 			/*alignment*/ 1, /*boundary*/ 0,
   1343  1.88.2.1   yamt 			/*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
   1344  1.88.2.1   yamt 			/*highaddr*/ BUS_SPACE_MAXADDR,
   1345  1.88.2.1   yamt 			/*filter*/NULL, /*filterarg*/NULL,
   1346  1.88.2.1   yamt 			/*maxsize*/ dbch->xferq.psize,
   1347  1.88.2.1   yamt 			/*nsegments*/ dbch->ndesc > 3 ? dbch->ndesc - 2 : 1,
   1348  1.88.2.1   yamt 			/*maxsegsz*/ MAX_REQCOUNT,
   1349  1.88.2.1   yamt 			/*flags*/ 0,
   1350  1.88.2.1   yamt 			/*lockfunc*/busdma_lock_mutex,
   1351  1.88.2.5   yamt 			/*lockarg*/FW_GMTX(&sc->fc),
   1352  1.88.2.1   yamt 			&dbch->dmat))
   1353  1.88.2.1   yamt 		return;
   1354      1.26  enami 
   1355  1.88.2.1   yamt 	/* allocate DB entries and attach one to each DMA channels */
   1356  1.88.2.1   yamt 	/* DB entry must start at 16 bytes bounary. */
   1357  1.88.2.1   yamt 	STAILQ_INIT(&dbch->db_trq);
   1358  1.88.2.1   yamt 	db_tr = (struct fwohcidb_tr *)
   1359  1.88.2.1   yamt 		malloc(sizeof(struct fwohcidb_tr) * dbch->ndb,
   1360  1.88.2.1   yamt 		M_FW, M_WAITOK | M_ZERO);
   1361  1.88.2.1   yamt 	if(db_tr == NULL){
   1362  1.88.2.1   yamt 		printf("fwohci_db_init: malloc(1) failed\n");
   1363  1.88.2.1   yamt 		return;
   1364  1.88.2.1   yamt 	}
   1365      1.35   onoe 
   1366  1.88.2.1   yamt #define DB_SIZE(x) (sizeof(struct fwohcidb) * (x)->ndesc)
   1367  1.88.2.1   yamt 	dbch->am = fwdma_malloc_multiseg(&sc->fc, DB_SIZE(dbch),
   1368  1.88.2.1   yamt 		DB_SIZE(dbch), dbch->ndb, BUS_DMA_WAITOK | BUS_DMA_COHERENT);
   1369  1.88.2.1   yamt 	if (dbch->am == NULL) {
   1370  1.88.2.1   yamt 		printf("fwohci_db_init: fwdma_malloc_multiseg failed\n");
   1371  1.88.2.1   yamt 		free(db_tr, M_FW);
   1372  1.88.2.1   yamt 		return;
   1373  1.88.2.1   yamt 	}
   1374  1.88.2.1   yamt 	/* Attach DB to DMA ch. */
   1375  1.88.2.1   yamt 	for(idb = 0 ; idb < dbch->ndb ; idb++){
   1376  1.88.2.1   yamt 		db_tr->dbcnt = 0;
   1377  1.88.2.1   yamt 		db_tr->db = (struct fwohcidb *)fwdma_v_addr(dbch->am, idb);
   1378  1.88.2.1   yamt 		db_tr->bus_addr = fwdma_bus_addr(dbch->am, idb);
   1379  1.88.2.1   yamt 		/* create dmamap for buffers */
   1380  1.88.2.1   yamt 		/* XXX do we need 4bytes alignment tag? */
   1381  1.88.2.1   yamt 		/* XXX don't alloc dma_map for AR */
   1382  1.88.2.1   yamt 		if (fw_bus_dmamap_create(dbch->dmat, 0, &db_tr->dma_map) != 0) {
   1383  1.88.2.1   yamt 			printf("fw_bus_dmamap_create failed\n");
   1384  1.88.2.1   yamt 			dbch->flags = FWOHCI_DBCH_INIT; /* XXX fake */
   1385  1.88.2.1   yamt 			fwohci_db_free(dbch);
   1386  1.88.2.1   yamt 			return;
   1387      1.35   onoe 		}
   1388  1.88.2.1   yamt 		STAILQ_INSERT_TAIL(&dbch->db_trq, db_tr, link);
   1389  1.88.2.1   yamt 		if (dbch->xferq.flag & FWXFERQ_EXTBUF) {
   1390  1.88.2.1   yamt 			if (idb % dbch->xferq.bnpacket == 0)
   1391  1.88.2.1   yamt 				dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket
   1392  1.88.2.3   yamt 						].start = (void *)db_tr;
   1393  1.88.2.1   yamt 			if ((idb + 1) % dbch->xferq.bnpacket == 0)
   1394  1.88.2.1   yamt 				dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket
   1395  1.88.2.3   yamt 						].end = (void *)db_tr;
   1396      1.26  enami 		}
   1397  1.88.2.1   yamt 		db_tr++;
   1398      1.26  enami 	}
   1399  1.88.2.1   yamt 	STAILQ_LAST(&dbch->db_trq, fwohcidb_tr,link)->link.stqe_next
   1400  1.88.2.1   yamt 			= STAILQ_FIRST(&dbch->db_trq);
   1401  1.88.2.1   yamt out:
   1402  1.88.2.1   yamt 	dbch->xferq.queued = 0;
   1403  1.88.2.1   yamt 	dbch->pdb_tr = NULL;
   1404  1.88.2.1   yamt 	dbch->top = STAILQ_FIRST(&dbch->db_trq);
   1405  1.88.2.1   yamt 	dbch->bottom = dbch->top;
   1406  1.88.2.1   yamt 	dbch->flags = FWOHCI_DBCH_INIT;
   1407  1.88.2.4   yamt 	selinit(&dbch->xferq.rsel);
   1408      1.24    jmc }
   1409      1.24    jmc 
   1410       1.5   matt static int
   1411  1.88.2.1   yamt fwohci_itx_disable(struct firewire_comm *fc, int dmach)
   1412       1.5   matt {
   1413  1.88.2.1   yamt 	struct fwohci_softc *sc = (struct fwohci_softc *)fc;
   1414  1.88.2.1   yamt 	int sleepch;
   1415       1.5   matt 
   1416  1.88.2.1   yamt 	OWRITE(sc, OHCI_ITCTLCLR(dmach),
   1417  1.88.2.1   yamt 			OHCI_CNTL_DMA_RUN | OHCI_CNTL_CYCMATCH_S);
   1418  1.88.2.1   yamt 	OWRITE(sc, OHCI_IT_MASKCLR, 1 << dmach);
   1419  1.88.2.1   yamt 	OWRITE(sc, OHCI_IT_STATCLR, 1 << dmach);
   1420  1.88.2.1   yamt 	/* XXX we cannot free buffers until the DMA really stops */
   1421  1.88.2.1   yamt 	tsleep((void *)&sleepch, FWPRI, "fwitxd", hz);
   1422  1.88.2.1   yamt 	fwohci_db_free(&sc->it[dmach]);
   1423  1.88.2.1   yamt 	sc->it[dmach].xferq.flag &= ~FWXFERQ_RUNNING;
   1424  1.88.2.1   yamt 	return 0;
   1425       1.5   matt }
   1426       1.5   matt 
   1427  1.88.2.1   yamt static int
   1428  1.88.2.1   yamt fwohci_irx_disable(struct firewire_comm *fc, int dmach)
   1429       1.3   onoe {
   1430  1.88.2.1   yamt 	struct fwohci_softc *sc = (struct fwohci_softc *)fc;
   1431  1.88.2.1   yamt 	int sleepch;
   1432       1.3   onoe 
   1433  1.88.2.1   yamt 	OWRITE(sc, OHCI_IRCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
   1434  1.88.2.1   yamt 	OWRITE(sc, OHCI_IR_MASKCLR, 1 << dmach);
   1435  1.88.2.1   yamt 	OWRITE(sc, OHCI_IR_STATCLR, 1 << dmach);
   1436  1.88.2.1   yamt 	/* XXX we cannot free buffers until the DMA really stops */
   1437  1.88.2.1   yamt 	tsleep((void *)&sleepch, FWPRI, "fwirxd", hz);
   1438  1.88.2.1   yamt 	fwohci_db_free(&sc->ir[dmach]);
   1439  1.88.2.1   yamt 	sc->ir[dmach].xferq.flag &= ~FWXFERQ_RUNNING;
   1440  1.88.2.1   yamt 	return 0;
   1441       1.3   onoe }
   1442       1.3   onoe 
   1443  1.88.2.1   yamt #if BYTE_ORDER == BIG_ENDIAN
   1444       1.7   onoe static void
   1445  1.88.2.1   yamt fwohci_irx_post (struct firewire_comm *fc , uint32_t *qld)
   1446       1.7   onoe {
   1447  1.88.2.1   yamt 	qld[0] = FWOHCI_DMA_READ(qld[0]);
   1448  1.88.2.1   yamt 	return;
   1449  1.88.2.1   yamt }
   1450  1.88.2.1   yamt #endif
   1451       1.7   onoe 
   1452  1.88.2.1   yamt static int
   1453  1.88.2.1   yamt fwohci_tx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
   1454  1.88.2.1   yamt {
   1455  1.88.2.1   yamt 	int err = 0;
   1456  1.88.2.1   yamt 	int idb, z, i, dmach = 0, ldesc;
   1457  1.88.2.1   yamt 	uint32_t off = 0;
   1458  1.88.2.1   yamt 	struct fwohcidb_tr *db_tr;
   1459  1.88.2.1   yamt 	struct fwohcidb *db;
   1460  1.88.2.1   yamt 
   1461  1.88.2.1   yamt 	if(!(dbch->xferq.flag & FWXFERQ_EXTBUF)){
   1462  1.88.2.1   yamt 		err = EINVAL;
   1463  1.88.2.1   yamt 		return err;
   1464  1.88.2.1   yamt 	}
   1465  1.88.2.1   yamt 	z = dbch->ndesc;
   1466  1.88.2.1   yamt 	for(dmach = 0 ; dmach < sc->fc.nisodma ; dmach++){
   1467  1.88.2.1   yamt 		if( &sc->it[dmach] == dbch){
   1468  1.88.2.1   yamt 			off = OHCI_ITOFF(dmach);
   1469       1.7   onoe 			break;
   1470  1.88.2.1   yamt 		}
   1471       1.7   onoe 	}
   1472  1.88.2.1   yamt 	if(off == 0){
   1473  1.88.2.1   yamt 		err = EINVAL;
   1474  1.88.2.1   yamt 		return err;
   1475  1.88.2.1   yamt 	}
   1476  1.88.2.1   yamt 	if(dbch->xferq.flag & FWXFERQ_RUNNING)
   1477  1.88.2.1   yamt 		return err;
   1478  1.88.2.1   yamt 	dbch->xferq.flag |= FWXFERQ_RUNNING;
   1479  1.88.2.1   yamt 	for( i = 0, dbch->bottom = dbch->top; i < (dbch->ndb - 1); i++){
   1480  1.88.2.1   yamt 		dbch->bottom = STAILQ_NEXT(dbch->bottom, link);
   1481  1.88.2.1   yamt 	}
   1482  1.88.2.1   yamt 	db_tr = dbch->top;
   1483  1.88.2.1   yamt 	for (idb = 0; idb < dbch->ndb; idb ++) {
   1484  1.88.2.1   yamt 		fwohci_add_tx_buf(dbch, db_tr, idb);
   1485  1.88.2.1   yamt 		if(STAILQ_NEXT(db_tr, link) == NULL){
   1486  1.88.2.1   yamt 			break;
   1487  1.88.2.1   yamt 		}
   1488  1.88.2.1   yamt 		db = db_tr->db;
   1489  1.88.2.1   yamt 		ldesc = db_tr->dbcnt - 1;
   1490  1.88.2.1   yamt 		FWOHCI_DMA_WRITE(db[0].db.desc.depend,
   1491  1.88.2.1   yamt 				STAILQ_NEXT(db_tr, link)->bus_addr | z);
   1492  1.88.2.1   yamt 		db[ldesc].db.desc.depend = db[0].db.desc.depend;
   1493  1.88.2.1   yamt 		if(dbch->xferq.flag & FWXFERQ_EXTBUF){
   1494  1.88.2.1   yamt 			if(((idb + 1 ) % dbch->xferq.bnpacket) == 0){
   1495  1.88.2.1   yamt 				FWOHCI_DMA_SET(
   1496  1.88.2.1   yamt 					db[ldesc].db.desc.cmd,
   1497  1.88.2.1   yamt 					OHCI_INTERRUPT_ALWAYS);
   1498  1.88.2.1   yamt 				/* OHCI 1.1 and above */
   1499  1.88.2.1   yamt 				FWOHCI_DMA_SET(
   1500  1.88.2.1   yamt 					db[0].db.desc.cmd,
   1501  1.88.2.1   yamt 					OHCI_INTERRUPT_ALWAYS);
   1502  1.88.2.1   yamt 			}
   1503  1.88.2.1   yamt 		}
   1504  1.88.2.1   yamt 		db_tr = STAILQ_NEXT(db_tr, link);
   1505  1.88.2.1   yamt 	}
   1506  1.88.2.1   yamt 	FWOHCI_DMA_CLEAR(
   1507  1.88.2.1   yamt 		dbch->bottom->db[dbch->bottom->dbcnt - 1].db.desc.depend, 0xf);
   1508  1.88.2.1   yamt 	return err;
   1509  1.88.2.1   yamt }
   1510       1.7   onoe 
   1511  1.88.2.1   yamt static int
   1512  1.88.2.1   yamt fwohci_rx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
   1513  1.88.2.1   yamt {
   1514  1.88.2.1   yamt 	int err = 0;
   1515  1.88.2.1   yamt 	int idb, z, i, dmach = 0, ldesc;
   1516  1.88.2.1   yamt 	uint32_t off = 0;
   1517  1.88.2.1   yamt 	struct fwohcidb_tr *db_tr;
   1518  1.88.2.1   yamt 	struct fwohcidb *db;
   1519  1.88.2.1   yamt 
   1520  1.88.2.1   yamt 	z = dbch->ndesc;
   1521  1.88.2.1   yamt 	if(&sc->arrq == dbch){
   1522  1.88.2.1   yamt 		off = OHCI_ARQOFF;
   1523  1.88.2.1   yamt 	}else if(&sc->arrs == dbch){
   1524  1.88.2.1   yamt 		off = OHCI_ARSOFF;
   1525  1.88.2.1   yamt 	}else{
   1526  1.88.2.1   yamt 		for(dmach = 0 ; dmach < sc->fc.nisodma ; dmach++){
   1527  1.88.2.1   yamt 			if( &sc->ir[dmach] == dbch){
   1528  1.88.2.1   yamt 				off = OHCI_IROFF(dmach);
   1529  1.88.2.1   yamt 				break;
   1530  1.88.2.1   yamt 			}
   1531  1.88.2.1   yamt 		}
   1532  1.88.2.1   yamt 	}
   1533  1.88.2.1   yamt 	if(off == 0){
   1534  1.88.2.1   yamt 		err = EINVAL;
   1535  1.88.2.1   yamt 		return err;
   1536  1.88.2.1   yamt 	}
   1537  1.88.2.1   yamt 	if(dbch->xferq.flag & FWXFERQ_STREAM){
   1538  1.88.2.1   yamt 		if(dbch->xferq.flag & FWXFERQ_RUNNING)
   1539  1.88.2.1   yamt 			return err;
   1540  1.88.2.1   yamt 	}else{
   1541  1.88.2.1   yamt 		if(dbch->xferq.flag & FWXFERQ_RUNNING){
   1542  1.88.2.1   yamt 			err = EBUSY;
   1543  1.88.2.1   yamt 			return err;
   1544  1.88.2.1   yamt 		}
   1545  1.88.2.1   yamt 	}
   1546  1.88.2.1   yamt 	dbch->xferq.flag |= FWXFERQ_RUNNING;
   1547  1.88.2.1   yamt 	dbch->top = STAILQ_FIRST(&dbch->db_trq);
   1548  1.88.2.1   yamt 	for( i = 0, dbch->bottom = dbch->top; i < (dbch->ndb - 1); i++){
   1549  1.88.2.1   yamt 		dbch->bottom = STAILQ_NEXT(dbch->bottom, link);
   1550  1.88.2.1   yamt 	}
   1551  1.88.2.1   yamt 	db_tr = dbch->top;
   1552  1.88.2.5   yamt 	if (db_tr->dbcnt != 0)
   1553  1.88.2.5   yamt 		goto run;
   1554  1.88.2.1   yamt 	for (idb = 0; idb < dbch->ndb; idb ++) {
   1555  1.88.2.1   yamt 		fwohci_add_rx_buf(dbch, db_tr, idb, &sc->dummy_dma);
   1556  1.88.2.1   yamt 		if (STAILQ_NEXT(db_tr, link) == NULL)
   1557  1.88.2.1   yamt 			break;
   1558  1.88.2.1   yamt 		db = db_tr->db;
   1559  1.88.2.1   yamt 		ldesc = db_tr->dbcnt - 1;
   1560  1.88.2.1   yamt 		FWOHCI_DMA_WRITE(db[ldesc].db.desc.depend,
   1561  1.88.2.1   yamt 			STAILQ_NEXT(db_tr, link)->bus_addr | z);
   1562  1.88.2.1   yamt 		if(dbch->xferq.flag & FWXFERQ_EXTBUF){
   1563  1.88.2.1   yamt 			if(((idb + 1 ) % dbch->xferq.bnpacket) == 0){
   1564  1.88.2.1   yamt 				FWOHCI_DMA_SET(
   1565  1.88.2.1   yamt 					db[ldesc].db.desc.cmd,
   1566  1.88.2.1   yamt 					OHCI_INTERRUPT_ALWAYS);
   1567  1.88.2.1   yamt 				FWOHCI_DMA_CLEAR(
   1568  1.88.2.1   yamt 					db[ldesc].db.desc.depend,
   1569  1.88.2.1   yamt 					0xf);
   1570  1.88.2.1   yamt 			}
   1571  1.88.2.1   yamt 		}
   1572  1.88.2.1   yamt 		db_tr = STAILQ_NEXT(db_tr, link);
   1573  1.88.2.1   yamt 	}
   1574  1.88.2.1   yamt 	FWOHCI_DMA_CLEAR(
   1575  1.88.2.1   yamt 		dbch->bottom->db[db_tr->dbcnt - 1].db.desc.depend, 0xf);
   1576  1.88.2.1   yamt 	dbch->buf_offset = 0;
   1577  1.88.2.5   yamt run:
   1578  1.88.2.1   yamt 	fwdma_sync_multiseg_all(dbch->am,
   1579  1.88.2.1   yamt 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1580  1.88.2.1   yamt 	if(dbch->xferq.flag & FWXFERQ_STREAM){
   1581  1.88.2.1   yamt 		return err;
   1582  1.88.2.1   yamt 	}else{
   1583  1.88.2.1   yamt 		OWRITE(sc, OHCI_DMACMD(off), dbch->top->bus_addr | z);
   1584  1.88.2.1   yamt 	}
   1585  1.88.2.1   yamt 	OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_RUN);
   1586  1.88.2.1   yamt 	return err;
   1587  1.88.2.1   yamt }
   1588       1.7   onoe 
   1589  1.88.2.1   yamt static int
   1590  1.88.2.1   yamt fwohci_next_cycle(struct firewire_comm *fc, int cycle_now)
   1591  1.88.2.1   yamt {
   1592  1.88.2.1   yamt 	int sec, cycle, cycle_match;
   1593  1.88.2.1   yamt 
   1594  1.88.2.1   yamt 	cycle = cycle_now & 0x1fff;
   1595  1.88.2.1   yamt 	sec = cycle_now >> 13;
   1596  1.88.2.1   yamt #define CYCLE_MOD	0x10
   1597  1.88.2.1   yamt #if 1
   1598  1.88.2.1   yamt #define CYCLE_DELAY	8	/* min delay to start DMA */
   1599       1.7   onoe #else
   1600  1.88.2.1   yamt #define CYCLE_DELAY	7000	/* min delay to start DMA */
   1601       1.7   onoe #endif
   1602  1.88.2.1   yamt 	cycle = cycle + CYCLE_DELAY;
   1603  1.88.2.1   yamt 	if (cycle >= 8000) {
   1604  1.88.2.1   yamt 		sec ++;
   1605  1.88.2.1   yamt 		cycle -= 8000;
   1606  1.88.2.1   yamt 	}
   1607  1.88.2.1   yamt 	cycle = roundup2(cycle, CYCLE_MOD);
   1608  1.88.2.1   yamt 	if (cycle >= 8000) {
   1609  1.88.2.1   yamt 		sec ++;
   1610  1.88.2.1   yamt 		if (cycle == 8000)
   1611  1.88.2.1   yamt 			cycle = 0;
   1612  1.88.2.1   yamt 		else
   1613  1.88.2.1   yamt 			cycle = CYCLE_MOD;
   1614  1.88.2.1   yamt 	}
   1615  1.88.2.1   yamt 	cycle_match = ((sec << 13) | cycle) & 0x7ffff;
   1616       1.7   onoe 
   1617  1.88.2.1   yamt 	return(cycle_match);
   1618  1.88.2.1   yamt }
   1619       1.7   onoe 
   1620  1.88.2.1   yamt static int
   1621  1.88.2.1   yamt fwohci_itxbuf_enable(struct firewire_comm *fc, int dmach)
   1622  1.88.2.1   yamt {
   1623  1.88.2.1   yamt 	struct fwohci_softc *sc = (struct fwohci_softc *)fc;
   1624  1.88.2.1   yamt 	int err = 0;
   1625  1.88.2.1   yamt 	unsigned short tag, ich;
   1626  1.88.2.1   yamt 	struct fwohci_dbch *dbch;
   1627  1.88.2.1   yamt 	int cycle_match, cycle_now, s, ldesc;
   1628  1.88.2.1   yamt 	uint32_t stat;
   1629  1.88.2.1   yamt 	struct fw_bulkxfer *first, *chunk, *prev;
   1630  1.88.2.1   yamt 	struct fw_xferq *it;
   1631  1.88.2.1   yamt 
   1632  1.88.2.1   yamt 	dbch = &sc->it[dmach];
   1633  1.88.2.1   yamt 	it = &dbch->xferq;
   1634  1.88.2.1   yamt 
   1635  1.88.2.1   yamt 	tag = (it->flag >> 6) & 3;
   1636  1.88.2.1   yamt 	ich = it->flag & 0x3f;
   1637  1.88.2.1   yamt 	if ((dbch->flags & FWOHCI_DBCH_INIT) == 0) {
   1638  1.88.2.1   yamt 		dbch->ndb = it->bnpacket * it->bnchunk;
   1639  1.88.2.1   yamt 		dbch->ndesc = 3;
   1640  1.88.2.1   yamt 		fwohci_db_init(sc, dbch);
   1641  1.88.2.1   yamt 		if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
   1642  1.88.2.1   yamt 			return ENOMEM;
   1643  1.88.2.5   yamt 
   1644  1.88.2.1   yamt 		err = fwohci_tx_enable(sc, dbch);
   1645  1.88.2.1   yamt 	}
   1646  1.88.2.1   yamt 	if(err)
   1647  1.88.2.1   yamt 		return err;
   1648  1.88.2.1   yamt 
   1649  1.88.2.1   yamt 	ldesc = dbch->ndesc - 1;
   1650  1.88.2.1   yamt 	s = splfw();
   1651  1.88.2.5   yamt 	FW_GLOCK(fc);
   1652  1.88.2.1   yamt 	prev = STAILQ_LAST(&it->stdma, fw_bulkxfer, link);
   1653  1.88.2.1   yamt 	while  ((chunk = STAILQ_FIRST(&it->stvalid)) != NULL) {
   1654  1.88.2.1   yamt 		struct fwohcidb *db;
   1655  1.88.2.1   yamt 
   1656  1.88.2.1   yamt 		fwdma_sync_multiseg(it->buf, chunk->poffset, it->bnpacket,
   1657  1.88.2.1   yamt 					BUS_DMASYNC_PREWRITE);
   1658  1.88.2.1   yamt 		fwohci_txbufdb(sc, dmach, chunk);
   1659  1.88.2.1   yamt 		if (prev != NULL) {
   1660  1.88.2.1   yamt 			db = ((struct fwohcidb_tr *)(prev->end))->db;
   1661  1.88.2.1   yamt #if 0 /* XXX necessary? */
   1662  1.88.2.1   yamt 			FWOHCI_DMA_SET(db[ldesc].db.desc.cmd,
   1663  1.88.2.1   yamt 						OHCI_BRANCH_ALWAYS);
   1664  1.88.2.1   yamt #endif
   1665  1.88.2.1   yamt #if 0 /* if bulkxfer->npacket changes */
   1666  1.88.2.1   yamt 			db[ldesc].db.desc.depend = db[0].db.desc.depend =
   1667  1.88.2.1   yamt 				((struct fwohcidb_tr *)
   1668  1.88.2.1   yamt 				(chunk->start))->bus_addr | dbch->ndesc;
   1669  1.88.2.1   yamt #else
   1670  1.88.2.1   yamt 			FWOHCI_DMA_SET(db[0].db.desc.depend, dbch->ndesc);
   1671  1.88.2.1   yamt 			FWOHCI_DMA_SET(db[ldesc].db.desc.depend, dbch->ndesc);
   1672  1.88.2.1   yamt #endif
   1673  1.88.2.1   yamt 		}
   1674  1.88.2.1   yamt 		STAILQ_REMOVE_HEAD(&it->stvalid, link);
   1675  1.88.2.1   yamt 		STAILQ_INSERT_TAIL(&it->stdma, chunk, link);
   1676  1.88.2.1   yamt 		prev = chunk;
   1677  1.88.2.1   yamt 	}
   1678  1.88.2.5   yamt 	FW_GUNLOCK(fc);
   1679  1.88.2.1   yamt 	fwdma_sync_multiseg_all(dbch->am,
   1680  1.88.2.1   yamt 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1681  1.88.2.1   yamt 	splx(s);
   1682  1.88.2.1   yamt 	stat = OREAD(sc, OHCI_ITCTL(dmach));
   1683  1.88.2.1   yamt 	if (firewire_debug && (stat & OHCI_CNTL_CYCMATCH_S))
   1684  1.88.2.1   yamt 		printf("stat 0x%x\n", stat);
   1685  1.88.2.1   yamt 
   1686  1.88.2.1   yamt 	if (stat & (OHCI_CNTL_DMA_ACTIVE | OHCI_CNTL_CYCMATCH_S))
   1687  1.88.2.1   yamt 		return 0;
   1688  1.88.2.1   yamt 
   1689  1.88.2.1   yamt #if 0
   1690  1.88.2.1   yamt 	OWRITE(sc, OHCI_ITCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
   1691  1.88.2.1   yamt #endif
   1692  1.88.2.1   yamt 	OWRITE(sc, OHCI_IT_MASKCLR, 1 << dmach);
   1693  1.88.2.1   yamt 	OWRITE(sc, OHCI_IT_STATCLR, 1 << dmach);
   1694  1.88.2.1   yamt 	OWRITE(sc, OHCI_IT_MASK, 1 << dmach);
   1695  1.88.2.1   yamt 	OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_DMA_IT);
   1696  1.88.2.1   yamt 
   1697  1.88.2.1   yamt 	first = STAILQ_FIRST(&it->stdma);
   1698  1.88.2.1   yamt 	OWRITE(sc, OHCI_ITCMD(dmach),
   1699  1.88.2.1   yamt 		((struct fwohcidb_tr *)(first->start))->bus_addr | dbch->ndesc);
   1700  1.88.2.1   yamt 	if (firewire_debug > 1) {
   1701  1.88.2.1   yamt 		printf("fwohci_itxbuf_enable: kick 0x%08x\n", stat);
   1702  1.88.2.1   yamt #if 1
   1703  1.88.2.1   yamt 		dump_dma(sc, ITX_CH + dmach);
   1704      1.22  enami #endif
   1705  1.88.2.1   yamt 	}
   1706  1.88.2.1   yamt 	if ((stat & OHCI_CNTL_DMA_RUN) == 0) {
   1707  1.88.2.1   yamt #if 1
   1708  1.88.2.1   yamt 		/* Don't start until all chunks are buffered */
   1709  1.88.2.1   yamt 		if (STAILQ_FIRST(&it->stfree) != NULL)
   1710  1.88.2.1   yamt 			goto out;
   1711  1.88.2.1   yamt #endif
   1712  1.88.2.1   yamt #if 1
   1713  1.88.2.1   yamt 		/* Clear cycle match counter bits */
   1714  1.88.2.1   yamt 		OWRITE(sc, OHCI_ITCTLCLR(dmach), 0xffff0000);
   1715       1.7   onoe 
   1716  1.88.2.1   yamt 		/* 2bit second + 13bit cycle */
   1717  1.88.2.1   yamt 		cycle_now = (fc->cyctimer(fc) >> 12) & 0x7fff;
   1718  1.88.2.1   yamt 		cycle_match = fwohci_next_cycle(fc, cycle_now);
   1719  1.88.2.1   yamt 
   1720  1.88.2.1   yamt 		OWRITE(sc, OHCI_ITCTL(dmach),
   1721  1.88.2.1   yamt 				OHCI_CNTL_CYCMATCH_S | (cycle_match << 16)
   1722  1.88.2.1   yamt 				| OHCI_CNTL_DMA_RUN);
   1723  1.88.2.1   yamt #else
   1724  1.88.2.1   yamt 		OWRITE(sc, OHCI_ITCTL(dmach), OHCI_CNTL_DMA_RUN);
   1725  1.88.2.1   yamt #endif
   1726  1.88.2.1   yamt 		if (firewire_debug > 1) {
   1727  1.88.2.1   yamt 			printf("cycle_match: 0x%04x->0x%04x\n",
   1728  1.88.2.1   yamt 						cycle_now, cycle_match);
   1729  1.88.2.1   yamt 			dump_dma(sc, ITX_CH + dmach);
   1730  1.88.2.1   yamt 			dump_db(sc, ITX_CH + dmach);
   1731  1.88.2.1   yamt 		}
   1732  1.88.2.1   yamt 	} else if ((stat & OHCI_CNTL_CYCMATCH_S) == 0) {
   1733  1.88.2.5   yamt 		fw_printf(sc->fc.dev, "IT DMA underrun (0x%08x)\n", stat);
   1734  1.88.2.1   yamt 		OWRITE(sc, OHCI_ITCTL(dmach), OHCI_CNTL_DMA_WAKE);
   1735  1.88.2.1   yamt 	}
   1736  1.88.2.1   yamt out:
   1737  1.88.2.1   yamt 	return err;
   1738  1.88.2.1   yamt }
   1739       1.7   onoe 
   1740  1.88.2.1   yamt static int
   1741  1.88.2.1   yamt fwohci_irx_enable(struct firewire_comm *fc, int dmach)
   1742  1.88.2.1   yamt {
   1743  1.88.2.1   yamt 	struct fwohci_softc *sc = (struct fwohci_softc *)fc;
   1744  1.88.2.1   yamt 	int err = 0, s, ldesc;
   1745  1.88.2.1   yamt 	unsigned short tag, ich;
   1746  1.88.2.1   yamt 	uint32_t stat;
   1747  1.88.2.1   yamt 	struct fwohci_dbch *dbch;
   1748  1.88.2.1   yamt 	struct fwohcidb_tr *db_tr;
   1749  1.88.2.1   yamt 	struct fw_bulkxfer *first, *prev, *chunk;
   1750  1.88.2.1   yamt 	struct fw_xferq *ir;
   1751  1.88.2.1   yamt 
   1752  1.88.2.1   yamt 	dbch = &sc->ir[dmach];
   1753  1.88.2.1   yamt 	ir = &dbch->xferq;
   1754  1.88.2.1   yamt 
   1755  1.88.2.1   yamt 	if ((ir->flag & FWXFERQ_RUNNING) == 0) {
   1756  1.88.2.1   yamt 		tag = (ir->flag >> 6) & 3;
   1757  1.88.2.1   yamt 		ich = ir->flag & 0x3f;
   1758  1.88.2.1   yamt 		OWRITE(sc, OHCI_IRMATCH(dmach), tagbit[tag] | ich);
   1759  1.88.2.1   yamt 
   1760  1.88.2.1   yamt 		ir->queued = 0;
   1761  1.88.2.1   yamt 		dbch->ndb = ir->bnpacket * ir->bnchunk;
   1762  1.88.2.1   yamt 		dbch->ndesc = 2;
   1763  1.88.2.1   yamt 		fwohci_db_init(sc, dbch);
   1764  1.88.2.1   yamt 		if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
   1765  1.88.2.1   yamt 			return ENOMEM;
   1766  1.88.2.1   yamt 		err = fwohci_rx_enable(sc, dbch);
   1767  1.88.2.1   yamt 	}
   1768  1.88.2.1   yamt 	if(err)
   1769  1.88.2.1   yamt 		return err;
   1770  1.88.2.1   yamt 
   1771  1.88.2.1   yamt 	first = STAILQ_FIRST(&ir->stfree);
   1772  1.88.2.1   yamt 	if (first == NULL) {
   1773  1.88.2.5   yamt 		fw_printf(fc->dev, "IR DMA no free chunk\n");
   1774  1.88.2.1   yamt 		return 0;
   1775  1.88.2.1   yamt 	}
   1776       1.7   onoe 
   1777  1.88.2.1   yamt 	ldesc = dbch->ndesc - 1;
   1778  1.88.2.1   yamt 	s = splfw();
   1779  1.88.2.5   yamt 	if ((ir->flag & FWXFERQ_HANDLER) == 0)
   1780  1.88.2.5   yamt 		FW_GLOCK(fc);
   1781  1.88.2.1   yamt 	prev = STAILQ_LAST(&ir->stdma, fw_bulkxfer, link);
   1782  1.88.2.1   yamt 	while  ((chunk = STAILQ_FIRST(&ir->stfree)) != NULL) {
   1783  1.88.2.1   yamt 		struct fwohcidb *db;
   1784  1.88.2.1   yamt 
   1785  1.88.2.1   yamt #if 1 /* XXX for if_fwe */
   1786  1.88.2.1   yamt 		if (chunk->mbuf != NULL) {
   1787  1.88.2.1   yamt 			db_tr = (struct fwohcidb_tr *)(chunk->start);
   1788  1.88.2.1   yamt 			db_tr->dbcnt = 1;
   1789  1.88.2.1   yamt 			err = fw_bus_dmamap_load_mbuf(
   1790  1.88.2.1   yamt 					dbch->dmat, db_tr->dma_map,
   1791  1.88.2.1   yamt 					chunk->mbuf, fwohci_execute_db2, db_tr,
   1792  1.88.2.1   yamt 					BUS_DMA_WAITOK);
   1793  1.88.2.1   yamt  			FWOHCI_DMA_SET(db_tr->db[1].db.desc.cmd,
   1794  1.88.2.1   yamt 				OHCI_UPDATE | OHCI_INPUT_LAST |
   1795  1.88.2.1   yamt 				OHCI_INTERRUPT_ALWAYS | OHCI_BRANCH_ALWAYS);
   1796  1.88.2.1   yamt 		}
   1797  1.88.2.1   yamt #endif
   1798  1.88.2.1   yamt 		db = ((struct fwohcidb_tr *)(chunk->end))->db;
   1799  1.88.2.1   yamt 		FWOHCI_DMA_WRITE(db[ldesc].db.desc.res, 0);
   1800  1.88.2.1   yamt 		FWOHCI_DMA_CLEAR(db[ldesc].db.desc.depend, 0xf);
   1801  1.88.2.1   yamt 		if (prev != NULL) {
   1802  1.88.2.1   yamt 			db = ((struct fwohcidb_tr *)(prev->end))->db;
   1803  1.88.2.1   yamt 			FWOHCI_DMA_SET(db[ldesc].db.desc.depend, dbch->ndesc);
   1804  1.88.2.1   yamt 		}
   1805  1.88.2.1   yamt 		STAILQ_REMOVE_HEAD(&ir->stfree, link);
   1806  1.88.2.1   yamt 		STAILQ_INSERT_TAIL(&ir->stdma, chunk, link);
   1807  1.88.2.1   yamt 		prev = chunk;
   1808  1.88.2.1   yamt 	}
   1809  1.88.2.5   yamt 	if ((ir->flag & FWXFERQ_HANDLER) == 0)
   1810  1.88.2.5   yamt 		FW_GUNLOCK(fc);
   1811  1.88.2.1   yamt 	fwdma_sync_multiseg_all(dbch->am,
   1812  1.88.2.1   yamt 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1813  1.88.2.1   yamt 	splx(s);
   1814  1.88.2.1   yamt 	stat = OREAD(sc, OHCI_IRCTL(dmach));
   1815  1.88.2.1   yamt 	if (stat & OHCI_CNTL_DMA_ACTIVE)
   1816  1.88.2.1   yamt 		return 0;
   1817  1.88.2.1   yamt 	if (stat & OHCI_CNTL_DMA_RUN) {
   1818  1.88.2.1   yamt 		OWRITE(sc, OHCI_IRCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
   1819  1.88.2.5   yamt 		fw_printf(sc->fc.dev, "IR DMA overrun (0x%08x)\n", stat);
   1820  1.88.2.1   yamt 	}
   1821  1.88.2.1   yamt 
   1822  1.88.2.1   yamt 	if (firewire_debug)
   1823  1.88.2.1   yamt 		printf("start IR DMA 0x%x\n", stat);
   1824  1.88.2.1   yamt 	OWRITE(sc, OHCI_IR_MASKCLR, 1 << dmach);
   1825  1.88.2.1   yamt 	OWRITE(sc, OHCI_IR_STATCLR, 1 << dmach);
   1826  1.88.2.1   yamt 	OWRITE(sc, OHCI_IR_MASK, 1 << dmach);
   1827  1.88.2.1   yamt 	OWRITE(sc, OHCI_IRCTLCLR(dmach), 0xf0000000);
   1828  1.88.2.1   yamt 	OWRITE(sc, OHCI_IRCTL(dmach), OHCI_CNTL_ISOHDR);
   1829  1.88.2.1   yamt 	OWRITE(sc, OHCI_IRCMD(dmach),
   1830  1.88.2.1   yamt 		((struct fwohcidb_tr *)(first->start))->bus_addr
   1831  1.88.2.1   yamt 							| dbch->ndesc);
   1832  1.88.2.1   yamt 	OWRITE(sc, OHCI_IRCTL(dmach), OHCI_CNTL_DMA_RUN);
   1833  1.88.2.1   yamt 	OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_DMA_IR);
   1834  1.88.2.1   yamt #if 0
   1835  1.88.2.1   yamt 	dump_db(sc, IRX_CH + dmach);
   1836  1.88.2.1   yamt #endif
   1837  1.88.2.1   yamt 	return err;
   1838  1.88.2.1   yamt }
   1839  1.88.2.1   yamt 
   1840  1.88.2.5   yamt int
   1841  1.88.2.5   yamt fwohci_stop(struct fwohci_softc *sc, device_t dev)
   1842  1.88.2.1   yamt {
   1843  1.88.2.1   yamt 	u_int i;
   1844  1.88.2.1   yamt 
   1845  1.88.2.1   yamt /* Now stopping all DMA channel */
   1846  1.88.2.1   yamt 	OWRITE(sc,  OHCI_ARQCTLCLR, OHCI_CNTL_DMA_RUN);
   1847  1.88.2.1   yamt 	OWRITE(sc,  OHCI_ARSCTLCLR, OHCI_CNTL_DMA_RUN);
   1848  1.88.2.1   yamt 	OWRITE(sc,  OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN);
   1849  1.88.2.1   yamt 	OWRITE(sc,  OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN);
   1850  1.88.2.1   yamt 
   1851  1.88.2.1   yamt 	for( i = 0 ; i < sc->fc.nisodma ; i ++ ){
   1852  1.88.2.1   yamt 		OWRITE(sc,  OHCI_IRCTLCLR(i), OHCI_CNTL_DMA_RUN);
   1853  1.88.2.1   yamt 		OWRITE(sc,  OHCI_ITCTLCLR(i), OHCI_CNTL_DMA_RUN);
   1854  1.88.2.1   yamt 	}
   1855  1.88.2.1   yamt 
   1856  1.88.2.5   yamt 	if (sc->fc.arq !=0 && sc->fc.arq->maxq > 0)
   1857  1.88.2.5   yamt 		fw_drain_txq(&sc->fc);
   1858  1.88.2.1   yamt 
   1859  1.88.2.5   yamt #if 0 /* Let dcons(4) be accessed */
   1860  1.88.2.1   yamt /* Stop interrupt */
   1861  1.88.2.1   yamt 	OWRITE(sc, FWOHCI_INTMASKCLR,
   1862  1.88.2.1   yamt 			OHCI_INT_EN | OHCI_INT_ERR | OHCI_INT_PHY_SID
   1863  1.88.2.1   yamt 			| OHCI_INT_PHY_INT
   1864  1.88.2.1   yamt 			| OHCI_INT_DMA_ATRQ | OHCI_INT_DMA_ATRS
   1865  1.88.2.1   yamt 			| OHCI_INT_DMA_PRRQ | OHCI_INT_DMA_PRRS
   1866  1.88.2.1   yamt 			| OHCI_INT_DMA_ARRQ | OHCI_INT_DMA_ARRS
   1867  1.88.2.1   yamt 			| OHCI_INT_PHY_BUS_R);
   1868  1.88.2.1   yamt 
   1869  1.88.2.5   yamt /* FLUSH FIFO and reset Transmitter/Reciever */
   1870  1.88.2.5   yamt 	OWRITE(sc,  OHCI_HCCCTL, OHCI_HCC_RESET);
   1871  1.88.2.5   yamt #endif
   1872  1.88.2.1   yamt 
   1873  1.88.2.1   yamt /* XXX Link down?  Bus reset? */
   1874  1.88.2.5   yamt 	return 0;
   1875       1.7   onoe }
   1876       1.7   onoe 
   1877  1.88.2.1   yamt int
   1878  1.88.2.1   yamt fwohci_resume(struct fwohci_softc *sc, device_t dev)
   1879       1.3   onoe {
   1880       1.3   onoe 	int i;
   1881  1.88.2.1   yamt 	struct fw_xferq *ir;
   1882  1.88.2.1   yamt 	struct fw_bulkxfer *chunk;
   1883       1.3   onoe 
   1884  1.88.2.1   yamt 	fwohci_reset(sc, dev);
   1885  1.88.2.1   yamt 	/* XXX resume isochronous receive automatically. (how about TX?) */
   1886  1.88.2.1   yamt 	for(i = 0; i < sc->fc.nisodma; i ++) {
   1887  1.88.2.1   yamt 		ir = &sc->ir[i].xferq;
   1888  1.88.2.1   yamt 		if((ir->flag & FWXFERQ_RUNNING) != 0) {
   1889  1.88.2.5   yamt 			fw_printf(sc->fc.dev,
   1890  1.88.2.1   yamt 				"resume iso receive ch: %d\n", i);
   1891  1.88.2.1   yamt 			ir->flag &= ~FWXFERQ_RUNNING;
   1892  1.88.2.1   yamt 			/* requeue stdma to stfree */
   1893  1.88.2.1   yamt 			while((chunk = STAILQ_FIRST(&ir->stdma)) != NULL) {
   1894  1.88.2.1   yamt 				STAILQ_REMOVE_HEAD(&ir->stdma, link);
   1895  1.88.2.1   yamt 				STAILQ_INSERT_TAIL(&ir->stfree, chunk, link);
   1896  1.88.2.1   yamt 			}
   1897  1.88.2.1   yamt 			sc->fc.irx_enable(&sc->fc, i);
   1898  1.88.2.1   yamt 		}
   1899  1.88.2.1   yamt 	}
   1900  1.88.2.1   yamt 
   1901  1.88.2.1   yamt #if defined(__FreeBSD__)
   1902  1.88.2.1   yamt 	bus_generic_resume(dev);
   1903  1.88.2.5   yamt #elif defined(__NetBSD__)
   1904  1.88.2.5   yamt 	{
   1905  1.88.2.5   yamt 		extern int firewire_resume(struct firewire_comm *);
   1906  1.88.2.5   yamt 		firewire_resume(&sc->fc);
   1907  1.88.2.5   yamt 	}
   1908  1.88.2.1   yamt #endif
   1909  1.88.2.1   yamt 	sc->fc.ibr(&sc->fc);
   1910  1.88.2.1   yamt 	return 0;
   1911  1.88.2.1   yamt }
   1912  1.88.2.1   yamt 
   1913  1.88.2.5   yamt #ifdef OHCI_DEBUG
   1914  1.88.2.1   yamt static void
   1915  1.88.2.5   yamt fwohci_dump_intr(struct fwohci_softc *sc, uint32_t stat)
   1916  1.88.2.1   yamt {
   1917  1.88.2.1   yamt 	if(stat & OREAD(sc, FWOHCI_INTMASK))
   1918  1.88.2.5   yamt 		fw_printf(fc->dev, "INTERRUPT < %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s> 0x%08x, 0x%08x\n",
   1919  1.88.2.1   yamt 			stat & OHCI_INT_EN ? "DMA_EN ":"",
   1920  1.88.2.1   yamt 			stat & OHCI_INT_PHY_REG ? "PHY_REG ":"",
   1921  1.88.2.1   yamt 			stat & OHCI_INT_CYC_LONG ? "CYC_LONG ":"",
   1922  1.88.2.1   yamt 			stat & OHCI_INT_ERR ? "INT_ERR ":"",
   1923  1.88.2.1   yamt 			stat & OHCI_INT_CYC_ERR ? "CYC_ERR ":"",
   1924  1.88.2.1   yamt 			stat & OHCI_INT_CYC_LOST ? "CYC_LOST ":"",
   1925  1.88.2.1   yamt 			stat & OHCI_INT_CYC_64SECOND ? "CYC_64SECOND ":"",
   1926  1.88.2.1   yamt 			stat & OHCI_INT_CYC_START ? "CYC_START ":"",
   1927  1.88.2.1   yamt 			stat & OHCI_INT_PHY_INT ? "PHY_INT ":"",
   1928  1.88.2.1   yamt 			stat & OHCI_INT_PHY_BUS_R ? "BUS_RESET ":"",
   1929  1.88.2.1   yamt 			stat & OHCI_INT_PHY_SID ? "SID ":"",
   1930  1.88.2.1   yamt 			stat & OHCI_INT_LR_ERR ? "DMA_LR_ERR ":"",
   1931  1.88.2.1   yamt 			stat & OHCI_INT_PW_ERR ? "DMA_PW_ERR ":"",
   1932  1.88.2.1   yamt 			stat & OHCI_INT_DMA_IR ? "DMA_IR ":"",
   1933  1.88.2.1   yamt 			stat & OHCI_INT_DMA_IT  ? "DMA_IT " :"",
   1934  1.88.2.1   yamt 			stat & OHCI_INT_DMA_PRRS  ? "DMA_PRRS " :"",
   1935  1.88.2.1   yamt 			stat & OHCI_INT_DMA_PRRQ  ? "DMA_PRRQ " :"",
   1936  1.88.2.1   yamt 			stat & OHCI_INT_DMA_ARRS  ? "DMA_ARRS " :"",
   1937  1.88.2.1   yamt 			stat & OHCI_INT_DMA_ARRQ  ? "DMA_ARRQ " :"",
   1938  1.88.2.1   yamt 			stat & OHCI_INT_DMA_ATRS  ? "DMA_ATRS " :"",
   1939  1.88.2.1   yamt 			stat & OHCI_INT_DMA_ATRQ  ? "DMA_ATRQ " :"",
   1940  1.88.2.1   yamt 			stat, OREAD(sc, FWOHCI_INTMASK)
   1941  1.88.2.1   yamt 		);
   1942  1.88.2.5   yamt }
   1943  1.88.2.1   yamt #endif
   1944  1.88.2.5   yamt static void
   1945  1.88.2.5   yamt fwohci_intr_core(struct fwohci_softc *sc, uint32_t stat, int count)
   1946  1.88.2.5   yamt {
   1947  1.88.2.5   yamt 	struct firewire_comm *fc = (struct firewire_comm *)sc;
   1948  1.88.2.5   yamt 	uint32_t node_id, plen;
   1949  1.88.2.5   yamt 
   1950  1.88.2.5   yamt 	CTR0(KTR_DEV, "fwohci_intr_core");
   1951  1.88.2.5   yamt 
   1952  1.88.2.5   yamt 	if ((stat & OHCI_INT_PHY_BUS_R) && (fc->status != FWBUSRESET)) {
   1953  1.88.2.5   yamt 		fc->status = FWBUSRESET;
   1954  1.88.2.1   yamt 		/* Disable bus reset interrupt until sid recv. */
   1955  1.88.2.1   yamt 		OWRITE(sc, FWOHCI_INTMASKCLR,  OHCI_INT_PHY_BUS_R);
   1956  1.88.2.1   yamt 
   1957  1.88.2.5   yamt 		fw_printf(fc->dev, "BUS reset\n");
   1958  1.88.2.1   yamt 		OWRITE(sc, FWOHCI_INTMASKCLR,  OHCI_INT_CYC_LOST);
   1959  1.88.2.1   yamt 		OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCSRC);
   1960  1.88.2.1   yamt 
   1961  1.88.2.1   yamt 		OWRITE(sc,  OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN);
   1962  1.88.2.1   yamt 		sc->atrq.xferq.flag &= ~FWXFERQ_RUNNING;
   1963  1.88.2.1   yamt 		OWRITE(sc,  OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN);
   1964  1.88.2.1   yamt 		sc->atrs.xferq.flag &= ~FWXFERQ_RUNNING;
   1965  1.88.2.1   yamt 
   1966  1.88.2.5   yamt 		if (!kdb_active)
   1967  1.88.2.5   yamt 			fw_taskqueue_enqueue(sc->fc.taskqueue,
   1968  1.88.2.5   yamt 			    &sc->fwohci_task_busreset);
   1969  1.88.2.5   yamt 	}
   1970  1.88.2.5   yamt 	if (stat & OHCI_INT_PHY_SID) {
   1971  1.88.2.5   yamt 		/* Enable bus reset interrupt */
   1972  1.88.2.1   yamt 		OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_PHY_BUS_R);
   1973  1.88.2.5   yamt 		OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_PHY_BUS_R);
   1974  1.88.2.5   yamt 
   1975  1.88.2.5   yamt 		/* Allow async. request to us */
   1976  1.88.2.5   yamt 		OWRITE(sc, OHCI_AREQHI, 1 << 31);
   1977  1.88.2.5   yamt 		if (firewire_phydma_enable) {
   1978  1.88.2.5   yamt 			/* allow from all nodes */
   1979  1.88.2.5   yamt 			OWRITE(sc, OHCI_PREQHI, 0x7fffffff);
   1980  1.88.2.5   yamt 			OWRITE(sc, OHCI_PREQLO, 0xffffffff);
   1981  1.88.2.5   yamt 			/* 0 to 4GB regison */
   1982  1.88.2.5   yamt 			OWRITE(sc, OHCI_PREQUPPER, 0x10000);
   1983  1.88.2.5   yamt 		}
   1984  1.88.2.5   yamt 		/* Set ATRetries register */
   1985  1.88.2.5   yamt 		OWRITE(sc, OHCI_ATRETRY, 1<<(13+16) | 0xfff);
   1986  1.88.2.5   yamt 
   1987  1.88.2.5   yamt 		/*
   1988  1.88.2.5   yamt 		 * Checking whether the node is root or not. If root, turn on
   1989  1.88.2.5   yamt 		 * cycle master.
   1990  1.88.2.5   yamt 		 */
   1991  1.88.2.5   yamt 		node_id = OREAD(sc, FWOHCI_NODEID);
   1992  1.88.2.5   yamt 		plen = OREAD(sc, OHCI_SID_CNT);
   1993  1.88.2.5   yamt 
   1994  1.88.2.5   yamt 		fc->nodeid = node_id & 0x3f;
   1995  1.88.2.5   yamt 		fw_printf(fc->dev, "node_id=0x%08x, gen=%d, ",
   1996  1.88.2.5   yamt 		    node_id, (plen >> 16) & 0xff);
   1997  1.88.2.5   yamt 		if (!(node_id & OHCI_NODE_VALID)) {
   1998  1.88.2.5   yamt 			printf("Bus reset failure\n");
   1999  1.88.2.5   yamt 			goto sidout;
   2000  1.88.2.5   yamt 		}
   2001  1.88.2.5   yamt 
   2002  1.88.2.5   yamt 		/* cycle timer */
   2003  1.88.2.5   yamt 		sc->cycle_lost = 0;
   2004  1.88.2.5   yamt 		OWRITE(sc, FWOHCI_INTMASK,  OHCI_INT_CYC_LOST);
   2005  1.88.2.5   yamt 		if ((node_id & OHCI_NODE_ROOT) && !nocyclemaster) {
   2006  1.88.2.5   yamt 			printf("CYCLEMASTER mode\n");
   2007  1.88.2.5   yamt 			OWRITE(sc, OHCI_LNKCTL,
   2008  1.88.2.5   yamt 			    OHCI_CNTL_CYCMTR | OHCI_CNTL_CYCTIMER);
   2009  1.88.2.5   yamt 		} else {
   2010  1.88.2.5   yamt 			printf("non CYCLEMASTER mode\n");
   2011  1.88.2.5   yamt 			OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCMTR);
   2012  1.88.2.5   yamt 			OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_CYCTIMER);
   2013  1.88.2.5   yamt 		}
   2014  1.88.2.5   yamt 
   2015  1.88.2.5   yamt 		fc->status = FWBUSINIT;
   2016  1.88.2.5   yamt 
   2017  1.88.2.5   yamt 		if (!kdb_active)
   2018  1.88.2.5   yamt 			fw_taskqueue_enqueue(sc->fc.taskqueue,
   2019  1.88.2.5   yamt 			    &sc->fwohci_task_sid);
   2020  1.88.2.5   yamt 	}
   2021  1.88.2.5   yamt sidout:
   2022  1.88.2.5   yamt 	if ((stat & ~(OHCI_INT_PHY_BUS_R | OHCI_INT_PHY_SID)) && (!kdb_active))
   2023  1.88.2.5   yamt 		fw_taskqueue_enqueue(sc->fc.taskqueue, &sc->fwohci_task_dma);
   2024  1.88.2.5   yamt 
   2025  1.88.2.5   yamt 	CTR0(KTR_DEV, "fwohci_intr_core done");
   2026  1.88.2.5   yamt }
   2027  1.88.2.5   yamt 
   2028  1.88.2.5   yamt static void
   2029  1.88.2.5   yamt fwohci_intr_dma(struct fwohci_softc *sc, uint32_t stat, int count)
   2030  1.88.2.5   yamt {
   2031  1.88.2.5   yamt 	uint32_t irstat, itstat;
   2032  1.88.2.5   yamt 	u_int i;
   2033  1.88.2.5   yamt 	struct firewire_comm *fc = (struct firewire_comm *)sc;
   2034  1.88.2.5   yamt 
   2035  1.88.2.5   yamt 	CTR0(KTR_DEV, "fwohci_intr_dma");
   2036  1.88.2.5   yamt 	if (stat & OHCI_INT_DMA_IR) {
   2037  1.88.2.5   yamt 		irstat = fw_atomic_readandclear_int(&sc->irstat);
   2038  1.88.2.1   yamt 		for(i = 0; i < fc->nisodma ; i++){
   2039  1.88.2.1   yamt 			struct fwohci_dbch *dbch;
   2040  1.88.2.1   yamt 
   2041  1.88.2.1   yamt 			if((irstat & (1 << i)) != 0){
   2042  1.88.2.1   yamt 				dbch = &sc->ir[i];
   2043  1.88.2.1   yamt 				if ((dbch->xferq.flag & FWXFERQ_OPEN) == 0) {
   2044  1.88.2.5   yamt 					fw_printf(sc->fc.dev,
   2045  1.88.2.1   yamt 						"dma(%d) not active\n", i);
   2046  1.88.2.1   yamt 					continue;
   2047  1.88.2.1   yamt 				}
   2048  1.88.2.1   yamt 				fwohci_rbuf_update(sc, i);
   2049  1.88.2.1   yamt 			}
   2050  1.88.2.1   yamt 		}
   2051       1.3   onoe 	}
   2052  1.88.2.5   yamt 	if (stat & OHCI_INT_DMA_IT) {
   2053  1.88.2.5   yamt 		itstat = fw_atomic_readandclear_int(&sc->itstat);
   2054  1.88.2.1   yamt 		for(i = 0; i < fc->nisodma ; i++){
   2055  1.88.2.1   yamt 			if((itstat & (1 << i)) != 0){
   2056  1.88.2.1   yamt 				fwohci_tbuf_update(sc, i);
   2057  1.88.2.1   yamt 			}
   2058  1.88.2.1   yamt 		}
   2059  1.88.2.1   yamt 	}
   2060  1.88.2.5   yamt 	if (stat & OHCI_INT_DMA_PRRS) {
   2061  1.88.2.1   yamt #if 0
   2062  1.88.2.1   yamt 		dump_dma(sc, ARRS_CH);
   2063  1.88.2.1   yamt 		dump_db(sc, ARRS_CH);
   2064  1.88.2.1   yamt #endif
   2065  1.88.2.1   yamt 		fwohci_arcv(sc, &sc->arrs, count);
   2066  1.88.2.1   yamt 	}
   2067  1.88.2.5   yamt 	if (stat & OHCI_INT_DMA_PRRQ) {
   2068  1.88.2.1   yamt #if 0
   2069  1.88.2.1   yamt 		dump_dma(sc, ARRQ_CH);
   2070  1.88.2.1   yamt 		dump_db(sc, ARRQ_CH);
   2071  1.88.2.1   yamt #endif
   2072  1.88.2.1   yamt 		fwohci_arcv(sc, &sc->arrq, count);
   2073  1.88.2.1   yamt 	}
   2074  1.88.2.1   yamt 	if (stat & OHCI_INT_CYC_LOST) {
   2075  1.88.2.1   yamt 		if (sc->cycle_lost >= 0)
   2076  1.88.2.1   yamt 			sc->cycle_lost ++;
   2077  1.88.2.1   yamt 		if (sc->cycle_lost > 10) {
   2078  1.88.2.1   yamt 			sc->cycle_lost = -1;
   2079  1.88.2.1   yamt #if 0
   2080  1.88.2.1   yamt 			OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCTIMER);
   2081  1.88.2.1   yamt #endif
   2082  1.88.2.1   yamt 			OWRITE(sc, FWOHCI_INTMASKCLR,  OHCI_INT_CYC_LOST);
   2083  1.88.2.5   yamt 			fw_printf(fc->dev, "too many cycle lost, "
   2084  1.88.2.1   yamt 			    "no cycle master presents?\n");
   2085  1.88.2.1   yamt 		}
   2086  1.88.2.1   yamt 	}
   2087  1.88.2.5   yamt 	if (stat & OHCI_INT_DMA_ATRQ) {
   2088  1.88.2.1   yamt 		fwohci_txd(sc, &(sc->atrq));
   2089  1.88.2.1   yamt 	}
   2090  1.88.2.5   yamt 	if (stat & OHCI_INT_DMA_ATRS) {
   2091  1.88.2.1   yamt 		fwohci_txd(sc, &(sc->atrs));
   2092       1.3   onoe 	}
   2093  1.88.2.5   yamt 	if (stat & OHCI_INT_PW_ERR) {
   2094  1.88.2.5   yamt 		fw_printf(fc->dev, "posted write error\n");
   2095  1.88.2.1   yamt 	}
   2096  1.88.2.5   yamt 	if (stat & OHCI_INT_ERR) {
   2097  1.88.2.5   yamt 		fw_printf(fc->dev, "unrecoverable error\n");
   2098  1.88.2.1   yamt 	}
   2099  1.88.2.5   yamt 	if (stat & OHCI_INT_PHY_INT) {
   2100  1.88.2.5   yamt 		fw_printf(fc->dev, "phy int\n");
   2101  1.88.2.1   yamt 	}
   2102  1.88.2.1   yamt 
   2103  1.88.2.5   yamt 	CTR0(KTR_DEV, "fwohci_intr_dma done");
   2104  1.88.2.1   yamt 	return;
   2105       1.3   onoe }
   2106       1.3   onoe 
   2107       1.7   onoe static void
   2108  1.88.2.5   yamt fwohci_task_busreset(void *arg, int pending)
   2109  1.88.2.5   yamt {
   2110  1.88.2.5   yamt 	struct fwohci_softc *sc = (struct fwohci_softc *)arg;
   2111  1.88.2.5   yamt 
   2112  1.88.2.5   yamt 	fw_busreset(&sc->fc, FWBUSRESET);
   2113  1.88.2.5   yamt 	OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0]));
   2114  1.88.2.5   yamt 	OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2]));
   2115  1.88.2.5   yamt }
   2116  1.88.2.5   yamt 
   2117  1.88.2.5   yamt static void
   2118  1.88.2.5   yamt fwohci_task_sid(void *arg, int pending)
   2119  1.88.2.5   yamt {
   2120  1.88.2.5   yamt 	struct fwohci_softc *sc = (struct fwohci_softc *)arg;
   2121  1.88.2.5   yamt 	struct firewire_comm *fc = &sc->fc;
   2122  1.88.2.5   yamt 	uint32_t *buf;
   2123  1.88.2.5   yamt 	int i, plen;
   2124  1.88.2.5   yamt 
   2125  1.88.2.5   yamt 	plen = OREAD(sc, OHCI_SID_CNT);
   2126  1.88.2.5   yamt 
   2127  1.88.2.5   yamt 	if (plen & OHCI_SID_ERR) {
   2128  1.88.2.5   yamt 		fw_printf(fc->dev, "SID Error\n");
   2129  1.88.2.5   yamt 		return;
   2130  1.88.2.5   yamt 	}
   2131  1.88.2.5   yamt 	plen &= OHCI_SID_CNT_MASK;
   2132  1.88.2.5   yamt 	if (plen < 4 || plen > OHCI_SIDSIZE) {
   2133  1.88.2.5   yamt 		fw_printf(fc->dev, "invalid SID len = %d\n", plen);
   2134  1.88.2.5   yamt 		return;
   2135  1.88.2.5   yamt 	}
   2136  1.88.2.5   yamt 	plen -= 4; /* chop control info */
   2137  1.88.2.5   yamt 	buf = (uint32_t *)malloc(OHCI_SIDSIZE, M_FW, M_NOWAIT);
   2138  1.88.2.5   yamt 	if (buf == NULL) {
   2139  1.88.2.5   yamt 		fw_printf(fc->dev, "malloc failed\n");
   2140  1.88.2.5   yamt 		return;
   2141  1.88.2.5   yamt 	}
   2142  1.88.2.5   yamt 	for (i = 0; i < plen / 4; i ++)
   2143  1.88.2.5   yamt 		buf[i] = FWOHCI_DMA_READ(sc->sid_buf[i+1]);
   2144  1.88.2.5   yamt #if 1 /* XXX needed?? */
   2145  1.88.2.5   yamt 	/* pending all pre-bus_reset packets */
   2146  1.88.2.5   yamt 	fwohci_txd(sc, &sc->atrq);
   2147  1.88.2.5   yamt 	fwohci_txd(sc, &sc->atrs);
   2148  1.88.2.5   yamt 	fwohci_arcv(sc, &sc->arrs, -1);
   2149  1.88.2.5   yamt 	fwohci_arcv(sc, &sc->arrq, -1);
   2150  1.88.2.5   yamt 	fw_drain_txq(fc);
   2151  1.88.2.5   yamt #endif
   2152  1.88.2.5   yamt 	fw_sidrcv(fc, buf, plen);
   2153  1.88.2.5   yamt 	free(buf, M_FW);
   2154  1.88.2.5   yamt }
   2155  1.88.2.5   yamt 
   2156  1.88.2.5   yamt static void
   2157  1.88.2.5   yamt fwohci_task_dma(void *arg, int pending)
   2158       1.7   onoe {
   2159  1.88.2.1   yamt 	struct fwohci_softc *sc = (struct fwohci_softc *)arg;
   2160  1.88.2.1   yamt 	uint32_t stat;
   2161       1.7   onoe 
   2162  1.88.2.1   yamt again:
   2163  1.88.2.5   yamt 	stat = fw_atomic_readandclear_int(&sc->intstat);
   2164  1.88.2.5   yamt 	if (stat)
   2165  1.88.2.5   yamt 		fwohci_intr_dma(sc, stat, -1);
   2166  1.88.2.5   yamt 	else
   2167  1.88.2.1   yamt 		return;
   2168  1.88.2.1   yamt 	goto again;
   2169       1.7   onoe }
   2170       1.7   onoe 
   2171  1.88.2.5   yamt static int
   2172  1.88.2.5   yamt fwohci_check_stat(struct fwohci_softc *sc)
   2173       1.7   onoe {
   2174  1.88.2.1   yamt 	uint32_t stat, irstat, itstat;
   2175       1.7   onoe 
   2176  1.88.2.1   yamt 	stat = OREAD(sc, FWOHCI_INTSTAT);
   2177  1.88.2.1   yamt 	CTR1(KTR_DEV, "fwoch_check_stat 0x%08x", stat);
   2178  1.88.2.1   yamt 	if (stat == 0xffffffff) {
   2179  1.88.2.5   yamt 		fw_printf(sc->fc.dev,
   2180  1.88.2.1   yamt 			"device physically ejected?\n");
   2181  1.88.2.5   yamt 		return (FILTER_STRAY);
   2182       1.7   onoe 	}
   2183  1.88.2.1   yamt 	if (stat)
   2184  1.88.2.5   yamt 		OWRITE(sc, FWOHCI_INTSTATCLR, stat & ~OHCI_INT_PHY_BUS_R);
   2185  1.88.2.5   yamt 
   2186  1.88.2.5   yamt 	stat &= sc->intmask;
   2187  1.88.2.5   yamt 	if (stat == 0)
   2188  1.88.2.5   yamt 		return (FILTER_STRAY);
   2189  1.88.2.5   yamt 
   2190  1.88.2.5   yamt 	fw_atomic_set_int(&sc->intstat, stat);
   2191  1.88.2.1   yamt 	if (stat & OHCI_INT_DMA_IR) {
   2192  1.88.2.1   yamt 		irstat = OREAD(sc, OHCI_IR_STAT);
   2193  1.88.2.1   yamt 		OWRITE(sc, OHCI_IR_STATCLR, irstat);
   2194  1.88.2.5   yamt 		fw_atomic_set_int(&sc->irstat, irstat);
   2195  1.88.2.1   yamt 	}
   2196  1.88.2.1   yamt 	if (stat & OHCI_INT_DMA_IT) {
   2197  1.88.2.1   yamt 		itstat = OREAD(sc, OHCI_IT_STAT);
   2198  1.88.2.1   yamt 		OWRITE(sc, OHCI_IT_STATCLR, itstat);
   2199  1.88.2.5   yamt 		fw_atomic_set_int(&sc->itstat, itstat);
   2200  1.88.2.1   yamt 	}
   2201  1.88.2.5   yamt 
   2202  1.88.2.5   yamt 	fwohci_intr_core(sc, stat, -1);
   2203  1.88.2.5   yamt 	return (FILTER_HANDLED);
   2204       1.7   onoe }
   2205       1.7   onoe 
   2206  1.88.2.5   yamt int
   2207  1.88.2.5   yamt fwohci_filt(void *arg)
   2208       1.3   onoe {
   2209  1.88.2.1   yamt 	struct fwohci_softc *sc = (struct fwohci_softc *)arg;
   2210       1.3   onoe 
   2211  1.88.2.1   yamt 	if (!(sc->intmask & OHCI_INT_EN)) {
   2212  1.88.2.1   yamt 		/* polling mode */
   2213  1.88.2.5   yamt 		return (FILTER_STRAY);
   2214       1.3   onoe 	}
   2215  1.88.2.5   yamt 	return (fwohci_check_stat(sc));
   2216  1.88.2.5   yamt }
   2217       1.3   onoe 
   2218  1.88.2.5   yamt void
   2219  1.88.2.5   yamt fwohci_intr(void *arg)
   2220  1.88.2.5   yamt {
   2221  1.88.2.5   yamt 
   2222  1.88.2.5   yamt 	fwohci_filt(arg);
   2223  1.88.2.1   yamt 	CTR0(KTR_DEV, "fwohci_intr end");
   2224       1.9   onoe }
   2225       1.9   onoe 
   2226  1.88.2.1   yamt void
   2227  1.88.2.1   yamt fwohci_poll(struct firewire_comm *fc, int quick, int count)
   2228       1.9   onoe {
   2229  1.88.2.5   yamt 	struct fwohci_softc *sc = (struct fwohci_softc *)fc;
   2230       1.9   onoe 
   2231  1.88.2.5   yamt 	fwohci_check_stat(sc);
   2232       1.3   onoe }
   2233       1.3   onoe 
   2234       1.3   onoe static void
   2235  1.88.2.1   yamt fwohci_set_intr(struct firewire_comm *fc, int enable)
   2236       1.9   onoe {
   2237  1.88.2.1   yamt 	struct fwohci_softc *sc;
   2238       1.9   onoe 
   2239  1.88.2.1   yamt 	sc = (struct fwohci_softc *)fc;
   2240  1.88.2.1   yamt 	if (firewire_debug)
   2241  1.88.2.5   yamt 		fw_printf(sc->fc.dev, "fwohci_set_intr: %d\n", enable);
   2242  1.88.2.1   yamt 	if (enable) {
   2243  1.88.2.1   yamt 		sc->intmask |= OHCI_INT_EN;
   2244  1.88.2.1   yamt 		OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_EN);
   2245  1.88.2.1   yamt 	} else {
   2246  1.88.2.1   yamt 		sc->intmask &= ~OHCI_INT_EN;
   2247  1.88.2.1   yamt 		OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_EN);
   2248  1.88.2.1   yamt 	}
   2249       1.9   onoe }
   2250       1.9   onoe 
   2251       1.9   onoe static void
   2252  1.88.2.1   yamt fwohci_tbuf_update(struct fwohci_softc *sc, int dmach)
   2253  1.88.2.1   yamt {
   2254  1.88.2.1   yamt 	struct firewire_comm *fc = &sc->fc;
   2255  1.88.2.1   yamt 	struct fwohcidb *db;
   2256  1.88.2.1   yamt 	struct fw_bulkxfer *chunk;
   2257  1.88.2.1   yamt 	struct fw_xferq *it;
   2258  1.88.2.1   yamt 	uint32_t stat, count;
   2259  1.88.2.1   yamt 	int s, w=0, ldesc;
   2260  1.88.2.1   yamt 
   2261  1.88.2.1   yamt 	it = fc->it[dmach];
   2262  1.88.2.1   yamt 	ldesc = sc->it[dmach].ndesc - 1;
   2263  1.88.2.1   yamt 	s = splfw(); /* unnecessary ? */
   2264  1.88.2.5   yamt 	FW_GLOCK(fc);
   2265  1.88.2.1   yamt 	fwdma_sync_multiseg_all(sc->it[dmach].am, BUS_DMASYNC_POSTREAD);
   2266  1.88.2.1   yamt 	if (firewire_debug)
   2267  1.88.2.1   yamt 		dump_db(sc, ITX_CH + dmach);
   2268  1.88.2.1   yamt 	while ((chunk = STAILQ_FIRST(&it->stdma)) != NULL) {
   2269  1.88.2.1   yamt 		db = ((struct fwohcidb_tr *)(chunk->end))->db;
   2270  1.88.2.1   yamt 		stat = FWOHCI_DMA_READ(db[ldesc].db.desc.res)
   2271  1.88.2.1   yamt 				>> OHCI_STATUS_SHIFT;
   2272  1.88.2.1   yamt 		db = ((struct fwohcidb_tr *)(chunk->start))->db;
   2273  1.88.2.1   yamt 		/* timestamp */
   2274  1.88.2.1   yamt 		count = FWOHCI_DMA_READ(db[ldesc].db.desc.res)
   2275  1.88.2.1   yamt 				& OHCI_COUNT_MASK;
   2276  1.88.2.1   yamt 		if (stat == 0)
   2277  1.88.2.1   yamt 			break;
   2278  1.88.2.1   yamt 		STAILQ_REMOVE_HEAD(&it->stdma, link);
   2279  1.88.2.1   yamt 		switch (stat & FWOHCIEV_MASK){
   2280  1.88.2.1   yamt 		case FWOHCIEV_ACKCOMPL:
   2281  1.88.2.1   yamt #if 0
   2282  1.88.2.5   yamt 			fw_printf(fc->dev, "0x%08x\n", count);
   2283  1.88.2.1   yamt #endif
   2284  1.88.2.1   yamt 			break;
   2285  1.88.2.1   yamt 		default:
   2286  1.88.2.5   yamt 			fw_printf(fc->dev,
   2287  1.88.2.1   yamt 				"Isochronous transmit err %02x(%s)\n",
   2288  1.88.2.1   yamt 					stat, fwohcicode[stat & 0x1f]);
   2289  1.88.2.1   yamt 		}
   2290  1.88.2.1   yamt 		STAILQ_INSERT_TAIL(&it->stfree, chunk, link);
   2291  1.88.2.1   yamt 		w++;
   2292       1.9   onoe 	}
   2293  1.88.2.5   yamt 	FW_GUNLOCK(fc);
   2294  1.88.2.1   yamt 	splx(s);
   2295  1.88.2.1   yamt 	if (w)
   2296  1.88.2.1   yamt 		wakeup(it);
   2297       1.3   onoe }
   2298       1.3   onoe 
   2299  1.88.2.1   yamt static void
   2300  1.88.2.1   yamt fwohci_rbuf_update(struct fwohci_softc *sc, int dmach)
   2301       1.3   onoe {
   2302  1.88.2.1   yamt 	struct firewire_comm *fc = &sc->fc;
   2303  1.88.2.1   yamt 	struct fwohcidb_tr *db_tr;
   2304  1.88.2.1   yamt 	struct fw_bulkxfer *chunk;
   2305  1.88.2.1   yamt 	struct fw_xferq *ir;
   2306  1.88.2.1   yamt 	uint32_t stat;
   2307  1.88.2.5   yamt 	int s, w = 0, ldesc;
   2308       1.3   onoe 
   2309  1.88.2.1   yamt 	ir = fc->ir[dmach];
   2310  1.88.2.1   yamt 	ldesc = sc->ir[dmach].ndesc - 1;
   2311  1.88.2.5   yamt 
   2312  1.88.2.1   yamt #if 0
   2313  1.88.2.1   yamt 	dump_db(sc, dmach);
   2314  1.88.2.1   yamt #endif
   2315  1.88.2.1   yamt 	s = splfw();
   2316  1.88.2.5   yamt 	if ((ir->flag & FWXFERQ_HANDLER) == 0)
   2317  1.88.2.5   yamt 		FW_GLOCK(fc);
   2318  1.88.2.1   yamt 	fwdma_sync_multiseg_all(sc->ir[dmach].am, BUS_DMASYNC_POSTREAD);
   2319  1.88.2.1   yamt 	while ((chunk = STAILQ_FIRST(&ir->stdma)) != NULL) {
   2320  1.88.2.1   yamt 		db_tr = (struct fwohcidb_tr *)chunk->end;
   2321  1.88.2.1   yamt 		stat = FWOHCI_DMA_READ(db_tr->db[ldesc].db.desc.res)
   2322  1.88.2.1   yamt 				>> OHCI_STATUS_SHIFT;
   2323  1.88.2.1   yamt 		if (stat == 0)
   2324  1.88.2.1   yamt 			break;
   2325       1.3   onoe 
   2326  1.88.2.1   yamt 		if (chunk->mbuf != NULL) {
   2327  1.88.2.1   yamt 			fw_bus_dmamap_sync(sc->ir[dmach].dmat, db_tr->dma_map,
   2328  1.88.2.1   yamt 						BUS_DMASYNC_POSTREAD);
   2329  1.88.2.1   yamt 			fw_bus_dmamap_unload(
   2330  1.88.2.1   yamt 				sc->ir[dmach].dmat, db_tr->dma_map);
   2331  1.88.2.1   yamt 		} else if (ir->buf != NULL) {
   2332  1.88.2.1   yamt 			fwdma_sync_multiseg(ir->buf, chunk->poffset,
   2333  1.88.2.1   yamt 				ir->bnpacket, BUS_DMASYNC_POSTREAD);
   2334  1.88.2.1   yamt 		} else {
   2335  1.88.2.1   yamt 			/* XXX */
   2336  1.88.2.1   yamt 			printf("fwohci_rbuf_update: this shouldn't happend\n");
   2337  1.88.2.1   yamt 		}
   2338       1.3   onoe 
   2339  1.88.2.1   yamt 		STAILQ_REMOVE_HEAD(&ir->stdma, link);
   2340  1.88.2.1   yamt 		STAILQ_INSERT_TAIL(&ir->stvalid, chunk, link);
   2341  1.88.2.1   yamt 		switch (stat & FWOHCIEV_MASK) {
   2342  1.88.2.1   yamt 		case FWOHCIEV_ACKCOMPL:
   2343  1.88.2.1   yamt 			chunk->resp = 0;
   2344  1.88.2.1   yamt 			break;
   2345  1.88.2.1   yamt 		default:
   2346  1.88.2.1   yamt 			chunk->resp = EINVAL;
   2347  1.88.2.5   yamt 			fw_printf(fc->dev, "Isochronous receive err %02x(%s)\n",
   2348  1.88.2.1   yamt 					stat, fwohcicode[stat & 0x1f]);
   2349  1.88.2.1   yamt 		}
   2350  1.88.2.1   yamt 		w++;
   2351  1.88.2.1   yamt 	}
   2352  1.88.2.5   yamt 	if ((ir->flag & FWXFERQ_HANDLER) == 0)
   2353  1.88.2.5   yamt 		FW_GUNLOCK(fc);
   2354  1.88.2.1   yamt 	splx(s);
   2355  1.88.2.5   yamt 	if (w == 0)
   2356  1.88.2.5   yamt 		return;
   2357  1.88.2.5   yamt 	if (ir->flag & FWXFERQ_HANDLER)
   2358  1.88.2.5   yamt 		ir->hand(ir);
   2359  1.88.2.5   yamt 	else
   2360  1.88.2.5   yamt 		wakeup(ir);
   2361       1.3   onoe }
   2362       1.3   onoe 
   2363  1.88.2.1   yamt void
   2364  1.88.2.1   yamt dump_dma(struct fwohci_softc *sc, uint32_t ch)
   2365       1.3   onoe {
   2366  1.88.2.1   yamt 	uint32_t off, cntl, stat, cmd, match;
   2367       1.3   onoe 
   2368  1.88.2.1   yamt 	if(ch == 0){
   2369  1.88.2.1   yamt 		off = OHCI_ATQOFF;
   2370  1.88.2.1   yamt 	}else if(ch == 1){
   2371  1.88.2.1   yamt 		off = OHCI_ATSOFF;
   2372  1.88.2.1   yamt 	}else if(ch == 2){
   2373  1.88.2.1   yamt 		off = OHCI_ARQOFF;
   2374  1.88.2.1   yamt 	}else if(ch == 3){
   2375  1.88.2.1   yamt 		off = OHCI_ARSOFF;
   2376  1.88.2.1   yamt 	}else if(ch < IRX_CH){
   2377  1.88.2.1   yamt 		off = OHCI_ITCTL(ch - ITX_CH);
   2378  1.88.2.1   yamt 	}else{
   2379  1.88.2.1   yamt 		off = OHCI_IRCTL(ch - IRX_CH);
   2380  1.88.2.1   yamt 	}
   2381  1.88.2.1   yamt 	cntl = stat = OREAD(sc, off);
   2382  1.88.2.1   yamt 	cmd = OREAD(sc, off + 0xc);
   2383  1.88.2.1   yamt 	match = OREAD(sc, off + 0x10);
   2384  1.88.2.1   yamt 
   2385  1.88.2.5   yamt 	fw_printf(sc->fc.dev, "ch %1x cntl:0x%08x cmd:0x%08x match:0x%08x\n",
   2386  1.88.2.1   yamt 		ch,
   2387  1.88.2.1   yamt 		cntl,
   2388  1.88.2.1   yamt 		cmd,
   2389  1.88.2.1   yamt 		match);
   2390  1.88.2.1   yamt 	stat &= 0xffff ;
   2391  1.88.2.1   yamt 	if (stat) {
   2392  1.88.2.5   yamt 		fw_printf(sc->fc.dev, "dma %d ch:%s%s%s%s%s%s %s(%x)\n",
   2393  1.88.2.1   yamt 			ch,
   2394  1.88.2.1   yamt 			stat & OHCI_CNTL_DMA_RUN ? "RUN," : "",
   2395  1.88.2.1   yamt 			stat & OHCI_CNTL_DMA_WAKE ? "WAKE," : "",
   2396  1.88.2.1   yamt 			stat & OHCI_CNTL_DMA_DEAD ? "DEAD," : "",
   2397  1.88.2.1   yamt 			stat & OHCI_CNTL_DMA_ACTIVE ? "ACTIVE," : "",
   2398  1.88.2.1   yamt 			stat & OHCI_CNTL_DMA_BT ? "BRANCH," : "",
   2399  1.88.2.1   yamt 			stat & OHCI_CNTL_DMA_BAD ? "BADDMA," : "",
   2400  1.88.2.1   yamt 			fwohcicode[stat & 0x1f],
   2401  1.88.2.1   yamt 			stat & 0x1f
   2402  1.88.2.1   yamt 		);
   2403  1.88.2.1   yamt 	}else{
   2404  1.88.2.5   yamt 		fw_printf(sc->fc.dev, "dma %d ch: Nostat\n", ch);
   2405  1.88.2.1   yamt 	}
   2406       1.3   onoe }
   2407       1.3   onoe 
   2408  1.88.2.1   yamt void
   2409  1.88.2.1   yamt dump_db(struct fwohci_softc *sc, uint32_t ch)
   2410       1.3   onoe {
   2411  1.88.2.1   yamt 	struct fwohci_dbch *dbch;
   2412  1.88.2.1   yamt 	struct fwohcidb_tr *cp = NULL, *pp, *np = NULL;
   2413  1.88.2.1   yamt 	struct fwohcidb *curr = NULL, *prev, *next = NULL;
   2414  1.88.2.1   yamt 	int idb, jdb;
   2415  1.88.2.1   yamt 	uint32_t cmd, off;
   2416  1.88.2.1   yamt 	if(ch == 0){
   2417  1.88.2.1   yamt 		off = OHCI_ATQOFF;
   2418  1.88.2.1   yamt 		dbch = &sc->atrq;
   2419  1.88.2.1   yamt 	}else if(ch == 1){
   2420  1.88.2.1   yamt 		off = OHCI_ATSOFF;
   2421  1.88.2.1   yamt 		dbch = &sc->atrs;
   2422  1.88.2.1   yamt 	}else if(ch == 2){
   2423  1.88.2.1   yamt 		off = OHCI_ARQOFF;
   2424  1.88.2.1   yamt 		dbch = &sc->arrq;
   2425  1.88.2.1   yamt 	}else if(ch == 3){
   2426  1.88.2.1   yamt 		off = OHCI_ARSOFF;
   2427  1.88.2.1   yamt 		dbch = &sc->arrs;
   2428  1.88.2.1   yamt 	}else if(ch < IRX_CH){
   2429  1.88.2.1   yamt 		off = OHCI_ITCTL(ch - ITX_CH);
   2430  1.88.2.1   yamt 		dbch = &sc->it[ch - ITX_CH];
   2431  1.88.2.1   yamt 	}else {
   2432  1.88.2.1   yamt 		off = OHCI_IRCTL(ch - IRX_CH);
   2433  1.88.2.1   yamt 		dbch = &sc->ir[ch - IRX_CH];
   2434  1.88.2.1   yamt 	}
   2435  1.88.2.1   yamt 	cmd = OREAD(sc, off + 0xc);
   2436       1.3   onoe 
   2437  1.88.2.1   yamt 	if( dbch->ndb == 0 ){
   2438  1.88.2.5   yamt 		fw_printf(sc->fc.dev, "No DB is attached ch=%d\n", ch);
   2439  1.88.2.1   yamt 		return;
   2440  1.88.2.1   yamt 	}
   2441  1.88.2.1   yamt 	pp = dbch->top;
   2442  1.88.2.1   yamt 	prev = pp->db;
   2443  1.88.2.1   yamt 	for(idb = 0 ; idb < dbch->ndb ; idb ++ ){
   2444  1.88.2.1   yamt 		cp = STAILQ_NEXT(pp, link);
   2445  1.88.2.1   yamt 		if(cp == NULL){
   2446  1.88.2.1   yamt 			curr = NULL;
   2447  1.88.2.1   yamt 			goto outdb;
   2448  1.88.2.1   yamt 		}
   2449  1.88.2.1   yamt 		np = STAILQ_NEXT(cp, link);
   2450  1.88.2.1   yamt 		for(jdb = 0 ; jdb < dbch->ndesc ; jdb ++ ){
   2451  1.88.2.1   yamt 			if ((cmd  & 0xfffffff0) == cp->bus_addr) {
   2452  1.88.2.1   yamt 				curr = cp->db;
   2453  1.88.2.1   yamt 				if(np != NULL){
   2454  1.88.2.1   yamt 					next = np->db;
   2455  1.88.2.1   yamt 				}else{
   2456  1.88.2.1   yamt 					next = NULL;
   2457  1.88.2.1   yamt 				}
   2458  1.88.2.1   yamt 				goto outdb;
   2459  1.88.2.1   yamt 			}
   2460  1.88.2.1   yamt 		}
   2461  1.88.2.1   yamt 		pp = STAILQ_NEXT(pp, link);
   2462  1.88.2.1   yamt 		if(pp == NULL){
   2463  1.88.2.1   yamt 			curr = NULL;
   2464  1.88.2.1   yamt 			goto outdb;
   2465      1.62   haya 		}
   2466  1.88.2.1   yamt 		prev = pp->db;
   2467  1.88.2.1   yamt 	}
   2468  1.88.2.1   yamt outdb:
   2469  1.88.2.1   yamt 	if( curr != NULL){
   2470  1.88.2.1   yamt #if 0
   2471  1.88.2.1   yamt 		printf("Prev DB %d\n", ch);
   2472  1.88.2.1   yamt 		print_db(pp, prev, ch, dbch->ndesc);
   2473  1.88.2.1   yamt #endif
   2474  1.88.2.1   yamt 		printf("Current DB %d\n", ch);
   2475  1.88.2.1   yamt 		print_db(cp, curr, ch, dbch->ndesc);
   2476  1.88.2.1   yamt #if 0
   2477  1.88.2.1   yamt 		printf("Next DB %d\n", ch);
   2478  1.88.2.1   yamt 		print_db(np, next, ch, dbch->ndesc);
   2479  1.88.2.1   yamt #endif
   2480  1.88.2.1   yamt 	}else{
   2481  1.88.2.1   yamt 		printf("dbdump err ch = %d cmd = 0x%08x\n", ch, cmd);
   2482       1.7   onoe 	}
   2483  1.88.2.1   yamt 	return;
   2484       1.7   onoe }
   2485       1.7   onoe 
   2486  1.88.2.1   yamt void
   2487  1.88.2.1   yamt print_db(struct fwohcidb_tr *db_tr, struct fwohcidb *db,
   2488  1.88.2.1   yamt 		uint32_t ch, uint32_t hogemax)
   2489       1.7   onoe {
   2490  1.88.2.1   yamt 	fwohcireg_t stat;
   2491  1.88.2.1   yamt 	int i, key;
   2492  1.88.2.1   yamt 	uint32_t cmd, res;
   2493  1.88.2.1   yamt 
   2494  1.88.2.1   yamt 	if(db == NULL){
   2495  1.88.2.1   yamt 		printf("No Descriptor is found\n");
   2496  1.88.2.1   yamt 		return;
   2497  1.88.2.1   yamt 	}
   2498       1.7   onoe 
   2499  1.88.2.1   yamt 	printf("ch = %d\n%8s %s %s %s %s %4s %8s %8s %4s:%4s\n",
   2500  1.88.2.1   yamt 		ch,
   2501  1.88.2.1   yamt 		"Current",
   2502  1.88.2.1   yamt 		"OP  ",
   2503  1.88.2.1   yamt 		"KEY",
   2504  1.88.2.1   yamt 		"INT",
   2505  1.88.2.1   yamt 		"BR ",
   2506  1.88.2.1   yamt 		"len",
   2507  1.88.2.1   yamt 		"Addr",
   2508  1.88.2.1   yamt 		"Depend",
   2509  1.88.2.1   yamt 		"Stat",
   2510  1.88.2.1   yamt 		"Cnt");
   2511  1.88.2.1   yamt 	for( i = 0 ; i <= hogemax ; i ++){
   2512  1.88.2.1   yamt 		cmd = FWOHCI_DMA_READ(db[i].db.desc.cmd);
   2513  1.88.2.1   yamt 		res = FWOHCI_DMA_READ(db[i].db.desc.res);
   2514  1.88.2.1   yamt 		key = cmd & OHCI_KEY_MASK;
   2515  1.88.2.1   yamt 		stat = res >> OHCI_STATUS_SHIFT;
   2516  1.88.2.1   yamt #if defined(__DragonFly__) || \
   2517  1.88.2.1   yamt     (defined(__FreeBSD__) && __FreeBSD_version < 500000)
   2518  1.88.2.1   yamt 		printf("%08x %s %s %s %s %5d %08x %08x %04x:%04x",
   2519  1.88.2.1   yamt 				db_tr->bus_addr,
   2520  1.88.2.1   yamt #else
   2521  1.88.2.1   yamt 		printf("%08jx %s %s %s %s %5d %08x %08x %04x:%04x",
   2522  1.88.2.1   yamt 				(uintmax_t)db_tr->bus_addr,
   2523  1.88.2.1   yamt #endif
   2524  1.88.2.1   yamt 				dbcode[(cmd >> 28) & 0xf],
   2525  1.88.2.1   yamt 				dbkey[(cmd >> 24) & 0x7],
   2526  1.88.2.1   yamt 				dbcond[(cmd >> 20) & 0x3],
   2527  1.88.2.1   yamt 				dbcond[(cmd >> 18) & 0x3],
   2528  1.88.2.1   yamt 				cmd & OHCI_COUNT_MASK,
   2529  1.88.2.1   yamt 				FWOHCI_DMA_READ(db[i].db.desc.addr),
   2530  1.88.2.1   yamt 				FWOHCI_DMA_READ(db[i].db.desc.depend),
   2531  1.88.2.1   yamt 				stat,
   2532  1.88.2.1   yamt 				res & OHCI_COUNT_MASK);
   2533  1.88.2.1   yamt 		if(stat & 0xff00){
   2534  1.88.2.1   yamt 			printf(" %s%s%s%s%s%s %s(%x)\n",
   2535  1.88.2.1   yamt 				stat & OHCI_CNTL_DMA_RUN ? "RUN," : "",
   2536  1.88.2.1   yamt 				stat & OHCI_CNTL_DMA_WAKE ? "WAKE," : "",
   2537  1.88.2.1   yamt 				stat & OHCI_CNTL_DMA_DEAD ? "DEAD," : "",
   2538  1.88.2.1   yamt 				stat & OHCI_CNTL_DMA_ACTIVE ? "ACTIVE," : "",
   2539  1.88.2.1   yamt 				stat & OHCI_CNTL_DMA_BT ? "BRANCH," : "",
   2540  1.88.2.1   yamt 				stat & OHCI_CNTL_DMA_BAD ? "BADDMA," : "",
   2541  1.88.2.1   yamt 				fwohcicode[stat & 0x1f],
   2542  1.88.2.1   yamt 				stat & 0x1f
   2543  1.88.2.1   yamt 			);
   2544  1.88.2.1   yamt 		}else{
   2545  1.88.2.1   yamt 			printf(" Nostat\n");
   2546  1.88.2.1   yamt 		}
   2547  1.88.2.1   yamt 		if(key == OHCI_KEY_ST2 ){
   2548  1.88.2.1   yamt 			printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
   2549  1.88.2.1   yamt 				FWOHCI_DMA_READ(db[i+1].db.immed[0]),
   2550  1.88.2.1   yamt 				FWOHCI_DMA_READ(db[i+1].db.immed[1]),
   2551  1.88.2.1   yamt 				FWOHCI_DMA_READ(db[i+1].db.immed[2]),
   2552  1.88.2.1   yamt 				FWOHCI_DMA_READ(db[i+1].db.immed[3]));
   2553  1.88.2.1   yamt 		}
   2554  1.88.2.1   yamt 		if(key == OHCI_KEY_DEVICE){
   2555  1.88.2.1   yamt 			return;
   2556  1.88.2.1   yamt 		}
   2557  1.88.2.1   yamt 		if((cmd & OHCI_BRANCH_MASK)
   2558  1.88.2.1   yamt 				== OHCI_BRANCH_ALWAYS){
   2559  1.88.2.1   yamt 			return;
   2560  1.88.2.1   yamt 		}
   2561  1.88.2.1   yamt 		if((cmd & OHCI_CMD_MASK)
   2562  1.88.2.1   yamt 				== OHCI_OUTPUT_LAST){
   2563  1.88.2.1   yamt 			return;
   2564  1.88.2.1   yamt 		}
   2565  1.88.2.1   yamt 		if((cmd & OHCI_CMD_MASK)
   2566  1.88.2.1   yamt 				== OHCI_INPUT_LAST){
   2567  1.88.2.1   yamt 			return;
   2568  1.88.2.1   yamt 		}
   2569  1.88.2.1   yamt 		if(key == OHCI_KEY_ST2 ){
   2570  1.88.2.1   yamt 			i++;
   2571      1.62   haya 		}
   2572       1.3   onoe 	}
   2573  1.88.2.1   yamt 	return;
   2574       1.3   onoe }
   2575       1.3   onoe 
   2576  1.88.2.1   yamt void
   2577  1.88.2.1   yamt fwohci_ibr(struct firewire_comm *fc)
   2578       1.7   onoe {
   2579  1.88.2.1   yamt 	struct fwohci_softc *sc;
   2580  1.88.2.1   yamt 	uint32_t fun;
   2581       1.7   onoe 
   2582  1.88.2.5   yamt 	fw_printf(fc->dev, "Initiate bus reset\n");
   2583  1.88.2.1   yamt 	sc = (struct fwohci_softc *)fc;
   2584       1.7   onoe 
   2585       1.7   onoe 	/*
   2586  1.88.2.1   yamt 	 * Make sure our cached values from the config rom are
   2587  1.88.2.1   yamt 	 * initialised.
   2588       1.7   onoe 	 */
   2589  1.88.2.1   yamt 	OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0]));
   2590  1.88.2.1   yamt 	OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2]));
   2591      1.36   onoe 
   2592      1.36   onoe 	/*
   2593  1.88.2.1   yamt 	 * Set root hold-off bit so that non cyclemaster capable node
   2594  1.88.2.1   yamt 	 * shouldn't became the root node.
   2595      1.36   onoe 	 */
   2596  1.88.2.1   yamt #if 1
   2597  1.88.2.1   yamt 	fun = fwphy_rddata(sc, FW_PHY_IBR_REG);
   2598  1.88.2.1   yamt 	fun |= FW_PHY_IBR | FW_PHY_RHB;
   2599  1.88.2.1   yamt 	fun = fwphy_wrdata(sc, FW_PHY_IBR_REG, fun);
   2600  1.88.2.1   yamt #else	/* Short bus reset */
   2601  1.88.2.1   yamt 	fun = fwphy_rddata(sc, FW_PHY_ISBR_REG);
   2602  1.88.2.1   yamt 	fun |= FW_PHY_ISBR | FW_PHY_RHB;
   2603  1.88.2.1   yamt 	fun = fwphy_wrdata(sc, FW_PHY_ISBR_REG, fun);
   2604  1.88.2.1   yamt #endif
   2605      1.36   onoe }
   2606      1.36   onoe 
   2607  1.88.2.1   yamt void
   2608  1.88.2.1   yamt fwohci_txbufdb(struct fwohci_softc *sc, int dmach, struct fw_bulkxfer *bulkxfer)
   2609      1.36   onoe {
   2610  1.88.2.1   yamt 	struct fwohcidb_tr *db_tr, *fdb_tr;
   2611  1.88.2.1   yamt 	struct fwohci_dbch *dbch;
   2612  1.88.2.1   yamt 	struct fwohcidb *db;
   2613  1.88.2.1   yamt 	struct fw_pkt *fp;
   2614  1.88.2.1   yamt 	struct fwohci_txpkthdr *ohcifp;
   2615  1.88.2.1   yamt 	unsigned short chtag;
   2616  1.88.2.1   yamt 	int idb;
   2617  1.88.2.1   yamt 
   2618  1.88.2.5   yamt 	FW_GLOCK_ASSERT(&sc->fc);
   2619  1.88.2.5   yamt 
   2620  1.88.2.1   yamt 	dbch = &sc->it[dmach];
   2621  1.88.2.1   yamt 	chtag = sc->it[dmach].xferq.flag & 0xff;
   2622  1.88.2.1   yamt 
   2623  1.88.2.1   yamt 	db_tr = (struct fwohcidb_tr *)(bulkxfer->start);
   2624  1.88.2.1   yamt 	fdb_tr = (struct fwohcidb_tr *)(bulkxfer->end);
   2625  1.88.2.1   yamt /*
   2626  1.88.2.5   yamt fw_printf(sc->fc.dev, "DB %08x %08x %08x\n", bulkxfer, db_tr->bus_addr, fdb_tr->bus_addr);
   2627  1.88.2.1   yamt */
   2628  1.88.2.1   yamt 	for (idb = 0; idb < dbch->xferq.bnpacket; idb ++) {
   2629  1.88.2.1   yamt 		db = db_tr->db;
   2630  1.88.2.1   yamt 		fp = (struct fw_pkt *)db_tr->buf;
   2631  1.88.2.1   yamt 		ohcifp = (struct fwohci_txpkthdr *) db[1].db.immed;
   2632  1.88.2.1   yamt 		ohcifp->mode.ld[0] = fp->mode.ld[0];
   2633  1.88.2.1   yamt 		ohcifp->mode.common.spd = 0 & 0x7;
   2634  1.88.2.1   yamt 		ohcifp->mode.stream.len = fp->mode.stream.len;
   2635  1.88.2.1   yamt 		ohcifp->mode.stream.chtag = chtag;
   2636  1.88.2.1   yamt 		ohcifp->mode.stream.tcode = 0xa;
   2637  1.88.2.1   yamt #if BYTE_ORDER == BIG_ENDIAN
   2638  1.88.2.1   yamt 		FWOHCI_DMA_WRITE(db[1].db.immed[0], db[1].db.immed[0]);
   2639  1.88.2.1   yamt 		FWOHCI_DMA_WRITE(db[1].db.immed[1], db[1].db.immed[1]);
   2640  1.88.2.1   yamt #endif
   2641      1.36   onoe 
   2642  1.88.2.1   yamt 		FWOHCI_DMA_CLEAR(db[2].db.desc.cmd, OHCI_COUNT_MASK);
   2643  1.88.2.1   yamt 		FWOHCI_DMA_SET(db[2].db.desc.cmd, fp->mode.stream.len);
   2644  1.88.2.1   yamt 		FWOHCI_DMA_WRITE(db[2].db.desc.res, 0);
   2645  1.88.2.1   yamt #if 0 /* if bulkxfer->npackets changes */
   2646  1.88.2.1   yamt 		db[2].db.desc.cmd = OHCI_OUTPUT_LAST
   2647  1.88.2.1   yamt 			| OHCI_UPDATE
   2648  1.88.2.1   yamt 			| OHCI_BRANCH_ALWAYS;
   2649  1.88.2.1   yamt 		db[0].db.desc.depend =
   2650  1.88.2.1   yamt 			= db[dbch->ndesc - 1].db.desc.depend
   2651  1.88.2.1   yamt 			= STAILQ_NEXT(db_tr, link)->bus_addr | dbch->ndesc;
   2652  1.88.2.1   yamt #else
   2653  1.88.2.1   yamt 		FWOHCI_DMA_SET(db[0].db.desc.depend, dbch->ndesc);
   2654  1.88.2.1   yamt 		FWOHCI_DMA_SET(db[dbch->ndesc - 1].db.desc.depend, dbch->ndesc);
   2655  1.88.2.1   yamt #endif
   2656  1.88.2.3   yamt 		bulkxfer->end = (void *)db_tr;
   2657  1.88.2.1   yamt 		db_tr = STAILQ_NEXT(db_tr, link);
   2658      1.36   onoe 	}
   2659  1.88.2.1   yamt 	db = ((struct fwohcidb_tr *)bulkxfer->end)->db;
   2660  1.88.2.1   yamt 	FWOHCI_DMA_CLEAR(db[0].db.desc.depend, 0xf);
   2661  1.88.2.1   yamt 	FWOHCI_DMA_CLEAR(db[dbch->ndesc - 1].db.desc.depend, 0xf);
   2662  1.88.2.1   yamt #if 0 /* if bulkxfer->npackets changes */
   2663  1.88.2.1   yamt 	db[dbch->ndesc - 1].db.desc.control |= OHCI_INTERRUPT_ALWAYS;
   2664  1.88.2.1   yamt 	/* OHCI 1.1 and above */
   2665  1.88.2.1   yamt 	db[0].db.desc.control |= OHCI_INTERRUPT_ALWAYS;
   2666  1.88.2.1   yamt #endif
   2667  1.88.2.1   yamt /*
   2668  1.88.2.1   yamt 	db_tr = (struct fwohcidb_tr *)bulkxfer->start;
   2669  1.88.2.1   yamt 	fdb_tr = (struct fwohcidb_tr *)bulkxfer->end;
   2670  1.88.2.5   yamt fw_printf(sc->fc.dev, "DB %08x %3d %08x %08x\n", bulkxfer, bulkxfer->npacket, db_tr->bus_addr, fdb_tr->bus_addr);
   2671  1.88.2.1   yamt */
   2672  1.88.2.1   yamt 	return;
   2673       1.7   onoe }
   2674       1.7   onoe 
   2675  1.88.2.1   yamt static int
   2676  1.88.2.1   yamt fwohci_add_tx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr,
   2677  1.88.2.1   yamt 								int poffset)
   2678       1.3   onoe {
   2679  1.88.2.1   yamt 	struct fwohcidb *db = db_tr->db;
   2680  1.88.2.1   yamt 	struct fw_xferq *it;
   2681  1.88.2.1   yamt 	int err = 0;
   2682       1.3   onoe 
   2683  1.88.2.1   yamt 	it = &dbch->xferq;
   2684  1.88.2.1   yamt 	if(it->buf == 0){
   2685  1.88.2.1   yamt 		err = EINVAL;
   2686  1.88.2.1   yamt 		return err;
   2687  1.88.2.1   yamt 	}
   2688  1.88.2.1   yamt 	db_tr->buf = fwdma_v_addr(it->buf, poffset);
   2689  1.88.2.1   yamt 	db_tr->dbcnt = 3;
   2690  1.88.2.1   yamt 
   2691  1.88.2.1   yamt 	FWOHCI_DMA_WRITE(db[0].db.desc.cmd,
   2692  1.88.2.1   yamt 		OHCI_OUTPUT_MORE | OHCI_KEY_ST2 | 8);
   2693  1.88.2.1   yamt 	FWOHCI_DMA_WRITE(db[0].db.desc.addr, 0);
   2694  1.88.2.1   yamt 	bzero((void *)&db[1].db.immed[0], sizeof(db[1].db.immed));
   2695  1.88.2.1   yamt 	FWOHCI_DMA_WRITE(db[2].db.desc.addr,
   2696  1.88.2.1   yamt 	    fwdma_bus_addr(it->buf, poffset) + sizeof(uint32_t));
   2697  1.88.2.1   yamt 
   2698  1.88.2.1   yamt 	FWOHCI_DMA_WRITE(db[2].db.desc.cmd,
   2699  1.88.2.1   yamt 		OHCI_OUTPUT_LAST | OHCI_UPDATE | OHCI_BRANCH_ALWAYS);
   2700  1.88.2.1   yamt #if 1
   2701  1.88.2.1   yamt 	FWOHCI_DMA_WRITE(db[0].db.desc.res, 0);
   2702  1.88.2.1   yamt 	FWOHCI_DMA_WRITE(db[2].db.desc.res, 0);
   2703      1.40   haya #endif
   2704  1.88.2.1   yamt 	return 0;
   2705      1.62   haya }
   2706      1.62   haya 
   2707      1.62   haya int
   2708  1.88.2.1   yamt fwohci_add_rx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr,
   2709  1.88.2.1   yamt 		int poffset, struct fwdma_alloc *dummy_dma)
   2710      1.62   haya {
   2711  1.88.2.1   yamt 	struct fwohcidb *db = db_tr->db;
   2712  1.88.2.1   yamt 	struct fw_xferq *ir;
   2713  1.88.2.1   yamt 	int i, ldesc;
   2714  1.88.2.1   yamt 	bus_addr_t dbuf[2];
   2715  1.88.2.1   yamt 	int dsiz[2];
   2716      1.62   haya 
   2717  1.88.2.1   yamt 	ir = &dbch->xferq;
   2718  1.88.2.2   yamt 	if (ir->buf == NULL && (dbch->xferq.flag & FWXFERQ_EXTBUF) == 0) {
   2719  1.88.2.2   yamt 		if (db_tr->buf == NULL)
   2720  1.88.2.2   yamt 			db_tr->buf = fwdma_malloc_size(
   2721  1.88.2.2   yamt 			    dbch->dmat, &db_tr->dma_map,
   2722  1.88.2.2   yamt 			    ir->psize, &dbuf[0], BUS_DMA_NOWAIT);
   2723  1.88.2.1   yamt 		if (db_tr->buf == NULL)
   2724  1.88.2.1   yamt 			return(ENOMEM);
   2725  1.88.2.1   yamt 		db_tr->dbcnt = 1;
   2726  1.88.2.1   yamt 		dsiz[0] = ir->psize;
   2727  1.88.2.1   yamt 		fw_bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
   2728  1.88.2.1   yamt 			BUS_DMASYNC_PREREAD);
   2729      1.62   haya 	} else {
   2730  1.88.2.1   yamt 		db_tr->dbcnt = 0;
   2731  1.88.2.1   yamt 		if (dummy_dma != NULL) {
   2732  1.88.2.1   yamt 			dsiz[db_tr->dbcnt] = sizeof(uint32_t);
   2733  1.88.2.1   yamt 			dbuf[db_tr->dbcnt++] = dummy_dma->bus_addr;
   2734      1.62   haya 		}
   2735  1.88.2.1   yamt 		dsiz[db_tr->dbcnt] = ir->psize;
   2736  1.88.2.2   yamt 		if (ir->buf != NULL) {
   2737  1.88.2.1   yamt 			db_tr->buf = fwdma_v_addr(ir->buf, poffset);
   2738  1.88.2.1   yamt 			dbuf[db_tr->dbcnt] = fwdma_bus_addr( ir->buf, poffset);
   2739      1.62   haya 		}
   2740  1.88.2.1   yamt 		db_tr->dbcnt++;
   2741      1.62   haya 	}
   2742  1.88.2.1   yamt 	for(i = 0 ; i < db_tr->dbcnt ; i++){
   2743  1.88.2.1   yamt 		FWOHCI_DMA_WRITE(db[i].db.desc.addr, dbuf[i]);
   2744  1.88.2.1   yamt 		FWOHCI_DMA_WRITE(db[i].db.desc.cmd, OHCI_INPUT_MORE | dsiz[i]);
   2745  1.88.2.1   yamt 		if (ir->flag & FWXFERQ_STREAM) {
   2746  1.88.2.1   yamt 			FWOHCI_DMA_SET(db[i].db.desc.cmd, OHCI_UPDATE);
   2747      1.62   haya 		}
   2748  1.88.2.1   yamt 		FWOHCI_DMA_WRITE(db[i].db.desc.res, dsiz[i]);
   2749      1.62   haya 	}
   2750  1.88.2.1   yamt 	ldesc = db_tr->dbcnt - 1;
   2751  1.88.2.1   yamt 	if (ir->flag & FWXFERQ_STREAM) {
   2752  1.88.2.1   yamt 		FWOHCI_DMA_SET(db[ldesc].db.desc.cmd, OHCI_INPUT_LAST);
   2753      1.62   haya 	}
   2754  1.88.2.1   yamt 	FWOHCI_DMA_SET(db[ldesc].db.desc.cmd, OHCI_BRANCH_ALWAYS);
   2755  1.88.2.1   yamt 	return 0;
   2756  1.88.2.1   yamt }
   2757      1.62   haya 
   2758      1.62   haya 
   2759  1.88.2.1   yamt static int
   2760  1.88.2.1   yamt fwohci_arcv_swap(struct fw_pkt *fp, int len)
   2761  1.88.2.1   yamt {
   2762  1.88.2.1   yamt 	struct fw_pkt *fp0;
   2763  1.88.2.1   yamt 	uint32_t ld0;
   2764  1.88.2.1   yamt 	int slen, hlen;
   2765  1.88.2.1   yamt #if BYTE_ORDER == BIG_ENDIAN
   2766  1.88.2.1   yamt 	int i;
   2767      1.62   haya #endif
   2768      1.62   haya 
   2769  1.88.2.1   yamt 	ld0 = FWOHCI_DMA_READ(fp->mode.ld[0]);
   2770  1.88.2.1   yamt #if 0
   2771  1.88.2.1   yamt 	printf("ld0: x%08x\n", ld0);
   2772      1.62   haya #endif
   2773  1.88.2.1   yamt 	fp0 = (struct fw_pkt *)&ld0;
   2774  1.88.2.1   yamt 	/* determine length to swap */
   2775  1.88.2.1   yamt 	switch (fp0->mode.common.tcode) {
   2776  1.88.2.1   yamt 	case FWTCODE_WRES:
   2777  1.88.2.1   yamt 		CTR0(KTR_DEV, "WRES");
   2778  1.88.2.1   yamt 	case FWTCODE_RREQQ:
   2779  1.88.2.1   yamt 	case FWTCODE_WREQQ:
   2780  1.88.2.1   yamt 	case FWTCODE_RRESQ:
   2781  1.88.2.1   yamt 	case FWOHCITCODE_PHY:
   2782  1.88.2.1   yamt 		slen = 12;
   2783  1.88.2.1   yamt 		break;
   2784  1.88.2.1   yamt 	case FWTCODE_RREQB:
   2785  1.88.2.1   yamt 	case FWTCODE_WREQB:
   2786  1.88.2.1   yamt 	case FWTCODE_LREQ:
   2787  1.88.2.1   yamt 	case FWTCODE_RRESB:
   2788  1.88.2.1   yamt 	case FWTCODE_LRES:
   2789  1.88.2.1   yamt 		slen = 16;
   2790  1.88.2.1   yamt 		break;
   2791  1.88.2.1   yamt 	default:
   2792  1.88.2.1   yamt 		printf("Unknown tcode %d\n", fp0->mode.common.tcode);
   2793  1.88.2.1   yamt 		return(0);
   2794      1.62   haya 	}
   2795  1.88.2.1   yamt 	hlen = tinfo[fp0->mode.common.tcode].hdr_len;
   2796  1.88.2.1   yamt 	if (hlen > len) {
   2797  1.88.2.1   yamt 		if (firewire_debug)
   2798  1.88.2.1   yamt 			printf("splitted header\n");
   2799  1.88.2.1   yamt 		return(-hlen);
   2800      1.62   haya 	}
   2801  1.88.2.1   yamt #if BYTE_ORDER == BIG_ENDIAN
   2802  1.88.2.1   yamt 	for(i = 0; i < slen/4; i ++)
   2803  1.88.2.1   yamt 		fp->mode.ld[i] = FWOHCI_DMA_READ(fp->mode.ld[i]);
   2804      1.62   haya #endif
   2805  1.88.2.1   yamt 	return(hlen);
   2806      1.62   haya }
   2807      1.62   haya 
   2808      1.62   haya static int
   2809  1.88.2.1   yamt fwohci_get_plen(struct fwohci_softc *sc, struct fwohci_dbch *dbch, struct fw_pkt *fp)
   2810      1.62   haya {
   2811  1.88.2.1   yamt 	const struct tcode_info *info;
   2812  1.88.2.1   yamt 	int r;
   2813      1.62   haya 
   2814  1.88.2.1   yamt 	info = &tinfo[fp->mode.common.tcode];
   2815  1.88.2.1   yamt 	r = info->hdr_len + sizeof(uint32_t);
   2816  1.88.2.1   yamt 	if ((info->flag & FWTI_BLOCK_ASY) != 0)
   2817  1.88.2.1   yamt 		r += roundup2(fp->mode.wreqb.len, sizeof(uint32_t));
   2818      1.62   haya 
   2819  1.88.2.1   yamt 	if (r == sizeof(uint32_t)) {
   2820  1.88.2.1   yamt 		/* XXX */
   2821  1.88.2.5   yamt 		fw_printf(sc->fc.dev, "Unknown tcode %d\n",
   2822  1.88.2.1   yamt 						fp->mode.common.tcode);
   2823  1.88.2.1   yamt 		return (-1);
   2824      1.62   haya 	}
   2825      1.62   haya 
   2826  1.88.2.1   yamt 	if (r > dbch->xferq.psize) {
   2827  1.88.2.5   yamt 		fw_printf(sc->fc.dev, "Invalid packet length %d\n", r);
   2828  1.88.2.1   yamt 		return (-1);
   2829  1.88.2.1   yamt 		/* panic ? */
   2830      1.62   haya 	}
   2831      1.62   haya 
   2832  1.88.2.1   yamt 	return r;
   2833      1.62   haya }
   2834      1.62   haya 
   2835      1.62   haya static void
   2836  1.88.2.1   yamt fwohci_arcv_free_buf(struct fwohci_softc *sc, struct fwohci_dbch *dbch,
   2837  1.88.2.1   yamt     struct fwohcidb_tr *db_tr, uint32_t off, int wake)
   2838      1.62   haya {
   2839  1.88.2.1   yamt 	struct fwohcidb *db = &db_tr->db[0];
   2840      1.62   haya 
   2841  1.88.2.1   yamt 	FWOHCI_DMA_CLEAR(db->db.desc.depend, 0xf);
   2842  1.88.2.1   yamt 	FWOHCI_DMA_WRITE(db->db.desc.res, dbch->xferq.psize);
   2843  1.88.2.1   yamt 	FWOHCI_DMA_SET(dbch->bottom->db[0].db.desc.depend, 1);
   2844  1.88.2.1   yamt 	fwdma_sync_multiseg_all(dbch->am,
   2845  1.88.2.1   yamt 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   2846  1.88.2.1   yamt 	dbch->bottom = db_tr;
   2847      1.62   haya 
   2848  1.88.2.1   yamt 	if (wake)
   2849  1.88.2.1   yamt 		OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_WAKE);
   2850      1.62   haya }
   2851      1.62   haya 
   2852  1.88.2.1   yamt static void
   2853  1.88.2.1   yamt fwohci_arcv(struct fwohci_softc *sc, struct fwohci_dbch *dbch, int count)
   2854      1.62   haya {
   2855  1.88.2.1   yamt 	struct fwohcidb_tr *db_tr;
   2856  1.88.2.1   yamt 	struct iovec vec[2];
   2857  1.88.2.1   yamt 	struct fw_pkt pktbuf;
   2858  1.88.2.1   yamt 	int nvec;
   2859  1.88.2.1   yamt 	struct fw_pkt *fp;
   2860  1.88.2.1   yamt 	uint8_t *ld;
   2861  1.88.2.1   yamt 	uint32_t stat, off, status, event;
   2862  1.88.2.1   yamt 	u_int spd;
   2863  1.88.2.1   yamt 	int len, plen, hlen, pcnt, offset;
   2864  1.88.2.1   yamt 	int s;
   2865  1.88.2.3   yamt 	void *buf;
   2866  1.88.2.1   yamt 	int resCount;
   2867      1.62   haya 
   2868  1.88.2.1   yamt 	CTR0(KTR_DEV, "fwohci_arv");
   2869      1.62   haya 
   2870  1.88.2.1   yamt 	if(&sc->arrq == dbch){
   2871  1.88.2.1   yamt 		off = OHCI_ARQOFF;
   2872  1.88.2.1   yamt 	}else if(&sc->arrs == dbch){
   2873  1.88.2.1   yamt 		off = OHCI_ARSOFF;
   2874  1.88.2.1   yamt 	}else{
   2875  1.88.2.1   yamt 		return;
   2876      1.62   haya 	}
   2877      1.62   haya 
   2878  1.88.2.1   yamt 	s = splfw();
   2879  1.88.2.1   yamt 	db_tr = dbch->top;
   2880  1.88.2.1   yamt 	pcnt = 0;
   2881  1.88.2.1   yamt 	/* XXX we cannot handle a packet which lies in more than two buf */
   2882  1.88.2.1   yamt 	fwdma_sync_multiseg_all(dbch->am,
   2883  1.88.2.1   yamt 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
   2884  1.88.2.1   yamt 	status = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res) >> OHCI_STATUS_SHIFT;
   2885  1.88.2.1   yamt 	resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res) & OHCI_COUNT_MASK;
   2886  1.88.2.1   yamt 	while (status & OHCI_CNTL_DMA_ACTIVE) {
   2887  1.88.2.1   yamt #if 0
   2888      1.62   haya 
   2889  1.88.2.1   yamt 		if (off == OHCI_ARQOFF)
   2890  1.88.2.1   yamt 			printf("buf 0x%08x, status 0x%04x, resCount 0x%04x\n",
   2891  1.88.2.1   yamt 			    db_tr->bus_addr, status, resCount);
   2892  1.88.2.1   yamt #endif
   2893  1.88.2.1   yamt 		len = dbch->xferq.psize - resCount;
   2894  1.88.2.1   yamt 		ld = (uint8_t *)db_tr->buf;
   2895  1.88.2.1   yamt 		if (dbch->pdb_tr == NULL) {
   2896  1.88.2.1   yamt 			len -= dbch->buf_offset;
   2897  1.88.2.1   yamt 			ld += dbch->buf_offset;
   2898  1.88.2.1   yamt 		}
   2899  1.88.2.1   yamt 		if (len > 0)
   2900  1.88.2.1   yamt 			fw_bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
   2901  1.88.2.1   yamt 					BUS_DMASYNC_POSTREAD);
   2902  1.88.2.1   yamt 		while (len > 0 ) {
   2903  1.88.2.1   yamt 			if (count >= 0 && count-- == 0)
   2904  1.88.2.1   yamt 				goto out;
   2905  1.88.2.1   yamt 			if(dbch->pdb_tr != NULL){
   2906  1.88.2.1   yamt 				/* we have a fragment in previous buffer */
   2907  1.88.2.1   yamt 				int rlen;
   2908  1.88.2.1   yamt 
   2909  1.88.2.1   yamt 				offset = dbch->buf_offset;
   2910  1.88.2.1   yamt 				if (offset < 0)
   2911  1.88.2.1   yamt 					offset = - offset;
   2912  1.88.2.3   yamt 				buf = (char *)dbch->pdb_tr->buf + offset;
   2913  1.88.2.1   yamt 				rlen = dbch->xferq.psize - offset;
   2914  1.88.2.1   yamt 				if (firewire_debug)
   2915  1.88.2.1   yamt 					printf("rlen=%d, offset=%d\n",
   2916  1.88.2.1   yamt 						rlen, dbch->buf_offset);
   2917  1.88.2.1   yamt 				if (dbch->buf_offset < 0) {
   2918  1.88.2.1   yamt 					/* splitted in header, pull up */
   2919  1.88.2.1   yamt 					char *p;
   2920  1.88.2.1   yamt 
   2921  1.88.2.1   yamt 					p = (char *)&pktbuf;
   2922  1.88.2.1   yamt 					bcopy(buf, p, rlen);
   2923  1.88.2.1   yamt 					p += rlen;
   2924  1.88.2.1   yamt 					/* this must be too long but harmless */
   2925  1.88.2.1   yamt 					rlen = sizeof(pktbuf) - rlen;
   2926  1.88.2.1   yamt 					if (rlen < 0)
   2927  1.88.2.1   yamt 						printf("why rlen < 0\n");
   2928  1.88.2.1   yamt 					bcopy(db_tr->buf, p, rlen);
   2929  1.88.2.1   yamt 					ld += rlen;
   2930  1.88.2.1   yamt 					len -= rlen;
   2931  1.88.2.1   yamt 					hlen = fwohci_arcv_swap(&pktbuf, sizeof(pktbuf));
   2932  1.88.2.1   yamt 					if (hlen <= 0) {
   2933  1.88.2.5   yamt 						printf("hlen should be positive.");
   2934  1.88.2.1   yamt 						goto err;
   2935  1.88.2.1   yamt 					}
   2936  1.88.2.1   yamt 					offset = sizeof(pktbuf);
   2937  1.88.2.1   yamt 					vec[0].iov_base = (char *)&pktbuf;
   2938  1.88.2.1   yamt 					vec[0].iov_len = offset;
   2939  1.88.2.1   yamt 				} else {
   2940  1.88.2.1   yamt 					/* splitted in payload */
   2941  1.88.2.1   yamt 					offset = rlen;
   2942  1.88.2.1   yamt 					vec[0].iov_base = buf;
   2943  1.88.2.1   yamt 					vec[0].iov_len = rlen;
   2944  1.88.2.1   yamt 				}
   2945  1.88.2.1   yamt 				fp=(struct fw_pkt *)vec[0].iov_base;
   2946  1.88.2.1   yamt 				nvec = 1;
   2947  1.88.2.1   yamt 			} else {
   2948  1.88.2.1   yamt 				/* no fragment in previous buffer */
   2949  1.88.2.1   yamt 				fp=(struct fw_pkt *)ld;
   2950  1.88.2.1   yamt 				hlen = fwohci_arcv_swap(fp, len);
   2951  1.88.2.1   yamt 				if (hlen == 0)
   2952  1.88.2.1   yamt 					goto err;
   2953  1.88.2.1   yamt 				if (hlen < 0) {
   2954  1.88.2.1   yamt 					dbch->pdb_tr = db_tr;
   2955  1.88.2.1   yamt 					dbch->buf_offset = - dbch->buf_offset;
   2956  1.88.2.1   yamt 					/* sanity check */
   2957  1.88.2.1   yamt 					if (resCount != 0)  {
   2958  1.88.2.1   yamt 						printf("resCount=%d hlen=%d\n",
   2959  1.88.2.1   yamt 						    resCount, hlen);
   2960  1.88.2.1   yamt 						goto err;
   2961  1.88.2.1   yamt 					}
   2962  1.88.2.1   yamt 					goto out;
   2963      1.62   haya 				}
   2964  1.88.2.1   yamt 				offset = 0;
   2965  1.88.2.1   yamt 				nvec = 0;
   2966  1.88.2.1   yamt 			}
   2967  1.88.2.1   yamt 			plen = fwohci_get_plen(sc, dbch, fp) - offset;
   2968  1.88.2.1   yamt 			if (plen < 0) {
   2969  1.88.2.1   yamt 				/* minimum header size + trailer
   2970  1.88.2.1   yamt 				= sizeof(fw_pkt) so this shouldn't happens */
   2971  1.88.2.1   yamt 				printf("plen(%d) is negative! offset=%d\n",
   2972  1.88.2.1   yamt 				    plen, offset);
   2973  1.88.2.1   yamt 				goto err;
   2974  1.88.2.1   yamt 			}
   2975  1.88.2.1   yamt 			if (plen > 0) {
   2976  1.88.2.1   yamt 				len -= plen;
   2977  1.88.2.1   yamt 				if (len < 0) {
   2978  1.88.2.1   yamt 					dbch->pdb_tr = db_tr;
   2979  1.88.2.1   yamt 					if (firewire_debug)
   2980  1.88.2.1   yamt 						printf("splitted payload\n");
   2981  1.88.2.1   yamt 					/* sanity check */
   2982  1.88.2.1   yamt 					if (resCount != 0)  {
   2983  1.88.2.1   yamt 						printf("resCount=%d plen=%d"
   2984  1.88.2.1   yamt 						    " len=%d\n",
   2985  1.88.2.1   yamt 						    resCount, plen, len);
   2986  1.88.2.1   yamt 						goto err;
   2987  1.88.2.1   yamt 					}
   2988  1.88.2.1   yamt 					goto out;
   2989  1.88.2.1   yamt 				}
   2990  1.88.2.1   yamt 				vec[nvec].iov_base = ld;
   2991  1.88.2.1   yamt 				vec[nvec].iov_len = plen;
   2992  1.88.2.1   yamt 				nvec ++;
   2993  1.88.2.1   yamt 				ld += plen;
   2994  1.88.2.1   yamt 			}
   2995  1.88.2.1   yamt 			dbch->buf_offset = ld - (uint8_t *)db_tr->buf;
   2996  1.88.2.1   yamt 			if (nvec == 0)
   2997  1.88.2.1   yamt 				printf("nvec == 0\n");
   2998  1.88.2.1   yamt 
   2999  1.88.2.1   yamt /* DMA result-code will be written at the tail of packet */
   3000  1.88.2.1   yamt 			stat = FWOHCI_DMA_READ(*(uint32_t *)(ld - sizeof(struct fwohci_trailer)));
   3001  1.88.2.1   yamt #if 0
   3002  1.88.2.1   yamt 			printf("plen: %d, stat %x\n",
   3003  1.88.2.1   yamt 			    plen ,stat);
   3004  1.88.2.1   yamt #endif
   3005  1.88.2.1   yamt 			spd = (stat >> 21) & 0x3;
   3006  1.88.2.1   yamt 			event = (stat >> 16) & 0x1f;
   3007  1.88.2.1   yamt 			switch (event) {
   3008  1.88.2.1   yamt 			case FWOHCIEV_ACKPEND:
   3009  1.88.2.1   yamt #if 0
   3010  1.88.2.1   yamt 				printf("fwohci_arcv: ack pending tcode=0x%x..\n", fp->mode.common.tcode);
   3011  1.88.2.1   yamt #endif
   3012  1.88.2.1   yamt 				/* fall through */
   3013  1.88.2.1   yamt 			case FWOHCIEV_ACKCOMPL:
   3014  1.88.2.1   yamt 			{
   3015  1.88.2.1   yamt 				struct fw_rcv_buf rb;
   3016  1.88.2.1   yamt 
   3017  1.88.2.1   yamt 				if ((vec[nvec-1].iov_len -=
   3018  1.88.2.1   yamt 					sizeof(struct fwohci_trailer)) == 0)
   3019  1.88.2.1   yamt 					nvec--;
   3020  1.88.2.1   yamt 				rb.fc = &sc->fc;
   3021  1.88.2.1   yamt 				rb.vec = vec;
   3022  1.88.2.1   yamt 				rb.nvec = nvec;
   3023  1.88.2.1   yamt 				rb.spd = spd;
   3024  1.88.2.1   yamt 				fw_rcv(&rb);
   3025      1.62   haya 				break;
   3026  1.88.2.1   yamt 			}
   3027  1.88.2.1   yamt 			case FWOHCIEV_BUSRST:
   3028  1.88.2.5   yamt 				if ((sc->fc.status != FWBUSRESET) &&
   3029  1.88.2.5   yamt 				    (sc->fc.status != FWBUSINIT))
   3030  1.88.2.1   yamt 					printf("got BUSRST packet!?\n");
   3031      1.62   haya 				break;
   3032      1.62   haya 			default:
   3033  1.88.2.5   yamt 				fw_printf(sc->fc.dev,
   3034  1.88.2.1   yamt 				    "Async DMA Receive error err=%02x %s"
   3035  1.88.2.1   yamt 				    " plen=%d offset=%d len=%d status=0x%08x"
   3036  1.88.2.1   yamt 				    " tcode=0x%x, stat=0x%08x\n",
   3037  1.88.2.1   yamt 				    event, fwohcicode[event], plen,
   3038  1.88.2.1   yamt 				    dbch->buf_offset, len,
   3039  1.88.2.1   yamt 				    OREAD(sc, OHCI_DMACTL(off)),
   3040  1.88.2.1   yamt 				    fp->mode.common.tcode, stat);
   3041  1.88.2.1   yamt #if 1 /* XXX */
   3042  1.88.2.1   yamt 				goto err;
   3043  1.88.2.1   yamt #endif
   3044      1.62   haya 				break;
   3045      1.62   haya 			}
   3046  1.88.2.1   yamt 			pcnt ++;
   3047  1.88.2.1   yamt 			if (dbch->pdb_tr != NULL) {
   3048  1.88.2.1   yamt 				fwohci_arcv_free_buf(sc, dbch, dbch->pdb_tr,
   3049  1.88.2.1   yamt 				    off, 1);
   3050  1.88.2.1   yamt 				dbch->pdb_tr = NULL;
   3051  1.88.2.1   yamt 			}
   3052      1.62   haya 
   3053      1.62   haya 		}
   3054  1.88.2.1   yamt out:
   3055  1.88.2.1   yamt 		if (resCount == 0) {
   3056  1.88.2.1   yamt 			/* done on this buffer */
   3057  1.88.2.1   yamt 			if (dbch->pdb_tr == NULL) {
   3058  1.88.2.1   yamt 				fwohci_arcv_free_buf(sc, dbch, db_tr, off, 1);
   3059  1.88.2.1   yamt 				dbch->buf_offset = 0;
   3060  1.88.2.1   yamt 			} else
   3061  1.88.2.1   yamt 				if (dbch->pdb_tr != db_tr)
   3062  1.88.2.1   yamt 					printf("pdb_tr != db_tr\n");
   3063  1.88.2.1   yamt 			db_tr = STAILQ_NEXT(db_tr, link);
   3064  1.88.2.1   yamt 			fwdma_sync_multiseg_all(dbch->am,
   3065  1.88.2.1   yamt 			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   3066  1.88.2.1   yamt 			status = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
   3067  1.88.2.1   yamt 						>> OHCI_STATUS_SHIFT;
   3068  1.88.2.1   yamt 			resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
   3069  1.88.2.1   yamt 						& OHCI_COUNT_MASK;
   3070  1.88.2.1   yamt 			/* XXX check buffer overrun */
   3071  1.88.2.1   yamt 			dbch->top = db_tr;
   3072      1.62   haya 		} else {
   3073  1.88.2.1   yamt 			dbch->buf_offset = dbch->xferq.psize - resCount;
   3074  1.88.2.1   yamt 			fw_bus_dmamap_sync(
   3075  1.88.2.1   yamt 			    dbch->dmat, db_tr->dma_map, BUS_DMASYNC_PREREAD);
   3076      1.62   haya 			break;
   3077      1.62   haya 		}
   3078  1.88.2.1   yamt 		/* XXX make sure DMA is not dead */
   3079      1.62   haya 	}
   3080  1.88.2.1   yamt #if 0
   3081  1.88.2.1   yamt 	if (pcnt < 1)
   3082  1.88.2.1   yamt 		printf("fwohci_arcv: no packets\n");
   3083  1.88.2.1   yamt #endif
   3084  1.88.2.1   yamt 	fwdma_sync_multiseg_all(dbch->am,
   3085  1.88.2.1   yamt 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   3086  1.88.2.1   yamt 	splx(s);
   3087  1.88.2.1   yamt 	return;
   3088      1.62   haya 
   3089  1.88.2.1   yamt err:
   3090  1.88.2.5   yamt 	fw_printf(sc->fc.dev, "AR DMA status=%x, ",
   3091  1.88.2.1   yamt 					OREAD(sc, OHCI_DMACTL(off)));
   3092  1.88.2.1   yamt 	dbch->pdb_tr = NULL;
   3093  1.88.2.1   yamt 	/* skip until resCount != 0 */
   3094  1.88.2.1   yamt 	printf(" skip buffer");
   3095  1.88.2.1   yamt 	while (resCount == 0) {
   3096  1.88.2.1   yamt 		printf(" #");
   3097  1.88.2.1   yamt 		fwohci_arcv_free_buf(sc, dbch, db_tr, off, 0);
   3098  1.88.2.1   yamt 		db_tr = STAILQ_NEXT(db_tr, link);
   3099  1.88.2.1   yamt 		resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
   3100  1.88.2.1   yamt 						& OHCI_COUNT_MASK;
   3101  1.88.2.1   yamt 	}
   3102  1.88.2.1   yamt 	printf(" done\n");
   3103  1.88.2.1   yamt 	dbch->top = db_tr;
   3104  1.88.2.1   yamt 	dbch->buf_offset = dbch->xferq.psize - resCount;
   3105  1.88.2.1   yamt 	OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_WAKE);
   3106  1.88.2.1   yamt 	fwdma_sync_multiseg_all(
   3107  1.88.2.1   yamt 	    dbch->am, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   3108  1.88.2.1   yamt 	fw_bus_dmamap_sync(dbch->dmat, db_tr->dma_map, BUS_DMASYNC_PREREAD);
   3109  1.88.2.1   yamt 	splx(s);
   3110      1.62   haya }
   3111  1.88.2.1   yamt #if defined(__NetBSD__)
   3112      1.62   haya 
   3113      1.62   haya int
   3114  1.88.2.1   yamt fwohci_print(void *aux, const char *pnp)
   3115      1.62   haya {
   3116  1.88.2.2   yamt 	struct fw_attach_args *fwa = (struct fw_attach_args *)aux;
   3117  1.88.2.1   yamt 
   3118  1.88.2.1   yamt 	if (pnp)
   3119  1.88.2.2   yamt 		aprint_normal("%s at %s", fwa->name, pnp);
   3120      1.62   haya 
   3121  1.88.2.1   yamt 	return UNCONF;
   3122      1.62   haya }
   3123  1.88.2.1   yamt #endif
   3124