Date: Fri, 18 Feb 2011 17:01:57 +0000 (UTC) From: "Kenneth D. Merry" <ken@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r218811 - head/sys/dev/mps Message-ID: <201102181701.p1IH1vqs065592@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ken Date: Fri Feb 18 17:01:57 2011 New Revision: 218811 URL: http://svn.freebsd.org/changeset/base/218811 Log: In the MPS driver, during device removal processing, don't assume that the controller firmware will return all of our commands. Instead, keep track of outstanding I/Os and return them to CAM once device removal processing completes. mpsvar.h: Declare the new "io_list" in the mps_softc. mps.c: Initialize the new "io_list" in the mps softc. mps_sas.c: o Track SCSI I/O requests on the io_list from the time of mpssas_action() through mpssas_scsiio_complete(). o Zero out the request structures used for device removal commands prior to filling them out. o Once the target reset task management function completes during device removal processing, assume any SCSI I/O commands that are still oustanding will never return from the controller, and process them manually. Submitted by: gibbs MFC after: 3 days Modified: head/sys/dev/mps/mps.c head/sys/dev/mps/mps_sas.c head/sys/dev/mps/mpsvar.h Modified: head/sys/dev/mps/mps.c ============================================================================== --- head/sys/dev/mps/mps.c Fri Feb 18 16:29:38 2011 (r218810) +++ head/sys/dev/mps/mps.c Fri Feb 18 17:01:57 2011 (r218811) @@ -898,6 +898,7 @@ mps_attach(struct mps_softc *sc) TAILQ_INIT(&sc->req_list); TAILQ_INIT(&sc->chain_list); TAILQ_INIT(&sc->tm_list); + TAILQ_INIT(&sc->io_list); if (((error = mps_alloc_queues(sc)) != 0) || ((error = mps_alloc_replies(sc)) != 0) || Modified: head/sys/dev/mps/mps_sas.c ============================================================================== --- head/sys/dev/mps/mps_sas.c Fri Feb 18 16:29:38 2011 (r218810) +++ head/sys/dev/mps/mps_sas.c Fri Feb 18 17:01:57 2011 (r218811) @@ -486,7 +486,10 @@ mpssas_prepare_remove(struct mpssas_soft return; } + mps_dprint(sc, MPS_INFO, "Preparing to remove target %d\n", targ->tid); + req = (MPI2_SCSI_TASK_MANAGE_REQUEST *)cm->cm_req; + memset(req, 0, sizeof(*req)); req->DevHandle = targ->handle; req->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; req->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; @@ -507,6 +510,7 @@ mpssas_remove_device(struct mps_softc *s MPI2_SCSI_TASK_MANAGE_REPLY *reply; MPI2_SAS_IOUNIT_CONTROL_REQUEST *req; struct mpssas_target *targ; + struct mps_command *next_cm; uint16_t handle; mps_dprint(sc, MPS_TRACE, "%s\n", __func__); @@ -523,11 +527,13 @@ mpssas_remove_device(struct mps_softc *s return; } - mps_printf(sc, "Reset aborted %d commands\n", reply->TerminationCount); + mps_dprint(sc, MPS_INFO, "Reset aborted %u commands\n", + reply->TerminationCount); mps_free_reply(sc, cm->cm_reply_data); /* Reuse the existing command */ req = (MPI2_SAS_IOUNIT_CONTROL_REQUEST *)cm->cm_req; + memset(req, 0, sizeof(*req)); req->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; req->Operation = MPI2_SAS_OP_REMOVE_DEVICE; req->DevHandle = handle; @@ -539,6 +545,17 @@ mpssas_remove_device(struct mps_softc *s mps_map_command(sc, cm); mps_dprint(sc, MPS_INFO, "clearing target handle 0x%04x\n", handle); + TAILQ_FOREACH_SAFE(cm, &sc->io_list, cm_link, next_cm) { + union ccb *ccb; + + if (cm->cm_targ->handle != handle) + continue; + + mps_dprint(sc, MPS_INFO, "Completing missed command %p\n", cm); + ccb = cm->cm_complete_data; + ccb->ccb_h.status = CAM_DEV_NOT_THERE; + mpssas_scsiio_complete(sc, cm); + } targ = mpssas_find_target(sc->sassc, 0, handle); if (targ != NULL) { targ->handle = 0x0; @@ -1430,6 +1447,7 @@ mpssas_action_scsiio(struct mpssas_softc cm->cm_complete_data = ccb; cm->cm_targ = targ; + TAILQ_INSERT_TAIL(&sc->io_list, cm, cm_link); callout_reset(&cm->cm_callout, (ccb->ccb_h.timeout * hz) / 1000, mpssas_scsiio_timeout, cm); @@ -1449,6 +1467,7 @@ mpssas_scsiio_complete(struct mps_softc mps_dprint(sc, MPS_TRACE, "%s\n", __func__); callout_stop(&cm->cm_callout); + TAILQ_REMOVE(&sc->io_list, cm, cm_link); sassc = sc->sassc; ccb = cm->cm_complete_data; @@ -1470,8 +1489,10 @@ mpssas_scsiio_complete(struct mps_softc /* Take the fast path to completion */ if (cm->cm_reply == NULL) { - ccb->ccb_h.status = CAM_REQ_CMP; - ccb->csio.scsi_status = SCSI_STATUS_OK; + if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) { + ccb->ccb_h.status = CAM_REQ_CMP; + ccb->csio.scsi_status = SCSI_STATUS_OK; + } mps_free_command(sc, cm); xpt_done(ccb); return; Modified: head/sys/dev/mps/mpsvar.h ============================================================================== --- head/sys/dev/mps/mpsvar.h Fri Feb 18 16:29:38 2011 (r218810) +++ head/sys/dev/mps/mpsvar.h Fri Feb 18 17:01:57 2011 (r218811) @@ -133,6 +133,7 @@ struct mps_softc { TAILQ_HEAD(, mps_command) req_list; TAILQ_HEAD(, mps_chain) chain_list; TAILQ_HEAD(, mps_command) tm_list; + TAILQ_HEAD(, mps_command) io_list; int replypostindex; int replyfreeindex;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201102181701.p1IH1vqs065592>