1/* 2 * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 16 unchanged lines hidden (view full) --- 25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 * |
33 * $FreeBSD: head/sys/dev/firewire/fwohci.c 108530 2003-01-01 08:25:32Z simokawa $ |
34 * 35 */ 36 37#define ATRQ_CH 0 38#define ATRS_CH 1 39#define ARRQ_CH 2 40#define ARRS_CH 3 41#define ITX_CH 4 --- 350 unchanged lines hidden (view full) --- 392 } 393 break; 394 default: 395 break; 396 } 397 return err; 398} 399 |
400static int 401fwohci_probe_phy(struct fwohci_softc *sc, device_t dev) |
402{ |
403 u_int32_t reg, reg2; 404 int e1394a = 1; 405/* 406 * probe PHY parameters 407 * 0. to prove PHY version, whether compliance of 1394a. 408 * 1. to probe maximum speed supported by the PHY and 409 * number of port supported by core-logic. 410 * It is not actually available port on your PC . 411 */ 412 OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LPS); 413#if 0 414 /* XXX wait for SCLK. */ 415 DELAY(100000); 416#endif 417 reg = fwphy_rddata(sc, FW_PHY_SPD_REG); 418 419 if((reg >> 5) != 7 ){ 420 sc->fc.mode &= ~FWPHYASYST; 421 sc->fc.nport = reg & FW_PHY_NP; 422 sc->fc.speed = reg & FW_PHY_SPD >> 6; 423 if (sc->fc.speed > MAX_SPEED) { 424 device_printf(dev, "invalid speed %d (fixed to %d).\n", 425 sc->fc.speed, MAX_SPEED); 426 sc->fc.speed = MAX_SPEED; 427 } 428 sc->fc.maxrec = maxrec[sc->fc.speed]; 429 device_printf(dev, 430 "Link 1394 only %s, %d ports, maxrec %d bytes.\n", 431 linkspeed[sc->fc.speed], sc->fc.nport, sc->fc.maxrec); 432 }else{ 433 reg2 = fwphy_rddata(sc, FW_PHY_ESPD_REG); 434 sc->fc.mode |= FWPHYASYST; 435 sc->fc.nport = reg & FW_PHY_NP; 436 sc->fc.speed = (reg2 & FW_PHY_ESPD) >> 5; 437 if (sc->fc.speed > MAX_SPEED) { 438 device_printf(dev, "invalid speed %d (fixed to %d).\n", 439 sc->fc.speed, MAX_SPEED); 440 sc->fc.speed = MAX_SPEED; 441 } 442 sc->fc.maxrec = maxrec[sc->fc.speed]; 443 device_printf(dev, 444 "Link 1394a available %s, %d ports, maxrec %d bytes.\n", 445 linkspeed[sc->fc.speed], sc->fc.nport, sc->fc.maxrec); 446 447 /* check programPhyEnable */ 448 reg2 = fwphy_rddata(sc, 5); 449#if 0 450 if (e1394a && (OREAD(sc, OHCI_HCCCTL) & OHCI_HCC_PRPHY)) { 451#else /* XXX force to enable 1394a */ 452 if (e1394a) { 453#endif 454 if (bootverbose) 455 device_printf(dev, 456 "Enable 1394a Enhancements\n"); 457 /* enable EAA EMC */ 458 reg2 |= 0x03; 459 /* set aPhyEnhanceEnable */ 460 OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_PHYEN); 461 OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_PRPHY); 462 } else { 463 /* for safe */ 464 reg2 &= ~0x83; 465 } 466 reg2 = fwphy_wrdata(sc, 5, reg2); 467 } 468 469 reg = fwphy_rddata(sc, FW_PHY_SPD_REG); 470 if((reg >> 5) == 7 ){ 471 reg = fwphy_rddata(sc, 4); 472 reg |= 1 << 6; 473 fwphy_wrdata(sc, 4, reg); 474 reg = fwphy_rddata(sc, 4); 475 } 476 return 0; 477} 478 479 480void 481fwohci_reset(struct fwohci_softc *sc, device_t dev) 482{ |
483 int i; 484 u_int32_t reg, reg2; 485 struct fwohcidb_tr *db_tr; |
486 |
487/* Disable interrupt */ 488 OWRITE(sc, FWOHCI_INTMASKCLR, ~0); 489 490/* Now stopping all DMA channel */ 491 OWRITE(sc, OHCI_ARQCTLCLR, OHCI_CNTL_DMA_RUN); 492 OWRITE(sc, OHCI_ARSCTLCLR, OHCI_CNTL_DMA_RUN); 493 OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN); 494 OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN); 495 496 OWRITE(sc, OHCI_IR_MASKCLR, ~0); 497 for( i = 0 ; i < sc->fc.nisodma ; i ++ ){ 498 OWRITE(sc, OHCI_IRCTLCLR(i), OHCI_CNTL_DMA_RUN); 499 OWRITE(sc, OHCI_ITCTLCLR(i), OHCI_CNTL_DMA_RUN); 500 } 501 502/* FLUSH FIFO and reset Transmitter/Reciever */ 503 OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_RESET); 504 if (bootverbose) 505 device_printf(dev, "resetting OHCI..."); 506 i = 0; 507 while(OREAD(sc, OHCI_HCCCTL) & OHCI_HCC_RESET) { 508 if (i++ > 100) break; 509 DELAY(1000); 510 } 511 if (bootverbose) 512 printf("done (loop=%d)\n", i); 513 514 reg = OREAD(sc, OHCI_BUS_OPT); 515 reg2 = reg | OHCI_BUSFNC; 516 /* XXX */ 517 if (((reg & 0x0000f000) >> 12) < 10) 518 reg2 = (reg2 & 0xffff0fff) | (10 << 12); 519 if (bootverbose) 520 device_printf(dev, "BUS_OPT 0x%x -> 0x%x\n", reg, reg2); 521 OWRITE(sc, OHCI_BUS_OPT, reg2); 522 523 OWRITE(sc, OHCI_CROMHDR, sc->fc.config_rom[0]); 524 OWRITE(sc, OHCI_CROMPTR, vtophys(&sc->fc.config_rom[0])); 525 OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_BIGEND); 526 OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_POSTWR); 527 528 fwohci_probe_phy(sc, dev); 529 530 OWRITE(sc, OHCI_SID_BUF, vtophys(sc->fc.sid_buf)); 531 OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_SID); 532 533 /* enable link */ 534 OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LINKEN); 535 fw_busreset(&sc->fc); 536 fwohci_rx_enable(sc, &sc->arrq); 537 fwohci_rx_enable(sc, &sc->arrs); 538 539 for( i = 0, db_tr = sc->atrq.top; i < sc->atrq.ndb ; 540 i ++, db_tr = STAILQ_NEXT(db_tr, link)){ 541 db_tr->xfer = NULL; 542 } 543 for( i = 0, db_tr = sc->atrs.top; i < sc->atrs.ndb ; 544 i ++, db_tr = STAILQ_NEXT(db_tr, link)){ 545 db_tr->xfer = NULL; 546 } 547 548 OWRITE(sc, FWOHCI_RETRY, 549 (0xffff << 16 )| (0x0f << 8) | (0x0f << 4) | 0x0f) ; 550 OWRITE(sc, FWOHCI_INTMASK, 551 OHCI_INT_ERR | OHCI_INT_PHY_SID 552 | OHCI_INT_DMA_ATRQ | OHCI_INT_DMA_ATRS 553 | OHCI_INT_DMA_PRRQ | OHCI_INT_DMA_PRRS 554 | OHCI_INT_PHY_BUS_R | OHCI_INT_PW_ERR); 555 fwohci_set_intr(&sc->fc, 1); 556 557 OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN | OHCI_CNTL_DMA_DEAD); 558 OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN | OHCI_CNTL_DMA_DEAD); 559} 560 561int 562fwohci_init(struct fwohci_softc *sc, device_t dev) 563{ 564 int i; 565 u_int32_t reg; 566 |
567 reg = OREAD(sc, OHCI_VERSION); 568 device_printf(dev, "OHCI version %x.%x (ROM=%d)\n", 569 (reg>>16) & 0xff, reg & 0xff, (reg>>24) & 1); 570 571/* XXX: Available Isochrounous DMA channel probe */ 572 for( i = 0 ; i < 0x20 ; i ++ ){ 573 OWRITE(sc, OHCI_IRCTL(i), OHCI_CNTL_DMA_RUN); 574 reg = OREAD(sc, OHCI_IRCTL(i)); --- 57 unchanged lines hidden (view full) --- 632 sc->fc.config_rom[2] = 0xf000a002; 633 sc->fc.config_rom[3] = OREAD(sc, OHCI_EUID_HI); 634 sc->fc.config_rom[4] = OREAD(sc, OHCI_EUID_LO); 635 sc->fc.config_rom[5] = 0; 636 sc->fc.config_rom[0] = (4 << 24) | (5 << 16); 637 638 sc->fc.config_rom[0] |= fw_crc16(&sc->fc.config_rom[1], 5*4); 639 |
640 |
641/* SID recieve buffer must allign 2^11 */ 642#define OHCI_SIDSIZE (1 << 11) 643 sc->fc.sid_buf = (u_int32_t *) vm_page_alloc_contig( OHCI_SIDSIZE, 644 0x10000, 0xffffffff, OHCI_SIDSIZE); 645 if (sc->fc.sid_buf == NULL) { 646 device_printf(dev, "sid_buf alloc failed.\n"); 647 return ENOMEM; 648 } 649 |
650 |
651 fwohci_db_init(&sc->arrq); 652 if ((sc->arrq.flags & FWOHCI_DBCH_INIT) == 0) 653 return ENOMEM; 654 655 fwohci_db_init(&sc->arrs); 656 if ((sc->arrs.flags & FWOHCI_DBCH_INIT) == 0) 657 return ENOMEM; 658 --- 28 unchanged lines hidden (view full) --- 687 sc->fc.itx_enable = fwohci_itxbuf_enable; 688 sc->fc.itx_disable = fwohci_itx_disable; 689 sc->fc.irx_post = fwohci_irx_post; 690 sc->fc.itx_post = NULL; 691 sc->fc.timeout = fwohci_timeout; 692 sc->fc.poll = fwohci_poll; 693 sc->fc.set_intr = fwohci_set_intr; 694 |
695 fw_init(&sc->fc); 696 fwohci_reset(sc, dev); |
697 |
698 return 0; |
699} 700 701void 702fwohci_timeout(void *arg) 703{ 704 struct fwohci_softc *sc; 705 706 sc = (struct fwohci_softc *)arg; --- 424 unchanged lines hidden (view full) --- 1131 return; 1132 } 1133 bzero(db, sizeof (struct fwohcidb) * dbch->ndesc * dbch->ndb); 1134 /* Attach DB to DMA ch. */ 1135 for(idb = 0 ; idb < dbch->ndb ; idb++){ 1136 db_tr->dbcnt = 0; 1137 db_tr->db = &db[idb * dbch->ndesc]; 1138 STAILQ_INSERT_TAIL(&dbch->db_trq, db_tr, link); |
1139 if (!(dbch->xferq.flag & FWXFERQ_PACKET) && 1140 dbch->xferq.bnpacket != 0) { 1141 /* XXX what thoes for? */ 1142 if (idb % dbch->xferq.bnpacket == 0) 1143 dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket 1144 ].start = (caddr_t)db_tr; 1145 if ((idb + 1) % dbch->xferq.bnpacket == 0) 1146 dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket 1147 ].end = (caddr_t)db_tr; |
1148 } |
1149 db_tr++; 1150 } 1151 STAILQ_LAST(&dbch->db_trq, fwohcidb_tr,link)->link.stqe_next 1152 = STAILQ_FIRST(&dbch->db_trq); 1153 dbch->top = STAILQ_FIRST(&dbch->db_trq); 1154 dbch->bottom = dbch->top; 1155 dbch->flags = FWOHCI_DBCH_INIT; 1156} --- 548 unchanged lines hidden (view full) --- 1705 OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_CYCTIMER); 1706 } 1707 fc->nodeid = OREAD(sc, FWOHCI_NODEID) & 0x3f; 1708 1709 plen = OREAD(sc, OHCI_SID_CNT) & OHCI_SID_CNT_MASK; 1710 plen -= 4; /* chop control info */ 1711 buf = malloc( FWPMAX_S400, M_DEVBUF, M_NOWAIT); 1712 if(buf == NULL) goto sidout; |
1713 bcopy((void *)(uintptr_t)(volatile void *)(fc->sid_buf + 1), |
1714 buf, plen); 1715 fw_sidrcv(fc, buf, plen, 0); 1716 } 1717sidout: 1718 if((stat & OHCI_INT_DMA_ATRQ )){ 1719#ifndef ACK_ALL 1720 OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_DMA_ATRQ); 1721#endif --- 866 unchanged lines hidden --- |