aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/core/ucma.c50
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
52MODULE_AUTHOR("Sean Hefty"); 53MODULE_AUTHOR("Sean Hefty");
53MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access"); 54MODULE_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
786static 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
785static ssize_t ucma_query(struct ucma_file *file, 832static 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;