FreeBSD/sys/dev/mps/mps_sas.c
/*
 * The MPT2 firmware performs debounce on the link to avoid transient link
 * errors and false removals.  When it does decide that link has been lost
 * and a device need to go away, it expects that the host will perform a
 * target reset and then an op remove.  The reset has the side-effect of
 * aborting any outstanding requests for the device, which is required for
 * the op-remove to succeed.  It's not clear if the host should check for
 * the device coming back alive after the reset.
 */
The MPT2 firmware performs debounce on the link to avoid transient link
errors and false removals.  When it does decide that link has been lost
and a device need to go away, it expects that the host will perform a
target reset and then an op remove.  The reset has the side-effect of
aborting any outstanding requests for the device, which is required for
the op-remove to succeed.  It's not clear if the host should check for
the device coming back alive after the reset.
The MPT2 firmware performs debounce on the link to avoid transient link errors and false removals . When it does decide that link has been lost and a device need to go away it expects that the host will perform a target reset and then an op remove . The reset has the side - effect of aborting any outstanding requests for the device which is required for the op - remove to succeed . It ' s not clear if the host should check for the device coming back alive after the reset .
void
mpssas_prepare_remove(struct mpssas_softc *sassc, uint16_t handle)
{
	MPI2_SCSI_TASK_MANAGE_REQUEST *req;
	struct mps_softc *sc;
	struct mps_command *cm;
	struct mpssas_target *targ = NULL;
	MPS_FUNCTRACE(sassc->sc);
	sc = sassc->sc;
	targ = mpssas_find_target_by_handle(sassc, 0, handle);
	if (targ == NULL) {
		mps_dprint(sc, MPS_ERROR,
		    "%s : invalid handle 0x%x \n", __func__, handle);
		return;
	}
	targ->flags |= MPSSAS_TARGET_INREMOVAL;
	cm = mpssas_alloc_tm(sc);
	if (cm == NULL) {
		mps_dprint(sc, MPS_ERROR,
		    "%s: command alloc failure\n", __func__);
		return;
	}
	mpssas_rescan_target(sc, targ);
	req = (MPI2_SCSI_TASK_MANAGE_REQUEST *)cm->cm_req;
	memset(req, 0, sizeof(*req));
	req->DevHandle = htole16(targ->handle);
	req->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
	req->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
	req->MsgFlags = MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET;
	cm->cm_targ = targ;
	cm->cm_data = NULL;
	cm->cm_desc.HighPriority.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
	cm->cm_complete = mpssas_remove_device;
	cm->cm_complete_data = (void *)(uintptr_t)handle;
	mps_dprint(sc, MPS_INFO, "%s: Sending reset for target ID %d\n",
	    __func__, targ->tid);
	mpssas_prepare_for_tm(sc, cm, targ, CAM_LUN_WILDCARD);
	mps_map_command(sc, cm);
}
void mpssas_prepare_remove ( struct mpssas_softc * sassc , uint16_t handle ) { MPI2_SCSI_TASK_MANAGE_REQUEST * req ; struct mps_softc * sc ; struct mps_command * cm ; struct mpssas_target * targ = NULL ; MPS_FUNCTRACE ( sassc -> sc ) ; sc = sassc -> sc ; targ = mpssas_find_target_by_handle ( sassc , 0 , handle ) ; if ( targ == NULL ) { mps_dprint ( sc , MPS_ERROR , " \n " , __func__ , handle ) ; return ; } targ -> flags |= MPSSAS_TARGET_INREMOVAL ; cm = mpssas_alloc_tm ( sc ) ; if ( cm == NULL ) { mps_dprint ( sc , MPS_ERROR , " \n " , __func__ ) ; return ; } mpssas_rescan_target ( sc , targ ) ; req = ( MPI2_SCSI_TASK_MANAGE_REQUEST * ) cm -> cm_req ; memset ( req , 0 , sizeof ( * req ) ) ; req -> DevHandle = htole16 ( targ -> handle ) ; req -> Function = MPI2_FUNCTION_SCSI_TASK_MGMT ; req -> TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET ; req -> MsgFlags = MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET ; cm -> cm_targ = targ ; cm -> cm_data = NULL ; cm -> cm_desc . HighPriority . RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY ; cm -> cm_complete = mpssas_remove_device ; cm -> cm_complete_data = ( void * ) ( uintptr_t ) handle ; mps_dprint ( sc , MPS_INFO , " \n " , __func__ , targ -> tid ) ; mpssas_prepare_for_tm ( sc , cm , targ , CAM_LUN_WILDCARD ) ; mps_map_command ( sc , cm ) ; }
The MPT2 firmware performs debounce on the link to avoid transient link
 errors and false removals.
The MPT2 firmware performs debounce on the link to avoid transient link errors and false removals .
/* FIXME: what is the action? */ /* We don't know about this device? */ /* SAS Hard Link Reset / SATA Link Reset */