fwohci.c (119289) | fwohci.c (120660) |
---|---|
1/* 2 * Copyright (c) 2003 Hidetoshi Shimokawa 3 * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 17 unchanged lines hidden (view full) --- 26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 * POSSIBILITY OF SUCH DAMAGE. 33 * | 1/* 2 * Copyright (c) 2003 Hidetoshi Shimokawa 3 * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 17 unchanged lines hidden (view full) --- 26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 * POSSIBILITY OF SUCH DAMAGE. 33 * |
34 * $FreeBSD: head/sys/dev/firewire/fwohci.c 119289 2003-08-22 07:30:41Z simokawa $ | 34 * $FreeBSD: head/sys/dev/firewire/fwohci.c 120660 2003-10-02 04:06:56Z simokawa $ |
35 * 36 */ 37 38#define ATRQ_CH 0 39#define ATRS_CH 1 40#define ARRQ_CH 2 41#define ARRS_CH 3 42#define ITX_CH 4 --- 90 unchanged lines hidden (view full) --- 133static int fwohci_itxbuf_enable __P((struct firewire_comm *, int)); 134static int fwohci_itx_disable __P((struct firewire_comm *, int)); 135static void fwohci_timeout __P((void *)); 136static void fwohci_set_intr __P((struct firewire_comm *, int)); 137 138static int fwohci_add_rx_buf __P((struct fwohci_dbch *, struct fwohcidb_tr *, int, struct fwdma_alloc *)); 139static int fwohci_add_tx_buf __P((struct fwohci_dbch *, struct fwohcidb_tr *, int)); 140static void dump_db __P((struct fwohci_softc *, u_int32_t)); | 35 * 36 */ 37 38#define ATRQ_CH 0 39#define ATRS_CH 1 40#define ARRQ_CH 2 41#define ARRS_CH 3 42#define ITX_CH 4 --- 90 unchanged lines hidden (view full) --- 133static int fwohci_itxbuf_enable __P((struct firewire_comm *, int)); 134static int fwohci_itx_disable __P((struct firewire_comm *, int)); 135static void fwohci_timeout __P((void *)); 136static void fwohci_set_intr __P((struct firewire_comm *, int)); 137 138static int fwohci_add_rx_buf __P((struct fwohci_dbch *, struct fwohcidb_tr *, int, struct fwdma_alloc *)); 139static int fwohci_add_tx_buf __P((struct fwohci_dbch *, struct fwohcidb_tr *, int)); 140static void dump_db __P((struct fwohci_softc *, u_int32_t)); |
141static void print_db __P((struct fwohcidb_tr *, volatile struct fwohcidb *, u_int32_t , u_int32_t)); | 141static void print_db __P((struct fwohcidb_tr *, struct fwohcidb *, u_int32_t , u_int32_t)); |
142static void dump_dma __P((struct fwohci_softc *, u_int32_t)); 143static u_int32_t fwohci_cyctimer __P((struct firewire_comm *)); 144static void fwohci_rbuf_update __P((struct fwohci_softc *, int)); 145static void fwohci_tbuf_update __P((struct fwohci_softc *, int)); 146void fwohci_txbufdb __P((struct fwohci_softc *, int , struct fw_bulkxfer *)); 147#if FWOHCI_TASKQUEUE 148static void fwohci_complete(void *, int); 149#endif --- 644 unchanged lines hidden (view full) --- 794 int _cnt = _dbtr->dbcnt; \ 795 db = &_dbtr->db[ (_cnt > 2) ? (_cnt -1) : 0]; \ 796} while (0) 797 798static void 799fwohci_execute_db(void *arg, bus_dma_segment_t *segs, int nseg, int error) 800{ 801 struct fwohcidb_tr *db_tr; | 142static void dump_dma __P((struct fwohci_softc *, u_int32_t)); 143static u_int32_t fwohci_cyctimer __P((struct firewire_comm *)); 144static void fwohci_rbuf_update __P((struct fwohci_softc *, int)); 145static void fwohci_tbuf_update __P((struct fwohci_softc *, int)); 146void fwohci_txbufdb __P((struct fwohci_softc *, int , struct fw_bulkxfer *)); 147#if FWOHCI_TASKQUEUE 148static void fwohci_complete(void *, int); 149#endif --- 644 unchanged lines hidden (view full) --- 794 int _cnt = _dbtr->dbcnt; \ 795 db = &_dbtr->db[ (_cnt > 2) ? (_cnt -1) : 0]; \ 796} while (0) 797 798static void 799fwohci_execute_db(void *arg, bus_dma_segment_t *segs, int nseg, int error) 800{ 801 struct fwohcidb_tr *db_tr; |
802 volatile struct fwohcidb *db; | 802 struct fwohcidb *db; |
803 bus_dma_segment_t *s; 804 int i; 805 806 db_tr = (struct fwohcidb_tr *)arg; 807 db = &db_tr->db[db_tr->dbcnt]; 808 if (error) { 809 if (firewire_debug || error != EFBIG) 810 printf("fwohci_execute_db: error=%d\n", error); --- 15 unchanged lines hidden (view full) --- 826{ 827 fwohci_execute_db(arg, segs, nseg, error); 828} 829 830static void 831fwohci_start(struct fwohci_softc *sc, struct fwohci_dbch *dbch) 832{ 833 int i, s; | 803 bus_dma_segment_t *s; 804 int i; 805 806 db_tr = (struct fwohcidb_tr *)arg; 807 db = &db_tr->db[db_tr->dbcnt]; 808 if (error) { 809 if (firewire_debug || error != EFBIG) 810 printf("fwohci_execute_db: error=%d\n", error); --- 15 unchanged lines hidden (view full) --- 826{ 827 fwohci_execute_db(arg, segs, nseg, error); 828} 829 830static void 831fwohci_start(struct fwohci_softc *sc, struct fwohci_dbch *dbch) 832{ 833 int i, s; |
834 int tcode, hdr_len, pl_off, pl_len; | 834 int tcode, hdr_len, pl_off; |
835 int fsegment = -1; 836 u_int32_t off; 837 struct fw_xfer *xfer; 838 struct fw_pkt *fp; | 835 int fsegment = -1; 836 u_int32_t off; 837 struct fw_xfer *xfer; 838 struct fw_pkt *fp; |
839 volatile struct fwohci_txpkthdr *ohcifp; | 839 struct fwohci_txpkthdr *ohcifp; |
840 struct fwohcidb_tr *db_tr; | 840 struct fwohcidb_tr *db_tr; |
841 volatile struct fwohcidb *db; 842 volatile u_int32_t *ld; | 841 struct fwohcidb *db; 842 u_int32_t *ld; |
843 struct tcode_info *info; 844 static int maxdesc=0; 845 846 if(&sc->atrq == dbch){ 847 off = OHCI_ATQOFF; 848 }else if(&sc->atrs == dbch){ 849 off = OHCI_ATSOFF; 850 }else{ --- 12 unchanged lines hidden (view full) --- 863 } 864 if(dbch->xferq.queued == 0 ){ 865 device_printf(sc->fc.dev, "TX queue empty\n"); 866 } 867 STAILQ_REMOVE_HEAD(&dbch->xferq.q, link); 868 db_tr->xfer = xfer; 869 xfer->state = FWXF_START; 870 | 843 struct tcode_info *info; 844 static int maxdesc=0; 845 846 if(&sc->atrq == dbch){ 847 off = OHCI_ATQOFF; 848 }else if(&sc->atrs == dbch){ 849 off = OHCI_ATSOFF; 850 }else{ --- 12 unchanged lines hidden (view full) --- 863 } 864 if(dbch->xferq.queued == 0 ){ 865 device_printf(sc->fc.dev, "TX queue empty\n"); 866 } 867 STAILQ_REMOVE_HEAD(&dbch->xferq.q, link); 868 db_tr->xfer = xfer; 869 xfer->state = FWXF_START; 870 |
871 fp = (struct fw_pkt *)xfer->send.buf; | 871 fp = &xfer->send.hdr; |
872 tcode = fp->mode.common.tcode; 873 | 872 tcode = fp->mode.common.tcode; 873 |
874 ohcifp = (volatile struct fwohci_txpkthdr *) db_tr->db[1].db.immed; | 874 ohcifp = (struct fwohci_txpkthdr *) db_tr->db[1].db.immed; |
875 info = &tinfo[tcode]; 876 hdr_len = pl_off = info->hdr_len; 877 878 ld = &ohcifp->mode.ld[0]; 879 ld[0] = ld[1] = ld[2] = ld[3] = 0; 880 for( i = 0 ; i < pl_off ; i+= 4) 881 ld[i/4] = fp->mode.ld[i/4]; 882 | 875 info = &tinfo[tcode]; 876 hdr_len = pl_off = info->hdr_len; 877 878 ld = &ohcifp->mode.ld[0]; 879 ld[0] = ld[1] = ld[2] = ld[3] = 0; 880 for( i = 0 ; i < pl_off ; i+= 4) 881 ld[i/4] = fp->mode.ld[i/4]; 882 |
883 ohcifp->mode.common.spd = xfer->spd & 0x7; | 883 ohcifp->mode.common.spd = xfer->send.spd & 0x7; |
884 if (tcode == FWTCODE_STREAM ){ 885 hdr_len = 8; 886 ohcifp->mode.stream.len = fp->mode.stream.len; 887 } else if (tcode == FWTCODE_PHY) { 888 hdr_len = 12; 889 ld[1] = fp->mode.ld[1]; 890 ld[2] = fp->mode.ld[2]; 891 ohcifp->mode.common.spd = 0; --- 18 unchanged lines hidden (view full) --- 910 hdr_len = 12; 911 for (i = 0; i < hdr_len/4; i ++) 912 FWOHCI_DMA_WRITE(ld[i], ld[i]); 913#endif 914 915again: 916 db_tr->dbcnt = 2; 917 db = &db_tr->db[db_tr->dbcnt]; | 884 if (tcode == FWTCODE_STREAM ){ 885 hdr_len = 8; 886 ohcifp->mode.stream.len = fp->mode.stream.len; 887 } else if (tcode == FWTCODE_PHY) { 888 hdr_len = 12; 889 ld[1] = fp->mode.ld[1]; 890 ld[2] = fp->mode.ld[2]; 891 ohcifp->mode.common.spd = 0; --- 18 unchanged lines hidden (view full) --- 910 hdr_len = 12; 911 for (i = 0; i < hdr_len/4; i ++) 912 FWOHCI_DMA_WRITE(ld[i], ld[i]); 913#endif 914 915again: 916 db_tr->dbcnt = 2; 917 db = &db_tr->db[db_tr->dbcnt]; |
918 pl_len = xfer->send.len - pl_off; 919 if (pl_len > 0) { | 918 if (xfer->send.pay_len > 0) { |
920 int err; 921 /* handle payload */ 922 if (xfer->mbuf == NULL) { | 919 int err; 920 /* handle payload */ 921 if (xfer->mbuf == NULL) { |
923 caddr_t pl_addr; 924 925 pl_addr = xfer->send.buf + pl_off; | |
926 err = bus_dmamap_load(dbch->dmat, db_tr->dma_map, | 922 err = bus_dmamap_load(dbch->dmat, db_tr->dma_map, |
927 pl_addr, pl_len, | 923 &xfer->send.payload[0], xfer->send.pay_len, |
928 fwohci_execute_db, db_tr, 929 /*flags*/0); 930 } else { 931 /* XXX we can handle only 6 (=8-2) mbuf chains */ 932 err = bus_dmamap_load_mbuf(dbch->dmat, db_tr->dma_map, 933 xfer->mbuf, 934 fwohci_execute_db2, db_tr, 935 /* flags */0); --- 89 unchanged lines hidden (view full) --- 1025 return; 1026} 1027 1028void 1029fwohci_txd(struct fwohci_softc *sc, struct fwohci_dbch *dbch) 1030{ 1031 int s, ch, err = 0; 1032 struct fwohcidb_tr *tr; | 924 fwohci_execute_db, db_tr, 925 /*flags*/0); 926 } else { 927 /* XXX we can handle only 6 (=8-2) mbuf chains */ 928 err = bus_dmamap_load_mbuf(dbch->dmat, db_tr->dma_map, 929 xfer->mbuf, 930 fwohci_execute_db2, db_tr, 931 /* flags */0); --- 89 unchanged lines hidden (view full) --- 1021 return; 1022} 1023 1024void 1025fwohci_txd(struct fwohci_softc *sc, struct fwohci_dbch *dbch) 1026{ 1027 int s, ch, err = 0; 1028 struct fwohcidb_tr *tr; |
1033 volatile struct fwohcidb *db; | 1029 struct fwohcidb *db; |
1034 struct fw_xfer *xfer; 1035 u_int32_t off; 1036 u_int stat, status; 1037 int packets; 1038 struct firewire_comm *fc = (struct firewire_comm *)sc; 1039 1040 if(&sc->atrq == dbch){ 1041 off = OHCI_ATQOFF; --- 76 unchanged lines hidden (view full) --- 1118 } else { 1119 xfer->state = FWXF_SENT; 1120 if (err == EBUSY && fc->status != FWBUSRESET) { 1121 xfer->state = FWXF_BUSY; 1122 xfer->resp = err; 1123 if (xfer->retry_req != NULL) 1124 xfer->retry_req(xfer); 1125 else { | 1030 struct fw_xfer *xfer; 1031 u_int32_t off; 1032 u_int stat, status; 1033 int packets; 1034 struct firewire_comm *fc = (struct firewire_comm *)sc; 1035 1036 if(&sc->atrq == dbch){ 1037 off = OHCI_ATQOFF; --- 76 unchanged lines hidden (view full) --- 1114 } else { 1115 xfer->state = FWXF_SENT; 1116 if (err == EBUSY && fc->status != FWBUSRESET) { 1117 xfer->state = FWXF_BUSY; 1118 xfer->resp = err; 1119 if (xfer->retry_req != NULL) 1120 xfer->retry_req(xfer); 1121 else { |
1126 xfer->recv.len = 0; | 1122 xfer->recv.pay_len = 0; |
1127 fw_xfer_done(xfer); 1128 } 1129 } else if (stat != FWOHCIEV_ACKPEND) { 1130 if (stat != FWOHCIEV_ACKCOMPL) 1131 xfer->state = FWXF_SENTERR; 1132 xfer->resp = err; | 1123 fw_xfer_done(xfer); 1124 } 1125 } else if (stat != FWOHCIEV_ACKPEND) { 1126 if (stat != FWOHCIEV_ACKCOMPL) 1127 xfer->state = FWXF_SENTERR; 1128 xfer->resp = err; |
1133 xfer->recv.len = 0; | 1129 xfer->recv.pay_len = 0; |
1134 fw_xfer_done(xfer); 1135 } 1136 } 1137 /* 1138 * The watchdog timer takes care of split 1139 * transcation timeout for ACKPEND case. 1140 */ 1141 } else { --- 172 unchanged lines hidden (view full) --- 1314 1315static int 1316fwohci_tx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch) 1317{ 1318 int err = 0; 1319 int idb, z, i, dmach = 0, ldesc; 1320 u_int32_t off = NULL; 1321 struct fwohcidb_tr *db_tr; | 1130 fw_xfer_done(xfer); 1131 } 1132 } 1133 /* 1134 * The watchdog timer takes care of split 1135 * transcation timeout for ACKPEND case. 1136 */ 1137 } else { --- 172 unchanged lines hidden (view full) --- 1310 1311static int 1312fwohci_tx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch) 1313{ 1314 int err = 0; 1315 int idb, z, i, dmach = 0, ldesc; 1316 u_int32_t off = NULL; 1317 struct fwohcidb_tr *db_tr; |
1322 volatile struct fwohcidb *db; | 1318 struct fwohcidb *db; |
1323 1324 if(!(dbch->xferq.flag & FWXFERQ_EXTBUF)){ 1325 err = EINVAL; 1326 return err; 1327 } 1328 z = dbch->ndesc; 1329 for(dmach = 0 ; dmach < sc->fc.nisodma ; dmach++){ 1330 if( &sc->it[dmach] == dbch){ --- 42 unchanged lines hidden (view full) --- 1373 1374static int 1375fwohci_rx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch) 1376{ 1377 int err = 0; 1378 int idb, z, i, dmach = 0, ldesc; 1379 u_int32_t off = NULL; 1380 struct fwohcidb_tr *db_tr; | 1319 1320 if(!(dbch->xferq.flag & FWXFERQ_EXTBUF)){ 1321 err = EINVAL; 1322 return err; 1323 } 1324 z = dbch->ndesc; 1325 for(dmach = 0 ; dmach < sc->fc.nisodma ; dmach++){ 1326 if( &sc->it[dmach] == dbch){ --- 42 unchanged lines hidden (view full) --- 1369 1370static int 1371fwohci_rx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch) 1372{ 1373 int err = 0; 1374 int idb, z, i, dmach = 0, ldesc; 1375 u_int32_t off = NULL; 1376 struct fwohcidb_tr *db_tr; |
1381 volatile struct fwohcidb *db; | 1377 struct fwohcidb *db; |
1382 1383 z = dbch->ndesc; 1384 if(&sc->arrq == dbch){ 1385 off = OHCI_ARQOFF; 1386 }else if(&sc->arrs == dbch){ 1387 off = OHCI_ARSOFF; 1388 }else{ 1389 for(dmach = 0 ; dmach < sc->fc.nisodma ; dmach++){ --- 114 unchanged lines hidden (view full) --- 1504 } 1505 if(err) 1506 return err; 1507 1508 ldesc = dbch->ndesc - 1; 1509 s = splfw(); 1510 prev = STAILQ_LAST(&it->stdma, fw_bulkxfer, link); 1511 while ((chunk = STAILQ_FIRST(&it->stvalid)) != NULL) { | 1378 1379 z = dbch->ndesc; 1380 if(&sc->arrq == dbch){ 1381 off = OHCI_ARQOFF; 1382 }else if(&sc->arrs == dbch){ 1383 off = OHCI_ARSOFF; 1384 }else{ 1385 for(dmach = 0 ; dmach < sc->fc.nisodma ; dmach++){ --- 114 unchanged lines hidden (view full) --- 1500 } 1501 if(err) 1502 return err; 1503 1504 ldesc = dbch->ndesc - 1; 1505 s = splfw(); 1506 prev = STAILQ_LAST(&it->stdma, fw_bulkxfer, link); 1507 while ((chunk = STAILQ_FIRST(&it->stvalid)) != NULL) { |
1512 volatile struct fwohcidb *db; | 1508 struct fwohcidb *db; |
1513 1514 fwdma_sync_multiseg(it->buf, chunk->poffset, it->bnpacket, 1515 BUS_DMASYNC_PREWRITE); 1516 fwohci_txbufdb(sc, dmach, chunk); 1517 if (prev != NULL) { 1518 db = ((struct fwohcidb_tr *)(prev->end))->db; 1519#if 0 /* XXX necessary? */ 1520 FWOHCI_DMA_SET(db[ldesc].db.desc.cmd, --- 110 unchanged lines hidden (view full) --- 1631 device_printf(fc->dev, "IR DMA no free chunk\n"); 1632 return 0; 1633 } 1634 1635 ldesc = dbch->ndesc - 1; 1636 s = splfw(); 1637 prev = STAILQ_LAST(&ir->stdma, fw_bulkxfer, link); 1638 while ((chunk = STAILQ_FIRST(&ir->stfree)) != NULL) { | 1509 1510 fwdma_sync_multiseg(it->buf, chunk->poffset, it->bnpacket, 1511 BUS_DMASYNC_PREWRITE); 1512 fwohci_txbufdb(sc, dmach, chunk); 1513 if (prev != NULL) { 1514 db = ((struct fwohcidb_tr *)(prev->end))->db; 1515#if 0 /* XXX necessary? */ 1516 FWOHCI_DMA_SET(db[ldesc].db.desc.cmd, --- 110 unchanged lines hidden (view full) --- 1627 device_printf(fc->dev, "IR DMA no free chunk\n"); 1628 return 0; 1629 } 1630 1631 ldesc = dbch->ndesc - 1; 1632 s = splfw(); 1633 prev = STAILQ_LAST(&ir->stdma, fw_bulkxfer, link); 1634 while ((chunk = STAILQ_FIRST(&ir->stfree)) != NULL) { |
1639 volatile struct fwohcidb *db; | 1635 struct fwohcidb *db; |
1640 1641#if 1 /* XXX for if_fwe */ 1642 if (chunk->mbuf != NULL) { 1643 db_tr = (struct fwohcidb_tr *)(chunk->start); 1644 db_tr->dbcnt = 1; 1645 err = bus_dmamap_load_mbuf(dbch->dmat, db_tr->dma_map, 1646 chunk->mbuf, fwohci_execute_db2, db_tr, 1647 /* flags */0); --- 451 unchanged lines hidden (view full) --- 2099 OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_EN); 2100 } 2101} 2102 2103static void 2104fwohci_tbuf_update(struct fwohci_softc *sc, int dmach) 2105{ 2106 struct firewire_comm *fc = &sc->fc; | 1636 1637#if 1 /* XXX for if_fwe */ 1638 if (chunk->mbuf != NULL) { 1639 db_tr = (struct fwohcidb_tr *)(chunk->start); 1640 db_tr->dbcnt = 1; 1641 err = bus_dmamap_load_mbuf(dbch->dmat, db_tr->dma_map, 1642 chunk->mbuf, fwohci_execute_db2, db_tr, 1643 /* flags */0); --- 451 unchanged lines hidden (view full) --- 2095 OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_EN); 2096 } 2097} 2098 2099static void 2100fwohci_tbuf_update(struct fwohci_softc *sc, int dmach) 2101{ 2102 struct firewire_comm *fc = &sc->fc; |
2107 volatile struct fwohcidb *db; | 2103 struct fwohcidb *db; |
2108 struct fw_bulkxfer *chunk; 2109 struct fw_xferq *it; 2110 u_int32_t stat, count; 2111 int s, w=0, ldesc; 2112 2113 it = fc->it[dmach]; 2114 ldesc = sc->it[dmach].ndesc - 1; 2115 s = splfw(); /* unnecessary ? */ --- 29 unchanged lines hidden (view full) --- 2145 if (w) 2146 wakeup(it); 2147} 2148 2149static void 2150fwohci_rbuf_update(struct fwohci_softc *sc, int dmach) 2151{ 2152 struct firewire_comm *fc = &sc->fc; | 2104 struct fw_bulkxfer *chunk; 2105 struct fw_xferq *it; 2106 u_int32_t stat, count; 2107 int s, w=0, ldesc; 2108 2109 it = fc->it[dmach]; 2110 ldesc = sc->it[dmach].ndesc - 1; 2111 s = splfw(); /* unnecessary ? */ --- 29 unchanged lines hidden (view full) --- 2141 if (w) 2142 wakeup(it); 2143} 2144 2145static void 2146fwohci_rbuf_update(struct fwohci_softc *sc, int dmach) 2147{ 2148 struct firewire_comm *fc = &sc->fc; |
2153 volatile struct fwohcidb_tr *db_tr; | 2149 struct fwohcidb_tr *db_tr; |
2154 struct fw_bulkxfer *chunk; 2155 struct fw_xferq *ir; 2156 u_int32_t stat; 2157 int s, w=0, ldesc; 2158 2159 ir = fc->ir[dmach]; 2160 ldesc = sc->ir[dmach].ndesc - 1; 2161#if 0 --- 88 unchanged lines hidden (view full) --- 2250 } 2251} 2252 2253void 2254dump_db(struct fwohci_softc *sc, u_int32_t ch) 2255{ 2256 struct fwohci_dbch *dbch; 2257 struct fwohcidb_tr *cp = NULL, *pp, *np = NULL; | 2150 struct fw_bulkxfer *chunk; 2151 struct fw_xferq *ir; 2152 u_int32_t stat; 2153 int s, w=0, ldesc; 2154 2155 ir = fc->ir[dmach]; 2156 ldesc = sc->ir[dmach].ndesc - 1; 2157#if 0 --- 88 unchanged lines hidden (view full) --- 2246 } 2247} 2248 2249void 2250dump_db(struct fwohci_softc *sc, u_int32_t ch) 2251{ 2252 struct fwohci_dbch *dbch; 2253 struct fwohcidb_tr *cp = NULL, *pp, *np = NULL; |
2258 volatile struct fwohcidb *curr = NULL, *prev, *next = NULL; | 2254 struct fwohcidb *curr = NULL, *prev, *next = NULL; |
2259 int idb, jdb; 2260 u_int32_t cmd, off; 2261 if(ch == 0){ 2262 off = OHCI_ATQOFF; 2263 dbch = &sc->atrq; 2264 }else if(ch == 1){ 2265 off = OHCI_ATSOFF; 2266 dbch = &sc->atrs; --- 57 unchanged lines hidden (view full) --- 2324#endif 2325 }else{ 2326 printf("dbdump err ch = %d cmd = 0x%08x\n", ch, cmd); 2327 } 2328 return; 2329} 2330 2331void | 2255 int idb, jdb; 2256 u_int32_t cmd, off; 2257 if(ch == 0){ 2258 off = OHCI_ATQOFF; 2259 dbch = &sc->atrq; 2260 }else if(ch == 1){ 2261 off = OHCI_ATSOFF; 2262 dbch = &sc->atrs; --- 57 unchanged lines hidden (view full) --- 2320#endif 2321 }else{ 2322 printf("dbdump err ch = %d cmd = 0x%08x\n", ch, cmd); 2323 } 2324 return; 2325} 2326 2327void |
2332print_db(struct fwohcidb_tr *db_tr, volatile struct fwohcidb *db, | 2328print_db(struct fwohcidb_tr *db_tr, struct fwohcidb *db, |
2333 u_int32_t ch, u_int32_t max) 2334{ 2335 fwohcireg_t stat; 2336 int i, key; 2337 u_int32_t cmd, res; 2338 2339 if(db == NULL){ 2340 printf("No Descriptor is found\n"); --- 100 unchanged lines hidden (view full) --- 2441#endif 2442} 2443 2444void 2445fwohci_txbufdb(struct fwohci_softc *sc, int dmach, struct fw_bulkxfer *bulkxfer) 2446{ 2447 struct fwohcidb_tr *db_tr, *fdb_tr; 2448 struct fwohci_dbch *dbch; | 2329 u_int32_t ch, u_int32_t max) 2330{ 2331 fwohcireg_t stat; 2332 int i, key; 2333 u_int32_t cmd, res; 2334 2335 if(db == NULL){ 2336 printf("No Descriptor is found\n"); --- 100 unchanged lines hidden (view full) --- 2437#endif 2438} 2439 2440void 2441fwohci_txbufdb(struct fwohci_softc *sc, int dmach, struct fw_bulkxfer *bulkxfer) 2442{ 2443 struct fwohcidb_tr *db_tr, *fdb_tr; 2444 struct fwohci_dbch *dbch; |
2449 volatile struct fwohcidb *db; | 2445 struct fwohcidb *db; |
2450 struct fw_pkt *fp; | 2446 struct fw_pkt *fp; |
2451 volatile struct fwohci_txpkthdr *ohcifp; | 2447 struct fwohci_txpkthdr *ohcifp; |
2452 unsigned short chtag; 2453 int idb; 2454 2455 dbch = &sc->it[dmach]; 2456 chtag = sc->it[dmach].xferq.flag & 0xff; 2457 2458 db_tr = (struct fwohcidb_tr *)(bulkxfer->start); 2459 fdb_tr = (struct fwohcidb_tr *)(bulkxfer->end); 2460/* 2461device_printf(sc->fc.dev, "DB %08x %08x %08x\n", bulkxfer, db_tr->bus_addr, fdb_tr->bus_addr); 2462*/ 2463 for (idb = 0; idb < dbch->xferq.bnpacket; idb ++) { 2464 db = db_tr->db; 2465 fp = (struct fw_pkt *)db_tr->buf; | 2448 unsigned short chtag; 2449 int idb; 2450 2451 dbch = &sc->it[dmach]; 2452 chtag = sc->it[dmach].xferq.flag & 0xff; 2453 2454 db_tr = (struct fwohcidb_tr *)(bulkxfer->start); 2455 fdb_tr = (struct fwohcidb_tr *)(bulkxfer->end); 2456/* 2457device_printf(sc->fc.dev, "DB %08x %08x %08x\n", bulkxfer, db_tr->bus_addr, fdb_tr->bus_addr); 2458*/ 2459 for (idb = 0; idb < dbch->xferq.bnpacket; idb ++) { 2460 db = db_tr->db; 2461 fp = (struct fw_pkt *)db_tr->buf; |
2466 ohcifp = (volatile struct fwohci_txpkthdr *) db[1].db.immed; | 2462 ohcifp = (struct fwohci_txpkthdr *) db[1].db.immed; |
2467 ohcifp->mode.ld[0] = fp->mode.ld[0]; 2468 ohcifp->mode.common.spd = 0 & 0x7; 2469 ohcifp->mode.stream.len = fp->mode.stream.len; 2470 ohcifp->mode.stream.chtag = chtag; 2471 ohcifp->mode.stream.tcode = 0xa; 2472#if BYTE_ORDER == BIG_ENDIAN 2473 FWOHCI_DMA_WRITE(db[1].db.immed[0], db[1].db.immed[0]); 2474 FWOHCI_DMA_WRITE(db[1].db.immed[1], db[1].db.immed[1]); --- 31 unchanged lines hidden (view full) --- 2506*/ 2507 return; 2508} 2509 2510static int 2511fwohci_add_tx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr, 2512 int poffset) 2513{ | 2463 ohcifp->mode.ld[0] = fp->mode.ld[0]; 2464 ohcifp->mode.common.spd = 0 & 0x7; 2465 ohcifp->mode.stream.len = fp->mode.stream.len; 2466 ohcifp->mode.stream.chtag = chtag; 2467 ohcifp->mode.stream.tcode = 0xa; 2468#if BYTE_ORDER == BIG_ENDIAN 2469 FWOHCI_DMA_WRITE(db[1].db.immed[0], db[1].db.immed[0]); 2470 FWOHCI_DMA_WRITE(db[1].db.immed[1], db[1].db.immed[1]); --- 31 unchanged lines hidden (view full) --- 2502*/ 2503 return; 2504} 2505 2506static int 2507fwohci_add_tx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr, 2508 int poffset) 2509{ |
2514 volatile struct fwohcidb *db = db_tr->db; | 2510 struct fwohcidb *db = db_tr->db; |
2515 struct fw_xferq *it; 2516 int err = 0; 2517 2518 it = &dbch->xferq; 2519 if(it->buf == 0){ 2520 err = EINVAL; 2521 return err; 2522 } 2523 db_tr->buf = fwdma_v_addr(it->buf, poffset); 2524 db_tr->dbcnt = 3; 2525 2526 FWOHCI_DMA_WRITE(db[0].db.desc.cmd, 2527 OHCI_OUTPUT_MORE | OHCI_KEY_ST2 | 8); 2528 FWOHCI_DMA_WRITE(db[0].db.desc.addr, 0); | 2511 struct fw_xferq *it; 2512 int err = 0; 2513 2514 it = &dbch->xferq; 2515 if(it->buf == 0){ 2516 err = EINVAL; 2517 return err; 2518 } 2519 db_tr->buf = fwdma_v_addr(it->buf, poffset); 2520 db_tr->dbcnt = 3; 2521 2522 FWOHCI_DMA_WRITE(db[0].db.desc.cmd, 2523 OHCI_OUTPUT_MORE | OHCI_KEY_ST2 | 8); 2524 FWOHCI_DMA_WRITE(db[0].db.desc.addr, 0); |
2529 bzero((void *)(uintptr_t)(volatile void *) 2530 &db[1].db.immed[0], sizeof(db[1].db.immed)); | 2525 bzero((void *)&db[1].db.immed[0], sizeof(db[1].db.immed)); |
2531 FWOHCI_DMA_WRITE(db[2].db.desc.addr, 2532 fwdma_bus_addr(it->buf, poffset) + sizeof(u_int32_t)); 2533 2534 FWOHCI_DMA_WRITE(db[2].db.desc.cmd, 2535 OHCI_OUTPUT_LAST | OHCI_UPDATE | OHCI_BRANCH_ALWAYS); 2536#if 1 2537 FWOHCI_DMA_WRITE(db[0].db.desc.res, 0); 2538 FWOHCI_DMA_WRITE(db[2].db.desc.res, 0); 2539#endif 2540 return 0; 2541} 2542 2543int 2544fwohci_add_rx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr, 2545 int poffset, struct fwdma_alloc *dummy_dma) 2546{ | 2526 FWOHCI_DMA_WRITE(db[2].db.desc.addr, 2527 fwdma_bus_addr(it->buf, poffset) + sizeof(u_int32_t)); 2528 2529 FWOHCI_DMA_WRITE(db[2].db.desc.cmd, 2530 OHCI_OUTPUT_LAST | OHCI_UPDATE | OHCI_BRANCH_ALWAYS); 2531#if 1 2532 FWOHCI_DMA_WRITE(db[0].db.desc.res, 0); 2533 FWOHCI_DMA_WRITE(db[2].db.desc.res, 0); 2534#endif 2535 return 0; 2536} 2537 2538int 2539fwohci_add_rx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr, 2540 int poffset, struct fwdma_alloc *dummy_dma) 2541{ |
2547 volatile struct fwohcidb *db = db_tr->db; | 2542 struct fwohcidb *db = db_tr->db; |
2548 struct fw_xferq *ir; 2549 int i, ldesc; 2550 bus_addr_t dbuf[2]; 2551 int dsiz[2]; 2552 2553 ir = &dbch->xferq; 2554 if (ir->buf == NULL && (dbch->xferq.flag & FWXFERQ_EXTBUF) == 0) { 2555 db_tr->buf = fwdma_malloc_size(dbch->dmat, &db_tr->dma_map, --- 34 unchanged lines hidden (view full) --- 2590} 2591 2592 2593static int 2594fwohci_arcv_swap(struct fw_pkt *fp, int len) 2595{ 2596 struct fw_pkt *fp0; 2597 u_int32_t ld0; | 2543 struct fw_xferq *ir; 2544 int i, ldesc; 2545 bus_addr_t dbuf[2]; 2546 int dsiz[2]; 2547 2548 ir = &dbch->xferq; 2549 if (ir->buf == NULL && (dbch->xferq.flag & FWXFERQ_EXTBUF) == 0) { 2550 db_tr->buf = fwdma_malloc_size(dbch->dmat, &db_tr->dma_map, --- 34 unchanged lines hidden (view full) --- 2585} 2586 2587 2588static int 2589fwohci_arcv_swap(struct fw_pkt *fp, int len) 2590{ 2591 struct fw_pkt *fp0; 2592 u_int32_t ld0; |
2598 int slen; | 2593 int slen, hlen; |
2599#if BYTE_ORDER == BIG_ENDIAN 2600 int i; 2601#endif 2602 2603 ld0 = FWOHCI_DMA_READ(fp->mode.ld[0]); 2604#if 0 2605 printf("ld0: x%08x\n", ld0); 2606#endif 2607 fp0 = (struct fw_pkt *)&ld0; | 2594#if BYTE_ORDER == BIG_ENDIAN 2595 int i; 2596#endif 2597 2598 ld0 = FWOHCI_DMA_READ(fp->mode.ld[0]); 2599#if 0 2600 printf("ld0: x%08x\n", ld0); 2601#endif 2602 fp0 = (struct fw_pkt *)&ld0; |
2603 /* determine length to swap */ |
|
2608 switch (fp0->mode.common.tcode) { 2609 case FWTCODE_RREQQ: 2610 case FWTCODE_WRES: 2611 case FWTCODE_WREQQ: 2612 case FWTCODE_RRESQ: 2613 case FWOHCITCODE_PHY: 2614 slen = 12; 2615 break; 2616 case FWTCODE_RREQB: 2617 case FWTCODE_WREQB: 2618 case FWTCODE_LREQ: 2619 case FWTCODE_RRESB: 2620 case FWTCODE_LRES: 2621 slen = 16; 2622 break; 2623 default: 2624 printf("Unknown tcode %d\n", fp0->mode.common.tcode); 2625 return(0); 2626 } | 2604 switch (fp0->mode.common.tcode) { 2605 case FWTCODE_RREQQ: 2606 case FWTCODE_WRES: 2607 case FWTCODE_WREQQ: 2608 case FWTCODE_RRESQ: 2609 case FWOHCITCODE_PHY: 2610 slen = 12; 2611 break; 2612 case FWTCODE_RREQB: 2613 case FWTCODE_WREQB: 2614 case FWTCODE_LREQ: 2615 case FWTCODE_RRESB: 2616 case FWTCODE_LRES: 2617 slen = 16; 2618 break; 2619 default: 2620 printf("Unknown tcode %d\n", fp0->mode.common.tcode); 2621 return(0); 2622 } |
2627 if (slen > len) { | 2623 hlen = tinfo[fp0->mode.common.tcode].hdr_len; 2624 if (hlen > len) { |
2628 if (firewire_debug) 2629 printf("splitted header\n"); | 2625 if (firewire_debug) 2626 printf("splitted header\n"); |
2630 return(-slen); | 2627 return(-hlen); |
2631 } 2632#if BYTE_ORDER == BIG_ENDIAN 2633 for(i = 0; i < slen/4; i ++) 2634 fp->mode.ld[i] = FWOHCI_DMA_READ(fp->mode.ld[i]); 2635#endif | 2628 } 2629#if BYTE_ORDER == BIG_ENDIAN 2630 for(i = 0; i < slen/4; i ++) 2631 fp->mode.ld[i] = FWOHCI_DMA_READ(fp->mode.ld[i]); 2632#endif |
2636 return(slen); | 2633 return(hlen); |
2637} 2638 | 2634} 2635 |
2639#define PLEN(x) roundup2(x, sizeof(u_int32_t)) | |
2640static int 2641fwohci_get_plen(struct fwohci_softc *sc, struct fwohci_dbch *dbch, struct fw_pkt *fp) 2642{ | 2636static int 2637fwohci_get_plen(struct fwohci_softc *sc, struct fwohci_dbch *dbch, struct fw_pkt *fp) 2638{ |
2639 struct tcode_info *info; |
|
2643 int r; 2644 | 2640 int r; 2641 |
2645 switch(fp->mode.common.tcode){ 2646 case FWTCODE_RREQQ: 2647 r = sizeof(fp->mode.rreqq) + sizeof(u_int32_t); 2648 break; 2649 case FWTCODE_WRES: 2650 r = sizeof(fp->mode.wres) + sizeof(u_int32_t); 2651 break; 2652 case FWTCODE_WREQQ: 2653 r = sizeof(fp->mode.wreqq) + sizeof(u_int32_t); 2654 break; 2655 case FWTCODE_RREQB: 2656 r = sizeof(fp->mode.rreqb) + sizeof(u_int32_t); 2657 break; 2658 case FWTCODE_RRESQ: 2659 r = sizeof(fp->mode.rresq) + sizeof(u_int32_t); 2660 break; 2661 case FWTCODE_WREQB: 2662 r = sizeof(struct fw_asyhdr) + PLEN(fp->mode.wreqb.len) 2663 + sizeof(u_int32_t); 2664 break; 2665 case FWTCODE_LREQ: 2666 r = sizeof(struct fw_asyhdr) + PLEN(fp->mode.lreq.len) 2667 + sizeof(u_int32_t); 2668 break; 2669 case FWTCODE_RRESB: 2670 r = sizeof(struct fw_asyhdr) + PLEN(fp->mode.rresb.len) 2671 + sizeof(u_int32_t); 2672 break; 2673 case FWTCODE_LRES: 2674 r = sizeof(struct fw_asyhdr) + PLEN(fp->mode.lres.len) 2675 + sizeof(u_int32_t); 2676 break; 2677 case FWOHCITCODE_PHY: 2678 r = 16; 2679 break; 2680 default: | 2642 info = &tinfo[fp->mode.common.tcode]; 2643 r = info->hdr_len + sizeof(u_int32_t); 2644 if ((info->flag & FWTI_BLOCK_ASY) != 0) 2645 r += roundup2(fp->mode.wreqb.len, sizeof(u_int32_t)); 2646 2647 if (r == sizeof(u_int32_t)) 2648 /* XXX */ |
2681 device_printf(sc->fc.dev, "Unknown tcode %d\n", 2682 fp->mode.common.tcode); | 2649 device_printf(sc->fc.dev, "Unknown tcode %d\n", 2650 fp->mode.common.tcode); |
2683 r = 0; 2684 } | 2651 |
2685 if (r > dbch->xferq.psize) { 2686 device_printf(sc->fc.dev, "Invalid packet length %d\n", r); 2687 /* panic ? */ 2688 } | 2652 if (r > dbch->xferq.psize) { 2653 device_printf(sc->fc.dev, "Invalid packet length %d\n", r); 2654 /* panic ? */ 2655 } |
2656 |
|
2689 return r; 2690} 2691 2692static void 2693fwohci_arcv_free_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr) 2694{ | 2657 return r; 2658} 2659 2660static void 2661fwohci_arcv_free_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr) 2662{ |
2695 volatile struct fwohcidb *db = &db_tr->db[0]; | 2663 struct fwohcidb *db = &db_tr->db[0]; |
2696 2697 FWOHCI_DMA_CLEAR(db->db.desc.depend, 0xf); 2698 FWOHCI_DMA_WRITE(db->db.desc.res, dbch->xferq.psize); 2699 FWOHCI_DMA_SET(dbch->bottom->db[0].db.desc.depend, 1); 2700 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE); 2701 dbch->bottom = db_tr; 2702} 2703 --- 103 unchanged lines hidden (view full) --- 2807 } 2808 offset = 0; 2809 nvec = 0; 2810 } 2811 plen = fwohci_get_plen(sc, dbch, fp) - offset; 2812 if (plen < 0) { 2813 /* minimum header size + trailer 2814 = sizeof(fw_pkt) so this shouldn't happens */ | 2664 2665 FWOHCI_DMA_CLEAR(db->db.desc.depend, 0xf); 2666 FWOHCI_DMA_WRITE(db->db.desc.res, dbch->xferq.psize); 2667 FWOHCI_DMA_SET(dbch->bottom->db[0].db.desc.depend, 1); 2668 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE); 2669 dbch->bottom = db_tr; 2670} 2671 --- 103 unchanged lines hidden (view full) --- 2775 } 2776 offset = 0; 2777 nvec = 0; 2778 } 2779 plen = fwohci_get_plen(sc, dbch, fp) - offset; 2780 if (plen < 0) { 2781 /* minimum header size + trailer 2782 = sizeof(fw_pkt) so this shouldn't happens */ |
2815 printf("plen is negative! offset=%d\n", offset); | 2783 printf("plen(%d) is negative! offset=%d\n", 2784 plen, offset); |
2816 goto out; 2817 } 2818 if (plen > 0) { 2819 len -= plen; 2820 if (len < 0) { 2821 dbch->pdb_tr = db_tr; 2822 if (firewire_debug) 2823 printf("splitted payload\n"); --- 13 unchanged lines hidden (view full) --- 2837 2838/* DMA result-code will be written at the tail of packet */ 2839#if BYTE_ORDER == BIG_ENDIAN 2840 stat = FWOHCI_DMA_READ(((struct fwohci_trailer *)(ld - sizeof(struct fwohci_trailer)))->stat) >> 16; 2841#else 2842 stat = ((struct fwohci_trailer *)(ld - sizeof(struct fwohci_trailer)))->stat; 2843#endif 2844#if 0 | 2785 goto out; 2786 } 2787 if (plen > 0) { 2788 len -= plen; 2789 if (len < 0) { 2790 dbch->pdb_tr = db_tr; 2791 if (firewire_debug) 2792 printf("splitted payload\n"); --- 13 unchanged lines hidden (view full) --- 2806 2807/* DMA result-code will be written at the tail of packet */ 2808#if BYTE_ORDER == BIG_ENDIAN 2809 stat = FWOHCI_DMA_READ(((struct fwohci_trailer *)(ld - sizeof(struct fwohci_trailer)))->stat) >> 16; 2810#else 2811 stat = ((struct fwohci_trailer *)(ld - sizeof(struct fwohci_trailer)))->stat; 2812#endif 2813#if 0 |
2845 printf("plen: %d, stat %x\n", plen ,stat); | 2814 printf("plen: %d, stat %x\n", 2815 plen ,stat); |
2846#endif 2847 spd = (stat >> 5) & 0x3; 2848 stat &= 0x1f; 2849 switch(stat){ 2850 case FWOHCIEV_ACKPEND: 2851#if 0 2852 printf("fwohci_arcv: ack pending tcode=0x%x..\n", fp->mode.common.tcode); 2853#endif 2854 /* fall through */ 2855 case FWOHCIEV_ACKCOMPL: | 2816#endif 2817 spd = (stat >> 5) & 0x3; 2818 stat &= 0x1f; 2819 switch(stat){ 2820 case FWOHCIEV_ACKPEND: 2821#if 0 2822 printf("fwohci_arcv: ack pending tcode=0x%x..\n", fp->mode.common.tcode); 2823#endif 2824 /* fall through */ 2825 case FWOHCIEV_ACKCOMPL: |
2826 { 2827 struct fw_rcv_buf rb; 2828 |
|
2856 if ((vec[nvec-1].iov_len -= 2857 sizeof(struct fwohci_trailer)) == 0) 2858 nvec--; | 2829 if ((vec[nvec-1].iov_len -= 2830 sizeof(struct fwohci_trailer)) == 0) 2831 nvec--; |
2859 fw_rcv(&sc->fc, vec, nvec, 0, spd); 2860 break; | 2832 rb.fc = &sc->fc; 2833 rb.vec = vec; 2834 rb.nvec = nvec; 2835 rb.spd = spd; 2836 fw_rcv(&rb); 2837 break; 2838 } |
2861 case FWOHCIEV_BUSRST: 2862 if (sc->fc.status != FWBUSRESET) 2863 printf("got BUSRST packet!?\n"); 2864 break; 2865 default: 2866 device_printf(sc->fc.dev, "Async DMA Receive error err = %02x %s\n", stat, fwohcicode[stat]); 2867#if 0 /* XXX */ 2868 goto out; --- 38 unchanged lines hidden --- | 2839 case FWOHCIEV_BUSRST: 2840 if (sc->fc.status != FWBUSRESET) 2841 printf("got BUSRST packet!?\n"); 2842 break; 2843 default: 2844 device_printf(sc->fc.dev, "Async DMA Receive error err = %02x %s\n", stat, fwohcicode[stat]); 2845#if 0 /* XXX */ 2846 goto out; --- 38 unchanged lines hidden --- |