diff options
author | 2013-05-20 08:19:47 +0000 | |
---|---|---|
committer | 2013-05-20 08:19:47 +0000 | |
commit | 58dcd7cbcc7ff2e661cdae301c6471ecb2d79784 (patch) | |
tree | 139d754406d8dd3b5687076819cf8be179e78de8 | |
parent | Support .Bl -offset in -mdoc -Tman. (diff) | |
download | wireguard-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.c | 5 | ||||
-rw-r--r-- | sys/dev/usb/ohci.c | 8 | ||||
-rw-r--r-- | sys/dev/usb/uhci.c | 5 |
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)); |