diff options
| author | Cy Schubert <cy@FreeBSD.org> | 2021-12-02 21:35:14 +0000 |
|---|---|---|
| committer | Cy Schubert <cy@FreeBSD.org> | 2021-12-02 21:35:14 +0000 |
| commit | 266f97b5e9a7958e365e78288616a459b40d924a (patch) | |
| tree | 47846fb735b2e0becce397e048f4a1d63f996a64 /sys/dev/mps | |
| parent | a10253cffea84c0c980a36ba6776b00ed96c3e3b (diff) | |
| parent | 56f32b0e4cc24d58cae7613188c0b2dcf5ca4a94 (diff) | |
Diffstat (limited to 'sys/dev/mps')
| -rw-r--r-- | sys/dev/mps/mps_sas.c | 38 |
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; } } } |
