⬢ DragonFlyBSD Kernel Audit
DF-3661 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/disk/isp/isp_freebsd.c
+++ b/sys/dev/disk/isp/isp_freebsd.c
@@ -92,9 +92,6 @@ isp_attach_chan(ispsoftc_t *isp, struct cam_devq *devq, int chan)
 	 */
 	sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp, device_get_unit(isp->isp_dev), &isp->isp_osinfo.lock, isp->isp_maxcmds, isp->isp_maxcmds, devq);
-	cam_simq_release(devq);
-
 	if (sim == NULL) {
 		return (ENOMEM);
 	}
@@ -252,9 +249,10 @@ unwind:
 		ISP_UNLOCK(isp);
 		cam_sim_free(sim);
 	}
+	/* All sims (and their devq refs) are gone - now drop our single ref. */
+	cam_simq_release(isp->isp_osinfo.devq);
 	if (isp->isp_osinfo.ehook_active) {
 		config_intrhook_disestablish(&isp->isp_osinfo.ehook);
 		isp->isp_osinfo.ehook_active = 0;
@@ -316,8 +314,10 @@ isp_detach(ispsoftc_t *isp)
 	if (isp->isp_osinfo.ehook_active) {
 		config_intrhook_disestablish(&isp->isp_osinfo.ehook);
 		isp->isp_osinfo.ehook_active = 0;
 	}
+	/* All sims (and their devq refs) are gone - now drop our single ref. */
+	cam_simq_release(isp->isp_osinfo.devq);
 	if (isp->isp_osinfo.devq != NULL) {
 		isp->isp_osinfo.devq = NULL;
 	}