fwohci.c (109280) | fwohci.c (109356) |
---|---|
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 * | 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 109280 2003-01-15 04:21:16Z simokawa $ | 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) { | 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 /* XXX what those for? */ | |
1170 if (idb % dbch->xferq.bnpacket == 0) 1171 dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket 1172 ].start = (caddr_t)db_tr; 1173 if ((idb + 1) % dbch->xferq.bnpacket == 0) 1174 dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket 1175 ].end = (caddr_t)db_tr; 1176 } 1177 db_tr++; --- 233 unchanged lines hidden (view full) --- 1411fwohci_itxbuf_enable(struct firewire_comm *fc, int dmach) 1412{ 1413 struct fwohci_softc *sc = (struct fwohci_softc *)fc; 1414 int err = 0; 1415 unsigned short tag, ich; 1416 struct fwohci_dbch *dbch; 1417 struct fw_pkt *fp; 1418 struct fwohcidb_tr *db_tr; | 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; |
|
1419 1420 tag = (sc->it[dmach].xferq.flag >> 6) & 3; 1421 ich = sc->it[dmach].xferq.flag & 0x3f; 1422 dbch = &sc->it[dmach]; 1423 if ((dbch->flags & FWOHCI_DBCH_INIT) == 0) { 1424 dbch->xferq.queued = 0; 1425 dbch->ndb = dbch->xferq.bnpacket * dbch->xferq.bnchunk; 1426 dbch->ndesc = 3; 1427 fwohci_db_init(dbch); 1428 if ((dbch->flags & FWOHCI_DBCH_INIT) == 0) 1429 return ENOMEM; 1430 err = fwohci_tx_enable(sc, dbch); 1431 } 1432 if(err) 1433 return err; | 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; |
1434 if(OREAD(sc, OHCI_ITCTL(dmach)) & OHCI_CNTL_DMA_ACTIVE){ | 1435 stat = OREAD(sc, OHCI_ITCTL(dmach)); 1436 if (stat & OHCI_CNTL_DMA_ACTIVE) { |
1435 if(dbch->xferq.stdma2 != NULL){ 1436 fwohci_txbufdb(sc, dmach, dbch->xferq.stdma2); 1437 ((struct fwohcidb_tr *) 1438 (dbch->xferq.stdma->end))->db[dbch->ndesc - 1].db.desc.cmd 1439 |= OHCI_BRANCH_ALWAYS; 1440 ((struct fwohcidb_tr *) 1441 (dbch->xferq.stdma->end))->db[dbch->ndesc - 1].db.desc.depend = 1442 vtophys(((struct fwohcidb_tr *)(dbch->xferq.stdma2->start))->db) | dbch->ndesc; 1443 ((struct fwohcidb_tr *)(dbch->xferq.stdma->end))->db[0].db.desc.depend = 1444 vtophys(((struct fwohcidb_tr *)(dbch->xferq.stdma2->start))->db) | dbch->ndesc; 1445 ((struct fwohcidb_tr *)(dbch->xferq.stdma2->end))->db[dbch->ndesc - 1].db.desc.depend &= ~0xf; 1446 ((struct fwohcidb_tr *)(dbch->xferq.stdma2->end))->db[0].db.desc.depend &= ~0xf; 1447 } | 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 } |
1448 }else if(!(OREAD(sc, OHCI_ITCTL(dmach)) & OHCI_CNTL_DMA_ACTIVE)){ | 1450 } else if(!(stat & OHCI_CNTL_DMA_RUN)) { |
1449 if (firewire_debug) 1450 printf("fwohci_itxbuf_enable: kick 0x%08x\n", 1451 OREAD(sc, OHCI_ITCTL(dmach))); 1452 fw_tbuf_update(&sc->fc, dmach, 0); 1453 if(dbch->xferq.stdma == NULL){ 1454 return err; 1455 } | 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 |
|
1456 OWRITE(sc, OHCI_ITCTLCLR(dmach), OHCI_CNTL_DMA_RUN); | 1459 OWRITE(sc, OHCI_ITCTLCLR(dmach), OHCI_CNTL_DMA_RUN); |
1460#endif |
|
1457 OWRITE(sc, OHCI_IT_MASKCLR, 1 << dmach); 1458 OWRITE(sc, OHCI_IT_STATCLR, 1 << dmach); 1459 OWRITE(sc, OHCI_IT_MASK, 1 << dmach); | 1461 OWRITE(sc, OHCI_IT_MASKCLR, 1 << dmach); 1462 OWRITE(sc, OHCI_IT_STATCLR, 1 << dmach); 1463 OWRITE(sc, OHCI_IT_MASK, 1 << dmach); |
1460 OWRITE(sc, OHCI_ITCTLCLR(dmach), 0xf0000000); | |
1461 fwohci_txbufdb(sc, dmach, dbch->xferq.stdma); 1462 if(dbch->xferq.stdma2 != NULL){ 1463 fwohci_txbufdb(sc, dmach, dbch->xferq.stdma2); 1464 ((struct fwohcidb_tr *) 1465 (dbch->xferq.stdma->end))->db[dbch->ndesc - 1].db.desc.cmd 1466 |= OHCI_BRANCH_ALWAYS; 1467 ((struct fwohcidb_tr *)(dbch->xferq.stdma->end))->db[dbch->ndesc - 1].db.desc.depend = 1468 vtophys(((struct fwohcidb_tr *)(dbch->xferq.stdma2->start))->db) | dbch->ndesc; 1469 ((struct fwohcidb_tr *)(dbch->xferq.stdma->end))->db[0].db.desc.depend = 1470 vtophys(((struct fwohcidb_tr *)(dbch->xferq.stdma2->start))->db) | dbch->ndesc; 1471 ((struct fwohcidb_tr *)(dbch->xferq.stdma2->end))->db[dbch->ndesc - 1].db.desc.depend &= ~0xf; 1472 ((struct fwohcidb_tr *) (dbch->xferq.stdma2->end))->db[0].db.desc.depend &= ~0xf; 1473 }else{ 1474 ((struct fwohcidb_tr *) (dbch->xferq.stdma->end))->db[dbch->ndesc - 1].db.desc.depend &= ~0xf; 1475 ((struct fwohcidb_tr *) (dbch->xferq.stdma->end))->db[0].db.desc.depend &= ~0xf; 1476 } 1477 OWRITE(sc, OHCI_ITCMD(dmach), 1478 vtophys(((struct fwohcidb_tr *) 1479 (dbch->xferq.stdma->start))->db) | dbch->ndesc); | 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 |
|
1480 if(dbch->xferq.flag & FWXFERQ_DV){ 1481 db_tr = (struct fwohcidb_tr *)dbch->xferq.stdma->start; 1482 fp = (struct fw_pkt *)db_tr->buf; | 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; |
1483 dbch->xferq.dvoffset = 1484 ((fc->cyctimer(fc) >> 12) + 4) & 0xf; 1485#if 0 1486 printf("dvoffset: %d\n", dbch->xferq.dvoffset); 1487#endif | 1487 dbch->xferq.dvoffset = CYCLE_OFFSET; |
1488 fp->mode.ld[2] |= htonl(dbch->xferq.dvoffset << 12); 1489 } | 1488 fp->mode.ld[2] |= htonl(dbch->xferq.dvoffset << 12); 1489 } |
1490 1491 OWRITE(sc, OHCI_ITCTL(dmach), OHCI_CNTL_DMA_RUN); | 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); |
1492 OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_DMA_IT); | 1518 OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_DMA_IT); |
1519 } else { 1520 OWRITE(sc, OHCI_ITCTL(dmach), OHCI_CNTL_DMA_WAKE); |
|
1493 } 1494 return err; 1495} 1496 1497static int 1498fwohci_irxbuf_enable(struct firewire_comm *fc, int dmach) 1499{ 1500 struct fwohci_softc *sc = (struct fwohci_softc *)fc; --- 427 unchanged lines hidden (view full) --- 1928 static int last_timer=0; 1929 1930 timer = (fc->cyctimer(fc) >> 12) & 0xffff; 1931 db_tr = (struct fwohcidb_tr *)dbch->xferq.stdma->start; 1932 fp = (struct fw_pkt *)db_tr->buf; 1933 ciph = (struct ciphdr *) &fp->mode.ld[1]; 1934 timestamp = db_tr->db[2].db.desc.count & 0xffff; 1935 cycl = ntohs(ciph->fdf.dv.cyc) >> 12; | 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; |
1936 diff = cycl - (timestamp & 0xf) - 1; | 1964 diff = cycl - (timestamp & 0xf) - CYCLE_OFFSET; |
1937 if (diff < 0) 1938 diff += 16; 1939 if (diff > 8) 1940 diff -= 16; 1941 if (firewire_debug || diff != 0) 1942 printf("dbc: %3d timer: 0x%04x packet: 0x%04x" 1943 " cyc: 0x%x diff: %+1d\n", 1944 ciph->dbc, last_timer, timestamp, cycl, diff); --- 746 unchanged lines hidden --- | 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 --- |