summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Meuser <jakemsr@cvs.openbsd.org>2010-09-23 05:44:17 +0000
committerJacob Meuser <jakemsr@cvs.openbsd.org>2010-09-23 05:44:17 +0000
commit73f94e14178edec7b40dbd3bfb5feb42e13e28b2 (patch)
treed50e11d1caef3143d1d803c79f4557fe1875bd0f
parent76bc9d27aac9908dd59bf4e39f2597381c872cd3 (diff)
add a 'dying' flag to struct usbd_bus. use this to signify the bus
is dying, instead of setting a flag in struct usb_softc. as usbd_device_handle has a pointer to the usbd_bus it's attached to, usb devices, and functions they run or functions run on their behalf, can now easily check if their bus is dying. use this to stop usbd_do_request* from running and the usb task thread from adding new tasks when a device's bus is dying.
-rw-r--r--sys/dev/usb/uhub.c7
-rw-r--r--sys/dev/usb/usb.c27
-rw-r--r--sys/dev/usb/usbdi.c6
-rw-r--r--sys/dev/usb/usbdivar.h3
4 files changed, 28 insertions, 15 deletions
diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c
index 706e94db1c5..75bc3325dee 100644
--- a/sys/dev/usb/uhub.c
+++ b/sys/dev/usb/uhub.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uhub.c,v 1.54 2010/09/23 04:58:02 jakemsr Exp $ */
+/* $OpenBSD: uhub.c,v 1.55 2010/09/23 05:44:15 jakemsr Exp $ */
/* $NetBSD: uhub.c,v 1.64 2003/02/08 03:32:51 ichiro Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhub.c,v 1.18 1999/11/17 22:33:43 n_hibma Exp $ */
@@ -353,6 +353,11 @@ uhub_explore(usbd_device_handle dev)
DPRINTFN(10, ("uhub_explore dev=%p addr=%d\n", dev, dev->address));
+ if (dev->bus->dying) {
+ DPRINTF(("%s: root hub gone at start\n", __func__));
+ return (USBD_IOERROR);
+ }
+
if (!sc->sc_running)
return (USBD_NOT_STARTED);
diff --git a/sys/dev/usb/usb.c b/sys/dev/usb/usb.c
index 04fd7192c47..166827d019d 100644
--- a/sys/dev/usb/usb.c
+++ b/sys/dev/usb/usb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: usb.c,v 1.66 2010/09/23 05:28:57 jakemsr Exp $ */
+/* $OpenBSD: usb.c,v 1.67 2010/09/23 05:44:15 jakemsr Exp $ */
/* $NetBSD: usb.c,v 1.77 2003/01/01 00:10:26 thorpej Exp $ */
/*
@@ -97,7 +97,6 @@ struct usb_softc {
struct usb_task sc_explore_task;
- char sc_dying;
struct timeval sc_ptime;
};
@@ -183,7 +182,7 @@ usb_attach(struct device *parent, struct device *self, void *aux)
break;
default:
printf(", not supported\n");
- sc->sc_dying = 1;
+ sc->sc_bus->dying = 1;
return;
}
printf("\n");
@@ -206,7 +205,7 @@ usb_attach(struct device *parent, struct device *self, void *aux)
sc->sc_bus->methods->soft_intr, sc->sc_bus);
if (sc->sc_bus->soft == NULL) {
printf("%s: can't register softintr\n", sc->sc_dev.dv_xname);
- sc->sc_dying = 1;
+ sc->sc_bus->dying = 1;
return;
}
@@ -215,7 +214,7 @@ usb_attach(struct device *parent, struct device *self, void *aux)
if (!err) {
dev = sc->sc_port.device;
if (dev->hub == NULL) {
- sc->sc_dying = 1;
+ sc->sc_bus->dying = 1;
printf("%s: root device is not a hub\n",
sc->sc_dev.dv_xname);
return;
@@ -233,12 +232,12 @@ usb_attach(struct device *parent, struct device *self, void *aux)
} else {
printf("%s: root hub problem, error=%d\n",
sc->sc_dev.dv_xname, err);
- sc->sc_dying = 1;
+ sc->sc_bus->dying = 1;
}
if (cold)
sc->sc_bus->use_polling--;
- if (!sc->sc_dying) {
+ if (!sc->sc_bus->dying) {
getmicrouptime(&sc->sc_ptime);
if (sc->sc_bus->usbrev == USBREV_2_0)
explore_pending++;
@@ -289,6 +288,10 @@ usb_add_task(usbd_device_handle dev, struct usb_task *task)
DPRINTFN(2,("%s: task=%p onqueue=%d\n", __func__, task, task->onqueue));
+ /* Don't add task if the device's root hub is dying. */
+ if (dev->bus->dying)
+ return;
+
s = splusb();
if (!task->onqueue) {
if (task->fun == usb_explore)
@@ -417,7 +420,7 @@ usbopen(dev_t dev, int flag, int mode, struct proc *p)
if (sc == NULL)
return (ENXIO);
- if (sc->sc_dying)
+ if (sc->sc_bus->dying)
return (EIO);
return (0);
@@ -496,7 +499,7 @@ usbioctl(dev_t devt, u_long cmd, caddr_t data, int flag, struct proc *p)
sc = usb_cd.cd_devs[unit];
- if (sc->sc_dying)
+ if (sc->sc_bus->dying)
return (EIO);
error = 0;
@@ -699,7 +702,7 @@ usb_explore(void *v)
return;
#endif
- if (!sc->sc_dying)
+ if (!sc->sc_bus->dying)
sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub);
if (sc->sc_bus->flags & USB_BUS_CONFIG_PENDING) {
@@ -828,7 +831,7 @@ usb_activate(struct device *self, int act)
case DVACT_ACTIVATE:
break;
case DVACT_DEACTIVATE:
- sc->sc_dying = 1;
+ sc->sc_bus->dying = 1;
if (dev != NULL && dev->cdesc != NULL &&
dev->subdevs != NULL) {
for (i = 0; dev->subdevs[i]; i++) {
@@ -850,7 +853,7 @@ usb_detach(struct device *self, int flags)
DPRINTF(("usb_detach: start\n"));
- sc->sc_dying = 1;
+ sc->sc_bus->dying = 1;
/* Make all devices disconnect. */
if (sc->sc_port.device != NULL)
diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c
index 043b104981e..f619fd23460 100644
--- a/sys/dev/usb/usbdi.c
+++ b/sys/dev/usb/usbdi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: usbdi.c,v 1.39 2010/09/23 04:58:02 jakemsr Exp $ */
+/* $OpenBSD: usbdi.c,v 1.40 2010/09/23 05:44:15 jakemsr Exp $ */
/* $NetBSD: usbdi.c,v 1.103 2002/09/27 15:37:38 provos Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $ */
@@ -922,6 +922,10 @@ usbd_do_request_flags_pipe(usbd_device_handle dev, usbd_pipe_handle pipe,
}
#endif
+ /* If the bus is gone, don't go any further. */
+ if (dev->bus->dying)
+ return (USBD_IOERROR);
+
xfer = usbd_alloc_xfer(dev);
if (xfer == NULL)
return (USBD_NOMEM);
diff --git a/sys/dev/usb/usbdivar.h b/sys/dev/usb/usbdivar.h
index f5953109a77..b2a22a27a86 100644
--- a/sys/dev/usb/usbdivar.h
+++ b/sys/dev/usb/usbdivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: usbdivar.h,v 1.38 2010/09/23 04:58:02 jakemsr Exp $ */
+/* $OpenBSD: usbdivar.h,v 1.39 2010/09/23 05:44:16 jakemsr Exp $ */
/* $NetBSD: usbdivar.h,v 1.70 2002/07/11 21:14:36 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdivar.h,v 1.11 1999/11/17 22:33:51 n_hibma Exp $ */
@@ -104,6 +104,7 @@ struct usbd_bus {
struct usbd_device *root_hub;
usbd_device_handle devices[USB_MAX_DEVICES];
char use_polling;
+ char dying;
int flags;
#define USB_BUS_CONFIG_PENDING 0x01
struct usb_softc *usbctl;