diff options
-rw-r--r-- | drivers/scsi/isci/host.c | 88 | ||||
-rw-r--r-- | drivers/scsi/isci/host.h | 47 | ||||
-rw-r--r-- | drivers/scsi/isci/isci.h | 2 | ||||
-rw-r--r-- | drivers/scsi/isci/port.c | 17 | ||||
-rw-r--r-- | drivers/scsi/isci/request.c | 12 |
5 files changed, 52 insertions, 114 deletions
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c index 343655bd1a6a..3c7042b8bc0e 100644 --- a/drivers/scsi/isci/host.c +++ b/drivers/scsi/isci/host.c @@ -284,23 +284,16 @@ static void scic_sds_controller_task_completion(struct scic_sds_controller *scic u32 completion_entry) { u32 index; - struct scic_sds_request *io_request; + struct scic_sds_request *sci_req; index = SCU_GET_COMPLETION_INDEX(completion_entry); - io_request = scic->io_request_table[index]; + sci_req = scic->io_request_table[index]; /* Make sure that we really want to process this IO request */ - if ( - (io_request != NULL) - && (io_request->io_tag != SCI_CONTROLLER_INVALID_IO_TAG) - && ( - scic_sds_io_tag_get_sequence(io_request->io_tag) - == scic->io_request_sequence[index] - ) - ) { + if (sci_req && sci_req->io_tag != SCI_CONTROLLER_INVALID_IO_TAG && + ISCI_TAG_SEQ(sci_req->io_tag) == scic->io_request_sequence[index]) /* Yep this is a valid io request pass it along to the io request handler */ - scic_sds_io_request_tc_completion(io_request, completion_entry); - } + scic_sds_io_request_tc_completion(sci_req, completion_entry); } static void scic_sds_controller_sdma_completion(struct scic_sds_controller *scic, @@ -2682,37 +2675,28 @@ void scic_sds_controller_copy_task_context( sci_req->task_context_buffer = task_context_buffer; } -/** - * This method returns the task context buffer for the given io tag. - * @scic: - * @io_tag: - * - * struct scu_task_context* - */ -struct scu_task_context *scic_sds_controller_get_task_context_buffer( - struct scic_sds_controller *scic, - u16 io_tag - ) { - u16 task_index = scic_sds_io_tag_get_index(io_tag); +struct scu_task_context *scic_sds_controller_get_task_context_buffer(struct scic_sds_controller *scic, + u16 io_tag) +{ + u16 tci = ISCI_TAG_TCI(io_tag); - if (task_index < scic->task_context_entries) { - return &scic->task_context_table[task_index]; + if (tci < scic->task_context_entries) { + return &scic->task_context_table[tci]; } return NULL; } -struct scic_sds_request *scic_request_by_tag(struct scic_sds_controller *scic, - u16 io_tag) +struct scic_sds_request *scic_request_by_tag(struct scic_sds_controller *scic, u16 io_tag) { u16 task_index; u16 task_sequence; - task_index = scic_sds_io_tag_get_index(io_tag); + task_index = ISCI_TAG_TCI(io_tag); - if (task_index < scic->task_context_entries) { + if (task_index < scic->task_context_entries) { if (scic->io_request_table[task_index] != NULL) { - task_sequence = scic_sds_io_tag_get_sequence(io_tag); + task_sequence = ISCI_TAG_SEQ(io_tag); if (task_sequence == scic->io_request_sequence[task_index]) { return scic->io_request_table[task_index]; @@ -2875,11 +2859,10 @@ void scic_sds_controller_release_frame( * successfully started the IO request. SCI_SUCCESS if the IO request was * successfully started. Determine the failure situations and return values. */ -enum sci_status scic_controller_start_io( - struct scic_sds_controller *scic, - struct scic_sds_remote_device *rdev, - struct scic_sds_request *req, - u16 io_tag) +enum sci_status scic_controller_start_io(struct scic_sds_controller *scic, + struct scic_sds_remote_device *rdev, + struct scic_sds_request *req, + u16 io_tag) { enum sci_status status; @@ -2892,7 +2875,7 @@ enum sci_status scic_controller_start_io( if (status != SCI_SUCCESS) return status; - scic->io_request_table[scic_sds_io_tag_get_index(req->io_tag)] = req; + scic->io_request_table[ISCI_TAG_TCI(req->io_tag)] = req; scic_sds_controller_post_request(scic, scic_sds_request_get_post_context(req)); return SCI_SUCCESS; } @@ -2979,7 +2962,7 @@ enum sci_status scic_controller_complete_io( if (status != SCI_SUCCESS) return status; - index = scic_sds_io_tag_get_index(request->io_tag); + index = ISCI_TAG_TCI(request->io_tag); scic->io_request_table[index] = NULL; return SCI_SUCCESS; default: @@ -2998,7 +2981,7 @@ enum sci_status scic_controller_continue_io(struct scic_sds_request *sci_req) return SCI_FAILURE_INVALID_STATE; } - scic->io_request_table[scic_sds_io_tag_get_index(sci_req->io_tag)] = sci_req; + scic->io_request_table[ISCI_TAG_TCI(sci_req->io_tag)] = sci_req; scic_sds_controller_post_request(scic, scic_sds_request_get_post_context(sci_req)); return SCI_SUCCESS; } @@ -3050,7 +3033,7 @@ enum sci_task_status scic_controller_start_task( status = scic_sds_remote_device_start_task(scic, rdev, req); switch (status) { case SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS: - scic->io_request_table[scic_sds_io_tag_get_index(req->io_tag)] = req; + scic->io_request_table[ISCI_TAG_TCI(req->io_tag)] = req; /* * We will let framework know this task request started successfully, @@ -3059,7 +3042,7 @@ enum sci_task_status scic_controller_start_task( */ return SCI_SUCCESS; case SCI_SUCCESS: - scic->io_request_table[scic_sds_io_tag_get_index(req->io_tag)] = req; + scic->io_request_table[ISCI_TAG_TCI(req->io_tag)] = req; scic_sds_controller_post_request(scic, scic_sds_request_get_post_context(req)); @@ -3096,14 +3079,12 @@ enum sci_task_status scic_controller_start_task( u16 scic_controller_allocate_io_tag(struct scic_sds_controller *scic) { struct isci_host *ihost = scic_to_ihost(scic); - u16 tci; - u16 seq; if (isci_tci_space(ihost)) { - tci = isci_tci_alloc(ihost); - seq = scic->io_request_sequence[tci]; + u16 tci = isci_tci_alloc(ihost); + u8 seq = scic->io_request_sequence[tci]; - return scic_sds_io_tag_construct(seq, tci); + return ISCI_TAG(seq, tci); } return SCI_CONTROLLER_INVALID_IO_TAG; @@ -3138,22 +3119,17 @@ enum sci_status scic_controller_free_io_tag(struct scic_sds_controller *scic, u16 io_tag) { struct isci_host *ihost = scic_to_ihost(scic); - u16 sequence; - u16 index; - - BUG_ON(io_tag == SCI_CONTROLLER_INVALID_IO_TAG); - - sequence = scic_sds_io_tag_get_sequence(io_tag); - index = scic_sds_io_tag_get_index(io_tag); + u16 tci = ISCI_TAG_TCI(io_tag); + u16 seq = ISCI_TAG_SEQ(io_tag); /* prevent tail from passing head */ if (isci_tci_active(ihost) == 0) return SCI_FAILURE_INVALID_IO_TAG; - if (sequence == scic->io_request_sequence[index]) { - scic_sds_io_sequence_increment(scic->io_request_sequence[index]); + if (seq == scic->io_request_sequence[tci]) { + scic->io_request_sequence[tci] = (seq+1) & (SCI_MAX_SEQ-1); - isci_tci_free(ihost, index); + isci_tci_free(ihost, ISCI_TAG_TCI(io_tag)); return SCI_SUCCESS; } diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h index c61a9fa130b7..7d17ab80f1a9 100644 --- a/drivers/scsi/isci/host.h +++ b/drivers/scsi/isci/host.h @@ -184,13 +184,8 @@ struct scic_sds_controller { */ struct scic_power_control power_control; - /** - * This field is the array of sequence values for the IO Tag fields. Even - * though only 4 bits of the field is used for the sequence the sequence is 16 - * bits in size so the sequence can be bitwise or'd with the TCi to build the - * IO Tag value. - */ - u16 io_request_sequence[SCI_MAX_IO_REQUESTS]; + /* sequence number per tci */ + u8 io_request_sequence[SCI_MAX_IO_REQUESTS]; /** * This field in the array of sequence values for the RNi. These are used @@ -552,40 +547,12 @@ static inline struct isci_host *scic_to_ihost(struct scic_sds_controller *scic) */ #define scic_sds_controller_get_protocol_engine_group(controller) 0 -/** - * scic_sds_io_tag_construct() - - * - * This macro constructs an IO tag from the sequence and index values. - */ -#define scic_sds_io_tag_construct(sequence, task_index) \ - ((sequence) << 12 | (task_index)) - -/** - * scic_sds_io_tag_get_sequence() - - * - * This macro returns the IO sequence from the IO tag value. - */ -#define scic_sds_io_tag_get_sequence(io_tag) \ - (((io_tag) & 0xF000) >> 12) - -/** - * scic_sds_io_tag_get_index() - - * - * This macro returns the TCi from the io tag value - */ -#define scic_sds_io_tag_get_index(io_tag) \ - ((io_tag) & 0x0FFF) +/* see scic_controller_io_tag_allocate|free for how seq and tci are built */ +#define ISCI_TAG(seq, tci) (((u16) (seq)) << 12 | tci) -/** - * scic_sds_io_sequence_increment() - - * - * This is a helper macro to increment the io sequence count. We may find in - * the future that it will be faster to store the sequence count in such a way - * as we dont perform the shift operation to build io tag values so therefore - * need a way to incrment them correctly - */ -#define scic_sds_io_sequence_increment(value) \ - ((value) = (((value) + 1) & 0x000F)) +/* these are returned by the hardware, so sanitize them */ +#define ISCI_TAG_SEQ(tag) (((tag) >> 12) & (SCI_MAX_SEQ-1)) +#define ISCI_TAG_TCI(tag) ((tag) & (SCI_MAX_IO_REQUESTS-1)) /* expander attached sata devices require 3 rnc slots */ static inline int scic_sds_remote_device_node_count(struct scic_sds_remote_device *sci_dev) diff --git a/drivers/scsi/isci/isci.h b/drivers/scsi/isci/isci.h index 84ba533ca51e..81bade421b96 100644 --- a/drivers/scsi/isci/isci.h +++ b/drivers/scsi/isci/isci.h @@ -83,6 +83,7 @@ enum sci_controller_mode { #define SCI_MAX_SMP_PHYS (384) /* not silicon constrained */ #define SCI_MAX_REMOTE_DEVICES (256UL) #define SCI_MAX_IO_REQUESTS (256UL) +#define SCI_MAX_SEQ (16) #define SCI_MAX_MSIX_MESSAGES (2) #define SCI_MAX_SCATTER_GATHER_ELEMENTS 130 /* not silicon constrained */ #define SCI_MAX_CONTROLLERS 2 @@ -113,6 +114,7 @@ static inline void check_sizes(void) BUILD_BUG_ON_NOT_POWER_OF_2(SCU_MAX_COMPLETION_QUEUE_ENTRIES); BUILD_BUG_ON(SCU_MAX_UNSOLICITED_FRAMES > SCU_ABSOLUTE_MAX_UNSOLICITED_FRAMES); BUILD_BUG_ON_NOT_POWER_OF_2(SCI_MAX_IO_REQUESTS); + BUILD_BUG_ON_NOT_POWER_OF_2(SCI_MAX_SEQ); } /** diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c index e540281ebd49..fb66e30da075 100644 --- a/drivers/scsi/isci/port.c +++ b/drivers/scsi/isci/port.c @@ -689,23 +689,16 @@ static void scic_sds_port_construct_dummy_rnc(struct scic_sds_port *sci_port, u1 rnc->ssp.arbitration_wait_time = 0; } -/** - * scic_sds_port_construct_dummy_task() - create dummy task for si workaround - * @sci_port The logical port on which we need to create the - * remote node context. - * context. - * @tci The remote node index for this remote node context. - * - * This routine will construct a dummy task context data structure. This +/* + * construct a dummy task context data structure. This * structure will be posted to the hardwre to work around a scheduler error * in the hardware. - * */ -static void scic_sds_port_construct_dummy_task(struct scic_sds_port *sci_port, u16 tci) +static void scic_sds_port_construct_dummy_task(struct scic_sds_port *sci_port, u16 tag) { struct scu_task_context *task_context; - task_context = scic_sds_controller_get_task_context_buffer(sci_port->owning_controller, tci); + task_context = scic_sds_controller_get_task_context_buffer(sci_port->owning_controller, tag); memset(task_context, 0, sizeof(struct scu_task_context)); @@ -716,7 +709,7 @@ static void scic_sds_port_construct_dummy_task(struct scic_sds_port *sci_port, u 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 = scic_sds_io_tag_get_index(tci); + task_context->task_index = ISCI_TAG_TCI(tag); task_context->valid = SCU_TASK_CONTEXT_VALID; task_context->context_type = SCU_TASK_CONTEXT_TYPE; diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index 433565c2b343..9d7531ad9a74 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c @@ -258,7 +258,7 @@ static void scu_ssp_reqeust_construct_task_context( SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) | (scic_sds_port_get_index(target_port) << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) | - scic_sds_io_tag_get_index(sds_request->io_tag)); + ISCI_TAG_TCI(sds_request->io_tag)); } else { /* * Build the task context now since we have already read @@ -433,7 +433,7 @@ static void scu_sata_reqeust_construct_task_context( SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) | (scic_sds_port_get_index(target_port) << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) | - scic_sds_io_tag_get_index(sci_req->io_tag)); + ISCI_TAG_TCI(sci_req->io_tag)); } else { /* * Build the task context now since we have already read @@ -741,7 +741,7 @@ static u32 sci_req_tx_bytes(struct scic_sds_request *sci_req) */ ret_val = readl(scu_reg_base + (SCU_TASK_CONTEXT_SRAM + offsetof(struct scu_task_context, type.ssp.data_offset)) + - ((sizeof(struct scu_task_context)) * scic_sds_io_tag_get_index(sci_req->io_tag))); + ((sizeof(struct scu_task_context)) * ISCI_TAG_TCI(sci_req->io_tag))); } return ret_val; @@ -777,7 +777,7 @@ enum sci_status scic_sds_request_start(struct scic_sds_request *sci_req) if (sci_req->io_tag != SCI_CONTROLLER_INVALID_IO_TAG) { task_context = sci_req->task_context_buffer; - task_context->task_index = scic_sds_io_tag_get_index(sci_req->io_tag); + task_context->task_index = ISCI_TAG_TCI(sci_req->io_tag); switch (task_context->protocol_type) { case SCU_TASK_CONTEXT_PROTOCOL_SMP: @@ -811,7 +811,7 @@ enum sci_status scic_sds_request_start(struct scic_sds_request *sci_req) scic_sds_controller_copy_task_context(scic, sci_req); /* Add to the post_context the io tag value */ - sci_req->post_context |= scic_sds_io_tag_get_index(sci_req->io_tag); + sci_req->post_context |= ISCI_TAG_TCI(sci_req->io_tag); /* Everything is good go ahead and change state */ sci_change_state(&sci_req->sm, SCI_REQ_STARTED); @@ -3325,7 +3325,7 @@ scu_smp_request_construct_task_context(struct scic_sds_request *sci_req, SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) | (scic_sds_port_get_index(sci_port) << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) | - scic_sds_io_tag_get_index(sci_req->io_tag)); + ISCI_TAG_TCI(sci_req->io_tag)); } else { /* * Build the task context now since we have already read |