summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2014-05-09 11:01:07 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2014-05-09 11:01:07 +0000
commitb99b48e4837ee6f17e2140826c16980ddf836b9b (patch)
treea0c4d37d1215d31ef5d2b4bc8be8346ac911cc82 /sys
parentc1e4530528edb2bc9995a81e769bc4d655c191bd (diff)
Plug an xfer leak when detaching root hubs.
This leak is similar to the public xfer leak #1 that was affecting device interrupt pipes except that root hubs are rarely detached. Note that this xfer is never associated to any TD and is just used to indicate that some of the HC ports has changed status, so there is no need to flag it as "done" before completing it.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/usb/ehci.c21
-rw-r--r--sys/dev/usb/ohci.c18
-rw-r--r--sys/dev/usb/uhci.c13
-rw-r--r--sys/dev/usb/xhci.c12
4 files changed, 17 insertions, 47 deletions
diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c
index 98c5f83dcaf..d9f83687d29 100644
--- a/sys/dev/usb/ehci.c
+++ b/sys/dev/usb/ehci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ehci.c,v 1.152 2014/05/08 14:00:52 mpi Exp $ */
+/* $OpenBSD: ehci.c,v 1.153 2014/05/09 11:01:06 mpi Exp $ */
/* $NetBSD: ehci.c,v 1.66 2004/06/30 03:11:56 mycroft Exp $ */
/*
@@ -2305,8 +2305,7 @@ ehci_root_intr_transfer(struct usbd_xfer *xfer)
usbd_status
ehci_root_intr_start(struct usbd_xfer *xfer)
{
- struct usbd_pipe *pipe = xfer->pipe;
- struct ehci_softc *sc = (struct ehci_softc *)pipe->device->bus;
+ struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
if (sc->sc_bus.dying)
return (USBD_IOERROR);
@@ -2316,31 +2315,23 @@ ehci_root_intr_start(struct usbd_xfer *xfer)
return (USBD_IN_PROGRESS);
}
-/* Abort a root interrupt request. */
void
ehci_root_intr_abort(struct usbd_xfer *xfer)
{
+ struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
int s;
- if (xfer->pipe->intrxfer == xfer) {
- DPRINTF(("ehci_root_intr_abort: remove\n"));
- xfer->pipe->intrxfer = NULL;
- }
+ sc->sc_intrxfer = NULL;
+
xfer->status = USBD_CANCELLED;
s = splusb();
usb_transfer_complete(xfer);
splx(s);
}
-/* Close the root pipe. */
void
ehci_root_intr_close(struct usbd_pipe *pipe)
{
- struct ehci_softc *sc = (struct ehci_softc *)pipe->device->bus;
-
- DPRINTF(("ehci_root_intr_close\n"));
-
- sc->sc_intrxfer = NULL;
}
void
@@ -2348,8 +2339,6 @@ ehci_root_ctrl_done(struct usbd_xfer *xfer)
{
}
-/************************/
-
struct ehci_soft_qh *
ehci_alloc_sqh(struct ehci_softc *sc)
{
diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c
index 3cbc1f79dbe..f0aa949be77 100644
--- a/sys/dev/usb/ohci.c
+++ b/sys/dev/usb/ohci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ohci.c,v 1.128 2014/05/04 14:42:36 mpi Exp $ */
+/* $OpenBSD: ohci.c,v 1.129 2014/05/09 11:01:06 mpi 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 $ */
@@ -2624,35 +2624,25 @@ ohci_root_intr_start(struct usbd_xfer *xfer)
return (USBD_IN_PROGRESS);
}
-/* Abort a root interrupt request. */
void
ohci_root_intr_abort(struct usbd_xfer *xfer)
{
+ struct ohci_softc *sc = (struct ohci_softc *)xfer->device->bus;
int s;
- if (xfer->pipe->intrxfer == xfer) {
- DPRINTF(("ohci_root_intr_abort: remove\n"));
- xfer->pipe->intrxfer = NULL;
- }
+ sc->sc_intrxfer = NULL;
+
xfer->status = USBD_CANCELLED;
s = splusb();
usb_transfer_complete(xfer);
splx(s);
}
-/* Close the root pipe. */
void
ohci_root_intr_close(struct usbd_pipe *pipe)
{
- struct ohci_softc *sc = (struct ohci_softc *)pipe->device->bus;
-
- DPRINTF(("ohci_root_intr_close\n"));
-
- sc->sc_intrxfer = NULL;
}
-/************************/
-
usbd_status
ohci_device_ctrl_transfer(struct usbd_xfer *xfer)
{
diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c
index b720b39eb74..7451e0dca60 100644
--- a/sys/dev/usb/uhci.c
+++ b/sys/dev/usb/uhci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uhci.c,v 1.115 2014/05/08 14:00:52 mpi Exp $ */
+/* $OpenBSD: uhci.c,v 1.116 2014/05/09 11:01:06 mpi 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 $ */
@@ -3294,24 +3294,19 @@ uhci_root_ctrl_close(struct usbd_pipe *pipe)
DPRINTF(("uhci_root_ctrl_close\n"));
}
-/* Abort a root interrupt request. */
void
uhci_root_intr_abort(struct usbd_xfer *xfer)
{
struct uhci_softc *sc = (struct uhci_softc *)xfer->device->bus;
+ int s;
timeout_del(&sc->sc_poll_handle);
sc->sc_intr_xfer = NULL;
- if (xfer->pipe->intrxfer == xfer) {
- DPRINTF(("uhci_root_intr_abort: remove\n"));
- xfer->pipe->intrxfer = 0;
- }
xfer->status = USBD_CANCELLED;
-#ifdef DIAGNOSTIC
- ((struct uhci_xfer *)xfer)->isdone = 1;
-#endif
+ s = splusb();
usb_transfer_complete(xfer);
+ splx(s);
}
usbd_status
diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c
index 74af7cb4d1a..7f880e46fbd 100644
--- a/sys/dev/usb/xhci.c
+++ b/sys/dev/usb/xhci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xhci.c,v 1.10 2014/04/29 12:45:29 mpi Exp $ */
+/* $OpenBSD: xhci.c,v 1.11 2014/05/09 11:01:06 mpi Exp $ */
/*
* Copyright (c) 2014 Martin Pieuchot
@@ -2092,10 +2092,12 @@ xhci_root_intr_start(struct usbd_xfer *xfer)
void
xhci_root_intr_abort(struct usbd_xfer *xfer)
{
+ struct xhci_softc *sc = (struct xhci_softc *)xfer->device->bus;
int s;
- xfer->status = USBD_CANCELLED;
+ sc->sc_intrxfer = NULL;
+ xfer->status = USBD_CANCELLED;
s = splusb();
usb_transfer_complete(xfer);
splx(s);
@@ -2104,12 +2106,6 @@ xhci_root_intr_abort(struct usbd_xfer *xfer)
void
xhci_root_intr_done(struct usbd_xfer *xfer)
{
- struct xhci_softc *sc = (struct xhci_softc *)xfer->device->bus;
-
- KASSERT(sc->sc_intrxfer == xfer);
-
- if (!xfer->pipe->repeat)
- sc->sc_intrxfer = NULL;
}
usbd_status