Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit af5ae893 authored by Dave Jiang's avatar Dave Jiang Committed by Dan Williams
Browse files

isci: Convert of sci_ssp_response_iu to ssp_response_iu



Converting to Linux native format. However the isci driver does a lot of
the calculation based on the max size of this data structure and the
Linux data structure only has a pointer to the response data. Thus the
sizeof(struct ssp_response_iu) will be incorrect and we need to define
the max size.

Signed-off-by: default avatarDave Jiang <dave.jiang@intel.com>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 0cfa890e
Loading
Loading
Loading
Loading
+0 −46
Original line number Original line Diff line number Diff line
@@ -160,52 +160,6 @@ enum sci_sas_frame_type {
	SCI_SAS_TASK_FRAME = 0x16
	SCI_SAS_TASK_FRAME = 0x16
};
};


#define SSP_RESPONSE_IU_MAX_DATA 64

#define SCI_SSP_RESPONSE_IU_DATA_PRESENT_MASK   (0x03)


#define sci_ssp_get_sense_data_length(sense_data_length_buffer)	\
	SCIC_BUILD_DWORD(sense_data_length_buffer)

#define sci_ssp_get_response_data_length(response_data_length_buffer) \
	SCIC_BUILD_DWORD(response_data_length_buffer)

/**
 * struct sci_ssp_response_iu - This structure depicts the contents of the SSP
 *    RESPONSE INFORMATION UNIT. For specific information on each of these
 *    individual fields please reference the SAS specification SSP transport
 *    layer section.
 *
 *
 */
struct sci_ssp_response_iu {
	u8 reserved0[8];

	u8 retry_delay_timer[2];
	u8 data_present;
	u8 status;

	u8 reserved1[4];
	u8 sense_data_length[4];
	u8 response_data_length[4];

	u32 data[SSP_RESPONSE_IU_MAX_DATA];

};

/**
 * enum _SCI_SAS_DATA_PRESENT_TYPE - This enumeration depicts the SAS
 *    specification defined SSP data present types in struct sci_ssp_response_iu.
 *
 *
 */
enum sci_ssp_response_iu_data_present_type {
	SCI_SSP_RESPONSE_IU_NO_DATA = 0x00,
	SCI_SSP_RESPONSE_IU_RESPONSE_DATA = 0x01,
	SCI_SSP_RESPONSE_IU_SENSE_DATA = 0x02
};

/**
/**
 * struct sci_ssp_frame_header - This structure depicts the contents of an SSP
 * struct sci_ssp_frame_header - This structure depicts the contents of an SSP
 *    frame header.  For specific information on the individual fields please
 *    frame header.  For specific information on the individual fields please
+95 −127
Original line number Original line Diff line number Diff line
@@ -100,7 +100,7 @@
#define scic_ssp_io_request_get_object_size() \
#define scic_ssp_io_request_get_object_size() \
	(\
	(\
		sizeof(struct ssp_cmd_iu) \
		sizeof(struct ssp_cmd_iu) \
		+ sizeof(struct sci_ssp_response_iu)	\
		+ SSP_RESP_IU_MAX_SIZE	\
	)
	)


/**
/**
@@ -121,7 +121,7 @@
 * memory
 * memory
 */
 */
#define scic_sds_ssp_request_get_response_buffer(memory) \
#define scic_sds_ssp_request_get_response_buffer(memory) \
	((struct sci_ssp_response_iu *)(\
	((struct ssp_response_iu *)(\
		 ((char *)(scic_sds_ssp_request_get_command_buffer(memory))) \
		 ((char *)(scic_sds_ssp_request_get_command_buffer(memory))) \
		 + sizeof(struct ssp_cmd_iu)	\
		 + sizeof(struct ssp_cmd_iu)	\
		 ))
		 ))
@@ -135,7 +135,7 @@
#define scic_sds_ssp_request_get_task_context_buffer(memory) \
#define scic_sds_ssp_request_get_task_context_buffer(memory) \
	((struct scu_task_context *)(\
	((struct scu_task_context *)(\
		 ((char *)(scic_sds_ssp_request_get_response_buffer(memory))) \
		 ((char *)(scic_sds_ssp_request_get_response_buffer(memory))) \
		 + sizeof(struct sci_ssp_response_iu) \
		 + SSP_RESP_IU_MAX_SIZE \
		 ))
		 ))


/**
/**
@@ -160,7 +160,7 @@
#define scic_ssp_task_request_get_object_size()	\
#define scic_ssp_task_request_get_object_size()	\
	(\
	(\
		sizeof(struct ssp_task_iu) \
		sizeof(struct ssp_task_iu) \
		+ sizeof(struct sci_ssp_response_iu)	\
		+ SSP_RESP_IU_MAX_SIZE \
	)
	)


/**
/**
@@ -181,7 +181,7 @@
 * request memory.
 * request memory.
 */
 */
#define scic_sds_ssp_task_request_get_response_buffer(memory) \
#define scic_sds_ssp_task_request_get_response_buffer(memory) \
	((struct sci_ssp_response_iu *)(\
	((struct ssp_response_iu *)(\
		 ((char *)(scic_sds_ssp_task_request_get_command_buffer(memory))) \
		 ((char *)(scic_sds_ssp_task_request_get_command_buffer(memory))) \
		 + sizeof(struct ssp_task_iu) \
		 + sizeof(struct ssp_task_iu) \
		 ))
		 ))
@@ -194,7 +194,7 @@
#define scic_sds_ssp_task_request_get_task_context_buffer(memory) \
#define scic_sds_ssp_task_request_get_task_context_buffer(memory) \
	((struct scu_task_context *)(\
	((struct scu_task_context *)(\
		 ((char *)(scic_sds_ssp_task_request_get_response_buffer(memory))) \
		 ((char *)(scic_sds_ssp_task_request_get_response_buffer(memory))) \
		 + sizeof(struct sci_ssp_response_iu) \
		 + SSP_RESP_IU_MAX_SIZE \
		 ))
		 ))




@@ -937,52 +937,29 @@ enum sci_status scic_sds_io_request_frame_handler(
	return SCI_FAILURE_INVALID_STATE;
	return SCI_FAILURE_INVALID_STATE;
}
}


/**
 *
 * @sci_req: The SCIC_SDS_IO_REQUEST_T object for which the task start
 *    operation is to be executed.
 *
 * This method invokes the core state task complete handler for the
 * SCIC_SDS_IO_REQUEST_T object. enum sci_status
 */

/*
/*
 * ****************************************************************************
 * This function copies response data for requests returning response data
 * * SCIC SDS PROTECTED METHODS
 * **************************************************************************** */

/**
 * This method copies response data for requests returning response data
 *    instead of sense data.
 *    instead of sense data.
 * @sci_req: This parameter specifies the request object for which to copy
 * @sci_req: This parameter specifies the request object for which to copy
 *    the response data.
 *    the response data.
 *
 */
 */
void scic_sds_io_request_copy_response(struct scic_sds_request *sds_request)
void scic_sds_io_request_copy_response(struct scic_sds_request *sci_req)
{
{
	void *response_buffer;
	void *resp_buf;
	u32 user_response_length;
	u32 len;
	u32 core_response_length;
	struct ssp_response_iu *ssp_response;
	struct sci_ssp_response_iu *ssp_response;
	struct isci_request *ireq = sci_req->ireq;
	struct isci_request *isci_request = sds_request->ireq;
	struct isci_tmf *isci_tmf = isci_request_access_tmf(ireq);

	ssp_response =
		(struct sci_ssp_response_iu *)sds_request->response_buffer;

	response_buffer =
		isci_task_ssp_request_get_response_data_address(
				isci_request);


	user_response_length =
	ssp_response = sci_req->response_buffer;
		isci_task_ssp_request_get_response_data_length(
				isci_request);


	core_response_length = sci_ssp_get_response_data_length(
	resp_buf = &isci_tmf->resp.resp_iu;
					ssp_response->response_data_length);


	user_response_length = min(user_response_length, core_response_length);
	len = min_t(u32,
		    SSP_RESP_IU_MAX_SIZE,
		    be32_to_cpu(ssp_response->response_data_len));


	memcpy(response_buffer, ssp_response->data, user_response_length);
	memcpy(resp_buf, ssp_response->resp_data, len);
}
}


/*
/*
@@ -1102,7 +1079,7 @@ enum sci_status scic_sds_request_started_state_abort_handler(
	return SCI_SUCCESS;
	return SCI_SUCCESS;
}
}


/**
/*
 * scic_sds_request_started_state_tc_completion_handler() - This method process
 * scic_sds_request_started_state_tc_completion_handler() - This method process
 *    TC (task context) completions for normal IO request (i.e. Task/Abort
 *    TC (task context) completions for normal IO request (i.e. Task/Abort
 *    Completions of type 0).  This method will update the
 *    Completions of type 0).  This method will update the
@@ -1113,50 +1090,51 @@ enum sci_status scic_sds_request_started_state_abort_handler(
 *    the SCU.
 *    the SCU.
 *
 *
 */
 */
enum sci_status scic_sds_request_started_state_tc_completion_handler(
enum sci_status
scic_sds_request_started_state_tc_completion_handler(
		struct scic_sds_request *sci_req,
		struct scic_sds_request *sci_req,
		u32 completion_code)
		u32 completion_code)
{
{
	u8 data_present;
	u8 datapres;
	struct sci_ssp_response_iu *response_buffer;
	struct ssp_response_iu *resp_iu;


	/**
	/*
	 * @todo Any SDMA return code of other than 0 is bad
	 * TODO: Any SDMA return code of other than 0 is bad
	 *       decode 0x003C0000 to determine SDMA status
	 *       decode 0x003C0000 to determine SDMA status
	 */
	 */
	switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
	switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
		scic_sds_request_set_status(
		scic_sds_request_set_status(sci_req,
			sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS
					    SCU_TASK_DONE_GOOD,
			);
					    SCI_SUCCESS);
		break;
		break;


	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_EARLY_RESP):
	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_EARLY_RESP):
	{
	{
		/*
		/*
		 * There are times when the SCU hardware will return an early response
		 * There are times when the SCU hardware will return an early
		 * because the io request specified more data than is returned by the
		 * response because the io request specified more data than is
		 * target device (mode pages, inquiry data, etc.).  We must check the
		 * returned by the target device (mode pages, inquiry data,
		 * response stats to see if this is truly a failed request or a good
		 * etc.).  We must check the response stats to see if this is
		 * request that just got completed early. */
		 * truly a failed request or a good request that just got
		struct sci_ssp_response_iu *response = (struct sci_ssp_response_iu *)
		 * completed early.
						  sci_req->response_buffer;
		 */
		struct ssp_response_iu *resp = sci_req->response_buffer;
		scic_word_copy_with_swap(
		scic_word_copy_with_swap(
			sci_req->response_buffer,
			sci_req->response_buffer,
			sci_req->response_buffer,
			sci_req->response_buffer,
			sizeof(struct sci_ssp_response_iu) / sizeof(u32)
			SSP_RESP_IU_MAX_SIZE / sizeof(u32));
			);


		if (response->status == 0) {
		if (resp->status == 0) {
			scic_sds_request_set_status(
			scic_sds_request_set_status(
				sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS_IO_DONE_EARLY
				sci_req,
				);
				SCU_TASK_DONE_GOOD,
				SCI_SUCCESS_IO_DONE_EARLY);
		} else {
		} else {
			scic_sds_request_set_status(
			scic_sds_request_set_status(
				sci_req,
				sci_req,
				SCU_TASK_DONE_CHECK_RESPONSE,
				SCU_TASK_DONE_CHECK_RESPONSE,
				SCI_FAILURE_IO_RESPONSE_VALID
				SCI_FAILURE_IO_RESPONSE_VALID);
				);
		}
		}
	}
	}
	break;
	break;
@@ -1165,36 +1143,31 @@ enum sci_status scic_sds_request_started_state_tc_completion_handler(
		scic_word_copy_with_swap(
		scic_word_copy_with_swap(
			sci_req->response_buffer,
			sci_req->response_buffer,
			sci_req->response_buffer,
			sci_req->response_buffer,
			sizeof(struct sci_ssp_response_iu) / sizeof(u32)
			SSP_RESP_IU_MAX_SIZE / sizeof(u32));
			);


		scic_sds_request_set_status(
		scic_sds_request_set_status(
			sci_req,
			sci_req,
			SCU_TASK_DONE_CHECK_RESPONSE,
			SCU_TASK_DONE_CHECK_RESPONSE,
			SCI_FAILURE_IO_RESPONSE_VALID
			SCI_FAILURE_IO_RESPONSE_VALID);
			);
		break;
		break;


	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RESP_LEN_ERR):
	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RESP_LEN_ERR):
		/*
		/*
		 * / @todo With TASK_DONE_RESP_LEN_ERR is the response frame guaranteed
		 * / @todo With TASK_DONE_RESP_LEN_ERR is the response frame
		 * /       to be received before this completion status is posted? */
		 * guaranteed to be received before this completion status is
		response_buffer =
		 * posted?
			(struct sci_ssp_response_iu *)sci_req->response_buffer;
		 */
		data_present =
		resp_iu = sci_req->response_buffer;
			response_buffer->data_present & SCI_SSP_RESPONSE_IU_DATA_PRESENT_MASK;
		datapres = resp_iu->datapres;


		if ((data_present == 0x01) || (data_present == 0x02)) {
		if ((datapres == 0x01) || (datapres == 0x02)) {
			scic_sds_request_set_status(
			scic_sds_request_set_status(
				sci_req,
				sci_req,
				SCU_TASK_DONE_CHECK_RESPONSE,
				SCU_TASK_DONE_CHECK_RESPONSE,
				SCI_FAILURE_IO_RESPONSE_VALID
				SCI_FAILURE_IO_RESPONSE_VALID);
				);
		} else
		} else {
			scic_sds_request_set_status(
			scic_sds_request_set_status(
				sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS
				sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS);
				);
		}
		break;
		break;


	/* only stp device gets suspended. */
	/* only stp device gets suspended. */
@@ -1212,15 +1185,15 @@ enum sci_status scic_sds_request_started_state_tc_completion_handler(
		if (sci_req->protocol == SCIC_STP_PROTOCOL) {
		if (sci_req->protocol == SCIC_STP_PROTOCOL) {
			scic_sds_request_set_status(
			scic_sds_request_set_status(
				sci_req,
				sci_req,
				SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT,
				SCU_GET_COMPLETION_TL_STATUS(completion_code) >>
				SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED
				SCU_COMPLETION_TL_STATUS_SHIFT,
				);
				SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED);
		} else {
		} else {
			scic_sds_request_set_status(
			scic_sds_request_set_status(
				sci_req,
				sci_req,
				SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT,
				SCU_GET_COMPLETION_TL_STATUS(completion_code) >>
				SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
				SCU_COMPLETION_TL_STATUS_SHIFT,
				);
				SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR);
		}
		}
		break;
		break;


@@ -1237,9 +1210,9 @@ enum sci_status scic_sds_request_started_state_tc_completion_handler(
	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED):
	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED):
		scic_sds_request_set_status(
		scic_sds_request_set_status(
			sci_req,
			sci_req,
			SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT,
			SCU_GET_COMPLETION_TL_STATUS(completion_code) >>
			SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED
			SCU_COMPLETION_TL_STATUS_SHIFT,
			);
			SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED);
		break;
		break;


	/* neither ssp nor stp gets suspended. */
	/* neither ssp nor stp gets suspended. */
@@ -1261,18 +1234,19 @@ enum sci_status scic_sds_request_started_state_tc_completion_handler(
	default:
	default:
		scic_sds_request_set_status(
		scic_sds_request_set_status(
			sci_req,
			sci_req,
			SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT,
			SCU_GET_COMPLETION_TL_STATUS(completion_code) >>
			SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
			SCU_COMPLETION_TL_STATUS_SHIFT,
			);
			SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR);
		break;
		break;
	}
	}


	/**
	/*
	 * @todo This is probably wrong for ACK/NAK timeout conditions
	 * TODO: This is probably wrong for ACK/NAK timeout conditions
	 */
	 */


	/* In all cases we will treat this as the completion of the IO request. */
	/* In all cases we will treat this as the completion of the IO req. */
	sci_base_state_machine_change_state(&sci_req->state_machine,
	sci_base_state_machine_change_state(
			&sci_req->state_machine,
			SCI_BASE_REQUEST_STATE_COMPLETED);
			SCI_BASE_REQUEST_STATE_COMPLETED);
	return SCI_SUCCESS;
	return SCI_SUCCESS;
}
}
@@ -1285,49 +1259,42 @@ enum sci_status scic_sds_request_started_state_tc_completion_handler(
 * at completion time. If the frame type is not a response buffer an error is
 * at completion time. If the frame type is not a response buffer an error is
 * logged. enum sci_status SCI_SUCCESS SCI_FAILURE_INVALID_PARAMETER_VALUE
 * logged. enum sci_status SCI_SUCCESS SCI_FAILURE_INVALID_PARAMETER_VALUE
 */
 */
static enum sci_status scic_sds_request_started_state_frame_handler(
static enum sci_status
	struct scic_sds_request *sci_req,
scic_sds_request_started_state_frame_handler(struct scic_sds_request *sci_req,
					     u32 frame_index)
					     u32 frame_index)
{
{
	enum sci_status status;
	enum sci_status status;
	struct sci_ssp_frame_header *frame_header;
	struct sci_ssp_frame_header *frame_header;


	/* / @todo If this is a response frame we must record that we received it */
	status = scic_sds_unsolicited_frame_control_get_header(
	status = scic_sds_unsolicited_frame_control_get_header(
		&(scic_sds_request_get_controller(sci_req)->uf_control),
		&(scic_sds_request_get_controller(sci_req)->uf_control),
		frame_index,
		frame_index,
		(void **)&frame_header
		(void **)&frame_header);
		);


	if (frame_header->frame_type == SCI_SAS_RESPONSE_FRAME) {
	if (frame_header->frame_type == SCI_SAS_RESPONSE_FRAME) {
		struct sci_ssp_response_iu *response_buffer;
		struct ssp_response_iu *resp_iu;


		status = scic_sds_unsolicited_frame_control_get_buffer(
		status = scic_sds_unsolicited_frame_control_get_buffer(
			&(scic_sds_request_get_controller(sci_req)->uf_control),
			&(scic_sds_request_get_controller(sci_req)->uf_control),
			frame_index,
			frame_index,
			(void **)&response_buffer
			(void **)&resp_iu);
			);


		scic_word_copy_with_swap(
		scic_word_copy_with_swap(sci_req->response_buffer,
			sci_req->response_buffer,
					 (u32 *)resp_iu,
			(u32 *)response_buffer,
					 SSP_RESP_IU_MAX_SIZE);
			sizeof(struct sci_ssp_response_iu)
			);


		response_buffer = (struct sci_ssp_response_iu *)sci_req->response_buffer;
		resp_iu = sci_req->response_buffer;


		if ((response_buffer->data_present == 0x01) ||
		if ((resp_iu->datapres == 0x01) ||
		    (response_buffer->data_present == 0x02)) {
		    (resp_iu->datapres == 0x02)) {
			scic_sds_request_set_status(
			scic_sds_request_set_status(
				sci_req,
				sci_req,
				SCU_TASK_DONE_CHECK_RESPONSE,
				SCU_TASK_DONE_CHECK_RESPONSE,
				SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
				SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR);
				);
		} else
		} else
			scic_sds_request_set_status(
			scic_sds_request_set_status(
				sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS
				sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS);
				);
	} else {
	} else
		/* This was not a response frame why did it get forwarded? */
		/* This was not a response frame why did it get forwarded? */
		dev_err(scic_to_dev(sci_req->owning_controller),
		dev_err(scic_to_dev(sci_req->owning_controller),
			"%s: SCIC IO Request 0x%p received unexpected "
			"%s: SCIC IO Request 0x%p received unexpected "
@@ -1336,13 +1303,14 @@ static enum sci_status scic_sds_request_started_state_frame_handler(
			sci_req,
			sci_req,
			frame_index,
			frame_index,
			frame_header->frame_type);
			frame_header->frame_type);
	}


	/*
	/*
	 * In any case we are done with this frame buffer return it to the
	 * In any case we are done with this frame buffer return it to the
	 * controller */
	 * controller
	 */
	scic_sds_controller_release_frame(
	scic_sds_controller_release_frame(
		sci_req->owning_controller, frame_index
		sci_req->owning_controller, frame_index);
		);


	return SCI_SUCCESS;
	return SCI_SUCCESS;
}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -102,7 +102,7 @@
#define scic_sds_stp_request_get_task_context_buffer(memory) \
#define scic_sds_stp_request_get_task_context_buffer(memory) \
	((struct scu_task_context *)(\
	((struct scu_task_context *)(\
		 ((char *)(scic_sds_stp_request_get_response_buffer(memory))) \
		 ((char *)(scic_sds_stp_request_get_response_buffer(memory))) \
		 + sizeof(struct sci_ssp_response_iu) \
		 + SSP_RESP_IU_MAX_SIZE \
		 ))
		 ))


/**
/**
+3 −0
Original line number Original line Diff line number Diff line
@@ -69,6 +69,9 @@
#define FIS_PIO_SETUP       0x5F
#define FIS_PIO_SETUP       0x5F
#define FIS_DATA            0x46
#define FIS_DATA            0x46


/**************************************************************************/
#define SSP_RESP_IU_MAX_SIZE	280

/*
/*
 * contents of the SSP COMMAND INFORMATION UNIT.
 * contents of the SSP COMMAND INFORMATION UNIT.
 * For specific information on each of these individual fields please
 * For specific information on each of these individual fields please
+34 −66
Original line number Original line Diff line number Diff line
@@ -55,6 +55,7 @@


#include <linux/completion.h>
#include <linux/completion.h>
#include <linux/irqflags.h>
#include <linux/irqflags.h>
#include "sas.h"
#include "scic_task_request.h"
#include "scic_task_request.h"
#include "scic_io_request.h"
#include "scic_io_request.h"
#include "remote_device.h"
#include "remote_device.h"
@@ -63,7 +64,8 @@
#include "request.h"
#include "request.h"
#include "sata.h"
#include "sata.h"
#include "task.h"
#include "task.h"
#include "core/scic_sds_request.h"
#include "scic_sds_stp_request.h"

/**
/**
* isci_task_refuse() - complete the request to the upper layer driver in
* isci_task_refuse() - complete the request to the upper layer driver in
*     the case where an I/O needs to be completed back in the submit path.
*     the case where an I/O needs to be completed back in the submit path.
@@ -1411,108 +1413,74 @@ int isci_task_query_task(
		return TMF_RESP_FUNC_SUCC;
		return TMF_RESP_FUNC_SUCC;
}
}


/**
/*
 * isci_task_request_complete() - This function is called by the sci core when
 * isci_task_request_complete() - This function is called by the sci core when
 *    an task request completes.
 *    an task request completes.
 * @isci_host: This parameter specifies the ISCI host object
 * @ihost: This parameter specifies the ISCI host object
 * @request: This parameter is the completed isci_request object.
 * @ireq: This parameter is the completed isci_request object.
 * @completion_status: This parameter specifies the completion status from the
 * @completion_status: This parameter specifies the completion status from the
 *    sci core.
 *    sci core.
 *
 *
 * none.
 * none.
 */
 */
void isci_task_request_complete(
void
	struct isci_host *isci_host,
isci_task_request_complete(struct isci_host *ihost,
	struct isci_request *request,
			   struct isci_request *ireq,
			   enum sci_task_status completion_status)
			   enum sci_task_status completion_status)
{
{
	struct isci_remote_device *isci_device = request->isci_device;
	struct isci_remote_device *idev = ireq->isci_device;
	enum isci_request_status old_state;
	enum isci_request_status old_state;
	struct isci_tmf *tmf = isci_request_access_tmf(request);
	struct isci_tmf *tmf = isci_request_access_tmf(ireq);
	struct completion *tmf_complete;
	struct completion *tmf_complete;
	struct scic_sds_request *sci_req = ireq->sci_request_handle;
	struct scic_sds_stp_request *stp_req =
		container_of(sci_req, typeof(*stp_req), parent);


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


	old_state = isci_request_change_state(request, completed);
	old_state = isci_request_change_state(ireq, completed);


	tmf->status = completion_status;
	tmf->status = completion_status;
	request->complete_in_target = true;
	ireq->complete_in_target = true;

	if (SAS_PROTOCOL_SSP == tmf->proto) {


	if (tmf->proto == SAS_PROTOCOL_SSP) {
		memcpy(&tmf->resp.resp_iu,
		memcpy(&tmf->resp.resp_iu,
		       scic_io_request_get_response_iu_address(
		       sci_req->response_buffer,
			       request->sci_request_handle
		       SSP_RESP_IU_MAX_SIZE);
			       ),
	} else if (tmf->proto == SAS_PROTOCOL_SATA) {
		       sizeof(struct sci_ssp_response_iu));

	} else if (SAS_PROTOCOL_SATA == tmf->proto) {

		memcpy(&tmf->resp.d2h_fis,
		memcpy(&tmf->resp.d2h_fis,
		       scic_stp_io_request_get_d2h_reg_address(
		       &stp_req->d2h_reg_fis,
			       request->sci_request_handle),
		       sizeof(struct dev_to_host_fis));
		       sizeof(struct dev_to_host_fis));
	}
	}


	/* Manage the timer if it is still running. */
	/* Manage the timer if it is still running. */
	if (tmf->timeout_timer) {
	if (tmf->timeout_timer) {
		isci_del_timer(isci_host, tmf->timeout_timer);
		isci_del_timer(ihost, tmf->timeout_timer);
		tmf->timeout_timer = NULL;
		tmf->timeout_timer = NULL;
	}
	}


	/* PRINT_TMF( ((struct isci_tmf *)request->task)); */
	/* PRINT_TMF( ((struct isci_tmf *)request->task)); */
	tmf_complete = tmf->complete;
	tmf_complete = tmf->complete;


	scic_controller_complete_io(
	scic_controller_complete_io(ihost->core_controller,
		isci_host->core_controller,
				    &idev->sci,
		&isci_device->sci,
				    ireq->sci_request_handle);
		request->sci_request_handle);

	/* NULL the request handle to make sure it cannot be terminated
	/*
	 * NULL the request handle to make sure it cannot be terminated
	 *  or completed again.
	 *  or completed again.
	 */
	 */
	request->sci_request_handle = NULL;
	ireq->sci_request_handle = NULL;


	isci_request_change_state(request, unallocated);
	isci_request_change_state(ireq, unallocated);
	list_del_init(&request->dev_node);
	list_del_init(&ireq->dev_node);


	/* The task management part completes last. */
	/* The task management part completes last. */
	complete(tmf_complete);
	complete(tmf_complete);
}
}


/**
 * isci_task_ssp_request_get_response_data_address() - This function is called
 *    by the sci core to retrieve the response data address for a given task
 *    request.
 * @request: This parameter is the isci_request object.
 *
 * response data address for specified task request.
 */
void *isci_task_ssp_request_get_response_data_address(
	struct isci_request *request)
{
	struct isci_tmf *isci_tmf = isci_request_access_tmf(request);

	return &isci_tmf->resp.resp_iu;
}

/**
 * isci_task_ssp_request_get_response_data_length() - This function is called
 *    by the sci core to retrieve the response data length for a given task
 *    request.
 * @request: This parameter is the isci_request object.
 *
 * response data length for specified task request.
 */
u32 isci_task_ssp_request_get_response_data_length(
	struct isci_request *request)
{
	struct isci_tmf *isci_tmf = isci_request_access_tmf(request);

	return sizeof(isci_tmf->resp.resp_iu);
}

/**
/**
 * isci_bus_reset_handler() - This function performs a target reset of the
 * isci_bus_reset_handler() - This function performs a target reset of the
 *    device referenced by "cmd'.  This function is exported through the
 *    device referenced by "cmd'.  This function is exported through the
Loading