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