forked from Minki/linux
isci: Fixup SSP command IU and task IU
Fixup of SSP command IU and SSP task IU to something that looks like Linux Signed-off-by: Dave Jiang <dave.jiang@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
ed0e24830e
commit
0cfa890e5a
@ -160,53 +160,6 @@ enum sci_sas_frame_type {
|
||||
SCI_SAS_TASK_FRAME = 0x16
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sci_ssp_command_iu - This structure depicts the contents of the SSP
|
||||
* COMMAND INFORMATION UNIT. For specific information on each of these
|
||||
* individual fields please reference the SAS specification SSP transport
|
||||
* layer section.
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct sci_ssp_command_iu {
|
||||
u32 lun_upper;
|
||||
u32 lun_lower;
|
||||
|
||||
u32 additional_cdb_length:6;
|
||||
u32 reserved0:2;
|
||||
u32 reserved1:8;
|
||||
u32 enable_first_burst:1;
|
||||
u32 task_priority:4;
|
||||
u32 task_attribute:3;
|
||||
u32 reserved2:8;
|
||||
|
||||
u32 cdb[4];
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sci_ssp_task_iu - This structure depicts the contents of the SSP TASK
|
||||
* INFORMATION UNIT. For specific information on each of these individual
|
||||
* fields please reference the SAS specification SSP transport layer section.
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct sci_ssp_task_iu {
|
||||
u32 lun_upper;
|
||||
u32 lun_lower;
|
||||
|
||||
u32 reserved0:8;
|
||||
u32 task_function:8;
|
||||
u32 reserved1:8;
|
||||
u32 reserved2:8;
|
||||
|
||||
u32 reserved3:16;
|
||||
u32 task_tag:16;
|
||||
|
||||
u32 reserved4[3];
|
||||
|
||||
};
|
||||
|
||||
#define SSP_RESPONSE_IU_MAX_DATA 64
|
||||
|
||||
#define SCI_SSP_RESPONSE_IU_DATA_PRESENT_MASK (0x03)
|
||||
|
@ -54,6 +54,7 @@
|
||||
*/
|
||||
|
||||
#include <scsi/sas.h>
|
||||
#include "sas.h"
|
||||
#include "intel_sas.h"
|
||||
#include "scic_controller.h"
|
||||
#include "scic_io_request.h"
|
||||
@ -98,7 +99,7 @@
|
||||
*/
|
||||
#define scic_ssp_io_request_get_object_size() \
|
||||
(\
|
||||
sizeof(struct sci_ssp_command_iu) \
|
||||
sizeof(struct ssp_cmd_iu) \
|
||||
+ sizeof(struct sci_ssp_response_iu) \
|
||||
)
|
||||
|
||||
@ -109,7 +110,7 @@
|
||||
* memory
|
||||
*/
|
||||
#define scic_sds_ssp_request_get_command_buffer(memory) \
|
||||
((struct sci_ssp_command_iu *)(\
|
||||
((struct ssp_cmd_iu *)(\
|
||||
((char *)(memory)) + sizeof(struct scic_sds_request) \
|
||||
))
|
||||
|
||||
@ -122,7 +123,7 @@
|
||||
#define scic_sds_ssp_request_get_response_buffer(memory) \
|
||||
((struct sci_ssp_response_iu *)(\
|
||||
((char *)(scic_sds_ssp_request_get_command_buffer(memory))) \
|
||||
+ sizeof(struct sci_ssp_command_iu) \
|
||||
+ sizeof(struct ssp_cmd_iu) \
|
||||
))
|
||||
|
||||
/**
|
||||
@ -158,7 +159,7 @@
|
||||
*/
|
||||
#define scic_ssp_task_request_get_object_size() \
|
||||
(\
|
||||
sizeof(struct sci_ssp_task_iu) \
|
||||
sizeof(struct ssp_task_iu) \
|
||||
+ sizeof(struct sci_ssp_response_iu) \
|
||||
)
|
||||
|
||||
@ -169,7 +170,7 @@
|
||||
* memory. Yes its the same as the above macro except for the name.
|
||||
*/
|
||||
#define scic_sds_ssp_task_request_get_command_buffer(memory) \
|
||||
((struct sci_ssp_task_iu *)(\
|
||||
((struct ssp_task_iu *)(\
|
||||
((char *)(memory)) + sizeof(struct scic_sds_request) \
|
||||
))
|
||||
|
||||
@ -182,7 +183,7 @@
|
||||
#define scic_sds_ssp_task_request_get_response_buffer(memory) \
|
||||
((struct sci_ssp_response_iu *)(\
|
||||
((char *)(scic_sds_ssp_task_request_get_command_buffer(memory))) \
|
||||
+ sizeof(struct sci_ssp_task_iu) \
|
||||
+ sizeof(struct ssp_task_iu) \
|
||||
))
|
||||
|
||||
/**
|
||||
@ -344,80 +345,49 @@ static void scic_sds_ssp_io_request_assign_buffers(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method constructs the SSP Command IU data for this io request object.
|
||||
* @sci_req: This parameter specifies the request object for which the SSP
|
||||
* command information unit is being built.
|
||||
*
|
||||
*/
|
||||
static void scic_sds_io_request_build_ssp_command_iu(
|
||||
struct scic_sds_request *sds_request)
|
||||
static void scic_sds_io_request_build_ssp_command_iu(struct scic_sds_request *sci_req)
|
||||
{
|
||||
struct sci_ssp_command_iu *command_frame;
|
||||
u32 cdb_length;
|
||||
u32 *cdb_buffer;
|
||||
struct isci_request *isci_request = sds_request->ireq;
|
||||
struct ssp_cmd_iu *cmd_iu;
|
||||
struct isci_request *ireq = sci_req->ireq;
|
||||
struct sas_task *task = isci_request_access_task(ireq);
|
||||
|
||||
command_frame =
|
||||
(struct sci_ssp_command_iu *)sds_request->command_buffer;
|
||||
cmd_iu = sci_req->command_buffer;
|
||||
|
||||
command_frame->lun_upper = 0;
|
||||
command_frame->lun_lower =
|
||||
isci_request_ssp_io_request_get_lun(isci_request);
|
||||
memcpy(cmd_iu->LUN, task->ssp_task.LUN, 8);
|
||||
cmd_iu->add_cdb_len = 0;
|
||||
cmd_iu->_r_a = 0;
|
||||
cmd_iu->_r_b = 0;
|
||||
cmd_iu->en_fburst = 0; /* unsupported */
|
||||
cmd_iu->task_prio = task->ssp_task.task_prio;
|
||||
cmd_iu->task_attr = task->ssp_task.task_attr;
|
||||
cmd_iu->_r_c = 0;
|
||||
|
||||
((u32 *)command_frame)[2] = 0;
|
||||
|
||||
cdb_length = isci_request_ssp_io_request_get_cdb_length(isci_request);
|
||||
cdb_buffer = (u32 *)isci_request_ssp_io_request_get_cdb_address(
|
||||
isci_request);
|
||||
|
||||
if (cdb_length > 16) {
|
||||
command_frame->additional_cdb_length = cdb_length - 16;
|
||||
}
|
||||
|
||||
/* / @todo Is it ok to leave junk at the end of the cdb buffer? */
|
||||
scic_word_copy_with_swap(
|
||||
(u32 *)(&command_frame->cdb),
|
||||
(u32 *)(cdb_buffer),
|
||||
(cdb_length + 3) / sizeof(u32)
|
||||
);
|
||||
|
||||
command_frame->enable_first_burst = 0;
|
||||
command_frame->task_priority =
|
||||
isci_request_ssp_io_request_get_command_priority(isci_request);
|
||||
command_frame->task_attribute =
|
||||
isci_request_ssp_io_request_get_task_attribute(isci_request);
|
||||
(u32 *)(&cmd_iu->cdb),
|
||||
(u32 *)task->ssp_task.cdb,
|
||||
sizeof(task->ssp_task.cdb) / sizeof(u32));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method constructs the SSP Task IU data for this io request object.
|
||||
* @sci_req:
|
||||
*
|
||||
*/
|
||||
static void scic_sds_task_request_build_ssp_task_iu(
|
||||
struct scic_sds_request *sds_request)
|
||||
static void scic_sds_task_request_build_ssp_task_iu(struct scic_sds_request *sci_req)
|
||||
{
|
||||
struct sci_ssp_task_iu *command_frame;
|
||||
struct isci_request *isci_request = sds_request->ireq;
|
||||
struct ssp_task_iu *task_iu;
|
||||
struct isci_request *ireq = sci_req->ireq;
|
||||
struct sas_task *task = isci_request_access_task(ireq);
|
||||
struct isci_tmf *isci_tmf = isci_request_access_tmf(ireq);
|
||||
|
||||
command_frame =
|
||||
(struct sci_ssp_task_iu *)sds_request->command_buffer;
|
||||
task_iu = sci_req->command_buffer;
|
||||
|
||||
command_frame->lun_upper = 0;
|
||||
command_frame->lun_lower = isci_request_ssp_io_request_get_lun(
|
||||
isci_request);
|
||||
memset(task_iu, 0, sizeof(struct ssp_task_iu));
|
||||
|
||||
((u32 *)command_frame)[2] = 0;
|
||||
memcpy(task_iu->LUN, task->ssp_task.LUN, 8);
|
||||
|
||||
command_frame->task_function =
|
||||
isci_task_ssp_request_get_function(isci_request);
|
||||
command_frame->task_tag =
|
||||
isci_task_ssp_request_get_io_tag_to_manage(
|
||||
isci_request);
|
||||
task_iu->task_func = isci_tmf->tmf_code;
|
||||
task_iu->task_tag =
|
||||
(ireq->ttype == tmf_task) ?
|
||||
isci_tmf->io_tag :
|
||||
SCI_CONTROLLER_INVALID_IO_TAG;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method is will fill in the SCU Task Context for any type of SSP request.
|
||||
* @sci_req:
|
||||
@ -533,7 +503,8 @@ static void scu_ssp_io_request_construct_task_context(
|
||||
|
||||
scu_ssp_reqeust_construct_task_context(sci_req, task_context);
|
||||
|
||||
task_context->ssp_command_iu_length = sizeof(struct sci_ssp_command_iu) / sizeof(u32);
|
||||
task_context->ssp_command_iu_length =
|
||||
sizeof(struct ssp_cmd_iu) / sizeof(u32);
|
||||
task_context->type.ssp.frame_type = SCI_SAS_COMMAND_FRAME;
|
||||
|
||||
switch (dir) {
|
||||
@ -605,7 +576,8 @@ static void scu_ssp_task_request_construct_task_context(
|
||||
task_context->task_type = SCU_TASK_TYPE_RAW_FRAME;
|
||||
task_context->transfer_length_bytes = 0;
|
||||
task_context->type.ssp.frame_type = SCI_SAS_TASK_FRAME;
|
||||
task_context->ssp_command_iu_length = sizeof(struct sci_ssp_task_iu) / sizeof(u32);
|
||||
task_context->ssp_command_iu_length =
|
||||
sizeof(struct ssp_task_iu) / sizeof(u32);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1241,124 +1241,3 @@ enum dma_data_direction isci_request_io_request_get_data_direction(
|
||||
|
||||
return task->data_dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* isci_request_sge_get_address_field() - This function is called by the sci
|
||||
* core to retrieve the address field contents for a given sge.
|
||||
* @request: This parameter is the isci_request object.
|
||||
* @sge_address: This parameter is the sge.
|
||||
*
|
||||
* physical address in the specified sge.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* isci_request_sge_get_length_field() - This function is called by the sci
|
||||
* core to retrieve the length field contents for a given sge.
|
||||
* @request: This parameter is the isci_request object.
|
||||
* @sge_address: This parameter is the sge.
|
||||
*
|
||||
* length field value in the specified sge.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* isci_request_ssp_io_request_get_cdb_address() - This function is called by
|
||||
* the sci core to retrieve the cdb address for a given request.
|
||||
* @request: This parameter is the isci_request object.
|
||||
*
|
||||
* cdb address for specified request.
|
||||
*/
|
||||
void *isci_request_ssp_io_request_get_cdb_address(
|
||||
struct isci_request *request)
|
||||
{
|
||||
struct sas_task *task = isci_request_access_task(request);
|
||||
|
||||
dev_dbg(&request->isci_host->pdev->dev,
|
||||
"%s: request->task->ssp_task.cdb = %p\n",
|
||||
__func__,
|
||||
task->ssp_task.cdb);
|
||||
return task->ssp_task.cdb;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* isci_request_ssp_io_request_get_cdb_length() - This function is called by
|
||||
* the sci core to retrieve the cdb length for a given request.
|
||||
* @request: This parameter is the isci_request object.
|
||||
*
|
||||
* cdb length for specified request.
|
||||
*/
|
||||
u32 isci_request_ssp_io_request_get_cdb_length(
|
||||
struct isci_request *request)
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* isci_request_ssp_io_request_get_lun() - This function is called by the sci
|
||||
* core to retrieve the lun for a given request.
|
||||
* @request: This parameter is the isci_request object.
|
||||
*
|
||||
* lun for specified request.
|
||||
*/
|
||||
u32 isci_request_ssp_io_request_get_lun(
|
||||
struct isci_request *request)
|
||||
{
|
||||
struct sas_task *task = isci_request_access_task(request);
|
||||
|
||||
#ifdef DEBUG
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
dev_dbg(&request->isci_host->pdev->dev,
|
||||
"%s: task->ssp_task.LUN[%d] = %x\n",
|
||||
__func__, i, task->ssp_task.LUN[i]);
|
||||
|
||||
#endif
|
||||
|
||||
return task->ssp_task.LUN[0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* isci_request_ssp_io_request_get_task_attribute() - This function is called
|
||||
* by the sci core to retrieve the task attribute for a given request.
|
||||
* @request: This parameter is the isci_request object.
|
||||
*
|
||||
* task attribute for specified request.
|
||||
*/
|
||||
u32 isci_request_ssp_io_request_get_task_attribute(
|
||||
struct isci_request *request)
|
||||
{
|
||||
struct sas_task *task = isci_request_access_task(request);
|
||||
|
||||
dev_dbg(&request->isci_host->pdev->dev,
|
||||
"%s: request->task->ssp_task.task_attr = %x\n",
|
||||
__func__,
|
||||
task->ssp_task.task_attr);
|
||||
|
||||
return task->ssp_task.task_attr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* isci_request_ssp_io_request_get_command_priority() - This function is called
|
||||
* by the sci core to retrieve the command priority for a given request.
|
||||
* @request: This parameter is the isci_request object.
|
||||
*
|
||||
* command priority for specified request.
|
||||
*/
|
||||
u32 isci_request_ssp_io_request_get_command_priority(
|
||||
struct isci_request *request)
|
||||
{
|
||||
struct sas_task *task = isci_request_access_task(request);
|
||||
|
||||
dev_dbg(&request->isci_host->pdev->dev,
|
||||
"%s: request->task->ssp_task.task_prio = %x\n",
|
||||
__func__,
|
||||
task->ssp_task.task_prio);
|
||||
|
||||
return task->ssp_task.task_prio;
|
||||
}
|
||||
|
@ -69,4 +69,38 @@
|
||||
#define FIS_PIO_SETUP 0x5F
|
||||
#define FIS_DATA 0x46
|
||||
|
||||
/*
|
||||
* contents of the SSP COMMAND INFORMATION UNIT.
|
||||
* For specific information on each of these individual fields please
|
||||
* reference the SAS specification SSP transport layer section.
|
||||
* XXX: This needs to go into <scsi/sas.h>
|
||||
*/
|
||||
struct ssp_cmd_iu {
|
||||
u8 LUN[8];
|
||||
u8 add_cdb_len:6;
|
||||
u8 _r_a:2;
|
||||
u8 _r_b;
|
||||
u8 en_fburst:1;
|
||||
u8 task_prio:4;
|
||||
u8 task_attr:3;
|
||||
u8 _r_c;
|
||||
|
||||
u8 cdb[16];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* contents of the SSP TASK INFORMATION UNIT.
|
||||
* For specific information on each of these individual fields please
|
||||
* reference the SAS specification SSP transport layer section.
|
||||
* XXX: This needs to go into <scsi/sas.h>
|
||||
*/
|
||||
struct ssp_task_iu {
|
||||
u8 LUN[8];
|
||||
u8 _r_a;
|
||||
u8 task_func;
|
||||
u8 _r_b[4];
|
||||
u16 task_tag;
|
||||
u8 _r_c[12];
|
||||
} __packed;
|
||||
|
||||
#endif
|
||||
|
@ -1481,55 +1481,6 @@ void isci_task_request_complete(
|
||||
complete(tmf_complete);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* isci_task_ssp_request_get_lun() - This function is called by the sci core to
|
||||
* retrieve the lun for a given task request.
|
||||
* @request: This parameter is the isci_request object.
|
||||
*
|
||||
* lun for specified task request.
|
||||
*/
|
||||
|
||||
/**
|
||||
* isci_task_ssp_request_get_function() - This function is called by the sci
|
||||
* core to retrieve the function for a given task request.
|
||||
* @request: This parameter is the isci_request object.
|
||||
*
|
||||
* function code for specified task request.
|
||||
*/
|
||||
u8 isci_task_ssp_request_get_function(struct isci_request *request)
|
||||
{
|
||||
struct isci_tmf *isci_tmf = isci_request_access_tmf(request);
|
||||
|
||||
dev_dbg(&request->isci_host->pdev->dev,
|
||||
"%s: func = %d\n", __func__, isci_tmf->tmf_code);
|
||||
|
||||
return isci_tmf->tmf_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* isci_task_ssp_request_get_io_tag_to_manage() - This function is called by
|
||||
* the sci core to retrieve the io tag for a given task request.
|
||||
* @request: This parameter is the isci_request object.
|
||||
*
|
||||
* io tag for specified task request.
|
||||
*/
|
||||
u16 isci_task_ssp_request_get_io_tag_to_manage(struct isci_request *request)
|
||||
{
|
||||
u16 io_tag = SCI_CONTROLLER_INVALID_IO_TAG;
|
||||
|
||||
if (tmf_task == request->ttype) {
|
||||
struct isci_tmf *tmf = isci_request_access_tmf(request);
|
||||
io_tag = tmf->io_tag;
|
||||
}
|
||||
|
||||
dev_dbg(&request->isci_host->pdev->dev,
|
||||
"%s: request = %p, io_tag = %d\n",
|
||||
__func__, request, io_tag);
|
||||
|
||||
return io_tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
Loading…
Reference in New Issue
Block a user