fwohci.c (109379) | fwohci.c (109403) |
---|---|
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 109379 2003-01-16 13:09:33Z simokawa $ | 33 * $FreeBSD: head/sys/dev/firewire/fwohci.c 109403 2003-01-17 03:52:48Z 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 --- 1102 unchanged lines hidden (view full) --- 1144 M_DEVBUF, M_DONTWAIT | M_ZERO); 1145 if(db_tr == NULL){ 1146 printf("fwohci_db_init: malloc(1) failed\n"); 1147 return; 1148 } 1149 1150 ndbpp = PAGE_SIZE / (sizeof(struct fwohcidb) * dbch->ndesc); 1151 dbch->npages = (dbch->ndb + ndbpp - 1)/ ndbpp; | 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 --- 1102 unchanged lines hidden (view full) --- 1144 M_DEVBUF, M_DONTWAIT | M_ZERO); 1145 if(db_tr == NULL){ 1146 printf("fwohci_db_init: malloc(1) failed\n"); 1147 return; 1148 } 1149 1150 ndbpp = PAGE_SIZE / (sizeof(struct fwohcidb) * dbch->ndesc); 1151 dbch->npages = (dbch->ndb + ndbpp - 1)/ ndbpp; |
1152#if 0 1153 printf("ndesc: %d, ndbpp: %d, ndb: %d, npages: %d\n", 1154 dbch->ndesc, ndbpp, dbch->ndb, dbch->npages); 1155#endif | 1152 if (firewire_debug) 1153 printf("ndesc: %d, ndbpp: %d, ndb: %d, npages: %d\n", 1154 dbch->ndesc, ndbpp, dbch->ndb, dbch->npages); |
1156 if (dbch->npages > FWOHCI_DBCH_MAX_PAGES) { 1157 printf("npages(%d) > DBCH_MAX_PAGES(%d)\n", 1158 dbch->npages, FWOHCI_DBCH_MAX_PAGES); 1159 return; 1160 } 1161 for (i = 0; i < dbch->npages; i++) { 1162 dbch->pages[i] = malloc(PAGE_SIZE, M_DEVBUF, 1163 M_DONTWAIT | M_ZERO); --- 288 unchanged lines hidden (view full) --- 1452 |= OHCI_BRANCH_ALWAYS; 1453 ((struct fwohcidb_tr *) 1454 (dbch->xferq.stdma->end))->db[dbch->ndesc - 1].db.desc.depend = 1455 vtophys(((struct fwohcidb_tr *)(dbch->xferq.stdma2->start))->db) | dbch->ndesc; 1456 ((struct fwohcidb_tr *)(dbch->xferq.stdma->end))->db[0].db.desc.depend = 1457 vtophys(((struct fwohcidb_tr *)(dbch->xferq.stdma2->start))->db) | dbch->ndesc; 1458 ((struct fwohcidb_tr *)(dbch->xferq.stdma2->end))->db[dbch->ndesc - 1].db.desc.depend &= ~0xf; 1459 ((struct fwohcidb_tr *)(dbch->xferq.stdma2->end))->db[0].db.desc.depend &= ~0xf; | 1155 if (dbch->npages > FWOHCI_DBCH_MAX_PAGES) { 1156 printf("npages(%d) > DBCH_MAX_PAGES(%d)\n", 1157 dbch->npages, FWOHCI_DBCH_MAX_PAGES); 1158 return; 1159 } 1160 for (i = 0; i < dbch->npages; i++) { 1161 dbch->pages[i] = malloc(PAGE_SIZE, M_DEVBUF, 1162 M_DONTWAIT | M_ZERO); --- 288 unchanged lines hidden (view full) --- 1451 |= OHCI_BRANCH_ALWAYS; 1452 ((struct fwohcidb_tr *) 1453 (dbch->xferq.stdma->end))->db[dbch->ndesc - 1].db.desc.depend = 1454 vtophys(((struct fwohcidb_tr *)(dbch->xferq.stdma2->start))->db) | dbch->ndesc; 1455 ((struct fwohcidb_tr *)(dbch->xferq.stdma->end))->db[0].db.desc.depend = 1456 vtophys(((struct fwohcidb_tr *)(dbch->xferq.stdma2->start))->db) | dbch->ndesc; 1457 ((struct fwohcidb_tr *)(dbch->xferq.stdma2->end))->db[dbch->ndesc - 1].db.desc.depend &= ~0xf; 1458 ((struct fwohcidb_tr *)(dbch->xferq.stdma2->end))->db[0].db.desc.depend &= ~0xf; |
1459 } else { 1460 if (firewire_debug) 1461 device_printf(fc->dev, 1462 "fwohci_itxbuf_enable: queue underrun\n"); |
|
1460 } | 1463 } |
1461 } else if(!(stat & OHCI_CNTL_DMA_RUN)) { 1462 if (firewire_debug) 1463 printf("fwohci_itxbuf_enable: kick 0x%08x\n", 1464 OREAD(sc, OHCI_ITCTL(dmach))); 1465 fw_tbuf_update(&sc->fc, dmach, 0); 1466 if(dbch->xferq.stdma == NULL){ 1467 return err; 1468 } 1469#if 0 1470 OWRITE(sc, OHCI_ITCTLCLR(dmach), OHCI_CNTL_DMA_RUN); 1471#endif 1472 OWRITE(sc, OHCI_IT_MASKCLR, 1 << dmach); 1473 OWRITE(sc, OHCI_IT_STATCLR, 1 << dmach); 1474 OWRITE(sc, OHCI_IT_MASK, 1 << dmach); 1475 fwohci_txbufdb(sc, dmach, dbch->xferq.stdma); 1476 if(dbch->xferq.stdma2 != NULL){ 1477 fwohci_txbufdb(sc, dmach, dbch->xferq.stdma2); 1478 ((struct fwohcidb_tr *) | 1464 return err; 1465 } 1466 if (firewire_debug) 1467 printf("fwohci_itxbuf_enable: kick 0x%08x\n", stat); 1468 fw_tbuf_update(&sc->fc, dmach, 0); 1469 if(dbch->xferq.stdma == NULL){ 1470 return err; 1471 } 1472 if(dbch->xferq.stdma2 == NULL){ 1473 /* wait until 2 chunks buffered */ 1474 return err; 1475 } 1476 OWRITE(sc, OHCI_IT_MASKCLR, 1 << dmach); 1477 OWRITE(sc, OHCI_IT_STATCLR, 1 << dmach); 1478 OWRITE(sc, OHCI_IT_MASK, 1 << dmach); 1479 fwohci_txbufdb(sc, dmach, dbch->xferq.stdma); 1480 fwohci_txbufdb(sc, dmach, dbch->xferq.stdma2); 1481 ((struct fwohcidb_tr *) |
1479 (dbch->xferq.stdma->end))->db[dbch->ndesc - 1].db.desc.cmd 1480 |= OHCI_BRANCH_ALWAYS; | 1482 (dbch->xferq.stdma->end))->db[dbch->ndesc - 1].db.desc.cmd 1483 |= OHCI_BRANCH_ALWAYS; |
1481 ((struct fwohcidb_tr *)(dbch->xferq.stdma->end))->db[dbch->ndesc - 1].db.desc.depend = | 1484 ((struct fwohcidb_tr *)(dbch->xferq.stdma->end))->db[dbch->ndesc - 1].db.desc.depend = |
1482 vtophys(((struct fwohcidb_tr *)(dbch->xferq.stdma2->start))->db) | dbch->ndesc; | 1485 vtophys(((struct fwohcidb_tr *)(dbch->xferq.stdma2->start))->db) | dbch->ndesc; |
1483 ((struct fwohcidb_tr *)(dbch->xferq.stdma->end))->db[0].db.desc.depend = | 1486 ((struct fwohcidb_tr *)(dbch->xferq.stdma->end))->db[0].db.desc.depend = |
1484 vtophys(((struct fwohcidb_tr *)(dbch->xferq.stdma2->start))->db) | dbch->ndesc; | 1487 vtophys(((struct fwohcidb_tr *)(dbch->xferq.stdma2->start))->db) | dbch->ndesc; |
1485 ((struct fwohcidb_tr *)(dbch->xferq.stdma2->end))->db[dbch->ndesc - 1].db.desc.depend &= ~0xf; 1486 ((struct fwohcidb_tr *) (dbch->xferq.stdma2->end))->db[0].db.desc.depend &= ~0xf; 1487 }else{ 1488 ((struct fwohcidb_tr *) (dbch->xferq.stdma->end))->db[dbch->ndesc - 1].db.desc.depend &= ~0xf; 1489 ((struct fwohcidb_tr *) (dbch->xferq.stdma->end))->db[0].db.desc.depend &= ~0xf; 1490 } 1491 OWRITE(sc, OHCI_ITCMD(dmach), 1492 vtophys(((struct fwohcidb_tr *) 1493 (dbch->xferq.stdma->start))->db) | dbch->ndesc); | 1488 ((struct fwohcidb_tr *)(dbch->xferq.stdma2->end))->db[dbch->ndesc - 1].db.desc.depend &= ~0xf; 1489 ((struct fwohcidb_tr *) (dbch->xferq.stdma2->end))->db[0].db.desc.depend &= ~0xf; 1490 OWRITE(sc, OHCI_ITCMD(dmach), 1491 vtophys(((struct fwohcidb_tr *) 1492 (dbch->xferq.stdma->start))->db) | dbch->ndesc); |
1494#define CYCLE_OFFSET 1 | 1493#define CYCLE_OFFSET 1 |
1494 if ((stat & OHCI_CNTL_DMA_RUN) == 0) { |
|
1495 if(dbch->xferq.flag & FWXFERQ_DV){ 1496 db_tr = (struct fwohcidb_tr *)dbch->xferq.stdma->start; 1497 fp = (struct fw_pkt *)db_tr->buf; 1498 dbch->xferq.dvoffset = CYCLE_OFFSET; 1499 fp->mode.ld[2] |= htonl(dbch->xferq.dvoffset << 12); 1500 } 1501 /* 2bit second + 13bit cycle */ 1502 cycle_now = (fc->cyctimer(fc) >> 12) & 0x7fff; --- 10 unchanged lines hidden (view full) --- 1513 if (cycle >= 8000) { 1514 sec ++; 1515 if (cycle == 8000) 1516 cycle = 0; 1517 else 1518 cycle = CYCLE_MOD; 1519 } 1520 cycle_match = ((sec << 13) | cycle) & 0x7ffff; | 1495 if(dbch->xferq.flag & FWXFERQ_DV){ 1496 db_tr = (struct fwohcidb_tr *)dbch->xferq.stdma->start; 1497 fp = (struct fw_pkt *)db_tr->buf; 1498 dbch->xferq.dvoffset = CYCLE_OFFSET; 1499 fp->mode.ld[2] |= htonl(dbch->xferq.dvoffset << 12); 1500 } 1501 /* 2bit second + 13bit cycle */ 1502 cycle_now = (fc->cyctimer(fc) >> 12) & 0x7fff; --- 10 unchanged lines hidden (view full) --- 1513 if (cycle >= 8000) { 1514 sec ++; 1515 if (cycle == 8000) 1516 cycle = 0; 1517 else 1518 cycle = CYCLE_MOD; 1519 } 1520 cycle_match = ((sec << 13) | cycle) & 0x7ffff; |
1521 if (firewire_debug) 1522 printf("cycle_match: 0x%04x->0x%04x\n", 1523 cycle_now, cycle_match); | |
1524 /* Clear cycle match counter bits */ 1525 OWRITE(sc, OHCI_ITCTLCLR(dmach), 0xffff0000); 1526 OWRITE(sc, OHCI_ITCTL(dmach), 1527 OHCI_CNTL_CYCMATCH_S | (cycle_match << 16) 1528 | OHCI_CNTL_DMA_RUN); 1529 OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_DMA_IT); | 1521 /* Clear cycle match counter bits */ 1522 OWRITE(sc, OHCI_ITCTLCLR(dmach), 0xffff0000); 1523 OWRITE(sc, OHCI_ITCTL(dmach), 1524 OHCI_CNTL_CYCMATCH_S | (cycle_match << 16) 1525 | OHCI_CNTL_DMA_RUN); 1526 OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_DMA_IT); |
1530 } else { 1531 OWRITE(sc, OHCI_ITCTL(dmach), OHCI_CNTL_DMA_WAKE); | 1527 if (firewire_debug) 1528 printf("cycle_match: 0x%04x->0x%04x\n", 1529 cycle_now, cycle_match); 1530 } else if ((stat & OHCI_CNTL_CYCMATCH_S) == 0) { 1531 if (firewire_debug) 1532 printf("fwohci_itxbuf_enable: restart 0x%08x\n", stat); 1533 OWRITE(sc, OHCI_ITCTLCLR(dmach), OHCI_CNTL_DMA_RUN); 1534 OWRITE(sc, OHCI_ITCTL(dmach), OHCI_CNTL_DMA_RUN); |
1532 } 1533 return err; 1534} 1535 1536static int 1537fwohci_irxbuf_enable(struct firewire_comm *fc, int dmach) 1538{ 1539 struct fwohci_softc *sc = (struct fwohci_softc *)fc; --- 412 unchanged lines hidden (view full) --- 1952/* 1953 * Overwrite highest significant 4 bits timestamp information 1954 */ 1955 fp = (struct fw_pkt *)db_tr->buf; 1956 fp->mode.ld[2] &= htonl(0xffff0fff); 1957 fp->mode.ld[2] |= htonl((fc->cyctimer(fc) + 0x4000) & 0xf000); 1958 } 1959#endif | 1535 } 1536 return err; 1537} 1538 1539static int 1540fwohci_irxbuf_enable(struct firewire_comm *fc, int dmach) 1541{ 1542 struct fwohci_softc *sc = (struct fwohci_softc *)fc; --- 412 unchanged lines hidden (view full) --- 1955/* 1956 * Overwrite highest significant 4 bits timestamp information 1957 */ 1958 fp = (struct fw_pkt *)db_tr->buf; 1959 fp->mode.ld[2] &= htonl(0xffff0fff); 1960 fp->mode.ld[2] |= htonl((fc->cyctimer(fc) + 0x4000) & 0xf000); 1961 } 1962#endif |
1963 /* 1964 * XXX interrupt could be missed. 1965 * We have to check more than one buffer/chunk 1966 */ 1967 if (firewire_debug && dbch->xferq.stdma2 != NULL) { 1968 db_tr = (struct fwohcidb_tr *)dbch->xferq.stdma2->end; 1969 stat = db_tr->db[2].db.desc.status; 1970 if (stat) 1971 printf("XXX stdma2 already done stat:0x%x\n", stat); 1972 } 1973 |
|
1960 stat = OREAD(sc, OHCI_ITCTL(dmach)) & 0x1f; 1961 switch(stat){ 1962 case FWOHCIEV_ACKCOMPL: 1963#if 1 1964 if (dbch->xferq.flag & FWXFERQ_DV) { 1965 struct ciphdr *ciph; 1966 int timer, timestamp, cycl, diff; 1967 static int last_timer=0; --- 762 unchanged lines hidden --- | 1974 stat = OREAD(sc, OHCI_ITCTL(dmach)) & 0x1f; 1975 switch(stat){ 1976 case FWOHCIEV_ACKCOMPL: 1977#if 1 1978 if (dbch->xferq.flag & FWXFERQ_DV) { 1979 struct ciphdr *ciph; 1980 int timer, timestamp, cycl, diff; 1981 static int last_timer=0; --- 762 unchanged lines hidden --- |