Version: 1
-Previous: 70b3767e09bbe961fd489b373b57135488914bfb
-Head: 9754eea0cdcfddb3cf2ea68dedafb76f9717bc4e
+Previous: 238efd9745ed2b9dca4ac7121b30bf0a1c7a9bc3
+Head: ea0fdc0d9acb6371d6131f7103373f37bfc9bd37
Applied:
ext: bd9562c3a152f1aeb3cd985d906fd28d1da11fe1
xrc: 563fb8c3e4ac4b1bb34706822e65c761cbb918d3
xsrq_sample: 5099ebb63980b28a82fde95e55bed02ea699092e
open_qp: 94332ed744f0a660d7654ddd75619d415c712289
open-qp-man: ff127a22f2a7e7190bde348b2ed38dd490ecfe20
- ofed: 102a2b871dba4b496d019398dd00248c340869f7
- refresh-temp: 9754eea0cdcfddb3cf2ea68dedafb76f9717bc4e
+ ofed: ea0fdc0d9acb6371d6131f7103373f37bfc9bd37
Unapplied:
Hidden:
Bottom: fd22b1cde9dbc9f53e043079140375fdc38b560b
-Top: 80221cbccfbc5378ebfeeeb991764644be408236
+Top: 87258c344a755791648258063d6a701efa4ffb61
Author: Sean Hefty <sean.hefty@intel.com>
Date: 2011-12-22 00:14:12 -0800
man_MANS = man/ibv_asyncwatch.1 man/ibv_devices.1 man/ibv_devinfo.1 \
man/ibv_rc_pingpong.1 man/ibv_uc_pingpong.1 man/ibv_ud_pingpong.1 \
+diff --git a/include/infiniband/ofverbs-defs.h b/include/infiniband/ofverbs-defs.h
+new file mode 100644
+index 0000000..c260006
+--- /dev/null
++++ b/include/infiniband/ofverbs-defs.h
+@@ -0,0 +1,54 @@
++/*
++ * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
++ * Copyright (c) 2004, 2011 Intel Corporation. All rights reserved.
++ * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved.
++ * Copyright (c) 2005 PathScale, Inc. All rights reserved.
++ *
++ * This software is available to you under a choice of one of two
++ * licenses. You may choose to be licensed under the terms of the GNU
++ * General Public License (GPL) Version 2, available from the file
++ * COPYING in the main directory of this source tree, or the
++ * OpenIB.org BSD license below:
++ *
++ * Redistribution and use in source and binary forms, with or
++ * without modification, are permitted provided that the following
++ * conditions are met:
++ *
++ * - Redistributions of source code must retain the above
++ * copyright notice, this list of conditions and the following
++ * disclaimer.
++ *
++ * - Redistributions in binary form must reproduce the above
++ * copyright notice, this list of conditions and the following
++ * disclaimer in the documentation and/or other materials
++ * provided with the distribution.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++ * SOFTWARE.
++ */
++
++#ifndef OFVERBS_DEFS_H
++#define OFVERBS_DEFS_H
++
++/*
++ * Include this file before verbs.h or at the top of verbs.h. This will
++ * map the names of the ibv_* structures to _real_ibv_*. The
++ * ofv_* structure names are then mapped to ibv_*.
++ */
++#ifdef OFED_VERBS
++
++#define ibv_srq _real_ibv_srq
++#define ibv_qp _real_ibv_qp
++#define ibv_qp_init_attr _real_ibv_qp_init_attr
++#define ibv_send_wr _real_ibv_send_wr
++#define ibv_async_event _real_ibv_async_event
++
++#endif /* OFED_VERBS */
++
++#endif /* OFVERBS_DEFS_H */
+diff --git a/include/infiniband/ofverbs.h b/include/infiniband/ofverbs.h
+new file mode 100644
+index 0000000..b03d7ae
+--- /dev/null
++++ b/include/infiniband/ofverbs.h
+@@ -0,0 +1,360 @@
++/*
++ * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
++ * Copyright (c) 2004, 2011 Intel Corporation. All rights reserved.
++ * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved.
++ * Copyright (c) 2005 PathScale, Inc. All rights reserved.
++ *
++ * This software is available to you under a choice of one of two
++ * licenses. You may choose to be licensed under the terms of the GNU
++ * General Public License (GPL) Version 2, available from the file
++ * COPYING in the main directory of this source tree, or the
++ * OpenIB.org BSD license below:
++ *
++ * Redistribution and use in source and binary forms, with or
++ * without modification, are permitted provided that the following
++ * conditions are met:
++ *
++ * - Redistributions of source code must retain the above
++ * copyright notice, this list of conditions and the following
++ * disclaimer.
++ *
++ * - Redistributions in binary form must reproduce the above
++ * copyright notice, this list of conditions and the following
++ * disclaimer in the documentation and/or other materials
++ * provided with the distribution.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++ * SOFTWARE.
++ */
++
++#ifndef OFVERBS_H
++#define OFVERBS_H
++
++/*
++ * Include this file after verbs.h or at the end of verbs.h. This will
++ * replace ibv_* structures and calls with syntax matching that shipped
++ * with the OFED version of libibverbs.
++ */
++
++#include <stdint.h>
++#include <stdlib.h>
++#include <stddef.h>
++#include <errno.h>
++
++#ifdef __cplusplus
++# define BEGIN_C_DECLS extern "C" {
++# define END_C_DECLS }
++#else /* !__cplusplus */
++# define BEGIN_C_DECLS
++# define END_C_DECLS
++#endif /* __cplusplus */
++
++#if __GNUC__ >= 3
++# define __attribute_const __attribute__((const))
++#else
++# define __attribute_const
++#endif
++
++BEGIN_C_DECLS
++
++/* Unmap defines from ofverbs-defs.h */
++#if OFED_VERBS
++#undef ibv_srq
++#undef ibv_qp
++#undef ibv_qp_init_attr
++#undef ibv_send_wr
++#undef ibv_async_event
++
++#define ofv_srq ibv_srq
++#define ofv_qp ibv_qp
++#define ofv_qp_init_attr ibv_qp_init_attr
++#define ofv_send_wr ibv_send_wr
++#define ofv_async_event ibv_async_event
++#define ofv_xrc_domain ibv_xrc_domain
++
++#define OFV_XRC_QP_EVENT_FLAG IBV_XRC_QP_EVENT_FLAG
++
++#else
++
++#define _real_ibv_srq ibv_srq
++#define _real_ibv_qp ibv_qp
++#define _real_ibv_qp_init_attr ibv_qp_init_attr
++#define _real_ibv_send_wr ibv_send_wr
++#define _real_ibv_async_event ibv_async_event
++#endif /* OFED_VERBS */
++
++enum ofv_event_flags {
++ OFV_XRC_QP_EVENT_FLAG = 0x80000000,
++};
++
++struct ofv_async_event {
++ union {
++ struct ibv_cq *cq;
++ struct ofv_qp *qp;
++ struct ofv_srq *srq;
++ int port_num;
++ uint32_t xrc_qp_num;
++ } element;
++ enum ibv_event_type event_type;
++ void *private;
++};
++
++int ofv_get_async_event(struct ibv_context *context,
++ struct ofv_async_event *event);
++
++void ofv_ack_async_event(struct ofv_async_event *event);
++
++struct ofv_xrc_domain {
++ struct ibv_context *context;
++ uint32_t handle;
++
++ struct ibv_xrcd *xrcd;
++ void *qp_tree;
++};
++
++struct ofv_xrc_domain *ofv_open_xrc_domain(struct ibv_context *context,
++ int fd, int oflags);
++
++int ofv_close_xrc_domain(struct ofv_xrc_domain *xrcd);
++
++enum {
++ OFV_QPT_XRC = IBV_QPT_XRC_SEND
++};
++
++struct ofv_srq {
++ struct ibv_context *context;
++ void *srq_context;
++ struct ibv_pd *pd;
++ uint32_t handle;
++
++ pthread_mutex_t mutex;
++ pthread_cond_t cond;
++ uint32_t events_completed;
++
++ enum ibv_srq_type srq_type;
++ struct ofv_xrc_domain *xrc_domain;
++ struct ibv_cq *xrc_cq;
++ uint32_t xrc_srq_num;
++};
++
++static inline struct ofv_srq *
++ofv_create_srq(struct ibv_pd *pd, struct ibv_srq_init_attr *srq_init_attr)
++{
++ return (struct ofv_srq *) ibv_create_srq(pd, srq_init_attr);
++}
++
++static inline struct ofv_srq *
++ofv_create_xrc_srq(struct ibv_pd *pd, struct ofv_xrc_domain *xrc_domain,
++ struct ibv_cq *xrc_cq, struct ibv_srq_init_attr *srq_init_attr)
++{
++ srq_init_attr->srq_type = IBV_SRQT_XRC;
++ srq_init_attr->ext.xrc.xrcd = xrc_domain->xrcd;
++ srq_init_attr->ext.xrc.cq = xrc_cq;
++ return (struct ofv_srq *) ibv_create_xsrq(pd, srq_init_attr);
++}
++
++static inline int
++ofv_modify_srq(struct ofv_srq *srq, struct ibv_srq_attr *srq_attr, int srq_attr_mask)
++{
++ return ibv_modify_srq((struct _real_ibv_srq *) srq, srq_attr, srq_attr_mask);
++}
++
++static inline int ofv_query_srq(struct ofv_srq *srq, struct ibv_srq_attr *srq_attr)
++{
++ return ibv_query_srq((struct _real_ibv_srq *) srq, srq_attr);
++}
++
++static inline int ofv_destroy_srq(struct ofv_srq *srq)
++{
++ return ibv_destroy_srq((struct _real_ibv_srq *) srq);
++}
++
++static inline int ofv_post_srq_recv(struct ofv_srq *srq,
++ struct ibv_recv_wr *recv_wr,
++ struct ibv_recv_wr **bad_recv_wr)
++{
++ return ibv_post_srq_recv((struct _real_ibv_srq *) srq, recv_wr, bad_recv_wr);
++}
++
++struct ofv_qp_init_attr {
++ void *qp_context;
++ struct ibv_cq *send_cq;
++ struct ibv_cq *recv_cq;
++ struct ofv_srq *srq;
++ struct ibv_qp_cap cap;
++ enum ibv_qp_type qp_type;
++ int sq_sig_all;
++
++ struct ofv_xrc_domain *xrc_domain;
++};
++
++struct ofv_qp {
++ struct ibv_context *context;
++ void *qp_context;
++ struct ibv_pd *pd;
++ struct ibv_cq *send_cq;
++ struct ibv_cq *recv_cq;
++ struct ofv_srq *srq;
++ uint32_t handle;
++ uint32_t qp_num;
++ enum ibv_qp_state state;
++ enum ibv_qp_type qp_type;
++
++ pthread_mutex_t mutex;
++ pthread_cond_t cond;
++ uint32_t events_completed;
++
++ struct ofv_xrc_domain *xrc_domain;
++};
++
++static inline struct ofv_qp *
++ofv_create_qp(struct ibv_pd *pd, struct ofv_qp_init_attr *qp_init_attr)
++{
++ return (struct ofv_qp *)
++ ibv_create_qp(pd, (struct _real_ibv_qp_init_attr *) qp_init_attr);
++}
++
++static inline int ofv_modify_qp(struct ofv_qp *qp, struct ibv_qp_attr *attr,
++ int attr_mask)
++{
++ return ibv_modify_qp((struct _real_ibv_qp *) qp, attr, attr_mask);
++}
++
++static inline int ofv_query_qp(struct ofv_qp *qp, struct ibv_qp_attr *attr,
++ int attr_mask, struct ofv_qp_init_attr *init_attr)
++{
++ return ibv_query_qp((struct _real_ibv_qp *) qp, attr, attr_mask,
++ (struct _real_ibv_qp_init_attr *) init_attr);
++}
++
++
++static inline int ofv_destroy_qp(struct ofv_qp *qp)
++{
++ return ibv_destroy_qp((struct _real_ibv_qp *) qp);
++}
++
++struct ofv_send_wr {
++ uint64_t wr_id;
++ struct ibv_send_wr *next;
++ struct ibv_sge *sg_list;
++ int num_sge;
++ enum ibv_wr_opcode opcode;
++ int send_flags;
++ uint32_t imm_data; /* in network byte order */
++ union {
++ union {
++ struct {
++ uint64_t remote_addr;
++ uint32_t rkey;
++ } rdma;
++ struct {
++ uint64_t remote_addr;
++ uint64_t compare_add;
++ uint64_t swap;
++ uint32_t rkey;
++ } atomic;
++ struct {
++ struct ibv_ah *ah;
++ uint32_t remote_qpn;
++ uint32_t remote_qkey;
++ } ud;
++ struct {
++ uint64_t reserved[3];
++ uint32_t reserved2;
++ uint32_t remote_srqn;
++ } xrc;
++ } wr;
++ struct {
++ uint64_t reserved[3];
++ uint32_t reserved2;
++ uint32_t xrc_remote_srq_num;
++ };
++ };
++};
++
++static inline int ofv_post_send(struct ofv_qp *qp, struct ofv_send_wr *wr,
++ struct ofv_send_wr **bad_wr)
++{
++ return ibv_post_send((struct _real_ibv_qp *) qp, (struct _real_ibv_send_wr *) wr,
++ (struct _real_ibv_send_wr **) bad_wr);
++}
++
++static inline int ofv_post_recv(struct ofv_qp *qp, struct ibv_recv_wr *wr,
++ struct ibv_recv_wr **bad_wr)
++{
++ return ibv_post_recv((struct _real_ibv_qp *) qp, wr, bad_wr);
++}
++
++static inline int ofv_attach_mcast(struct ofv_qp *qp, const union ibv_gid *gid,
++ uint16_t lid)
++{
++ return ibv_attach_mcast((struct _real_ibv_qp *) qp, gid, lid);
++}
++
++static inline int ofv_detach_mcast(struct ofv_qp *qp, const union ibv_gid *gid,
++ uint16_t lid)
++{
++ return ibv_detach_mcast((struct _real_ibv_qp *) qp, gid, lid);
++}
++
++int ofv_create_xrc_rcv_qp(struct ofv_qp_init_attr *init_attr, uint32_t *xrc_rcv_qpn);
++
++int ofv_modify_xrc_rcv_qp(struct ofv_xrc_domain *xrc_domain,
++ uint32_t xrc_qp_num,
++ struct ibv_qp_attr *attr, int attr_mask);
++
++int ofv_query_xrc_rcv_qp(struct ofv_xrc_domain *xrc_domain,
++ uint32_t xrc_qp_num,
++ struct ibv_qp_attr *attr, int attr_mask,
++ struct ofv_qp_init_attr *init_attr);
++
++int ofv_reg_xrc_rcv_qp(struct ofv_xrc_domain *xrc_domain, uint32_t xrc_qp_num);
++
++int ofv_unreg_xrc_rcv_qp(struct ofv_xrc_domain *xrc_domain, uint32_t xrc_qp_num);
++
++/*
++ * Map the ibv_* calls to OFED verbs versions.
++ */
++#ifdef OFED_VERBS
++#define ibv_get_async_event(c,e) ofv_get_async_event(c,e)
++#define ibv_ack_async_event(e) ofv_ack_async_event(e)
++
++#define ibv_open_xrc_domain(c,f,g) ofv_open_xrc_domain(c,f,g)
++#define ibv_close_xrc_domain(d) ofv_close_xrc_domain(d)
++
++#define ibv_create_srq(p,a) ofv_create_srq(p,a)
++#define ibv_create_xrc_srq(p,d,c,a) ofv_create_xrc_srq(p,d,c,a)
++#define ibv_modify_srq(s,a,m) ofv_modify_srq(s,a,m)
++#define ibv_query_srq(s,a) ofv_query_srq(s,a)
++#define ibv_destroy_srq(s) ofv_destroy_srq(s)
++#define ibv_post_srq_recv(s,w,b) ofv_post_srq_recv(s,w,b)
++
++#define IBV_QPT_XRC ((enum ibv_qp_type) OFV_QPT_XRC)
++#define ibv_create_qp(p,a) ofv_create_qp(p,a)
++#define ibv_query_qp(q,a,m,i) ofv_query_qp(p,a,m,i)
++#define ibv_modify_qp(q,a,m) ofv_modify_qp(q,a,m)
++#define ibv_query_qp(q,a,m,i) ofv_query_qp(q,a,m,i)
++#define ibv_destroy_qp(q) ofv_destroy_qp(q)
++#define ibv_post_send(q,w,b) ofv_post_send(q,w,b)
++#define ibv_post_recv(q,w,b) ofv_post_recv(q,w,b)
++#define ibv_attach_mcast(q,g,l) ofv_attach_mcast(q,g,l)
++#define ibv_detach_mcast(q,g,l) ofv_detach_mcast(q,g,l)
++
++#define ibv_create_xrc_rcv_qp(a,q) ofv_create_xrc_rcv_qp(a,q)
++#define ibv_modify_xrc_rcv_qp(d,q,a,m) ofv_modify_xrc_rcv_qp(d,q,a,m)
++#define ibv_query_xrc_rcv_qp(d,q,a,m,i) ofv_query_xrc_rcv_qp(d,q,a,m,i)
++#define ibv_reg_xrc_rcv_qp(d,q) ofv_reg_xrc_rcv_qp(d,q)
++#define ibv_unreg_xrc_rcv_qp(d,q) ofv_unreg_xrc_rcv_qp(d,q)
++#endif /* OFED_VERBS */
++
++END_C_DECLS
++
++# undef __attribute_const
++
++#endif /* OFVERBS_H */
diff --git a/include/infiniband/verbs.h b/include/infiniband/verbs.h
index a499a50..1dcd17f 100644
--- a/include/infiniband/verbs.h
+ ofv_reg_xrc_rcv_qp;
+ ofv_unreg_xrc_rcv_qp;
} IBVERBS_1.0;
+diff --git a/src/ofverbs.c b/src/ofverbs.c
+new file mode 100644
+index 0000000..0486552
+--- /dev/null
++++ b/src/ofverbs.c
+@@ -0,0 +1,218 @@
++/*
++ * Copyright (c) 2011 Intel Corporation, Inc. All rights reserved.
++ *
++ * This software is available to you under a choice of one of two
++ * licenses. You may choose to be licensed under the terms of the GNU
++ * General Public License (GPL) Version 2, available from the file
++ * COPYING in the main directory of this source tree, or the
++ * OpenIB.org BSD license below:
++ *
++ * Redistribution and use in source and binary forms, with or
++ * without modification, are permitted provided that the following
++ * conditions are met:
++ *
++ * - Redistributions of source code must retain the above
++ * copyright notice, this list of conditions and the following
++ * disclaimer.
++ *
++ * - Redistributions in binary form must reproduce the above
++ * copyright notice, this list of conditions and the following
++ * disclaimer in the documentation and/or other materials
++ * provided with the distribution.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++ * SOFTWARE.
++ */
++
++#if HAVE_CONFIG_H
++# include <config.h>
++#endif /* HAVE_CONFIG_H */
++
++#include <stdint.h>
++#include <search.h>
++#include <stdlib.h>
++#include <stddef.h>
++#include <errno.h>
++
++#include <infiniband/ofverbs-defs.h>
++#include <infiniband/verbs.h>
++#include <infiniband/ofverbs.h>
++#include "ibverbs.h"
++
++int __ofv_get_async_event(struct ibv_context *context,
++ struct ofv_async_event *event)
++{
++ int ret;
++
++ ret = ibv_get_async_event(context, (struct ibv_async_event *) event);
++ if (!ret) {
++ switch (event->event_type) {
++ case IBV_EVENT_QP_FATAL:
++ case IBV_EVENT_QP_REQ_ERR:
++ case IBV_EVENT_QP_ACCESS_ERR:
++ case IBV_EVENT_COMM_EST:
++ case IBV_EVENT_PATH_MIG:
++ case IBV_EVENT_PATH_MIG_ERR:
++ case IBV_EVENT_QP_LAST_WQE_REACHED:
++ if (event->element.qp->qp_type == IBV_QPT_XRC_RECV) {
++ event->private = event->element.qp;
++ event->event_type |= OFV_XRC_QP_EVENT_FLAG;
++ event->element.xrc_qp_num = event->element.qp->qp_num;
++ }
++ default:
++ break;
++ }
++ }
++ return ret;
++}
++default_symver(__ofv_get_async_event, ofv_get_async_event);
++
++void ofv_ack_async_event(struct ofv_async_event *event)
++{
++ if (event->event_type & OFV_XRC_QP_EVENT_FLAG) {
++ event->element.qp = event->private;
++ event->event_type &= ~OFV_XRC_QP_EVENT_FLAG;
++ }
++ ibv_ack_async_event((struct ibv_async_event *) event);
++}
++default_symver(__ofv_ack_async_event, ofv_ack_async_event);
++
++struct ofv_xrc_domain *
++__ofv_open_xrc_domain(struct ibv_context *context, int fd, int oflags)
++{
++ struct ofv_xrc_domain *xrcd;
++
++ xrcd = calloc(1, sizeof *xrcd);
++ if (!xrcd)
++ return NULL;
++
++ xrcd->xrcd = ibv_open_xrcd(context, fd, oflags);
++ if (!xrcd->xrcd) {
++ free(xrcd);
++ return NULL;
++ }
++
++ xrcd->context = context;
++ xrcd->handle = xrcd->xrcd->handle;
++ return xrcd;
++}
++default_symver(__ofv_open_xrc_domain, ofv_open_xrc_domain);
++
++static void ofv_free_node(void *node)
++{
++}
++
++int __ofv_close_xrc_domain(struct ofv_xrc_domain *xrcd)
++{
++ int ret;
++
++ ret = ibv_close_xrcd(xrcd->xrcd);
++ if (ret)
++ return ret;
++
++ tdestroy(xrcd->qp_tree, ofv_free_node);
++ free(xrcd);
++ return 0;
++}
++default_symver(__ofv_close_xrc_domain, ofv_close_xrc_domain);
++
++static int ofv_qp_compare(const void *a, const void *b)
++{
++ if ((*(uint32_t *) a) < (*(uint32_t *) b))
++ return -1;
++ else if ((*(uint32_t *) a) > (*(uint32_t *) b))
++ return 1;
++ else
++ return 0;
++}
++
++int __ofv_create_xrc_rcv_qp(struct ofv_qp_init_attr *init_attr, uint32_t *xrc_rcv_qpn)
++{
++ struct ofv_xrc_domain *xrcd;
++ struct ibv_qp *qp;
++
++ xrcd = init_attr->xrc_domain;
++ init_attr->qp_type = IBV_QPT_XRC_RECV;
++ ((struct ibv_qp_init_attr *) init_attr)->ext.xrc_recv.xrcd = xrcd->xrcd;
++ qp = ibv_create_qp(NULL, (struct ibv_qp_init_attr *) init_attr);
++ init_attr->xrc_domain = xrcd;
++ if (!qp)
++ return ENOMEM;
++
++ tsearch(&qp->qp_num, &xrcd->qp_tree, ofv_qp_compare);
++ *xrc_rcv_qpn = qp->qp_num;
++ return 0;
++}
++default_symver(__ofv_create_xrc_rcv_qp, ofv_create_xrc_rcv_qp);
++
++int __ofv_modify_xrc_rcv_qp(struct ofv_xrc_domain *xrc_domain,
++ uint32_t xrc_qp_num,
++ struct ibv_qp_attr *attr, int attr_mask)
++{
++ struct ibv_qp *qp;
++ uint32_t **qpn;
++
++ qpn = tfind(&xrc_qp_num, &xrc_domain->qp_tree, ofv_qp_compare);
++ if (!qpn)
++ return EINVAL;
++
++ qp = ((struct ibv_qp *) ((void *) *qpn - offsetof(struct ibv_qp, qp_num)));
++ return ibv_modify_qp(qp, attr, attr_mask);
++}
++default_symver(__ofv_modify_xrc_rcv_qp, ofv_modify_xrc_rcv_qp);
++
++int __ofv_query_xrc_rcv_qp(struct ofv_xrc_domain *xrc_domain,
++ uint32_t xrc_qp_num,
++ struct ibv_qp_attr *attr, int attr_mask,
++ struct ofv_qp_init_attr *init_attr)
++{
++ struct ibv_qp *qp;
++ uint32_t **qpn;
++
++ qpn = tfind(&xrc_qp_num, &xrc_domain->qp_tree, ofv_qp_compare);
++ if (!qpn)
++ return EINVAL;
++
++ qp = ((struct ibv_qp *) ((void *) *qpn - offsetof(struct ibv_qp, qp_num)));
++ return ibv_query_qp(qp, attr, attr_mask,
++ (struct ibv_qp_init_attr *) init_attr);
++}
++default_symver(__ofv_query_xrc_rcv_qp, ofv_query_xrc_rcv_qp);
++
++int ofv_reg_xrc_rcv_qp(struct ofv_xrc_domain *xrc_domain, uint32_t xrc_qp_num)
++{
++ struct ibv_qp *qp;
++ struct ibv_qp_open_attr attr;
++
++ attr.qp_context = xrc_domain;
++ attr.qp_num = xrc_qp_num;
++ attr.qp_type = IBV_QPT_XRC_RECV;
++
++ qp = ibv_open_qp(xrc_domain->xrcd, &attr);
++ if (!qp)
++ return ENOMEM;
++
++ tsearch(&qp->qp_num, &xrc_domain->qp_tree, ofv_qp_compare);
++ return 0;
++}
++default_symver(__ofv_reg_xrc_rcv_qp, ofv_reg_xrc_rcv_qp);
++
++int ofv_unreg_xrc_rcv_qp(struct ofv_xrc_domain *xrc_domain, uint32_t xrc_qp_num)
++{
++ struct ibv_qp *qp;
++ uint32_t **qpn;
++
++ qpn = tfind(&xrc_qp_num, &xrc_domain->qp_tree, ofv_qp_compare);
++ if (!qpn)
++ return EINVAL;
++
++ qp = ((struct ibv_qp *) ((void *) *qpn - offsetof(struct ibv_qp, qp_num)));
++ return ibv_destroy_qp(qp);
++}
++default_symver(__ofv_unreg_xrc_rcv_qp, ofv_unreg_xrc_rcv_qp);
+++ /dev/null
-Bottom: 80221cbccfbc5378ebfeeeb991764644be408236
-Top: 87258c344a755791648258063d6a701efa4ffb61
-Author: Sean Hefty <sean.hefty@intel.com>
-Date: 2011-12-22 00:16:28 -0800
-
-Refresh of ofed
-
----
-
-diff --git a/include/infiniband/ofverbs-defs.h b/include/infiniband/ofverbs-defs.h
-new file mode 100644
-index 0000000..c260006
---- /dev/null
-+++ b/include/infiniband/ofverbs-defs.h
-@@ -0,0 +1,54 @@
-+/*
-+ * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
-+ * Copyright (c) 2004, 2011 Intel Corporation. All rights reserved.
-+ * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved.
-+ * Copyright (c) 2005 PathScale, Inc. All rights reserved.
-+ *
-+ * This software is available to you under a choice of one of two
-+ * licenses. You may choose to be licensed under the terms of the GNU
-+ * General Public License (GPL) Version 2, available from the file
-+ * COPYING in the main directory of this source tree, or the
-+ * OpenIB.org BSD license below:
-+ *
-+ * Redistribution and use in source and binary forms, with or
-+ * without modification, are permitted provided that the following
-+ * conditions are met:
-+ *
-+ * - Redistributions of source code must retain the above
-+ * copyright notice, this list of conditions and the following
-+ * disclaimer.
-+ *
-+ * - Redistributions in binary form must reproduce the above
-+ * copyright notice, this list of conditions and the following
-+ * disclaimer in the documentation and/or other materials
-+ * provided with the distribution.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-+ * SOFTWARE.
-+ */
-+
-+#ifndef OFVERBS_DEFS_H
-+#define OFVERBS_DEFS_H
-+
-+/*
-+ * Include this file before verbs.h or at the top of verbs.h. This will
-+ * map the names of the ibv_* structures to _real_ibv_*. The
-+ * ofv_* structure names are then mapped to ibv_*.
-+ */
-+#ifdef OFED_VERBS
-+
-+#define ibv_srq _real_ibv_srq
-+#define ibv_qp _real_ibv_qp
-+#define ibv_qp_init_attr _real_ibv_qp_init_attr
-+#define ibv_send_wr _real_ibv_send_wr
-+#define ibv_async_event _real_ibv_async_event
-+
-+#endif /* OFED_VERBS */
-+
-+#endif /* OFVERBS_DEFS_H */
-diff --git a/include/infiniband/ofverbs.h b/include/infiniband/ofverbs.h
-new file mode 100644
-index 0000000..b03d7ae
---- /dev/null
-+++ b/include/infiniband/ofverbs.h
-@@ -0,0 +1,360 @@
-+/*
-+ * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
-+ * Copyright (c) 2004, 2011 Intel Corporation. All rights reserved.
-+ * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved.
-+ * Copyright (c) 2005 PathScale, Inc. All rights reserved.
-+ *
-+ * This software is available to you under a choice of one of two
-+ * licenses. You may choose to be licensed under the terms of the GNU
-+ * General Public License (GPL) Version 2, available from the file
-+ * COPYING in the main directory of this source tree, or the
-+ * OpenIB.org BSD license below:
-+ *
-+ * Redistribution and use in source and binary forms, with or
-+ * without modification, are permitted provided that the following
-+ * conditions are met:
-+ *
-+ * - Redistributions of source code must retain the above
-+ * copyright notice, this list of conditions and the following
-+ * disclaimer.
-+ *
-+ * - Redistributions in binary form must reproduce the above
-+ * copyright notice, this list of conditions and the following
-+ * disclaimer in the documentation and/or other materials
-+ * provided with the distribution.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-+ * SOFTWARE.
-+ */
-+
-+#ifndef OFVERBS_H
-+#define OFVERBS_H
-+
-+/*
-+ * Include this file after verbs.h or at the end of verbs.h. This will
-+ * replace ibv_* structures and calls with syntax matching that shipped
-+ * with the OFED version of libibverbs.
-+ */
-+
-+#include <stdint.h>
-+#include <stdlib.h>
-+#include <stddef.h>
-+#include <errno.h>
-+
-+#ifdef __cplusplus
-+# define BEGIN_C_DECLS extern "C" {
-+# define END_C_DECLS }
-+#else /* !__cplusplus */
-+# define BEGIN_C_DECLS
-+# define END_C_DECLS
-+#endif /* __cplusplus */
-+
-+#if __GNUC__ >= 3
-+# define __attribute_const __attribute__((const))
-+#else
-+# define __attribute_const
-+#endif
-+
-+BEGIN_C_DECLS
-+
-+/* Unmap defines from ofverbs-defs.h */
-+#if OFED_VERBS
-+#undef ibv_srq
-+#undef ibv_qp
-+#undef ibv_qp_init_attr
-+#undef ibv_send_wr
-+#undef ibv_async_event
-+
-+#define ofv_srq ibv_srq
-+#define ofv_qp ibv_qp
-+#define ofv_qp_init_attr ibv_qp_init_attr
-+#define ofv_send_wr ibv_send_wr
-+#define ofv_async_event ibv_async_event
-+#define ofv_xrc_domain ibv_xrc_domain
-+
-+#define OFV_XRC_QP_EVENT_FLAG IBV_XRC_QP_EVENT_FLAG
-+
-+#else
-+
-+#define _real_ibv_srq ibv_srq
-+#define _real_ibv_qp ibv_qp
-+#define _real_ibv_qp_init_attr ibv_qp_init_attr
-+#define _real_ibv_send_wr ibv_send_wr
-+#define _real_ibv_async_event ibv_async_event
-+#endif /* OFED_VERBS */
-+
-+enum ofv_event_flags {
-+ OFV_XRC_QP_EVENT_FLAG = 0x80000000,
-+};
-+
-+struct ofv_async_event {
-+ union {
-+ struct ibv_cq *cq;
-+ struct ofv_qp *qp;
-+ struct ofv_srq *srq;
-+ int port_num;
-+ uint32_t xrc_qp_num;
-+ } element;
-+ enum ibv_event_type event_type;
-+ void *private;
-+};
-+
-+int ofv_get_async_event(struct ibv_context *context,
-+ struct ofv_async_event *event);
-+
-+void ofv_ack_async_event(struct ofv_async_event *event);
-+
-+struct ofv_xrc_domain {
-+ struct ibv_context *context;
-+ uint32_t handle;
-+
-+ struct ibv_xrcd *xrcd;
-+ void *qp_tree;
-+};
-+
-+struct ofv_xrc_domain *ofv_open_xrc_domain(struct ibv_context *context,
-+ int fd, int oflags);
-+
-+int ofv_close_xrc_domain(struct ofv_xrc_domain *xrcd);
-+
-+enum {
-+ OFV_QPT_XRC = IBV_QPT_XRC_SEND
-+};
-+
-+struct ofv_srq {
-+ struct ibv_context *context;
-+ void *srq_context;
-+ struct ibv_pd *pd;
-+ uint32_t handle;
-+
-+ pthread_mutex_t mutex;
-+ pthread_cond_t cond;
-+ uint32_t events_completed;
-+
-+ enum ibv_srq_type srq_type;
-+ struct ofv_xrc_domain *xrc_domain;
-+ struct ibv_cq *xrc_cq;
-+ uint32_t xrc_srq_num;
-+};
-+
-+static inline struct ofv_srq *
-+ofv_create_srq(struct ibv_pd *pd, struct ibv_srq_init_attr *srq_init_attr)
-+{
-+ return (struct ofv_srq *) ibv_create_srq(pd, srq_init_attr);
-+}
-+
-+static inline struct ofv_srq *
-+ofv_create_xrc_srq(struct ibv_pd *pd, struct ofv_xrc_domain *xrc_domain,
-+ struct ibv_cq *xrc_cq, struct ibv_srq_init_attr *srq_init_attr)
-+{
-+ srq_init_attr->srq_type = IBV_SRQT_XRC;
-+ srq_init_attr->ext.xrc.xrcd = xrc_domain->xrcd;
-+ srq_init_attr->ext.xrc.cq = xrc_cq;
-+ return (struct ofv_srq *) ibv_create_xsrq(pd, srq_init_attr);
-+}
-+
-+static inline int
-+ofv_modify_srq(struct ofv_srq *srq, struct ibv_srq_attr *srq_attr, int srq_attr_mask)
-+{
-+ return ibv_modify_srq((struct _real_ibv_srq *) srq, srq_attr, srq_attr_mask);
-+}
-+
-+static inline int ofv_query_srq(struct ofv_srq *srq, struct ibv_srq_attr *srq_attr)
-+{
-+ return ibv_query_srq((struct _real_ibv_srq *) srq, srq_attr);
-+}
-+
-+static inline int ofv_destroy_srq(struct ofv_srq *srq)
-+{
-+ return ibv_destroy_srq((struct _real_ibv_srq *) srq);
-+}
-+
-+static inline int ofv_post_srq_recv(struct ofv_srq *srq,
-+ struct ibv_recv_wr *recv_wr,
-+ struct ibv_recv_wr **bad_recv_wr)
-+{
-+ return ibv_post_srq_recv((struct _real_ibv_srq *) srq, recv_wr, bad_recv_wr);
-+}
-+
-+struct ofv_qp_init_attr {
-+ void *qp_context;
-+ struct ibv_cq *send_cq;
-+ struct ibv_cq *recv_cq;
-+ struct ofv_srq *srq;
-+ struct ibv_qp_cap cap;
-+ enum ibv_qp_type qp_type;
-+ int sq_sig_all;
-+
-+ struct ofv_xrc_domain *xrc_domain;
-+};
-+
-+struct ofv_qp {
-+ struct ibv_context *context;
-+ void *qp_context;
-+ struct ibv_pd *pd;
-+ struct ibv_cq *send_cq;
-+ struct ibv_cq *recv_cq;
-+ struct ofv_srq *srq;
-+ uint32_t handle;
-+ uint32_t qp_num;
-+ enum ibv_qp_state state;
-+ enum ibv_qp_type qp_type;
-+
-+ pthread_mutex_t mutex;
-+ pthread_cond_t cond;
-+ uint32_t events_completed;
-+
-+ struct ofv_xrc_domain *xrc_domain;
-+};
-+
-+static inline struct ofv_qp *
-+ofv_create_qp(struct ibv_pd *pd, struct ofv_qp_init_attr *qp_init_attr)
-+{
-+ return (struct ofv_qp *)
-+ ibv_create_qp(pd, (struct _real_ibv_qp_init_attr *) qp_init_attr);
-+}
-+
-+static inline int ofv_modify_qp(struct ofv_qp *qp, struct ibv_qp_attr *attr,
-+ int attr_mask)
-+{
-+ return ibv_modify_qp((struct _real_ibv_qp *) qp, attr, attr_mask);
-+}
-+
-+static inline int ofv_query_qp(struct ofv_qp *qp, struct ibv_qp_attr *attr,
-+ int attr_mask, struct ofv_qp_init_attr *init_attr)
-+{
-+ return ibv_query_qp((struct _real_ibv_qp *) qp, attr, attr_mask,
-+ (struct _real_ibv_qp_init_attr *) init_attr);
-+}
-+
-+
-+static inline int ofv_destroy_qp(struct ofv_qp *qp)
-+{
-+ return ibv_destroy_qp((struct _real_ibv_qp *) qp);
-+}
-+
-+struct ofv_send_wr {
-+ uint64_t wr_id;
-+ struct ibv_send_wr *next;
-+ struct ibv_sge *sg_list;
-+ int num_sge;
-+ enum ibv_wr_opcode opcode;
-+ int send_flags;
-+ uint32_t imm_data; /* in network byte order */
-+ union {
-+ union {
-+ struct {
-+ uint64_t remote_addr;
-+ uint32_t rkey;
-+ } rdma;
-+ struct {
-+ uint64_t remote_addr;
-+ uint64_t compare_add;
-+ uint64_t swap;
-+ uint32_t rkey;
-+ } atomic;
-+ struct {
-+ struct ibv_ah *ah;
-+ uint32_t remote_qpn;
-+ uint32_t remote_qkey;
-+ } ud;
-+ struct {
-+ uint64_t reserved[3];
-+ uint32_t reserved2;
-+ uint32_t remote_srqn;
-+ } xrc;
-+ } wr;
-+ struct {
-+ uint64_t reserved[3];
-+ uint32_t reserved2;
-+ uint32_t xrc_remote_srq_num;
-+ };
-+ };
-+};
-+
-+static inline int ofv_post_send(struct ofv_qp *qp, struct ofv_send_wr *wr,
-+ struct ofv_send_wr **bad_wr)
-+{
-+ return ibv_post_send((struct _real_ibv_qp *) qp, (struct _real_ibv_send_wr *) wr,
-+ (struct _real_ibv_send_wr **) bad_wr);
-+}
-+
-+static inline int ofv_post_recv(struct ofv_qp *qp, struct ibv_recv_wr *wr,
-+ struct ibv_recv_wr **bad_wr)
-+{
-+ return ibv_post_recv((struct _real_ibv_qp *) qp, wr, bad_wr);
-+}
-+
-+static inline int ofv_attach_mcast(struct ofv_qp *qp, const union ibv_gid *gid,
-+ uint16_t lid)
-+{
-+ return ibv_attach_mcast((struct _real_ibv_qp *) qp, gid, lid);
-+}
-+
-+static inline int ofv_detach_mcast(struct ofv_qp *qp, const union ibv_gid *gid,
-+ uint16_t lid)
-+{
-+ return ibv_detach_mcast((struct _real_ibv_qp *) qp, gid, lid);
-+}
-+
-+int ofv_create_xrc_rcv_qp(struct ofv_qp_init_attr *init_attr, uint32_t *xrc_rcv_qpn);
-+
-+int ofv_modify_xrc_rcv_qp(struct ofv_xrc_domain *xrc_domain,
-+ uint32_t xrc_qp_num,
-+ struct ibv_qp_attr *attr, int attr_mask);
-+
-+int ofv_query_xrc_rcv_qp(struct ofv_xrc_domain *xrc_domain,
-+ uint32_t xrc_qp_num,
-+ struct ibv_qp_attr *attr, int attr_mask,
-+ struct ofv_qp_init_attr *init_attr);
-+
-+int ofv_reg_xrc_rcv_qp(struct ofv_xrc_domain *xrc_domain, uint32_t xrc_qp_num);
-+
-+int ofv_unreg_xrc_rcv_qp(struct ofv_xrc_domain *xrc_domain, uint32_t xrc_qp_num);
-+
-+/*
-+ * Map the ibv_* calls to OFED verbs versions.
-+ */
-+#ifdef OFED_VERBS
-+#define ibv_get_async_event(c,e) ofv_get_async_event(c,e)
-+#define ibv_ack_async_event(e) ofv_ack_async_event(e)
-+
-+#define ibv_open_xrc_domain(c,f,g) ofv_open_xrc_domain(c,f,g)
-+#define ibv_close_xrc_domain(d) ofv_close_xrc_domain(d)
-+
-+#define ibv_create_srq(p,a) ofv_create_srq(p,a)
-+#define ibv_create_xrc_srq(p,d,c,a) ofv_create_xrc_srq(p,d,c,a)
-+#define ibv_modify_srq(s,a,m) ofv_modify_srq(s,a,m)
-+#define ibv_query_srq(s,a) ofv_query_srq(s,a)
-+#define ibv_destroy_srq(s) ofv_destroy_srq(s)
-+#define ibv_post_srq_recv(s,w,b) ofv_post_srq_recv(s,w,b)
-+
-+#define IBV_QPT_XRC ((enum ibv_qp_type) OFV_QPT_XRC)
-+#define ibv_create_qp(p,a) ofv_create_qp(p,a)
-+#define ibv_query_qp(q,a,m,i) ofv_query_qp(p,a,m,i)
-+#define ibv_modify_qp(q,a,m) ofv_modify_qp(q,a,m)
-+#define ibv_query_qp(q,a,m,i) ofv_query_qp(q,a,m,i)
-+#define ibv_destroy_qp(q) ofv_destroy_qp(q)
-+#define ibv_post_send(q,w,b) ofv_post_send(q,w,b)
-+#define ibv_post_recv(q,w,b) ofv_post_recv(q,w,b)
-+#define ibv_attach_mcast(q,g,l) ofv_attach_mcast(q,g,l)
-+#define ibv_detach_mcast(q,g,l) ofv_detach_mcast(q,g,l)
-+
-+#define ibv_create_xrc_rcv_qp(a,q) ofv_create_xrc_rcv_qp(a,q)
-+#define ibv_modify_xrc_rcv_qp(d,q,a,m) ofv_modify_xrc_rcv_qp(d,q,a,m)
-+#define ibv_query_xrc_rcv_qp(d,q,a,m,i) ofv_query_xrc_rcv_qp(d,q,a,m,i)
-+#define ibv_reg_xrc_rcv_qp(d,q) ofv_reg_xrc_rcv_qp(d,q)
-+#define ibv_unreg_xrc_rcv_qp(d,q) ofv_unreg_xrc_rcv_qp(d,q)
-+#endif /* OFED_VERBS */
-+
-+END_C_DECLS
-+
-+# undef __attribute_const
-+
-+#endif /* OFVERBS_H */
-diff --git a/src/ofverbs.c b/src/ofverbs.c
-new file mode 100644
-index 0000000..0486552
---- /dev/null
-+++ b/src/ofverbs.c
-@@ -0,0 +1,218 @@
-+/*
-+ * Copyright (c) 2011 Intel Corporation, Inc. All rights reserved.
-+ *
-+ * This software is available to you under a choice of one of two
-+ * licenses. You may choose to be licensed under the terms of the GNU
-+ * General Public License (GPL) Version 2, available from the file
-+ * COPYING in the main directory of this source tree, or the
-+ * OpenIB.org BSD license below:
-+ *
-+ * Redistribution and use in source and binary forms, with or
-+ * without modification, are permitted provided that the following
-+ * conditions are met:
-+ *
-+ * - Redistributions of source code must retain the above
-+ * copyright notice, this list of conditions and the following
-+ * disclaimer.
-+ *
-+ * - Redistributions in binary form must reproduce the above
-+ * copyright notice, this list of conditions and the following
-+ * disclaimer in the documentation and/or other materials
-+ * provided with the distribution.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-+ * SOFTWARE.
-+ */
-+
-+#if HAVE_CONFIG_H
-+# include <config.h>
-+#endif /* HAVE_CONFIG_H */
-+
-+#include <stdint.h>
-+#include <search.h>
-+#include <stdlib.h>
-+#include <stddef.h>
-+#include <errno.h>
-+
-+#include <infiniband/ofverbs-defs.h>
-+#include <infiniband/verbs.h>
-+#include <infiniband/ofverbs.h>
-+#include "ibverbs.h"
-+
-+int __ofv_get_async_event(struct ibv_context *context,
-+ struct ofv_async_event *event)
-+{
-+ int ret;
-+
-+ ret = ibv_get_async_event(context, (struct ibv_async_event *) event);
-+ if (!ret) {
-+ switch (event->event_type) {
-+ case IBV_EVENT_QP_FATAL:
-+ case IBV_EVENT_QP_REQ_ERR:
-+ case IBV_EVENT_QP_ACCESS_ERR:
-+ case IBV_EVENT_COMM_EST:
-+ case IBV_EVENT_PATH_MIG:
-+ case IBV_EVENT_PATH_MIG_ERR:
-+ case IBV_EVENT_QP_LAST_WQE_REACHED:
-+ if (event->element.qp->qp_type == IBV_QPT_XRC_RECV) {
-+ event->private = event->element.qp;
-+ event->event_type |= OFV_XRC_QP_EVENT_FLAG;
-+ event->element.xrc_qp_num = event->element.qp->qp_num;
-+ }
-+ default:
-+ break;
-+ }
-+ }
-+ return ret;
-+}
-+default_symver(__ofv_get_async_event, ofv_get_async_event);
-+
-+void ofv_ack_async_event(struct ofv_async_event *event)
-+{
-+ if (event->event_type & OFV_XRC_QP_EVENT_FLAG) {
-+ event->element.qp = event->private;
-+ event->event_type &= ~OFV_XRC_QP_EVENT_FLAG;
-+ }
-+ ibv_ack_async_event((struct ibv_async_event *) event);
-+}
-+default_symver(__ofv_ack_async_event, ofv_ack_async_event);
-+
-+struct ofv_xrc_domain *
-+__ofv_open_xrc_domain(struct ibv_context *context, int fd, int oflags)
-+{
-+ struct ofv_xrc_domain *xrcd;
-+
-+ xrcd = calloc(1, sizeof *xrcd);
-+ if (!xrcd)
-+ return NULL;
-+
-+ xrcd->xrcd = ibv_open_xrcd(context, fd, oflags);
-+ if (!xrcd->xrcd) {
-+ free(xrcd);
-+ return NULL;
-+ }
-+
-+ xrcd->context = context;
-+ xrcd->handle = xrcd->xrcd->handle;
-+ return xrcd;
-+}
-+default_symver(__ofv_open_xrc_domain, ofv_open_xrc_domain);
-+
-+static void ofv_free_node(void *node)
-+{
-+}
-+
-+int __ofv_close_xrc_domain(struct ofv_xrc_domain *xrcd)
-+{
-+ int ret;
-+
-+ ret = ibv_close_xrcd(xrcd->xrcd);
-+ if (ret)
-+ return ret;
-+
-+ tdestroy(xrcd->qp_tree, ofv_free_node);
-+ free(xrcd);
-+ return 0;
-+}
-+default_symver(__ofv_close_xrc_domain, ofv_close_xrc_domain);
-+
-+static int ofv_qp_compare(const void *a, const void *b)
-+{
-+ if ((*(uint32_t *) a) < (*(uint32_t *) b))
-+ return -1;
-+ else if ((*(uint32_t *) a) > (*(uint32_t *) b))
-+ return 1;
-+ else
-+ return 0;
-+}
-+
-+int __ofv_create_xrc_rcv_qp(struct ofv_qp_init_attr *init_attr, uint32_t *xrc_rcv_qpn)
-+{
-+ struct ofv_xrc_domain *xrcd;
-+ struct ibv_qp *qp;
-+
-+ xrcd = init_attr->xrc_domain;
-+ init_attr->qp_type = IBV_QPT_XRC_RECV;
-+ ((struct ibv_qp_init_attr *) init_attr)->ext.xrc_recv.xrcd = xrcd->xrcd;
-+ qp = ibv_create_qp(NULL, (struct ibv_qp_init_attr *) init_attr);
-+ init_attr->xrc_domain = xrcd;
-+ if (!qp)
-+ return ENOMEM;
-+
-+ tsearch(&qp->qp_num, &xrcd->qp_tree, ofv_qp_compare);
-+ *xrc_rcv_qpn = qp->qp_num;
-+ return 0;
-+}
-+default_symver(__ofv_create_xrc_rcv_qp, ofv_create_xrc_rcv_qp);
-+
-+int __ofv_modify_xrc_rcv_qp(struct ofv_xrc_domain *xrc_domain,
-+ uint32_t xrc_qp_num,
-+ struct ibv_qp_attr *attr, int attr_mask)
-+{
-+ struct ibv_qp *qp;
-+ uint32_t **qpn;
-+
-+ qpn = tfind(&xrc_qp_num, &xrc_domain->qp_tree, ofv_qp_compare);
-+ if (!qpn)
-+ return EINVAL;
-+
-+ qp = ((struct ibv_qp *) ((void *) *qpn - offsetof(struct ibv_qp, qp_num)));
-+ return ibv_modify_qp(qp, attr, attr_mask);
-+}
-+default_symver(__ofv_modify_xrc_rcv_qp, ofv_modify_xrc_rcv_qp);
-+
-+int __ofv_query_xrc_rcv_qp(struct ofv_xrc_domain *xrc_domain,
-+ uint32_t xrc_qp_num,
-+ struct ibv_qp_attr *attr, int attr_mask,
-+ struct ofv_qp_init_attr *init_attr)
-+{
-+ struct ibv_qp *qp;
-+ uint32_t **qpn;
-+
-+ qpn = tfind(&xrc_qp_num, &xrc_domain->qp_tree, ofv_qp_compare);
-+ if (!qpn)
-+ return EINVAL;
-+
-+ qp = ((struct ibv_qp *) ((void *) *qpn - offsetof(struct ibv_qp, qp_num)));
-+ return ibv_query_qp(qp, attr, attr_mask,
-+ (struct ibv_qp_init_attr *) init_attr);
-+}
-+default_symver(__ofv_query_xrc_rcv_qp, ofv_query_xrc_rcv_qp);
-+
-+int ofv_reg_xrc_rcv_qp(struct ofv_xrc_domain *xrc_domain, uint32_t xrc_qp_num)
-+{
-+ struct ibv_qp *qp;
-+ struct ibv_qp_open_attr attr;
-+
-+ attr.qp_context = xrc_domain;
-+ attr.qp_num = xrc_qp_num;
-+ attr.qp_type = IBV_QPT_XRC_RECV;
-+
-+ qp = ibv_open_qp(xrc_domain->xrcd, &attr);
-+ if (!qp)
-+ return ENOMEM;
-+
-+ tsearch(&qp->qp_num, &xrc_domain->qp_tree, ofv_qp_compare);
-+ return 0;
-+}
-+default_symver(__ofv_reg_xrc_rcv_qp, ofv_reg_xrc_rcv_qp);
-+
-+int ofv_unreg_xrc_rcv_qp(struct ofv_xrc_domain *xrc_domain, uint32_t xrc_qp_num)
-+{
-+ struct ibv_qp *qp;
-+ uint32_t **qpn;
-+
-+ qpn = tfind(&xrc_qp_num, &xrc_domain->qp_tree, ofv_qp_compare);
-+ if (!qpn)
-+ return EINVAL;
-+
-+ qp = ((struct ibv_qp *) ((void *) *qpn - offsetof(struct ibv_qp, qp_num)));
-+ return ibv_destroy_qp(qp);
-+}
-+default_symver(__ofv_unreg_xrc_rcv_qp, ofv_unreg_xrc_rcv_qp);