Index: head/sys/cam/nvme/nvme_da.c
===================================================================
--- head/sys/cam/nvme/nvme_da.c
+++ head/sys/cam/nvme/nvme_da.c
@@ -336,6 +336,8 @@
 
 	while (softc->refcount != 0)
 		cam_periph_sleep(periph, &softc->refcount, PRIBIO, "ndaclose", 1);
+	KASSERT(softc->outstanding_cmds == 0,
+	    ("nda %d outstanding commands", softc->outstanding_cmds));
 	cam_periph_unlock(periph);
 	cam_periph_release(periph);
 	return (0);	
@@ -986,10 +988,11 @@
 out:
 		start_ccb->ccb_h.flags |= CAM_UNLOCKED;
 		softc->outstanding_cmds++;
-		softc->refcount++;
+		softc->refcount++;			/* For submission only */
 		cam_periph_unlock(periph);
 		xpt_action(start_ccb);
 		cam_periph_lock(periph);
+		softc->refcount--;			/* Submission done */
 
 		/* May have more work to do, so ensure we stay scheduled */
 		ndaschedule(periph);
@@ -1085,6 +1088,7 @@
 			bp1 = TAILQ_FIRST(&queue);
 			cam_iosched_bio_complete(softc->cam_iosched, bp1, done_ccb);
 			xpt_release_ccb(done_ccb);
+			softc->outstanding_cmds--;
 			ndaschedule(periph);
 			cam_periph_unlock(periph);
 			while ((bp2 = TAILQ_FIRST(&queue)) != NULL) {
@@ -1100,11 +1104,6 @@
 				biodone(bp2);
 			}
 		}
-		/*
-		 * Release the periph refcount taken in mdastart() for each CCB.
-		 */
-		KASSERT(softc->refcount >= 1, ("ndadone softc %p refcount %d", softc, softc->refcount));
-		softc->refcount--;
 		return;
 	}
 	case NDA_CCB_DUMP: