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