diff options
author | Roland Dreier <rolandd@cisco.com> | 2005-07-07 20:57:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-07-07 21:23:50 -0400 |
commit | 80c8ec2c04e539aac4e9810a46bc04c1b424b4dd (patch) | |
tree | 2f6b7a3e455f93435797c85a36ea3d07e74fb0cc /drivers/infiniband/hw/mthca/mthca_provider.c | |
parent | 74c2174e7be52f9d2d210511bf3b490f4b41574c (diff) |
[PATCH] IB uverbs: add mthca user QP support
Add support for userspace queue pairs (QPs) to mthca.
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/infiniband/hw/mthca/mthca_provider.c')
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_provider.c | 80 |
1 files changed, 68 insertions, 12 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 9feb7618ba41..7a58ce90e179 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c | |||
@@ -424,6 +424,7 @@ static struct ib_qp *mthca_create_qp(struct ib_pd *pd, | |||
424 | struct ib_qp_init_attr *init_attr, | 424 | struct ib_qp_init_attr *init_attr, |
425 | struct ib_udata *udata) | 425 | struct ib_udata *udata) |
426 | { | 426 | { |
427 | struct mthca_create_qp ucmd; | ||
427 | struct mthca_qp *qp; | 428 | struct mthca_qp *qp; |
428 | int err; | 429 | int err; |
429 | 430 | ||
@@ -432,41 +433,82 @@ static struct ib_qp *mthca_create_qp(struct ib_pd *pd, | |||
432 | case IB_QPT_UC: | 433 | case IB_QPT_UC: |
433 | case IB_QPT_UD: | 434 | case IB_QPT_UD: |
434 | { | 435 | { |
436 | struct mthca_ucontext *context; | ||
437 | |||
435 | qp = kmalloc(sizeof *qp, GFP_KERNEL); | 438 | qp = kmalloc(sizeof *qp, GFP_KERNEL); |
436 | if (!qp) | 439 | if (!qp) |
437 | return ERR_PTR(-ENOMEM); | 440 | return ERR_PTR(-ENOMEM); |
438 | 441 | ||
439 | qp->sq.max = init_attr->cap.max_send_wr; | 442 | if (pd->uobject) { |
440 | qp->rq.max = init_attr->cap.max_recv_wr; | 443 | context = to_mucontext(pd->uobject->context); |
441 | qp->sq.max_gs = init_attr->cap.max_send_sge; | 444 | |
442 | qp->rq.max_gs = init_attr->cap.max_recv_sge; | 445 | if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) |
446 | return ERR_PTR(-EFAULT); | ||
447 | |||
448 | err = mthca_map_user_db(to_mdev(pd->device), &context->uar, | ||
449 | context->db_tab, | ||
450 | ucmd.sq_db_index, ucmd.sq_db_page); | ||
451 | if (err) { | ||
452 | kfree(qp); | ||
453 | return ERR_PTR(err); | ||
454 | } | ||
455 | |||
456 | err = mthca_map_user_db(to_mdev(pd->device), &context->uar, | ||
457 | context->db_tab, | ||
458 | ucmd.rq_db_index, ucmd.rq_db_page); | ||
459 | if (err) { | ||
460 | mthca_unmap_user_db(to_mdev(pd->device), | ||
461 | &context->uar, | ||
462 | context->db_tab, | ||
463 | ucmd.sq_db_index); | ||
464 | kfree(qp); | ||
465 | return ERR_PTR(err); | ||
466 | } | ||
467 | |||
468 | qp->mr.ibmr.lkey = ucmd.lkey; | ||
469 | qp->sq.db_index = ucmd.sq_db_index; | ||
470 | qp->rq.db_index = ucmd.rq_db_index; | ||
471 | } | ||
443 | 472 | ||
444 | err = mthca_alloc_qp(to_mdev(pd->device), to_mpd(pd), | 473 | err = mthca_alloc_qp(to_mdev(pd->device), to_mpd(pd), |
445 | to_mcq(init_attr->send_cq), | 474 | to_mcq(init_attr->send_cq), |
446 | to_mcq(init_attr->recv_cq), | 475 | to_mcq(init_attr->recv_cq), |
447 | init_attr->qp_type, init_attr->sq_sig_type, | 476 | init_attr->qp_type, init_attr->sq_sig_type, |
448 | qp); | 477 | &init_attr->cap, qp); |
478 | |||
479 | if (err && pd->uobject) { | ||
480 | context = to_mucontext(pd->uobject->context); | ||
481 | |||
482 | mthca_unmap_user_db(to_mdev(pd->device), | ||
483 | &context->uar, | ||
484 | context->db_tab, | ||
485 | ucmd.sq_db_index); | ||
486 | mthca_unmap_user_db(to_mdev(pd->device), | ||
487 | &context->uar, | ||
488 | context->db_tab, | ||
489 | ucmd.rq_db_index); | ||
490 | } | ||
491 | |||
449 | qp->ibqp.qp_num = qp->qpn; | 492 | qp->ibqp.qp_num = qp->qpn; |
450 | break; | 493 | break; |
451 | } | 494 | } |
452 | case IB_QPT_SMI: | 495 | case IB_QPT_SMI: |
453 | case IB_QPT_GSI: | 496 | case IB_QPT_GSI: |
454 | { | 497 | { |
498 | /* Don't allow userspace to create special QPs */ | ||
499 | if (pd->uobject) | ||
500 | return ERR_PTR(-EINVAL); | ||
501 | |||
455 | qp = kmalloc(sizeof (struct mthca_sqp), GFP_KERNEL); | 502 | qp = kmalloc(sizeof (struct mthca_sqp), GFP_KERNEL); |
456 | if (!qp) | 503 | if (!qp) |
457 | return ERR_PTR(-ENOMEM); | 504 | return ERR_PTR(-ENOMEM); |
458 | 505 | ||
459 | qp->sq.max = init_attr->cap.max_send_wr; | ||
460 | qp->rq.max = init_attr->cap.max_recv_wr; | ||
461 | qp->sq.max_gs = init_attr->cap.max_send_sge; | ||
462 | qp->rq.max_gs = init_attr->cap.max_recv_sge; | ||
463 | |||
464 | qp->ibqp.qp_num = init_attr->qp_type == IB_QPT_SMI ? 0 : 1; | 506 | qp->ibqp.qp_num = init_attr->qp_type == IB_QPT_SMI ? 0 : 1; |
465 | 507 | ||
466 | err = mthca_alloc_sqp(to_mdev(pd->device), to_mpd(pd), | 508 | err = mthca_alloc_sqp(to_mdev(pd->device), to_mpd(pd), |
467 | to_mcq(init_attr->send_cq), | 509 | to_mcq(init_attr->send_cq), |
468 | to_mcq(init_attr->recv_cq), | 510 | to_mcq(init_attr->recv_cq), |
469 | init_attr->sq_sig_type, | 511 | init_attr->sq_sig_type, &init_attr->cap, |
470 | qp->ibqp.qp_num, init_attr->port_num, | 512 | qp->ibqp.qp_num, init_attr->port_num, |
471 | to_msqp(qp)); | 513 | to_msqp(qp)); |
472 | break; | 514 | break; |
@@ -481,13 +523,27 @@ static struct ib_qp *mthca_create_qp(struct ib_pd *pd, | |||
481 | return ERR_PTR(err); | 523 | return ERR_PTR(err); |
482 | } | 524 | } |
483 | 525 | ||
484 | init_attr->cap.max_inline_data = 0; | 526 | init_attr->cap.max_inline_data = 0; |
527 | init_attr->cap.max_send_wr = qp->sq.max; | ||
528 | init_attr->cap.max_recv_wr = qp->rq.max; | ||
529 | init_attr->cap.max_send_sge = qp->sq.max_gs; | ||
530 | init_attr->cap.max_recv_sge = qp->rq.max_gs; | ||
485 | 531 | ||
486 | return &qp->ibqp; | 532 | return &qp->ibqp; |
487 | } | 533 | } |
488 | 534 | ||
489 | static int mthca_destroy_qp(struct ib_qp *qp) | 535 | static int mthca_destroy_qp(struct ib_qp *qp) |
490 | { | 536 | { |
537 | if (qp->uobject) { | ||
538 | mthca_unmap_user_db(to_mdev(qp->device), | ||
539 | &to_mucontext(qp->uobject->context)->uar, | ||
540 | to_mucontext(qp->uobject->context)->db_tab, | ||
541 | to_mqp(qp)->sq.db_index); | ||
542 | mthca_unmap_user_db(to_mdev(qp->device), | ||
543 | &to_mucontext(qp->uobject->context)->uar, | ||
544 | to_mucontext(qp->uobject->context)->db_tab, | ||
545 | to_mqp(qp)->rq.db_index); | ||
546 | } | ||
491 | mthca_free_qp(to_mdev(qp->device), to_mqp(qp)); | 547 | mthca_free_qp(to_mdev(qp->device), to_mqp(qp)); |
492 | kfree(qp); | 548 | kfree(qp); |
493 | return 0; | 549 | return 0; |