diff options
author | Jacob Meuser <jakemsr@cvs.openbsd.org> | 2010-09-23 05:44:17 +0000 |
---|---|---|
committer | Jacob Meuser <jakemsr@cvs.openbsd.org> | 2010-09-23 05:44:17 +0000 |
commit | 73f94e14178edec7b40dbd3bfb5feb42e13e28b2 (patch) | |
tree | d50e11d1caef3143d1d803c79f4557fe1875bd0f | |
parent | 76bc9d27aac9908dd59bf4e39f2597381c872cd3 (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.c | 7 | ||||
-rw-r--r-- | sys/dev/usb/usb.c | 27 | ||||
-rw-r--r-- | sys/dev/usb/usbdi.c | 6 | ||||
-rw-r--r-- | sys/dev/usb/usbdivar.h | 3 |
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; |