diff options
Diffstat (limited to 'drivers/infiniband/hw/ehca/ehca_qp.c')
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_qp.c | 78 |
1 files changed, 14 insertions, 64 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index 34b85556d01..95efef921f1 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c | |||
@@ -637,7 +637,6 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd, | |||
637 | struct ipz_queue *ipz_rqueue = &my_qp->ipz_rqueue; | 637 | struct ipz_queue *ipz_rqueue = &my_qp->ipz_rqueue; |
638 | struct ipz_queue *ipz_squeue = &my_qp->ipz_squeue; | 638 | struct ipz_queue *ipz_squeue = &my_qp->ipz_squeue; |
639 | struct ehca_create_qp_resp resp; | 639 | struct ehca_create_qp_resp resp; |
640 | struct vm_area_struct * vma; | ||
641 | memset(&resp, 0, sizeof(resp)); | 640 | memset(&resp, 0, sizeof(resp)); |
642 | 641 | ||
643 | resp.qp_num = my_qp->real_qp_num; | 642 | resp.qp_num = my_qp->real_qp_num; |
@@ -651,59 +650,21 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd, | |||
651 | resp.ipz_rqueue.queue_length = ipz_rqueue->queue_length; | 650 | resp.ipz_rqueue.queue_length = ipz_rqueue->queue_length; |
652 | resp.ipz_rqueue.pagesize = ipz_rqueue->pagesize; | 651 | resp.ipz_rqueue.pagesize = ipz_rqueue->pagesize; |
653 | resp.ipz_rqueue.toggle_state = ipz_rqueue->toggle_state; | 652 | resp.ipz_rqueue.toggle_state = ipz_rqueue->toggle_state; |
654 | ret = ehca_mmap_nopage(((u64)(my_qp->token) << 32) | 0x22000000, | ||
655 | ipz_rqueue->queue_length, | ||
656 | (void**)&resp.ipz_rqueue.queue, | ||
657 | &vma); | ||
658 | if (ret) { | ||
659 | ehca_err(pd->device, "Could not mmap rqueue pages"); | ||
660 | goto create_qp_exit3; | ||
661 | } | ||
662 | my_qp->uspace_rqueue = resp.ipz_rqueue.queue; | ||
663 | /* squeue properties */ | 653 | /* squeue properties */ |
664 | resp.ipz_squeue.qe_size = ipz_squeue->qe_size; | 654 | resp.ipz_squeue.qe_size = ipz_squeue->qe_size; |
665 | resp.ipz_squeue.act_nr_of_sg = ipz_squeue->act_nr_of_sg; | 655 | resp.ipz_squeue.act_nr_of_sg = ipz_squeue->act_nr_of_sg; |
666 | resp.ipz_squeue.queue_length = ipz_squeue->queue_length; | 656 | resp.ipz_squeue.queue_length = ipz_squeue->queue_length; |
667 | resp.ipz_squeue.pagesize = ipz_squeue->pagesize; | 657 | resp.ipz_squeue.pagesize = ipz_squeue->pagesize; |
668 | resp.ipz_squeue.toggle_state = ipz_squeue->toggle_state; | 658 | resp.ipz_squeue.toggle_state = ipz_squeue->toggle_state; |
669 | ret = ehca_mmap_nopage(((u64)(my_qp->token) << 32) | 0x23000000, | ||
670 | ipz_squeue->queue_length, | ||
671 | (void**)&resp.ipz_squeue.queue, | ||
672 | &vma); | ||
673 | if (ret) { | ||
674 | ehca_err(pd->device, "Could not mmap squeue pages"); | ||
675 | goto create_qp_exit4; | ||
676 | } | ||
677 | my_qp->uspace_squeue = resp.ipz_squeue.queue; | ||
678 | /* fw_handle */ | ||
679 | resp.galpas = my_qp->galpas; | ||
680 | ret = ehca_mmap_register(my_qp->galpas.user.fw_handle, | ||
681 | (void**)&resp.galpas.kernel.fw_handle, | ||
682 | &vma); | ||
683 | if (ret) { | ||
684 | ehca_err(pd->device, "Could not mmap fw_handle"); | ||
685 | goto create_qp_exit5; | ||
686 | } | ||
687 | my_qp->uspace_fwh = (u64)resp.galpas.kernel.fw_handle; | ||
688 | |||
689 | if (ib_copy_to_udata(udata, &resp, sizeof resp)) { | 659 | if (ib_copy_to_udata(udata, &resp, sizeof resp)) { |
690 | ehca_err(pd->device, "Copy to udata failed"); | 660 | ehca_err(pd->device, "Copy to udata failed"); |
691 | ret = -EINVAL; | 661 | ret = -EINVAL; |
692 | goto create_qp_exit6; | 662 | goto create_qp_exit3; |
693 | } | 663 | } |
694 | } | 664 | } |
695 | 665 | ||
696 | return &my_qp->ib_qp; | 666 | return &my_qp->ib_qp; |
697 | 667 | ||
698 | create_qp_exit6: | ||
699 | ehca_munmap(my_qp->uspace_fwh, EHCA_PAGESIZE); | ||
700 | |||
701 | create_qp_exit5: | ||
702 | ehca_munmap(my_qp->uspace_squeue, my_qp->ipz_squeue.queue_length); | ||
703 | |||
704 | create_qp_exit4: | ||
705 | ehca_munmap(my_qp->uspace_rqueue, my_qp->ipz_rqueue.queue_length); | ||
706 | |||
707 | create_qp_exit3: | 668 | create_qp_exit3: |
708 | ipz_queue_dtor(&my_qp->ipz_rqueue); | 669 | ipz_queue_dtor(&my_qp->ipz_rqueue); |
709 | ipz_queue_dtor(&my_qp->ipz_squeue); | 670 | ipz_queue_dtor(&my_qp->ipz_squeue); |
@@ -931,7 +892,7 @@ static int internal_modify_qp(struct ib_qp *ibqp, | |||
931 | my_qp->qp_type == IB_QPT_SMI) && | 892 | my_qp->qp_type == IB_QPT_SMI) && |
932 | statetrans == IB_QPST_SQE2RTS) { | 893 | statetrans == IB_QPST_SQE2RTS) { |
933 | /* mark next free wqe if kernel */ | 894 | /* mark next free wqe if kernel */ |
934 | if (my_qp->uspace_squeue == 0) { | 895 | if (!ibqp->uobject) { |
935 | struct ehca_wqe *wqe; | 896 | struct ehca_wqe *wqe; |
936 | /* lock send queue */ | 897 | /* lock send queue */ |
937 | spin_lock_irqsave(&my_qp->spinlock_s, spl_flags); | 898 | spin_lock_irqsave(&my_qp->spinlock_s, spl_flags); |
@@ -1417,11 +1378,18 @@ int ehca_destroy_qp(struct ib_qp *ibqp) | |||
1417 | enum ib_qp_type qp_type; | 1378 | enum ib_qp_type qp_type; |
1418 | unsigned long flags; | 1379 | unsigned long flags; |
1419 | 1380 | ||
1420 | if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context && | 1381 | if (ibqp->uobject) { |
1421 | my_pd->ownpid != cur_pid) { | 1382 | if (my_qp->mm_count_galpa || |
1422 | ehca_err(ibqp->device, "Invalid caller pid=%x ownpid=%x", | 1383 | my_qp->mm_count_rqueue || my_qp->mm_count_squeue) { |
1423 | cur_pid, my_pd->ownpid); | 1384 | ehca_err(ibqp->device, "Resources still referenced in " |
1424 | return -EINVAL; | 1385 | "user space qp_num=%x", ibqp->qp_num); |
1386 | return -EINVAL; | ||
1387 | } | ||
1388 | if (my_pd->ownpid != cur_pid) { | ||
1389 | ehca_err(ibqp->device, "Invalid caller pid=%x ownpid=%x", | ||
1390 | cur_pid, my_pd->ownpid); | ||
1391 | return -EINVAL; | ||
1392 | } | ||
1425 | } | 1393 | } |
1426 | 1394 | ||
1427 | if (my_qp->send_cq) { | 1395 | if (my_qp->send_cq) { |
@@ -1439,24 +1407,6 @@ int ehca_destroy_qp(struct ib_qp *ibqp) | |||
1439 | idr_remove(&ehca_qp_idr, my_qp->token); | 1407 | idr_remove(&ehca_qp_idr, my_qp->token); |
1440 | spin_unlock_irqrestore(&ehca_qp_idr_lock, flags); | 1408 | spin_unlock_irqrestore(&ehca_qp_idr_lock, flags); |
1441 | 1409 | ||
1442 | /* un-mmap if vma alloc */ | ||
1443 | if (my_qp->uspace_rqueue) { | ||
1444 | ret = ehca_munmap(my_qp->uspace_rqueue, | ||
1445 | my_qp->ipz_rqueue.queue_length); | ||
1446 | if (ret) | ||
1447 | ehca_err(ibqp->device, "Could not munmap rqueue " | ||
1448 | "qp_num=%x", qp_num); | ||
1449 | ret = ehca_munmap(my_qp->uspace_squeue, | ||
1450 | my_qp->ipz_squeue.queue_length); | ||
1451 | if (ret) | ||
1452 | ehca_err(ibqp->device, "Could not munmap squeue " | ||
1453 | "qp_num=%x", qp_num); | ||
1454 | ret = ehca_munmap(my_qp->uspace_fwh, EHCA_PAGESIZE); | ||
1455 | if (ret) | ||
1456 | ehca_err(ibqp->device, "Could not munmap fwh qp_num=%x", | ||
1457 | qp_num); | ||
1458 | } | ||
1459 | |||
1460 | h_ret = hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp); | 1410 | h_ret = hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp); |
1461 | if (h_ret != H_SUCCESS) { | 1411 | if (h_ret != H_SUCCESS) { |
1462 | ehca_err(ibqp->device, "hipz_h_destroy_qp() failed rc=%lx " | 1412 | ehca_err(ibqp->device, "hipz_h_destroy_qp() failed rc=%lx " |