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);