1 /* $NetBSD: fwohci.c,v 1.41 2001/07/18 02:59:54 onoe Exp $ */ 2 3 #define DOUBLEBUF 1 4 #define NO_THREAD 1 5 /*- 6 * Copyright (c) 2000 The NetBSD Foundation, Inc. 7 * All rights reserved. 8 * 9 * This code is derived from software contributed to The NetBSD Foundation 10 * by Matt Thomas of 3am Software Foundry. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the NetBSD 23 * Foundation, Inc. and its contributors. 24 * 4. Neither the name of The NetBSD Foundation nor the names of its 25 * contributors may be used to endorse or promote products derived 26 * from this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 * POSSIBILITY OF SUCH DAMAGE. 39 */ 40 41 /* 42 * IEEE1394 Open Host Controller Interface 43 * based on OHCI Specification 1.1 (January 6, 2000) 44 * The first version to support network interface part is wrtten by 45 * Atsushi Onoe <onoe@netbsd.org>. 46 */ 47 48 /* 49 * The first version to support isochronous acquisition part is wrtten 50 * by HAYAKAWA Koichi <haya@netbsd.org>. 51 */ 52 53 #include "opt_inet.h" 54 55 #include <sys/param.h> 56 #include <sys/systm.h> 57 #include <sys/kthread.h> 58 #include <sys/types.h> 59 #include <sys/socket.h> 60 #include <sys/callout.h> 61 #include <sys/device.h> 62 #include <sys/kernel.h> 63 #include <sys/malloc.h> 64 #include <sys/mbuf.h> 65 66 #if __NetBSD_Version__ >= 105010000 67 #include <uvm/uvm_extern.h> 68 #else 69 #include <vm/vm.h> 70 #endif 71 72 #include <machine/bus.h> 73 #include <machine/intr.h> 74 75 #include <dev/ieee1394/ieee1394reg.h> 76 #include <dev/ieee1394/fwohcireg.h> 77 78 #include <dev/ieee1394/ieee1394var.h> 79 #include <dev/ieee1394/fwohcivar.h> 80 81 static const char * const ieee1394_speeds[] = { IEEE1394_SPD_STRINGS }; 82 83 #if 0 84 static int fwohci_dnamem_alloc(struct fwohci_softc *sc, int size, 85 int alignment, bus_dmamap_t *mapp, caddr_t *kvap, int flags); 86 #endif 87 static void fwohci_create_event_thread(void *); 88 static void fwohci_thread_init(void *); 89 90 static void fwohci_event_thread(struct fwohci_softc *); 91 static void fwohci_hw_init(struct fwohci_softc *); 92 static void fwohci_power(int, void *); 93 static void fwohci_shutdown(void *); 94 95 static int fwohci_desc_alloc(struct fwohci_softc *); 96 static struct fwohci_desc *fwohci_desc_get(struct fwohci_softc *, int); 97 static void fwohci_desc_put(struct fwohci_softc *, struct fwohci_desc *, int); 98 99 static int fwohci_ctx_alloc(struct fwohci_softc *, struct fwohci_ctx **, 100 int, int, int); 101 static void fwohci_ctx_free(struct fwohci_softc *, struct fwohci_ctx *); 102 static void fwohci_ctx_init(struct fwohci_softc *, struct fwohci_ctx *); 103 104 static int fwohci_buf_alloc(struct fwohci_softc *, struct fwohci_buf *); 105 static void fwohci_buf_free(struct fwohci_softc *, struct fwohci_buf *); 106 static void fwohci_buf_init_rx(struct fwohci_softc *); 107 static void fwohci_buf_start_rx(struct fwohci_softc *); 108 static void fwohci_buf_stop_tx(struct fwohci_softc *); 109 static void fwohci_buf_stop_rx(struct fwohci_softc *); 110 static void fwohci_buf_next(struct fwohci_softc *, struct fwohci_ctx *); 111 static int fwohci_buf_pktget(struct fwohci_softc *, struct fwohci_buf **, 112 caddr_t *, int); 113 static int fwohci_buf_input(struct fwohci_softc *, struct fwohci_ctx *, 114 struct fwohci_pkt *); 115 static int fwohci_buf_input_ppb(struct fwohci_softc *, struct fwohci_ctx *, 116 struct fwohci_pkt *); 117 118 static u_int8_t fwohci_phy_read(struct fwohci_softc *, u_int8_t); 119 static void fwohci_phy_write(struct fwohci_softc *, u_int8_t, u_int8_t); 120 static void fwohci_phy_busreset(struct fwohci_softc *); 121 static void fwohci_phy_input(struct fwohci_softc *, struct fwohci_pkt *); 122 123 static int fwohci_handler_set(struct fwohci_softc *, int, u_int32_t, u_int32_t, 124 int (*)(struct fwohci_softc *, void *, struct fwohci_pkt *), void *); 125 126 static void fwohci_arrq_input(struct fwohci_softc *, struct fwohci_ctx *); 127 static void fwohci_arrs_input(struct fwohci_softc *, struct fwohci_ctx *); 128 static void fwohci_ir_input(struct fwohci_softc *, struct fwohci_ctx *); 129 130 static int fwohci_at_output(struct fwohci_softc *, struct fwohci_ctx *, 131 struct fwohci_pkt *); 132 static void fwohci_at_done(struct fwohci_softc *, struct fwohci_ctx *, int); 133 static void fwohci_atrs_output(struct fwohci_softc *, int, struct fwohci_pkt *, 134 struct fwohci_pkt *); 135 136 static int fwohci_guidrom_init(struct fwohci_softc *); 137 static void fwohci_configrom_init(struct fwohci_softc *); 138 static int fwohci_configrom_input(struct fwohci_softc *, void *, 139 struct fwohci_pkt *); 140 static void fwohci_selfid_init(struct fwohci_softc *); 141 static int fwohci_selfid_input(struct fwohci_softc *); 142 143 static void fwohci_csr_init(struct fwohci_softc *); 144 static int fwohci_csr_input(struct fwohci_softc *, void *, 145 struct fwohci_pkt *); 146 147 static void fwohci_uid_collect(struct fwohci_softc *); 148 static void fwohci_uid_req(struct fwohci_softc *, int); 149 static int fwohci_uid_input(struct fwohci_softc *, void *, 150 struct fwohci_pkt *); 151 static int fwohci_uid_lookup(struct fwohci_softc *, const u_int8_t *); 152 static void fwohci_check_nodes(struct fwohci_softc *); 153 154 static int fwohci_if_inreg(struct device *, u_int32_t, u_int32_t, 155 void (*)(struct device *, struct mbuf *)); 156 static int fwohci_if_input(struct fwohci_softc *, void *, struct fwohci_pkt *); 157 static int fwohci_if_input_iso(struct fwohci_softc *, void *, struct fwohci_pkt *); 158 static int fwohci_if_output(struct device *, struct mbuf *, 159 void (*)(struct device *, struct mbuf *)); 160 static int fwohci_if_setiso(struct device *, u_int32_t, u_int32_t, u_int32_t, 161 void (*)(struct device *, struct mbuf *)); 162 static int fwohci_read(struct ieee1394_abuf *); 163 static int fwohci_write(struct ieee1394_abuf *); 164 static int fwohci_read_resp(struct fwohci_softc *, void *, struct fwohci_pkt *); 165 static int fwohci_write_ack(struct fwohci_softc *, void *, struct fwohci_pkt *); 166 static int fwohci_read_multi_resp(struct fwohci_softc *, void *, 167 struct fwohci_pkt *); 168 static int fwohci_inreg(struct ieee1394_abuf *, int); 169 static int fwohci_parse_input(struct fwohci_softc *, void *, 170 struct fwohci_pkt *); 171 static int fwohci_submatch(struct device *, struct cfdata *, void *); 172 173 #ifdef FW_DEBUG 174 static void fwohci_show_intr(struct fwohci_softc *, u_int32_t); 175 static void fwohci_show_phypkt(struct fwohci_softc *, u_int32_t); 176 177 /* 1 is normal debug, 2 is verbose debug, 3 is complete (packet dumps). */ 178 179 #define DPRINTF(x) if (fwdebug) printf x 180 #define DPRINTFN(n,x) if (fwdebug>(n)) printf x 181 int fwdebug = 0; 182 #else 183 #define DPRINTF(x) 184 #define DPRINTFN(n,x) 185 #endif 186 187 int 188 fwohci_init(struct fwohci_softc *sc, const struct evcnt *ev) 189 { 190 int i; 191 u_int32_t val; 192 #if 0 193 int error; 194 #endif 195 196 evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, ev, 197 sc->sc_sc1394.sc1394_dev.dv_xname, "intr"); 198 199 evcnt_attach_dynamic(&sc->sc_isocnt, EVCNT_TYPE_MISC, ev, 200 sc->sc_sc1394.sc1394_dev.dv_xname, "iso"); 201 evcnt_attach_dynamic(&sc->sc_isopktcnt, EVCNT_TYPE_MISC, ev, 202 sc->sc_sc1394.sc1394_dev.dv_xname, "isopackets"); 203 204 /* 205 * Wait for reset completion 206 */ 207 for (i = 0; i < OHCI_LOOP; i++) { 208 val = OHCI_CSR_READ(sc, OHCI_REG_HCControlClear); 209 if ((val & OHCI_HCControl_SoftReset) == 0) 210 break; 211 DELAY(10); 212 } 213 214 /* What dialect of OHCI is this device? 215 */ 216 val = OHCI_CSR_READ(sc, OHCI_REG_Version); 217 printf("%s: OHCI %u.%u", sc->sc_sc1394.sc1394_dev.dv_xname, 218 OHCI_Version_GET_Version(val), OHCI_Version_GET_Revision(val)); 219 220 LIST_INIT(&sc->sc_nodelist); 221 222 if (fwohci_guidrom_init(sc) != 0) { 223 printf("\n%s: fatal: no global UID ROM\n", 224 sc->sc_sc1394.sc1394_dev.dv_xname); 225 return -1; 226 } 227 228 printf(", %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", 229 sc->sc_sc1394.sc1394_guid[0], sc->sc_sc1394.sc1394_guid[1], 230 sc->sc_sc1394.sc1394_guid[2], sc->sc_sc1394.sc1394_guid[3], 231 sc->sc_sc1394.sc1394_guid[4], sc->sc_sc1394.sc1394_guid[5], 232 sc->sc_sc1394.sc1394_guid[6], sc->sc_sc1394.sc1394_guid[7]); 233 234 /* Get the maximum link speed and receive size 235 */ 236 val = OHCI_CSR_READ(sc, OHCI_REG_BusOptions); 237 sc->sc_sc1394.sc1394_link_speed = 238 OHCI_BITVAL(val, OHCI_BusOptions_LinkSpd); 239 if (sc->sc_sc1394.sc1394_link_speed < IEEE1394_SPD_MAX) { 240 printf(", %s", 241 ieee1394_speeds[sc->sc_sc1394.sc1394_link_speed]); 242 } else { 243 printf(", unknown speed %u", sc->sc_sc1394.sc1394_link_speed); 244 } 245 246 /* MaxRec is encoded as log2(max_rec_octets)-1 247 */ 248 sc->sc_sc1394.sc1394_max_receive = 249 1 << (OHCI_BITVAL(val, OHCI_BusOptions_MaxRec) + 1); 250 printf(", %u max_rec", sc->sc_sc1394.sc1394_max_receive); 251 252 /* 253 * Count how many isochronous ctx we have. 254 */ 255 OHCI_CSR_WRITE(sc, OHCI_REG_IsoRecvIntMaskSet, ~0); 256 val = OHCI_CSR_READ(sc, OHCI_REG_IsoRecvIntMaskClear); 257 OHCI_CSR_WRITE(sc, OHCI_REG_IsoRecvIntMaskClear, ~0); 258 for (i = 0; val != 0; val >>= 1) { 259 if (val & 0x1) 260 i++; 261 } 262 sc->sc_isoctx = i; 263 printf(", %d iso_ctx", sc->sc_isoctx); 264 265 printf("\n"); 266 267 #if 0 268 error = fwohci_dnamem_alloc(sc, OHCI_CONFIG_SIZE, 269 OHCI_CONFIG_ALIGNMENT, &sc->sc_configrom_map, 270 (caddr_t *) &sc->sc_configrom, BUS_DMA_WAITOK|BUS_DMA_COHERENT); 271 return error; 272 #endif 273 274 sc->sc_dying = 0; 275 sc->sc_nodeid = 0xffff; /* invalid */ 276 277 kthread_create(fwohci_create_event_thread, sc); 278 return 0; 279 } 280 281 static int 282 fwohci_if_setiso(struct device *self, u_int32_t channel, u_int32_t tag, 283 u_int32_t direction, void (*handler)(struct device *, struct mbuf *)) 284 { 285 struct fwohci_softc *sc = (struct fwohci_softc *)self; 286 int retval; 287 int s; 288 289 if (direction == 1) { 290 return EIO; 291 } 292 293 s = splnet(); 294 retval = fwohci_handler_set(sc, IEEE1394_TCODE_STREAM_DATA, 295 channel, tag, fwohci_if_input_iso, handler); 296 splx(s); 297 298 if (!retval) { 299 printf("%s: dummy iso handler set\n", 300 sc->sc_sc1394.sc1394_dev.dv_xname); 301 } else { 302 printf("%s: dummy iso handler cannot set\n", 303 sc->sc_sc1394.sc1394_dev.dv_xname); 304 } 305 306 return retval; 307 } 308 309 int 310 fwohci_intr(void *arg) 311 { 312 struct fwohci_softc * const sc = arg; 313 int progress = 0; 314 u_int32_t intmask, iso; 315 316 for (;;) { 317 intmask = OHCI_CSR_READ(sc, OHCI_REG_IntEventClear); 318 319 /* 320 * On a bus reset, everything except bus reset gets 321 * cleared. That can't get cleared until the selfid 322 * phase completes (which happens outside the 323 * interrupt routines). So if just a bus reset is left 324 * in the mask and it's already in the sc_intmask, 325 * just return. 326 */ 327 328 if ((intmask == 0) || 329 (progress && (intmask == OHCI_Int_BusReset) && 330 (sc->sc_intmask & OHCI_Int_BusReset))) { 331 if (progress) 332 wakeup(fwohci_event_thread); 333 return progress; 334 } 335 OHCI_CSR_WRITE(sc, OHCI_REG_IntEventClear, 336 intmask & ~OHCI_Int_BusReset); 337 #ifdef FW_DEBUG 338 if (fwdebug > 1) 339 fwohci_show_intr(sc, intmask); 340 #endif 341 342 if (intmask & OHCI_Int_BusReset) { 343 /* 344 * According to OHCI spec 6.1.1 "busReset", 345 * All asynchronous transmit must be stopped before 346 * clearing BusReset. Moreover, the BusReset 347 * interrupt bit should not be cleared during the 348 * SelfID phase. Thus we turned off interrupt mask 349 * bit of BusReset instead until SelfID completion 350 * or SelfID timeout. 351 */ 352 intmask &= OHCI_Int_SelfIDComplete; 353 OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskClear, 354 OHCI_Int_BusReset); 355 sc->sc_intmask = OHCI_Int_BusReset; 356 } 357 sc->sc_intmask |= intmask; 358 359 if (intmask & OHCI_Int_IsochTx) { 360 iso = OHCI_CSR_READ(sc, OHCI_REG_IsoXmitIntEventClear); 361 OHCI_CSR_WRITE(sc, OHCI_REG_IsoXmitIntEventClear, iso); 362 } 363 if (intmask & OHCI_Int_IsochRx) { 364 #if NO_THREAD 365 int i; 366 int asyncstream = 0; 367 #endif 368 369 iso = OHCI_CSR_READ(sc, OHCI_REG_IsoRecvIntEventClear); 370 OHCI_CSR_WRITE(sc, OHCI_REG_IsoRecvIntEventClear, iso); 371 #if NO_THREAD 372 for (i = 0; i < sc->sc_isoctx; i++) { 373 if ((iso & (1<<i)) && sc->sc_ctx_ir[i] != NULL) { 374 if (sc->sc_ctx_ir[i]->fc_type == FWOHCI_CTX_ISO_SINGLE) { 375 asyncstream |= (1 << i); 376 continue; 377 } 378 bus_dmamap_sync(sc->sc_dmat, 379 sc->sc_ddmamap, 380 0, sizeof(struct fwohci_desc) * sc->sc_descsize, 381 BUS_DMASYNC_PREREAD); 382 sc->sc_isocnt.ev_count++; 383 384 fwohci_ir_input(sc, sc->sc_ctx_ir[i]); 385 } 386 } 387 if (asyncstream != 0) { 388 sc->sc_iso |= asyncstream; 389 } else { 390 /* all iso intr is pure isochronous */ 391 sc->sc_intmask &= ~OHCI_Int_IsochRx; 392 } 393 #else 394 sc->sc_iso |= iso; 395 #endif /* NO_THREAD */ 396 } 397 398 if (!progress) { 399 sc->sc_intrcnt.ev_count++; 400 progress = 1; 401 } 402 } 403 } 404 405 static void 406 fwohci_create_event_thread(void *arg) 407 { 408 struct fwohci_softc *sc = arg; 409 410 if (kthread_create1(fwohci_thread_init, sc, &sc->sc_event_thread, "%s", 411 sc->sc_sc1394.sc1394_dev.dv_xname)) { 412 printf("%s: unable to create event thread\n", 413 sc->sc_sc1394.sc1394_dev.dv_xname); 414 panic("fwohci_create_event_thread"); 415 } 416 } 417 418 static void 419 fwohci_thread_init(void *arg) 420 { 421 struct fwohci_softc *sc = arg; 422 int i; 423 424 /* 425 * Allocate descriptors 426 */ 427 if (fwohci_desc_alloc(sc)) { 428 printf("%s: not enabling interrupts\n", 429 sc->sc_sc1394.sc1394_dev.dv_xname); 430 kthread_exit(1); 431 } 432 433 /* 434 * Enable Link Power 435 */ 436 437 OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet, OHCI_HCControl_LPS); 438 439 /* 440 * Allocate DMA Context 441 */ 442 fwohci_ctx_alloc(sc, &sc->sc_ctx_arrq, OHCI_BUF_ARRQ_CNT, 443 OHCI_CTX_ASYNC_RX_REQUEST, FWOHCI_CTX_ASYNC); 444 fwohci_ctx_alloc(sc, &sc->sc_ctx_arrs, OHCI_BUF_ARRS_CNT, 445 OHCI_CTX_ASYNC_RX_RESPONSE, FWOHCI_CTX_ASYNC); 446 fwohci_ctx_alloc(sc, &sc->sc_ctx_atrq, 0, OHCI_CTX_ASYNC_TX_REQUEST, 447 FWOHCI_CTX_ASYNC); 448 fwohci_ctx_alloc(sc, &sc->sc_ctx_atrs, 0, OHCI_CTX_ASYNC_TX_RESPONSE, 449 FWOHCI_CTX_ASYNC); 450 sc->sc_ctx_ir = malloc(sizeof(sc->sc_ctx_ir[0]) * sc->sc_isoctx, 451 M_DEVBUF, M_WAITOK); 452 for (i = 0; i < sc->sc_isoctx; i++) 453 sc->sc_ctx_ir[i] = NULL; 454 455 /* 456 * Allocate buffer for configuration ROM and SelfID buffer 457 */ 458 fwohci_buf_alloc(sc, &sc->sc_buf_cnfrom); 459 fwohci_buf_alloc(sc, &sc->sc_buf_selfid); 460 461 callout_init(&sc->sc_selfid_callout); 462 463 sc->sc_sc1394.sc1394_ifinreg = fwohci_if_inreg; 464 sc->sc_sc1394.sc1394_ifoutput = fwohci_if_output; 465 sc->sc_sc1394.sc1394_ifsetiso = fwohci_if_setiso; 466 467 /* 468 * establish hooks for shutdown and suspend/resume 469 */ 470 sc->sc_shutdownhook = shutdownhook_establish(fwohci_shutdown, sc); 471 sc->sc_powerhook = powerhook_establish(fwohci_power, sc); 472 473 sc->sc_sc1394.sc1394_if = config_found(&sc->sc_sc1394.sc1394_dev, "fw", 474 fwohci_print); 475 476 /* Main loop. It's not coming back normally. */ 477 478 fwohci_event_thread(sc); 479 480 kthread_exit(0); 481 } 482 483 static void 484 fwohci_event_thread(struct fwohci_softc *sc) 485 { 486 int i, s; 487 u_int32_t intmask, iso; 488 489 s = splbio(); 490 491 /* 492 * Initialize hardware registers. 493 */ 494 495 fwohci_hw_init(sc); 496 497 /* Initial Bus Reset */ 498 fwohci_phy_busreset(sc); 499 splx(s); 500 501 while (!sc->sc_dying) { 502 s = splbio(); 503 intmask = sc->sc_intmask; 504 if (intmask == 0) { 505 tsleep(fwohci_event_thread, PZERO, "fwohciev", 0); 506 splx(s); 507 continue; 508 } 509 sc->sc_intmask = 0; 510 splx(s); 511 512 if (intmask & OHCI_Int_BusReset) { 513 fwohci_buf_stop_tx(sc); 514 if (sc->sc_uidtbl != NULL) { 515 free(sc->sc_uidtbl, M_DEVBUF); 516 sc->sc_uidtbl = NULL; 517 } 518 519 callout_reset(&sc->sc_selfid_callout, 520 OHCI_SELFID_TIMEOUT, 521 (void (*)(void *))fwohci_phy_busreset, sc); 522 sc->sc_nodeid = 0xffff; /* indicate invalid */ 523 sc->sc_rootid = 0; 524 sc->sc_irmid = IEEE1394_BCAST_PHY_ID; 525 } 526 if (intmask & OHCI_Int_SelfIDComplete) { 527 s = splbio(); 528 OHCI_CSR_WRITE(sc, OHCI_REG_IntEventClear, 529 OHCI_Int_BusReset); 530 OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskSet, 531 OHCI_Int_BusReset); 532 splx(s); 533 callout_stop(&sc->sc_selfid_callout); 534 if (fwohci_selfid_input(sc) == 0) { 535 fwohci_buf_start_rx(sc); 536 fwohci_uid_collect(sc); 537 } 538 } 539 if (intmask & OHCI_Int_ReqTxComplete) 540 fwohci_at_done(sc, sc->sc_ctx_atrq, 0); 541 if (intmask & OHCI_Int_RespTxComplete) 542 fwohci_at_done(sc, sc->sc_ctx_atrs, 0); 543 if (intmask & OHCI_Int_RQPkt) 544 fwohci_arrq_input(sc, sc->sc_ctx_arrq); 545 if (intmask & OHCI_Int_RSPkt) 546 fwohci_arrs_input(sc, sc->sc_ctx_arrs); 547 if (intmask & OHCI_Int_IsochRx) { 548 s = splbio(); 549 iso = sc->sc_iso; 550 sc->sc_iso = 0; 551 splx(s); 552 for (i = 0; i < sc->sc_isoctx; i++) { 553 if ((iso & (1 << i)) && 554 sc->sc_ctx_ir[i] != NULL) { 555 fwohci_ir_input(sc, sc->sc_ctx_ir[i]); 556 sc->sc_isocnt.ev_count++; 557 } 558 } 559 } 560 } 561 } 562 563 #if 0 564 static int 565 fwohci_dnamem_alloc(struct fwohci_softc *sc, int size, int alignment, 566 bus_dmamap_t *mapp, caddr_t *kvap, int flags) 567 { 568 bus_dma_segment_t segs[1]; 569 int error, nsegs, steps; 570 571 steps = 0; 572 error = bus_dmamem_alloc(sc->sc_dmat, size, alignment, alignment, 573 segs, 1, &nsegs, flags); 574 if (error) 575 goto cleanup; 576 577 steps = 1; 578 error = bus_dmamem_map(sc->sc_dmat, segs, nsegs, segs[0].ds_len, 579 kvap, flags); 580 if (error) 581 goto cleanup; 582 583 if (error == 0) 584 error = bus_dmamap_create(sc->sc_dmat, size, 1, alignment, 585 size, flags, mapp); 586 if (error) 587 goto cleanup; 588 if (error == 0) 589 error = bus_dmamap_load(sc->sc_dmat, *mapp, *kvap, size, NULL, 590 flags); 591 if (error) 592 goto cleanup; 593 594 cleanup: 595 switch (steps) { 596 case 1: 597 bus_dmamem_free(sc->sc_dmat, segs, nsegs); 598 } 599 600 return error; 601 } 602 #endif 603 604 int 605 fwohci_print(void *aux, const char *pnp) 606 { 607 char *name = aux; 608 609 if (pnp) 610 printf("%s at %s", name, pnp); 611 612 return QUIET; 613 } 614 615 static void 616 fwohci_hw_init(struct fwohci_softc *sc) 617 { 618 int i; 619 u_int32_t val; 620 621 /* 622 * Software Reset. 623 */ 624 OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet, OHCI_HCControl_SoftReset); 625 for (i = 0; i < OHCI_LOOP; i++) { 626 val = OHCI_CSR_READ(sc, OHCI_REG_HCControlClear); 627 if ((val & OHCI_HCControl_SoftReset) == 0) 628 break; 629 DELAY(10); 630 } 631 632 OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet, OHCI_HCControl_LPS); 633 634 /* 635 * First, initilize CSRs with undefined value to default settings. 636 */ 637 val = OHCI_CSR_READ(sc, OHCI_REG_BusOptions); 638 val |= OHCI_BusOptions_ISC | OHCI_BusOptions_CMC; 639 #if 0 640 val |= OHCI_BusOptions_BMC | OHCI_BusOptions_IRMC; 641 #else 642 val &= ~(OHCI_BusOptions_BMC | OHCI_BusOptions_IRMC); 643 #endif 644 OHCI_CSR_WRITE(sc, OHCI_REG_BusOptions, val); 645 for (i = 0; i < sc->sc_isoctx; i++) { 646 OHCI_SYNC_RX_DMA_WRITE(sc, i, OHCI_SUBREG_ContextControlClear, 647 ~0); 648 } 649 OHCI_CSR_WRITE(sc, OHCI_REG_LinkControlClear, ~0); 650 651 fwohci_configrom_init(sc); 652 fwohci_selfid_init(sc); 653 fwohci_buf_init_rx(sc); 654 fwohci_csr_init(sc); 655 656 /* 657 * Final CSR settings. 658 */ 659 OHCI_CSR_WRITE(sc, OHCI_REG_LinkControlSet, 660 OHCI_LinkControl_CycleTimerEnable | 661 OHCI_LinkControl_RcvSelfID | OHCI_LinkControl_RcvPhyPkt); 662 663 OHCI_CSR_WRITE(sc, OHCI_REG_ATRetries, 0x00000888); /*XXX*/ 664 665 /* clear receive filter */ 666 OHCI_CSR_WRITE(sc, OHCI_REG_IRMultiChanMaskHiClear, ~0); 667 OHCI_CSR_WRITE(sc, OHCI_REG_IRMultiChanMaskLoClear, ~0); 668 OHCI_CSR_WRITE(sc, OHCI_REG_AsynchronousRequestFilterHiSet, 0x80000000); 669 670 OHCI_CSR_WRITE(sc, OHCI_REG_HCControlClear, 671 OHCI_HCControl_NoByteSwapData | OHCI_HCControl_APhyEnhanceEnable); 672 #if BYTE_ORDER == BIG_ENDIAN 673 OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet, 674 OHCI_HCControl_NoByteSwapData); 675 #endif 676 677 OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskClear, ~0); 678 OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskSet, OHCI_Int_BusReset | 679 OHCI_Int_SelfIDComplete | OHCI_Int_IsochRx | OHCI_Int_IsochTx | 680 OHCI_Int_RSPkt | OHCI_Int_RQPkt | OHCI_Int_ARRS | OHCI_Int_ARRQ | 681 OHCI_Int_RespTxComplete | OHCI_Int_ReqTxComplete); 682 OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskSet, OHCI_Int_CycleTooLong | 683 OHCI_Int_UnrecoverableError | OHCI_Int_CycleInconsistent | 684 OHCI_Int_LockRespErr | OHCI_Int_PostedWriteErr); 685 OHCI_CSR_WRITE(sc, OHCI_REG_IsoXmitIntMaskSet, ~0); 686 OHCI_CSR_WRITE(sc, OHCI_REG_IsoRecvIntMaskSet, ~0); 687 OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskSet, OHCI_Int_MasterEnable); 688 689 OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet, OHCI_HCControl_LinkEnable); 690 691 /* 692 * Start the receivers 693 */ 694 fwohci_buf_start_rx(sc); 695 } 696 697 static void 698 fwohci_power(int why, void *arg) 699 { 700 struct fwohci_softc *sc = arg; 701 int s; 702 703 s = splbio(); 704 switch (why) { 705 case PWR_SUSPEND: 706 case PWR_STANDBY: 707 fwohci_shutdown(sc); 708 break; 709 case PWR_RESUME: 710 fwohci_hw_init(sc); 711 fwohci_phy_busreset(sc); 712 break; 713 case PWR_SOFTSUSPEND: 714 case PWR_SOFTSTANDBY: 715 case PWR_SOFTRESUME: 716 break; 717 } 718 splx(s); 719 } 720 721 static void 722 fwohci_shutdown(void *arg) 723 { 724 struct fwohci_softc *sc = arg; 725 u_int32_t val; 726 727 callout_stop(&sc->sc_selfid_callout); 728 /* disable all interrupt */ 729 OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskClear, OHCI_Int_MasterEnable); 730 fwohci_buf_stop_tx(sc); 731 fwohci_buf_stop_rx(sc); 732 val = OHCI_CSR_READ(sc, OHCI_REG_BusOptions); 733 val &= ~(OHCI_BusOptions_BMC | OHCI_BusOptions_ISC | 734 OHCI_BusOptions_CMC | OHCI_BusOptions_IRMC); 735 OHCI_CSR_WRITE(sc, OHCI_REG_BusOptions, val); 736 fwohci_phy_busreset(sc); 737 OHCI_CSR_WRITE(sc, OHCI_REG_HCControlClear, OHCI_HCControl_LinkEnable); 738 OHCI_CSR_WRITE(sc, OHCI_REG_HCControlClear, OHCI_HCControl_LPS); 739 OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet, OHCI_HCControl_SoftReset); 740 } 741 742 /* 743 * COMMON FUNCTIONS 744 */ 745 746 /* 747 * read the PHY Register. 748 */ 749 static u_int8_t 750 fwohci_phy_read(struct fwohci_softc *sc, u_int8_t reg) 751 { 752 int i; 753 u_int32_t val; 754 755 OHCI_CSR_WRITE(sc, OHCI_REG_PhyControl, 756 OHCI_PhyControl_RdReg | (reg << OHCI_PhyControl_RegAddr_BITPOS)); 757 for (i = 0; i < OHCI_LOOP; i++) { 758 if (OHCI_CSR_READ(sc, OHCI_REG_PhyControl) & 759 OHCI_PhyControl_RdDone) 760 break; 761 DELAY(10); 762 } 763 val = OHCI_CSR_READ(sc, OHCI_REG_PhyControl); 764 return (val & OHCI_PhyControl_RdData) >> OHCI_PhyControl_RdData_BITPOS; 765 } 766 767 /* 768 * write the PHY Register. 769 */ 770 static void 771 fwohci_phy_write(struct fwohci_softc *sc, u_int8_t reg, u_int8_t val) 772 { 773 int i; 774 775 OHCI_CSR_WRITE(sc, OHCI_REG_PhyControl, OHCI_PhyControl_WrReg | 776 (reg << OHCI_PhyControl_RegAddr_BITPOS) | 777 (val << OHCI_PhyControl_WrData_BITPOS)); 778 for (i = 0; i < OHCI_LOOP; i++) { 779 if (!(OHCI_CSR_READ(sc, OHCI_REG_PhyControl) & 780 OHCI_PhyControl_WrReg)) 781 break; 782 DELAY(10); 783 } 784 } 785 786 /* 787 * Initiate Bus Reset 788 */ 789 static void 790 fwohci_phy_busreset(struct fwohci_softc *sc) 791 { 792 int s; 793 u_int8_t val; 794 795 s = splbio(); 796 OHCI_CSR_WRITE(sc, OHCI_REG_IntEventClear, 797 OHCI_Int_BusReset | OHCI_Int_SelfIDComplete); 798 OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskSet, OHCI_Int_BusReset); 799 callout_stop(&sc->sc_selfid_callout); 800 val = fwohci_phy_read(sc, 1); 801 val = (val & 0x80) | /* preserve RHB (force root) */ 802 0x40 | /* Initiate Bus Reset */ 803 0x3f; /* default GAP count */ 804 fwohci_phy_write(sc, 1, val); 805 splx(s); 806 } 807 808 /* 809 * PHY Packet 810 */ 811 static void 812 fwohci_phy_input(struct fwohci_softc *sc, struct fwohci_pkt *pkt) 813 { 814 u_int32_t val; 815 816 val = pkt->fp_hdr[1]; 817 if (val != ~pkt->fp_hdr[2]) { 818 if (val == 0 && ((*pkt->fp_trail & 0x001f0000) >> 16) == 819 OHCI_CTXCTL_EVENT_BUS_RESET) { 820 DPRINTFN(1, ("fwohci_phy_input: BusReset: 0x%08x\n", 821 pkt->fp_hdr[2])); 822 } else { 823 printf("%s: phy packet corrupted (0x%08x, 0x%08x)\n", 824 sc->sc_sc1394.sc1394_dev.dv_xname, val, 825 pkt->fp_hdr[2]); 826 } 827 return; 828 } 829 #ifdef FW_DEBUG 830 if (fwdebug > 1) 831 fwohci_show_phypkt(sc, val); 832 #endif 833 } 834 835 /* 836 * Descriptor for context DMA. 837 */ 838 static int 839 fwohci_desc_alloc(struct fwohci_softc *sc) 840 { 841 int error, mapsize, dsize; 842 843 /* 844 * allocate descriptor buffer 845 */ 846 847 sc->sc_descsize = OHCI_BUF_ARRQ_CNT + OHCI_BUF_ARRS_CNT + 848 OHCI_BUF_ATRQ_CNT + OHCI_BUF_ATRS_CNT + 849 OHCI_BUF_IR_CNT * sc->sc_isoctx + 2; 850 dsize = sizeof(struct fwohci_desc) * sc->sc_descsize; 851 mapsize = howmany(sc->sc_descsize, NBBY); 852 sc->sc_descmap = malloc(mapsize, M_DEVBUF, M_WAITOK); 853 memset(sc->sc_descmap, 0, mapsize); 854 855 if ((error = bus_dmamem_alloc(sc->sc_dmat, dsize, PAGE_SIZE, 0, 856 &sc->sc_dseg, 1, &sc->sc_dnseg, 0)) != 0) { 857 printf("%s: unable to allocate descriptor buffer, error = %d\n", 858 sc->sc_sc1394.sc1394_dev.dv_xname, error); 859 goto fail_0; 860 } 861 862 if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dseg, sc->sc_dnseg, 863 dsize, (caddr_t *)&sc->sc_desc, BUS_DMA_COHERENT | BUS_DMA_WAITOK)) 864 != 0) { 865 printf("%s: unable to map descriptor buffer, error = %d\n", 866 sc->sc_sc1394.sc1394_dev.dv_xname, error); 867 goto fail_1; 868 } 869 870 if ((error = bus_dmamap_create(sc->sc_dmat, dsize, sc->sc_dnseg, 871 dsize, 0, BUS_DMA_WAITOK, &sc->sc_ddmamap)) != 0) { 872 printf("%s: unable to create descriptor buffer DMA map, " 873 "error = %d\n", sc->sc_sc1394.sc1394_dev.dv_xname, error); 874 goto fail_2; 875 } 876 877 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_ddmamap, sc->sc_desc, 878 dsize, NULL, BUS_DMA_WAITOK)) != 0) { 879 printf("%s: unable to load descriptor buffer DMA map, " 880 "error = %d\n", sc->sc_sc1394.sc1394_dev.dv_xname, error); 881 goto fail_3; 882 } 883 884 return 0; 885 886 fail_3: 887 bus_dmamap_destroy(sc->sc_dmat, sc->sc_ddmamap); 888 fail_2: 889 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_desc, dsize); 890 fail_1: 891 bus_dmamem_free(sc->sc_dmat, &sc->sc_dseg, sc->sc_dnseg); 892 fail_0: 893 return error; 894 } 895 896 static struct fwohci_desc * 897 fwohci_desc_get(struct fwohci_softc *sc, int ndesc) 898 { 899 int i, n; 900 901 for (n = 0; n <= sc->sc_descsize - ndesc; n++) { 902 for (i = 0; ; i++) { 903 if (i == ndesc) { 904 for (i = 0; i < ndesc; i++) 905 setbit(sc->sc_descmap, n + i); 906 return sc->sc_desc + n; 907 } 908 if (isset(sc->sc_descmap, n + i)) 909 break; 910 } 911 } 912 return NULL; 913 } 914 915 static void 916 fwohci_desc_put(struct fwohci_softc *sc, struct fwohci_desc *fd, int ndesc) 917 { 918 int i, n; 919 920 n = fd - sc->sc_desc; 921 for (i = 0; i < ndesc; i++, n++) { 922 #ifdef DIAGNOSTIC 923 if (isclr(sc->sc_descmap, n)) 924 panic("fwohci_desc_put: duplicated free"); 925 #endif 926 clrbit(sc->sc_descmap, n); 927 } 928 } 929 930 /* 931 * Asyncronous/Isochronous Transmit/Receive Context 932 */ 933 static int 934 fwohci_ctx_alloc(struct fwohci_softc *sc, struct fwohci_ctx **fcp, 935 int bufcnt, int ctx, int ctxtype) 936 { 937 int i, error; 938 struct fwohci_ctx *fc; 939 struct fwohci_buf *fb; 940 struct fwohci_desc *fd; 941 int buf2cnt; 942 943 fc = malloc(sizeof(*fc) + sizeof(*fb) * bufcnt, M_DEVBUF, M_WAITOK); 944 memset(fc, 0, sizeof(*fc) + sizeof(*fb) * bufcnt); 945 LIST_INIT(&fc->fc_handler); 946 TAILQ_INIT(&fc->fc_buf); 947 fc->fc_ctx = ctx; 948 fc->fc_bufcnt = bufcnt; 949 fb = (struct fwohci_buf *)&fc[1]; 950 #if DOUBLEBUF 951 TAILQ_INIT(&fc->fc_buf2); /* for isochronous */ 952 if (ctxtype == FWOHCI_CTX_ISO_MULTI) { 953 buf2cnt = bufcnt/2; 954 bufcnt -= buf2cnt; 955 if (buf2cnt == 0) { 956 panic("cannot allocate iso buffer"); 957 } 958 } 959 #endif 960 for (i = 0; i < bufcnt; i++, fb++) { 961 if ((error = fwohci_buf_alloc(sc, fb)) != 0) 962 goto fail; 963 if ((fd = fwohci_desc_get(sc, 1)) == NULL) { 964 error = ENOBUFS; 965 goto fail; 966 } 967 fb->fb_desc = fd; 968 fb->fb_daddr = sc->sc_ddmamap->dm_segs[0].ds_addr + 969 ((caddr_t)fd - (caddr_t)sc->sc_desc); 970 fd->fd_flags = OHCI_DESC_INPUT | OHCI_DESC_STATUS | 971 OHCI_DESC_INTR_ALWAYS | OHCI_DESC_BRANCH; 972 fd->fd_reqcount = fb->fb_dmamap->dm_segs[0].ds_len; 973 fd->fd_data = fb->fb_dmamap->dm_segs[0].ds_addr; 974 TAILQ_INSERT_TAIL(&fc->fc_buf, fb, fb_list); 975 } 976 #if DOUBLEBUF 977 if (ctxtype == FWOHCI_CTX_ISO_MULTI) { 978 for (i = bufcnt; i < bufcnt + buf2cnt; i++, fb++) { 979 if ((error = fwohci_buf_alloc(sc, fb)) != 0) 980 goto fail; 981 if ((fd = fwohci_desc_get(sc, 1)) == NULL) { 982 error = ENOBUFS; 983 goto fail; 984 } 985 fb->fb_desc = fd; 986 fb->fb_daddr = sc->sc_ddmamap->dm_segs[0].ds_addr + 987 ((caddr_t)fd - (caddr_t)sc->sc_desc); 988 bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap, 989 (caddr_t)fd - (caddr_t)sc->sc_desc, sizeof(struct fwohci_desc), 990 BUS_DMASYNC_PREWRITE); 991 fd->fd_flags = OHCI_DESC_INPUT | OHCI_DESC_STATUS | 992 OHCI_DESC_INTR_ALWAYS | OHCI_DESC_BRANCH; 993 fd->fd_reqcount = fb->fb_dmamap->dm_segs[0].ds_len; 994 fd->fd_data = fb->fb_dmamap->dm_segs[0].ds_addr; 995 TAILQ_INSERT_TAIL(&fc->fc_buf2, fb, fb_list); 996 bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap, 997 (caddr_t)fd - (caddr_t)sc->sc_desc, sizeof(struct fwohci_desc), 998 BUS_DMASYNC_POSTWRITE); 999 } 1000 } 1001 #endif /* DOUBLEBUF */ 1002 fc->fc_type = ctxtype; 1003 *fcp = fc; 1004 return 0; 1005 1006 fail: 1007 while (i-- > 0) { 1008 fb--; 1009 if (fb->fb_desc) 1010 fwohci_desc_put(sc, fb->fb_desc, 1); 1011 fwohci_buf_free(sc, fb); 1012 } 1013 free(fc, M_DEVBUF); 1014 return error; 1015 } 1016 1017 static void 1018 fwohci_ctx_free(struct fwohci_softc *sc, struct fwohci_ctx *fc) 1019 { 1020 struct fwohci_buf *fb; 1021 struct fwohci_handler *fh; 1022 1023 while ((fh = LIST_FIRST(&fc->fc_handler)) != NULL) 1024 fwohci_handler_set(sc, fh->fh_tcode, fh->fh_key1, fh->fh_key2, 1025 NULL, NULL); 1026 while ((fb = TAILQ_FIRST(&fc->fc_buf)) != NULL) { 1027 TAILQ_REMOVE(&fc->fc_buf, fb, fb_list); 1028 if (fb->fb_desc) 1029 fwohci_desc_put(sc, fb->fb_desc, 1); 1030 fwohci_buf_free(sc, fb); 1031 } 1032 #if DOUBLEBUF 1033 while ((fb = TAILQ_FIRST(&fc->fc_buf2)) != NULL) { 1034 TAILQ_REMOVE(&fc->fc_buf2, fb, fb_list); 1035 if (fb->fb_desc) 1036 fwohci_desc_put(sc, fb->fb_desc, 1); 1037 fwohci_buf_free(sc, fb); 1038 } 1039 #endif /* DOUBLEBUF */ 1040 free(fc, M_DEVBUF); 1041 } 1042 1043 static void 1044 fwohci_ctx_init(struct fwohci_softc *sc, struct fwohci_ctx *fc) 1045 { 1046 struct fwohci_buf *fb, *nfb; 1047 struct fwohci_desc *fd; 1048 struct fwohci_handler *fh; 1049 int n; 1050 1051 for (fb = TAILQ_FIRST(&fc->fc_buf); fb != NULL; fb = nfb) { 1052 nfb = TAILQ_NEXT(fb, fb_list); 1053 fb->fb_off = 0; 1054 fd = fb->fb_desc; 1055 fd->fd_branch = (nfb != NULL) ? (nfb->fb_daddr | 1) : 0; 1056 fd->fd_rescount = fd->fd_reqcount; 1057 } 1058 1059 #if DOUBLEBUF 1060 for (fb = TAILQ_FIRST(&fc->fc_buf2); fb != NULL; fb = nfb) { 1061 bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap, 1062 (caddr_t)fd - (caddr_t)sc->sc_desc, sizeof(struct fwohci_desc), 1063 BUS_DMASYNC_PREWRITE); 1064 nfb = TAILQ_NEXT(fb, fb_list); 1065 fb->fb_off = 0; 1066 fd = fb->fb_desc; 1067 fd->fd_branch = (nfb != NULL) ? (nfb->fb_daddr | 1) : 0; 1068 fd->fd_rescount = fd->fd_reqcount; 1069 bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap, 1070 (caddr_t)fd - (caddr_t)sc->sc_desc, sizeof(struct fwohci_desc), 1071 BUS_DMASYNC_POSTWRITE); 1072 } 1073 #endif /* DOUBLEBUF */ 1074 1075 n = fc->fc_ctx; 1076 fb = TAILQ_FIRST(&fc->fc_buf); 1077 if (fc->fc_type != FWOHCI_CTX_ASYNC) { 1078 OHCI_SYNC_RX_DMA_WRITE(sc, n, OHCI_SUBREG_CommandPtr, 1079 fb->fb_daddr | 1); 1080 OHCI_SYNC_RX_DMA_WRITE(sc, n, OHCI_SUBREG_ContextControlClear, 1081 OHCI_CTXCTL_RX_BUFFER_FILL | 1082 OHCI_CTXCTL_RX_CYCLE_MATCH_ENABLE | 1083 OHCI_CTXCTL_RX_MULTI_CHAN_MODE | 1084 OHCI_CTXCTL_RX_DUAL_BUFFER_MODE); 1085 OHCI_SYNC_RX_DMA_WRITE(sc, n, OHCI_SUBREG_ContextControlSet, 1086 OHCI_CTXCTL_RX_ISOCH_HEADER); 1087 if (fc->fc_type == FWOHCI_CTX_ISO_MULTI) { 1088 OHCI_SYNC_RX_DMA_WRITE(sc, n, 1089 OHCI_SUBREG_ContextControlSet, 1090 OHCI_CTXCTL_RX_BUFFER_FILL); 1091 } 1092 fh = LIST_FIRST(&fc->fc_handler); 1093 OHCI_SYNC_RX_DMA_WRITE(sc, n, OHCI_SUBREG_ContextMatch, 1094 (OHCI_CTXMATCH_TAG0 << fh->fh_key2) | fh->fh_key1); 1095 } else { 1096 OHCI_ASYNC_DMA_WRITE(sc, n, OHCI_SUBREG_CommandPtr, 1097 fb->fb_daddr | 1); 1098 } 1099 } 1100 1101 /* 1102 * DMA data buffer 1103 */ 1104 static int 1105 fwohci_buf_alloc(struct fwohci_softc *sc, struct fwohci_buf *fb) 1106 { 1107 int error; 1108 1109 if ((error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE, 1110 PAGE_SIZE, &fb->fb_seg, 1, &fb->fb_nseg, BUS_DMA_WAITOK)) != 0) { 1111 printf("%s: unable to allocate buffer, error = %d\n", 1112 sc->sc_sc1394.sc1394_dev.dv_xname, error); 1113 goto fail_0; 1114 } 1115 1116 if ((error = bus_dmamem_map(sc->sc_dmat, &fb->fb_seg, 1117 fb->fb_nseg, PAGE_SIZE, &fb->fb_buf, BUS_DMA_WAITOK)) != 0) { 1118 printf("%s: unable to map buffer, error = %d\n", 1119 sc->sc_sc1394.sc1394_dev.dv_xname, error); 1120 goto fail_1; 1121 } 1122 1123 if ((error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, fb->fb_nseg, 1124 PAGE_SIZE, 0, BUS_DMA_WAITOK, &fb->fb_dmamap)) != 0) { 1125 printf("%s: unable to create buffer DMA map, " 1126 "error = %d\n", sc->sc_sc1394.sc1394_dev.dv_xname, 1127 error); 1128 goto fail_2; 1129 } 1130 1131 if ((error = bus_dmamap_load(sc->sc_dmat, fb->fb_dmamap, 1132 fb->fb_buf, PAGE_SIZE, NULL, BUS_DMA_WAITOK)) != 0) { 1133 printf("%s: unable to load buffer DMA map, " 1134 "error = %d\n", sc->sc_sc1394.sc1394_dev.dv_xname, 1135 error); 1136 goto fail_3; 1137 } 1138 1139 return 0; 1140 1141 bus_dmamap_unload(sc->sc_dmat, fb->fb_dmamap); 1142 fail_3: 1143 bus_dmamap_destroy(sc->sc_dmat, fb->fb_dmamap); 1144 fail_2: 1145 bus_dmamem_unmap(sc->sc_dmat, fb->fb_buf, PAGE_SIZE); 1146 fail_1: 1147 bus_dmamem_free(sc->sc_dmat, &fb->fb_seg, fb->fb_nseg); 1148 fail_0: 1149 return error; 1150 } 1151 1152 static void 1153 fwohci_buf_free(struct fwohci_softc *sc, struct fwohci_buf *fb) 1154 { 1155 1156 bus_dmamap_unload(sc->sc_dmat, fb->fb_dmamap); 1157 bus_dmamap_destroy(sc->sc_dmat, fb->fb_dmamap); 1158 bus_dmamem_unmap(sc->sc_dmat, fb->fb_buf, PAGE_SIZE); 1159 bus_dmamem_free(sc->sc_dmat, &fb->fb_seg, fb->fb_nseg); 1160 } 1161 1162 static void 1163 fwohci_buf_init_rx(struct fwohci_softc *sc) 1164 { 1165 int i; 1166 1167 /* 1168 * Initialize for Asynchronous Receive Queue. 1169 */ 1170 fwohci_ctx_init(sc, sc->sc_ctx_arrq); 1171 fwohci_ctx_init(sc, sc->sc_ctx_arrs); 1172 1173 /* 1174 * Initialize for Isochronous Receive Queue. 1175 */ 1176 for (i = 0; i < sc->sc_isoctx; i++) { 1177 if (sc->sc_ctx_ir[i] != NULL) 1178 fwohci_ctx_init(sc, sc->sc_ctx_ir[i]); 1179 } 1180 } 1181 1182 static void 1183 fwohci_buf_start_rx(struct fwohci_softc *sc) 1184 { 1185 int i; 1186 1187 OHCI_ASYNC_DMA_WRITE(sc, OHCI_CTX_ASYNC_RX_REQUEST, 1188 OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_RUN); 1189 OHCI_ASYNC_DMA_WRITE(sc, OHCI_CTX_ASYNC_RX_RESPONSE, 1190 OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_RUN); 1191 for (i = 0; i < sc->sc_isoctx; i++) { 1192 if (sc->sc_ctx_ir[i] != NULL) 1193 OHCI_SYNC_RX_DMA_WRITE(sc, i, 1194 OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_RUN); 1195 } 1196 } 1197 1198 static void 1199 fwohci_buf_stop_tx(struct fwohci_softc *sc) 1200 { 1201 int i; 1202 1203 OHCI_ASYNC_DMA_WRITE(sc, OHCI_CTX_ASYNC_TX_REQUEST, 1204 OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN); 1205 OHCI_ASYNC_DMA_WRITE(sc, OHCI_CTX_ASYNC_TX_RESPONSE, 1206 OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN); 1207 1208 /* 1209 * Make sure the transmitter is stopped. 1210 */ 1211 for (i = 0; i < OHCI_LOOP; i++) { 1212 DELAY(10); 1213 if (OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_TX_REQUEST, 1214 OHCI_SUBREG_ContextControlClear) & OHCI_CTXCTL_ACTIVE) 1215 continue; 1216 if (OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_TX_RESPONSE, 1217 OHCI_SUBREG_ContextControlClear) & OHCI_CTXCTL_ACTIVE) 1218 continue; 1219 break; 1220 } 1221 1222 /* 1223 * Initialize for Asynchronous Transmit Queue. 1224 */ 1225 fwohci_at_done(sc, sc->sc_ctx_atrq, 1); 1226 fwohci_at_done(sc, sc->sc_ctx_atrs, 1); 1227 } 1228 1229 static void 1230 fwohci_buf_stop_rx(struct fwohci_softc *sc) 1231 { 1232 int i; 1233 1234 OHCI_ASYNC_DMA_WRITE(sc, OHCI_CTX_ASYNC_RX_REQUEST, 1235 OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN); 1236 OHCI_ASYNC_DMA_WRITE(sc, OHCI_CTX_ASYNC_RX_RESPONSE, 1237 OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN); 1238 for (i = 0; i < sc->sc_isoctx; i++) { 1239 OHCI_SYNC_RX_DMA_WRITE(sc, i, 1240 OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN); 1241 } 1242 } 1243 1244 static void 1245 fwohci_buf_next(struct fwohci_softc *sc, struct fwohci_ctx *fc) 1246 { 1247 struct fwohci_buf *fb, *tfb; 1248 1249 #if DOUBLEBUF 1250 if (fc->fc_type != FWOHCI_CTX_ISO_MULTI) { 1251 #endif 1252 while ((fb = TAILQ_FIRST(&fc->fc_buf)) != NULL) { 1253 if (fc->fc_type) { 1254 if (fb->fb_off == 0) 1255 break; 1256 } else { 1257 if (fb->fb_off != fb->fb_desc->fd_reqcount || 1258 fb->fb_desc->fd_rescount != 0) 1259 break; 1260 } 1261 TAILQ_REMOVE(&fc->fc_buf, fb, fb_list); 1262 fb->fb_desc->fd_rescount = fb->fb_desc->fd_reqcount; 1263 fb->fb_off = 0; 1264 fb->fb_desc->fd_branch = 0; 1265 tfb = TAILQ_LAST(&fc->fc_buf, fwohci_buf_s); 1266 tfb->fb_desc->fd_branch = fb->fb_daddr | 1; 1267 TAILQ_INSERT_TAIL(&fc->fc_buf, fb, fb_list); 1268 } 1269 #if DOUBLEBUF 1270 } else { 1271 struct fwohci_buf_s fctmp; 1272 1273 /* cleaning buffer */ 1274 for (fb = TAILQ_FIRST(&fc->fc_buf); fb != NULL; 1275 fb = TAILQ_NEXT(fb, fb_list)) { 1276 fb->fb_off = 0; 1277 fb->fb_desc->fd_rescount = fb->fb_desc->fd_reqcount; 1278 } 1279 1280 /* rotating buffer */ 1281 fctmp = fc->fc_buf; 1282 fc->fc_buf = fc->fc_buf2; 1283 fc->fc_buf2 = fctmp; 1284 } 1285 #endif 1286 } 1287 1288 static int 1289 fwohci_buf_pktget(struct fwohci_softc *sc, struct fwohci_buf **fbp, caddr_t *pp, 1290 int len) 1291 { 1292 struct fwohci_buf *fb; 1293 struct fwohci_desc *fd; 1294 int bufend; 1295 1296 fb = *fbp; 1297 again: 1298 fd = fb->fb_desc; 1299 DPRINTFN(1, ("fwohci_buf_pktget: desc %ld, off %d, req %d, res %d," 1300 " len %d, avail %d\n", (long)(fd - sc->sc_desc), fb->fb_off, 1301 fd->fd_reqcount, fd->fd_rescount, len, 1302 fd->fd_reqcount - fd->fd_rescount - fb->fb_off)); 1303 bufend = fd->fd_reqcount - fd->fd_rescount; 1304 if (fb->fb_off >= bufend) { 1305 DPRINTFN(5, ("buf %x finish req %d res %d off %d ", 1306 fb->fb_desc->fd_data, fd->fd_reqcount, fd->fd_rescount, 1307 fb->fb_off)); 1308 if (fd->fd_rescount == 0) { 1309 *fbp = fb = TAILQ_NEXT(fb, fb_list); 1310 if (fb != NULL) 1311 goto again; 1312 } 1313 return 0; 1314 } 1315 if (fb->fb_off + len > bufend) 1316 len = bufend - fb->fb_off; 1317 bus_dmamap_sync(sc->sc_dmat, fb->fb_dmamap, fb->fb_off, len, 1318 BUS_DMASYNC_POSTREAD); 1319 *pp = fb->fb_buf + fb->fb_off; 1320 fb->fb_off += roundup(len, 4); 1321 return len; 1322 } 1323 1324 static int 1325 fwohci_buf_input(struct fwohci_softc *sc, struct fwohci_ctx *fc, 1326 struct fwohci_pkt *pkt) 1327 { 1328 caddr_t p; 1329 struct fwohci_buf *fb; 1330 int len, count, i; 1331 1332 memset(pkt, 0, sizeof(*pkt)); 1333 pkt->fp_uio.uio_iov = pkt->fp_iov; 1334 pkt->fp_uio.uio_rw = UIO_WRITE; 1335 pkt->fp_uio.uio_segflg = UIO_SYSSPACE; 1336 1337 /* get first quadlet */ 1338 fb = TAILQ_FIRST(&fc->fc_buf); 1339 count = 4; 1340 len = fwohci_buf_pktget(sc, &fb, &p, count); 1341 if (len <= 0) { 1342 DPRINTFN(1, ("fwohci_buf_input: no input for %d\n", 1343 fc->fc_ctx)); 1344 return 0; 1345 } 1346 pkt->fp_hdr[0] = *(u_int32_t *)p; 1347 pkt->fp_tcode = (pkt->fp_hdr[0] & 0x000000f0) >> 4; 1348 switch (pkt->fp_tcode) { 1349 case IEEE1394_TCODE_WRITE_REQ_QUAD: 1350 case IEEE1394_TCODE_READ_RESP_QUAD: 1351 pkt->fp_hlen = 12; 1352 pkt->fp_dlen = 4; 1353 break; 1354 case IEEE1394_TCODE_READ_REQ_BLOCK: 1355 pkt->fp_hlen = 16; 1356 pkt->fp_dlen = 0; 1357 break; 1358 case IEEE1394_TCODE_WRITE_REQ_BLOCK: 1359 case IEEE1394_TCODE_READ_RESP_BLOCK: 1360 case IEEE1394_TCODE_LOCK_REQ: 1361 case IEEE1394_TCODE_LOCK_RESP: 1362 pkt->fp_hlen = 16; 1363 break; 1364 case IEEE1394_TCODE_STREAM_DATA: 1365 #ifdef DIAGNOSTIC 1366 if (fc->fc_type == FWOHCI_CTX_ISO_MULTI) 1367 #endif 1368 { 1369 pkt->fp_hlen = 4; 1370 pkt->fp_dlen = pkt->fp_hdr[0] >> 16; 1371 DPRINTFN(5, ("[%d]", pkt->fp_dlen)); 1372 break; 1373 } 1374 #ifdef DIAGNOSTIC 1375 else { 1376 printf("fwohci_buf_input: bad tcode: STREAM_DATA\n"); 1377 return 0; 1378 } 1379 #endif 1380 default: 1381 pkt->fp_hlen = 12; 1382 pkt->fp_dlen = 0; 1383 break; 1384 } 1385 1386 /* get header */ 1387 while (count < pkt->fp_hlen) { 1388 len = fwohci_buf_pktget(sc, &fb, &p, pkt->fp_hlen - count); 1389 if (len == 0) { 1390 printf("fwohci_buf_input: malformed input 1: %d\n", 1391 pkt->fp_hlen - count); 1392 return 0; 1393 } 1394 memcpy((caddr_t)pkt->fp_hdr + count, p, len); 1395 count += len; 1396 } 1397 if (pkt->fp_hlen == 16 && 1398 pkt->fp_tcode != IEEE1394_TCODE_READ_REQ_BLOCK) 1399 pkt->fp_dlen = pkt->fp_hdr[3] >> 16; 1400 DPRINTFN(1, ("fwohci_buf_input: tcode=0x%x, hlen=%d, dlen=%d\n", 1401 pkt->fp_tcode, pkt->fp_hlen, pkt->fp_dlen)); 1402 1403 /* get data */ 1404 count = 0; 1405 i = 0; 1406 while (count < pkt->fp_dlen) { 1407 len = fwohci_buf_pktget(sc, &fb, 1408 (caddr_t *)&pkt->fp_iov[i].iov_base, 1409 pkt->fp_dlen - count); 1410 if (len == 0) { 1411 printf("fwohci_buf_input: malformed input 2: %d\n", 1412 pkt->fp_dlen - count); 1413 return 0; 1414 } 1415 pkt->fp_iov[i++].iov_len = len; 1416 count += len; 1417 } 1418 pkt->fp_uio.uio_iovcnt = i; 1419 pkt->fp_uio.uio_resid = count; 1420 1421 /* get trailer */ 1422 len = fwohci_buf_pktget(sc, &fb, (caddr_t *)&pkt->fp_trail, 1423 sizeof(*pkt->fp_trail)); 1424 if (len <= 0) { 1425 printf("fwohci_buf_input: malformed input 3: %d\n", 1426 pkt->fp_hlen - count); 1427 return 0; 1428 } 1429 return 1; 1430 } 1431 1432 static int 1433 fwohci_buf_input_ppb(struct fwohci_softc *sc, struct fwohci_ctx *fc, 1434 struct fwohci_pkt *pkt) 1435 { 1436 caddr_t p; 1437 int len; 1438 struct fwohci_buf *fb; 1439 struct fwohci_desc *fd; 1440 1441 if (fc->fc_type == FWOHCI_CTX_ISO_MULTI) { 1442 return fwohci_buf_input(sc, fc, pkt); 1443 } 1444 1445 memset(pkt, 0, sizeof(*pkt)); 1446 pkt->fp_uio.uio_iov = pkt->fp_iov; 1447 pkt->fp_uio.uio_rw = UIO_WRITE; 1448 pkt->fp_uio.uio_segflg = UIO_SYSSPACE; 1449 1450 for (fb = TAILQ_FIRST(&fc->fc_buf); ; fb = TAILQ_NEXT(fb, fb_list)) { 1451 if (fb == NULL) 1452 return 0; 1453 if (fb->fb_off == 0) 1454 break; 1455 } 1456 fd = fb->fb_desc; 1457 len = fd->fd_reqcount - fd->fd_rescount; 1458 if (len == 0) 1459 return 0; 1460 bus_dmamap_sync(sc->sc_dmat, fb->fb_dmamap, fb->fb_off, len, 1461 BUS_DMASYNC_POSTREAD); 1462 1463 p = fb->fb_buf; 1464 fb->fb_off += roundup(len, 4); 1465 if (len < 8) { 1466 printf("fwohci_buf_input_ppb: malformed input 1: %d\n", len); 1467 return 0; 1468 } 1469 1470 /* 1471 * get trailer first, may be bogus data unless status update 1472 * in descriptor is set. 1473 */ 1474 pkt->fp_trail = (u_int32_t *)p; 1475 *pkt->fp_trail = (*pkt->fp_trail & 0xffff) | (fd->fd_status << 16); 1476 pkt->fp_hdr[0] = ((u_int32_t *)p)[1]; 1477 pkt->fp_tcode = (pkt->fp_hdr[0] & 0x000000f0) >> 4; 1478 #ifdef DIAGNOSTIC 1479 if (pkt->fp_tcode != IEEE1394_TCODE_STREAM_DATA) { 1480 printf("fwohci_buf_input_ppb: bad tcode: 0x%x\n", 1481 pkt->fp_tcode); 1482 return 0; 1483 } 1484 #endif 1485 pkt->fp_hlen = 4; 1486 pkt->fp_dlen = pkt->fp_hdr[0] >> 16; 1487 p += 8; 1488 len -= 8; 1489 if (pkt->fp_dlen != len) { 1490 printf("fwohci_buf_input_ppb: malformed input 2: %d != %d\n", 1491 pkt->fp_dlen, len); 1492 return 0; 1493 } 1494 DPRINTFN(1, ("fwohci_buf_input_ppb: tcode=0x%x, hlen=%d, dlen=%d\n", 1495 pkt->fp_tcode, pkt->fp_hlen, pkt->fp_dlen)); 1496 pkt->fp_iov[0].iov_base = p; 1497 pkt->fp_iov[0].iov_len = len; 1498 pkt->fp_uio.uio_iovcnt = 0; 1499 pkt->fp_uio.uio_resid = len; 1500 return 1; 1501 } 1502 1503 static int 1504 fwohci_handler_set(struct fwohci_softc *sc, 1505 int tcode, u_int32_t key1, u_int32_t key2, 1506 int (*handler)(struct fwohci_softc *, void *, struct fwohci_pkt *), 1507 void *arg) 1508 { 1509 struct fwohci_ctx *fc; 1510 struct fwohci_handler *fh; 1511 int i, j; 1512 1513 if (tcode == IEEE1394_TCODE_STREAM_DATA) { 1514 int isasync = key1 & OHCI_ASYNC_STREAM; 1515 1516 key1 &= IEEE1394_ISOCH_MASK; 1517 j = sc->sc_isoctx; 1518 fh = NULL; 1519 for (i = 0; i < sc->sc_isoctx; i++) { 1520 if ((fc = sc->sc_ctx_ir[i]) == NULL) { 1521 if (j == sc->sc_isoctx) 1522 j = i; 1523 continue; 1524 } 1525 fh = LIST_FIRST(&fc->fc_handler); 1526 if (fh->fh_tcode == tcode && 1527 fh->fh_key1 == key1 && fh->fh_key2 == key2) 1528 break; 1529 fh = NULL; 1530 } 1531 if (fh == NULL) { 1532 if (handler == NULL) 1533 return 0; 1534 if (j == sc->sc_isoctx) { 1535 DPRINTF(("fwohci_handler_set: no more free " 1536 "context\n")); 1537 return ENOMEM; 1538 } 1539 if ((fc = sc->sc_ctx_ir[j]) == NULL) { 1540 fwohci_ctx_alloc(sc, &fc, OHCI_BUF_IR_CNT, j, 1541 isasync ? FWOHCI_CTX_ISO_SINGLE : 1542 FWOHCI_CTX_ISO_MULTI); 1543 sc->sc_ctx_ir[j] = fc; 1544 } 1545 } 1546 } else { 1547 switch (tcode) { 1548 case IEEE1394_TCODE_WRITE_REQ_QUAD: 1549 case IEEE1394_TCODE_WRITE_REQ_BLOCK: 1550 case IEEE1394_TCODE_READ_REQ_QUAD: 1551 case IEEE1394_TCODE_READ_REQ_BLOCK: 1552 case IEEE1394_TCODE_LOCK_REQ: 1553 fc = sc->sc_ctx_arrq; 1554 break; 1555 case IEEE1394_TCODE_WRITE_RESP: 1556 case IEEE1394_TCODE_READ_RESP_QUAD: 1557 case IEEE1394_TCODE_READ_RESP_BLOCK: 1558 case IEEE1394_TCODE_LOCK_RESP: 1559 fc = sc->sc_ctx_arrs; 1560 break; 1561 default: 1562 return EIO; 1563 } 1564 for (fh = LIST_FIRST(&fc->fc_handler); fh != NULL; 1565 fh = LIST_NEXT(fh, fh_list)) { 1566 if (fh->fh_tcode == tcode && 1567 fh->fh_key1 == key1 && fh->fh_key2 == key2) 1568 break; 1569 } 1570 } 1571 if (handler == NULL) { 1572 if (fh != NULL) { 1573 LIST_REMOVE(fh, fh_list); 1574 free(fh, M_DEVBUF); 1575 } 1576 if (tcode == IEEE1394_TCODE_STREAM_DATA) { 1577 OHCI_SYNC_RX_DMA_WRITE(sc, fc->fc_ctx, 1578 OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN); 1579 sc->sc_ctx_ir[fc->fc_ctx] = NULL; 1580 fwohci_ctx_free(sc, fc); 1581 } 1582 return 0; 1583 } 1584 if (fh == NULL) { 1585 fh = malloc(sizeof(*fh), M_DEVBUF, M_WAITOK); 1586 LIST_INSERT_HEAD(&fc->fc_handler, fh, fh_list); 1587 } 1588 fh->fh_tcode = tcode; 1589 fh->fh_key1 = key1; 1590 fh->fh_key2 = key2; 1591 fh->fh_handler = handler; 1592 fh->fh_handarg = arg; 1593 DPRINTFN(1, ("fwohci_handler_set: ctx %d, tcode %x, key 0x%x, 0x%x\n", 1594 fc->fc_ctx, tcode, key1, key2)); 1595 1596 if (tcode == IEEE1394_TCODE_STREAM_DATA) { 1597 fwohci_ctx_init(sc, fc); 1598 DPRINTFN(1, ("fwohci_handler_set: SYNC desc %ld\n", 1599 (long)(TAILQ_FIRST(&fc->fc_buf)->fb_desc - sc->sc_desc))); 1600 OHCI_SYNC_RX_DMA_WRITE(sc, fc->fc_ctx, 1601 OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_RUN); 1602 } 1603 return 0; 1604 } 1605 1606 /* 1607 * Asyncronous Receive Requests input frontend. 1608 */ 1609 static void 1610 fwohci_arrq_input(struct fwohci_softc *sc, struct fwohci_ctx *fc) 1611 { 1612 int rcode; 1613 u_int32_t key1, key2; 1614 struct fwohci_handler *fh; 1615 struct fwohci_pkt pkt, res; 1616 1617 /* 1618 * Do not return if next packet is in the buffer, or the next 1619 * packet cannot be received until the next receive interrupt. 1620 */ 1621 while (fwohci_buf_input(sc, fc, &pkt)) { 1622 if (pkt.fp_tcode == OHCI_TCODE_PHY) { 1623 fwohci_phy_input(sc, &pkt); 1624 continue; 1625 } 1626 key1 = pkt.fp_hdr[1] & 0xffff; 1627 key2 = pkt.fp_hdr[2]; 1628 memset(&res, 0, sizeof(res)); 1629 res.fp_uio.uio_rw = UIO_WRITE; 1630 res.fp_uio.uio_segflg = UIO_SYSSPACE; 1631 for (fh = LIST_FIRST(&fc->fc_handler); fh != NULL; 1632 fh = LIST_NEXT(fh, fh_list)) { 1633 if (pkt.fp_tcode == fh->fh_tcode && 1634 key1 == fh->fh_key1 && 1635 key2 == fh->fh_key2) { 1636 rcode = (*fh->fh_handler)(sc, fh->fh_handarg, 1637 &pkt); 1638 break; 1639 } 1640 } 1641 if (fh == NULL) { 1642 rcode = IEEE1394_RCODE_ADDRESS_ERROR; 1643 DPRINTFN(1, ("fwohci_arrq_input: no listener: tcode " 1644 "0x%x, addr=0x%04x %08x\n", pkt.fp_tcode, key1, 1645 key2)); 1646 } 1647 if (((*pkt.fp_trail & 0x001f0000) >> 16) != 1648 OHCI_CTXCTL_EVENT_ACK_PENDING) 1649 continue; 1650 if (rcode != -1) 1651 fwohci_atrs_output(sc, rcode, &pkt, &res); 1652 } 1653 fwohci_buf_next(sc, fc); 1654 OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx, 1655 OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_WAKE); 1656 } 1657 1658 1659 /* 1660 * Asynchronous Receive Response input frontend. 1661 */ 1662 static void 1663 fwohci_arrs_input(struct fwohci_softc *sc, struct fwohci_ctx *fc) 1664 { 1665 struct fwohci_pkt pkt; 1666 struct fwohci_handler *fh; 1667 u_int16_t srcid; 1668 int rcode, tlabel; 1669 1670 while (fwohci_buf_input(sc, fc, &pkt)) { 1671 srcid = pkt.fp_hdr[1] >> 16; 1672 rcode = (pkt.fp_hdr[1] & 0x0000f000) >> 12; 1673 tlabel = (pkt.fp_hdr[0] & 0x0000fc00) >> 10; 1674 DPRINTFN(1, ("fwohci_arrs_input: tcode 0x%x, from 0x%04x," 1675 " tlabel 0x%x, rcode 0x%x, hlen %d, dlen %d\n", 1676 pkt.fp_tcode, srcid, tlabel, rcode, pkt.fp_hlen, 1677 pkt.fp_dlen)); 1678 for (fh = LIST_FIRST(&fc->fc_handler); fh != NULL; 1679 fh = LIST_NEXT(fh, fh_list)) { 1680 if (pkt.fp_tcode == fh->fh_tcode && 1681 (srcid & OHCI_NodeId_NodeNumber) == fh->fh_key1 && 1682 tlabel == fh->fh_key2) { 1683 (*fh->fh_handler)(sc, fh->fh_handarg, &pkt); 1684 LIST_REMOVE(fh, fh_list); 1685 free(fh, M_DEVBUF); 1686 break; 1687 } 1688 } 1689 if (fh == NULL) 1690 DPRINTFN(1, ("fwohci_arrs_input: no listner\n")); 1691 } 1692 fwohci_buf_next(sc, fc); 1693 OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx, 1694 OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_WAKE); 1695 } 1696 1697 /* 1698 * Isochronous Receive input frontend. 1699 */ 1700 static void 1701 fwohci_ir_input(struct fwohci_softc *sc, struct fwohci_ctx *fc) 1702 { 1703 int rcode, chan, tag; 1704 struct iovec *iov; 1705 struct fwohci_handler *fh; 1706 struct fwohci_pkt pkt; 1707 1708 #if DOUBLEBUF 1709 if (fc->fc_type == FWOHCI_CTX_ISO_MULTI) { 1710 struct fwohci_buf *fb; 1711 int i; 1712 u_int32_t reg; 1713 1714 /* stop dma engine before read buffer */ 1715 reg = OHCI_SYNC_RX_DMA_READ(sc, fc->fc_ctx, 1716 OHCI_SUBREG_ContextControlClear); 1717 DPRINTFN(5, ("ir_input %08x =>", reg)); 1718 if (reg & OHCI_CTXCTL_RUN) { 1719 OHCI_SYNC_RX_DMA_WRITE(sc, fc->fc_ctx, 1720 OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN); 1721 } 1722 DPRINTFN(5, (" %08x\n", OHCI_SYNC_RX_DMA_READ(sc, fc->fc_ctx, OHCI_SUBREG_ContextControlClear))); 1723 1724 i = 0; 1725 while ((reg = OHCI_SYNC_RX_DMA_READ(sc, fc->fc_ctx, OHCI_SUBREG_ContextControlSet)) & OHCI_CTXCTL_ACTIVE) { 1726 delay(10); 1727 if (++i > 10000) { 1728 printf("cannot stop dma engine 0x08x\n", reg); 1729 return; 1730 } 1731 } 1732 1733 /* rotate dma buffer */ 1734 fb = TAILQ_FIRST(&fc->fc_buf2); 1735 OHCI_SYNC_RX_DMA_WRITE(sc, fc->fc_ctx, OHCI_SUBREG_CommandPtr, 1736 fb->fb_daddr | 1); 1737 /* start dma engine */ 1738 OHCI_SYNC_RX_DMA_WRITE(sc, fc->fc_ctx, 1739 OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_RUN); 1740 OHCI_CSR_WRITE(sc, OHCI_REG_IsoRecvIntEventClear, 1741 (1 << fc->fc_ctx)); 1742 } 1743 #endif 1744 1745 while (fwohci_buf_input_ppb(sc, fc, &pkt)) { 1746 chan = (pkt.fp_hdr[0] & 0x00003f00) >> 8; 1747 tag = (pkt.fp_hdr[0] & 0x0000c000) >> 14; 1748 DPRINTFN(1, ("fwohci_ir_input: hdr 0x%08x, tcode %d, hlen %d, " 1749 "dlen %d\n", pkt.fp_hdr[0], pkt.fp_tcode, pkt.fp_hlen, 1750 pkt.fp_dlen)); 1751 if (tag == IEEE1394_TAG_GASP) { 1752 /* 1753 * The pkt with tag=3 is GASP format. 1754 * Move GASP header to header part. 1755 */ 1756 if (pkt.fp_dlen < 8) 1757 continue; 1758 iov = pkt.fp_iov; 1759 /* assuming pkt per buffer mode */ 1760 pkt.fp_hdr[1] = ntohl(((u_int32_t *)iov->iov_base)[0]); 1761 pkt.fp_hdr[2] = ntohl(((u_int32_t *)iov->iov_base)[1]); 1762 iov->iov_base = (caddr_t)iov->iov_base + 8; 1763 iov->iov_len -= 8; 1764 pkt.fp_hlen += 8; 1765 pkt.fp_dlen -= 8; 1766 } 1767 sc->sc_isopktcnt.ev_count++; 1768 for (fh = LIST_FIRST(&fc->fc_handler); fh != NULL; 1769 fh = LIST_NEXT(fh, fh_list)) { 1770 if (pkt.fp_tcode == fh->fh_tcode && 1771 chan == fh->fh_key1 && tag == fh->fh_key2) { 1772 rcode = (*fh->fh_handler)(sc, fh->fh_handarg, 1773 &pkt); 1774 break; 1775 } 1776 } 1777 #ifdef FW_DEBUG 1778 if (fh == NULL) { 1779 DPRINTFN(1, ("fwohci_ir_input: no handler\n")); 1780 } else { 1781 DPRINTFN(1, ("fwohci_ir_input: rcode %d\n", rcode)); 1782 } 1783 #endif 1784 } 1785 fwohci_buf_next(sc, fc); 1786 1787 if (fc->fc_type == FWOHCI_CTX_ISO_SINGLE) { 1788 OHCI_SYNC_RX_DMA_WRITE(sc, fc->fc_ctx, 1789 OHCI_SUBREG_ContextControlSet, 1790 OHCI_CTXCTL_WAKE); 1791 } 1792 } 1793 1794 /* 1795 * Asynchronous Transmit common routine. 1796 */ 1797 static int 1798 fwohci_at_output(struct fwohci_softc *sc, struct fwohci_ctx *fc, 1799 struct fwohci_pkt *pkt) 1800 { 1801 struct fwohci_buf *fb; 1802 struct fwohci_desc *fd; 1803 struct mbuf *m, *m0; 1804 int i, ndesc, error, off, len; 1805 u_int32_t val; 1806 #ifdef FW_DEBUG 1807 struct iovec *iov; 1808 #endif 1809 1810 if ((sc->sc_nodeid & OHCI_NodeId_NodeNumber) == IEEE1394_BCAST_PHY_ID) 1811 /* We can't send anything during selfid duration */ 1812 return EAGAIN; 1813 1814 #ifdef FW_DEBUG 1815 DPRINTFN(1, ("fwohci_at_output: tcode 0x%x, hlen %d, dlen %d", 1816 pkt->fp_tcode, pkt->fp_hlen, pkt->fp_dlen)); 1817 for (i = 0; i < pkt->fp_hlen/4; i++) 1818 DPRINTFN(2, ("%s%08x", i?" ":"\n ", pkt->fp_hdr[i])); 1819 DPRINTFN(2, ("$")); 1820 for (ndesc = 0, iov = pkt->fp_iov; 1821 ndesc < pkt->fp_uio.uio_iovcnt; ndesc++, iov++) { 1822 for (i = 0; i < iov->iov_len; i++) 1823 DPRINTFN(2, ("%s%02x", (i%32)?((i%4)?"":" "):"\n ", 1824 ((u_int8_t *)iov->iov_base)[i])); 1825 DPRINTFN(2, ("$")); 1826 } 1827 DPRINTFN(1, ("\n")); 1828 #endif 1829 1830 if ((m = pkt->fp_m) != NULL) { 1831 for (ndesc = 2; m != NULL; m = m->m_next) 1832 ndesc++; 1833 if (ndesc > OHCI_DESC_MAX) { 1834 m0 = NULL; 1835 ndesc = 2; 1836 for (off = 0; off < pkt->fp_dlen; off += len) { 1837 if (m0 == NULL) { 1838 MGETHDR(m0, M_DONTWAIT, MT_DATA); 1839 if (m0 != NULL) 1840 M_COPY_PKTHDR(m0, pkt->fp_m); 1841 m = m0; 1842 } else { 1843 MGET(m->m_next, M_DONTWAIT, MT_DATA); 1844 m = m->m_next; 1845 } 1846 if (m != NULL) 1847 MCLGET(m, M_DONTWAIT); 1848 if (m == NULL || (m->m_flags & M_EXT) == 0) { 1849 m_freem(m0); 1850 return ENOMEM; 1851 } 1852 len = pkt->fp_dlen - off; 1853 if (len > m->m_ext.ext_size) 1854 len = m->m_ext.ext_size; 1855 m_copydata(pkt->fp_m, off, len, 1856 mtod(m, caddr_t)); 1857 m->m_len = len; 1858 ndesc++; 1859 } 1860 m_freem(pkt->fp_m); 1861 pkt->fp_m = m0; 1862 } 1863 } else 1864 ndesc = 2 + pkt->fp_uio.uio_iovcnt; 1865 1866 if (ndesc > OHCI_DESC_MAX) 1867 return ENOBUFS; 1868 1869 if (fc->fc_bufcnt > 50) /*XXX*/ 1870 return ENOBUFS; 1871 fb = malloc(sizeof(*fb), M_DEVBUF, M_WAITOK); 1872 fb->fb_nseg = ndesc; 1873 fb->fb_desc = fwohci_desc_get(sc, ndesc); 1874 if (fb->fb_desc == NULL) { 1875 free(fb, M_DEVBUF); 1876 return ENOBUFS; 1877 } 1878 fb->fb_daddr = sc->sc_ddmamap->dm_segs[0].ds_addr + 1879 ((caddr_t)fb->fb_desc - (caddr_t)sc->sc_desc); 1880 fb->fb_m = pkt->fp_m; 1881 fb->fb_callback = pkt->fp_callback; 1882 fb->fb_statuscb = pkt->fp_statuscb; 1883 fb->fb_statusarg = pkt->fp_statusarg; 1884 1885 if (ndesc > 2) { 1886 if ((error = bus_dmamap_create(sc->sc_dmat, pkt->fp_dlen, ndesc, 1887 PAGE_SIZE, 0, BUS_DMA_WAITOK, &fb->fb_dmamap)) != 0) { 1888 fwohci_desc_put(sc, fb->fb_desc, ndesc); 1889 free(fb, M_DEVBUF); 1890 return error; 1891 } 1892 1893 if (pkt->fp_m != NULL) 1894 error = bus_dmamap_load_mbuf(sc->sc_dmat, fb->fb_dmamap, 1895 pkt->fp_m, BUS_DMA_WAITOK); 1896 else 1897 error = bus_dmamap_load_uio(sc->sc_dmat, fb->fb_dmamap, 1898 &pkt->fp_uio, BUS_DMA_WAITOK); 1899 if (error != 0) { 1900 bus_dmamap_destroy(sc->sc_dmat, fb->fb_dmamap); 1901 fwohci_desc_put(sc, fb->fb_desc, ndesc); 1902 free(fb, M_DEVBUF); 1903 return error; 1904 } 1905 bus_dmamap_sync(sc->sc_dmat, fb->fb_dmamap, 0, pkt->fp_dlen, 1906 BUS_DMASYNC_PREWRITE); 1907 } 1908 1909 fd = fb->fb_desc; 1910 fd->fd_flags = OHCI_DESC_IMMED; 1911 fd->fd_reqcount = pkt->fp_hlen; 1912 fd->fd_data = 0; 1913 fd->fd_branch = 0; 1914 fd->fd_status = 0; 1915 if (fc->fc_ctx == OHCI_CTX_ASYNC_TX_RESPONSE) { 1916 i = 3; /* XXX: 3 sec */ 1917 val = OHCI_CSR_READ(sc, OHCI_REG_IsochronousCycleTimer); 1918 fd->fd_timestamp = ((val >> 12) & 0x1fff) | 1919 ((((val >> 25) + i) & 0x7) << 13); 1920 } else 1921 fd->fd_timestamp = 0; 1922 memcpy(fd + 1, pkt->fp_hdr, pkt->fp_hlen); 1923 for (i = 0; i < ndesc - 2; i++) { 1924 fd = fb->fb_desc + 2 + i; 1925 fd->fd_flags = 0; 1926 fd->fd_reqcount = fb->fb_dmamap->dm_segs[i].ds_len; 1927 fd->fd_data = fb->fb_dmamap->dm_segs[i].ds_addr; 1928 fd->fd_branch = 0; 1929 fd->fd_status = 0; 1930 fd->fd_timestamp = 0; 1931 } 1932 fd->fd_flags |= OHCI_DESC_LAST | OHCI_DESC_BRANCH; 1933 fd->fd_flags |= OHCI_DESC_INTR_ALWAYS; 1934 1935 #ifdef FW_DEBUG 1936 DPRINTFN(1, ("fwohci_at_output: desc %ld", 1937 (long)(fb->fb_desc - sc->sc_desc))); 1938 for (i = 0; i < ndesc * 4; i++) 1939 DPRINTFN(2, ("%s%08x", i&7?" ":"\n ", 1940 ((u_int32_t *)fb->fb_desc)[i])); 1941 DPRINTFN(1, ("\n")); 1942 #endif 1943 1944 val = OHCI_ASYNC_DMA_READ(sc, fc->fc_ctx, 1945 OHCI_SUBREG_ContextControlClear); 1946 1947 if (val & OHCI_CTXCTL_RUN) { 1948 if (fc->fc_branch == NULL) { 1949 OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx, 1950 OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN); 1951 goto run; 1952 } 1953 *fc->fc_branch = fb->fb_daddr | ndesc; 1954 OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx, 1955 OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_WAKE); 1956 } else { 1957 run: 1958 OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx, 1959 OHCI_SUBREG_CommandPtr, fb->fb_daddr | ndesc); 1960 OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx, 1961 OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_RUN); 1962 } 1963 fc->fc_branch = &fd->fd_branch; 1964 1965 fc->fc_bufcnt++; 1966 TAILQ_INSERT_TAIL(&fc->fc_buf, fb, fb_list); 1967 pkt->fp_m = NULL; 1968 return 0; 1969 } 1970 1971 static void 1972 fwohci_at_done(struct fwohci_softc *sc, struct fwohci_ctx *fc, int force) 1973 { 1974 struct fwohci_buf *fb; 1975 struct fwohci_desc *fd; 1976 struct fwohci_pkt pkt; 1977 int i; 1978 1979 while ((fb = TAILQ_FIRST(&fc->fc_buf)) != NULL) { 1980 fd = fb->fb_desc; 1981 #ifdef FW_DEBUG 1982 DPRINTFN(1, ("fwohci_at_done: %sdesc %ld (%d)", 1983 force ? "force " : "", (long)(fd - sc->sc_desc), 1984 fb->fb_nseg)); 1985 for (i = 0; i < fb->fb_nseg * 4; i++) 1986 DPRINTFN(2, ("%s%08x", i&7?" ":"\n ", 1987 ((u_int32_t *)fd)[i])); 1988 DPRINTFN(1, ("\n")); 1989 #endif 1990 if (fb->fb_nseg > 2) 1991 fd += fb->fb_nseg - 1; 1992 if (!force && !(fd->fd_status & OHCI_CTXCTL_ACTIVE)) 1993 break; 1994 TAILQ_REMOVE(&fc->fc_buf, fb, fb_list); 1995 if (fc->fc_branch == &fd->fd_branch) { 1996 OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx, 1997 OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN); 1998 fc->fc_branch = NULL; 1999 for (i = 0; i < OHCI_LOOP; i++) { 2000 if (!(OHCI_ASYNC_DMA_READ(sc, fc->fc_ctx, 2001 OHCI_SUBREG_ContextControlClear) & 2002 OHCI_CTXCTL_ACTIVE)) 2003 break; 2004 DELAY(10); 2005 } 2006 } 2007 2008 if (fb->fb_statuscb) { 2009 memset(&pkt, 0, sizeof(pkt)); 2010 pkt.fp_status = fd->fd_status; 2011 memcpy(pkt.fp_hdr, fd + 1, sizeof(pkt.fp_hdr[0])); 2012 2013 /* Indicate this is just returning the status bits. */ 2014 pkt.fp_tcode = -1; 2015 (*fb->fb_statuscb)(sc, fb->fb_statusarg, &pkt); 2016 fb->fb_statuscb = NULL; 2017 fb->fb_statusarg = NULL; 2018 } 2019 fwohci_desc_put(sc, fb->fb_desc, fb->fb_nseg); 2020 if (fb->fb_nseg > 2) 2021 bus_dmamap_destroy(sc->sc_dmat, fb->fb_dmamap); 2022 fc->fc_bufcnt--; 2023 if (fb->fb_callback) { 2024 (*fb->fb_callback)(sc->sc_sc1394.sc1394_if, fb->fb_m); 2025 fb->fb_callback = NULL; 2026 } else if (fb->fb_m != NULL) 2027 m_freem(fb->fb_m); 2028 free(fb, M_DEVBUF); 2029 } 2030 } 2031 2032 /* 2033 * Asynchronous Transmit Reponse -- in response of request packet. 2034 */ 2035 static void 2036 fwohci_atrs_output(struct fwohci_softc *sc, int rcode, struct fwohci_pkt *req, 2037 struct fwohci_pkt *res) 2038 { 2039 2040 if (((*req->fp_trail & 0x001f0000) >> 16) != 2041 OHCI_CTXCTL_EVENT_ACK_PENDING) 2042 return; 2043 2044 res->fp_hdr[0] = (req->fp_hdr[0] & 0x0000fc00) | 0x00000100; 2045 res->fp_hdr[1] = (req->fp_hdr[1] & 0xffff0000) | (rcode << 12); 2046 switch (req->fp_tcode) { 2047 case IEEE1394_TCODE_WRITE_REQ_QUAD: 2048 case IEEE1394_TCODE_WRITE_REQ_BLOCK: 2049 res->fp_tcode = IEEE1394_TCODE_WRITE_RESP; 2050 res->fp_hlen = 12; 2051 break; 2052 case IEEE1394_TCODE_READ_REQ_QUAD: 2053 res->fp_tcode = IEEE1394_TCODE_READ_RESP_QUAD; 2054 res->fp_hlen = 16; 2055 res->fp_dlen = 0; 2056 if (res->fp_uio.uio_iovcnt == 1 && res->fp_iov[0].iov_len == 4) 2057 res->fp_hdr[3] = 2058 *(u_int32_t *)res->fp_iov[0].iov_base; 2059 res->fp_uio.uio_iovcnt = 0; 2060 break; 2061 case IEEE1394_TCODE_READ_REQ_BLOCK: 2062 case IEEE1394_TCODE_LOCK_REQ: 2063 if (req->fp_tcode == IEEE1394_TCODE_LOCK_REQ) 2064 res->fp_tcode = IEEE1394_TCODE_LOCK_RESP; 2065 else 2066 res->fp_tcode = IEEE1394_TCODE_READ_RESP_BLOCK; 2067 res->fp_hlen = 16; 2068 res->fp_dlen = res->fp_uio.uio_resid; 2069 res->fp_hdr[3] = res->fp_dlen << 16; 2070 break; 2071 } 2072 res->fp_hdr[0] |= (res->fp_tcode << 4); 2073 fwohci_at_output(sc, sc->sc_ctx_atrs, res); 2074 } 2075 2076 /* 2077 * APPLICATION LAYER SERVICES 2078 */ 2079 2080 /* 2081 * Retrieve Global UID from GUID ROM 2082 */ 2083 static int 2084 fwohci_guidrom_init(struct fwohci_softc *sc) 2085 { 2086 int i, n, off; 2087 u_int32_t val1, val2; 2088 2089 /* Extract the Global UID 2090 */ 2091 val1 = OHCI_CSR_READ(sc, OHCI_REG_GUIDHi); 2092 val2 = OHCI_CSR_READ(sc, OHCI_REG_GUIDLo); 2093 2094 if (val1 != 0 || val2 != 0) { 2095 sc->sc_sc1394.sc1394_guid[0] = (val1 >> 24) & 0xff; 2096 sc->sc_sc1394.sc1394_guid[1] = (val1 >> 16) & 0xff; 2097 sc->sc_sc1394.sc1394_guid[2] = (val1 >> 8) & 0xff; 2098 sc->sc_sc1394.sc1394_guid[3] = (val1 >> 0) & 0xff; 2099 sc->sc_sc1394.sc1394_guid[4] = (val2 >> 24) & 0xff; 2100 sc->sc_sc1394.sc1394_guid[5] = (val2 >> 16) & 0xff; 2101 sc->sc_sc1394.sc1394_guid[6] = (val2 >> 8) & 0xff; 2102 sc->sc_sc1394.sc1394_guid[7] = (val2 >> 0) & 0xff; 2103 } else { 2104 val1 = OHCI_CSR_READ(sc, OHCI_REG_Version); 2105 if ((val1 & OHCI_Version_GUID_ROM) == 0) 2106 return -1; 2107 OHCI_CSR_WRITE(sc, OHCI_REG_Guid_Rom, OHCI_Guid_AddrReset); 2108 for (i = 0; i < OHCI_LOOP; i++) { 2109 val1 = OHCI_CSR_READ(sc, OHCI_REG_Guid_Rom); 2110 if (!(val1 & OHCI_Guid_AddrReset)) 2111 break; 2112 DELAY(10); 2113 } 2114 off = OHCI_BITVAL(val1, OHCI_Guid_MiniROM) + 4; 2115 val2 = 0; 2116 for (n = 0; n < off + sizeof(sc->sc_sc1394.sc1394_guid); n++) { 2117 OHCI_CSR_WRITE(sc, OHCI_REG_Guid_Rom, 2118 OHCI_Guid_RdStart); 2119 for (i = 0; i < OHCI_LOOP; i++) { 2120 val1 = OHCI_CSR_READ(sc, OHCI_REG_Guid_Rom); 2121 if (!(val1 & OHCI_Guid_RdStart)) 2122 break; 2123 DELAY(10); 2124 } 2125 if (n < off) 2126 continue; 2127 val1 = OHCI_BITVAL(val1, OHCI_Guid_RdData); 2128 sc->sc_sc1394.sc1394_guid[n - off] = val1; 2129 val2 |= val1; 2130 } 2131 if (val2 == 0) 2132 return -1; 2133 } 2134 return 0; 2135 } 2136 2137 /* 2138 * Initialization for Configuration ROM (no DMA context) 2139 */ 2140 2141 #define CFR_MAXUNIT 20 2142 2143 struct configromctx { 2144 u_int32_t *ptr; 2145 int curunit; 2146 struct { 2147 u_int32_t *start; 2148 int length; 2149 u_int32_t *refer; 2150 int refunit; 2151 } unit[CFR_MAXUNIT]; 2152 }; 2153 2154 #define CFR_PUT_DATA4(cfr, d1, d2, d3, d4) \ 2155 (*(cfr)->ptr++ = (((d1)<<24) | ((d2)<<16) | ((d3)<<8) | (d4))) 2156 2157 #define CFR_PUT_DATA1(cfr, d) (*(cfr)->ptr++ = (d)) 2158 2159 #define CFR_PUT_VALUE(cfr, key, d) (*(cfr)->ptr++ = ((key)<<24) | (d)) 2160 2161 #define CFR_PUT_CRC(cfr, n) \ 2162 (*(cfr)->unit[n].start = ((cfr)->unit[n].length << 16) | \ 2163 fwohci_crc16((cfr)->unit[n].start + 1, (cfr)->unit[n].length)) 2164 2165 #define CFR_START_UNIT(cfr, n) \ 2166 do { \ 2167 if ((cfr)->unit[n].refer != NULL) { \ 2168 *(cfr)->unit[n].refer |= \ 2169 (cfr)->ptr - (cfr)->unit[n].refer; \ 2170 CFR_PUT_CRC(cfr, (cfr)->unit[n].refunit); \ 2171 } \ 2172 (cfr)->curunit = (n); \ 2173 (cfr)->unit[n].start = (cfr)->ptr++; \ 2174 } while (0 /* CONSTCOND */) 2175 2176 #define CFR_PUT_REFER(cfr, key, n) \ 2177 do { \ 2178 (cfr)->unit[n].refer = (cfr)->ptr; \ 2179 (cfr)->unit[n].refunit = (cfr)->curunit; \ 2180 *(cfr)->ptr++ = (key) << 24; \ 2181 } while (0 /* CONSTCOND */) 2182 2183 #define CFR_END_UNIT(cfr) \ 2184 do { \ 2185 (cfr)->unit[(cfr)->curunit].length = (cfr)->ptr - \ 2186 ((cfr)->unit[(cfr)->curunit].start + 1); \ 2187 CFR_PUT_CRC(cfr, (cfr)->curunit); \ 2188 } while (0 /* CONSTCOND */) 2189 2190 static u_int16_t 2191 fwohci_crc16(u_int32_t *ptr, int len) 2192 { 2193 int shift; 2194 u_int32_t crc, sum, data; 2195 2196 crc = 0; 2197 while (len-- > 0) { 2198 data = *ptr++; 2199 for (shift = 28; shift >= 0; shift -= 4) { 2200 sum = ((crc >> 12) ^ (data >> shift)) & 0x000f; 2201 crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ sum; 2202 } 2203 crc &= 0xffff; 2204 } 2205 return crc; 2206 } 2207 2208 static void 2209 fwohci_configrom_init(struct fwohci_softc *sc) 2210 { 2211 int i, val; 2212 struct fwohci_buf *fb; 2213 u_int32_t *hdr; 2214 struct configromctx cfr; 2215 2216 fb = &sc->sc_buf_cnfrom; 2217 memset(&cfr, 0, sizeof(cfr)); 2218 cfr.ptr = hdr = (u_int32_t *)fb->fb_buf; 2219 2220 /* headers */ 2221 CFR_START_UNIT(&cfr, 0); 2222 CFR_PUT_DATA1(&cfr, OHCI_CSR_READ(sc, OHCI_REG_BusId)); 2223 CFR_PUT_DATA1(&cfr, OHCI_CSR_READ(sc, OHCI_REG_BusOptions)); 2224 CFR_PUT_DATA1(&cfr, OHCI_CSR_READ(sc, OHCI_REG_GUIDHi)); 2225 CFR_PUT_DATA1(&cfr, OHCI_CSR_READ(sc, OHCI_REG_GUIDLo)); 2226 CFR_END_UNIT(&cfr); 2227 /* copy info_length from crc_length */ 2228 *hdr |= (*hdr & 0x00ff0000) << 8; 2229 OHCI_CSR_WRITE(sc, OHCI_REG_ConfigROMhdr, *hdr); 2230 2231 /* root directory */ 2232 CFR_START_UNIT(&cfr, 1); 2233 CFR_PUT_VALUE(&cfr, 0x03, 0x00005e); /* vendor id */ 2234 CFR_PUT_REFER(&cfr, 0x81, 2); /* textual descriptor offset */ 2235 CFR_PUT_VALUE(&cfr, 0x0c, 0x0083c0); /* node capability */ 2236 /* spt,64,fix,lst,drq */ 2237 #ifdef INET 2238 CFR_PUT_REFER(&cfr, 0xd1, 3); /* IPv4 unit directory */ 2239 #endif /* INET */ 2240 #ifdef INET6 2241 CFR_PUT_REFER(&cfr, 0xd1, 4); /* IPv6 unit directory */ 2242 #endif /* INET6 */ 2243 CFR_END_UNIT(&cfr); 2244 2245 CFR_START_UNIT(&cfr, 2); 2246 CFR_PUT_VALUE(&cfr, 0, 0); /* textual descriptor */ 2247 CFR_PUT_DATA1(&cfr, 0); /* minimal ASCII */ 2248 CFR_PUT_DATA4(&cfr, 'N', 'e', 't', 'B'); 2249 CFR_PUT_DATA4(&cfr, 'S', 'D', 0x00, 0x00); 2250 CFR_END_UNIT(&cfr); 2251 2252 #ifdef INET 2253 /* IPv4 unit directory */ 2254 CFR_START_UNIT(&cfr, 3); 2255 CFR_PUT_VALUE(&cfr, 0x12, 0x00005e); /* unit spec id */ 2256 CFR_PUT_REFER(&cfr, 0x81, 6); /* textual descriptor offset */ 2257 CFR_PUT_VALUE(&cfr, 0x13, 0x000001); /* unit sw version */ 2258 CFR_PUT_REFER(&cfr, 0x81, 7); /* textual descriptor offset */ 2259 CFR_END_UNIT(&cfr); 2260 2261 CFR_START_UNIT(&cfr, 6); 2262 CFR_PUT_VALUE(&cfr, 0, 0); /* textual descriptor */ 2263 CFR_PUT_DATA1(&cfr, 0); /* minimal ASCII */ 2264 CFR_PUT_DATA4(&cfr, 'I', 'A', 'N', 'A'); 2265 CFR_END_UNIT(&cfr); 2266 2267 CFR_START_UNIT(&cfr, 7); 2268 CFR_PUT_VALUE(&cfr, 0, 0); /* textual descriptor */ 2269 CFR_PUT_DATA1(&cfr, 0); /* minimal ASCII */ 2270 CFR_PUT_DATA4(&cfr, 'I', 'P', 'v', '4'); 2271 CFR_END_UNIT(&cfr); 2272 #endif /* INET */ 2273 2274 #ifdef INET6 2275 /* IPv6 unit directory */ 2276 CFR_START_UNIT(&cfr, 4); 2277 CFR_PUT_VALUE(&cfr, 0x12, 0x00005e); /* unit spec id */ 2278 CFR_PUT_REFER(&cfr, 0x81, 8); /* textual descriptor offset */ 2279 CFR_PUT_VALUE(&cfr, 0x13, 0x000002); /* unit sw version */ 2280 /* XXX: TBA by IANA */ 2281 CFR_PUT_REFER(&cfr, 0x81, 9); /* textual descriptor offset */ 2282 CFR_END_UNIT(&cfr); 2283 2284 CFR_START_UNIT(&cfr, 8); 2285 CFR_PUT_VALUE(&cfr, 0, 0); /* textual descriptor */ 2286 CFR_PUT_DATA1(&cfr, 0); /* minimal ASCII */ 2287 CFR_PUT_DATA4(&cfr, 'I', 'A', 'N', 'A'); 2288 CFR_END_UNIT(&cfr); 2289 2290 CFR_START_UNIT(&cfr, 9); 2291 CFR_PUT_VALUE(&cfr, 0, 0); /* textual descriptor */ 2292 CFR_PUT_DATA1(&cfr, 0); 2293 CFR_PUT_DATA4(&cfr, 'I', 'P', 'v', '6'); 2294 CFR_END_UNIT(&cfr); 2295 #endif /* INET6 */ 2296 2297 fb->fb_off = cfr.ptr - hdr; 2298 #ifdef FW_DEBUG 2299 DPRINTFN(2, ("%s: Config ROM:", sc->sc_sc1394.sc1394_dev.dv_xname)); 2300 for (i = 0; i < fb->fb_off; i++) 2301 DPRINTFN(2, ("%s%08x", i&7?" ":"\n ", hdr[i])); 2302 DPRINTFN(2, ("\n")); 2303 #endif /* FW_DEBUG */ 2304 2305 /* 2306 * Make network byte order for DMA 2307 */ 2308 for (i = 0; i < fb->fb_off; i++) 2309 HTONL(hdr[i]); 2310 bus_dmamap_sync(sc->sc_dmat, fb->fb_dmamap, 0, 2311 (caddr_t)cfr.ptr - fb->fb_buf, BUS_DMASYNC_PREWRITE); 2312 2313 OHCI_CSR_WRITE(sc, OHCI_REG_ConfigROMmap, 2314 fb->fb_dmamap->dm_segs[0].ds_addr); 2315 2316 /* This register is only valid on OHCI 1.1. */ 2317 val = OHCI_CSR_READ(sc, OHCI_REG_Version); 2318 if ((OHCI_Version_GET_Version(val) == 1) && 2319 (OHCI_Version_GET_Revision(val) == 1)) 2320 OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet, 2321 OHCI_HCControl_BIBImageValid); 2322 2323 /* Just allow quad reads of the rom. */ 2324 for (i = 0; i < fb->fb_off; i++) 2325 fwohci_handler_set(sc, IEEE1394_TCODE_READ_REQ_QUAD, 2326 CSR_BASE_HI, CSR_BASE_LO + CSR_CONFIG_ROM + (i * 4), 2327 fwohci_configrom_input, NULL); 2328 } 2329 2330 static int 2331 fwohci_configrom_input(struct fwohci_softc *sc, void *arg, 2332 struct fwohci_pkt *pkt) 2333 { 2334 struct fwohci_pkt res; 2335 u_int32_t loc, *rom; 2336 2337 /* This will be used as an array index so size accordingly. */ 2338 loc = pkt->fp_hdr[2] - (CSR_BASE_LO + CSR_CONFIG_ROM); 2339 if ((loc & 0x03) != 0) { 2340 /* alignment error */ 2341 return IEEE1394_RCODE_ADDRESS_ERROR; 2342 } 2343 else 2344 loc /= 4; 2345 rom = (u_int32_t *)sc->sc_buf_cnfrom.fb_buf; 2346 2347 DPRINTFN(1, ("fwohci_configrom_input: ConfigRom[0x%04x]: 0x%08x\n", loc, 2348 ntohl(rom[loc]))); 2349 2350 memset(&res, 0, sizeof(res)); 2351 res.fp_hdr[3] = rom[loc]; 2352 fwohci_atrs_output(sc, IEEE1394_RCODE_COMPLETE, pkt, &res); 2353 return -1; 2354 } 2355 2356 /* 2357 * SelfID buffer (no DMA context) 2358 */ 2359 static void 2360 fwohci_selfid_init(struct fwohci_softc *sc) 2361 { 2362 struct fwohci_buf *fb; 2363 2364 fb = &sc->sc_buf_selfid; 2365 #ifdef DIAGNOSTIC 2366 if ((fb->fb_dmamap->dm_segs[0].ds_addr & 0x7ff) != 0) 2367 panic("fwohci_selfid_init: not aligned: %p (%ld) %p", 2368 (caddr_t)fb->fb_dmamap->dm_segs[0].ds_addr, 2369 (unsigned long)fb->fb_dmamap->dm_segs[0].ds_len, fb->fb_buf); 2370 #endif 2371 memset(fb->fb_buf, 0, fb->fb_dmamap->dm_segs[0].ds_len); 2372 bus_dmamap_sync(sc->sc_dmat, fb->fb_dmamap, 0, 2373 fb->fb_dmamap->dm_segs[0].ds_len, BUS_DMASYNC_PREREAD); 2374 2375 OHCI_CSR_WRITE(sc, OHCI_REG_SelfIDBuffer, 2376 fb->fb_dmamap->dm_segs[0].ds_addr); 2377 } 2378 2379 static int 2380 fwohci_selfid_input(struct fwohci_softc *sc) 2381 { 2382 int i; 2383 u_int32_t count, val, gen; 2384 u_int32_t *buf; 2385 2386 buf = (u_int32_t *)sc->sc_buf_selfid.fb_buf; 2387 val = OHCI_CSR_READ(sc, OHCI_REG_SelfIDCount); 2388 again: 2389 if (val & OHCI_SelfID_Error) { 2390 printf("%s: SelfID Error\n", sc->sc_sc1394.sc1394_dev.dv_xname); 2391 return -1; 2392 } 2393 count = OHCI_BITVAL(val, OHCI_SelfID_Size); 2394 2395 bus_dmamap_sync(sc->sc_dmat, sc->sc_buf_selfid.fb_dmamap, 2396 0, count << 2, BUS_DMASYNC_POSTREAD); 2397 gen = OHCI_BITVAL(buf[0], OHCI_SelfID_Gen); 2398 2399 #ifdef FW_DEBUG 2400 DPRINTFN(1, ("%s: SelfID: 0x%08x", sc->sc_sc1394.sc1394_dev.dv_xname, 2401 val)); 2402 for (i = 0; i < count; i++) 2403 DPRINTFN(2, ("%s%08x", i&7?" ":"\n ", buf[i])); 2404 DPRINTFN(1, ("\n")); 2405 #endif /* FW_DEBUG */ 2406 2407 for (i = 1; i < count; i += 2) { 2408 if (buf[i] != ~buf[i + 1]) 2409 break; 2410 if (buf[i] & 0x00000001) 2411 continue; /* more pkt */ 2412 if (buf[i] & 0x00800000) 2413 continue; /* external id */ 2414 sc->sc_rootid = (buf[i] & 0x3f000000) >> 24; 2415 if ((buf[i] & 0x00400800) == 0x00400800) 2416 sc->sc_irmid = sc->sc_rootid; 2417 } 2418 2419 val = OHCI_CSR_READ(sc, OHCI_REG_SelfIDCount); 2420 if (OHCI_BITVAL(val, OHCI_SelfID_Gen) != gen) { 2421 if (OHCI_BITVAL(val, OHCI_SelfID_Gen) != 2422 OHCI_BITVAL(buf[0], OHCI_SelfID_Gen)) 2423 goto again; 2424 DPRINTF(("%s: SelfID Gen mismatch (%d, %d)\n", 2425 sc->sc_sc1394.sc1394_dev.dv_xname, gen, 2426 OHCI_BITVAL(val, OHCI_SelfID_Gen))); 2427 return -1; 2428 } 2429 if (i != count) { 2430 printf("%s: SelfID corrupted (%d, 0x%08x, 0x%08x)\n", 2431 sc->sc_sc1394.sc1394_dev.dv_xname, i, buf[i], buf[i + 1]); 2432 #if 1 2433 if (i == 1 && buf[i] == 0 && buf[i + 1] == 0) { 2434 /* 2435 * XXX: CXD3222 sometimes fails to DMA 2436 * selfid packet?? 2437 */ 2438 sc->sc_rootid = (count - 1) / 2 - 1; 2439 sc->sc_irmid = sc->sc_rootid; 2440 } else 2441 #endif 2442 return -1; 2443 } 2444 2445 val = OHCI_CSR_READ(sc, OHCI_REG_NodeId); 2446 if ((val & OHCI_NodeId_IDValid) == 0) { 2447 sc->sc_nodeid = 0xffff; /* invalid */ 2448 printf("%s: nodeid is invalid\n", 2449 sc->sc_sc1394.sc1394_dev.dv_xname); 2450 return -1; 2451 } 2452 sc->sc_nodeid = val & 0xffff; 2453 2454 DPRINTF(("%s: nodeid=0x%04x(%d), rootid=%d, irmid=%d\n", 2455 sc->sc_sc1394.sc1394_dev.dv_xname, sc->sc_nodeid, 2456 sc->sc_nodeid & OHCI_NodeId_NodeNumber, sc->sc_rootid, 2457 sc->sc_irmid)); 2458 2459 if ((sc->sc_nodeid & OHCI_NodeId_NodeNumber) > sc->sc_rootid) 2460 return -1; 2461 2462 if ((sc->sc_nodeid & OHCI_NodeId_NodeNumber) == sc->sc_rootid) 2463 OHCI_CSR_WRITE(sc, OHCI_REG_LinkControlSet, 2464 OHCI_LinkControl_CycleMaster); 2465 else 2466 OHCI_CSR_WRITE(sc, OHCI_REG_LinkControlClear, 2467 OHCI_LinkControl_CycleMaster); 2468 return 0; 2469 } 2470 2471 /* 2472 * some CSRs are handled by driver. 2473 */ 2474 static void 2475 fwohci_csr_init(struct fwohci_softc *sc) 2476 { 2477 int i; 2478 static u_int32_t csr[] = { 2479 CSR_STATE_CLEAR, CSR_STATE_SET, CSR_SB_CYCLE_TIME, 2480 CSR_SB_BUS_TIME, CSR_SB_BUSY_TIMEOUT, CSR_SB_BUS_MANAGER_ID, 2481 CSR_SB_CHANNEL_AVAILABLE_HI, CSR_SB_CHANNEL_AVAILABLE_LO, 2482 CSR_SB_BROADCAST_CHANNEL 2483 }; 2484 2485 for (i = 0; i < sizeof(csr) / sizeof(csr[0]); i++) { 2486 fwohci_handler_set(sc, IEEE1394_TCODE_WRITE_REQ_QUAD, 2487 CSR_BASE_HI, CSR_BASE_LO + csr[i], fwohci_csr_input, NULL); 2488 fwohci_handler_set(sc, IEEE1394_TCODE_READ_REQ_QUAD, 2489 CSR_BASE_HI, CSR_BASE_LO + csr[i], fwohci_csr_input, NULL); 2490 } 2491 sc->sc_csr[CSR_SB_BROADCAST_CHANNEL] = 31; /*XXX*/ 2492 } 2493 2494 static int 2495 fwohci_csr_input(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt) 2496 { 2497 struct fwohci_pkt res; 2498 u_int32_t reg; 2499 2500 /* 2501 * XXX need to do special functionality other than just r/w... 2502 */ 2503 reg = pkt->fp_hdr[2] - CSR_BASE_LO; 2504 2505 if ((reg & 0x03) != 0) { 2506 /* alignment error */ 2507 return IEEE1394_RCODE_ADDRESS_ERROR; 2508 } 2509 DPRINTFN(1, ("fwohci_csr_input: CSR[0x%04x]: 0x%08x", reg, 2510 *(u_int32_t *)(&sc->sc_csr[reg]))); 2511 if (pkt->fp_tcode == IEEE1394_TCODE_WRITE_REQ_QUAD) { 2512 DPRINTFN(1, (" -> 0x%08x\n", 2513 ntohl(*(u_int32_t *)pkt->fp_iov[0].iov_base))); 2514 *(u_int32_t *)&sc->sc_csr[reg] = 2515 ntohl(*(u_int32_t *)pkt->fp_iov[0].iov_base); 2516 } else { 2517 DPRINTFN(1, ("\n")); 2518 res.fp_hdr[3] = htonl(*(u_int32_t *)&sc->sc_csr[reg]); 2519 res.fp_iov[0].iov_base = &res.fp_hdr[3]; 2520 res.fp_iov[0].iov_len = 4; 2521 res.fp_uio.uio_resid = 4; 2522 res.fp_uio.uio_iovcnt = 1; 2523 fwohci_atrs_output(sc, IEEE1394_RCODE_COMPLETE, pkt, &res); 2524 return -1; 2525 } 2526 return IEEE1394_RCODE_COMPLETE; 2527 } 2528 2529 /* 2530 * Mapping between nodeid and unique ID (EUI-64). 2531 * 2532 * Track old mappings and simply update their devices with the new id's when 2533 * they match an existing EUI. This allows proper renumeration of the bus. 2534 */ 2535 static void 2536 fwohci_uid_collect(struct fwohci_softc *sc) 2537 { 2538 int i; 2539 struct fwohci_uidtbl *fu; 2540 struct ieee1394_softc *iea; 2541 2542 LIST_FOREACH(iea, &sc->sc_nodelist, sc1394_node) 2543 iea->sc1394_node_id = 0xffff; 2544 2545 if (sc->sc_uidtbl != NULL) 2546 free(sc->sc_uidtbl, M_DEVBUF); 2547 sc->sc_uidtbl = malloc(sizeof(*fu) * (sc->sc_rootid + 1), M_DEVBUF, 2548 M_NOWAIT); /* XXX M_WAITOK requires locks */ 2549 if (sc->sc_uidtbl == NULL) 2550 return; 2551 memset(sc->sc_uidtbl, 0, sizeof(*fu) * (sc->sc_rootid + 1)); 2552 2553 for (i = 0, fu = sc->sc_uidtbl; i <= sc->sc_rootid; i++, fu++) { 2554 if (i == (sc->sc_nodeid & OHCI_NodeId_NodeNumber)) { 2555 memcpy(fu->fu_uid, sc->sc_sc1394.sc1394_guid, 8); 2556 fu->fu_valid = 3; 2557 2558 iea = (struct ieee1394_softc *)sc->sc_sc1394.sc1394_if; 2559 if (iea) { 2560 iea->sc1394_node_id = i; 2561 DPRINTF(("%s: Updating nodeid to %d\n", 2562 iea->sc1394_dev.dv_xname, 2563 iea->sc1394_node_id)); 2564 } 2565 } else { 2566 fu->fu_valid = 0; 2567 fwohci_uid_req(sc, i); 2568 } 2569 } 2570 if (sc->sc_rootid == 0) 2571 fwohci_check_nodes(sc); 2572 } 2573 2574 static void 2575 fwohci_uid_req(struct fwohci_softc *sc, int phyid) 2576 { 2577 struct fwohci_pkt pkt; 2578 2579 memset(&pkt, 0, sizeof(pkt)); 2580 pkt.fp_tcode = IEEE1394_TCODE_READ_REQ_QUAD; 2581 pkt.fp_hlen = 12; 2582 pkt.fp_dlen = 0; 2583 pkt.fp_hdr[0] = 0x00000100 | (sc->sc_tlabel << 10) | 2584 (pkt.fp_tcode << 4); 2585 pkt.fp_hdr[1] = ((0xffc0 | phyid) << 16) | CSR_BASE_HI; 2586 pkt.fp_hdr[2] = CSR_BASE_LO + CSR_CONFIG_ROM + 12; 2587 fwohci_handler_set(sc, IEEE1394_TCODE_READ_RESP_QUAD, phyid, 2588 sc->sc_tlabel, fwohci_uid_input, (void *)0); 2589 sc->sc_tlabel = (sc->sc_tlabel + 1) & 0x3f; 2590 fwohci_at_output(sc, sc->sc_ctx_atrq, &pkt); 2591 2592 pkt.fp_hdr[0] = 0x00000100 | (sc->sc_tlabel << 10) | 2593 (pkt.fp_tcode << 4); 2594 pkt.fp_hdr[2] = CSR_BASE_LO + CSR_CONFIG_ROM + 16; 2595 fwohci_handler_set(sc, IEEE1394_TCODE_READ_RESP_QUAD, phyid, 2596 sc->sc_tlabel, fwohci_uid_input, (void *)1); 2597 sc->sc_tlabel = (sc->sc_tlabel + 1) & 0x3f; 2598 fwohci_at_output(sc, sc->sc_ctx_atrq, &pkt); 2599 } 2600 2601 static int 2602 fwohci_uid_input(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *res) 2603 { 2604 struct fwohci_uidtbl *fu; 2605 struct ieee1394_softc *iea; 2606 struct ieee1394_attach_args fwa; 2607 int i, n, done, rcode, found; 2608 2609 found = 0; 2610 2611 n = (res->fp_hdr[1] >> 16) & OHCI_NodeId_NodeNumber; 2612 rcode = (res->fp_hdr[1] & 0x0000f000) >> 12; 2613 if (rcode != IEEE1394_RCODE_COMPLETE || 2614 sc->sc_uidtbl == NULL || 2615 n > sc->sc_rootid) 2616 return 0; 2617 fu = &sc->sc_uidtbl[n]; 2618 if (arg == 0) { 2619 memcpy(fu->fu_uid, res->fp_iov[0].iov_base, 4); 2620 fu->fu_valid |= 0x1; 2621 } else { 2622 memcpy(fu->fu_uid + 4, res->fp_iov[0].iov_base, 4); 2623 fu->fu_valid |= 0x2; 2624 } 2625 #ifdef FW_DEBUG 2626 if (fu->fu_valid == 0x3) 2627 DPRINTFN(1, ("fwohci_uid_input: " 2628 "Node %d, UID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", n, 2629 fu->fu_uid[0], fu->fu_uid[1], fu->fu_uid[2], fu->fu_uid[3], 2630 fu->fu_uid[4], fu->fu_uid[5], fu->fu_uid[6], fu->fu_uid[7])); 2631 #endif 2632 if (fu->fu_valid == 0x3) { 2633 LIST_FOREACH(iea, &sc->sc_nodelist, sc1394_node) 2634 if (memcmp(iea->sc1394_guid, fu->fu_uid, 8) == 0) { 2635 found = 1; 2636 iea->sc1394_node_id = n; 2637 DPRINTF(("%s: Updating nodeid to %d\n", 2638 iea->sc1394_dev.dv_xname, 2639 iea->sc1394_node_id)); 2640 break; 2641 } 2642 if (!found) { 2643 strcpy(fwa.name, "fwnode"); 2644 memcpy(fwa.uid, fu->fu_uid, 8); 2645 fwa.nodeid = n; 2646 fwa.read = fwohci_read; 2647 fwa.write = fwohci_write; 2648 fwa.inreg = fwohci_inreg; 2649 iea = (struct ieee1394_softc *) 2650 config_found_sm(&sc->sc_sc1394.sc1394_dev, &fwa, 2651 fwohci_print, fwohci_submatch); 2652 if (iea != NULL) 2653 LIST_INSERT_HEAD(&sc->sc_nodelist, iea, 2654 sc1394_node); 2655 } 2656 } 2657 done = 1; 2658 2659 for (i = 0; i < sc->sc_rootid + 1; i++) { 2660 fu = &sc->sc_uidtbl[i]; 2661 if (fu->fu_valid != 0x3) { 2662 done = 0; 2663 break; 2664 } 2665 } 2666 if (done) 2667 fwohci_check_nodes(sc); 2668 2669 return 0; 2670 } 2671 2672 static void 2673 fwohci_check_nodes(struct fwohci_softc *sc) 2674 { 2675 struct device *detach = NULL; 2676 struct ieee1394_softc *iea; 2677 2678 LIST_FOREACH(iea, &sc->sc_nodelist, sc1394_node) { 2679 2680 /* 2681 * Have to defer detachment until the next 2682 * loop iteration since config_detach 2683 * free's the softc and the loop iterator 2684 * needs data from the softc to move 2685 * forward. 2686 */ 2687 2688 if (detach) { 2689 config_detach(detach, 0); 2690 detach = NULL; 2691 } 2692 if (iea->sc1394_node_id == 0xffff) { 2693 detach = (struct device *)iea; 2694 LIST_REMOVE(iea, sc1394_node); 2695 } 2696 } 2697 if (detach) 2698 config_detach(detach, 0); 2699 } 2700 2701 static int 2702 fwohci_uid_lookup(struct fwohci_softc *sc, const u_int8_t *uid) 2703 { 2704 struct fwohci_uidtbl *fu; 2705 int n; 2706 static const u_int8_t bcast[] = 2707 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 2708 2709 fu = sc->sc_uidtbl; 2710 if (fu == NULL) { 2711 if (memcmp(uid, bcast, sizeof(bcast)) == 0) 2712 return IEEE1394_BCAST_PHY_ID; 2713 fwohci_uid_collect(sc); /* try to get */ 2714 return -1; 2715 } 2716 for (n = 0; n <= sc->sc_rootid; n++, fu++) { 2717 if (fu->fu_valid == 0x3 && memcmp(fu->fu_uid, uid, 8) == 0) 2718 return n; 2719 } 2720 if (memcmp(uid, bcast, sizeof(bcast)) == 0) 2721 return IEEE1394_BCAST_PHY_ID; 2722 for (n = 0, fu = sc->sc_uidtbl; n <= sc->sc_rootid; n++, fu++) { 2723 if (fu->fu_valid != 0x3) { 2724 /* 2725 * XXX: need timer before retransmission 2726 */ 2727 fwohci_uid_req(sc, n); 2728 } 2729 } 2730 return -1; 2731 } 2732 2733 /* 2734 * functions to support network interface 2735 */ 2736 static int 2737 fwohci_if_inreg(struct device *self, u_int32_t offhi, u_int32_t offlo, 2738 void (*handler)(struct device *, struct mbuf *)) 2739 { 2740 struct fwohci_softc *sc = (struct fwohci_softc *)self; 2741 2742 fwohci_handler_set(sc, IEEE1394_TCODE_WRITE_REQ_BLOCK, offhi, offlo, 2743 handler ? fwohci_if_input : NULL, handler); 2744 fwohci_handler_set(sc, IEEE1394_TCODE_STREAM_DATA, 2745 (sc->sc_csr[CSR_SB_BROADCAST_CHANNEL] & IEEE1394_ISOCH_MASK) | OHCI_ASYNC_STREAM, 2746 IEEE1394_TAG_GASP, handler ? fwohci_if_input : NULL, handler); 2747 return 0; 2748 } 2749 2750 static int 2751 fwohci_if_input(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt) 2752 { 2753 int n, len; 2754 struct mbuf *m; 2755 struct iovec *iov; 2756 void (*handler)(struct device *, struct mbuf *) = arg; 2757 2758 #ifdef FW_DEBUG 2759 int i; 2760 DPRINTFN(1, ("fwohci_if_input: tcode=0x%x, dlen=%d", pkt->fp_tcode, 2761 pkt->fp_dlen)); 2762 for (i = 0; i < pkt->fp_hlen/4; i++) 2763 DPRINTFN(2, ("%s%08x", i?" ":"\n ", pkt->fp_hdr[i])); 2764 DPRINTFN(2, ("$")); 2765 for (n = 0, len = pkt->fp_dlen; len > 0; len -= i, n++){ 2766 iov = &pkt->fp_iov[n]; 2767 for (i = 0; i < iov->iov_len; i++) 2768 DPRINTFN(2, ("%s%02x", (i%32)?((i%4)?"":" "):"\n ", 2769 ((u_int8_t *)iov->iov_base)[i])); 2770 DPRINTFN(2, ("$")); 2771 } 2772 DPRINTFN(1, ("\n")); 2773 #endif /* FW_DEBUG */ 2774 len = pkt->fp_dlen; 2775 MGETHDR(m, M_DONTWAIT, MT_DATA); 2776 if (m == NULL) 2777 return IEEE1394_RCODE_COMPLETE; 2778 m->m_len = 16; 2779 if (len + m->m_len > MHLEN) { 2780 MCLGET(m, M_DONTWAIT); 2781 if ((m->m_flags & M_EXT) == 0) { 2782 m_freem(m); 2783 return IEEE1394_RCODE_COMPLETE; 2784 } 2785 } 2786 n = (pkt->fp_hdr[1] >> 16) & OHCI_NodeId_NodeNumber; 2787 if (sc->sc_uidtbl == NULL || n > sc->sc_rootid || 2788 sc->sc_uidtbl[n].fu_valid != 0x3) { 2789 printf("%s: packet from unknown node: phy id %d\n", 2790 sc->sc_sc1394.sc1394_dev.dv_xname, n); 2791 m_freem(m); 2792 fwohci_uid_req(sc, n); 2793 return IEEE1394_RCODE_COMPLETE; 2794 } 2795 memcpy(mtod(m, caddr_t), sc->sc_uidtbl[n].fu_uid, 8); 2796 if (pkt->fp_tcode == IEEE1394_TCODE_STREAM_DATA) { 2797 m->m_flags |= M_BCAST; 2798 mtod(m, u_int32_t *)[2] = mtod(m, u_int32_t *)[3] = 0; 2799 } else { 2800 mtod(m, u_int32_t *)[2] = htonl(pkt->fp_hdr[1]); 2801 mtod(m, u_int32_t *)[3] = htonl(pkt->fp_hdr[2]); 2802 } 2803 mtod(m, u_int8_t *)[8] = n; /*XXX: node id for debug */ 2804 mtod(m, u_int8_t *)[9] = 2805 (*pkt->fp_trail >> (16 + OHCI_CTXCTL_SPD_BITPOS)) & 2806 ((1 << OHCI_CTXCTL_SPD_BITLEN) - 1); 2807 2808 m->m_pkthdr.rcvif = NULL; /* set in child */ 2809 m->m_pkthdr.len = len + m->m_len; 2810 /* 2811 * We may use receive buffer by external mbuf instead of copy here. 2812 * But asynchronous receive buffer must be operate in buffer fill 2813 * mode, so that each receive buffer will shared by multiple mbufs. 2814 * If upper layer doesn't free mbuf soon, e.g. application program 2815 * is suspended, buffer must be reallocated. 2816 * Isochronous buffer must be operate in packet buffer mode, and 2817 * it is easy to map receive buffer to external mbuf. But it is 2818 * used for broadcast/multicast only, and is expected not so 2819 * performance sensitive for now. 2820 * XXX: The performance may be important for multicast case, 2821 * so we should revisit here later. 2822 * -- onoe 2823 */ 2824 n = 0; 2825 iov = pkt->fp_uio.uio_iov; 2826 while (len > 0) { 2827 memcpy(mtod(m, caddr_t) + m->m_len, iov->iov_base, 2828 iov->iov_len); 2829 m->m_len += iov->iov_len; 2830 len -= iov->iov_len; 2831 iov++; 2832 } 2833 (*handler)(sc->sc_sc1394.sc1394_if, m); 2834 return IEEE1394_RCODE_COMPLETE; 2835 } 2836 2837 static int 2838 fwohci_if_input_iso(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt) 2839 { 2840 int n, len; 2841 int chan, tag; 2842 struct mbuf *m; 2843 struct iovec *iov; 2844 void (*handler)(struct device *, struct mbuf *) = arg; 2845 #ifdef FW_DEBUG 2846 int i; 2847 #endif 2848 2849 chan = (pkt->fp_hdr[0] & 0x00003f00) >> 8; 2850 tag = (pkt->fp_hdr[0] & 0x0000c000) >> 14; 2851 #ifdef FW_DEBUG 2852 DPRINTFN(1, ("fwohci_if_input_iso: " 2853 "tcode=0x%x, chan=%d, tag=%x, dlen=%d", 2854 pkt->fp_tcode, chan, tag, pkt->fp_dlen)); 2855 for (i = 0; i < pkt->fp_hlen/4; i++) 2856 DPRINTFN(2, ("%s%08x", i?" ":"\n\t", pkt->fp_hdr[i])); 2857 DPRINTFN(2, ("$")); 2858 for (n = 0, len = pkt->fp_dlen; len > 0; len -= i, n++){ 2859 iov = &pkt->fp_iov[n]; 2860 for (i = 0; i < iov->iov_len; i++) 2861 DPRINTFN(2, ("%s%02x", 2862 (i%32)?((i%4)?"":" "):"\n\t", 2863 ((u_int8_t *)iov->iov_base)[i])); 2864 DPRINTFN(2, ("$")); 2865 } 2866 DPRINTFN(2, ("\n")); 2867 #endif /* FW_DEBUG */ 2868 len = pkt->fp_dlen; 2869 MGETHDR(m, M_DONTWAIT, MT_DATA); 2870 if (m == NULL) 2871 return IEEE1394_RCODE_COMPLETE; 2872 m->m_len = 16; 2873 if (m->m_len + len > MHLEN) { 2874 MCLGET(m, M_DONTWAIT); 2875 if ((m->m_flags & M_EXT) == 0) { 2876 m_freem(m); 2877 return IEEE1394_RCODE_COMPLETE; 2878 } 2879 } 2880 2881 m->m_flags |= M_BCAST; 2882 2883 if (tag == IEEE1394_TAG_GASP) { 2884 n = (pkt->fp_hdr[1] >> 16) & OHCI_NodeId_NodeNumber; 2885 if (sc->sc_uidtbl == NULL || n > sc->sc_rootid || 2886 sc->sc_uidtbl[n].fu_valid != 0x3) { 2887 printf("%s: packet from unknown node: phy id %d\n", 2888 sc->sc_sc1394.sc1394_dev.dv_xname, n); 2889 m_freem(m); 2890 return IEEE1394_RCODE_COMPLETE; 2891 } 2892 memcpy(mtod(m, caddr_t), sc->sc_uidtbl[n].fu_uid, 8); 2893 mtod(m, u_int32_t *)[2] = htonl(pkt->fp_hdr[1]); 2894 mtod(m, u_int32_t *)[3] = htonl(pkt->fp_hdr[2]); 2895 mtod(m, u_int8_t *)[8] = n; /*XXX: node id for debug */ 2896 mtod(m, u_int8_t *)[9] = 2897 (*pkt->fp_trail >> (16 + OHCI_CTXCTL_SPD_BITPOS)) & 2898 ((1 << OHCI_CTXCTL_SPD_BITLEN) - 1); 2899 } else { 2900 m->m_flags |= M_LINK0; 2901 } 2902 mtod(m, u_int8_t *)[14] = chan; 2903 mtod(m, u_int8_t *)[15] = tag; 2904 2905 2906 m->m_pkthdr.rcvif = NULL; /* set in child */ 2907 m->m_pkthdr.len = len + m->m_len; 2908 /* 2909 * We may use receive buffer by external mbuf instead of copy here. 2910 * But asynchronous receive buffer must be operate in buffer fill 2911 * mode, so that each receive buffer will shared by multiple mbufs. 2912 * If upper layer doesn't free mbuf soon, e.g. application program 2913 * is suspended, buffer must be reallocated. 2914 * Isochronous buffer must be operate in packet buffer mode, and 2915 * it is easy to map receive buffer to external mbuf. But it is 2916 * used for broadcast/multicast only, and is expected not so 2917 * performance sensitive for now. 2918 * XXX: The performance may be important for multicast case, 2919 * so we should revisit here later. 2920 * -- onoe 2921 */ 2922 n = 0; 2923 iov = pkt->fp_uio.uio_iov; 2924 while (len > 0) { 2925 memcpy(mtod(m, caddr_t) + m->m_len, iov->iov_base, 2926 iov->iov_len); 2927 m->m_len += iov->iov_len; 2928 len -= iov->iov_len; 2929 iov++; 2930 } 2931 (*handler)(sc->sc_sc1394.sc1394_if, m); 2932 return IEEE1394_RCODE_COMPLETE; 2933 } 2934 2935 2936 2937 static int 2938 fwohci_if_output(struct device *self, struct mbuf *m0, 2939 void (*callback)(struct device *, struct mbuf *)) 2940 { 2941 struct fwohci_softc *sc = (struct fwohci_softc *)self; 2942 struct fwohci_pkt pkt; 2943 u_int8_t *p; 2944 int n, error, spd, hdrlen, maxrec; 2945 #ifdef FW_DEBUG 2946 struct mbuf *m; 2947 #endif 2948 2949 p = mtod(m0, u_int8_t *); 2950 if (m0->m_flags & (M_BCAST | M_MCAST)) { 2951 spd = IEEE1394_SPD_S100; /*XXX*/ 2952 maxrec = 512; /*XXX*/ 2953 hdrlen = 8; 2954 } else { 2955 n = fwohci_uid_lookup(sc, p); 2956 if (n < 0) { 2957 printf("%s: nodeid unknown:" 2958 " %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", 2959 sc->sc_sc1394.sc1394_dev.dv_xname, 2960 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); 2961 error = EHOSTUNREACH; 2962 goto end; 2963 } 2964 if (n == IEEE1394_BCAST_PHY_ID) { 2965 printf("%s: broadcast with !M_MCAST\n", 2966 sc->sc_sc1394.sc1394_dev.dv_xname); 2967 #ifdef FW_DEBUG 2968 DPRINTFN(2, ("packet:")); 2969 for (m = m0; m != NULL; m = m->m_next) { 2970 for (n = 0; n < m->m_len; n++) 2971 DPRINTFN(2, ("%s%02x", (n%32)? 2972 ((n%4)?"":" "):"\n ", 2973 mtod(m, u_int8_t *)[n])); 2974 DPRINTFN(2, ("$")); 2975 } 2976 DPRINTFN(2, ("\n")); 2977 #endif 2978 error = EHOSTUNREACH; 2979 goto end; 2980 } 2981 maxrec = 2 << p[8]; 2982 spd = p[9]; 2983 hdrlen = 0; 2984 } 2985 if (spd > sc->sc_sc1394.sc1394_link_speed) { 2986 DPRINTF(("fwohci_if_output: spd (%d) is faster than %d\n", 2987 spd, sc->sc_sc1394.sc1394_link_speed)); 2988 spd = sc->sc_sc1394.sc1394_link_speed; 2989 } 2990 if (maxrec > (512 << spd)) { 2991 DPRINTF(("fwohci_if_output: maxrec (%d) is larger for spd (%d)" 2992 "\n", maxrec, spd)); 2993 maxrec = 512 << spd; 2994 } 2995 while (maxrec > sc->sc_sc1394.sc1394_max_receive) { 2996 DPRINTF(("fwohci_if_output: maxrec (%d) is larger than" 2997 " %d\n", maxrec, sc->sc_sc1394.sc1394_max_receive)); 2998 maxrec >>= 1; 2999 } 3000 if (maxrec < 512) { 3001 DPRINTF(("fwohci_if_output: maxrec (%d) is smaller than " 3002 "minimum\n", maxrec)); 3003 maxrec = 512; 3004 } 3005 3006 m_adj(m0, 16 - hdrlen); 3007 if (m0->m_pkthdr.len > maxrec) { 3008 DPRINTF(("fwohci_if_output: packet too big: hdr %d, pktlen " 3009 "%d, maxrec %d\n", hdrlen, m0->m_pkthdr.len, maxrec)); 3010 error = E2BIG; /*XXX*/ 3011 goto end; 3012 } 3013 3014 memset(&pkt, 0, sizeof(pkt)); 3015 pkt.fp_uio.uio_iov = pkt.fp_iov; 3016 pkt.fp_uio.uio_segflg = UIO_SYSSPACE; 3017 pkt.fp_uio.uio_rw = UIO_WRITE; 3018 if (m0->m_flags & (M_BCAST | M_MCAST)) { 3019 /* construct GASP header */ 3020 p = mtod(m0, u_int8_t *); 3021 p[0] = sc->sc_nodeid >> 8; 3022 p[1] = sc->sc_nodeid & 0xff; 3023 p[2] = 0x00; p[3] = 0x00; p[4] = 0x5e; 3024 p[5] = 0x00; p[6] = 0x00; p[7] = 0x01; 3025 pkt.fp_tcode = IEEE1394_TCODE_STREAM_DATA; 3026 pkt.fp_hlen = 8; 3027 pkt.fp_hdr[0] = (spd << 16) | (IEEE1394_TAG_GASP << 14) | 3028 ((sc->sc_csr[CSR_SB_BROADCAST_CHANNEL] & 3029 OHCI_NodeId_NodeNumber) << 8); 3030 pkt.fp_hdr[1] = m0->m_pkthdr.len << 16; 3031 } else { 3032 pkt.fp_tcode = IEEE1394_TCODE_WRITE_REQ_BLOCK; 3033 pkt.fp_hlen = 16; 3034 pkt.fp_hdr[0] = 0x00800100 | (sc->sc_tlabel << 10) | 3035 (spd << 16); 3036 pkt.fp_hdr[1] = 3037 (((sc->sc_nodeid & OHCI_NodeId_BusNumber) | n) << 16) | 3038 (p[10] << 8) | p[11]; 3039 pkt.fp_hdr[2] = (p[12]<<24) | (p[13]<<16) | (p[14]<<8) | p[15]; 3040 pkt.fp_hdr[3] = m0->m_pkthdr.len << 16; 3041 sc->sc_tlabel = (sc->sc_tlabel + 1) & 0x3f; 3042 } 3043 pkt.fp_hdr[0] |= (pkt.fp_tcode << 4); 3044 pkt.fp_dlen = m0->m_pkthdr.len; 3045 pkt.fp_m = m0; 3046 pkt.fp_callback = callback; 3047 error = fwohci_at_output(sc, sc->sc_ctx_atrq, &pkt); 3048 m0 = pkt.fp_m; 3049 end: 3050 if (m0 != NULL) { 3051 if (callback) 3052 (*callback)(sc->sc_sc1394.sc1394_if, m0); 3053 else 3054 m_freem(m0); 3055 } 3056 return error; 3057 } 3058 3059 /* 3060 * High level routines to provide abstraction to attaching layers to 3061 * send/receive data. 3062 */ 3063 3064 /* 3065 * These break down into 4 routines as follows: 3066 * 3067 * int fwohci_read(struct ieee1394_abuf *) 3068 * 3069 * This routine will attempt to read a region from the requested node. 3070 * A callback must be provided which will be called when either the completed 3071 * read is done or an unrecoverable error occurs. This is mainly a convenience 3072 * routine since it will encapsulate retrying a region as quadlet vs. block reads 3073 * and recombining all the returned data. This could also be done with a series 3074 * of write/inreg's for each packet sent. 3075 * 3076 * int fwohci_write(struct ieee1394_abuf *) 3077 * 3078 * The work horse main entry point for putting packets on the bus. This is the 3079 * generalized interface for fwnode/etc code to put packets out onto the bus. 3080 * It accepts all standard ieee1394 tcodes (XXX: only a few today) and optionally 3081 * will callback via a func pointer to the calling code with the resulting ACK 3082 * code from the packet. If the ACK code is to be ignored (i.e. no cb) then the 3083 * write routine will take care of free'ing the abuf since the fwnode/etc code 3084 * won't have any knowledge of when to do this. This allows for simple one-off 3085 * packets to be sent from the upper-level code without worrying about a callback 3086 * for cleanup. 3087 * 3088 * int fwohci_inreg(struct ieee1394_abuf *, int) 3089 * 3090 * This is very simple. It evals the abuf passed in and registers an internal 3091 * handler as the callback for packets received for that operation. 3092 * The integer argument specifies whether on a block read/write operation to 3093 * allow sub-regions to be read/written (in block form) as well. 3094 * 3095 * XXX: This whole structure needs to be redone as a list of regions and 3096 * operations allowed on those regions. 3097 * 3098 * int fwohci_unreg(struct ieee1394_abuf *, int) 3099 * 3100 * XXX: TBD. For now passing in a NULL ab_cb to inreg will unregister. This 3101 * routine will simply verify ab_cb is NULL and call inreg. 3102 * 3103 * This simply unregisters the respective callback done via inreg for items 3104 * which only need to register an area for a one-time operation (like a status 3105 * buffer a remote node will write to when the current operation is done). The 3106 * int argument specifies the same behavior as inreg, except in reverse (i.e. 3107 * it unregisters). 3108 */ 3109 3110 static int 3111 fwohci_read(struct ieee1394_abuf *ab) 3112 { 3113 struct fwohci_pkt pkt; 3114 struct ieee1394_softc *sc = ab->ab_req; 3115 struct fwohci_softc *psc = 3116 (struct fwohci_softc *)sc->sc1394_dev.dv_parent; 3117 struct fwohci_cb *fcb; 3118 u_int32_t high, lo; 3119 int rv, tcode; 3120 3121 /* Have to have a callback when reading. */ 3122 if (ab->ab_cb == NULL) 3123 return -1; 3124 3125 fcb = malloc(sizeof(struct fwohci_cb), M_DEVBUF, M_WAITOK); 3126 fcb->ab = ab; 3127 fcb->count = 0; 3128 fcb->abuf_valid = 1; 3129 3130 high = ((ab->ab_csr & 0x0000ffff00000000) >> 32); 3131 lo = (ab->ab_csr & 0x00000000ffffffff); 3132 3133 memset(&pkt, 0, sizeof(pkt)); 3134 pkt.fp_hdr[1] = ((0xffc0 | ab->ab_req->sc1394_node_id) << 16) | high; 3135 pkt.fp_hdr[2] = lo; 3136 pkt.fp_dlen = 0; 3137 3138 if (ab->ab_length == 4) { 3139 pkt.fp_tcode = IEEE1394_TCODE_READ_REQ_QUAD; 3140 tcode = IEEE1394_TCODE_READ_RESP_QUAD; 3141 pkt.fp_hlen = 12; 3142 } else { 3143 pkt.fp_tcode = IEEE1394_TCODE_READ_REQ_BLOCK; 3144 pkt.fp_hlen = 16; 3145 tcode = IEEE1394_TCODE_READ_RESP_BLOCK; 3146 pkt.fp_hdr[3] = (ab->ab_length << 16); 3147 } 3148 pkt.fp_hdr[0] = 0x00000100 | (sc->sc1394_link_speed << 16) | 3149 (psc->sc_tlabel << 10) | (pkt.fp_tcode << 4); 3150 3151 pkt.fp_statusarg = fcb; 3152 pkt.fp_statuscb = fwohci_read_resp; 3153 3154 rv = fwohci_handler_set(psc, tcode, ab->ab_req->sc1394_node_id, 3155 psc->sc_tlabel, fwohci_read_resp, fcb); 3156 if (rv) 3157 return rv; 3158 rv = fwohci_at_output(psc, psc->sc_ctx_atrq, &pkt); 3159 if (rv) 3160 fwohci_handler_set(psc, tcode, ab->ab_req->sc1394_node_id, 3161 psc->sc_tlabel, NULL, NULL); 3162 psc->sc_tlabel = (psc->sc_tlabel + 1) & 0x3f; 3163 fcb->count = 1; 3164 return rv; 3165 } 3166 3167 static int 3168 fwohci_write(struct ieee1394_abuf *ab) 3169 { 3170 struct fwohci_pkt pkt; 3171 struct ieee1394_softc *sc = ab->ab_req; 3172 struct fwohci_softc *psc = 3173 (struct fwohci_softc *)sc->sc1394_dev.dv_parent; 3174 u_int32_t high, lo; 3175 int rv; 3176 3177 if (ab->ab_length > sc->sc1394_max_receive) { 3178 DPRINTF(("Packet too large: %d\n", ab->ab_length)); 3179 return E2BIG; 3180 } 3181 3182 memset(&pkt, 0, sizeof(pkt)); 3183 3184 pkt.fp_tcode = ab->ab_tcode; 3185 pkt.fp_uio.uio_iov = pkt.fp_iov; 3186 pkt.fp_uio.uio_segflg = UIO_SYSSPACE; 3187 pkt.fp_uio.uio_rw = UIO_WRITE; 3188 3189 pkt.fp_statusarg = ab; 3190 pkt.fp_statuscb = fwohci_write_ack; 3191 3192 switch (ab->ab_tcode) { 3193 case IEEE1394_TCODE_WRITE_RESP: 3194 pkt.fp_hlen = 12; 3195 case IEEE1394_TCODE_READ_RESP_QUAD: 3196 case IEEE1394_TCODE_READ_RESP_BLOCK: 3197 if (!pkt.fp_hlen) 3198 pkt.fp_hlen = 16; 3199 high = ab->ab_retlen; 3200 ab->ab_retlen = 0; 3201 lo = 0; 3202 pkt.fp_hdr[0] = 0x00000100 | (sc->sc1394_link_speed << 16) | 3203 (ab->ab_tlabel << 10) | (pkt.fp_tcode << 4); 3204 break; 3205 default: 3206 pkt.fp_hlen = 16; 3207 high = ((ab->ab_csr & 0x0000ffff00000000) >> 32); 3208 lo = (ab->ab_csr & 0x00000000ffffffff); 3209 pkt.fp_hdr[0] = 0x00000100 | (sc->sc1394_link_speed << 16) | 3210 (psc->sc_tlabel << 10) | (pkt.fp_tcode << 4); 3211 break; 3212 } 3213 3214 pkt.fp_hdr[1] = ((0xffc0 | ab->ab_req->sc1394_node_id) << 16) | high; 3215 pkt.fp_hdr[2] = lo; 3216 if (pkt.fp_hlen == 16) { 3217 if (ab->ab_length == 4) { 3218 pkt.fp_hdr[3] = ab->ab_data[0]; 3219 pkt.fp_dlen = 0; 3220 } else { 3221 pkt.fp_hdr[3] = (ab->ab_length << 16); 3222 pkt.fp_dlen = ab->ab_length; 3223 pkt.fp_uio.uio_iovcnt = 1; 3224 pkt.fp_uio.uio_resid = ab->ab_length; 3225 pkt.fp_iov[0].iov_base = ab->ab_data; 3226 pkt.fp_iov[0].iov_len = ab->ab_length; 3227 } 3228 } 3229 switch (ab->ab_tcode) { 3230 case IEEE1394_TCODE_WRITE_RESP: 3231 case IEEE1394_TCODE_READ_RESP_QUAD: 3232 case IEEE1394_TCODE_READ_RESP_BLOCK: 3233 rv = fwohci_at_output(psc, psc->sc_ctx_atrs, &pkt); 3234 break; 3235 default: 3236 rv = fwohci_at_output(psc, psc->sc_ctx_atrq, &pkt); 3237 break; 3238 } 3239 return rv; 3240 } 3241 3242 static int 3243 fwohci_read_resp(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt) 3244 { 3245 struct fwohci_cb *fcb = arg; 3246 struct ieee1394_abuf *ab = fcb->ab; 3247 struct fwohci_pkt newpkt; 3248 u_int32_t *cur, high, lo; 3249 int i, tcode, rcode, status, rv; 3250 3251 /* 3252 * Both the ACK handling and normal response callbacks are handled here. 3253 * The main reason for this is the various error conditions that can 3254 * occur trying to block read some areas and the ways that gets reported 3255 * back to calling station. This is a variety of ACK codes, responses, 3256 * etc which makes it much more difficult to process if both aren't 3257 * handled here. 3258 */ 3259 3260 /* Check for status packet. */ 3261 3262 if (pkt->fp_tcode == -1) { 3263 status = pkt->fp_status & OHCI_DESC_STATUS_ACK_MASK; 3264 rcode = -1; 3265 tcode = (pkt->fp_hdr[0] >> 4) & 0xf; 3266 if ((status != OHCI_CTXCTL_EVENT_ACK_COMPLETE) && 3267 (status != OHCI_CTXCTL_EVENT_ACK_PENDING)) 3268 DPRINTF(("Got status packet: 0x%02x\n", 3269 (unsigned int)status)); 3270 fcb->count--; 3271 3272 /* 3273 * Got all the ack's back and the buffer is invalid (i.e. the 3274 * callback has been called. Clean up. 3275 */ 3276 3277 if (fcb->abuf_valid == 0) { 3278 if (fcb->count == 0) 3279 free(fcb, M_DEVBUF); 3280 return IEEE1394_RCODE_COMPLETE; 3281 } 3282 } else { 3283 status = -1; 3284 tcode = pkt->fp_tcode; 3285 rcode = (pkt->fp_hdr[1] & 0x0000f000) >> 12; 3286 } 3287 3288 /* 3289 * Some area's (like the config rom want to be read as quadlets only. 3290 * 3291 * The current ideas to try are: 3292 * 3293 * Got an ACK_TYPE_ERROR on a block read. 3294 * 3295 * Got either RCODE_TYPE or RCODE_ADDRESS errors in a block read 3296 * response. 3297 * 3298 * In all cases construct a new packet for a quadlet read and let 3299 * mutli_resp handle the iteration over the space. 3300 */ 3301 3302 if (((status == OHCI_CTXCTL_EVENT_ACK_TYPE_ERROR) && 3303 (tcode == IEEE1394_TCODE_READ_REQ_BLOCK)) || 3304 (((rcode == IEEE1394_RCODE_TYPE_ERROR) || 3305 (rcode == IEEE1394_RCODE_ADDRESS_ERROR)) && 3306 (tcode == IEEE1394_TCODE_READ_RESP_BLOCK))) { 3307 3308 /* Read the area in quadlet chunks (internally track this). */ 3309 3310 memset(&newpkt, 0, sizeof(newpkt)); 3311 3312 high = ((ab->ab_csr & 0x0000ffff00000000) >> 32); 3313 lo = (ab->ab_csr & 0x00000000ffffffff); 3314 3315 newpkt.fp_tcode = IEEE1394_TCODE_READ_REQ_QUAD; 3316 newpkt.fp_hlen = 12; 3317 newpkt.fp_dlen = 0; 3318 newpkt.fp_hdr[1] = 3319 ((0xffc0 | ab->ab_req->sc1394_node_id) << 16) | high; 3320 newpkt.fp_hdr[2] = lo; 3321 newpkt.fp_hdr[0] = 0x00000100 | (sc->sc_tlabel << 10) | 3322 (newpkt.fp_tcode << 4); 3323 3324 rv = fwohci_handler_set(sc, IEEE1394_TCODE_READ_RESP_QUAD, 3325 ab->ab_req->sc1394_node_id, sc->sc_tlabel, 3326 fwohci_read_multi_resp, fcb); 3327 if (rv) { 3328 (*ab->ab_cb)(ab, -1); 3329 goto cleanup; 3330 } 3331 newpkt.fp_statusarg = fcb; 3332 newpkt.fp_statuscb = fwohci_read_resp; 3333 rv = fwohci_at_output(sc, sc->sc_ctx_atrq, &newpkt); 3334 if (rv) { 3335 fwohci_handler_set(sc, IEEE1394_TCODE_READ_RESP_QUAD, 3336 ab->ab_req->sc1394_node_id, sc->sc_tlabel, NULL, 3337 NULL); 3338 (*ab->ab_cb)(ab, -1); 3339 goto cleanup; 3340 } 3341 fcb->count++; 3342 sc->sc_tlabel = (sc->sc_tlabel + 1) & 0x3f; 3343 return IEEE1394_RCODE_COMPLETE; 3344 } else if ((rcode != -1) || ((status != -1) && 3345 (status != OHCI_CTXCTL_EVENT_ACK_COMPLETE) && 3346 (status != OHCI_CTXCTL_EVENT_ACK_PENDING))) { 3347 3348 /* 3349 * Recombine all the iov data into 1 chunk for higher 3350 * level code. 3351 */ 3352 3353 if (rcode != -1) { 3354 cur = ab->ab_data; 3355 for (i = 0; i < pkt->fp_uio.uio_iovcnt; i++) { 3356 /* 3357 * Make sure and don't exceed the buffer 3358 * allocated for return. 3359 */ 3360 if ((ab->ab_retlen + pkt->fp_iov[i].iov_len) > 3361 ab->ab_length) { 3362 memcpy(cur, pkt->fp_iov[i].iov_base, 3363 (ab->ab_length - ab->ab_retlen)); 3364 ab->ab_retlen = ab->ab_length; 3365 break; 3366 } 3367 memcpy(cur, pkt->fp_iov[i].iov_base, 3368 pkt->fp_iov[i].iov_len); 3369 cur += pkt->fp_iov[i].iov_len; 3370 ab->ab_retlen += pkt->fp_iov[i].iov_len; 3371 } 3372 } 3373 if (status != -1) 3374 /* XXX: Need a complete tlabel interface. */ 3375 for (i = 0; i < 64; i++) 3376 fwohci_handler_set(sc, 3377 IEEE1394_TCODE_READ_RESP_QUAD, 3378 ab->ab_req->sc1394_node_id, i, NULL, NULL); 3379 (*ab->ab_cb)(ab, rcode); 3380 goto cleanup; 3381 } else 3382 /* Good ack packet. */ 3383 return IEEE1394_RCODE_COMPLETE; 3384 3385 /* Can't get here unless ab->ab_cb has been called. */ 3386 3387 cleanup: 3388 fcb->abuf_valid = 0; 3389 if (fcb->count == 0) 3390 free(fcb, M_DEVBUF); 3391 return IEEE1394_RCODE_COMPLETE; 3392 } 3393 3394 static int 3395 fwohci_read_multi_resp(struct fwohci_softc *sc, void *arg, 3396 struct fwohci_pkt *pkt) 3397 { 3398 struct fwohci_cb *fcb = arg; 3399 struct ieee1394_abuf *ab = fcb->ab; 3400 struct fwohci_pkt newpkt; 3401 u_int32_t high, lo; 3402 int rcode, rv; 3403 3404 /* 3405 * Bad return codes from the wire, just return what's already in the 3406 * buf. 3407 */ 3408 3409 /* Make sure a response packet didn't arrive after a bad ACK. */ 3410 if (fcb->abuf_valid == 0) 3411 return IEEE1394_RCODE_COMPLETE; 3412 3413 rcode = (pkt->fp_hdr[1] & 0x0000f000) >> 12; 3414 3415 if (rcode) { 3416 (*ab->ab_cb)(ab, rcode); 3417 goto cleanup; 3418 } 3419 3420 if ((ab->ab_retlen + pkt->fp_iov[0].iov_len) > ab->ab_length) { 3421 memcpy(((char *)ab->ab_data + ab->ab_retlen), 3422 pkt->fp_iov[0].iov_base, (ab->ab_length - ab->ab_retlen)); 3423 ab->ab_retlen = ab->ab_length; 3424 } else { 3425 memcpy(((char *)ab->ab_data + ab->ab_retlen), 3426 pkt->fp_iov[0].iov_base, 4); 3427 ab->ab_retlen += 4; 3428 } 3429 /* Still more, loop and read 4 more bytes. */ 3430 if (ab->ab_retlen < ab->ab_length) { 3431 memset(&newpkt, 0, sizeof(newpkt)); 3432 3433 high = ((ab->ab_csr & 0x0000ffff00000000) >> 32); 3434 lo = (ab->ab_csr & 0x00000000ffffffff) + ab->ab_retlen; 3435 3436 newpkt.fp_tcode = IEEE1394_TCODE_READ_REQ_QUAD; 3437 newpkt.fp_hlen = 12; 3438 newpkt.fp_dlen = 0; 3439 newpkt.fp_hdr[1] = 3440 ((0xffc0 | ab->ab_req->sc1394_node_id) << 16) | high; 3441 newpkt.fp_hdr[2] = lo; 3442 newpkt.fp_hdr[0] = 0x00000100 | (sc->sc_tlabel << 10) | 3443 (newpkt.fp_tcode << 4); 3444 3445 newpkt.fp_statusarg = fcb; 3446 newpkt.fp_statuscb = fwohci_read_resp; 3447 3448 /* 3449 * Bad return code. Just give up and return what's 3450 * come in now. 3451 */ 3452 rv = fwohci_handler_set(sc, IEEE1394_TCODE_READ_RESP_QUAD, 3453 ab->ab_req->sc1394_node_id, sc->sc_tlabel, 3454 fwohci_read_multi_resp, fcb); 3455 if (rv) 3456 (*ab->ab_cb)(ab, -1); 3457 else { 3458 rv = fwohci_at_output(sc, sc->sc_ctx_atrq, &newpkt); 3459 if (rv) { 3460 fwohci_handler_set(sc, 3461 IEEE1394_TCODE_READ_RESP_QUAD, 3462 ab->ab_req->sc1394_node_id, sc->sc_tlabel, 3463 NULL, NULL); 3464 (*ab->ab_cb)(ab, -1); 3465 } else { 3466 sc->sc_tlabel = (sc->sc_tlabel + 1) & 0x3f; 3467 fcb->count++; 3468 return IEEE1394_RCODE_COMPLETE; 3469 } 3470 } 3471 } else 3472 (*ab->ab_cb)(ab, IEEE1394_RCODE_COMPLETE); 3473 3474 cleanup: 3475 /* Can't get here unless ab_cb has been called. */ 3476 fcb->abuf_valid = 0; 3477 if (fcb->count == 0) 3478 free(fcb, M_DEVBUF); 3479 return IEEE1394_RCODE_COMPLETE; 3480 } 3481 3482 static int 3483 fwohci_write_ack(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt) 3484 { 3485 struct ieee1394_abuf *ab = arg; 3486 u_int16_t status; 3487 3488 3489 status = pkt->fp_status & OHCI_DESC_STATUS_ACK_MASK; 3490 if ((status != OHCI_CTXCTL_EVENT_ACK_COMPLETE) && 3491 (status != OHCI_CTXCTL_EVENT_ACK_PENDING)) 3492 DPRINTF(("Got status packet: 0x%02x\n", 3493 (unsigned int)status)); 3494 3495 /* No callback means this level should free the buffers. */ 3496 if (ab->ab_cb) 3497 (*ab->ab_cb)(ab, status); 3498 else { 3499 if (ab->ab_data) 3500 free(ab->ab_data, M_1394DATA); 3501 free(ab, M_1394DATA); 3502 } 3503 return IEEE1394_RCODE_COMPLETE; 3504 } 3505 3506 static int 3507 fwohci_inreg(struct ieee1394_abuf *ab, int allow) 3508 { 3509 struct ieee1394_softc *sc = ab->ab_req; 3510 struct fwohci_softc *psc = 3511 (struct fwohci_softc *)sc->sc1394_dev.dv_parent; 3512 u_int32_t high, lo; 3513 int i, j, rv; 3514 3515 high = ((ab->ab_csr & 0x0000ffff00000000) >> 32); 3516 lo = (ab->ab_csr & 0x00000000ffffffff); 3517 3518 rv = 0; 3519 switch (ab->ab_tcode) { 3520 case IEEE1394_TCODE_READ_REQ_QUAD: 3521 case IEEE1394_TCODE_WRITE_REQ_QUAD: 3522 if (ab->ab_cb) 3523 rv = fwohci_handler_set(psc, ab->ab_tcode, high, lo, 3524 fwohci_parse_input, ab); 3525 else 3526 fwohci_handler_set(psc, ab->ab_tcode, high, lo, NULL, 3527 NULL); 3528 break; 3529 case IEEE1394_TCODE_READ_REQ_BLOCK: 3530 case IEEE1394_TCODE_WRITE_REQ_BLOCK: 3531 if (allow) { 3532 for (i = 0; i < (ab->ab_length / 4); i++) { 3533 if (ab->ab_cb) { 3534 rv = fwohci_handler_set(psc, 3535 ab->ab_tcode, high, lo + (i * 4), 3536 fwohci_parse_input, ab); 3537 if (rv) 3538 break; 3539 } else 3540 fwohci_handler_set(psc, ab->ab_tcode, 3541 high, lo + (i * 4), NULL, NULL); 3542 } 3543 if (i != (ab->ab_length / 4)) { 3544 j = i + 1; 3545 for (i = 0; i < j; i++) 3546 fwohci_handler_set(psc, ab->ab_tcode, 3547 high, lo + (i * 4), NULL, NULL); 3548 } else 3549 ab->ab_data = (void *)1; 3550 } else { 3551 if (ab->ab_cb) 3552 rv = fwohci_handler_set(psc, ab->ab_tcode, high, 3553 lo, fwohci_parse_input, ab); 3554 else 3555 fwohci_handler_set(psc, ab->ab_tcode, high, lo, 3556 NULL, NULL); 3557 } 3558 break; 3559 default: 3560 DPRINTF(("Invalid registration tcode: %d\n", ab->ab_tcode)); 3561 return -1; 3562 break; 3563 } 3564 return rv; 3565 } 3566 3567 static int 3568 fwohci_parse_input(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt) 3569 { 3570 struct ieee1394_abuf *ab = (struct ieee1394_abuf *)arg; 3571 u_int64_t csr; 3572 u_int32_t *cur; 3573 int i, count; 3574 3575 ab->ab_tcode = (pkt->fp_hdr[0] >> 4) & 0xf; 3576 ab->ab_tlabel = (pkt->fp_hdr[0] >> 10) & 0x3f; 3577 csr = (((u_int64_t)(pkt->fp_hdr[1] & 0xffff) << 32) | pkt->fp_hdr[2]); 3578 3579 switch (ab->ab_tcode) { 3580 case IEEE1394_TCODE_READ_REQ_QUAD: 3581 ab->ab_retlen = 4; 3582 break; 3583 case IEEE1394_TCODE_READ_REQ_BLOCK: 3584 ab->ab_retlen = (pkt->fp_hdr[3] >> 16) & 0xffff; 3585 if (ab->ab_data) { 3586 if ((csr + ab->ab_retlen) > 3587 (ab->ab_csr + ab->ab_length)) 3588 return IEEE1394_RCODE_ADDRESS_ERROR; 3589 ab->ab_data = NULL; 3590 } else 3591 if (ab->ab_retlen != ab->ab_length) 3592 return IEEE1394_RCODE_ADDRESS_ERROR; 3593 break; 3594 case IEEE1394_TCODE_WRITE_REQ_QUAD: 3595 ab->ab_retlen = 4; 3596 case IEEE1394_TCODE_WRITE_REQ_BLOCK: 3597 if (!ab->ab_retlen) 3598 ab->ab_retlen = (pkt->fp_hdr[3] >> 16) & 0xffff; 3599 if (ab->ab_data) { 3600 if ((csr + ab->ab_retlen) > 3601 (ab->ab_csr + ab->ab_length)) 3602 return IEEE1394_RCODE_ADDRESS_ERROR; 3603 ab->ab_data = NULL; 3604 } else 3605 if (ab->ab_retlen != ab->ab_length) 3606 return IEEE1394_RCODE_ADDRESS_ERROR; 3607 3608 ab->ab_data = malloc(ab->ab_retlen, M_1394DATA, M_WAITOK); 3609 if (ab->ab_tcode == IEEE1394_TCODE_WRITE_REQ_QUAD) 3610 ab->ab_data[0] = pkt->fp_hdr[3]; 3611 else { 3612 count = 0; 3613 cur = ab->ab_data; 3614 for (i = 0; i < pkt->fp_uio.uio_iovcnt; i++) { 3615 memcpy(cur, pkt->fp_iov[i].iov_base, 3616 pkt->fp_iov[i].iov_len); 3617 cur += pkt->fp_iov[i].iov_len; 3618 count += pkt->fp_iov[i].iov_len; 3619 } 3620 if (ab->ab_retlen != count) 3621 panic("Packet claims %d length " 3622 "but only %d bytes returned\n", 3623 ab->ab_retlen, count); 3624 } 3625 break; 3626 default: 3627 panic("Got a callback for a tcode that wasn't requested: %d\n", 3628 ab->ab_tcode); 3629 break; 3630 } 3631 ab->ab_csr = csr; 3632 ab->ab_cb(ab, IEEE1394_RCODE_COMPLETE); 3633 return -1; 3634 } 3635 3636 static int 3637 fwohci_submatch(struct device *parent, struct cfdata *cf, void *aux) 3638 { 3639 struct ieee1394_attach_args *fwa = aux; 3640 3641 /* Both halves must be filled in for a match. */ 3642 if ((cf->fwbuscf_idhi == FWBUS_UNK_IDHI && 3643 cf->fwbuscf_idlo == FWBUS_UNK_IDLO) || 3644 (cf->fwbuscf_idhi == ntohl(*((u_int32_t *)&fwa->uid[0])) && 3645 cf->fwbuscf_idlo == ntohl(*((u_int32_t *)&fwa->uid[4])))) 3646 return ((*cf->cf_attach->ca_match)(parent, cf, aux)); 3647 return 0; 3648 } 3649 3650 #ifdef FW_DEBUG 3651 static void 3652 fwohci_show_intr(struct fwohci_softc *sc, u_int32_t intmask) 3653 { 3654 3655 printf("%s: intmask=0x%08x:", sc->sc_sc1394.sc1394_dev.dv_xname, 3656 intmask); 3657 if (intmask & OHCI_Int_CycleTooLong) 3658 printf(" CycleTooLong"); 3659 if (intmask & OHCI_Int_UnrecoverableError) 3660 printf(" UnrecoverableError"); 3661 if (intmask & OHCI_Int_CycleInconsistent) 3662 printf(" CycleInconsistent"); 3663 if (intmask & OHCI_Int_BusReset) 3664 printf(" BusReset"); 3665 if (intmask & OHCI_Int_SelfIDComplete) 3666 printf(" SelfIDComplete"); 3667 if (intmask & OHCI_Int_LockRespErr) 3668 printf(" LockRespErr"); 3669 if (intmask & OHCI_Int_PostedWriteErr) 3670 printf(" PostedWriteErr"); 3671 if (intmask & OHCI_Int_ReqTxComplete) 3672 printf(" ReqTxComplete(0x%04x)", 3673 OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_TX_REQUEST, 3674 OHCI_SUBREG_ContextControlClear)); 3675 if (intmask & OHCI_Int_RespTxComplete) 3676 printf(" RespTxComplete(0x%04x)", 3677 OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_TX_RESPONSE, 3678 OHCI_SUBREG_ContextControlClear)); 3679 if (intmask & OHCI_Int_ARRS) 3680 printf(" ARRS(0x%04x)", 3681 OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_RX_RESPONSE, 3682 OHCI_SUBREG_ContextControlClear)); 3683 if (intmask & OHCI_Int_ARRQ) 3684 printf(" ARRQ(0x%04x)", 3685 OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_RX_REQUEST, 3686 OHCI_SUBREG_ContextControlClear)); 3687 if (intmask & OHCI_Int_IsochRx) 3688 printf(" IsochRx(0x%08x)", 3689 OHCI_CSR_READ(sc, OHCI_REG_IsoRecvIntEventClear)); 3690 if (intmask & OHCI_Int_IsochTx) 3691 printf(" IsochTx(0x%08x)", 3692 OHCI_CSR_READ(sc, OHCI_REG_IsoXmitIntEventClear)); 3693 if (intmask & OHCI_Int_RQPkt) 3694 printf(" RQPkt(0x%04x)", 3695 OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_RX_REQUEST, 3696 OHCI_SUBREG_ContextControlClear)); 3697 if (intmask & OHCI_Int_RSPkt) 3698 printf(" RSPkt(0x%04x)", 3699 OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_RX_RESPONSE, 3700 OHCI_SUBREG_ContextControlClear)); 3701 printf("\n"); 3702 } 3703 3704 static void 3705 fwohci_show_phypkt(struct fwohci_softc *sc, u_int32_t val) 3706 { 3707 u_int8_t key, phyid; 3708 3709 key = (val & 0xc0000000) >> 30; 3710 phyid = (val & 0x3f000000) >> 24; 3711 printf("%s: PHY packet from %d: ", 3712 sc->sc_sc1394.sc1394_dev.dv_xname, phyid); 3713 switch (key) { 3714 case 0: 3715 printf("PHY Config:"); 3716 if (val & 0x00800000) 3717 printf(" ForceRoot"); 3718 if (val & 0x00400000) 3719 printf(" Gap=%x", (val & 0x003f0000) >> 16); 3720 printf("\n"); 3721 break; 3722 case 1: 3723 printf("Link-on\n"); 3724 break; 3725 case 2: 3726 printf("SelfID:"); 3727 if (val & 0x00800000) { 3728 printf(" #%d", (val & 0x00700000) >> 20); 3729 } else { 3730 if (val & 0x00400000) 3731 printf(" LinkActive"); 3732 printf(" Gap=%x", (val & 0x003f0000) >> 16); 3733 printf(" Spd=S%d", 100 << ((val & 0x0000c000) >> 14)); 3734 if (val & 0x00000800) 3735 printf(" Cont"); 3736 if (val & 0x00000002) 3737 printf(" InitiateBusReset"); 3738 } 3739 if (val & 0x00000001) 3740 printf(" +"); 3741 printf("\n"); 3742 break; 3743 default: 3744 printf("unknown: 0x%08x\n", val); 3745 break; 3746 } 3747 } 3748 #endif /* FW_DEBUG */ 3749