aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/mthca/mthca_provider.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/mthca/mthca_provider.c')
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c69
1 files changed, 63 insertions, 6 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index bbdfcbe6bade..9feb7618ba41 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -497,28 +497,85 @@ static struct ib_cq *mthca_create_cq(struct ib_device *ibdev, int entries,
497 struct ib_ucontext *context, 497 struct ib_ucontext *context,
498 struct ib_udata *udata) 498 struct ib_udata *udata)
499{ 499{
500 struct mthca_create_cq ucmd;
500 struct mthca_cq *cq; 501 struct mthca_cq *cq;
501 int nent; 502 int nent;
502 int err; 503 int err;
503 504
505 if (context) {
506 if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
507 return ERR_PTR(-EFAULT);
508
509 err = mthca_map_user_db(to_mdev(ibdev), &to_mucontext(context)->uar,
510 to_mucontext(context)->db_tab,
511 ucmd.set_db_index, ucmd.set_db_page);
512 if (err)
513 return ERR_PTR(err);
514
515 err = mthca_map_user_db(to_mdev(ibdev), &to_mucontext(context)->uar,
516 to_mucontext(context)->db_tab,
517 ucmd.arm_db_index, ucmd.arm_db_page);
518 if (err)
519 goto err_unmap_set;
520 }
521
504 cq = kmalloc(sizeof *cq, GFP_KERNEL); 522 cq = kmalloc(sizeof *cq, GFP_KERNEL);
505 if (!cq) 523 if (!cq) {
506 return ERR_PTR(-ENOMEM); 524 err = -ENOMEM;
525 goto err_unmap_arm;
526 }
527
528 if (context) {
529 cq->mr.ibmr.lkey = ucmd.lkey;
530 cq->set_ci_db_index = ucmd.set_db_index;
531 cq->arm_db_index = ucmd.arm_db_index;
532 }
507 533
508 for (nent = 1; nent <= entries; nent <<= 1) 534 for (nent = 1; nent <= entries; nent <<= 1)
509 ; /* nothing */ 535 ; /* nothing */
510 536
511 err = mthca_init_cq(to_mdev(ibdev), nent, cq); 537 err = mthca_init_cq(to_mdev(ibdev), nent,
512 if (err) { 538 context ? to_mucontext(context) : NULL,
513 kfree(cq); 539 context ? ucmd.pdn : to_mdev(ibdev)->driver_pd.pd_num,
514 cq = ERR_PTR(err); 540 cq);
541 if (err)
542 goto err_free;
543
544 if (context && ib_copy_to_udata(udata, &cq->cqn, sizeof (__u32))) {
545 mthca_free_cq(to_mdev(ibdev), cq);
546 goto err_free;
515 } 547 }
516 548
517 return &cq->ibcq; 549 return &cq->ibcq;
550
551err_free:
552 kfree(cq);
553
554err_unmap_arm:
555 if (context)
556 mthca_unmap_user_db(to_mdev(ibdev), &to_mucontext(context)->uar,
557 to_mucontext(context)->db_tab, ucmd.arm_db_index);
558
559err_unmap_set:
560 if (context)
561 mthca_unmap_user_db(to_mdev(ibdev), &to_mucontext(context)->uar,
562 to_mucontext(context)->db_tab, ucmd.set_db_index);
563
564 return ERR_PTR(err);
518} 565}
519 566
520static int mthca_destroy_cq(struct ib_cq *cq) 567static int mthca_destroy_cq(struct ib_cq *cq)
521{ 568{
569 if (cq->uobject) {
570 mthca_unmap_user_db(to_mdev(cq->device),
571 &to_mucontext(cq->uobject->context)->uar,
572 to_mucontext(cq->uobject->context)->db_tab,
573 to_mcq(cq)->arm_db_index);
574 mthca_unmap_user_db(to_mdev(cq->device),
575 &to_mucontext(cq->uobject->context)->uar,
576 to_mucontext(cq->uobject->context)->db_tab,
577 to_mcq(cq)->set_ci_db_index);
578 }
522 mthca_free_cq(to_mdev(cq->device), to_mcq(cq)); 579 mthca_free_cq(to_mdev(cq->device), to_mcq(cq));
523 kfree(cq); 580 kfree(cq);
524 581