summaryrefslogtreecommitdiffstats
path: root/sys/dev/mps
diff options
context:
space:
mode:
authorken <ken@FreeBSD.org>2010-09-16 22:54:56 +0000
committerken <ken@FreeBSD.org>2010-09-16 22:54:56 +0000
commit75468fb55b0a1f39f796cf72e9f525ad8a19c364 (patch)
tree444ef2963795d747834ff06d8f94971dcbbe50e0 /sys/dev/mps
parentdbb001c036f23d47d86b79fcc1ded46937cf4e07 (diff)
downloadFreeBSD-src-75468fb55b0a1f39f796cf72e9f525ad8a19c364.zip
FreeBSD-src-75468fb55b0a1f39f796cf72e9f525ad8a19c364.tar.gz
MFp4 (//depot/projects/mps/...):
According to the MPT2 spec, task management commands are serialized, and so no I/O should start while task management commands are active. So, to comply with that, freeze the SIM queue before we send any task management commands (abort, target reset, etc.) down to the IOC. We unfreeze the queue once the task management command completes. It isn't clear from the spec whether multiple simultaneous task management commands are supported. Right now it is possible to have multiple outstanding task management commands, especially in the abort case. Multiple outstanding aborts do complete successfully, so it may be supported. We also don't yet have any recovery mechanism (e.g. reset the IOC) if the task management command fails.
Diffstat (limited to 'sys/dev/mps')
-rw-r--r--sys/dev/mps/mps_sas.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/sys/dev/mps/mps_sas.c b/sys/dev/mps/mps_sas.c
index b4f1e4c..5d29c9d 100644
--- a/sys/dev/mps/mps_sas.c
+++ b/sys/dev/mps/mps_sas.c
@@ -438,6 +438,7 @@ mpssas_prepare_remove(struct mpssas_softc *sassc, MPI2_EVENT_SAS_TOPO_PHY_ENTRY
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_complete = mpssas_remove_device;
cm->cm_targ = targ;
+ xpt_freeze_simq(sc->sassc->sim, 1);
mps_map_command(sc, cm);
}
@@ -453,6 +454,7 @@ mpssas_remove_device(struct mps_softc *sc, struct mps_command *cm)
reply = (MPI2_SCSI_TASK_MANAGE_REPLY *)cm->cm_reply;
handle = cm->cm_targ->handle;
+ xpt_release_simq(sc->sassc->sim, 1);
if (reply->IOCStatus != MPI2_IOCSTATUS_SUCCESS) {
mps_printf(sc, "Failure 0x%x reseting device 0x%04x\n",
reply->IOCStatus, handle);
@@ -983,6 +985,11 @@ mpssas_abort_complete(struct mps_softc *sc, struct mps_command *cm)
mps_printf(sc, "%s: abort request on handle %#04x SMID %d "
"complete\n", __func__, req->DevHandle, req->TaskMID);
+ /*
+ * Release the SIM queue, we froze it when we sent the abort.
+ */
+ xpt_release_simq(sc->sassc->sim, 1);
+
mps_free_command(sc, cm);
}
@@ -1013,10 +1020,19 @@ mpssas_recovery(struct mps_softc *sc, struct mps_command *abort_cm)
cm->cm_data = NULL;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
+ /*
+ * Freeze the SIM queue while we issue the abort. According to the
+ * Fusion-MPT 2.0 spec, task management requests are serialized,
+ * and so the host should not send any I/O requests while task
+ * management requests are pending.
+ */
+ xpt_freeze_simq(sc->sassc->sim, 1);
+
error = mps_map_command(sc, cm);
if (error != 0) {
mps_printf(sc, "%s: error mapping abort request!\n", __func__);
+ xpt_release_simq(sc->sassc->sim, 1);
}
#if 0
error = mpssas_reset(sc, targ, &resetcm);
@@ -1361,7 +1377,13 @@ mpssas_resetdev(struct mpssas_softc *sassc, struct mps_command *cm)
cm->cm_data = NULL;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
+ xpt_freeze_simq(sassc->sim, 1);
+
error = mps_map_command(sassc->sc, cm);
+
+ if (error != 0)
+ xpt_release_simq(sassc->sim, 1);
+
return (error);
}
@@ -1385,6 +1407,9 @@ mpssas_resetdev_complete(struct mps_softc *sc, struct mps_command *cm)
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
mps_free_command(sc, cm);
+
+ xpt_release_simq(sc->sassc->sim, 1);
+
xpt_done(ccb);
}
OpenPOWER on IntegriCloud