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 109356 2003-01-16 07:01:54Z 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 --- 1119 unchanged lines hidden (view full) --- 1161 bzero(db, sizeof (struct fwohcidb) * dbch->ndesc * dbch->ndb); 1162 /* Attach DB to DMA ch. */ 1163 for(idb = 0 ; idb < dbch->ndb ; idb++){ 1164 db_tr->dbcnt = 0; 1165 db_tr->db = &db[idb * dbch->ndesc]; 1166 STAILQ_INSERT_TAIL(&dbch->db_trq, db_tr, link); 1167 if (!(dbch->xferq.flag & FWXFERQ_PACKET) && 1168 dbch->xferq.bnpacket != 0) { |
1169 if (idb % dbch->xferq.bnpacket == 0) 1170 dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket 1171 ].start = (caddr_t)db_tr; 1172 if ((idb + 1) % dbch->xferq.bnpacket == 0) 1173 dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket 1174 ].end = (caddr_t)db_tr; 1175 } 1176 db_tr++; --- 233 unchanged lines hidden (view full) --- 1410fwohci_itxbuf_enable(struct firewire_comm *fc, int dmach) 1411{ 1412 struct fwohci_softc *sc = (struct fwohci_softc *)fc; 1413 int err = 0; 1414 unsigned short tag, ich; 1415 struct fwohci_dbch *dbch; 1416 struct fw_pkt *fp; 1417 struct fwohcidb_tr *db_tr; |
1418 int cycle_now, sec, cycle, cycle_match; 1419 u_int32_t stat; |
1420 1421 tag = (sc->it[dmach].xferq.flag >> 6) & 3; 1422 ich = sc->it[dmach].xferq.flag & 0x3f; 1423 dbch = &sc->it[dmach]; 1424 if ((dbch->flags & FWOHCI_DBCH_INIT) == 0) { 1425 dbch->xferq.queued = 0; 1426 dbch->ndb = dbch->xferq.bnpacket * dbch->xferq.bnchunk; 1427 dbch->ndesc = 3; 1428 fwohci_db_init(dbch); 1429 if ((dbch->flags & FWOHCI_DBCH_INIT) == 0) 1430 return ENOMEM; 1431 err = fwohci_tx_enable(sc, dbch); 1432 } 1433 if(err) 1434 return err; |
1435 stat = OREAD(sc, OHCI_ITCTL(dmach)); 1436 if (stat & OHCI_CNTL_DMA_ACTIVE) { |
1437 if(dbch->xferq.stdma2 != NULL){ 1438 fwohci_txbufdb(sc, dmach, dbch->xferq.stdma2); 1439 ((struct fwohcidb_tr *) 1440 (dbch->xferq.stdma->end))->db[dbch->ndesc - 1].db.desc.cmd 1441 |= OHCI_BRANCH_ALWAYS; 1442 ((struct fwohcidb_tr *) 1443 (dbch->xferq.stdma->end))->db[dbch->ndesc - 1].db.desc.depend = 1444 vtophys(((struct fwohcidb_tr *)(dbch->xferq.stdma2->start))->db) | dbch->ndesc; 1445 ((struct fwohcidb_tr *)(dbch->xferq.stdma->end))->db[0].db.desc.depend = 1446 vtophys(((struct fwohcidb_tr *)(dbch->xferq.stdma2->start))->db) | dbch->ndesc; 1447 ((struct fwohcidb_tr *)(dbch->xferq.stdma2->end))->db[dbch->ndesc - 1].db.desc.depend &= ~0xf; 1448 ((struct fwohcidb_tr *)(dbch->xferq.stdma2->end))->db[0].db.desc.depend &= ~0xf; 1449 } |
1450 } else if(!(stat & OHCI_CNTL_DMA_RUN)) { |
1451 if (firewire_debug) 1452 printf("fwohci_itxbuf_enable: kick 0x%08x\n", 1453 OREAD(sc, OHCI_ITCTL(dmach))); 1454 fw_tbuf_update(&sc->fc, dmach, 0); 1455 if(dbch->xferq.stdma == NULL){ 1456 return err; 1457 } |
1458#if 0 |
1459 OWRITE(sc, OHCI_ITCTLCLR(dmach), OHCI_CNTL_DMA_RUN); |
1460#endif |
1461 OWRITE(sc, OHCI_IT_MASKCLR, 1 << dmach); 1462 OWRITE(sc, OHCI_IT_STATCLR, 1 << dmach); 1463 OWRITE(sc, OHCI_IT_MASK, 1 << dmach); |
1464 fwohci_txbufdb(sc, dmach, dbch->xferq.stdma); 1465 if(dbch->xferq.stdma2 != NULL){ 1466 fwohci_txbufdb(sc, dmach, dbch->xferq.stdma2); 1467 ((struct fwohcidb_tr *) 1468 (dbch->xferq.stdma->end))->db[dbch->ndesc - 1].db.desc.cmd 1469 |= OHCI_BRANCH_ALWAYS; 1470 ((struct fwohcidb_tr *)(dbch->xferq.stdma->end))->db[dbch->ndesc - 1].db.desc.depend = 1471 vtophys(((struct fwohcidb_tr *)(dbch->xferq.stdma2->start))->db) | dbch->ndesc; 1472 ((struct fwohcidb_tr *)(dbch->xferq.stdma->end))->db[0].db.desc.depend = 1473 vtophys(((struct fwohcidb_tr *)(dbch->xferq.stdma2->start))->db) | dbch->ndesc; 1474 ((struct fwohcidb_tr *)(dbch->xferq.stdma2->end))->db[dbch->ndesc - 1].db.desc.depend &= ~0xf; 1475 ((struct fwohcidb_tr *) (dbch->xferq.stdma2->end))->db[0].db.desc.depend &= ~0xf; 1476 }else{ 1477 ((struct fwohcidb_tr *) (dbch->xferq.stdma->end))->db[dbch->ndesc - 1].db.desc.depend &= ~0xf; 1478 ((struct fwohcidb_tr *) (dbch->xferq.stdma->end))->db[0].db.desc.depend &= ~0xf; 1479 } 1480 OWRITE(sc, OHCI_ITCMD(dmach), 1481 vtophys(((struct fwohcidb_tr *) 1482 (dbch->xferq.stdma->start))->db) | dbch->ndesc); |
1483#define CYCLE_OFFSET 1 |
1484 if(dbch->xferq.flag & FWXFERQ_DV){ 1485 db_tr = (struct fwohcidb_tr *)dbch->xferq.stdma->start; 1486 fp = (struct fw_pkt *)db_tr->buf; |
1487 dbch->xferq.dvoffset = CYCLE_OFFSET; |
1488 fp->mode.ld[2] |= htonl(dbch->xferq.dvoffset << 12); 1489 } |
1490 /* 2bit second + 13bit cycle */ 1491 cycle_now = (fc->cyctimer(fc) >> 12) & 0x7fff; 1492 cycle = cycle_now & 0x1fff; 1493 sec = cycle_now >> 13; 1494#define CYCLE_MOD 0x10 1495#define CYCLE_DELAY 8 /* min delay to start DMA */ 1496 cycle = cycle + CYCLE_DELAY; 1497 if (cycle >= 8000) { 1498 sec ++; 1499 cycle -= 8000; 1500 } 1501 cycle = ((cycle + CYCLE_MOD - 1) / CYCLE_MOD) * CYCLE_MOD; 1502 if (cycle >= 8000) { 1503 sec ++; 1504 if (cycle == 8000) 1505 cycle = 0; 1506 else 1507 cycle = CYCLE_MOD; 1508 } 1509 cycle_match = ((sec << 13) | cycle) & 0x7ffff; 1510 if (firewire_debug) 1511 printf("cycle_match: 0x%04x->0x%04x\n", 1512 cycle_now, cycle_match); 1513 /* Clear cycle match counter bits */ 1514 OWRITE(sc, OHCI_ITCTLCLR(dmach), 0xffff0000); 1515 OWRITE(sc, OHCI_ITCTL(dmach), 1516 OHCI_CNTL_CYCMATCH_S | (cycle_match << 16) 1517 | OHCI_CNTL_DMA_RUN); |
1518 OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_DMA_IT); |
1519 } else { 1520 OWRITE(sc, OHCI_ITCTL(dmach), OHCI_CNTL_DMA_WAKE); |
1521 } 1522 return err; 1523} 1524 1525static int 1526fwohci_irxbuf_enable(struct firewire_comm *fc, int dmach) 1527{ 1528 struct fwohci_softc *sc = (struct fwohci_softc *)fc; --- 427 unchanged lines hidden (view full) --- 1956 static int last_timer=0; 1957 1958 timer = (fc->cyctimer(fc) >> 12) & 0xffff; 1959 db_tr = (struct fwohcidb_tr *)dbch->xferq.stdma->start; 1960 fp = (struct fw_pkt *)db_tr->buf; 1961 ciph = (struct ciphdr *) &fp->mode.ld[1]; 1962 timestamp = db_tr->db[2].db.desc.count & 0xffff; 1963 cycl = ntohs(ciph->fdf.dv.cyc) >> 12; |
1964 diff = cycl - (timestamp & 0xf) - CYCLE_OFFSET; |
1965 if (diff < 0) 1966 diff += 16; 1967 if (diff > 8) 1968 diff -= 16; 1969 if (firewire_debug || diff != 0) 1970 printf("dbc: %3d timer: 0x%04x packet: 0x%04x" 1971 " cyc: 0x%x diff: %+1d\n", 1972 ciph->dbc, last_timer, timestamp, cycl, diff); --- 746 unchanged lines hidden --- |