aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-06-17 17:18:39 -0400
committerDan Williams <dan.j.williams@intel.com>2011-07-03 07:04:51 -0400
commitdb0562509800a2d4cb5cb14a66413c30484f165c (patch)
treed05cc34b78a8f2a6b9024b8d45e5e8e50786ee64 /drivers/scsi
parent38d8879baeb61b6946052739e7c03fa79b3a57f0 (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/scsi')
-rw-r--r--drivers/scsi/isci/host.c70
-rw-r--r--drivers/scsi/isci/host.h11
-rw-r--r--drivers/scsi/isci/remote_device.c9
-rw-r--r--drivers/scsi/isci/request.c89
-rw-r--r--drivers/scsi/isci/request.h26
-rw-r--r--drivers/scsi/isci/task.c19
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)
255static void scic_sds_controller_task_completion(struct scic_sds_controller *scic, 255static 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)
136static enum sci_status scic_sds_remote_device_terminate_requests(struct scic_sds_remote_device *sci_dev) 136static 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[] = {
3017static void 3017static void
3018scic_sds_general_request_construct(struct scic_sds_controller *scic, 3018scic_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
3038static enum sci_status 3033static enum sci_status
3039scic_io_request_construct(struct scic_sds_controller *scic, 3034scic_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 */
3292static enum sci_status isci_io_request_build(struct isci_host *isci_host, 3287static 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
3362static struct isci_request *isci_request_alloc_core(struct isci_host *ihost, 3353static 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
3390static struct isci_request *isci_request_alloc_io(struct isci_host *ihost, 3369static 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
3405struct isci_request *isci_request_alloc_tmf(struct isci_host *ihost, 3383struct 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
3419int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *idev, 3396int 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 */
599static 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
615struct isci_request *isci_request_alloc_tmf(struct isci_host *ihost, 599struct 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);
618int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *idev, 602int 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);
620void isci_terminate_pending_requests(struct isci_host *ihost, 604void isci_terminate_pending_requests(struct isci_host *ihost,
621 struct isci_remote_device *idev); 605 struct isci_remote_device *idev);
622enum sci_status 606enum 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
293int isci_task_execute_tmf(struct isci_host *ihost, 290int 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