summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/port.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-06-28 13:47:09 -0700
committerDan Williams <dan.j.williams@intel.com>2011-07-03 04:04:51 -0700
commit312e0c2455c18716cf640d4336dcb1e9e5053818 (patch)
treebe2dbc9a3e5ba39783448f0029231ea43e6e0428 /drivers/scsi/isci/port.c
parent9274f45ea551421cd3bf329de9dd8d1e6208285a (diff)
downloadblackbird-op-linux-312e0c2455c18716cf640d4336dcb1e9e5053818.tar.gz
blackbird-op-linux-312e0c2455c18716cf640d4336dcb1e9e5053818.zip
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>
Diffstat (limited to 'drivers/scsi/isci/port.c')
-rw-r--r--drivers/scsi/isci/port.c61
1 files changed, 23 insertions, 38 deletions
diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c
index 5f4a4e3954db..0e84e29335dd 100644
--- a/drivers/scsi/isci/port.c
+++ b/drivers/scsi/isci/port.c
@@ -695,35 +695,21 @@ static void scic_sds_port_construct_dummy_rnc(struct scic_sds_port *sci_port, u1
*/
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 @@ static void scic_sds_port_destroy_dummy_resources(struct scic_sds_port *sci_port
{
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 @@ scic_sds_port_suspend_port_task_scheduler(struct scic_sds_port *port)
*/
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;
-
- task_context = scic_sds_controller_get_task_context_buffer(scic, tci);
+ u16 tag = sci_port->reserved_tag;
+ struct scu_task_context *tc;
+ u32 command;
- 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_post_dummy_request(struct scic_sds_port *sci_port)
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 @@ enum sci_status scic_sds_port_start(struct scic_sds_port *sci_port)
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 @@ void scic_sds_port_construct(struct scic_sds_port *sci_port, u8 index,
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);
OpenPOWER on IntegriCloud