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.
Unified · Split
| @@ -255,14 +255,14 @@ static bool scic_sds_controller_error_isr(struct scic_sds_controller *scic) · 254 unmodified lines | ||
| 255 | 255 | static void scic_sds_controller_task_completion(struct scic_sds_controller *scic, |
| 256 | 256 | u32 completion_entry) |
| 257 | 257 | { |
| 258 | − u32 index; | |
| 259 | − struct scic_sds_request *sci_req; | |
| 260 | − | |
| 261 | − index = SCU_GET_COMPLETION_INDEX(completion_entry); | |
| 262 | − sci_req = scic->io_request_table[index]; | |
| 258 | + u32 index = SCU_GET_COMPLETION_INDEX(completion_entry); | |
| 259 | + struct isci_host *ihost = scic_to_ihost(scic); | |
| 260 | + struct isci_request *ireq = ihost->reqs[index]; | |
| 261 | + struct scic_sds_request *sci_req = &ireq->sci; | |
| 263 | 262 | |
| 264 | 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 | 266 | ISCI_TAG_SEQ(sci_req->io_tag) == scic->io_request_sequence[index]) |
| 267 | 267 | /* Yep this is a valid io request pass it along to the io request handler */ |
| 268 | 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 · 11 unmodified lines | ||
| 280 | 280 | switch (scu_get_command_request_type(completion_entry)) { |
| 281 | 281 | case SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC: |
| 282 | 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 | 284 | dev_warn(scic_to_dev(scic), |
| 285 | 285 | "%s: SCIC SDS Completion type SDMA %x for io request " |
| 286 | 286 | "%p\n", |
| @@ -418,7 +418,7 @@ static void scic_sds_controller_event_completion(struct scic_sds_controller *sci · 131 unmodified lines | ||
| 418 | 418 | break; |
| 419 | 419 | |
| 420 | 420 | case SCU_EVENT_TYPE_TRANSPORT_ERROR: |
| 421 | − io_request = scic->io_request_table[index]; | |
| 421 | + io_request = &ihost->reqs[index]->sci; | |
| 422 | 422 | scic_sds_io_request_event_handler(io_request, completion_entry); |
| 423 | 423 | break; |
| 424 | 424 | |
| @@ -426,7 +426,7 @@ static void scic_sds_controller_event_completion(struct scic_sds_controller *sci · 1 unmodified line | ||
| 426 | 426 | switch (scu_get_event_specifier(completion_entry)) { |
| 427 | 427 | case SCU_EVENT_SPECIFIC_SMP_RESPONSE_NO_PE: |
| 428 | 428 | case SCU_EVENT_SPECIFIC_TASK_TIMEOUT: |
| 429 | − io_request = scic->io_request_table[index]; | |
| 429 | + io_request = &ihost->reqs[index]->sci; | |
| 430 | 430 | if (io_request != NULL) |
| 431 | 431 | scic_sds_io_request_event_handler(io_request, completion_entry); |
| 432 | 432 | else |
| @@ -1187,9 +1187,6 @@ static void isci_host_completion_routine(unsigned long data) · 754 unmodified lines | ||
| 1187 | 1187 | spin_lock_irq(&isci_host->scic_lock); |
| 1188 | 1188 | isci_free_tag(isci_host, request->sci.io_tag); |
| 1189 | 1189 | spin_unlock_irq(&isci_host->scic_lock); |
| 1190 | − | |
| 1191 | − /* Free the request object. */ | |
| 1192 | − isci_request_free(isci_host, request); | |
| 1193 | 1190 | } |
| 1194 | 1191 | list_for_each_entry_safe(request, next_request, &errored_request_list, |
| 1195 | 1192 | completed_node) { |
| @@ -1227,9 +1224,6 @@ static void isci_host_completion_routine(unsigned long data) · 31 unmodified lines | ||
| 1227 | 1224 | list_del_init(&request->dev_node); |
| 1228 | 1225 | isci_free_tag(isci_host, request->sci.io_tag); |
| 1229 | 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) · 1233 unmodified lines | ||
| 2469 | 2463 | if (err) |
| 2470 | 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 | 2466 | for (i = 0; i < SCI_MAX_PORTS; i++) |
| 2480 | 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) · 7 unmodified lines | ||
| 2489 | 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 | 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 · 107 unmodified lines | ||
| 2602 | 2608 | task_index = ISCI_TAG_TCI(io_tag); |
| 2603 | 2609 | |
| 2604 | 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 | 2614 | task_sequence = ISCI_TAG_SEQ(io_tag); |
| 2607 | 2615 | |
| 2608 | − if (task_sequence == scic->io_request_sequence[task_index]) { | |
| 2609 | − return scic->io_request_table[task_index]; | |
| 2610 | − } | |
| 2616 | + if (task_sequence == scic->io_request_sequence[task_index]) | |
| 2617 | + return &ireq->sci; | |
| 2611 | 2618 | } |
| 2612 | 2619 | } |
| 2613 | 2620 | |
| @@ -2820,7 +2827,7 @@ enum sci_status scic_controller_start_io(struct scic_sds_controller *scic, · 206 unmodified lines | ||
| 2820 | 2827 | if (status != SCI_SUCCESS) |
| 2821 | 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 | 2831 | scic_sds_controller_post_request(scic, scic_sds_request_get_post_context(req)); |
| 2825 | 2832 | return SCI_SUCCESS; |
| 2826 | 2833 | } |
| @@ -2897,7 +2904,7 @@ enum sci_status scic_controller_complete_io( · 70 unmodified lines | ||
| 2897 | 2904 | return status; |
| 2898 | 2905 | |
| 2899 | 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 | 2908 | return SCI_SUCCESS; |
| 2902 | 2909 | default: |
| 2903 | 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) · 11 unmodified lines | ||
| 2915 | 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 | 2926 | scic_sds_controller_post_request(scic, scic_sds_request_get_post_context(sci_req)); |
| 2920 | 2927 | return SCI_SUCCESS; |
| 2921 | 2928 | } |
| @@ -2934,6 +2941,7 @@ enum sci_task_status scic_controller_start_task( · 12 unmodified lines | ||
| 2934 | 2941 | struct scic_sds_remote_device *rdev, |
| 2935 | 2942 | struct scic_sds_request *req) |
| 2936 | 2943 | { |
| 2944 | + struct isci_request *ireq = sci_req_to_ireq(req); | |
| 2937 | 2945 | enum sci_status status; |
| 2938 | 2946 | |
| 2939 | 2947 | if (scic->sm.current_state_id != SCIC_READY) { |
| @@ -2947,7 +2955,7 @@ enum sci_task_status scic_controller_start_task( · 7 unmodified lines | ||
| 2947 | 2955 | status = scic_sds_remote_device_start_task(scic, rdev, req); |
| 2948 | 2956 | switch (status) { |
| 2949 | 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 | 2961 | * We will let framework know this task request started successfully, |
| @@ -2956,7 +2964,7 @@ enum sci_task_status scic_controller_start_task( · 2 unmodified lines | ||
| 2956 | 2964 | */ |
| 2957 | 2965 | return SCI_SUCCESS; |
| 2958 | 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 | 2969 | scic_sds_controller_post_request(scic, |
| 2962 | 2970 | scic_sds_request_get_post_context(req)); |
| @@ -165,14 +165,6 @@ struct scic_sds_controller { · 164 unmodified lines | ||
| 165 | 165 | */ |
| 166 | 166 | struct scic_sds_remote_device *device_table[SCI_MAX_REMOTE_DEVICES]; |
| 167 | 167 | |
| 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 | 168 | /** |
| 177 | 169 | * This field is the free RNi data structure |
| 178 | 170 | */ |
| @@ -298,7 +290,6 @@ struct isci_host { · 119 unmodified lines | ||
| 298 | 290 | union scic_oem_parameters oem_parameters; |
| 299 | 291 | |
| 300 | 292 | int id; /* unique within a given pci device */ |
| 301 | − struct dma_pool *dma_pool; | |
| 302 | 293 | struct isci_phy phys[SCI_MAX_PHYS]; |
| 303 | 294 | struct isci_port ports[SCI_MAX_PORTS + 1]; /* includes dummy port */ |
| 304 | 295 | struct sas_ha_struct sas_ha; |
| @@ -315,7 +306,7 @@ struct isci_host { · 10 unmodified lines | ||
| 315 | 306 | struct list_head requests_to_complete; |
| 316 | 307 | struct list_head requests_to_errorback; |
| 317 | 308 | spinlock_t scic_lock; |
| 318 | − | |
| 309 | + struct isci_request *reqs[SCI_MAX_IO_REQUESTS]; | |
| 319 | 310 | struct isci_remote_device devices[SCI_MAX_REMOTE_DEVICES]; |
| 320 | 311 | }; |
| 321 | 312 | |
| @@ -136,16 +136,19 @@ static void rnc_destruct_done(void *_dev) · 135 unmodified lines | ||
| 136 | 136 | static enum sci_status scic_sds_remote_device_terminate_requests(struct scic_sds_remote_device *sci_dev) |
| 137 | 137 | { |
| 138 | 138 | struct scic_sds_controller *scic = sci_dev->owning_port->owning_controller; |
| 139 | + struct isci_host *ihost = scic_to_ihost(scic); | |
| 139 | 140 | u32 i, request_count = sci_dev->started_request_count; |
| 140 | 141 | enum sci_status status = SCI_SUCCESS; |
| 141 | 142 | |
| 142 | 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 | 146 | enum sci_status s; |
| 145 | 147 | |
| 146 | − sci_req = scic->io_request_table[i]; | |
| 147 | − if (!sci_req || sci_req->target_device != sci_dev) | |
| 148 | + if (!test_bit(IREQ_ACTIVE, &ireq->flags) || | |
| 149 | + sci_req->target_device != sci_dev) | |
| 148 | 150 | continue; |
| 151 | + | |
| 149 | 152 | s = scic_controller_terminate_request(scic, sci_dev, sci_req); |
| 150 | 153 | if (s != SCI_SUCCESS) |
| 151 | 154 | status = s; |
| @@ -3017,13 +3017,10 @@ static const struct sci_base_state scic_sds_request_state_table[] = { · 3016 unmodified lines | ||
| 3017 | 3017 | static void |
| 3018 | 3018 | scic_sds_general_request_construct(struct scic_sds_controller *scic, |
| 3019 | 3019 | struct scic_sds_remote_device *sci_dev, |
| 3020 | − u16 io_tag, | |
| 3021 | 3020 | struct scic_sds_request *sci_req) |
| 3022 | 3021 | { |
| 3023 | 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 | 3024 | sci_req->target_device = sci_dev; |
| 3028 | 3025 | sci_req->protocol = SCIC_NO_PROTOCOL; |
| 3029 | 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, · 1 unmodified line | ||
| 3031 | 3028 | sci_req->sci_status = SCI_SUCCESS; |
| 3032 | 3029 | sci_req->scu_status = 0; |
| 3033 | 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 | 3033 | static enum sci_status |
| 3039 | 3034 | scic_io_request_construct(struct scic_sds_controller *scic, |
| 3040 | 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 | 3038 | struct domain_device *dev = sci_dev_to_domain(sci_dev); |
| 3044 | 3039 | enum sci_status status = SCI_SUCCESS; |
| 3045 | 3040 | |
| 3046 | 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 | 3044 | if (sci_dev->rnc.remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) |
| 3050 | 3045 | return SCI_FAILURE_INVALID_REMOTE_DEVICE; |
| @@ -3071,7 +3066,7 @@ enum sci_status scic_task_request_construct(struct scic_sds_controller *scic, · 20 unmodified lines | ||
| 3071 | 3066 | enum sci_status status = SCI_SUCCESS; |
| 3072 | 3067 | |
| 3073 | 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 | 3071 | if (dev->dev_type == SAS_END_DEV || |
| 3077 | 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) · 213 unmodified lines | ||
| 3291 | 3286 | */ |
| 3292 | 3287 | static enum sci_status isci_io_request_build(struct isci_host *isci_host, |
| 3293 | 3288 | struct isci_request *request, |
| 3294 | − struct isci_remote_device *isci_device, | |
| 3295 | − u16 tag) | |
| 3289 | + struct isci_remote_device *isci_device) | |
| 3296 | 3290 | { |
| 3297 | 3291 | enum sci_status status = SCI_SUCCESS; |
| 3298 | 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, · 26 unmodified lines | ||
| 3325 | 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 | 3322 | status = scic_io_request_construct(&isci_host->sci, sci_device, |
| 3332 | − tag, &request->sci); | |
| 3323 | + &request->sci); | |
| 3333 | 3324 | |
| 3334 | 3325 | if (status != SCI_SUCCESS) { |
| 3335 | 3326 | dev_warn(&isci_host->pdev->dev, |
| @@ -3359,65 +3350,51 @@ static enum sci_status isci_io_request_build(struct isci_host *isci_host, · 23 unmodified lines | ||
| 3359 | 3350 | return SCI_SUCCESS; |
| 3360 | 3351 | } |
| 3361 | 3352 | |
| 3362 | −static struct isci_request *isci_request_alloc_core(struct isci_host *ihost, | |
| 3363 | − gfp_t gfp_flags) | |
| 3353 | +static struct isci_request *isci_request_from_tag(struct isci_host *ihost, u16 tag) | |
| 3364 | 3354 | { |
| 3365 | − dma_addr_t handle; | |
| 3366 | 3355 | struct isci_request *ireq; |
| 3367 | 3356 | |
| 3368 | − ireq = dma_pool_alloc(ihost->dma_pool, gfp_flags, &handle); | |
| 3369 | − if (!ireq) { | |
| 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; | |
| 3357 | + ireq = ihost->reqs[ISCI_TAG_TCI(tag)]; | |
| 3358 | + ireq->sci.io_tag = tag; | |
| 3379 | 3359 | ireq->io_request_completion = NULL; |
| 3380 | 3360 | ireq->flags = 0; |
| 3381 | 3361 | ireq->num_sg_entries = 0; |
| 3382 | 3362 | INIT_LIST_HEAD(&ireq->completed_node); |
| 3383 | 3363 | INIT_LIST_HEAD(&ireq->dev_node); |
| 3384 | − | |
| 3385 | 3364 | isci_request_change_state(ireq, allocated); |
| 3386 | 3365 | |
| 3387 | 3366 | return ireq; |
| 3388 | 3367 | } |
| 3389 | 3368 | |
| 3390 | −static struct isci_request *isci_request_alloc_io(struct isci_host *ihost, | |
| 3391 | − struct sas_task *task, | |
| 3392 | − gfp_t gfp_flags) | |
| 3369 | +static struct isci_request *isci_io_request_from_tag(struct isci_host *ihost, | |
| 3370 | + struct sas_task *task, | |
| 3371 | + u16 tag) | |
| 3393 | 3372 | { |
| 3394 | 3373 | struct isci_request *ireq; |
| 3395 | 3374 | |
| 3396 | − ireq = isci_request_alloc_core(ihost, gfp_flags); | |
| 3397 | − if (ireq) { | |
| 3398 | − ireq->ttype_ptr.io_task_ptr = task; | |
| 3399 | − ireq->ttype = io_task; | |
| 3400 | − task->lldd_task = ireq; | |
| 3401 | − } | |
| 3375 | + ireq = isci_request_from_tag(ihost, tag); | |
| 3376 | + ireq->ttype_ptr.io_task_ptr = task; | |
| 3377 | + ireq->ttype = io_task; | |
| 3378 | + task->lldd_task = ireq; | |
| 3379 | + | |
| 3402 | 3380 | return ireq; |
| 3403 | 3381 | } |
| 3404 | 3382 | |
| 3405 | −struct isci_request *isci_request_alloc_tmf(struct isci_host *ihost, | |
| 3406 | − struct isci_tmf *isci_tmf, | |
| 3407 | − gfp_t gfp_flags) | |
| 3383 | +struct isci_request *isci_tmf_request_from_tag(struct isci_host *ihost, | |
| 3384 | + struct isci_tmf *isci_tmf, | |
| 3385 | + u16 tag) | |
| 3408 | 3386 | { |
| 3409 | 3387 | struct isci_request *ireq; |
| 3410 | 3388 | |
| 3411 | − ireq = isci_request_alloc_core(ihost, gfp_flags); | |
| 3412 | − if (ireq) { | |
| 3413 | − ireq->ttype_ptr.tmf_task_ptr = isci_tmf; | |
| 3414 | − ireq->ttype = tmf_task; | |
| 3415 | − } | |
| 3389 | + ireq = isci_request_from_tag(ihost, tag); | |
| 3390 | + ireq->ttype_ptr.tmf_task_ptr = isci_tmf; | |
| 3391 | + ireq->ttype = tmf_task; | |
| 3392 | + | |
| 3416 | 3393 | return ireq; |
| 3417 | 3394 | } |
| 3418 | 3395 | |
| 3419 | 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 | 3399 | enum sci_status status = SCI_FAILURE_UNSUPPORTED_PROTOCOL; |
| 3423 | 3400 | struct isci_request *ireq; |
| @@ -3425,17 +3402,15 @@ int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *ide · 1 unmodified line | ||
| 3425 | 3402 | int ret = 0; |
| 3426 | 3403 | |
| 3427 | 3404 | /* do common allocation and init of request object. */ |
| 3428 | − ireq = isci_request_alloc_io(ihost, task, gfp_flags); | |
| 3429 | − if (!ireq) | |
| 3430 | − goto out; | |
| 3405 | + ireq = isci_io_request_from_tag(ihost, task, tag); | |
| 3431 | 3406 | |
| 3432 | − status = isci_io_request_build(ihost, ireq, idev, tag); | |
| 3407 | + status = isci_io_request_build(ihost, ireq, idev); | |
| 3433 | 3408 | if (status != SCI_SUCCESS) { |
| 3434 | 3409 | dev_warn(&ihost->pdev->dev, |
| 3435 | 3410 | "%s: request_construct failed - status = 0x%x\n", |
| 3436 | 3411 | __func__, |
| 3437 | 3412 | status); |
| 3438 | − goto out; | |
| 3413 | + return status; | |
| 3439 | 3414 | } |
| 3440 | 3415 | |
| 3441 | 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 · 26 unmodified lines | ||
| 3468 | 3443 | "%s: failed request start (0x%x)\n", |
| 3469 | 3444 | __func__, status); |
| 3470 | 3445 | spin_unlock_irqrestore(&ihost->scic_lock, flags); |
| 3471 | − goto out; | |
| 3446 | + return status; | |
| 3472 | 3447 | } |
| 3473 | 3448 | |
| 3474 | 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 · 43 unmodified lines | ||
| 3518 | 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 | 3496 | return ret; |
| 3530 | 3497 | } |
| @@ -257,6 +257,7 @@ struct isci_request { · 256 unmodified lines | ||
| 257 | 257 | #define IREQ_COMPLETE_IN_TARGET 0 |
| 258 | 258 | #define IREQ_TERMINATED 1 |
| 259 | 259 | #define IREQ_TMF 2 |
| 260 | + #define IREQ_ACTIVE 3 | |
| 260 | 261 | unsigned long flags; |
| 261 | 262 | |
| 262 | 263 | union ttype_ptr_union { |
| @@ -590,33 +591,16 @@ isci_request_change_started_to_aborted(struct isci_request *isci_request, · 327 unmodified lines | ||
| 590 | 591 | completion_ptr, |
| 591 | 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 | 595 | #define isci_request_access_task(req) ((req)->ttype_ptr.io_task_ptr) |
| 612 | 596 | |
| 613 | 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, | |
| 616 | − struct isci_tmf *isci_tmf, | |
| 617 | − gfp_t gfp_flags); | |
| 599 | +struct isci_request *isci_tmf_request_from_tag(struct isci_host *ihost, | |
| 600 | + struct isci_tmf *isci_tmf, | |
| 601 | + u16 tag); | |
| 618 | 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 | 604 | void isci_terminate_pending_requests(struct isci_host *ihost, |
| 621 | 605 | struct isci_remote_device *idev); |
| 622 | 606 | enum sci_status |
| @@ -203,7 +203,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) · 202 unmodified lines | ||
| 203 | 203 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
| 204 | 204 | |
| 205 | 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 | 208 | if (status != SCI_SUCCESS) { |
| 209 | 209 | |
| @@ -252,7 +252,7 @@ static struct isci_request *isci_task_request_build(struct isci_host *ihost, · 42 unmodified lines | ||
| 252 | 252 | dev = idev->domain_dev; |
| 253 | 253 | |
| 254 | 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 | 256 | if (!ireq) |
| 257 | 257 | return NULL; |
| 258 | 258 | |
| @@ -266,7 +266,7 @@ static struct isci_request *isci_task_request_build(struct isci_host *ihost, · 7 unmodified lines | ||
| 266 | 266 | "status = 0x%x\n", |
| 267 | 267 | __func__, |
| 268 | 268 | status); |
| 269 | − goto errout; | |
| 269 | + return NULL; | |
| 270 | 270 | } |
| 271 | 271 | |
| 272 | 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, · 1 unmodified line | ||
| 274 | 274 | isci_tmf->proto = SAS_PROTOCOL_SSP; |
| 275 | 275 | status = scic_task_request_construct_ssp(&ireq->sci); |
| 276 | 276 | if (status != SCI_SUCCESS) |
| 277 | − goto errout; | |
| 277 | + return NULL; | |
| 278 | 278 | } |
| 279 | 279 | |
| 280 | 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, · 1 unmodified line | ||
| 282 | 282 | status = isci_sata_management_task_request_build(ireq); |
| 283 | 283 | |
| 284 | 284 | if (status != SCI_SUCCESS) |
| 285 | − goto errout; | |
| 285 | + return NULL; | |
| 286 | 286 | } |
| 287 | 287 | return ireq; |
| 288 | − errout: | |
| 289 | − isci_request_free(ihost, ireq); | |
| 290 | − return NULL; | |
| 291 | 288 | } |
| 292 | 289 | |
| 293 | 290 | int isci_task_execute_tmf(struct isci_host *ihost, |
| @@ -349,7 +346,7 @@ int isci_task_execute_tmf(struct isci_host *ihost, · 55 unmodified lines | ||
| 349 | 346 | status, |
| 350 | 347 | ireq); |
| 351 | 348 | spin_unlock_irqrestore(&ihost->scic_lock, flags); |
| 352 | − goto err_ireq; | |
| 349 | + goto err_tci; | |
| 353 | 350 | } |
| 354 | 351 | |
| 355 | 352 | if (tmf->cb_state_func != NULL) |
| @@ -401,8 +398,6 @@ int isci_task_execute_tmf(struct isci_host *ihost, · 45 unmodified lines | ||
| 401 | 398 | |
| 402 | 399 | return ret; |
| 403 | 400 | |
| 404 | − err_ireq: | |
| 405 | − isci_request_free(ihost, ireq); | |
| 406 | 401 | err_tci: |
| 407 | 402 | spin_lock_irqsave(&ihost->scic_lock, flags); |
| 408 | 403 | isci_tci_free(ihost, ISCI_TAG_TCI(tag)); |
| @@ -516,8 +511,6 @@ static void isci_request_cleanup_completed_loiterer( · 107 unmodified lines | ||
| 516 | 511 | spin_lock_irqsave(&isci_host->scic_lock, flags); |
| 517 | 512 | list_del_init(&isci_request->dev_node); |
| 518 | 513 | spin_unlock_irqrestore(&isci_host->scic_lock, flags); |
| 519 | − | |
| 520 | − isci_request_free(isci_host, isci_request); | |
| 521 | 514 | } |
| 522 | 515 | } |
| 523 | 516 | |