diff options
-rw-r--r-- | sys/dev/firewire/firewire.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/sys/dev/firewire/firewire.c b/sys/dev/firewire/firewire.c index aa0f1aa..f1ebb6d 100644 --- a/sys/dev/firewire/firewire.c +++ b/sys/dev/firewire/firewire.c @@ -374,6 +374,7 @@ firewire_xfer_timeout(void *arg, int pending) "tl=0x%x flag=0x%02x\n", i, xfer->flag); fw_dump_hdr(&xfer->send.hdr, "send"); xfer->resp = ETIMEDOUT; + xfer->tl = -1; STAILQ_REMOVE_HEAD(&fc->tlabels[i], tlabel); STAILQ_INSERT_TAIL(&xfer_timeout, xfer, tlabel); } @@ -608,6 +609,7 @@ fw_drain_txq(struct firewire_comm *fc) while ((xfer = STAILQ_FIRST(&fc->tlabels[i])) != NULL) { if (firewire_debug) printf("tl=%d flag=%d\n", i, xfer->flag); + xfer->tl = -1; xfer->resp = EAGAIN; STAILQ_REMOVE_HEAD(&fc->tlabels[i], tlabel); STAILQ_INSERT_TAIL(&xfer_drain, xfer, tlabel); @@ -1044,11 +1046,12 @@ fw_tl_free(struct firewire_comm *fc, struct fw_xfer *xfer) struct fw_xfer *txfer; int s; - if (xfer->tl < 0) - return; - s = splfw(); mtx_lock(&fc->tlabel_lock); + if (xfer->tl < 0) { + mtx_unlock(&fc->tlabel_lock); + return; + } #if 1 /* make sure the label is allocated */ STAILQ_FOREACH(txfer, &fc->tlabels[xfer->tl], tlabel) if(txfer == xfer) @@ -1067,6 +1070,7 @@ fw_tl_free(struct firewire_comm *fc, struct fw_xfer *xfer) #endif STAILQ_REMOVE(&fc->tlabels[xfer->tl], xfer, fw_xfer, tlabel); + xfer->tl = -1; mtx_unlock(&fc->tlabel_lock); splx(s); return; @@ -1191,6 +1195,11 @@ fw_xfer_unload(struct fw_xfer* xfer) splx(s); } if (xfer->fc != NULL) { + /* + * Ensure that any tlabel owner can't access this + * xfer after it's freed. + */ + fw_tl_free(xfer->fc, xfer); #if 1 if(xfer->flag & FWXF_START) /* |