예제 #1
0
/*ARGSUSED*/
stmf_status_t
pppt_lport_send_status(scsi_task_t *task, uint32_t ioflags)
{
	pppt_task_t *ptask =		task->task_port_private;
	stmf_ic_msg_t			*msg;
	stmf_ic_msg_status_t		ic_msg_status;

	/*
	 * Mark task completed.  If the state indicates it was aborted
	 * then we don't need to respond.
	 */
	if (pppt_task_done(ptask) == PPPT_STATUS_ABORTED) {
		return (STMF_SUCCESS);
	}

	/*
	 * Send status.
	 */
	msg = stmf_ic_scsi_status_msg_alloc(
	    ptask->pt_task_id,
	    ptask->pt_sess->ps_session_id,
	    ptask->pt_lun_id,
	    0,
	    task->task_scsi_status,
	    task->task_status_ctrl, task->task_resid,
	    task->task_sense_length, task->task_sense_data, 0);

	ic_msg_status = stmf_ic_tx_msg(msg);

	if (ic_msg_status != STMF_IC_MSG_SUCCESS) {
		pppt_task_sent_status(ptask);
		stmf_send_status_done(ptask->pt_stmf_task,
		    STMF_FAILURE, STMF_IOF_LPORT_DONE);
		return (STMF_FAILURE);
	} else {
		pppt_task_sent_status(ptask);
		stmf_send_status_done(ptask->pt_stmf_task,
		    STMF_SUCCESS, STMF_IOF_LPORT_DONE);
		return (STMF_SUCCESS);
	}
}
예제 #2
0
/*
 * srpt_ch_rsp_comp()
 *
 * Process a completion for an IB SEND message.  A SEND completion
 * is for a SRP response packet sent back to the initiator.  It
 * will not have a STMF SCSI task associated with it if it was
 * sent for a rejected IU, or was a task management abort response.
 */
static void
srpt_ch_rsp_comp(srpt_channel_t *ch, srpt_iu_t *iu,
	ibt_wc_status_t wc_status)
{
	stmf_status_t	st = STMF_SUCCESS;

	ASSERT(iu->iu_ch == ch);

	/*
	 * Process the completion regardless whether it's a failure or
	 * success.  At this point, we've processed as far as we can and
	 * just need to complete the associated task.
	 */

	if (wc_status != IBT_SUCCESS) {
		SRPT_DPRINTF_L2("ch_rsp_comp, WC status err(%d)",
		    wc_status);

		st = STMF_FAILURE;

		if (wc_status != IBT_WC_WR_FLUSHED_ERR) {
			srpt_ch_disconnect(ch);
		}
	}

	/*
	 * If the IU response completion is not associated with
	 * with a SCSI task, release the IU to return the resource
	 * and the reference to the channel it holds.
	 */
	mutex_enter(&iu->iu_lock);
	atomic_dec_32(&iu->iu_sq_posted_cnt);

	if (iu->iu_stmf_task == NULL) {
		srpt_ioc_repost_recv_iu(iu->iu_ioc, iu);
		mutex_exit(&iu->iu_lock);
		srpt_ch_release_ref(ch, 0);
		return;
	}

	/*
	 * We should not get a SEND completion where the task has already
	 * completed aborting and STMF has been informed.
	 */
	ASSERT((iu->iu_flags & SRPT_IU_ABORTED) == 0);

	/*
	 * Let STMF know we are done.
	 */
	mutex_exit(&iu->iu_lock);

	stmf_send_status_done(iu->iu_stmf_task, st, STMF_IOF_LPORT_DONE);
}
예제 #3
0
/*
 * srpt_ch_rsp_comp()
 *
 * Process a completion for an IB SEND message.  A SEND completion
 * is for a SRP response packet sent back to the initiator.  It
 * will not have a STMF SCSI task associated with it if it was
 * sent for a rejected IU, or was a task management abort response.
 */
static void
srpt_ch_rsp_comp(srpt_channel_t *ch, srpt_iu_t *iu,
	ibt_wc_status_t wc_status)
{
	ASSERT(iu->iu_ch == ch);

	/*
	 * If work completion indicates failure, decrement the
	 * send posted count.  If it is a flush error, we are
	 * done; for all other errors start a channel disconnect.
	 */
	if (wc_status != IBT_SUCCESS) {
		SRPT_DPRINTF_L2("ch_rsp_comp, WC status err(%d)",
		    wc_status);
		atomic_dec_32(&iu->iu_sq_posted_cnt);

		if (wc_status != IBT_WC_WR_FLUSHED_ERR) {
			srpt_ch_disconnect(ch);
		}

		mutex_enter(&iu->iu_lock);
		if (iu->iu_stmf_task == NULL) {
			srpt_ioc_repost_recv_iu(iu->iu_ioc, iu);
			mutex_exit(&iu->iu_lock);
			srpt_ch_release_ref(ch, 0);
		} else {
			/* cleanup handled in task_free */
			mutex_exit(&iu->iu_lock);
		}
		return;
	}

	/*
	 * If the IU response completion is not associated with
	 * with a SCSI task, release the IU to return the resource
	 * and the reference to the channel it holds.
	 */
	mutex_enter(&iu->iu_lock);
	atomic_dec_32(&iu->iu_sq_posted_cnt);

	if (iu->iu_stmf_task == NULL) {
		srpt_ioc_repost_recv_iu(iu->iu_ioc, iu);
		mutex_exit(&iu->iu_lock);
		srpt_ch_release_ref(ch, 0);
		return;
	}

	/*
	 * If STMF has requested the IU task be aborted, then notify STMF
	 * the command is now aborted.
	 */
	if ((iu->iu_flags & SRPT_IU_STMF_ABORTING) != 0) {
		scsi_task_t	*abort_task = iu->iu_stmf_task;

		mutex_exit(&iu->iu_lock);
		stmf_abort(STMF_REQUEUE_TASK_ABORT_LPORT, abort_task,
		    STMF_ABORTED, NULL);
		return;
	}

	/*
	 * We should not get a SEND completion where the task has already
	 * completed aborting and STMF has been informed.
	 */
	ASSERT((iu->iu_flags & SRPT_IU_ABORTED) == 0);

	/*
	 * Successful status response completion for SCSI task.
	 * Let STMF know we are done.
	 */
	mutex_exit(&iu->iu_lock);

	stmf_send_status_done(iu->iu_stmf_task, STMF_SUCCESS,
	    STMF_IOF_LPORT_DONE);
}