Actively manage cam rescan timeouts in the usb subsystem. This does not
authorMatthew Dillon <dillon@dragonflybsd.org>
Sat, 14 Feb 2004 19:56:28 +0000 (19:56 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Sat, 14 Feb 2004 19:56:28 +0000 (19:56 +0000)
fix any known issues but it should make things a bit more robust.

sys/dev/usbmisc/umass/umass.c

index 78ec944..6543cb9 100644 (file)
@@ -26,7 +26,7 @@
  *
  * $NetBSD: umass.c,v 1.28 2000/04/02 23:46:53 augustss Exp $
  * $FreeBSD: src/sys/dev/usb/umass.c,v 1.96 2003/12/19 12:19:11 sanpei Exp $
- * $DragonFly: src/sys/dev/usbmisc/umass/umass.c,v 1.7 2004/02/11 15:13:06 joerg Exp $
+ * $DragonFly: src/sys/dev/usbmisc/umass/umass.c,v 1.8 2004/02/14 19:56:28 dillon Exp $
  */
 
 /*
@@ -529,6 +529,7 @@ struct umass_softc {
        struct scsi_sense       cam_scsi_test_unit_ready;
 
        int                     maxlun;                 /* maximum LUN number */
+       struct callout_handle   rescan_timeout;
 };
 
 #ifdef USB_DEBUG
@@ -2144,9 +2145,10 @@ umass_cam_rescan(void *addr)
 {
        struct umass_softc *sc = (struct umass_softc *) addr;
        struct cam_path *path;
-       union ccb *ccb = malloc(sizeof(union ccb), M_USBDEV, M_WAITOK);
+       union ccb *ccb;
 
-       memset(ccb, 0, sizeof(union ccb));
+       sc->rescan_timeout.callout = NULL;
+       ccb = malloc(sizeof(union ccb), M_USBDEV, M_WAITOK|M_ZERO);
 
        DPRINTF(UDMASS_SCSI, ("scbus%d: scanning for %s:%d:%d:%d\n",
                cam_sim_path(sc->umass_sim),
@@ -2179,17 +2181,15 @@ umass_cam_attach(struct umass_softc *sc)
                        cam_sim_path(sc->umass_sim));
 
        if (!cold) {
-               /* Notify CAM of the new device after 1 second delay. Any
+               /* 
+                * Notify CAM of the new device after 1 second delay. Any
                 * failure is benign, as the user can still do it by hand
                 * (camcontrol rescan <busno>). Only do this if we are not
                 * booting, because CAM does a scan after booting has
                 * completed, when interrupts have been enabled.
                 */
-
-               /* XXX This will bomb if the driver is unloaded between attach
-                * and execution of umass_cam_rescan.
-                */
-               timeout(umass_cam_rescan, sc, MS_TO_TICKS(200));
+               sc->rescan_timeout =
+                       timeout(umass_cam_rescan, sc, MS_TO_TICKS(200));
        }
 
        return(0);      /* always succesfull */
@@ -2202,6 +2202,10 @@ umass_cam_attach(struct umass_softc *sc)
 Static int
 umass_cam_detach_sim(struct umass_softc *sc)
 {
+       if (sc->rescan_timeout.callout) {
+               untimeout(umass_cam_rescan, sc, sc->rescan_timeout);
+               sc->rescan_timeout.callout = NULL;
+       }
        if (sc->umass_sim) {
                if (xpt_bus_deregister(cam_sim_path(sc->umass_sim)))
                        cam_sim_free(sc->umass_sim, /*free_devq*/TRUE);