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