forked from Minki/linux
isci: have the driver use native SG calls and DMA-API
Remove abstraction for SG building and get rid of callbacks for getting DMA memory mapping. 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
103a00c200
commit
6389a77596
@ -84,3 +84,18 @@ void *scic_request_get_virt_addr(struct scic_sds_request *sci_req, dma_addr_t ph
|
|||||||
return (char *)ireq + offset;
|
return (char *)ireq + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dma_addr_t scic_io_request_get_dma_addr(struct scic_sds_request *sds_request,
|
||||||
|
void *virt_addr)
|
||||||
|
{
|
||||||
|
struct isci_request *isci_request =
|
||||||
|
(struct isci_request *)sci_object_get_association(sds_request);
|
||||||
|
|
||||||
|
char *requested_addr = (char *)virt_addr;
|
||||||
|
char *base_addr = (char *)isci_request;
|
||||||
|
|
||||||
|
BUG_ON(requested_addr < base_addr);
|
||||||
|
BUG_ON((requested_addr - base_addr) >=
|
||||||
|
isci_request->request_alloc_size);
|
||||||
|
|
||||||
|
return isci_request->request_daddr + (requested_addr - base_addr);
|
||||||
|
}
|
||||||
|
@ -102,4 +102,7 @@ void scic_word_copy_with_swap(u32 *destination, u32 *source, u32 word_count);
|
|||||||
void *scic_request_get_virt_addr(struct scic_sds_request *sds_request,
|
void *scic_request_get_virt_addr(struct scic_sds_request *sds_request,
|
||||||
dma_addr_t phys_addr);
|
dma_addr_t phys_addr);
|
||||||
|
|
||||||
|
dma_addr_t scic_io_request_get_dma_addr(struct scic_sds_request *sds_request,
|
||||||
|
void *virt_addr);
|
||||||
|
|
||||||
#endif /* _SCI_UTIL_H_ */
|
#endif /* _SCI_UTIL_H_ */
|
||||||
|
@ -259,56 +259,70 @@ static struct scu_sgl_element_pair *scic_sds_request_get_sgl_element_pair(
|
|||||||
* the Scatter-Gather List.
|
* the Scatter-Gather List.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void scic_sds_request_build_sgl(
|
void scic_sds_request_build_sgl(struct scic_sds_request *sds_request)
|
||||||
struct scic_sds_request *this_request)
|
|
||||||
{
|
{
|
||||||
void *os_sge;
|
struct isci_request *isci_request =
|
||||||
void *os_handle;
|
(struct isci_request *)sci_object_get_association(sds_request);
|
||||||
dma_addr_t physical_address;
|
struct isci_host *isci_host = isci_request->isci_host;
|
||||||
u32 sgl_pair_index = 0;
|
struct sas_task *task = isci_request_access_task(isci_request);
|
||||||
struct scu_sgl_element_pair *scu_sgl_list = NULL;
|
struct scatterlist *sg = NULL;
|
||||||
struct scu_sgl_element_pair *previous_pair = NULL;
|
dma_addr_t dma_addr;
|
||||||
|
u32 sg_idx = 0;
|
||||||
|
struct scu_sgl_element_pair *scu_sg = NULL;
|
||||||
|
struct scu_sgl_element_pair *prev_sg = NULL;
|
||||||
|
|
||||||
os_handle = scic_sds_request_get_user_request(this_request);
|
if (task->num_scatter > 0) {
|
||||||
scic_cb_io_request_get_next_sge(os_handle, NULL, &os_sge);
|
sg = task->scatter;
|
||||||
|
|
||||||
while (os_sge != NULL) {
|
while (sg) {
|
||||||
scu_sgl_list =
|
scu_sg = scic_sds_request_get_sgl_element_pair(
|
||||||
scic_sds_request_get_sgl_element_pair(this_request, sgl_pair_index);
|
sds_request,
|
||||||
|
sg_idx);
|
||||||
|
|
||||||
SCU_SGL_COPY(os_handle, scu_sgl_list->A, os_sge);
|
SCU_SGL_COPY(scu_sg->A, sg);
|
||||||
|
|
||||||
scic_cb_io_request_get_next_sge(os_handle, os_sge, &os_sge);
|
sg = sg_next(sg);
|
||||||
|
|
||||||
if (os_sge != NULL) {
|
if (sg) {
|
||||||
SCU_SGL_COPY(os_handle, scu_sgl_list->B, os_sge);
|
SCU_SGL_COPY(scu_sg->B, sg);
|
||||||
|
sg = sg_next(sg);
|
||||||
|
} else
|
||||||
|
SCU_SGL_ZERO(scu_sg->B);
|
||||||
|
|
||||||
scic_cb_io_request_get_next_sge(os_handle, os_sge, &os_sge);
|
if (prev_sg) {
|
||||||
} else {
|
dma_addr =
|
||||||
SCU_SGL_ZERO(scu_sgl_list->B);
|
scic_io_request_get_dma_addr(
|
||||||
|
sds_request,
|
||||||
|
scu_sg);
|
||||||
|
|
||||||
|
prev_sg->next_pair_upper =
|
||||||
|
upper_32_bits(dma_addr);
|
||||||
|
prev_sg->next_pair_lower =
|
||||||
|
lower_32_bits(dma_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_sg = scu_sg;
|
||||||
|
sg_idx++;
|
||||||
}
|
}
|
||||||
|
} else { /* handle when no sg */
|
||||||
|
scu_sg = scic_sds_request_get_sgl_element_pair(sds_request,
|
||||||
|
sg_idx);
|
||||||
|
|
||||||
if (previous_pair != NULL) {
|
dma_addr = dma_map_single(&isci_host->pdev->dev,
|
||||||
scic_cb_io_request_get_physical_address(
|
task->scatter,
|
||||||
scic_sds_request_get_controller(this_request),
|
task->total_xfer_len,
|
||||||
this_request,
|
task->data_dir);
|
||||||
scu_sgl_list,
|
|
||||||
&physical_address
|
|
||||||
);
|
|
||||||
|
|
||||||
previous_pair->next_pair_upper =
|
isci_request->zero_scatter_daddr = dma_addr;
|
||||||
upper_32_bits(physical_address);
|
|
||||||
previous_pair->next_pair_lower =
|
|
||||||
lower_32_bits(physical_address);
|
|
||||||
}
|
|
||||||
|
|
||||||
previous_pair = scu_sgl_list;
|
scu_sg->A.length = task->total_xfer_len;
|
||||||
sgl_pair_index++;
|
scu_sg->A.address_upper = upper_32_bits(dma_addr);
|
||||||
|
scu_sg->A.address_lower = lower_32_bits(dma_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scu_sgl_list != NULL) {
|
if (scu_sg) {
|
||||||
scu_sgl_list->next_pair_upper = 0;
|
scu_sg->next_pair_upper = 0;
|
||||||
scu_sgl_list->next_pair_lower = 0;
|
scu_sg->next_pair_lower = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,17 +487,17 @@ static void scic_sds_task_request_build_ssp_task_iu(
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void scu_ssp_reqeust_construct_task_context(
|
static void scu_ssp_reqeust_construct_task_context(
|
||||||
struct scic_sds_request *this_request,
|
struct scic_sds_request *sds_request,
|
||||||
struct scu_task_context *task_context)
|
struct scu_task_context *task_context)
|
||||||
{
|
{
|
||||||
dma_addr_t physical_address;
|
dma_addr_t dma_addr;
|
||||||
struct scic_sds_controller *owning_controller;
|
struct scic_sds_controller *controller;
|
||||||
struct scic_sds_remote_device *target_device;
|
struct scic_sds_remote_device *target_device;
|
||||||
struct scic_sds_port *target_port;
|
struct scic_sds_port *target_port;
|
||||||
|
|
||||||
owning_controller = scic_sds_request_get_controller(this_request);
|
controller = scic_sds_request_get_controller(sds_request);
|
||||||
target_device = scic_sds_request_get_device(this_request);
|
target_device = scic_sds_request_get_device(sds_request);
|
||||||
target_port = scic_sds_request_get_port(this_request);
|
target_port = scic_sds_request_get_port(sds_request);
|
||||||
|
|
||||||
/* Fill in the TC with the its required data */
|
/* Fill in the TC with the its required data */
|
||||||
task_context->abort = 0;
|
task_context->abort = 0;
|
||||||
@ -492,7 +506,7 @@ static void scu_ssp_reqeust_construct_task_context(
|
|||||||
task_context->connection_rate =
|
task_context->connection_rate =
|
||||||
scic_remote_device_get_connection_rate(target_device);
|
scic_remote_device_get_connection_rate(target_device);
|
||||||
task_context->protocol_engine_index =
|
task_context->protocol_engine_index =
|
||||||
scic_sds_controller_get_protocol_engine_group(owning_controller);
|
scic_sds_controller_get_protocol_engine_group(controller);
|
||||||
task_context->logical_port_index =
|
task_context->logical_port_index =
|
||||||
scic_sds_port_get_index(target_port);
|
scic_sds_port_get_index(target_port);
|
||||||
task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SSP;
|
task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SSP;
|
||||||
@ -500,7 +514,7 @@ static void scu_ssp_reqeust_construct_task_context(
|
|||||||
task_context->context_type = SCU_TASK_CONTEXT_TYPE;
|
task_context->context_type = SCU_TASK_CONTEXT_TYPE;
|
||||||
|
|
||||||
task_context->remote_node_index =
|
task_context->remote_node_index =
|
||||||
scic_sds_remote_device_get_index(this_request->target_device);
|
scic_sds_remote_device_get_index(sds_request->target_device);
|
||||||
task_context->command_code = 0;
|
task_context->command_code = 0;
|
||||||
|
|
||||||
task_context->link_layer_control = 0;
|
task_context->link_layer_control = 0;
|
||||||
@ -515,61 +529,55 @@ static void scu_ssp_reqeust_construct_task_context(
|
|||||||
/* task_context->type.ssp.tag = this_request->io_tag; */
|
/* task_context->type.ssp.tag = this_request->io_tag; */
|
||||||
task_context->task_phase = 0x01;
|
task_context->task_phase = 0x01;
|
||||||
|
|
||||||
if (this_request->was_tag_assigned_by_user) {
|
if (sds_request->was_tag_assigned_by_user) {
|
||||||
/* Build the task context now since we have already read the data */
|
/*
|
||||||
this_request->post_context = (
|
* Build the task context now since we have already read
|
||||||
SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
|
* the data
|
||||||
| (
|
*/
|
||||||
scic_sds_controller_get_protocol_engine_group(owning_controller)
|
sds_request->post_context =
|
||||||
<< SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
|
(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
|
||||||
)
|
(scic_sds_controller_get_protocol_engine_group(
|
||||||
| (
|
controller) <<
|
||||||
scic_sds_port_get_index(target_port)
|
SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
|
||||||
<< SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
|
(scic_sds_port_get_index(target_port) <<
|
||||||
)
|
SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
|
||||||
| scic_sds_io_tag_get_index(this_request->io_tag)
|
scic_sds_io_tag_get_index(sds_request->io_tag));
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
/* Build the task context now since we have already read the data */
|
/*
|
||||||
this_request->post_context = (
|
* Build the task context now since we have already read
|
||||||
SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
|
* the data
|
||||||
| (
|
*
|
||||||
scic_sds_controller_get_protocol_engine_group(owning_controller)
|
* I/O tag index is not assigned because we have to wait
|
||||||
<< SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
|
* until we get a TCi
|
||||||
)
|
*/
|
||||||
| (
|
sds_request->post_context =
|
||||||
scic_sds_port_get_index(target_port)
|
(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
|
||||||
<< SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
|
(scic_sds_controller_get_protocol_engine_group(
|
||||||
)
|
owning_controller) <<
|
||||||
/* This is not assigned because we have to wait until we get a TCi */
|
SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
|
||||||
);
|
(scic_sds_port_get_index(target_port) <<
|
||||||
|
SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the physical address for the command buffer to the SCU Task Context */
|
/*
|
||||||
scic_cb_io_request_get_physical_address(
|
* Copy the physical address for the command buffer to the
|
||||||
scic_sds_request_get_controller(this_request),
|
* SCU Task Context
|
||||||
this_request,
|
*/
|
||||||
this_request->command_buffer,
|
dma_addr = scic_io_request_get_dma_addr(sds_request,
|
||||||
&physical_address
|
sds_request->command_buffer);
|
||||||
);
|
|
||||||
|
|
||||||
task_context->command_iu_upper =
|
task_context->command_iu_upper = upper_32_bits(dma_addr);
|
||||||
upper_32_bits(physical_address);
|
task_context->command_iu_lower = lower_32_bits(dma_addr);
|
||||||
task_context->command_iu_lower =
|
|
||||||
lower_32_bits(physical_address);
|
|
||||||
|
|
||||||
/* Copy the physical address for the response buffer to the SCU Task Context */
|
/*
|
||||||
scic_cb_io_request_get_physical_address(
|
* Copy the physical address for the response buffer to the
|
||||||
scic_sds_request_get_controller(this_request),
|
* SCU Task Context
|
||||||
this_request,
|
*/
|
||||||
this_request->response_buffer,
|
dma_addr = scic_io_request_get_dma_addr(sds_request,
|
||||||
&physical_address
|
sds_request->response_buffer);
|
||||||
);
|
|
||||||
|
|
||||||
task_context->response_iu_upper =
|
task_context->response_iu_upper = upper_32_bits(dma_addr);
|
||||||
upper_32_bits(physical_address);
|
task_context->response_iu_lower = lower_32_bits(dma_addr);
|
||||||
task_context->response_iu_lower =
|
|
||||||
lower_32_bits(physical_address);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -389,14 +389,13 @@ extern const struct scic_sds_io_request_state_handler scic_sds_smp_request_start
|
|||||||
* This macro copys the SGL Element data from the host os to the hardware SGL
|
* This macro copys the SGL Element data from the host os to the hardware SGL
|
||||||
* elment data
|
* elment data
|
||||||
*/
|
*/
|
||||||
#define SCU_SGL_COPY(os_handle, scu_sge, os_sge) \
|
#define SCU_SGL_COPY(scu_sge, os_sge) \
|
||||||
{ \
|
{ \
|
||||||
(scu_sge).length = \
|
(scu_sge).length = sg_dma_len(sg); \
|
||||||
scic_cb_sge_get_length_field(os_handle, os_sge); \
|
|
||||||
(scu_sge).address_upper = \
|
(scu_sge).address_upper = \
|
||||||
upper_32_bits(scic_cb_sge_get_address_field(os_handle, os_sge)); \
|
upper_32_bits(sg_dma_address(sg)); \
|
||||||
(scu_sge).address_lower = \
|
(scu_sge).address_lower = \
|
||||||
lower_32_bits(scic_cb_sge_get_address_field(os_handle, os_sge)); \
|
lower_32_bits(sg_dma_address(sg)); \
|
||||||
(scu_sge).address_modifier = 0; \
|
(scu_sge).address_modifier = 0; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,37 +234,36 @@ enum sci_status scic_io_request_construct_smp(
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void scu_smp_request_construct_task_context(
|
static void scu_smp_request_construct_task_context(
|
||||||
struct scic_sds_request *this_request,
|
struct scic_sds_request *sds_request,
|
||||||
struct smp_request *smp_request)
|
struct smp_request *smp_request)
|
||||||
{
|
{
|
||||||
dma_addr_t physical_address;
|
dma_addr_t dma_addr;
|
||||||
struct scic_sds_controller *owning_controller;
|
struct scic_sds_controller *controller;
|
||||||
struct scic_sds_remote_device *target_device;
|
struct scic_sds_remote_device *target_device;
|
||||||
struct scic_sds_port *target_port;
|
struct scic_sds_port *target_port;
|
||||||
struct scu_task_context *task_context;
|
struct scu_task_context *task_context;
|
||||||
|
|
||||||
/* byte swap the smp request. */
|
/* byte swap the smp request. */
|
||||||
scic_word_copy_with_swap(
|
scic_word_copy_with_swap(sds_request->command_buffer,
|
||||||
this_request->command_buffer,
|
(u32 *)smp_request,
|
||||||
(u32 *)smp_request,
|
sizeof(struct smp_request) / sizeof(u32));
|
||||||
sizeof(struct smp_request) / sizeof(u32)
|
|
||||||
);
|
|
||||||
|
|
||||||
task_context = scic_sds_request_get_task_context(this_request);
|
task_context = scic_sds_request_get_task_context(sds_request);
|
||||||
|
|
||||||
owning_controller = scic_sds_request_get_controller(this_request);
|
controller = scic_sds_request_get_controller(sds_request);
|
||||||
target_device = scic_sds_request_get_device(this_request);
|
target_device = scic_sds_request_get_device(sds_request);
|
||||||
target_port = scic_sds_request_get_port(this_request);
|
target_port = scic_sds_request_get_port(sds_request);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fill in the TC with the its required data
|
* Fill in the TC with the its required data
|
||||||
* 00h */
|
* 00h
|
||||||
|
*/
|
||||||
task_context->priority = 0;
|
task_context->priority = 0;
|
||||||
task_context->initiator_request = 1;
|
task_context->initiator_request = 1;
|
||||||
task_context->connection_rate =
|
task_context->connection_rate =
|
||||||
scic_remote_device_get_connection_rate(target_device);
|
scic_remote_device_get_connection_rate(target_device);
|
||||||
task_context->protocol_engine_index =
|
task_context->protocol_engine_index =
|
||||||
scic_sds_controller_get_protocol_engine_group(owning_controller);
|
scic_sds_controller_get_protocol_engine_group(controller);
|
||||||
task_context->logical_port_index =
|
task_context->logical_port_index =
|
||||||
scic_sds_port_get_index(target_port);
|
scic_sds_port_get_index(target_port);
|
||||||
task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SMP;
|
task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SMP;
|
||||||
@ -273,7 +272,8 @@ static void scu_smp_request_construct_task_context(
|
|||||||
task_context->context_type = SCU_TASK_CONTEXT_TYPE;
|
task_context->context_type = SCU_TASK_CONTEXT_TYPE;
|
||||||
|
|
||||||
/* 04h */
|
/* 04h */
|
||||||
task_context->remote_node_index = this_request->target_device->rnc->remote_node_index;
|
task_context->remote_node_index =
|
||||||
|
sds_request->target_device->rnc->remote_node_index;
|
||||||
task_context->command_code = 0;
|
task_context->command_code = 0;
|
||||||
task_context->task_type = SCU_TASK_TYPE_SMP_REQUEST;
|
task_context->task_type = SCU_TASK_TYPE_SMP_REQUEST;
|
||||||
|
|
||||||
@ -289,7 +289,8 @@ static void scu_smp_request_construct_task_context(
|
|||||||
task_context->address_modifier = 0;
|
task_context->address_modifier = 0;
|
||||||
|
|
||||||
/* 10h */
|
/* 10h */
|
||||||
task_context->ssp_command_iu_length = smp_request->header.request_length;
|
task_context->ssp_command_iu_length =
|
||||||
|
smp_request->header.request_length;
|
||||||
|
|
||||||
/* 14h */
|
/* 14h */
|
||||||
task_context->transfer_length_bytes = 0;
|
task_context->transfer_length_bytes = 0;
|
||||||
@ -298,59 +299,57 @@ static void scu_smp_request_construct_task_context(
|
|||||||
* 18h ~ 30h, protocol specific
|
* 18h ~ 30h, protocol specific
|
||||||
* since commandIU has been build by framework at this point, we just
|
* since commandIU has been build by framework at this point, we just
|
||||||
* copy the frist DWord from command IU to this location. */
|
* copy the frist DWord from command IU to this location. */
|
||||||
memcpy((void *)(&task_context->type.smp), this_request->command_buffer, sizeof(u32));
|
memcpy((void *)(&task_context->type.smp),
|
||||||
|
sds_request->command_buffer,
|
||||||
|
sizeof(u32));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 40h
|
* 40h
|
||||||
* "For SMP you could program it to zero. We would prefer that way so that
|
* "For SMP you could program it to zero. We would prefer that way
|
||||||
* done code will be consistent." - Venki */
|
* so that done code will be consistent." - Venki
|
||||||
|
*/
|
||||||
task_context->task_phase = 0;
|
task_context->task_phase = 0;
|
||||||
|
|
||||||
if (this_request->was_tag_assigned_by_user) {
|
if (sds_request->was_tag_assigned_by_user) {
|
||||||
/* Build the task context now since we have already read the data */
|
/*
|
||||||
this_request->post_context = (
|
* Build the task context now since we have already read
|
||||||
SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
|
* the data
|
||||||
| (
|
*/
|
||||||
scic_sds_controller_get_protocol_engine_group(owning_controller)
|
sds_request->post_context =
|
||||||
<< SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
|
(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
|
||||||
)
|
(scic_sds_controller_get_protocol_engine_group(
|
||||||
| (
|
controller) <<
|
||||||
scic_sds_port_get_index(target_port)
|
SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
|
||||||
<< SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
|
(scic_sds_port_get_index(target_port) <<
|
||||||
)
|
SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
|
||||||
| scic_sds_io_tag_get_index(this_request->io_tag)
|
scic_sds_io_tag_get_index(sds_request->io_tag));
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
/* Build the task context now since we have already read the data */
|
/*
|
||||||
this_request->post_context = (
|
* Build the task context now since we have already read
|
||||||
SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
|
* the data.
|
||||||
| (
|
* I/O tag index is not assigned because we have to wait
|
||||||
scic_sds_controller_get_protocol_engine_group(owning_controller)
|
* until we get a TCi.
|
||||||
<< SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
|
*/
|
||||||
)
|
sds_request->post_context =
|
||||||
| (
|
(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
|
||||||
scic_sds_port_get_index(target_port)
|
(scic_sds_controller_get_protocol_engine_group(
|
||||||
<< SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
|
controller) <<
|
||||||
)
|
SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
|
||||||
/* This is not assigned because we have to wait until we get a TCi */
|
(scic_sds_port_get_index(target_port) <<
|
||||||
);
|
SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy the physical address for the command buffer to the SCU Task Context
|
* Copy the physical address for the command buffer to the SCU Task
|
||||||
* command buffer should not contain command header. */
|
* Context command buffer should not contain command header.
|
||||||
scic_cb_io_request_get_physical_address(
|
*/
|
||||||
scic_sds_request_get_controller(this_request),
|
dma_addr = scic_io_request_get_dma_addr(sds_request,
|
||||||
this_request,
|
(char *)
|
||||||
((char *)(this_request->command_buffer) + sizeof(u32)),
|
(sds_request->command_buffer) +
|
||||||
&physical_address
|
sizeof(u32));
|
||||||
);
|
|
||||||
|
|
||||||
task_context->command_iu_upper =
|
|
||||||
upper_32_bits(physical_address);
|
|
||||||
task_context->command_iu_lower =
|
|
||||||
lower_32_bits(physical_address);
|
|
||||||
|
|
||||||
|
task_context->command_iu_upper = upper_32_bits(dma_addr);
|
||||||
|
task_context->command_iu_lower = lower_32_bits(dma_addr);
|
||||||
|
|
||||||
/* SMP response comes as UF, so no need to set response IU address. */
|
/* SMP response comes as UF, so no need to set response IU address. */
|
||||||
task_context->response_iu_upper = 0;
|
task_context->response_iu_upper = 0;
|
||||||
|
@ -253,30 +253,26 @@ enum sci_status scic_sds_stp_packet_request_process_status_fis(
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void scic_sds_stp_packet_internal_request_sense_build_sgl(
|
void scic_sds_stp_packet_internal_request_sense_build_sgl(
|
||||||
struct scic_sds_request *this_request)
|
struct scic_sds_request *sds_request)
|
||||||
{
|
{
|
||||||
void *sge;
|
void *sge;
|
||||||
struct scu_sgl_element_pair *scu_sgl_list = NULL;
|
struct scu_sgl_element_pair *scu_sgl_list = NULL;
|
||||||
struct scu_task_context *task_context;
|
struct scu_task_context *task_context;
|
||||||
dma_addr_t physical_address;
|
dma_addr_t dma_addr;
|
||||||
|
|
||||||
struct sci_ssp_response_iu *rsp_iu =
|
struct sci_ssp_response_iu *rsp_iu =
|
||||||
(struct sci_ssp_response_iu *)this_request->response_buffer;
|
(struct sci_ssp_response_iu *)sds_request->response_buffer;
|
||||||
|
|
||||||
sge = (void *)&rsp_iu->data[0];
|
sge = (void *)&rsp_iu->data[0];
|
||||||
|
|
||||||
task_context = (struct scu_task_context *)this_request->task_context_buffer;
|
task_context =
|
||||||
|
(struct scu_task_context *)sds_request->task_context_buffer;
|
||||||
scu_sgl_list = &task_context->sgl_pair_ab;
|
scu_sgl_list = &task_context->sgl_pair_ab;
|
||||||
|
|
||||||
scic_cb_io_request_get_physical_address(
|
dma_addr = scic_io_request_get_dma_addr(sds_request, sge);
|
||||||
scic_sds_request_get_controller(this_request),
|
|
||||||
this_request,
|
|
||||||
((char *)sge),
|
|
||||||
&physical_address
|
|
||||||
);
|
|
||||||
|
|
||||||
scu_sgl_list->A.address_upper = sci_cb_physical_address_upper(physical_address);
|
scu_sgl_list->A.address_upper = upper_32_bits(dma_addr);
|
||||||
scu_sgl_list->A.address_lower = sci_cb_physical_address_lower(physical_address);
|
scu_sgl_list->A.address_lower = lower_32_bits(dma_addr);
|
||||||
scu_sgl_list->A.length = task_context->transfer_length_bytes;
|
scu_sgl_list->A.length = task_context->transfer_length_bytes;
|
||||||
scu_sgl_list->A.address_modifier = 0;
|
scu_sgl_list->A.address_modifier = 0;
|
||||||
|
|
||||||
|
@ -175,17 +175,17 @@ void scic_sds_stp_request_assign_buffers(
|
|||||||
* determine what is common for SSP/SMP/STP task context structures.
|
* determine what is common for SSP/SMP/STP task context structures.
|
||||||
*/
|
*/
|
||||||
static void scu_sata_reqeust_construct_task_context(
|
static void scu_sata_reqeust_construct_task_context(
|
||||||
struct scic_sds_request *this_request,
|
struct scic_sds_request *sds_request,
|
||||||
struct scu_task_context *task_context)
|
struct scu_task_context *task_context)
|
||||||
{
|
{
|
||||||
dma_addr_t physical_address;
|
dma_addr_t dma_addr;
|
||||||
struct scic_sds_controller *owning_controller;
|
struct scic_sds_controller *controller;
|
||||||
struct scic_sds_remote_device *target_device;
|
struct scic_sds_remote_device *target_device;
|
||||||
struct scic_sds_port *target_port;
|
struct scic_sds_port *target_port;
|
||||||
|
|
||||||
owning_controller = scic_sds_request_get_controller(this_request);
|
controller = scic_sds_request_get_controller(sds_request);
|
||||||
target_device = scic_sds_request_get_device(this_request);
|
target_device = scic_sds_request_get_device(sds_request);
|
||||||
target_port = scic_sds_request_get_port(this_request);
|
target_port = scic_sds_request_get_port(sds_request);
|
||||||
|
|
||||||
/* Fill in the TC with the its required data */
|
/* Fill in the TC with the its required data */
|
||||||
task_context->abort = 0;
|
task_context->abort = 0;
|
||||||
@ -194,7 +194,7 @@ static void scu_sata_reqeust_construct_task_context(
|
|||||||
task_context->connection_rate =
|
task_context->connection_rate =
|
||||||
scic_remote_device_get_connection_rate(target_device);
|
scic_remote_device_get_connection_rate(target_device);
|
||||||
task_context->protocol_engine_index =
|
task_context->protocol_engine_index =
|
||||||
scic_sds_controller_get_protocol_engine_group(owning_controller);
|
scic_sds_controller_get_protocol_engine_group(controller);
|
||||||
task_context->logical_port_index =
|
task_context->logical_port_index =
|
||||||
scic_sds_port_get_index(target_port);
|
scic_sds_port_get_index(target_port);
|
||||||
task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_STP;
|
task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_STP;
|
||||||
@ -202,7 +202,7 @@ static void scu_sata_reqeust_construct_task_context(
|
|||||||
task_context->context_type = SCU_TASK_CONTEXT_TYPE;
|
task_context->context_type = SCU_TASK_CONTEXT_TYPE;
|
||||||
|
|
||||||
task_context->remote_node_index =
|
task_context->remote_node_index =
|
||||||
scic_sds_remote_device_get_index(this_request->target_device);
|
scic_sds_remote_device_get_index(sds_request->target_device);
|
||||||
task_context->command_code = 0;
|
task_context->command_code = 0;
|
||||||
|
|
||||||
task_context->link_layer_control = 0;
|
task_context->link_layer_control = 0;
|
||||||
@ -219,53 +219,50 @@ static void scu_sata_reqeust_construct_task_context(
|
|||||||
(sizeof(struct sata_fis_reg_h2d) - sizeof(u32)) / sizeof(u32);
|
(sizeof(struct sata_fis_reg_h2d) - sizeof(u32)) / sizeof(u32);
|
||||||
|
|
||||||
/* Set the first word of the H2D REG FIS */
|
/* Set the first word of the H2D REG FIS */
|
||||||
task_context->type.words[0] = *(u32 *)this_request->command_buffer;
|
task_context->type.words[0] = *(u32 *)sds_request->command_buffer;
|
||||||
|
|
||||||
if (this_request->was_tag_assigned_by_user) {
|
if (sds_request->was_tag_assigned_by_user) {
|
||||||
/* Build the task context now since we have already read the data */
|
/*
|
||||||
this_request->post_context = (
|
* Build the task context now since we have already read
|
||||||
SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
|
* the data
|
||||||
| (
|
*/
|
||||||
scic_sds_controller_get_protocol_engine_group(owning_controller)
|
sds_request->post_context =
|
||||||
<< SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
|
(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
|
||||||
)
|
(scic_sds_controller_get_protocol_engine_group(
|
||||||
| (
|
controller) <<
|
||||||
scic_sds_port_get_index(target_port)
|
SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
|
||||||
<< SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
|
(scic_sds_port_get_index(target_port) <<
|
||||||
)
|
SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
|
||||||
| scic_sds_io_tag_get_index(this_request->io_tag)
|
scic_sds_io_tag_get_index(sds_request->io_tag));
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
/* Build the task context now since we have already read the data */
|
/*
|
||||||
this_request->post_context = (
|
* Build the task context now since we have already read
|
||||||
SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
|
* the data.
|
||||||
| (
|
* I/O tag index is not assigned because we have to wait
|
||||||
scic_sds_controller_get_protocol_engine_group(owning_controller)
|
* until we get a TCi.
|
||||||
<< SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
|
*/
|
||||||
)
|
sds_request->post_context =
|
||||||
| (
|
(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
|
||||||
scic_sds_port_get_index(target_port)
|
(scic_sds_controller_get_protocol_engine_group(
|
||||||
<< SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
|
controller) <<
|
||||||
)
|
SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
|
||||||
/* This is not assigned because we have to wait until we get a TCi */
|
(scic_sds_port_get_index(target_port) <<
|
||||||
);
|
SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy the physical address for the command buffer to the SCU Task Context
|
* Copy the physical address for the command buffer to the SCU Task
|
||||||
* We must offset the command buffer by 4 bytes because the first 4 bytes are
|
* Context. We must offset the command buffer by 4 bytes because the
|
||||||
* transfered in the body of the TC */
|
* first 4 bytes are transfered in the body of the TC.
|
||||||
scic_cb_io_request_get_physical_address(
|
*/
|
||||||
scic_sds_request_get_controller(this_request),
|
dma_addr =
|
||||||
this_request,
|
scic_io_request_get_dma_addr(sds_request,
|
||||||
((char *)this_request->command_buffer) + sizeof(u32),
|
(char *)sds_request->
|
||||||
&physical_address
|
command_buffer +
|
||||||
);
|
sizeof(u32));
|
||||||
|
|
||||||
task_context->command_iu_upper =
|
task_context->command_iu_upper = upper_32_bits(dma_addr);
|
||||||
upper_32_bits(physical_address);
|
task_context->command_iu_lower = lower_32_bits(dma_addr);
|
||||||
task_context->command_iu_lower =
|
|
||||||
lower_32_bits(physical_address);
|
|
||||||
|
|
||||||
/* SATA Requests do not have a response buffer */
|
/* SATA Requests do not have a response buffer */
|
||||||
task_context->response_iu_upper = 0;
|
task_context->response_iu_upper = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user