Home | History | Annotate | Line # | Download | only in ieee1394
fwohci.c revision 1.88.2.3
      1  1.88.2.3      yamt /*	$NetBSD: fwohci.c,v 1.88.2.3 2007/09/03 14:35:27 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.3      yamt __KERNEL_RCSID(0, "$NetBSD: fwohci.c,v 1.88.2.3 2007/09/03 14:35:27 yamt Exp $");
     62      1.40      haya 
     63  1.88.2.1      yamt #if defined(__DragonFly__) || __FreeBSD_version < 500000
     64  1.88.2.1      yamt #include <machine/clock.h>		/* for DELAY() */
     65  1.88.2.1      yamt #endif
     66       1.3      onoe 
     67  1.88.2.1      yamt #ifdef __DragonFly__
     68  1.88.2.1      yamt #include "fw_port.h"
     69  1.88.2.1      yamt #include "firewire.h"
     70  1.88.2.1      yamt #include "firewirereg.h"
     71  1.88.2.1      yamt #include "fwdma.h"
     72  1.88.2.1      yamt #include "fwohcireg.h"
     73  1.88.2.1      yamt #include "fwohcivar.h"
     74  1.88.2.1      yamt #include "firewire_phy.h"
     75  1.88.2.1      yamt #else
     76  1.88.2.1      yamt #include <dev/firewire/fw_port.h>
     77  1.88.2.1      yamt #include <dev/firewire/firewire.h>
     78  1.88.2.1      yamt #include <dev/firewire/firewirereg.h>
     79  1.88.2.1      yamt #include <dev/firewire/fwdma.h>
     80  1.88.2.1      yamt #include <dev/firewire/fwohcireg.h>
     81  1.88.2.1      yamt #include <dev/firewire/fwohcivar.h>
     82  1.88.2.1      yamt #include <dev/firewire/firewire_phy.h>
     83  1.88.2.1      yamt #endif
     84  1.88.2.1      yamt #elif defined(__NetBSD__)
     85       1.1      matt #include <sys/param.h>
     86       1.1      matt #include <sys/device.h>
     87  1.88.2.1      yamt #include <sys/errno.h>
     88  1.88.2.1      yamt #include <sys/conf.h>
     89       1.7      onoe #include <sys/kernel.h>
     90       1.3      onoe #include <sys/malloc.h>
     91       1.3      onoe #include <sys/mbuf.h>
     92  1.88.2.1      yamt #include <sys/proc.h>
     93  1.88.2.1      yamt #include <sys/reboot.h>
     94  1.88.2.1      yamt #include <sys/sysctl.h>
     95  1.88.2.1      yamt #include <sys/systm.h>
     96       1.7      onoe 
     97       1.1      matt #include <machine/bus.h>
     98       1.1      matt 
     99  1.88.2.1      yamt #include <dev/ieee1394/fw_port.h>
    100  1.88.2.1      yamt #include <dev/ieee1394/firewire.h>
    101  1.88.2.1      yamt #include <dev/ieee1394/firewirereg.h>
    102  1.88.2.1      yamt #include <dev/ieee1394/fwdma.h>
    103       1.1      matt #include <dev/ieee1394/fwohcireg.h>
    104       1.1      matt #include <dev/ieee1394/fwohcivar.h>
    105  1.88.2.1      yamt #include <dev/ieee1394/firewire_phy.h>
    106  1.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.1      yamt }
   1295      1.26     enami 
   1296  1.88.2.1      yamt static void
   1297  1.88.2.1      yamt fwohci_db_init(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
   1298  1.88.2.1      yamt {
   1299  1.88.2.1      yamt 	int	idb;
   1300  1.88.2.1      yamt 	struct fwohcidb_tr *db_tr;
   1301  1.88.2.1      yamt 
   1302  1.88.2.1      yamt 	if ((dbch->flags & FWOHCI_DBCH_INIT) != 0)
   1303  1.88.2.1      yamt 		goto out;
   1304  1.88.2.1      yamt 
   1305  1.88.2.1      yamt 	/* create dma_tag for buffers */
   1306  1.88.2.1      yamt #define MAX_REQCOUNT	0xffff
   1307  1.88.2.1      yamt 	if (fw_bus_dma_tag_create(/*parent*/ sc->fc.dmat,
   1308  1.88.2.1      yamt 			/*alignment*/ 1, /*boundary*/ 0,
   1309  1.88.2.1      yamt 			/*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
   1310  1.88.2.1      yamt 			/*highaddr*/ BUS_SPACE_MAXADDR,
   1311  1.88.2.1      yamt 			/*filter*/NULL, /*filterarg*/NULL,
   1312  1.88.2.1      yamt 			/*maxsize*/ dbch->xferq.psize,
   1313  1.88.2.1      yamt 			/*nsegments*/ dbch->ndesc > 3 ? dbch->ndesc - 2 : 1,
   1314  1.88.2.1      yamt 			/*maxsegsz*/ MAX_REQCOUNT,
   1315  1.88.2.1      yamt 			/*flags*/ 0,
   1316  1.88.2.1      yamt 			/*lockfunc*/busdma_lock_mutex,
   1317  1.88.2.1      yamt 			/*lockarg*/&Giant,
   1318  1.88.2.1      yamt 			&dbch->dmat))
   1319  1.88.2.1      yamt 		return;
   1320      1.26     enami 
   1321  1.88.2.1      yamt 	/* allocate DB entries and attach one to each DMA channels */
   1322  1.88.2.1      yamt 	/* DB entry must start at 16 bytes bounary. */
   1323  1.88.2.1      yamt 	STAILQ_INIT(&dbch->db_trq);
   1324  1.88.2.1      yamt 	db_tr = (struct fwohcidb_tr *)
   1325  1.88.2.1      yamt 		malloc(sizeof(struct fwohcidb_tr) * dbch->ndb,
   1326  1.88.2.1      yamt 		M_FW, M_WAITOK | M_ZERO);
   1327  1.88.2.1      yamt 	if(db_tr == NULL){
   1328  1.88.2.1      yamt 		printf("fwohci_db_init: malloc(1) failed\n");
   1329  1.88.2.1      yamt 		return;
   1330  1.88.2.1      yamt 	}
   1331      1.35      onoe 
   1332  1.88.2.1      yamt #define DB_SIZE(x) (sizeof(struct fwohcidb) * (x)->ndesc)
   1333  1.88.2.1      yamt 	dbch->am = fwdma_malloc_multiseg(&sc->fc, DB_SIZE(dbch),
   1334  1.88.2.1      yamt 		DB_SIZE(dbch), dbch->ndb, BUS_DMA_WAITOK | BUS_DMA_COHERENT);
   1335  1.88.2.1      yamt 	if (dbch->am == NULL) {
   1336  1.88.2.1      yamt 		printf("fwohci_db_init: fwdma_malloc_multiseg failed\n");
   1337  1.88.2.1      yamt 		free(db_tr, M_FW);
   1338  1.88.2.1      yamt 		return;
   1339  1.88.2.1      yamt 	}
   1340  1.88.2.1      yamt 	/* Attach DB to DMA ch. */
   1341  1.88.2.1      yamt 	for(idb = 0 ; idb < dbch->ndb ; idb++){
   1342  1.88.2.1      yamt 		db_tr->dbcnt = 0;
   1343  1.88.2.1      yamt 		db_tr->db = (struct fwohcidb *)fwdma_v_addr(dbch->am, idb);
   1344  1.88.2.1      yamt 		db_tr->bus_addr = fwdma_bus_addr(dbch->am, idb);
   1345  1.88.2.1      yamt 		/* create dmamap for buffers */
   1346  1.88.2.1      yamt 		/* XXX do we need 4bytes alignment tag? */
   1347  1.88.2.1      yamt 		/* XXX don't alloc dma_map for AR */
   1348  1.88.2.1      yamt 		if (fw_bus_dmamap_create(dbch->dmat, 0, &db_tr->dma_map) != 0) {
   1349  1.88.2.1      yamt 			printf("fw_bus_dmamap_create failed\n");
   1350  1.88.2.1      yamt 			dbch->flags = FWOHCI_DBCH_INIT; /* XXX fake */
   1351  1.88.2.1      yamt 			fwohci_db_free(dbch);
   1352  1.88.2.1      yamt 			return;
   1353      1.35      onoe 		}
   1354  1.88.2.1      yamt 		STAILQ_INSERT_TAIL(&dbch->db_trq, db_tr, link);
   1355  1.88.2.1      yamt 		if (dbch->xferq.flag & FWXFERQ_EXTBUF) {
   1356  1.88.2.1      yamt 			if (idb % dbch->xferq.bnpacket == 0)
   1357  1.88.2.1      yamt 				dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket
   1358  1.88.2.3      yamt 						].start = (void *)db_tr;
   1359  1.88.2.1      yamt 			if ((idb + 1) % dbch->xferq.bnpacket == 0)
   1360  1.88.2.1      yamt 				dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket
   1361  1.88.2.3      yamt 						].end = (void *)db_tr;
   1362      1.26     enami 		}
   1363  1.88.2.1      yamt 		db_tr++;
   1364      1.26     enami 	}
   1365  1.88.2.1      yamt 	STAILQ_LAST(&dbch->db_trq, fwohcidb_tr,link)->link.stqe_next
   1366  1.88.2.1      yamt 			= STAILQ_FIRST(&dbch->db_trq);
   1367  1.88.2.1      yamt out:
   1368  1.88.2.1      yamt 	dbch->xferq.queued = 0;
   1369  1.88.2.1      yamt 	dbch->pdb_tr = NULL;
   1370  1.88.2.1      yamt 	dbch->top = STAILQ_FIRST(&dbch->db_trq);
   1371  1.88.2.1      yamt 	dbch->bottom = dbch->top;
   1372  1.88.2.1      yamt 	dbch->flags = FWOHCI_DBCH_INIT;
   1373      1.24       jmc }
   1374      1.24       jmc 
   1375       1.5      matt static int
   1376  1.88.2.1      yamt fwohci_itx_disable(struct firewire_comm *fc, int dmach)
   1377       1.5      matt {
   1378  1.88.2.1      yamt 	struct fwohci_softc *sc = (struct fwohci_softc *)fc;
   1379  1.88.2.1      yamt 	int sleepch;
   1380       1.5      matt 
   1381  1.88.2.1      yamt 	OWRITE(sc, OHCI_ITCTLCLR(dmach),
   1382  1.88.2.1      yamt 			OHCI_CNTL_DMA_RUN | OHCI_CNTL_CYCMATCH_S);
   1383  1.88.2.1      yamt 	OWRITE(sc, OHCI_IT_MASKCLR, 1 << dmach);
   1384  1.88.2.1      yamt 	OWRITE(sc, OHCI_IT_STATCLR, 1 << dmach);
   1385  1.88.2.1      yamt 	/* XXX we cannot free buffers until the DMA really stops */
   1386  1.88.2.1      yamt 	tsleep((void *)&sleepch, FWPRI, "fwitxd", hz);
   1387  1.88.2.1      yamt 	fwohci_db_free(&sc->it[dmach]);
   1388  1.88.2.1      yamt 	sc->it[dmach].xferq.flag &= ~FWXFERQ_RUNNING;
   1389  1.88.2.1      yamt 	return 0;
   1390       1.5      matt }
   1391       1.5      matt 
   1392  1.88.2.1      yamt static int
   1393  1.88.2.1      yamt fwohci_irx_disable(struct firewire_comm *fc, int dmach)
   1394       1.3      onoe {
   1395  1.88.2.1      yamt 	struct fwohci_softc *sc = (struct fwohci_softc *)fc;
   1396  1.88.2.1      yamt 	int sleepch;
   1397       1.3      onoe 
   1398  1.88.2.1      yamt 	OWRITE(sc, OHCI_IRCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
   1399  1.88.2.1      yamt 	OWRITE(sc, OHCI_IR_MASKCLR, 1 << dmach);
   1400  1.88.2.1      yamt 	OWRITE(sc, OHCI_IR_STATCLR, 1 << dmach);
   1401  1.88.2.1      yamt 	/* XXX we cannot free buffers until the DMA really stops */
   1402  1.88.2.1      yamt 	tsleep((void *)&sleepch, FWPRI, "fwirxd", hz);
   1403  1.88.2.1      yamt 	fwohci_db_free(&sc->ir[dmach]);
   1404  1.88.2.1      yamt 	sc->ir[dmach].xferq.flag &= ~FWXFERQ_RUNNING;
   1405  1.88.2.1      yamt 	return 0;
   1406       1.3      onoe }
   1407       1.3      onoe 
   1408  1.88.2.1      yamt #if BYTE_ORDER == BIG_ENDIAN
   1409       1.7      onoe static void
   1410  1.88.2.1      yamt fwohci_irx_post (struct firewire_comm *fc , uint32_t *qld)
   1411       1.7      onoe {
   1412  1.88.2.1      yamt 	qld[0] = FWOHCI_DMA_READ(qld[0]);
   1413  1.88.2.1      yamt 	return;
   1414  1.88.2.1      yamt }
   1415  1.88.2.1      yamt #endif
   1416       1.7      onoe 
   1417  1.88.2.1      yamt static int
   1418  1.88.2.1      yamt fwohci_tx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
   1419  1.88.2.1      yamt {
   1420  1.88.2.1      yamt 	int err = 0;
   1421  1.88.2.1      yamt 	int idb, z, i, dmach = 0, ldesc;
   1422  1.88.2.1      yamt 	uint32_t off = 0;
   1423  1.88.2.1      yamt 	struct fwohcidb_tr *db_tr;
   1424  1.88.2.1      yamt 	struct fwohcidb *db;
   1425  1.88.2.1      yamt 
   1426  1.88.2.1      yamt 	if(!(dbch->xferq.flag & FWXFERQ_EXTBUF)){
   1427  1.88.2.1      yamt 		err = EINVAL;
   1428  1.88.2.1      yamt 		return err;
   1429  1.88.2.1      yamt 	}
   1430  1.88.2.1      yamt 	z = dbch->ndesc;
   1431  1.88.2.1      yamt 	for(dmach = 0 ; dmach < sc->fc.nisodma ; dmach++){
   1432  1.88.2.1      yamt 		if( &sc->it[dmach] == dbch){
   1433  1.88.2.1      yamt 			off = OHCI_ITOFF(dmach);
   1434       1.7      onoe 			break;
   1435  1.88.2.1      yamt 		}
   1436       1.7      onoe 	}
   1437  1.88.2.1      yamt 	if(off == 0){
   1438  1.88.2.1      yamt 		err = EINVAL;
   1439  1.88.2.1      yamt 		return err;
   1440  1.88.2.1      yamt 	}
   1441  1.88.2.1      yamt 	if(dbch->xferq.flag & FWXFERQ_RUNNING)
   1442  1.88.2.1      yamt 		return err;
   1443  1.88.2.1      yamt 	dbch->xferq.flag |= FWXFERQ_RUNNING;
   1444  1.88.2.1      yamt 	for( i = 0, dbch->bottom = dbch->top; i < (dbch->ndb - 1); i++){
   1445  1.88.2.1      yamt 		dbch->bottom = STAILQ_NEXT(dbch->bottom, link);
   1446  1.88.2.1      yamt 	}
   1447  1.88.2.1      yamt 	db_tr = dbch->top;
   1448  1.88.2.1      yamt 	for (idb = 0; idb < dbch->ndb; idb ++) {
   1449  1.88.2.1      yamt 		fwohci_add_tx_buf(dbch, db_tr, idb);
   1450  1.88.2.1      yamt 		if(STAILQ_NEXT(db_tr, link) == NULL){
   1451  1.88.2.1      yamt 			break;
   1452  1.88.2.1      yamt 		}
   1453  1.88.2.1      yamt 		db = db_tr->db;
   1454  1.88.2.1      yamt 		ldesc = db_tr->dbcnt - 1;
   1455  1.88.2.1      yamt 		FWOHCI_DMA_WRITE(db[0].db.desc.depend,
   1456  1.88.2.1      yamt 				STAILQ_NEXT(db_tr, link)->bus_addr | z);
   1457  1.88.2.1      yamt 		db[ldesc].db.desc.depend = db[0].db.desc.depend;
   1458  1.88.2.1      yamt 		if(dbch->xferq.flag & FWXFERQ_EXTBUF){
   1459  1.88.2.1      yamt 			if(((idb + 1 ) % dbch->xferq.bnpacket) == 0){
   1460  1.88.2.1      yamt 				FWOHCI_DMA_SET(
   1461  1.88.2.1      yamt 					db[ldesc].db.desc.cmd,
   1462  1.88.2.1      yamt 					OHCI_INTERRUPT_ALWAYS);
   1463  1.88.2.1      yamt 				/* OHCI 1.1 and above */
   1464  1.88.2.1      yamt 				FWOHCI_DMA_SET(
   1465  1.88.2.1      yamt 					db[0].db.desc.cmd,
   1466  1.88.2.1      yamt 					OHCI_INTERRUPT_ALWAYS);
   1467  1.88.2.1      yamt 			}
   1468  1.88.2.1      yamt 		}
   1469  1.88.2.1      yamt 		db_tr = STAILQ_NEXT(db_tr, link);
   1470  1.88.2.1      yamt 	}
   1471  1.88.2.1      yamt 	FWOHCI_DMA_CLEAR(
   1472  1.88.2.1      yamt 		dbch->bottom->db[dbch->bottom->dbcnt - 1].db.desc.depend, 0xf);
   1473  1.88.2.1      yamt 	return err;
   1474  1.88.2.1      yamt }
   1475       1.7      onoe 
   1476  1.88.2.1      yamt static int
   1477  1.88.2.1      yamt fwohci_rx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
   1478  1.88.2.1      yamt {
   1479  1.88.2.1      yamt 	int err = 0;
   1480  1.88.2.1      yamt 	int idb, z, i, dmach = 0, ldesc;
   1481  1.88.2.1      yamt 	uint32_t off = 0;
   1482  1.88.2.1      yamt 	struct fwohcidb_tr *db_tr;
   1483  1.88.2.1      yamt 	struct fwohcidb *db;
   1484  1.88.2.1      yamt 
   1485  1.88.2.1      yamt 	z = dbch->ndesc;
   1486  1.88.2.1      yamt 	if(&sc->arrq == dbch){
   1487  1.88.2.1      yamt 		off = OHCI_ARQOFF;
   1488  1.88.2.1      yamt 	}else if(&sc->arrs == dbch){
   1489  1.88.2.1      yamt 		off = OHCI_ARSOFF;
   1490  1.88.2.1      yamt 	}else{
   1491  1.88.2.1      yamt 		for(dmach = 0 ; dmach < sc->fc.nisodma ; dmach++){
   1492  1.88.2.1      yamt 			if( &sc->ir[dmach] == dbch){
   1493  1.88.2.1      yamt 				off = OHCI_IROFF(dmach);
   1494  1.88.2.1      yamt 				break;
   1495  1.88.2.1      yamt 			}
   1496  1.88.2.1      yamt 		}
   1497  1.88.2.1      yamt 	}
   1498  1.88.2.1      yamt 	if(off == 0){
   1499  1.88.2.1      yamt 		err = EINVAL;
   1500  1.88.2.1      yamt 		return err;
   1501  1.88.2.1      yamt 	}
   1502  1.88.2.1      yamt 	if(dbch->xferq.flag & FWXFERQ_STREAM){
   1503  1.88.2.1      yamt 		if(dbch->xferq.flag & FWXFERQ_RUNNING)
   1504  1.88.2.1      yamt 			return err;
   1505  1.88.2.1      yamt 	}else{
   1506  1.88.2.1      yamt 		if(dbch->xferq.flag & FWXFERQ_RUNNING){
   1507  1.88.2.1      yamt 			err = EBUSY;
   1508  1.88.2.1      yamt 			return err;
   1509  1.88.2.1      yamt 		}
   1510  1.88.2.1      yamt 	}
   1511  1.88.2.1      yamt 	dbch->xferq.flag |= FWXFERQ_RUNNING;
   1512  1.88.2.1      yamt 	dbch->top = STAILQ_FIRST(&dbch->db_trq);
   1513  1.88.2.1      yamt 	for( i = 0, dbch->bottom = dbch->top; i < (dbch->ndb - 1); i++){
   1514  1.88.2.1      yamt 		dbch->bottom = STAILQ_NEXT(dbch->bottom, link);
   1515  1.88.2.1      yamt 	}
   1516  1.88.2.1      yamt 	db_tr = dbch->top;
   1517  1.88.2.1      yamt 	for (idb = 0; idb < dbch->ndb; idb ++) {
   1518  1.88.2.1      yamt 		fwohci_add_rx_buf(dbch, db_tr, idb, &sc->dummy_dma);
   1519  1.88.2.1      yamt 		if (STAILQ_NEXT(db_tr, link) == NULL)
   1520  1.88.2.1      yamt 			break;
   1521  1.88.2.1      yamt 		db = db_tr->db;
   1522  1.88.2.1      yamt 		ldesc = db_tr->dbcnt - 1;
   1523  1.88.2.1      yamt 		FWOHCI_DMA_WRITE(db[ldesc].db.desc.depend,
   1524  1.88.2.1      yamt 			STAILQ_NEXT(db_tr, link)->bus_addr | z);
   1525  1.88.2.1      yamt 		if(dbch->xferq.flag & FWXFERQ_EXTBUF){
   1526  1.88.2.1      yamt 			if(((idb + 1 ) % dbch->xferq.bnpacket) == 0){
   1527  1.88.2.1      yamt 				FWOHCI_DMA_SET(
   1528  1.88.2.1      yamt 					db[ldesc].db.desc.cmd,
   1529  1.88.2.1      yamt 					OHCI_INTERRUPT_ALWAYS);
   1530  1.88.2.1      yamt 				FWOHCI_DMA_CLEAR(
   1531  1.88.2.1      yamt 					db[ldesc].db.desc.depend,
   1532  1.88.2.1      yamt 					0xf);
   1533  1.88.2.1      yamt 			}
   1534  1.88.2.1      yamt 		}
   1535  1.88.2.1      yamt 		db_tr = STAILQ_NEXT(db_tr, link);
   1536  1.88.2.1      yamt 	}
   1537  1.88.2.1      yamt 	FWOHCI_DMA_CLEAR(
   1538  1.88.2.1      yamt 		dbch->bottom->db[db_tr->dbcnt - 1].db.desc.depend, 0xf);
   1539  1.88.2.1      yamt 	dbch->buf_offset = 0;
   1540  1.88.2.1      yamt 	fwdma_sync_multiseg_all(dbch->am,
   1541  1.88.2.1      yamt 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1542  1.88.2.1      yamt 	if(dbch->xferq.flag & FWXFERQ_STREAM){
   1543  1.88.2.1      yamt 		return err;
   1544  1.88.2.1      yamt 	}else{
   1545  1.88.2.1      yamt 		OWRITE(sc, OHCI_DMACMD(off), dbch->top->bus_addr | z);
   1546  1.88.2.1      yamt 	}
   1547  1.88.2.1      yamt 	OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_RUN);
   1548  1.88.2.1      yamt 	return err;
   1549  1.88.2.1      yamt }
   1550       1.7      onoe 
   1551  1.88.2.1      yamt static int
   1552  1.88.2.1      yamt fwohci_next_cycle(struct firewire_comm *fc, int cycle_now)
   1553  1.88.2.1      yamt {
   1554  1.88.2.1      yamt 	int sec, cycle, cycle_match;
   1555  1.88.2.1      yamt 
   1556  1.88.2.1      yamt 	cycle = cycle_now & 0x1fff;
   1557  1.88.2.1      yamt 	sec = cycle_now >> 13;
   1558  1.88.2.1      yamt #define CYCLE_MOD	0x10
   1559  1.88.2.1      yamt #if 1
   1560  1.88.2.1      yamt #define CYCLE_DELAY	8	/* min delay to start DMA */
   1561       1.7      onoe #else
   1562  1.88.2.1      yamt #define CYCLE_DELAY	7000	/* min delay to start DMA */
   1563       1.7      onoe #endif
   1564  1.88.2.1      yamt 	cycle = cycle + CYCLE_DELAY;
   1565  1.88.2.1      yamt 	if (cycle >= 8000) {
   1566  1.88.2.1      yamt 		sec ++;
   1567  1.88.2.1      yamt 		cycle -= 8000;
   1568  1.88.2.1      yamt 	}
   1569  1.88.2.1      yamt 	cycle = roundup2(cycle, CYCLE_MOD);
   1570  1.88.2.1      yamt 	if (cycle >= 8000) {
   1571  1.88.2.1      yamt 		sec ++;
   1572  1.88.2.1      yamt 		if (cycle == 8000)
   1573  1.88.2.1      yamt 			cycle = 0;
   1574  1.88.2.1      yamt 		else
   1575  1.88.2.1      yamt 			cycle = CYCLE_MOD;
   1576  1.88.2.1      yamt 	}
   1577  1.88.2.1      yamt 	cycle_match = ((sec << 13) | cycle) & 0x7ffff;
   1578       1.7      onoe 
   1579  1.88.2.1      yamt 	return(cycle_match);
   1580  1.88.2.1      yamt }
   1581       1.7      onoe 
   1582  1.88.2.1      yamt static int
   1583  1.88.2.1      yamt fwohci_itxbuf_enable(struct firewire_comm *fc, int dmach)
   1584  1.88.2.1      yamt {
   1585  1.88.2.1      yamt 	struct fwohci_softc *sc = (struct fwohci_softc *)fc;
   1586  1.88.2.1      yamt 	int err = 0;
   1587  1.88.2.1      yamt 	unsigned short tag, ich;
   1588  1.88.2.1      yamt 	struct fwohci_dbch *dbch;
   1589  1.88.2.1      yamt 	int cycle_match, cycle_now, s, ldesc;
   1590  1.88.2.1      yamt 	uint32_t stat;
   1591  1.88.2.1      yamt 	struct fw_bulkxfer *first, *chunk, *prev;
   1592  1.88.2.1      yamt 	struct fw_xferq *it;
   1593  1.88.2.1      yamt 
   1594  1.88.2.1      yamt 	dbch = &sc->it[dmach];
   1595  1.88.2.1      yamt 	it = &dbch->xferq;
   1596  1.88.2.1      yamt 
   1597  1.88.2.1      yamt 	tag = (it->flag >> 6) & 3;
   1598  1.88.2.1      yamt 	ich = it->flag & 0x3f;
   1599  1.88.2.1      yamt 	if ((dbch->flags & FWOHCI_DBCH_INIT) == 0) {
   1600  1.88.2.1      yamt 		dbch->ndb = it->bnpacket * it->bnchunk;
   1601  1.88.2.1      yamt 		dbch->ndesc = 3;
   1602  1.88.2.1      yamt 		fwohci_db_init(sc, dbch);
   1603  1.88.2.1      yamt 		if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
   1604  1.88.2.1      yamt 			return ENOMEM;
   1605  1.88.2.1      yamt 		err = fwohci_tx_enable(sc, dbch);
   1606  1.88.2.1      yamt 	}
   1607  1.88.2.1      yamt 	if(err)
   1608  1.88.2.1      yamt 		return err;
   1609  1.88.2.1      yamt 
   1610  1.88.2.1      yamt 	ldesc = dbch->ndesc - 1;
   1611  1.88.2.1      yamt 	s = splfw();
   1612  1.88.2.1      yamt 	prev = STAILQ_LAST(&it->stdma, fw_bulkxfer, link);
   1613  1.88.2.1      yamt 	while  ((chunk = STAILQ_FIRST(&it->stvalid)) != NULL) {
   1614  1.88.2.1      yamt 		struct fwohcidb *db;
   1615  1.88.2.1      yamt 
   1616  1.88.2.1      yamt 		fwdma_sync_multiseg(it->buf, chunk->poffset, it->bnpacket,
   1617  1.88.2.1      yamt 					BUS_DMASYNC_PREWRITE);
   1618  1.88.2.1      yamt 		fwohci_txbufdb(sc, dmach, chunk);
   1619  1.88.2.1      yamt 		if (prev != NULL) {
   1620  1.88.2.1      yamt 			db = ((struct fwohcidb_tr *)(prev->end))->db;
   1621  1.88.2.1      yamt #if 0 /* XXX necessary? */
   1622  1.88.2.1      yamt 			FWOHCI_DMA_SET(db[ldesc].db.desc.cmd,
   1623  1.88.2.1      yamt 						OHCI_BRANCH_ALWAYS);
   1624  1.88.2.1      yamt #endif
   1625  1.88.2.1      yamt #if 0 /* if bulkxfer->npacket changes */
   1626  1.88.2.1      yamt 			db[ldesc].db.desc.depend = db[0].db.desc.depend =
   1627  1.88.2.1      yamt 				((struct fwohcidb_tr *)
   1628  1.88.2.1      yamt 				(chunk->start))->bus_addr | dbch->ndesc;
   1629  1.88.2.1      yamt #else
   1630  1.88.2.1      yamt 			FWOHCI_DMA_SET(db[0].db.desc.depend, dbch->ndesc);
   1631  1.88.2.1      yamt 			FWOHCI_DMA_SET(db[ldesc].db.desc.depend, dbch->ndesc);
   1632  1.88.2.1      yamt #endif
   1633  1.88.2.1      yamt 		}
   1634  1.88.2.1      yamt 		STAILQ_REMOVE_HEAD(&it->stvalid, link);
   1635  1.88.2.1      yamt 		STAILQ_INSERT_TAIL(&it->stdma, chunk, link);
   1636  1.88.2.1      yamt 		prev = chunk;
   1637  1.88.2.1      yamt 	}
   1638  1.88.2.1      yamt 	fwdma_sync_multiseg_all(dbch->am,
   1639  1.88.2.1      yamt 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1640  1.88.2.1      yamt 	splx(s);
   1641  1.88.2.1      yamt 	stat = OREAD(sc, OHCI_ITCTL(dmach));
   1642  1.88.2.1      yamt 	if (firewire_debug && (stat & OHCI_CNTL_CYCMATCH_S))
   1643  1.88.2.1      yamt 		printf("stat 0x%x\n", stat);
   1644  1.88.2.1      yamt 
   1645  1.88.2.1      yamt 	if (stat & (OHCI_CNTL_DMA_ACTIVE | OHCI_CNTL_CYCMATCH_S))
   1646  1.88.2.1      yamt 		return 0;
   1647  1.88.2.1      yamt 
   1648  1.88.2.1      yamt #if 0
   1649  1.88.2.1      yamt 	OWRITE(sc, OHCI_ITCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
   1650  1.88.2.1      yamt #endif
   1651  1.88.2.1      yamt 	OWRITE(sc, OHCI_IT_MASKCLR, 1 << dmach);
   1652  1.88.2.1      yamt 	OWRITE(sc, OHCI_IT_STATCLR, 1 << dmach);
   1653  1.88.2.1      yamt 	OWRITE(sc, OHCI_IT_MASK, 1 << dmach);
   1654  1.88.2.1      yamt 	OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_DMA_IT);
   1655  1.88.2.1      yamt 
   1656  1.88.2.1      yamt 	first = STAILQ_FIRST(&it->stdma);
   1657  1.88.2.1      yamt 	OWRITE(sc, OHCI_ITCMD(dmach),
   1658  1.88.2.1      yamt 		((struct fwohcidb_tr *)(first->start))->bus_addr | dbch->ndesc);
   1659  1.88.2.1      yamt 	if (firewire_debug > 1) {
   1660  1.88.2.1      yamt 		printf("fwohci_itxbuf_enable: kick 0x%08x\n", stat);
   1661  1.88.2.1      yamt #if 1
   1662  1.88.2.1      yamt 		dump_dma(sc, ITX_CH + dmach);
   1663      1.22     enami #endif
   1664  1.88.2.1      yamt 	}
   1665  1.88.2.1      yamt 	if ((stat & OHCI_CNTL_DMA_RUN) == 0) {
   1666  1.88.2.1      yamt #if 1
   1667  1.88.2.1      yamt 		/* Don't start until all chunks are buffered */
   1668  1.88.2.1      yamt 		if (STAILQ_FIRST(&it->stfree) != NULL)
   1669  1.88.2.1      yamt 			goto out;
   1670  1.88.2.1      yamt #endif
   1671  1.88.2.1      yamt #if 1
   1672  1.88.2.1      yamt 		/* Clear cycle match counter bits */
   1673  1.88.2.1      yamt 		OWRITE(sc, OHCI_ITCTLCLR(dmach), 0xffff0000);
   1674       1.7      onoe 
   1675  1.88.2.1      yamt 		/* 2bit second + 13bit cycle */
   1676  1.88.2.1      yamt 		cycle_now = (fc->cyctimer(fc) >> 12) & 0x7fff;
   1677  1.88.2.1      yamt 		cycle_match = fwohci_next_cycle(fc, cycle_now);
   1678  1.88.2.1      yamt 
   1679  1.88.2.1      yamt 		OWRITE(sc, OHCI_ITCTL(dmach),
   1680  1.88.2.1      yamt 				OHCI_CNTL_CYCMATCH_S | (cycle_match << 16)
   1681  1.88.2.1      yamt 				| OHCI_CNTL_DMA_RUN);
   1682  1.88.2.1      yamt #else
   1683  1.88.2.1      yamt 		OWRITE(sc, OHCI_ITCTL(dmach), OHCI_CNTL_DMA_RUN);
   1684  1.88.2.1      yamt #endif
   1685  1.88.2.1      yamt 		if (firewire_debug > 1) {
   1686  1.88.2.1      yamt 			printf("cycle_match: 0x%04x->0x%04x\n",
   1687  1.88.2.1      yamt 						cycle_now, cycle_match);
   1688  1.88.2.1      yamt 			dump_dma(sc, ITX_CH + dmach);
   1689  1.88.2.1      yamt 			dump_db(sc, ITX_CH + dmach);
   1690  1.88.2.1      yamt 		}
   1691  1.88.2.1      yamt 	} else if ((stat & OHCI_CNTL_CYCMATCH_S) == 0) {
   1692  1.88.2.1      yamt 		device_printf(sc->fc.dev,
   1693  1.88.2.1      yamt 			"IT DMA underrun (0x%08x)\n", stat);
   1694  1.88.2.1      yamt 		OWRITE(sc, OHCI_ITCTL(dmach), OHCI_CNTL_DMA_WAKE);
   1695  1.88.2.1      yamt 	}
   1696  1.88.2.1      yamt out:
   1697  1.88.2.1      yamt 	return err;
   1698  1.88.2.1      yamt }
   1699       1.7      onoe 
   1700  1.88.2.1      yamt static int
   1701  1.88.2.1      yamt fwohci_irx_enable(struct firewire_comm *fc, int dmach)
   1702  1.88.2.1      yamt {
   1703  1.88.2.1      yamt 	struct fwohci_softc *sc = (struct fwohci_softc *)fc;
   1704  1.88.2.1      yamt 	int err = 0, s, ldesc;
   1705  1.88.2.1      yamt 	unsigned short tag, ich;
   1706  1.88.2.1      yamt 	uint32_t stat;
   1707  1.88.2.1      yamt 	struct fwohci_dbch *dbch;
   1708  1.88.2.1      yamt 	struct fwohcidb_tr *db_tr;
   1709  1.88.2.1      yamt 	struct fw_bulkxfer *first, *prev, *chunk;
   1710  1.88.2.1      yamt 	struct fw_xferq *ir;
   1711  1.88.2.1      yamt 
   1712  1.88.2.1      yamt 	dbch = &sc->ir[dmach];
   1713  1.88.2.1      yamt 	ir = &dbch->xferq;
   1714  1.88.2.1      yamt 
   1715  1.88.2.1      yamt 	if ((ir->flag & FWXFERQ_RUNNING) == 0) {
   1716  1.88.2.1      yamt 		tag = (ir->flag >> 6) & 3;
   1717  1.88.2.1      yamt 		ich = ir->flag & 0x3f;
   1718  1.88.2.1      yamt 		OWRITE(sc, OHCI_IRMATCH(dmach), tagbit[tag] | ich);
   1719  1.88.2.1      yamt 
   1720  1.88.2.1      yamt 		ir->queued = 0;
   1721  1.88.2.1      yamt 		dbch->ndb = ir->bnpacket * ir->bnchunk;
   1722  1.88.2.1      yamt 		dbch->ndesc = 2;
   1723  1.88.2.1      yamt 		fwohci_db_init(sc, dbch);
   1724  1.88.2.1      yamt 		if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
   1725  1.88.2.1      yamt 			return ENOMEM;
   1726  1.88.2.1      yamt 		err = fwohci_rx_enable(sc, dbch);
   1727  1.88.2.1      yamt 	}
   1728  1.88.2.1      yamt 	if(err)
   1729  1.88.2.1      yamt 		return err;
   1730  1.88.2.1      yamt 
   1731  1.88.2.1      yamt 	first = STAILQ_FIRST(&ir->stfree);
   1732  1.88.2.1      yamt 	if (first == NULL) {
   1733  1.88.2.1      yamt 		device_printf(fc->dev, "IR DMA no free chunk\n");
   1734  1.88.2.1      yamt 		return 0;
   1735  1.88.2.1      yamt 	}
   1736       1.7      onoe 
   1737  1.88.2.1      yamt 	ldesc = dbch->ndesc - 1;
   1738  1.88.2.1      yamt 	s = splfw();
   1739  1.88.2.1      yamt 	prev = STAILQ_LAST(&ir->stdma, fw_bulkxfer, link);
   1740  1.88.2.1      yamt 	while  ((chunk = STAILQ_FIRST(&ir->stfree)) != NULL) {
   1741  1.88.2.1      yamt 		struct fwohcidb *db;
   1742  1.88.2.1      yamt 
   1743  1.88.2.1      yamt #if 1 /* XXX for if_fwe */
   1744  1.88.2.1      yamt 		if (chunk->mbuf != NULL) {
   1745  1.88.2.1      yamt 			db_tr = (struct fwohcidb_tr *)(chunk->start);
   1746  1.88.2.1      yamt 			db_tr->dbcnt = 1;
   1747  1.88.2.1      yamt 			err = fw_bus_dmamap_load_mbuf(
   1748  1.88.2.1      yamt 					dbch->dmat, db_tr->dma_map,
   1749  1.88.2.1      yamt 					chunk->mbuf, fwohci_execute_db2, db_tr,
   1750  1.88.2.1      yamt 					BUS_DMA_WAITOK);
   1751  1.88.2.1      yamt  			FWOHCI_DMA_SET(db_tr->db[1].db.desc.cmd,
   1752  1.88.2.1      yamt 				OHCI_UPDATE | OHCI_INPUT_LAST |
   1753  1.88.2.1      yamt 				OHCI_INTERRUPT_ALWAYS | OHCI_BRANCH_ALWAYS);
   1754  1.88.2.1      yamt 		}
   1755  1.88.2.1      yamt #endif
   1756  1.88.2.1      yamt 		db = ((struct fwohcidb_tr *)(chunk->end))->db;
   1757  1.88.2.1      yamt 		FWOHCI_DMA_WRITE(db[ldesc].db.desc.res, 0);
   1758  1.88.2.1      yamt 		FWOHCI_DMA_CLEAR(db[ldesc].db.desc.depend, 0xf);
   1759  1.88.2.1      yamt 		if (prev != NULL) {
   1760  1.88.2.1      yamt 			db = ((struct fwohcidb_tr *)(prev->end))->db;
   1761  1.88.2.1      yamt 			FWOHCI_DMA_SET(db[ldesc].db.desc.depend, dbch->ndesc);
   1762  1.88.2.1      yamt 		}
   1763  1.88.2.1      yamt 		STAILQ_REMOVE_HEAD(&ir->stfree, link);
   1764  1.88.2.1      yamt 		STAILQ_INSERT_TAIL(&ir->stdma, chunk, link);
   1765  1.88.2.1      yamt 		prev = chunk;
   1766  1.88.2.1      yamt 	}
   1767  1.88.2.1      yamt 	fwdma_sync_multiseg_all(dbch->am,
   1768  1.88.2.1      yamt 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1769  1.88.2.1      yamt 	splx(s);
   1770  1.88.2.1      yamt 	stat = OREAD(sc, OHCI_IRCTL(dmach));
   1771  1.88.2.1      yamt 	if (stat & OHCI_CNTL_DMA_ACTIVE)
   1772  1.88.2.1      yamt 		return 0;
   1773  1.88.2.1      yamt 	if (stat & OHCI_CNTL_DMA_RUN) {
   1774  1.88.2.1      yamt 		OWRITE(sc, OHCI_IRCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
   1775  1.88.2.1      yamt 		device_printf(sc->fc.dev, "IR DMA overrun (0x%08x)\n", stat);
   1776  1.88.2.1      yamt 	}
   1777  1.88.2.1      yamt 
   1778  1.88.2.1      yamt 	if (firewire_debug)
   1779  1.88.2.1      yamt 		printf("start IR DMA 0x%x\n", stat);
   1780  1.88.2.1      yamt 	OWRITE(sc, OHCI_IR_MASKCLR, 1 << dmach);
   1781  1.88.2.1      yamt 	OWRITE(sc, OHCI_IR_STATCLR, 1 << dmach);
   1782  1.88.2.1      yamt 	OWRITE(sc, OHCI_IR_MASK, 1 << dmach);
   1783  1.88.2.1      yamt 	OWRITE(sc, OHCI_IRCTLCLR(dmach), 0xf0000000);
   1784  1.88.2.1      yamt 	OWRITE(sc, OHCI_IRCTL(dmach), OHCI_CNTL_ISOHDR);
   1785  1.88.2.1      yamt 	OWRITE(sc, OHCI_IRCMD(dmach),
   1786  1.88.2.1      yamt 		((struct fwohcidb_tr *)(first->start))->bus_addr
   1787  1.88.2.1      yamt 							| dbch->ndesc);
   1788  1.88.2.1      yamt 	OWRITE(sc, OHCI_IRCTL(dmach), OHCI_CNTL_DMA_RUN);
   1789  1.88.2.1      yamt 	OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_DMA_IR);
   1790  1.88.2.1      yamt #if 0
   1791  1.88.2.1      yamt 	dump_db(sc, IRX_CH + dmach);
   1792  1.88.2.1      yamt #endif
   1793  1.88.2.1      yamt 	return err;
   1794  1.88.2.1      yamt }
   1795  1.88.2.1      yamt 
   1796  1.88.2.1      yamt FWOHCI_STOP()
   1797  1.88.2.1      yamt {
   1798  1.88.2.1      yamt 	FWOHCI_STOP_START;
   1799  1.88.2.1      yamt 	u_int i;
   1800  1.88.2.1      yamt 
   1801  1.88.2.1      yamt /* Now stopping all DMA channel */
   1802  1.88.2.1      yamt 	OWRITE(sc,  OHCI_ARQCTLCLR, OHCI_CNTL_DMA_RUN);
   1803  1.88.2.1      yamt 	OWRITE(sc,  OHCI_ARSCTLCLR, OHCI_CNTL_DMA_RUN);
   1804  1.88.2.1      yamt 	OWRITE(sc,  OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN);
   1805  1.88.2.1      yamt 	OWRITE(sc,  OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN);
   1806  1.88.2.1      yamt 
   1807  1.88.2.1      yamt 	for( i = 0 ; i < sc->fc.nisodma ; i ++ ){
   1808  1.88.2.1      yamt 		OWRITE(sc,  OHCI_IRCTLCLR(i), OHCI_CNTL_DMA_RUN);
   1809  1.88.2.1      yamt 		OWRITE(sc,  OHCI_ITCTLCLR(i), OHCI_CNTL_DMA_RUN);
   1810  1.88.2.1      yamt 	}
   1811  1.88.2.1      yamt 
   1812  1.88.2.1      yamt /* FLUSH FIFO and reset Transmitter/Reciever */
   1813  1.88.2.1      yamt 	OWRITE(sc,  OHCI_HCCCTL, OHCI_HCC_RESET);
   1814  1.88.2.1      yamt 
   1815  1.88.2.1      yamt /* Stop interrupt */
   1816  1.88.2.1      yamt 	OWRITE(sc, FWOHCI_INTMASKCLR,
   1817  1.88.2.1      yamt 			OHCI_INT_EN | OHCI_INT_ERR | OHCI_INT_PHY_SID
   1818  1.88.2.1      yamt 			| OHCI_INT_PHY_INT
   1819  1.88.2.1      yamt 			| OHCI_INT_DMA_ATRQ | OHCI_INT_DMA_ATRS
   1820  1.88.2.1      yamt 			| OHCI_INT_DMA_PRRQ | OHCI_INT_DMA_PRRS
   1821  1.88.2.1      yamt 			| OHCI_INT_DMA_ARRQ | OHCI_INT_DMA_ARRS
   1822  1.88.2.1      yamt 			| OHCI_INT_PHY_BUS_R);
   1823  1.88.2.1      yamt 
   1824  1.88.2.1      yamt 	if (sc->fc.arq !=0 && sc->fc.arq->maxq > 0)
   1825  1.88.2.1      yamt 		fw_drain_txq(&sc->fc);
   1826  1.88.2.1      yamt 
   1827  1.88.2.1      yamt /* XXX Link down?  Bus reset? */
   1828  1.88.2.1      yamt 	FWOHCI_STOP_RETURN(0);
   1829       1.7      onoe }
   1830       1.7      onoe 
   1831  1.88.2.1      yamt #if defined(__NetBSD__)
   1832       1.7      onoe static void
   1833       1.7      onoe fwohci_power(int why, void *arg)
   1834       1.7      onoe {
   1835       1.7      onoe 	struct fwohci_softc *sc = arg;
   1836       1.7      onoe 	int s;
   1837       1.7      onoe 
   1838      1.24       jmc 	s = splbio();
   1839      1.10  takemura 	switch (why) {
   1840      1.10  takemura 	case PWR_SUSPEND:
   1841      1.10  takemura 	case PWR_STANDBY:
   1842  1.88.2.1      yamt 		fwohci_stop(arg);
   1843      1.10  takemura 		break;
   1844      1.10  takemura 	case PWR_RESUME:
   1845  1.88.2.1      yamt 		fwohci_resume(sc, sc->fc.dev);
   1846      1.10  takemura 		break;
   1847      1.10  takemura 	case PWR_SOFTSUSPEND:
   1848      1.10  takemura 	case PWR_SOFTSTANDBY:
   1849      1.10  takemura 	case PWR_SOFTRESUME:
   1850      1.10  takemura 		break;
   1851       1.7      onoe 	}
   1852       1.7      onoe 	splx(s);
   1853       1.7      onoe }
   1854  1.88.2.1      yamt #endif
   1855       1.7      onoe 
   1856  1.88.2.1      yamt int
   1857  1.88.2.1      yamt fwohci_resume(struct fwohci_softc *sc, device_t dev)
   1858       1.3      onoe {
   1859       1.3      onoe 	int i;
   1860  1.88.2.1      yamt 	struct fw_xferq *ir;
   1861  1.88.2.1      yamt 	struct fw_bulkxfer *chunk;
   1862       1.3      onoe 
   1863  1.88.2.1      yamt 	fwohci_reset(sc, dev);
   1864  1.88.2.1      yamt 	/* XXX resume isochronous receive automatically. (how about TX?) */
   1865  1.88.2.1      yamt 	for(i = 0; i < sc->fc.nisodma; i ++) {
   1866  1.88.2.1      yamt 		ir = &sc->ir[i].xferq;
   1867  1.88.2.1      yamt 		if((ir->flag & FWXFERQ_RUNNING) != 0) {
   1868  1.88.2.1      yamt 			device_printf(sc->fc.dev,
   1869  1.88.2.1      yamt 				"resume iso receive ch: %d\n", i);
   1870  1.88.2.1      yamt 			ir->flag &= ~FWXFERQ_RUNNING;
   1871  1.88.2.1      yamt 			/* requeue stdma to stfree */
   1872  1.88.2.1      yamt 			while((chunk = STAILQ_FIRST(&ir->stdma)) != NULL) {
   1873  1.88.2.1      yamt 				STAILQ_REMOVE_HEAD(&ir->stdma, link);
   1874  1.88.2.1      yamt 				STAILQ_INSERT_TAIL(&ir->stfree, chunk, link);
   1875  1.88.2.1      yamt 			}
   1876  1.88.2.1      yamt 			sc->fc.irx_enable(&sc->fc, i);
   1877  1.88.2.1      yamt 		}
   1878  1.88.2.1      yamt 	}
   1879  1.88.2.1      yamt 
   1880  1.88.2.1      yamt #if defined(__FreeBSD__)
   1881  1.88.2.1      yamt 	bus_generic_resume(dev);
   1882  1.88.2.1      yamt #endif
   1883  1.88.2.1      yamt 	sc->fc.ibr(&sc->fc);
   1884  1.88.2.1      yamt 	return 0;
   1885  1.88.2.1      yamt }
   1886  1.88.2.1      yamt 
   1887  1.88.2.1      yamt #define ACK_ALL
   1888  1.88.2.1      yamt static void
   1889  1.88.2.1      yamt fwohci_intr_body(struct fwohci_softc *sc, uint32_t stat, int count)
   1890  1.88.2.1      yamt {
   1891  1.88.2.1      yamt 	uint32_t irstat, itstat;
   1892  1.88.2.1      yamt 	u_int i;
   1893  1.88.2.1      yamt 	struct firewire_comm *fc = (struct firewire_comm *)sc;
   1894  1.88.2.1      yamt 
   1895  1.88.2.1      yamt 	CTR0(KTR_DEV, "fwohci_intr_body");
   1896  1.88.2.1      yamt #ifdef OHCI_DEBUG
   1897  1.88.2.1      yamt 	if(stat & OREAD(sc, FWOHCI_INTMASK))
   1898  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",
   1899  1.88.2.1      yamt 			stat & OHCI_INT_EN ? "DMA_EN ":"",
   1900  1.88.2.1      yamt 			stat & OHCI_INT_PHY_REG ? "PHY_REG ":"",
   1901  1.88.2.1      yamt 			stat & OHCI_INT_CYC_LONG ? "CYC_LONG ":"",
   1902  1.88.2.1      yamt 			stat & OHCI_INT_ERR ? "INT_ERR ":"",
   1903  1.88.2.1      yamt 			stat & OHCI_INT_CYC_ERR ? "CYC_ERR ":"",
   1904  1.88.2.1      yamt 			stat & OHCI_INT_CYC_LOST ? "CYC_LOST ":"",
   1905  1.88.2.1      yamt 			stat & OHCI_INT_CYC_64SECOND ? "CYC_64SECOND ":"",
   1906  1.88.2.1      yamt 			stat & OHCI_INT_CYC_START ? "CYC_START ":"",
   1907  1.88.2.1      yamt 			stat & OHCI_INT_PHY_INT ? "PHY_INT ":"",
   1908  1.88.2.1      yamt 			stat & OHCI_INT_PHY_BUS_R ? "BUS_RESET ":"",
   1909  1.88.2.1      yamt 			stat & OHCI_INT_PHY_SID ? "SID ":"",
   1910  1.88.2.1      yamt 			stat & OHCI_INT_LR_ERR ? "DMA_LR_ERR ":"",
   1911  1.88.2.1      yamt 			stat & OHCI_INT_PW_ERR ? "DMA_PW_ERR ":"",
   1912  1.88.2.1      yamt 			stat & OHCI_INT_DMA_IR ? "DMA_IR ":"",
   1913  1.88.2.1      yamt 			stat & OHCI_INT_DMA_IT  ? "DMA_IT " :"",
   1914  1.88.2.1      yamt 			stat & OHCI_INT_DMA_PRRS  ? "DMA_PRRS " :"",
   1915  1.88.2.1      yamt 			stat & OHCI_INT_DMA_PRRQ  ? "DMA_PRRQ " :"",
   1916  1.88.2.1      yamt 			stat & OHCI_INT_DMA_ARRS  ? "DMA_ARRS " :"",
   1917  1.88.2.1      yamt 			stat & OHCI_INT_DMA_ARRQ  ? "DMA_ARRQ " :"",
   1918  1.88.2.1      yamt 			stat & OHCI_INT_DMA_ATRS  ? "DMA_ATRS " :"",
   1919  1.88.2.1      yamt 			stat & OHCI_INT_DMA_ATRQ  ? "DMA_ATRQ " :"",
   1920  1.88.2.1      yamt 			stat, OREAD(sc, FWOHCI_INTMASK)
   1921  1.88.2.1      yamt 		);
   1922  1.88.2.1      yamt #endif
   1923  1.88.2.1      yamt /* Bus reset */
   1924  1.88.2.1      yamt 	if(stat & OHCI_INT_PHY_BUS_R ){
   1925  1.88.2.1      yamt 		if (fc->status == FWBUSRESET)
   1926  1.88.2.1      yamt 			goto busresetout;
   1927  1.88.2.1      yamt 		/* Disable bus reset interrupt until sid recv. */
   1928  1.88.2.1      yamt 		OWRITE(sc, FWOHCI_INTMASKCLR,  OHCI_INT_PHY_BUS_R);
   1929  1.88.2.1      yamt 
   1930  1.88.2.1      yamt 		device_printf(fc->dev, "BUS reset\n");
   1931  1.88.2.1      yamt 		OWRITE(sc, FWOHCI_INTMASKCLR,  OHCI_INT_CYC_LOST);
   1932  1.88.2.1      yamt 		OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCSRC);
   1933  1.88.2.1      yamt 
   1934  1.88.2.1      yamt 		OWRITE(sc,  OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN);
   1935  1.88.2.1      yamt 		sc->atrq.xferq.flag &= ~FWXFERQ_RUNNING;
   1936  1.88.2.1      yamt 		OWRITE(sc,  OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN);
   1937  1.88.2.1      yamt 		sc->atrs.xferq.flag &= ~FWXFERQ_RUNNING;
   1938  1.88.2.1      yamt 
   1939  1.88.2.1      yamt #ifndef ACK_ALL
   1940  1.88.2.1      yamt 		OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_PHY_BUS_R);
   1941  1.88.2.1      yamt #endif
   1942  1.88.2.1      yamt 		fw_busreset(fc);
   1943  1.88.2.1      yamt 		OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0]));
   1944  1.88.2.1      yamt 		OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2]));
   1945  1.88.2.1      yamt 	}
   1946  1.88.2.1      yamt busresetout:
   1947  1.88.2.1      yamt 	if((stat & OHCI_INT_DMA_IR )){
   1948  1.88.2.1      yamt #ifndef ACK_ALL
   1949  1.88.2.1      yamt 		OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_DMA_IR);
   1950  1.88.2.1      yamt #endif
   1951  1.88.2.1      yamt #if defined(__DragonFly__) || __FreeBSD_version < 500000 || defined(__NetBSD__)
   1952  1.88.2.1      yamt 		irstat = sc->irstat;
   1953  1.88.2.1      yamt 		sc->irstat = 0;
   1954  1.88.2.1      yamt #else
   1955  1.88.2.1      yamt 		irstat = atomic_readandclear_int(&sc->irstat);
   1956  1.88.2.1      yamt #endif
   1957  1.88.2.1      yamt 		for(i = 0; i < fc->nisodma ; i++){
   1958  1.88.2.1      yamt 			struct fwohci_dbch *dbch;
   1959  1.88.2.1      yamt 
   1960  1.88.2.1      yamt 			if((irstat & (1 << i)) != 0){
   1961  1.88.2.1      yamt 				dbch = &sc->ir[i];
   1962  1.88.2.1      yamt 				if ((dbch->xferq.flag & FWXFERQ_OPEN) == 0) {
   1963  1.88.2.1      yamt 					device_printf(sc->fc.dev,
   1964  1.88.2.1      yamt 						"dma(%d) not active\n", i);
   1965  1.88.2.1      yamt 					continue;
   1966  1.88.2.1      yamt 				}
   1967  1.88.2.1      yamt 				fwohci_rbuf_update(sc, i);
   1968  1.88.2.1      yamt 			}
   1969  1.88.2.1      yamt 		}
   1970       1.3      onoe 	}
   1971  1.88.2.1      yamt 	if((stat & OHCI_INT_DMA_IT )){
   1972  1.88.2.1      yamt #ifndef ACK_ALL
   1973  1.88.2.1      yamt 		OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_DMA_IT);
   1974  1.88.2.1      yamt #endif
   1975  1.88.2.1      yamt #if defined(__DragonFly__) || __FreeBSD_version < 500000 || defined(__NetBSD__)
   1976  1.88.2.1      yamt 		itstat = sc->itstat;
   1977  1.88.2.1      yamt 		sc->itstat = 0;
   1978  1.88.2.1      yamt #else
   1979  1.88.2.1      yamt 		itstat = atomic_readandclear_int(&sc->itstat);
   1980  1.88.2.1      yamt #endif
   1981  1.88.2.1      yamt 		for(i = 0; i < fc->nisodma ; i++){
   1982  1.88.2.1      yamt 			if((itstat & (1 << i)) != 0){
   1983  1.88.2.1      yamt 				fwohci_tbuf_update(sc, i);
   1984  1.88.2.1      yamt 			}
   1985  1.88.2.1      yamt 		}
   1986  1.88.2.1      yamt 	}
   1987  1.88.2.1      yamt 	if((stat & OHCI_INT_DMA_PRRS )){
   1988  1.88.2.1      yamt #ifndef ACK_ALL
   1989  1.88.2.1      yamt 		OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_DMA_PRRS);
   1990  1.88.2.1      yamt #endif
   1991  1.88.2.1      yamt #if 0
   1992  1.88.2.1      yamt 		dump_dma(sc, ARRS_CH);
   1993  1.88.2.1      yamt 		dump_db(sc, ARRS_CH);
   1994  1.88.2.1      yamt #endif
   1995  1.88.2.1      yamt 		fwohci_arcv(sc, &sc->arrs, count);
   1996  1.88.2.1      yamt 	}
   1997  1.88.2.1      yamt 	if((stat & OHCI_INT_DMA_PRRQ )){
   1998  1.88.2.1      yamt #ifndef ACK_ALL
   1999  1.88.2.1      yamt 		OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_DMA_PRRQ);
   2000  1.88.2.1      yamt #endif
   2001  1.88.2.1      yamt #if 0
   2002  1.88.2.1      yamt 		dump_dma(sc, ARRQ_CH);
   2003  1.88.2.1      yamt 		dump_db(sc, ARRQ_CH);
   2004  1.88.2.1      yamt #endif
   2005  1.88.2.1      yamt 		fwohci_arcv(sc, &sc->arrq, count);
   2006  1.88.2.1      yamt 	}
   2007  1.88.2.1      yamt 	if (stat & OHCI_INT_CYC_LOST) {
   2008  1.88.2.1      yamt 		if (sc->cycle_lost >= 0)
   2009  1.88.2.1      yamt 			sc->cycle_lost ++;
   2010  1.88.2.1      yamt 		if (sc->cycle_lost > 10) {
   2011  1.88.2.1      yamt 			sc->cycle_lost = -1;
   2012  1.88.2.1      yamt #if 0
   2013  1.88.2.1      yamt 			OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCTIMER);
   2014  1.88.2.1      yamt #endif
   2015  1.88.2.1      yamt 			OWRITE(sc, FWOHCI_INTMASKCLR,  OHCI_INT_CYC_LOST);
   2016  1.88.2.1      yamt 			device_printf(fc->dev, "too many cycle lost, "
   2017  1.88.2.1      yamt 			    "no cycle master presents?\n");
   2018  1.88.2.1      yamt 		}
   2019  1.88.2.1      yamt 	}
   2020  1.88.2.1      yamt 	if(stat & OHCI_INT_PHY_SID){
   2021  1.88.2.1      yamt 		uint32_t *buf, node_id;
   2022  1.88.2.1      yamt 		int plen;
   2023  1.88.2.1      yamt 
   2024  1.88.2.1      yamt #ifndef ACK_ALL
   2025  1.88.2.1      yamt 		OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_PHY_SID);
   2026  1.88.2.1      yamt #endif
   2027  1.88.2.1      yamt 		/* Enable bus reset interrupt */
   2028  1.88.2.1      yamt 		OWRITE(sc, FWOHCI_INTMASK,  OHCI_INT_PHY_BUS_R);
   2029  1.88.2.1      yamt 		/* Allow async. request to us */
   2030  1.88.2.1      yamt 		OWRITE(sc, OHCI_AREQHI, 1 << 31);
   2031  1.88.2.1      yamt 		/* XXX insecure ?? */
   2032  1.88.2.1      yamt 		/* allow from all nodes */
   2033  1.88.2.1      yamt 		OWRITE(sc, OHCI_PREQHI, 0x7fffffff);
   2034  1.88.2.1      yamt 		OWRITE(sc, OHCI_PREQLO, 0xffffffff);
   2035  1.88.2.1      yamt 		/* 0 to 4GB regison */
   2036  1.88.2.1      yamt 		OWRITE(sc, OHCI_PREQUPPER, 0x10000);
   2037  1.88.2.1      yamt 		/* Set ATRetries register */
   2038  1.88.2.1      yamt 		OWRITE(sc, OHCI_ATRETRY, 1<<(13+16) | 0xfff);
   2039  1.88.2.1      yamt /*
   2040  1.88.2.1      yamt ** Checking whether the node is root or not. If root, turn on
   2041  1.88.2.1      yamt ** cycle master.
   2042  1.88.2.1      yamt */
   2043  1.88.2.1      yamt 		node_id = OREAD(sc, FWOHCI_NODEID);
   2044  1.88.2.1      yamt 		plen = OREAD(sc, OHCI_SID_CNT);
   2045  1.88.2.1      yamt 
   2046  1.88.2.1      yamt 		device_printf(fc->dev, "node_id=0x%08x, gen=%d, ",
   2047  1.88.2.1      yamt 			node_id, (plen >> 16) & 0xff);
   2048  1.88.2.1      yamt 		if (!(node_id & OHCI_NODE_VALID)) {
   2049  1.88.2.1      yamt 			printf("Bus reset failure\n");
   2050  1.88.2.1      yamt 			goto sidout;
   2051  1.88.2.1      yamt 		}
   2052  1.88.2.1      yamt 
   2053  1.88.2.1      yamt 		/* cycle timer */
   2054  1.88.2.1      yamt 		sc->cycle_lost = 0;
   2055  1.88.2.1      yamt 		OWRITE(sc, FWOHCI_INTMASK,  OHCI_INT_CYC_LOST);
   2056  1.88.2.1      yamt 		if ((node_id & OHCI_NODE_ROOT) && !nocyclemaster) {
   2057  1.88.2.1      yamt 			printf("CYCLEMASTER mode\n");
   2058  1.88.2.1      yamt 			OWRITE(sc, OHCI_LNKCTL,
   2059  1.88.2.1      yamt 				OHCI_CNTL_CYCMTR | OHCI_CNTL_CYCTIMER);
   2060  1.88.2.1      yamt 		} else {
   2061  1.88.2.1      yamt 			printf("non CYCLEMASTER mode\n");
   2062  1.88.2.1      yamt 			OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCMTR);
   2063  1.88.2.1      yamt 			OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_CYCTIMER);
   2064  1.88.2.1      yamt 		}
   2065       1.7      onoe 
   2066  1.88.2.1      yamt 		fc->nodeid = node_id & 0x3f;
   2067       1.7      onoe 
   2068  1.88.2.1      yamt 		if (plen & OHCI_SID_ERR) {
   2069  1.88.2.1      yamt 			device_printf(fc->dev, "SID Error\n");
   2070  1.88.2.1      yamt 			goto sidout;
   2071  1.88.2.1      yamt 		}
   2072  1.88.2.1      yamt 		plen &= OHCI_SID_CNT_MASK;
   2073  1.88.2.1      yamt 		if (plen < 4 || plen > OHCI_SIDSIZE) {
   2074  1.88.2.1      yamt 			device_printf(fc->dev, "invalid SID len = %d\n", plen);
   2075  1.88.2.1      yamt 			goto sidout;
   2076  1.88.2.1      yamt 		}
   2077  1.88.2.1      yamt 		plen -= 4; /* chop control info */
   2078  1.88.2.1      yamt 		buf = (uint32_t *)malloc(OHCI_SIDSIZE, M_FW, M_NOWAIT);
   2079  1.88.2.1      yamt 		if (buf == NULL) {
   2080  1.88.2.1      yamt 			device_printf(fc->dev, "malloc failed\n");
   2081  1.88.2.1      yamt 			goto sidout;
   2082  1.88.2.1      yamt 		}
   2083  1.88.2.1      yamt 		for (i = 0; i < plen / 4; i ++)
   2084  1.88.2.1      yamt 			buf[i] = FWOHCI_DMA_READ(sc->sid_buf[i+1]);
   2085  1.88.2.1      yamt #if defined(__NetBSD__) && defined(macppc)
   2086  1.88.2.1      yamt 		/* XXX required as bootdisk for macppc. */
   2087  1.88.2.1      yamt 		delay(500000);
   2088  1.88.2.1      yamt #endif
   2089  1.88.2.1      yamt #if 1 /* XXX needed?? */
   2090  1.88.2.1      yamt 		/* pending all pre-bus_reset packets */
   2091  1.88.2.1      yamt 		fwohci_txd(sc, &sc->atrq);
   2092  1.88.2.1      yamt 		fwohci_txd(sc, &sc->atrs);
   2093  1.88.2.1      yamt 		fwohci_arcv(sc, &sc->arrs, -1);
   2094  1.88.2.1      yamt 		fwohci_arcv(sc, &sc->arrq, -1);
   2095  1.88.2.1      yamt 		fw_drain_txq(fc);
   2096  1.88.2.1      yamt #endif
   2097  1.88.2.1      yamt 		fw_sidrcv(fc, buf, plen);
   2098  1.88.2.1      yamt 		free(buf, M_FW);
   2099  1.88.2.1      yamt 	}
   2100  1.88.2.1      yamt sidout:
   2101  1.88.2.1      yamt 	if((stat & OHCI_INT_DMA_ATRQ )){
   2102  1.88.2.1      yamt #ifndef ACK_ALL
   2103  1.88.2.1      yamt 		OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_DMA_ATRQ);
   2104  1.88.2.1      yamt #endif
   2105  1.88.2.1      yamt 		fwohci_txd(sc, &(sc->atrq));
   2106  1.88.2.1      yamt 	}
   2107  1.88.2.1      yamt 	if((stat & OHCI_INT_DMA_ATRS )){
   2108  1.88.2.1      yamt #ifndef ACK_ALL
   2109  1.88.2.1      yamt 		OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_DMA_ATRS);
   2110  1.88.2.1      yamt #endif
   2111  1.88.2.1      yamt 		fwohci_txd(sc, &(sc->atrs));
   2112       1.3      onoe 	}
   2113  1.88.2.1      yamt 	if((stat & OHCI_INT_PW_ERR )){
   2114  1.88.2.1      yamt #ifndef ACK_ALL
   2115  1.88.2.1      yamt 		OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_PW_ERR);
   2116  1.88.2.1      yamt #endif
   2117  1.88.2.1      yamt 		device_printf(fc->dev, "posted write error\n");
   2118  1.88.2.1      yamt 	}
   2119  1.88.2.1      yamt 	if((stat & OHCI_INT_ERR )){
   2120  1.88.2.1      yamt #ifndef ACK_ALL
   2121  1.88.2.1      yamt 		OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_ERR);
   2122  1.88.2.1      yamt #endif
   2123  1.88.2.1      yamt 		device_printf(fc->dev, "unrecoverable error\n");
   2124  1.88.2.1      yamt 	}
   2125  1.88.2.1      yamt 	if((stat & OHCI_INT_PHY_INT)) {
   2126  1.88.2.1      yamt #ifndef ACK_ALL
   2127  1.88.2.1      yamt 		OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_PHY_INT);
   2128  1.88.2.1      yamt #endif
   2129  1.88.2.1      yamt 		device_printf(fc->dev, "phy int\n");
   2130  1.88.2.1      yamt 	}
   2131  1.88.2.1      yamt 
   2132  1.88.2.1      yamt 	CTR0(KTR_DEV, "fwohci_intr_body done");
   2133  1.88.2.1      yamt 	return;
   2134       1.3      onoe }
   2135       1.3      onoe 
   2136  1.88.2.1      yamt #if FWOHCI_TASKQUEUE
   2137       1.7      onoe static void
   2138  1.88.2.1      yamt fwohci_complete(void *arg, int pending)
   2139       1.7      onoe {
   2140  1.88.2.1      yamt 	struct fwohci_softc *sc = (struct fwohci_softc *)arg;
   2141  1.88.2.1      yamt 	uint32_t stat;
   2142       1.7      onoe 
   2143  1.88.2.1      yamt again:
   2144  1.88.2.1      yamt 	stat = atomic_readandclear_int(&sc->intstat);
   2145  1.88.2.1      yamt 	if (stat) {
   2146  1.88.2.1      yamt 		FW_LOCK;
   2147  1.88.2.1      yamt 		fwohci_intr_body(sc, stat, -1);
   2148  1.88.2.1      yamt 		FW_UNLOCK;
   2149  1.88.2.1      yamt 	} else
   2150  1.88.2.1      yamt 		return;
   2151  1.88.2.1      yamt 	goto again;
   2152       1.7      onoe }
   2153  1.88.2.1      yamt #endif
   2154       1.7      onoe 
   2155  1.88.2.1      yamt static uint32_t
   2156  1.88.2.1      yamt fwochi_check_stat(struct fwohci_softc *sc)
   2157       1.7      onoe {
   2158  1.88.2.1      yamt 	uint32_t stat, irstat, itstat;
   2159       1.7      onoe 
   2160  1.88.2.1      yamt 	stat = OREAD(sc, FWOHCI_INTSTAT);
   2161  1.88.2.1      yamt 	CTR1(KTR_DEV, "fwoch_check_stat 0x%08x", stat);
   2162  1.88.2.1      yamt 	if (stat == 0xffffffff) {
   2163  1.88.2.1      yamt 		device_printf(sc->fc.dev,
   2164  1.88.2.1      yamt 			"device physically ejected?\n");
   2165  1.88.2.1      yamt 		return(stat);
   2166       1.7      onoe 	}
   2167  1.88.2.1      yamt #ifdef ACK_ALL
   2168  1.88.2.1      yamt 	if (stat)
   2169  1.88.2.1      yamt 		OWRITE(sc, FWOHCI_INTSTATCLR, stat);
   2170       1.7      onoe #endif
   2171  1.88.2.1      yamt 	if (stat & OHCI_INT_DMA_IR) {
   2172  1.88.2.1      yamt 		irstat = OREAD(sc, OHCI_IR_STAT);
   2173  1.88.2.1      yamt 		OWRITE(sc, OHCI_IR_STATCLR, irstat);
   2174  1.88.2.1      yamt 		atomic_set_int(&sc->irstat, irstat);
   2175  1.88.2.1      yamt 	}
   2176  1.88.2.1      yamt 	if (stat & OHCI_INT_DMA_IT) {
   2177  1.88.2.1      yamt 		itstat = OREAD(sc, OHCI_IT_STAT);
   2178  1.88.2.1      yamt 		OWRITE(sc, OHCI_IT_STATCLR, itstat);
   2179  1.88.2.1      yamt 		atomic_set_int(&sc->itstat, itstat);
   2180  1.88.2.1      yamt 	}
   2181  1.88.2.1      yamt 	return(stat);
   2182       1.7      onoe }
   2183       1.7      onoe 
   2184  1.88.2.1      yamt FW_INTR(fwohci)
   2185       1.3      onoe {
   2186  1.88.2.1      yamt 	struct fwohci_softc *sc = (struct fwohci_softc *)arg;
   2187  1.88.2.1      yamt 	uint32_t stat;
   2188  1.88.2.1      yamt #if !FWOHCI_TASKQUEUE
   2189  1.88.2.1      yamt 	uint32_t bus_reset = 0;
   2190  1.88.2.1      yamt #endif
   2191       1.3      onoe 
   2192  1.88.2.1      yamt 	if (!(sc->intmask & OHCI_INT_EN)) {
   2193  1.88.2.1      yamt 		/* polling mode */
   2194  1.88.2.1      yamt 		FW_INTR_RETURN(0);
   2195       1.3      onoe 	}
   2196       1.3      onoe 
   2197  1.88.2.1      yamt #if !FWOHCI_TASKQUEUE
   2198  1.88.2.1      yamt again:
   2199  1.88.2.1      yamt #endif
   2200  1.88.2.1      yamt 	CTR0(KTR_DEV, "fwohci_intr");
   2201  1.88.2.1      yamt 	stat = fwochi_check_stat(sc);
   2202  1.88.2.1      yamt 	if (stat == 0 || stat == 0xffffffff)
   2203  1.88.2.1      yamt 		FW_INTR_RETURN(1);
   2204  1.88.2.1      yamt #if FWOHCI_TASKQUEUE
   2205  1.88.2.1      yamt 	atomic_set_int(&sc->intstat, stat);
   2206  1.88.2.1      yamt 	/* XXX mask bus reset intr. during bus reset phase */
   2207  1.88.2.1      yamt 	if (stat)
   2208  1.88.2.1      yamt #if 1
   2209  1.88.2.1      yamt 		taskqueue_enqueue_fast(taskqueue_fast,
   2210  1.88.2.1      yamt 		    &sc->fwohci_task_complete);
   2211  1.88.2.1      yamt #else
   2212  1.88.2.1      yamt 		taskqueue_enqueue(taskqueue_swi,
   2213  1.88.2.1      yamt 		    &sc->fwohci_task_complete);
   2214  1.88.2.1      yamt #endif
   2215  1.88.2.1      yamt #else
   2216  1.88.2.1      yamt 	/* We cannot clear bus reset event during bus reset phase */
   2217  1.88.2.1      yamt 	if ((stat & ~bus_reset) == 0)
   2218  1.88.2.1      yamt 		FW_INTR_RETURN(1);
   2219  1.88.2.1      yamt 	bus_reset = stat & OHCI_INT_PHY_BUS_R;
   2220  1.88.2.1      yamt 	fwohci_intr_body(sc, stat, -1);
   2221  1.88.2.1      yamt 	goto again;
   2222  1.88.2.1      yamt #endif
   2223  1.88.2.1      yamt 	CTR0(KTR_DEV, "fwohci_intr end");
   2224       1.9      onoe }
   2225       1.9      onoe 
   2226  1.88.2.1      yamt void
   2227  1.88.2.1      yamt fwohci_poll(struct firewire_comm *fc, int quick, int count)
   2228       1.9      onoe {
   2229  1.88.2.1      yamt 	int s;
   2230  1.88.2.1      yamt 	uint32_t stat;
   2231  1.88.2.1      yamt 	struct fwohci_softc *sc;
   2232       1.9      onoe 
   2233       1.9      onoe 
   2234  1.88.2.1      yamt 	sc = (struct fwohci_softc *)fc;
   2235  1.88.2.1      yamt 	stat = OHCI_INT_DMA_IR | OHCI_INT_DMA_IT |
   2236  1.88.2.1      yamt 		OHCI_INT_DMA_PRRS | OHCI_INT_DMA_PRRQ |
   2237  1.88.2.1      yamt 		OHCI_INT_DMA_ATRQ | OHCI_INT_DMA_ATRS;
   2238  1.88.2.1      yamt #if 0
   2239  1.88.2.1      yamt 	if (!quick) {
   2240  1.88.2.1      yamt #else
   2241  1.88.2.1      yamt 	if (1) {
   2242      1.40      haya #endif
   2243  1.88.2.1      yamt 		stat = fwochi_check_stat(sc);
   2244  1.88.2.1      yamt 		if (stat == 0 || stat == 0xffffffff)
   2245  1.88.2.1      yamt 			return;
   2246      1.38      onoe 	}
   2247  1.88.2.1      yamt 	s = splfw();
   2248  1.88.2.1      yamt 	fwohci_intr_body(sc, stat, count);
   2249  1.88.2.1      yamt 	splx(s);
   2250       1.3      onoe }
   2251       1.3      onoe 
   2252       1.3      onoe static void
   2253  1.88.2.1      yamt fwohci_set_intr(struct firewire_comm *fc, int enable)
   2254       1.9      onoe {
   2255  1.88.2.1      yamt 	struct fwohci_softc *sc;
   2256       1.9      onoe 
   2257  1.88.2.1      yamt 	sc = (struct fwohci_softc *)fc;
   2258  1.88.2.1      yamt 	if (firewire_debug)
   2259  1.88.2.1      yamt 		device_printf(sc->fc.dev, "fwohci_set_intr: %d\n", enable);
   2260  1.88.2.1      yamt 	if (enable) {
   2261  1.88.2.1      yamt 		sc->intmask |= OHCI_INT_EN;
   2262  1.88.2.1      yamt 		OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_EN);
   2263  1.88.2.1      yamt 	} else {
   2264  1.88.2.1      yamt 		sc->intmask &= ~OHCI_INT_EN;
   2265  1.88.2.1      yamt 		OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_EN);
   2266  1.88.2.1      yamt 	}
   2267       1.9      onoe }
   2268       1.9      onoe 
   2269       1.9      onoe static void
   2270  1.88.2.1      yamt fwohci_tbuf_update(struct fwohci_softc *sc, int dmach)
   2271  1.88.2.1      yamt {
   2272  1.88.2.1      yamt 	struct firewire_comm *fc = &sc->fc;
   2273  1.88.2.1      yamt 	struct fwohcidb *db;
   2274  1.88.2.1      yamt 	struct fw_bulkxfer *chunk;
   2275  1.88.2.1      yamt 	struct fw_xferq *it;
   2276  1.88.2.1      yamt 	uint32_t stat, count;
   2277  1.88.2.1      yamt 	int s, w=0, ldesc;
   2278  1.88.2.1      yamt 
   2279  1.88.2.1      yamt 	it = fc->it[dmach];
   2280  1.88.2.1      yamt 	ldesc = sc->it[dmach].ndesc - 1;
   2281  1.88.2.1      yamt 	s = splfw(); /* unnecessary ? */
   2282  1.88.2.1      yamt 	fwdma_sync_multiseg_all(sc->it[dmach].am, BUS_DMASYNC_POSTREAD);
   2283  1.88.2.1      yamt 	if (firewire_debug)
   2284  1.88.2.1      yamt 		dump_db(sc, ITX_CH + dmach);
   2285  1.88.2.1      yamt 	while ((chunk = STAILQ_FIRST(&it->stdma)) != NULL) {
   2286  1.88.2.1      yamt 		db = ((struct fwohcidb_tr *)(chunk->end))->db;
   2287  1.88.2.1      yamt 		stat = FWOHCI_DMA_READ(db[ldesc].db.desc.res)
   2288  1.88.2.1      yamt 				>> OHCI_STATUS_SHIFT;
   2289  1.88.2.1      yamt 		db = ((struct fwohcidb_tr *)(chunk->start))->db;
   2290  1.88.2.1      yamt 		/* timestamp */
   2291  1.88.2.1      yamt 		count = FWOHCI_DMA_READ(db[ldesc].db.desc.res)
   2292  1.88.2.1      yamt 				& OHCI_COUNT_MASK;
   2293  1.88.2.1      yamt 		if (stat == 0)
   2294  1.88.2.1      yamt 			break;
   2295  1.88.2.1      yamt 		STAILQ_REMOVE_HEAD(&it->stdma, link);
   2296  1.88.2.1      yamt 		switch (stat & FWOHCIEV_MASK){
   2297  1.88.2.1      yamt 		case FWOHCIEV_ACKCOMPL:
   2298  1.88.2.1      yamt #if 0
   2299  1.88.2.1      yamt 			device_printf(fc->dev, "0x%08x\n", count);
   2300  1.88.2.1      yamt #endif
   2301  1.88.2.1      yamt 			break;
   2302  1.88.2.1      yamt 		default:
   2303  1.88.2.1      yamt 			device_printf(fc->dev,
   2304  1.88.2.1      yamt 				"Isochronous transmit err %02x(%s)\n",
   2305  1.88.2.1      yamt 					stat, fwohcicode[stat & 0x1f]);
   2306  1.88.2.1      yamt 		}
   2307  1.88.2.1      yamt 		STAILQ_INSERT_TAIL(&it->stfree, chunk, link);
   2308  1.88.2.1      yamt 		w++;
   2309       1.9      onoe 	}
   2310  1.88.2.1      yamt 	splx(s);
   2311  1.88.2.1      yamt 	if (w)
   2312  1.88.2.1      yamt 		wakeup(it);
   2313       1.3      onoe }
   2314       1.3      onoe 
   2315  1.88.2.1      yamt static void
   2316  1.88.2.1      yamt fwohci_rbuf_update(struct fwohci_softc *sc, int dmach)
   2317       1.3      onoe {
   2318  1.88.2.1      yamt 	struct firewire_comm *fc = &sc->fc;
   2319  1.88.2.1      yamt 	struct fwohcidb_tr *db_tr;
   2320  1.88.2.1      yamt 	struct fw_bulkxfer *chunk;
   2321  1.88.2.1      yamt 	struct fw_xferq *ir;
   2322  1.88.2.1      yamt 	uint32_t stat;
   2323  1.88.2.1      yamt 	int s, w=0, ldesc;
   2324       1.3      onoe 
   2325  1.88.2.1      yamt 	ir = fc->ir[dmach];
   2326  1.88.2.1      yamt 	ldesc = sc->ir[dmach].ndesc - 1;
   2327  1.88.2.1      yamt #if 0
   2328  1.88.2.1      yamt 	dump_db(sc, dmach);
   2329  1.88.2.1      yamt #endif
   2330  1.88.2.1      yamt 	s = splfw();
   2331  1.88.2.1      yamt 	fwdma_sync_multiseg_all(sc->ir[dmach].am, BUS_DMASYNC_POSTREAD);
   2332  1.88.2.1      yamt 	while ((chunk = STAILQ_FIRST(&ir->stdma)) != NULL) {
   2333  1.88.2.1      yamt 		db_tr = (struct fwohcidb_tr *)chunk->end;
   2334  1.88.2.1      yamt 		stat = FWOHCI_DMA_READ(db_tr->db[ldesc].db.desc.res)
   2335  1.88.2.1      yamt 				>> OHCI_STATUS_SHIFT;
   2336  1.88.2.1      yamt 		if (stat == 0)
   2337  1.88.2.1      yamt 			break;
   2338       1.3      onoe 
   2339  1.88.2.1      yamt 		if (chunk->mbuf != NULL) {
   2340  1.88.2.1      yamt 			fw_bus_dmamap_sync(sc->ir[dmach].dmat, db_tr->dma_map,
   2341  1.88.2.1      yamt 						BUS_DMASYNC_POSTREAD);
   2342  1.88.2.1      yamt 			fw_bus_dmamap_unload(
   2343  1.88.2.1      yamt 				sc->ir[dmach].dmat, db_tr->dma_map);
   2344  1.88.2.1      yamt 		} else if (ir->buf != NULL) {
   2345  1.88.2.1      yamt 			fwdma_sync_multiseg(ir->buf, chunk->poffset,
   2346  1.88.2.1      yamt 				ir->bnpacket, BUS_DMASYNC_POSTREAD);
   2347  1.88.2.1      yamt 		} else {
   2348  1.88.2.1      yamt 			/* XXX */
   2349  1.88.2.1      yamt 			printf("fwohci_rbuf_update: this shouldn't happend\n");
   2350  1.88.2.1      yamt 		}
   2351       1.3      onoe 
   2352  1.88.2.1      yamt 		STAILQ_REMOVE_HEAD(&ir->stdma, link);
   2353  1.88.2.1      yamt 		STAILQ_INSERT_TAIL(&ir->stvalid, chunk, link);
   2354  1.88.2.1      yamt 		switch (stat & FWOHCIEV_MASK) {
   2355  1.88.2.1      yamt 		case FWOHCIEV_ACKCOMPL:
   2356  1.88.2.1      yamt 			chunk->resp = 0;
   2357  1.88.2.1      yamt 			break;
   2358  1.88.2.1      yamt 		default:
   2359  1.88.2.1      yamt 			chunk->resp = EINVAL;
   2360  1.88.2.1      yamt 			device_printf(fc->dev,
   2361  1.88.2.1      yamt 				"Isochronous receive err %02x(%s)\n",
   2362  1.88.2.1      yamt 					stat, fwohcicode[stat & 0x1f]);
   2363  1.88.2.1      yamt 		}
   2364  1.88.2.1      yamt 		w++;
   2365  1.88.2.1      yamt 	}
   2366  1.88.2.1      yamt 	splx(s);
   2367  1.88.2.1      yamt 	if (w) {
   2368  1.88.2.1      yamt 		if (ir->flag & FWXFERQ_HANDLER)
   2369  1.88.2.1      yamt 			ir->hand(ir);
   2370  1.88.2.1      yamt 		else
   2371  1.88.2.1      yamt 			wakeup(ir);
   2372  1.88.2.1      yamt 	}
   2373       1.3      onoe }
   2374       1.3      onoe 
   2375  1.88.2.1      yamt void
   2376  1.88.2.1      yamt dump_dma(struct fwohci_softc *sc, uint32_t ch)
   2377       1.3      onoe {
   2378  1.88.2.1      yamt 	uint32_t off, cntl, stat, cmd, match;
   2379       1.3      onoe 
   2380  1.88.2.1      yamt 	if(ch == 0){
   2381  1.88.2.1      yamt 		off = OHCI_ATQOFF;
   2382  1.88.2.1      yamt 	}else if(ch == 1){
   2383  1.88.2.1      yamt 		off = OHCI_ATSOFF;
   2384  1.88.2.1      yamt 	}else if(ch == 2){
   2385  1.88.2.1      yamt 		off = OHCI_ARQOFF;
   2386  1.88.2.1      yamt 	}else if(ch == 3){
   2387  1.88.2.1      yamt 		off = OHCI_ARSOFF;
   2388  1.88.2.1      yamt 	}else if(ch < IRX_CH){
   2389  1.88.2.1      yamt 		off = OHCI_ITCTL(ch - ITX_CH);
   2390  1.88.2.1      yamt 	}else{
   2391  1.88.2.1      yamt 		off = OHCI_IRCTL(ch - IRX_CH);
   2392  1.88.2.1      yamt 	}
   2393  1.88.2.1      yamt 	cntl = stat = OREAD(sc, off);
   2394  1.88.2.1      yamt 	cmd = OREAD(sc, off + 0xc);
   2395  1.88.2.1      yamt 	match = OREAD(sc, off + 0x10);
   2396  1.88.2.1      yamt 
   2397  1.88.2.1      yamt 	device_printf(sc->fc.dev, "ch %1x cntl:0x%08x cmd:0x%08x match:0x%08x\n",
   2398  1.88.2.1      yamt 		ch,
   2399  1.88.2.1      yamt 		cntl,
   2400  1.88.2.1      yamt 		cmd,
   2401  1.88.2.1      yamt 		match);
   2402  1.88.2.1      yamt 	stat &= 0xffff ;
   2403  1.88.2.1      yamt 	if (stat) {
   2404  1.88.2.1      yamt 		device_printf(sc->fc.dev, "dma %d ch:%s%s%s%s%s%s %s(%x)\n",
   2405  1.88.2.1      yamt 			ch,
   2406  1.88.2.1      yamt 			stat & OHCI_CNTL_DMA_RUN ? "RUN," : "",
   2407  1.88.2.1      yamt 			stat & OHCI_CNTL_DMA_WAKE ? "WAKE," : "",
   2408  1.88.2.1      yamt 			stat & OHCI_CNTL_DMA_DEAD ? "DEAD," : "",
   2409  1.88.2.1      yamt 			stat & OHCI_CNTL_DMA_ACTIVE ? "ACTIVE," : "",
   2410  1.88.2.1      yamt 			stat & OHCI_CNTL_DMA_BT ? "BRANCH," : "",
   2411  1.88.2.1      yamt 			stat & OHCI_CNTL_DMA_BAD ? "BADDMA," : "",
   2412  1.88.2.1      yamt 			fwohcicode[stat & 0x1f],
   2413  1.88.2.1      yamt 			stat & 0x1f
   2414  1.88.2.1      yamt 		);
   2415  1.88.2.1      yamt 	}else{
   2416  1.88.2.1      yamt 		device_printf(sc->fc.dev, "dma %d ch: Nostat\n", ch);
   2417  1.88.2.1      yamt 	}
   2418       1.3      onoe }
   2419       1.3      onoe 
   2420  1.88.2.1      yamt void
   2421  1.88.2.1      yamt dump_db(struct fwohci_softc *sc, uint32_t ch)
   2422       1.3      onoe {
   2423  1.88.2.1      yamt 	struct fwohci_dbch *dbch;
   2424  1.88.2.1      yamt 	struct fwohcidb_tr *cp = NULL, *pp, *np = NULL;
   2425  1.88.2.1      yamt 	struct fwohcidb *curr = NULL, *prev, *next = NULL;
   2426  1.88.2.1      yamt 	int idb, jdb;
   2427  1.88.2.1      yamt 	uint32_t cmd, off;
   2428  1.88.2.1      yamt 	if(ch == 0){
   2429  1.88.2.1      yamt 		off = OHCI_ATQOFF;
   2430  1.88.2.1      yamt 		dbch = &sc->atrq;
   2431  1.88.2.1      yamt 	}else if(ch == 1){
   2432  1.88.2.1      yamt 		off = OHCI_ATSOFF;
   2433  1.88.2.1      yamt 		dbch = &sc->atrs;
   2434  1.88.2.1      yamt 	}else if(ch == 2){
   2435  1.88.2.1      yamt 		off = OHCI_ARQOFF;
   2436  1.88.2.1      yamt 		dbch = &sc->arrq;
   2437  1.88.2.1      yamt 	}else if(ch == 3){
   2438  1.88.2.1      yamt 		off = OHCI_ARSOFF;
   2439  1.88.2.1      yamt 		dbch = &sc->arrs;
   2440  1.88.2.1      yamt 	}else if(ch < IRX_CH){
   2441  1.88.2.1      yamt 		off = OHCI_ITCTL(ch - ITX_CH);
   2442  1.88.2.1      yamt 		dbch = &sc->it[ch - ITX_CH];
   2443  1.88.2.1      yamt 	}else {
   2444  1.88.2.1      yamt 		off = OHCI_IRCTL(ch - IRX_CH);
   2445  1.88.2.1      yamt 		dbch = &sc->ir[ch - IRX_CH];
   2446  1.88.2.1      yamt 	}
   2447  1.88.2.1      yamt 	cmd = OREAD(sc, off + 0xc);
   2448       1.3      onoe 
   2449  1.88.2.1      yamt 	if( dbch->ndb == 0 ){
   2450  1.88.2.1      yamt 		device_printf(sc->fc.dev, "No DB is attached ch=%d\n", ch);
   2451  1.88.2.1      yamt 		return;
   2452  1.88.2.1      yamt 	}
   2453  1.88.2.1      yamt 	pp = dbch->top;
   2454  1.88.2.1      yamt 	prev = pp->db;
   2455  1.88.2.1      yamt 	for(idb = 0 ; idb < dbch->ndb ; idb ++ ){
   2456  1.88.2.1      yamt 		cp = STAILQ_NEXT(pp, link);
   2457  1.88.2.1      yamt 		if(cp == NULL){
   2458  1.88.2.1      yamt 			curr = NULL;
   2459  1.88.2.1      yamt 			goto outdb;
   2460  1.88.2.1      yamt 		}
   2461  1.88.2.1      yamt 		np = STAILQ_NEXT(cp, link);
   2462  1.88.2.1      yamt 		for(jdb = 0 ; jdb < dbch->ndesc ; jdb ++ ){
   2463  1.88.2.1      yamt 			if ((cmd  & 0xfffffff0) == cp->bus_addr) {
   2464  1.88.2.1      yamt 				curr = cp->db;
   2465  1.88.2.1      yamt 				if(np != NULL){
   2466  1.88.2.1      yamt 					next = np->db;
   2467  1.88.2.1      yamt 				}else{
   2468  1.88.2.1      yamt 					next = NULL;
   2469  1.88.2.1      yamt 				}
   2470  1.88.2.1      yamt 				goto outdb;
   2471  1.88.2.1      yamt 			}
   2472  1.88.2.1      yamt 		}
   2473  1.88.2.1      yamt 		pp = STAILQ_NEXT(pp, link);
   2474  1.88.2.1      yamt 		if(pp == NULL){
   2475  1.88.2.1      yamt 			curr = NULL;
   2476  1.88.2.1      yamt 			goto outdb;
   2477      1.62      haya 		}
   2478  1.88.2.1      yamt 		prev = pp->db;
   2479  1.88.2.1      yamt 	}
   2480  1.88.2.1      yamt outdb:
   2481  1.88.2.1      yamt 	if( curr != NULL){
   2482  1.88.2.1      yamt #if 0
   2483  1.88.2.1      yamt 		printf("Prev DB %d\n", ch);
   2484  1.88.2.1      yamt 		print_db(pp, prev, ch, dbch->ndesc);
   2485  1.88.2.1      yamt #endif
   2486  1.88.2.1      yamt 		printf("Current DB %d\n", ch);
   2487  1.88.2.1      yamt 		print_db(cp, curr, ch, dbch->ndesc);
   2488  1.88.2.1      yamt #if 0
   2489  1.88.2.1      yamt 		printf("Next DB %d\n", ch);
   2490  1.88.2.1      yamt 		print_db(np, next, ch, dbch->ndesc);
   2491  1.88.2.1      yamt #endif
   2492  1.88.2.1      yamt 	}else{
   2493  1.88.2.1      yamt 		printf("dbdump err ch = %d cmd = 0x%08x\n", ch, cmd);
   2494       1.7      onoe 	}
   2495  1.88.2.1      yamt 	return;
   2496       1.7      onoe }
   2497       1.7      onoe 
   2498  1.88.2.1      yamt void
   2499  1.88.2.1      yamt print_db(struct fwohcidb_tr *db_tr, struct fwohcidb *db,
   2500  1.88.2.1      yamt 		uint32_t ch, uint32_t hogemax)
   2501       1.7      onoe {
   2502  1.88.2.1      yamt 	fwohcireg_t stat;
   2503  1.88.2.1      yamt 	int i, key;
   2504  1.88.2.1      yamt 	uint32_t cmd, res;
   2505  1.88.2.1      yamt 
   2506  1.88.2.1      yamt 	if(db == NULL){
   2507  1.88.2.1      yamt 		printf("No Descriptor is found\n");
   2508  1.88.2.1      yamt 		return;
   2509  1.88.2.1      yamt 	}
   2510       1.7      onoe 
   2511  1.88.2.1      yamt 	printf("ch = %d\n%8s %s %s %s %s %4s %8s %8s %4s:%4s\n",
   2512  1.88.2.1      yamt 		ch,
   2513  1.88.2.1      yamt 		"Current",
   2514  1.88.2.1      yamt 		"OP  ",
   2515  1.88.2.1      yamt 		"KEY",
   2516  1.88.2.1      yamt 		"INT",
   2517  1.88.2.1      yamt 		"BR ",
   2518  1.88.2.1      yamt 		"len",
   2519  1.88.2.1      yamt 		"Addr",
   2520  1.88.2.1      yamt 		"Depend",
   2521  1.88.2.1      yamt 		"Stat",
   2522  1.88.2.1      yamt 		"Cnt");
   2523  1.88.2.1      yamt 	for( i = 0 ; i <= hogemax ; i ++){
   2524  1.88.2.1      yamt 		cmd = FWOHCI_DMA_READ(db[i].db.desc.cmd);
   2525  1.88.2.1      yamt 		res = FWOHCI_DMA_READ(db[i].db.desc.res);
   2526  1.88.2.1      yamt 		key = cmd & OHCI_KEY_MASK;
   2527  1.88.2.1      yamt 		stat = res >> OHCI_STATUS_SHIFT;
   2528  1.88.2.1      yamt #if defined(__DragonFly__) || \
   2529  1.88.2.1      yamt     (defined(__FreeBSD__) && __FreeBSD_version < 500000)
   2530  1.88.2.1      yamt 		printf("%08x %s %s %s %s %5d %08x %08x %04x:%04x",
   2531  1.88.2.1      yamt 				db_tr->bus_addr,
   2532  1.88.2.1      yamt #else
   2533  1.88.2.1      yamt 		printf("%08jx %s %s %s %s %5d %08x %08x %04x:%04x",
   2534  1.88.2.1      yamt 				(uintmax_t)db_tr->bus_addr,
   2535  1.88.2.1      yamt #endif
   2536  1.88.2.1      yamt 				dbcode[(cmd >> 28) & 0xf],
   2537  1.88.2.1      yamt 				dbkey[(cmd >> 24) & 0x7],
   2538  1.88.2.1      yamt 				dbcond[(cmd >> 20) & 0x3],
   2539  1.88.2.1      yamt 				dbcond[(cmd >> 18) & 0x3],
   2540  1.88.2.1      yamt 				cmd & OHCI_COUNT_MASK,
   2541  1.88.2.1      yamt 				FWOHCI_DMA_READ(db[i].db.desc.addr),
   2542  1.88.2.1      yamt 				FWOHCI_DMA_READ(db[i].db.desc.depend),
   2543  1.88.2.1      yamt 				stat,
   2544  1.88.2.1      yamt 				res & OHCI_COUNT_MASK);
   2545  1.88.2.1      yamt 		if(stat & 0xff00){
   2546  1.88.2.1      yamt 			printf(" %s%s%s%s%s%s %s(%x)\n",
   2547  1.88.2.1      yamt 				stat & OHCI_CNTL_DMA_RUN ? "RUN," : "",
   2548  1.88.2.1      yamt 				stat & OHCI_CNTL_DMA_WAKE ? "WAKE," : "",
   2549  1.88.2.1      yamt 				stat & OHCI_CNTL_DMA_DEAD ? "DEAD," : "",
   2550  1.88.2.1      yamt 				stat & OHCI_CNTL_DMA_ACTIVE ? "ACTIVE," : "",
   2551  1.88.2.1      yamt 				stat & OHCI_CNTL_DMA_BT ? "BRANCH," : "",
   2552  1.88.2.1      yamt 				stat & OHCI_CNTL_DMA_BAD ? "BADDMA," : "",
   2553  1.88.2.1      yamt 				fwohcicode[stat & 0x1f],
   2554  1.88.2.1      yamt 				stat & 0x1f
   2555  1.88.2.1      yamt 			);
   2556  1.88.2.1      yamt 		}else{
   2557  1.88.2.1      yamt 			printf(" Nostat\n");
   2558  1.88.2.1      yamt 		}
   2559  1.88.2.1      yamt 		if(key == OHCI_KEY_ST2 ){
   2560  1.88.2.1      yamt 			printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
   2561  1.88.2.1      yamt 				FWOHCI_DMA_READ(db[i+1].db.immed[0]),
   2562  1.88.2.1      yamt 				FWOHCI_DMA_READ(db[i+1].db.immed[1]),
   2563  1.88.2.1      yamt 				FWOHCI_DMA_READ(db[i+1].db.immed[2]),
   2564  1.88.2.1      yamt 				FWOHCI_DMA_READ(db[i+1].db.immed[3]));
   2565  1.88.2.1      yamt 		}
   2566  1.88.2.1      yamt 		if(key == OHCI_KEY_DEVICE){
   2567  1.88.2.1      yamt 			return;
   2568  1.88.2.1      yamt 		}
   2569  1.88.2.1      yamt 		if((cmd & OHCI_BRANCH_MASK)
   2570  1.88.2.1      yamt 				== OHCI_BRANCH_ALWAYS){
   2571  1.88.2.1      yamt 			return;
   2572  1.88.2.1      yamt 		}
   2573  1.88.2.1      yamt 		if((cmd & OHCI_CMD_MASK)
   2574  1.88.2.1      yamt 				== OHCI_OUTPUT_LAST){
   2575  1.88.2.1      yamt 			return;
   2576  1.88.2.1      yamt 		}
   2577  1.88.2.1      yamt 		if((cmd & OHCI_CMD_MASK)
   2578  1.88.2.1      yamt 				== OHCI_INPUT_LAST){
   2579  1.88.2.1      yamt 			return;
   2580  1.88.2.1      yamt 		}
   2581  1.88.2.1      yamt 		if(key == OHCI_KEY_ST2 ){
   2582  1.88.2.1      yamt 			i++;
   2583      1.62      haya 		}
   2584       1.3      onoe 	}
   2585  1.88.2.1      yamt 	return;
   2586       1.3      onoe }
   2587       1.3      onoe 
   2588  1.88.2.1      yamt void
   2589  1.88.2.1      yamt fwohci_ibr(struct firewire_comm *fc)
   2590       1.7      onoe {
   2591  1.88.2.1      yamt 	struct fwohci_softc *sc;
   2592  1.88.2.1      yamt 	uint32_t fun;
   2593       1.7      onoe 
   2594  1.88.2.1      yamt 	device_printf(fc->dev, "Initiate bus reset\n");
   2595  1.88.2.1      yamt 	sc = (struct fwohci_softc *)fc;
   2596       1.7      onoe 
   2597       1.7      onoe 	/*
   2598  1.88.2.1      yamt 	 * Make sure our cached values from the config rom are
   2599  1.88.2.1      yamt 	 * initialised.
   2600       1.7      onoe 	 */
   2601  1.88.2.1      yamt 	OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0]));
   2602  1.88.2.1      yamt 	OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2]));
   2603      1.36      onoe 
   2604      1.36      onoe 	/*
   2605  1.88.2.1      yamt 	 * Set root hold-off bit so that non cyclemaster capable node
   2606  1.88.2.1      yamt 	 * shouldn't became the root node.
   2607      1.36      onoe 	 */
   2608  1.88.2.1      yamt #if 1
   2609  1.88.2.1      yamt 	fun = fwphy_rddata(sc, FW_PHY_IBR_REG);
   2610  1.88.2.1      yamt 	fun |= FW_PHY_IBR | FW_PHY_RHB;
   2611  1.88.2.1      yamt 	fun = fwphy_wrdata(sc, FW_PHY_IBR_REG, fun);
   2612  1.88.2.1      yamt #else	/* Short bus reset */
   2613  1.88.2.1      yamt 	fun = fwphy_rddata(sc, FW_PHY_ISBR_REG);
   2614  1.88.2.1      yamt 	fun |= FW_PHY_ISBR | FW_PHY_RHB;
   2615  1.88.2.1      yamt 	fun = fwphy_wrdata(sc, FW_PHY_ISBR_REG, fun);
   2616  1.88.2.1      yamt #endif
   2617      1.36      onoe }
   2618      1.36      onoe 
   2619  1.88.2.1      yamt void
   2620  1.88.2.1      yamt fwohci_txbufdb(struct fwohci_softc *sc, int dmach, struct fw_bulkxfer *bulkxfer)
   2621      1.36      onoe {
   2622  1.88.2.1      yamt 	struct fwohcidb_tr *db_tr, *fdb_tr;
   2623  1.88.2.1      yamt 	struct fwohci_dbch *dbch;
   2624  1.88.2.1      yamt 	struct fwohcidb *db;
   2625  1.88.2.1      yamt 	struct fw_pkt *fp;
   2626  1.88.2.1      yamt 	struct fwohci_txpkthdr *ohcifp;
   2627  1.88.2.1      yamt 	unsigned short chtag;
   2628  1.88.2.1      yamt 	int idb;
   2629  1.88.2.1      yamt 
   2630  1.88.2.1      yamt 	dbch = &sc->it[dmach];
   2631  1.88.2.1      yamt 	chtag = sc->it[dmach].xferq.flag & 0xff;
   2632  1.88.2.1      yamt 
   2633  1.88.2.1      yamt 	db_tr = (struct fwohcidb_tr *)(bulkxfer->start);
   2634  1.88.2.1      yamt 	fdb_tr = (struct fwohcidb_tr *)(bulkxfer->end);
   2635  1.88.2.1      yamt /*
   2636  1.88.2.1      yamt device_printf(sc->fc.dev, "DB %08x %08x %08x\n", bulkxfer, db_tr->bus_addr, fdb_tr->bus_addr);
   2637  1.88.2.1      yamt */
   2638  1.88.2.1      yamt 	for (idb = 0; idb < dbch->xferq.bnpacket; idb ++) {
   2639  1.88.2.1      yamt 		db = db_tr->db;
   2640  1.88.2.1      yamt 		fp = (struct fw_pkt *)db_tr->buf;
   2641  1.88.2.1      yamt 		ohcifp = (struct fwohci_txpkthdr *) db[1].db.immed;
   2642  1.88.2.1      yamt 		ohcifp->mode.ld[0] = fp->mode.ld[0];
   2643  1.88.2.1      yamt 		ohcifp->mode.common.spd = 0 & 0x7;
   2644  1.88.2.1      yamt 		ohcifp->mode.stream.len = fp->mode.stream.len;
   2645  1.88.2.1      yamt 		ohcifp->mode.stream.chtag = chtag;
   2646  1.88.2.1      yamt 		ohcifp->mode.stream.tcode = 0xa;
   2647  1.88.2.1      yamt #if BYTE_ORDER == BIG_ENDIAN
   2648  1.88.2.1      yamt 		FWOHCI_DMA_WRITE(db[1].db.immed[0], db[1].db.immed[0]);
   2649  1.88.2.1      yamt 		FWOHCI_DMA_WRITE(db[1].db.immed[1], db[1].db.immed[1]);
   2650  1.88.2.1      yamt #endif
   2651      1.36      onoe 
   2652  1.88.2.1      yamt 		FWOHCI_DMA_CLEAR(db[2].db.desc.cmd, OHCI_COUNT_MASK);
   2653  1.88.2.1      yamt 		FWOHCI_DMA_SET(db[2].db.desc.cmd, fp->mode.stream.len);
   2654  1.88.2.1      yamt 		FWOHCI_DMA_WRITE(db[2].db.desc.res, 0);
   2655  1.88.2.1      yamt #if 0 /* if bulkxfer->npackets changes */
   2656  1.88.2.1      yamt 		db[2].db.desc.cmd = OHCI_OUTPUT_LAST
   2657  1.88.2.1      yamt 			| OHCI_UPDATE
   2658  1.88.2.1      yamt 			| OHCI_BRANCH_ALWAYS;
   2659  1.88.2.1      yamt 		db[0].db.desc.depend =
   2660  1.88.2.1      yamt 			= db[dbch->ndesc - 1].db.desc.depend
   2661  1.88.2.1      yamt 			= STAILQ_NEXT(db_tr, link)->bus_addr | dbch->ndesc;
   2662  1.88.2.1      yamt #else
   2663  1.88.2.1      yamt 		FWOHCI_DMA_SET(db[0].db.desc.depend, dbch->ndesc);
   2664  1.88.2.1      yamt 		FWOHCI_DMA_SET(db[dbch->ndesc - 1].db.desc.depend, dbch->ndesc);
   2665  1.88.2.1      yamt #endif
   2666  1.88.2.3      yamt 		bulkxfer->end = (void *)db_tr;
   2667  1.88.2.1      yamt 		db_tr = STAILQ_NEXT(db_tr, link);
   2668      1.36      onoe 	}
   2669  1.88.2.1      yamt 	db = ((struct fwohcidb_tr *)bulkxfer->end)->db;
   2670  1.88.2.1      yamt 	FWOHCI_DMA_CLEAR(db[0].db.desc.depend, 0xf);
   2671  1.88.2.1      yamt 	FWOHCI_DMA_CLEAR(db[dbch->ndesc - 1].db.desc.depend, 0xf);
   2672  1.88.2.1      yamt #if 0 /* if bulkxfer->npackets changes */
   2673  1.88.2.1      yamt 	db[dbch->ndesc - 1].db.desc.control |= OHCI_INTERRUPT_ALWAYS;
   2674  1.88.2.1      yamt 	/* OHCI 1.1 and above */
   2675  1.88.2.1      yamt 	db[0].db.desc.control |= OHCI_INTERRUPT_ALWAYS;
   2676  1.88.2.1      yamt #endif
   2677  1.88.2.1      yamt /*
   2678  1.88.2.1      yamt 	db_tr = (struct fwohcidb_tr *)bulkxfer->start;
   2679  1.88.2.1      yamt 	fdb_tr = (struct fwohcidb_tr *)bulkxfer->end;
   2680  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);
   2681  1.88.2.1      yamt */
   2682  1.88.2.1      yamt 	return;
   2683       1.7      onoe }
   2684       1.7      onoe 
   2685  1.88.2.1      yamt static int
   2686  1.88.2.1      yamt fwohci_add_tx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr,
   2687  1.88.2.1      yamt 								int poffset)
   2688       1.3      onoe {
   2689  1.88.2.1      yamt 	struct fwohcidb *db = db_tr->db;
   2690  1.88.2.1      yamt 	struct fw_xferq *it;
   2691  1.88.2.1      yamt 	int err = 0;
   2692       1.3      onoe 
   2693  1.88.2.1      yamt 	it = &dbch->xferq;
   2694  1.88.2.1      yamt 	if(it->buf == 0){
   2695  1.88.2.1      yamt 		err = EINVAL;
   2696  1.88.2.1      yamt 		return err;
   2697  1.88.2.1      yamt 	}
   2698  1.88.2.1      yamt 	db_tr->buf = fwdma_v_addr(it->buf, poffset);
   2699  1.88.2.1      yamt 	db_tr->dbcnt = 3;
   2700  1.88.2.1      yamt 
   2701  1.88.2.1      yamt 	FWOHCI_DMA_WRITE(db[0].db.desc.cmd,
   2702  1.88.2.1      yamt 		OHCI_OUTPUT_MORE | OHCI_KEY_ST2 | 8);
   2703  1.88.2.1      yamt 	FWOHCI_DMA_WRITE(db[0].db.desc.addr, 0);
   2704  1.88.2.1      yamt 	bzero((void *)&db[1].db.immed[0], sizeof(db[1].db.immed));
   2705  1.88.2.1      yamt 	FWOHCI_DMA_WRITE(db[2].db.desc.addr,
   2706  1.88.2.1      yamt 	    fwdma_bus_addr(it->buf, poffset) + sizeof(uint32_t));
   2707  1.88.2.1      yamt 
   2708  1.88.2.1      yamt 	FWOHCI_DMA_WRITE(db[2].db.desc.cmd,
   2709  1.88.2.1      yamt 		OHCI_OUTPUT_LAST | OHCI_UPDATE | OHCI_BRANCH_ALWAYS);
   2710  1.88.2.1      yamt #if 1
   2711  1.88.2.1      yamt 	FWOHCI_DMA_WRITE(db[0].db.desc.res, 0);
   2712  1.88.2.1      yamt 	FWOHCI_DMA_WRITE(db[2].db.desc.res, 0);
   2713      1.40      haya #endif
   2714  1.88.2.1      yamt 	return 0;
   2715      1.62      haya }
   2716      1.62      haya 
   2717      1.62      haya int
   2718  1.88.2.1      yamt fwohci_add_rx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr,
   2719  1.88.2.1      yamt 		int poffset, struct fwdma_alloc *dummy_dma)
   2720      1.62      haya {
   2721  1.88.2.1      yamt 	struct fwohcidb *db = db_tr->db;
   2722  1.88.2.1      yamt 	struct fw_xferq *ir;
   2723  1.88.2.1      yamt 	int i, ldesc;
   2724  1.88.2.1      yamt 	bus_addr_t dbuf[2];
   2725  1.88.2.1      yamt 	int dsiz[2];
   2726      1.62      haya 
   2727  1.88.2.1      yamt 	ir = &dbch->xferq;
   2728  1.88.2.2      yamt 	if (ir->buf == NULL && (dbch->xferq.flag & FWXFERQ_EXTBUF) == 0) {
   2729  1.88.2.2      yamt 		if (db_tr->buf == NULL)
   2730  1.88.2.2      yamt 			db_tr->buf = fwdma_malloc_size(
   2731  1.88.2.2      yamt 			    dbch->dmat, &db_tr->dma_map,
   2732  1.88.2.2      yamt 			    ir->psize, &dbuf[0], BUS_DMA_NOWAIT);
   2733  1.88.2.1      yamt 		if (db_tr->buf == NULL)
   2734  1.88.2.1      yamt 			return(ENOMEM);
   2735  1.88.2.1      yamt 		db_tr->dbcnt = 1;
   2736  1.88.2.1      yamt 		dsiz[0] = ir->psize;
   2737  1.88.2.1      yamt 		fw_bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
   2738  1.88.2.1      yamt 			BUS_DMASYNC_PREREAD);
   2739      1.62      haya 	} else {
   2740  1.88.2.1      yamt 		db_tr->dbcnt = 0;
   2741  1.88.2.1      yamt 		if (dummy_dma != NULL) {
   2742  1.88.2.1      yamt 			dsiz[db_tr->dbcnt] = sizeof(uint32_t);
   2743  1.88.2.1      yamt 			dbuf[db_tr->dbcnt++] = dummy_dma->bus_addr;
   2744      1.62      haya 		}
   2745  1.88.2.1      yamt 		dsiz[db_tr->dbcnt] = ir->psize;
   2746  1.88.2.2      yamt 		if (ir->buf != NULL) {
   2747  1.88.2.1      yamt 			db_tr->buf = fwdma_v_addr(ir->buf, poffset);
   2748  1.88.2.1      yamt 			dbuf[db_tr->dbcnt] = fwdma_bus_addr( ir->buf, poffset);
   2749      1.62      haya 		}
   2750  1.88.2.1      yamt 		db_tr->dbcnt++;
   2751      1.62      haya 	}
   2752  1.88.2.1      yamt 	for(i = 0 ; i < db_tr->dbcnt ; i++){
   2753  1.88.2.1      yamt 		FWOHCI_DMA_WRITE(db[i].db.desc.addr, dbuf[i]);
   2754  1.88.2.1      yamt 		FWOHCI_DMA_WRITE(db[i].db.desc.cmd, OHCI_INPUT_MORE | dsiz[i]);
   2755  1.88.2.1      yamt 		if (ir->flag & FWXFERQ_STREAM) {
   2756  1.88.2.1      yamt 			FWOHCI_DMA_SET(db[i].db.desc.cmd, OHCI_UPDATE);
   2757      1.62      haya 		}
   2758  1.88.2.1      yamt 		FWOHCI_DMA_WRITE(db[i].db.desc.res, dsiz[i]);
   2759      1.62      haya 	}
   2760  1.88.2.1      yamt 	ldesc = db_tr->dbcnt - 1;
   2761  1.88.2.1      yamt 	if (ir->flag & FWXFERQ_STREAM) {
   2762  1.88.2.1      yamt 		FWOHCI_DMA_SET(db[ldesc].db.desc.cmd, OHCI_INPUT_LAST);
   2763      1.62      haya 	}
   2764  1.88.2.1      yamt 	FWOHCI_DMA_SET(db[ldesc].db.desc.cmd, OHCI_BRANCH_ALWAYS);
   2765  1.88.2.1      yamt 	return 0;
   2766  1.88.2.1      yamt }
   2767      1.62      haya 
   2768      1.62      haya 
   2769  1.88.2.1      yamt static int
   2770  1.88.2.1      yamt fwohci_arcv_swap(struct fw_pkt *fp, int len)
   2771  1.88.2.1      yamt {
   2772  1.88.2.1      yamt 	struct fw_pkt *fp0;
   2773  1.88.2.1      yamt 	uint32_t ld0;
   2774  1.88.2.1      yamt 	int slen, hlen;
   2775  1.88.2.1      yamt #if BYTE_ORDER == BIG_ENDIAN
   2776  1.88.2.1      yamt 	int i;
   2777      1.62      haya #endif
   2778      1.62      haya 
   2779  1.88.2.1      yamt 	ld0 = FWOHCI_DMA_READ(fp->mode.ld[0]);
   2780  1.88.2.1      yamt #if 0
   2781  1.88.2.1      yamt 	printf("ld0: x%08x\n", ld0);
   2782      1.62      haya #endif
   2783  1.88.2.1      yamt 	fp0 = (struct fw_pkt *)&ld0;
   2784  1.88.2.1      yamt 	/* determine length to swap */
   2785  1.88.2.1      yamt 	switch (fp0->mode.common.tcode) {
   2786  1.88.2.1      yamt 	case FWTCODE_WRES:
   2787  1.88.2.1      yamt 		CTR0(KTR_DEV, "WRES");
   2788  1.88.2.1      yamt 	case FWTCODE_RREQQ:
   2789  1.88.2.1      yamt 	case FWTCODE_WREQQ:
   2790  1.88.2.1      yamt 	case FWTCODE_RRESQ:
   2791  1.88.2.1      yamt 	case FWOHCITCODE_PHY:
   2792  1.88.2.1      yamt 		slen = 12;
   2793  1.88.2.1      yamt 		break;
   2794  1.88.2.1      yamt 	case FWTCODE_RREQB:
   2795  1.88.2.1      yamt 	case FWTCODE_WREQB:
   2796  1.88.2.1      yamt 	case FWTCODE_LREQ:
   2797  1.88.2.1      yamt 	case FWTCODE_RRESB:
   2798  1.88.2.1      yamt 	case FWTCODE_LRES:
   2799  1.88.2.1      yamt 		slen = 16;
   2800  1.88.2.1      yamt 		break;
   2801  1.88.2.1      yamt 	default:
   2802  1.88.2.1      yamt 		printf("Unknown tcode %d\n", fp0->mode.common.tcode);
   2803  1.88.2.1      yamt 		return(0);
   2804      1.62      haya 	}
   2805  1.88.2.1      yamt 	hlen = tinfo[fp0->mode.common.tcode].hdr_len;
   2806  1.88.2.1      yamt 	if (hlen > len) {
   2807  1.88.2.1      yamt 		if (firewire_debug)
   2808  1.88.2.1      yamt 			printf("splitted header\n");
   2809  1.88.2.1      yamt 		return(-hlen);
   2810      1.62      haya 	}
   2811  1.88.2.1      yamt #if BYTE_ORDER == BIG_ENDIAN
   2812  1.88.2.1      yamt 	for(i = 0; i < slen/4; i ++)
   2813  1.88.2.1      yamt 		fp->mode.ld[i] = FWOHCI_DMA_READ(fp->mode.ld[i]);
   2814      1.62      haya #endif
   2815  1.88.2.1      yamt 	return(hlen);
   2816      1.62      haya }
   2817      1.62      haya 
   2818      1.62      haya static int
   2819  1.88.2.1      yamt fwohci_get_plen(struct fwohci_softc *sc, struct fwohci_dbch *dbch, struct fw_pkt *fp)
   2820      1.62      haya {
   2821  1.88.2.1      yamt 	const struct tcode_info *info;
   2822  1.88.2.1      yamt 	int r;
   2823      1.62      haya 
   2824  1.88.2.1      yamt 	info = &tinfo[fp->mode.common.tcode];
   2825  1.88.2.1      yamt 	r = info->hdr_len + sizeof(uint32_t);
   2826  1.88.2.1      yamt 	if ((info->flag & FWTI_BLOCK_ASY) != 0)
   2827  1.88.2.1      yamt 		r += roundup2(fp->mode.wreqb.len, sizeof(uint32_t));
   2828      1.62      haya 
   2829  1.88.2.1      yamt 	if (r == sizeof(uint32_t)) {
   2830  1.88.2.1      yamt 		/* XXX */
   2831  1.88.2.1      yamt 		device_printf(sc->fc.dev, "Unknown tcode %d\n",
   2832  1.88.2.1      yamt 						fp->mode.common.tcode);
   2833  1.88.2.1      yamt 		return (-1);
   2834      1.62      haya 	}
   2835      1.62      haya 
   2836  1.88.2.1      yamt 	if (r > dbch->xferq.psize) {
   2837  1.88.2.1      yamt 		device_printf(sc->fc.dev, "Invalid packet length %d\n", r);
   2838  1.88.2.1      yamt 		return (-1);
   2839  1.88.2.1      yamt 		/* panic ? */
   2840      1.62      haya 	}
   2841      1.62      haya 
   2842  1.88.2.1      yamt 	return r;
   2843      1.62      haya }
   2844      1.62      haya 
   2845      1.62      haya static void
   2846  1.88.2.1      yamt fwohci_arcv_free_buf(struct fwohci_softc *sc, struct fwohci_dbch *dbch,
   2847  1.88.2.1      yamt     struct fwohcidb_tr *db_tr, uint32_t off, int wake)
   2848      1.62      haya {
   2849  1.88.2.1      yamt 	struct fwohcidb *db = &db_tr->db[0];
   2850      1.62      haya 
   2851  1.88.2.1      yamt 	FWOHCI_DMA_CLEAR(db->db.desc.depend, 0xf);
   2852  1.88.2.1      yamt 	FWOHCI_DMA_WRITE(db->db.desc.res, dbch->xferq.psize);
   2853  1.88.2.1      yamt 	FWOHCI_DMA_SET(dbch->bottom->db[0].db.desc.depend, 1);
   2854  1.88.2.1      yamt 	fwdma_sync_multiseg_all(dbch->am,
   2855  1.88.2.1      yamt 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   2856  1.88.2.1      yamt 	dbch->bottom = db_tr;
   2857      1.62      haya 
   2858  1.88.2.1      yamt 	if (wake)
   2859  1.88.2.1      yamt 		OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_WAKE);
   2860      1.62      haya }
   2861      1.62      haya 
   2862  1.88.2.1      yamt static void
   2863  1.88.2.1      yamt fwohci_arcv(struct fwohci_softc *sc, struct fwohci_dbch *dbch, int count)
   2864      1.62      haya {
   2865  1.88.2.1      yamt 	struct fwohcidb_tr *db_tr;
   2866  1.88.2.1      yamt 	struct iovec vec[2];
   2867  1.88.2.1      yamt 	struct fw_pkt pktbuf;
   2868  1.88.2.1      yamt 	int nvec;
   2869  1.88.2.1      yamt 	struct fw_pkt *fp;
   2870  1.88.2.1      yamt 	uint8_t *ld;
   2871  1.88.2.1      yamt 	uint32_t stat, off, status, event;
   2872  1.88.2.1      yamt 	u_int spd;
   2873  1.88.2.1      yamt 	int len, plen, hlen, pcnt, offset;
   2874  1.88.2.1      yamt 	int s;
   2875  1.88.2.3      yamt 	void *buf;
   2876  1.88.2.1      yamt 	int resCount;
   2877      1.62      haya 
   2878  1.88.2.1      yamt 	CTR0(KTR_DEV, "fwohci_arv");
   2879      1.62      haya 
   2880  1.88.2.1      yamt 	if(&sc->arrq == dbch){
   2881  1.88.2.1      yamt 		off = OHCI_ARQOFF;
   2882  1.88.2.1      yamt 	}else if(&sc->arrs == dbch){
   2883  1.88.2.1      yamt 		off = OHCI_ARSOFF;
   2884  1.88.2.1      yamt 	}else{
   2885  1.88.2.1      yamt 		return;
   2886      1.62      haya 	}
   2887      1.62      haya 
   2888  1.88.2.1      yamt 	s = splfw();
   2889  1.88.2.1      yamt 	db_tr = dbch->top;
   2890  1.88.2.1      yamt 	pcnt = 0;
   2891  1.88.2.1      yamt 	/* XXX we cannot handle a packet which lies in more than two buf */
   2892  1.88.2.1      yamt 	fwdma_sync_multiseg_all(dbch->am,
   2893  1.88.2.1      yamt 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
   2894  1.88.2.1      yamt 	status = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res) >> OHCI_STATUS_SHIFT;
   2895  1.88.2.1      yamt 	resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res) & OHCI_COUNT_MASK;
   2896  1.88.2.1      yamt 	while (status & OHCI_CNTL_DMA_ACTIVE) {
   2897  1.88.2.1      yamt #if 0
   2898      1.62      haya 
   2899  1.88.2.1      yamt 		if (off == OHCI_ARQOFF)
   2900  1.88.2.1      yamt 			printf("buf 0x%08x, status 0x%04x, resCount 0x%04x\n",
   2901  1.88.2.1      yamt 			    db_tr->bus_addr, status, resCount);
   2902  1.88.2.1      yamt #endif
   2903  1.88.2.1      yamt 		len = dbch->xferq.psize - resCount;
   2904  1.88.2.1      yamt 		ld = (uint8_t *)db_tr->buf;
   2905  1.88.2.1      yamt 		if (dbch->pdb_tr == NULL) {
   2906  1.88.2.1      yamt 			len -= dbch->buf_offset;
   2907  1.88.2.1      yamt 			ld += dbch->buf_offset;
   2908  1.88.2.1      yamt 		}
   2909  1.88.2.1      yamt 		if (len > 0)
   2910  1.88.2.1      yamt 			fw_bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
   2911  1.88.2.1      yamt 					BUS_DMASYNC_POSTREAD);
   2912  1.88.2.1      yamt 		while (len > 0 ) {
   2913  1.88.2.1      yamt 			if (count >= 0 && count-- == 0)
   2914  1.88.2.1      yamt 				goto out;
   2915  1.88.2.1      yamt 			if(dbch->pdb_tr != NULL){
   2916  1.88.2.1      yamt 				/* we have a fragment in previous buffer */
   2917  1.88.2.1      yamt 				int rlen;
   2918  1.88.2.1      yamt 
   2919  1.88.2.1      yamt 				offset = dbch->buf_offset;
   2920  1.88.2.1      yamt 				if (offset < 0)
   2921  1.88.2.1      yamt 					offset = - offset;
   2922  1.88.2.3      yamt 				buf = (char *)dbch->pdb_tr->buf + offset;
   2923  1.88.2.1      yamt 				rlen = dbch->xferq.psize - offset;
   2924  1.88.2.1      yamt 				if (firewire_debug)
   2925  1.88.2.1      yamt 					printf("rlen=%d, offset=%d\n",
   2926  1.88.2.1      yamt 						rlen, dbch->buf_offset);
   2927  1.88.2.1      yamt 				if (dbch->buf_offset < 0) {
   2928  1.88.2.1      yamt 					/* splitted in header, pull up */
   2929  1.88.2.1      yamt 					char *p;
   2930  1.88.2.1      yamt 
   2931  1.88.2.1      yamt 					p = (char *)&pktbuf;
   2932  1.88.2.1      yamt 					bcopy(buf, p, rlen);
   2933  1.88.2.1      yamt 					p += rlen;
   2934  1.88.2.1      yamt 					/* this must be too long but harmless */
   2935  1.88.2.1      yamt 					rlen = sizeof(pktbuf) - rlen;
   2936  1.88.2.1      yamt 					if (rlen < 0)
   2937  1.88.2.1      yamt 						printf("why rlen < 0\n");
   2938  1.88.2.1      yamt 					bcopy(db_tr->buf, p, rlen);
   2939  1.88.2.1      yamt 					ld += rlen;
   2940  1.88.2.1      yamt 					len -= rlen;
   2941  1.88.2.1      yamt 					hlen = fwohci_arcv_swap(&pktbuf, sizeof(pktbuf));
   2942  1.88.2.1      yamt 					if (hlen <= 0) {
   2943  1.88.2.1      yamt 						printf("hlen < 0 shouldn't happen");
   2944  1.88.2.1      yamt 						goto err;
   2945  1.88.2.1      yamt 					}
   2946  1.88.2.1      yamt 					offset = sizeof(pktbuf);
   2947  1.88.2.1      yamt 					vec[0].iov_base = (char *)&pktbuf;
   2948  1.88.2.1      yamt 					vec[0].iov_len = offset;
   2949  1.88.2.1      yamt 				} else {
   2950  1.88.2.1      yamt 					/* splitted in payload */
   2951  1.88.2.1      yamt 					offset = rlen;
   2952  1.88.2.1      yamt 					vec[0].iov_base = buf;
   2953  1.88.2.1      yamt 					vec[0].iov_len = rlen;
   2954  1.88.2.1      yamt 				}
   2955  1.88.2.1      yamt 				fp=(struct fw_pkt *)vec[0].iov_base;
   2956  1.88.2.1      yamt 				nvec = 1;
   2957  1.88.2.1      yamt 			} else {
   2958  1.88.2.1      yamt 				/* no fragment in previous buffer */
   2959  1.88.2.1      yamt 				fp=(struct fw_pkt *)ld;
   2960  1.88.2.1      yamt 				hlen = fwohci_arcv_swap(fp, len);
   2961  1.88.2.1      yamt 				if (hlen == 0)
   2962  1.88.2.1      yamt 					goto err;
   2963  1.88.2.1      yamt 				if (hlen < 0) {
   2964  1.88.2.1      yamt 					dbch->pdb_tr = db_tr;
   2965  1.88.2.1      yamt 					dbch->buf_offset = - dbch->buf_offset;
   2966  1.88.2.1      yamt 					/* sanity check */
   2967  1.88.2.1      yamt 					if (resCount != 0)  {
   2968  1.88.2.1      yamt 						printf("resCount=%d hlen=%d\n",
   2969  1.88.2.1      yamt 						    resCount, hlen);
   2970  1.88.2.1      yamt 						goto err;
   2971  1.88.2.1      yamt 					}
   2972  1.88.2.1      yamt 					goto out;
   2973      1.62      haya 				}
   2974  1.88.2.1      yamt 				offset = 0;
   2975  1.88.2.1      yamt 				nvec = 0;
   2976  1.88.2.1      yamt 			}
   2977  1.88.2.1      yamt 			plen = fwohci_get_plen(sc, dbch, fp) - offset;
   2978  1.88.2.1      yamt 			if (plen < 0) {
   2979  1.88.2.1      yamt 				/* minimum header size + trailer
   2980  1.88.2.1      yamt 				= sizeof(fw_pkt) so this shouldn't happens */
   2981  1.88.2.1      yamt 				printf("plen(%d) is negative! offset=%d\n",
   2982  1.88.2.1      yamt 				    plen, offset);
   2983  1.88.2.1      yamt 				goto err;
   2984  1.88.2.1      yamt 			}
   2985  1.88.2.1      yamt 			if (plen > 0) {
   2986  1.88.2.1      yamt 				len -= plen;
   2987  1.88.2.1      yamt 				if (len < 0) {
   2988  1.88.2.1      yamt 					dbch->pdb_tr = db_tr;
   2989  1.88.2.1      yamt 					if (firewire_debug)
   2990  1.88.2.1      yamt 						printf("splitted payload\n");
   2991  1.88.2.1      yamt 					/* sanity check */
   2992  1.88.2.1      yamt 					if (resCount != 0)  {
   2993  1.88.2.1      yamt 						printf("resCount=%d plen=%d"
   2994  1.88.2.1      yamt 						    " len=%d\n",
   2995  1.88.2.1      yamt 						    resCount, plen, len);
   2996  1.88.2.1      yamt 						goto err;
   2997  1.88.2.1      yamt 					}
   2998  1.88.2.1      yamt 					goto out;
   2999  1.88.2.1      yamt 				}
   3000  1.88.2.1      yamt 				vec[nvec].iov_base = ld;
   3001  1.88.2.1      yamt 				vec[nvec].iov_len = plen;
   3002  1.88.2.1      yamt 				nvec ++;
   3003  1.88.2.1      yamt 				ld += plen;
   3004  1.88.2.1      yamt 			}
   3005  1.88.2.1      yamt 			dbch->buf_offset = ld - (uint8_t *)db_tr->buf;
   3006  1.88.2.1      yamt 			if (nvec == 0)
   3007  1.88.2.1      yamt 				printf("nvec == 0\n");
   3008  1.88.2.1      yamt 
   3009  1.88.2.1      yamt /* DMA result-code will be written at the tail of packet */
   3010  1.88.2.1      yamt 			stat = FWOHCI_DMA_READ(*(uint32_t *)(ld - sizeof(struct fwohci_trailer)));
   3011  1.88.2.1      yamt #if 0
   3012  1.88.2.1      yamt 			printf("plen: %d, stat %x\n",
   3013  1.88.2.1      yamt 			    plen ,stat);
   3014  1.88.2.1      yamt #endif
   3015  1.88.2.1      yamt 			spd = (stat >> 21) & 0x3;
   3016  1.88.2.1      yamt 			event = (stat >> 16) & 0x1f;
   3017  1.88.2.1      yamt 			switch (event) {
   3018  1.88.2.1      yamt 			case FWOHCIEV_ACKPEND:
   3019  1.88.2.1      yamt #if 0
   3020  1.88.2.1      yamt 				printf("fwohci_arcv: ack pending tcode=0x%x..\n", fp->mode.common.tcode);
   3021  1.88.2.1      yamt #endif
   3022  1.88.2.1      yamt 				/* fall through */
   3023  1.88.2.1      yamt 			case FWOHCIEV_ACKCOMPL:
   3024  1.88.2.1      yamt 			{
   3025  1.88.2.1      yamt 				struct fw_rcv_buf rb;
   3026  1.88.2.1      yamt 
   3027  1.88.2.1      yamt 				if ((vec[nvec-1].iov_len -=
   3028  1.88.2.1      yamt 					sizeof(struct fwohci_trailer)) == 0)
   3029  1.88.2.1      yamt 					nvec--;
   3030  1.88.2.1      yamt 				rb.fc = &sc->fc;
   3031  1.88.2.1      yamt 				rb.vec = vec;
   3032  1.88.2.1      yamt 				rb.nvec = nvec;
   3033  1.88.2.1      yamt 				rb.spd = spd;
   3034  1.88.2.1      yamt 				fw_rcv(&rb);
   3035      1.62      haya 				break;
   3036  1.88.2.1      yamt 			}
   3037  1.88.2.1      yamt 			case FWOHCIEV_BUSRST:
   3038  1.88.2.1      yamt 				if (sc->fc.status != FWBUSRESET)
   3039  1.88.2.1      yamt 					printf("got BUSRST packet!?\n");
   3040      1.62      haya 				break;
   3041      1.62      haya 			default:
   3042  1.88.2.1      yamt 				device_printf(sc->fc.dev,
   3043  1.88.2.1      yamt 				    "Async DMA Receive error err=%02x %s"
   3044  1.88.2.1      yamt 				    " plen=%d offset=%d len=%d status=0x%08x"
   3045  1.88.2.1      yamt 				    " tcode=0x%x, stat=0x%08x\n",
   3046  1.88.2.1      yamt 				    event, fwohcicode[event], plen,
   3047  1.88.2.1      yamt 				    dbch->buf_offset, len,
   3048  1.88.2.1      yamt 				    OREAD(sc, OHCI_DMACTL(off)),
   3049  1.88.2.1      yamt 				    fp->mode.common.tcode, stat);
   3050  1.88.2.1      yamt #if 1 /* XXX */
   3051  1.88.2.1      yamt 				goto err;
   3052  1.88.2.1      yamt #endif
   3053      1.62      haya 				break;
   3054      1.62      haya 			}
   3055  1.88.2.1      yamt 			pcnt ++;
   3056  1.88.2.1      yamt 			if (dbch->pdb_tr != NULL) {
   3057  1.88.2.1      yamt 				fwohci_arcv_free_buf(sc, dbch, dbch->pdb_tr,
   3058  1.88.2.1      yamt 				    off, 1);
   3059  1.88.2.1      yamt 				dbch->pdb_tr = NULL;
   3060  1.88.2.1      yamt 			}
   3061      1.62      haya 
   3062      1.62      haya 		}
   3063  1.88.2.1      yamt out:
   3064  1.88.2.1      yamt 		if (resCount == 0) {
   3065  1.88.2.1      yamt 			/* done on this buffer */
   3066  1.88.2.1      yamt 			if (dbch->pdb_tr == NULL) {
   3067  1.88.2.1      yamt 				fwohci_arcv_free_buf(sc, dbch, db_tr, off, 1);
   3068  1.88.2.1      yamt 				dbch->buf_offset = 0;
   3069  1.88.2.1      yamt 			} else
   3070  1.88.2.1      yamt 				if (dbch->pdb_tr != db_tr)
   3071  1.88.2.1      yamt 					printf("pdb_tr != db_tr\n");
   3072  1.88.2.1      yamt 			db_tr = STAILQ_NEXT(db_tr, link);
   3073  1.88.2.1      yamt 			fwdma_sync_multiseg_all(dbch->am,
   3074  1.88.2.1      yamt 			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   3075  1.88.2.1      yamt 			status = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
   3076  1.88.2.1      yamt 						>> OHCI_STATUS_SHIFT;
   3077  1.88.2.1      yamt 			resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
   3078  1.88.2.1      yamt 						& OHCI_COUNT_MASK;
   3079  1.88.2.1      yamt 			/* XXX check buffer overrun */
   3080  1.88.2.1      yamt 			dbch->top = db_tr;
   3081      1.62      haya 		} else {
   3082  1.88.2.1      yamt 			dbch->buf_offset = dbch->xferq.psize - resCount;
   3083  1.88.2.1      yamt 			fw_bus_dmamap_sync(
   3084  1.88.2.1      yamt 			    dbch->dmat, db_tr->dma_map, BUS_DMASYNC_PREREAD);
   3085      1.62      haya 			break;
   3086      1.62      haya 		}
   3087  1.88.2.1      yamt 		/* XXX make sure DMA is not dead */
   3088      1.62      haya 	}
   3089  1.88.2.1      yamt #if 0
   3090  1.88.2.1      yamt 	if (pcnt < 1)
   3091  1.88.2.1      yamt 		printf("fwohci_arcv: no packets\n");
   3092  1.88.2.1      yamt #endif
   3093  1.88.2.1      yamt 	fwdma_sync_multiseg_all(dbch->am,
   3094  1.88.2.1      yamt 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   3095  1.88.2.1      yamt 	splx(s);
   3096  1.88.2.1      yamt 	return;
   3097      1.62      haya 
   3098  1.88.2.1      yamt err:
   3099  1.88.2.1      yamt 	device_printf(sc->fc.dev, "AR DMA status=%x, ",
   3100  1.88.2.1      yamt 					OREAD(sc, OHCI_DMACTL(off)));
   3101  1.88.2.1      yamt 	dbch->pdb_tr = NULL;
   3102  1.88.2.1      yamt 	/* skip until resCount != 0 */
   3103  1.88.2.1      yamt 	printf(" skip buffer");
   3104  1.88.2.1      yamt 	while (resCount == 0) {
   3105  1.88.2.1      yamt 		printf(" #");
   3106  1.88.2.1      yamt 		fwohci_arcv_free_buf(sc, dbch, db_tr, off, 0);
   3107  1.88.2.1      yamt 		db_tr = STAILQ_NEXT(db_tr, link);
   3108  1.88.2.1      yamt 		resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
   3109  1.88.2.1      yamt 						& OHCI_COUNT_MASK;
   3110  1.88.2.1      yamt 	}
   3111  1.88.2.1      yamt 	printf(" done\n");
   3112  1.88.2.1      yamt 	dbch->top = db_tr;
   3113  1.88.2.1      yamt 	dbch->buf_offset = dbch->xferq.psize - resCount;
   3114  1.88.2.1      yamt 	OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_WAKE);
   3115  1.88.2.1      yamt 	fwdma_sync_multiseg_all(
   3116  1.88.2.1      yamt 	    dbch->am, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   3117  1.88.2.1      yamt 	fw_bus_dmamap_sync(dbch->dmat, db_tr->dma_map, BUS_DMASYNC_PREREAD);
   3118  1.88.2.1      yamt 	splx(s);
   3119      1.62      haya }
   3120  1.88.2.1      yamt #if defined(__NetBSD__)
   3121      1.62      haya 
   3122      1.62      haya int
   3123  1.88.2.1      yamt fwohci_print(void *aux, const char *pnp)
   3124      1.62      haya {
   3125  1.88.2.2      yamt 	struct fw_attach_args *fwa = (struct fw_attach_args *)aux;
   3126  1.88.2.1      yamt 
   3127  1.88.2.1      yamt 	if (pnp)
   3128  1.88.2.2      yamt 		aprint_normal("%s at %s", fwa->name, pnp);
   3129      1.62      haya 
   3130  1.88.2.1      yamt 	return UNCONF;
   3131      1.62      haya }
   3132  1.88.2.1      yamt #endif
   3133