summaryrefslogtreecommitdiff
path: root/sys/dev/mps
diff options
context:
space:
mode:
authorCy Schubert <cy@FreeBSD.org>2021-12-02 21:35:14 +0000
committerCy Schubert <cy@FreeBSD.org>2021-12-02 21:35:14 +0000
commit266f97b5e9a7958e365e78288616a459b40d924a (patch)
tree47846fb735b2e0becce397e048f4a1d63f996a64 /sys/dev/mps
parenta10253cffea84c0c980a36ba6776b00ed96c3e3b (diff)
parent56f32b0e4cc24d58cae7613188c0b2dcf5ca4a94 (diff)
Diffstat (limited to 'sys/dev/mps')
-rw-r--r--sys/dev/mps/mps_sas.c38
1 files changed, 16 insertions, 22 deletions
diff --git a/sys/dev/mps/mps_sas.c b/sys/dev/mps/mps_sas.c
index 681565aca2d1..c54c2a82faff 100644
--- a/sys/dev/mps/mps_sas.c
+++ b/sys/dev/mps/mps_sas.c
@@ -235,6 +235,8 @@ mpssas_alloc_tm(struct mps_softc *sc)
void
mpssas_free_tm(struct mps_softc *sc, struct mps_command *tm)
{
+ int target_id = 0xFFFFFFFF;
+
if (tm == NULL)
return;
@@ -243,11 +245,13 @@ mpssas_free_tm(struct mps_softc *sc, struct mps_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_ccb) {
- mps_dprint(sc, MPS_XINFO | MPS_RECOVERY,
- "Unfreezing devq for target ID %d\n",
- tm->cm_targ->tid);
+ if (tm->cm_targ != NULL) {
tm->cm_targ->flags &= ~MPSSAS_TARGET_INRESET;
+ target_id = tm->cm_targ->tid;
+ }
+ if (tm->cm_ccb) {
+ mps_dprint(sc, MPS_INFO, "Unfreezing devq for target ID %d\n",
+ target_id);
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);
@@ -1695,11 +1699,11 @@ mpssas_action_scsiio(struct mpssas_softc *sassc, union ccb *ccb)
}
/*
- * If target has a reset in progress, the devq should be frozen.
- * Geting here we likely hit a race, so just requeue.
+ * If target has a reset in progress, freeze the devq and return. The
+ * devq will be released when the TM reset is finished.
*/
if (targ->flags & MPSSAS_TARGET_INRESET) {
- ccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_DEV_QFRZN;
+ ccb->ccb_h.status = CAM_BUSY | CAM_DEV_QFRZN;
mps_dprint(sc, MPS_INFO, "%s: Freezing devq for target ID %d\n",
__func__, targ->tid);
xpt_freeze_devq(ccb->ccb_h.path, 1);
@@ -3240,15 +3244,11 @@ mpssas_async(void *callback_arg, uint32_t code, struct cam_path *path,
}
/*
- * 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
+ * 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
* when the TM completes.
- * We only need to do this when we're entering reset, not at each time we
- * need to send an abort (which will happen if multiple commands timeout
- * while we're sending the abort). We do not release the queue for each
- * command we complete (just at the end when we free the tm), so freezing
- * it each time doesn't make sense.
*/
void
mpssas_prepare_for_tm(struct mps_softc *sc, struct mps_command *tm,
@@ -3266,13 +3266,7 @@ mpssas_prepare_for_tm(struct mps_softc *sc, struct mps_command *tm,
} else {
tm->cm_ccb = ccb;
tm->cm_targ = target;
- if ((target->flags & MPSSAS_TARGET_INRESET) == 0) {
- mps_dprint(sc, MPS_XINFO | MPS_RECOVERY,
- "%s: Freezing devq for target ID %d\n",
- __func__, target->tid);
- xpt_freeze_devq(ccb->ccb_h.path, 1);
- target->flags |= MPSSAS_TARGET_INRESET;
- }
+ target->flags |= MPSSAS_TARGET_INRESET;
}
}
}