summaryrefslogtreecommitdiffstats
path: root/sys/dev/firewire/fwohci.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/firewire/fwohci.c')
-rw-r--r--sys/dev/firewire/fwohci.c140
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");
OpenPOWER on IntegriCloud