summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/firewire/firewire.c15
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)
/*
OpenPOWER on IntegriCloud