diff options
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/ucma.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 722f2ff0400f..45bb052f573e 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <rdma/rdma_cm.h> | 48 | #include <rdma/rdma_cm.h> |
49 | #include <rdma/rdma_cm_ib.h> | 49 | #include <rdma/rdma_cm_ib.h> |
50 | #include <rdma/ib_addr.h> | 50 | #include <rdma/ib_addr.h> |
51 | #include <rdma/ib.h> | ||
51 | 52 | ||
52 | MODULE_AUTHOR("Sean Hefty"); | 53 | MODULE_AUTHOR("Sean Hefty"); |
53 | MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access"); | 54 | MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access"); |
@@ -782,6 +783,52 @@ static ssize_t ucma_query_path(struct ucma_context *ctx, | |||
782 | return ret; | 783 | return ret; |
783 | } | 784 | } |
784 | 785 | ||
786 | static ssize_t ucma_query_gid(struct ucma_context *ctx, | ||
787 | void __user *response, int out_len) | ||
788 | { | ||
789 | struct rdma_ucm_query_addr_resp resp; | ||
790 | struct sockaddr_ib *addr; | ||
791 | int ret = 0; | ||
792 | |||
793 | if (out_len < sizeof(resp)) | ||
794 | return -ENOSPC; | ||
795 | |||
796 | memset(&resp, 0, sizeof resp); | ||
797 | |||
798 | ucma_query_device_addr(ctx->cm_id, &resp); | ||
799 | |||
800 | addr = (struct sockaddr_ib *) &resp.src_addr; | ||
801 | resp.src_size = sizeof(*addr); | ||
802 | if (ctx->cm_id->route.addr.src_addr.ss_family == AF_IB) { | ||
803 | memcpy(addr, &ctx->cm_id->route.addr.src_addr, resp.src_size); | ||
804 | } else { | ||
805 | addr->sib_family = AF_IB; | ||
806 | addr->sib_pkey = (__force __be16) resp.pkey; | ||
807 | rdma_addr_get_sgid(&ctx->cm_id->route.addr.dev_addr, | ||
808 | (union ib_gid *) &addr->sib_addr); | ||
809 | addr->sib_sid = rdma_get_service_id(ctx->cm_id, (struct sockaddr *) | ||
810 | &ctx->cm_id->route.addr.src_addr); | ||
811 | } | ||
812 | |||
813 | addr = (struct sockaddr_ib *) &resp.dst_addr; | ||
814 | resp.dst_size = sizeof(*addr); | ||
815 | if (ctx->cm_id->route.addr.dst_addr.ss_family == AF_IB) { | ||
816 | memcpy(addr, &ctx->cm_id->route.addr.dst_addr, resp.dst_size); | ||
817 | } else { | ||
818 | addr->sib_family = AF_IB; | ||
819 | addr->sib_pkey = (__force __be16) resp.pkey; | ||
820 | rdma_addr_get_dgid(&ctx->cm_id->route.addr.dev_addr, | ||
821 | (union ib_gid *) &addr->sib_addr); | ||
822 | addr->sib_sid = rdma_get_service_id(ctx->cm_id, (struct sockaddr *) | ||
823 | &ctx->cm_id->route.addr.dst_addr); | ||
824 | } | ||
825 | |||
826 | if (copy_to_user(response, &resp, sizeof(resp))) | ||
827 | ret = -EFAULT; | ||
828 | |||
829 | return ret; | ||
830 | } | ||
831 | |||
785 | static ssize_t ucma_query(struct ucma_file *file, | 832 | static ssize_t ucma_query(struct ucma_file *file, |
786 | const char __user *inbuf, | 833 | const char __user *inbuf, |
787 | int in_len, int out_len) | 834 | int in_len, int out_len) |
@@ -806,6 +853,9 @@ static ssize_t ucma_query(struct ucma_file *file, | |||
806 | case RDMA_USER_CM_QUERY_PATH: | 853 | case RDMA_USER_CM_QUERY_PATH: |
807 | ret = ucma_query_path(ctx, response, out_len); | 854 | ret = ucma_query_path(ctx, response, out_len); |
808 | break; | 855 | break; |
856 | case RDMA_USER_CM_QUERY_GID: | ||
857 | ret = ucma_query_gid(ctx, response, out_len); | ||
858 | break; | ||
809 | default: | 859 | default: |
810 | ret = -ENOSYS; | 860 | ret = -ENOSYS; |
811 | break; | 861 | break; |