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

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
...@@ -160,52 +160,6 @@ enum sci_sas_frame_type { ...@@ -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
......
...@@ -100,7 +100,7 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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( ...@@ -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( ...@@ -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( ...@@ -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
struct scic_sds_request *sci_req, scic_sds_request_started_state_tc_completion_handler(
u32 completion_code) struct scic_sds_request *sci_req,
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( ...@@ -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( ...@@ -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( ...@@ -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,19 +1234,20 @@ enum sci_status scic_sds_request_started_state_tc_completion_handler( ...@@ -1261,19 +1234,20 @@ 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_BASE_REQUEST_STATE_COMPLETED); &sci_req->state_machine,
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( ...@@ -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( ...@@ -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;
} }
......
...@@ -102,7 +102,7 @@ ...@@ -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 \
)) ))
/** /**
......
...@@ -69,6 +69,9 @@ ...@@ -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
......
...@@ -55,6 +55,7 @@ ...@@ -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 @@ ...@@ -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( ...@@ -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
......
...@@ -99,7 +99,7 @@ struct isci_tmf { ...@@ -99,7 +99,7 @@ struct isci_tmf {
struct completion *complete; struct completion *complete;
enum sas_protocol proto; enum sas_protocol proto;
union { union {
struct sci_ssp_response_iu resp_iu; struct ssp_response_iu resp_iu;
struct dev_to_host_fis d2h_fis; struct dev_to_host_fis d2h_fis;
} resp; } resp;
unsigned char lun[8]; unsigned char lun[8];
...@@ -120,8 +120,7 @@ struct isci_tmf { ...@@ -120,8 +120,7 @@ struct isci_tmf {
}; };
static inline void isci_print_tmf( static inline void isci_print_tmf(struct isci_tmf *tmf)
struct isci_tmf *tmf)
{ {
if (SAS_PROTOCOL_SATA == tmf->proto) if (SAS_PROTOCOL_SATA == tmf->proto)
dev_dbg(&tmf->device->isci_port->isci_host->pdev->dev, dev_dbg(&tmf->device->isci_port->isci_host->pdev->dev,
...@@ -144,16 +143,13 @@ static inline void isci_print_tmf( ...@@ -144,16 +143,13 @@ static inline void isci_print_tmf(
"tmf->resp.resp_iu.data[3] = %x\n", "tmf->resp.resp_iu.data[3] = %x\n",
__func__, __func__,
tmf->status, tmf->status,
tmf->resp.resp_iu.data_present, tmf->resp.resp_iu.datapres,
tmf->resp.resp_iu.status, tmf->resp.resp_iu.status,
(tmf->resp.resp_iu.response_data_length[0] << 24) + be32_to_cpu(tmf->resp.resp_iu.response_data_len),
(tmf->resp.resp_iu.response_data_length[1] << 16) + tmf->resp.resp_iu.resp_data[0],
(tmf->resp.resp_iu.response_data_length[2] << 8) + tmf->resp.resp_iu.resp_data[1],
tmf->resp.resp_iu.response_data_length[3], tmf->resp.resp_iu.resp_data[2],
tmf->resp.resp_iu.data[0], tmf->resp.resp_iu.resp_data[3]);
tmf->resp.resp_iu.data[1],
tmf->resp.resp_iu.data[2],
tmf->resp.resp_iu.data[3]);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment