Beispiel #1
0
/*
 * isci_task_request_complete() - This function is called by the sci core when
 *    an task request completes.
 * @ihost: This parameter specifies the ISCI host object
 * @ireq: This parameter is the completed isci_request object.
 * @completion_status: This parameter specifies the completion status from the
 *    sci core.
 *
 * none.
 */
void
isci_task_request_complete(struct isci_host *ihost,
			   struct isci_request *ireq,
			   enum sci_task_status completion_status)
{
	struct isci_tmf *tmf = isci_request_access_tmf(ireq);
	struct completion *tmf_complete = NULL;
	struct completion *request_complete = ireq->io_request_completion;

	dev_dbg(&ihost->pdev->dev,
		"%s: request = %p, status=%d\n",
		__func__, ireq, completion_status);

	isci_request_change_state(ireq, completed);

	set_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags);

	if (tmf) {
		tmf->status = completion_status;

		if (tmf->proto == SAS_PROTOCOL_SSP) {
			memcpy(&tmf->resp.resp_iu,
			       &ireq->ssp.rsp,
			       SSP_RESP_IU_MAX_SIZE);
		} else if (tmf->proto == SAS_PROTOCOL_SATA) {
			memcpy(&tmf->resp.d2h_fis,
			       &ireq->stp.rsp,
			       sizeof(struct dev_to_host_fis));
		}
		/* PRINT_TMF( ((struct isci_tmf *)request->task)); */
		tmf_complete = tmf->complete;
	}
	sci_controller_complete_io(ihost, ireq->target_device, ireq);
	/* set the 'terminated' flag handle to make sure it cannot be terminated
	 *  or completed again.
	 */
	set_bit(IREQ_TERMINATED, &ireq->flags);

	/* As soon as something is in the terminate path, deallocation is
	 * managed there.  Note that the final non-managed state of a task
	 * request is "completed".
	 */
	if ((ireq->status == completed) ||
	    !isci_request_is_dealloc_managed(ireq->status)) {
		isci_request_change_state(ireq, unallocated);
		isci_free_tag(ihost, ireq->io_tag);
		list_del_init(&ireq->dev_node);
	}

	/* "request_complete" is set if the task was being terminated. */
	if (request_complete)
		complete(request_complete);

	/* The task management part completes last. */
	if (tmf_complete)
		complete(tmf_complete);
}
Beispiel #2
0
/**
* isci_request_mark_zombie() - This function must be called with scic_lock held.
*/
static void isci_request_mark_zombie(struct isci_host *ihost, struct isci_request *ireq)
{
	struct completion *tmf_completion = NULL;
	struct completion *req_completion;

	/* Set the request state to "dead". */
	ireq->status = dead;

	req_completion = ireq->io_request_completion;
	ireq->io_request_completion = NULL;

	if (test_bit(IREQ_TMF, &ireq->flags)) {
		/* Break links with the TMF request. */
		struct isci_tmf *tmf = isci_request_access_tmf(ireq);

		/* In the case where a task request is dying,
		 * the thread waiting on the complete will sit and
		 * timeout unless we wake it now.  Since the TMF
		 * has a default error status, complete it here
		 * to wake the waiting thread.
		 */
		if (tmf) {
			tmf_completion = tmf->complete;
			tmf->complete = NULL;
		}
		ireq->ttype_ptr.tmf_task_ptr = NULL;
		dev_dbg(&ihost->pdev->dev, "%s: tmf_code %d, managed tag %#x\n",
			__func__, tmf->tmf_code, tmf->io_tag);
	} else {
		/* Break links with the sas_task - the callback is done
		 * elsewhere.
		 */
		struct sas_task *task = isci_request_access_task(ireq);

		if (task)
			task->lldd_task = NULL;

		ireq->ttype_ptr.io_task_ptr = NULL;
	}

	dev_warn(&ihost->pdev->dev, "task context unrecoverable (tag: %#x)\n",
		 ireq->io_tag);

	/* Don't force waiting threads to timeout. */
	if (req_completion)
		complete(req_completion);

	if (tmf_completion != NULL)
		complete(tmf_completion);
}
void
isci_task_request_complete(struct isci_host *ihost,
			   struct isci_request *ireq,
			   enum sci_task_status completion_status)
{
	struct isci_tmf *tmf = isci_request_access_tmf(ireq);
	struct completion *tmf_complete = NULL;
	struct completion *request_complete = ireq->io_request_completion;

	dev_dbg(&ihost->pdev->dev,
		"%s: request = %p, status=%d\n",
		__func__, ireq, completion_status);

	isci_request_change_state(ireq, completed);

	set_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags);

	if (tmf) {
		tmf->status = completion_status;

		if (tmf->proto == SAS_PROTOCOL_SSP) {
			memcpy(&tmf->resp.resp_iu,
			       &ireq->ssp.rsp,
			       SSP_RESP_IU_MAX_SIZE);
		} else if (tmf->proto == SAS_PROTOCOL_SATA) {
			memcpy(&tmf->resp.d2h_fis,
			       &ireq->stp.rsp,
			       sizeof(struct dev_to_host_fis));
		}
		
		tmf_complete = tmf->complete;
	}
	sci_controller_complete_io(ihost, ireq->target_device, ireq);
	set_bit(IREQ_TERMINATED, &ireq->flags);

	if ((ireq->status == completed) ||
	    !isci_request_is_dealloc_managed(ireq->status)) {
		isci_request_change_state(ireq, unallocated);
		isci_free_tag(ihost, ireq->io_tag);
		list_del_init(&ireq->dev_node);
	}

	
	if (request_complete)
		complete(request_complete);

	
	if (tmf_complete)
		complete(tmf_complete);
}
Beispiel #4
0
/*
 * isci_task_request_complete() - This function is called by the sci core when
 *    an task request completes.
 * @ihost: This parameter specifies the ISCI host object
 * @ireq: This parameter is the completed isci_request object.
 * @completion_status: This parameter specifies the completion status from the
 *    sci core.
 *
 * none.
 */
void
isci_task_request_complete(struct isci_host *ihost,
			   struct isci_request *ireq,
			   enum sci_task_status completion_status)
{
	struct isci_tmf *tmf = isci_request_access_tmf(ireq);
	struct completion *tmf_complete = NULL;

	dev_dbg(&ihost->pdev->dev,
		"%s: request = %p, status=%d\n",
		__func__, ireq, completion_status);

	set_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags);

	if (tmf) {
		tmf->status = completion_status;

		if (tmf->proto == SAS_PROTOCOL_SSP) {
			memcpy(&tmf->resp.resp_iu,
			       &ireq->ssp.rsp,
			       SSP_RESP_IU_MAX_SIZE);
		} else if (tmf->proto == SAS_PROTOCOL_SATA) {
			memcpy(&tmf->resp.d2h_fis,
			       &ireq->stp.rsp,
			       sizeof(struct dev_to_host_fis));
		}
		/* PRINT_TMF( ((struct isci_tmf *)request->task)); */
		tmf_complete = tmf->complete;
	}
	sci_controller_complete_io(ihost, ireq->target_device, ireq);
	/* set the 'terminated' flag handle to make sure it cannot be terminated
	 *  or completed again.
	 */
	set_bit(IREQ_TERMINATED, &ireq->flags);

	if (test_and_clear_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags))
		wake_up_all(&ihost->eventq);

	if (!test_bit(IREQ_NO_AUTO_FREE_TAG, &ireq->flags))
		isci_free_tag(ihost, ireq->io_tag);

	/* The task management part completes last. */
	if (tmf_complete)
		complete(tmf_complete);
}
static void isci_request_mark_zombie(struct isci_host *ihost, struct isci_request *ireq)
{
	struct completion *tmf_completion = NULL;
	struct completion *req_completion;

	
	ireq->status = dead;

	req_completion = ireq->io_request_completion;
	ireq->io_request_completion = NULL;

	if (test_bit(IREQ_TMF, &ireq->flags)) {
		
		struct isci_tmf *tmf = isci_request_access_tmf(ireq);

		if (tmf) {
			tmf_completion = tmf->complete;
			tmf->complete = NULL;
		}
		ireq->ttype_ptr.tmf_task_ptr = NULL;
		dev_dbg(&ihost->pdev->dev, "%s: tmf_code %d, managed tag %#x\n",
			__func__, tmf->tmf_code, tmf->io_tag);
	} else {
		struct sas_task *task = isci_request_access_task(ireq);

		if (task)
			task->lldd_task = NULL;

		ireq->ttype_ptr.io_task_ptr = NULL;
	}

	dev_warn(&ihost->pdev->dev, "task context unrecoverable (tag: %#x)\n",
		 ireq->io_tag);

	
	if (req_completion)
		complete(req_completion);

	if (tmf_completion != NULL)
		complete(tmf_completion);
}