if a usb device is plugged in, then unplugged before the driver fully
attaches, the driver detach routine might try to release resources that
haven't been allocated.  timeout(9)s are one such resource.  the
following diff checks if a timeout exists with timeout_initialized()
before doing timeout_del().  I am doing this more or less unconditionally
for purposes of consistency.  it's clear to me that not all usb device
driver authors are aware of this issue.

ok?

-- 
jake...@sdf.lonestar.org
SDF Public Access UNIX System - http://sdf.lonestar.org

Index: hidkbd.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/hidkbd.c,v
retrieving revision 1.3
diff -u -p -r1.3 hidkbd.c
--- hidkbd.c    1 Aug 2010 21:37:08 -0000       1.3
+++ hidkbd.c    23 Oct 2010 15:48:55 -0000
@@ -224,7 +224,8 @@ hidkbd_detach(struct hidkbd *kbd, int fl
        DPRINTF(("hidkbd_detach: sc=%p flags=%d\n", kbd->sc_device, flags));
 
 #ifdef WSDISPLAY_COMPAT_RAWKBD
-       timeout_del(&kbd->sc_rawrepeat_ch);
+       if (timeout_initialized(&kbd->sc_rawrepeat_ch))
+               timeout_del(&kbd->sc_rawrepeat_ch);
 #endif
 
        if (kbd->sc_console_keyboard) {
Index: if_aue.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_aue.c,v
retrieving revision 1.80
diff -u -p -r1.80 if_aue.c
--- if_aue.c    23 Oct 2010 15:42:09 -0000      1.80
+++ if_aue.c    23 Oct 2010 15:48:56 -0000
@@ -855,7 +855,8 @@ aue_detach(struct device *self, int flag
        if (!sc->aue_attached) 
                return (0);
 
-       timeout_del(&sc->aue_stat_ch);
+       if (timeout_initialized(&sc->aue_stat_ch))
+               timeout_del(&sc->aue_stat_ch);
 
        /*
         * Remove any pending tasks.  They cannot be executing because they run
Index: if_axe.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_axe.c,v
retrieving revision 1.100
diff -u -p -r1.100 if_axe.c
--- if_axe.c    23 Oct 2010 15:42:09 -0000      1.100
+++ if_axe.c    23 Oct 2010 15:48:56 -0000
@@ -835,7 +835,8 @@ axe_detach(struct device *self, int flag
        if (!sc->axe_attached)
                return (0);
 
-       timeout_del(&sc->axe_stat_ch);
+       if (timeout_initialized(&sc->axe_stat_ch))
+               timeout_del(&sc->axe_stat_ch);
 
        if (sc->axe_ep[AXE_ENDPT_TX] != NULL)
                usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_TX]);
Index: if_cue.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_cue.c,v
retrieving revision 1.54
diff -u -p -r1.54 if_cue.c
--- if_cue.c    23 Oct 2010 15:42:09 -0000      1.54
+++ if_cue.c    23 Oct 2010 15:48:57 -0000
@@ -561,7 +561,8 @@ cue_detach(struct device *self, int flag
        if (!sc->cue_attached)
                return (0);
 
-       timeout_del(&sc->cue_stat_ch);
+       if (timeout_initialized(&sc->cue_stat_ch))
+               timeout_del(&sc->cue_stat_ch);
 
        /*
         * Remove any pending task.  It cannot be executing because it run
Index: if_mos.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_mos.c,v
retrieving revision 1.9
diff -u -p -r1.9 if_mos.c
--- if_mos.c    23 Oct 2010 15:42:09 -0000      1.9
+++ if_mos.c    23 Oct 2010 15:48:57 -0000
@@ -771,7 +771,8 @@ mos_detach(struct device *self, int flag
        if (!sc->mos_attached)
                return (0);
 
-       timeout_del(&sc->mos_stat_ch);
+       if (timeout_initialized(&sc->mos_stat_ch))
+               timeout_del(&sc->mos_stat_ch);
 
        if (sc->mos_ep[MOS_ENDPT_TX] != NULL)
                usbd_abort_pipe(sc->mos_ep[MOS_ENDPT_TX]);
Index: if_otus.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_otus.c,v
retrieving revision 1.19
diff -u -p -r1.19 if_otus.c
--- if_otus.c   23 Oct 2010 15:42:09 -0000      1.19
+++ if_otus.c   23 Oct 2010 15:48:58 -0000
@@ -250,8 +250,10 @@ otus_detach(struct device *self, int fla
        while (sc->cmdq.queued > 0)
                tsleep(&sc->cmdq, 0, "cmdq", 0);
 
-       timeout_del(&sc->scan_to);
-       timeout_del(&sc->calib_to);
+       if (timeout_initialized(&sc->scan_to))
+               timeout_del(&sc->scan_to);
+       if (timeout_initialized(&sc->calib_to))
+               timeout_del(&sc->calib_to);
 
        if (ifp->if_flags != 0) {       /* if_attach() has been called. */
                ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
Index: if_ral.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_ral.c,v
retrieving revision 1.114
diff -u -p -r1.114 if_ral.c
--- if_ral.c    23 Oct 2010 15:42:09 -0000      1.114
+++ if_ral.c    23 Oct 2010 15:48:58 -0000
@@ -367,8 +367,10 @@ ural_detach(struct device *self, int fla
        if_detach(ifp);
 
        usb_rem_task(sc->sc_udev, &sc->sc_task);
-       timeout_del(&sc->scan_to);
-       timeout_del(&sc->amrr_to);
+       if (timeout_initialized(&sc->scan_to))
+               timeout_del(&sc->scan_to);
+       if (timeout_initialized(&sc->amrr_to))
+               timeout_del(&sc->amrr_to);
 
        if (sc->amrr_xfer != NULL) {
                usbd_free_xfer(sc->amrr_xfer);
Index: if_rum.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_rum.c,v
retrieving revision 1.91
diff -u -p -r1.91 if_rum.c
--- if_rum.c    23 Oct 2010 15:42:09 -0000      1.91
+++ if_rum.c    23 Oct 2010 15:48:59 -0000
@@ -464,8 +464,10 @@ rum_detach(struct device *self, int flag
        if_detach(ifp);
 
        usb_rem_task(sc->sc_udev, &sc->sc_task);
-       timeout_del(&sc->scan_to);
-       timeout_del(&sc->amrr_to);
+       if (timeout_initialized(&sc->scan_to))
+               timeout_del(&sc->scan_to);
+       if (timeout_initialized(&sc->amrr_to))
+               timeout_del(&sc->amrr_to);
 
        if (sc->amrr_xfer != NULL) {
                usbd_free_xfer(sc->amrr_xfer);
Index: if_run.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_run.c,v
retrieving revision 1.73
diff -u -p -r1.73 if_run.c
--- if_run.c    23 Oct 2010 15:42:09 -0000      1.73
+++ if_run.c    23 Oct 2010 15:49:00 -0000
@@ -595,8 +595,10 @@ run_detach(struct device *self, int flag
        while (sc->cmdq.queued > 0)
                tsleep(&sc->cmdq, 0, "cmdq", 0);
 
-       timeout_del(&sc->scan_to);
-       timeout_del(&sc->calib_to);
+       if (timeout_initialized(&sc->scan_to))
+               timeout_del(&sc->scan_to);
+       if (timeout_initialized(&sc->calib_to))
+               timeout_del(&sc->calib_to);
 
        if (ifp->if_flags != 0) {       /* if_attach() has been called */
                ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
Index: if_uath.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_uath.c,v
retrieving revision 1.44
diff -u -p -r1.44 if_uath.c
--- if_uath.c   23 Oct 2010 15:42:09 -0000      1.44
+++ if_uath.c   23 Oct 2010 15:49:00 -0000
@@ -447,8 +447,10 @@ uath_detach(struct device *self, int fla
        /* post-firmware device */
 
        usb_rem_task(sc->sc_udev, &sc->sc_task);
-       timeout_del(&sc->scan_to);
-       timeout_del(&sc->stat_to);
+       if (timeout_initialized(&sc->scan_to))
+               timeout_del(&sc->scan_to);
+       if (timeout_initialized(&sc->stat_to))
+               timeout_del(&sc->stat_to);
 
        /* abort and free xfers */
        uath_free_tx_data_list(sc);
Index: if_udav.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_udav.c,v
retrieving revision 1.47
diff -u -p -r1.47 if_udav.c
--- if_udav.c   23 Oct 2010 15:42:09 -0000      1.47
+++ if_udav.c   23 Oct 2010 15:49:01 -0000
@@ -333,7 +333,8 @@ udav_detach(struct device *self, int fla
        if (!sc->sc_attached)
                return (0);
 
-       timeout_del(&sc->sc_stat_ch);
+       if (timeout_initialized(&sc->sc_stat_ch))
+               timeout_del(&sc->sc_stat_ch);
 
        /* Remove any pending tasks */
        usb_rem_task(sc->sc_udev, &sc->sc_tick_task);
Index: if_upgt.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_upgt.c,v
retrieving revision 1.51
diff -u -p -r1.51 if_upgt.c
--- if_upgt.c   23 Oct 2010 15:42:09 -0000      1.51
+++ if_upgt.c   23 Oct 2010 15:49:02 -0000
@@ -486,8 +486,10 @@ upgt_detach(struct device *self, int fla
        /* remove tasks and timeouts */
        usb_rem_task(sc->sc_udev, &sc->sc_task_newstate);
        usb_rem_task(sc->sc_udev, &sc->sc_task_tx);
-       timeout_del(&sc->scan_to);
-       timeout_del(&sc->led_to);
+       if (timeout_initialized(&sc->scan_to))
+               timeout_del(&sc->scan_to);
+       if (timeout_initialized(&sc->led_to))
+               timeout_del(&sc->led_to);
 
        /* free xfers */
        upgt_free_tx(sc);
Index: if_url.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_url.c,v
retrieving revision 1.57
diff -u -p -r1.57 if_url.c
--- if_url.c    23 Oct 2010 15:42:09 -0000      1.57
+++ if_url.c    23 Oct 2010 15:49:02 -0000
@@ -339,7 +339,8 @@ url_detach(struct device *self, int flag
        if (!sc->sc_attached)
                return (0);
 
-       timeout_del(&sc->sc_stat_ch);
+       if (timeout_initialized(&sc->sc_stat_ch))
+               timeout_del(&sc->sc_stat_ch);
 
        /* Remove any pending tasks */
        usb_rem_task(sc->sc_udev, &sc->sc_tick_task);
Index: if_urtw.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_urtw.c,v
retrieving revision 1.32
diff -u -p -r1.32 if_urtw.c
--- if_urtw.c   23 Oct 2010 15:42:09 -0000      1.32
+++ if_urtw.c   23 Oct 2010 15:49:03 -0000
@@ -780,8 +780,10 @@ urtw_detach(struct device *self, int fla
 
        usb_rem_task(sc->sc_udev, &sc->sc_task);
        usb_rem_task(sc->sc_udev, &sc->sc_ledtask);
-       timeout_del(&sc->scan_to);
-       timeout_del(&sc->sc_led_ch);
+       if (timeout_initialized(&sc->scan_to))
+               timeout_del(&sc->scan_to);
+       if (timeout_initialized(&sc->sc_led_ch))
+               timeout_del(&sc->sc_led_ch);
 
        /* abort and free xfers */
        urtw_free_tx_data_list(sc);
Index: if_zyd.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_zyd.c,v
retrieving revision 1.83
diff -u -p -r1.83 if_zyd.c
--- if_zyd.c    23 Oct 2010 15:42:09 -0000      1.83
+++ if_zyd.c    23 Oct 2010 15:49:04 -0000
@@ -443,8 +443,10 @@ zyd_detach(struct device *self, int flag
        s = splusb();
 
        usb_rem_task(sc->sc_udev, &sc->sc_task);
-       timeout_del(&sc->scan_to);
-       timeout_del(&sc->amrr_to);
+       if (timeout_initialized(&sc->scan_to))
+               timeout_del(&sc->scan_to);
+       if (timeout_initialized(&sc->amrr_to))
+               timeout_del(&sc->amrr_to);
 
        zyd_close_pipes(sc);
 
Index: udcf.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/udcf.c,v
retrieving revision 1.49
diff -u -p -r1.49 udcf.c
--- udcf.c      23 Oct 2010 15:42:09 -0000      1.49
+++ udcf.c      23 Oct 2010 15:49:04 -0000
@@ -334,13 +334,20 @@ udcf_detach(struct device *self, int fla
 {
        struct udcf_softc       *sc = (struct udcf_softc *)self;
 
-       timeout_del(&sc->sc_to);
-       timeout_del(&sc->sc_bv_to);
-       timeout_del(&sc->sc_mg_to);
-       timeout_del(&sc->sc_sl_to);
-       timeout_del(&sc->sc_it_to);
-       if (sc->sc_detect_ct)
-               timeout_del(&sc->sc_ct_to);
+       if (timeout_initialized(&sc->sc_to))
+               timeout_del(&sc->sc_to);
+       if (timeout_initialized(&sc->sc_bv_to))
+               timeout_del(&sc->sc_bv_to);
+       if (timeout_initialized(&sc->sc_mg_to))
+               timeout_del(&sc->sc_mg_to);
+       if (timeout_initialized(&sc->sc_sl_to))
+               timeout_del(&sc->sc_sl_to);
+       if (timeout_initialized(&sc->sc_it_to))
+               timeout_del(&sc->sc_it_to);
+       if (sc->sc_detect_ct) {
+               if (timeout_initialized(&sc->sc_ct_to))
+                       timeout_del(&sc->sc_ct_to);
+       }
 
        /* Unregister the clock with the kernel */
        sensordev_deinstall(&sc->sc_sensordev);
Index: umbg.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/umbg.c,v
retrieving revision 1.13
diff -u -p -r1.13 umbg.c
--- umbg.c      23 Oct 2010 15:42:09 -0000      1.13
+++ umbg.c      23 Oct 2010 15:49:04 -0000
@@ -296,8 +296,10 @@ umbg_detach(struct device *self, int fla
        struct umbg_softc *sc = (struct umbg_softc *)self;
        usbd_status err;
 
-       timeout_del(&sc->sc_to);
-       timeout_del(&sc->sc_it_to);
+       if (timeout_initialized(&sc->sc_to))
+               timeout_del(&sc->sc_to);
+       if (timeout_initialized(&sc->sc_it_to))
+               timeout_del(&sc->sc_it_to);
 
        usb_rem_task(sc->sc_udev, &sc->sc_task);

Reply via email to