Lines Matching +full:ats +full:- +full:supported

1 /*-
2 * SPDX-License-Identifier: BSD-4-Clause
5 * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
121 #define OWRITE(sc, r, x) bus_space_write_4((sc)->bst, (sc)->bsh, (r), (x))
122 #define OREAD(sc, r) bus_space_read_4((sc)->bst, (sc)->bsh, (r))
299 device_printf(sc->fc.dev, "%s: %d->%d (loop=%d)\n", in fwohci_set_bus_manager()
324 device_printf(sc->fc.dev, "%s: failed(1).\n", __func__); in fwphy_rddata()
335 device_printf(sc->fc.dev, "%s: failed(2).\n", __func__); in fwphy_rddata()
342 device_printf(sc->fc.dev, in fwphy_rddata()
364 fc = (struct fwohci_softc *)sc->fc; in fwohci_ioctl()
372 if (reg->addr <= OHCI_MAX_REG) { in fwohci_ioctl()
373 OWRITE(fc, reg->addr, reg->data); in fwohci_ioctl()
374 reg->data = OREAD(fc, reg->addr); in fwohci_ioctl()
380 if (reg->addr <= OHCI_MAX_REG) { in fwohci_ioctl()
381 reg->data = OREAD(fc, reg->addr); in fwohci_ioctl()
398 if (reg->addr <= OHCI_MAX_PHY_REG) in fwohci_ioctl()
399 reg->data = fwphy_rddata(fc, reg->addr); in fwohci_ioctl()
404 if (reg->addr <= OHCI_MAX_PHY_REG) in fwohci_ioctl()
405 reg->data = fwphy_wrdata(fc, reg->addr, reg->data); in fwohci_ioctl()
425 * 1. to probe maximum speed supported by the PHY and
426 * number of port supported by core-logic.
435 sc->fc.mode &= ~FWPHYASYST;
436 sc->fc.nport = reg & FW_PHY_NP;
437 sc->fc.speed = reg & FW_PHY_SPD >> 6;
438 if (sc->fc.speed > MAX_SPEED) {
440 sc->fc.speed, MAX_SPEED);
441 sc->fc.speed = MAX_SPEED;
445 linkspeed[sc->fc.speed], sc->fc.nport);
448 sc->fc.mode |= FWPHYASYST;
449 sc->fc.nport = reg & FW_PHY_NP;
450 sc->fc.speed = (reg2 & FW_PHY_ESPD) >> 5;
451 if (sc->fc.speed > MAX_SPEED) {
453 sc->fc.speed, MAX_SPEED);
454 sc->fc.speed = MAX_SPEED;
458 linkspeed[sc->fc.speed], sc->fc.nport);
510 for (i = 0; i < sc->fc.nisodma; i++) {
538 sc->fc.maxrec = sc->fc.speed + 8;
539 if (max_rec != sc->fc.maxrec) {
540 reg2 = (reg2 & 0xffff0fff) | (sc->fc.maxrec << 12);
541 device_printf(dev, "max_rec %d -> %d\n",
542 MAXREC(max_rec), MAXREC(sc->fc.maxrec));
545 device_printf(dev, "BUS_OPT 0x%x -> 0x%x\n", reg, reg2);
549 OWRITE(sc, OHCI_CROMHDR, sc->fc.config_rom[0]);
550 OWRITE(sc, OHCI_CROMPTR, sc->crom_dma.bus_addr);
553 OWRITE(sc, OHCI_SID_BUF, sc->sid_dma.bus_addr);
560 sc->arrq.xferq.flag &= ~FWXFERQ_RUNNING;
561 sc->arrs.xferq.flag &= ~FWXFERQ_RUNNING;
562 fwohci_rx_enable(sc, &sc->arrq);
563 fwohci_rx_enable(sc, &sc->arrs);
574 sc->atrq.top = STAILQ_FIRST(&sc->atrq.db_trq);
575 sc->atrs.top = STAILQ_FIRST(&sc->atrs.db_trq);
576 sc->atrq.bottom = sc->atrq.top;
577 sc->atrs.bottom = sc->atrs.top;
579 for (i = 0, db_tr = sc->atrq.top; i < sc->atrq.ndb;
581 db_tr->xfer = NULL;
583 for (i = 0, db_tr = sc->atrs.top; i < sc->atrs.ndb;
585 db_tr->xfer = NULL;
589 sc->intmask = (OHCI_INT_ERR | OHCI_INT_PHY_SID
593 sc->intmask |= OHCI_INT_DMA_IR | OHCI_INT_DMA_IT;
594 sc->intmask |= OHCI_INT_CYC_LOST | OHCI_INT_PHY_INT;
595 OWRITE(sc, FWOHCI_INTMASK, sc->intmask);
596 fwohci_set_intr(&sc->fc, 1);
625 sc->fc.nisodma = i;
630 sc->fc.arq = &sc->arrq.xferq;
631 sc->fc.ars = &sc->arrs.xferq;
632 sc->fc.atq = &sc->atrq.xferq;
633 sc->fc.ats = &sc->atrs.xferq;
635 sc->arrq.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
636 sc->arrs.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
637 sc->atrq.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
638 sc->atrs.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
640 sc->arrq.xferq.start = NULL;
641 sc->arrs.xferq.start = NULL;
642 sc->atrq.xferq.start = fwohci_start_atq;
643 sc->atrs.xferq.start = fwohci_start_ats;
645 sc->arrq.xferq.buf = NULL;
646 sc->arrs.xferq.buf = NULL;
647 sc->atrq.xferq.buf = NULL;
648 sc->atrs.xferq.buf = NULL;
650 sc->arrq.xferq.dmach = -1;
651 sc->arrs.xferq.dmach = -1;
652 sc->atrq.xferq.dmach = -1;
653 sc->atrs.xferq.dmach = -1;
655 sc->arrq.ndesc = 1;
656 sc->arrs.ndesc = 1;
657 sc->atrq.ndesc = 8; /* equal to maximum of mbuf chains */
658 sc->atrs.ndesc = 2;
660 sc->arrq.ndb = NDB;
661 sc->arrs.ndb = NDB / 2;
662 sc->atrq.ndb = NDB;
663 sc->atrs.ndb = NDB / 2;
665 for (i = 0; i < sc->fc.nisodma; i++) {
666 sc->fc.it[i] = &sc->it[i].xferq;
667 sc->fc.ir[i] = &sc->ir[i].xferq;
668 sc->it[i].xferq.dmach = i;
669 sc->ir[i].xferq.dmach = i;
670 sc->it[i].ndb = 0;
671 sc->ir[i].ndb = 0;
674 sc->fc.tcode = tinfo;
675 sc->fc.dev = dev;
677 sc->fc.config_rom = fwdma_malloc(&sc->fc, CROMSIZE, CROMSIZE,
678 &sc->crom_dma, BUS_DMA_WAITOK | BUS_DMA_COHERENT);
679 if (sc->fc.config_rom == NULL) {
685 bzero(&sc->fc.config_rom[0], CROMSIZE);
686 sc->fc.config_rom[1] = 0x31333934;
687 sc->fc.config_rom[2] = 0xf000a002;
688 sc->fc.config_rom[3] = OREAD(sc, OHCI_EUID_HI);
689 sc->fc.config_rom[4] = OREAD(sc, OHCI_EUID_LO);
690 sc->fc.config_rom[5] = 0;
691 sc->fc.config_rom[0] = (4 << 24) | (5 << 16);
693 sc->fc.config_rom[0] |= fw_crc16(&sc->fc.config_rom[1], 5*4);
698 sc->sid_buf = fwdma_malloc(&sc->fc, OHCI_SIDSIZE, OHCI_SIDSIZE,
699 &sc->sid_dma, BUS_DMA_WAITOK | BUS_DMA_COHERENT);
700 if (sc->sid_buf == NULL) {
705 fwdma_malloc(&sc->fc, sizeof(uint32_t), sizeof(uint32_t),
706 &sc->dummy_dma, BUS_DMA_WAITOK);
708 if (sc->dummy_dma.v_addr == NULL) {
713 fwohci_db_init(sc, &sc->arrq);
714 if ((sc->arrq.flags & FWOHCI_DBCH_INIT) == 0)
717 fwohci_db_init(sc, &sc->arrs);
718 if ((sc->arrs.flags & FWOHCI_DBCH_INIT) == 0)
721 fwohci_db_init(sc, &sc->atrq);
722 if ((sc->atrq.flags & FWOHCI_DBCH_INIT) == 0)
725 fwohci_db_init(sc, &sc->atrs);
726 if ((sc->atrs.flags & FWOHCI_DBCH_INIT) == 0)
729 sc->fc.eui.hi = OREAD(sc, FWOHCIGUID_H);
730 sc->fc.eui.lo = OREAD(sc, FWOHCIGUID_L);
732 ui[i] = FW_EUI64_BYTE(&sc->fc.eui,i);
736 sc->fc.ioctl = fwohci_ioctl;
737 sc->fc.cyctimer = fwohci_cyctimer;
738 sc->fc.set_bmr = fwohci_set_bus_manager;
739 sc->fc.ibr = fwohci_ibr;
740 sc->fc.irx_enable = fwohci_irx_enable;
741 sc->fc.irx_disable = fwohci_irx_disable;
743 sc->fc.itx_enable = fwohci_itxbuf_enable;
744 sc->fc.itx_disable = fwohci_itx_disable;
746 sc->fc.irx_post = fwohci_irx_post;
748 sc->fc.irx_post = NULL;
750 sc->fc.itx_post = NULL;
751 sc->fc.timeout = fwohci_timeout;
752 sc->fc.poll = fwohci_poll;
753 sc->fc.set_intr = fwohci_set_intr;
755 sc->intmask = sc->irstat = sc->itstat = 0;
758 sc->fc.taskqueue = taskqueue_create_fast("fw_taskq", M_WAITOK,
759 taskqueue_thread_enqueue, &sc->fc.taskqueue);
760 taskqueue_start_threads(&sc->fc.taskqueue, 1, PI_NET, "fw%d_taskq",
762 TASK_INIT(&sc->fwohci_task_busreset, 2, fwohci_task_busreset, sc);
763 TASK_INIT(&sc->fwohci_task_sid, 1, fwohci_task_sid, sc);
764 TASK_INIT(&sc->fwohci_task_dma, 0, fwohci_task_dma, sc);
766 fw_init(&sc->fc);
792 if (sc->sid_buf != NULL)
793 fwdma_free(&sc->fc, &sc->sid_dma);
794 if (sc->fc.config_rom != NULL)
795 fwdma_free(&sc->fc, &sc->crom_dma);
797 fwohci_db_free(&sc->arrq);
798 fwohci_db_free(&sc->arrs);
800 fwohci_db_free(&sc->atrq);
801 fwohci_db_free(&sc->atrs);
803 for (i = 0; i < sc->fc.nisodma; i++) {
804 fwohci_db_free(&sc->it[i]);
805 fwohci_db_free(&sc->ir[i]);
807 if (sc->fc.taskqueue != NULL) {
808 taskqueue_drain(sc->fc.taskqueue, &sc->fwohci_task_busreset);
809 taskqueue_drain(sc->fc.taskqueue, &sc->fwohci_task_sid);
810 taskqueue_drain(sc->fc.taskqueue, &sc->fwohci_task_dma);
811 taskqueue_drain(sc->fc.taskqueue, &sc->fc.task_timeout);
812 taskqueue_free(sc->fc.taskqueue);
813 sc->fc.taskqueue = NULL;
821 int _cnt = _dbtr->dbcnt; \
822 db = &_dbtr->db[ (_cnt > 2) ? (_cnt -1) : 0]; \
834 db = &db_tr->db[db_tr->dbcnt];
842 FWOHCI_DMA_WRITE(db->db.desc.addr, s->ds_addr);
843 FWOHCI_DMA_WRITE(db->db.desc.cmd, s->ds_len);
844 FWOHCI_DMA_WRITE(db->db.desc.res, 0);
846 db_tr->dbcnt++;
862 int fsegment = -1;
873 FW_GLOCK_ASSERT(&sc->fc);
875 if (&sc->atrq == dbch) {
877 } else if (&sc->atrs == dbch) {
883 if (dbch->flags & FWOHCI_DBCH_FULL)
886 db_tr = dbch->top;
888 xfer = STAILQ_FIRST(&dbch->xferq.q);
893 if (dbch->xferq.queued == 0) {
894 device_printf(sc->fc.dev, "TX queue empty\n");
897 STAILQ_REMOVE_HEAD(&dbch->xferq.q, link);
898 db_tr->xfer = xfer;
899 xfer->flag = FWXF_START;
901 fp = &xfer->send.hdr;
902 tcode = fp->mode.common.tcode;
904 ohcifp = (struct fwohci_txpkthdr *) db_tr->db[1].db.immed;
906 hdr_len = pl_off = info->hdr_len;
908 ld = &ohcifp->mode.ld[0];
911 ld[i/4] = fp->mode.ld[i/4];
913 ohcifp->mode.common.spd = xfer->send.spd & 0x7;
916 ohcifp->mode.stream.len = fp->mode.stream.len;
919 ld[1] = fp->mode.ld[1];
920 ld[2] = fp->mode.ld[2];
921 ohcifp->mode.common.spd = 0;
922 ohcifp->mode.common.tcode = FWOHCITCODE_PHY;
924 ohcifp->mode.asycomm.dst = fp->mode.hdr.dst;
925 ohcifp->mode.asycomm.srcbus = OHCI_ASYSRCBUS;
926 ohcifp->mode.asycomm.tlrt |= FWRETRY_X;
928 db = &db_tr->db[0];
929 FWOHCI_DMA_WRITE(db->db.desc.cmd,
931 FWOHCI_DMA_WRITE(db->db.desc.addr, 0);
932 FWOHCI_DMA_WRITE(db->db.desc.res, 0);
934 if (&sc->atrs == dbch) {
935 FWOHCI_DMA_WRITE(db->db.desc.res,
946 db_tr->dbcnt = 2;
947 db = &db_tr->db[db_tr->dbcnt];
948 if (xfer->send.pay_len > 0) {
951 if (xfer->mbuf == NULL) {
952 err = bus_dmamap_load(dbch->dmat, db_tr->dma_map,
953 &xfer->send.payload[0], xfer->send.pay_len,
957 /* XXX we can handle only 6 (=8-2) mbuf chains */
958 err = bus_dmamap_load_mbuf(dbch->dmat, db_tr->dma_map,
959 xfer->mbuf,
966 device_printf(sc->fc.dev, "EFBIG.\n");
969 m_copydata(xfer->mbuf, 0,
970 xfer->mbuf->m_pkthdr.len,
972 m0->m_len = m0->m_pkthdr.len =
973 xfer->mbuf->m_pkthdr.len;
974 m_freem(xfer->mbuf);
975 xfer->mbuf = m0;
978 device_printf(sc->fc.dev, "m_getcl failed.\n");
983 bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
986 for (i = 2; i < db_tr->dbcnt; i++)
987 FWOHCI_DMA_SET(db_tr->db[i].db.desc.cmd,
991 if (maxdesc < db_tr->dbcnt) {
992 maxdesc = db_tr->dbcnt;
994 device_printf(sc->fc.dev, "%s: maxdesc %d\n", __func__, maxdesc);
998 FWOHCI_DMA_SET(db->db.desc.cmd,
1000 FWOHCI_DMA_WRITE(db->db.desc.depend,
1001 STAILQ_NEXT(db_tr, link)->bus_addr);
1003 if (fsegment == -1)
1004 fsegment = db_tr->dbcnt;
1005 if (dbch->pdb_tr != NULL) {
1006 LAST_DB(dbch->pdb_tr, db);
1007 FWOHCI_DMA_SET(db->db.desc.depend, db_tr->dbcnt);
1009 dbch->xferq.queued++;
1010 dbch->pdb_tr = db_tr;
1012 if (db_tr != dbch->bottom) {
1015 device_printf(sc->fc.dev, "fwohci_start: lack of db_trq\n");
1016 dbch->flags |= FWOHCI_DBCH_FULL;
1020 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREREAD);
1021 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE);
1023 if (dbch->xferq.flag & FWXFERQ_RUNNING) {
1027 device_printf(sc->fc.dev, "start AT DMA status=%x\n",
1029 OWRITE(sc, OHCI_DMACMD(off), dbch->top->bus_addr | fsegment);
1031 dbch->xferq.flag |= FWXFERQ_RUNNING;
1034 dbch->top = db_tr;
1042 FW_GLOCK(&sc->fc);
1043 fwohci_start(sc, &(sc->atrq));
1044 FW_GUNLOCK(&sc->fc);
1052 FW_GLOCK(&sc->fc);
1053 fwohci_start(sc, &(sc->atrs));
1054 FW_GUNLOCK(&sc->fc);
1070 if (&sc->atrq == dbch) {
1073 } else if (&sc->atrs == dbch) {
1080 tr = dbch->bottom;
1082 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_POSTREAD);
1083 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_POSTWRITE);
1084 while (dbch->xferq.queued > 0) {
1086 status = FWOHCI_DMA_READ(db->db.desc.res) >> OHCI_STATUS_SHIFT;
1088 if (fc->status != FWBUSINIT)
1092 bus_dmamap_sync(dbch->dmat, tr->dma_map,
1094 bus_dmamap_unload(dbch->dmat, tr->dma_map);
1102 device_printf(sc->fc.dev, "force reset AT FIFO\n");
1136 if (tr->xfer != NULL) {
1137 xfer = tr->xfer;
1138 if (xfer->flag & FWXF_RCVD) {
1145 microtime(&xfer->tv);
1146 xfer->flag = FWXF_SENT;
1148 xfer->flag = FWXF_BUSY;
1149 xfer->resp = err;
1150 xfer->recv.pay_len = 0;
1154 xfer->flag = FWXF_SENTERR;
1155 xfer->resp = err;
1156 xfer->recv.pay_len = 0;
1168 dbch->xferq.queued--;
1170 tr->xfer = NULL;
1174 dbch->bottom = tr;
1175 if (dbch->bottom == dbch->top) {
1177 if (firewire_debug && dbch->xferq.queued > 0)
1183 if ((dbch->flags & FWOHCI_DBCH_FULL) && packets > 0) {
1185 dbch->flags &= ~FWOHCI_DBCH_FULL;
1199 if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
1202 for (db_tr = STAILQ_FIRST(&dbch->db_trq), idb = 0; idb < dbch->ndb;
1204 if ((dbch->xferq.flag & FWXFERQ_EXTBUF) == 0 &&
1205 db_tr->buf != NULL) {
1206 fwdma_free_size(dbch->dmat, db_tr->dma_map,
1207 db_tr->buf, dbch->xferq.psize);
1208 db_tr->buf = NULL;
1209 } else if (db_tr->dma_map != NULL)
1210 bus_dmamap_destroy(dbch->dmat, db_tr->dma_map);
1212 dbch->ndb = 0;
1213 db_tr = STAILQ_FIRST(&dbch->db_trq);
1214 fwdma_free_multiseg(dbch->am);
1216 STAILQ_INIT(&dbch->db_trq);
1217 dbch->flags &= ~FWOHCI_DBCH_INIT;
1226 if ((dbch->flags & FWOHCI_DBCH_INIT) != 0)
1231 if (bus_dma_tag_create(/*parent*/ sc->fc.dmat,
1236 /*maxsize*/ dbch->xferq.psize,
1237 /*nsegments*/ dbch->ndesc > 3 ? dbch->ndesc - 2 : 1,
1241 /*lockarg*/FW_GMTX(&sc->fc),
1242 &dbch->dmat))
1247 STAILQ_INIT(&dbch->db_trq);
1249 malloc(sizeof(struct fwohcidb_tr) * dbch->ndb,
1252 #define DB_SIZE(x) (sizeof(struct fwohcidb) * (x)->ndesc)
1253 dbch->am = fwdma_malloc_multiseg(&sc->fc, sizeof(struct fwohcidb),
1254 DB_SIZE(dbch), dbch->ndb, BUS_DMA_WAITOK);
1255 if (dbch->am == NULL) {
1261 for (idb = 0; idb < dbch->ndb; idb++) {
1262 db_tr->dbcnt = 0;
1263 db_tr->db = (struct fwohcidb *)fwdma_v_addr(dbch->am, idb);
1264 db_tr->bus_addr = fwdma_bus_addr(dbch->am, idb);
1268 if (bus_dmamap_create(dbch->dmat, 0, &db_tr->dma_map) != 0) {
1270 dbch->flags = FWOHCI_DBCH_INIT; /* XXX fake */
1274 STAILQ_INSERT_TAIL(&dbch->db_trq, db_tr, link);
1275 if (dbch->xferq.flag & FWXFERQ_EXTBUF) {
1276 if (idb % dbch->xferq.bnpacket == 0)
1277 dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket
1279 if ((idb + 1) % dbch->xferq.bnpacket == 0)
1280 dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket
1285 STAILQ_LAST(&dbch->db_trq, fwohcidb_tr,link)->link.stqe_next
1286 = STAILQ_FIRST(&dbch->db_trq);
1288 dbch->xferq.queued = 0;
1289 dbch->pdb_tr = NULL;
1290 dbch->top = STAILQ_FIRST(&dbch->db_trq);
1291 dbch->bottom = dbch->top;
1292 dbch->flags = FWOHCI_DBCH_INIT;
1306 fwohci_db_free(&sc->it[dmach]);
1307 sc->it[dmach].xferq.flag &= ~FWXFERQ_RUNNING;
1321 fwohci_db_free(&sc->ir[dmach]);
1322 sc->ir[dmach].xferq.flag &= ~FWXFERQ_RUNNING;
1344 if (!(dbch->xferq.flag & FWXFERQ_EXTBUF)) {
1348 z = dbch->ndesc;
1349 for (dmach = 0; dmach < sc->fc.nisodma; dmach++) {
1350 if (&sc->it[dmach] == dbch) {
1359 if (dbch->xferq.flag & FWXFERQ_RUNNING)
1361 dbch->xferq.flag |= FWXFERQ_RUNNING;
1362 for (i = 0, dbch->bottom = dbch->top; i < (dbch->ndb - 1); i++) {
1363 dbch->bottom = STAILQ_NEXT(dbch->bottom, link);
1365 db_tr = dbch->top;
1366 for (idb = 0; idb < dbch->ndb; idb++) {
1371 db = db_tr->db;
1372 ldesc = db_tr->dbcnt - 1;
1374 STAILQ_NEXT(db_tr, link)->bus_addr | z);
1376 if (dbch->xferq.flag & FWXFERQ_EXTBUF) {
1377 if (((idb + 1) % dbch->xferq.bnpacket) == 0) {
1390 dbch->bottom->db[dbch->bottom->dbcnt - 1].db.desc.depend, 0xf);
1403 z = dbch->ndesc;
1404 if (&sc->arrq == dbch) {
1406 } else if (&sc->arrs == dbch) {
1409 for (dmach = 0; dmach < sc->fc.nisodma; dmach++) {
1410 if (&sc->ir[dmach] == dbch) {
1420 if (dbch->xferq.flag & FWXFERQ_STREAM) {
1421 if (dbch->xferq.flag & FWXFERQ_RUNNING)
1424 if (dbch->xferq.flag & FWXFERQ_RUNNING) {
1429 dbch->xferq.flag |= FWXFERQ_RUNNING;
1430 dbch->top = STAILQ_FIRST(&dbch->db_trq);
1431 for (i = 0, dbch->bottom = dbch->top; i < (dbch->ndb - 1); i++) {
1432 dbch->bottom = STAILQ_NEXT(dbch->bottom, link);
1434 db_tr = dbch->top;
1435 for (idb = 0; idb < dbch->ndb; idb++) {
1436 fwohci_add_rx_buf(dbch, db_tr, idb, &sc->dummy_dma);
1439 db = db_tr->db;
1440 ldesc = db_tr->dbcnt - 1;
1442 STAILQ_NEXT(db_tr, link)->bus_addr | z);
1443 if (dbch->xferq.flag & FWXFERQ_EXTBUF) {
1444 if (((idb + 1) % dbch->xferq.bnpacket) == 0) {
1456 dbch->bottom->db[db_tr->dbcnt - 1].db.desc.depend, 0xf);
1457 dbch->buf_offset = 0;
1458 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREREAD);
1459 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE);
1460 if (dbch->xferq.flag & FWXFERQ_STREAM) {
1463 OWRITE(sc, OHCI_DMACMD(off), dbch->top->bus_addr | z);
1485 cycle -= 8000;
1511 dbch = &sc->it[dmach];
1512 it = &dbch->xferq;
1514 if ((dbch->flags & FWOHCI_DBCH_INIT) == 0) {
1515 dbch->ndb = it->bnpacket * it->bnchunk;
1516 dbch->ndesc = 3;
1518 if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
1526 ldesc = dbch->ndesc - 1;
1529 prev = STAILQ_LAST(&it->stdma, fw_bulkxfer, link);
1530 while ((chunk = STAILQ_FIRST(&it->stvalid)) != NULL) {
1533 fwdma_sync_multiseg(it->buf, chunk->poffset, it->bnpacket,
1537 db = ((struct fwohcidb_tr *)(prev->end))->db;
1542 #if 0 /* if bulkxfer->npacket changes */
1545 (chunk->start))->bus_addr | dbch->ndesc;
1547 FWOHCI_DMA_SET(db[0].db.desc.depend, dbch->ndesc);
1548 FWOHCI_DMA_SET(db[ldesc].db.desc.depend, dbch->ndesc);
1551 STAILQ_REMOVE_HEAD(&it->stvalid, link);
1552 STAILQ_INSERT_TAIL(&it->stdma, chunk, link);
1556 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE);
1557 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREREAD);
1574 first = STAILQ_FIRST(&it->stdma);
1576 ((struct fwohcidb_tr *)(first->start))->bus_addr | dbch->ndesc);
1586 if (STAILQ_FIRST(&it->stfree) != NULL)
1594 cycle_now = (fc->cyctimer(fc) >> 12) & 0x7fff;
1604 printf("cycle_match: 0x%04x->0x%04x\n",
1610 device_printf(sc->fc.dev,
1630 dbch = &sc->ir[dmach];
1631 ir = &dbch->xferq;
1633 if ((ir->flag & FWXFERQ_RUNNING) == 0) {
1634 tag = (ir->flag >> 6) & 3;
1635 ich = ir->flag & 0x3f;
1638 ir->queued = 0;
1639 dbch->ndb = ir->bnpacket * ir->bnchunk;
1640 dbch->ndesc = 2;
1642 if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
1649 first = STAILQ_FIRST(&ir->stfree);
1651 device_printf(fc->dev, "IR DMA no free chunk\n");
1655 ldesc = dbch->ndesc - 1;
1657 if ((ir->flag & FWXFERQ_HANDLER) == 0)
1659 prev = STAILQ_LAST(&ir->stdma, fw_bulkxfer, link);
1660 while ((chunk = STAILQ_FIRST(&ir->stfree)) != NULL) {
1664 if (chunk->mbuf != NULL) {
1665 db_tr = (struct fwohcidb_tr *)(chunk->start);
1666 db_tr->dbcnt = 1;
1667 err = bus_dmamap_load_mbuf(dbch->dmat, db_tr->dma_map,
1668 chunk->mbuf, fwohci_execute_db2, db_tr,
1670 FWOHCI_DMA_SET(db_tr->db[1].db.desc.cmd,
1675 db = ((struct fwohcidb_tr *)(chunk->end))->db;
1679 db = ((struct fwohcidb_tr *)(prev->end))->db;
1680 FWOHCI_DMA_SET(db[ldesc].db.desc.depend, dbch->ndesc);
1682 STAILQ_REMOVE_HEAD(&ir->stfree, link);
1683 STAILQ_INSERT_TAIL(&ir->stdma, chunk, link);
1686 if ((ir->flag & FWXFERQ_HANDLER) == 0)
1688 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE);
1689 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREREAD);
1696 device_printf(sc->fc.dev, "IR DMA overrun (0x%08x)\n", stat);
1707 ((struct fwohcidb_tr *)(first->start))->bus_addr
1708 | dbch->ndesc);
1722 fwohci_set_intr(&sc->fc, 0);
1730 for (i = 0; i < sc->fc.nisodma; i++) {
1762 for (i = 0; i < sc->fc.nisodma; i++) {
1763 ir = &sc->ir[i].xferq;
1764 if ((ir->flag & FWXFERQ_RUNNING) != 0) {
1765 device_printf(sc->fc.dev,
1767 ir->flag &= ~FWXFERQ_RUNNING;
1769 while ((chunk = STAILQ_FIRST(&ir->stdma)) != NULL) {
1770 STAILQ_REMOVE_HEAD(&ir->stdma, link);
1771 STAILQ_INSERT_TAIL(&ir->stfree, chunk, link);
1773 sc->fc.irx_enable(&sc->fc, i);
1778 sc->fc.ibr(&sc->fc);
1787 device_printf(fc->dev, "INTERRUPT < %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s> 0x%08x, 0x%08x\n",
1822 if ((stat & OHCI_INT_PHY_BUS_R) && (fc->status != FWBUSRESET)) {
1823 fc->status = FWBUSRESET;
1827 device_printf(fc->dev, "%s: BUS reset\n", __func__);
1832 sc->atrq.xferq.flag &= ~FWXFERQ_RUNNING;
1834 sc->atrs.xferq.flag &= ~FWXFERQ_RUNNING;
1837 taskqueue_enqueue(sc->fc.taskqueue, &sc->fwohci_task_busreset);
1852 device_printf(fc->dev,
1863 device_printf(fc->dev,
1867 device_printf(fc->dev,
1882 fc->nodeid = node_id & 0x3f;
1883 device_printf(fc->dev, "%s: node_id=0x%08x, SelfID Count=%d, ",
1884 __func__, fc->nodeid, (plen >> 16) & 0xff);
1886 device_printf(fc->dev, "%s: Bus reset failure\n",
1892 sc->cycle_lost = 0;
1904 fc->status = FWBUSINIT;
1907 taskqueue_enqueue(sc->fc.taskqueue, &sc->fwohci_task_sid);
1911 taskqueue_enqueue(sc->fc.taskqueue, &sc->fwohci_task_dma);
1922 irstat = atomic_readandclear_int(&sc->irstat);
1923 for (i = 0; i < fc->nisodma; i++) {
1927 dbch = &sc->ir[i];
1928 if ((dbch->xferq.flag & FWXFERQ_OPEN) == 0) {
1929 device_printf(sc->fc.dev,
1938 itstat = atomic_readandclear_int(&sc->itstat);
1939 for (i = 0; i < fc->nisodma; i++) {
1950 fwohci_arcv(sc, &sc->arrs, count);
1957 fwohci_arcv(sc, &sc->arrq, count);
1960 if (sc->cycle_lost >= 0)
1961 sc->cycle_lost++;
1962 if (sc->cycle_lost > 10) {
1963 sc->cycle_lost = -1;
1968 device_printf(fc->dev, "too many cycles lost, "
1973 fwohci_txd(sc, &(sc->atrq));
1976 fwohci_txd(sc, &(sc->atrs));
1979 device_printf(fc->dev, "posted write error\n");
1982 device_printf(fc->dev, "unrecoverable error\n");
1985 device_printf(fc->dev, "phy int\n");
1994 FW_GLOCK(&sc->fc);
1995 fw_busreset(&sc->fc, FWBUSRESET);
1996 OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0]));
1997 OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2]));
1998 FW_GUNLOCK(&sc->fc);
2005 struct firewire_comm *fc = &sc->fc;
2017 device_printf(fc->dev, "SID Error\n");
2022 device_printf(fc->dev, "invalid SID len = %d\n", plen);
2025 plen -= 4; /* chop control info */
2028 device_printf(fc->dev, "malloc failed\n");
2032 buf[i] = FWOHCI_DMA_READ(sc->sid_buf[i + 1]);
2034 /* pending all pre-bus_reset packets */
2035 fwohci_txd(sc, &sc->atrq);
2036 fwohci_txd(sc, &sc->atrs);
2037 fwohci_arcv(sc, &sc->arrs, -1);
2038 fwohci_arcv(sc, &sc->arrq, -1);
2051 stat = atomic_readandclear_int(&sc->intstat);
2053 fwohci_intr_dma(sc, stat, -1);
2064 FW_GLOCK_ASSERT(&sc->fc);
2067 if (!bus_child_present(sc->fc.dev))
2069 device_printf(sc->fc.dev, "device physically ejected?\n");
2075 stat &= sc->intmask;
2079 atomic_set_int(&sc->intstat, stat);
2083 atomic_set_int(&sc->irstat, irstat);
2088 atomic_set_int(&sc->itstat, itstat);
2091 fwohci_intr_core(sc, stat, -1);
2100 FW_GLOCK(&sc->fc);
2102 FW_GUNLOCK(&sc->fc);
2122 device_printf(sc->fc.dev, "fwohci_set_intr: %d\n", enable);
2124 sc->intmask |= OHCI_INT_EN;
2127 sc->intmask &= ~OHCI_INT_EN;
2135 struct firewire_comm *fc = &sc->fc;
2142 it = fc->it[dmach];
2143 ldesc = sc->it[dmach].ndesc - 1;
2146 fwdma_sync_multiseg_all(sc->it[dmach].am, BUS_DMASYNC_POSTREAD);
2149 while ((chunk = STAILQ_FIRST(&it->stdma)) != NULL) {
2150 db = ((struct fwohcidb_tr *)(chunk->end))->db;
2153 db = ((struct fwohcidb_tr *)(chunk->start))->db;
2159 STAILQ_REMOVE_HEAD(&it->stdma, link);
2163 device_printf(fc->dev, "0x%08x\n", count);
2167 device_printf(fc->dev,
2171 STAILQ_INSERT_TAIL(&it->stfree, chunk, link);
2183 struct firewire_comm *fc = &sc->fc;
2190 ir = fc->ir[dmach];
2191 ldesc = sc->ir[dmach].ndesc - 1;
2196 if ((ir->flag & FWXFERQ_HANDLER) == 0)
2198 fwdma_sync_multiseg_all(sc->ir[dmach].am, BUS_DMASYNC_POSTREAD);
2199 while ((chunk = STAILQ_FIRST(&ir->stdma)) != NULL) {
2200 db_tr = (struct fwohcidb_tr *)chunk->end;
2201 stat = FWOHCI_DMA_READ(db_tr->db[ldesc].db.desc.res)
2206 if (chunk->mbuf != NULL) {
2207 bus_dmamap_sync(sc->ir[dmach].dmat, db_tr->dma_map,
2209 bus_dmamap_unload(sc->ir[dmach].dmat, db_tr->dma_map);
2210 } else if (ir->buf != NULL) {
2211 fwdma_sync_multiseg(ir->buf, chunk->poffset,
2212 ir->bnpacket, BUS_DMASYNC_POSTREAD);
2218 STAILQ_REMOVE_HEAD(&ir->stdma, link);
2219 STAILQ_INSERT_TAIL(&ir->stvalid, chunk, link);
2222 chunk->resp = 0;
2225 chunk->resp = EINVAL;
2226 device_printf(fc->dev,
2232 if ((ir->flag & FWXFERQ_HANDLER) == 0)
2237 if (ir->flag & FWXFERQ_HANDLER)
2238 ir->hand(ir);
2257 off = OHCI_ITCTL(ch - ITX_CH);
2259 off = OHCI_IRCTL(ch - IRX_CH);
2265 device_printf(sc->fc.dev, "ch %1x cntl:0x%08x cmd:0x%08x match:0x%08x\n",
2272 device_printf(sc->fc.dev, "dma %d ch:%s%s%s%s%s%s %s(%x)\n",
2284 device_printf(sc->fc.dev, "dma %d ch: Nostat\n", ch);
2304 dbch = &sc->atrq;
2307 dbch = &sc->atrs;
2310 dbch = &sc->arrq;
2313 dbch = &sc->arrs;
2315 off = OHCI_ITCTL(ch - ITX_CH);
2316 dbch = &sc->it[ch - ITX_CH];
2318 off = OHCI_IRCTL(ch - IRX_CH);
2319 dbch = &sc->ir[ch - IRX_CH];
2323 if (dbch->ndb == 0) {
2324 device_printf(sc->fc.dev, "No DB is attached ch=%d\n", ch);
2327 pp = dbch->top;
2329 prev = pp->db;
2331 for (idb = 0; idb < dbch->ndb; idb++) {
2340 for (jdb = 0; jdb < dbch->ndesc; jdb++) {
2341 if ((cmd & 0xfffffff0) == cp->bus_addr) {
2342 curr = cp->db;
2345 next = np->db;
2359 prev = pp->db;
2366 print_db(pp, prev, ch, dbch->ndesc);
2369 print_db(cp, curr, ch, dbch->ndesc);
2372 print_db(np, next, ch, dbch->ndesc);
2411 (uintmax_t)db_tr->bus_addr,
2470 device_printf(fc->dev, "Initiate bus reset\n");
2478 OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0]));
2479 OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2]));
2482 * Set root hold-off bit so that non cyclemaster capable node
2511 FW_GLOCK_ASSERT(&sc->fc);
2513 dbch = &sc->it[dmach];
2514 chtag = sc->it[dmach].xferq.flag & 0xff;
2516 db_tr = (struct fwohcidb_tr *)(bulkxfer->start);
2518 fdb_tr = (struct fwohcidb_tr *)(bulkxfer->end);
2519 device_printf(sc->fc.dev, "DB %08x %08x %08x\n", bulkxfer, db_tr->bus_addr, fdb_tr->bus_addr);
2521 for (idb = 0; idb < dbch->xferq.bnpacket; idb++) {
2522 db = db_tr->db;
2523 fp = (struct fw_pkt *)db_tr->buf;
2525 ohcifp->mode.ld[0] = fp->mode.ld[0];
2526 ohcifp->mode.common.spd = 0 & 0x7;
2527 ohcifp->mode.stream.len = fp->mode.stream.len;
2528 ohcifp->mode.stream.chtag = chtag;
2529 ohcifp->mode.stream.tcode = 0xa;
2536 FWOHCI_DMA_SET(db[2].db.desc.cmd, fp->mode.stream.len);
2538 #if 0 /* if bulkxfer->npackets changes */
2543 = db[dbch->ndesc - 1].db.desc.depend
2544 = STAILQ_NEXT(db_tr, link)->bus_addr | dbch->ndesc;
2546 FWOHCI_DMA_SET(db[0].db.desc.depend, dbch->ndesc);
2547 FWOHCI_DMA_SET(db[dbch->ndesc - 1].db.desc.depend, dbch->ndesc);
2549 bulkxfer->end = (caddr_t)db_tr;
2552 db = ((struct fwohcidb_tr *)bulkxfer->end)->db;
2554 FWOHCI_DMA_CLEAR(db[dbch->ndesc - 1].db.desc.depend, 0xf);
2555 #if 0 /* if bulkxfer->npackets changes */
2556 db[dbch->ndesc - 1].db.desc.control |= OHCI_INTERRUPT_ALWAYS;
2561 db_tr = (struct fwohcidb_tr *)bulkxfer->start;
2562 fdb_tr = (struct fwohcidb_tr *)bulkxfer->end;
2563 device_printf(sc->fc.dev, "DB %08x %3d %08x %08x\n", bulkxfer, bulkxfer->npacket, db_tr->bus_addr, …
2572 struct fwohcidb *db = db_tr->db;
2576 it = &dbch->xferq;
2577 if (it->buf == 0) {
2581 db_tr->buf = fwdma_v_addr(it->buf, poffset);
2582 db_tr->dbcnt = 3;
2589 fwdma_bus_addr(it->buf, poffset) + sizeof(uint32_t));
2604 struct fwohcidb *db = db_tr->db;
2610 ir = &dbch->xferq;
2611 if (ir->buf == NULL && (dbch->xferq.flag & FWXFERQ_EXTBUF) == 0) {
2612 if (db_tr->buf == NULL) {
2613 db_tr->buf = fwdma_malloc_size(dbch->dmat,
2614 &db_tr->dma_map, ir->psize, &dbuf[0],
2616 if (db_tr->buf == NULL)
2619 db_tr->dbcnt = 1;
2620 dsiz[0] = ir->psize;
2621 bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
2624 db_tr->dbcnt = 0;
2626 dsiz[db_tr->dbcnt] = sizeof(uint32_t);
2627 dbuf[db_tr->dbcnt++] = dummy_dma->bus_addr;
2629 dsiz[db_tr->dbcnt] = ir->psize;
2630 if (ir->buf != NULL) {
2631 db_tr->buf = fwdma_v_addr(ir->buf, poffset);
2632 dbuf[db_tr->dbcnt] = fwdma_bus_addr(ir->buf, poffset);
2634 db_tr->dbcnt++;
2636 for (i = 0; i < db_tr->dbcnt; i++) {
2639 if (ir->flag & FWXFERQ_STREAM) {
2644 ldesc = db_tr->dbcnt - 1;
2645 if (ir->flag & FWXFERQ_STREAM) {
2664 ld0 = FWOHCI_DMA_READ(fp->mode.ld[0]);
2670 switch (fp0->mode.common.tcode) {
2690 printf("Unknown tcode %d\n", fp0->mode.common.tcode);
2693 hlen = tinfo[fp0->mode.common.tcode].hdr_len;
2697 return (-hlen);
2701 fp->mode.ld[i] = FWOHCI_DMA_READ(fp->mode.ld[i]);
2712 info = &tinfo[fp->mode.common.tcode];
2713 r = info->hdr_len + sizeof(uint32_t);
2714 if ((info->flag & FWTI_BLOCK_ASY) != 0)
2715 r += roundup2((uint32_t)fp->mode.wreqb.len, sizeof(uint32_t));
2719 device_printf(sc->fc.dev, "Unknown tcode %d\n",
2720 fp->mode.common.tcode);
2721 return (-1);
2724 if (r > dbch->xferq.psize) {
2725 device_printf(sc->fc.dev, "Invalid packet length %d\n", r);
2726 return (-1);
2737 struct fwohcidb *db = &db_tr->db[0];
2739 FWOHCI_DMA_CLEAR(db->db.desc.depend, 0xf);
2740 FWOHCI_DMA_WRITE(db->db.desc.res, dbch->xferq.psize);
2741 FWOHCI_DMA_SET(dbch->bottom->db[0].db.desc.depend, 1);
2742 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE);
2743 dbch->bottom = db_tr;
2768 if (&sc->arrq == dbch) {
2770 } else if (&sc->arrs == dbch) {
2777 db_tr = dbch->top;
2782 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_POSTREAD);
2783 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_POSTWRITE);
2784 status = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res) >> OHCI_STATUS_SHIFT;
2785 resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res) & OHCI_COUNT_MASK;
2791 db_tr->bus_addr, status, resCount);
2793 len = dbch->xferq.psize - resCount;
2794 ld = (uint8_t *)db_tr->buf;
2795 if (dbch->pdb_tr == NULL) {
2796 len -= dbch->buf_offset;
2797 ld += dbch->buf_offset;
2800 bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
2803 if (count >= 0 && count-- == 0)
2805 if (dbch->pdb_tr != NULL) {
2809 offset = dbch->buf_offset;
2811 offset = - offset;
2812 buf = dbch->pdb_tr->buf + offset;
2813 rlen = dbch->xferq.psize - offset;
2816 rlen, dbch->buf_offset);
2817 if (dbch->buf_offset < 0) {
2825 rlen = sizeof(pktbuf) - rlen;
2828 bcopy(db_tr->buf, p, rlen);
2830 len -= rlen;
2854 dbch->pdb_tr = db_tr;
2855 dbch->buf_offset = - dbch->buf_offset;
2867 plen = fwohci_get_plen(sc, dbch, fp) - offset;
2876 len -= plen;
2878 dbch->pdb_tr = db_tr;
2895 dbch->buf_offset = ld - (uint8_t *)db_tr->buf;
2899 /* DMA result-code will be written at the tail of packet */
2900 stat = FWOHCI_DMA_READ(*(uint32_t *)(ld - sizeof(struct fwohci_trailer)));
2910 printf("fwohci_arcv: ack pending tcode=0x%x..\n", fp->mode.common.tcode);
2917 if ((vec[nvec-1].iov_len -=
2919 nvec--;
2920 rb.fc = &sc->fc;
2928 if ((sc->fc.status != FWBUSRESET) &&
2929 (sc->fc.status != FWBUSINIT))
2933 device_printf(sc->fc.dev,
2938 dbch->buf_offset, len,
2940 fp->mode.common.tcode, stat);
2949 if (dbch->pdb_tr != NULL) {
2950 fwohci_arcv_free_buf(sc, dbch, dbch->pdb_tr,
2952 dbch->pdb_tr = NULL;
2959 if (dbch->pdb_tr == NULL) {
2961 dbch->buf_offset = 0;
2963 if (dbch->pdb_tr != db_tr)
2966 status = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
2968 resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
2971 dbch->top = db_tr;
2973 dbch->buf_offset = dbch->xferq.psize - resCount;
2986 device_printf(sc->fc.dev, "AR DMA status=%x, ",
2988 dbch->pdb_tr = NULL;
2995 resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
2999 dbch->top = db_tr;
3000 dbch->buf_offset = dbch->xferq.psize - resCount;