[DAPL2] synchronize with OFED DAPL git tree.
authorstansmith <stansmith@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 23 Nov 2009 18:59:00 +0000 (18:59 +0000)
committerstansmith <stansmith@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 23 Nov 2009 18:59:00 +0000 (18:59 +0000)
git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@2594 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

ulp/dapl2/ChangeLog
ulp/dapl2/configure.in
ulp/dapl2/dapl.spec.in
ulp/dapl2/dapl/common/dapl_evd_util.c
ulp/dapl2/dapl/dirs
ulp/dapl2/dapl/openib_cma/cm.c
ulp/dapl2/dapl/openib_cma/windows/openib_osd.h
ulp/dapl2/dapl/openib_ucm/cm.c
ulp/dapl2/test/dtest/windows/dtest/SOURCES
ulp/dapl2/test/dtest/windows/dtest/dtest.c

index 001549c..38ba49a 100644 (file)
@@ -1,3 +1,266 @@
+commit 9fe7506ff9ddf1ae6297cfc6a9dd4d6a57e1939e\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Fri Oct 30 12:57:22 2009 -0800\r
+\r
+    winof: Utilize WinOF version of inet_ntop() for Windows OSes which do not support inet_ntop().\r
+    \r
+    Signed-off-by: stan smith <stan.smith@intel.com>\r
+\r
+commit d56c645a2bf234e9e0cf215b112c2aa9d5e01945\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Fri Oct 30 07:17:26 2009 -0800\r
+\r
+    ucm: windows build issue with new CQ completion channel\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 2d2e7e1e185c08542ee31b0e77561a1eeb4bde6c\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Fri Oct 30 06:35:33 2009 -0800\r
+\r
+    winof: add ucm provider to windows build\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 94b2206093607214e0a9709651460692e8196e1c\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Fri Oct 30 06:32:56 2009 -0800\r
+\r
+    winof: add missing build files for ibal, scm\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 66b76d7a8035b9164b69781d7630a0c77ce1bb5a\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Wed Oct 28 09:52:50 2009 -0800\r
+\r
+    scm: connection peer resets under heavy load, incorrect event on error\r
+    \r
+    Under heavy load, we get a peer reset from the remote stack. In this\r
+    case retry the socket connection for this QP setup.\r
+    \r
+    Add debugging with PID's and socket ports to help isolate\r
+    these types of socket scaling issues.\r
+    \r
+    Report correct UD event during error, check remote_ah creation.\r
+    \r
+    Fix dapl_poll return codes for single event type only.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit f8108a9bda0200355107fdd6c43cb5885f47d648\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Wed Oct 28 09:47:37 2009 -0800\r
+\r
+    ucm: increase default reply and rtu timeout values.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 9c13d0d01c78eeb5071e802fbb53811cdb377059\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Wed Oct 28 07:48:20 2009 -0800\r
+\r
+    ucm: change some debug message levels and add check for valid UD REPLY during retries.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 1c404bb3dcc0a45e21ef3aa973d59714413beae0\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Tue Oct 27 10:37:45 2009 -0800\r
+\r
+    ucm: increase timers during subsequent retries\r
+    \r
+    check/process create_ah errors during connect phase\r
+    cleanup some debug messaging.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit cd8c48586f53e846de4fbe10994b73ba457f6406\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Mon Oct 19 10:38:36 2009 -0700\r
+\r
+    ucm, scm: address handles need destroyed when freeing Endpoints with UD QP's.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit ce19f5744c0dd9461c09d999b309e8f0e2242767\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Fri Oct 16 14:42:00 2009 -0700\r
+\r
+    openib_common: ignore pd free errors, clear pd_handle and return.\r
+    \r
+    some older adapters have some issues\r
+    with pd free so just clear handle and return\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 81f5ac17d9039e2edcd8324f7d5ed5f66fcff9f2\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Fri Oct 16 08:52:21 2009 -0700\r
+\r
+    ucm: using UD type QP's, ucm reports wrong reject event when user rejects AH resolution request.\r
+    \r
+    During rejects, both usr and ucm internal, the qp_type does not get initialized\r
+    so the check for UD type QP messages fail on active side and the wrong\r
+    event gets generated. Initialize saddr.ib information before sending reject\r
+    back to active side.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit f0214e5a7a81a68819d308cb921eb75f5246207d\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Fri Oct 16 07:57:25 2009 -0700\r
+\r
+    ucm, scm, cma: Fix CNO support on DTO type EVD's\r
+    \r
+    EVD wait_object should be used for CNO processing\r
+    and not the direct CQ event channels. Add proper\r
+    checking for DTO type EVD's with CNO at wait\r
+    and wakeup.\r
+    \r
+    UCM missing support for collective EVD's under a\r
+    CNO. Add support to create common channel for\r
+    collective EVD's during device open. Add support\r
+    in cm_thread to check this channel. Also,\r
+    during disconnect, move QP to error to properly\r
+    flush queue instead of moving to reset and init.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 960950a7d9f5437dd831bd56ca2ad0c06cb4e324\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Thu Oct 15 09:19:45 2009 -0700\r
+\r
+    ucm: fix lock init bug in ucm_cm_find\r
+    \r
+    the lock should be setup as pointer to lock\r
+    not lock structure. Cleanup lock and list\r
+    in cm_find function and cm_print function.\r
+    \r
+    Add debug aid by passing process id in\r
+    msg resv area. cleanup cr references\r
+    and change to cm for consistency.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit f86fec772f2d82eaf60228d288b295e0b7b86c59\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Wed Oct 14 10:03:47 2009 -0700\r
+\r
+    ucm: fix build problem with latest windows ucm changes\r
+    \r
+    define dapls_thread_signal as inline\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 87b6c8ba92f3063a35d49bdb49d6cd0a5100a36c\r
+Author: Sean Hefty <sean.hefty@intel.com>\r
+Date:   Wed Oct 14 09:34:22 2009 -0700\r
+\r
+    Signed-off-by: Sean Hefty <sean.hefty@intel.com>\r
+\r
+commit 9fdd8d74f2cba83e9cf513256933f5241495c1da\r
+Author: Sean Hefty <sean.hefty@intel.com>\r
+Date:   Wed Oct 14 09:34:18 2009 -0700\r
+\r
+    The HCA should not be closed until all resources have been released.\r
+    This results in a hang on windows, since closing the device frees\r
+    the event processing thread.\r
+    \r
+    Signed-off-by: Sean Hefty <sean.hefty@intel.com>\r
+\r
+commit f9833db469f2d686842bb1d52d1ea53b74fa72a8\r
+Author: Sean Hefty <sean.hefty@intel.com>\r
+Date:   Wed Oct 14 09:34:13 2009 -0700\r
+\r
+    Fix build warning when compiling on 32-bit systems.\r
+    \r
+    Signed-off-by: Sean Hefty <sean.hefty@intel.com>\r
+\r
+commit c80515bd4b1bd11a125dc17e3f7db44240ee1fff\r
+Author: Sean Hefty <sean.hefty@intel.com>\r
+Date:   Wed Oct 14 09:34:07 2009 -0700\r
+\r
+    Trying to deregister the same memory region twice leads to an\r
+    application crash on windows.\r
+    \r
+    Signed-off-by: Sean Hefty <sean.hefty@intel.com>\r
+\r
+commit 6aa2c0d901daa9cfca7e771c1df2ead074d230bd\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Wed Oct 14 07:59:23 2009 -0700\r
+\r
+    dat: reduce debug message level when parsing for location of dat.conf\r
+    \r
+    Don't output failover to default /etc/dat.conf from\r
+    sysconfdir at ERROR level. Reduce to DAT_OS_DBG_TYPE_SR.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit e4038e078747201b57203f16ba793b7fc22c12f2\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Thu Oct 8 16:23:22 2009 -0700\r
+\r
+    ucm: update ucm provider for windows environment\r
+    \r
+    add dapls_thread_signal abstraction and a new\r
+    cm_thread function specific for windows.\r
+    \r
+    Signed-off-by: Sean Hefty <sean.hefty@intel.com>\r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit d80ce42390eb57b9c4f816b4df063f90bd5699bc\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Thu Oct 8 16:02:52 2009 -0700\r
+\r
+    ucm: add timer/retry CM logic to the ucm provider\r
+    \r
+    add reply, rtu and retry count options via\r
+    environment variables. Times in msecs.\r
+    DAPL_UCM_RETRY 10\r
+    DAPL_UCM_REP_TIME 400\r
+    DAPL_UCM_RTU_TIME 200\r
+    \r
+    Add RTU_PENDING and DISC_RECV states\r
+    \r
+    Add check timer code to the cm_thread\r
+    and the option to the select abstaction\r
+    to take timeout values in msecs.\r
+    DREQ, REQ, and REPLY will all be timed\r
+    and retried.\r
+    \r
+    Split out reply code and disconnect_final\r
+    code to better facilitate retry timers.\r
+    Add checking for duplicate messages.\r
+    \r
+    Added new UD extension events for errors.\r
+    DAT_IB_UD_CONNECTION_REJECT_EVENT\r
+    DAT_IB_UD_CONNECTION_ERROR_EVENT\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 1186bfc949f4bb7278c30c2c59b7fcb6d5142638\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Fri Oct 2 14:49:52 2009 -0700\r
+\r
+    Release 2.0.23\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit a5f1220cfd96983c9c89a595d80fab7ddcb1a954\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Fri Oct 2 14:48:15 2009 -0700\r
+\r
+    cma: cannot reuse the cm_id and qp for new connection, must reallocate a new one.\r
+    \r
+    When merging common code base the dapls_ib_reinit_ep mistakely\r
+    modified QP to reset then init for all providers. Will\r
+    not work for rdma_cm (cma provider) since the cm_id cannot\r
+    be reused.  Add build check for _OPENIB_CMA_ to pull in correct\r
+    free and reallocate method for reinit_ep.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
 commit 7b07435495de0938e59be064fe8642cfd739f1ac\r
 Author: Arlin Davis <arlin.r.davis@intel.com>\r
 Date:   Fri Oct 2 13:50:12 2009 -0700\r
index e073aee..2cfc990 100644 (file)
@@ -1,11 +1,11 @@
 dnl Process this file with autoconf to produce a configure script.\r
 \r
 AC_PREREQ(2.57)\r
-AC_INIT(dapl, 2.0.23, general@lists.openfabrics.org)\r
+AC_INIT(dapl, 2.0.24, general@lists.openfabrics.org)\r
 AC_CONFIG_SRCDIR([dat/udat/udat.c])\r
 AC_CONFIG_AUX_DIR(config)\r
 AM_CONFIG_HEADER(config.h)\r
-AM_INIT_AUTOMAKE(dapl, 2.0.23)\r
+AM_INIT_AUTOMAKE(dapl, 2.0.24)\r
 \r
 AM_PROG_LIBTOOL\r
 \r
index 139a000..44ee4bd 100644 (file)
@@ -140,8 +140,11 @@ fi
 %{_mandir}/man5/*.5*\r
 \r
 %changelog\r
+* Fri Oct 30 2009 Arlin Davis <ardavis@ichips.intel.com> - 2.0.24\r
+- DAT/DAPL Version 2.0.24 Release 1, OFED 1.5 RC2 \r
+\r
 * Fri Oct 2 2009 Arlin Davis <ardavis@ichips.intel.com> - 2.0.23\r
-- DAT/DAPL Version 2.0.22 Release 1, OFED 1.5 RC1 \r
+- DAT/DAPL Version 2.0.23 Release 1, OFED 1.5 RC1 \r
 \r
 * Wed Aug 19 2009 Arlin Davis <ardavis@ichips.intel.com> - 2.0.22\r
 - DAT/DAPL Version 2.0.22 Release 1, OFED 1.5 ALPHA new UCM provider \r
index 02909e9..cc0aa17 100644 (file)
@@ -159,9 +159,11 @@ dapls_evd_internal_create(DAPL_IA * ia_ptr,
        /*
         * If we are dealing with event streams besides a CQ event stream,
         * be conservative and set producer side locking.  Otherwise, no.
+        * Note: CNO is not considered CQ event stream.
         */
        evd_ptr->evd_producer_locking_needed =
-           !(evd_flags & (DAT_EVD_DTO_FLAG | DAT_EVD_RMR_BIND_FLAG));
+           (!(evd_flags & (DAT_EVD_DTO_FLAG | DAT_EVD_RMR_BIND_FLAG)) ||
+            evd_ptr->cno_ptr);
 
        /* Before we setup any callbacks, transition state to OPEN.  */
        evd_ptr->evd_state = DAPL_EVD_STATE_OPEN;
@@ -646,8 +648,9 @@ dapli_evd_post_event(IN DAPL_EVD * evd_ptr, IN const DAT_EVENT * event_ptr)
        DAT_RETURN dat_status;
        DAPL_CNO *cno_to_trigger = NULL;
 
-       dapl_dbg_log(DAPL_DBG_TYPE_EVD, "%s: Called with event %s\n",
-                    __FUNCTION__, dapl_event_str(event_ptr->event_number));
+       dapl_dbg_log(DAPL_DBG_TYPE_EVD, "%s: %s evd %p state %d\n",
+                    __FUNCTION__, dapl_event_str(event_ptr->event_number), 
+                    evd_ptr, evd_ptr->evd_state);
 
        dat_status = dapls_rbuf_add(&evd_ptr->pending_event_queue,
                                    (void *)event_ptr);
index 936e11b..732a37b 100644 (file)
@@ -1 +1 @@
-DIRS = ibal openib_common openib_scm openib_cma openib_ucm
\ No newline at end of file
+DIRS = ibal openib_common openib_scm openib_cma openib_ucm \r
index 40634b2..e49a721 100644 (file)
-/*
- * Copyright (c) 2005 Voltaire Inc.  All rights reserved.
- * Copyright (c) 2005-2007 Intel Corporation. All rights reserved.
- * Copyright (c) 2004-2005, Mellanox Technologies, Inc. All rights reserved. 
- * Copyright (c) 2003 Topspin Corporation.  All rights reserved. 
- * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
- *
- * This Software is licensed under one of the following licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- *
- * 2) under the terms of the "The BSD License" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- *
- * Licensee has the right to choose one of the above licenses.
- *
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/**********************************************************************
- *
- * MODULE: dapl_ib_cm.c
- *
- * PURPOSE: The OFED provider - uCMA, name and route resolution
- *
- * $Id: $
- *
- **********************************************************************/
-
-#include "dapl.h"
-#include "dapl_adapter_util.h"
-#include "dapl_evd_util.h"
-#include "dapl_cr_util.h"
-#include "dapl_name_service.h"
-#include "dapl_ib_util.h"
-#include "dapl_vendor.h"
-#include "dapl_osd.h"
-
-extern struct rdma_event_channel *g_cm_events;
-
-/* local prototypes */
-static struct dapl_cm_id *dapli_req_recv(struct dapl_cm_id *conn,
-                                        struct rdma_cm_event *event);
-static void dapli_cm_active_cb(struct dapl_cm_id *conn,
-                              struct rdma_cm_event *event);
-static void dapli_cm_passive_cb(struct dapl_cm_id *conn,
-                               struct rdma_cm_event *event);
-static void dapli_addr_resolve(struct dapl_cm_id *conn);
-static void dapli_route_resolve(struct dapl_cm_id *conn);
-
-/* cma requires 16 bit SID, in network order */
-#define IB_PORT_MOD 32001
-#define IB_PORT_BASE (65535 - IB_PORT_MOD)
-#define SID_TO_PORT(SID) \
-    (SID > 0xffff ? \
-    htons((unsigned short)((SID % IB_PORT_MOD) + IB_PORT_BASE)) :\
-    htons((unsigned short)SID))
-
-#define PORT_TO_SID(p) ntohs(p)
-
-/* private data header to validate consumer rejects versus abnormal events */
-struct dapl_pdata_hdr {
-       DAT_UINT32 version;
-};
-
-static void dapli_addr_resolve(struct dapl_cm_id *conn)
-{
-       int ret;
-#ifdef DAPL_DBG
-       struct rdma_addr *ipaddr = &conn->cm_id->route.addr;
-#endif
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " addr_resolve: cm_id %p SRC %x DST %x\n",
-                    conn->cm_id, ntohl(((struct sockaddr_in *)
-                                        &ipaddr->src_addr)->sin_addr.s_addr),
-                    ntohl(((struct sockaddr_in *)
-                           &ipaddr->dst_addr)->sin_addr.s_addr));
-
-       ret = rdma_resolve_route(conn->cm_id, conn->route_timeout);
-       if (ret) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " dapl_cma_connect: rdma_resolve_route ERR 0x%x %s\n",
-                        ret, strerror(errno));
-               dapl_evd_connection_callback(conn,
-                                            IB_CME_LOCAL_FAILURE,
-                                            NULL, conn->ep);
-       }
-}
-
-static void dapli_route_resolve(struct dapl_cm_id *conn)
-{
-       int ret;
-#ifdef DAPL_DBG
-       struct rdma_addr *ipaddr = &conn->cm_id->route.addr;
-       struct ib_addr *ibaddr = &conn->cm_id->route.addr.addr.ibaddr;
-#endif
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " route_resolve: cm_id %p SRC %x DST %x PORT %d\n",
-                    conn->cm_id, ntohl(((struct sockaddr_in *)
-                                        &ipaddr->src_addr)->sin_addr.s_addr),
-                    ntohl(((struct sockaddr_in *)
-                           &ipaddr->dst_addr)->sin_addr.s_addr),
-                    ntohs(((struct sockaddr_in *)
-                           &ipaddr->dst_addr)->sin_port));
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " route_resolve: SRC GID subnet %016llx id %016llx\n",
-                    (unsigned long long)
-                    ntohll(ibaddr->sgid.global.subnet_prefix),
-                    (unsigned long long)
-                    ntohll(ibaddr->sgid.global.interface_id));
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " route_resolve: DST GID subnet %016llx id %016llx\n",
-                    (unsigned long long)
-                    ntohll(ibaddr->dgid.global.subnet_prefix),
-                    (unsigned long long)
-                    ntohll(ibaddr->dgid.global.interface_id));
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " route_resolve: cm_id %p pdata %p plen %d rr %d ind %d\n",
-                    conn->cm_id,
-                    conn->params.private_data,
-                    conn->params.private_data_len,
-                    conn->params.responder_resources,
-                    conn->params.initiator_depth);
-
-       ret = rdma_connect(conn->cm_id, &conn->params);
-       if (ret) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " dapl_cma_connect: rdma_connect ERR %d %s\n",
-                        ret, strerror(errno));
-               goto bail;
-       }
-       return;
-
-      bail:
-       dapl_evd_connection_callback(conn,
-                                    IB_CME_LOCAL_FAILURE, NULL, conn->ep);
-}
-
-dp_ib_cm_handle_t dapls_ib_cm_create(DAPL_EP *ep)
-{
-       dp_ib_cm_handle_t conn;
-       struct rdma_cm_id *cm_id;
-
-       /* Allocate CM and initialize lock */
-       if ((conn = dapl_os_alloc(sizeof(*conn))) == NULL)
-               return NULL;
-
-       dapl_os_memzero(conn, sizeof(*conn));
-       dapl_os_lock_init(&conn->lock);
-       conn->refs++;
-
-       /* create CM_ID, bind to local device, create QP */
-       if (rdma_create_id(g_cm_events, &cm_id, (void *)conn, RDMA_PS_TCP)) {
-               dapl_os_free(conn, sizeof(*conn));
-               return NULL;
-       }
-       conn->cm_id = cm_id;
-
-       /* setup timers for address and route resolution */
-       conn->arp_timeout = dapl_os_get_env_val("DAPL_CM_ARP_TIMEOUT_MS",
-                                               IB_ARP_TIMEOUT);
-       conn->arp_retries = dapl_os_get_env_val("DAPL_CM_ARP_RETRY_COUNT",
-                                               IB_ARP_RETRY_COUNT);
-       conn->route_timeout = dapl_os_get_env_val("DAPL_CM_ROUTE_TIMEOUT_MS",
-                                                 IB_ROUTE_TIMEOUT);
-       conn->route_retries = dapl_os_get_env_val("DAPL_CM_ROUTE_RETRY_COUNT",
-                                                 IB_ROUTE_RETRY_COUNT);
-       if (ep != NULL) {
-               conn->ep = ep;
-               conn->hca = ((DAPL_IA *)ep->param.ia_handle)->hca_ptr;
-       }
-
-       return conn;
-}
-
-/* 
- * Only called from consumer thread via dat_ep_free()
- * accept, reject, or connect.
- * Cannot be called from callback thread.
- * rdma_destroy_id will block until rdma_get_cm_event is acked.
- */
-void dapls_ib_cm_free(dp_ib_cm_handle_t conn, DAPL_EP *ep)
-{
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " destroy_conn: conn %p id %d\n", 
-                    conn, conn->cm_id);
-
-       dapl_os_lock(&conn->lock);
-       conn->refs--;
-       dapl_os_unlock(&conn->lock);
-
-       /* block until event thread complete */
-       while (conn->refs) 
-               dapl_os_sleep_usec(10000);
-       
-       if (ep) {
-               ep->cm_handle = NULL;
-               ep->qp_handle = NULL;
-               ep->qp_state = IB_QP_STATE_ERROR;
-       }
-
-       if (conn->cm_id) {
-               if (conn->cm_id->qp)
-                       rdma_destroy_qp(conn->cm_id);
-               rdma_destroy_id(conn->cm_id);
-       }
-
-       dapl_os_free(conn, sizeof(*conn));
-}
-
-static struct dapl_cm_id *dapli_req_recv(struct dapl_cm_id *conn,
-                                        struct rdma_cm_event *event)
-{
-       struct dapl_cm_id *new_conn;
-#ifdef DAPL_DBG
-       struct rdma_addr *ipaddr = &event->id->route.addr;
-#endif
-
-       if (conn->sp == NULL) {
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                            " dapli_rep_recv: on invalid listen " "handle\n");
-               return NULL;
-       }
-
-       /* allocate new cm_id and merge listen parameters */
-       new_conn = dapl_os_alloc(sizeof(*new_conn));
-       if (new_conn) {
-               (void)dapl_os_memzero(new_conn, sizeof(*new_conn));
-               dapl_os_lock_init(&new_conn->lock);
-               new_conn->cm_id = event->id;    /* provided by uCMA */
-               event->id->context = new_conn;  /* update CM_ID context */
-               new_conn->sp = conn->sp;
-               new_conn->hca = conn->hca;
-               new_conn->refs++;
-
-               /* Get requesters connect data, setup for accept */
-               new_conn->params.responder_resources =
-                   DAPL_MIN(event->param.conn.responder_resources,
-                            conn->hca->ib_trans.rd_atom_in);
-               new_conn->params.initiator_depth =
-                   DAPL_MIN(event->param.conn.initiator_depth,
-                            conn->hca->ib_trans.rd_atom_out);
-
-               new_conn->params.flow_control = event->param.conn.flow_control;
-               new_conn->params.rnr_retry_count =
-                   event->param.conn.rnr_retry_count;
-               new_conn->params.retry_count = event->param.conn.retry_count;
-
-               /* save private data */
-               if (event->param.conn.private_data_len) {
-                       dapl_os_memcpy(new_conn->p_data,
-                                      event->param.conn.private_data,
-                                      event->param.conn.private_data_len);
-                       new_conn->params.private_data = new_conn->p_data;
-                       new_conn->params.private_data_len =
-                           event->param.conn.private_data_len;
-               }
-
-               dapl_dbg_log(DAPL_DBG_TYPE_CM, " passive_cb: "
-                            "REQ: SP %p PORT %d LID %d "
-                            "NEW CONN %p ID %p pdata %p,%d\n",
-                            new_conn->sp, ntohs(((struct sockaddr_in *)
-                                                 &ipaddr->src_addr)->sin_port),
-                            event->listen_id, new_conn, event->id,
-                            event->param.conn.private_data,
-                            event->param.conn.private_data_len);
-
-               dapl_dbg_log(DAPL_DBG_TYPE_CM, " passive_cb: "
-                            "REQ: IP SRC %x PORT %d DST %x PORT %d "
-                            "rr %d init %d\n", ntohl(((struct sockaddr_in *)
-                                                      &ipaddr->src_addr)->
-                                                     sin_addr.s_addr),
-                            ntohs(((struct sockaddr_in *)
-                                   &ipaddr->src_addr)->sin_port),
-                            ntohl(((struct sockaddr_in *)
-                                   &ipaddr->dst_addr)->sin_addr.s_addr),
-                            ntohs(((struct sockaddr_in *)
-                                   &ipaddr->dst_addr)->sin_port),
-                            new_conn->params.responder_resources,
-                            new_conn->params.initiator_depth);
-       }
-       return new_conn;
-}
-
-static void dapli_cm_active_cb(struct dapl_cm_id *conn,
-                              struct rdma_cm_event *event)
-{
-       DAPL_OS_LOCK *lock = &conn->lock;
-       ib_cm_events_t ib_cm_event;
-       const void *pdata = NULL;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " active_cb: conn %p id %d event %d\n",
-                    conn, conn->cm_id, event->event);
-
-       /* There is a chance that we can get events after
-        * the consumer calls disconnect in a pending state
-        * since the IB CM and uDAPL states are not shared.
-        * In some cases, IB CM could generate either a DCONN
-        * or CONN_ERR after the consumer returned from
-        * dapl_ep_disconnect with a DISCONNECTED event
-        * already queued. Check state here and bail to
-        * avoid any events after a disconnect.
-        */
-       if (DAPL_BAD_HANDLE(conn->ep, DAPL_MAGIC_EP))
-               return;
-
-       dapl_os_lock(&conn->ep->header.lock);
-       if (conn->ep->param.ep_state == DAT_EP_STATE_DISCONNECTED) {
-               dapl_os_unlock(&conn->ep->header.lock);
-               return;
-       }
-       if (event->event == RDMA_CM_EVENT_DISCONNECTED)
-               conn->ep->param.ep_state = DAT_EP_STATE_DISCONNECTED;
-
-       dapl_os_unlock(&conn->ep->header.lock);
-       dapl_os_lock(lock);
-
-       switch (event->event) {
-       case RDMA_CM_EVENT_UNREACHABLE:
-       case RDMA_CM_EVENT_CONNECT_ERROR:
-               dapl_log(DAPL_DBG_TYPE_WARN,
-                        "dapl_cma_active: CONN_ERR event=0x%x"
-                        " status=%d %s DST %s, %d\n",
-                        event->event, event->status,
-                        (event->status == -ETIMEDOUT) ? "TIMEOUT" : "",
-                        inet_ntoa(((struct sockaddr_in *)
-                                   &conn->cm_id->route.addr.dst_addr)->
-                                  sin_addr),
-                        ntohs(((struct sockaddr_in *)
-                               &conn->cm_id->route.addr.dst_addr)->
-                              sin_port));
-
-               /* per DAT SPEC provider always returns UNREACHABLE */
-               ib_cm_event = IB_CME_DESTINATION_UNREACHABLE;
-               break;
-       case RDMA_CM_EVENT_REJECTED:
-               dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                            " dapli_cm_active_handler: REJECTED reason=%d\n",
-                            event->status);
-
-               /* valid REJ from consumer will always contain private data */
-               if (event->status == 28 &&
-                   event->param.conn.private_data_len) {
-                       ib_cm_event = IB_CME_DESTINATION_REJECT_PRIVATE_DATA;
-                       pdata =
-                           (unsigned char *)event->param.conn.
-                           private_data +
-                           sizeof(struct dapl_pdata_hdr);
-               } else {
-                       ib_cm_event = IB_CME_DESTINATION_REJECT;
-                       dapl_log(DAPL_DBG_TYPE_WARN,
-                                "dapl_cma_active: non-consumer REJ,"
-                                " reason=%d, DST %s, %d\n",
-                                event->status,
-                                inet_ntoa(((struct sockaddr_in *)
-                                           &conn->cm_id->route.addr.
-                                           dst_addr)->sin_addr),
-                                ntohs(((struct sockaddr_in *)
-                                       &conn->cm_id->route.addr.
-                                       dst_addr)->sin_port));
-               }
-               break;
-       case RDMA_CM_EVENT_ESTABLISHED:
-               dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                            " active_cb: cm_id %d PORT %d CONNECTED to %s!\n",
-                            conn->cm_id, ntohs(((struct sockaddr_in *)
-                                                &conn->cm_id->route.addr.
-                                                dst_addr)->sin_port),
-                            inet_ntoa(((struct sockaddr_in *)
-                                       &conn->cm_id->route.addr.dst_addr)->
-                                      sin_addr));
-
-               /* setup local and remote ports for ep query */
-               conn->ep->param.remote_port_qual =
-                   PORT_TO_SID(rdma_get_dst_port(conn->cm_id));
-               conn->ep->param.local_port_qual =
-                   PORT_TO_SID(rdma_get_src_port(conn->cm_id));
-
-               ib_cm_event = IB_CME_CONNECTED;
-               pdata = event->param.conn.private_data;
-               break;
-       case RDMA_CM_EVENT_DISCONNECTED:
-               dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                            " active_cb: DISC EVENT - EP %p\n",conn->ep);
-               rdma_disconnect(conn->cm_id);   /* required for DREP */
-               ib_cm_event = IB_CME_DISCONNECTED;
-               /* validate EP handle */
-               if (DAPL_BAD_HANDLE(conn->ep, DAPL_MAGIC_EP))
-                       conn = NULL;
-               break;
-       default:
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                            " dapli_cm_active_cb_handler: Unexpected CM "
-                            "event %d on ID 0x%p\n", event->event,
-                            conn->cm_id);
-               conn = NULL;
-               break;
-       }
-
-       dapl_os_unlock(lock);
-       if (conn)
-               dapl_evd_connection_callback(conn, ib_cm_event, pdata, conn->ep);
-}
-
-static void dapli_cm_passive_cb(struct dapl_cm_id *conn,
-                               struct rdma_cm_event *event)
-{
-       ib_cm_events_t ib_cm_event;
-       struct dapl_cm_id *conn_recv = conn;
-       const void *pdata = NULL;
-       
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " passive_cb: conn %p id %d event %d\n",
-                    conn, event->id, event->event);
-
-       dapl_os_lock(&conn->lock);
-
-       switch (event->event) {
-       case RDMA_CM_EVENT_CONNECT_REQUEST:
-               /* create new conn object with new conn_id from event */
-               conn_recv = dapli_req_recv(conn, event);
-               ib_cm_event = IB_CME_CONNECTION_REQUEST_PENDING;
-               pdata = event->param.conn.private_data;
-               break;
-       case RDMA_CM_EVENT_UNREACHABLE:
-       case RDMA_CM_EVENT_CONNECT_ERROR:
-               dapl_log(DAPL_DBG_TYPE_WARN,
-                        "dapl_cm_passive: CONN_ERR event=0x%x status=%d %s,"
-                        " DST %s,%d\n",
-                        event->event, event->status,
-                        (event->status == -ETIMEDOUT) ? "TIMEOUT" : "",
-                        inet_ntoa(((struct sockaddr_in *)
-                                   &conn->cm_id->route.addr.dst_addr)->
-                                  sin_addr), ntohs(((struct sockaddr_in *)
-                                                    &conn->cm_id->route.addr.
-                                                    dst_addr)->sin_port));
-               ib_cm_event = IB_CME_DESTINATION_UNREACHABLE;
-               break;
-       case RDMA_CM_EVENT_REJECTED:
-               /* will alwasys be abnormal NON-consumer from active side */
-               dapl_log(DAPL_DBG_TYPE_WARN,
-                        "dapl_cm_passive: non-consumer REJ, reason=%d,"
-                        " DST %s, %d\n",
-                        event->status,
-                        inet_ntoa(((struct sockaddr_in *)
-                                   &conn->cm_id->route.addr.dst_addr)->
-                                  sin_addr),
-                        ntohs(((struct sockaddr_in *)
-                               &conn->cm_id->route.addr.dst_addr)->
-                              sin_port));
-               ib_cm_event = IB_CME_DESTINATION_REJECT;
-               break;
-       case RDMA_CM_EVENT_ESTABLISHED:
-               dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                            " passive_cb: cm_id %p PORT %d CONNECTED from 0x%x!\n",
-                            conn->cm_id, ntohs(((struct sockaddr_in *)
-                                                &conn->cm_id->route.addr.
-                                                src_addr)->sin_port),
-                            ntohl(((struct sockaddr_in *)
-                                   &conn->cm_id->route.addr.dst_addr)->
-                                  sin_addr.s_addr));
-               ib_cm_event = IB_CME_CONNECTED;
-               break;
-       case RDMA_CM_EVENT_DISCONNECTED:
-               rdma_disconnect(conn->cm_id);   /* required for DREP */
-               ib_cm_event = IB_CME_DISCONNECTED;
-               /* validate SP handle context */
-               if (DAPL_BAD_HANDLE(conn->sp, DAPL_MAGIC_PSP) &&
-                   DAPL_BAD_HANDLE(conn->sp, DAPL_MAGIC_RSP))
-                       conn_recv = NULL;
-               break;
-       default:
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR, " passive_cb: "
-                            "Unexpected CM event %d on ID 0x%p\n",
-                            event->event, conn->cm_id);
-               conn_recv = NULL;
-               break;
-       }
-
-       dapl_os_unlock(&conn->lock);
-       if (conn_recv)
-               dapls_cr_callback(conn_recv, ib_cm_event, pdata, conn_recv->sp);
-}
-
-/************************ DAPL provider entry points **********************/
-
-/*
- * dapls_ib_connect
- *
- * Initiate a connection with the passive listener on another node
- *
- * Input:
- *     ep_handle,
- *     remote_ia_address,
- *     remote_conn_qual,
- *     prd_size                size of private data and structure
- *     prd_prt                 pointer to private data structure
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *     DAT_INVALID_PARAMETER
- *
- */
-DAT_RETURN dapls_ib_connect(IN DAT_EP_HANDLE ep_handle,
-                           IN DAT_IA_ADDRESS_PTR r_addr,
-                           IN DAT_CONN_QUAL r_qual,
-                           IN DAT_COUNT p_size, IN void *p_data)
-{
-       struct dapl_ep *ep_ptr = ep_handle;
-       struct dapl_cm_id *conn = ep_ptr->cm_handle;
-       int ret;
-
-       /* Sanity check */
-       if (NULL == ep_ptr)
-               return DAT_SUCCESS;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " connect: rSID 0x%llx rPort %d, pdata %p, ln %d\n",
-                    r_qual, ntohs(SID_TO_PORT(r_qual)), p_data, p_size);
-
-       /* rdma conn and cm_id pre-bound; reference via ep_ptr->cm_handle */
-
-       /* Setup QP/CM parameters and private data in cm_id */
-       (void)dapl_os_memzero(&conn->params, sizeof(conn->params));
-       conn->params.responder_resources =
-           ep_ptr->param.ep_attr.max_rdma_read_in;
-       conn->params.initiator_depth = ep_ptr->param.ep_attr.max_rdma_read_out;
-       conn->params.flow_control = 1;
-       conn->params.rnr_retry_count = IB_RNR_RETRY_COUNT;
-       conn->params.retry_count = IB_RC_RETRY_COUNT;
-       if (p_size) {
-               dapl_os_memcpy(conn->p_data, p_data, p_size);
-               conn->params.private_data = conn->p_data;
-               conn->params.private_data_len = p_size;
-       }
-
-       /* copy in remote address, need a copy for retry attempts */
-       dapl_os_memcpy(&conn->r_addr, r_addr, sizeof(*r_addr));
-
-       /* Resolve remote address, src already bound during QP create */
-       ((struct sockaddr_in *)&conn->r_addr)->sin_port = SID_TO_PORT(r_qual);
-       ((struct sockaddr_in *)&conn->r_addr)->sin_family = AF_INET;
-
-       ret = rdma_resolve_addr(conn->cm_id, NULL,
-                               (struct sockaddr *)&conn->r_addr,
-                               conn->arp_timeout);
-       if (ret) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " dapl_cma_connect: rdma_resolve_addr ERR 0x%x %s\n",
-                        ret, strerror(errno));
-               return dapl_convert_errno(errno, "ib_connect");
-       }
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " connect: resolve_addr: cm_id %p -> %s port %d\n",
-                    conn->cm_id,
-                    inet_ntoa(((struct sockaddr_in *)&conn->r_addr)->sin_addr),
-                    ((struct sockaddr_in *)&conn->r_addr)->sin_port);
-
-       return DAT_SUCCESS;
-}
-
-/*
- * dapls_ib_disconnect
- *
- * Disconnect an EP
- *
- * Input:
- *     ep_handle,
- *     disconnect_flags
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *
- */
-DAT_RETURN
-dapls_ib_disconnect(IN DAPL_EP * ep_ptr, IN DAT_CLOSE_FLAGS close_flags)
-{
-       dp_ib_cm_handle_t conn = ep_ptr->cm_handle;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " disconnect(ep %p, conn %p, id %d flags %x)\n",
-                    ep_ptr, conn, (conn ? conn->cm_id : 0), close_flags);
-
-       if ((conn == IB_INVALID_HANDLE) || (conn->cm_id == NULL))
-               return DAT_SUCCESS;
-
-       /* no graceful half-pipe disconnect option */
-       rdma_disconnect(conn->cm_id);
-
-       /* 
-        * DAT event notification occurs from the callback
-        * Note: will fire even if DREQ goes unanswered on timeout 
-        */
-       return DAT_SUCCESS;
-}
-
-/*
- * dapls_ib_disconnect_clean
- *
- * Clean up outstanding connection data. This routine is invoked
- * after the final disconnect callback has occurred. Only on the
- * ACTIVE side of a connection.
- *
- * Input:
- *     ep_ptr          DAPL_EP
- *     active          Indicates active side of connection
- *
- * Output:
- *     none
- *
- * Returns:
- *     void
- *
- */
-void
-dapls_ib_disconnect_clean(IN DAPL_EP * ep_ptr,
-                         IN DAT_BOOLEAN active,
-                         IN const ib_cm_events_t ib_cm_event)
-{
-       /* nothing to do */
-       return;
-}
-
-/*
- * dapl_ib_setup_conn_listener
- *
- * Have the CM set up a connection listener.
- *
- * Input:
- *     ibm_hca_handle          HCA handle
- *     qp_handle                       QP handle
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *     DAT_INTERNAL_ERROR
- *     DAT_CONN_QUAL_UNAVAILBLE
- *     DAT_CONN_QUAL_IN_USE
- *
- */
-DAT_RETURN
-dapls_ib_setup_conn_listener(IN DAPL_IA * ia_ptr,
-                            IN DAT_UINT64 ServiceID, IN DAPL_SP * sp_ptr)
-{
-       DAT_RETURN dat_status = DAT_SUCCESS;
-       ib_cm_srvc_handle_t conn;
-       DAT_SOCK_ADDR6 addr;    /* local binding address */
-
-       /* Allocate CM and initialize lock */
-       if ((conn = dapl_os_alloc(sizeof(*conn))) == NULL)
-               return DAT_INSUFFICIENT_RESOURCES;
-
-       dapl_os_memzero(conn, sizeof(*conn));
-       dapl_os_lock_init(&conn->lock);
-       conn->refs++;
-
-       /* create CM_ID, bind to local device, create QP */
-       if (rdma_create_id
-           (g_cm_events, &conn->cm_id, (void *)conn, RDMA_PS_TCP)) {
-               dapl_os_free(conn, sizeof(*conn));
-               return (dapl_convert_errno(errno, "setup_listener"));
-       }
-
-       /* open identifies the local device; per DAT specification */
-       /* Get family and address then set port to consumer's ServiceID */
-       dapl_os_memcpy(&addr, &ia_ptr->hca_ptr->hca_address, sizeof(addr));
-       ((struct sockaddr_in *)&addr)->sin_port = SID_TO_PORT(ServiceID);
-
-       if (rdma_bind_addr(conn->cm_id, (struct sockaddr *)&addr)) {
-               if ((errno == EBUSY) || (errno == EADDRINUSE))
-                       dat_status = DAT_CONN_QUAL_IN_USE;
-               else
-                       dat_status =
-                           dapl_convert_errno(errno, "setup_listener");
-               goto bail;
-       }
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " listen(ia_ptr %p SID 0x%llx Port %d sp %p conn %p id %d)\n",
-                    ia_ptr, ServiceID, ntohs(SID_TO_PORT(ServiceID)),
-                    sp_ptr, conn, conn->cm_id);
-
-       sp_ptr->cm_srvc_handle = conn;
-       conn->sp = sp_ptr;
-       conn->hca = ia_ptr->hca_ptr;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_EP,
-                    " listen(conn=%p cm_id=%d)\n",
-                    sp_ptr->cm_srvc_handle, conn->cm_id);
-
-       if (rdma_listen(conn->cm_id, 0)) {      /* max cma backlog */
-
-               if ((errno == EBUSY) || (errno == EADDRINUSE))
-                       dat_status = DAT_CONN_QUAL_IN_USE;
-               else
-                       dat_status =
-                           dapl_convert_errno(errno, "setup_listener");
-               goto bail;
-       }
-
-       /* success */
-       return DAT_SUCCESS;
-
-      bail:
-       rdma_destroy_id(conn->cm_id);
-       dapl_os_free(conn, sizeof(*conn));
-       return dat_status;
-}
-
-/*
- * dapl_ib_remove_conn_listener
- *
- * Have the CM remove a connection listener.
- *
- * Input:
- *     ia_handle               IA handle
- *     ServiceID               IB Channel Service ID
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INVALID_STATE
- *
- */
-DAT_RETURN
-dapls_ib_remove_conn_listener(IN DAPL_IA * ia_ptr, IN DAPL_SP * sp_ptr)
-{
-       ib_cm_srvc_handle_t conn = sp_ptr->cm_srvc_handle;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " remove_listen(ia_ptr %p sp_ptr %p cm_ptr %p)\n",
-                    ia_ptr, sp_ptr, conn);
-
-       if (conn != IB_INVALID_HANDLE) {
-               sp_ptr->cm_srvc_handle = NULL;
-               dapls_ib_cm_free(conn, NULL);
-       }
-       return DAT_SUCCESS;
-}
-
-/*
- * dapls_ib_accept_connection
- *
- * Perform necessary steps to accept a connection
- *
- * Input:
- *     cr_handle
- *     ep_handle
- *     private_data_size
- *     private_data
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *     DAT_INTERNAL_ERROR
- *
- */
-DAT_RETURN
-dapls_ib_accept_connection(IN DAT_CR_HANDLE cr_handle,
-                          IN DAT_EP_HANDLE ep_handle,
-                          IN DAT_COUNT p_size, IN const DAT_PVOID p_data)
-{
-       DAPL_CR *cr_ptr = (DAPL_CR *) cr_handle;
-       DAPL_EP *ep_ptr = (DAPL_EP *) ep_handle;
-       DAPL_IA *ia_ptr = ep_ptr->header.owner_ia;
-       struct dapl_cm_id *cr_conn = cr_ptr->ib_cm_handle;
-       int ret;
-       DAT_RETURN dat_status;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " accept(cr %p conn %p, id %p, p_data %p, p_sz=%d)\n",
-                    cr_ptr, cr_conn, cr_conn->cm_id, p_data, p_size);
-
-       /* Obtain size of private data structure & contents */
-       if (p_size > IB_MAX_REP_PDATA_SIZE) {
-               dat_status = DAT_ERROR(DAT_LENGTH_ERROR, DAT_NO_SUBTYPE);
-               goto bail;
-       }
-
-       if (ep_ptr->qp_state == DAPL_QP_STATE_UNATTACHED) {
-               /* 
-                * If we are lazy attaching the QP then we may need to
-                * hook it up here. Typically, we run this code only for
-                * DAT_PSP_PROVIDER_FLAG
-                */
-               dat_status = dapls_ib_qp_alloc(ia_ptr, ep_ptr, NULL);
-               if (dat_status != DAT_SUCCESS) {
-                       dapl_log(DAPL_DBG_TYPE_ERR,
-                                " dapl_cma_accept: qp_alloc ERR %d\n",
-                                dat_status);
-                       goto bail;
-               }
-       }
-
-       /* 
-        * Validate device and port in EP cm_id against inbound 
-        * CR cm_id. The pre-allocated EP cm_id is already bound to 
-        * a local device (cm_id and QP) when created. Move the QP
-        * to the new cm_id only if device and port numbers match.
-        */
-       if (ep_ptr->cm_handle->cm_id->verbs == cr_conn->cm_id->verbs &&
-           ep_ptr->cm_handle->cm_id->port_num == cr_conn->cm_id->port_num) {
-               /* move QP to new cr_conn, remove QP ref in EP cm_id */
-               cr_conn->cm_id->qp = ep_ptr->cm_handle->cm_id->qp;
-               ep_ptr->cm_handle->cm_id->qp = NULL;
-               dapls_ib_cm_free(ep_ptr->cm_handle, NULL);
-       } else {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " dapl_cma_accept: ERR dev(%p!=%p) or"
-                        " port mismatch(%d!=%d)\n",
-                        ep_ptr->cm_handle->cm_id->verbs, cr_conn->cm_id->verbs,
-                        ntohs(ep_ptr->cm_handle->cm_id->port_num),
-                        ntohs(cr_conn->cm_id->port_num));
-               dat_status = DAT_INTERNAL_ERROR;
-               goto bail;
-       }
-
-       cr_ptr->param.local_ep_handle = ep_handle;
-       cr_conn->params.private_data = p_data;
-       cr_conn->params.private_data_len = p_size;
-
-       ret = rdma_accept(cr_conn->cm_id, &cr_conn->params);
-       if (ret) {
-               dapl_log(DAPL_DBG_TYPE_ERR, " dapl_cma_accept: ERR %d %s\n",
-                        ret, strerror(errno));
-               dat_status = dapl_convert_errno(ret, "accept");
-               goto bail;
-       }
-
-       /* save accepted conn and EP reference, qp_handle unchanged */
-       ep_ptr->cm_handle = cr_conn;
-       cr_conn->ep = ep_ptr;
-
-       /* setup local and remote ports for ep query */
-       /* Note: port qual in network order */
-       ep_ptr->param.remote_port_qual =
-           PORT_TO_SID(rdma_get_dst_port(cr_conn->cm_id));
-       ep_ptr->param.local_port_qual =
-           PORT_TO_SID(rdma_get_src_port(cr_conn->cm_id));
-
-       return DAT_SUCCESS;
-      bail:
-       rdma_reject(cr_conn->cm_id, NULL, 0);
-       dapls_ib_cm_free(cr_conn, NULL);
-       return dat_status;
-}
-
-/*
- * dapls_ib_reject_connection
- *
- * Reject a connection
- *
- * Input:
- *     cr_handle
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INTERNAL_ERROR
- *
- */
-DAT_RETURN
-dapls_ib_reject_connection(IN dp_ib_cm_handle_t cm_handle,
-                          IN int reason,
-                          IN DAT_COUNT private_data_size,
-                          IN const DAT_PVOID private_data)
-{
-       int ret;
-       int offset = sizeof(struct dapl_pdata_hdr);
-       struct dapl_pdata_hdr pdata_hdr;
-
-       memset(&pdata_hdr, 0, sizeof pdata_hdr);
-       pdata_hdr.version = htonl((DAT_VERSION_MAJOR << 24) |
-                                 (DAT_VERSION_MINOR << 16) |
-                                 (VN_PROVIDER_MAJOR << 8) |
-                                 (VN_PROVIDER_MINOR));
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " reject: handle %p reason %x, ver=%x, data %p, sz=%d\n",
-                    cm_handle, reason, ntohl(pdata_hdr.version),
-                    private_data, private_data_size);
-
-       if (cm_handle == IB_INVALID_HANDLE) {
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                            " reject: invalid handle: reason %d\n", reason);
-               return DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_CR);
-       }
-
-       if (private_data_size >
-           dapls_ib_private_data_size(NULL, DAPL_PDATA_CONN_REJ,
-                                      cm_handle->hca))
-               return DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3);
-
-       /* setup pdata_hdr and users data, in CR pdata buffer */
-       dapl_os_memcpy(cm_handle->p_data, &pdata_hdr, offset);
-       if (private_data_size)
-               dapl_os_memcpy(cm_handle->p_data + offset,
-                              private_data, private_data_size);
-
-       /*
-        * Always some private data with reject so active peer can
-        * determine real application reject from an abnormal 
-        * application termination
-        */
-       ret = rdma_reject(cm_handle->cm_id,
-                         cm_handle->p_data, offset + private_data_size);
-
-       dapls_ib_cm_free(cm_handle, NULL);
-       return dapl_convert_errno(ret, "reject");
-}
-
-/*
- * dapls_ib_cm_remote_addr
- *
- * Obtain the remote IP address given a connection
- *
- * Input:
- *     cr_handle
- *
- * Output:
- *     remote_ia_address: where to place the remote address
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INVALID_HANDLE
- *
- */
-DAT_RETURN
-dapls_ib_cm_remote_addr(IN DAT_HANDLE dat_handle, OUT DAT_SOCK_ADDR6 * raddr)
-{
-       DAPL_HEADER *header;
-       dp_ib_cm_handle_t ib_cm_handle;
-       struct rdma_addr *ipaddr;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_EP,
-                    " remote_addr(cm_handle=%p, r_addr=%p)\n",
-                    dat_handle, raddr);
-
-       header = (DAPL_HEADER *) dat_handle;
-
-       if (header->magic == DAPL_MAGIC_EP)
-               ib_cm_handle = ((DAPL_EP *) dat_handle)->cm_handle;
-       else if (header->magic == DAPL_MAGIC_CR)
-               ib_cm_handle = ((DAPL_CR *) dat_handle)->ib_cm_handle;
-       else
-               return DAT_INVALID_HANDLE;
-
-       /* get remote IP address from cm_id route */
-       ipaddr = &ib_cm_handle->cm_id->route.addr;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " remote_addr: conn %p id %p SRC %x DST %x PORT %d\n",
-                    ib_cm_handle, ib_cm_handle->cm_id,
-                    ntohl(((struct sockaddr_in *)
-                           &ipaddr->src_addr)->sin_addr.s_addr),
-                    ntohl(((struct sockaddr_in *)
-                           &ipaddr->dst_addr)->sin_addr.s_addr),
-                    ntohs(((struct sockaddr_in *)
-                           &ipaddr->dst_addr)->sin_port));
-
-       dapl_os_memcpy(raddr, &ipaddr->dst_addr, sizeof(DAT_SOCK_ADDR));
-       return DAT_SUCCESS;
-}
-
-/*
- * dapls_ib_private_data_size
- *
- * Return the size of private data given a connection op type
- *
- * Input:
- *     prd_ptr         private data pointer
- *     conn_op         connection operation type
- *      hca_ptr         hca pointer, needed for transport type
- *
- * If prd_ptr is NULL, this is a query for the max size supported by
- * the provider, otherwise it is the actual size of the private data
- * contained in prd_ptr.
- *
- *
- * Output:
- *     None
- *
- * Returns:
- *     length of private data
- *
- */
-int dapls_ib_private_data_size(IN DAPL_PRIVATE * prd_ptr,
-                              IN DAPL_PDATA_OP conn_op, IN DAPL_HCA * hca_ptr)
-{
-       int size;
-
-       if (hca_ptr->ib_hca_handle->device->transport_type
-           == IBV_TRANSPORT_IWARP)
-               return (IWARP_MAX_PDATA_SIZE - sizeof(struct dapl_pdata_hdr));
-
-       switch (conn_op) {
-
-       case DAPL_PDATA_CONN_REQ:
-               size = IB_MAX_REQ_PDATA_SIZE;
-               break;
-       case DAPL_PDATA_CONN_REP:
-               size = IB_MAX_REP_PDATA_SIZE;
-               break;
-       case DAPL_PDATA_CONN_REJ:
-               size = IB_MAX_REJ_PDATA_SIZE - sizeof(struct dapl_pdata_hdr);
-               break;
-       case DAPL_PDATA_CONN_DREQ:
-               size = IB_MAX_DREQ_PDATA_SIZE;
-               break;
-       case DAPL_PDATA_CONN_DREP:
-               size = IB_MAX_DREP_PDATA_SIZE;
-               break;
-       default:
-               size = 0;
-
-       }                       /* end case */
-
-       return size;
-}
-
-/*
- * Map all CMA event codes to the DAT equivelent.
- */
-#define DAPL_IB_EVENT_CNT      13
-
-static struct ib_cm_event_map {
-       const ib_cm_events_t ib_cm_event;
-       DAT_EVENT_NUMBER dat_event_num;
-} ib_cm_event_map[DAPL_IB_EVENT_CNT] = {
-       /* 00 */  {
-       IB_CME_CONNECTED, DAT_CONNECTION_EVENT_ESTABLISHED},
-           /* 01 */  {
-       IB_CME_DISCONNECTED, DAT_CONNECTION_EVENT_DISCONNECTED},
-           /* 02 */  {
-       IB_CME_DISCONNECTED_ON_LINK_DOWN,
-                   DAT_CONNECTION_EVENT_DISCONNECTED},
-           /* 03 */  {
-       IB_CME_CONNECTION_REQUEST_PENDING, DAT_CONNECTION_REQUEST_EVENT},
-           /* 04 */  {
-       IB_CME_CONNECTION_REQUEST_PENDING_PRIVATE_DATA,
-                   DAT_CONNECTION_REQUEST_EVENT},
-           /* 05 */  {
-       IB_CME_CONNECTION_REQUEST_ACKED, DAT_CONNECTION_REQUEST_EVENT},
-           /* 06 */  {
-       IB_CME_DESTINATION_REJECT,
-                   DAT_CONNECTION_EVENT_NON_PEER_REJECTED},
-           /* 07 */  {
-       IB_CME_DESTINATION_REJECT_PRIVATE_DATA,
-                   DAT_CONNECTION_EVENT_PEER_REJECTED},
-           /* 08 */  {
-       IB_CME_DESTINATION_UNREACHABLE, DAT_CONNECTION_EVENT_UNREACHABLE},
-           /* 09 */  {
-       IB_CME_TOO_MANY_CONNECTION_REQUESTS,
-                   DAT_CONNECTION_EVENT_NON_PEER_REJECTED},
-           /* 10 */  {
-       IB_CME_LOCAL_FAILURE, DAT_CONNECTION_EVENT_BROKEN},
-           /* 11 */  {
-       IB_CME_BROKEN, DAT_CONNECTION_EVENT_BROKEN},
-           /* 12 */  {
-IB_CME_TIMEOUT, DAT_CONNECTION_EVENT_TIMED_OUT},};
-
-/*
- * dapls_ib_get_cm_event
- *
- * Return a DAT connection event given a provider CM event.
- *
- * Input:
- *     dat_event_num   DAT event we need an equivelent CM event for
- *
- * Output:
- *     none
- *
- * Returns:
- *     ib_cm_event of translated DAPL value
- */
-DAT_EVENT_NUMBER
-dapls_ib_get_dat_event(IN const ib_cm_events_t ib_cm_event,
-                      IN DAT_BOOLEAN active)
-{
-       DAT_EVENT_NUMBER dat_event_num;
-       int i;
-
-       active = active;
-
-       dat_event_num = 0;
-       for (i = 0; i < DAPL_IB_EVENT_CNT; i++) {
-               if (ib_cm_event == ib_cm_event_map[i].ib_cm_event) {
-                       dat_event_num = ib_cm_event_map[i].dat_event_num;
-                       break;
-               }
-       }
-       dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,
-                    "dapls_ib_get_dat_event: event(%s) ib=0x%x dat=0x%x\n",
-                    active ? "active" : "passive", ib_cm_event, dat_event_num);
-
-       return dat_event_num;
-}
-
-/*
- * dapls_ib_get_dat_event
- *
- * Return a DAT connection event given a provider CM event.
- * 
- * Input:
- *     ib_cm_event     event provided to the dapl callback routine
- *     active          switch indicating active or passive connection
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_EVENT_NUMBER of translated provider value
- */
-ib_cm_events_t dapls_ib_get_cm_event(IN DAT_EVENT_NUMBER dat_event_num)
-{
-       ib_cm_events_t ib_cm_event;
-       int i;
-
-       ib_cm_event = 0;
-       for (i = 0; i < DAPL_IB_EVENT_CNT; i++) {
-               if (dat_event_num == ib_cm_event_map[i].dat_event_num) {
-                       ib_cm_event = ib_cm_event_map[i].ib_cm_event;
-                       break;
-               }
-       }
-       return ib_cm_event;
-}
-
-void dapli_cma_event_cb(void)
-{
-       struct rdma_cm_event *event;
-                               
-       /* process one CM event, fairness, non-blocking */
-       if (!rdma_get_cm_event(g_cm_events, &event)) {
-               struct dapl_cm_id *conn;
-
-               /* set proper conn from cm_id context */
-               if (event->event == RDMA_CM_EVENT_CONNECT_REQUEST)
-                       conn = (struct dapl_cm_id *)event->listen_id->context;
-               else
-                       conn = (struct dapl_cm_id *)event->id->context;
-
-               dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                            " cm_event: EVENT=%d ID=%p LID=%p CTX=%p\n",
-                            event->event, event->id, event->listen_id, conn);
-               
-               /* cm_free is blocked waiting for ack  */
-               dapl_os_lock(&conn->lock);
-               if (!conn->refs) {
-                       dapl_os_unlock(&conn->lock);
-                       rdma_ack_cm_event(event);
-                       return;
-               }
-               conn->refs++;
-               dapl_os_unlock(&conn->lock);
-
-               switch (event->event) {
-               case RDMA_CM_EVENT_ADDR_RESOLVED:
-                       dapli_addr_resolve(conn);
-                       break;
-
-               case RDMA_CM_EVENT_ROUTE_RESOLVED:
-                       dapli_route_resolve(conn);
-                       break;
-
-               case RDMA_CM_EVENT_ADDR_ERROR:
-                       dapl_log(DAPL_DBG_TYPE_WARN,
-                                "dapl_cma_active: CM ADDR ERROR: ->"
-                                " DST %s retry (%d)..\n",
-                                inet_ntoa(((struct sockaddr_in *)
-                                           &conn->r_addr)->sin_addr),
-                                conn->arp_retries);
-
-                       /* retry address resolution */
-                       if ((--conn->arp_retries) &&
-                           (event->status == -ETIMEDOUT)) {
-                               int ret;
-                               ret = rdma_resolve_addr(conn->cm_id, NULL,
-                                                       (struct sockaddr *)
-                                                       &conn->r_addr,
-                                                       conn->arp_timeout);
-                               if (!ret)
-                                       break;
-                               else {
-                                       dapl_dbg_log(DAPL_DBG_TYPE_WARN,
-                                                    " ERROR: rdma_resolve_addr = "
-                                                    "%d %s\n",
-                                                    ret, strerror(errno));
-                               }
-                       }
-                       /* retries exhausted or resolve_addr failed */
-                       dapl_log(DAPL_DBG_TYPE_ERR,
-                                "dapl_cma_active: ARP_ERR, retries(%d)"
-                                " exhausted -> DST %s,%d\n",
-                                IB_ARP_RETRY_COUNT,
-                                inet_ntoa(((struct sockaddr_in *)
-                                           &conn->cm_id->route.addr.dst_addr)->
-                                          sin_addr),
-                                ntohs(((struct sockaddr_in *)
-                                       &conn->cm_id->route.addr.dst_addr)->
-                                      sin_port));
-
-                       dapl_evd_connection_callback(conn,
-                                                    IB_CME_DESTINATION_UNREACHABLE,
-                                                    NULL, conn->ep);
-                       break;
-
-               case RDMA_CM_EVENT_ROUTE_ERROR:
-                       dapl_log(DAPL_DBG_TYPE_WARN,
-                                "dapl_cma_active: CM ROUTE ERROR: ->"
-                                " DST %s retry (%d)..\n",
-                                inet_ntoa(((struct sockaddr_in *)
-                                           &conn->r_addr)->sin_addr),
-                                conn->route_retries);
-
-                       /* retry route resolution */
-                       if ((--conn->route_retries) &&
-                           (event->status == -ETIMEDOUT))
-                               dapli_addr_resolve(conn);
-                       else {
-                               dapl_log(DAPL_DBG_TYPE_ERR,
-                                        "dapl_cma_active: PATH_RECORD_ERR,"
-                                        " retries(%d) exhausted, DST %s,%d\n",
-                                        IB_ROUTE_RETRY_COUNT,
-                                        inet_ntoa(((struct sockaddr_in *)
-                                                   &conn->cm_id->route.addr.
-                                                   dst_addr)->sin_addr),
-                                        ntohs(((struct sockaddr_in *)
-                                               &conn->cm_id->route.addr.
-                                               dst_addr)->sin_port));
-
-                               dapl_evd_connection_callback(conn,
-                                                            IB_CME_DESTINATION_UNREACHABLE,
-                                                            NULL, conn->ep);
-                       }
-                       break;
-
-               case RDMA_CM_EVENT_DEVICE_REMOVAL:
-                       dapl_evd_connection_callback(conn,
-                                                    IB_CME_LOCAL_FAILURE,
-                                                    NULL, conn->ep);
-                       break;
-               case RDMA_CM_EVENT_CONNECT_REQUEST:
-               case RDMA_CM_EVENT_CONNECT_ERROR:
-               case RDMA_CM_EVENT_UNREACHABLE:
-               case RDMA_CM_EVENT_REJECTED:
-               case RDMA_CM_EVENT_ESTABLISHED:
-               case RDMA_CM_EVENT_DISCONNECTED:
-                       /* passive or active */
-                       if (conn->sp)
-                               dapli_cm_passive_cb(conn, event);
-                       else
-                               dapli_cm_active_cb(conn, event);
-                       break;
-               case RDMA_CM_EVENT_CONNECT_RESPONSE:
-#ifdef RDMA_CM_EVENT_TIMEWAIT_EXIT
-               case RDMA_CM_EVENT_TIMEWAIT_EXIT:
-#endif
-                       break;
-               default:
-                       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                                    " cm_event: UNEXPECTED EVENT=%p ID=%p CTX=%p\n",
-                                    event->event, event->id,
-                                    event->id->context);
-                       break;
-               }
-               
-               /* ack event, unblocks destroy_cm_id in consumer threads */
-               rdma_ack_cm_event(event);
-
-               dapl_os_lock(&conn->lock);
-                conn->refs--;
-               dapl_os_unlock(&conn->lock);
-       } 
-}
-
-/*
- * Local variables:
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 8
- * End:
- */
+/*\r
+ * Copyright (c) 2005 Voltaire Inc.  All rights reserved.\r
+ * Copyright (c) 2005-2007 Intel Corporation. All rights reserved.\r
+ * Copyright (c) 2004-2005, Mellanox Technologies, Inc. All rights reserved. \r
+ * Copyright (c) 2003 Topspin Corporation.  All rights reserved. \r
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.\r
+ *\r
+ * This Software is licensed under one of the following licenses:\r
+ *\r
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/cpl.php.\r
+ *\r
+ * 2) under the terms of the "The BSD License" a copy of which is\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/bsd-license.php.\r
+ *\r
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a\r
+ *    copy of which is available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/gpl-license.php.\r
+ *\r
+ * Licensee has the right to choose one of the above licenses.\r
+ *\r
+ * Redistributions of source code must retain the above copyright\r
+ * notice and one of the license notices.\r
+ *\r
+ * Redistributions in binary form must reproduce both the above copyright\r
+ * notice, one of the license notices in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ */\r
+\r
+/**********************************************************************\r
+ *\r
+ * MODULE: dapl_ib_cm.c\r
+ *\r
+ * PURPOSE: The OFED provider - uCMA, name and route resolution\r
+ *\r
+ * $Id: $\r
+ *\r
+ **********************************************************************/\r
+\r
+#include "dapl.h"\r
+#include "dapl_adapter_util.h"\r
+#include "dapl_evd_util.h"\r
+#include "dapl_cr_util.h"\r
+#include "dapl_name_service.h"\r
+#include "dapl_ib_util.h"\r
+#include "dapl_vendor.h"\r
+#include "dapl_osd.h"\r
+\r
+extern struct rdma_event_channel *g_cm_events;\r
+\r
+/* local prototypes */\r
+static struct dapl_cm_id *dapli_req_recv(struct dapl_cm_id *conn,\r
+                                        struct rdma_cm_event *event);\r
+static void dapli_cm_active_cb(struct dapl_cm_id *conn,\r
+                              struct rdma_cm_event *event);\r
+static void dapli_cm_passive_cb(struct dapl_cm_id *conn,\r
+                               struct rdma_cm_event *event);\r
+static void dapli_addr_resolve(struct dapl_cm_id *conn);\r
+static void dapli_route_resolve(struct dapl_cm_id *conn);\r
+\r
+/* cma requires 16 bit SID, in network order */\r
+#define IB_PORT_MOD 32001\r
+#define IB_PORT_BASE (65535 - IB_PORT_MOD)\r
+#define SID_TO_PORT(SID) \\r
+    (SID > 0xffff ? \\r
+    htons((unsigned short)((SID % IB_PORT_MOD) + IB_PORT_BASE)) :\\r
+    htons((unsigned short)SID))\r
+\r
+#define PORT_TO_SID(p) ntohs(p)\r
+\r
+/* private data header to validate consumer rejects versus abnormal events */\r
+struct dapl_pdata_hdr {\r
+       DAT_UINT32 version;\r
+};\r
+\r
+static void dapli_addr_resolve(struct dapl_cm_id *conn)\r
+{\r
+       int ret;\r
+#ifdef DAPL_DBG\r
+       struct rdma_addr *ipaddr = &conn->cm_id->route.addr;\r
+#endif\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " addr_resolve: cm_id %p SRC %x DST %x\n",\r
+                    conn->cm_id, ntohl(((struct sockaddr_in *)\r
+                                        &ipaddr->src_addr)->sin_addr.s_addr),\r
+                    ntohl(((struct sockaddr_in *)\r
+                           &ipaddr->dst_addr)->sin_addr.s_addr));\r
+\r
+       ret = rdma_resolve_route(conn->cm_id, conn->route_timeout);\r
+       if (ret) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " dapl_cma_connect: rdma_resolve_route ERR 0x%x %s\n",\r
+                        ret, strerror(errno));\r
+               dapl_evd_connection_callback(conn,\r
+                                            IB_CME_LOCAL_FAILURE,\r
+                                            NULL, conn->ep);\r
+       }\r
+}\r
+\r
+static void dapli_route_resolve(struct dapl_cm_id *conn)\r
+{\r
+       int ret;\r
+#ifdef DAPL_DBG\r
+       struct rdma_addr *ipaddr = &conn->cm_id->route.addr;\r
+       struct ib_addr *ibaddr = &conn->cm_id->route.addr.addr.ibaddr;\r
+#endif\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " route_resolve: cm_id %p SRC %x DST %x PORT %d\n",\r
+                    conn->cm_id, ntohl(((struct sockaddr_in *)\r
+                                        &ipaddr->src_addr)->sin_addr.s_addr),\r
+                    ntohl(((struct sockaddr_in *)\r
+                           &ipaddr->dst_addr)->sin_addr.s_addr),\r
+                    ntohs(((struct sockaddr_in *)\r
+                           &ipaddr->dst_addr)->sin_port));\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " route_resolve: SRC GID subnet %016llx id %016llx\n",\r
+                    (unsigned long long)\r
+                    ntohll(ibaddr->sgid.global.subnet_prefix),\r
+                    (unsigned long long)\r
+                    ntohll(ibaddr->sgid.global.interface_id));\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " route_resolve: DST GID subnet %016llx id %016llx\n",\r
+                    (unsigned long long)\r
+                    ntohll(ibaddr->dgid.global.subnet_prefix),\r
+                    (unsigned long long)\r
+                    ntohll(ibaddr->dgid.global.interface_id));\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " route_resolve: cm_id %p pdata %p plen %d rr %d ind %d\n",\r
+                    conn->cm_id,\r
+                    conn->params.private_data,\r
+                    conn->params.private_data_len,\r
+                    conn->params.responder_resources,\r
+                    conn->params.initiator_depth);\r
+\r
+       ret = rdma_connect(conn->cm_id, &conn->params);\r
+       if (ret) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " dapl_cma_connect: rdma_connect ERR %d %s\n",\r
+                        ret, strerror(errno));\r
+               goto bail;\r
+       }\r
+       return;\r
+\r
+      bail:\r
+       dapl_evd_connection_callback(conn,\r
+                                    IB_CME_LOCAL_FAILURE, NULL, conn->ep);\r
+}\r
+\r
+dp_ib_cm_handle_t dapls_ib_cm_create(DAPL_EP *ep)\r
+{\r
+       dp_ib_cm_handle_t conn;\r
+       struct rdma_cm_id *cm_id;\r
+\r
+       /* Allocate CM and initialize lock */\r
+       if ((conn = dapl_os_alloc(sizeof(*conn))) == NULL)\r
+               return NULL;\r
+\r
+       dapl_os_memzero(conn, sizeof(*conn));\r
+       dapl_os_lock_init(&conn->lock);\r
+       conn->refs++;\r
+\r
+       /* create CM_ID, bind to local device, create QP */\r
+       if (rdma_create_id(g_cm_events, &cm_id, (void *)conn, RDMA_PS_TCP)) {\r
+               dapl_os_free(conn, sizeof(*conn));\r
+               return NULL;\r
+       }\r
+       conn->cm_id = cm_id;\r
+\r
+       /* setup timers for address and route resolution */\r
+       conn->arp_timeout = dapl_os_get_env_val("DAPL_CM_ARP_TIMEOUT_MS",\r
+                                               IB_ARP_TIMEOUT);\r
+       conn->arp_retries = dapl_os_get_env_val("DAPL_CM_ARP_RETRY_COUNT",\r
+                                               IB_ARP_RETRY_COUNT);\r
+       conn->route_timeout = dapl_os_get_env_val("DAPL_CM_ROUTE_TIMEOUT_MS",\r
+                                                 IB_ROUTE_TIMEOUT);\r
+       conn->route_retries = dapl_os_get_env_val("DAPL_CM_ROUTE_RETRY_COUNT",\r
+                                                 IB_ROUTE_RETRY_COUNT);\r
+       if (ep != NULL) {\r
+               conn->ep = ep;\r
+               conn->hca = ((DAPL_IA *)ep->param.ia_handle)->hca_ptr;\r
+       }\r
+\r
+       return conn;\r
+}\r
+\r
+/* \r
+ * Only called from consumer thread via dat_ep_free()\r
+ * accept, reject, or connect.\r
+ * Cannot be called from callback thread.\r
+ * rdma_destroy_id will block until rdma_get_cm_event is acked.\r
+ */\r
+void dapls_ib_cm_free(dp_ib_cm_handle_t conn, DAPL_EP *ep)\r
+{\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " destroy_conn: conn %p id %d\n", \r
+                    conn, conn->cm_id);\r
+\r
+       dapl_os_lock(&conn->lock);\r
+       conn->refs--;\r
+       dapl_os_unlock(&conn->lock);\r
+\r
+       /* block until event thread complete */\r
+       while (conn->refs) \r
+               dapl_os_sleep_usec(10000);\r
+       \r
+       if (ep) {\r
+               ep->cm_handle = NULL;\r
+               ep->qp_handle = NULL;\r
+               ep->qp_state = IB_QP_STATE_ERROR;\r
+       }\r
+\r
+       if (conn->cm_id) {\r
+               if (conn->cm_id->qp)\r
+                       rdma_destroy_qp(conn->cm_id);\r
+               rdma_destroy_id(conn->cm_id);\r
+       }\r
+\r
+       dapl_os_free(conn, sizeof(*conn));\r
+}\r
+\r
+static struct dapl_cm_id *dapli_req_recv(struct dapl_cm_id *conn,\r
+                                        struct rdma_cm_event *event)\r
+{\r
+       struct dapl_cm_id *new_conn;\r
+#ifdef DAPL_DBG\r
+       struct rdma_addr *ipaddr = &event->id->route.addr;\r
+#endif\r
+\r
+       if (conn->sp == NULL) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+                            " dapli_rep_recv: on invalid listen " "handle\n");\r
+               return NULL;\r
+       }\r
+\r
+       /* allocate new cm_id and merge listen parameters */\r
+       new_conn = dapl_os_alloc(sizeof(*new_conn));\r
+       if (new_conn) {\r
+               (void)dapl_os_memzero(new_conn, sizeof(*new_conn));\r
+               dapl_os_lock_init(&new_conn->lock);\r
+               new_conn->cm_id = event->id;    /* provided by uCMA */\r
+               event->id->context = new_conn;  /* update CM_ID context */\r
+               new_conn->sp = conn->sp;\r
+               new_conn->hca = conn->hca;\r
+               new_conn->refs++;\r
+\r
+               /* Get requesters connect data, setup for accept */\r
+               new_conn->params.responder_resources =\r
+                   DAPL_MIN(event->param.conn.responder_resources,\r
+                            conn->hca->ib_trans.rd_atom_in);\r
+               new_conn->params.initiator_depth =\r
+                   DAPL_MIN(event->param.conn.initiator_depth,\r
+                            conn->hca->ib_trans.rd_atom_out);\r
+\r
+               new_conn->params.flow_control = event->param.conn.flow_control;\r
+               new_conn->params.rnr_retry_count =\r
+                   event->param.conn.rnr_retry_count;\r
+               new_conn->params.retry_count = event->param.conn.retry_count;\r
+\r
+               /* save private data */\r
+               if (event->param.conn.private_data_len) {\r
+                       dapl_os_memcpy(new_conn->p_data,\r
+                                      event->param.conn.private_data,\r
+                                      event->param.conn.private_data_len);\r
+                       new_conn->params.private_data = new_conn->p_data;\r
+                       new_conn->params.private_data_len =\r
+                           event->param.conn.private_data_len;\r
+               }\r
+\r
+               dapl_dbg_log(DAPL_DBG_TYPE_CM, " passive_cb: "\r
+                            "REQ: SP %p PORT %d LID %d "\r
+                            "NEW CONN %p ID %p pdata %p,%d\n",\r
+                            new_conn->sp, ntohs(((struct sockaddr_in *)\r
+                                                 &ipaddr->src_addr)->sin_port),\r
+                            event->listen_id, new_conn, event->id,\r
+                            event->param.conn.private_data,\r
+                            event->param.conn.private_data_len);\r
+\r
+               dapl_dbg_log(DAPL_DBG_TYPE_CM, " passive_cb: "\r
+                            "REQ: IP SRC %x PORT %d DST %x PORT %d "\r
+                            "rr %d init %d\n", ntohl(((struct sockaddr_in *)\r
+                                                      &ipaddr->src_addr)->\r
+                                                     sin_addr.s_addr),\r
+                            ntohs(((struct sockaddr_in *)\r
+                                   &ipaddr->src_addr)->sin_port),\r
+                            ntohl(((struct sockaddr_in *)\r
+                                   &ipaddr->dst_addr)->sin_addr.s_addr),\r
+                            ntohs(((struct sockaddr_in *)\r
+                                   &ipaddr->dst_addr)->sin_port),\r
+                            new_conn->params.responder_resources,\r
+                            new_conn->params.initiator_depth);\r
+       }\r
+       return new_conn;\r
+}\r
+\r
+static void dapli_cm_active_cb(struct dapl_cm_id *conn,\r
+                              struct rdma_cm_event *event)\r
+{\r
+       DAPL_OS_LOCK *lock = &conn->lock;\r
+       ib_cm_events_t ib_cm_event;\r
+       const void *pdata = NULL;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " active_cb: conn %p id %d event %d\n",\r
+                    conn, conn->cm_id, event->event);\r
+\r
+       /* There is a chance that we can get events after\r
+        * the consumer calls disconnect in a pending state\r
+        * since the IB CM and uDAPL states are not shared.\r
+        * In some cases, IB CM could generate either a DCONN\r
+        * or CONN_ERR after the consumer returned from\r
+        * dapl_ep_disconnect with a DISCONNECTED event\r
+        * already queued. Check state here and bail to\r
+        * avoid any events after a disconnect.\r
+        */\r
+       if (DAPL_BAD_HANDLE(conn->ep, DAPL_MAGIC_EP))\r
+               return;\r
+\r
+       dapl_os_lock(&conn->ep->header.lock);\r
+       if (conn->ep->param.ep_state == DAT_EP_STATE_DISCONNECTED) {\r
+               dapl_os_unlock(&conn->ep->header.lock);\r
+               return;\r
+       }\r
+       if (event->event == RDMA_CM_EVENT_DISCONNECTED)\r
+               conn->ep->param.ep_state = DAT_EP_STATE_DISCONNECTED;\r
+\r
+       dapl_os_unlock(&conn->ep->header.lock);\r
+       dapl_os_lock(lock);\r
+\r
+       switch (event->event) {\r
+       case RDMA_CM_EVENT_UNREACHABLE:\r
+       case RDMA_CM_EVENT_CONNECT_ERROR:\r
+               dapl_log(DAPL_DBG_TYPE_WARN,\r
+                        "dapl_cma_active: CONN_ERR event=0x%x"\r
+                        " status=%d %s DST %s, %d\n",\r
+                        event->event, event->status,\r
+                        (event->status == -ETIMEDOUT) ? "TIMEOUT" : "",\r
+                        inet_ntoa(((struct sockaddr_in *)\r
+                                   &conn->cm_id->route.addr.dst_addr)->\r
+                                  sin_addr),\r
+                        ntohs(((struct sockaddr_in *)\r
+                               &conn->cm_id->route.addr.dst_addr)->\r
+                              sin_port));\r
+\r
+               /* per DAT SPEC provider always returns UNREACHABLE */\r
+               ib_cm_event = IB_CME_DESTINATION_UNREACHABLE;\r
+               break;\r
+       case RDMA_CM_EVENT_REJECTED:\r
+               dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                            " dapli_cm_active_handler: REJECTED reason=%d\n",\r
+                            event->status);\r
+\r
+               /* valid REJ from consumer will always contain private data */\r
+               if (event->status == 28 &&\r
+                   event->param.conn.private_data_len) {\r
+                       ib_cm_event = IB_CME_DESTINATION_REJECT_PRIVATE_DATA;\r
+                       pdata =\r
+                           (unsigned char *)event->param.conn.\r
+                           private_data +\r
+                           sizeof(struct dapl_pdata_hdr);\r
+               } else {\r
+                       ib_cm_event = IB_CME_DESTINATION_REJECT;\r
+                       dapl_log(DAPL_DBG_TYPE_WARN,\r
+                                "dapl_cma_active: non-consumer REJ,"\r
+                                " reason=%d, DST %s, %d\n",\r
+                                event->status,\r
+                                inet_ntoa(((struct sockaddr_in *)\r
+                                           &conn->cm_id->route.addr.\r
+                                           dst_addr)->sin_addr),\r
+                                ntohs(((struct sockaddr_in *)\r
+                                       &conn->cm_id->route.addr.\r
+                                       dst_addr)->sin_port));\r
+               }\r
+               break;\r
+       case RDMA_CM_EVENT_ESTABLISHED:\r
+               dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                            " active_cb: cm_id %d PORT %d CONNECTED to %s!\n",\r
+                            conn->cm_id, ntohs(((struct sockaddr_in *)\r
+                                                &conn->cm_id->route.addr.\r
+                                                dst_addr)->sin_port),\r
+                            inet_ntoa(((struct sockaddr_in *)\r
+                                       &conn->cm_id->route.addr.dst_addr)->\r
+                                      sin_addr));\r
+\r
+               /* setup local and remote ports for ep query */\r
+               conn->ep->param.remote_port_qual =\r
+                   PORT_TO_SID(rdma_get_dst_port(conn->cm_id));\r
+               conn->ep->param.local_port_qual =\r
+                   PORT_TO_SID(rdma_get_src_port(conn->cm_id));\r
+\r
+               ib_cm_event = IB_CME_CONNECTED;\r
+               pdata = event->param.conn.private_data;\r
+               break;\r
+       case RDMA_CM_EVENT_DISCONNECTED:\r
+               dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                            " active_cb: DISC EVENT - EP %p\n",conn->ep);\r
+               rdma_disconnect(conn->cm_id);   /* required for DREP */\r
+               ib_cm_event = IB_CME_DISCONNECTED;\r
+               /* validate EP handle */\r
+               if (DAPL_BAD_HANDLE(conn->ep, DAPL_MAGIC_EP))\r
+                       conn = NULL;\r
+               break;\r
+       default:\r
+               dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+                            " dapli_cm_active_cb_handler: Unexpected CM "\r
+                            "event %d on ID 0x%p\n", event->event,\r
+                            conn->cm_id);\r
+               conn = NULL;\r
+               break;\r
+       }\r
+\r
+       dapl_os_unlock(lock);\r
+       if (conn)\r
+               dapl_evd_connection_callback(conn, ib_cm_event, pdata, conn->ep);\r
+}\r
+\r
+static void dapli_cm_passive_cb(struct dapl_cm_id *conn,\r
+                               struct rdma_cm_event *event)\r
+{\r
+       ib_cm_events_t ib_cm_event;\r
+       struct dapl_cm_id *conn_recv = conn;\r
+       const void *pdata = NULL;\r
+       \r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " passive_cb: conn %p id %d event %d\n",\r
+                    conn, event->id, event->event);\r
+\r
+       dapl_os_lock(&conn->lock);\r
+\r
+       switch (event->event) {\r
+       case RDMA_CM_EVENT_CONNECT_REQUEST:\r
+               /* create new conn object with new conn_id from event */\r
+               conn_recv = dapli_req_recv(conn, event);\r
+               ib_cm_event = IB_CME_CONNECTION_REQUEST_PENDING;\r
+               pdata = event->param.conn.private_data;\r
+               break;\r
+       case RDMA_CM_EVENT_UNREACHABLE:\r
+       case RDMA_CM_EVENT_CONNECT_ERROR:\r
+               dapl_log(DAPL_DBG_TYPE_WARN,\r
+                        "dapl_cm_passive: CONN_ERR event=0x%x status=%d %s,"\r
+                        " DST %s,%d\n",\r
+                        event->event, event->status,\r
+                        (event->status == -ETIMEDOUT) ? "TIMEOUT" : "",\r
+                        inet_ntoa(((struct sockaddr_in *)\r
+                                   &conn->cm_id->route.addr.dst_addr)->\r
+                                  sin_addr), ntohs(((struct sockaddr_in *)\r
+                                                    &conn->cm_id->route.addr.\r
+                                                    dst_addr)->sin_port));\r
+               ib_cm_event = IB_CME_DESTINATION_UNREACHABLE;\r
+               break;\r
+       case RDMA_CM_EVENT_REJECTED:\r
+               /* will alwasys be abnormal NON-consumer from active side */\r
+               dapl_log(DAPL_DBG_TYPE_WARN,\r
+                        "dapl_cm_passive: non-consumer REJ, reason=%d,"\r
+                        " DST %s, %d\n",\r
+                        event->status,\r
+                        inet_ntoa(((struct sockaddr_in *)\r
+                                   &conn->cm_id->route.addr.dst_addr)->\r
+                                  sin_addr),\r
+                        ntohs(((struct sockaddr_in *)\r
+                               &conn->cm_id->route.addr.dst_addr)->\r
+                              sin_port));\r
+               ib_cm_event = IB_CME_DESTINATION_REJECT;\r
+               break;\r
+       case RDMA_CM_EVENT_ESTABLISHED:\r
+               dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                            " passive_cb: cm_id %p PORT %d CONNECTED from 0x%x!\n",\r
+                            conn->cm_id, ntohs(((struct sockaddr_in *)\r
+                                                &conn->cm_id->route.addr.\r
+                                                src_addr)->sin_port),\r
+                            ntohl(((struct sockaddr_in *)\r
+                                   &conn->cm_id->route.addr.dst_addr)->\r
+                                  sin_addr.s_addr));\r
+               ib_cm_event = IB_CME_CONNECTED;\r
+               break;\r
+       case RDMA_CM_EVENT_DISCONNECTED:\r
+               rdma_disconnect(conn->cm_id);   /* required for DREP */\r
+               ib_cm_event = IB_CME_DISCONNECTED;\r
+               /* validate SP handle context */\r
+               if (DAPL_BAD_HANDLE(conn->sp, DAPL_MAGIC_PSP) &&\r
+                   DAPL_BAD_HANDLE(conn->sp, DAPL_MAGIC_RSP))\r
+                       conn_recv = NULL;\r
+               break;\r
+       default:\r
+               dapl_dbg_log(DAPL_DBG_TYPE_ERR, " passive_cb: "\r
+                            "Unexpected CM event %d on ID 0x%p\n",\r
+                            event->event, conn->cm_id);\r
+               conn_recv = NULL;\r
+               break;\r
+       }\r
+\r
+       dapl_os_unlock(&conn->lock);\r
+       if (conn_recv)\r
+               dapls_cr_callback(conn_recv, ib_cm_event, pdata, conn_recv->sp);\r
+}\r
+\r
+/************************ DAPL provider entry points **********************/\r
+\r
+/*\r
+ * dapls_ib_connect\r
+ *\r
+ * Initiate a connection with the passive listener on another node\r
+ *\r
+ * Input:\r
+ *     ep_handle,\r
+ *     remote_ia_address,\r
+ *     remote_conn_qual,\r
+ *     prd_size                size of private data and structure\r
+ *     prd_prt                 pointer to private data structure\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *     DAT_INVALID_PARAMETER\r
+ *\r
+ */\r
+DAT_RETURN dapls_ib_connect(IN DAT_EP_HANDLE ep_handle,\r
+                           IN DAT_IA_ADDRESS_PTR r_addr,\r
+                           IN DAT_CONN_QUAL r_qual,\r
+                           IN DAT_COUNT p_size, IN void *p_data)\r
+{\r
+       struct dapl_ep *ep_ptr = ep_handle;\r
+       struct dapl_cm_id *conn = ep_ptr->cm_handle;\r
+       int ret;\r
+\r
+       /* Sanity check */\r
+       if (NULL == ep_ptr)\r
+               return DAT_SUCCESS;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " connect: rSID 0x%llx rPort %d, pdata %p, ln %d\n",\r
+                    r_qual, ntohs(SID_TO_PORT(r_qual)), p_data, p_size);\r
+\r
+       /* rdma conn and cm_id pre-bound; reference via ep_ptr->cm_handle */\r
+\r
+       /* Setup QP/CM parameters and private data in cm_id */\r
+       (void)dapl_os_memzero(&conn->params, sizeof(conn->params));\r
+       conn->params.responder_resources =\r
+           ep_ptr->param.ep_attr.max_rdma_read_in;\r
+       conn->params.initiator_depth = ep_ptr->param.ep_attr.max_rdma_read_out;\r
+       conn->params.flow_control = 1;\r
+       conn->params.rnr_retry_count = IB_RNR_RETRY_COUNT;\r
+       conn->params.retry_count = IB_RC_RETRY_COUNT;\r
+       if (p_size) {\r
+               dapl_os_memcpy(conn->p_data, p_data, p_size);\r
+               conn->params.private_data = conn->p_data;\r
+               conn->params.private_data_len = p_size;\r
+       }\r
+\r
+       /* copy in remote address, need a copy for retry attempts */\r
+       dapl_os_memcpy(&conn->r_addr, r_addr, sizeof(*r_addr));\r
+\r
+       /* Resolve remote address, src already bound during QP create */\r
+       ((struct sockaddr_in *)&conn->r_addr)->sin_port = SID_TO_PORT(r_qual);\r
+       ((struct sockaddr_in *)&conn->r_addr)->sin_family = AF_INET;\r
+\r
+       ret = rdma_resolve_addr(conn->cm_id, NULL,\r
+                               (struct sockaddr *)&conn->r_addr,\r
+                               conn->arp_timeout);\r
+       if (ret) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " dapl_cma_connect: rdma_resolve_addr ERR 0x%x %s\n",\r
+                        ret, strerror(errno));\r
+               return dapl_convert_errno(errno, "ib_connect");\r
+       }\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " connect: resolve_addr: cm_id %p -> %s port %d\n",\r
+                    conn->cm_id,\r
+                    inet_ntoa(((struct sockaddr_in *)&conn->r_addr)->sin_addr),\r
+                    ((struct sockaddr_in *)&conn->r_addr)->sin_port);\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * dapls_ib_disconnect\r
+ *\r
+ * Disconnect an EP\r
+ *\r
+ * Input:\r
+ *     ep_handle,\r
+ *     disconnect_flags\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_disconnect(IN DAPL_EP * ep_ptr, IN DAT_CLOSE_FLAGS close_flags)\r
+{\r
+       dp_ib_cm_handle_t conn = ep_ptr->cm_handle;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " disconnect(ep %p, conn %p, id %d flags %x)\n",\r
+                    ep_ptr, conn, (conn ? conn->cm_id : 0), close_flags);\r
+\r
+       if ((conn == IB_INVALID_HANDLE) || (conn->cm_id == NULL))\r
+               return DAT_SUCCESS;\r
+\r
+       /* no graceful half-pipe disconnect option */\r
+       rdma_disconnect(conn->cm_id);\r
+\r
+       /* \r
+        * DAT event notification occurs from the callback\r
+        * Note: will fire even if DREQ goes unanswered on timeout \r
+        */\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * dapls_ib_disconnect_clean\r
+ *\r
+ * Clean up outstanding connection data. This routine is invoked\r
+ * after the final disconnect callback has occurred. Only on the\r
+ * ACTIVE side of a connection.\r
+ *\r
+ * Input:\r
+ *     ep_ptr          DAPL_EP\r
+ *     active          Indicates active side of connection\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     void\r
+ *\r
+ */\r
+void\r
+dapls_ib_disconnect_clean(IN DAPL_EP * ep_ptr,\r
+                         IN DAT_BOOLEAN active,\r
+                         IN const ib_cm_events_t ib_cm_event)\r
+{\r
+       /* nothing to do */\r
+       return;\r
+}\r
+\r
+/*\r
+ * dapl_ib_setup_conn_listener\r
+ *\r
+ * Have the CM set up a connection listener.\r
+ *\r
+ * Input:\r
+ *     ibm_hca_handle          HCA handle\r
+ *     qp_handle                       QP handle\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *     DAT_INTERNAL_ERROR\r
+ *     DAT_CONN_QUAL_UNAVAILBLE\r
+ *     DAT_CONN_QUAL_IN_USE\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_setup_conn_listener(IN DAPL_IA * ia_ptr,\r
+                            IN DAT_UINT64 ServiceID, IN DAPL_SP * sp_ptr)\r
+{\r
+       DAT_RETURN dat_status = DAT_SUCCESS;\r
+       ib_cm_srvc_handle_t conn;\r
+       DAT_SOCK_ADDR6 addr;    /* local binding address */\r
+\r
+       /* Allocate CM and initialize lock */\r
+       if ((conn = dapl_os_alloc(sizeof(*conn))) == NULL)\r
+               return DAT_INSUFFICIENT_RESOURCES;\r
+\r
+       dapl_os_memzero(conn, sizeof(*conn));\r
+       dapl_os_lock_init(&conn->lock);\r
+       conn->refs++;\r
+\r
+       /* create CM_ID, bind to local device, create QP */\r
+       if (rdma_create_id\r
+           (g_cm_events, &conn->cm_id, (void *)conn, RDMA_PS_TCP)) {\r
+               dapl_os_free(conn, sizeof(*conn));\r
+               return (dapl_convert_errno(errno, "setup_listener"));\r
+       }\r
+\r
+       /* open identifies the local device; per DAT specification */\r
+       /* Get family and address then set port to consumer's ServiceID */\r
+       dapl_os_memcpy(&addr, &ia_ptr->hca_ptr->hca_address, sizeof(addr));\r
+       ((struct sockaddr_in *)&addr)->sin_port = SID_TO_PORT(ServiceID);\r
+\r
+       if (rdma_bind_addr(conn->cm_id, (struct sockaddr *)&addr)) {\r
+               if ((errno == EBUSY) || (errno == EADDRINUSE) || \r
+                   (errno == EADDRNOTAVAIL))\r
+                       dat_status = DAT_CONN_QUAL_IN_USE;\r
+               else\r
+                       dat_status =\r
+                           dapl_convert_errno(errno, "setup_listener");\r
+               goto bail;\r
+       }\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " listen(ia_ptr %p SID 0x%llx Port %d sp %p conn %p id %d)\n",\r
+                    ia_ptr, ServiceID, ntohs(SID_TO_PORT(ServiceID)),\r
+                    sp_ptr, conn, conn->cm_id);\r
+\r
+       sp_ptr->cm_srvc_handle = conn;\r
+       conn->sp = sp_ptr;\r
+       conn->hca = ia_ptr->hca_ptr;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_EP,\r
+                    " listen(conn=%p cm_id=%d)\n",\r
+                    sp_ptr->cm_srvc_handle, conn->cm_id);\r
+\r
+       if (rdma_listen(conn->cm_id, 0)) {      /* max cma backlog */\r
+\r
+               if ((errno == EBUSY) || (errno == EADDRINUSE) ||\r
+                   (errno == EADDRNOTAVAIL))\r
+                       dat_status = DAT_CONN_QUAL_IN_USE;\r
+               else\r
+                       dat_status =\r
+                           dapl_convert_errno(errno, "setup_listener");\r
+               goto bail;\r
+       }\r
+\r
+       /* success */\r
+       return DAT_SUCCESS;\r
+\r
+      bail:\r
+       rdma_destroy_id(conn->cm_id);\r
+       dapl_os_free(conn, sizeof(*conn));\r
+       return dat_status;\r
+}\r
+\r
+/*\r
+ * dapl_ib_remove_conn_listener\r
+ *\r
+ * Have the CM remove a connection listener.\r
+ *\r
+ * Input:\r
+ *     ia_handle               IA handle\r
+ *     ServiceID               IB Channel Service ID\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INVALID_STATE\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_remove_conn_listener(IN DAPL_IA * ia_ptr, IN DAPL_SP * sp_ptr)\r
+{\r
+       ib_cm_srvc_handle_t conn = sp_ptr->cm_srvc_handle;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " remove_listen(ia_ptr %p sp_ptr %p cm_ptr %p)\n",\r
+                    ia_ptr, sp_ptr, conn);\r
+\r
+       if (conn != IB_INVALID_HANDLE) {\r
+               sp_ptr->cm_srvc_handle = NULL;\r
+               dapls_ib_cm_free(conn, NULL);\r
+       }\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * dapls_ib_accept_connection\r
+ *\r
+ * Perform necessary steps to accept a connection\r
+ *\r
+ * Input:\r
+ *     cr_handle\r
+ *     ep_handle\r
+ *     private_data_size\r
+ *     private_data\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *     DAT_INTERNAL_ERROR\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_accept_connection(IN DAT_CR_HANDLE cr_handle,\r
+                          IN DAT_EP_HANDLE ep_handle,\r
+                          IN DAT_COUNT p_size, IN const DAT_PVOID p_data)\r
+{\r
+       DAPL_CR *cr_ptr = (DAPL_CR *) cr_handle;\r
+       DAPL_EP *ep_ptr = (DAPL_EP *) ep_handle;\r
+       DAPL_IA *ia_ptr = ep_ptr->header.owner_ia;\r
+       struct dapl_cm_id *cr_conn = cr_ptr->ib_cm_handle;\r
+       int ret;\r
+       DAT_RETURN dat_status;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " accept(cr %p conn %p, id %p, p_data %p, p_sz=%d)\n",\r
+                    cr_ptr, cr_conn, cr_conn->cm_id, p_data, p_size);\r
+\r
+       /* Obtain size of private data structure & contents */\r
+       if (p_size > IB_MAX_REP_PDATA_SIZE) {\r
+               dat_status = DAT_ERROR(DAT_LENGTH_ERROR, DAT_NO_SUBTYPE);\r
+               goto bail;\r
+       }\r
+\r
+       if (ep_ptr->qp_state == DAPL_QP_STATE_UNATTACHED) {\r
+               /* \r
+                * If we are lazy attaching the QP then we may need to\r
+                * hook it up here. Typically, we run this code only for\r
+                * DAT_PSP_PROVIDER_FLAG\r
+                */\r
+               dat_status = dapls_ib_qp_alloc(ia_ptr, ep_ptr, NULL);\r
+               if (dat_status != DAT_SUCCESS) {\r
+                       dapl_log(DAPL_DBG_TYPE_ERR,\r
+                                " dapl_cma_accept: qp_alloc ERR %d\n",\r
+                                dat_status);\r
+                       goto bail;\r
+               }\r
+       }\r
+\r
+       /* \r
+        * Validate device and port in EP cm_id against inbound \r
+        * CR cm_id. The pre-allocated EP cm_id is already bound to \r
+        * a local device (cm_id and QP) when created. Move the QP\r
+        * to the new cm_id only if device and port numbers match.\r
+        */\r
+       if (ep_ptr->cm_handle->cm_id->verbs == cr_conn->cm_id->verbs &&\r
+           ep_ptr->cm_handle->cm_id->port_num == cr_conn->cm_id->port_num) {\r
+               /* move QP to new cr_conn, remove QP ref in EP cm_id */\r
+               cr_conn->cm_id->qp = ep_ptr->cm_handle->cm_id->qp;\r
+               ep_ptr->cm_handle->cm_id->qp = NULL;\r
+               dapls_ib_cm_free(ep_ptr->cm_handle, NULL);\r
+       } else {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " dapl_cma_accept: ERR dev(%p!=%p) or"\r
+                        " port mismatch(%d!=%d)\n",\r
+                        ep_ptr->cm_handle->cm_id->verbs, cr_conn->cm_id->verbs,\r
+                        ntohs(ep_ptr->cm_handle->cm_id->port_num),\r
+                        ntohs(cr_conn->cm_id->port_num));\r
+               dat_status = DAT_INTERNAL_ERROR;\r
+               goto bail;\r
+       }\r
+\r
+       cr_ptr->param.local_ep_handle = ep_handle;\r
+       cr_conn->params.private_data = p_data;\r
+       cr_conn->params.private_data_len = p_size;\r
+\r
+       ret = rdma_accept(cr_conn->cm_id, &cr_conn->params);\r
+       if (ret) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR, " dapl_cma_accept: ERR %d %s\n",\r
+                        ret, strerror(errno));\r
+               dat_status = dapl_convert_errno(ret, "accept");\r
+               goto bail;\r
+       }\r
+\r
+       /* save accepted conn and EP reference, qp_handle unchanged */\r
+       ep_ptr->cm_handle = cr_conn;\r
+       cr_conn->ep = ep_ptr;\r
+\r
+       /* setup local and remote ports for ep query */\r
+       /* Note: port qual in network order */\r
+       ep_ptr->param.remote_port_qual =\r
+           PORT_TO_SID(rdma_get_dst_port(cr_conn->cm_id));\r
+       ep_ptr->param.local_port_qual =\r
+           PORT_TO_SID(rdma_get_src_port(cr_conn->cm_id));\r
+\r
+       return DAT_SUCCESS;\r
+      bail:\r
+       rdma_reject(cr_conn->cm_id, NULL, 0);\r
+       dapls_ib_cm_free(cr_conn, NULL);\r
+       return dat_status;\r
+}\r
+\r
+/*\r
+ * dapls_ib_reject_connection\r
+ *\r
+ * Reject a connection\r
+ *\r
+ * Input:\r
+ *     cr_handle\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INTERNAL_ERROR\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_reject_connection(IN dp_ib_cm_handle_t cm_handle,\r
+                          IN int reason,\r
+                          IN DAT_COUNT private_data_size,\r
+                          IN const DAT_PVOID private_data)\r
+{\r
+       int ret;\r
+       int offset = sizeof(struct dapl_pdata_hdr);\r
+       struct dapl_pdata_hdr pdata_hdr;\r
+\r
+       memset(&pdata_hdr, 0, sizeof pdata_hdr);\r
+       pdata_hdr.version = htonl((DAT_VERSION_MAJOR << 24) |\r
+                                 (DAT_VERSION_MINOR << 16) |\r
+                                 (VN_PROVIDER_MAJOR << 8) |\r
+                                 (VN_PROVIDER_MINOR));\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " reject: handle %p reason %x, ver=%x, data %p, sz=%d\n",\r
+                    cm_handle, reason, ntohl(pdata_hdr.version),\r
+                    private_data, private_data_size);\r
+\r
+       if (cm_handle == IB_INVALID_HANDLE) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+                            " reject: invalid handle: reason %d\n", reason);\r
+               return DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_CR);\r
+       }\r
+\r
+       if (private_data_size >\r
+           dapls_ib_private_data_size(NULL, DAPL_PDATA_CONN_REJ,\r
+                                      cm_handle->hca))\r
+               return DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3);\r
+\r
+       /* setup pdata_hdr and users data, in CR pdata buffer */\r
+       dapl_os_memcpy(cm_handle->p_data, &pdata_hdr, offset);\r
+       if (private_data_size)\r
+               dapl_os_memcpy(cm_handle->p_data + offset,\r
+                              private_data, private_data_size);\r
+\r
+       /*\r
+        * Always some private data with reject so active peer can\r
+        * determine real application reject from an abnormal \r
+        * application termination\r
+        */\r
+       ret = rdma_reject(cm_handle->cm_id,\r
+                         cm_handle->p_data, offset + private_data_size);\r
+\r
+       dapls_ib_cm_free(cm_handle, NULL);\r
+       return dapl_convert_errno(ret, "reject");\r
+}\r
+\r
+/*\r
+ * dapls_ib_cm_remote_addr\r
+ *\r
+ * Obtain the remote IP address given a connection\r
+ *\r
+ * Input:\r
+ *     cr_handle\r
+ *\r
+ * Output:\r
+ *     remote_ia_address: where to place the remote address\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INVALID_HANDLE\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_cm_remote_addr(IN DAT_HANDLE dat_handle, OUT DAT_SOCK_ADDR6 * raddr)\r
+{\r
+       DAPL_HEADER *header;\r
+       dp_ib_cm_handle_t ib_cm_handle;\r
+       struct rdma_addr *ipaddr;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_EP,\r
+                    " remote_addr(cm_handle=%p, r_addr=%p)\n",\r
+                    dat_handle, raddr);\r
+\r
+       header = (DAPL_HEADER *) dat_handle;\r
+\r
+       if (header->magic == DAPL_MAGIC_EP)\r
+               ib_cm_handle = ((DAPL_EP *) dat_handle)->cm_handle;\r
+       else if (header->magic == DAPL_MAGIC_CR)\r
+               ib_cm_handle = ((DAPL_CR *) dat_handle)->ib_cm_handle;\r
+       else\r
+               return DAT_INVALID_HANDLE;\r
+\r
+       /* get remote IP address from cm_id route */\r
+       ipaddr = &ib_cm_handle->cm_id->route.addr;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " remote_addr: conn %p id %p SRC %x DST %x PORT %d\n",\r
+                    ib_cm_handle, ib_cm_handle->cm_id,\r
+                    ntohl(((struct sockaddr_in *)\r
+                           &ipaddr->src_addr)->sin_addr.s_addr),\r
+                    ntohl(((struct sockaddr_in *)\r
+                           &ipaddr->dst_addr)->sin_addr.s_addr),\r
+                    ntohs(((struct sockaddr_in *)\r
+                           &ipaddr->dst_addr)->sin_port));\r
+\r
+       dapl_os_memcpy(raddr, &ipaddr->dst_addr, sizeof(DAT_SOCK_ADDR));\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * dapls_ib_private_data_size\r
+ *\r
+ * Return the size of private data given a connection op type\r
+ *\r
+ * Input:\r
+ *     prd_ptr         private data pointer\r
+ *     conn_op         connection operation type\r
+ *      hca_ptr         hca pointer, needed for transport type\r
+ *\r
+ * If prd_ptr is NULL, this is a query for the max size supported by\r
+ * the provider, otherwise it is the actual size of the private data\r
+ * contained in prd_ptr.\r
+ *\r
+ *\r
+ * Output:\r
+ *     None\r
+ *\r
+ * Returns:\r
+ *     length of private data\r
+ *\r
+ */\r
+int dapls_ib_private_data_size(IN DAPL_PRIVATE * prd_ptr,\r
+                              IN DAPL_PDATA_OP conn_op, IN DAPL_HCA * hca_ptr)\r
+{\r
+       int size;\r
+\r
+       if (hca_ptr->ib_hca_handle->device->transport_type\r
+           == IBV_TRANSPORT_IWARP)\r
+               return (IWARP_MAX_PDATA_SIZE - sizeof(struct dapl_pdata_hdr));\r
+\r
+       switch (conn_op) {\r
+\r
+       case DAPL_PDATA_CONN_REQ:\r
+               size = IB_MAX_REQ_PDATA_SIZE;\r
+               break;\r
+       case DAPL_PDATA_CONN_REP:\r
+               size = IB_MAX_REP_PDATA_SIZE;\r
+               break;\r
+       case DAPL_PDATA_CONN_REJ:\r
+               size = IB_MAX_REJ_PDATA_SIZE - sizeof(struct dapl_pdata_hdr);\r
+               break;\r
+       case DAPL_PDATA_CONN_DREQ:\r
+               size = IB_MAX_DREQ_PDATA_SIZE;\r
+               break;\r
+       case DAPL_PDATA_CONN_DREP:\r
+               size = IB_MAX_DREP_PDATA_SIZE;\r
+               break;\r
+       default:\r
+               size = 0;\r
+\r
+       }                       /* end case */\r
+\r
+       return size;\r
+}\r
+\r
+/*\r
+ * Map all CMA event codes to the DAT equivelent.\r
+ */\r
+#define DAPL_IB_EVENT_CNT      13\r
+\r
+static struct ib_cm_event_map {\r
+       const ib_cm_events_t ib_cm_event;\r
+       DAT_EVENT_NUMBER dat_event_num;\r
+} ib_cm_event_map[DAPL_IB_EVENT_CNT] = {\r
+       /* 00 */  {\r
+       IB_CME_CONNECTED, DAT_CONNECTION_EVENT_ESTABLISHED},\r
+           /* 01 */  {\r
+       IB_CME_DISCONNECTED, DAT_CONNECTION_EVENT_DISCONNECTED},\r
+           /* 02 */  {\r
+       IB_CME_DISCONNECTED_ON_LINK_DOWN,\r
+                   DAT_CONNECTION_EVENT_DISCONNECTED},\r
+           /* 03 */  {\r
+       IB_CME_CONNECTION_REQUEST_PENDING, DAT_CONNECTION_REQUEST_EVENT},\r
+           /* 04 */  {\r
+       IB_CME_CONNECTION_REQUEST_PENDING_PRIVATE_DATA,\r
+                   DAT_CONNECTION_REQUEST_EVENT},\r
+           /* 05 */  {\r
+       IB_CME_CONNECTION_REQUEST_ACKED, DAT_CONNECTION_REQUEST_EVENT},\r
+           /* 06 */  {\r
+       IB_CME_DESTINATION_REJECT,\r
+                   DAT_CONNECTION_EVENT_NON_PEER_REJECTED},\r
+           /* 07 */  {\r
+       IB_CME_DESTINATION_REJECT_PRIVATE_DATA,\r
+                   DAT_CONNECTION_EVENT_PEER_REJECTED},\r
+           /* 08 */  {\r
+       IB_CME_DESTINATION_UNREACHABLE, DAT_CONNECTION_EVENT_UNREACHABLE},\r
+           /* 09 */  {\r
+       IB_CME_TOO_MANY_CONNECTION_REQUESTS,\r
+                   DAT_CONNECTION_EVENT_NON_PEER_REJECTED},\r
+           /* 10 */  {\r
+       IB_CME_LOCAL_FAILURE, DAT_CONNECTION_EVENT_BROKEN},\r
+           /* 11 */  {\r
+       IB_CME_BROKEN, DAT_CONNECTION_EVENT_BROKEN},\r
+           /* 12 */  {\r
+IB_CME_TIMEOUT, DAT_CONNECTION_EVENT_TIMED_OUT},};\r
+\r
+/*\r
+ * dapls_ib_get_cm_event\r
+ *\r
+ * Return a DAT connection event given a provider CM event.\r
+ *\r
+ * Input:\r
+ *     dat_event_num   DAT event we need an equivelent CM event for\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     ib_cm_event of translated DAPL value\r
+ */\r
+DAT_EVENT_NUMBER\r
+dapls_ib_get_dat_event(IN const ib_cm_events_t ib_cm_event,\r
+                      IN DAT_BOOLEAN active)\r
+{\r
+       DAT_EVENT_NUMBER dat_event_num;\r
+       int i;\r
+\r
+       active = active;\r
+\r
+       dat_event_num = 0;\r
+       for (i = 0; i < DAPL_IB_EVENT_CNT; i++) {\r
+               if (ib_cm_event == ib_cm_event_map[i].ib_cm_event) {\r
+                       dat_event_num = ib_cm_event_map[i].dat_event_num;\r
+                       break;\r
+               }\r
+       }\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,\r
+                    "dapls_ib_get_dat_event: event(%s) ib=0x%x dat=0x%x\n",\r
+                    active ? "active" : "passive", ib_cm_event, dat_event_num);\r
+\r
+       return dat_event_num;\r
+}\r
+\r
+/*\r
+ * dapls_ib_get_dat_event\r
+ *\r
+ * Return a DAT connection event given a provider CM event.\r
+ * \r
+ * Input:\r
+ *     ib_cm_event     event provided to the dapl callback routine\r
+ *     active          switch indicating active or passive connection\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_EVENT_NUMBER of translated provider value\r
+ */\r
+ib_cm_events_t dapls_ib_get_cm_event(IN DAT_EVENT_NUMBER dat_event_num)\r
+{\r
+       ib_cm_events_t ib_cm_event;\r
+       int i;\r
+\r
+       ib_cm_event = 0;\r
+       for (i = 0; i < DAPL_IB_EVENT_CNT; i++) {\r
+               if (dat_event_num == ib_cm_event_map[i].dat_event_num) {\r
+                       ib_cm_event = ib_cm_event_map[i].ib_cm_event;\r
+                       break;\r
+               }\r
+       }\r
+       return ib_cm_event;\r
+}\r
+\r
+void dapli_cma_event_cb(void)\r
+{\r
+       struct rdma_cm_event *event;\r
+                               \r
+       /* process one CM event, fairness, non-blocking */\r
+       if (!rdma_get_cm_event(g_cm_events, &event)) {\r
+               struct dapl_cm_id *conn;\r
+\r
+               /* set proper conn from cm_id context */\r
+               if (event->event == RDMA_CM_EVENT_CONNECT_REQUEST)\r
+                       conn = (struct dapl_cm_id *)event->listen_id->context;\r
+               else\r
+                       conn = (struct dapl_cm_id *)event->id->context;\r
+\r
+               dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                            " cm_event: EVENT=%d ID=%p LID=%p CTX=%p\n",\r
+                            event->event, event->id, event->listen_id, conn);\r
+               \r
+               /* cm_free is blocked waiting for ack  */\r
+               dapl_os_lock(&conn->lock);\r
+               if (!conn->refs) {\r
+                       dapl_os_unlock(&conn->lock);\r
+                       rdma_ack_cm_event(event);\r
+                       return;\r
+               }\r
+               conn->refs++;\r
+               dapl_os_unlock(&conn->lock);\r
+\r
+               switch (event->event) {\r
+               case RDMA_CM_EVENT_ADDR_RESOLVED:\r
+                       dapli_addr_resolve(conn);\r
+                       break;\r
+\r
+               case RDMA_CM_EVENT_ROUTE_RESOLVED:\r
+                       dapli_route_resolve(conn);\r
+                       break;\r
+\r
+               case RDMA_CM_EVENT_ADDR_ERROR:\r
+                       dapl_log(DAPL_DBG_TYPE_WARN,\r
+                                "dapl_cma_active: CM ADDR ERROR: ->"\r
+                                " DST %s retry (%d)..\n",\r
+                                inet_ntoa(((struct sockaddr_in *)\r
+                                           &conn->r_addr)->sin_addr),\r
+                                conn->arp_retries);\r
+\r
+                       /* retry address resolution */\r
+                       if ((--conn->arp_retries) &&\r
+                           (event->status == -ETIMEDOUT)) {\r
+                               int ret;\r
+                               ret = rdma_resolve_addr(conn->cm_id, NULL,\r
+                                                       (struct sockaddr *)\r
+                                                       &conn->r_addr,\r
+                                                       conn->arp_timeout);\r
+                               if (!ret)\r
+                                       break;\r
+                               else {\r
+                                       dapl_dbg_log(DAPL_DBG_TYPE_WARN,\r
+                                                    " ERROR: rdma_resolve_addr = "\r
+                                                    "%d %s\n",\r
+                                                    ret, strerror(errno));\r
+                               }\r
+                       }\r
+                       /* retries exhausted or resolve_addr failed */\r
+                       dapl_log(DAPL_DBG_TYPE_ERR,\r
+                                "dapl_cma_active: ARP_ERR, retries(%d)"\r
+                                " exhausted -> DST %s,%d\n",\r
+                                IB_ARP_RETRY_COUNT,\r
+                                inet_ntoa(((struct sockaddr_in *)\r
+                                           &conn->cm_id->route.addr.dst_addr)->\r
+                                          sin_addr),\r
+                                ntohs(((struct sockaddr_in *)\r
+                                       &conn->cm_id->route.addr.dst_addr)->\r
+                                      sin_port));\r
+\r
+                       dapl_evd_connection_callback(conn,\r
+                                                    IB_CME_DESTINATION_UNREACHABLE,\r
+                                                    NULL, conn->ep);\r
+                       break;\r
+\r
+               case RDMA_CM_EVENT_ROUTE_ERROR:\r
+                       dapl_log(DAPL_DBG_TYPE_WARN,\r
+                                "dapl_cma_active: CM ROUTE ERROR: ->"\r
+                                " DST %s retry (%d)..\n",\r
+                                inet_ntoa(((struct sockaddr_in *)\r
+                                           &conn->r_addr)->sin_addr),\r
+                                conn->route_retries);\r
+\r
+                       /* retry route resolution */\r
+                       if ((--conn->route_retries) &&\r
+                           (event->status == -ETIMEDOUT))\r
+                               dapli_addr_resolve(conn);\r
+                       else {\r
+                               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                                        "dapl_cma_active: PATH_RECORD_ERR,"\r
+                                        " retries(%d) exhausted, DST %s,%d\n",\r
+                                        IB_ROUTE_RETRY_COUNT,\r
+                                        inet_ntoa(((struct sockaddr_in *)\r
+                                                   &conn->cm_id->route.addr.\r
+                                                   dst_addr)->sin_addr),\r
+                                        ntohs(((struct sockaddr_in *)\r
+                                               &conn->cm_id->route.addr.\r
+                                               dst_addr)->sin_port));\r
+\r
+                               dapl_evd_connection_callback(conn,\r
+                                                            IB_CME_DESTINATION_UNREACHABLE,\r
+                                                            NULL, conn->ep);\r
+                       }\r
+                       break;\r
+\r
+               case RDMA_CM_EVENT_DEVICE_REMOVAL:\r
+                       dapl_evd_connection_callback(conn,\r
+                                                    IB_CME_LOCAL_FAILURE,\r
+                                                    NULL, conn->ep);\r
+                       break;\r
+               case RDMA_CM_EVENT_CONNECT_REQUEST:\r
+               case RDMA_CM_EVENT_CONNECT_ERROR:\r
+               case RDMA_CM_EVENT_UNREACHABLE:\r
+               case RDMA_CM_EVENT_REJECTED:\r
+               case RDMA_CM_EVENT_ESTABLISHED:\r
+               case RDMA_CM_EVENT_DISCONNECTED:\r
+                       /* passive or active */\r
+                       if (conn->sp)\r
+                               dapli_cm_passive_cb(conn, event);\r
+                       else\r
+                               dapli_cm_active_cb(conn, event);\r
+                       break;\r
+               case RDMA_CM_EVENT_CONNECT_RESPONSE:\r
+#ifdef RDMA_CM_EVENT_TIMEWAIT_EXIT\r
+               case RDMA_CM_EVENT_TIMEWAIT_EXIT:\r
+#endif\r
+                       break;\r
+               default:\r
+                       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                                    " cm_event: UNEXPECTED EVENT=%p ID=%p CTX=%p\n",\r
+                                    event->event, event->id,\r
+                                    event->id->context);\r
+                       break;\r
+               }\r
+               \r
+               /* ack event, unblocks destroy_cm_id in consumer threads */\r
+               rdma_ack_cm_event(event);\r
+\r
+               dapl_os_lock(&conn->lock);\r
+                conn->refs--;\r
+               dapl_os_unlock(&conn->lock);\r
+       } \r
+}\r
+\r
+/*\r
+ * Local variables:\r
+ *  c-indent-level: 4\r
+ *  c-basic-offset: 4\r
+ *  tab-width: 8\r
+ * End:\r
+ */\r
index d008fc0..581b908 100644 (file)
@@ -3,3 +3,7 @@
 \r
 #define ntohll _byteswap_uint64\r
 #define htonll _byteswap_uint64\r
+\r
+#ifndef EADDRNOTAVAIL\r
+#define EADDRNOTAVAIL  WSAEADDRNOTAVAIL\r
+#endif\r
index 836dd76..fd6884b 100644 (file)
@@ -711,7 +711,8 @@ static void ucm_ud_free(DAPL_EP *ep)
 void dapls_ib_cm_free(dp_ib_cm_handle_t cm, DAPL_EP *ep)\r
 {\r
        dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
-                    " cm_destroy: cm %p ep %p\n", cm, ep);\r
+                    " cm_destroy: %s cm %p ep %p\n",\r
+                    cm ? dapl_cm_state_str(cm->state) : "", cm, ep);\r
 \r
        if (!cm && ep) {\r
                ucm_ud_free(ep);\r
@@ -813,6 +814,10 @@ DAT_RETURN dapli_cm_disconnect(dp_ib_cm_handle_t cm)
        dapl_os_lock(&cm->lock);\r
        switch (cm->state) {\r
        case DCM_CONNECTED:\r
+               /* CONSUMER: move to err state to flush, if not UD */\r
+               if (cm->ep->qp_handle->qp_type != IBV_QPT_UD) \r
+                       dapls_modify_qp_state(cm->ep->qp_handle, IBV_QPS_ERR,0,0,0);\r
+\r
                /* send DREQ, event after DREP or DREQ timeout */\r
                cm->state = DCM_DISC_PENDING;\r
                cm->msg.op = htons(DCM_DREQ);\r
@@ -836,6 +841,10 @@ DAT_RETURN dapli_cm_disconnect(dp_ib_cm_handle_t cm)
                }\r
                break;\r
        case DCM_DISC_RECV:\r
+               /* CM_THREAD: move to err state to flush, if not UD */\r
+               if (cm->ep->qp_handle->qp_type != IBV_QPT_UD) \r
+                       dapls_modify_qp_state(cm->ep->qp_handle, IBV_QPS_ERR,0,0,0);\r
+\r
                /* DREQ received, send DREP and schedule event */\r
                cm->msg.op = htons(DCM_DREP);\r
                break;\r
@@ -1547,10 +1556,6 @@ dapls_ib_disconnect(IN DAPL_EP *ep, IN DAT_CLOSE_FLAGS close_flags)
        dapl_dbg_log(DAPL_DBG_TYPE_EP,\r
                     "dapls_ib_disconnect(ep_handle %p ....)\n", ep);\r
 \r
-       /* move to err state to flush, if not UD */\r
-       if (ep->qp_handle->qp_type != IBV_QPT_UD) \r
-               dapls_modify_qp_state(ep->qp_handle, IBV_QPS_ERR,0,0,0);\r
-       \r
        if (ep->cm_handle == NULL ||\r
            ep->param.ep_state == DAT_EP_STATE_DISCONNECTED)\r
                return DAT_SUCCESS;\r
index 0b5051d..2683609 100644 (file)
@@ -14,8 +14,8 @@ SOURCES = \
        dtest.c
        
 INCLUDES = ..\..\..\..\dat\include;..\..\..\..\..\..\inc;\
-       ..\..\..\..\..\..\inc\user;\
-       ..\..\..\..\..\..\inc\user\linux;
+          ..\..\..\..\..\..\inc\user;\
+          ..\..\..\..\..\..\inc\user\linux;
 
 RCOPTIONS=/I..\..\..\..\..\..\inc;
 
index 1ed1771..f3d9238 100644 (file)
@@ -1,4 +1,4 @@
-#include "..\..\..\..\..\..\etc\user\gtod.c"
 #include "..\..\..\..\..\..\etc\user\inet.c"
+#include "..\..\..\..\..\..\etc\user\gtod.c"
 #include "..\..\dtest.c"