summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2014-05-18 17:10:27 +0000
committermpi <mpi@openbsd.org>2014-05-18 17:10:27 +0000
commitca68072a688cf728a88c80bb1a274b92d9c7ce09 (patch)
tree19561ec7dc39bd6a6c2d7495de336f8636042fc8
parentOut of all the openssl apps, just one of them has code to mess around with (diff)
downloadwireguard-openbsd-ca68072a688cf728a88c80bb1a274b92d9c7ce09.tar.xz
wireguard-openbsd-ca68072a688cf728a88c80bb1a274b92d9c7ce09.zip
Do not pass an xfer pointer to the timeout routine checking for root hub
status changes because it might be freed when detaching the root uhub(4). Also do not reschedule a timeout if the pipe is being aborted. Finally do not add more code to retrieve the 'bInterval' value of the root hub endpoint descriptor since this value is hardcoded in the uhci(4) driver.
-rw-r--r--sys/dev/usb/uhci.c69
-rw-r--r--sys/dev/usb/uhcivar.h7
2 files changed, 29 insertions, 47 deletions
diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c
index e3bd38aadea..04d6f0f2dd6 100644
--- a/sys/dev/usb/uhci.c
+++ b/sys/dev/usb/uhci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uhci.c,v 1.118 2014/05/16 19:00:18 mpi Exp $ */
+/* $OpenBSD: uhci.c,v 1.119 2014/05/18 17:10:27 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 $ */
@@ -481,7 +481,7 @@ uhci_init(struct uhci_softc *sc)
LIST_INIT(&sc->sc_intrhead);
- timeout_set(&sc->sc_poll_handle, NULL, NULL);
+ timeout_set(&sc->sc_root_intr, uhci_poll_hub, sc);
/* Set up the bus struct. */
sc->sc_bus.methods = &uhci_bus_methods;
@@ -511,8 +511,6 @@ uhci_activate(struct device *self, int act)
uhci_dumpregs(sc);
#endif
rv = config_activate_children(self, act);
- if (sc->sc_intr_xfer != NULL)
- timeout_del(&sc->sc_poll_handle);
sc->sc_bus.use_polling++;
uhci_run(sc, 0); /* stop the controller */
@@ -557,12 +555,6 @@ uhci_activate(struct device *self, int act)
uhci_run(sc, 1); /* and start traffic again */
usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY);
sc->sc_bus.use_polling--;
- if (sc->sc_intr_xfer != NULL) {
- timeout_del(&sc->sc_poll_handle);
- timeout_set(&sc->sc_poll_handle, uhci_poll_hub,
- sc->sc_intr_xfer);
- timeout_add_msec(&sc->sc_poll_handle, sc->sc_ival);
- }
#ifdef UHCI_DEBUG
if (uhcidebug > 2)
uhci_dumpregs(sc);
@@ -587,10 +579,7 @@ uhci_detach(struct device *self, int flags)
if (rv != 0)
return (rv);
- if (sc->sc_intr_xfer != NULL) {
- timeout_del(&sc->sc_poll_handle);
- sc->sc_intr_xfer = NULL;
- }
+ KASSERT(sc->sc_intrxfer == NULL);
/* XXX free other data structures XXX */
@@ -820,19 +809,17 @@ void exdump(void) { uhci_dump_xfers(thesc); }
void
uhci_poll_hub(void *addr)
{
- struct usbd_xfer *xfer = addr;
- struct uhci_softc *sc = (struct uhci_softc *)xfer->device->bus;
+ struct uhci_softc *sc = addr;
+ struct usbd_xfer *xfer;
int s;
u_char *p;
- DPRINTFN(20, ("uhci_poll_hub\n"));
-
if (sc->sc_bus.dying)
return;
- timeout_del(&sc->sc_poll_handle);
- timeout_set(&sc->sc_poll_handle, uhci_poll_hub, xfer);
- timeout_add_msec(&sc->sc_poll_handle, sc->sc_ival);
+ xfer = sc->sc_intrxfer;
+ if (xfer == NULL)
+ return;
p = KERNADDR(&xfer->dmabuf, 0);
p[0] = 0;
@@ -840,12 +827,15 @@ uhci_poll_hub(void *addr)
p[0] |= 1<<1;
if (UREAD2(sc, UHCI_PORTSC2) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC))
p[0] |= 1<<2;
- if (p[0] == 0)
+ if (p[0] == 0) {
/* No change, try again in a while */
+ timeout_add_msec(&sc->sc_root_intr, 255);
return;
+ }
- xfer->actlen = 1;
+ xfer->actlen = xfer->length;
xfer->status = USBD_NORMAL_COMPLETION;
+
s = splusb();
xfer->device->bus->intr_context++;
usb_transfer_complete(xfer);
@@ -854,11 +844,6 @@ uhci_poll_hub(void *addr)
}
void
-uhci_root_intr_done(struct usbd_xfer *xfer)
-{
-}
-
-void
uhci_root_ctrl_done(struct usbd_xfer *xfer)
{
}
@@ -3297,8 +3282,8 @@ 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;
+ timeout_del(&sc->sc_root_intr);
+ sc->sc_intrxfer = NULL;
xfer->status = USBD_CANCELLED;
s = splusb();
@@ -3328,27 +3313,25 @@ uhci_root_intr_start(struct usbd_xfer *xfer)
{
struct uhci_softc *sc = (struct uhci_softc *)xfer->device->bus;
- DPRINTFN(3, ("uhci_root_intr_start: xfer=%p len=%u flags=%d\n",
- xfer, xfer->length, xfer->flags));
-
if (sc->sc_bus.dying)
return (USBD_IOERROR);
- sc->sc_ival = xfer->pipe->endpoint->edesc->bInterval;
- timeout_del(&sc->sc_poll_handle);
- timeout_set(&sc->sc_poll_handle, uhci_poll_hub, xfer);
- timeout_add_msec(&sc->sc_poll_handle, sc->sc_ival);
- sc->sc_intr_xfer = xfer;
+ sc->sc_intrxfer = xfer;
+ timeout_add_msec(&sc->sc_root_intr, 255);
+
return (USBD_IN_PROGRESS);
}
-/* Close the root interrupt pipe. */
void
uhci_root_intr_close(struct usbd_pipe *pipe)
{
- struct uhci_softc *sc = (struct uhci_softc *)pipe->device->bus;
+}
+
+void
+uhci_root_intr_done(struct usbd_xfer *xfer)
+{
+ struct uhci_softc *sc = (struct uhci_softc *)xfer->device->bus;
- timeout_del(&sc->sc_poll_handle);
- sc->sc_intr_xfer = NULL;
- DPRINTF(("uhci_root_intr_close\n"));
+ if (xfer->pipe->repeat)
+ timeout_add_msec(&sc->sc_root_intr, 255);
}
diff --git a/sys/dev/usb/uhcivar.h b/sys/dev/usb/uhcivar.h
index 8e4c45c11f0..77801bba836 100644
--- a/sys/dev/usb/uhcivar.h
+++ b/sys/dev/usb/uhcivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uhcivar.h,v 1.32 2014/05/16 18:17:03 mpi Exp $ */
+/* $OpenBSD: uhcivar.h,v 1.33 2014/05/18 17:10:27 mpi Exp $ */
/* $NetBSD: uhcivar.h,v 1.36 2002/12/31 00:39:11 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhcivar.h,v 1.14 1999/11/17 22:33:42 n_hibma Exp $ */
@@ -151,9 +151,8 @@ struct uhci_softc {
LIST_HEAD(, uhci_xfer) sc_intrhead;
/* Info for the root hub interrupt "pipe". */
- int sc_ival; /* time between root hub intrs */
- struct usbd_xfer *sc_intr_xfer; /* root hub interrupt transfer */
- struct timeout sc_poll_handle;
+ struct usbd_xfer *sc_intrxfer;
+ struct timeout sc_root_intr;
char sc_vendor[32]; /* vendor string for root hub */
int sc_id_vendor; /* vendor ID for root hub */