isci: unify can_queue tracking on the tci_pool, uplevel tag assignment
The tci_pool tracks our outstanding command slots which are also the 'index'
portion of our tags. Grabbing the tag early in ->lldd_execute_task let's us
drop the isci_host_can_queue() and ->was_tag_assigned_by_user infrastructure.
->was_tag_assigned_by_user required the task context to be duplicated in
request-local buffer. With the tci established early we can build the
task_context directly into its final location and skip a memcpy.
With the task context buffer at a known address at request construction we
have the opportunity/obligation to also fix sgl handling. This rework feels
like it belongs in another patch but the sgl handling and task_context are too
intertwined.
1/ fix the 'ab' pair embedded in the task context to point to the 'cd' pair in
the task context (previously we were prematurely linking to the staging
buffer).
2/ fix the broken iteration of pio sgls that assumes all sgls are relative to
the request, and does a dangerous looking reverse lookup of physical
address to virtual address.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c
index 5f4a4e3..0e84e29 100644
--- a/drivers/scsi/isci/port.c
+++ b/drivers/scsi/isci/port.c
@@ -695,35 +695,21 @@
*/
static void scic_sds_port_construct_dummy_task(struct scic_sds_port *sci_port, u16 tag)
{
+ struct scic_sds_controller *scic = sci_port->owning_controller;
struct scu_task_context *task_context;
- task_context = scic_sds_controller_get_task_context_buffer(sci_port->owning_controller, tag);
-
+ task_context = &scic->task_context_table[ISCI_TAG_TCI(tag)];
memset(task_context, 0, sizeof(struct scu_task_context));
- task_context->abort = 0;
- task_context->priority = 0;
task_context->initiator_request = 1;
task_context->connection_rate = 1;
- task_context->protocol_engine_index = 0;
task_context->logical_port_index = sci_port->physical_port_index;
task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SSP;
task_context->task_index = ISCI_TAG_TCI(tag);
task_context->valid = SCU_TASK_CONTEXT_VALID;
task_context->context_type = SCU_TASK_CONTEXT_TYPE;
-
task_context->remote_node_index = sci_port->reserved_rni;
- task_context->command_code = 0;
-
- task_context->link_layer_control = 0;
task_context->do_not_dma_ssp_good_response = 1;
- task_context->strict_ordering = 0;
- task_context->control_frame = 0;
- task_context->timeout_enable = 0;
- task_context->block_guard_enable = 0;
-
- task_context->address_modifier = 0;
-
task_context->task_phase = 0x01;
}
@@ -731,15 +717,15 @@
{
struct scic_sds_controller *scic = sci_port->owning_controller;
- if (sci_port->reserved_tci != SCU_DUMMY_INDEX)
- scic_controller_free_io_tag(scic, sci_port->reserved_tci);
+ if (sci_port->reserved_tag != SCI_CONTROLLER_INVALID_IO_TAG)
+ isci_free_tag(scic_to_ihost(scic), sci_port->reserved_tag);
if (sci_port->reserved_rni != SCU_DUMMY_INDEX)
scic_sds_remote_node_table_release_remote_node_index(&scic->available_remote_nodes,
1, sci_port->reserved_rni);
sci_port->reserved_rni = SCU_DUMMY_INDEX;
- sci_port->reserved_tci = SCU_DUMMY_INDEX;
+ sci_port->reserved_tag = SCI_CONTROLLER_INVALID_IO_TAG;
}
/**
@@ -1119,18 +1105,17 @@
*/
static void scic_sds_port_post_dummy_request(struct scic_sds_port *sci_port)
{
- u32 command;
- struct scu_task_context *task_context;
struct scic_sds_controller *scic = sci_port->owning_controller;
- u16 tci = sci_port->reserved_tci;
+ u16 tag = sci_port->reserved_tag;
+ struct scu_task_context *tc;
+ u32 command;
- task_context = scic_sds_controller_get_task_context_buffer(scic, tci);
-
- task_context->abort = 0;
+ tc = &scic->task_context_table[ISCI_TAG_TCI(tag)];
+ tc->abort = 0;
command = SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
sci_port->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT |
- tci;
+ ISCI_TAG_TCI(tag);
scic_sds_controller_post_request(scic, command);
}
@@ -1145,17 +1130,16 @@
static void scic_sds_port_abort_dummy_request(struct scic_sds_port *sci_port)
{
struct scic_sds_controller *scic = sci_port->owning_controller;
- u16 tci = sci_port->reserved_tci;
+ u16 tag = sci_port->reserved_tag;
struct scu_task_context *tc;
u32 command;
- tc = scic_sds_controller_get_task_context_buffer(scic, tci);
-
+ tc = &scic->task_context_table[ISCI_TAG_TCI(tag)];
tc->abort = 1;
command = SCU_CONTEXT_COMMAND_REQUEST_POST_TC_ABORT |
sci_port->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT |
- tci;
+ ISCI_TAG_TCI(tag);
scic_sds_controller_post_request(scic, command);
}
@@ -1333,15 +1317,16 @@
sci_port->reserved_rni = rni;
}
- if (sci_port->reserved_tci == SCU_DUMMY_INDEX) {
- /* Allocate a TCI and remove the sequence nibble */
- u16 tci = scic_controller_allocate_io_tag(scic);
+ if (sci_port->reserved_tag == SCI_CONTROLLER_INVALID_IO_TAG) {
+ struct isci_host *ihost = scic_to_ihost(scic);
+ u16 tag;
- if (tci != SCU_DUMMY_INDEX)
- scic_sds_port_construct_dummy_task(sci_port, tci);
- else
+ tag = isci_alloc_tag(ihost);
+ if (tag == SCI_CONTROLLER_INVALID_IO_TAG)
status = SCI_FAILURE_INSUFFICIENT_RESOURCES;
- sci_port->reserved_tci = tci;
+ else
+ scic_sds_port_construct_dummy_task(sci_port, tag);
+ sci_port->reserved_tag = tag;
}
if (status == SCI_SUCCESS) {
@@ -1859,7 +1844,7 @@
sci_port->assigned_device_count = 0;
sci_port->reserved_rni = SCU_DUMMY_INDEX;
- sci_port->reserved_tci = SCU_DUMMY_INDEX;
+ sci_port->reserved_tag = SCI_CONTROLLER_INVALID_IO_TAG;
sci_init_timer(&sci_port->timer, port_timeout);