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