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 */

Reply via email to