⬢ DragonFlyBSD Kernel Audit
DF-4590 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/raid/tws/tws.c
+++ b/sys/dev/raid/tws/tws.c
@@ -348,6 +348,7 @@
 {
     struct tws_softc *sc = device_get_softc(dev);
     int error;
+    int i;
     u_int32_t reg;
 
     TWS_TRACE_DEBUG(sc, "entry", 0, 0);
@@ -381,6 +382,19 @@
     if (sc->intr_type == PCI_INTR_TYPE_MSI)
         pci_release_msi(sc->tws_dev);
 
+    /*
+     * Interrupts are torn down: cancel any pending driver callouts
+     * (tws_reset_cb / tws_reinit poll loops, per-request timeouts)
+     * before the softc memory they reference is freed.
+     */
+    callout_cancel(&sc->print_stats_handle);
+    callout_cancel(&sc->reset_cb_handle);
+    callout_cancel(&sc->reinit_handle);
+    if (sc->reqs) {
+        for (i = 0; i < tws_queue_depth; i++)
+            callout_cancel(&sc->reqs[i].thandle);
+    }
+
     tws_cam_detach(sc);
 
     /* Release memory resource */
@@ -613,6 +627,7 @@
             return(FAILURE);
         }
         sc->reqs[i].cmd_pkt =  &cmd_buf[i];
+        callout_init(&sc->reqs[i].thandle);
 
         sc->sense_bufs[i].hdr = &cmd_buf[i].hdr ;
         sc->sense_bufs[i].hdr_pkt_phy = sc->dma_mem_phys +