diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-06-17 17:18:39 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 07:04:51 -0400 |
commit | db0562509800a2d4cb5cb14a66413c30484f165c (patch) | |
tree | d05cc34b78a8f2a6b9024b8d45e5e8e50786ee64 /drivers | |
parent | 38d8879baeb61b6946052739e7c03fa79b3a57f0 (diff) |
isci: preallocate requests
the dma_pool interface is optimized for object_size << page_size which
is not the case with isci_request objects and the dma_pool routines show
up in the top of the profile.
The old io_request_table which tracked whether tci slots were in-flight
or not is replaced with an IREQ_ACTIVE flag per request.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/isci/host.c | 70 | ||||
-rw-r--r-- | drivers/scsi/isci/host.h | 11 | ||||
-rw-r--r-- | drivers/scsi/isci/remote_device.c | 9 | ||||
-rw-r--r-- | drivers/scsi/isci/request.c | 89 | ||||
-rw-r--r-- | drivers/scsi/isci/request.h | 26 | ||||
-rw-r--r-- | drivers/scsi/isci/task.c | 19 |
6 files changed, 85 insertions, 139 deletions
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c index c99fab53dd0c..0884ae3253e5 100644 --- a/drivers/scsi/isci/host.c +++ b/drivers/scsi/isci/host.c | |||
@@ -255,14 +255,14 @@ static bool scic_sds_controller_error_isr(struct scic_sds_controller *scic) | |||
255 | static void scic_sds_controller_task_completion(struct scic_sds_controller *scic, | 255 | static void scic_sds_controller_task_completion(struct scic_sds_controller *scic, |
256 | u32 completion_entry) | 256 | u32 completion_entry) |
257 | { | 257 | { |
258 | u32 index; | 258 | u32 index = SCU_GET_COMPLETION_INDEX(completion_entry); |
259 | struct scic_sds_request *sci_req; | 259 | struct isci_host *ihost = scic_to_ihost(scic); |
260 | 260 | struct isci_request *ireq = ihost->reqs[index]; | |
261 | index = SCU_GET_COMPLETION_INDEX(completion_entry); | 261 | struct scic_sds_request *sci_req = &ireq->sci; |
262 | sci_req = scic->io_request_table[index]; | ||
263 | 262 | ||
264 | /* Make sure that we really want to process this IO request */ | 263 | /* Make sure that we really want to process this IO request */ |
265 | if (sci_req && sci_req->io_tag != SCI_CONTROLLER_INVALID_IO_TAG && | 264 | if (test_bit(IREQ_ACTIVE, &ireq->flags) && |
265 | sci_req->io_tag != SCI_CONTROLLER_INVALID_IO_TAG && | ||
266 | ISCI_TAG_SEQ(sci_req->io_tag) == scic->io_request_sequence[index]) | 266 | ISCI_TAG_SEQ(sci_req->io_tag) == scic->io_request_sequence[index]) |
267 | /* Yep this is a valid io request pass it along to the io request handler */ | 267 | /* Yep this is a valid io request pass it along to the io request handler */ |
268 | scic_sds_io_request_tc_completion(sci_req, completion_entry); | 268 | scic_sds_io_request_tc_completion(sci_req, completion_entry); |
@@ -280,7 +280,7 @@ static void scic_sds_controller_sdma_completion(struct scic_sds_controller *scic | |||
280 | switch (scu_get_command_request_type(completion_entry)) { | 280 | switch (scu_get_command_request_type(completion_entry)) { |
281 | case SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC: | 281 | case SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC: |
282 | case SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_TC: | 282 | case SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_TC: |
283 | io_request = scic->io_request_table[index]; | 283 | io_request = &scic_to_ihost(scic)->reqs[index]->sci; |
284 | dev_warn(scic_to_dev(scic), | 284 | dev_warn(scic_to_dev(scic), |
285 | "%s: SCIC SDS Completion type SDMA %x for io request " | 285 | "%s: SCIC SDS Completion type SDMA %x for io request " |
286 | "%p\n", | 286 | "%p\n", |
@@ -418,7 +418,7 @@ static void scic_sds_controller_event_completion(struct scic_sds_controller *sci | |||
418 | break; | 418 | break; |
419 | 419 | ||
420 | case SCU_EVENT_TYPE_TRANSPORT_ERROR: | 420 | case SCU_EVENT_TYPE_TRANSPORT_ERROR: |
421 | io_request = scic->io_request_table[index]; | 421 | io_request = &ihost->reqs[index]->sci; |
422 | scic_sds_io_request_event_handler(io_request, completion_entry); | 422 | scic_sds_io_request_event_handler(io_request, completion_entry); |
423 | break; | 423 | break; |
424 | 424 | ||
@@ -426,7 +426,7 @@ static void scic_sds_controller_event_completion(struct scic_sds_controller *sci | |||
426 | switch (scu_get_event_specifier(completion_entry)) { | 426 | switch (scu_get_event_specifier(completion_entry)) { |
427 | case SCU_EVENT_SPECIFIC_SMP_RESPONSE_NO_PE: | 427 | case SCU_EVENT_SPECIFIC_SMP_RESPONSE_NO_PE: |
428 | case SCU_EVENT_SPECIFIC_TASK_TIMEOUT: | 428 | case SCU_EVENT_SPECIFIC_TASK_TIMEOUT: |
429 | io_request = scic->io_request_table[index]; | 429 | io_request = &ihost->reqs[index]->sci; |
430 | if (io_request != NULL) | 430 | if (io_request != NULL) |
431 | scic_sds_io_request_event_handler(io_request, completion_entry); | 431 | scic_sds_io_request_event_handler(io_request, completion_entry); |
432 | else | 432 | else |
@@ -1187,9 +1187,6 @@ static void isci_host_completion_routine(unsigned long data) | |||
1187 | spin_lock_irq(&isci_host->scic_lock); | 1187 | spin_lock_irq(&isci_host->scic_lock); |
1188 | isci_free_tag(isci_host, request->sci.io_tag); | 1188 | isci_free_tag(isci_host, request->sci.io_tag); |
1189 | spin_unlock_irq(&isci_host->scic_lock); | 1189 | spin_unlock_irq(&isci_host->scic_lock); |
1190 | |||
1191 | /* Free the request object. */ | ||
1192 | isci_request_free(isci_host, request); | ||
1193 | } | 1190 | } |
1194 | list_for_each_entry_safe(request, next_request, &errored_request_list, | 1191 | list_for_each_entry_safe(request, next_request, &errored_request_list, |
1195 | completed_node) { | 1192 | completed_node) { |
@@ -1227,9 +1224,6 @@ static void isci_host_completion_routine(unsigned long data) | |||
1227 | list_del_init(&request->dev_node); | 1224 | list_del_init(&request->dev_node); |
1228 | isci_free_tag(isci_host, request->sci.io_tag); | 1225 | isci_free_tag(isci_host, request->sci.io_tag); |
1229 | spin_unlock_irq(&isci_host->scic_lock); | 1226 | spin_unlock_irq(&isci_host->scic_lock); |
1230 | |||
1231 | /* Free the request object. */ | ||
1232 | isci_request_free(isci_host, request); | ||
1233 | } | 1227 | } |
1234 | } | 1228 | } |
1235 | 1229 | ||
@@ -2469,13 +2463,6 @@ int isci_host_init(struct isci_host *isci_host) | |||
2469 | if (err) | 2463 | if (err) |
2470 | return err; | 2464 | return err; |
2471 | 2465 | ||
2472 | isci_host->dma_pool = dmam_pool_create(DRV_NAME, &isci_host->pdev->dev, | ||
2473 | sizeof(struct isci_request), | ||
2474 | SLAB_HWCACHE_ALIGN, 0); | ||
2475 | |||
2476 | if (!isci_host->dma_pool) | ||
2477 | return -ENOMEM; | ||
2478 | |||
2479 | for (i = 0; i < SCI_MAX_PORTS; i++) | 2466 | for (i = 0; i < SCI_MAX_PORTS; i++) |
2480 | isci_port_init(&isci_host->ports[i], isci_host, i); | 2467 | isci_port_init(&isci_host->ports[i], isci_host, i); |
2481 | 2468 | ||
@@ -2489,6 +2476,25 @@ int isci_host_init(struct isci_host *isci_host) | |||
2489 | INIT_LIST_HEAD(&idev->node); | 2476 | INIT_LIST_HEAD(&idev->node); |
2490 | } | 2477 | } |
2491 | 2478 | ||
2479 | for (i = 0; i < SCI_MAX_IO_REQUESTS; i++) { | ||
2480 | struct isci_request *ireq; | ||
2481 | dma_addr_t dma; | ||
2482 | |||
2483 | ireq = dmam_alloc_coherent(&isci_host->pdev->dev, | ||
2484 | sizeof(struct isci_request), &dma, | ||
2485 | GFP_KERNEL); | ||
2486 | if (!ireq) | ||
2487 | return -ENOMEM; | ||
2488 | |||
2489 | ireq->sci.tc = &isci_host->sci.task_context_table[i]; | ||
2490 | ireq->sci.owning_controller = &isci_host->sci; | ||
2491 | spin_lock_init(&ireq->state_lock); | ||
2492 | ireq->request_daddr = dma; | ||
2493 | ireq->isci_host = isci_host; | ||
2494 | |||
2495 | isci_host->reqs[i] = ireq; | ||
2496 | } | ||
2497 | |||
2492 | return 0; | 2498 | return 0; |
2493 | } | 2499 | } |
2494 | 2500 | ||
@@ -2602,12 +2608,13 @@ struct scic_sds_request *scic_request_by_tag(struct scic_sds_controller *scic, u | |||
2602 | task_index = ISCI_TAG_TCI(io_tag); | 2608 | task_index = ISCI_TAG_TCI(io_tag); |
2603 | 2609 | ||
2604 | if (task_index < scic->task_context_entries) { | 2610 | if (task_index < scic->task_context_entries) { |
2605 | if (scic->io_request_table[task_index] != NULL) { | 2611 | struct isci_request *ireq = scic_to_ihost(scic)->reqs[task_index]; |
2612 | |||
2613 | if (test_bit(IREQ_ACTIVE, &ireq->flags)) { | ||
2606 | task_sequence = ISCI_TAG_SEQ(io_tag); | 2614 | task_sequence = ISCI_TAG_SEQ(io_tag); |
2607 | 2615 | ||
2608 | if (task_sequence == scic->io_request_sequence[task_index]) { | 2616 | if (task_sequence == scic->io_request_sequence[task_index]) |
2609 | return scic->io_request_table[task_index]; | 2617 | return &ireq->sci; |
2610 | } | ||
2611 | } | 2618 | } |
2612 | } | 2619 | } |
2613 | 2620 | ||
@@ -2820,7 +2827,7 @@ enum sci_status scic_controller_start_io(struct scic_sds_controller *scic, | |||
2820 | if (status != SCI_SUCCESS) | 2827 | if (status != SCI_SUCCESS) |
2821 | return status; | 2828 | return status; |
2822 | 2829 | ||
2823 | scic->io_request_table[ISCI_TAG_TCI(req->io_tag)] = req; | 2830 | set_bit(IREQ_ACTIVE, &sci_req_to_ireq(req)->flags); |
2824 | scic_sds_controller_post_request(scic, scic_sds_request_get_post_context(req)); | 2831 | scic_sds_controller_post_request(scic, scic_sds_request_get_post_context(req)); |
2825 | return SCI_SUCCESS; | 2832 | return SCI_SUCCESS; |
2826 | } | 2833 | } |
@@ -2897,7 +2904,7 @@ enum sci_status scic_controller_complete_io( | |||
2897 | return status; | 2904 | return status; |
2898 | 2905 | ||
2899 | index = ISCI_TAG_TCI(request->io_tag); | 2906 | index = ISCI_TAG_TCI(request->io_tag); |
2900 | scic->io_request_table[index] = NULL; | 2907 | clear_bit(IREQ_ACTIVE, &sci_req_to_ireq(request)->flags); |
2901 | return SCI_SUCCESS; | 2908 | return SCI_SUCCESS; |
2902 | default: | 2909 | default: |
2903 | dev_warn(scic_to_dev(scic), "invalid state to complete I/O"); | 2910 | dev_warn(scic_to_dev(scic), "invalid state to complete I/O"); |
@@ -2915,7 +2922,7 @@ enum sci_status scic_controller_continue_io(struct scic_sds_request *sci_req) | |||
2915 | return SCI_FAILURE_INVALID_STATE; | 2922 | return SCI_FAILURE_INVALID_STATE; |
2916 | } | 2923 | } |
2917 | 2924 | ||
2918 | scic->io_request_table[ISCI_TAG_TCI(sci_req->io_tag)] = sci_req; | 2925 | set_bit(IREQ_ACTIVE, &sci_req_to_ireq(sci_req)->flags); |
2919 | scic_sds_controller_post_request(scic, scic_sds_request_get_post_context(sci_req)); | 2926 | scic_sds_controller_post_request(scic, scic_sds_request_get_post_context(sci_req)); |
2920 | return SCI_SUCCESS; | 2927 | return SCI_SUCCESS; |
2921 | } | 2928 | } |
@@ -2934,6 +2941,7 @@ enum sci_task_status scic_controller_start_task( | |||
2934 | struct scic_sds_remote_device *rdev, | 2941 | struct scic_sds_remote_device *rdev, |
2935 | struct scic_sds_request *req) | 2942 | struct scic_sds_request *req) |
2936 | { | 2943 | { |
2944 | struct isci_request *ireq = sci_req_to_ireq(req); | ||
2937 | enum sci_status status; | 2945 | enum sci_status status; |
2938 | 2946 | ||
2939 | if (scic->sm.current_state_id != SCIC_READY) { | 2947 | if (scic->sm.current_state_id != SCIC_READY) { |
@@ -2947,7 +2955,7 @@ enum sci_task_status scic_controller_start_task( | |||
2947 | status = scic_sds_remote_device_start_task(scic, rdev, req); | 2955 | status = scic_sds_remote_device_start_task(scic, rdev, req); |
2948 | switch (status) { | 2956 | switch (status) { |
2949 | case SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS: | 2957 | case SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS: |
2950 | scic->io_request_table[ISCI_TAG_TCI(req->io_tag)] = req; | 2958 | set_bit(IREQ_ACTIVE, &ireq->flags); |
2951 | 2959 | ||
2952 | /* | 2960 | /* |
2953 | * We will let framework know this task request started successfully, | 2961 | * We will let framework know this task request started successfully, |
@@ -2956,7 +2964,7 @@ enum sci_task_status scic_controller_start_task( | |||
2956 | */ | 2964 | */ |
2957 | return SCI_SUCCESS; | 2965 | return SCI_SUCCESS; |
2958 | case SCI_SUCCESS: | 2966 | case SCI_SUCCESS: |
2959 | scic->io_request_table[ISCI_TAG_TCI(req->io_tag)] = req; | 2967 | set_bit(IREQ_ACTIVE, &ireq->flags); |
2960 | 2968 | ||
2961 | scic_sds_controller_post_request(scic, | 2969 | scic_sds_controller_post_request(scic, |
2962 | scic_sds_request_get_post_context(req)); | 2970 | scic_sds_request_get_post_context(req)); |
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h index d8164f5d7988..446fade19b3a 100644 --- a/drivers/scsi/isci/host.h +++ b/drivers/scsi/isci/host.h | |||
@@ -166,14 +166,6 @@ struct scic_sds_controller { | |||
166 | struct scic_sds_remote_device *device_table[SCI_MAX_REMOTE_DEVICES]; | 166 | struct scic_sds_remote_device *device_table[SCI_MAX_REMOTE_DEVICES]; |
167 | 167 | ||
168 | /** | 168 | /** |
169 | * This field is the array of IO request objects that are currently active for | ||
170 | * this controller object. This table is used as a fast lookup of the io | ||
171 | * request object that need to handle completion queue notifications. The | ||
172 | * table is TCi based. | ||
173 | */ | ||
174 | struct scic_sds_request *io_request_table[SCI_MAX_IO_REQUESTS]; | ||
175 | |||
176 | /** | ||
177 | * This field is the free RNi data structure | 169 | * This field is the free RNi data structure |
178 | */ | 170 | */ |
179 | struct scic_remote_node_table available_remote_nodes; | 171 | struct scic_remote_node_table available_remote_nodes; |
@@ -298,7 +290,6 @@ struct isci_host { | |||
298 | union scic_oem_parameters oem_parameters; | 290 | union scic_oem_parameters oem_parameters; |
299 | 291 | ||
300 | int id; /* unique within a given pci device */ | 292 | int id; /* unique within a given pci device */ |
301 | struct dma_pool *dma_pool; | ||
302 | struct isci_phy phys[SCI_MAX_PHYS]; | 293 | struct isci_phy phys[SCI_MAX_PHYS]; |
303 | struct isci_port ports[SCI_MAX_PORTS + 1]; /* includes dummy port */ | 294 | struct isci_port ports[SCI_MAX_PORTS + 1]; /* includes dummy port */ |
304 | struct sas_ha_struct sas_ha; | 295 | struct sas_ha_struct sas_ha; |
@@ -315,7 +306,7 @@ struct isci_host { | |||
315 | struct list_head requests_to_complete; | 306 | struct list_head requests_to_complete; |
316 | struct list_head requests_to_errorback; | 307 | struct list_head requests_to_errorback; |
317 | spinlock_t scic_lock; | 308 | spinlock_t scic_lock; |
318 | 309 | struct isci_request *reqs[SCI_MAX_IO_REQUESTS]; | |
319 | struct isci_remote_device devices[SCI_MAX_REMOTE_DEVICES]; | 310 | struct isci_remote_device devices[SCI_MAX_REMOTE_DEVICES]; |
320 | }; | 311 | }; |
321 | 312 | ||
diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c index c5ce0f0f3645..5a86bb1e96df 100644 --- a/drivers/scsi/isci/remote_device.c +++ b/drivers/scsi/isci/remote_device.c | |||
@@ -136,16 +136,19 @@ static void rnc_destruct_done(void *_dev) | |||
136 | static enum sci_status scic_sds_remote_device_terminate_requests(struct scic_sds_remote_device *sci_dev) | 136 | static enum sci_status scic_sds_remote_device_terminate_requests(struct scic_sds_remote_device *sci_dev) |
137 | { | 137 | { |
138 | struct scic_sds_controller *scic = sci_dev->owning_port->owning_controller; | 138 | struct scic_sds_controller *scic = sci_dev->owning_port->owning_controller; |
139 | struct isci_host *ihost = scic_to_ihost(scic); | ||
139 | u32 i, request_count = sci_dev->started_request_count; | 140 | u32 i, request_count = sci_dev->started_request_count; |
140 | enum sci_status status = SCI_SUCCESS; | 141 | enum sci_status status = SCI_SUCCESS; |
141 | 142 | ||
142 | for (i = 0; i < SCI_MAX_IO_REQUESTS && i < request_count; i++) { | 143 | for (i = 0; i < SCI_MAX_IO_REQUESTS && i < request_count; i++) { |
143 | struct scic_sds_request *sci_req; | 144 | struct isci_request *ireq = ihost->reqs[i]; |
145 | struct scic_sds_request *sci_req = &ireq->sci; | ||
144 | enum sci_status s; | 146 | enum sci_status s; |
145 | 147 | ||
146 | sci_req = scic->io_request_table[i]; | 148 | if (!test_bit(IREQ_ACTIVE, &ireq->flags) || |
147 | if (!sci_req || sci_req->target_device != sci_dev) | 149 | sci_req->target_device != sci_dev) |
148 | continue; | 150 | continue; |
151 | |||
149 | s = scic_controller_terminate_request(scic, sci_dev, sci_req); | 152 | s = scic_controller_terminate_request(scic, sci_dev, sci_req); |
150 | if (s != SCI_SUCCESS) | 153 | if (s != SCI_SUCCESS) |
151 | status = s; | 154 | status = s; |
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index 27376ba22483..3c7ed4e61b4a 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c | |||
@@ -3017,13 +3017,10 @@ static const struct sci_base_state scic_sds_request_state_table[] = { | |||
3017 | static void | 3017 | static void |
3018 | scic_sds_general_request_construct(struct scic_sds_controller *scic, | 3018 | scic_sds_general_request_construct(struct scic_sds_controller *scic, |
3019 | struct scic_sds_remote_device *sci_dev, | 3019 | struct scic_sds_remote_device *sci_dev, |
3020 | u16 io_tag, | ||
3021 | struct scic_sds_request *sci_req) | 3020 | struct scic_sds_request *sci_req) |
3022 | { | 3021 | { |
3023 | sci_init_sm(&sci_req->sm, scic_sds_request_state_table, SCI_REQ_INIT); | 3022 | sci_init_sm(&sci_req->sm, scic_sds_request_state_table, SCI_REQ_INIT); |
3024 | 3023 | ||
3025 | sci_req->io_tag = io_tag; | ||
3026 | sci_req->owning_controller = scic; | ||
3027 | sci_req->target_device = sci_dev; | 3024 | sci_req->target_device = sci_dev; |
3028 | sci_req->protocol = SCIC_NO_PROTOCOL; | 3025 | sci_req->protocol = SCIC_NO_PROTOCOL; |
3029 | sci_req->saved_rx_frame_index = SCU_INVALID_FRAME_INDEX; | 3026 | sci_req->saved_rx_frame_index = SCU_INVALID_FRAME_INDEX; |
@@ -3031,20 +3028,18 @@ scic_sds_general_request_construct(struct scic_sds_controller *scic, | |||
3031 | sci_req->sci_status = SCI_SUCCESS; | 3028 | sci_req->sci_status = SCI_SUCCESS; |
3032 | sci_req->scu_status = 0; | 3029 | sci_req->scu_status = 0; |
3033 | sci_req->post_context = 0xFFFFFFFF; | 3030 | sci_req->post_context = 0xFFFFFFFF; |
3034 | sci_req->tc = &scic->task_context_table[ISCI_TAG_TCI(io_tag)]; | ||
3035 | WARN_ONCE(io_tag == SCI_CONTROLLER_INVALID_IO_TAG, "straggling invalid tag usage\n"); | ||
3036 | } | 3031 | } |
3037 | 3032 | ||
3038 | static enum sci_status | 3033 | static enum sci_status |
3039 | scic_io_request_construct(struct scic_sds_controller *scic, | 3034 | scic_io_request_construct(struct scic_sds_controller *scic, |
3040 | struct scic_sds_remote_device *sci_dev, | 3035 | struct scic_sds_remote_device *sci_dev, |
3041 | u16 io_tag, struct scic_sds_request *sci_req) | 3036 | struct scic_sds_request *sci_req) |
3042 | { | 3037 | { |
3043 | struct domain_device *dev = sci_dev_to_domain(sci_dev); | 3038 | struct domain_device *dev = sci_dev_to_domain(sci_dev); |
3044 | enum sci_status status = SCI_SUCCESS; | 3039 | enum sci_status status = SCI_SUCCESS; |
3045 | 3040 | ||
3046 | /* Build the common part of the request */ | 3041 | /* Build the common part of the request */ |
3047 | scic_sds_general_request_construct(scic, sci_dev, io_tag, sci_req); | 3042 | scic_sds_general_request_construct(scic, sci_dev, sci_req); |
3048 | 3043 | ||
3049 | if (sci_dev->rnc.remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) | 3044 | if (sci_dev->rnc.remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) |
3050 | return SCI_FAILURE_INVALID_REMOTE_DEVICE; | 3045 | return SCI_FAILURE_INVALID_REMOTE_DEVICE; |
@@ -3071,7 +3066,7 @@ enum sci_status scic_task_request_construct(struct scic_sds_controller *scic, | |||
3071 | enum sci_status status = SCI_SUCCESS; | 3066 | enum sci_status status = SCI_SUCCESS; |
3072 | 3067 | ||
3073 | /* Build the common part of the request */ | 3068 | /* Build the common part of the request */ |
3074 | scic_sds_general_request_construct(scic, sci_dev, io_tag, sci_req); | 3069 | scic_sds_general_request_construct(scic, sci_dev, sci_req); |
3075 | 3070 | ||
3076 | if (dev->dev_type == SAS_END_DEV || | 3071 | if (dev->dev_type == SAS_END_DEV || |
3077 | dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) { | 3072 | dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) { |
@@ -3291,8 +3286,7 @@ static enum sci_status isci_smp_request_build(struct isci_request *ireq) | |||
3291 | */ | 3286 | */ |
3292 | static enum sci_status isci_io_request_build(struct isci_host *isci_host, | 3287 | static enum sci_status isci_io_request_build(struct isci_host *isci_host, |
3293 | struct isci_request *request, | 3288 | struct isci_request *request, |
3294 | struct isci_remote_device *isci_device, | 3289 | struct isci_remote_device *isci_device) |
3295 | u16 tag) | ||
3296 | { | 3290 | { |
3297 | enum sci_status status = SCI_SUCCESS; | 3291 | enum sci_status status = SCI_SUCCESS; |
3298 | struct sas_task *task = isci_request_access_task(request); | 3292 | struct sas_task *task = isci_request_access_task(request); |
@@ -3325,11 +3319,8 @@ static enum sci_status isci_io_request_build(struct isci_host *isci_host, | |||
3325 | return SCI_FAILURE_INSUFFICIENT_RESOURCES; | 3319 | return SCI_FAILURE_INSUFFICIENT_RESOURCES; |
3326 | } | 3320 | } |
3327 | 3321 | ||
3328 | /* build the common request object. For now, | ||
3329 | * we will let the core allocate the IO tag. | ||
3330 | */ | ||
3331 | status = scic_io_request_construct(&isci_host->sci, sci_device, | 3322 | status = scic_io_request_construct(&isci_host->sci, sci_device, |
3332 | tag, &request->sci); | 3323 | &request->sci); |
3333 | 3324 | ||
3334 | if (status != SCI_SUCCESS) { | 3325 | if (status != SCI_SUCCESS) { |
3335 | dev_warn(&isci_host->pdev->dev, | 3326 | dev_warn(&isci_host->pdev->dev, |
@@ -3359,65 +3350,51 @@ static enum sci_status isci_io_request_build(struct isci_host *isci_host, | |||
3359 | return SCI_SUCCESS; | 3350 | return SCI_SUCCESS; |
3360 | } | 3351 | } |
3361 | 3352 | ||
3362 | static struct isci_request *isci_request_alloc_core(struct isci_host *ihost, | 3353 | static struct isci_request *isci_request_from_tag(struct isci_host *ihost, u16 tag) |
3363 | gfp_t gfp_flags) | ||
3364 | { | 3354 | { |
3365 | dma_addr_t handle; | ||
3366 | struct isci_request *ireq; | 3355 | struct isci_request *ireq; |
3367 | 3356 | ||
3368 | ireq = dma_pool_alloc(ihost->dma_pool, gfp_flags, &handle); | 3357 | ireq = ihost->reqs[ISCI_TAG_TCI(tag)]; |
3369 | if (!ireq) { | 3358 | ireq->sci.io_tag = tag; |
3370 | dev_warn(&ihost->pdev->dev, | ||
3371 | "%s: dma_pool_alloc returned NULL\n", __func__); | ||
3372 | return NULL; | ||
3373 | } | ||
3374 | |||
3375 | /* initialize the request object. */ | ||
3376 | spin_lock_init(&ireq->state_lock); | ||
3377 | ireq->request_daddr = handle; | ||
3378 | ireq->isci_host = ihost; | ||
3379 | ireq->io_request_completion = NULL; | 3359 | ireq->io_request_completion = NULL; |
3380 | ireq->flags = 0; | 3360 | ireq->flags = 0; |
3381 | ireq->num_sg_entries = 0; | 3361 | ireq->num_sg_entries = 0; |
3382 | INIT_LIST_HEAD(&ireq->completed_node); | 3362 | INIT_LIST_HEAD(&ireq->completed_node); |
3383 | INIT_LIST_HEAD(&ireq->dev_node); | 3363 | INIT_LIST_HEAD(&ireq->dev_node); |
3384 | |||
3385 | isci_request_change_state(ireq, allocated); | 3364 | isci_request_change_state(ireq, allocated); |
3386 | 3365 | ||
3387 | return ireq; | 3366 | return ireq; |
3388 | } | 3367 | } |
3389 | 3368 | ||
3390 | static struct isci_request *isci_request_alloc_io(struct isci_host *ihost, | 3369 | static struct isci_request *isci_io_request_from_tag(struct isci_host *ihost, |
3391 | struct sas_task *task, | 3370 | struct sas_task *task, |
3392 | gfp_t gfp_flags) | 3371 | u16 tag) |
3393 | { | 3372 | { |
3394 | struct isci_request *ireq; | 3373 | struct isci_request *ireq; |
3395 | 3374 | ||
3396 | ireq = isci_request_alloc_core(ihost, gfp_flags); | 3375 | ireq = isci_request_from_tag(ihost, tag); |
3397 | if (ireq) { | 3376 | ireq->ttype_ptr.io_task_ptr = task; |
3398 | ireq->ttype_ptr.io_task_ptr = task; | 3377 | ireq->ttype = io_task; |
3399 | ireq->ttype = io_task; | 3378 | task->lldd_task = ireq; |
3400 | task->lldd_task = ireq; | 3379 | |
3401 | } | ||
3402 | return ireq; | 3380 | return ireq; |
3403 | } | 3381 | } |
3404 | 3382 | ||
3405 | struct isci_request *isci_request_alloc_tmf(struct isci_host *ihost, | 3383 | struct isci_request *isci_tmf_request_from_tag(struct isci_host *ihost, |
3406 | struct isci_tmf *isci_tmf, | 3384 | struct isci_tmf *isci_tmf, |
3407 | gfp_t gfp_flags) | 3385 | u16 tag) |
3408 | { | 3386 | { |
3409 | struct isci_request *ireq; | 3387 | struct isci_request *ireq; |
3410 | 3388 | ||
3411 | ireq = isci_request_alloc_core(ihost, gfp_flags); | 3389 | ireq = isci_request_from_tag(ihost, tag); |
3412 | if (ireq) { | 3390 | ireq->ttype_ptr.tmf_task_ptr = isci_tmf; |
3413 | ireq->ttype_ptr.tmf_task_ptr = isci_tmf; | 3391 | ireq->ttype = tmf_task; |
3414 | ireq->ttype = tmf_task; | 3392 | |
3415 | } | ||
3416 | return ireq; | 3393 | return ireq; |
3417 | } | 3394 | } |
3418 | 3395 | ||
3419 | int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *idev, | 3396 | int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *idev, |
3420 | struct sas_task *task, u16 tag, gfp_t gfp_flags) | 3397 | struct sas_task *task, u16 tag) |
3421 | { | 3398 | { |
3422 | enum sci_status status = SCI_FAILURE_UNSUPPORTED_PROTOCOL; | 3399 | enum sci_status status = SCI_FAILURE_UNSUPPORTED_PROTOCOL; |
3423 | struct isci_request *ireq; | 3400 | struct isci_request *ireq; |
@@ -3425,17 +3402,15 @@ int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *ide | |||
3425 | int ret = 0; | 3402 | int ret = 0; |
3426 | 3403 | ||
3427 | /* do common allocation and init of request object. */ | 3404 | /* do common allocation and init of request object. */ |
3428 | ireq = isci_request_alloc_io(ihost, task, gfp_flags); | 3405 | ireq = isci_io_request_from_tag(ihost, task, tag); |
3429 | if (!ireq) | ||
3430 | goto out; | ||
3431 | 3406 | ||
3432 | status = isci_io_request_build(ihost, ireq, idev, tag); | 3407 | status = isci_io_request_build(ihost, ireq, idev); |
3433 | if (status != SCI_SUCCESS) { | 3408 | if (status != SCI_SUCCESS) { |
3434 | dev_warn(&ihost->pdev->dev, | 3409 | dev_warn(&ihost->pdev->dev, |
3435 | "%s: request_construct failed - status = 0x%x\n", | 3410 | "%s: request_construct failed - status = 0x%x\n", |
3436 | __func__, | 3411 | __func__, |
3437 | status); | 3412 | status); |
3438 | goto out; | 3413 | return status; |
3439 | } | 3414 | } |
3440 | 3415 | ||
3441 | spin_lock_irqsave(&ihost->scic_lock, flags); | 3416 | spin_lock_irqsave(&ihost->scic_lock, flags); |
@@ -3468,7 +3443,7 @@ int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *ide | |||
3468 | "%s: failed request start (0x%x)\n", | 3443 | "%s: failed request start (0x%x)\n", |
3469 | __func__, status); | 3444 | __func__, status); |
3470 | spin_unlock_irqrestore(&ihost->scic_lock, flags); | 3445 | spin_unlock_irqrestore(&ihost->scic_lock, flags); |
3471 | goto out; | 3446 | return status; |
3472 | } | 3447 | } |
3473 | 3448 | ||
3474 | /* Either I/O started OK, or the core has signaled that | 3449 | /* Either I/O started OK, or the core has signaled that |
@@ -3518,13 +3493,5 @@ int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *ide | |||
3518 | status = SCI_SUCCESS; | 3493 | status = SCI_SUCCESS; |
3519 | } | 3494 | } |
3520 | 3495 | ||
3521 | out: | ||
3522 | if (status != SCI_SUCCESS) { | ||
3523 | /* release dma memory on failure. */ | ||
3524 | isci_request_free(ihost, ireq); | ||
3525 | ireq = NULL; | ||
3526 | ret = SCI_FAILURE; | ||
3527 | } | ||
3528 | |||
3529 | return ret; | 3496 | return ret; |
3530 | } | 3497 | } |
diff --git a/drivers/scsi/isci/request.h b/drivers/scsi/isci/request.h index f440e421ea0e..7628decbd535 100644 --- a/drivers/scsi/isci/request.h +++ b/drivers/scsi/isci/request.h | |||
@@ -257,6 +257,7 @@ struct isci_request { | |||
257 | #define IREQ_COMPLETE_IN_TARGET 0 | 257 | #define IREQ_COMPLETE_IN_TARGET 0 |
258 | #define IREQ_TERMINATED 1 | 258 | #define IREQ_TERMINATED 1 |
259 | #define IREQ_TMF 2 | 259 | #define IREQ_TMF 2 |
260 | #define IREQ_ACTIVE 3 | ||
260 | unsigned long flags; | 261 | unsigned long flags; |
261 | 262 | ||
262 | union ttype_ptr_union { | 263 | union ttype_ptr_union { |
@@ -590,33 +591,16 @@ isci_request_change_started_to_aborted(struct isci_request *isci_request, | |||
590 | completion_ptr, | 591 | completion_ptr, |
591 | aborted); | 592 | aborted); |
592 | } | 593 | } |
593 | /** | ||
594 | * isci_request_free() - This function frees the request object. | ||
595 | * @isci_host: This parameter specifies the ISCI host object | ||
596 | * @isci_request: This parameter points to the isci_request object | ||
597 | * | ||
598 | */ | ||
599 | static inline void isci_request_free(struct isci_host *isci_host, | ||
600 | struct isci_request *isci_request) | ||
601 | { | ||
602 | if (!isci_request) | ||
603 | return; | ||
604 | |||
605 | /* release the dma memory if we fail. */ | ||
606 | dma_pool_free(isci_host->dma_pool, | ||
607 | isci_request, | ||
608 | isci_request->request_daddr); | ||
609 | } | ||
610 | 594 | ||
611 | #define isci_request_access_task(req) ((req)->ttype_ptr.io_task_ptr) | 595 | #define isci_request_access_task(req) ((req)->ttype_ptr.io_task_ptr) |
612 | 596 | ||
613 | #define isci_request_access_tmf(req) ((req)->ttype_ptr.tmf_task_ptr) | 597 | #define isci_request_access_tmf(req) ((req)->ttype_ptr.tmf_task_ptr) |
614 | 598 | ||
615 | struct isci_request *isci_request_alloc_tmf(struct isci_host *ihost, | 599 | struct isci_request *isci_tmf_request_from_tag(struct isci_host *ihost, |
616 | struct isci_tmf *isci_tmf, | 600 | struct isci_tmf *isci_tmf, |
617 | gfp_t gfp_flags); | 601 | u16 tag); |
618 | int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *idev, | 602 | int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *idev, |
619 | struct sas_task *task, u16 tag, gfp_t gfp_flags); | 603 | struct sas_task *task, u16 tag); |
620 | void isci_terminate_pending_requests(struct isci_host *ihost, | 604 | void isci_terminate_pending_requests(struct isci_host *ihost, |
621 | struct isci_remote_device *idev); | 605 | struct isci_remote_device *idev); |
622 | enum sci_status | 606 | enum sci_status |
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c index d1a46710f4a7..d2dba8354899 100644 --- a/drivers/scsi/isci/task.c +++ b/drivers/scsi/isci/task.c | |||
@@ -203,7 +203,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) | |||
203 | spin_unlock_irqrestore(&task->task_state_lock, flags); | 203 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
204 | 204 | ||
205 | /* build and send the request. */ | 205 | /* build and send the request. */ |
206 | status = isci_request_execute(ihost, idev, task, tag, gfp_flags); | 206 | status = isci_request_execute(ihost, idev, task, tag); |
207 | 207 | ||
208 | if (status != SCI_SUCCESS) { | 208 | if (status != SCI_SUCCESS) { |
209 | 209 | ||
@@ -252,7 +252,7 @@ static struct isci_request *isci_task_request_build(struct isci_host *ihost, | |||
252 | dev = idev->domain_dev; | 252 | dev = idev->domain_dev; |
253 | 253 | ||
254 | /* do common allocation and init of request object. */ | 254 | /* do common allocation and init of request object. */ |
255 | ireq = isci_request_alloc_tmf(ihost, isci_tmf, GFP_ATOMIC); | 255 | ireq = isci_tmf_request_from_tag(ihost, isci_tmf, tag); |
256 | if (!ireq) | 256 | if (!ireq) |
257 | return NULL; | 257 | return NULL; |
258 | 258 | ||
@@ -266,7 +266,7 @@ static struct isci_request *isci_task_request_build(struct isci_host *ihost, | |||
266 | "status = 0x%x\n", | 266 | "status = 0x%x\n", |
267 | __func__, | 267 | __func__, |
268 | status); | 268 | status); |
269 | goto errout; | 269 | return NULL; |
270 | } | 270 | } |
271 | 271 | ||
272 | /* XXX convert to get this from task->tproto like other drivers */ | 272 | /* XXX convert to get this from task->tproto like other drivers */ |
@@ -274,7 +274,7 @@ static struct isci_request *isci_task_request_build(struct isci_host *ihost, | |||
274 | isci_tmf->proto = SAS_PROTOCOL_SSP; | 274 | isci_tmf->proto = SAS_PROTOCOL_SSP; |
275 | status = scic_task_request_construct_ssp(&ireq->sci); | 275 | status = scic_task_request_construct_ssp(&ireq->sci); |
276 | if (status != SCI_SUCCESS) | 276 | if (status != SCI_SUCCESS) |
277 | goto errout; | 277 | return NULL; |
278 | } | 278 | } |
279 | 279 | ||
280 | if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) { | 280 | if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) { |
@@ -282,12 +282,9 @@ static struct isci_request *isci_task_request_build(struct isci_host *ihost, | |||
282 | status = isci_sata_management_task_request_build(ireq); | 282 | status = isci_sata_management_task_request_build(ireq); |
283 | 283 | ||
284 | if (status != SCI_SUCCESS) | 284 | if (status != SCI_SUCCESS) |
285 | goto errout; | 285 | return NULL; |
286 | } | 286 | } |
287 | return ireq; | 287 | return ireq; |
288 | errout: | ||
289 | isci_request_free(ihost, ireq); | ||
290 | return NULL; | ||
291 | } | 288 | } |
292 | 289 | ||
293 | int isci_task_execute_tmf(struct isci_host *ihost, | 290 | int isci_task_execute_tmf(struct isci_host *ihost, |
@@ -349,7 +346,7 @@ int isci_task_execute_tmf(struct isci_host *ihost, | |||
349 | status, | 346 | status, |
350 | ireq); | 347 | ireq); |
351 | spin_unlock_irqrestore(&ihost->scic_lock, flags); | 348 | spin_unlock_irqrestore(&ihost->scic_lock, flags); |
352 | goto err_ireq; | 349 | goto err_tci; |
353 | } | 350 | } |
354 | 351 | ||
355 | if (tmf->cb_state_func != NULL) | 352 | if (tmf->cb_state_func != NULL) |
@@ -401,8 +398,6 @@ int isci_task_execute_tmf(struct isci_host *ihost, | |||
401 | 398 | ||
402 | return ret; | 399 | return ret; |
403 | 400 | ||
404 | err_ireq: | ||
405 | isci_request_free(ihost, ireq); | ||
406 | err_tci: | 401 | err_tci: |
407 | spin_lock_irqsave(&ihost->scic_lock, flags); | 402 | spin_lock_irqsave(&ihost->scic_lock, flags); |
408 | isci_tci_free(ihost, ISCI_TAG_TCI(tag)); | 403 | isci_tci_free(ihost, ISCI_TAG_TCI(tag)); |
@@ -516,8 +511,6 @@ static void isci_request_cleanup_completed_loiterer( | |||
516 | spin_lock_irqsave(&isci_host->scic_lock, flags); | 511 | spin_lock_irqsave(&isci_host->scic_lock, flags); |
517 | list_del_init(&isci_request->dev_node); | 512 | list_del_init(&isci_request->dev_node); |
518 | spin_unlock_irqrestore(&isci_host->scic_lock, flags); | 513 | spin_unlock_irqrestore(&isci_host->scic_lock, flags); |
519 | |||
520 | isci_request_free(isci_host, isci_request); | ||
521 | } | 514 | } |
522 | } | 515 | } |
523 | 516 | ||