diff --git a/sys/dev/mpr/mpr_sas.c b/sys/dev/mpr/mpr_sas.c index e1739028dd8f..a8bb7c90b5c4 100644 --- a/sys/dev/mpr/mpr_sas.c +++ b/sys/dev/mpr/mpr_sas.c @@ -237,7 +237,6 @@ mprsas_alloc_tm(struct mpr_softc *sc) void mprsas_free_tm(struct mpr_softc *sc, struct mpr_command *tm) { - int target_id = 0xFFFFFFFF; MPR_FUNCTRACE(sc); if (tm == NULL) @@ -248,13 +247,10 @@ mprsas_free_tm(struct mpr_softc *sc, struct mpr_command *tm) * free the resources used for freezing the devq. Must clear the * INRESET flag as well or scsi I/O will not work. */ - if (tm->cm_targ != NULL) { - tm->cm_targ->flags &= ~MPRSAS_TARGET_INRESET; - target_id = tm->cm_targ->tid; - } if (tm->cm_ccb) { - mpr_dprint(sc, MPR_INFO, "Unfreezing devq for target ID %d\n", - target_id); + mpr_dprint(sc, MPR_XINFO, "Unfreezing devq for target ID %d\n", + tm->cm_targ->tid); + tm->cm_targ->flags &= ~MPRSAS_TARGET_INRESET; xpt_release_devq(tm->cm_ccb->ccb_h.path, 1, TRUE); xpt_free_path(tm->cm_ccb->ccb_h.path); xpt_free_ccb(tm->cm_ccb); @@ -1923,13 +1919,11 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb) } /* - * If target has a reset in progress, freeze the devq and return. The - * devq will be released when the TM reset is finished. + * If target has a reset in progress, the devq should be frozen. + * Geting here we likely hit a race, so just requeue. */ if (targ->flags & MPRSAS_TARGET_INRESET) { - ccb->ccb_h.status = CAM_BUSY | CAM_DEV_QFRZN; - mpr_dprint(sc, MPR_INFO, "%s: Freezing devq for target ID %d\n", - __func__, targ->tid); + ccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_DEV_QFRZN; xpt_freeze_devq(ccb->ccb_h.path, 1); xpt_done(ccb); return; @@ -3426,10 +3420,9 @@ mprsas_async(void *callback_arg, uint32_t code, struct cam_path *path, } /* - * Set the INRESET flag for this target so that no I/O will be sent to - * the target until the reset has completed. If an I/O request does - * happen, the devq will be frozen. The CCB holds the path which is - * used to release the devq. The devq is released and the CCB is freed + * Freeze the devq and set the INRESET flag so that no I/O will be sent to + * the target until the reset has completed. The CCB holds the path which + * is used to release the devq. The devq is released and the CCB is freed * when the TM completes. */ void @@ -3446,6 +3439,10 @@ mprsas_prepare_for_tm(struct mpr_softc *sc, struct mpr_command *tm, target->tid, lun_id) != CAM_REQ_CMP) { xpt_free_ccb(ccb); } else { + mpr_dprint(sc, MPR_XINFO, + "%s: Freezing devq for target ID %d\n", + __func__, target->tid); + xpt_freeze_devq(ccb->ccb_h.path, 1); tm->cm_ccb = ccb; tm->cm_targ = target; target->flags |= MPRSAS_TARGET_INRESET;