when a usb device is removed from a port, a hub interrupt is generated. this causes a hub explore task to be scheduled, which will find that the device has been removed then detach the driver via usb_disconnect_port(). so there is some time between when the device is removed and the driver detachment. if the kernel tries to access the device after it has been removed but before the driver is detached, a kernel crash is likely. also, the kernel does not know the device has been removed until the driver is detached; config_deactivate() is never called.
the following patch adds a 'dying' field to struct usbd_device, and a couple functions, usbd_deactivate() and usbd_is_dying(). usbd_deactivate() sets the new dying field, and usbd_is_dying() checks whether the dying field is set. usb_disconnect_port() is changed to call config_deactivate() for devices to be detached before calling config_detach(), and usbd_deactivate() is added to the DVACT_DEACTIVATE case for many devices' activate() functions. also, usbd_is_dying() is either added or replaces driver specific state variables at places where it would be good to know if the hardware is still usable. the idea is to give drivers a chance to quit accessing the hardware before the driver is detached, so we don't detach the driver while a request is stalled trying to read/write nonexistent hardware. oh, usbd_is_dying() also checks if the underlying bus is detached, because if the bus is detached, the device has also been detached. I think this will avoid the crash described in http://marc.info/?l=openbsd-bugs&m=129050458925460&w=2 it seems that that device generates a hub interrupt (the only thing that causes uhub_explore() to be run) when detached. on the one hand this makes sense: hub interrupt means the status of the hub changed. on the other, it's nonsensical: the hub is gone, we don't need an interrupt to know that the hub state has changed. the idea is really from yuo@, in some commit messages from a couple months ago. I've been running this diff for quite some time, and it was actually in snapshots for some time in early October. thoughts? p.s. yes, this doesn't convert *all* drivers at this time. that will happen, I promise. -- jake...@sdf.lonestar.org SDF Public Access UNIX System - http://sdf.lonestar.org Index: if_atu.c =================================================================== RCS file: /cvs/src/sys/dev/usb/if_atu.c,v retrieving revision 1.96 diff -u -p -r1.96 if_atu.c --- if_atu.c 27 Oct 2010 17:51:11 -0000 1.96 +++ if_atu.c 24 Nov 2010 19:53:58 -0000 @@ -902,7 +902,7 @@ atu_internal_firmware(void *arg) if (err != 0) { printf("%s: %s loadfirmware error %d\n", sc->atu_dev.dv_xname, name, err); - return; + goto fail; } ptr = firm; @@ -918,7 +918,7 @@ atu_internal_firmware(void *arg) DPRINTF(("%s: dfu_getstatus failed!\n", sc->atu_dev.dv_xname)); free(firm, M_DEVBUF); - return; + goto fail; } /* success means state => DnLoadIdle */ state = DFUState_DnLoadIdle; @@ -940,7 +940,7 @@ atu_internal_firmware(void *arg) DPRINTF(("%s: dfu_dnload failed\n", sc->atu_dev.dv_xname)); free(firm, M_DEVBUF); - return; + goto fail; } ptr += block_size; @@ -969,14 +969,14 @@ atu_internal_firmware(void *arg) if (err) { DPRINTF(("%s: dfu_getstatus failed!\n", sc->atu_dev.dv_xname)); - return; + goto fail; } DPRINTFN(15, ("%s: sending remap\n", sc->atu_dev.dv_xname)); err = atu_usb_request(sc, DFU_REMAP, 0, 0, 0, NULL); if ((err) && (!ISSET(sc->atu_quirk, ATU_QUIRK_NO_REMAP))) { DPRINTF(("%s: remap failed!\n", sc->atu_dev.dv_xname)); - return; + goto fail; } /* after a lot of trying and measuring I found out the device needs @@ -989,6 +989,9 @@ atu_internal_firmware(void *arg) printf("%s: reattaching after firmware upload\n", sc->atu_dev.dv_xname); usb_needs_reattach(sc->atu_udev); + +fail: + usbd_deactivate(sc->atu_udev); } void @@ -1169,7 +1172,7 @@ atu_task(void *arg) DPRINTFN(10, ("%s: atu_task\n", sc->atu_dev.dv_xname)); - if (sc->sc_state != ATU_S_OK) + if (usbd_is_dying(sc->atu_udev)) return; switch (sc->sc_cmd) { @@ -1259,25 +1262,23 @@ atu_attach(struct device *parent, struct u_int8_t mode, channel; int i; - sc->sc_state = ATU_S_UNCONFIG; + sc->atu_unit = self->dv_unit; + sc->atu_udev = dev; err = usbd_set_config_no(dev, ATU_CONFIG_NO, 1); if (err) { printf("%s: setting config no failed\n", sc->atu_dev.dv_xname); - return; + goto fail; } err = usbd_device2interface_handle(dev, ATU_IFACE_IDX, &sc->atu_iface); if (err) { printf("%s: getting interface handle failed\n", sc->atu_dev.dv_xname); - return; + goto fail; } - sc->atu_unit = self->dv_unit; - sc->atu_udev = dev; - /* * look up the radio_type for the device * basically does the same as USB_MATCH @@ -1361,6 +1362,8 @@ atu_attach(struct device *parent, struct /* all the firmwares are in place, so complete the attach */ atu_complete_attach(sc); } +fail: + usbd_deactivate(sc->atu_udev); } void @@ -1386,7 +1389,7 @@ atu_complete_attach(struct atu_softc *sc sc->atu_iface->idesc->bNumEndpoints)); DPRINTF(("%s: couldn't get ep %d\n", sc->atu_dev.dv_xname, i)); - return; + goto fail; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { @@ -1402,7 +1405,7 @@ atu_complete_attach(struct atu_softc *sc if (err) { printf("%s: could not get card cfg!\n", sc->atu_dev.dv_xname); - return; + goto fail; } #ifdef ATU_DEBUG @@ -1482,7 +1485,8 @@ atu_complete_attach(struct atu_softc *sc sc->sc_txtap.rt_ihdr.it_present = htole32(ATU_TX_RADIOTAP_PRESENT); #endif - sc->sc_state = ATU_S_OK; +fail: + usbd_deactivate(sc->atu_udev); } int @@ -1491,23 +1495,21 @@ atu_detach(struct device *self, int flag struct atu_softc *sc = (struct atu_softc *)self; struct ifnet *ifp = &sc->sc_ic.ic_if; - DPRINTFN(10, ("%s: atu_detach state=%d\n", sc->atu_dev.dv_xname, - sc->sc_state)); + DPRINTFN(10, ("%s: atu_detach\n", sc->atu_dev.dv_xname)); - if (sc->sc_state != ATU_S_UNCONFIG) { + if (ifp->if_flags & IFF_RUNNING) atu_stop(ifp, 1); - usb_rem_task(sc->atu_udev, &sc->sc_task); + usb_rem_task(sc->atu_udev, &sc->sc_task); - if (sc->atu_ep[ATU_ENDPT_TX] != NULL) - usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_TX]); - if (sc->atu_ep[ATU_ENDPT_RX] != NULL) - usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_RX]); - - if (ifp->if_softc != NULL) { - ieee80211_ifdetach(ifp); - if_detach(ifp); - } + if (sc->atu_ep[ATU_ENDPT_TX] != NULL) + usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_TX]); + if (sc->atu_ep[ATU_ENDPT_RX] != NULL) + usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_RX]); + + if (ifp->if_softc != NULL) { + ieee80211_ifdetach(ifp); + if_detach(ifp); } return(0); @@ -1522,8 +1524,7 @@ atu_activate(struct device *self, int ac case DVACT_ACTIVATE: break; case DVACT_DEACTIVATE: - if (sc->sc_state != ATU_S_UNCONFIG) - sc->sc_state = ATU_S_DEAD; + usbd_deactivate(sc->atu_udev); break; } return (0); @@ -1665,7 +1666,7 @@ atu_rxeof(usbd_xfer_handle xfer, usbd_pr DPRINTFN(25, ("%s: atu_rxeof\n", sc->atu_dev.dv_xname)); - if (sc->sc_state != ATU_S_OK) + if (usbd_is_dying(sc->atu_udev)) return; if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP)) @@ -1859,7 +1860,7 @@ atu_tx_start(struct atu_softc *sc, struc DPRINTFN(25, ("%s: atu_tx_start\n", sc->atu_dev.dv_xname)); /* Don't try to send when we're shutting down the driver */ - if (sc->sc_state != ATU_S_OK) { + if (usbd_is_dying(sc->atu_udev)) { m_freem(m); return(EIO); } @@ -2256,7 +2257,7 @@ atu_watchdog(struct ifnet *ifp) if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP)) return; - if (sc->sc_state != ATU_S_OK) + if (usbd_is_dying(sc->atu_udev)) return; sc = ifp->if_softc; Index: if_atureg.h =================================================================== RCS file: /cvs/src/sys/dev/usb/if_atureg.h,v retrieving revision 1.31 diff -u -p -r1.31 if_atureg.h --- if_atureg.h 27 Nov 2007 16:22:13 -0000 1.31 +++ if_atureg.h 24 Nov 2010 19:53:58 -0000 @@ -173,10 +173,6 @@ struct atu_softc { int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int); - char sc_state; -#define ATU_S_DEAD 0 -#define ATU_S_OK 1 -#define ATU_S_UNCONFIG 2 char sc_cmd; #define ATU_C_NONE 0 #define ATU_C_SCAN 1 Index: if_aue.c =================================================================== RCS file: /cvs/src/sys/dev/usb/if_aue.c,v retrieving revision 1.82 diff -u -p -r1.82 if_aue.c --- if_aue.c 27 Oct 2010 17:51:11 -0000 1.82 +++ if_aue.c 24 Nov 2010 19:53:58 -0000 @@ -277,7 +277,7 @@ aue_csr_read_1(struct aue_softc *sc, int usbd_status err; uByte val = 0; - if (sc->aue_dying) + if (usbd_is_dying(sc->aue_udev)) return (0); req.bmRequestType = UT_READ_VENDOR_DEVICE; @@ -304,7 +304,7 @@ aue_csr_read_2(struct aue_softc *sc, int usbd_status err; uWord val; - if (sc->aue_dying) + if (usbd_is_dying(sc->aue_udev)) return (0); req.bmRequestType = UT_READ_VENDOR_DEVICE; @@ -331,7 +331,7 @@ aue_csr_write_1(struct aue_softc *sc, in usbd_status err; uByte val; - if (sc->aue_dying) + if (usbd_is_dying(sc->aue_udev)) return (0); val = aval; @@ -359,7 +359,7 @@ aue_csr_write_2(struct aue_softc *sc, in usbd_status err; uWord val; - if (sc->aue_dying) + if (usbd_is_dying(sc->aue_udev)) return (0); USETW(val, aval); @@ -446,7 +446,7 @@ aue_miibus_readreg(struct device *dev, i int i; u_int16_t val; - if (sc->aue_dying) { + if (usbd_is_dying(sc->aue_udev)) { #ifdef DIAGNOSTIC printf("%s: dying\n", sc->aue_dev.dv_xname); #endif @@ -557,7 +557,7 @@ aue_miibus_statchg(struct device *dev) * This turns on the 'dual link LED' bin in the auxmode * register of the Broadcom PHY. */ - if (!sc->aue_dying && (sc->aue_flags & LSYS)) { + if (!usbd_is_dying(sc->aue_udev) && (sc->aue_flags & LSYS)) { u_int16_t auxmode; auxmode = aue_miibus_readreg(dev, 0, 0x1b); aue_miibus_writereg(dev, 0, 0x1b, auxmode | 0x04); @@ -727,6 +727,8 @@ aue_attach(struct device *parent, struct DPRINTFN(5,(" : aue_attach: sc=%p", sc)); + sc->aue_udev = dev; + err = usbd_set_config_no(dev, AUE_CONFIG_NO, 1); if (err) { printf("%s: setting config no failed\n", @@ -749,7 +751,6 @@ aue_attach(struct device *parent, struct sc->aue_flags = aue_lookup(uaa->vendor, uaa->product)->aue_flags; - sc->aue_udev = dev; sc->aue_iface = iface; sc->aue_product = uaa->product; sc->aue_vendor = uaa->vendor; @@ -835,7 +836,6 @@ aue_attach(struct device *parent, struct timeout_set(&sc->aue_stat_ch, aue_tick, sc); - sc->aue_attached = 1; splx(s); usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->aue_udev, @@ -851,10 +851,6 @@ aue_detach(struct device *self, int flag DPRINTFN(2,("%s: %s: enter\n", sc->aue_dev.dv_xname, __func__)); - /* Detached before attached finished, so just bail out. */ - if (!sc->aue_attached) - return (0); - if (timeout_initialized(&sc->aue_stat_ch)) timeout_del(&sc->aue_stat_ch); @@ -885,8 +881,6 @@ aue_detach(struct device *self, int flag sc->aue_dev.dv_xname); #endif - sc->aue_attached = 0; - if (--sc->aue_refcnt >= 0) { /* Wait for processes to go away. */ usb_detach_wait(&sc->aue_dev); @@ -911,7 +905,7 @@ aue_activate(struct device *self, int ac break; case DVACT_DEACTIVATE: - sc->aue_dying = 1; + usbd_deactivate(sc->aue_udev); break; } return (0); @@ -1021,7 +1015,7 @@ aue_intr(usbd_xfer_handle xfer, usbd_pri DPRINTFN(15,("%s: %s: enter\n", sc->aue_dev.dv_xname,__func__)); - if (sc->aue_dying) + if (usbd_is_dying(sc->aue_udev)) return; if (!(ifp->if_flags & IFF_RUNNING)) @@ -1067,7 +1061,7 @@ aue_rxeof(usbd_xfer_handle xfer, usbd_pr DPRINTFN(10,("%s: %s: enter\n", sc->aue_dev.dv_xname,__func__)); - if (sc->aue_dying) + if (usbd_is_dying(sc->aue_udev)) return; if (!(ifp->if_flags & IFF_RUNNING)) @@ -1165,7 +1159,7 @@ aue_txeof(usbd_xfer_handle xfer, usbd_pr struct ifnet *ifp = GET_IFP(sc); int s; - if (sc->aue_dying) + if (usbd_is_dying(sc->aue_udev)) return; s = splnet(); @@ -1211,7 +1205,7 @@ aue_tick(void *xsc) if (sc == NULL) return; - if (sc->aue_dying) + if (usbd_is_dying(sc->aue_udev)) return; /* Perform periodic stuff in process context. */ @@ -1228,7 +1222,7 @@ aue_tick_task(void *xsc) DPRINTFN(15,("%s: %s: enter\n", sc->aue_dev.dv_xname,__func__)); - if (sc->aue_dying) + if (usbd_is_dying(sc->aue_udev)) return; ifp = GET_IFP(sc); @@ -1311,7 +1305,7 @@ aue_start(struct ifnet *ifp) DPRINTFN(5,("%s: %s: enter, link=%d\n", sc->aue_dev.dv_xname, __func__, sc->aue_link)); - if (sc->aue_dying) + if (usbd_is_dying(sc->aue_udev)) return; if (!sc->aue_link) @@ -1359,7 +1353,7 @@ aue_init(void *xsc) DPRINTFN(5,("%s: %s: enter\n", sc->aue_dev.dv_xname, __func__)); - if (sc->aue_dying) + if (usbd_is_dying(sc->aue_udev)) return; if (ifp->if_flags & IFF_RUNNING) @@ -1479,7 +1473,7 @@ aue_ifmedia_upd(struct ifnet *ifp) DPRINTFN(5,("%s: %s: enter\n", sc->aue_dev.dv_xname, __func__)); - if (sc->aue_dying) + if (usbd_is_dying(sc->aue_udev)) return (0); sc->aue_link = 0; @@ -1519,7 +1513,7 @@ aue_ioctl(struct ifnet *ifp, u_long comm struct mii_data *mii; int s, error = 0; - if (sc->aue_dying) + if (usbd_is_dying(sc->aue_udev)) return (EIO); s = splnet(); Index: if_auereg.h =================================================================== RCS file: /cvs/src/sys/dev/usb/if_auereg.h,v retrieving revision 1.14 diff -u -p -r1.14 if_auereg.h --- if_auereg.h 10 Aug 2009 20:02:19 -0000 1.14 +++ if_auereg.h 24 Nov 2010 19:53:58 -0000 @@ -247,8 +247,6 @@ struct aue_softc { u_int16_t aue_flags; int aue_refcnt; - char aue_dying; - char aue_attached; u_int aue_rx_errs; u_int aue_intr_errs; struct timeval aue_rx_notice; Index: if_axe.c =================================================================== RCS file: /cvs/src/sys/dev/usb/if_axe.c,v retrieving revision 1.103 diff -u -p -r1.103 if_axe.c --- if_axe.c 14 Nov 2010 20:38:43 -0000 1.103 +++ if_axe.c 24 Nov 2010 19:53:59 -0000 @@ -244,7 +244,7 @@ axe_cmd(struct axe_softc *sc, int cmd, i usb_device_request_t req; usbd_status err; - if (sc->axe_dying) + if (usbd_is_dying(sc->axe_udev)) return(0); if (AXE_CMD_DIR(cmd)) @@ -274,7 +274,7 @@ axe_miibus_readreg(struct device *dev, i uWord val; int ival; - if (sc->axe_dying) { + if (usbd_is_dying(sc->axe_udev)) { DPRINTF(("axe: dying\n")); return(0); } @@ -332,7 +332,7 @@ axe_miibus_writereg(struct device *dev, usbd_status err; uWord uval; - if (sc->axe_dying) + if (usbd_is_dying(sc->axe_udev)) return; if (sc->axe_phyno != phy) return; @@ -465,7 +465,7 @@ axe_setmulti(struct axe_softc *sc) u_int16_t rxmode; u_int8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - if (sc->axe_dying) + if (usbd_is_dying(sc->axe_udev)) return; ifp = GET_IFP(sc); @@ -502,7 +502,7 @@ allmulti: void axe_reset(struct axe_softc *sc) { - if (sc->axe_dying) + if (usbd_is_dying(sc->axe_udev)) return; /* XXX What to reset? */ @@ -666,6 +666,7 @@ axe_attach(struct device *parent, struct int i, s; sc->axe_unit = self->dv_unit; /*device_get_unit(self);*/ + sc->axe_udev = dev; err = usbd_set_config_no(dev, AXE_CONFIG_NO, 1); if (err) { @@ -689,7 +690,6 @@ axe_attach(struct device *parent, struct return; } - sc->axe_udev = dev; sc->axe_product = uaa->product; sc->axe_vendor = uaa->vendor; @@ -813,7 +813,6 @@ axe_attach(struct device *parent, struct timeout_set(&sc->axe_stat_ch, axe_tick, sc); - sc->axe_attached = 1; splx(s); usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->axe_udev, @@ -829,10 +828,6 @@ axe_detach(struct device *self, int flag DPRINTFN(2,("%s: %s: enter\n", sc->axe_dev.dv_xname, __func__)); - /* Detached before attached finished, so just bail out. */ - if (!sc->axe_attached) - return (0); - if (timeout_initialized(&sc->axe_stat_ch)) timeout_del(&sc->axe_stat_ch); @@ -875,8 +870,6 @@ axe_detach(struct device *self, int flag sc->axe_dev.dv_xname); #endif - sc->axe_attached = 0; - if (--sc->axe_refcnt >= 0) { /* Wait for processes to go away. */ usb_detach_wait(&sc->axe_dev); @@ -901,7 +894,7 @@ axe_activate(struct device *self, int ac break; case DVACT_DEACTIVATE: - sc->axe_dying = 1; + usbd_deactivate(sc->axe_udev); break; } return (0); @@ -1009,7 +1002,7 @@ axe_rxeof(usbd_xfer_handle xfer, usbd_pr DPRINTFN(10,("%s: %s: enter\n", sc->axe_dev.dv_xname,__func__)); - if (sc->axe_dying) + if (usbd_is_dying(sc->axe_udev)) return; if (!(ifp->if_flags & IFF_RUNNING)) @@ -1122,7 +1115,7 @@ axe_txeof(usbd_xfer_handle xfer, usbd_pr sc = c->axe_sc; ifp = &sc->arpcom.ac_if; - if (sc->axe_dying) + if (usbd_is_dying(sc->axe_udev)) return; s = splnet(); @@ -1166,7 +1159,7 @@ axe_tick(void *xsc) DPRINTFN(0xff, ("%s: %s: enter\n", sc->axe_dev.dv_xname, __func__)); - if (sc->axe_dying) + if (usbd_is_dying(sc->axe_udev)) return; /* Perform periodic stuff in process context */ @@ -1187,7 +1180,7 @@ axe_tick_task(void *xsc) if (sc == NULL) return; - if (sc->axe_dying) + if (usbd_is_dying(sc->axe_udev)) return; ifp = GET_IFP(sc); Index: if_axereg.h =================================================================== RCS file: /cvs/src/sys/dev/usb/if_axereg.h,v retrieving revision 1.19 diff -u -p -r1.19 if_axereg.h --- if_axereg.h 21 Sep 2010 08:02:49 -0000 1.19 +++ if_axereg.h 24 Nov 2010 19:53:59 -0000 @@ -226,8 +226,6 @@ struct axe_softc { struct timeout axe_stat_ch; int axe_refcnt; - char axe_dying; - char axe_attached; struct usb_task axe_tick_task; struct usb_task axe_stop_task; Index: if_cue.c =================================================================== RCS file: /cvs/src/sys/dev/usb/if_cue.c,v retrieving revision 1.56 diff -u -p -r1.56 if_cue.c --- if_cue.c 27 Oct 2010 17:51:11 -0000 1.56 +++ if_cue.c 24 Nov 2010 19:53:59 -0000 @@ -166,7 +166,7 @@ cue_csr_read_1(struct cue_softc *sc, int usbd_status err; u_int8_t val = 0; - if (sc->cue_dying) + if (usbd_is_dying(sc->cue_udev)) return (0); req.bmRequestType = UT_READ_VENDOR_DEVICE; @@ -196,7 +196,7 @@ cue_csr_read_2(struct cue_softc *sc, int usbd_status err; uWord val; - if (sc->cue_dying) + if (usbd_is_dying(sc->cue_udev)) return (0); req.bmRequestType = UT_READ_VENDOR_DEVICE; @@ -225,7 +225,7 @@ cue_csr_write_1(struct cue_softc *sc, in usb_device_request_t req; usbd_status err; - if (sc->cue_dying) + if (usbd_is_dying(sc->cue_udev)) return (0); DPRINTFN(10,("%s: cue_csr_write_1 reg=0x%x val=0x%x\n", @@ -260,7 +260,7 @@ cue_csr_write_2(struct cue_softc *sc, in uWord val; int s; - if (sc->cue_dying) + if (usbd_is_dying(sc->cue_udev)) return (0); DPRINTFN(10,("%s: cue_csr_write_2 reg=0x%x val=0x%x\n", @@ -405,7 +405,7 @@ cue_reset(struct cue_softc *sc) DPRINTFN(2,("%s: cue_reset\n", sc->cue_dev.dv_xname)); - if (sc->cue_dying) + if (usbd_is_dying(sc->cue_udev)) return; req.bmRequestType = UT_WRITE_VENDOR_DEVICE; @@ -459,6 +459,8 @@ cue_attach(struct device *parent, struct DPRINTFN(5,(" : cue_attach: sc=%p, dev=%p", sc, dev)); + sc->cue_udev = dev; + err = usbd_set_config_no(dev, CUE_CONFIG_NO, 1); if (err) { printf("%s: setting config no failed\n", @@ -466,7 +468,6 @@ cue_attach(struct device *parent, struct return; } - sc->cue_udev = dev; sc->cue_product = uaa->product; sc->cue_vendor = uaa->vendor; @@ -541,7 +542,6 @@ cue_attach(struct device *parent, struct timeout_set(&sc->cue_stat_ch, cue_tick, sc); - sc->cue_attached = 1; splx(s); usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->cue_udev, @@ -557,10 +557,6 @@ cue_detach(struct device *self, int flag DPRINTFN(2,("%s: %s: enter\n", sc->cue_dev.dv_xname, __func__)); - /* Detached before attached finished, so just bail out. */ - if (!sc->cue_attached) - return (0); - if (timeout_initialized(&sc->cue_stat_ch)) timeout_del(&sc->cue_stat_ch); @@ -589,7 +585,6 @@ cue_detach(struct device *self, int flag sc->cue_dev.dv_xname); #endif - sc->cue_attached = 0; splx(s); usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->cue_udev, @@ -610,7 +605,7 @@ cue_activate(struct device *self, int ac break; case DVACT_DEACTIVATE: - sc->cue_dying = 1; + usbd_deactivate(sc->cue_udev); break; } return (0); @@ -727,7 +722,7 @@ cue_rxeof(usbd_xfer_handle xfer, usbd_pr DPRINTFN(10,("%s: %s: enter status=%d\n", sc->cue_dev.dv_xname, __func__, status)); - if (sc->cue_dying) + if (usbd_is_dying(sc->cue_udev)) return; if (!(ifp->if_flags & IFF_RUNNING)) @@ -817,7 +812,7 @@ cue_txeof(usbd_xfer_handle xfer, usbd_pr struct ifnet *ifp = GET_IFP(sc); int s; - if (sc->cue_dying) + if (usbd_is_dying(sc->cue_udev)) return; s = splnet(); @@ -861,7 +856,7 @@ cue_tick(void *xsc) if (sc == NULL) return; - if (sc->cue_dying) + if (usbd_is_dying(sc->cue_udev)) return; DPRINTFN(2,("%s: %s: enter\n", sc->cue_dev.dv_xname, __func__)); @@ -876,7 +871,7 @@ cue_tick_task(void *xsc) struct cue_softc *sc = xsc; struct ifnet *ifp; - if (sc->cue_dying) + if (usbd_is_dying(sc->cue_udev)) return; DPRINTFN(2,("%s: %s: enter\n", sc->cue_dev.dv_xname, __func__)); @@ -941,7 +936,7 @@ cue_start(struct ifnet *ifp) struct cue_softc *sc = ifp->if_softc; struct mbuf *m_head = NULL; - if (sc->cue_dying) + if (usbd_is_dying(sc->cue_udev)) return; DPRINTFN(10,("%s: %s: enter\n", sc->cue_dev.dv_xname,__func__)); @@ -985,7 +980,7 @@ cue_init(void *xsc) int i, s, ctl; u_char *eaddr; - if (sc->cue_dying) + if (usbd_is_dying(sc->cue_udev)) return; DPRINTFN(10,("%s: %s: enter\n", sc->cue_dev.dv_xname,__func__)); @@ -1106,7 +1101,7 @@ cue_ioctl(struct ifnet *ifp, u_long comm struct ifaddr *ifa = (struct ifaddr *)data; int s, error = 0; - if (sc->cue_dying) + if (usbd_is_dying(sc->cue_udev)) return (EIO); s = splnet(); @@ -1171,7 +1166,7 @@ cue_watchdog(struct ifnet *ifp) DPRINTFN(5,("%s: %s: enter\n", sc->cue_dev.dv_xname,__func__)); - if (sc->cue_dying) + if (usbd_is_dying(sc->cue_udev)) return; ifp->if_oerrors++; Index: if_cuereg.h =================================================================== RCS file: /cvs/src/sys/dev/usb/if_cuereg.h,v retrieving revision 1.10 diff -u -p -r1.10 if_cuereg.h --- if_cuereg.h 10 Jun 2007 10:15:35 -0000 1.10 +++ if_cuereg.h 24 Nov 2010 19:53:59 -0000 @@ -183,8 +183,6 @@ struct cue_softc { u_int16_t cue_rxfilt; struct cue_cdata cue_cdata; - char cue_dying; - char cue_attached; u_int cue_rx_errs; struct timeval cue_rx_notice; Index: if_mos.c =================================================================== RCS file: /cvs/src/sys/dev/usb/if_mos.c,v retrieving revision 1.11 diff -u -p -r1.11 if_mos.c --- if_mos.c 27 Oct 2010 17:51:11 -0000 1.11 +++ if_mos.c 24 Nov 2010 19:53:59 -0000 @@ -208,8 +208,8 @@ mos_reg_read_1(struct mos_softc *sc, int usbd_status err; uByte val = 0; - if (sc->mos_dying) - return (0); + if (usbd_is_dying(sc->mos_udev)) + return(0); req.bmRequestType = UT_READ_VENDOR_DEVICE; req.bRequest = MOS_UR_READREG; @@ -236,7 +236,7 @@ mos_reg_read_2(struct mos_softc *sc, int USETW(val,0); - if (sc->mos_dying) + if (usbd_is_dying(sc->mos_udev)) return(0); req.bmRequestType = UT_READ_VENDOR_DEVICE; @@ -264,7 +264,7 @@ mos_reg_write_1(struct mos_softc *sc, in val = aval; - if (sc->mos_dying) + if (usbd_is_dying(sc->mos_udev)) return(0); req.bmRequestType = UT_WRITE_VENDOR_DEVICE; @@ -292,7 +292,7 @@ mos_reg_write_2(struct mos_softc *sc, in USETW(val, aval); - if (sc->mos_dying) + if (usbd_is_dying(sc->mos_udev)) return (0); req.bmRequestType = UT_WRITE_VENDOR_DEVICE; @@ -317,7 +317,7 @@ mos_readmac(struct mos_softc *sc, u_char usb_device_request_t req; usbd_status err; - if (sc->mos_dying) + if (usbd_is_dying(sc->mos_udev)) return(0); req.bmRequestType = UT_READ_VENDOR_DEVICE; @@ -342,7 +342,7 @@ mos_writemac(struct mos_softc *sc, u_cha usb_device_request_t req; usbd_status err; - if (sc->mos_dying) + if (usbd_is_dying(sc->mos_udev)) return(0); req.bmRequestType = UT_WRITE_VENDOR_DEVICE; @@ -367,7 +367,7 @@ mos_write_mcast(struct mos_softc *sc, u_ usb_device_request_t req; usbd_status err; - if (sc->mos_dying) + if (usbd_is_dying(sc->mos_udev)) return(0); req.bmRequestType = UT_WRITE_VENDOR_DEVICE; @@ -393,7 +393,7 @@ mos_miibus_readreg(struct device *dev, i uWord val; int i,res; - if (sc->mos_dying) { + if (usbd_is_dying(sc->mos_udev)) { DPRINTF(("mos: dying\n")); return (0); } @@ -429,7 +429,7 @@ mos_miibus_writereg(struct device *dev, struct mos_softc *sc = (void *)dev; int i; - if (sc->mos_dying) + if (usbd_is_dying(sc->mos_udev)) return; mos_lock_mii(sc); @@ -539,7 +539,7 @@ mos_setmulti(struct mos_softc *sc) u_int8_t rxmode; u_int8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - if (sc->mos_dying) + if (usbd_is_dying(sc->mos_udev)) return; ifp = GET_IFP(sc); @@ -576,7 +576,7 @@ void mos_reset(struct mos_softc *sc) { u_int8_t ctl; - if (sc->mos_dying) + if (usbd_is_dying(sc->mos_udev)) return; ctl = mos_reg_read_1(sc, MOS_CTL); @@ -643,6 +643,7 @@ mos_attach(struct device *parent, struct u_char eaddr[ETHER_ADDR_LEN]; int i,s; + sc->mos_udev = dev; sc->mos_unit = self->dv_unit; err = usbd_set_config_no(dev, MOS_CONFIG_NO, 1); @@ -665,7 +666,6 @@ mos_attach(struct device *parent, struct return; } - sc->mos_udev = dev; sc->mos_flags = mos_lookup(uaa->vendor, uaa->product)->mos_flags; id = usbd_get_interface_descriptor(sc->mos_iface); @@ -752,7 +752,6 @@ mos_attach(struct device *parent, struct timeout_set(&sc->mos_stat_ch, mos_tick, sc); - sc->mos_attached = 1; splx(s); usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->mos_udev, @@ -768,9 +767,6 @@ mos_detach(struct device *self, int flag DPRINTFN(2,("%s: %s: enter\n", sc->mos_dev.dv_xname, __func__)); - if (!sc->mos_attached) - return (0); - if (timeout_initialized(&sc->mos_stat_ch)) timeout_del(&sc->mos_stat_ch); @@ -812,8 +808,6 @@ mos_detach(struct device *self, int flag sc->mos_dev.dv_xname); #endif - sc->mos_attached = 0; - if (--sc->mos_refcnt >= 0) { /* Wait for processes to go away. */ usb_detach_wait(&sc->mos_dev); @@ -839,7 +833,7 @@ mos_activate(struct device *self, int ac break; case DVACT_DEACTIVATE: - sc->mos_dying = 1; + usbd_deactivate(sc->mos_udev); break; } return (0); @@ -947,7 +941,7 @@ mos_rxeof(usbd_xfer_handle xfer, usbd_pr DPRINTFN(10,("%s: %s: enter\n", sc->mos_dev.dv_xname,__func__)); - if (sc->mos_dying) + if (usbd_is_dying(sc->mos_udev)) return; if (!(ifp->if_flags & IFF_RUNNING)) @@ -1049,7 +1043,7 @@ mos_txeof(usbd_xfer_handle xfer, usbd_pr sc = c->mos_sc; ifp = &sc->arpcom.ac_if; - if (sc->mos_dying) + if (usbd_is_dying(sc->mos_udev)) return; s = splnet(); @@ -1093,7 +1087,7 @@ mos_tick(void *xsc) DPRINTFN(0xff, ("%s: %s: enter\n", sc->mos_dev.dv_xname, __func__)); - if (sc->mos_dying) + if (usbd_is_dying(sc->mos_udev)) return; /* Perform periodic stuff in process context */ @@ -1114,7 +1108,7 @@ mos_tick_task(void *xsc) if (sc == NULL) return; - if (sc->mos_dying) + if (usbd_is_dying(sc->mos_udev)) return; ifp = GET_IFP(sc); Index: if_mosreg.h =================================================================== RCS file: /cvs/src/sys/dev/usb/if_mosreg.h,v retrieving revision 1.3 diff -u -p -r1.3 if_mosreg.h --- if_mosreg.h 22 Nov 2008 09:46:12 -0000 1.3 +++ if_mosreg.h 24 Nov 2010 19:53:59 -0000 @@ -183,8 +183,6 @@ struct mos_softc { struct timeout mos_stat_ch; int mos_refcnt; - char mos_dying; - char mos_attached; int mos_link; unsigned char mos_ipgs[2]; Index: if_ral.c =================================================================== RCS file: /cvs/src/sys/dev/usb/if_ral.c,v retrieving revision 1.116 diff -u -p -r1.116 if_ral.c --- if_ral.c 27 Oct 2010 17:51:11 -0000 1.116 +++ if_ral.c 24 Nov 2010 19:53:59 -0000 @@ -2209,11 +2209,14 @@ ural_amrr_update(usbd_xfer_handle xfer, int ural_activate(struct device *self, int act) { + struct ural_softc *sc = (struct ural_softc *)self; + switch (act) { case DVACT_ACTIVATE: break; case DVACT_DEACTIVATE: + usbd_deactivate(sc->sc_udev); break; } Index: if_rum.c =================================================================== RCS file: /cvs/src/sys/dev/usb/if_rum.c,v retrieving revision 1.93 diff -u -p -r1.93 if_rum.c --- if_rum.c 27 Oct 2010 17:51:11 -0000 1.93 +++ if_rum.c 24 Nov 2010 19:54:00 -0000 @@ -644,6 +644,9 @@ rum_next_scan(void *arg) struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = &ic->ic_if; + if (usbd_is_dying(sc->sc_udev)) + return; + if (ic->ic_state == IEEE80211_S_SCAN) ieee80211_next_scan(ifp); } @@ -657,6 +660,9 @@ rum_task(void *arg) struct ieee80211_node *ni; uint32_t tmp; + if (usbd_is_dying(sc->sc_udev)) + return; + ostate = ic->ic_state; switch (sc->sc_state) { @@ -2239,6 +2245,9 @@ rum_amrr_timeout(void *arg) struct rum_softc *sc = arg; usb_device_request_t req; + if (usbd_is_dying(sc->sc_udev)) + return; + /* * Asynchronously read statistic registers (cleared by read). */ @@ -2287,11 +2296,14 @@ rum_amrr_update(usbd_xfer_handle xfer, u int rum_activate(struct device *self, int act) { + struct rum_softc *sc = (struct rum_softc *)self; + switch (act) { case DVACT_ACTIVATE: break; case DVACT_DEACTIVATE: + usbd_deactivate(sc->sc_udev); break; } Index: if_uath.c =================================================================== RCS file: /cvs/src/sys/dev/usb/if_uath.c,v retrieving revision 1.46 diff -u -p -r1.46 if_uath.c --- if_uath.c 27 Oct 2010 17:51:11 -0000 1.46 +++ if_uath.c 24 Nov 2010 19:54:00 -0000 @@ -427,6 +427,7 @@ fail4: uath_free_tx_data_list(sc); fail3: uath_free_rx_cmd_list(sc); fail2: uath_free_tx_cmd_list(sc); fail1: uath_close_pipes(sc); + usbd_deactivate(sc->sc_udev); } int @@ -2130,11 +2131,14 @@ fail1: return error; int uath_activate(struct device *self, int act) { + struct uath_softc *sc = (struct uath_softc *)self; + switch (act) { case DVACT_ACTIVATE: break; case DVACT_DEACTIVATE: + usbd_deactivate(sc->sc_udev); break; } return 0; Index: if_udav.c =================================================================== RCS file: /cvs/src/sys/dev/usb/if_udav.c,v retrieving revision 1.49 diff -u -p -r1.49 if_udav.c --- if_udav.c 27 Oct 2010 17:51:11 -0000 1.49 +++ if_udav.c 24 Nov 2010 19:54:00 -0000 @@ -204,6 +204,8 @@ udav_attach(struct device *parent, struc printf("%s: ", devname); + sc->sc_udev = dev; + /* Move the device into the configured state. */ err = usbd_set_config_no(dev, UDAV_CONFIG_NO, 1); if (err) { @@ -224,7 +226,6 @@ udav_attach(struct device *parent, struc goto bad; } - sc->sc_udev = dev; sc->sc_ctl_iface = iface; sc->sc_flags = udav_lookup(uaa->vendor, uaa->product)->udav_flags; @@ -308,7 +309,7 @@ udav_attach(struct device *parent, struc ether_ifattach(ifp); timeout_set(&sc->sc_stat_ch, udav_tick, sc); - sc->sc_attached = 1; + splx(s); usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, dev, &sc->sc_dev); @@ -316,7 +317,7 @@ udav_attach(struct device *parent, struc return; bad: - sc->sc_dying = 1; + usbd_deactivate(sc->sc_udev); } /* detach */ @@ -329,9 +330,6 @@ udav_detach(struct device *self, int fla DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - /* Detached before attached finished */ - if (!sc->sc_attached) - return (0); if (timeout_initialized(&sc->sc_stat_ch)) timeout_del(&sc->sc_stat_ch); @@ -367,8 +365,6 @@ udav_detach(struct device *self, int fla printf("%s: detach has active intr endpoint.\n", sc->sc_dev.dv_xname); #endif - sc->sc_attached = 0; - splx(s); usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, @@ -391,7 +387,7 @@ udav_mem_read(struct udav_softc *sc, int DPRINTFN(0x200, ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return (0); offset &= 0xffff; @@ -428,7 +424,7 @@ udav_mem_write(struct udav_softc *sc, in DPRINTFN(0x200, ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return (0); offset &= 0xffff; @@ -465,7 +461,7 @@ udav_mem_write1(struct udav_softc *sc, i DPRINTFN(0x200, ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return (0); offset &= 0xffff; @@ -502,7 +498,7 @@ udav_csr_read(struct udav_softc *sc, int DPRINTFN(0x200, ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return (0); offset &= 0xff; @@ -539,7 +535,7 @@ udav_csr_write(struct udav_softc *sc, in DPRINTFN(0x200, ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return (0); offset &= 0xff; @@ -574,9 +570,6 @@ udav_csr_read1(struct udav_softc *sc, in DPRINTFN(0x200, ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) - return (0); - return (udav_csr_read(sc, offset, &val, 1) ? 0 : val); } @@ -593,7 +586,7 @@ udav_csr_write1(struct udav_softc *sc, i DPRINTFN(0x200, ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return (0); offset &= 0xff; @@ -626,9 +619,6 @@ udav_init(struct ifnet *ifp) DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) - return (EIO); - s = splnet(); /* Cancel pending I/O and free all TX/RX buffers */ @@ -700,7 +690,7 @@ udav_reset(struct udav_softc *sc) DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; /* Select PHY */ @@ -740,7 +730,7 @@ udav_activate(struct device *self, int a break; case DVACT_DEACTIVATE: - sc->sc_dying = 1; + usbd_deactivate(sc->sc_udev); break; } return (0); @@ -762,7 +752,7 @@ udav_setmulti(struct udav_softc *sc) DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; ifp = GET_IFP(sc); @@ -811,7 +801,7 @@ udav_openpipes(struct udav_softc *sc) int i; int error = 0; - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return (EIO); sc->sc_refcnt++; @@ -976,7 +966,7 @@ udav_start(struct ifnet *ifp) DPRINTF(("%s: %s: enter, link=%d\n", sc->sc_dev.dv_xname, __func__, sc->sc_link)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; if (!sc->sc_link) @@ -1067,7 +1057,7 @@ udav_txeof(usbd_xfer_handle xfer, usbd_p struct ifnet *ifp = GET_IFP(sc); int s; - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; s = splnet(); @@ -1119,7 +1109,7 @@ udav_rxeof(usbd_xfer_handle xfer, usbd_p DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname,__func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; if (status != USBD_NORMAL_COMPLETION) { @@ -1217,7 +1207,7 @@ udav_ioctl(struct ifnet *ifp, u_long cmd DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return (EIO); s = splnet(); @@ -1256,7 +1246,7 @@ udav_ioctl(struct ifnet *ifp, u_long cmd udav_init(ifp); } else { if (ifp->if_flags & IFF_RUNNING) - udav_stop(ifp, 1); + udav_stop(ifp, 1); } error = 0; break; @@ -1400,7 +1390,7 @@ udav_ifmedia_change(struct ifnet *ifp) DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return (0); sc->sc_link = 0; @@ -1423,7 +1413,7 @@ udav_ifmedia_status(struct ifnet *ifp, s DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; if ((ifp->if_flags & IFF_RUNNING) == 0) { @@ -1448,9 +1438,6 @@ udav_tick(void *xsc) DPRINTFN(0xff, ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) - return; - /* Perform periodic stuff in process context */ usb_add_task(sc->sc_udev, &sc->sc_tick_task); } @@ -1469,7 +1456,7 @@ udav_tick_task(void *xsc) DPRINTFN(0xff, ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; ifp = GET_IFP(sc); @@ -1532,7 +1519,7 @@ udav_miibus_readreg(struct device *dev, DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n", sc->sc_dev.dv_xname, __func__, phy, reg)); - if (sc->sc_dying) { + if (usbd_is_dying(sc->sc_udev)) { #ifdef DIAGNOSTIC printf("%s: %s: dying\n", sc->sc_dev.dv_xname, __func__); @@ -1588,7 +1575,7 @@ udav_miibus_writereg(struct device *dev, DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n", sc->sc_dev.dv_xname, __func__, phy, reg, data)); - if (sc->sc_dying) { + if (usbd_is_dying(sc->sc_udev)) { #ifdef DIAGNOSTIC printf("%s: %s: dying\n", sc->sc_dev.dv_xname, __func__); Index: if_udavreg.h =================================================================== RCS file: /cvs/src/sys/dev/usb/if_udavreg.h,v retrieving revision 1.10 diff -u -p -r1.10 if_udavreg.h --- if_udavreg.h 25 Nov 2007 16:40:03 -0000 1.10 +++ if_udavreg.h 24 Nov 2010 19:54:00 -0000 @@ -185,8 +185,6 @@ struct udav_softc { #define sc_media udav_mii.mii_media struct udav_cdata sc_cdata; - int sc_attached; - int sc_dying; int sc_refcnt; struct usb_task sc_tick_task; Index: if_upgt.c =================================================================== RCS file: /cvs/src/sys/dev/usb/if_upgt.c,v retrieving revision 1.53 diff -u -p -r1.53 if_upgt.c --- if_upgt.c 27 Oct 2010 17:51:11 -0000 1.53 +++ if_upgt.c 24 Nov 2010 19:54:01 -0000 @@ -454,9 +454,6 @@ upgt_attach_hook(void *arg) printf("%s: address %s\n", sc->sc_dev.dv_xname, ether_sprintf(ic->ic_myaddr)); - /* device attached */ - sc->sc_flags |= UPGT_DEVICE_ATTACHED; - return; fail: printf("%s: %s failed!\n", sc->sc_dev.dv_xname, __func__); @@ -515,10 +512,13 @@ upgt_detach(struct device *self, int fla int upgt_activate(struct device *self, int act) { + struct upgt_softc *sc = (struct upgt_softc *)self; + switch (act) { case DVACT_ACTIVATE: break; case DVACT_DEACTIVATE: + usbd_deactivate(sc->sc_udev); break; } @@ -1469,7 +1469,6 @@ upgt_start(struct ifnet *ifp) /* process the TX queue in process context */ ifp->if_timer = 5; ifp->if_flags |= IFF_OACTIVE; - usb_rem_task(sc->sc_udev, &sc->sc_task_tx); usb_add_task(sc->sc_udev, &sc->sc_task_tx); } } Index: if_upgtvar.h =================================================================== RCS file: /cvs/src/sys/dev/usb/if_upgtvar.h,v retrieving revision 1.15 diff -u -p -r1.15 if_upgtvar.h --- if_upgtvar.h 10 Aug 2009 20:02:19 -0000 1.15 +++ if_upgtvar.h 24 Nov 2010 19:54:01 -0000 @@ -421,7 +421,6 @@ struct upgt_softc { unsigned sc_cur_chan; uint8_t sc_cur_rateset[8]; - int sc_flags; uint8_t *sc_fw; size_t sc_fw_size; int sc_fw_type; Index: if_upl.c =================================================================== RCS file: /cvs/src/sys/dev/usb/if_upl.c,v retrieving revision 1.44 diff -u -p -r1.44 if_upl.c --- if_upl.c 24 Sep 2010 08:33:59 -0000 1.44 +++ if_upl.c 24 Nov 2010 19:54:01 -0000 @@ -334,7 +334,8 @@ upl_detach(struct device *self, int flag if (ifp->if_flags & IFF_RUNNING) upl_stop(sc); - if_detach(ifp); + if (ifp->if_softc != NULL) + if_detach(ifp); #ifdef DIAGNOSTIC if (sc->sc_ep[UPL_ENDPT_TX] != NULL || Index: if_url.c =================================================================== RCS file: /cvs/src/sys/dev/usb/if_url.c,v retrieving revision 1.59 diff -u -p -r1.59 if_url.c --- if_url.c 27 Oct 2010 17:51:11 -0000 1.59 +++ if_url.c 24 Nov 2010 19:54:01 -0000 @@ -201,6 +201,8 @@ url_attach(struct device *parent, struct u_char eaddr[ETHER_ADDR_LEN]; int i, s; + sc->sc_udev = dev; + /* Move the device into the configured state. */ err = usbd_set_config_no(dev, URL_CONFIG_NO, 1); if (err) { @@ -222,7 +224,6 @@ url_attach(struct device *parent, struct goto bad; } - sc->sc_udev = dev; sc->sc_ctl_iface = iface; sc->sc_flags = url_lookup(uaa->vendor, uaa->product)->url_flags; @@ -314,7 +315,7 @@ url_attach(struct device *parent, struct ether_ifattach(ifp); timeout_set(&sc->sc_stat_ch, url_tick, sc); - sc->sc_attached = 1; + splx(s); usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, dev, &sc->sc_dev); @@ -322,7 +323,7 @@ url_attach(struct device *parent, struct return; bad: - sc->sc_dying = 1; + usbd_deactivate(sc->sc_udev); } /* detach */ @@ -335,10 +336,6 @@ url_detach(struct device *self, int flag DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - /* Detached before attached finished */ - if (!sc->sc_attached) - return (0); - if (timeout_initialized(&sc->sc_stat_ch)) timeout_del(&sc->sc_stat_ch); @@ -375,8 +372,6 @@ url_detach(struct device *self, int flag sc->sc_dev.dv_xname); #endif - sc->sc_attached = 0; - splx(s); usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, @@ -398,7 +393,7 @@ url_mem(struct url_softc *sc, int cmd, i DPRINTFN(0x200, ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return (0); if (cmd == URL_CMD_READMEM) @@ -433,9 +428,6 @@ url_csr_read_1(struct url_softc *sc, int DPRINTFN(0x100, ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) - return (0); - return (url_mem(sc, URL_CMD_READMEM, reg, &val, 1) ? 0 : val); } @@ -448,9 +440,6 @@ url_csr_read_2(struct url_softc *sc, int DPRINTFN(0x100, ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) - return (0); - USETW(val, 0); return (url_mem(sc, URL_CMD_READMEM, reg, &val, 2) ? 0 : UGETW(val)); } @@ -464,9 +453,6 @@ url_csr_write_1(struct url_softc *sc, in DPRINTFN(0x100, ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) - return (0); - return (url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 1) ? -1 : 0); } @@ -481,9 +467,6 @@ url_csr_write_2(struct url_softc *sc, in USETW(val, aval); - if (sc->sc_dying) - return (0); - return (url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 2) ? -1 : 0); } @@ -498,9 +481,6 @@ url_csr_write_4(struct url_softc *sc, in USETDW(val, aval); - if (sc->sc_dying) - return (0); - return (url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 4) ? -1 : 0); } @@ -514,9 +494,6 @@ url_init(struct ifnet *ifp) DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) - return (EIO); - s = splnet(); /* Cancel pending I/O and free all TX/RX buffers */ @@ -592,7 +569,7 @@ url_reset(struct url_softc *sc) DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; URL_SETBIT(sc, URL_CR, URL_CR_SOFT_RST); @@ -619,7 +596,7 @@ url_activate(struct device *self, int ac break; case DVACT_DEACTIVATE: - sc->sc_dying = 1; + usbd_deactivate(sc->sc_udev); break; } @@ -641,7 +618,7 @@ url_setmulti(struct url_softc *sc) DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; ifp = GET_IFP(sc); @@ -698,7 +675,7 @@ url_openpipes(struct url_softc *sc) int i; int error = 0; - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return (EIO); sc->sc_refcnt++; @@ -863,7 +840,7 @@ url_start(struct ifnet *ifp) DPRINTF(("%s: %s: enter, link=%d\n", sc->sc_dev.dv_xname, __func__, sc->sc_link)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; if (!sc->sc_link) @@ -947,7 +924,7 @@ url_txeof(usbd_xfer_handle xfer, usbd_pr struct ifnet *ifp = GET_IFP(sc); int s; - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; s = splnet(); @@ -999,7 +976,7 @@ url_rxeof(usbd_xfer_handle xfer, usbd_pr DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname,__func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; if (status != USBD_NORMAL_COMPLETION) { @@ -1101,7 +1078,7 @@ url_ioctl(struct ifnet *ifp, u_long cmd, DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return (EIO); s = splnet(); @@ -1284,7 +1261,7 @@ url_ifmedia_change(struct ifnet *ifp) DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return (0); sc->sc_link = 0; @@ -1307,7 +1284,7 @@ url_ifmedia_status(struct ifnet *ifp, st DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; if ((ifp->if_flags & IFF_RUNNING) == 0) { @@ -1332,7 +1309,7 @@ url_tick(void *xsc) DPRINTFN(0xff, ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; /* Perform periodic stuff in process context */ @@ -1353,7 +1330,7 @@ url_tick_task(void *xsc) DPRINTFN(0xff, ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; ifp = GET_IFP(sc); @@ -1415,7 +1392,7 @@ url_int_miibus_readreg(struct device *de DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n", sc->sc_dev.dv_xname, __func__, phy, reg)); - if (sc->sc_dying) { + if (usbd_is_dying(sc->sc_udev)) { #ifdef DIAGNOSTIC printf("%s: %s: dying\n", sc->sc_dev.dv_xname, __func__); @@ -1487,7 +1464,7 @@ url_int_miibus_writereg(struct device *d DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n", sc->sc_dev.dv_xname, __func__, phy, reg, data)); - if (sc->sc_dying) { + if (usbd_is_dying(sc->sc_udev)) { #ifdef DIAGNOSTIC printf("%s: %s: dying\n", sc->sc_dev.dv_xname, __func__); @@ -1569,7 +1546,7 @@ url_ext_miibus_redreg(struct device *dev DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x\n", sc->sc_dev.dv_xname, __func__, phy, reg)); - if (sc->sc_dying) { + if (usbd_is_dying(sc->sc_udev)) { #ifdef DIAGNOSTIC printf("%s: %s: dying\n", sc->sc_dev.dv_xname, __func__); @@ -1612,7 +1589,7 @@ url_ext_miibus_writereg(struct device *d DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n", sc->sc_dev.dv_xname, __func__, phy, reg, data)); - if (sc->sc_dying) { + if (usbd_is_dying(sc->sc_udev)) { #ifdef DIAGNOSTIC printf("%s: %s: dying\n", sc->sc_dev.dv_xname, __func__); Index: if_urlreg.h =================================================================== RCS file: /cvs/src/sys/dev/usb/if_urlreg.h,v retrieving revision 1.12 diff -u -p -r1.12 if_urlreg.h --- if_urlreg.h 25 Nov 2007 16:40:03 -0000 1.12 +++ if_urlreg.h 24 Nov 2010 19:54:01 -0000 @@ -175,8 +175,6 @@ struct url_softc { #define sc_media url_mii.mii_media struct url_cdata sc_cdata; - int sc_attached; - int sc_dying; int sc_refcnt; struct usb_task sc_tick_task; Index: if_urtw.c =================================================================== RCS file: /cvs/src/sys/dev/usb/if_urtw.c,v retrieving revision 1.34 diff -u -p -r1.34 if_urtw.c --- if_urtw.c 27 Oct 2010 17:51:11 -0000 1.34 +++ if_urtw.c 24 Nov 2010 19:54:02 -0000 @@ -803,10 +803,13 @@ urtw_detach(struct device *self, int fla int urtw_activate(struct device *self, int act) { + struct urtw_softc *sc = (struct urtw_softc *)self; + switch (act) { case DVACT_ACTIVATE: break; case DVACT_DEACTIVATE: + usbd_deactivate(sc->sc_udev); break; } Index: if_zyd.c =================================================================== RCS file: /cvs/src/sys/dev/usb/if_zyd.c,v retrieving revision 1.85 diff -u -p -r1.85 if_zyd.c --- if_zyd.c 27 Oct 2010 17:51:11 -0000 1.85 +++ if_zyd.c 24 Nov 2010 19:54:02 -0000 @@ -2588,11 +2588,14 @@ zyd_newassoc(struct ieee80211com *ic, st int zyd_activate(struct device *self, int act) { + struct zyd_softc *sc = (struct zyd_softc *)self; + switch (act) { case DVACT_ACTIVATE: break; case DVACT_DEACTIVATE: + usbd_deactivate(sc->sc_udev); break; } return 0; Index: udcf.c =================================================================== RCS file: /cvs/src/sys/dev/usb/udcf.c,v retrieving revision 1.50 diff -u -p -r1.50 udcf.c --- udcf.c 23 Oct 2010 16:14:07 -0000 1.50 +++ udcf.c 24 Nov 2010 19:54:02 -0000 @@ -68,7 +68,6 @@ struct udcf_softc { struct device sc_dev; /* base device */ usbd_device_handle sc_udev; /* USB device */ usbd_interface_handle sc_iface; /* data interface */ - u_char sc_dying; /* disconnecting */ struct timeout sc_to; struct usb_task sc_task; @@ -326,7 +325,7 @@ udcf_attach(struct device *parent, struc fishy: DPRINTF(("udcf_attach failed\n")); - sc->sc_dying = 1; + usbd_deactivate(sc->sc_udev); } int @@ -519,7 +518,7 @@ udcf_probe(void *xsc) struct timespec now; int data; - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; data = sc->sc_signal(sc); @@ -594,7 +593,7 @@ udcf_bv_probe(void *xsc) struct udcf_softc *sc = xsc; int data; - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; data = sc->sc_signal(sc); @@ -751,7 +750,7 @@ udcf_sl_probe(void *xsc) { struct udcf_softc *sc = xsc; - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; DPRINTF(("no signal\n")); @@ -766,7 +765,7 @@ udcf_it_intr(void *xsc) { struct udcf_softc *sc = xsc; - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; if (sc->sc_sensor.status == SENSOR_S_OK) { @@ -789,7 +788,7 @@ udcf_ct_probe(void *xsc) struct udcf_softc *sc = xsc; int data; - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; data = sc->sc_signal(sc); @@ -812,7 +811,7 @@ udcf_activate(struct device *self, int a case DVACT_ACTIVATE: break; case DVACT_DEACTIVATE: - sc->sc_dying = 1; + usbd_deactivate(sc->sc_udev); break; } return 0; Index: ueagle.c =================================================================== RCS file: /cvs/src/sys/dev/usb/ueagle.c,v retrieving revision 1.29 diff -u -p -r1.29 ueagle.c --- ueagle.c 23 Oct 2010 15:42:09 -0000 1.29 +++ ueagle.c 24 Nov 2010 19:54:02 -0000 @@ -256,7 +256,8 @@ ueagle_detach(struct device *self, int f sc->sc_dev.dv_xname)); } - if_detach(ifp); + if (ifp->if_softc != NULL) + if_detach(ifp); usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, &sc->sc_dev); @@ -318,6 +319,9 @@ ueagle_loadpage(void *xsc) uint8_t *p; int i; + if (usbd_is_dying(sc->sc_udev)) + return; + p = sc->dsp; pagecount = *p++; @@ -576,6 +580,8 @@ ueagle_stat_thread(void *arg) break; usbd_delay_ms(sc->sc_udev, 5000); + if (usbd_is_dying(sc->sc_udev)) + break; } wakeup(sc->stat_thread); @@ -1467,7 +1473,7 @@ ueagle_activate(struct device *self, int break; case DVACT_DEACTIVATE: - sc->gone = 1; + usbd_deactivate(sc->sc_udev); break; } Index: ueaglevar.h =================================================================== RCS file: /cvs/src/sys/dev/usb/ueaglevar.h,v retrieving revision 1.2 diff -u -p -r1.2 ueaglevar.h --- ueaglevar.h 6 Jun 2007 19:25:49 -0000 1.2 +++ ueaglevar.h 24 Nov 2010 19:54:02 -0000 @@ -184,8 +184,6 @@ struct ueagle_softc { uint16_t isize; char ibuf[32]; - int gone; - uint16_t index; uint32_t data; }; Index: uhub.c =================================================================== RCS file: /cvs/src/sys/dev/usb/uhub.c,v retrieving revision 1.55 diff -u -p -r1.55 uhub.c --- uhub.c 23 Sep 2010 05:44:15 -0000 1.55 +++ uhub.c 24 Nov 2010 19:54:03 -0000 @@ -353,8 +353,8 @@ 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__)); + if (usbd_is_dying(dev)) { + DPRINTF(("%s: dying\n", __func__)); return (USBD_IOERROR); } Index: ukbdmap.c =================================================================== RCS file: /cvs/src/sys/dev/usb/ukbdmap.c,v retrieving revision 1.37 diff -u -p -r1.37 ukbdmap.c --- ukbdmap.c 28 Aug 2010 16:40:32 -0000 1.37 +++ ukbdmap.c 24 Nov 2010 19:54:03 -0000 @@ -1,4 +1,4 @@ -/* $OpenBSD: ukbdmap.c,v 1.37 2010/08/28 16:40:32 miod Exp $ */ +/* $OpenBSD$ */ /* * THIS FILE IS AUTOMAGICALLY GENERATED. DO NOT EDIT. Index: umbg.c =================================================================== RCS file: /cvs/src/sys/dev/usb/umbg.c,v retrieving revision 1.14 diff -u -p -r1.14 umbg.c --- umbg.c 23 Oct 2010 16:14:07 -0000 1.14 +++ umbg.c 24 Nov 2010 19:54:03 -0000 @@ -53,7 +53,6 @@ struct umbg_softc { struct device sc_dev; /* base device */ usbd_device_handle sc_udev; /* USB device */ usbd_interface_handle sc_iface; /* data interface */ - u_char sc_dying; /* disconnecting */ int sc_bulkin_no; usbd_pipe_handle sc_bulkin_pipe; @@ -287,7 +286,7 @@ umbg_attach(struct device *parent, struc return; fishy: - sc->sc_dying = 1; + usbd_deactivate(sc->sc_udev); } int @@ -350,7 +349,7 @@ umbg_task(void *arg) int64_t tlocal, trecv; int signal; - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; if (umbg_read(sc, MBG_GET_TIME_HR, (char *)&tframe, sizeof(tframe), @@ -438,7 +437,7 @@ umbg_it_intr(void *xsc) { struct umbg_softc *sc = xsc; - if (sc->sc_dying) + if (usbd_is_dying(sc->sc_udev)) return; if (sc->sc_timedelta.status == SENSOR_S_OK) { @@ -461,7 +460,7 @@ umbg_activate(struct device *self, int a case DVACT_ACTIVATE: break; case DVACT_DEACTIVATE: - sc->sc_dying = 1; + usbd_deactivate(sc->sc_udev); break; } return 0; Index: usb.c =================================================================== RCS file: /cvs/src/sys/dev/usb/usb.c,v retrieving revision 1.69 diff -u -p -r1.69 usb.c --- usb.c 23 Oct 2010 15:42:09 -0000 1.69 +++ usb.c 24 Nov 2010 19:54:03 -0000 @@ -300,7 +300,7 @@ usb_add_task(usbd_device_handle dev, str task->onqueue, task->type)); /* Don't add task if the device's root hub is dying. */ - if (dev->bus->dying) + if (usbd_is_dying(dev)) return; s = splusb(); @@ -429,7 +429,7 @@ usb_task_thread(void *arg) } task->onqueue = 0; /* Don't execute the task if the root hub is gone. */ - if (task->dev->bus->dying) + if (usbd_is_dying(task->dev)) continue; task->running = 1; splx(s); @@ -466,7 +466,7 @@ usb_abort_task_thread(void *arg) } task->onqueue = 0; /* Don't execute the task if the root hub is gone. */ - if (task->dev->bus->dying) + if (usbd_is_dying(task->dev)) continue; task->running = 1; splx(s); @@ -945,13 +945,15 @@ usb_detach(struct device *self, int flag sc->sc_bus->dying = 1; - /* Make all devices disconnect. */ - if (sc->sc_port.device != NULL) - usb_disconnect_port(&sc->sc_port, self); + if (sc->sc_bus->root_hub != NULL) { + /* Make all devices disconnect. */ + if (sc->sc_port.device != NULL) + usb_disconnect_port(&sc->sc_port, self); - usb_rem_wait_task(sc->sc_bus->root_hub, &sc->sc_explore_task); + usb_rem_wait_task(sc->sc_bus->root_hub, &sc->sc_explore_task); - usbd_finish(); + usbd_finish(); + } if (sc->sc_bus->soft != NULL) { softintr_disestablish(sc->sc_bus->soft); Index: usb_subr.c =================================================================== RCS file: /cvs/src/sys/dev/usb/usb_subr.c,v retrieving revision 1.74 diff -u -p -r1.74 usb_subr.c --- usb_subr.c 24 Sep 2010 00:12:36 -0000 1.74 +++ usb_subr.c 24 Nov 2010 19:54:03 -0000 @@ -1461,6 +1461,10 @@ usb_disconnect_port(struct usbd_port *up parent->dv_xname)); if (up->portno != 0) DPRINTF((" port %d", up->portno)); + DPRINTF((" (addr %d) deactivated\n", dev->address)); + config_deactivate(dev->subdevs[i]); + } + for (i = 0; dev->subdevs[i]; i++) { DPRINTF((" (addr %d) disconnected\n", dev->address)); config_detach(dev->subdevs[i], DETACH_FORCE); dev->subdevs[i] = 0; Index: usbdi.c =================================================================== RCS file: /cvs/src/sys/dev/usb/usbdi.c,v retrieving revision 1.40 diff -u -p -r1.40 usbdi.c --- usbdi.c 23 Sep 2010 05:44:15 -0000 1.40 +++ usbdi.c 24 Nov 2010 19:54:03 -0000 @@ -85,6 +85,18 @@ usbd_finish(void) usb_end_tasks(); } +int +usbd_is_dying(usbd_device_handle dev) +{ + return (dev->dying || dev->bus->dying); +} + +void +usbd_deactivate(usbd_device_handle dev) +{ + dev->dying = 1; +} + static __inline int usbd_xfer_isread(usbd_xfer_handle xfer) { @@ -269,6 +281,9 @@ usbd_transfer(usbd_xfer_handle xfer) u_int size; int s; + if (usbd_is_dying(pipe->device)) + return (USBD_IOERROR); + DPRINTFN(5,("usbd_transfer: xfer=%p, flags=%d, pipe=%p, running=%d\n", xfer, xfer->flags, pipe, pipe->running)); #ifdef USB_DEBUG @@ -923,7 +938,7 @@ usbd_do_request_flags_pipe(usbd_device_h #endif /* If the bus is gone, don't go any further. */ - if (dev->bus->dying) + if (usbd_is_dying(dev)) return (USBD_IOERROR); xfer = usbd_alloc_xfer(dev); Index: usbdi.h =================================================================== RCS file: /cvs/src/sys/dev/usb/usbdi.h,v retrieving revision 1.35 diff -u -p -r1.35 usbdi.h --- usbdi.h 23 Oct 2010 15:42:09 -0000 1.35 +++ usbdi.h 24 Nov 2010 19:54:03 -0000 @@ -165,6 +165,9 @@ usbd_status usbd_reload_device_desc(usbd int usbd_ratecheck(struct timeval *last); +int usbd_is_dying(usbd_device_handle); +void usbd_deactivate(usbd_device_handle); + /* An iterator for descriptors. */ typedef struct { const uByte *cur; Index: usbdivar.h =================================================================== RCS file: /cvs/src/sys/dev/usb/usbdivar.h,v retrieving revision 1.39 diff -u -p -r1.39 usbdivar.h --- usbdivar.h 23 Sep 2010 05:44:16 -0000 1.39 +++ usbdivar.h 24 Nov 2010 19:54:03 -0000 @@ -125,6 +125,7 @@ struct usbd_bus { struct usbd_device { struct usbd_bus *bus; /* our controller */ struct usbd_pipe *default_pipe; /* pipe 0 */ + u_int8_t dying; /* removed */ u_int8_t address; /* device address */ u_int8_t config; /* current configuration # */ u_int8_t depth; /* distance from root hub */