aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/srp/ib_srp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/ulp/srp/ib_srp.c')
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c48
1 files changed, 35 insertions, 13 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index e3c2c5b4297f..62d2a18e1b41 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -130,6 +130,7 @@ static void srp_send_completion(struct ib_cq *cq, void *target_ptr);
130static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event); 130static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event);
131 131
132static struct scsi_transport_template *ib_srp_transport_template; 132static struct scsi_transport_template *ib_srp_transport_template;
133static struct workqueue_struct *srp_remove_wq;
133 134
134static struct ib_client srp_client = { 135static struct ib_client srp_client = {
135 .name = "srp", 136 .name = "srp",
@@ -731,7 +732,7 @@ static bool srp_queue_remove_work(struct srp_target_port *target)
731 spin_unlock_irq(&target->lock); 732 spin_unlock_irq(&target->lock);
732 733
733 if (changed) 734 if (changed)
734 queue_work(system_long_wq, &target->remove_work); 735 queue_work(srp_remove_wq, &target->remove_work);
735 736
736 return changed; 737 return changed;
737} 738}
@@ -1643,10 +1644,14 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp)
1643 SCSI_SENSE_BUFFERSIZE)); 1644 SCSI_SENSE_BUFFERSIZE));
1644 } 1645 }
1645 1646
1646 if (rsp->flags & (SRP_RSP_FLAG_DOOVER | SRP_RSP_FLAG_DOUNDER)) 1647 if (unlikely(rsp->flags & SRP_RSP_FLAG_DIUNDER))
1647 scsi_set_resid(scmnd, be32_to_cpu(rsp->data_out_res_cnt));
1648 else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER))
1649 scsi_set_resid(scmnd, be32_to_cpu(rsp->data_in_res_cnt)); 1648 scsi_set_resid(scmnd, be32_to_cpu(rsp->data_in_res_cnt));
1649 else if (unlikely(rsp->flags & SRP_RSP_FLAG_DIOVER))
1650 scsi_set_resid(scmnd, -be32_to_cpu(rsp->data_in_res_cnt));
1651 else if (unlikely(rsp->flags & SRP_RSP_FLAG_DOUNDER))
1652 scsi_set_resid(scmnd, be32_to_cpu(rsp->data_out_res_cnt));
1653 else if (unlikely(rsp->flags & SRP_RSP_FLAG_DOOVER))
1654 scsi_set_resid(scmnd, -be32_to_cpu(rsp->data_out_res_cnt));
1650 1655
1651 srp_free_req(target, req, scmnd, 1656 srp_free_req(target, req, scmnd,
1652 be32_to_cpu(rsp->req_lim_delta)); 1657 be32_to_cpu(rsp->req_lim_delta));
@@ -3261,9 +3266,10 @@ static void srp_remove_one(struct ib_device *device)
3261 spin_unlock(&host->target_lock); 3266 spin_unlock(&host->target_lock);
3262 3267
3263 /* 3268 /*
3264 * Wait for target port removal tasks. 3269 * Wait for tl_err and target port removal tasks.
3265 */ 3270 */
3266 flush_workqueue(system_long_wq); 3271 flush_workqueue(system_long_wq);
3272 flush_workqueue(srp_remove_wq);
3267 3273
3268 kfree(host); 3274 kfree(host);
3269 } 3275 }
@@ -3313,16 +3319,22 @@ static int __init srp_init_module(void)
3313 indirect_sg_entries = cmd_sg_entries; 3319 indirect_sg_entries = cmd_sg_entries;
3314 } 3320 }
3315 3321
3322 srp_remove_wq = create_workqueue("srp_remove");
3323 if (!srp_remove_wq) {
3324 ret = -ENOMEM;
3325 goto out;
3326 }
3327
3328 ret = -ENOMEM;
3316 ib_srp_transport_template = 3329 ib_srp_transport_template =
3317 srp_attach_transport(&ib_srp_transport_functions); 3330 srp_attach_transport(&ib_srp_transport_functions);
3318 if (!ib_srp_transport_template) 3331 if (!ib_srp_transport_template)
3319 return -ENOMEM; 3332 goto destroy_wq;
3320 3333
3321 ret = class_register(&srp_class); 3334 ret = class_register(&srp_class);
3322 if (ret) { 3335 if (ret) {
3323 pr_err("couldn't register class infiniband_srp\n"); 3336 pr_err("couldn't register class infiniband_srp\n");
3324 srp_release_transport(ib_srp_transport_template); 3337 goto release_tr;
3325 return ret;
3326 } 3338 }
3327 3339
3328 ib_sa_register_client(&srp_sa_client); 3340 ib_sa_register_client(&srp_sa_client);
@@ -3330,13 +3342,22 @@ static int __init srp_init_module(void)
3330 ret = ib_register_client(&srp_client); 3342 ret = ib_register_client(&srp_client);
3331 if (ret) { 3343 if (ret) {
3332 pr_err("couldn't register IB client\n"); 3344 pr_err("couldn't register IB client\n");
3333 srp_release_transport(ib_srp_transport_template); 3345 goto unreg_sa;
3334 ib_sa_unregister_client(&srp_sa_client);
3335 class_unregister(&srp_class);
3336 return ret;
3337 } 3346 }
3338 3347
3339 return 0; 3348out:
3349 return ret;
3350
3351unreg_sa:
3352 ib_sa_unregister_client(&srp_sa_client);
3353 class_unregister(&srp_class);
3354
3355release_tr:
3356 srp_release_transport(ib_srp_transport_template);
3357
3358destroy_wq:
3359 destroy_workqueue(srp_remove_wq);
3360 goto out;
3340} 3361}
3341 3362
3342static void __exit srp_cleanup_module(void) 3363static void __exit srp_cleanup_module(void)
@@ -3345,6 +3366,7 @@ static void __exit srp_cleanup_module(void)
3345 ib_sa_unregister_client(&srp_sa_client); 3366 ib_sa_unregister_client(&srp_sa_client);
3346 class_unregister(&srp_class); 3367 class_unregister(&srp_class);
3347 srp_release_transport(ib_srp_transport_template); 3368 srp_release_transport(ib_srp_transport_template);
3369 destroy_workqueue(srp_remove_wq);
3348} 3370}
3349 3371
3350module_init(srp_init_module); 3372module_init(srp_init_module);