diff options
Diffstat (limited to 'sys/dev/firewire/fwohci.c')
-rw-r--r-- | sys/dev/firewire/fwohci.c | 140 |
1 files changed, 59 insertions, 81 deletions
diff --git a/sys/dev/firewire/fwohci.c b/sys/dev/firewire/fwohci.c index 3b71c47..20d72c9 100644 --- a/sys/dev/firewire/fwohci.c +++ b/sys/dev/firewire/fwohci.c @@ -138,7 +138,7 @@ static void fwohci_set_intr __P((struct firewire_comm *, int)); static int fwohci_add_rx_buf __P((struct fwohci_dbch *, struct fwohcidb_tr *, int, struct fwdma_alloc *)); static int fwohci_add_tx_buf __P((struct fwohci_dbch *, struct fwohcidb_tr *, int)); static void dump_db __P((struct fwohci_softc *, u_int32_t)); -static void print_db __P((struct fwohcidb_tr *, volatile struct fwohcidb *, u_int32_t , u_int32_t)); +static void print_db __P((struct fwohcidb_tr *, struct fwohcidb *, u_int32_t , u_int32_t)); static void dump_dma __P((struct fwohci_softc *, u_int32_t)); static u_int32_t fwohci_cyctimer __P((struct firewire_comm *)); static void fwohci_rbuf_update __P((struct fwohci_softc *, int)); @@ -799,7 +799,7 @@ static void fwohci_execute_db(void *arg, bus_dma_segment_t *segs, int nseg, int error) { struct fwohcidb_tr *db_tr; - volatile struct fwohcidb *db; + struct fwohcidb *db; bus_dma_segment_t *s; int i; @@ -831,15 +831,15 @@ static void fwohci_start(struct fwohci_softc *sc, struct fwohci_dbch *dbch) { int i, s; - int tcode, hdr_len, pl_off, pl_len; + int tcode, hdr_len, pl_off; int fsegment = -1; u_int32_t off; struct fw_xfer *xfer; struct fw_pkt *fp; - volatile struct fwohci_txpkthdr *ohcifp; + struct fwohci_txpkthdr *ohcifp; struct fwohcidb_tr *db_tr; - volatile struct fwohcidb *db; - volatile u_int32_t *ld; + struct fwohcidb *db; + u_int32_t *ld; struct tcode_info *info; static int maxdesc=0; @@ -868,10 +868,10 @@ txloop: db_tr->xfer = xfer; xfer->state = FWXF_START; - fp = (struct fw_pkt *)xfer->send.buf; + fp = &xfer->send.hdr; tcode = fp->mode.common.tcode; - ohcifp = (volatile struct fwohci_txpkthdr *) db_tr->db[1].db.immed; + ohcifp = (struct fwohci_txpkthdr *) db_tr->db[1].db.immed; info = &tinfo[tcode]; hdr_len = pl_off = info->hdr_len; @@ -880,7 +880,7 @@ txloop: for( i = 0 ; i < pl_off ; i+= 4) ld[i/4] = fp->mode.ld[i/4]; - ohcifp->mode.common.spd = xfer->spd & 0x7; + ohcifp->mode.common.spd = xfer->send.spd & 0x7; if (tcode == FWTCODE_STREAM ){ hdr_len = 8; ohcifp->mode.stream.len = fp->mode.stream.len; @@ -915,16 +915,12 @@ txloop: again: db_tr->dbcnt = 2; db = &db_tr->db[db_tr->dbcnt]; - pl_len = xfer->send.len - pl_off; - if (pl_len > 0) { + if (xfer->send.pay_len > 0) { int err; /* handle payload */ if (xfer->mbuf == NULL) { - caddr_t pl_addr; - - pl_addr = xfer->send.buf + pl_off; err = bus_dmamap_load(dbch->dmat, db_tr->dma_map, - pl_addr, pl_len, + &xfer->send.payload[0], xfer->send.pay_len, fwohci_execute_db, db_tr, /*flags*/0); } else { @@ -1030,7 +1026,7 @@ fwohci_txd(struct fwohci_softc *sc, struct fwohci_dbch *dbch) { int s, ch, err = 0; struct fwohcidb_tr *tr; - volatile struct fwohcidb *db; + struct fwohcidb *db; struct fw_xfer *xfer; u_int32_t off; u_int stat, status; @@ -1123,14 +1119,14 @@ fwohci_txd(struct fwohci_softc *sc, struct fwohci_dbch *dbch) if (xfer->retry_req != NULL) xfer->retry_req(xfer); else { - xfer->recv.len = 0; + xfer->recv.pay_len = 0; fw_xfer_done(xfer); } } else if (stat != FWOHCIEV_ACKPEND) { if (stat != FWOHCIEV_ACKCOMPL) xfer->state = FWXF_SENTERR; xfer->resp = err; - xfer->recv.len = 0; + xfer->recv.pay_len = 0; fw_xfer_done(xfer); } } @@ -1319,7 +1315,7 @@ fwohci_tx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch) int idb, z, i, dmach = 0, ldesc; u_int32_t off = NULL; struct fwohcidb_tr *db_tr; - volatile struct fwohcidb *db; + struct fwohcidb *db; if(!(dbch->xferq.flag & FWXFERQ_EXTBUF)){ err = EINVAL; @@ -1378,7 +1374,7 @@ fwohci_rx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch) int idb, z, i, dmach = 0, ldesc; u_int32_t off = NULL; struct fwohcidb_tr *db_tr; - volatile struct fwohcidb *db; + struct fwohcidb *db; z = dbch->ndesc; if(&sc->arrq == dbch){ @@ -1509,7 +1505,7 @@ fwohci_itxbuf_enable(struct firewire_comm *fc, int dmach) s = splfw(); prev = STAILQ_LAST(&it->stdma, fw_bulkxfer, link); while ((chunk = STAILQ_FIRST(&it->stvalid)) != NULL) { - volatile struct fwohcidb *db; + struct fwohcidb *db; fwdma_sync_multiseg(it->buf, chunk->poffset, it->bnpacket, BUS_DMASYNC_PREWRITE); @@ -1636,7 +1632,7 @@ fwohci_irx_enable(struct firewire_comm *fc, int dmach) s = splfw(); prev = STAILQ_LAST(&ir->stdma, fw_bulkxfer, link); while ((chunk = STAILQ_FIRST(&ir->stfree)) != NULL) { - volatile struct fwohcidb *db; + struct fwohcidb *db; #if 1 /* XXX for if_fwe */ if (chunk->mbuf != NULL) { @@ -2104,7 +2100,7 @@ static void fwohci_tbuf_update(struct fwohci_softc *sc, int dmach) { struct firewire_comm *fc = &sc->fc; - volatile struct fwohcidb *db; + struct fwohcidb *db; struct fw_bulkxfer *chunk; struct fw_xferq *it; u_int32_t stat, count; @@ -2150,7 +2146,7 @@ static void fwohci_rbuf_update(struct fwohci_softc *sc, int dmach) { struct firewire_comm *fc = &sc->fc; - volatile struct fwohcidb_tr *db_tr; + struct fwohcidb_tr *db_tr; struct fw_bulkxfer *chunk; struct fw_xferq *ir; u_int32_t stat; @@ -2255,7 +2251,7 @@ dump_db(struct fwohci_softc *sc, u_int32_t ch) { struct fwohci_dbch *dbch; struct fwohcidb_tr *cp = NULL, *pp, *np = NULL; - volatile struct fwohcidb *curr = NULL, *prev, *next = NULL; + struct fwohcidb *curr = NULL, *prev, *next = NULL; int idb, jdb; u_int32_t cmd, off; if(ch == 0){ @@ -2329,7 +2325,7 @@ outdb: } void -print_db(struct fwohcidb_tr *db_tr, volatile struct fwohcidb *db, +print_db(struct fwohcidb_tr *db_tr, struct fwohcidb *db, u_int32_t ch, u_int32_t max) { fwohcireg_t stat; @@ -2446,9 +2442,9 @@ fwohci_txbufdb(struct fwohci_softc *sc, int dmach, struct fw_bulkxfer *bulkxfer) { struct fwohcidb_tr *db_tr, *fdb_tr; struct fwohci_dbch *dbch; - volatile struct fwohcidb *db; + struct fwohcidb *db; struct fw_pkt *fp; - volatile struct fwohci_txpkthdr *ohcifp; + struct fwohci_txpkthdr *ohcifp; unsigned short chtag; int idb; @@ -2463,7 +2459,7 @@ device_printf(sc->fc.dev, "DB %08x %08x %08x\n", bulkxfer, db_tr->bus_addr, fdb_ for (idb = 0; idb < dbch->xferq.bnpacket; idb ++) { db = db_tr->db; fp = (struct fw_pkt *)db_tr->buf; - ohcifp = (volatile struct fwohci_txpkthdr *) db[1].db.immed; + ohcifp = (struct fwohci_txpkthdr *) db[1].db.immed; ohcifp->mode.ld[0] = fp->mode.ld[0]; ohcifp->mode.common.spd = 0 & 0x7; ohcifp->mode.stream.len = fp->mode.stream.len; @@ -2511,7 +2507,7 @@ static int fwohci_add_tx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr, int poffset) { - volatile struct fwohcidb *db = db_tr->db; + struct fwohcidb *db = db_tr->db; struct fw_xferq *it; int err = 0; @@ -2526,8 +2522,7 @@ fwohci_add_tx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr, FWOHCI_DMA_WRITE(db[0].db.desc.cmd, OHCI_OUTPUT_MORE | OHCI_KEY_ST2 | 8); FWOHCI_DMA_WRITE(db[0].db.desc.addr, 0); - bzero((void *)(uintptr_t)(volatile void *) - &db[1].db.immed[0], sizeof(db[1].db.immed)); + bzero((void *)&db[1].db.immed[0], sizeof(db[1].db.immed)); FWOHCI_DMA_WRITE(db[2].db.desc.addr, fwdma_bus_addr(it->buf, poffset) + sizeof(u_int32_t)); @@ -2544,7 +2539,7 @@ int fwohci_add_rx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr, int poffset, struct fwdma_alloc *dummy_dma) { - volatile struct fwohcidb *db = db_tr->db; + struct fwohcidb *db = db_tr->db; struct fw_xferq *ir; int i, ldesc; bus_addr_t dbuf[2]; @@ -2595,7 +2590,7 @@ fwohci_arcv_swap(struct fw_pkt *fp, int len) { struct fw_pkt *fp0; u_int32_t ld0; - int slen; + int slen, hlen; #if BYTE_ORDER == BIG_ENDIAN int i; #endif @@ -2605,6 +2600,7 @@ fwohci_arcv_swap(struct fw_pkt *fp, int len) printf("ld0: x%08x\n", ld0); #endif fp0 = (struct fw_pkt *)&ld0; + /* determine length to swap */ switch (fp0->mode.common.tcode) { case FWTCODE_RREQQ: case FWTCODE_WRES: @@ -2624,75 +2620,47 @@ fwohci_arcv_swap(struct fw_pkt *fp, int len) printf("Unknown tcode %d\n", fp0->mode.common.tcode); return(0); } - if (slen > len) { + hlen = tinfo[fp0->mode.common.tcode].hdr_len; + if (hlen > len) { if (firewire_debug) printf("splitted header\n"); - return(-slen); + return(-hlen); } #if BYTE_ORDER == BIG_ENDIAN for(i = 0; i < slen/4; i ++) fp->mode.ld[i] = FWOHCI_DMA_READ(fp->mode.ld[i]); #endif - return(slen); + return(hlen); } -#define PLEN(x) roundup2(x, sizeof(u_int32_t)) static int fwohci_get_plen(struct fwohci_softc *sc, struct fwohci_dbch *dbch, struct fw_pkt *fp) { + struct tcode_info *info; int r; - switch(fp->mode.common.tcode){ - case FWTCODE_RREQQ: - r = sizeof(fp->mode.rreqq) + sizeof(u_int32_t); - break; - case FWTCODE_WRES: - r = sizeof(fp->mode.wres) + sizeof(u_int32_t); - break; - case FWTCODE_WREQQ: - r = sizeof(fp->mode.wreqq) + sizeof(u_int32_t); - break; - case FWTCODE_RREQB: - r = sizeof(fp->mode.rreqb) + sizeof(u_int32_t); - break; - case FWTCODE_RRESQ: - r = sizeof(fp->mode.rresq) + sizeof(u_int32_t); - break; - case FWTCODE_WREQB: - r = sizeof(struct fw_asyhdr) + PLEN(fp->mode.wreqb.len) - + sizeof(u_int32_t); - break; - case FWTCODE_LREQ: - r = sizeof(struct fw_asyhdr) + PLEN(fp->mode.lreq.len) - + sizeof(u_int32_t); - break; - case FWTCODE_RRESB: - r = sizeof(struct fw_asyhdr) + PLEN(fp->mode.rresb.len) - + sizeof(u_int32_t); - break; - case FWTCODE_LRES: - r = sizeof(struct fw_asyhdr) + PLEN(fp->mode.lres.len) - + sizeof(u_int32_t); - break; - case FWOHCITCODE_PHY: - r = 16; - break; - default: + info = &tinfo[fp->mode.common.tcode]; + r = info->hdr_len + sizeof(u_int32_t); + if ((info->flag & FWTI_BLOCK_ASY) != 0) + r += roundup2(fp->mode.wreqb.len, sizeof(u_int32_t)); + + if (r == sizeof(u_int32_t)) + /* XXX */ device_printf(sc->fc.dev, "Unknown tcode %d\n", fp->mode.common.tcode); - r = 0; - } + if (r > dbch->xferq.psize) { device_printf(sc->fc.dev, "Invalid packet length %d\n", r); /* panic ? */ } + return r; } static void fwohci_arcv_free_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr) { - volatile struct fwohcidb *db = &db_tr->db[0]; + struct fwohcidb *db = &db_tr->db[0]; FWOHCI_DMA_CLEAR(db->db.desc.depend, 0xf); FWOHCI_DMA_WRITE(db->db.desc.res, dbch->xferq.psize); @@ -2812,7 +2780,8 @@ fwohci_arcv(struct fwohci_softc *sc, struct fwohci_dbch *dbch, int count) if (plen < 0) { /* minimum header size + trailer = sizeof(fw_pkt) so this shouldn't happens */ - printf("plen is negative! offset=%d\n", offset); + printf("plen(%d) is negative! offset=%d\n", + plen, offset); goto out; } if (plen > 0) { @@ -2842,7 +2811,8 @@ fwohci_arcv(struct fwohci_softc *sc, struct fwohci_dbch *dbch, int count) stat = ((struct fwohci_trailer *)(ld - sizeof(struct fwohci_trailer)))->stat; #endif #if 0 - printf("plen: %d, stat %x\n", plen ,stat); + printf("plen: %d, stat %x\n", + plen ,stat); #endif spd = (stat >> 5) & 0x3; stat &= 0x1f; @@ -2853,11 +2823,19 @@ fwohci_arcv(struct fwohci_softc *sc, struct fwohci_dbch *dbch, int count) #endif /* fall through */ case FWOHCIEV_ACKCOMPL: + { + struct fw_rcv_buf rb; + if ((vec[nvec-1].iov_len -= sizeof(struct fwohci_trailer)) == 0) nvec--; - fw_rcv(&sc->fc, vec, nvec, 0, spd); - break; + rb.fc = &sc->fc; + rb.vec = vec; + rb.nvec = nvec; + rb.spd = spd; + fw_rcv(&rb); + break; + } case FWOHCIEV_BUSRST: if (sc->fc.status != FWBUSRESET) printf("got BUSRST packet!?\n"); |