[Pkg-ofed-commits] [librdmacm] 14/18: Imported Upstream version 1.0.15

Ana Beatriz Guerrero López ana at moszumanska.debian.org
Wed Jul 2 13:58:25 UTC 2014


This is an automated email from the git hooks/post-receive script.

ana pushed a commit to branch master
in repository librdmacm.

commit 3657f183d977f44fefea711499cca666197aef80
Author: Ana Guerrero López <ana at ekaia.org>
Date:   Wed Jul 2 15:58:07 2014 +0200

    Imported Upstream version 1.0.15
---
 Makefile.am                 |  11 +-
 Makefile.in                 |  61 +++-
 README                      |  11 +
 config.h.in                 |   3 +
 configure                   | 147 +++++++--
 configure.in                |   7 +-
 examples/cmatose.c          |  12 +-
 examples/rdma_server.c      |   2 +-
 examples/rdma_xclient.c     | 297 ++++++++++++++++++
 examples/rdma_xserver.c     | 376 ++++++++++++++++++++++
 examples/rping.c            |  10 +-
 include/rdma/rdma_cma.h     |  36 ++-
 include/rdma/rdma_cma_abi.h |  62 +++-
 include/rdma/rdma_verbs.h   |  26 +-
 librdmacm.spec              |   4 +-
 librdmacm.spec.in           |   2 +-
 man/rdma_accept.3           |   7 +-
 man/rdma_connect.3          |   3 +
 man/rdma_create_qp.3        |   3 +-
 man/rdma_create_srq.3       |  44 +++
 man/rdma_destroy_ep.3       |   5 +-
 man/rdma_destroy_srq.3      |  21 ++
 man/rdma_join_multicast.3   |   9 +-
 man/rdma_notify.3           |   6 +-
 man/rdma_xclient.1          |  35 +++
 man/rdma_xserver.1          |  29 ++
 src/addrinfo.c              |  58 +++-
 src/cma.c                   | 750 ++++++++++++++++++++++----------------------
 src/librdmacm.map           |   2 +
 29 files changed, 1571 insertions(+), 468 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 4e92e35..1e3e582 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,7 +19,8 @@ src_librdmacm_la_LDFLAGS = -version-info 1 -export-dynamic \
 src_librdmacm_la_DEPENDENCIES =  $(srcdir)/src/librdmacm.map
 
 bin_PROGRAMS = examples/ucmatose examples/rping examples/udaddy examples/mckey \
-	       examples/rdma_client examples/rdma_server
+	       examples/rdma_client examples/rdma_server examples/rdma_xclient \
+	       examples/rdma_xserver
 examples_ucmatose_SOURCES = examples/cmatose.c
 examples_ucmatose_LDADD = $(top_builddir)/src/librdmacm.la
 examples_rping_SOURCES = examples/rping.c
@@ -32,6 +33,10 @@ examples_rdma_client_SOURCES = examples/rdma_client.c
 examples_rdma_client_LDADD = $(top_builddir)/src/librdmacm.la
 examples_rdma_server_SOURCES = examples/rdma_server.c
 examples_rdma_server_LDADD = $(top_builddir)/src/librdmacm.la
+examples_rdma_xclient_SOURCES = examples/rdma_xclient.c
+examples_rdma_xclient_LDADD = $(top_builddir)/src/librdmacm.la
+examples_rdma_xserver_SOURCES = examples/rdma_xserver.c
+examples_rdma_xserver_LDADD = $(top_builddir)/src/librdmacm.la
 
 librdmacmincludedir = $(includedir)/rdma
 infinibandincludedir = $(includedir)/infiniband
@@ -50,9 +55,11 @@ man_MANS = \
 	man/rdma_create_event_channel.3 \
 	man/rdma_create_id.3 \
 	man/rdma_create_qp.3 \
+	man/rdma_create_srq.3 \
 	man/rdma_destroy_event_channel.3 \
 	man/rdma_destroy_id.3 \
 	man/rdma_destroy_qp.3 \
+	man/rdma_destroy_srq.3 \
 	man/rdma_disconnect.3 \
 	man/rdma_free_devices.3 \
 	man/rdma_get_cm_event.3 \
@@ -96,6 +103,8 @@ man_MANS = \
 	man/rping.1 \
 	man/rdma_server.1 \
 	man/rdma_client.1 \
+	man/rdma_xserver.1 \
+	man/rdma_xclient.1 \
 	man/rdma_cm.7
 
 EXTRA_DIST = src/cma.h src/librdmacm.map librdmacm.spec.in $(man_MANS)
diff --git a/Makefile.in b/Makefile.in
index 8b9ff38..2311ee5 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -40,7 +40,8 @@ build_triplet = @build@
 host_triplet = @host@
 bin_PROGRAMS = examples/ucmatose$(EXEEXT) examples/rping$(EXEEXT) \
 	examples/udaddy$(EXEEXT) examples/mckey$(EXEEXT) \
-	examples/rdma_client$(EXEEXT) examples/rdma_server$(EXEEXT)
+	examples/rdma_client$(EXEEXT) examples/rdma_server$(EXEEXT) \
+	examples/rdma_xclient$(EXEEXT) examples/rdma_xserver$(EXEEXT)
 DIST_COMMON = README $(am__configure_deps) \
 	$(infinibandinclude_HEADERS) $(librdmacminclude_HEADERS) \
 	$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
@@ -87,6 +88,12 @@ examples_rdma_client_DEPENDENCIES = $(top_builddir)/src/librdmacm.la
 am_examples_rdma_server_OBJECTS = rdma_server.$(OBJEXT)
 examples_rdma_server_OBJECTS = $(am_examples_rdma_server_OBJECTS)
 examples_rdma_server_DEPENDENCIES = $(top_builddir)/src/librdmacm.la
+am_examples_rdma_xclient_OBJECTS = rdma_xclient.$(OBJEXT)
+examples_rdma_xclient_OBJECTS = $(am_examples_rdma_xclient_OBJECTS)
+examples_rdma_xclient_DEPENDENCIES = $(top_builddir)/src/librdmacm.la
+am_examples_rdma_xserver_OBJECTS = rdma_xserver.$(OBJEXT)
+examples_rdma_xserver_OBJECTS = $(am_examples_rdma_xserver_OBJECTS)
+examples_rdma_xserver_DEPENDENCIES = $(top_builddir)/src/librdmacm.la
 am_examples_rping_OBJECTS = rping.$(OBJEXT)
 examples_rping_OBJECTS = $(am_examples_rping_OBJECTS)
 examples_rping_DEPENDENCIES = $(top_builddir)/src/librdmacm.la
@@ -109,11 +116,15 @@ LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
 	$(AM_LDFLAGS) $(LDFLAGS) -o $@
 SOURCES = $(src_librdmacm_la_SOURCES) $(examples_mckey_SOURCES) \
 	$(examples_rdma_client_SOURCES) \
-	$(examples_rdma_server_SOURCES) $(examples_rping_SOURCES) \
+	$(examples_rdma_server_SOURCES) \
+	$(examples_rdma_xclient_SOURCES) \
+	$(examples_rdma_xserver_SOURCES) $(examples_rping_SOURCES) \
 	$(examples_ucmatose_SOURCES) $(examples_udaddy_SOURCES)
 DIST_SOURCES = $(src_librdmacm_la_SOURCES) $(examples_mckey_SOURCES) \
 	$(examples_rdma_client_SOURCES) \
-	$(examples_rdma_server_SOURCES) $(examples_rping_SOURCES) \
+	$(examples_rdma_server_SOURCES) \
+	$(examples_rdma_xclient_SOURCES) \
+	$(examples_rdma_xserver_SOURCES) $(examples_rping_SOURCES) \
 	$(examples_ucmatose_SOURCES) $(examples_udaddy_SOURCES)
 man1dir = $(mandir)/man1
 man3dir = $(mandir)/man3
@@ -258,6 +269,10 @@ examples_rdma_client_SOURCES = examples/rdma_client.c
 examples_rdma_client_LDADD = $(top_builddir)/src/librdmacm.la
 examples_rdma_server_SOURCES = examples/rdma_server.c
 examples_rdma_server_LDADD = $(top_builddir)/src/librdmacm.la
+examples_rdma_xclient_SOURCES = examples/rdma_xclient.c
+examples_rdma_xclient_LDADD = $(top_builddir)/src/librdmacm.la
+examples_rdma_xserver_SOURCES = examples/rdma_xserver.c
+examples_rdma_xserver_LDADD = $(top_builddir)/src/librdmacm.la
 librdmacmincludedir = $(includedir)/rdma
 infinibandincludedir = $(includedir)/infiniband
 librdmacminclude_HEADERS = $(top_srcdir)/include/rdma/rdma_cma_abi.h \
@@ -273,9 +288,11 @@ man_MANS = \
 	man/rdma_create_event_channel.3 \
 	man/rdma_create_id.3 \
 	man/rdma_create_qp.3 \
+	man/rdma_create_srq.3 \
 	man/rdma_destroy_event_channel.3 \
 	man/rdma_destroy_id.3 \
 	man/rdma_destroy_qp.3 \
+	man/rdma_destroy_srq.3 \
 	man/rdma_disconnect.3 \
 	man/rdma_free_devices.3 \
 	man/rdma_get_cm_event.3 \
@@ -319,6 +336,8 @@ man_MANS = \
 	man/rping.1 \
 	man/rdma_server.1 \
 	man/rdma_client.1 \
+	man/rdma_xserver.1 \
+	man/rdma_xclient.1 \
 	man/rdma_cm.7
 
 EXTRA_DIST = src/cma.h src/librdmacm.map librdmacm.spec.in $(man_MANS)
@@ -451,6 +470,12 @@ examples/rdma_client$(EXEEXT): $(examples_rdma_client_OBJECTS) $(examples_rdma_c
 examples/rdma_server$(EXEEXT): $(examples_rdma_server_OBJECTS) $(examples_rdma_server_DEPENDENCIES) examples/$(am__dirstamp)
 	@rm -f examples/rdma_server$(EXEEXT)
 	$(LINK) $(examples_rdma_server_LDFLAGS) $(examples_rdma_server_OBJECTS) $(examples_rdma_server_LDADD) $(LIBS)
+examples/rdma_xclient$(EXEEXT): $(examples_rdma_xclient_OBJECTS) $(examples_rdma_xclient_DEPENDENCIES) examples/$(am__dirstamp)
+	@rm -f examples/rdma_xclient$(EXEEXT)
+	$(LINK) $(examples_rdma_xclient_LDFLAGS) $(examples_rdma_xclient_OBJECTS) $(examples_rdma_xclient_LDADD) $(LIBS)
+examples/rdma_xserver$(EXEEXT): $(examples_rdma_xserver_OBJECTS) $(examples_rdma_xserver_DEPENDENCIES) examples/$(am__dirstamp)
+	@rm -f examples/rdma_xserver$(EXEEXT)
+	$(LINK) $(examples_rdma_xserver_LDFLAGS) $(examples_rdma_xserver_OBJECTS) $(examples_rdma_xserver_LDADD) $(LIBS)
 examples/rping$(EXEEXT): $(examples_rping_OBJECTS) $(examples_rping_DEPENDENCIES) examples/$(am__dirstamp)
 	@rm -f examples/rping$(EXEEXT)
 	$(LINK) $(examples_rping_LDFLAGS) $(examples_rping_OBJECTS) $(examples_rping_LDADD) $(LIBS)
@@ -471,6 +496,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mckey.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rdma_client.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rdma_server.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rdma_xclient.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rdma_xserver.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rping.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/src_librdmacm_la-acm.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/src_librdmacm_la-addrinfo.Plo at am__quote@
@@ -561,6 +588,34 @@ rdma_server.obj: examples/rdma_server.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rdma_server.obj `if test -f 'examples/rdma_server.c'; then $(CYGPATH_W) 'examples/rdma_server.c'; else $(CYGPATH_W) '$(srcdir)/examples/rdma_server.c'; fi`
 
+rdma_xclient.o: examples/rdma_xclient.c
+ at am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rdma_xclient.o -MD -MP -MF "$(DEPDIR)/rdma_xclient.Tpo" -c -o rdma_xclient.o `test -f 'examples/rdma_xclient.c' || echo '$(srcdir)/'`examples/rdma_xclient.c; \
+ at am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/rdma_xclient.Tpo" "$(DEPDIR)/rdma_xclient.Po"; else rm -f "$(DEPDIR)/rdma_xclient.Tpo"; exit 1; fi
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='examples/rdma_xclient.c' object='rdma_xclient.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rdma_xclient.o `test -f 'examples/rdma_xclient.c' || echo '$(srcdir)/'`examples/rdma_xclient.c
+
+rdma_xclient.obj: examples/rdma_xclient.c
+ at am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rdma_xclient.obj -MD -MP -MF "$(DEPDIR)/rdma_xclient.Tpo" -c -o rdma_xclient.obj `if test -f 'examples/rdma_xclient.c'; then $(CYGPATH_W) 'examples/rdma_xclient.c'; else $(CYGPATH_W) '$(srcdir)/examples/rdma_xclient.c'; fi`; \
+ at am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/rdma_xclient.Tpo" "$(DEPDIR)/rdma_xclient.Po"; else rm -f "$(DEPDIR)/rdma_xclient.Tpo"; exit 1; fi
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='examples/rdma_xclient.c' object='rdma_xclient.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rdma_xclient.obj `if test -f 'examples/rdma_xclient.c'; then $(CYGPATH_W) 'examples/rdma_xclient.c'; else $(CYGPATH_W) '$(srcdir)/examples/rdma_xclient.c'; fi`
+
+rdma_xserver.o: examples/rdma_xserver.c
+ at am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rdma_xserver.o -MD -MP -MF "$(DEPDIR)/rdma_xserver.Tpo" -c -o rdma_xserver.o `test -f 'examples/rdma_xserver.c' || echo '$(srcdir)/'`examples/rdma_xserver.c; \
+ at am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/rdma_xserver.Tpo" "$(DEPDIR)/rdma_xserver.Po"; else rm -f "$(DEPDIR)/rdma_xserver.Tpo"; exit 1; fi
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='examples/rdma_xserver.c' object='rdma_xserver.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rdma_xserver.o `test -f 'examples/rdma_xserver.c' || echo '$(srcdir)/'`examples/rdma_xserver.c
+
+rdma_xserver.obj: examples/rdma_xserver.c
+ at am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rdma_xserver.obj -MD -MP -MF "$(DEPDIR)/rdma_xserver.Tpo" -c -o rdma_xserver.obj `if test -f 'examples/rdma_xserver.c'; then $(CYGPATH_W) 'examples/rdma_xserver.c'; else $(CYGPATH_W) '$(srcdir)/examples/rdma_xserver.c'; fi`; \
+ at am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/rdma_xserver.Tpo" "$(DEPDIR)/rdma_xserver.Po"; else rm -f "$(DEPDIR)/rdma_xserver.Tpo"; exit 1; fi
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='examples/rdma_xserver.c' object='rdma_xserver.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rdma_xserver.obj `if test -f 'examples/rdma_xserver.c'; then $(CYGPATH_W) 'examples/rdma_xserver.c'; else $(CYGPATH_W) '$(srcdir)/examples/rdma_xserver.c'; fi`
+
 rping.o: examples/rping.c
 @am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rping.o -MD -MP -MF "$(DEPDIR)/rping.Tpo" -c -o rping.o `test -f 'examples/rping.c' || echo '$(srcdir)/'`examples/rping.c; \
 @am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/rping.Tpo" "$(DEPDIR)/rping.Po"; else rm -f "$(DEPDIR)/rping.Tpo"; exit 1; fi
diff --git a/README b/README
index 4d104cd..e1f2227 100644
--- a/README
+++ b/README
@@ -48,3 +48,14 @@ Using multiple interfaces
 	address carried in the ARP request.  This causes the RDMA stack
 	to incorrectly map the remote IP address to the wrong RDMA
 	device.
+
+Using loopback
+	The librdmacm relies on ARP to resolve IP address to RDMA
+	addresses.  To support loopback connections between different
+	ports on the same system, ARP must be enabled for local
+	resolution:
+
+	sysctl net.ipv4.conf.all.accept_local=1
+
+	Without this setting, loopback connections may timeout
+	during address resolution.
diff --git a/config.h.in b/config.h.in
index 1de8d63..0c8c0c0 100644
--- a/config.h.in
+++ b/config.h.in
@@ -12,6 +12,9 @@
 /* Define to 1 if you have the `ibverbs' library (-libverbs). */
 #undef HAVE_LIBIBVERBS
 
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+#undef HAVE_LIBPTHREAD
+
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
diff --git a/configure b/configure
index b8c4833..bf54c52 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.59 for librdmacm 1.0.14.1.
+# Generated by GNU Autoconf 2.59 for librdmacm 1.0.15.
 #
 # Report bugs to <general at lists.openfabrics.org>.
 #
@@ -423,8 +423,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='librdmacm'
 PACKAGE_TARNAME='librdmacm'
-PACKAGE_VERSION='1.0.14.1'
-PACKAGE_STRING='librdmacm 1.0.14.1'
+PACKAGE_VERSION='1.0.15'
+PACKAGE_STRING='librdmacm 1.0.15'
 PACKAGE_BUGREPORT='general at lists.openfabrics.org'
 
 ac_unique_file="src/cma.c"
@@ -954,7 +954,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures librdmacm 1.0.14.1 to adapt to many kinds of systems.
+\`configure' configures librdmacm 1.0.15 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1020,7 +1020,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of librdmacm 1.0.14.1:";;
+     short | recursive ) echo "Configuration of librdmacm 1.0.15:";;
    esac
   cat <<\_ACEOF
 
@@ -1162,7 +1162,7 @@ fi
 test -n "$ac_init_help" && exit 0
 if $ac_init_version; then
   cat <<\_ACEOF
-librdmacm configure 1.0.14.1
+librdmacm configure 1.0.15
 generated by GNU Autoconf 2.59
 
 Copyright (C) 2003 Free Software Foundation, Inc.
@@ -1176,7 +1176,7 @@ cat >&5 <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by librdmacm $as_me 1.0.14.1, which was
+It was created by librdmacm $as_me 1.0.15, which was
 generated by GNU Autoconf 2.59.  Invocation command line was
 
   $ $0 $@
@@ -1833,7 +1833,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE=librdmacm
- VERSION=1.0.14.1
+ VERSION=1.0.15
 
 
 cat >>confdefs.h <<_ACEOF
@@ -1964,6 +1964,7 @@ am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
 
 
 
+
 # Check whether --enable-shared or --disable-shared was given.
 if test "${enable_shared+set}" = set; then
   enableval="$enable_shared"
@@ -3688,7 +3689,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 3691 "configure"' > conftest.$ac_ext
+  echo '#line 3692 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -5287,7 +5288,7 @@ fi
 
 
 # Provide some information about the compiler.
-echo "$as_me:5290:" \
+echo "$as_me:5291:" \
      "checking for Fortran 77 compiler version" >&5
 ac_compiler=`set X $ac_compile; echo $2`
 { (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
@@ -6350,11 +6351,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:6353: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:6354: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:6357: \$? = $ac_status" >&5
+   echo "$as_me:6358: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -6618,11 +6619,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:6621: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:6622: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:6625: \$? = $ac_status" >&5
+   echo "$as_me:6626: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -6722,11 +6723,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:6725: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:6726: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:6729: \$? = $ac_status" >&5
+   echo "$as_me:6730: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -9067,7 +9068,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 9070 "configure"
+#line 9071 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -9167,7 +9168,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 9170 "configure"
+#line 9171 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11507,11 +11508,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:11510: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:11511: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:11514: \$? = $ac_status" >&5
+   echo "$as_me:11515: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -11611,11 +11612,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:11614: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:11615: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:11618: \$? = $ac_status" >&5
+   echo "$as_me:11619: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -13181,11 +13182,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:13184: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:13185: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:13188: \$? = $ac_status" >&5
+   echo "$as_me:13189: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -13285,11 +13286,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:13288: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:13289: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:13292: \$? = $ac_status" >&5
+   echo "$as_me:13293: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -15488,11 +15489,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:15491: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:15492: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:15495: \$? = $ac_status" >&5
+   echo "$as_me:15496: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -15756,11 +15757,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:15759: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:15760: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:15763: \$? = $ac_status" >&5
+   echo "$as_me:15764: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -15860,11 +15861,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:15863: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:15864: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:15867: \$? = $ac_status" >&5
+   echo "$as_me:15868: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -19931,6 +19932,84 @@ _ACEOF
 
 
 
+
+echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthread" >&5
+echo $ECHO_N "checking for pthread_mutex_init in -lpthread... $ECHO_C" >&6
+if test "${ac_cv_lib_pthread_pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pthread_mutex_init ();
+int
+main ()
+{
+pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_pthread_pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_pthread_pthread_mutex_init=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_pthread_pthread_mutex_init" >&6
+if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBPTHREAD 1
+_ACEOF
+
+  LIBS="-lpthread $LIBS"
+
+else
+  { { echo "$as_me:$LINENO: error: pthread_mutex_init() not found.  librdmacm requires libpthread." >&5
+echo "$as_me: error: pthread_mutex_init() not found.  librdmacm requires libpthread." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
 if test "$disable_libcheck" != "yes"; then
 
 echo "$as_me:$LINENO: checking for ibv_get_device_list in -libverbs" >&5
@@ -21164,7 +21243,7 @@ _ASBOX
 } >&5
 cat >&5 <<_CSEOF
 
-This file was extended by librdmacm $as_me 1.0.14.1, which was
+This file was extended by librdmacm $as_me 1.0.15, which was
 generated by GNU Autoconf 2.59.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -21227,7 +21306,7 @@ _ACEOF
 
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-librdmacm config.status 1.0.14.1
+librdmacm config.status 1.0.15
 configured by $0, generated by GNU Autoconf 2.59,
   with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
 
diff --git a/configure.in b/configure.in
index 927a6ea..03dbed8 100644
--- a/configure.in
+++ b/configure.in
@@ -1,12 +1,13 @@
 dnl Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.57)
-AC_INIT(librdmacm, 1.0.14.1, general at lists.openfabrics.org)
+AC_INIT(librdmacm, 1.0.15, general at lists.openfabrics.org)
 AC_CONFIG_SRCDIR([src/cma.c])
 AC_CONFIG_AUX_DIR(config)
 AC_CONFIG_MACRO_DIR(config)
 AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(librdmacm, 1.0.14.1)
+AM_INIT_AUTOMAKE(librdmacm, 1.0.15)
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 
 AM_PROG_LIBTOOL
 
@@ -45,6 +46,8 @@ AC_C_CONST
 AC_CHECK_SIZEOF(long)
 
 dnl Checks for libraries
+AC_CHECK_LIB(pthread, pthread_mutex_init, [],
+    AC_MSG_ERROR([pthread_mutex_init() not found.  librdmacm requires libpthread.]))
 if test "$disable_libcheck" != "yes"; then
 AC_CHECK_LIB(ibverbs, ibv_get_device_list, [],
     AC_MSG_ERROR([ibv_get_device_list() not found.  librdmacm requires libibverbs.]))
diff --git a/examples/cmatose.c b/examples/cmatose.c
index 84831ec..82e0d7c 100644
--- a/examples/cmatose.c
+++ b/examples/cmatose.c
@@ -541,13 +541,13 @@ static int run_server(void)
 		if (ret)
 			goto out;
 		if (test.addr.src_addr.sa_family == AF_INET)
-			((struct sockaddr_in *) &test.addr.src_addr)->sin_port = port;
+			test.addr.src_sin.sin_port = port;
 		else
-			((struct sockaddr_in6 *) &test.addr.src_addr)->sin6_port = port;
+			test.addr.src_sin6.sin6_port = port;
 		
 	} else {
-		test.addr.src_addr.sa_family = PF_INET;
-		((struct sockaddr_in *) &test.addr.src_addr)->sin_port = port;
+		test.addr.src_addr.sa_family = AF_INET;
+		test.addr.src_sin.sin_port = port;
 	}
 
 	ret = rdma_bind_addr(listen_id, &test.addr.src_addr);
@@ -628,9 +628,9 @@ static int run_client(void)
 		return ret;
 
 	if (test.addr.dst_addr.sa_family == AF_INET)
-		((struct sockaddr_in *) &test.addr.dst_addr)->sin_port = port;
+		test.addr.dst_sin.sin_port = port;
 	else
-		((struct sockaddr_in6 *) &test.addr.dst_addr)->sin6_port = port;
+		test.addr.dst_sin6.sin6_port = port;
 
 	printf("cmatose: connecting\n");
 	for (i = 0; i < connections; i++) {
diff --git a/examples/rdma_server.c b/examples/rdma_server.c
index 2831d0c..5b9e16d 100644
--- a/examples/rdma_server.c
+++ b/examples/rdma_server.c
@@ -97,7 +97,7 @@ static int run(void)
 
 	ret = rdma_accept(id, NULL);
 	if (ret) {
-		printf("rdma_connect %d\n", errno);
+		printf("rdma_accept %d\n", errno);
 		return ret;
 	}
 
diff --git a/examples/rdma_xclient.c b/examples/rdma_xclient.c
new file mode 100644
index 0000000..e192290
--- /dev/null
+++ b/examples/rdma_xclient.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2010-2011 Intel Corporation.  All rights reserved.
+ *
+ * This software is available to you under 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 AWV
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+#include <ctype.h>
+#include <rdma/rdma_cma.h>
+#include <rdma/rdma_verbs.h>
+
+static char *server = "127.0.0.1";
+static char port[6] = "7471";
+
+static int (*run_func)() = NULL;
+struct rdma_cm_id *id;
+struct ibv_mr *mr;
+enum ibv_qp_type qpt = IBV_QPT_RC;
+
+#define MSG_SIZE 16
+uint8_t send_msg[MSG_SIZE];
+uint8_t recv_msg[MSG_SIZE];
+
+#ifdef IBV_XRC_OPS
+#define PRINT_XRC_OPT printf("\t    x - XRC: extended-reliable-connected\n")
+uint32_t srqn;
+
+/*
+ * Connect XRC SEND QP.
+ */
+static int xrc_connect_send(void)
+{
+	struct rdma_addrinfo hints, *res;
+	struct ibv_qp_init_attr attr;
+	int ret;
+
+	memset(&hints, 0, sizeof hints);
+	hints.ai_port_space = RDMA_PS_IB;
+	hints.ai_qp_type = IBV_QPT_XRC_SEND;
+	ret = rdma_getaddrinfo(server, port, &hints, &res);
+	if (ret) {
+		printf("rdma_getaddrinfo connect send %d\n", errno);
+		return ret;
+	}
+
+	memset(&attr, 0, sizeof attr);
+	attr.cap.max_send_wr = 1;
+	attr.cap.max_send_sge = 1;
+	attr.cap.max_inline_data = sizeof send_msg;
+	attr.qp_context = id;
+	attr.sq_sig_all = 1;
+	ret = rdma_create_ep(&id, res, NULL, &attr);
+	rdma_freeaddrinfo(res);
+	if (ret) {
+		printf("rdma_create_ep send qp %d\n", errno);
+		return ret;
+	}
+
+	ret = rdma_connect(id, NULL);
+	if (ret) {
+		printf("rdma_connect send qp %d\n", errno);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
+ * Resolve remote SRQ number
+ */
+static int xrc_resolve_srqn(void)
+{
+	struct rdma_addrinfo hints, *res;
+	struct rdma_cm_id *id;
+	int ret;
+
+	memset(&hints, 0, sizeof hints);
+	hints.ai_qp_type = IBV_QPT_UD; /* for now */
+	hints.ai_port_space = RDMA_PS_IB;
+	sprintf(port, "%d", atoi(port) + 1);
+	ret = rdma_getaddrinfo(server, port, &hints, &res);
+	if (ret) {
+		printf("rdma_getaddrinfo resolve srqn %d\n", errno);
+		return ret;
+	}
+
+	ret = rdma_create_ep(&id, res, NULL, NULL);
+	rdma_freeaddrinfo(res);
+	if (ret) {
+		printf("rdma_create_ep for srqn %d\n", errno);
+		return ret;
+	}
+
+	ret = rdma_connect(id, NULL);
+	if (ret) {
+		printf("rdma_connect for srqn %d\n", errno);
+		return ret;
+	}
+
+	srqn = id->event->param.ud.qp_num;
+	rdma_destroy_ep(id);
+	return 0;
+}
+
+static int xrc_test(void)
+{
+	struct ibv_send_wr wr, *bad;
+	struct ibv_sge sge;
+	struct ibv_wc wc;
+	int ret;
+
+	ret = xrc_connect_send();
+	if (ret)
+		return ret;
+
+	ret = xrc_resolve_srqn();
+	if (ret)
+		return ret;
+
+	sge.addr = (uint64_t) (uintptr_t) send_msg;
+	sge.length = (uint32_t) sizeof send_msg;
+	sge.lkey = 0;
+	wr.wr_id = (uintptr_t) NULL;
+	wr.next = NULL;
+	wr.sg_list = &sge;
+	wr.num_sge = 1;
+	wr.opcode = IBV_WR_SEND;
+	wr.send_flags = IBV_SEND_INLINE;
+	wr.wr.xrc.remote_srqn = srqn;
+
+	ret = ibv_post_send(id->qp, &wr, &bad);
+	if (ret) {
+		printf("rdma_post_send %d\n", errno);
+		return ret;
+	}
+
+	ret = rdma_get_send_comp(id, &wc);
+	if (ret <= 0) {
+		printf("rdma_get_recv_comp %d\n", ret);
+		return ret;
+	}
+
+	rdma_disconnect(id);
+	rdma_destroy_ep(id);
+	return 0;
+}
+
+static inline int set_xrc_qpt(void)
+{
+	qpt = IBV_QPT_XRC_SEND;
+	run_func = xrc_test;
+	return 0;
+}
+
+#else
+#define PRINT_XRC_OPT
+#define set_xrc_qpt() -1
+#endif /* IBV_XRC_OPS */
+
+static int rc_test(void)
+{
+	struct rdma_addrinfo hints, *res;
+	struct ibv_qp_init_attr attr;
+	struct ibv_wc wc;
+	int ret;
+
+	memset(&hints, 0, sizeof hints);
+	hints.ai_port_space = RDMA_PS_TCP;
+	ret = rdma_getaddrinfo(server, port, &hints, &res);
+	if (ret) {
+		printf("rdma_getaddrinfo %d\n", errno);
+		return ret;
+	}
+
+	memset(&attr, 0, sizeof attr);
+	attr.cap.max_send_wr = attr.cap.max_recv_wr = 1;
+	attr.cap.max_send_sge = attr.cap.max_recv_sge = 1;
+	attr.cap.max_inline_data = sizeof send_msg;
+	attr.qp_context = id;
+	attr.sq_sig_all = 1;
+	ret = rdma_create_ep(&id, res, NULL, &attr);
+	rdma_freeaddrinfo(res);
+	if (ret) {
+		printf("rdma_create_ep %d\n", errno);
+		return ret;
+	}
+
+	mr = rdma_reg_msgs(id, recv_msg, sizeof recv_msg);
+	if (!mr) {
+		printf("rdma_reg_msgs %d\n", errno);
+		return ret;
+	}
+
+	ret = rdma_post_recv(id, NULL, recv_msg, sizeof recv_msg, mr);
+	if (ret) {
+		printf("rdma_post_recv %d\n", errno);
+		return ret;
+	}
+
+	ret = rdma_connect(id, NULL);
+	if (ret) {
+		printf("rdma_connect %d\n", errno);
+		return ret;
+	}
+
+	ret = rdma_post_send(id, NULL, send_msg, sizeof send_msg, NULL, IBV_SEND_INLINE);
+	if (ret) {
+		printf("rdma_post_send %d\n", errno);
+		return ret;
+	}
+
+	ret = rdma_get_recv_comp(id, &wc);
+	if (ret <= 0) {
+		printf("rdma_get_recv_comp %d\n", ret);
+		return ret;
+	}
+
+	rdma_disconnect(id);
+	rdma_dereg_mr(mr);
+	rdma_destroy_ep(id);
+	return 0;
+}
+
+static int set_qpt(char type)
+{
+	if (type == 'r') {
+		qpt = IBV_QPT_RC;
+		return 0;
+	} else if (type == 'x') {
+		return set_xrc_qpt();
+	}
+	return -1;
+}
+
+int main(int argc, char **argv)
+{
+	int op, ret;
+
+	run_func = rc_test;
+	while ((op = getopt(argc, argv, "s:p:c:")) != -1) {
+		switch (op) {
+		case 's':
+			server = optarg;
+			break;
+		case 'p':
+			strncpy(port, optarg, sizeof port - 1);
+			break;
+		case 'c':
+			if (set_qpt(tolower(optarg[0])))
+				goto err;
+			break;
+		default:
+			goto err;
+		}
+	}
+
+	printf("%s: start\n", argv[0]);
+	ret = run_func();
+	printf("%s: end %d\n", argv[0], ret);
+	return ret;
+
+err:
+	printf("usage: %s\n", argv[0]);
+	printf("\t[-s server]\n");
+	printf("\t[-p port_number]\n");
+	printf("\t[-c communication type]\n");
+	printf("\t    r - RC: reliable-connected (default)\n");
+	PRINT_XRC_OPT;
+	exit(1);
+}
diff --git a/examples/rdma_xserver.c b/examples/rdma_xserver.c
new file mode 100644
index 0000000..df3e665
--- /dev/null
+++ b/examples/rdma_xserver.c
@@ -0,0 +1,376 @@
+/*
+ * Copyright (c) 2005-2011 Intel Corporation.  All rights reserved.
+ *
+ * This software is available to you under 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 AWV
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+#include <netdb.h>
+#include <ctype.h>
+#include <netinet/in.h>
+#include <rdma/rdma_cma.h>
+#include <rdma/rdma_verbs.h>
+
+static char *port = "7471";
+
+static int (*run_func)();
+struct rdma_cm_id *listen_id, *id;
+struct ibv_mr *mr;
+enum ibv_qp_type qpt = IBV_QPT_RC;
+
+#define MSG_SIZE 16
+uint8_t send_msg[MSG_SIZE];
+uint8_t recv_msg[MSG_SIZE];
+
+
+#ifdef IBV_XRC_OPS
+#define PRINT_XRC_OPT printf("\t    x - XRC: extended-reliable-connected\n")
+struct rdma_cm_id *srq_id;
+
+/*
+ * Listen for XRC RECV QP connection request.
+ */
+static struct rdma_cm_id * xrc_listen_recv(void)
+{
+	struct rdma_addrinfo hints, *res;
+	struct rdma_cm_id *id;
+	int ret;
+
+	memset(&hints, 0, sizeof hints);
+	hints.ai_flags = RAI_PASSIVE;
+	hints.ai_port_space = RDMA_PS_IB;
+	hints.ai_qp_type = IBV_QPT_XRC_RECV;
+	ret = rdma_getaddrinfo(NULL, port, &hints, &res);
+	if (ret) {
+		printf("rdma_getaddrinfo listen recv %d\n", errno);
+		return NULL;
+	}
+
+	ret = rdma_create_ep(&listen_id, res, NULL, NULL);
+	rdma_freeaddrinfo(res);
+	if (ret) {
+		printf("rdma_create_ep listen recv %d\n", errno);
+		return NULL;
+	}
+
+	ret = rdma_listen(listen_id, 0);
+	if (ret) {
+		printf("rdma_listen %d\n", errno);
+		return NULL;
+	}
+
+	ret = rdma_get_request(listen_id, &id);
+	if (ret) {
+		printf("rdma_get_request %d\n", errno);
+		return NULL;
+	}
+
+	return id;
+}
+
+/*
+ * Create SRQ and listen for XRC SRQN lookup request.
+ */
+static int xrc_create_srq_listen(struct sockaddr *addr, socklen_t addr_len)
+{
+	struct rdma_addrinfo rai;
+	struct sockaddr_storage ss;
+	struct ibv_srq_init_attr attr;
+	int ret;
+
+	memset(&rai, 0, sizeof rai);
+	rai.ai_flags = RAI_PASSIVE;
+	rai.ai_family = addr->sa_family;
+	rai.ai_qp_type = IBV_QPT_UD; /* for now */
+	rai.ai_port_space = RDMA_PS_IB;
+	memcpy(&ss, addr, addr_len);
+	rai.ai_src_len = addr_len;
+	rai.ai_src_addr = (struct sockaddr *) &ss;
+	((struct sockaddr_in *) &ss)->sin_port = htons((short) atoi(port) + 1);
+
+	ret = rdma_create_ep(&srq_id, &rai, NULL, NULL);
+	if (ret) {
+		printf("rdma_create_ep srq ep %d\n", errno);
+		return ret;
+	}
+
+	if (!srq_id->verbs) {
+		printf("rdma_create_ep failed to bind to device.\n");
+		printf("XRC tests cannot use loopback addressing\n");
+		return -1;
+	}
+
+	memset(&attr, 0, sizeof attr);
+	attr.attr.max_wr = 1;
+	attr.attr.max_sge = 1;
+	attr.srq_type = IBV_SRQT_XRC;
+
+	attr.ext.xrc.xrcd = ibv_open_xrcd(srq_id->verbs, -1, 0);
+	if (!attr.ext.xrc.xrcd) {
+		printf("Unable to open xrcd\n");
+		return -1;
+	}
+
+	ret = rdma_create_srq(srq_id, NULL, &attr);
+	if (ret) {
+		printf("Unable to create srq %d\n", errno);
+		return ret;
+	}
+
+	ret = rdma_listen(srq_id, 0);
+	if (ret) {
+		printf("rdma_listen srq id %d\n", errno);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int xrc_test(void)
+{
+	struct rdma_cm_id *conn_id, *lookup_id;
+	struct ibv_qp_init_attr attr;
+	struct rdma_conn_param param;
+	struct rdma_cm_event *event;
+	struct ibv_wc wc;
+	int ret;
+
+	conn_id = xrc_listen_recv();
+	if (!conn_id)
+		return -1;
+
+	ret = xrc_create_srq_listen(rdma_get_local_addr(conn_id),
+				    sizeof(struct sockaddr_storage));
+	if (ret)
+		return -1;
+
+	memset(&attr, 0, sizeof attr);
+	attr.qp_type = IBV_QPT_XRC_RECV;
+	attr.ext.xrc_recv.xrcd = srq_id->srq->ext.xrc.xrcd;
+	ret = rdma_create_qp(conn_id, NULL, &attr);
+	if (ret) {
+		printf("Unable to create xrc recv qp %d\n", errno);
+		return ret;
+	}
+
+	ret = rdma_accept(conn_id, NULL);
+	if (ret) {
+		printf("rdma_accept failed for xrc recv qp %d\n", errno);
+		return ret;
+	}
+
+	ret = rdma_get_request(srq_id, &lookup_id);
+	if (ret) {
+		printf("rdma_get_request %d\n", errno);
+		return ret;
+	}
+
+	mr = rdma_reg_msgs(srq_id, recv_msg, sizeof recv_msg);
+	if (!mr) {
+		printf("ibv_reg_msgs %d\n", errno);
+		return ret;
+	}
+
+	ret = rdma_post_recv(srq_id, NULL, recv_msg, sizeof recv_msg, mr);
+	if (ret) {
+		printf("rdma_post_recv %d\n", errno);
+		return ret;
+	}
+
+	memset(&param, 0, sizeof param);
+	param.qp_num = srq_id->srq->ext.xrc.srq_num;
+	ret = rdma_accept(lookup_id, &param);
+	if (ret) {
+		printf("rdma_accept failed for srqn lookup %d\n", errno);
+		return ret;
+	}
+
+	rdma_destroy_id(lookup_id);
+
+	ret = rdma_get_recv_comp(srq_id, &wc);
+	if (ret <= 0) {
+		printf("rdma_get_recv_comp %d\n", ret);
+		return ret;
+	}
+
+	ret = rdma_get_cm_event(conn_id->channel, &event);
+	if (ret || event->event != RDMA_CM_EVENT_DISCONNECTED) {
+		printf("Failed to get disconnect event\n");
+		return -1;
+	}
+
+	rdma_ack_cm_event(event);
+	rdma_disconnect(conn_id);
+	rdma_destroy_ep(conn_id);
+	rdma_dereg_mr(mr);
+	rdma_destroy_ep(srq_id);
+	rdma_destroy_ep(listen_id);
+	return 0;
+}
+
+static inline int set_xrc_qpt(void)
+{
+	qpt = IBV_QPT_XRC_RECV;
+	run_func = xrc_test;
+	return 0;
+}
+
+#else
+#define PRINT_XRC_OPT
+#define set_xrc_qpt() -1
+#endif /* IBV_XRC_OPS */
+
+
+static int rc_test(void)
+{
+	struct rdma_addrinfo hints, *res;
+	struct ibv_qp_init_attr attr;
+	struct ibv_wc wc;
+	int ret;
+
+	memset(&hints, 0, sizeof hints);
+	hints.ai_flags = RAI_PASSIVE;
+	hints.ai_port_space = RDMA_PS_TCP;
+	ret = rdma_getaddrinfo(NULL, port, &hints, &res);
+	if (ret) {
+		printf("rdma_getaddrinfo %d\n", errno);
+		return ret;
+	}
+
+	memset(&attr, 0, sizeof attr);
+	attr.cap.max_send_wr = attr.cap.max_recv_wr = 1;
+	attr.cap.max_send_sge = attr.cap.max_recv_sge = 1;
+	attr.cap.max_inline_data = sizeof send_msg;
+	attr.sq_sig_all = 1;
+	ret = rdma_create_ep(&listen_id, res, NULL, &attr);
+	rdma_freeaddrinfo(res);
+	if (ret) {
+		printf("rdma_create_ep %d\n", errno);
+		return ret;
+	}
+
+	ret = rdma_listen(listen_id, 0);
+	if (ret) {
+		printf("rdma_listen %d\n", errno);
+		return ret;
+	}
+
+	ret = rdma_get_request(listen_id, &id);
+	if (ret) {
+		printf("rdma_get_request %d\n", errno);
+		return ret;
+	}
+
+	mr = rdma_reg_msgs(id, recv_msg, sizeof recv_msg);
+	if (!mr) {
+		printf("rdma_reg_msgs %d\n", errno);
+		return ret;
+	}
+
+	ret = rdma_post_recv(id, NULL, recv_msg, sizeof recv_msg, mr);
+	if (ret) {
+		printf("rdma_post_recv %d\n", errno);
+		return ret;
+	}
+
+	ret = rdma_accept(id, NULL);
+	if (ret) {
+		printf("rdma_accept %d\n", errno);
+		return ret;
+	}
+
+	ret = rdma_get_recv_comp(id, &wc);
+	if (ret <= 0) {
+		printf("rdma_get_recv_comp %d\n", ret);
+		return ret;
+	}
+
+	ret = rdma_post_send(id, NULL, send_msg, sizeof send_msg, NULL, IBV_SEND_INLINE);
+	if (ret) {
+		printf("rdma_post_send %d\n", errno);
+		return ret;
+	}
+
+	ret = rdma_get_send_comp(id, &wc);
+	if (ret <= 0) {
+		printf("rdma_get_send_comp %d\n", ret);
+		return ret;
+	}
+
+	rdma_disconnect(id);
+	rdma_dereg_mr(mr);
+	rdma_destroy_ep(id);
+	rdma_destroy_ep(listen_id);
+	return 0;
+}
+
+static int set_qpt(char type)
+{
+	if (type == 'r') {
+		qpt = IBV_QPT_RC;
+		return 0;
+	} else if (type == 'x') {
+		return set_xrc_qpt();
+	}
+	return -1;
+}
+
+int main(int argc, char **argv)
+{
+	int op, ret;
+
+	run_func = rc_test;
+	while ((op = getopt(argc, argv, "p:c:")) != -1) {
+		switch (op) {
+		case 'p':
+			port = optarg;
+			break;
+		case 'c':
+			if (set_qpt(tolower(optarg[0])))
+				goto err;
+			break;
+		default:
+			goto err;
+		}
+	}
+
+	printf("%s: start\n", argv[0]);
+	ret = run_func();
+	printf("%s: end %d\n", argv[0], ret);
+	return ret;
+
+err:
+	printf("usage: %s\n", argv[0]);
+	printf("\t[-p port_number]\n");
+	printf("\t[-c communication type]\n");
+	printf("\t    r - RC: reliable-connected (default)\n");
+	PRINT_XRC_OPT;
+	exit(1);
+}
diff --git a/examples/rping.c b/examples/rping.c
index 2d4c2de..ee292ec 100644
--- a/examples/rping.c
+++ b/examples/rping.c
@@ -280,12 +280,11 @@ static int rping_cq_event_handler(struct rping_cb *cb)
 		ret = 0;
 
 		if (wc.status) {
-			if (wc.status != IBV_WC_WR_FLUSH_ERR) {
+			if (wc.status != IBV_WC_WR_FLUSH_ERR)
 				fprintf(stderr,
 					"cq completion failed status %d\n",
 					wc.status);
-				ret = -1;
-			}
+			ret = -1;
 			goto error;
 		}
 
@@ -802,10 +801,9 @@ static void *rping_persistent_server_thread(void *arg)
 
 	rping_test_server(cb);
 	rdma_disconnect(cb->child_cm_id);
+	pthread_join(cb->cqthread, NULL);
 	rping_free_buffers(cb);
 	rping_free_qp(cb);
-	pthread_cancel(cb->cqthread);
-	pthread_join(cb->cqthread, NULL);
 	rdma_destroy_id(cb->child_cm_id);
 	free_cb(cb);
 	return NULL;
@@ -890,6 +888,7 @@ static int rping_run_server(struct rping_cb *cb)
 
 	rping_test_server(cb);
 	rdma_disconnect(cb->child_cm_id);
+	pthread_join(cb->cqthread, NULL);
 	rdma_destroy_id(cb->child_cm_id);
 err2:
 	rping_free_buffers(cb);
@@ -1057,6 +1056,7 @@ static int rping_run_client(struct rping_cb *cb)
 
 	rping_test_client(cb);
 	rdma_disconnect(cb->cm_id);
+	pthread_join(cb->cqthread, NULL);
 err2:
 	rping_free_buffers(cb);
 err1:
diff --git a/include/rdma/rdma_cma.h b/include/rdma/rdma_cma.h
index b48cd2e..c0f83b1 100755
--- a/include/rdma/rdma_cma.h
+++ b/include/rdma/rdma_cma.h
@@ -68,9 +68,9 @@ enum rdma_cm_event_type {
 
 enum rdma_port_space {
 	RDMA_PS_IPOIB = 0x0002,
-	RDMA_PS_IB    = 0x0003,
 	RDMA_PS_TCP   = 0x0106,
 	RDMA_PS_UDP   = 0x0111,
+	RDMA_PS_IB    = 0x013F,
 };
 
 #define RDMA_IB_IP_PS_MASK   0xFFFFFFFFFFFF0000ULL
@@ -91,12 +91,18 @@ struct rdma_ib_addr {
 };
 
 struct rdma_addr {
-	struct sockaddr		src_addr;
-	uint8_t			src_pad[sizeof(struct sockaddr_storage) -
-					sizeof(struct sockaddr)];
-	struct sockaddr		dst_addr;
-	uint8_t			dst_pad[sizeof(struct sockaddr_storage) -
-					sizeof(struct sockaddr)];
+	union {
+		struct sockaddr		src_addr;
+		struct sockaddr_in	src_sin;
+		struct sockaddr_in6	src_sin6;
+		struct sockaddr_storage src_storage;
+	};
+	union {
+		struct sockaddr		dst_addr;
+		struct sockaddr_in	dst_sin;
+		struct sockaddr_in6	dst_sin6;
+		struct sockaddr_storage dst_storage;
+	};
 	union {
 		struct rdma_ib_addr	ibaddr;
 	} addr;
@@ -125,6 +131,9 @@ struct rdma_cm_id {
 	struct ibv_cq		*send_cq;
 	struct ibv_comp_channel *recv_cq_channel;
 	struct ibv_cq		*recv_cq;
+	struct ibv_srq		*srq;
+	struct ibv_pd		*pd;
+	enum ibv_qp_type	qp_type;
 };
 
 enum {
@@ -575,15 +584,15 @@ int rdma_ack_cm_event(struct rdma_cm_event *event);
 static inline uint16_t rdma_get_src_port(struct rdma_cm_id *id)
 {
 	return	id->route.addr.src_addr.sa_family == PF_INET6 ?
-		((struct sockaddr_in6 *) &id->route.addr.src_addr)->sin6_port :
-		((struct sockaddr_in *) &id->route.addr.src_addr)->sin_port;
+		id->route.addr.src_sin6.sin6_port :
+		id->route.addr.src_sin.sin_port;
 }
 
 static inline uint16_t rdma_get_dst_port(struct rdma_cm_id *id)
 {
 	return	id->route.addr.dst_addr.sa_family == PF_INET6 ?
-		((struct sockaddr_in6 *) &id->route.addr.dst_addr)->sin6_port :
-		((struct sockaddr_in *) &id->route.addr.dst_addr)->sin_port;
+		id->route.addr.dst_sin6.sin6_port :
+		id->route.addr.dst_sin.sin_port;
 }
 
 static inline struct sockaddr *rdma_get_local_addr(struct rdma_cm_id *id)
@@ -639,8 +648,9 @@ enum {
 
 /* Option details */
 enum {
-	RDMA_OPTION_ID_TOS	= 0,	/* uint8_t: RFC 2474 */
-	RDMA_OPTION_IB_PATH	= 1	/* struct ibv_path_data[] */
+	RDMA_OPTION_ID_TOS	 = 0,	/* uint8_t: RFC 2474 */
+	RDMA_OPTION_ID_REUSEADDR = 1,   /* int: ~SO_REUSEADDR */
+	RDMA_OPTION_IB_PATH	 = 1	/* struct ibv_path_data[] */
 };
 
 /**
diff --git a/include/rdma/rdma_cma_abi.h b/include/rdma/rdma_cma_abi.h
index ddd0d90..b72f330 100644
--- a/include/rdma/rdma_cma_abi.h
+++ b/include/rdma/rdma_cma_abi.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005-2006 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2005-2011 Intel Corporation.  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
@@ -79,6 +79,9 @@ struct ucma_abi_cmd_hdr {
 };
 
 struct ucma_abi_create_id {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
 	__u64 uid;
 	__u64 response;
 	__u16 ps;
@@ -91,6 +94,9 @@ struct ucma_abi_create_id_resp {
 };
 
 struct ucma_abi_destroy_id {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
 	__u64 response;
 	__u32 id;
 	__u32 reserved;
@@ -101,12 +107,18 @@ struct ucma_abi_destroy_id_resp {
 };
 
 struct ucma_abi_bind_ip {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
 	__u64 response;
 	struct sockaddr_in6 addr;
 	__u32 id;
 };
 
 struct ucma_abi_bind {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
 	__u32 id;
 	__u16 addr_size;
 	__u16 reserved;
@@ -114,6 +126,9 @@ struct ucma_abi_bind {
 };
 
 struct ucma_abi_resolve_ip {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
 	struct sockaddr_in6 src_addr;
 	struct sockaddr_in6 dst_addr;
 	__u32 id;
@@ -121,6 +136,9 @@ struct ucma_abi_resolve_ip {
 };
 
 struct ucma_abi_resolve_addr {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
 	__u32 id;
 	__u32 timeout_ms;
 	__u16 src_size;
@@ -131,6 +149,9 @@ struct ucma_abi_resolve_addr {
 };
 
 struct ucma_abi_resolve_route {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
 	__u32 id;
 	__u32 timeout_ms;
 };
@@ -142,6 +163,9 @@ enum {
 };
 
 struct ucma_abi_query {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
 	__u64 response;
 	__u32 id;
 	__u32 option;
@@ -199,17 +223,26 @@ struct ucma_abi_ud_param {
 };
 
 struct ucma_abi_connect {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
 	struct ucma_abi_conn_param conn_param;
 	__u32 id;
 	__u32 reserved;
 };
 
 struct ucma_abi_listen {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
 	__u32 id;
 	__u32 backlog;
 };
 
 struct ucma_abi_accept {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
 	__u64 uid;
 	struct ucma_abi_conn_param conn_param;
 	__u32 id;
@@ -217,6 +250,9 @@ struct ucma_abi_accept {
 };
 
 struct ucma_abi_reject {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
 	__u32 id;
 	__u8  private_data_len;
 	__u8  reserved[3];
@@ -224,21 +260,33 @@ struct ucma_abi_reject {
 };
 
 struct ucma_abi_disconnect {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
 	__u32 id;
 };
 
 struct ucma_abi_init_qp_attr {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
 	__u64 response;
 	__u32 id;
 	__u32 qp_state;
 };
 
 struct ucma_abi_notify {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
 	__u32 id;
 	__u32 event;
 };
 
 struct ucma_abi_join_ip_mcast {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
 	__u64 response;		/* ucma_abi_create_id_resp */
 	__u64 uid;
 	struct sockaddr_in6 addr;
@@ -246,6 +294,9 @@ struct ucma_abi_join_ip_mcast {
 };
 
 struct ucma_abi_join_mcast {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
 	__u64 response;		/* rdma_ucma_create_id_resp */
 	__u64 uid;
 	__u32 id;
@@ -255,6 +306,9 @@ struct ucma_abi_join_mcast {
 };
 
 struct ucma_abi_get_event {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
 	__u64 response;
 };
 
@@ -270,6 +324,9 @@ struct ucma_abi_event_resp {
 };
 
 struct ucma_abi_set_option {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
 	__u64 optval;
 	__u32 id;
 	__u32 level;
@@ -278,6 +335,9 @@ struct ucma_abi_set_option {
 };
 
 struct ucma_abi_migrate_id {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
 	__u64 response;
 	__u32 id;
 	__u32 fd;
diff --git a/include/rdma/rdma_verbs.h b/include/rdma/rdma_verbs.h
index e6a6b42..eca2c7a 100644
--- a/include/rdma/rdma_verbs.h
+++ b/include/rdma/rdma_verbs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2010-2011 Intel Corporation.  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
@@ -52,26 +52,35 @@ static inline int rdma_seterrno(int ret)
 }
 
 /*
+ * Shared receive queues.
+ */
+int rdma_create_srq(struct rdma_cm_id *id, struct ibv_pd *pd,
+		    struct ibv_srq_init_attr *attr);
+
+void rdma_destroy_srq(struct rdma_cm_id *id);
+
+
+/*
  * Memory registration helpers.
  */
 static inline struct ibv_mr *
 rdma_reg_msgs(struct rdma_cm_id *id, void *addr, size_t length)
 {
-	return ibv_reg_mr(id->qp->pd, addr, length, IBV_ACCESS_LOCAL_WRITE);
+	return ibv_reg_mr(id->pd, addr, length, IBV_ACCESS_LOCAL_WRITE);
 }
 
 static inline struct ibv_mr *
 rdma_reg_read(struct rdma_cm_id *id, void *addr, size_t length)
 {
-	return ibv_reg_mr(id->qp->pd, addr, length, IBV_ACCESS_LOCAL_WRITE |
-						    IBV_ACCESS_REMOTE_READ);
+	return ibv_reg_mr(id->pd, addr, length, IBV_ACCESS_LOCAL_WRITE |
+						IBV_ACCESS_REMOTE_READ);
 }
 
 static inline struct ibv_mr *
 rdma_reg_write(struct rdma_cm_id *id, void *addr, size_t length)
 {
-	return ibv_reg_mr(id->qp->pd, addr, length, IBV_ACCESS_LOCAL_WRITE |
-						    IBV_ACCESS_REMOTE_WRITE);
+	return ibv_reg_mr(id->pd, addr, length, IBV_ACCESS_LOCAL_WRITE |
+						IBV_ACCESS_REMOTE_WRITE);
 }
 
 static inline int
@@ -96,7 +105,10 @@ rdma_post_recvv(struct rdma_cm_id *id, void *context, struct ibv_sge *sgl,
 	wr.sg_list = sgl;
 	wr.num_sge = nsge;
 
-	return rdma_seterrno(ibv_post_recv(id->qp, &wr, &bad));
+	if (id->srq)
+		return rdma_seterrno(ibv_post_srq_recv(id->srq, &wr, &bad));
+	else
+		return rdma_seterrno(ibv_post_recv(id->qp, &wr, &bad));
 }
 
 static inline int
diff --git a/librdmacm.spec b/librdmacm.spec
index 7bbbdb9..c9e8bec 100644
--- a/librdmacm.spec
+++ b/librdmacm.spec
@@ -1,7 +1,7 @@
-%define ver 1.0.14.1
+%define ver 1.0.15
 
 Name: librdmacm
-Version: 1.0.14.1
+Version: 1.0.15
 Release: 1%{?dist}
 Summary: Userspace RDMA Connection Manager
 
diff --git a/librdmacm.spec.in b/librdmacm.spec.in
index 0044a2d..7248137 100644
--- a/librdmacm.spec.in
+++ b/librdmacm.spec.in
@@ -1,7 +1,7 @@
 %define ver @VERSION@
 
 Name: librdmacm
-Version: 1.0.14.1
+Version: 1.0.15
 Release: 1%{?dist}
 Summary: Userspace RDMA Connection Manager
 
diff --git a/man/rdma_accept.3 b/man/rdma_accept.3
old mode 100644
new mode 100755
index ac04e2c..92e1a07
--- a/man/rdma_accept.3
+++ b/man/rdma_accept.3
@@ -47,8 +47,8 @@ be larger than that requested.
 The maximum number of outstanding RDMA read and atomic operations that the
 local side will accept from the remote side.  Applies only to RDMA_PS_TCP.
 This value must be less than or equal to the local RDMA device attribute
-max_qp_rd_atom and the responder_resources value reported in the connect
-request event.
+max_qp_rd_atom, but preferably greater than or equal to the responder_resources
+value reported in the connect request event.
 .IP initiator_depth
 The maximum number of outstanding RDMA read and atomic operations that the
 local side will have to the remote side.  Applies only to RDMA_PS_TCP.
@@ -84,5 +84,8 @@ by the active side of the connection.  The HCA ACK delay is a property of
 the locally used HCA.
 .P
 The RNR retry count is a 3-bit value.
+.P
+The length of the private data provided by the user is limited to 196 bytes
+for RDMA_PS_TCP, or 136 bytes for RDMA_PS_UDP.
 .SH "SEE ALSO"
 rdma_listen(3), rdma_reject(3), rdma_get_cm_event(3)
diff --git a/man/rdma_connect.3 b/man/rdma_connect.3
old mode 100644
new mode 100755
index b0cc51e..51056a0
--- a/man/rdma_connect.3
+++ b/man/rdma_connect.3
@@ -79,6 +79,9 @@ Administrator and is part of the resolved route (path record) information.
 The HCA ACK delay is a property of the locally used HCA.
 .P
 Retry count and RNR retry count values are 3-bit values.
+.P
+The length of the private data provided by the user is limited to 56 bytes
+for RDMA_PS_TCP, or 180 bytes for RDMA_PS_UDP.
 .SH "IWARP SPECIFIC"
 Connections established over iWarp RDMA devices currently require that the
 active side of the connection send the first message.
diff --git a/man/rdma_create_qp.3 b/man/rdma_create_qp.3
old mode 100644
new mode 100755
index 7445db3..7e37888
--- a/man/rdma_create_qp.3
+++ b/man/rdma_create_qp.3
@@ -41,7 +41,8 @@ channels.  Completion channels and CQ data created by the rdma_cm are
 exposed to the user through the rdma_cm_id structure.
 .P
 The actual capabilities and properties of the created QP will be
-returned to the user through the qp_init_attr parameter.
+returned to the user through the qp_init_attr parameter.  An rdma_cm_id
+may only be associated with a single QP.
 .SH "SEE ALSO"
 rdma_bind_addr(3), rdma_resolve_addr(3), rdma_destroy_qp(3), ibv_create_qp(3),
 ibv_modify_qp(3)
diff --git a/man/rdma_create_srq.3 b/man/rdma_create_srq.3
new file mode 100644
index 0000000..9b917c2
--- /dev/null
+++ b/man/rdma_create_srq.3
@@ -0,0 +1,44 @@
+.TH "RDMA_CREATE_SRQ" 3 "2011-06-15" "librdmacm" "Librdmacm Programmer's Manual" librdmacm
+.SH NAME
+rdma_create_srq \- Allocate a shared receive queue.
+.SH SYNOPSIS
+.B "#include <rdma/rdma_verbs.h>"
+.P
+.B "int" rdma_create_srq
+.BI "(struct rdma_cm_id *" id ","
+.BI "struct ibv_pd *" pd ","
+.BI "struct ibv_srq_init_attr *" attr ");"
+.SH ARGUMENTS
+.IP "id" 12
+RDMA identifier.
+.IP "pd" 12
+Optional protection domain for the SRQ.
+.IP "attr" 12
+Initial SRQ attributes.
+.SH "DESCRIPTION"
+Allocate a SRQ associated with the specified rdma_cm_id.
+.SH "RETURN VALUE"
+Returns 0 on success, or -1 on error.  If an error occurs, errno will be
+set to indicate the failure reason.
+.SH "NOTES"
+The rdma_cm_id must be bound to a local RDMA device before calling this
+function, and the protection domain, if provided, must be for that same device.
+After being allocated, the SRQ will be ready to handle posting of receives.
+.P
+If a protection domain is not given - pd parameter is NULL - then
+the rdma_cm_id will be created using a default protection domain.  One
+default protection domain is allocated per RDMA device.
+.P
+The initial SRQ attributes are specified by the attr parameter.  The
+ext.xrc.cq fields in the ibv_srq_init_attr is optional.  If
+a completion queue is not specified for an XRC SRQ, then a CQ will be
+allocated by the rdma_cm for the SRQ, along with corresponding completion
+channels.  Completion channels and CQ data created by the rdma_cm are
+exposed to the user through the rdma_cm_id structure.
+.P
+The actual capabilities and properties of the created SRQ will be
+returned to the user through the attr parameter.  An rdma_cm_id
+may only be associated with a single SRQ.
+.SH "SEE ALSO"
+rdma_bind_addr(3), rdma_resolve_addr(3), rdma_create_ep(3),
+rdma_destroy_srq(3), ibv_create_srq(3), ibv_create_xsrq(3)
diff --git a/man/rdma_destroy_ep.3 b/man/rdma_destroy_ep.3
index 13a8766..b48a1e5 100644
--- a/man/rdma_destroy_ep.3
+++ b/man/rdma_destroy_ep.3
@@ -1,4 +1,5 @@
-.TH "RDMA_DESTROY_EP" 3 "2007-05-15" "librdmacm" "Librdmacm Programmer's Manual" librdmacm
+
+.TH "RDMA_DESTROY_EP" 3 "2011-06-15" "librdmacm" "Librdmacm Programmer's Manual" librdmacm
 .SH NAME
 rdma_destroy_ep \- Release a communication identifier.
 .SH SYNOPSIS
@@ -15,7 +16,7 @@ Destroys the specified rdma_cm_id and all associated resources
 Returns 0 on success, or -1 on error.  If an error occurs, errno will be
 set to indicate the failure reason.
 .SH "NOTES"
-rdma_destroy_ep will automatically destroy any QP associated with
+rdma_destroy_ep will automatically destroy any QP and SRQ associated with
 the rdma_cm_id.
 .SH "SEE ALSO"
 rdma_create_ep(3)
diff --git a/man/rdma_destroy_srq.3 b/man/rdma_destroy_srq.3
new file mode 100644
index 0000000..5f0dfe0
--- /dev/null
+++ b/man/rdma_destroy_srq.3
@@ -0,0 +1,21 @@
+.TH "RDMA_DESTROY_SRQ" 3 "2011-06-15" "librdmacm" "Librdmacm Programmer's Manual" librdmacm
+.SH NAME
+rdma_destroy_srq \- Deallocate a SRQ.
+.SH SYNOPSIS
+.B "#include <rdma/rdma_verbs.h>"
+.P
+.B "void" rdma_destroy_srq
+.BI "(struct rdma_cm_id *" id ");"
+.SH ARGUMENTS
+.IP "id" 12
+RDMA identifier.
+.SH "DESCRIPTION"
+Destroy an SRQ allocated on the rdma_cm_id.
+.SH "RETURN VALUE"
+Returns 0 on success, or -1 on error.  If an error occurs, errno will be
+set to indicate the failure reason.
+.SH "NOTES"
+Users should destroy any SRQ associated with an rdma_cm_id before
+destroying the ID.
+.SH "SEE ALSO"
+rdma_create_srq(3), rdma_destroy_id(3), ibv_destroy_srq(3)
diff --git a/man/rdma_join_multicast.3 b/man/rdma_join_multicast.3
old mode 100644
new mode 100755
index 92c2d8d..7886716
--- a/man/rdma_join_multicast.3
+++ b/man/rdma_join_multicast.3
@@ -27,9 +27,12 @@ rdma_resolve_addr requires the local routing tables to resolve the
 multicast address to an RDMA device, unless a specific source address
 is provided.  The user must call rdma_leave_multicast to leave the
 multicast group and release any multicast resources.  After the join
-operation completes, any associated QP is automatically attached to the
-multicast group, and the join context is returned to the user through
-the private_data field in the rdma_cm_event.
+operation completes, if a QP is associated with the rdma_cm_id,
+it is automatically attached to the multicast group when the multicast
+event is retrieved by the user.  Otherwise, the user is responsible
+for calling ibv_attach_mcast to bind the QP to the multicast group.
+The join context is returned to the user through the private_data
+field in the rdma_cm_event.
 .SH "SEE ALSO"
 rdma_leave_multicast(3), rdma_bind_addr(3), rdma_resolve_addr(3), rdma_create_qp(3),
 rdma_get_cm_event(3)
diff --git a/man/rdma_notify.3 b/man/rdma_notify.3
old mode 100644
new mode 100755
index a29ee07..62db575
--- a/man/rdma_notify.3
+++ b/man/rdma_notify.3
@@ -17,7 +17,11 @@ Used to notify the librdmacm of asynchronous events that have occurred
 on a QP associated with the rdma_cm_id.
 .SH "RETURN VALUE"
 Returns 0 on success, or -1 on error.  If an error occurs, errno will be
-set to indicate the failure reason.
+set to indicate the failure reason.  If errno is set to EISCONN
+(transport endpoint is already connected), this indicates that the 
+the underlying communication manager established the connection before
+the call to rdma_notify could be processed.  In this case, the error may
+safely be ignored.
 .SH "NOTES"
 Asynchronous events that occur on a QP are reported through the user's
 device event handler.  This routine is used to notify the librdmacm of
diff --git a/man/rdma_xclient.1 b/man/rdma_xclient.1
new file mode 100644
index 0000000..087e7fe
--- /dev/null
+++ b/man/rdma_xclient.1
@@ -0,0 +1,35 @@
+.TH "RDMA_XCLIENT" 1 "2011-06-15" "librdmacm" "librdmacm" librdmacm
+.SH NAME
+rdma_xclient \- RDMA CM communication client test program
+.SH SYNOPSIS
+.sp
+.nf
+\fIrdma_xclient\fR [-s server_address] [-p server_port] [-c comm_type]
+.fi
+.SH "DESCRIPTION"
+Uses synchronous librdmam calls to establish an RDMA connection between
+two nodes.  This example is intended to provide a very simple coding
+example of how to use RDMA.
+.SH "OPTIONS"
+.TP
+\-s server_address
+Specifies the address of the system that the rdma_server is running on.
+By default, the client will attempt to connect to the server using
+127.0.0.1.
+.TP
+\-p server_port
+Specifies the port number that the server listens on.  By default the server
+listens on port 7471.
+\-c communication type
+Specifies the type of communication established with the server program.
+'r' results in using a reliable-connected QP (the default).  'x' uses
+extended reliable-connected XRC QPs.
+.SH "NOTES"
+Basic usage is to start rdma_xserver, then connect to the server using the
+rdma_client program.
+.P
+Because this test maps RDMA resources to userspace, users must ensure
+that they have available system resources and permissions.  See the
+libibverbs README file for additional details.
+.SH "SEE ALSO"
+rdma_cm(7), udaddy(1), mckey(1), rping(1), rdma_xserver(1), rdma_client(1)
diff --git a/man/rdma_xserver.1 b/man/rdma_xserver.1
new file mode 100644
index 0000000..75529e4
--- /dev/null
+++ b/man/rdma_xserver.1
@@ -0,0 +1,29 @@
+.TH "RDMA_XSERVER" 1 "2011-06-15" "librdmacm" "librdmacm" librdmacm
+.SH NAME
+rdma_xserver \- RDMA CM communication server test program
+.SH SYNOPSIS
+.sp
+.nf
+\fIrdma_xserver\fR [-p port] [-c comm_type]
+.fi
+.SH "DESCRIPTION"
+Uses the librdmacm to establish various forms of communication and exchange
+data.
+.SH "OPTIONS"
+.TP
+\-p port
+Changes the port number that the server listens on.  By default the server
+listens on port 7471.
+\-c communication type
+Specifies the type of communication established with the client program.
+'r' results in using a reliable-connected QP (the default).  'x' uses
+extended reliable-connected XRC QPs.
+.SH "NOTES"
+Basic usage is to start rdma_xserver, then connect to the server using the
+rdma_xclient program.
+.P
+Because this test maps RDMA resources to userspace, users must ensure
+that they have available system resources and permissions.  See the
+libibverbs README file for additional details.
+.SH "SEE ALSO"
+rdma_cm(7), udaddy(1), mckey(1), rping(1), rdma_server(1), rdma_xclient(1)
diff --git a/src/addrinfo.c b/src/addrinfo.c
index 021f7c4..695430b 100755
--- a/src/addrinfo.c
+++ b/src/addrinfo.c
@@ -45,6 +45,14 @@
 #include <rdma/rdma_cma.h>
 #include <infiniband/ib.h>
 
+#ifdef IBV_XRC_OPS
+#define RDMA_QPT_XRC_SEND IBV_QPT_XRC_SEND
+#define RDMA_QPT_XRC_RECV IBV_QPT_XRC_RECV
+#else
+#define RDMA_QPT_XRC_SEND 9
+#define RDMA_QPT_XRC_RECV 10
+#endif
+
 static void ucma_convert_to_ai(struct addrinfo *ai, struct rdma_addrinfo *rai)
 {
 	memset(ai, 0, sizeof *ai);
@@ -54,6 +62,9 @@ static void ucma_convert_to_ai(struct addrinfo *ai, struct rdma_addrinfo *rai)
 
 	switch (rai->ai_qp_type) {
 	case IBV_QPT_RC:
+	case IBV_QPT_UC:
+	case RDMA_QPT_XRC_SEND:
+	case RDMA_QPT_XRC_RECV:
 		ai->ai_socktype = SOCK_STREAM;
 		break;
 	case IBV_QPT_UD:
@@ -69,6 +80,12 @@ static void ucma_convert_to_ai(struct addrinfo *ai, struct rdma_addrinfo *rai)
 	case RDMA_PS_UDP:
 		ai->ai_protocol = IPPROTO_UDP;
 		break;
+	case RDMA_PS_IB:
+		if (ai->ai_socktype == SOCK_STREAM)
+			ai->ai_protocol = IPPROTO_TCP;
+		else if (ai->ai_socktype == SOCK_DGRAM)
+			ai->ai_protocol = IPPROTO_UDP;
+		break;
 	}
 
 	if (rai->ai_flags & RAI_PASSIVE) {
@@ -82,29 +99,38 @@ static void ucma_convert_to_ai(struct addrinfo *ai, struct rdma_addrinfo *rai)
 	ai->ai_next = NULL;
 }
 
-static int ucma_convert_to_rai(struct rdma_addrinfo *rai, struct addrinfo *ai)
+static int ucma_convert_to_rai(struct rdma_addrinfo *rai,
+			       struct rdma_addrinfo *hints, struct addrinfo *ai)
 {
 	struct sockaddr *addr;
 	char *canonname;
 
 	rai->ai_family = ai->ai_family;
 
-	switch (ai->ai_socktype) {
-	case SOCK_STREAM:
-		rai->ai_qp_type = IBV_QPT_RC;
-		break;
-	case SOCK_DGRAM:
-		rai->ai_qp_type = IBV_QPT_UD;
-		break;
+	if (hints && hints->ai_qp_type) {
+		rai->ai_qp_type = hints->ai_qp_type;
+	} else {
+		switch (ai->ai_socktype) {
+		case SOCK_STREAM:
+			rai->ai_qp_type = IBV_QPT_RC;
+			break;
+		case SOCK_DGRAM:
+			rai->ai_qp_type = IBV_QPT_UD;
+			break;
+		}
 	}
 
-	switch (ai->ai_protocol) {
-	case IPPROTO_TCP:
-		rai->ai_port_space = RDMA_PS_TCP;
-		break;
-	case IPPROTO_UDP:
-		rai->ai_port_space = RDMA_PS_UDP;
-		break;
+	if (hints && hints->ai_port_space) {
+		rai->ai_port_space = hints->ai_port_space;
+	} else {
+		switch (ai->ai_protocol) {
+		case IPPROTO_TCP:
+			rai->ai_port_space = RDMA_PS_TCP;
+			break;
+		case IPPROTO_UDP:
+			rai->ai_port_space = RDMA_PS_UDP;
+			break;
+		}
 	}
 
 	addr = malloc(ai->ai_addrlen);
@@ -149,7 +175,7 @@ static int ucma_convert_gai(char *node, char *service,
 	if (ret)
 		return ret;
 
-	ret = ucma_convert_to_rai(rai, ai);
+	ret = ucma_convert_to_rai(rai, hints, ai);
 	freeaddrinfo(ai);
 	return ret;
 }
diff --git a/src/cma.c b/src/cma.c
index 7ac5335..91e110e 100755
--- a/src/cma.c
+++ b/src/cma.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005-2006 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2005-2011 Intel Corporation.  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
@@ -28,8 +28,6 @@
  * 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.
- *
- * $Id: cm.c 3453 2005-09-15 21:43:21Z sean.hefty $
  */
 
 #if HAVE_CONFIG_H
@@ -59,40 +57,18 @@
 #include <rdma/rdma_verbs.h>
 #include <infiniband/ib.h>
 
-#define CMA_CREATE_MSG_CMD_RESP(msg, cmd, resp, type, size) \
-do {                                        \
-	struct ucma_abi_cmd_hdr *hdr;         \
-                                            \
-	size = sizeof(*hdr) + sizeof(*cmd); \
-	msg = alloca(size);                 \
-	if (!msg)                           \
-		return ERR(ENOMEM);         \
-	hdr = msg;                          \
-	cmd = msg + sizeof(*hdr);           \
-	hdr->cmd = type;                    \
-	hdr->in  = sizeof(*cmd);            \
-	hdr->out = sizeof(*resp);           \
-	memset(cmd, 0, sizeof(*cmd));       \
-	resp = alloca(sizeof(*resp));       \
-	if (!resp)                          \
-		return ERR(ENOMEM);         \
-	cmd->response = (uintptr_t)resp;\
+#define CMA_INIT_CMD(req, req_size, op)		\
+do {						\
+	memset(req, 0, req_size);		\
+	(req)->cmd = UCMA_CMD_##op;		\
+	(req)->in  = req_size - sizeof(struct ucma_abi_cmd_hdr); \
 } while (0)
 
-#define CMA_CREATE_MSG_CMD(msg, cmd, type, size) \
-do {                                        \
-	struct ucma_abi_cmd_hdr *hdr;       \
-                                            \
-	size = sizeof(*hdr) + sizeof(*cmd); \
-	msg = alloca(size);                 \
-	if (!msg)                           \
-		return ERR(ENOMEM);         \
-	hdr = msg;                          \
-	cmd = msg + sizeof(*hdr);           \
-	hdr->cmd = type;                    \
-	hdr->in  = sizeof(*cmd);            \
-	hdr->out = 0;                       \
-	memset(cmd, 0, sizeof(*cmd));       \
+#define CMA_INIT_CMD_RESP(req, req_size, op, resp, resp_size) \
+do {						\
+	CMA_INIT_CMD(req, req_size, op);	\
+	(req)->out = resp_size;			\
+	(req)->response = (uintptr_t) (resp);	\
 } while (0)
 
 struct cma_device {
@@ -116,7 +92,6 @@ struct cma_id_private {
 	pthread_mutex_t		mut;
 	uint32_t		handle;
 	struct cma_multicast	*mc_list;
-	struct ibv_pd		*pd;
 	struct ibv_qp_init_attr	*qp_init_attr;
 	uint8_t			initiator_depth;
 	uint8_t			responder_resources;
@@ -253,6 +228,12 @@ int ucma_init(void)
 		goto err1;
 	}
 
+	if (!dev_cnt) {
+		printf("CMA: no RDMA devices found\n");
+		ret = ERR(ENODEV);
+		goto err2;
+	}
+		
 	cma_dev_array = malloc(sizeof *cma_dev * dev_cnt);
 	if (!cma_dev_array) {
 		ret = ERR(ENOMEM);
@@ -381,6 +362,7 @@ static int ucma_get_device(struct cma_id_private *id_priv, uint64_t guid)
 		if (cma_dev->guid == guid) {
 			id_priv->cma_dev = cma_dev;
 			id_priv->id.verbs = cma_dev->verbs;
+			id_priv->id.pd = cma_dev->pd;
 			return 0;
 		}
 	}
@@ -404,7 +386,8 @@ static void ucma_free_id(struct cma_id_private *id_priv)
 
 static struct cma_id_private *ucma_alloc_id(struct rdma_event_channel *channel,
 					    void *context,
-					    enum rdma_port_space ps)
+					    enum rdma_port_space ps,
+					    enum ibv_qp_type qp_type)
 {
 	struct cma_id_private *id_priv;
 
@@ -414,6 +397,7 @@ static struct cma_id_private *ucma_alloc_id(struct rdma_event_channel *channel,
 
 	id_priv->id.context = context;
 	id_priv->id.ps = ps;
+	id_priv->id.qp_type = qp_type;
 
 	if (!channel) {
 		id_priv->id.channel = rdma_create_event_channel();
@@ -438,32 +422,31 @@ static int rdma_create_id2(struct rdma_event_channel *channel,
 			   struct rdma_cm_id **id, void *context,
 			   enum rdma_port_space ps, enum ibv_qp_type qp_type)
 {
-	struct ucma_abi_create_id_resp *resp;
-	struct ucma_abi_create_id *cmd;
+	struct ucma_abi_create_id_resp resp;
+	struct ucma_abi_create_id cmd;
 	struct cma_id_private *id_priv;
-	void *msg;
-	int ret, size;
+	int ret;
 
 	ret = ucma_init();
 	if (ret)
 		return ret;
 
-	id_priv = ucma_alloc_id(channel, context, ps);
+	id_priv = ucma_alloc_id(channel, context, ps, qp_type);
 	if (!id_priv)
 		return ERR(ENOMEM);
 
-	CMA_CREATE_MSG_CMD_RESP(msg, cmd, resp, UCMA_CMD_CREATE_ID, size);
-	cmd->uid = (uintptr_t) id_priv;
-	cmd->ps = ps;
-	cmd->qp_type = qp_type;
+	CMA_INIT_CMD_RESP(&cmd, sizeof cmd, CREATE_ID, &resp, sizeof resp);
+	cmd.uid = (uintptr_t) id_priv;
+	cmd.ps = ps;
+	cmd.qp_type = qp_type;
 
-	ret = write(id_priv->id.channel->fd, msg, size);
-	if (ret != size)
+	ret = write(id_priv->id.channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd)
 		goto err;
 
-	VALGRIND_MAKE_MEM_DEFINED(resp, sizeof *resp);
+	VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp);
 
-	id_priv->handle = resp->id;
+	id_priv->handle = resp.id;
 	*id = &id_priv->id;
 	return 0;
 
@@ -484,21 +467,20 @@ int rdma_create_id(struct rdma_event_channel *channel,
 
 static int ucma_destroy_kern_id(int fd, uint32_t handle)
 {
-	struct ucma_abi_destroy_id_resp *resp;
-	struct ucma_abi_destroy_id *cmd;
-	void *msg;
-	int ret, size;
+	struct ucma_abi_destroy_id_resp resp;
+	struct ucma_abi_destroy_id cmd;
+	int ret;
 	
-	CMA_CREATE_MSG_CMD_RESP(msg, cmd, resp, UCMA_CMD_DESTROY_ID, size);
-	cmd->id = handle;
+	CMA_INIT_CMD_RESP(&cmd, sizeof cmd, DESTROY_ID, &resp, sizeof resp);
+	cmd.id = handle;
 
-	ret = write(fd, msg, size);
-	if (ret != size)
+	ret = write(fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd)
 		return (ret >= 0) ? ERR(ENODATA) : -1;
 
-	VALGRIND_MAKE_MEM_DEFINED(resp, sizeof *resp);
+	VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp);
 
-	return resp->events_reported;
+	return resp.events_reported;
 }
 
 int rdma_destroy_id(struct rdma_cm_id *id)
@@ -542,32 +524,31 @@ static int ucma_addrlen(struct sockaddr *addr)
 
 static int ucma_query_addr(struct rdma_cm_id *id)
 {
-	struct ucma_abi_query_addr_resp *resp;
-	struct ucma_abi_query *cmd;
+	struct ucma_abi_query_addr_resp resp;
+	struct ucma_abi_query cmd;
 	struct cma_id_private *id_priv;
-	void *msg;
-	int ret, size;
+	int ret;
 	
-	CMA_CREATE_MSG_CMD_RESP(msg, cmd, resp, UCMA_CMD_QUERY, size);
+	CMA_INIT_CMD_RESP(&cmd, sizeof cmd, QUERY, &resp, sizeof resp);
 	id_priv = container_of(id, struct cma_id_private, id);
-	cmd->id = id_priv->handle;
-	cmd->option = UCMA_QUERY_ADDR;
+	cmd.id = id_priv->handle;
+	cmd.option = UCMA_QUERY_ADDR;
 
-	ret = write(id->channel->fd, msg, size);
-	if (ret != size)
+	ret = write(id->channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd)
 		return (ret >= 0) ? ERR(ENODATA) : -1;
 
-	VALGRIND_MAKE_MEM_DEFINED(resp, sizeof *resp);
+	VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp);
 
-	memcpy(&id->route.addr.src_addr, &resp->src_addr, resp->src_size);
-	memcpy(&id->route.addr.dst_addr, &resp->dst_addr, resp->dst_size);
+	memcpy(&id->route.addr.src_addr, &resp.src_addr, resp.src_size);
+	memcpy(&id->route.addr.dst_addr, &resp.dst_addr, resp.dst_size);
 
-	if (!id_priv->cma_dev && resp->node_guid) {
-		ret = ucma_get_device(id_priv, resp->node_guid);
+	if (!id_priv->cma_dev && resp.node_guid) {
+		ret = ucma_get_device(id_priv, resp.node_guid);
 		if (ret)
 			return ret;
-		id->port_num = resp->port_num;
-		id->route.addr.addr.ibaddr.pkey = resp->pkey;
+		id->port_num = resp.port_num;
+		id->route.addr.addr.ibaddr.pkey = resp.pkey;
 	}
 
 	return 0;
@@ -575,29 +556,28 @@ static int ucma_query_addr(struct rdma_cm_id *id)
 
 static int ucma_query_gid(struct rdma_cm_id *id)
 {
-	struct ucma_abi_query_addr_resp *resp;
-	struct ucma_abi_query *cmd;
+	struct ucma_abi_query_addr_resp resp;
+	struct ucma_abi_query cmd;
 	struct cma_id_private *id_priv;
 	struct sockaddr_ib *sib;
-	void *msg;
-	int ret, size;
+	int ret;
 	
-	CMA_CREATE_MSG_CMD_RESP(msg, cmd, resp, UCMA_CMD_QUERY, size);
+	CMA_INIT_CMD_RESP(&cmd, sizeof cmd, QUERY, &resp, sizeof resp);
 	id_priv = container_of(id, struct cma_id_private, id);
-	cmd->id = id_priv->handle;
-	cmd->option = UCMA_QUERY_GID;
+	cmd.id = id_priv->handle;
+	cmd.option = UCMA_QUERY_GID;
 
-	ret = write(id->channel->fd, msg, size);
-	if (ret != size)
+	ret = write(id->channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd)
 		return (ret >= 0) ? ERR(ENODATA) : -1;
 
-	VALGRIND_MAKE_MEM_DEFINED(resp, sizeof *resp);
+	VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp);
 
-	sib = (struct sockaddr_ib *) &resp->src_addr;
+	sib = (struct sockaddr_ib *) &resp.src_addr;
 	memcpy(id->route.addr.addr.ibaddr.sgid.raw, sib->sib_addr.sib_raw,
 	       sizeof id->route.addr.addr.ibaddr.sgid);
 
-	sib = (struct sockaddr_ib *) &resp->dst_addr;
+	sib = (struct sockaddr_ib *) &resp.dst_addr;
 	memcpy(id->route.addr.addr.ibaddr.dgid.raw, sib->sib_addr.sib_raw,
 	       sizeof id->route.addr.addr.ibaddr.dgid);
 
@@ -637,40 +617,25 @@ static void ucma_convert_path(struct ibv_path_data *path_data,
 static int ucma_query_path(struct rdma_cm_id *id)
 {
 	struct ucma_abi_query_path_resp *resp;
-	struct ucma_abi_query *cmd;
-	struct ucma_abi_cmd_hdr *hdr;
+	struct ucma_abi_query cmd;
 	struct cma_id_private *id_priv;
-	void *msg;
-	int ret, size, i;
-
-	size = sizeof(*hdr) + sizeof(*cmd);
-	msg = alloca(size);
-	if (!msg)
-		return ERR(ENOMEM);
+	int ret, i, size;
 
-	hdr = msg;
-	cmd = msg + sizeof(*hdr);
-
-	hdr->cmd = UCMA_CMD_QUERY;
-	hdr->in  = sizeof(*cmd);
-	hdr->out = sizeof(*resp) + sizeof(struct ibv_path_data) * 6;
-
-	memset(cmd, 0, sizeof(*cmd));
-
-	resp = alloca(hdr->out);
+	size = sizeof(*resp) + sizeof(struct ibv_path_data) * 6;
+	resp = alloca(size);
 	if (!resp)
 		return ERR(ENOMEM);
 
+	CMA_INIT_CMD_RESP(&cmd, sizeof cmd, QUERY, resp, size);
 	id_priv = container_of(id, struct cma_id_private, id);
-	cmd->response = (uintptr_t) resp;
-	cmd->id = id_priv->handle;
-	cmd->option = UCMA_QUERY_PATH;
+	cmd.id = id_priv->handle;
+	cmd.option = UCMA_QUERY_PATH;
 
-	ret = write(id->channel->fd, msg, size);
-	if (ret != size)
+	ret = write(id->channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd)
 		return (ret >= 0) ? ERR(ENODATA) : -1;
 
-	VALGRIND_MAKE_MEM_DEFINED(resp, hdr->out);
+	VALGRIND_MAKE_MEM_DEFINED(resp, size);
 
 	if (resp->num_paths) {
 		id->route.path_rec = malloc(sizeof(*id->route.path_rec) *
@@ -688,49 +653,48 @@ static int ucma_query_path(struct rdma_cm_id *id)
 
 static int ucma_query_route(struct rdma_cm_id *id)
 {
-	struct ucma_abi_query_route_resp *resp;
-	struct ucma_abi_query *cmd;
+	struct ucma_abi_query_route_resp resp;
+	struct ucma_abi_query cmd;
 	struct cma_id_private *id_priv;
-	void *msg;
-	int ret, size, i;
+	int ret, i;
 
-	CMA_CREATE_MSG_CMD_RESP(msg, cmd, resp, UCMA_CMD_QUERY_ROUTE, size);
+	CMA_INIT_CMD_RESP(&cmd, sizeof cmd, QUERY_ROUTE, &resp, sizeof resp);
 	id_priv = container_of(id, struct cma_id_private, id);
-	cmd->id = id_priv->handle;
+	cmd.id = id_priv->handle;
 
-	ret = write(id->channel->fd, msg, size);
-	if (ret != size)
+	ret = write(id->channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd)
 		return (ret >= 0) ? ERR(ENODATA) : -1;
 
-	VALGRIND_MAKE_MEM_DEFINED(resp, sizeof *resp);
+	VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp);
 
-	if (resp->num_paths) {
+	if (resp.num_paths) {
 		id->route.path_rec = malloc(sizeof *id->route.path_rec *
-					    resp->num_paths);
+					    resp.num_paths);
 		if (!id->route.path_rec)
 			return ERR(ENOMEM);
 
-		id->route.num_paths = resp->num_paths;
-		for (i = 0; i < resp->num_paths; i++)
+		id->route.num_paths = resp.num_paths;
+		for (i = 0; i < resp.num_paths; i++)
 			ibv_copy_path_rec_from_kern(&id->route.path_rec[i],
-						    &resp->ib_route[i]);
+						    &resp.ib_route[i]);
 	}
 
-	memcpy(id->route.addr.addr.ibaddr.sgid.raw, resp->ib_route[0].sgid,
+	memcpy(id->route.addr.addr.ibaddr.sgid.raw, resp.ib_route[0].sgid,
 	       sizeof id->route.addr.addr.ibaddr.sgid);
-	memcpy(id->route.addr.addr.ibaddr.dgid.raw, resp->ib_route[0].dgid,
+	memcpy(id->route.addr.addr.ibaddr.dgid.raw, resp.ib_route[0].dgid,
 	       sizeof id->route.addr.addr.ibaddr.dgid);
-	id->route.addr.addr.ibaddr.pkey = resp->ib_route[0].pkey;
-	memcpy(&id->route.addr.src_addr, &resp->src_addr,
-	       sizeof resp->src_addr);
-	memcpy(&id->route.addr.dst_addr, &resp->dst_addr,
-	       sizeof resp->dst_addr);
-
-	if (!id_priv->cma_dev && resp->node_guid) {
-		ret = ucma_get_device(id_priv, resp->node_guid);
+	id->route.addr.addr.ibaddr.pkey = resp.ib_route[0].pkey;
+	memcpy(&id->route.addr.src_addr, &resp.src_addr,
+	       sizeof resp.src_addr);
+	memcpy(&id->route.addr.dst_addr, &resp.dst_addr,
+	       sizeof resp.dst_addr);
+
+	if (!id_priv->cma_dev && resp.node_guid) {
+		ret = ucma_get_device(id_priv, resp.node_guid);
 		if (ret)
 			return ret;
-		id_priv->id.port_num = resp->port_num;
+		id_priv->id.port_num = resp.port_num;
 	}
 
 	return 0;
@@ -739,20 +703,18 @@ static int ucma_query_route(struct rdma_cm_id *id)
 static int rdma_bind_addr2(struct rdma_cm_id *id, struct sockaddr *addr,
 			   socklen_t addrlen)
 {
-	struct ucma_abi_bind *cmd;
+	struct ucma_abi_bind cmd;
 	struct cma_id_private *id_priv;
-	void *msg;
-	int ret, size;
+	int ret;
 	
-	CMA_CREATE_MSG_CMD(msg, cmd, UCMA_CMD_BIND, size);
+	CMA_INIT_CMD(&cmd, sizeof cmd, BIND);
 	id_priv = container_of(id, struct cma_id_private, id);
-	cmd->id = id_priv->handle;
-	cmd->addr_size = addrlen;
-	cmd->reserved = 0;
-	memcpy(&cmd->addr, addr, addrlen);
+	cmd.id = id_priv->handle;
+	cmd.addr_size = addrlen;
+	memcpy(&cmd.addr, addr, addrlen);
 
-	ret = write(id->channel->fd, msg, size);
-	if (ret != size)
+	ret = write(id->channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd)
 		return (ret >= 0) ? ERR(ENODATA) : -1;
 
 	return ucma_query_addr(id);
@@ -760,10 +722,9 @@ static int rdma_bind_addr2(struct rdma_cm_id *id, struct sockaddr *addr,
 
 int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
 {
-	struct ucma_abi_bind_ip *cmd;
+	struct ucma_abi_bind_ip cmd;
 	struct cma_id_private *id_priv;
-	void *msg;
-	int ret, size, addrlen;
+	int ret, addrlen;
 	
 	addrlen = ucma_addrlen(addr);
 	if (!addrlen)
@@ -772,13 +733,13 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
 	if (af_ib_support)
 		return rdma_bind_addr2(id, addr, addrlen);
 
-	CMA_CREATE_MSG_CMD(msg, cmd, UCMA_CMD_BIND_IP, size);
+	CMA_INIT_CMD(&cmd, sizeof cmd, BIND_IP);
 	id_priv = container_of(id, struct cma_id_private, id);
-	cmd->id = id_priv->handle;
-	memcpy(&cmd->addr, addr, addrlen);
+	cmd.id = id_priv->handle;
+	memcpy(&cmd.addr, addr, addrlen);
 
-	ret = write(id->channel->fd, msg, size);
-	if (ret != size)
+	ret = write(id->channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd)
 		return (ret >= 0) ? ERR(ENODATA) : -1;
 
 	return ucma_query_route(id);
@@ -809,23 +770,21 @@ static int rdma_resolve_addr2(struct rdma_cm_id *id, struct sockaddr *src_addr,
 			      socklen_t src_len, struct sockaddr *dst_addr,
 			      socklen_t dst_len, int timeout_ms)
 {
-	struct ucma_abi_resolve_addr *cmd;
+	struct ucma_abi_resolve_addr cmd;
 	struct cma_id_private *id_priv;
-	void *msg;
-	int ret, size;
+	int ret;
 	
-	CMA_CREATE_MSG_CMD(msg, cmd, UCMA_CMD_RESOLVE_ADDR, size);
+	CMA_INIT_CMD(&cmd, sizeof cmd, RESOLVE_ADDR);
 	id_priv = container_of(id, struct cma_id_private, id);
-	cmd->id = id_priv->handle;
-	if ((cmd->src_size = src_len))
-		memcpy(&cmd->src_addr, src_addr, src_len);
-	memcpy(&cmd->dst_addr, dst_addr, dst_len);
-	cmd->dst_size = dst_len;
-	cmd->timeout_ms = timeout_ms;
-	cmd->reserved = 0;
-
-	ret = write(id->channel->fd, msg, size);
-	if (ret != size)
+	cmd.id = id_priv->handle;
+	if ((cmd.src_size = src_len))
+		memcpy(&cmd.src_addr, src_addr, src_len);
+	memcpy(&cmd.dst_addr, dst_addr, dst_len);
+	cmd.dst_size = dst_len;
+	cmd.timeout_ms = timeout_ms;
+
+	ret = write(id->channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd)
 		return (ret >= 0) ? ERR(ENODATA) : -1;
 
 	memcpy(&id->route.addr.dst_addr, dst_addr, dst_len);
@@ -835,10 +794,9 @@ static int rdma_resolve_addr2(struct rdma_cm_id *id, struct sockaddr *src_addr,
 int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
 		      struct sockaddr *dst_addr, int timeout_ms)
 {
-	struct ucma_abi_resolve_ip *cmd;
+	struct ucma_abi_resolve_ip cmd;
 	struct cma_id_private *id_priv;
-	void *msg;
-	int ret, size, dst_len, src_len;
+	int ret, dst_len, src_len;
 	
 	dst_len = ucma_addrlen(dst_addr);
 	if (!dst_len)
@@ -849,16 +807,16 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
 		return rdma_resolve_addr2(id, src_addr, src_len, dst_addr,
 					  dst_len, timeout_ms);
 
-	CMA_CREATE_MSG_CMD(msg, cmd, UCMA_CMD_RESOLVE_IP, size);
+	CMA_INIT_CMD(&cmd, sizeof cmd, RESOLVE_IP);
 	id_priv = container_of(id, struct cma_id_private, id);
-	cmd->id = id_priv->handle;
+	cmd.id = id_priv->handle;
 	if (src_addr)
-		memcpy(&cmd->src_addr, src_addr, src_len);
-	memcpy(&cmd->dst_addr, dst_addr, dst_len);
-	cmd->timeout_ms = timeout_ms;
+		memcpy(&cmd.src_addr, src_addr, src_len);
+	memcpy(&cmd.dst_addr, dst_addr, dst_len);
+	cmd.timeout_ms = timeout_ms;
 
-	ret = write(id->channel->fd, msg, size);
-	if (ret != size)
+	ret = write(id->channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd)
 		return (ret >= 0) ? ERR(ENODATA) : -1;
 
 	memcpy(&id->route.addr.dst_addr, dst_addr, dst_len);
@@ -890,10 +848,9 @@ static int ucma_set_ib_route(struct rdma_cm_id *id)
 
 int rdma_resolve_route(struct rdma_cm_id *id, int timeout_ms)
 {
-	struct ucma_abi_resolve_route *cmd;
+	struct ucma_abi_resolve_route cmd;
 	struct cma_id_private *id_priv;
-	void *msg;
-	int ret, size;
+	int ret;
 
 	id_priv = container_of(id, struct cma_id_private, id);
 	if (id->verbs->device->transport_type == IBV_TRANSPORT_IB) {
@@ -902,45 +859,44 @@ int rdma_resolve_route(struct rdma_cm_id *id, int timeout_ms)
 			goto out;
 	}
 
-	CMA_CREATE_MSG_CMD(msg, cmd, UCMA_CMD_RESOLVE_ROUTE, size);
-	cmd->id = id_priv->handle;
-	cmd->timeout_ms = timeout_ms;
+	CMA_INIT_CMD(&cmd, sizeof cmd, RESOLVE_ROUTE);
+	cmd.id = id_priv->handle;
+	cmd.timeout_ms = timeout_ms;
 
-	ret = write(id->channel->fd, msg, size);
-	if (ret != size)
+	ret = write(id->channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd)
 		return (ret >= 0) ? ERR(ENODATA) : -1;
 
 out:
 	return ucma_complete(id_priv);
 }
 
-static int ucma_is_ud_ps(enum rdma_port_space ps)
+static int ucma_is_ud_qp(enum ibv_qp_type qp_type)
 {
-	return (ps == RDMA_PS_UDP || ps == RDMA_PS_IPOIB);
+	return (qp_type == IBV_QPT_UD);
 }
 
 static int rdma_init_qp_attr(struct rdma_cm_id *id, struct ibv_qp_attr *qp_attr,
 			     int *qp_attr_mask)
 {
-	struct ucma_abi_init_qp_attr *cmd;
-	struct ibv_kern_qp_attr *resp;
+	struct ucma_abi_init_qp_attr cmd;
+	struct ibv_kern_qp_attr resp;
 	struct cma_id_private *id_priv;
-	void *msg;
-	int ret, size;
+	int ret;
 	
-	CMA_CREATE_MSG_CMD_RESP(msg, cmd, resp, UCMA_CMD_INIT_QP_ATTR, size);
+	CMA_INIT_CMD_RESP(&cmd, sizeof cmd, INIT_QP_ATTR, &resp, sizeof resp);
 	id_priv = container_of(id, struct cma_id_private, id);
-	cmd->id = id_priv->handle;
-	cmd->qp_state = qp_attr->qp_state;
+	cmd.id = id_priv->handle;
+	cmd.qp_state = qp_attr->qp_state;
 
-	ret = write(id->channel->fd, msg, size);
-	if (ret != size)
+	ret = write(id->channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd)
 		return (ret >= 0) ? ERR(ENODATA) : -1;
 
-	VALGRIND_MAKE_MEM_DEFINED(resp, sizeof *resp);
+	VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp);
 
-	ibv_copy_qp_attr_from_kern(qp_attr, resp);
-	*qp_attr_mask = resp->qp_attr_mask;
+	ibv_copy_qp_attr_from_kern(qp_attr, &resp);
+	*qp_attr_mask = resp.qp_attr_mask;
 	return 0;
 }
 
@@ -1135,32 +1091,28 @@ static void ucma_destroy_cqs(struct rdma_cm_id *id)
 		ibv_destroy_comp_channel(id->send_cq_channel);
 }
 
-static int ucma_create_cqs(struct rdma_cm_id *id, struct ibv_qp_init_attr *attr)
+static int ucma_create_cqs(struct rdma_cm_id *id, uint32_t send_size, uint32_t recv_size)
 {
-	if (!attr->recv_cq) {
+	if (recv_size) {
 		id->recv_cq_channel = ibv_create_comp_channel(id->verbs);
 		if (!id->recv_cq_channel)
 			goto err;
 
-		id->recv_cq = ibv_create_cq(id->verbs, attr->cap.max_recv_wr,
+		id->recv_cq = ibv_create_cq(id->verbs, recv_size,
 					    id, id->recv_cq_channel, 0);
 		if (!id->recv_cq)
 			goto err;
-
-		attr->recv_cq = id->recv_cq;
 	}
 
-	if (!attr->send_cq) {
+	if (send_size) {
 		id->send_cq_channel = ibv_create_comp_channel(id->verbs);
 		if (!id->send_cq_channel)
 			goto err;
 
-		id->send_cq = ibv_create_cq(id->verbs, attr->cap.max_send_wr,
+		id->send_cq = ibv_create_cq(id->verbs, send_size,
 					    id, id->send_cq_channel, 0);
 		if (!id->send_cq)
 			goto err;
-
-		attr->send_cq = id->send_cq;
 	}
 
 	return 0;
@@ -1169,6 +1121,53 @@ err:
 	return ERR(ENOMEM);
 }
 
+int rdma_create_srq(struct rdma_cm_id *id, struct ibv_pd *pd,
+		    struct ibv_srq_init_attr *attr)
+{
+	struct cma_id_private *id_priv;
+	struct ibv_srq *srq;
+	int ret;
+
+	id_priv = container_of(id, struct cma_id_private, id);
+	if (!pd)
+		pd = id->pd;
+
+#ifdef IBV_XRC_OPS
+	if (attr->srq_type == IBV_SRQT_XRC) {
+		if (!attr->ext.xrc.cq) {
+			ret = ucma_create_cqs(id, 0, attr->attr.max_wr);
+			if (ret)
+				return ret;
+
+			attr->ext.xrc.cq = id->recv_cq;
+		}
+	}
+
+	srq = ibv_create_xsrq(pd, attr);
+#else
+	srq = ibv_create_srq(pd, attr);
+#endif
+	if (!srq) {
+		ret = -1;
+		goto err;
+	}
+
+	id->pd = pd;
+	id->srq = srq;
+	return 0;
+err:
+	ucma_destroy_cqs(id);
+	return ret;
+}
+
+void rdma_destroy_srq(struct rdma_cm_id *id)
+{
+	ibv_destroy_srq(id->srq);
+	if (!id->qp)
+		ucma_destroy_cqs(id);
+	id->srq = NULL;
+}
+
 int rdma_create_qp(struct rdma_cm_id *id, struct ibv_pd *pd,
 		   struct ibv_qp_init_attr *qp_init_attr)
 {
@@ -1176,29 +1175,38 @@ int rdma_create_qp(struct rdma_cm_id *id, struct ibv_pd *pd,
 	struct ibv_qp *qp;
 	int ret;
 
+	if (id->qp)
+		return ERR(EINVAL);
+
 	id_priv = container_of(id, struct cma_id_private, id);
 	if (!pd)
-		pd = id_priv->cma_dev->pd;
+		pd = id->pd;
 	else if (id->verbs != pd->context)
 		return ERR(EINVAL);
 
-	ret = ucma_create_cqs(id, qp_init_attr);
+	ret = ucma_create_cqs(id, qp_init_attr->send_cq ? 0 : qp_init_attr->cap.max_send_wr,
+			      qp_init_attr->recv_cq ? 0 : qp_init_attr->cap.max_recv_wr);
 	if (ret)
 		return ret;
 
+	if (!qp_init_attr->send_cq)
+		qp_init_attr->send_cq = id->send_cq;
+	if (!qp_init_attr->recv_cq)
+		qp_init_attr->recv_cq = id->recv_cq;
 	qp = ibv_create_qp(pd, qp_init_attr);
 	if (!qp) {
 		ret = ERR(ENOMEM);
 		goto err1;
 	}
 
-	if (ucma_is_ud_ps(id->ps))
+	if (ucma_is_ud_qp(id->qp_type))
 		ret = ucma_init_ud_qp(id_priv, qp);
 	else
 		ret = ucma_init_conn_qp(id_priv, qp);
 	if (ret)
 		goto err2;
 
+	id->pd = pd;
 	id->qp = qp;
 	return 0;
 err2:
@@ -1274,10 +1282,9 @@ static void ucma_copy_conn_param_to_kern(struct cma_id_private *id_priv,
 
 int rdma_connect(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
 {
-	struct ucma_abi_connect *cmd;
+	struct ucma_abi_connect cmd;
 	struct cma_id_private *id_priv;
-	void *msg;
-	int ret, size;
+	int ret;
 	
 	id_priv = container_of(id, struct cma_id_private, id);
 	ret = ucma_valid_param(id_priv, conn_param);
@@ -1293,19 +1300,23 @@ int rdma_connect(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
 	else
 		id_priv->responder_resources = id_priv->cma_dev->max_responder_resources;
 
-	CMA_CREATE_MSG_CMD(msg, cmd, UCMA_CMD_CONNECT, size);
-	cmd->id = id_priv->handle;
-	if (id->qp)
-		ucma_copy_conn_param_to_kern(id_priv, &cmd->conn_param,
+	CMA_INIT_CMD(&cmd, sizeof cmd, CONNECT);
+	cmd.id = id_priv->handle;
+	if (id->qp) {
+		ucma_copy_conn_param_to_kern(id_priv, &cmd.conn_param,
 					     conn_param, id->qp->qp_num,
 					     (id->qp->srq != NULL));
-	else
-		ucma_copy_conn_param_to_kern(id_priv, &cmd->conn_param,
+	} else if (conn_param) {
+		ucma_copy_conn_param_to_kern(id_priv, &cmd.conn_param,
 					     conn_param, conn_param->qp_num,
 					     conn_param->srq);
+	} else {
+		ucma_copy_conn_param_to_kern(id_priv, &cmd.conn_param,
+					     conn_param, 0, 0);
+	}
 
-	ret = write(id->channel->fd, msg, size);
-	if (ret != size)
+	ret = write(id->channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd)
 		return (ret >= 0) ? ERR(ENODATA) : -1;
 
 	if (id_priv->connect) {
@@ -1318,18 +1329,17 @@ int rdma_connect(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
 
 int rdma_listen(struct rdma_cm_id *id, int backlog)
 {
-	struct ucma_abi_listen *cmd;
+	struct ucma_abi_listen cmd;
 	struct cma_id_private *id_priv;
-	void *msg;
-	int ret, size;
+	int ret;
 	
-	CMA_CREATE_MSG_CMD(msg, cmd, UCMA_CMD_LISTEN, size);
+	CMA_INIT_CMD(&cmd, sizeof cmd, LISTEN);
 	id_priv = container_of(id, struct cma_id_private, id);
-	cmd->id = id_priv->handle;
-	cmd->backlog = backlog;
+	cmd.id = id_priv->handle;
+	cmd.backlog = backlog;
 
-	ret = write(id->channel->fd, msg, size);
-	if (ret != size)
+	ret = write(id->channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd)
 		return (ret >= 0) ? ERR(ENODATA) : -1;
 
 	if (af_ib_support)
@@ -1371,7 +1381,7 @@ int rdma_get_request(struct rdma_cm_id *listen, struct rdma_cm_id **id)
 		struct ibv_qp_init_attr attr;
 
 		attr = *id_priv->qp_init_attr;
-		ret = rdma_create_qp(event->id, id_priv->pd, &attr);
+		ret = rdma_create_qp(event->id, listen->pd, &attr);
 		if (ret)
 			goto err;
 	}
@@ -1387,10 +1397,9 @@ err:
 
 int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
 {
-	struct ucma_abi_accept *cmd;
+	struct ucma_abi_accept cmd;
 	struct cma_id_private *id_priv;
-	void *msg;
-	int ret, size;
+	int ret;
 
 	id_priv = container_of(id, struct cma_id_private, id);
 	ret = ucma_valid_param(id_priv, conn_param);
@@ -1410,7 +1419,7 @@ int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
 		id_priv->responder_resources = conn_param->responder_resources;
 	}
 
-	if (!ucma_is_ud_ps(id->ps)) {
+	if (!ucma_is_ud_qp(id->qp_type)) {
 		ret = ucma_modify_qp_rtr(id, id_priv->responder_resources);
 		if (ret)
 			return ret;
@@ -1420,47 +1429,48 @@ int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
 			return ret;
 	}
 
-	CMA_CREATE_MSG_CMD(msg, cmd, UCMA_CMD_ACCEPT, size);
-	cmd->id = id_priv->handle;
-	cmd->uid = (uintptr_t) id_priv;
+	CMA_INIT_CMD(&cmd, sizeof cmd, ACCEPT);
+	cmd.id = id_priv->handle;
+	cmd.uid = (uintptr_t) id_priv;
 	if (id->qp)
-		ucma_copy_conn_param_to_kern(id_priv, &cmd->conn_param,
+		ucma_copy_conn_param_to_kern(id_priv, &cmd.conn_param,
 					     conn_param, id->qp->qp_num,
 					     (id->qp->srq != NULL));
 	else
-		ucma_copy_conn_param_to_kern(id_priv, &cmd->conn_param,
+		ucma_copy_conn_param_to_kern(id_priv, &cmd.conn_param,
 					     conn_param, conn_param->qp_num,
 					     conn_param->srq);
 
-	ret = write(id->channel->fd, msg, size);
-	if (ret != size) {
+	ret = write(id->channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd) {
 		ucma_modify_qp_err(id);
 		return (ret >= 0) ? ERR(ENODATA) : -1;
 	}
 
+	if (ucma_is_ud_qp(id->qp_type))
+		return 0;
+
 	return ucma_complete(id_priv);
 }
 
 int rdma_reject(struct rdma_cm_id *id, const void *private_data,
 		uint8_t private_data_len)
 {
-	struct ucma_abi_reject *cmd;
+	struct ucma_abi_reject cmd;
 	struct cma_id_private *id_priv;
-	void *msg;
-	int ret, size;
+	int ret;
 	
-	CMA_CREATE_MSG_CMD(msg, cmd, UCMA_CMD_REJECT, size);
+	CMA_INIT_CMD(&cmd, sizeof cmd, REJECT);
 
 	id_priv = container_of(id, struct cma_id_private, id);
-	cmd->id = id_priv->handle;
+	cmd.id = id_priv->handle;
 	if (private_data && private_data_len) {
-		memcpy(cmd->private_data, private_data, private_data_len);
-		cmd->private_data_len = private_data_len;
-	} else
-		cmd->private_data_len = 0;
+		memcpy(cmd.private_data, private_data, private_data_len);
+		cmd.private_data_len = private_data_len;
+	}
 
-	ret = write(id->channel->fd, msg, size);
-	if (ret != size)
+	ret = write(id->channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd)
 		return (ret >= 0) ? ERR(ENODATA) : -1;
 
 	return 0;
@@ -1468,18 +1478,17 @@ int rdma_reject(struct rdma_cm_id *id, const void *private_data,
 
 int rdma_notify(struct rdma_cm_id *id, enum ibv_event_type event)
 {
-	struct ucma_abi_notify *cmd;
+	struct ucma_abi_notify cmd;
 	struct cma_id_private *id_priv;
-	void *msg;
-	int ret, size;
+	int ret;
 	
-	CMA_CREATE_MSG_CMD(msg, cmd, UCMA_CMD_NOTIFY, size);
+	CMA_INIT_CMD(&cmd, sizeof cmd, NOTIFY);
 
 	id_priv = container_of(id, struct cma_id_private, id);
-	cmd->id = id_priv->handle;
-	cmd->event = event;
-	ret = write(id->channel->fd, msg, size);
-	if (ret != size)
+	cmd.id = id_priv->handle;
+	cmd.event = event;
+	ret = write(id->channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd)
 		return (ret >= 0) ? ERR(ENODATA) : -1;
 
 	return 0;
@@ -1487,10 +1496,9 @@ int rdma_notify(struct rdma_cm_id *id, enum ibv_event_type event)
 
 int rdma_disconnect(struct rdma_cm_id *id)
 {
-	struct ucma_abi_disconnect *cmd;
+	struct ucma_abi_disconnect cmd;
 	struct cma_id_private *id_priv;
-	void *msg;
-	int ret, size;
+	int ret;
 
 	switch (id->verbs->device->transport_type) {
 	case IBV_TRANSPORT_IB:
@@ -1505,12 +1513,12 @@ int rdma_disconnect(struct rdma_cm_id *id)
 	if (ret)
 		return ret;
 
-	CMA_CREATE_MSG_CMD(msg, cmd, UCMA_CMD_DISCONNECT, size);
+	CMA_INIT_CMD(&cmd, sizeof cmd, DISCONNECT);
 	id_priv = container_of(id, struct cma_id_private, id);
-	cmd->id = id_priv->handle;
+	cmd.id = id_priv->handle;
 
-	ret = write(id->channel->fd, msg, size);
-	if (ret != size)
+	ret = write(id->channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd)
 		return (ret >= 0) ? ERR(ENODATA) : -1;
 
 	return ucma_complete(id_priv);
@@ -1519,11 +1527,10 @@ int rdma_disconnect(struct rdma_cm_id *id)
 static int rdma_join_multicast2(struct rdma_cm_id *id, struct sockaddr *addr,
 				socklen_t addrlen, void *context)
 {
-	struct ucma_abi_create_id_resp *resp;
+	struct ucma_abi_create_id_resp resp;
 	struct cma_id_private *id_priv;
 	struct cma_multicast *mc, **pos;
-	void *msg;
-	int ret, size;
+	int ret;
 	
 	id_priv = container_of(id, struct cma_id_private, id);
 	mc = calloc(1, sizeof *mc);
@@ -1544,32 +1551,38 @@ static int rdma_join_multicast2(struct rdma_cm_id *id, struct sockaddr *addr,
 	pthread_mutex_unlock(&id_priv->mut);
 
 	if (af_ib_support) {
-		struct ucma_abi_join_mcast *cmd;
-
-		CMA_CREATE_MSG_CMD_RESP(msg, cmd, resp, UCMA_CMD_JOIN_MCAST, size);
-		cmd->id = id_priv->handle;
-		memcpy(&cmd->addr, addr, addrlen);
-		cmd->addr_size = addrlen;
-		cmd->uid = (uintptr_t) mc;
-		cmd->reserved = 0;
+		struct ucma_abi_join_mcast cmd;
+
+		CMA_INIT_CMD_RESP(&cmd, sizeof cmd, JOIN_MCAST, &resp, sizeof resp);
+		cmd.id = id_priv->handle;
+		memcpy(&cmd.addr, addr, addrlen);
+		cmd.addr_size = addrlen;
+		cmd.uid = (uintptr_t) mc;
+		cmd.reserved = 0;
+
+		ret = write(id->channel->fd, &cmd, sizeof cmd);
+		if (ret != sizeof cmd) {
+			ret = (ret >= 0) ? ERR(ENODATA) : -1;
+			goto err2;
+		}
 	} else {
-		struct ucma_abi_join_ip_mcast *cmd;
+		struct ucma_abi_join_ip_mcast cmd;
 
-		CMA_CREATE_MSG_CMD_RESP(msg, cmd, resp, UCMA_CMD_JOIN_IP_MCAST, size);
-		cmd->id = id_priv->handle;
-		memcpy(&cmd->addr, addr, addrlen);
-		cmd->uid = (uintptr_t) mc;
-	}
+		CMA_INIT_CMD_RESP(&cmd, sizeof cmd, JOIN_IP_MCAST, &resp, sizeof resp);
+		cmd.id = id_priv->handle;
+		memcpy(&cmd.addr, addr, addrlen);
+		cmd.uid = (uintptr_t) mc;
 
-	ret = write(id->channel->fd, msg, size);
-	if (ret != size) {
-		ret = (ret >= 0) ? ERR(ENODATA) : -1;
-		goto err2;
+		ret = write(id->channel->fd, &cmd, sizeof cmd);
+		if (ret != sizeof cmd) {
+			ret = (ret >= 0) ? ERR(ENODATA) : -1;
+			goto err2;
+		}
 	}
 
-	VALGRIND_MAKE_MEM_DEFINED(resp, sizeof *resp);
+	VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp);
 
-	mc->handle = resp->id;
+	mc->handle = resp.id;
 	return ucma_complete(id_priv);
 
 err2:
@@ -1597,12 +1610,11 @@ int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr,
 
 int rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr)
 {
-	struct ucma_abi_destroy_id *cmd;
-	struct ucma_abi_destroy_id_resp *resp;
+	struct ucma_abi_destroy_id cmd;
+	struct ucma_abi_destroy_id_resp resp;
 	struct cma_id_private *id_priv;
 	struct cma_multicast *mc, **pos;
-	void *msg;
-	int ret, size, addrlen;
+	int ret, addrlen;
 	
 	addrlen = ucma_addrlen(addr);
 	if (!addrlen)
@@ -1624,19 +1636,19 @@ int rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr)
 	if (id->qp)
 		ibv_detach_mcast(id->qp, &mc->mgid, mc->mlid);
 	
-	CMA_CREATE_MSG_CMD_RESP(msg, cmd, resp, UCMA_CMD_LEAVE_MCAST, size);
-	cmd->id = mc->handle;
+	CMA_INIT_CMD_RESP(&cmd, sizeof cmd, LEAVE_MCAST, &resp, sizeof resp);
+	cmd.id = mc->handle;
 
-	ret = write(id->channel->fd, msg, size);
-	if (ret != size) {
+	ret = write(id->channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd) {
 		ret = (ret >= 0) ? ERR(ENODATA) : -1;
 		goto free;
 	}
 
-	VALGRIND_MAKE_MEM_DEFINED(resp, sizeof *resp);
+	VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp);
 
 	pthread_mutex_lock(&id_priv->mut);
-	while (mc->events_completed < resp->events_reported)
+	while (mc->events_completed < resp.events_reported)
 		pthread_cond_wait(&mc->cond, &id_priv->mut);
 	pthread_mutex_unlock(&id_priv->mut);
 
@@ -1739,7 +1751,8 @@ static int ucma_process_conn_req(struct cma_event *evt,
 	int ret;
 
 	id_priv = ucma_alloc_id(evt->id_priv->id.channel,
-				evt->id_priv->id.context, evt->id_priv->id.ps);
+				evt->id_priv->id.context, evt->id_priv->id.ps,
+				evt->id_priv->id.qp_type);
 	if (!id_priv) {
 		ucma_destroy_kern_id(evt->id_priv->id.channel->fd, handle);
 		ret = ERR(ENOMEM);
@@ -1773,9 +1786,8 @@ err1:
 
 static int ucma_process_conn_resp(struct cma_id_private *id_priv)
 {
-	struct ucma_abi_accept *cmd;
-	void *msg;
-	int ret, size;
+	struct ucma_abi_accept cmd;
+	int ret;
 
 	ret = ucma_modify_qp_rtr(&id_priv->id, RDMA_MAX_RESP_RES);
 	if (ret)
@@ -1785,11 +1797,11 @@ static int ucma_process_conn_resp(struct cma_id_private *id_priv)
 	if (ret)
 		goto err;
 
-	CMA_CREATE_MSG_CMD(msg, cmd, UCMA_CMD_ACCEPT, size);
-	cmd->id = id_priv->handle;
+	CMA_INIT_CMD(&cmd, sizeof cmd, ACCEPT);
+	cmd.id = id_priv->handle;
 
-	ret = write(id_priv->id.channel->fd, msg, size);
-	if (ret != size) {
+	ret = write(id_priv->id.channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd) {
 		ret = (ret >= 0) ? ERR(ENODATA) : -1;
 		goto err;
 	}
@@ -1853,11 +1865,10 @@ static void ucma_copy_ud_event(struct cma_event *event,
 int rdma_get_cm_event(struct rdma_event_channel *channel,
 		      struct rdma_cm_event **event)
 {
-	struct ucma_abi_event_resp *resp;
-	struct ucma_abi_get_event *cmd;
+	struct ucma_abi_event_resp resp;
+	struct ucma_abi_get_event cmd;
 	struct cma_event *evt;
-	void *msg;
-	int ret, size;
+	int ret;
 
 	ret = ucma_init();
 	if (ret)
@@ -1872,21 +1883,21 @@ int rdma_get_cm_event(struct rdma_event_channel *channel,
 
 retry:
 	memset(evt, 0, sizeof *evt);
-	CMA_CREATE_MSG_CMD_RESP(msg, cmd, resp, UCMA_CMD_GET_EVENT, size);
-	ret = write(channel->fd, msg, size);
-	if (ret != size) {
+	CMA_INIT_CMD_RESP(&cmd, sizeof cmd, GET_EVENT, &resp, sizeof resp);
+	ret = write(channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd) {
 		free(evt);
 		return (ret >= 0) ? ERR(ENODATA) : -1;
 	}
 	
-	VALGRIND_MAKE_MEM_DEFINED(resp, sizeof *resp);
+	VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp);
 
-	evt->event.event = resp->event;
-	evt->id_priv = (void *) (uintptr_t) resp->uid;
+	evt->event.event = resp.event;
+	evt->id_priv = (void *) (uintptr_t) resp.uid;
 	evt->event.id = &evt->id_priv->id;
-	evt->event.status = resp->status;
+	evt->event.status = resp.status;
 
-	switch (resp->event) {
+	switch (resp.event) {
 	case RDMA_CM_EVENT_ADDR_RESOLVED:
 		ucma_process_addr_resolved(evt);
 		break;
@@ -1894,18 +1905,18 @@ retry:
 		ucma_process_route_resolved(evt);
 		break;
 	case RDMA_CM_EVENT_CONNECT_REQUEST:
-		evt->id_priv = (void *) (uintptr_t) resp->uid;
-		if (ucma_is_ud_ps(evt->id_priv->id.ps))
-			ucma_copy_ud_event(evt, &resp->param.ud);
+		evt->id_priv = (void *) (uintptr_t) resp.uid;
+		if (ucma_is_ud_qp(evt->id_priv->id.qp_type))
+			ucma_copy_ud_event(evt, &resp.param.ud);
 		else
-			ucma_copy_conn_event(evt, &resp->param.conn);
+			ucma_copy_conn_event(evt, &resp.param.conn);
 
-		ret = ucma_process_conn_req(evt, resp->id);
+		ret = ucma_process_conn_req(evt, resp.id);
 		if (ret)
 			goto retry;
 		break;
 	case RDMA_CM_EVENT_CONNECT_RESPONSE:
-		ucma_copy_conn_event(evt, &resp->param.conn);
+		ucma_copy_conn_event(evt, &resp.param.conn);
 		evt->event.status = ucma_process_conn_resp(evt->id_priv);
 		if (!evt->event.status)
 			evt->event.event = RDMA_CM_EVENT_ESTABLISHED;
@@ -1915,19 +1926,19 @@ retry:
 		}
 		break;
 	case RDMA_CM_EVENT_ESTABLISHED:
-		if (ucma_is_ud_ps(evt->id_priv->id.ps)) {
-			ucma_copy_ud_event(evt, &resp->param.ud);
+		if (ucma_is_ud_qp(evt->id_priv->id.qp_type)) {
+			ucma_copy_ud_event(evt, &resp.param.ud);
 			break;
 		}
 
-		ucma_copy_conn_event(evt, &resp->param.conn);
+		ucma_copy_conn_event(evt, &resp.param.conn);
 		break;
 	case RDMA_CM_EVENT_REJECTED:
 		if (evt->id_priv->connect_error) {
 			ucma_complete_event(evt->id_priv);
 			goto retry;
 		}
-		ucma_copy_conn_event(evt, &resp->param.conn);
+		ucma_copy_conn_event(evt, &resp.param.conn);
 		ucma_modify_qp_err(evt->event.id);
 		break;
 	case RDMA_CM_EVENT_DISCONNECTED:
@@ -1935,32 +1946,32 @@ retry:
 			ucma_complete_event(evt->id_priv);
 			goto retry;
 		}
-		ucma_copy_conn_event(evt, &resp->param.conn);
+		ucma_copy_conn_event(evt, &resp.param.conn);
 		break;
 	case RDMA_CM_EVENT_MULTICAST_JOIN:
-		evt->mc = (void *) (uintptr_t) resp->uid;
+		evt->mc = (void *) (uintptr_t) resp.uid;
 		evt->id_priv = evt->mc->id_priv;
 		evt->event.id = &evt->id_priv->id;
-		ucma_copy_ud_event(evt, &resp->param.ud);
+		ucma_copy_ud_event(evt, &resp.param.ud);
 		evt->event.param.ud.private_data = evt->mc->context;
 		evt->event.status = ucma_process_join(evt);
 		if (evt->event.status)
 			evt->event.event = RDMA_CM_EVENT_MULTICAST_ERROR;
 		break;
 	case RDMA_CM_EVENT_MULTICAST_ERROR:
-		evt->mc = (void *) (uintptr_t) resp->uid;
+		evt->mc = (void *) (uintptr_t) resp.uid;
 		evt->id_priv = evt->mc->id_priv;
 		evt->event.id = &evt->id_priv->id;
 		evt->event.param.ud.private_data = evt->mc->context;
 		break;
 	default:
-		evt->id_priv = (void *) (uintptr_t) resp->uid;
+		evt->id_priv = (void *) (uintptr_t) resp.uid;
 		evt->event.id = &evt->id_priv->id;
-		evt->event.status = resp->status;
-		if (ucma_is_ud_ps(evt->id_priv->id.ps))
-			ucma_copy_ud_event(evt, &resp->param.ud);
+		evt->event.status = resp.status;
+		if (ucma_is_ud_qp(evt->id_priv->id.qp_type))
+			ucma_copy_ud_event(evt, &resp.param.ud);
 		else
-			ucma_copy_conn_event(evt, &resp->param.conn);
+			ucma_copy_conn_event(evt, &resp.param.conn);
 		break;
 	}
 
@@ -2011,21 +2022,20 @@ const char *rdma_event_str(enum rdma_cm_event_type event)
 int rdma_set_option(struct rdma_cm_id *id, int level, int optname,
 		    void *optval, size_t optlen)
 {
-	struct ucma_abi_set_option *cmd;
+	struct ucma_abi_set_option cmd;
 	struct cma_id_private *id_priv;
-	void *msg;
-	int ret, size;
+	int ret;
 	
-	CMA_CREATE_MSG_CMD(msg, cmd, UCMA_CMD_SET_OPTION, size);
+	CMA_INIT_CMD(&cmd, sizeof cmd, SET_OPTION);
 	id_priv = container_of(id, struct cma_id_private, id);
-	cmd->id = id_priv->handle;
-	cmd->optval = (uintptr_t) optval;
-	cmd->level = level;
-	cmd->optname = optname;
-	cmd->optlen = optlen;
-
-	ret = write(id->channel->fd, msg, size);
-	if (ret != size)
+	cmd.id = id_priv->handle;
+	cmd.optval = (uintptr_t) optval;
+	cmd.level = level;
+	cmd.optname = optname;
+	cmd.optlen = optlen;
+
+	ret = write(id->channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd)
 		return (ret >= 0) ? ERR(ENODATA) : -1;
 
 	return 0;
@@ -2033,11 +2043,10 @@ int rdma_set_option(struct rdma_cm_id *id, int level, int optname,
 
 int rdma_migrate_id(struct rdma_cm_id *id, struct rdma_event_channel *channel)
 {
-	struct ucma_abi_migrate_resp *resp;
-	struct ucma_abi_migrate_id *cmd;
+	struct ucma_abi_migrate_resp resp;
+	struct ucma_abi_migrate_id cmd;
 	struct cma_id_private *id_priv;
-	void *msg;
-	int ret, size, sync;
+	int ret, sync;
 
 	id_priv = container_of(id, struct cma_id_private, id);
 	if (id_priv->sync && !channel)
@@ -2049,15 +2058,18 @@ int rdma_migrate_id(struct rdma_cm_id *id, struct rdma_event_channel *channel)
 			return -1;
 	}
 
-	CMA_CREATE_MSG_CMD_RESP(msg, cmd, resp, UCMA_CMD_MIGRATE_ID, size);
-	cmd->id = id_priv->handle;
-	cmd->fd = id->channel->fd;
+	CMA_INIT_CMD_RESP(&cmd, sizeof cmd, MIGRATE_ID, &resp, sizeof resp);
+	cmd.id = id_priv->handle;
+	cmd.fd = id->channel->fd;
 
-	ret = write(channel->fd, msg, size);
-	if (ret != size)
+	ret = write(channel->fd, &cmd, sizeof cmd);
+	if (ret != sizeof cmd) {
+		if (sync)
+			rdma_destroy_event_channel(channel);
 		return (ret >= 0) ? ERR(ENODATA) : -1;
+	}
 
-	VALGRIND_MAKE_MEM_DEFINED(resp, sizeof *resp);
+	VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp);
 
 	if (id_priv->sync) {
 		if (id->event) {
@@ -2077,7 +2089,7 @@ int rdma_migrate_id(struct rdma_cm_id *id, struct rdma_event_channel *channel)
 	pthread_mutex_lock(&id_priv->mut);
 	id_priv->sync = sync;
 	id->channel = channel;
-	while (id_priv->events_completed < resp->events_reported)
+	while (id_priv->events_completed < resp.events_reported)
 		pthread_cond_wait(&id_priv->cond, &id_priv->mut);
 	pthread_mutex_unlock(&id_priv->mut);
 
@@ -2098,7 +2110,8 @@ static int ucma_passive_ep(struct rdma_cm_id *id, struct rdma_addrinfo *res,
 		return ret;
 
 	id_priv = container_of(id, struct cma_id_private, id);
-	id_priv->pd = pd;
+	if (pd)
+		id->pd = pd;
 
 	if (qp_init_attr) {
 		id_priv->qp_init_attr = malloc(sizeof *qp_init_attr);
@@ -2183,6 +2196,9 @@ void rdma_destroy_ep(struct rdma_cm_id *id)
 	if (id->qp)
 		rdma_destroy_qp(id);
 
+	if (id->srq)
+		rdma_destroy_srq(id);
+
 	id_priv = container_of(id, struct cma_id_private, id);
 	if (id_priv->qp_init_attr)
 		free(id_priv->qp_init_attr);
diff --git a/src/librdmacm.map b/src/librdmacm.map
index 19b193a..b3235ff 100644
--- a/src/librdmacm.map
+++ b/src/librdmacm.map
@@ -33,5 +33,7 @@ RDMACM_1.0 {
 		rdma_get_request;
 		rdma_create_ep;
 		rdma_destroy_ep;
+		rdma_create_srq;
+		rdma_destroy_srq;
 	local: *;
 };

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ofed/librdmacm.git



More information about the Pkg-ofed-commits mailing list