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