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