Deleted Added
full compact
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 ---