From ec99409e7ee1427ef102597e6827561d9c3602bd Mon Sep 17 00:00:00 2001 From: "Kenneth D. Merry" Date: Wed, 21 Aug 2013 21:30:56 +0000 Subject: [PATCH] Fix mps(4) driver breakage that came in in change 253550 that manifested itself in out of chain frame conditions. When the driver ran out of chain frames, the request in question would get completed early, and go through mpssas_scsiio_complete(). In mpssas_scsiio_complete(), the negation of the CAM status values (CAM_STATUS_MASK | CAM_SIM_QUEUED) was ORed in instead of being ANDed in. This resulted in a bogus CAM CCB status value. This didn't show up in the non-error case, because the status was reset to something valid (e.g. CAM_REQ_CMP) later on in the function. But in the error case, such as when the driver ran out of chain frames, the CAM_REQUEUE_REQ status was ORed in to the bogus status value. This led to the CAM transport layer repeatedly releasing the SIM queue, because it though that the CAM_RELEASE_SIMQ flag had been set. The symptom was messages like this on the console when INVARIANTS were enabled: xpt_release_simq: requested 1 > present 0 xpt_release_simq: requested 1 > present 0 xpt_release_simq: requested 1 > present 0 mps_sas.c: In mpssas_scsiio_complete(), use &= to take status bits out. |= adds them in. In the error case in mpssas_scsiio_complete(), set the status to CAM_REQUEUE_REQ, don't OR it in. MFC after: 3 days Sponsored by: Spectra Logic --- sys/dev/mps/mps_sas.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/mps/mps_sas.c b/sys/dev/mps/mps_sas.c index 6e5252bec1de..b6ee542a5f47 100644 --- a/sys/dev/mps/mps_sas.c +++ b/sys/dev/mps/mps_sas.c @@ -2103,7 +2103,7 @@ mpssas_scsiio_complete(struct mps_softc *sc, struct mps_command *cm) cm->cm_targ->completed++; cm->cm_targ->outstanding--; TAILQ_REMOVE(&cm->cm_targ->commands, cm, cm_link); - ccb->ccb_h.status |= ~(CAM_STATUS_MASK | CAM_SIM_QUEUED); + ccb->ccb_h.status &= ~(CAM_STATUS_MASK | CAM_SIM_QUEUED); if (cm->cm_state == MPS_CM_STATE_TIMEDOUT) { TAILQ_REMOVE(&cm->cm_targ->timedout_commands, cm, cm_recovery); @@ -2145,7 +2145,7 @@ mpssas_scsiio_complete(struct mps_softc *sc, struct mps_command *cm) * because there can be no reply when we haven't actually * gone out to the hardware. */ - ccb->ccb_h.status |= CAM_REQUEUE_REQ; + ccb->ccb_h.status = CAM_REQUEUE_REQ; /* * Currently the only error included in the mask is