Index: sys/cam/scsi/scsi_da.c =================================================================== --- sys/cam/scsi/scsi_da.c +++ sys/cam/scsi/scsi_da.c @@ -1686,7 +1686,7 @@ da_ref_text[token], token); cnt = atomic_fetchadd_int(&softc->ref_flags[token], -1); if (cnt != 1) - panic("Unholding %d with cnt = %d", token, cnt); + panic("releasing (locked) %d with cnt = %d", token, cnt); cam_periph_release_locked(periph); } @@ -2133,8 +2133,8 @@ "Capacity data has changed\n"); cam_periph_lock(periph); softc->flags &= ~DA_FLAG_PROBED; - cam_periph_unlock(periph); dareprobe(periph); + cam_periph_unlock(periph); } else if (asc == 0x28 && ascq == 0x00) { cam_periph_lock(periph); softc->flags &= ~DA_FLAG_PROBED; @@ -2145,8 +2145,8 @@ "INQUIRY data has changed\n"); cam_periph_lock(periph); softc->flags &= ~DA_FLAG_PROBED; - cam_periph_unlock(periph); dareprobe(periph); + cam_periph_unlock(periph); } } break; @@ -4611,6 +4611,14 @@ cam_periph_assert(periph, MA_OWNED); + KASSERT(softc->state == DA_STATE_PROBE_WP, + ("State (%d) not PROBE_WP in dadone_probewp, periph %p ccb %p", + softc->state, periph, done_ccb)); + KASSERT((csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK) == DA_CCB_PROBE_WP, + ("CCB State (%lu) not PROBE_WP in dadone_probewp, periph %p ccb %p", + (unsigned long)csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK, periph, + done_ccb)); + if (softc->minimum_cmd_size > 6) { mode_hdr10 = (struct scsi_mode_header_10 *)csio->data_ptr; dev_spec = mode_hdr10->dev_spec; @@ -4643,11 +4651,11 @@ } free(csio->data_ptr, M_SCSIDA); - xpt_release_ccb(done_ccb); if ((softc->flags & DA_FLAG_CAN_RC16) != 0) softc->state = DA_STATE_PROBE_RC16; else softc->state = DA_STATE_PROBE_RC; + xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); return; } @@ -4671,6 +4679,13 @@ csio = &done_ccb->csio; state = csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK; + KASSERT(softc->state == DA_STATE_PROBE_RC || softc->state == DA_STATE_PROBE_RC16, + ("State (%d) not PROBE_RC* in dadone_proberc, periph %p ccb %p", + softc->state, periph, done_ccb)); + KASSERT(state == DA_CCB_PROBE_RC || state == DA_CCB_PROBE_RC16, + ("CCB State (%lu) not PROBE_RC* in dadone_probewp, periph %p ccb %p", + (unsigned long)state, periph, done_ccb)); + lbp = 0; rdcap = NULL; rcaplong = NULL; @@ -4707,8 +4722,8 @@ */ if (maxsector == 0xffffffff) { free(rdcap, M_SCSIDA); - xpt_release_ccb(done_ccb); softc->state = DA_STATE_PROBE_RC16; + xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); return; } @@ -4814,8 +4829,8 @@ cam_periph_assert(periph, MA_OWNED); softc->flags &= ~DA_FLAG_CAN_RC16; free(rdcap, M_SCSIDA); - xpt_release_ccb(done_ccb); softc->state = DA_STATE_PROBE_RC; + xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); return; } @@ -4922,14 +4937,14 @@ dadeleteflag(softc, DA_DELETE_WS10, 1); dadeleteflag(softc, DA_DELETE_UNMAP, 1); - xpt_release_ccb(done_ccb); softc->state = DA_STATE_PROBE_LBP; + xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); return; } - xpt_release_ccb(done_ccb); softc->state = DA_STATE_PROBE_BDC; + xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); return; } @@ -4986,8 +5001,8 @@ } free(lbp, M_SCSIDA); - xpt_release_ccb(done_ccb); softc->state = DA_STATE_PROBE_BLK_LIMITS; + xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); return; } @@ -5080,8 +5095,8 @@ } free(block_limits, M_SCSIDA); - xpt_release_ccb(done_ccb); softc->state = DA_STATE_PROBE_BDC; + xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); return; } @@ -5181,8 +5196,8 @@ } free(bdc, M_SCSIDA); - xpt_release_ccb(done_ccb); softc->state = DA_STATE_PROBE_ATA; + xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); return; } @@ -5321,8 +5336,8 @@ continue_probe = 1; } if (continue_probe != 0) { - xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); + xpt_release_ccb(done_ccb); return; } else daprobedone(periph, done_ccb); @@ -5811,8 +5826,8 @@ /*timeout*/0, /*getcount_only*/0); } - xpt_release_ccb(done_ccb); softc->flags &= ~DA_FLAG_TUR_PENDING; + xpt_release_ccb(done_ccb); da_periph_release_locked(periph, DA_REF_TUR); return; } @@ -5825,6 +5840,8 @@ softc = (struct da_softc *)periph->softc; + cam_periph_assert(periph, MA_OWNED); + /* Probe in progress; don't interfere. */ if (softc->state != DA_STATE_NORMAL) return;