Index: sys/dev/mpr/mpr_sas.c =================================================================== --- sys/dev/mpr/mpr_sas.c +++ sys/dev/mpr/mpr_sas.c @@ -559,7 +559,6 @@ MPI2_SCSI_TASK_MANAGE_REPLY *reply; MPI2_SAS_IOUNIT_CONTROL_REQUEST *req; struct mprsas_target *targ; - struct mpr_command *next_cm; uint16_t handle; MPR_FUNCTRACE(sc); @@ -618,15 +617,6 @@ "connector name (%4s)\n", targ->encl_level, targ->encl_slot, targ->connector_name); } - TAILQ_FOREACH_SAFE(tm, &targ->commands, cm_link, next_cm) { - union ccb *ccb; - - mpr_dprint(sc, MPR_XINFO, "Completing missed command %p\n", tm); - ccb = tm->cm_complete_data; - mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); - tm->cm_state = MPR_CM_STATE_BUSY; - mprsas_scsiio_complete(sc, tm); - } } static void @@ -674,7 +664,25 @@ */ if ((le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK) == MPI2_IOCSTATUS_SUCCESS) { + struct mpr_command *next_cm; + + /* + * Once MPI2_SAS_OP_REMOVE_DEVICE completes, we should have + * already completed all the I/O that we've queued to the + * target. As a failsafe, make sure that we complete the I/O + * here should any fall through the cracks (which indicates + * a bug, most likely, in this driver). + */ targ = tm->cm_targ; + TAILQ_FOREACH_SAFE(tm, &targ->commands, cm_link, next_cm) { + union ccb *ccb; + + mpr_dprint(sc, MPR_INFO, "Completing missed command %p\n", tm); + ccb = tm->cm_complete_data; + mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); + tm->cm_state = MPR_CM_STATE_BUSY; + mprsas_scsiio_complete(sc, tm); + } targ->handle = 0x0; targ->encl_handle = 0x0; targ->encl_level_valid = 0x0; Index: sys/dev/mps/mps_sas.c =================================================================== --- sys/dev/mps/mps_sas.c +++ sys/dev/mps/mps_sas.c @@ -556,7 +556,6 @@ 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_FUNCTRACE(sc); @@ -613,15 +612,6 @@ mps_dprint(sc, MPS_XINFO, "clearing target %u handle 0x%04x\n", targ->tid, handle); - TAILQ_FOREACH_SAFE(tm, &targ->commands, cm_link, next_cm) { - union ccb *ccb; - - mps_dprint(sc, MPS_XINFO, "Completing missed command %p\n", tm); - ccb = tm->cm_complete_data; - mpssas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); - tm->cm_state = MPS_CM_STATE_BUSY; - mpssas_scsiio_complete(sc, tm); - } } static void @@ -671,7 +661,26 @@ */ if ((le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK) == MPI2_IOCSTATUS_SUCCESS) { + struct mps_command *next_cm; + + /* + * Once MPI2_SAS_OP_REMOVE_DEVICE completes, we should have + * already completed all the I/O that we've queued to the + * target. As a failsafe, make sure that we complete the I/O + * here should any fall through the cracks (which indicates + * a bug, most likely, in this driver). + */ targ = tm->cm_targ; + TAILQ_FOREACH_SAFE(tm, &targ->commands, cm_link, next_cm) { + union ccb *ccb; + + mps_dprint(sc, MPS_INFO, "Completing missed command %p\n", tm); + ccb = tm->cm_complete_data; + mpssas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); + tm->cm_state = MPS_CM_STATE_BUSY; + mpssas_scsiio_complete(sc, tm); + } + targ->handle = 0x0; targ->encl_handle = 0x0; targ->encl_slot = 0x0;