aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/mpr
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2021-08-20 18:37:55 +0000
committerAlexander Motin <mav@FreeBSD.org>2021-08-20 18:51:12 +0000
commit9781c28c6d63cfa8438d1aa31f512a6b217a6b2b (patch)
tree5854793526ba8e90ec1bbd461aef773b575422ec /sys/dev/mpr
parent5d75ffdd0c6751e220fdadcf216124013139f1ac (diff)
Diffstat (limited to 'sys/dev/mpr')
-rw-r--r--sys/dev/mpr/mpr_sas.c29
1 files changed, 13 insertions, 16 deletions
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;