Date: Mon, 21 Feb 2011 16:55:54 +0000 (UTC) From: "Kenneth D. Merry" <ken@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r218921 - stable/8/sys/dev/mps Message-ID: <201102211655.p1LGtsk5076942@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ken Date: Mon Feb 21 16:55:53 2011 New Revision: 218921 URL: http://svn.freebsd.org/changeset/base/218921 Log: MFC: r218811: 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 Modified: stable/8/sys/dev/mps/mps.c stable/8/sys/dev/mps/mps_sas.c stable/8/sys/dev/mps/mpsvar.h Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) Modified: stable/8/sys/dev/mps/mps.c ============================================================================== --- stable/8/sys/dev/mps/mps.c Mon Feb 21 16:33:01 2011 (r218920) +++ stable/8/sys/dev/mps/mps.c Mon Feb 21 16:55:53 2011 (r218921) @@ -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: stable/8/sys/dev/mps/mps_sas.c ============================================================================== --- stable/8/sys/dev/mps/mps_sas.c Mon Feb 21 16:33:01 2011 (r218920) +++ stable/8/sys/dev/mps/mps_sas.c Mon Feb 21 16:55:53 2011 (r218921) @@ -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: stable/8/sys/dev/mps/mpsvar.h ============================================================================== --- stable/8/sys/dev/mps/mpsvar.h Mon Feb 21 16:33:01 2011 (r218920) +++ stable/8/sys/dev/mps/mpsvar.h Mon Feb 21 16:55:53 2011 (r218921) @@ -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?201102211655.p1LGtsk5076942>