summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryasuoka <yasuoka@openbsd.org>2013-05-20 08:19:47 +0000
committeryasuoka <yasuoka@openbsd.org>2013-05-20 08:19:47 +0000
commit58dcd7cbcc7ff2e661cdae301c6471ecb2d79784 (patch)
tree139d754406d8dd3b5687076819cf8be179e78de8
parentSupport .Bl -offset in -mdoc -Tman. (diff)
downloadwireguard-openbsd-58dcd7cbcc7ff2e661cdae301c6471ecb2d79784.tar.xz
wireguard-openbsd-58dcd7cbcc7ff2e661cdae301c6471ecb2d79784.zip
Remove `abort_task' from usb task queue before recycling a `struct
usbd_xfer object' which includes the `abort_task'. Otherwise usb_abort_task_thread() may try to dequeue the recycled task then it causes panic with page fault. reported by Edd Barrett and Wade, Daniel. ok mpi
-rw-r--r--sys/dev/usb/ehci.c5
-rw-r--r--sys/dev/usb/ohci.c8
-rw-r--r--sys/dev/usb/uhci.c5
3 files changed, 15 insertions, 3 deletions
diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c
index cba453d4846..57f30ca7506 100644
--- a/sys/dev/usb/ehci.c
+++ b/sys/dev/usb/ehci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ehci.c,v 1.131 2013/04/19 08:58:53 mpi Exp $ */
+/* $OpenBSD: ehci.c,v 1.132 2013/05/20 08:19:47 yasuoka Exp $ */
/* $NetBSD: ehci.c,v 1.66 2004/06/30 03:11:56 mycroft Exp $ */
/*
@@ -800,6 +800,7 @@ ehci_check_itd_intr(struct ehci_softc *sc, struct ehci_xfer *ex) {
done:
DPRINTFN(12, ("ehci_check_itd_intr: ex=%p done\n", ex));
timeout_del(&ex->xfer.timeout_handle);
+ usb_rem_task(ex->xfer.pipe->device, &ex->abort_task);
ehci_idone(ex);
}
@@ -2859,6 +2860,7 @@ ehci_abort_isoc_xfer(struct usbd_xfer *xfer, usbd_status status)
s = splusb();
xfer->status = status;
timeout_del(&xfer->timeout_handle);
+ usb_rem_task(epipe->pipe.device, &exfer->abort_task);
usb_transfer_complete(xfer);
splx(s);
return;
@@ -2883,6 +2885,7 @@ ehci_abort_isoc_xfer(struct usbd_xfer *xfer, usbd_status status)
xfer->status = status;
timeout_del(&xfer->timeout_handle);
+ usb_rem_task(epipe->pipe.device, &exfer->abort_task);
s = splusb();
for (itd = exfer->itdstart; itd != NULL; itd = itd->xfer_next) {
diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c
index f1e61abe7d0..87770263d74 100644
--- a/sys/dev/usb/ohci.c
+++ b/sys/dev/usb/ohci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ohci.c,v 1.111 2013/04/19 08:58:53 mpi Exp $ */
+/* $OpenBSD: ohci.c,v 1.112 2013/05/20 08:19:47 yasuoka Exp $ */
/* $NetBSD: ohci.c,v 1.139 2003/02/22 05:24:16 tsutsui Exp $ */
/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */
@@ -1315,6 +1315,8 @@ ohci_softintr(void *v)
continue;
}
timeout_del(&xfer->timeout_handle);
+ usb_rem_task(xfer->pipe->device,
+ &((struct ohci_xfer *)xfer)->abort_task);
len = std->len;
if (std->td.td_cbp != 0)
@@ -2151,6 +2153,8 @@ ohci_abort_xfer(struct usbd_xfer *xfer, usbd_status status)
s = splusb();
xfer->status = status; /* make software ignore it */
timeout_del(&xfer->timeout_handle);
+ usb_rem_task(xfer->pipe->device,
+ &((struct ohci_xfer *)xfer)->abort_task);
usb_transfer_complete(xfer);
splx(s);
return;
@@ -2165,6 +2169,8 @@ ohci_abort_xfer(struct usbd_xfer *xfer, usbd_status status)
s = splusb();
xfer->status = status; /* make software ignore it */
timeout_del(&xfer->timeout_handle);
+ usb_rem_task(xfer->pipe->device,
+ &((struct ohci_xfer *)xfer)->abort_task);
splx(s);
DPRINTFN(1,("ohci_abort_xfer: stop ed=%p\n", sed));
sed->ed.ed_flags |= htole32(OHCI_ED_SKIP); /* force hardware skip */
diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c
index be8b5b16de2..487fda3922d 100644
--- a/sys/dev/usb/uhci.c
+++ b/sys/dev/usb/uhci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uhci.c,v 1.96 2013/04/19 08:58:53 mpi Exp $ */
+/* $OpenBSD: uhci.c,v 1.97 2013/05/20 08:19:47 yasuoka Exp $ */
/* $NetBSD: uhci.c,v 1.172 2003/02/23 04:19:26 simonb Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */
@@ -1264,6 +1264,7 @@ uhci_check_intr(struct uhci_softc *sc, struct uhci_intr_info *ii)
done:
DPRINTFN(12, ("uhci_check_intr: ii=%p done\n", ii));
timeout_del(&ii->xfer->timeout_handle);
+ usb_rem_task(ii->xfer->pipe->device, &UXFER(ii->xfer)->abort_task);
uhci_idone(ii);
}
@@ -1856,6 +1857,7 @@ uhci_abort_xfer(struct usbd_xfer *xfer, usbd_status status)
s = splusb();
xfer->status = status; /* make software ignore it */
timeout_del(&xfer->timeout_handle);
+ usb_rem_task(xfer->pipe->device, &UXFER(xfer)->abort_task);
usb_transfer_complete(xfer);
splx(s);
return;
@@ -1870,6 +1872,7 @@ uhci_abort_xfer(struct usbd_xfer *xfer, usbd_status status)
s = splusb();
xfer->status = status; /* make software ignore it */
timeout_del(&xfer->timeout_handle);
+ usb_rem_task(xfer->pipe->device, &UXFER(xfer)->abort_task);
DPRINTFN(1,("uhci_abort_xfer: stop ii=%p\n", ii));
for (std = ii->stdstart; std != NULL; std = std->link.std)
std->td.td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC));