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