]> git.openfabrics.org - ~shefty/rdma-win.git/commitdiff
dapl: update to commit 455e9d6d0aeb753a9ecb4a130b0b237e1ffd4146
authorSean Hefty <sean.hefty@intel.com>
Thu, 1 Jul 2010 04:07:23 +0000 (04:07 +0000)
committerSean Hefty <sean.hefty@intel.com>
Thu, 1 Jul 2010 04:07:23 +0000 (04:07 +0000)
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
git-svn-id: svn://openib.tc.cornell.edu/gen1@2842 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

36 files changed:
trunk/ulp/dapl2/ChangeLog
trunk/ulp/dapl2/Makefile.am
trunk/ulp/dapl2/configure.in
trunk/ulp/dapl2/dapl.spec.in
trunk/ulp/dapl2/dapl/common/dapl_cr_util.c
trunk/ulp/dapl2/dapl/common/dapl_ep_connect.c
trunk/ulp/dapl2/dapl/common/dapl_ep_free.c
trunk/ulp/dapl2/dapl/common/dapl_ep_util.c
trunk/ulp/dapl2/dapl/common/dapl_evd_util.c
trunk/ulp/dapl2/dapl/common/dapl_hca_util.c
trunk/ulp/dapl2/dapl/common/dapl_lmr_free.c
trunk/ulp/dapl2/dapl/common/dapl_rmr_bind.c
trunk/ulp/dapl2/dapl/ibal/dapl_ibal_cm.c
trunk/ulp/dapl2/dapl/ibal/dapl_ibal_qp.c
trunk/ulp/dapl2/dapl/ibal/dapl_ibal_util.h
trunk/ulp/dapl2/dapl/ibal/makefile
trunk/ulp/dapl2/dapl/ibal/udapl.rc
trunk/ulp/dapl2/dapl/include/dapl.h
trunk/ulp/dapl2/dapl/openib_cma/cm.c
trunk/ulp/dapl2/dapl/openib_cma/dapl_ib_util.h
trunk/ulp/dapl2/dapl/openib_cma/device.c
trunk/ulp/dapl2/dapl/openib_cma/linux/openib_osd.h
trunk/ulp/dapl2/dapl/openib_common/dapl_ib_common.h
trunk/ulp/dapl2/dapl/openib_common/qp.c
trunk/ulp/dapl2/dapl/openib_common/util.c
trunk/ulp/dapl2/dapl/openib_scm/SOURCES
trunk/ulp/dapl2/dapl/openib_scm/cm.c
trunk/ulp/dapl2/dapl/openib_scm/dapl_ib_util.h
trunk/ulp/dapl2/dapl/openib_scm/device.c
trunk/ulp/dapl2/dapl/openib_ucm/SOURCES
trunk/ulp/dapl2/dapl/openib_ucm/cm.c
trunk/ulp/dapl2/dapl/openib_ucm/dapl_ib_util.h
trunk/ulp/dapl2/dapl/openib_ucm/device.c
trunk/ulp/dapl2/dapl/udapl/dapl_lmr_create.c
trunk/ulp/dapl2/man/dat.conf.5
trunk/ulp/dapl2/test/dapltest/include/dapl_server_info.h

index abc9cc7bb5c100aca4cba1781935f0aec7aa6148..8d5fa0abcbb79687ecc0200a829d23fe3e3f74b4 100644 (file)
@@ -1,3 +1,463 @@
+commit 6c6a482b8ad33d134f0631019b249bd0fea71007
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Thu Jun 17 12:40:21 2010 -0700
+
+    scm, ucm: add pkey, pkey_index, sl override for QP's
+    
+    On a per open basis, add environment variables
+    DAPL_IB_SL and DAPL_IB_PKEY and use on
+    connection setup (QP modify) to override default
+    values of 0 for SL and PKEY index. If pkey is
+    provided then find the pkey index with
+    ibv_query_pkey for dev_attr.max_pkeys.
+    Will be used for RC and UD type QP's.
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 876942781e9bf72302184f3534a2ddc4068550ac
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Thu Jun 10 11:40:45 2010 -0700
+
+    cma: remove dependency on rdma_cma_abi.h
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit b34ea37650b5eefeedfc463345775ff568df259e
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Wed Jun 2 14:13:05 2010 -0700
+
+    configure: need a false conditional for verbs attr.link_layer member check
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 977f11871d3d4e98f602f890ade1c31cf4169c9c
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Wed Jun 2 10:05:03 2010 -0700
+
+    ucm: incorrectly freeing port on passive side after reject
+    
+    cm_release was incorrectly freeing a client port
+    assuming it was the server listening port. Move
+    the listening port cleanup to remove_conn_listner
+    and only cleanup client ports in cm_release.
+    
+    Error Messages indicating problem:
+    
+      CM_REQ retry 1 [lid, port, qpn]: 9 ff9a 340085 -> 9 6fa 34004e Time(ms) 1999 > 1600
+      DUPLICATE: op REQ st CM_CONNECTED [lid, port, qpn]: 9 6fa 0x0 <- 0x9 ff9a 0x340085
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 7aedfb1e9dcb9e2841ebe3496bb9aae33c1f6a5b
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Wed Jun 2 09:45:42 2010 -0700
+
+    ucm: modify debug CM output for consistency, all ports, qpn in hex
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 8e776ff0621cee1824be224b7a32f79e89b0ebc2
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Mon May 24 16:44:25 2010 -0700
+
+    Release 2.0.28
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 8fdbd949ef464aa57b13743ab087ea72f035fbc3
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Mon May 24 16:28:05 2010 -0700
+
+    config: add conditional check for new verbs port_attr.link_layer
+    
+    Check for link_layer type ETHERNET and set global for GID
+    configuration on modify QP.
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 1ce0875fb2ac6120cfee006b48a20a4ec38f599b
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Mon May 24 10:30:28 2010 -0700
+
+    dat.conf: update manpage with latest provider information, add examples
+    
+    Add information regarding OpenFabrics provider choices
+    and explain cma, scm, and ucm providers.
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 9c42d5872feb07f25f003e01263a3062ebc3bdbb
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Wed May 19 16:38:53 2010 -0700
+
+    cma, scm: new provider entries for Mellanox RDMA over Ethernet device
+    
+    Add options for netdev eth2 and eth3 for cma and for device mlx4_0 port 1 and 2 for scm.
+    
+    ofa-v2-cma-roe-eth2 u2.0 nonthreadsafe default libdaplofa.so.2 dapl.2.0 "eth2 0" ""
+    ofa-v2-cma-roe-eth3 u2.0 nonthreadsafe default libdaplofa.so.2 dapl.2.0 "eth3 0" ""
+    ofa-v2-scm-roe-mlx4_0-1 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 "mlx4_0 1" ""
+    ofa-v2-scm-roe-mlx4_0-2 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 "mlx4_0 2" ""
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit d947e05317fe7fef19c90f772ec8f458ff52b196
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Wed May 19 15:17:58 2010 -0700
+
+    dapltest: server info devicename is not large enough for dapl_name storage
+    
+    Server info device name is a 80 char array but the dapl device name
+    that is copied is 256 bytes. Increase started_server.devicename definition.
+    Chalk one up for windows SDK OACR (auto code review).
+    
+    Signed-off-by: Sean Hefty <sean.hefty@intel.com>
+
+commit c7a7a886af194cf735ee1eb62d9e14967d51249a
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Wed May 19 14:48:49 2010 -0700
+
+    windows: comp_channel.cpp is included by util.c in the openib_common.
+    
+    Remove it from device.c in individual providers to avoid
+    duplicate definitions.
+    
+    Line endings were corrected to linux format from windows as part of
+    the change.
+    
+    Signed-off-by: Sean Hefty <sean.hefty@intel.com>
+
+commit bcaa400778d14a977d5cd224056baa0cff06126d
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Wed May 19 14:45:55 2010 -0700
+
+    windows: need to include linux directory to pick up _errno.h
+    
+    Signed-off-by: Sean Hefty <sean.hefty@intel.com>
+
+commit c616a8549db461e39feed71f0f10228313d17b90
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Mon May 17 16:22:30 2010 -0700
+
+    scm: check for hca object before signaling thread
+    
+    There may not be an hca object attached to cm object
+    when freeing during cleanup.
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 1dbba72741da267f71903a9f2ec03628f3e8a47a
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Mon May 17 16:15:21 2010 -0700
+
+    scm, cma: fini code can be called multiple times and hang via fork
+    
+    The providers should protect against forked child exits and
+    not cleanup until the parent init actually exits. Otherwise,
+    the child will hang trying to cleanup dapl thread. Modify to
+    check process id for proper init to fini cleanup and limit
+    cleanup to parent only.
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit b35cb1b16a9dda349dbb19bce9f9bd4afb7240a4
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Fri May 14 16:20:52 2010 -0700
+
+    scm: add option to use other network devices with environment variable DAPL_SCM_NETDEV
+    
+    New environment variable can be used to set the netdev
+    for sockets to use instead of the default network device
+    returned using gethostname.
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit cfdf8bb8951b1c19b8e42d58e4ec26070fdc078e
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Fri May 14 10:27:50 2010 -0700
+
+    scm: cr_thread occasionally segv's when disconnecting all-to-all MPI static connections
+    
+    Note: no valid calltrace for segv on cr_thread because
+    of state changing in switch statement from another
+    thread, jumped unknown location.
+    
+    Program received signal SIGSEGV, Segmentation fault.
+    [Switching to Thread 0x41a65940 (LWP 1328)]
+    0x00002b2e7d9d5134 in ?? ()
+    
+    Add cm object locking on all state change/checking. When
+    freeing CM object wakeup cr_thread to process
+    state change to CM_FREE.
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 4b04afc32940ac42fb2a9bc789a537b527d149fe
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Thu May 13 10:31:17 2010 -0700
+
+    scm: SOCKOPT ERR Connection timed out on large clusters
+    
+    Large scale all to all connections on +1000 cores
+    the listen backlog is reached and SYN's are dropped
+    which causes the connect to timeout. Retry connect
+    on timeout errors.
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 625369f991982f020c04156f312ecf2ecafd77b3
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Mon May 10 12:46:17 2010 -0700
+
+    ucm: UD mode, active side cm object released to soon, the RTU could be lost.
+    
+    Will see following message with DAPL_DBG_TYPE set for Errors & Warnings (0x3):
+    ucm_recv: NO MATCH op REP 0x120 65487 i0x60005e c0x60005e < 0xd2 19824 0x60006a
+    
+    The cm object was released on the active side after the connection
+    was established, RTU sent. This is a problem if the RTU is lost
+    and the remote side retries the REPLY. The RTU is never resent.
+    Keep the cm object until the EP is destroyed.
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 83eec7f19a7442fe568dea685cee7b02fef2f4d1
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Mon May 10 12:35:51 2010 -0700
+
+    cma, ucm: cleanup issues with dat_ep_free on a connected EP without disconnecting.
+    
+    During EP free, disconnecting with ABRUPT close flag, the disconnect should wait
+    for the DISC event to fire to allow the CM to be properly destroyed upon return.
+    
+    The cma must also release the lock when calling the blocking rdma_destroy_id given
+    the callback thread could attempt to acquire the lock for reference counting.
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit da83172db68d05f54b2c1c77b84ecf86dea0c693
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Wed Apr 28 15:37:27 2010 -0700
+
+    ucm: increase default UCM retry count for connect reply to 15
+    
+    On very large clusters UCM is timing out with retries at 10.
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 5c710a197bb60268e99e8d1cd7fa26f89b366172
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Tue Apr 27 11:20:08 2010 -0700
+
+    scm: remove modify QP to ERR state during disconnect on UD type QP
+    
+    The disconnect on a UD type QP should not modify QP to error
+    since this is a shared QP. The disconnect should be treated
+    as a NOP on the UD type QP and only be transitioned during
+    the QP destroy (dat_ep_free).
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 64c8009f7ba48c22a6829862447ab5f67c66ba55
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Thu Apr 8 16:32:02 2010 -0700
+
+    windows: remove static paths from dapltest scripts
+    
+    signed-off-by: stan smith <stan.smith@intel.com>
+
+commit 84b78b0b586ee25c7ab78e2c5f7f19a3ce3f21ee
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Thu Apr 8 09:38:57 2010 -0700
+
+    common: EP links to EVD, PZ incorrectly released before provider CM objects freed.
+    
+    unlink/clear references after ALL CM objects linked to EP are freed.
+    Otherwise, event processing via CM objects could reference the handles
+    still linked to EP. After CM objects are freed (blocking) these handles
+    linked to EP are guaranteed not to refereence from underlying provider.
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 297e149e7af631663ecc60472a3ee093a7f72059
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Wed Apr 7 11:12:21 2010 -0700
+
+    common: remove unnecessary lmr lkey hashing and duplicate lkey checking
+    
+    lmr lkey hashing is too restrictive given the returned lkey could be
+    the same value for different regions on some rdma devices. Actually,
+    this checking is really unecesssary and requires considerable overhead
+    for hashing so just remove hashing of lmr lkey's. Let verbs device
+    level do the checking and validation.
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 96fba2ee7a0a1766f200c9486e62aad46d18bb09
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Mon Mar 29 12:20:34 2010 -0800
+
+    ibal: output completion code in deciaml & hex as intended
+    
+    sign-off-by: stan smith <stan.smith@intel.com>
+
+commit 753f7d35c814367f431deeb307e6decd933a8b5a
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Tue Mar 16 15:02:44 2010 -0800
+
+    ucm: set timer during RTU_PENDING state change.
+    
+    The timer thread may pick up an unitialized timer
+    value and timeout before the reply was sent.
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 9fc851021d91b282054cf28b4f83f7e5d376f228
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Tue Mar 16 14:47:58 2010 -0800
+
+    ucm: fix issues with new EP to CM linking changes
+    
+    Add EP locking around QP modify
+    Remove release during disconnect event processing
+    Add check in cm_free to check state and schedule thread if necessary.
+    Add some additional debugging
+    Add processing in disconnect_clean for conn_req timeout
+    Remove extra CR's
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit a5da5e4dac52366a9fe9efeb9a128bd4511481e2
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Tue Mar 16 14:18:06 2010 -0800
+
+    scm: add EP locking and cm checking to socket cm disconnect
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 7f733cd1a9acd4b9b270a807673290362050053d
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Tue Mar 16 09:44:44 2010 -0800
+
+    scm: new cm_ep linking broke UD mode over socket cm
+    
+    Add EP locking around modify_qp for EP state.
+    Add new dapli_ep_check for debugging EP
+    Cleanup extra CR's
+    Change socket errno to dapl_socket_errno() abstraction
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit a528267020972e0c449f240ba72a0cc80a5d372e
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Tue Mar 16 09:17:01 2010 -0800
+
+    openib common: add some debug prints to help isolate QP type issues
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit fdfdc439d091c878c74d23b9ac46a3320379199d
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Tue Mar 16 09:15:12 2010 -0800
+
+    common: dapl_event_str function missing 2 IB extended events
+    
+    Add all IB extended events in event string print function
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 2bf3eb939e9a584ae0fe2de70f16cdcca8acf014
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Tue Mar 16 09:12:11 2010 -0800
+
+    common: dat_ep_connect should not set timer UD endpoints
+    
+    connect for UD type is simply AH resolution and doesn't
+    need timed. The common code is not designed to handle
+    multiple timed events on connect requests so just ignore
+    timing UD AH requests.
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 73ca06debe4735dfc11f44076a13dde079657b2e
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Mon Mar 15 10:23:47 2010 -0800
+
+    ucm: fix error path during accept_usr reply failure
+    
+    if accept_usr fails when sending reply the EP was
+    being linked to CM instead of properly unlinked.
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 944ef4445faceeb90bb61d4e377274ad0fd6711f
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Mon Mar 8 13:56:28 2010 -0800
+
+    ibal: add missing windows makefile
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 1d53e8eb90e6f74b41e7767e1c71851ff4ec73fd
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Mon Mar 8 12:53:45 2010 -0800
+
+    ibal: changes for EP to CM linking and synchronization.
+    
+    Windows IBAL changes to allocate and manage CM objects
+    and to link them to the EP. This will insure the CM
+    IBAL objects and cm_id's are not destroy before EP.
+    Remove windows only ibal_cm_handle in EP structure.
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 4b939076aa32bb52957fcc6791e187c9433d4c24
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Wed Feb 24 12:00:07 2010 -0800
+
+    scm: add support for canceling conn request that times out.
+    
+    print warning message during timeout.
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit f38fc04d517ee6c0560b271298293c56cc619522
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Wed Feb 24 11:28:04 2010 -0800
+
+    scm, cma, ucm: consolidate dat event/provider event translation
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 41739dab38a4be8076ecd9e61b5e175cf91ab322
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Wed Feb 24 11:26:25 2010 -0800
+
+    common: missed linking changes from atomic to acquire/release
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit 7ff4f840bf1150fa2c2f541c93d810622ea9733b
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Wed Feb 24 10:03:57 2010 -0800
+
+    common: add CM-EP linking to support mutiple CM's and proper protection during destruction
+    
+    Add linking for CM to EP, including reference counting, to insure syncronization
+    during creation and destruction. A cm_list_head has been added to the EP object to
+    support multiple CM objects (UD) per EP. If the CM object is linked to an EP it
+    cannot be destroyed.
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
+commit c9fbd6e7a8131d4077039d5da716b618727d4009
+Author: Arlin Davis <arlin.r.davis@intel.com>
+Date:   Tue Feb 23 16:26:41 2010 -0800
+
+    Release 2.0.27-1
+    
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
+
 commit 454c27b1f357c7c3070e459b25d12929f86304ca
 Author: Arlin Davis <arlin.r.davis@intel.com>
 Date:   Mon Feb 22 09:42:17 2010 -0800
index bf828537951e79e4765c5e3ac287d514e4e73648..0be62980db0db66f60665090f915fd8d055f85ca 100644 (file)
@@ -23,6 +23,10 @@ XFLAGS =
 XPROGRAMS =
 endif
 
+if DEFINE_ATTR_LINK_LAYER
+XFLAGS += -DDEFINE_ATTR_LINK_LAYER
+endif
+
 if DEBUG
 AM_CFLAGS = -g -Wall -D_GNU_SOURCE -DDAPL_DBG -DDAT_CONF="\"$(sysconfdir)/dat.conf\""
 else
@@ -562,7 +566,11 @@ install-exec-hook:
        echo ofa-v2-mlx4_0-1u u2.0 nonthreadsafe default libdaploucm.so.2 dapl.2.0 '"mlx4_0 1" ""' >> $(DESTDIR)$(sysconfdir)/dat.conf; \
        echo ofa-v2-mlx4_0-2u u2.0 nonthreadsafe default libdaploucm.so.2 dapl.2.0 '"mlx4_0 2" ""' >> $(DESTDIR)$(sysconfdir)/dat.conf; \
        echo ofa-v2-mthca0-1u u2.0 nonthreadsafe default libdaploucm.so.2 dapl.2.0 '"mthca0 1" ""' >> $(DESTDIR)$(sysconfdir)/dat.conf; \
-       echo ofa-v2-mthca0-2u u2.0 nonthreadsafe default libdaploucm.so.2 dapl.2.0 '"mthca0 2" ""' >> $(DESTDIR)$(sysconfdir)/dat.conf;
+       echo ofa-v2-mthca0-2u u2.0 nonthreadsafe default libdaploucm.so.2 dapl.2.0 '"mthca0 2" ""' >> $(DESTDIR)$(sysconfdir)/dat.conf; \
+       echo ofa-v2-cma-roe-eth2 u2.0 nonthreadsafe default libdaplofa.so.2 dapl.2.0 '"eth2 0" ""' >> $(DESTDIR)$(sysconfdir)/dat.conf; \
+       echo ofa-v2-cma-roe-eth3 u2.0 nonthreadsafe default libdaplofa.so.2 dapl.2.0 '"eth3 0" ""' >> $(DESTDIR)$(sysconfdir)/dat.conf; \
+       echo ofa-v2-scm-roe-mlx4_0-1 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"mlx4_0 1" ""' >> $(DESTDIR)$(sysconfdir)/dat.conf; \
+       echo ofa-v2-scm-roe-mlx4_0-2 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"mlx4_0 2" ""' >> $(DESTDIR)$(sysconfdir)/dat.conf; 
 
 uninstall-hook:
        if test -e $(DESTDIR)$(sysconfdir)/dat.conf; then \
index 0979cae56ace519dd3795fa034bbdeb81c65e401..d505fad19614962cd4166110fd0ace78fd398f4b 100644 (file)
@@ -1,11 +1,11 @@
 dnl Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.57)
-AC_INIT(dapl, 2.0.27, linux-rdma@vger.kernel.org)
+AC_INIT(dapl, 2.0.29, linux-rdma@vger.kernel.org)
 AC_CONFIG_SRCDIR([dat/udat/udat.c])
 AC_CONFIG_AUX_DIR(config)
 AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(dapl, 2.0.27)
+AM_INIT_AUTOMAKE(dapl, 2.0.29)
 
 AM_PROG_LIBTOOL
 
@@ -23,13 +23,16 @@ if test "$disable_libcheck" != "yes"
 then
 AC_CHECK_LIB(ibverbs, ibv_get_device_list, [],
     AC_MSG_ERROR([ibv_get_device_list() not found.  libdapl requires libibverbs.]))
-fi
 
-dnl Checks for header files.
-if test "$disable_libcheck" != "yes"
-then
 AC_CHECK_HEADER(infiniband/verbs.h, [],
     AC_MSG_ERROR([<infiniband/verbs.h> not found.  Is libibverbs installed?]))
+
+AC_CHECK_MEMBER(struct ibv_port_attr.link_layer, 
+    AM_CONDITIONAL(DEFINE_ATTR_LINK_LAYER, test "yes" = "yes"), 
+    AM_CONDITIONAL(DEFINE_ATTR_LINK_LAYER, test "yes" = "no"), 
+    [#include <infiniband/verbs.h>])
+else
+    AM_CONDITIONAL(DEFINE_ATTR_LINK_LAYER, test "yes" = "no")
 fi
 
 AC_CACHE_CHECK(whether ld accepts --version-script, ac_cv_version_script,
index 0f2c38089c53af99dbf3992c26d20e63c8a73270..168a2bb6a9f8ef3c852b77b2dbfaedab617c25aa 100644 (file)
@@ -110,6 +110,10 @@ echo ofa-v2-mlx4_0-1u u2.0 nonthreadsafe default libdaploucm.so.2 dapl.2.0 '"mlx
 echo ofa-v2-mlx4_0-2u u2.0 nonthreadsafe default libdaploucm.so.2 dapl.2.0 '"mlx4_0 2" ""' >> %{_sysconfdir}/dat.conf
 echo ofa-v2-mthca0-1u u2.0 nonthreadsafe default libdaploucm.so.2 dapl.2.0 '"mthca0 1" ""' >> %{_sysconfdir}/dat.conf
 echo ofa-v2-mthca0-2u u2.0 nonthreadsafe default libdaploucm.so.2 dapl.2.0 '"mthca0 2" ""' >> %{_sysconfdir}/dat.conf
+echo ofa-v2-cma-roe-eth2 u2.0 nonthreadsafe default libdaplofa.so.2 dapl.2.0 '"eth2 0" ""' >> %{_sysconfdir}/dat.conf
+echo ofa-v2-cma-roe-eth3 u2.0 nonthreadsafe default libdaplofa.so.2 dapl.2.0 '"eth3 0" ""' >> %{_sysconfdir}/dat.conf
+echo ofa-v2-scm-roe-mlx4_0-1 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"mlx4_0 1" ""' >> %{_sysconfdir}/dat.conf
+echo ofa-v2-scm-roe-mlx4_0-2 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"mlx4_0 2" ""' >> %{_sysconfdir}/dat.conf
 
 %postun 
 /sbin/ldconfig
@@ -140,6 +144,12 @@ fi
 %{_mandir}/man5/*.5*
 
 %changelog
+* Thu Jun 17 2010 Arlin Davis <ardavis@ichips.intel.com> - 2.0.29
+- DAT/DAPL Version 2.0.29 Release 1, OFED 1.5.2 RC2 
+
+* Mon May 24 2010 Arlin Davis <ardavis@ichips.intel.com> - 2.0.28
+- DAT/DAPL Version 2.0.28 Release 1, OFED 1.5.2 RC1 
+
 * Tue Feb 23 2010 Arlin Davis <ardavis@ichips.intel.com> - 2.0.27
 - DAT/DAPL Version 2.0.27 Release 1, OFED 1.5.1  
 
index 2479479cc739aa020f4b4d9875489746f1cd54eb..5970fa0fe596ac52049dc6b78bd39e65a07a0673 100644 (file)
-/*\r
- * Copyright (c) 2002-2003, Network Appliance, 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_cr_util.c\r
- *\r
- * PURPOSE: Manage CR (Connection Request) structure\r
- *\r
- * $Id:$\r
- **********************************************************************/\r
-\r
-#include "dapl.h"\r
-#include "dapl_cr_util.h"\r
-\r
-/*\r
- * dapls_cr_create\r
- *\r
- * Create a CR. Part of the passive side of a connection\r
- *\r
- * Input:\r
- *     ia_ptr\r
- *\r
- * Returns:\r
- *     DAPL_CR\r
- *\r
- */\r
-\r
-DAPL_CR *dapls_cr_alloc(DAPL_IA * ia_ptr)\r
-{\r
-       DAPL_CR *cr_ptr;\r
-\r
-       /* Allocate EP */\r
-       cr_ptr = (DAPL_CR *) dapl_os_alloc(sizeof(DAPL_CR));\r
-       if (cr_ptr == NULL) {\r
-               return (NULL);\r
-       }\r
-\r
-       /* zero the structure */\r
-       dapl_os_memzero(cr_ptr, sizeof(DAPL_CR));\r
-\r
-       /*\r
-        * initialize the header\r
-        */\r
-       cr_ptr->header.provider = ia_ptr->header.provider;\r
-       cr_ptr->header.magic = DAPL_MAGIC_CR;\r
-       cr_ptr->header.handle_type = DAT_HANDLE_TYPE_CR;\r
-       cr_ptr->header.owner_ia = ia_ptr;\r
-       cr_ptr->header.user_context.as_64 = 0;\r
-       cr_ptr->header.user_context.as_ptr = NULL;\r
-       dapl_llist_init_entry(&cr_ptr->header.ia_list_entry);\r
-       dapl_os_lock_init(&cr_ptr->header.lock);\r
-\r
-       return (cr_ptr);\r
-}\r
-\r
-/*\r
- * dapls_cr_free\r
- *\r
- * Free the passed in CR structure.\r
- *\r
- * Input:\r
- *     entry point pointer\r
- *\r
- * Output:\r
- *     none\r
- *\r
- * Returns:\r
- *     none\r
- *\r
- */\r
-void dapls_cr_free(IN DAPL_CR * cr_ptr)\r
-{\r
-       dapl_os_assert(cr_ptr->header.magic == DAPL_MAGIC_CR ||\r
-                      cr_ptr->header.magic == DAPL_MAGIC_CR_DESTROYED);\r
-\r
-       cr_ptr->header.magic = DAPL_MAGIC_INVALID;      /* reset magic to prevent reuse */\r
-       dapl_os_free(cr_ptr, sizeof(DAPL_CR));\r
-}\r
+/*
+ * Copyright (c) 2002-2003, Network Appliance, 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_cr_util.c
+ *
+ * PURPOSE: Manage CR (Connection Request) structure
+ *
+ * $Id:$
+ **********************************************************************/
+
+#include "dapl.h"
+#include "dapl_cr_util.h"
+
+/*
+ * dapls_cr_create
+ *
+ * Create a CR. Part of the passive side of a connection
+ *
+ * Input:
+ *     ia_ptr
+ *
+ * Returns:
+ *     DAPL_CR
+ *
+ */
+
+DAPL_CR *dapls_cr_alloc(DAPL_IA * ia_ptr)
+{
+       DAPL_CR *cr_ptr;
+
+       /* Allocate EP */
+       cr_ptr = (DAPL_CR *) dapl_os_alloc(sizeof(DAPL_CR));
+       if (cr_ptr == NULL) {
+               return (NULL);
+       }
+
+       /* zero the structure */
+       dapl_os_memzero(cr_ptr, sizeof(DAPL_CR));
+
+       /*
+        * initialize the header
+        */
+       cr_ptr->header.provider = ia_ptr->header.provider;
+       cr_ptr->header.magic = DAPL_MAGIC_CR;
+       cr_ptr->header.handle_type = DAT_HANDLE_TYPE_CR;
+       cr_ptr->header.owner_ia = ia_ptr;
+       cr_ptr->header.user_context.as_64 = 0;
+       cr_ptr->header.user_context.as_ptr = NULL;
+       dapl_llist_init_entry(&cr_ptr->header.ia_list_entry);
+       dapl_os_lock_init(&cr_ptr->header.lock);
+
+       return (cr_ptr);
+}
+
+/*
+ * dapls_cr_free
+ *
+ * Free the passed in CR structure.
+ *
+ * Input:
+ *     entry point pointer
+ *
+ * Output:
+ *     none
+ *
+ * Returns:
+ *     none
+ *
+ */
+void dapls_cr_free(IN DAPL_CR * cr_ptr)
+{
+       dapl_os_assert(cr_ptr->header.magic == DAPL_MAGIC_CR ||
+                      cr_ptr->header.magic == DAPL_MAGIC_CR_DESTROYED);
+
+       cr_ptr->header.magic = DAPL_MAGIC_INVALID;      /* reset magic to prevent reuse */
+       dapl_os_free(cr_ptr, sizeof(DAPL_CR));
+}
index 1f193ae31953c9c6381e4b53674fb43438d1dc9d..9b5829ef2fb4036f2c523672b0f4674e9287445b 100644 (file)
@@ -327,7 +327,8 @@ dapl_ep_connect(IN DAT_EP_HANDLE ep_handle,
                dapl_os_lock(&ep_ptr->header.lock);
                if (ep_ptr->param.ep_state ==
                    DAT_EP_STATE_ACTIVE_CONNECTION_PENDING
-                   && timeout != DAT_TIMEOUT_INFINITE) {
+                   && timeout != DAT_TIMEOUT_INFINITE &&
+                   ep_ptr->param.ep_attr.service_type == DAT_SERVICE_TYPE_RC) {
                        ep_ptr->cxn_timer =
                            (DAPL_OS_TIMER *)
                            dapl_os_alloc(sizeof(DAPL_OS_TIMER));
index 8708e6fc63cb4aa18e568286165bb489fa0663dc..3bfc5417ba1e365d4e3fa41eb51b7e1dcbfa511c 100644 (file)
@@ -110,6 +110,20 @@ DAT_RETURN DAT_API dapl_ep_free(IN DAT_EP_HANDLE ep_handle)
         */
        (void)dapl_ep_disconnect(ep_ptr, DAT_CLOSE_ABRUPT_FLAG);
 
+       /* Free all CM objects */
+       cm_ptr = (dapl_llist_is_empty(&ep_ptr->cm_list_head)
+                 ? NULL : dapl_llist_peek_head(&ep_ptr->cm_list_head));
+       while (cm_ptr != NULL) {
+                dapl_log(DAPL_DBG_TYPE_EP,
+                        "dapl_ep_free: Free CM: EP=%p CM=%p\n",
+                        ep_ptr, cm_ptr);
+
+               next_cm_ptr = dapl_llist_next_entry(&ep_ptr->cm_list_head,
+                                                   &cm_ptr->list_entry);
+               dapls_cm_free(cm_ptr); /* blocking call */
+               cm_ptr = next_cm_ptr;
+       }
+
        /*
         * Do verification of parameters and the state change atomically.
         */
@@ -188,20 +202,6 @@ DAT_RETURN DAT_API dapl_ep_free(IN DAT_EP_HANDLE ep_handle)
                }
        }
 
-       /* Free all CM objects */
-       cm_ptr = (dapl_llist_is_empty(&ep_ptr->cm_list_head)
-                 ? NULL : dapl_llist_peek_head(&ep_ptr->cm_list_head));
-       while (cm_ptr != NULL) {
-                dapl_log(DAPL_DBG_TYPE_EP,
-                        "dapl_ep_free: Free CM: EP=%p CM=%p\n",
-                        ep_ptr, cm_ptr);
-
-               next_cm_ptr = dapl_llist_next_entry(&ep_ptr->cm_list_head,
-                                                   &cm_ptr->list_entry);
-               dapls_cm_free(cm_ptr); /* blocking call */
-               cm_ptr = next_cm_ptr;
-       }
-
        /* Free the resource */
        dapl_ep_dealloc(ep_ptr);
 
index e6432b98992ce18de3bb977f9eca150ef0e72a2a..9aff242c0f6fa595ceb17a8536ad499fe9c71c57 100644 (file)
-/*\r
- * Copyright (c) 2002-2003, Network Appliance, 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_ep_util.c\r
- *\r
- * PURPOSE: Manage EP Info structure\r
- *\r
- * $Id:$\r
- **********************************************************************/\r
-\r
-#include "dapl_ep_util.h"\r
-#include "dapl_ring_buffer_util.h"\r
-#include "dapl_cookie.h"\r
-#include "dapl_adapter_util.h"\r
-#include "dapl_evd_util.h"\r
-#include "dapl_cr_util.h"      /* for callback routine */\r
-\r
-/*\r
- * Local definitions\r
- */\r
-/*\r
- * Default number of I/O operations on an end point\r
- */\r
-#define IB_IO_DEFAULT  16\r
-/*\r
- * Default number of scatter/gather entries available to a single\r
- * post send/recv\r
- */\r
-#define IB_IOV_DEFAULT 4\r
-\r
-/*\r
- * Default number of RDMA operations in progress at a time\r
- */\r
-#define IB_RDMA_DEFAULT        4\r
-\r
-extern void dapli_ep_default_attrs(IN DAPL_EP * ep_ptr);\r
-\r
-char *dapl_get_ep_state_str(DAT_EP_STATE state)\r
-{\r
-#ifdef DAPL_DBG\r
-       static char *state_str[DAT_EP_STATE_CONNECTED_MULTI_PATH + 1] = {\r
-               "DAT_EP_STATE_UNCONNECTED",     /* quiescent state */\r
-               "DAT_EP_STATE_UNCONFIGURED_UNCONNECTED",\r
-               "DAT_EP_STATE_RESERVED",\r
-               "DAT_EP_STATE_UNCONFIGURED_RESERVED",\r
-               "DAT_EP_STATE_PASSIVE_CONNECTION_PENDING",\r
-               "DAT_EP_STATE_UNCONFIGURED_PASSIVE",\r
-               "DAT_EP_STATE_ACTIVE_CONNECTION_PENDING",\r
-               "DAT_EP_STATE_TENTATIVE_CONNECTION_PENDING",\r
-               "DAT_EP_STATE_UNCONFIGURED_TENTATIVE",\r
-               "DAT_EP_STATE_CONNECTED",\r
-               "DAT_EP_STATE_DISCONNECT_PENDING",\r
-               "DAT_EP_STATE_DISCONNECTED",\r
-               "DAT_EP_STATE_COMPLETION_PENDING",\r
-               "DAT_EP_STATE_CONNECTED_SINGLE_PATH",\r
-               "DAT_EP_STATE_CONNECTED_MULTI_PATH"\r
-       };\r
-       return state_str[state];\r
-#else\r
-       static char buf[12];\r
-       sprintf(buf, "%d", state);\r
-       return buf;\r
-#endif\r
-}\r
-\r
-/*\r
- * dapl_ep_alloc\r
- *\r
- * alloc and initialize an EP INFO struct\r
- *\r
- * Input:\r
- *     IA INFO struct ptr\r
- *\r
- * Output:\r
- *     ep_ptr\r
- *\r
- * Returns:\r
- *     none\r
- *\r
- */\r
-DAPL_EP *dapl_ep_alloc(IN DAPL_IA * ia_ptr, IN const DAT_EP_ATTR * ep_attr)\r
-{\r
-       DAPL_EP *ep_ptr;\r
-\r
-       /* Allocate EP */\r
-       ep_ptr =\r
-           (DAPL_EP *) dapl_os_alloc(sizeof(DAPL_EP) + sizeof(DAT_SOCK_ADDR));\r
-       if (ep_ptr == NULL) {\r
-               goto bail;\r
-       }\r
-\r
-       /* zero the structure */\r
-       dapl_os_memzero(ep_ptr, sizeof(DAPL_EP) + sizeof(DAT_SOCK_ADDR));\r
-\r
-#ifdef DAPL_COUNTERS\r
-       /* Allocate counters */\r
-       ep_ptr->cntrs =\r
-           dapl_os_alloc(sizeof(DAT_UINT64) * DCNT_EP_ALL_COUNTERS);\r
-       if (ep_ptr->cntrs == NULL) {\r
-               dapl_os_free(ep_ptr, sizeof(DAPL_EP) + sizeof(DAT_SOCK_ADDR));\r
-               return (NULL);\r
-       }\r
-       dapl_os_memzero(ep_ptr->cntrs,\r
-                       sizeof(DAT_UINT64) * DCNT_EP_ALL_COUNTERS);\r
-#endif                         /* DAPL_COUNTERS */\r
-\r
-       /*\r
-        * initialize the header\r
-        */\r
-       ep_ptr->header.provider = ia_ptr->header.provider;\r
-       ep_ptr->header.magic = DAPL_MAGIC_EP;\r
-       ep_ptr->header.handle_type = DAT_HANDLE_TYPE_EP;\r
-       ep_ptr->header.owner_ia = ia_ptr;\r
-       ep_ptr->header.user_context.as_64 = 0;\r
-       ep_ptr->header.user_context.as_ptr = NULL;\r
-\r
-       dapl_llist_init_entry(&ep_ptr->header.ia_list_entry);\r
-       dapl_llist_init_head(&ep_ptr->cm_list_head);\r
-       dapl_os_lock_init(&ep_ptr->header.lock);\r
-\r
-       /*\r
-        * Initialize the body\r
-        */\r
-       /*\r
-        * Set up default parameters if the user passed in a NULL\r
-        */\r
-       if (ep_attr == NULL) {\r
-               dapli_ep_default_attrs(ep_ptr);\r
-       } else {\r
-               ep_ptr->param.ep_attr = *ep_attr;\r
-       }\r
-\r
-       /*\r
-        * IBM OS API specific fields\r
-        */\r
-       ep_ptr->qp_handle = IB_INVALID_HANDLE;\r
-       ep_ptr->qpn = 0;\r
-       ep_ptr->qp_state = DAPL_QP_STATE_UNATTACHED;\r
-\r
-       if (DAT_SUCCESS != dapls_cb_create(&ep_ptr->req_buffer,\r
-                                          ep_ptr,\r
-                                          ep_ptr->param.ep_attr.\r
-                                          max_request_dtos)) {\r
-               dapl_ep_dealloc(ep_ptr);\r
-               ep_ptr = NULL;\r
-               goto bail;\r
-       }\r
-\r
-       if (DAT_SUCCESS != dapls_cb_create(&ep_ptr->recv_buffer,\r
-                                          ep_ptr,\r
-                                          ep_ptr->param.ep_attr.max_recv_dtos))\r
-       {\r
-               dapl_ep_dealloc(ep_ptr);\r
-               ep_ptr = NULL;\r
-               goto bail;\r
-       }\r
-\r
-       dapls_io_trc_alloc(ep_ptr);\r
-\r
-      bail:\r
-       return ep_ptr;\r
-}\r
-\r
-/*\r
- * dapl_ep_dealloc\r
- *\r
- * Free the passed in EP structure.\r
- *\r
- * Input:\r
- *     entry point pointer\r
- *\r
- * Output:\r
- *     none\r
- *\r
- * Returns:\r
- *     none\r
- *\r
- */\r
-void dapl_ep_dealloc(IN DAPL_EP * ep_ptr)\r
-{\r
-       dapl_os_assert(ep_ptr->header.magic == DAPL_MAGIC_EP);\r
-\r
-       ep_ptr->header.magic = DAPL_MAGIC_INVALID;      /* reset magic to prevent reuse */\r
-\r
-       dapls_cb_free(&ep_ptr->req_buffer);\r
-       dapls_cb_free(&ep_ptr->recv_buffer);\r
-\r
-       if (NULL != ep_ptr->cxn_timer) {\r
-               dapl_os_free(ep_ptr->cxn_timer, sizeof(DAPL_OS_TIMER));\r
-       }\r
-\r
-#ifdef DAPL_COUNTERS\r
-       dapl_os_free(ep_ptr->cntrs, sizeof(DAT_UINT64) * DCNT_EP_ALL_COUNTERS);\r
-#endif                         /* DAPL_COUNTERS */\r
-\r
-       dapl_os_free(ep_ptr, sizeof(DAPL_EP) + sizeof(DAT_SOCK_ADDR));\r
-}\r
-\r
-/*\r
- * dapl_ep_default_attrs\r
- *\r
- * Set default values in the parameter fields\r
- *\r
- * Input:\r
- *     entry point pointer\r
- *\r
- * Output:\r
- *     none\r
- *\r
- * Returns:\r
- *     none\r
- *\r
- */\r
-void dapli_ep_default_attrs(IN DAPL_EP * ep_ptr)\r
-{\r
-       DAT_EP_ATTR ep_attr_limit;\r
-       DAT_EP_ATTR *ep_attr;\r
-       DAT_RETURN dat_status;\r
-\r
-       ep_attr = &ep_ptr->param.ep_attr;\r
-       /* Set up defaults */\r
-       dapl_os_memzero(ep_attr, sizeof(DAT_EP_ATTR));\r
-\r
-       /* mtu and rdma sizes fixed in IB as per IBTA 1.1, 9.4.3, 9.4.4, 9.7.7.  */\r
-       ep_attr->max_mtu_size = 0x80000000;\r
-       ep_attr->max_rdma_size = 0x80000000;\r
-\r
-       ep_attr->qos = DAT_QOS_BEST_EFFORT;\r
-       ep_attr->service_type = DAT_SERVICE_TYPE_RC;\r
-       ep_attr->max_recv_dtos = IB_IO_DEFAULT;\r
-       ep_attr->max_request_dtos = IB_IO_DEFAULT;\r
-       ep_attr->max_recv_iov = IB_IOV_DEFAULT;\r
-       ep_attr->max_request_iov = IB_IOV_DEFAULT;\r
-       ep_attr->max_rdma_read_in = IB_RDMA_DEFAULT;\r
-       ep_attr->max_rdma_read_out = IB_RDMA_DEFAULT;\r
-\r
-       /*\r
-        * Configure the EP as a standard completion type, which will be\r
-        * used by the EVDs. A threshold of 1 is the default state of an\r
-        * EVD.\r
-        */\r
-       ep_attr->request_completion_flags = DAT_COMPLETION_EVD_THRESHOLD_FLAG;\r
-       ep_attr->recv_completion_flags = DAT_COMPLETION_EVD_THRESHOLD_FLAG;\r
-       /*\r
-        * Unspecified defaults:\r
-        *    - ep_privileges: No RDMA capabilities\r
-        *    - num_transport_specific_params: none\r
-        *    - transport_specific_params: none\r
-        *    - num_provider_specific_params: 0\r
-        *    - provider_specific_params: 0\r
-        */\r
-\r
-       dat_status = dapls_ib_query_hca(ep_ptr->header.owner_ia->hca_ptr,\r
-                                       NULL, &ep_attr_limit, NULL);\r
-       /* check against HCA maximums */\r
-       if (dat_status == DAT_SUCCESS) {\r
-               ep_ptr->param.ep_attr.max_mtu_size =\r
-                   DAPL_MIN(ep_ptr->param.ep_attr.max_mtu_size,\r
-                            ep_attr_limit.max_mtu_size);\r
-               ep_ptr->param.ep_attr.max_rdma_size =\r
-                   DAPL_MIN(ep_ptr->param.ep_attr.max_rdma_size,\r
-                            ep_attr_limit.max_rdma_size);\r
-               ep_ptr->param.ep_attr.max_recv_dtos =\r
-                   DAPL_MIN(ep_ptr->param.ep_attr.max_recv_dtos,\r
-                            ep_attr_limit.max_recv_dtos);\r
-               ep_ptr->param.ep_attr.max_request_dtos =\r
-                   DAPL_MIN(ep_ptr->param.ep_attr.max_request_dtos,\r
-                            ep_attr_limit.max_request_dtos);\r
-               ep_ptr->param.ep_attr.max_recv_iov =\r
-                   DAPL_MIN(ep_ptr->param.ep_attr.max_recv_iov,\r
-                            ep_attr_limit.max_recv_iov);\r
-               ep_ptr->param.ep_attr.max_request_iov =\r
-                   DAPL_MIN(ep_ptr->param.ep_attr.max_request_iov,\r
-                            ep_attr_limit.max_request_iov);\r
-               ep_ptr->param.ep_attr.max_rdma_read_in =\r
-                   DAPL_MIN(ep_ptr->param.ep_attr.max_rdma_read_in,\r
-                            ep_attr_limit.max_rdma_read_in);\r
-               ep_ptr->param.ep_attr.max_rdma_read_out =\r
-                   DAPL_MIN(ep_ptr->param.ep_attr.max_rdma_read_out,\r
-                            ep_attr_limit.max_rdma_read_out);\r
-       }\r
-}\r
-\r
-DAT_RETURN dapl_ep_check_recv_completion_flags(DAT_COMPLETION_FLAGS flags)\r
-{\r
-\r
-       /*\r
-        * InfiniBand will not allow signal suppression for RECV completions,\r
-        * see the 1.0.1 spec section 10.7.3.1, 10.8.6.\r
-        * N.B. SIGNALLED has a different meaning in dapl than it does\r
-        *      in IB; IB SIGNALLED is the same as DAPL SUPPRESS. DAPL\r
-        *      SIGNALLED simply means the user will not get awakened when\r
-        *      an EVD completes, even though the dapl handler is invoked.\r
-        */\r
-\r
-       if (flags & DAT_COMPLETION_SUPPRESS_FLAG) {\r
-               return DAT_INVALID_PARAMETER;\r
-       }\r
-\r
-       return DAT_SUCCESS;\r
-}\r
-\r
-DAT_RETURN dapl_ep_check_request_completion_flags(DAT_COMPLETION_FLAGS flags)\r
-{\r
-       return DAT_SUCCESS;\r
-}\r
-\r
-DAT_RETURN\r
-dapl_ep_post_send_req(IN DAT_EP_HANDLE ep_handle,\r
-                     IN DAT_COUNT num_segments,\r
-                     IN DAT_LMR_TRIPLET * local_iov,\r
-                     IN DAT_DTO_COOKIE user_cookie,\r
-                     IN const DAT_RMR_TRIPLET * remote_iov,\r
-                     IN DAT_COMPLETION_FLAGS completion_flags,\r
-                     IN DAPL_DTO_TYPE dto_type, IN int op_type)\r
-{\r
-       DAPL_EP *ep_ptr;\r
-       DAPL_COOKIE *cookie;\r
-       DAT_RETURN dat_status;\r
-\r
-       if (DAPL_BAD_HANDLE(ep_handle, DAPL_MAGIC_EP)) {\r
-               dat_status =\r
-                   DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP);\r
-               goto bail;\r
-       }\r
-\r
-       ep_ptr = (DAPL_EP *) ep_handle;\r
-\r
-       /*\r
-        * Synchronization ok since this buffer is only used for send\r
-        * requests, which aren't allowed to race with each other.\r
-        */\r
-       dat_status = dapls_dto_cookie_alloc(&ep_ptr->req_buffer,\r
-                                           dto_type, user_cookie, &cookie);\r
-       if (dat_status != DAT_SUCCESS) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        " dapl_post_req resource ERR:"\r
-                        " dtos pending = %d, max_dtos %d, max_cb %d hd %d tl %d\n",\r
-                        dapls_cb_pending(&ep_ptr->req_buffer),\r
-                        ep_ptr->param.ep_attr.max_request_dtos,\r
-                        ep_ptr->req_buffer.pool_size,\r
-                        ep_ptr->req_buffer.head, ep_ptr->req_buffer.tail);\r
-\r
-               goto bail;\r
-       }\r
-\r
-       /*\r
-        * Invoke provider specific routine to post DTO\r
-        */\r
-       dat_status = dapls_ib_post_send(ep_ptr,\r
-                                       op_type,\r
-                                       cookie,\r
-                                       num_segments,\r
-                                       local_iov,\r
-                                       remote_iov, completion_flags);\r
-\r
-       if (dat_status != DAT_SUCCESS) {\r
-               dapls_cookie_dealloc(&ep_ptr->req_buffer, cookie);\r
-       }\r
-\r
-      bail:\r
-       return dat_status;\r
-}\r
-\r
-/*\r
- * dapli_ep_timeout\r
- *\r
- * If this routine is invoked before a connection occurs, generate an\r
- * event\r
- */\r
-void dapls_ep_timeout(uintptr_t arg)\r
-{\r
-       DAPL_EP *ep_ptr;\r
-       ib_cm_events_t ib_cm_event;\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_CM, "--> dapls_ep_timeout! ep %lx\n", arg);\r
-\r
-       ep_ptr = (DAPL_EP *) arg;\r
-\r
-       /* reset the EP state */\r
-       ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;\r
-\r
-       /* Clean up the EP and put the underlying QP into the ERROR state.\r
-        * The disconnect_clean interface requires the provided dependent \r
-        *cm event number.\r
-        */\r
-       ib_cm_event = dapls_ib_get_cm_event(DAT_CONNECTION_EVENT_TIMED_OUT);\r
-       dapls_ib_disconnect_clean(ep_ptr, DAT_TRUE, ib_cm_event);\r
-\r
-       (void)dapls_evd_post_connection_event((DAPL_EVD *) ep_ptr->param.\r
-                                             connect_evd_handle,\r
-                                             DAT_CONNECTION_EVENT_TIMED_OUT,\r
-                                             (DAT_HANDLE) ep_ptr, 0, 0);\r
-}\r
-\r
-/*\r
- * dapls_ep_state_subtype\r
- *\r
- * Return the INVALID_STATE connection subtype associated with an\r
- * INVALID_STATE on an EP. Strictly for error reporting.\r
- */\r
-DAT_RETURN_SUBTYPE dapls_ep_state_subtype(IN DAPL_EP * ep_ptr)\r
-{\r
-       DAT_RETURN_SUBTYPE dat_status;\r
-\r
-       switch (ep_ptr->param.ep_state) {\r
-       case DAT_EP_STATE_UNCONNECTED:\r
-               {\r
-                       dat_status = DAT_INVALID_STATE_EP_UNCONNECTED;\r
-                       break;\r
-               }\r
-       case DAT_EP_STATE_RESERVED:\r
-               {\r
-                       dat_status = DAT_INVALID_STATE_EP_RESERVED;\r
-                       break;\r
-               }\r
-       case DAT_EP_STATE_PASSIVE_CONNECTION_PENDING:\r
-               {\r
-                       dat_status = DAT_INVALID_STATE_EP_PASSCONNPENDING;\r
-                       break;\r
-               }\r
-       case DAT_EP_STATE_ACTIVE_CONNECTION_PENDING:\r
-               {\r
-                       dat_status = DAT_INVALID_STATE_EP_ACTCONNPENDING;\r
-                       break;\r
-               }\r
-       case DAT_EP_STATE_TENTATIVE_CONNECTION_PENDING:\r
-               {\r
-                       dat_status = DAT_INVALID_STATE_EP_TENTCONNPENDING;\r
-                       break;\r
-               }\r
-       case DAT_EP_STATE_CONNECTED:\r
-               {\r
-                       dat_status = DAT_INVALID_STATE_EP_CONNECTED;\r
-                       break;\r
-               }\r
-       case DAT_EP_STATE_DISCONNECT_PENDING:\r
-               {\r
-                       dat_status = DAT_INVALID_STATE_EP_DISCPENDING;\r
-                       break;\r
-               }\r
-       case DAT_EP_STATE_DISCONNECTED:\r
-               {\r
-                       dat_status = DAT_INVALID_STATE_EP_DISCONNECTED;\r
-                       break;\r
-               }\r
-       case DAT_EP_STATE_COMPLETION_PENDING:\r
-               {\r
-                       dat_status = DAT_INVALID_STATE_EP_COMPLPENDING;\r
-                       break;\r
-               }\r
-\r
-       default:\r
-               {\r
-                       dat_status = 0;\r
-                       break;\r
-               }\r
-       }\r
-\r
-       return dat_status;\r
-}\r
-\r
-#ifdef DAPL_DBG_IO_TRC\r
-/* allocate trace buffer */\r
-void dapls_io_trc_alloc(DAPL_EP * ep_ptr)\r
-{\r
-       DAT_RETURN dat_status;\r
-       int i;\r
-       struct io_buf_track *ibt;\r
-\r
-       ep_ptr->ibt_dumped = 0; /* bool to control how often we print */\r
-       dat_status = dapls_rbuf_alloc(&ep_ptr->ibt_queue, DBG_IO_TRC_QLEN);\r
-       if (dat_status != DAT_SUCCESS) {\r
-               goto bail;\r
-       }\r
-       ibt =\r
-           (struct io_buf_track *)dapl_os_alloc(sizeof(struct io_buf_track) *\r
-                                                DBG_IO_TRC_QLEN);\r
-\r
-       if (dat_status != DAT_SUCCESS) {\r
-               dapls_rbuf_destroy(&ep_ptr->ibt_queue);\r
-               goto bail;\r
-       }\r
-       ep_ptr->ibt_base = ibt;\r
-       dapl_os_memzero(ibt, sizeof(struct io_buf_track) * DBG_IO_TRC_QLEN);\r
-\r
-       /* add events to free event queue */\r
-       for (i = 0; i < DBG_IO_TRC_QLEN; i++) {\r
-               dapls_rbuf_add(&ep_ptr->ibt_queue, ibt++);\r
-       }\r
-      bail:\r
-       return;\r
-}\r
-#endif                         /* DAPL_DBG_IO_TRC */\r
-\r
-/*\r
- * Generate a disconnect event on abruct close for older verbs providers \r
- * that do not do it automatically.\r
- */\r
-\r
-void\r
-dapl_ep_legacy_post_disconnect(DAPL_EP * ep_ptr,\r
-                              DAT_CLOSE_FLAGS disconnect_flags)\r
-{\r
-       ib_cm_events_t ib_cm_event;\r
-       DAPL_CR *cr_ptr;\r
-       dp_ib_cm_handle_t cm_ptr;\r
-\r
-       /*\r
-        * Acquire the lock and make sure we didn't get a callback\r
-        * that cleaned up.\r
-        */\r
-       dapl_os_lock(&ep_ptr->header.lock);\r
-       if (disconnect_flags == DAT_CLOSE_ABRUPT_FLAG &&\r
-           ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECT_PENDING) {\r
-               /*\r
-                * If this is an ABRUPT close, the provider will not generate\r
-                * a disconnect message so we do it manually here. Just invoke\r
-                * the CM callback as it will clean up the appropriate\r
-                * data structures, reset the state, and generate the event\r
-                * on the way out. Obtain the provider dependent cm_event to \r
-                * pass into the callback for a disconnect.\r
-                */\r
-               ib_cm_event =\r
-                   dapls_ib_get_cm_event(DAT_CONNECTION_EVENT_DISCONNECTED);\r
-\r
-               cr_ptr = ep_ptr->cr_ptr;\r
-               cm_ptr = (dapl_llist_is_empty(&ep_ptr->cm_list_head)\r
-                         ? NULL : dapl_llist_peek_head(&ep_ptr->cm_list_head));\r
-               dapl_os_unlock(&ep_ptr->header.lock);\r
-\r
-               if (cr_ptr != NULL) {\r
-                       dapl_dbg_log(DAPL_DBG_TYPE_API | DAPL_DBG_TYPE_CM,\r
-                                    "    dapl_ep_disconnect force callback on EP %p CM handle %x\n",\r
-                                    ep_ptr, cr_ptr->ib_cm_handle);\r
-\r
-                       dapls_cr_callback(cr_ptr->ib_cm_handle,\r
-                                         ib_cm_event, NULL, 0, cr_ptr->sp_ptr);\r
-               } else {\r
-                       dapl_evd_connection_callback(cm_ptr,\r
-                                                    ib_cm_event,\r
-                                                    NULL, 0, (void *)ep_ptr);\r
-               }\r
-       } else {\r
-               dapl_os_unlock(&ep_ptr->header.lock);\r
-       }\r
-}\r
-\r
-/*\r
- * dapl_ep_link_cm\r
- *\r
- * Add linking of provider's CM object to a EP structure\r
- * This enables multiple CM's per EP, and syncronization\r
- *\r
- * Input:\r
- *     DAPL_EP *ep_ptr\r
- *     dp_ib_cm_handle_t *cm_ptr  defined in provider's dapl_util.h\r
- *\r
- *     CM objects linked with EP using  ->list_entry\r
- * Output:\r
- *     none\r
- *\r
- * Returns:\r
- *     none\r
- *\r
- */\r
-void dapl_ep_link_cm(IN DAPL_EP *ep_ptr, IN dp_ib_cm_handle_t cm_ptr)\r
-{\r
-       dapl_os_lock(&ep_ptr->header.lock);\r
-       dapls_cm_acquire(cm_ptr);\r
-       dapl_llist_add_tail(&ep_ptr->cm_list_head, &cm_ptr->list_entry, cm_ptr);\r
-       dapl_os_unlock(&ep_ptr->header.lock);\r
-}\r
-\r
-void dapl_ep_unlink_cm(IN DAPL_EP *ep_ptr, IN dp_ib_cm_handle_t cm_ptr)\r
-{\r
-       dapl_os_lock(&ep_ptr->header.lock);\r
-       dapl_llist_remove_entry(&ep_ptr->cm_list_head, &cm_ptr->list_entry);\r
-       dapls_cm_release(cm_ptr);\r
-       dapl_os_unlock(&ep_ptr->header.lock);\r
-}\r
-\r
-/*\r
- * Local variables:\r
- *  c-indent-level: 4\r
- *  c-basic-offset: 4\r
- *  tab-width: 8\r
- * End:\r
- */\r
+/*
+ * Copyright (c) 2002-2003, Network Appliance, 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_ep_util.c
+ *
+ * PURPOSE: Manage EP Info structure
+ *
+ * $Id:$
+ **********************************************************************/
+
+#include "dapl_ep_util.h"
+#include "dapl_ring_buffer_util.h"
+#include "dapl_cookie.h"
+#include "dapl_adapter_util.h"
+#include "dapl_evd_util.h"
+#include "dapl_cr_util.h"      /* for callback routine */
+
+/*
+ * Local definitions
+ */
+/*
+ * Default number of I/O operations on an end point
+ */
+#define IB_IO_DEFAULT  16
+/*
+ * Default number of scatter/gather entries available to a single
+ * post send/recv
+ */
+#define IB_IOV_DEFAULT 4
+
+/*
+ * Default number of RDMA operations in progress at a time
+ */
+#define IB_RDMA_DEFAULT        4
+
+extern void dapli_ep_default_attrs(IN DAPL_EP * ep_ptr);
+
+char *dapl_get_ep_state_str(DAT_EP_STATE state)
+{
+#ifdef DAPL_DBG
+       static char *state_str[DAT_EP_STATE_CONNECTED_MULTI_PATH + 1] = {
+               "DAT_EP_STATE_UNCONNECTED",     /* quiescent state */
+               "DAT_EP_STATE_UNCONFIGURED_UNCONNECTED",
+               "DAT_EP_STATE_RESERVED",
+               "DAT_EP_STATE_UNCONFIGURED_RESERVED",
+               "DAT_EP_STATE_PASSIVE_CONNECTION_PENDING",
+               "DAT_EP_STATE_UNCONFIGURED_PASSIVE",
+               "DAT_EP_STATE_ACTIVE_CONNECTION_PENDING",
+               "DAT_EP_STATE_TENTATIVE_CONNECTION_PENDING",
+               "DAT_EP_STATE_UNCONFIGURED_TENTATIVE",
+               "DAT_EP_STATE_CONNECTED",
+               "DAT_EP_STATE_DISCONNECT_PENDING",
+               "DAT_EP_STATE_DISCONNECTED",
+               "DAT_EP_STATE_COMPLETION_PENDING",
+               "DAT_EP_STATE_CONNECTED_SINGLE_PATH",
+               "DAT_EP_STATE_CONNECTED_MULTI_PATH"
+       };
+       return state_str[state];
+#else
+       static char buf[12];
+       sprintf(buf, "%d", state);
+       return buf;
+#endif
+}
+
+/*
+ * dapl_ep_alloc
+ *
+ * alloc and initialize an EP INFO struct
+ *
+ * Input:
+ *     IA INFO struct ptr
+ *
+ * Output:
+ *     ep_ptr
+ *
+ * Returns:
+ *     none
+ *
+ */
+DAPL_EP *dapl_ep_alloc(IN DAPL_IA * ia_ptr, IN const DAT_EP_ATTR * ep_attr)
+{
+       DAPL_EP *ep_ptr;
+
+       /* Allocate EP */
+       ep_ptr =
+           (DAPL_EP *) dapl_os_alloc(sizeof(DAPL_EP) + sizeof(DAT_SOCK_ADDR));
+       if (ep_ptr == NULL) {
+               goto bail;
+       }
+
+       /* zero the structure */
+       dapl_os_memzero(ep_ptr, sizeof(DAPL_EP) + sizeof(DAT_SOCK_ADDR));
+
+#ifdef DAPL_COUNTERS
+       /* Allocate counters */
+       ep_ptr->cntrs =
+           dapl_os_alloc(sizeof(DAT_UINT64) * DCNT_EP_ALL_COUNTERS);
+       if (ep_ptr->cntrs == NULL) {
+               dapl_os_free(ep_ptr, sizeof(DAPL_EP) + sizeof(DAT_SOCK_ADDR));
+               return (NULL);
+       }
+       dapl_os_memzero(ep_ptr->cntrs,
+                       sizeof(DAT_UINT64) * DCNT_EP_ALL_COUNTERS);
+#endif                         /* DAPL_COUNTERS */
+
+       /*
+        * initialize the header
+        */
+       ep_ptr->header.provider = ia_ptr->header.provider;
+       ep_ptr->header.magic = DAPL_MAGIC_EP;
+       ep_ptr->header.handle_type = DAT_HANDLE_TYPE_EP;
+       ep_ptr->header.owner_ia = ia_ptr;
+       ep_ptr->header.user_context.as_64 = 0;
+       ep_ptr->header.user_context.as_ptr = NULL;
+
+       dapl_llist_init_entry(&ep_ptr->header.ia_list_entry);
+       dapl_llist_init_head(&ep_ptr->cm_list_head);
+       dapl_os_lock_init(&ep_ptr->header.lock);
+
+       /*
+        * Initialize the body
+        */
+       /*
+        * Set up default parameters if the user passed in a NULL
+        */
+       if (ep_attr == NULL) {
+               dapli_ep_default_attrs(ep_ptr);
+       } else {
+               ep_ptr->param.ep_attr = *ep_attr;
+       }
+
+       /*
+        * IBM OS API specific fields
+        */
+       ep_ptr->qp_handle = IB_INVALID_HANDLE;
+       ep_ptr->qpn = 0;
+       ep_ptr->qp_state = DAPL_QP_STATE_UNATTACHED;
+
+       if (DAT_SUCCESS != dapls_cb_create(&ep_ptr->req_buffer,
+                                          ep_ptr,
+                                          ep_ptr->param.ep_attr.
+                                          max_request_dtos)) {
+               dapl_ep_dealloc(ep_ptr);
+               ep_ptr = NULL;
+               goto bail;
+       }
+
+       if (DAT_SUCCESS != dapls_cb_create(&ep_ptr->recv_buffer,
+                                          ep_ptr,
+                                          ep_ptr->param.ep_attr.max_recv_dtos))
+       {
+               dapl_ep_dealloc(ep_ptr);
+               ep_ptr = NULL;
+               goto bail;
+       }
+
+       dapls_io_trc_alloc(ep_ptr);
+
+      bail:
+       return ep_ptr;
+}
+
+/*
+ * dapl_ep_dealloc
+ *
+ * Free the passed in EP structure.
+ *
+ * Input:
+ *     entry point pointer
+ *
+ * Output:
+ *     none
+ *
+ * Returns:
+ *     none
+ *
+ */
+void dapl_ep_dealloc(IN DAPL_EP * ep_ptr)
+{
+       dapl_os_assert(ep_ptr->header.magic == DAPL_MAGIC_EP);
+
+       ep_ptr->header.magic = DAPL_MAGIC_INVALID;      /* reset magic to prevent reuse */
+
+       dapls_cb_free(&ep_ptr->req_buffer);
+       dapls_cb_free(&ep_ptr->recv_buffer);
+
+       if (NULL != ep_ptr->cxn_timer) {
+               dapl_os_free(ep_ptr->cxn_timer, sizeof(DAPL_OS_TIMER));
+       }
+
+#ifdef DAPL_COUNTERS
+       dapl_os_free(ep_ptr->cntrs, sizeof(DAT_UINT64) * DCNT_EP_ALL_COUNTERS);
+#endif                         /* DAPL_COUNTERS */
+
+       dapl_os_free(ep_ptr, sizeof(DAPL_EP) + sizeof(DAT_SOCK_ADDR));
+}
+
+/*
+ * dapl_ep_default_attrs
+ *
+ * Set default values in the parameter fields
+ *
+ * Input:
+ *     entry point pointer
+ *
+ * Output:
+ *     none
+ *
+ * Returns:
+ *     none
+ *
+ */
+void dapli_ep_default_attrs(IN DAPL_EP * ep_ptr)
+{
+       DAT_EP_ATTR ep_attr_limit;
+       DAT_EP_ATTR *ep_attr;
+       DAT_RETURN dat_status;
+
+       ep_attr = &ep_ptr->param.ep_attr;
+       /* Set up defaults */
+       dapl_os_memzero(ep_attr, sizeof(DAT_EP_ATTR));
+
+       /* mtu and rdma sizes fixed in IB as per IBTA 1.1, 9.4.3, 9.4.4, 9.7.7.  */
+       ep_attr->max_mtu_size = 0x80000000;
+       ep_attr->max_rdma_size = 0x80000000;
+
+       ep_attr->qos = DAT_QOS_BEST_EFFORT;
+       ep_attr->service_type = DAT_SERVICE_TYPE_RC;
+       ep_attr->max_recv_dtos = IB_IO_DEFAULT;
+       ep_attr->max_request_dtos = IB_IO_DEFAULT;
+       ep_attr->max_recv_iov = IB_IOV_DEFAULT;
+       ep_attr->max_request_iov = IB_IOV_DEFAULT;
+       ep_attr->max_rdma_read_in = IB_RDMA_DEFAULT;
+       ep_attr->max_rdma_read_out = IB_RDMA_DEFAULT;
+
+       /*
+        * Configure the EP as a standard completion type, which will be
+        * used by the EVDs. A threshold of 1 is the default state of an
+        * EVD.
+        */
+       ep_attr->request_completion_flags = DAT_COMPLETION_EVD_THRESHOLD_FLAG;
+       ep_attr->recv_completion_flags = DAT_COMPLETION_EVD_THRESHOLD_FLAG;
+       /*
+        * Unspecified defaults:
+        *    - ep_privileges: No RDMA capabilities
+        *    - num_transport_specific_params: none
+        *    - transport_specific_params: none
+        *    - num_provider_specific_params: 0
+        *    - provider_specific_params: 0
+        */
+
+       dat_status = dapls_ib_query_hca(ep_ptr->header.owner_ia->hca_ptr,
+                                       NULL, &ep_attr_limit, NULL);
+       /* check against HCA maximums */
+       if (dat_status == DAT_SUCCESS) {
+               ep_ptr->param.ep_attr.max_mtu_size =
+                   DAPL_MIN(ep_ptr->param.ep_attr.max_mtu_size,
+                            ep_attr_limit.max_mtu_size);
+               ep_ptr->param.ep_attr.max_rdma_size =
+                   DAPL_MIN(ep_ptr->param.ep_attr.max_rdma_size,
+                            ep_attr_limit.max_rdma_size);
+               ep_ptr->param.ep_attr.max_recv_dtos =
+                   DAPL_MIN(ep_ptr->param.ep_attr.max_recv_dtos,
+                            ep_attr_limit.max_recv_dtos);
+               ep_ptr->param.ep_attr.max_request_dtos =
+                   DAPL_MIN(ep_ptr->param.ep_attr.max_request_dtos,
+                            ep_attr_limit.max_request_dtos);
+               ep_ptr->param.ep_attr.max_recv_iov =
+                   DAPL_MIN(ep_ptr->param.ep_attr.max_recv_iov,
+                            ep_attr_limit.max_recv_iov);
+               ep_ptr->param.ep_attr.max_request_iov =
+                   DAPL_MIN(ep_ptr->param.ep_attr.max_request_iov,
+                            ep_attr_limit.max_request_iov);
+               ep_ptr->param.ep_attr.max_rdma_read_in =
+                   DAPL_MIN(ep_ptr->param.ep_attr.max_rdma_read_in,
+                            ep_attr_limit.max_rdma_read_in);
+               ep_ptr->param.ep_attr.max_rdma_read_out =
+                   DAPL_MIN(ep_ptr->param.ep_attr.max_rdma_read_out,
+                            ep_attr_limit.max_rdma_read_out);
+       }
+}
+
+DAT_RETURN dapl_ep_check_recv_completion_flags(DAT_COMPLETION_FLAGS flags)
+{
+
+       /*
+        * InfiniBand will not allow signal suppression for RECV completions,
+        * see the 1.0.1 spec section 10.7.3.1, 10.8.6.
+        * N.B. SIGNALLED has a different meaning in dapl than it does
+        *      in IB; IB SIGNALLED is the same as DAPL SUPPRESS. DAPL
+        *      SIGNALLED simply means the user will not get awakened when
+        *      an EVD completes, even though the dapl handler is invoked.
+        */
+
+       if (flags & DAT_COMPLETION_SUPPRESS_FLAG) {
+               return DAT_INVALID_PARAMETER;
+       }
+
+       return DAT_SUCCESS;
+}
+
+DAT_RETURN dapl_ep_check_request_completion_flags(DAT_COMPLETION_FLAGS flags)
+{
+       return DAT_SUCCESS;
+}
+
+DAT_RETURN
+dapl_ep_post_send_req(IN DAT_EP_HANDLE ep_handle,
+                     IN DAT_COUNT num_segments,
+                     IN DAT_LMR_TRIPLET * local_iov,
+                     IN DAT_DTO_COOKIE user_cookie,
+                     IN const DAT_RMR_TRIPLET * remote_iov,
+                     IN DAT_COMPLETION_FLAGS completion_flags,
+                     IN DAPL_DTO_TYPE dto_type, IN int op_type)
+{
+       DAPL_EP *ep_ptr;
+       DAPL_COOKIE *cookie;
+       DAT_RETURN dat_status;
+
+       if (DAPL_BAD_HANDLE(ep_handle, DAPL_MAGIC_EP)) {
+               dat_status =
+                   DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP);
+               goto bail;
+       }
+
+       ep_ptr = (DAPL_EP *) ep_handle;
+
+       /*
+        * Synchronization ok since this buffer is only used for send
+        * requests, which aren't allowed to race with each other.
+        */
+       dat_status = dapls_dto_cookie_alloc(&ep_ptr->req_buffer,
+                                           dto_type, user_cookie, &cookie);
+       if (dat_status != DAT_SUCCESS) {
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                        " dapl_post_req resource ERR:"
+                        " dtos pending = %d, max_dtos %d, max_cb %d hd %d tl %d\n",
+                        dapls_cb_pending(&ep_ptr->req_buffer),
+                        ep_ptr->param.ep_attr.max_request_dtos,
+                        ep_ptr->req_buffer.pool_size,
+                        ep_ptr->req_buffer.head, ep_ptr->req_buffer.tail);
+
+               goto bail;
+       }
+
+       /*
+        * Invoke provider specific routine to post DTO
+        */
+       dat_status = dapls_ib_post_send(ep_ptr,
+                                       op_type,
+                                       cookie,
+                                       num_segments,
+                                       local_iov,
+                                       remote_iov, completion_flags);
+
+       if (dat_status != DAT_SUCCESS) {
+               dapls_cookie_dealloc(&ep_ptr->req_buffer, cookie);
+       }
+
+      bail:
+       return dat_status;
+}
+
+/*
+ * dapli_ep_timeout
+ *
+ * If this routine is invoked before a connection occurs, generate an
+ * event
+ */
+void dapls_ep_timeout(uintptr_t arg)
+{
+       DAPL_EP *ep_ptr;
+       ib_cm_events_t ib_cm_event;
+
+       dapl_dbg_log(DAPL_DBG_TYPE_CM, "--> dapls_ep_timeout! ep %lx\n", arg);
+
+       ep_ptr = (DAPL_EP *) arg;
+
+       /* reset the EP state */
+       ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;
+
+       /* Clean up the EP and put the underlying QP into the ERROR state.
+        * The disconnect_clean interface requires the provided dependent 
+        *cm event number.
+        */
+       ib_cm_event = dapls_ib_get_cm_event(DAT_CONNECTION_EVENT_TIMED_OUT);
+       dapls_ib_disconnect_clean(ep_ptr, DAT_TRUE, ib_cm_event);
+
+       (void)dapls_evd_post_connection_event((DAPL_EVD *) ep_ptr->param.
+                                             connect_evd_handle,
+                                             DAT_CONNECTION_EVENT_TIMED_OUT,
+                                             (DAT_HANDLE) ep_ptr, 0, 0);
+}
+
+/*
+ * dapls_ep_state_subtype
+ *
+ * Return the INVALID_STATE connection subtype associated with an
+ * INVALID_STATE on an EP. Strictly for error reporting.
+ */
+DAT_RETURN_SUBTYPE dapls_ep_state_subtype(IN DAPL_EP * ep_ptr)
+{
+       DAT_RETURN_SUBTYPE dat_status;
+
+       switch (ep_ptr->param.ep_state) {
+       case DAT_EP_STATE_UNCONNECTED:
+               {
+                       dat_status = DAT_INVALID_STATE_EP_UNCONNECTED;
+                       break;
+               }
+       case DAT_EP_STATE_RESERVED:
+               {
+                       dat_status = DAT_INVALID_STATE_EP_RESERVED;
+                       break;
+               }
+       case DAT_EP_STATE_PASSIVE_CONNECTION_PENDING:
+               {
+                       dat_status = DAT_INVALID_STATE_EP_PASSCONNPENDING;
+                       break;
+               }
+       case DAT_EP_STATE_ACTIVE_CONNECTION_PENDING:
+               {
+                       dat_status = DAT_INVALID_STATE_EP_ACTCONNPENDING;
+                       break;
+               }
+       case DAT_EP_STATE_TENTATIVE_CONNECTION_PENDING:
+               {
+                       dat_status = DAT_INVALID_STATE_EP_TENTCONNPENDING;
+                       break;
+               }
+       case DAT_EP_STATE_CONNECTED:
+               {
+                       dat_status = DAT_INVALID_STATE_EP_CONNECTED;
+                       break;
+               }
+       case DAT_EP_STATE_DISCONNECT_PENDING:
+               {
+                       dat_status = DAT_INVALID_STATE_EP_DISCPENDING;
+                       break;
+               }
+       case DAT_EP_STATE_DISCONNECTED:
+               {
+                       dat_status = DAT_INVALID_STATE_EP_DISCONNECTED;
+                       break;
+               }
+       case DAT_EP_STATE_COMPLETION_PENDING:
+               {
+                       dat_status = DAT_INVALID_STATE_EP_COMPLPENDING;
+                       break;
+               }
+
+       default:
+               {
+                       dat_status = 0;
+                       break;
+               }
+       }
+
+       return dat_status;
+}
+
+#ifdef DAPL_DBG_IO_TRC
+/* allocate trace buffer */
+void dapls_io_trc_alloc(DAPL_EP * ep_ptr)
+{
+       DAT_RETURN dat_status;
+       int i;
+       struct io_buf_track *ibt;
+
+       ep_ptr->ibt_dumped = 0; /* bool to control how often we print */
+       dat_status = dapls_rbuf_alloc(&ep_ptr->ibt_queue, DBG_IO_TRC_QLEN);
+       if (dat_status != DAT_SUCCESS) {
+               goto bail;
+       }
+       ibt =
+           (struct io_buf_track *)dapl_os_alloc(sizeof(struct io_buf_track) *
+                                                DBG_IO_TRC_QLEN);
+
+       if (dat_status != DAT_SUCCESS) {
+               dapls_rbuf_destroy(&ep_ptr->ibt_queue);
+               goto bail;
+       }
+       ep_ptr->ibt_base = ibt;
+       dapl_os_memzero(ibt, sizeof(struct io_buf_track) * DBG_IO_TRC_QLEN);
+
+       /* add events to free event queue */
+       for (i = 0; i < DBG_IO_TRC_QLEN; i++) {
+               dapls_rbuf_add(&ep_ptr->ibt_queue, ibt++);
+       }
+      bail:
+       return;
+}
+#endif                         /* DAPL_DBG_IO_TRC */
+
+/*
+ * Generate a disconnect event on abruct close for older verbs providers 
+ * that do not do it automatically.
+ */
+
+void
+dapl_ep_legacy_post_disconnect(DAPL_EP * ep_ptr,
+                              DAT_CLOSE_FLAGS disconnect_flags)
+{
+       ib_cm_events_t ib_cm_event;
+       DAPL_CR *cr_ptr;
+       dp_ib_cm_handle_t cm_ptr;
+
+       /*
+        * Acquire the lock and make sure we didn't get a callback
+        * that cleaned up.
+        */
+       dapl_os_lock(&ep_ptr->header.lock);
+       if (disconnect_flags == DAT_CLOSE_ABRUPT_FLAG &&
+           ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECT_PENDING) {
+               /*
+                * If this is an ABRUPT close, the provider will not generate
+                * a disconnect message so we do it manually here. Just invoke
+                * the CM callback as it will clean up the appropriate
+                * data structures, reset the state, and generate the event
+                * on the way out. Obtain the provider dependent cm_event to 
+                * pass into the callback for a disconnect.
+                */
+               ib_cm_event =
+                   dapls_ib_get_cm_event(DAT_CONNECTION_EVENT_DISCONNECTED);
+
+               cr_ptr = ep_ptr->cr_ptr;
+               cm_ptr = (dapl_llist_is_empty(&ep_ptr->cm_list_head)
+                         ? NULL : dapl_llist_peek_head(&ep_ptr->cm_list_head));
+               dapl_os_unlock(&ep_ptr->header.lock);
+
+               if (cr_ptr != NULL) {
+                       dapl_dbg_log(DAPL_DBG_TYPE_API | DAPL_DBG_TYPE_CM,
+                                    "    dapl_ep_disconnect force callback on EP %p CM handle %x\n",
+                                    ep_ptr, cr_ptr->ib_cm_handle);
+
+                       dapls_cr_callback(cr_ptr->ib_cm_handle,
+                                         ib_cm_event, NULL, 0, cr_ptr->sp_ptr);
+               } else {
+                       dapl_evd_connection_callback(cm_ptr,
+                                                    ib_cm_event,
+                                                    NULL, 0, (void *)ep_ptr);
+               }
+       } else {
+               dapl_os_unlock(&ep_ptr->header.lock);
+       }
+}
+
+/*
+ * dapl_ep_link_cm
+ *
+ * Add linking of provider's CM object to a EP structure
+ * This enables multiple CM's per EP, and syncronization
+ *
+ * Input:
+ *     DAPL_EP *ep_ptr
+ *     dp_ib_cm_handle_t *cm_ptr  defined in provider's dapl_util.h
+ *
+ *     CM objects linked with EP using  ->list_entry
+ * Output:
+ *     none
+ *
+ * Returns:
+ *     none
+ *
+ */
+void dapl_ep_link_cm(IN DAPL_EP *ep_ptr, IN dp_ib_cm_handle_t cm_ptr)
+{
+       dapl_os_lock(&ep_ptr->header.lock);
+       dapls_cm_acquire(cm_ptr);
+       dapl_llist_add_tail(&ep_ptr->cm_list_head, &cm_ptr->list_entry, cm_ptr);
+       dapl_os_unlock(&ep_ptr->header.lock);
+}
+
+void dapl_ep_unlink_cm(IN DAPL_EP *ep_ptr, IN dp_ib_cm_handle_t cm_ptr)
+{
+       dapl_os_lock(&ep_ptr->header.lock);
+       dapl_llist_remove_entry(&ep_ptr->cm_list_head, &cm_ptr->list_entry);
+       dapls_cm_release(cm_ptr);
+       dapl_os_unlock(&ep_ptr->header.lock);
+}
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 8
+ * End:
+ */
index 14a10c79fc4f840192a9811ac9bdeaaf7940d37a..cb3eb1b7da136dff2880b04fd2b0e056222dea53 100644 (file)
@@ -96,6 +96,10 @@ char *dapl_event_str(IN DAT_EVENT_NUMBER event_num)
                 DAT_IB_EXTENSION_RANGE_BASE + 1},
                {"DAT_IB_UD_CONNECTION_EVENT_ESTABLISHED",
                 DAT_IB_EXTENSION_RANGE_BASE + 2},
+               {"DAT_IB_UD_CONNECTION_REJECT_EVENT",
+                DAT_IB_EXTENSION_RANGE_BASE + 3},
+               {"DAT_IB_UD_CONNECTION_ERROR_EVENT",
+                DAT_IB_EXTENSION_RANGE_BASE + 4},
                {"DAT_IW_EXTENSION_RANGE_BASE", DAT_IW_EXTENSION_RANGE_BASE},
 #endif                         /* DAT_EXTENSIONS */
                {NULL, 0},
index b8f068c941ea134559134fe57b66ad0e8aec891d..4a8a4006a03436fe70255a5bd6a65deaaa405f10 100644 (file)
@@ -38,7 +38,6 @@
 #include "dapl_adapter_util.h"
 #include "dapl_provider.h"
 #include "dapl_hca_util.h"
-#include "dapl_hash.h"
 
 /*
  * dapl_hca_alloc
@@ -66,13 +65,6 @@ DAPL_HCA *dapl_hca_alloc(char *name, char *port)
        }
 
        dapl_os_memzero(hca_ptr, sizeof(DAPL_HCA));
-
-       if (DAT_SUCCESS !=
-           dapls_hash_create(DAPL_HASH_TABLE_DEFAULT_CAPACITY,
-                             &hca_ptr->lmr_hash_table)) {
-               goto bail;
-       }
-
        dapl_os_lock_init(&hca_ptr->lock);
        dapl_llist_init_head(&hca_ptr->ia_list_head);
 
@@ -87,13 +79,8 @@ DAPL_HCA *dapl_hca_alloc(char *name, char *port)
        return (hca_ptr);
 
       bail:
-       if (NULL != hca_ptr) {
-               if (NULL != hca_ptr->lmr_hash_table) {
-                       dapls_hash_free(hca_ptr->lmr_hash_table);
-               }
-
+       if (NULL != hca_ptr) 
                dapl_os_free(hca_ptr, sizeof(DAPL_HCA));
-       }
 
        return NULL;
 }
@@ -115,7 +102,6 @@ DAPL_HCA *dapl_hca_alloc(char *name, char *port)
  */
 void dapl_hca_free(DAPL_HCA * hca_ptr)
 {
-       (void)dapls_hash_free(hca_ptr->lmr_hash_table);
        dapl_os_free(hca_ptr->name, dapl_os_strlen(hca_ptr->name) + 1);
        dapl_os_free(hca_ptr, sizeof(DAPL_HCA));
 }
index e72824a8961f6ad1f2adb87df4d4e726196e75d8..5f9336f8be6e08234685f3cba52e327a0bb91f87 100644 (file)
@@ -90,29 +90,12 @@ DAT_RETURN DAT_API dapl_lmr_free(IN DAT_LMR_HANDLE lmr_handle)
                                return DAT_INVALID_STATE;
                        }
 
-                       dat_status =
-                           dapls_hash_remove(lmr->header.owner_ia->hca_ptr->
-                                             lmr_hash_table,
-                                             lmr->param.lmr_context, NULL);
-                       if (dat_status != DAT_SUCCESS) {
-                               goto bail;
-                       }
-
                        dat_status = dapls_ib_mr_deregister(lmr);
 
                        if (dat_status == DAT_SUCCESS) {
                                dapl_os_atomic_dec(&pz->pz_ref_count);
                                dapl_lmr_dealloc(lmr);
-                       } else {
-                               /*
-                                * Deregister failed; put it back in the
-                                * hash table.
-                                */
-                               dapls_hash_insert(lmr->header.owner_ia->
-                                                 hca_ptr->lmr_hash_table,
-                                                 lmr->param.lmr_context, lmr);
-                       }
-
+                       } 
                        break;
                }
 #if defined(__KDAPL__)
index 9793f38c72e0c9826c5e87d1ea946d2833537acd..ecb190b7d0615fb9b484ed354128ccd5ca8e50c0 100644 (file)
@@ -48,7 +48,8 @@
 
 STATIC _INLINE_ DAT_RETURN
 dapli_rmr_bind_fuse(IN DAPL_RMR * rmr,
-                   IN const DAT_LMR_TRIPLET * lmr_triplet,
+                   IN DAT_LMR_HANDLE lmr_handle,
+                   IN const DAT_LMR_TRIPLET * lmr_triplet,
                    IN DAT_MEM_PRIV_FLAGS mem_priv,
                    IN DAPL_EP * ep_ptr,
                    IN DAT_RMR_COOKIE user_cookie,
@@ -69,6 +70,7 @@ dapli_rmr_bind_unfuse(IN DAPL_RMR * rmr,
 
 DAT_RETURN
 dapli_rmr_bind_fuse(IN DAPL_RMR * rmr,
+                   IN DAT_LMR_HANDLE lmr_handle,
                    IN const DAT_LMR_TRIPLET * lmr_triplet,
                    IN DAT_MEM_PRIV_FLAGS mem_priv,
                    IN DAPL_EP * ep_ptr,
@@ -80,16 +82,8 @@ dapli_rmr_bind_fuse(IN DAPL_RMR * rmr,
        DAPL_COOKIE *cookie;
        DAT_RETURN dat_status;
        DAT_BOOLEAN is_signaled;
-       DAPL_HASH_DATA hash_lmr;
 
-       dat_status =
-           dapls_hash_search(rmr->header.owner_ia->hca_ptr->lmr_hash_table,
-                             lmr_triplet->lmr_context, &hash_lmr);
-       if (DAT_SUCCESS != dat_status) {
-               dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2);
-               goto bail;
-       }
-       lmr = (DAPL_LMR *) hash_lmr;
+       lmr = (DAPL_LMR *) lmr_handle;
 
        /* if the ep in unconnected return an error. IB requires that the */
        /* QP be connected to change a memory window binding since:       */
@@ -305,6 +299,7 @@ dapl_rmr_bind(IN DAT_RMR_HANDLE rmr_handle,
        /* if the rmr should be bound */
        if (0 != lmr_triplet->segment_length) {
                return dapli_rmr_bind_fuse(rmr,
+                                          lmr_handle,
                                           lmr_triplet,
                                           mem_priv,
                                           ep_ptr,
index a35b1188cebacf3d2528e2fe6c017865ff6bbb1c..e3c12ffe7e498f3f213da39c907d89b73d1d44d4 100644 (file)
-\r
-/*\r
- * Copyright (c) 2005-2007 Intel Corporation. All rights reserved.\r
- * Copyright (c) 2002, Network Appliance, Inc. All rights reserved. \r
- * \r
- * This Software is licensed under the terms of the "Common Public\r
- * License" a copy of which is in the file LICENSE.txt in the root\r
- * directory. The license is also available from the Open Source\r
- * Initiative, see http://www.opensource.org/licenses/cpl.php.\r
- *\r
- */\r
-\r
-/**********************************************************************\r
- * \r
- * MODULE: dapl_ibal_cm.c\r
- *\r
- * PURPOSE: IB Connection routines for access to IBAL APIs\r
- *\r
- * $Id: dapl_ibal_cm.c 584 2007-02-07 13:12:18Z sleybo $\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_sp_util.h"\r
-#include "dapl_ep_util.h"\r
-#include "dapl_ia_util.h"\r
-#include "dapl_ibal_util.h"\r
-#include "dapl_name_service.h"\r
-#include "dapl_ibal_name_service.h"\r
-#include "dapl_cookie.h"\r
-\r
-#define IB_INFINITE_SERVICE_LEASE   0xFFFFFFFF\r
-#define  DAPL_ATS_SERVICE_ID        ATS_SERVICE_ID //0x10000CE100415453\r
-#define  DAPL_ATS_NAME              ATS_NAME\r
-#define  HCA_IPV6_ADDRESS_LENGTH    16\r
-\r
-/* until dapl_ibal_util.h define of IB_INVALID_HANDLE which overlaps the\r
- * Windows ib_types.h typedef enu ib_api_status_t IB_INVALID_HANDLE is fixed.\r
- */\r
-#undef IB_INVALID_HANDLE\r
-#define DAPL_IB_INVALID_HANDLE NULL\r
-\r
-int g_dapl_loopback_connection = 0;\r
-extern dapl_ibal_root_t        dapl_ibal_root;\r
-\r
-/*\r
- * Prototypes\r
- */\r
-\r
-char *\r
-dapli_ib_cm_event_str(ib_cm_events_t e)\r
-{\r
-#ifdef DBG\r
-    char        *cp;\r
-    static char *event_str[13] = {\r
-        "IB_CME_CONNECTED",\r
-        "IB_CME_DISCONNECTED",\r
-        "IB_CME_DISCONNECTED_ON_LINK_DOWN",\r
-        "IB_CME_CONNECTION_REQUEST_PENDING",\r
-        "IB_CME_CONNECTION_REQUEST_PENDING_PRIVATE_DATA",\r
-        "IB_CME_DESTINATION_REJECT",\r
-        "IB_CME_DESTINATION_REJECT_PRIVATE_DATA",\r
-        "IB_CME_DESTINATION_UNREACHABLE",\r
-        "IB_CME_TOO_MANY_CONNECTION_REQUESTS",\r
-        "IB_CME_LOCAL_FAILURE",\r
-        "IB_CME_REPLY_RECEIVED",\r
-        "IB_CME_REPLY_RECEIVED_PRIVATE_DATA",\r
-        "IB_CM_LOCAL_FAILURE"\r
-    };\r
-\r
-    if (e > IB_CM_LOCAL_FAILURE || e < IB_CME_CONNECTED)\r
-       cp =  "BAD EVENT";\r
-    else\r
-        cp = event_str[e];\r
-\r
-    return cp;\r
-#else\r
-    static char num[8];\r
-    sprintf(num,"%d",e);\r
-    return num;\r
-#endif\r
-}\r
-\r
-\r
-#if defined(DAPL_DBG)\r
-\r
-void dapli_print_private_data( char *prefix, const uint8_t *pd, int len )\r
-{\r
-    int i;\r
-            \r
-    if ( !pd || len <= 0 )\r
-       return;\r
-\r
-    dapl_log ( DAPL_DBG_TYPE_CM, "--> %s: private_data(len %d)\n    ",prefix,len);\r
-\r
-    if (len > IB_MAX_REP_PDATA_SIZE)\r
-    {\r
-       dapl_log ( DAPL_DBG_TYPE_ERR,\r
-               "    Private data size(%d) > Max(%d), ignored.\n    ",\r
-                                       len,DAPL_MAX_PRIVATE_DATA_SIZE);\r
-       len = IB_MAX_REP_PDATA_SIZE;\r
-    }\r
-\r
-    for ( i = 0 ; i < len; i++ )\r
-    {\r
-       dapl_log ( DAPL_DBG_TYPE_CM, "%2x ", pd[i]);\r
-       if ( ((i+1) % 5) == 0 ) \r
-           dapl_log ( DAPL_DBG_TYPE_CM, "\n    ");\r
-    }\r
-   dapl_log ( DAPL_DBG_TYPE_CM, "\n");\r
-}\r
-#endif\r
-\r
-/* EP-CM linking support */\r
-dp_ib_cm_handle_t ibal_cm_alloc(void)\r
-{\r
-       dp_ib_cm_handle_t cm_ptr;\r
-\r
-       /* Allocate CM, init lock, and initialize */\r
-       if ((cm_ptr = dapl_os_alloc(sizeof(*cm_ptr))) == NULL)\r
-               return NULL;\r
-\r
-       (void)dapl_os_memzero(cm_ptr, sizeof(*cm_ptr));\r
-       cm_ptr->ref_count = 1;\r
-\r
-       if (dapl_os_lock_init(&cm_ptr->lock)) {\r
-               dapl_os_free(cm_ptr, sizeof(*cm_ptr));\r
-               return NULL;\r
-       }\r
-\r
-       dapl_llist_init_entry((DAPL_LLIST_ENTRY *)&cm_ptr->list_entry);\r
-       \r
-       return cm_ptr;\r
-}\r
-\r
-/* free CM object resources */\r
-static void ibal_cm_dealloc(dp_ib_cm_handle_t cm_ptr) \r
-{\r
-       dapl_os_assert(!cm_ptr->ref_count);\r
-       dapl_os_lock_destroy(&cm_ptr->lock);\r
-       dapl_os_free(cm_ptr, sizeof(*cm_ptr));\r
-}\r
-\r
-void dapls_cm_acquire(dp_ib_cm_handle_t cm_ptr)\r
-{\r
-       dapl_os_lock(&cm_ptr->lock);\r
-       cm_ptr->ref_count++;\r
-       dapl_os_unlock(&cm_ptr->lock);\r
-}\r
-\r
-void dapls_cm_release(dp_ib_cm_handle_t cm_ptr)\r
-{\r
-       dapl_os_lock(&cm_ptr->lock);\r
-       cm_ptr->ref_count--;\r
-       if (cm_ptr->ref_count) {\r
-                dapl_os_unlock(&cm_ptr->lock);\r
-               return;\r
-       }\r
-       dapl_os_unlock(&cm_ptr->lock);\r
-       ibal_cm_dealloc(cm_ptr);\r
-}\r
-\r
-/* blocking: called from user thread dapl_ep_free() only */\r
-void dapls_cm_free(dp_ib_cm_handle_t cm_ptr)\r
-{\r
-       dapl_ep_unlink_cm(cm_ptr->ep, cm_ptr);\r
-\r
-       /* final reference, alloc */\r
-       dapls_cm_release(cm_ptr);\r
-}\r
-\r
-static void \r
-dapli_ib_cm_apr_cb (\r
-        IN    ib_cm_apr_rec_t          *p_cm_apr_rec )\r
-{\r
-    UNUSED_PARAM( p_cm_apr_rec );\r
-\r
-    dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
-                  "--> DiCAcb: CM callback APR (Alternate Path Request)\n");\r
-}\r
-\r
-static void \r
-dapli_ib_cm_lap_cb (\r
-        IN    ib_cm_lap_rec_t          *p_cm_lap_rec )\r
-{\r
-    UNUSED_PARAM( p_cm_lap_rec );\r
-\r
-    dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
-                  "--> DiCLcb: CM callback LAP (Load Alternate Path)\n");\r
-}\r
-\r
-/*\r
- * Connection Disconnect Request callback\r
- * We received a DREQ, return a DREP (disconnect reply).\r
- */\r
-\r
-static void \r
-dapli_ib_cm_dreq_cb (\r
-        IN    ib_cm_dreq_rec_t          *p_cm_dreq_rec )\r
-{\r
-    ib_cm_drep_t        cm_drep;\r
-    DAPL_EP             *ep_ptr;\r
-    int                        bail=10;\r
-    dp_ib_cm_handle_t  cm_ptr;\r
-    \r
-    dapl_os_assert (p_cm_dreq_rec);\r
-\r
-    ep_ptr  = (DAPL_EP * __ptr64) p_cm_dreq_rec->qp_context;\r
-    if ( DAPL_BAD_PTR(ep_ptr) )\r
-    {\r
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR, \r
-                      "--> %s: BAD_PTR EP %lx\n", __FUNCTION__, ep_ptr);\r
-        return;\r
-    }\r
-    if ( ep_ptr->header.magic != DAPL_MAGIC_EP  )\r
-    {\r
-        if ( ep_ptr->header.magic == DAPL_MAGIC_INVALID )\r
-            return;\r
-\r
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                      "--> %s: EP %p BAD_EP_MAGIC %x != wanted %x\n",\r
-                      __FUNCTION__, ep_ptr, ep_ptr->header.magic,\r
-                      DAPL_MAGIC_EP );\r
-        return;\r
-    }\r
-    cm_ptr = dapl_get_cm_from_ep(ep_ptr);\r
-    if (!cm_ptr)\r
-    {\r
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                      "--> %s: !CM_PTR on EP %p\n", __FUNCTION__, ep_ptr);\r
-        return;\r
-    }\r
-    dapl_os_assert(cm_ptr->ib_cm.h_qp == p_cm_dreq_rec->h_cm_dreq.h_qp);\r
-\r
-    dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
-                  "--> %s() EP %p, %s sent_discreq %s\n",\r
-                  __FUNCTION__,ep_ptr,\r
-                  dapl_get_ep_state_str(ep_ptr->param.ep_state),\r
-                  (ep_ptr->sent_discreq == DAT_TRUE ? "TRUE":"FALSE"));\r
-\r
-    dapl_os_lock (&ep_ptr->header.lock);\r
-    if ( ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED\r
-         /*|| ( ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECT_PENDING\r
-           && ep_ptr->sent_discreq == DAT_TRUE)*/ )\r
-    {\r
-        dapl_os_unlock (&ep_ptr->header.lock);\r
-        dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
-                      "--> DiCDcb: EP %lx QP %lx already Disconnected\n",\r
-                      ep_ptr, ep_ptr->qp_handle);\r
-        return;\r
-    }\r
-\r
-    ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECT_PENDING;\r
-    ep_ptr->recv_discreq = DAT_TRUE;\r
-    dapl_os_unlock (&ep_ptr->header.lock);\r
-\r
-    dapl_os_memzero (&cm_drep, sizeof(ib_cm_drep_t));\r
-\r
-    /* Could fail if we received reply from other side, no need to retry */\r
-    /* Wait for any send ops in process holding reference */\r
-    while (dapls_cb_pending(&ep_ptr->req_buffer) && bail-- > 0 )\r
-    {\r
-       dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
-                  "--> DiCDcb: WAIT for EP=%lx req_count(%d) != 0\n", \r
-                  ep_ptr, dapls_cb_pending(&ep_ptr->req_buffer));\r
-       dapl_os_sleep_usec (100);\r
-    }\r
-\r
-    ib_cm_drep (p_cm_dreq_rec->h_cm_dreq, &cm_drep);\r
-\r
-    /* CM puts QP in reset state */\r
-    ep_ptr->qp_state = IB_QPS_RESET;\r
-          \r
-    if (ep_ptr->cr_ptr)\r
-    {\r
-        /* passive side */\r
-        dapls_cr_callback ( cm_ptr,\r
-                            IB_CME_DISCONNECTED,\r
-                            (void * __ptr64) p_cm_dreq_rec->p_dreq_pdata,\r
-                           IB_DREQ_PDATA_SIZE,\r
-                            (void *) (((DAPL_CR *) ep_ptr->cr_ptr)->sp_ptr) );\r
-    }\r
-    else\r
-    {\r
-        /* active side */\r
-        dapl_evd_connection_callback (\r
-                                  cm_ptr,\r
-                                  IB_CME_DISCONNECTED,\r
-                                  (void * __ptr64)\r
-                                  p_cm_dreq_rec->p_dreq_pdata,\r
-                                 IB_DREQ_PDATA_SIZE,\r
-                                  p_cm_dreq_rec->qp_context );\r
-    }\r
-}\r
-\r
-/*\r
- * Connection Disconnect Reply callback\r
- * We sent a DREQ and received a DREP.\r
- */\r
-\r
-static void \r
-dapli_ib_cm_drep_cb (\r
-        IN    ib_cm_drep_rec_t          *p_cm_drep_rec )\r
-{\r
-    DAPL_EP            *ep_ptr;\r
-    dp_ib_cm_handle_t  cm_ptr;\r
-    \r
-    dapl_os_assert (p_cm_drep_rec != NULL);\r
-\r
-    ep_ptr  = (DAPL_EP * __ptr64) p_cm_drep_rec->qp_context;\r
-\r
-    if (p_cm_drep_rec->cm_status)\r
-    {\r
-         dapl_dbg_log (DAPL_DBG_TYPE_CM,\r
-                  "--> %s: DREP cm_status(%s) EP=%p\n", __FUNCTION__,\r
-                  ib_get_err_str(p_cm_drep_rec->cm_status), ep_ptr); \r
-    }\r
-\r
-    if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )\r
-    {\r
-         dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                  "--> %s: BAD EP Handle EP=%lx\n", __FUNCTION__,ep_ptr); \r
-        return;\r
-    }\r
-    cm_ptr = dapl_get_cm_from_ep(ep_ptr);\r
-    if (!cm_ptr)\r
-    {\r
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                      "--> %s: !CM_PTR on EP %p\n", __FUNCTION__, ep_ptr);\r
-        return;\r
-    }\r
-    dapl_os_assert(cm_ptr->ib_cm.h_qp == p_cm_drep_rec->h_qp);\r
-    \r
-    dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
-       "--> DiCDpcb: EP %p state %s cm_hdl %p\n",ep_ptr,\r
-                  dapl_get_ep_state_str(ep_ptr->param.ep_state),\r
-                  cm_ptr);\r
-\r
-    if ( ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED )\r
-    {\r
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR, \r
-                      "--> DiCDpcb: EP %lx QP %lx already Disconnected\n",\r
-                      ep_ptr, ep_ptr->qp_handle);\r
-        return;\r
-    }\r
-\r
-    if (ep_ptr->cr_ptr)\r
-    {\r
-        /* passive connection side */\r
-        dapls_cr_callback ( cm_ptr,\r
-                            IB_CME_DISCONNECTED,\r
-                           (void * __ptr64) p_cm_drep_rec->p_drep_pdata,\r
-                          IB_DREP_PDATA_SIZE,\r
-                           (void *) (((DAPL_CR *) ep_ptr->cr_ptr)->sp_ptr) );\r
-    }\r
-    else\r
-    {\r
-        /* active connection side */\r
-        dapl_evd_connection_callback (\r
-                                   cm_ptr,\r
-                                   IB_CME_DISCONNECTED,\r
-                                   (void * __ptr64) p_cm_drep_rec->p_drep_pdata,\r
-                                  IB_DREP_PDATA_SIZE,\r
-                                   p_cm_drep_rec->qp_context );\r
-    }\r
-}\r
-\r
-/*\r
- * CM reply callback\r
- */\r
-\r
-static void \r
-dapli_ib_cm_rep_cb (\r
-        IN    ib_cm_rep_rec_t          *p_cm_rep_rec )\r
-{\r
-    ib_api_status_t     ib_status; \r
-    ib_cm_rtu_t         cm_rtu;\r
-    uint8_t             cm_cb_op;\r
-    DAPL_PRIVATE        *prd_ptr;\r
-    DAPL_EP             *ep_ptr;\r
-    dapl_ibal_ca_t      *p_ca;\r
-    dp_ib_cm_handle_t  cm_ptr;\r
-        \r
-    dapl_os_assert (p_cm_rep_rec != NULL);\r
-\r
-    ep_ptr  = (DAPL_EP * __ptr64) p_cm_rep_rec->qp_context;\r
-\r
-    if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )\r
-    {\r
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: EP %lx invalid or FREED\n",\r
-                      __FUNCTION__, ep_ptr);\r
-        return;\r
-    }\r
-    cm_ptr = dapl_get_cm_from_ep(ep_ptr);\r
-    if (!cm_ptr)\r
-    {\r
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                      "--> %s: !CM_PTR on EP %p\n", __FUNCTION__, ep_ptr);\r
-        return;\r
-    }\r
-    dapl_os_assert(cm_ptr->ib_cm.h_qp == p_cm_rep_rec->h_cm_rep.h_qp);\r
-\r
-    dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
-                  "--> DiCRpcb: EP %lx local_max_rdma_read_in %d\n", \r
-                  ep_ptr, p_cm_rep_rec->resp_res);\r
-\r
-    p_ca   = (dapl_ibal_ca_t *) \r
-             ep_ptr->header.owner_ia->hca_ptr->ib_hca_handle;\r
-\r
-    dapl_os_memzero (&cm_rtu, sizeof ( ib_cm_rtu_t ));\r
-    cm_rtu.pfn_cm_apr_cb  = dapli_ib_cm_apr_cb;\r
-    cm_rtu.pfn_cm_dreq_cb = dapli_ib_cm_dreq_cb;\r
-    cm_rtu.p_rtu_pdata    = NULL;\r
-    cm_rtu.access_ctrl = \r
-               IB_AC_LOCAL_WRITE|IB_AC_RDMA_WRITE|IB_AC_MW_BIND|IB_AC_ATOMIC;\r
-    if ((ep_ptr->param.ep_attr.max_rdma_read_in > 0) || \r
-               (ep_ptr->param.ep_attr.max_rdma_read_out > 0))\r
-    {\r
-       cm_rtu.access_ctrl |= IB_AC_RDMA_READ;\r
-    }\r
-           \r
-    cm_rtu.rq_depth       = 0;\r
-    cm_rtu.sq_depth       = 0;\r
-       \r
-    ib_status = ib_cm_rtu (p_cm_rep_rec->h_cm_rep, &cm_rtu);\r
-\r
-    if (ib_status == IB_SUCCESS)\r
-    {\r
-        cm_cb_op = IB_CME_CONNECTED;\r
-        dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
-                  "--> DiCRpcb: EP %lx Connected req_count %d\n", \r
-                  ep_ptr, dapls_cb_pending(&ep_ptr->req_buffer));\r
-    }\r
-    else\r
-    {\r
-        cm_cb_op = IB_CME_LOCAL_FAILURE;\r
-    }\r
-\r
-    prd_ptr = (DAPL_PRIVATE * __ptr64) p_cm_rep_rec->p_rep_pdata;\r
-\r
-#if defined(DAPL_DBG) && 0\r
-    dapli_print_private_data( "DiCRpcb",\r
-                             prd_ptr->private_data,\r
-                             IB_MAX_REP_PDATA_SIZE);\r
-#endif\r
-\r
-    dapl_evd_connection_callback ( \r
-                            cm_ptr,\r
-                            cm_cb_op,\r
-                            (void *) prd_ptr,\r
-                           IB_REP_PDATA_SIZE,\r
-                            (void * __ptr64) p_cm_rep_rec->qp_context);\r
-}\r
-\r
-\r
-static void \r
-dapli_ib_cm_rej_cb (\r
-        IN    ib_cm_rej_rec_t          *p_cm_rej_rec )\r
-{\r
-    DAPL_EP         *ep_ptr;\r
-    ib_cm_events_t  cm_event;\r
-    dp_ib_cm_handle_t  cm_ptr;\r
-\r
-    dapl_os_assert (p_cm_rej_rec);\r
-\r
-    ep_ptr = (DAPL_EP * __ptr64) p_cm_rej_rec->qp_context;\r
-\r
-    if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )\r
-    {\r
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: EP %lx invalid or FREED\n",\r
-                      __FUNCTION__, ep_ptr);\r
-        return;\r
-    }\r
-    cm_ptr = dapl_get_cm_from_ep(ep_ptr);\r
-    if (!cm_ptr)\r
-    {\r
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR, \r
-                      "--> %s: !CM_PTR on EP %p\n", __FUNCTION__, ep_ptr);\r
-        return;\r
-    }\r
-    dapl_os_assert(cm_ptr->ib_cm.h_qp == p_cm_rej_rec->h_qp);\r
-\r
-    dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
-                  "--> DiCRjcb: EP = %lx QP = %lx rej reason = 0x%x\n", \r
-                  ep_ptr,ep_ptr->qp_handle,CL_NTOH16(p_cm_rej_rec->rej_status));\r
-\r
-    switch (p_cm_rej_rec->rej_status)\r
-    {\r
-        case IB_REJ_INSUF_RESOURCES:\r
-        case IB_REJ_INSUF_QP:\r
-        case IB_REJ_INVALID_COMM_ID:\r
-        case IB_REJ_INVALID_COMM_INSTANCE:\r
-        case IB_REJ_INVALID_PKT_RATE:\r
-        case IB_REJ_INVALID_ALT_GID:\r
-        case IB_REJ_INVALID_ALT_LID:\r
-        case IB_REJ_INVALID_ALT_SL:\r
-        case IB_REJ_INVALID_ALT_TRAFFIC_CLASS:\r
-        case IB_REJ_INVALID_ALT_PKT_RATE:\r
-        case IB_REJ_INVALID_ALT_HOP_LIMIT:\r
-        case IB_REJ_INVALID_ALT_FLOW_LBL:\r
-        case IB_REJ_INVALID_GID:\r
-        case IB_REJ_INVALID_LID:\r
-        case IB_REJ_INVALID_SID:\r
-        case IB_REJ_INVALID_SL:\r
-        case IB_REJ_INVALID_TRAFFIC_CLASS:\r
-        case IB_REJ_PORT_REDIRECT:\r
-        case IB_REJ_INVALID_MTU:\r
-        case IB_REJ_INSUFFICIENT_RESP_RES:\r
-        case IB_REJ_INVALID_CLASS_VER:\r
-        case IB_REJ_INVALID_FLOW_LBL:\r
-            cm_event = IB_CME_DESTINATION_REJECT;\r
-            break;\r
-\r
-        case IB_REJ_TIMEOUT:\r
-            cm_event = IB_CME_DESTINATION_UNREACHABLE;\r
-            dapl_dbg_log (DAPL_DBG_TYPE_CM, "--> DiCRjcb: CR TIMEOUT\n");\r
-            break;\r
-\r
-        case IB_REJ_USER_DEFINED:\r
-            cm_event = IB_CME_DESTINATION_REJECT;\r
-            dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
-                               "--> DiCRjcb: user defined rej reason %s\n",\r
-                               p_cm_rej_rec->p_ari);\r
-            break;\r
-\r
-        default:\r
-            cm_event = IB_CME_LOCAL_FAILURE;\r
-            dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
-                               "--> DiCRjcb: with unknown status %x\n", \r
-                               p_cm_rej_rec->rej_status);\r
-            break;\r
-     }\r
-\r
-    /* FIXME - Vu\r
-     * We do not take care off the user defined rej reason with additional \r
-     * rejection information (p_ari)\r
-     */\r
-\r
-    if (ep_ptr->cr_ptr)\r
-    {\r
-        dapls_cr_callback ( cm_ptr,\r
-                            cm_event,\r
-                            (void * __ptr64) p_cm_rej_rec->p_rej_pdata,\r
-                           IB_REJ_PDATA_SIZE,\r
-                            (void *) ((DAPL_CR *) ep_ptr->cr_ptr)->sp_ptr);\r
-    }\r
-    else\r
-    {\r
-        dapl_evd_connection_callback (\r
-                                   cm_ptr,\r
-                                   cm_event,\r
-                                   (void * __ptr64) p_cm_rej_rec->p_rej_pdata,\r
-                                  IB_REJ_PDATA_SIZE,\r
-                                   (void * __ptr64) p_cm_rej_rec->qp_context );\r
-    }\r
-\r
-}\r
-\r
-\r
-\r
-static void \r
-dapli_ib_cm_req_cb ( IN  ib_cm_req_rec_t  *p_cm_req_rec )\r
-{\r
-    DAPL_SP              *sp_ptr;\r
-    DAT_SOCK_ADDR6       dest_ia_addr;\r
-    dp_ib_cm_handle_t    cm_ptr;\r
-\r
-    dapl_os_assert (p_cm_req_rec);\r
-\r
-    sp_ptr = (DAPL_SP * __ptr64) p_cm_req_rec->context;\r
-\r
-    dapl_os_assert (sp_ptr);\r
-\r
-    /*\r
-     * The context pointer could have been cleaned up in a racing\r
-     * CM callback, check to see if we should just exit here\r
-     */\r
-    if (sp_ptr->header.magic == DAPL_MAGIC_INVALID)\r
-    {\r
-        dapl_dbg_log (DAPL_DBG_TYPE_CM,\r
-                     "%s: BAD-Magic in SP %lx, racing CM callback?\n",\r
-                      __FUNCTION__, sp_ptr );\r
-       return;\r
-    }\r
-\r
-    dapl_os_assert ( sp_ptr->header.magic == DAPL_MAGIC_PSP || \r
-                     sp_ptr->header.magic == DAPL_MAGIC_RSP );\r
-\r
-    /* preserve ibal's connection handle storage so we have a consistent\r
-     * pointer value. The reasons this is done dynamically instead of a static\r
-     * allocation in an end_point is the pointer value is set in the SP list\r
-     * of CR's here and searched for from disconnect callbacks. If the pointer\r
-     * value changes, you never find the CR on the sp list...\r
-     * EP struct deallocation is where this memory is released or prior in the\r
-     * error case.\r
-     */\r
-    cm_ptr = ibal_cm_alloc();\r
-    if (!cm_ptr)\r
-    {\r
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
-                       "%s: FAILED to alloc IB CM handle storage?\n",\r
-                       __FUNCTION__);\r
-        return;\r
-    }\r
-\r
-    /*\r
-     * Save the cm_srvc_handle to avoid the race condition between\r
-     * the return of the ib_cm_listen and the notification of a conn req\r
-     */\r
-    if (sp_ptr->cm_srvc_handle != p_cm_req_rec->h_cm_listen)\r
-    {\r
-        dapl_dbg_log (DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK, \r
-                           "--> DiCRqcb: cm_service_handle is changed\n"); \r
-        sp_ptr->cm_srvc_handle = p_cm_req_rec->h_cm_listen;\r
-    }\r
-\r
-    dapl_os_memzero (&dest_ia_addr, sizeof (dest_ia_addr));\r
-\r
-#ifdef NO_NAME_SERVICE\r
-\r
-    {\r
-        DAPL_PRIVATE *prd_ptr;\r
-        \r
-        prd_ptr = (DAPL_PRIVATE *)p_cm_req_rec->p_req_pdata;\r
-\r
-        dapl_os_memcpy ((void *)&dest_ia_addr,\r
-                        (void *)&prd_ptr->hca_address,\r
-                        sizeof (DAT_SOCK_ADDR6));        \r
-    }\r
-    \r
-#else\r
-\r
-    {\r
-        GID            dest_gid;\r
-\r
-        dapl_os_memzero (&dest_gid, sizeof (dest_gid));\r
-\r
-        dest_gid.guid = p_cm_req_rec->primary_path.dgid.unicast.interface_id;\r
-        dest_gid.gid_prefix = p_cm_req_rec->primary_path.dgid.unicast.prefix;\r
-\r
-        if (DAT_SUCCESS != dapls_ns_map_ipaddr (\r
-                                 sp_ptr->header.owner_ia->hca_ptr,\r
-                                 dest_gid,\r
-                                 (DAT_IA_ADDRESS_PTR)&dest_ia_addr))\r
-        {\r
-            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
-                           "cm_req_cb: SP = %lx failed mapping GID-IPaddr\n",\r
-                           sp_ptr);\r
-        }\r
-    }\r
-\r
-#endif /* NO_NAME_SERVICE */\r
-\r
-    /* preserve CR cm handle data */\r
-    dapl_os_memcpy( (void*)&cm_ptr->ib_cm,\r
-                    (void*)&p_cm_req_rec->h_cm_req,\r
-                    sizeof(ib_cm_handle_t));\r
-\r
-    /* preserve remote IP address */\r
-    dapl_os_memcpy( (void*)&cm_ptr->dst_ip_addr,\r
-                    (void*)&dest_ia_addr,\r
-                    sizeof(dest_ia_addr));\r
-\r
-#if defined(DAPL_DBG)\r
-    {\r
-        char ipa[20];\r
-  \r
-        //rval = ((struct sockaddr_in *) (&dest_ia_addr))->sin_addr.s_addr;\r
-\r
-        dapl_dbg_log (DAPL_DBG_TYPE_CM|DAPL_DBG_TYPE_CALLBACK, \r
-                      "%s: query SA (CM %lx)->dst_ip_addr: %s\n",\r
-                      __FUNCTION__,cm_ptr,\r
-                      dapli_get_ip_addr_str(\r
-                               (DAT_SOCK_ADDR6*) &cm_ptr->dst_ip_addr, ipa) );\r
-    }\r
-#endif\r
-\r
-    /* FIXME - Vu\r
-     * We have NOT used/saved the primary and alternative path record\r
-     * ie. p_cm_req_rec->p_primary_path and p_cm_req_rec->p_alt_path\r
-     * We should cache some fields in path record in the Name Service DB\r
-     * such as: dgid, dlid\r
-     * Also we do not save resp_res (ie. max_oustanding_rdma_read/atomic)\r
-     * rnr_retry_cnt and flow_ctrl fields\r
-     */\r
-    dapl_dbg_log (DAPL_DBG_TYPE_CM,\r
-                  "%s: SP %lx max_rdma_read %d PrivateData %lx\n",\r
-                  __FUNCTION__, sp_ptr, p_cm_req_rec->resp_res,\r
-                  p_cm_req_rec->p_req_pdata);\r
-\r
-    dapls_cr_callback ( cm_ptr,\r
-                        IB_CME_CONNECTION_REQUEST_PENDING,\r
-                        (void * __ptr64) p_cm_req_rec->p_req_pdata,\r
-                                               IB_REQ_PDATA_SIZE,\r
-                        (void * __ptr64) sp_ptr );\r
-}\r
-\r
-\r
-static void \r
-dapli_ib_cm_mra_cb (\r
-        IN    ib_cm_mra_rec_t          *p_cm_mra_rec )\r
-{\r
-       UNUSED_PARAM( p_cm_mra_rec );\r
-       dapl_dbg_log (DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK, \r
-                       "--> DiCMcb: CM callback MRA\n");\r
-}\r
-\r
-static void \r
-dapli_ib_cm_rtu_cb (\r
-        IN    ib_cm_rtu_rec_t          *p_cm_rtu_rec )\r
-{\r
-    DAPL_EP            *ep_ptr;\r
-    dp_ib_cm_handle_t  cm_ptr;\r
-\r
-    dapl_os_assert (p_cm_rtu_rec != NULL);\r
-   \r
-    ep_ptr = (DAPL_EP * __ptr64) p_cm_rtu_rec->qp_context;\r
-\r
-    if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )\r
-    {\r
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: EP %lx invalid or FREED\n",\r
-                      __FUNCTION__, ep_ptr);\r
-        return;\r
-    }\r
-    cm_ptr = dapl_get_cm_from_ep(ep_ptr);\r
-    if (!cm_ptr)\r
-    {\r
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                      "--> %s: !CM_PTR on EP %p\n", __FUNCTION__, ep_ptr);\r
-        return;\r
-    }\r
-    dapl_os_assert(cm_ptr->ib_cm.h_qp == p_cm_rtu_rec->h_qp);\r
-\r
-    dapl_dbg_log (DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK, \r
-                  "--> DiCRucb: EP %lx QP %lx CR %lx\n",\r
-                  ep_ptr, ep_ptr->qp_handle, ep_ptr->cr_ptr); \r
-\r
-    if (ep_ptr->cr_ptr)\r
-    {\r
-        DAPL_SP  *sp_ptr;\r
-\r
-        sp_ptr = ((DAPL_CR *) ep_ptr->cr_ptr)->sp_ptr;\r
-\r
-        /* passive connection side */\r
-        dapls_cr_callback ( cm_ptr,\r
-                            IB_CME_CONNECTED,\r
-                            (void * __ptr64) p_cm_rtu_rec->p_rtu_pdata,\r
-                            IB_RTU_PDATA_SIZE,\r
-                            (void *) sp_ptr);\r
-                            \r
-    }\r
-    else\r
-    {\r
-        dapl_evd_connection_callback ( \r
-                            cm_ptr,\r
-                            IB_CME_CONNECTED,\r
-                            (void * __ptr64) p_cm_rtu_rec->p_rtu_pdata,\r
-                           IB_RTU_PDATA_SIZE,\r
-                            (void *) ep_ptr);\r
-    }\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 (\r
-    IN      DAT_HANDLE          dat_handle,\r
-    OUT     DAT_SOCK_ADDR6      *remote_address )\r
-{\r
-\r
-    DAPL_HEADER        *header;\r
-    dp_ib_cm_handle_t  cm;\r
-    char               ipa[20];\r
-    char               *rtype;\r
-\r
-    header = (DAPL_HEADER *)dat_handle;\r
-\r
-    if (header->magic == DAPL_MAGIC_EP) \r
-    {\r
-       cm = dapl_get_cm_from_ep((DAPL_EP *)dat_handle);\r
-       rtype = "EP";\r
-    }\r
-    else if (header->magic == DAPL_MAGIC_CR) \r
-    {\r
-       cm = ((DAPL_CR *) dat_handle)->ib_cm_handle;\r
-       rtype = "CR";\r
-    }\r
-    else \r
-    {\r
-        dapl_dbg_log ( DAPL_DBG_TYPE_CM,\r
-                       "%s: hdr->magic %x, dat_handle(%lx)\n",\r
-                       __FUNCTION__, header->magic, dat_handle );\r
-       return DAT_INVALID_HANDLE;\r
-    }\r
-\r
-    dapl_os_memcpy( remote_address, &cm->dst_ip_addr, sizeof(DAT_SOCK_ADDR6) );\r
-\r
-    dapl_dbg_log ( DAPL_DBG_TYPE_CM, "%s: returns %s remote Addrs %s\n",\r
-                   __FUNCTION__, rtype,\r
-                   dapli_get_ip_addr_str((DAT_SOCK_ADDR6*)remote_address,ipa) );\r
-\r
-    return DAT_SUCCESS;\r
-}\r
-\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\r
-dapls_ib_connect (\r
-        IN        DAT_EP_HANDLE                ep_handle,\r
-        IN        DAT_IA_ADDRESS_PTR           remote_ia_address,\r
-        IN        DAT_CONN_QUAL                remote_conn_qual,\r
-        IN        DAT_COUNT                    private_data_size,\r
-        IN        DAT_PVOID                    private_data )\r
-{\r
-    DAPL_EP                      *ep_ptr;\r
-    DAPL_IA                      *ia_ptr;\r
-    ib_api_status_t              ib_status;\r
-    dapl_ibal_port_t             *p_active_port;\r
-    dapl_ibal_ca_t               *p_ca;\r
-    ib_cm_req_t                  cm_req;\r
-    ib_path_rec_t                path_rec;\r
-    GID                          dest_GID;\r
-    ib_query_req_t               query_req;\r
-    ib_gid_pair_t                gid_pair;\r
-    ib_service_record_t          service_rec;\r
-    int                          retry_cnt;\r
-    DAT_RETURN                   dat_status;\r
-\r
-    ep_ptr         = (DAPL_EP *) ep_handle;\r
-    ia_ptr         = ep_ptr->header.owner_ia;\r
-    ep_ptr->cr_ptr = NULL;\r
-    retry_cnt      = 0;\r
-    dat_status     = DAT_SUCCESS;\r
-\r
-    p_ca = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;\r
-\r
-    /*\r
-     * We are using the first active port in the list for\r
-     * communication. We have to get back here when we decide to support\r
-     * fail-over and high-availability.\r
-     */\r
-    p_active_port = dapli_ibal_get_port ( p_ca,\r
-                                          (uint8_t)ia_ptr->hca_ptr->port_num );\r
-\r
-    if (NULL == p_active_port)\r
-    {\r
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"--> DsC: Port %d not available %d\n",\r
-                       ia_ptr->hca_ptr->port_num, __LINE__ );\r
-        return (DAT_INVALID_STATE);\r
-    }\r
-\r
-    dapl_os_memzero (&dest_GID, sizeof (GID));\r
-    dapl_os_memzero (&cm_req, sizeof (ib_cm_req_t));\r
-    dapl_os_memzero (&path_rec, sizeof (ib_path_rec_t));\r
-    dapl_os_memzero (&service_rec, sizeof (ib_service_record_t));\r
-    dapl_os_memzero (&query_req, sizeof (ib_query_req_t));\r
-    dapl_os_memzero (&gid_pair, sizeof (ib_gid_pair_t));\r
-    dapl_os_memzero (&ep_ptr->remote_ia_address, sizeof (DAT_SOCK_ADDR6));\r
-\r
-    dapl_os_memcpy (&ep_ptr->remote_ia_address, \r
-                    remote_ia_address, \r
-                    sizeof (ep_ptr->remote_ia_address));\r
-\r
-\r
-#ifdef NO_NAME_SERVICE\r
-\r
-    if (DAT_SUCCESS !=\r
-        (dat_status = dapls_ns_lookup_address (\r
-                                         ia_ptr,\r
-                                         remote_ia_address,\r
-                                         &dest_GID         )))\r
-    {\r
-        /*\r
-         * Remote address not in the table, this is a\r
-         * strange return code!\r
-         */\r
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"--> DsC: exits status = %x\n", dat_status);\r
-        return dat_status;\r
-    }\r
-\r
-    dest_GID.guid = CL_HTON64 (dest_GID.guid);\r
-    dest_GID.gid_prefix = CL_HTON64 (dest_GID.gid_prefix);\r
-\r
-#else\r
-\r
-    /*\r
-     * We query the SA to get the dest_gid with the \r
-     * {uDAPL_svc_id, IP-address} as the key to get GID.\r
-     */\r
-    if (DAT_SUCCESS !=\r
-        (dat_status = dapls_ns_map_gid (ia_ptr->hca_ptr, \r
-                                        remote_ia_address,\r
-                                        &dest_GID)))\r
-        \r
-    {\r
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR, "--> DsC: fail to map remote_ia_addr "\r
-                       "(sa_family %d) to gid\n",\r
-                       remote_ia_address->sa_family); \r
-        return dat_status;\r
-    }\r
-#endif /* NO_NAME_SERVICE */\r
-\r
-    gid_pair.dest_gid.unicast.interface_id = dest_GID.guid;\r
-    gid_pair.dest_gid.unicast.prefix       = dest_GID.gid_prefix;\r
-\r
-    dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
-                  "dapls_ib_connect: EP %lx QP %lx SERVER GID{0x" F64x\r
-                  ", 0x" F64x "}\n", \r
-                  ep_ptr, ep_ptr->qp_handle,\r
-                  cl_hton64 (gid_pair.dest_gid.unicast.prefix),\r
-                  cl_hton64 (gid_pair.dest_gid.unicast.interface_id));\r
-\r
-    gid_pair.src_gid = p_active_port->p_attr->p_gid_table[0];\r
-/*\r
-    if ((gid_pair.src_gid.unicast.interface_id == \r
-         gid_pair.dest_gid.unicast.interface_id   ) &&\r
-        (gid_pair.src_gid.unicast.prefix == \r
-         gid_pair.dest_gid.unicast.prefix   ))\r
-    {\r
-        path_rec.dgid     = gid_pair.dest_gid;\r
-        path_rec.sgid     = gid_pair.src_gid;\r
-        path_rec.slid     = path_rec.dlid = p_active_port->p_attr->lid;\r
-        path_rec.pkey     = p_active_port->p_attr->p_pkey_table[0];\r
-        path_rec.mtu      = p_active_port->p_attr->mtu;\r
-               path_rec.pkt_life = 18;  // 1 sec\r
-               path_rec.rate     = IB_PATH_RECORD_RATE_10_GBS;\r
-       \r
-       }\r
-    else\r
-    {\r
-  */\r
-        /*\r
-         * Query SA to get the path record from pair of GIDs\r
-         */\r
-        dapl_os_memzero (&query_req, sizeof (ib_query_req_t));\r
-        query_req.query_type      = IB_QUERY_PATH_REC_BY_GIDS;\r
-        query_req.p_query_input   = (void *) &gid_pair;\r
-        query_req.flags           = IB_FLAGS_SYNC;  \r
-        query_req.timeout_ms      = 1 * 1000;       /* 1 second */\r
-        query_req.retry_cnt       = 3;\r
-        /* query SA using this port */\r
-        query_req.port_guid       = p_active_port->p_attr->port_guid;\r
-        query_req.query_context   = (void *) &path_rec;\r
-        query_req.pfn_query_cb    = dapli_ib_sa_query_cb;\r
\r
-        ib_status = ib_query (dapl_ibal_root.h_al, &query_req, NULL);\r
-\r
-        if ((ib_status != IB_SUCCESS) || (!path_rec.dlid))\r
-        {\r
-            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"--> DsC: EP %lx QP %lx query "\r
-                           "pair_gids status = %s\n", \r
-                           ep_ptr, ep_ptr->qp_handle,ib_get_err_str(ib_status));\r
-            return DAT_INVALID_PARAMETER;\r
-        }\r
-\r
-    //}\r
-\r
-       /*\r
-        * Tavor has a HW bug that causes bandwidth with 2K MTU to be less than\r
-        * with 1K MTU.  Cap the MTU based on device ID to compensate for this.\r
-        */\r
-       if( (p_ca->p_ca_attr->dev_id == 0x5A44) &&\r
-               (ib_path_rec_mtu( &path_rec ) > IB_MTU_LEN_1024) )\r
-       {\r
-            /* Local endpoint is Tavor - cap MTU to 1K for extra bandwidth. */\r
-            path_rec.mtu &= IB_PATH_REC_SELECTOR_MASK;\r
-            path_rec.mtu |= IB_MTU_LEN_1024;\r
-       }\r
-\r
-       /* \r
-     * prepare the Service ID from conn_qual \r
-     */\r
-    cm_req.svc_id           = remote_conn_qual;\r
-    cm_req.p_primary_path   = &path_rec;\r
-    cm_req.p_alt_path       = NULL;\r
-    cm_req.h_qp             = ep_ptr->qp_handle;\r
-    cm_req.qp_type          = IB_QPT_RELIABLE_CONN;\r
-    cm_req.p_req_pdata      = (uint8_t *) private_data;\r
-    cm_req.req_length       = (uint8_t)\r
-                               min(private_data_size,IB_MAX_REQ_PDATA_SIZE);\r
-    /* cm retry to send this request messages, IB max of 4 bits */\r
-    cm_req.max_cm_retries   = 15; /* timer outside of call, s/be infinite */\r
-    /* qp retry to send any wr */\r
-    cm_req.retry_cnt        = 5;\r
-    /* max num of oustanding RDMA read/atomic support */\r
-    cm_req.resp_res         = (uint8_t)ep_ptr->param.ep_attr.max_rdma_read_in;\r
-    /* max num of oustanding RDMA read/atomic will use */\r
-    cm_req.init_depth       = (uint8_t)ep_ptr->param.ep_attr.max_rdma_read_out;\r
-\r
-    /* time wait before retrying a pkt after receiving a RNR NAK */\r
-    cm_req.rnr_nak_timeout  = IB_RNR_NAK_TIMEOUT;\r
-    \r
-       /* \r
-     * number of time local QP should retry after receiving RNR NACK before\r
-     * reporting an error\r
-     */\r
-    cm_req.rnr_retry_cnt       = IB_RNR_RETRY_CNT;\r
-\r
-    cm_req.remote_resp_timeout = 16;   /* 250ms */\r
-    cm_req.local_resp_timeout  = 16;   /* 250ms */\r
-    \r
-    cm_req.flow_ctrl           = TRUE;\r
-    cm_req.flags               = 0;\r
-    /*\r
-     * We do not use specific data buffer to check for specific connection\r
-     */\r
-    cm_req.p_compare_buffer    = NULL;\r
-    cm_req.compare_offset      = 0;\r
-    cm_req.compare_length      = 0;\r
-\r
-    dapl_dbg_log (DAPL_DBG_TYPE_CM, "--> DsConn: EP=%lx QP=%lx rio=%d,%d pl=%d "\r
-                  "mtu=%d slid=%#x dlid=%#x\n", \r
-                  ep_ptr, ep_ptr->qp_handle,  cm_req.resp_res, \r
-                  cm_req.init_depth, ib_path_rec_pkt_life(&path_rec),\r
-                  ib_path_rec_mtu(&path_rec),\r
-                  cm_req.p_primary_path->slid,\r
-                  cm_req.p_primary_path->dlid);\r
-\r
-    /*\r
-     * We do not support peer_to_peer; therefore, we set pfn_cm_req_cb = NULL\r
-     */\r
-    cm_req.pfn_cm_req_cb       = NULL;\r
-    cm_req.pfn_cm_rep_cb       = dapli_ib_cm_rep_cb;\r
-    cm_req.pfn_cm_rej_cb       = dapli_ib_cm_rej_cb;\r
-    /* callback when a message received acknowledgement is received */\r
-    cm_req.pfn_cm_mra_cb       = dapli_ib_cm_mra_cb;\r
-\r
-    ib_status = ib_cm_req (&cm_req);\r
-    \r
-    if ( ib_status != IB_SUCCESS )\r
-    {\r
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
-                       "--> DsC: EP %lx QP %lx conn_request failed = %s\n", \r
-                       ep_ptr, ep_ptr->qp_handle, ib_get_err_str(ib_status));\r
-\r
-        return  (dapl_ib_status_convert (ib_status));\r
-    }\r
-\r
-    return DAT_SUCCESS;\r
-}\r
-\r
-\r
-/*\r
- * dapls_ib_disconnect\r
- *\r
- * Disconnect an EP\r
- *\r
- * Input:\r
- *        ep_handle,\r
- *        disconnect_flags\r
- *           DAT_CLOSE_ABRUPT_FLAG - no callback\r
- *           DAT_CLOSE_GRACEFUL_FLAG - callback desired.\r
- *\r
- * Output:\r
- *         none\r
- *\r
- * Returns:\r
- *        DAT_SUCCESS\r
- *        DAT_INSUFFICIENT_RESOURCES\r
- *        DAT_INVALID_PARAMETER\r
- *\r
- */\r
-DAT_RETURN\r
-dapls_ib_disconnect ( IN   DAPL_EP           *ep_ptr,\r
-                      IN   DAT_CLOSE_FLAGS   disconnect_flags )\r
-{\r
-    ib_api_status_t    ib_status = IB_SUCCESS;\r
-    ib_cm_dreq_t       cm_dreq;\r
-    dp_ib_cm_handle_t  cm_ptr;\r
-\r
-    dapl_os_assert(ep_ptr);\r
-\r
-    if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )\r
-    {\r
-         dapl_dbg_log (DAPL_DBG_TYPE_CM,\r
-                  "--> %s: BAD EP Magic EP=%lx\n", __FUNCTION__,ep_ptr); \r
-        return DAT_SUCCESS;\r
-    }\r
-    cm_ptr = dapl_get_cm_from_ep(ep_ptr);\r
-    if (!cm_ptr)\r
-    {\r
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR, \r
-                      "--> %s: !CM_PTR on EP %p\n", __FUNCTION__, ep_ptr);\r
-        return DAT_SUCCESS;\r
-    }\r
\r
-    dapl_dbg_log (DAPL_DBG_TYPE_CM,\r
-       "--> %s() EP %p %s rx_drq %d tx_drq %d Close %s\n", __FUNCTION__,\r
-       ep_ptr, dapl_get_ep_state_str(ep_ptr->param.ep_state),\r
-                  ep_ptr->recv_discreq, ep_ptr->sent_discreq,\r
-       (disconnect_flags == DAT_CLOSE_ABRUPT_FLAG ? "Abrupt":"Graceful"));\r
-\r
-    if ( disconnect_flags == DAT_CLOSE_ABRUPT_FLAG )\r
-    {\r
-       if ( ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED )\r
-        return DAT_SUCCESS;\r
-\r
-       if ( ep_ptr->param.ep_state != DAT_EP_STATE_DISCONNECT_PENDING )\r
-    {\r
-           dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
-                       "%s() calling legacy_post_disconnect()\n",__FUNCTION__);\r
-            dapl_ep_legacy_post_disconnect(ep_ptr, disconnect_flags);\r
-            return DAT_SUCCESS;\r
-       }\r
-    }\r
-\r
-    dapl_os_memzero(&cm_dreq, sizeof(ib_cm_dreq_t));\r
-\r
-    cm_dreq.qp_type        = IB_QPT_RELIABLE_CONN;\r
-    cm_dreq.h_qp           = ep_ptr->qp_handle;\r
-    cm_dreq.pfn_cm_drep_cb = dapli_ib_cm_drep_cb;\r
-    \r
-    /* \r
-     * Currently we do not send any disconnect private data to\r
-     * the other endpoint because DAT 2.0 does not support it.  \r
-     */\r
-    cm_dreq.p_dreq_pdata   = NULL;\r
-    cm_dreq.flags          = IB_FLAGS_SYNC;\r
-\r
-    /*\r
-     * still need to send DREQ (disconnect request)?\r
-     */\r
-    if ( (ep_ptr->recv_discreq == DAT_FALSE)\r
-          && (ep_ptr->sent_discreq == DAT_FALSE)\r
-         && (ep_ptr->qp_state != IB_QPS_RESET) )\r
-    {\r
-        ep_ptr->sent_discreq = DAT_TRUE;\r
-        ib_status = ib_cm_dreq ( &cm_dreq );\r
-\r
-       if ( ib_status == IB_SUCCESS )\r
-           dapl_dbg_log (DAPL_DBG_TYPE_CM,\r
-                       "--> DsD: EP %p  DREQ SENT\n", ep_ptr);\r
-\r
-       /* tolerate INVALID_STATE error as the other side can race ahead and\r
-        * generate a DREQ before we do.\r
-        */\r
-       if ( ib_status == IB_INVALID_STATE || ib_status == IB_INVALID_HANDLE )\r
-       {\r
-           ib_status = IB_SUCCESS;\r
-       }\r
-       else if (ib_status)\r
-       {\r
-           dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
-                       "%s() EP %p ib_cm_dreq() status %s\n",\r
-                       __FUNCTION__,ep_ptr,ib_get_err_str(ib_status));\r
-       }\r
-    }\r
-    return ib_status;\r
-}\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_INVALID_PARAMETER\r
- *\r
- */\r
-DAT_RETURN\r
-dapls_ib_setup_conn_listener (\r
-        IN  DAPL_IA               *ia_ptr,\r
-        IN  DAT_UINT64            ServiceID,\r
-        IN  DAPL_SP               *sp_ptr )\r
-{\r
-    ib_api_status_t               ib_status;\r
-    ib_cm_listen_t                cm_listen;\r
-    dapl_ibal_ca_t                *p_ca;\r
-    dapl_ibal_port_t              *p_active_port;\r
-\r
-    p_ca = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;\r
-\r
-    /*\r
-     * We are using the first active port in the list for\r
-     * communication. We have to get back here when we decide to support\r
-     * fail-over and high-availability.\r
-     */\r
-    p_active_port = dapli_ibal_get_port( p_ca,\r
-                                       (uint8_t)ia_ptr->hca_ptr->port_num );\r
-\r
-    if (NULL == p_active_port)\r
-    {\r
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"%s: SP %lx port %d not available\n",\r
-                __FUNCTION__, sp_ptr, ia_ptr->hca_ptr->port_num );\r
-        return (DAT_INVALID_STATE);\r
-    }\r
-\r
-    if (p_active_port->p_attr->lid == 0)\r
-    {\r
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
-                       "--> DsSCL: SP %lx SID 0x" F64x " port %d\n", \r
-                       sp_ptr, cl_hton64(ServiceID),\r
-                       p_active_port->p_attr->port_num);\r
-        return (DAT_INVALID_STATE);\r
-    }\r
-\r
-    dapl_dbg_log (DAPL_DBG_TYPE_CM,\r
-         "%s: SP %lx port %d GID{0x" F64x ", 0x" F64x "} and SID 0x" F64x "\n", \r
-         __FUNCTION__,\r
-         sp_ptr, p_active_port->p_attr->port_num,\r
-         cl_hton64 (p_active_port->p_attr->p_gid_table[0].unicast.prefix),\r
-         cl_hton64 (p_active_port->p_attr->p_gid_table[0].unicast.interface_id),\r
-         cl_hton64 (ServiceID));\r
-    \r
-    dapl_os_memzero (&cm_listen, sizeof (ib_cm_listen_t));\r
-\r
-    /*\r
-     * Listen for all request on  this specific CA\r
-     */\r
-    cm_listen.ca_guid = (p_ca->p_ca_attr->ca_guid);\r
-    cm_listen.svc_id  = ServiceID;\r
-    cm_listen.qp_type = IB_QPT_RELIABLE_CONN; \r
-\r
-    /*\r
-     * We do not use specific data buffer to check for specific connection\r
-     */\r
-    cm_listen.p_compare_buffer = NULL;//(uint8_t*)&sp_ptr->conn_qual;\r
-    cm_listen.compare_offset   = 0;//IB_MAX_REQ_PDATA_SIZE - sizeof(DAT_CONN_QUAL);\r
-    cm_listen.compare_length   = 0;//sizeof(DAT_CONN_QUAL);\r
-\r
-    /*\r
-     * We can pick a port here for communication and the others are reserved\r
-     * for fail-over / high-availability - TBD\r
-     */\r
-    cm_listen.port_guid     = p_active_port->p_attr->port_guid;\r
-    cm_listen.lid           = p_active_port->p_attr->lid;\r
-    cm_listen.pkey          = p_active_port->p_attr->p_pkey_table[0];\r
-\r
-    /*\r
-     * Register request or mra callback functions\r
-     */\r
-    cm_listen.pfn_cm_req_cb = dapli_ib_cm_req_cb;\r
-\r
-    ib_status = ib_cm_listen ( dapl_ibal_root.h_al,\r
-                               &cm_listen,\r
-                               (void *) sp_ptr,\r
-                               &sp_ptr->cm_srvc_handle );\r
-\r
-    if (ib_status != IB_SUCCESS)\r
-    {\r
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
-                       "%s: SP %lx SID 0x" F64x " listen failed %s\n", \r
-                       __FUNCTION__, sp_ptr, cl_hton64 (ServiceID),\r
-                       ib_get_err_str(ib_status));\r
-    }\r
-\r
-    return dapl_ib_status_convert (ib_status);\r
-}\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_PARAMETER\r
- *\r
- */\r
-DAT_RETURN\r
-dapls_ib_remove_conn_listener (\r
-        IN  DAPL_IA        *ia_ptr,\r
-        IN  DAPL_SP        *sp_ptr )\r
-{\r
-    ib_api_status_t        ib_status;\r
-    DAT_RETURN             dat_status = DAT_SUCCESS;\r
-       \r
-    UNUSED_PARAM( ia_ptr );\r
-\r
-    dapl_os_assert ( sp_ptr );\r
-\r
-    dapl_os_assert ( sp_ptr->header.magic == DAPL_MAGIC_PSP ||\r
-         sp_ptr->header.magic == DAPL_MAGIC_RSP );\r
-\r
-    dapl_dbg_log ( DAPL_DBG_TYPE_CM, "%s() cm_srvc_handle %lx\n",\r
-                   __FUNCTION__, sp_ptr->cm_srvc_handle );\r
-\r
-    if (sp_ptr->cm_srvc_handle)\r
-    {\r
-        ib_status = ib_cm_cancel ( sp_ptr->cm_srvc_handle, \r
-                                   NULL );\r
-        \r
-        if (ib_status != IB_SUCCESS)\r
-        {\r
-            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
-                           "--> DsRCL: SP %lx ib_cm_cancel failed(0x%x) %s\n", \r
-                           sp_ptr, sp_ptr->cm_srvc_handle,\r
-                           ib_get_err_str(ib_status));\r
-            sp_ptr->cm_srvc_handle = NULL;\r
-            return (DAT_INVALID_PARAMETER);\r
-        }\r
-\r
-        sp_ptr->cm_srvc_handle = NULL;\r
-    }\r
-\r
-    return dat_status;\r
-}\r
-\r
-/*\r
- * dapls_ib_reject_connection\r
- *\r
- * Perform necessary steps to reject a connection\r
- *\r
- * Input:\r
- *        cr_handle\r
- *\r
- * Output:\r
- *         none\r
- *\r
- * Returns:\r
- *         DAT_SUCCESS\r
- *        DAT_INSUFFICIENT_RESOURCES\r
- *        DAT_INVALID_PARAMETER\r
- *\r
- */\r
-DAT_RETURN\r
-dapls_ib_reject_connection ( IN  dp_ib_cm_handle_t   ib_cm_handle,\r
-                             IN  int                 reject_reason,\r
-                             IN  DAT_COUNT           private_data_size,\r
-                             IN  const DAT_PVOID     private_data)\r
-{\r
-    ib_api_status_t        ib_status;\r
-    ib_cm_rej_t            cm_rej;\r
-    static char            *rej_table[] =\r
-    {\r
-        "INVALID_REJ_REASON",\r
-        "INVALID_REJ_REASON",\r
-        "INVALID_REJ_REASON",\r
-        "INVALID_REJ_REASON",\r
-        "INVALID_REJ_REASON",\r
-        "IB_CME_DESTINATION_REJECT",\r
-        "IB_CME_DESTINATION_REJECT_PRIVATE_DATA",\r
-        "IB_CME_DESTINATION_UNREACHABLE",\r
-        "IB_CME_TOO_MANY_CONNECTION_REQUESTS",\r
-        "IB_CME_LOCAL_FAILURE",\r
-        "IB_CM_LOCAL_FAILURE"\r
-    };\r
-\r
-#define REJ_TABLE_SIZE  IB_CM_LOCAL_FAILURE\r
-\r
-    reject_reason = __min( reject_reason & 0xff, REJ_TABLE_SIZE);\r
-\r
-    cm_rej.rej_status   = IB_REJ_USER_DEFINED;\r
-    cm_rej.p_ari        = (ib_ari_t *)&rej_table[reject_reason]; \r
-    cm_rej.ari_length   = (uint8_t)strlen (rej_table[reject_reason]);\r
-\r
-    cm_rej.p_rej_pdata  = private_data;\r
-    cm_rej.rej_length   = private_data_size;\r
-\r
-#if defined(DAPL_DBG) && 0\r
-    dapli_print_private_data("DsRjC",private_data,private_data_size);\r
-#endif\r
-\r
-    ib_status = ib_cm_rej(ib_cm_handle->ib_cm, &cm_rej);\r
-\r
-    if (ib_status != IB_SUCCESS)\r
-    {\r
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
-                       "--> DsRjC: cm_handle %p reject failed %s\n", \r
-                       ib_cm_handle, ib_get_err_str(ib_status) );\r
-    }\r
-\r
-    return ( dapl_ib_status_convert ( ib_status ) );\r
-}\r
-\r
-\r
-\r
-#if 0\r
-static void\r
-dapli_query_qp( ib_qp_handle_t qp_handle, ib_qp_attr_t  *qpa )\r
-{\r
-    ib_api_status_t        ib_status;\r
-    \r
-    ib_status = ib_query_qp ( qp_handle, qpa );\r
-    if (ib_status != IB_SUCCESS)\r
-    {\r
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"ib_query_qp(%lx) '%s'\n",\r
-                qp_handle, ib_get_err_str(ib_status) );\r
-    }\r
-    else\r
-    {\r
-        dapl_dbg_log ( DAPL_DBG_TYPE_CM, "--> QP(%lx) state %s "\r
-                       "type %d init %d acc %x\n",\r
-                       qp_handle,\r
-                       ib_get_port_state_str(qpa->state),\r
-                       qpa->qp_type,\r
-                       qpa->init_depth,\r
-                       qpa->access_ctrl );\r
-    }\r
-}\r
-#endif\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_INVALID_PARAMETER\r
- *\r
- */\r
-DAT_RETURN\r
-dapls_ib_accept_connection (\r
-        IN        DAT_CR_HANDLE            cr_handle,\r
-        IN        DAT_EP_HANDLE            ep_handle,\r
-        IN        DAT_COUNT                private_data_size,\r
-        IN const  DAT_PVOID                private_data )\r
-{\r
-    DAPL_CR                *cr_ptr;\r
-    DAPL_EP                *ep_ptr;\r
-    DAPL_IA                *ia_ptr;\r
-    DAT_RETURN             dat_status;\r
-    ib_api_status_t        ib_status;\r
-    dapl_ibal_ca_t         *p_ca;\r
-    dapl_ibal_port_t       *p_active_port;\r
-    ib_cm_rep_t            cm_rep;\r
-    ib_qp_attr_t           qpa;\r
-    dp_ib_cm_handle_t      cm_ptr;\r
-\r
-    cr_ptr = (DAPL_CR *) cr_handle;\r
-    ep_ptr = (DAPL_EP *) ep_handle;\r
-    ia_ptr = ep_ptr->header.owner_ia;\r
-\r
-    if ( ep_ptr->qp_state == DAPL_QP_STATE_UNATTACHED )\r
-    {\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, ep_ptr );\r
-\r
-        if ( dat_status != DAT_SUCCESS)\r
-        {\r
-            /* This is not a great error code, but all the spec allows */\r
-            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
-                           "-->  DsIBAC: CR %lx EP %lx alloc QP failed 0x%x\n",\r
-                           cr_ptr, ep_ptr, dat_status );\r
-            return (dat_status);\r
-        }\r
-    }\r
-\r
-    p_ca = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;\r
-    p_active_port = dapli_ibal_get_port ( p_ca,\r
-                                          (uint8_t)ia_ptr->hca_ptr->port_num );\r
-    if (NULL == p_active_port)\r
-    {\r
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
-                       "--> DsIBAC: CR %lx EP %lx port %d is not available\n",\r
-                       cr_ptr, ep_ptr, ia_ptr->hca_ptr->port_num);\r
-        return (DAT_INVALID_STATE);\r
-    }\r
-\r
-    cr_ptr->param.local_ep_handle = ep_handle;\r
-\r
-    /*\r
-     * assume ownership, in that once the EP is released the dynamic\r
-     * memory containing the IBAL CM handle (ib_cm_handle_t) struct will\r
-     * be released; see dapl_ep_dealloc().\r
-     */\r
-   \r
-    /* EP-CM, save/release CR CM object, use EP CM object already linked */\r
-    cm_ptr = dapl_get_cm_from_ep(ep_ptr);\r
-    if (!cm_ptr) {\r
-       dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
-                       "--> DsIBAC: CM linking to EP %p not available\n",\r
-                       ep_ptr);\r
-       return (DAT_INVALID_STATE);\r
-    }\r
-     \r
-    /* set remote IP addr fields. IP addr data is deduced from Connection\r
-     * Request record (gid/lib) and stashed away for use here. DAPL 1.1\r
-     * had an interface for passing the IP info down, interface went away\r
-     * in 2.0?\r
-     */\r
-    dapl_os_memcpy( (void*)&ep_ptr->remote_ia_address,\r
-                    (void*)&cr_ptr->ib_cm_handle->dst_ip_addr,\r
-                    sizeof(DAT_SOCK_ADDR6) );\r
-\r
-    dapl_os_memcpy( (void*)&cr_ptr->remote_ia_address,\r
-                    (void*)&ep_ptr->remote_ia_address,\r
-                    sizeof(DAT_SOCK_ADDR6) );\r
-\r
-#if defined(DAPL_DBG)\r
-    {\r
-        char ipa[20];\r
-\r
-        dapl_dbg_log (DAPL_DBG_TYPE_CM|DAPL_DBG_TYPE_CALLBACK, \r
-                      "%s: EP(%lx) RemoteAddr: %s\n",\r
-                      __FUNCTION__, ep_ptr,\r
-                     dapli_get_ip_addr_str(\r
-                            (DAT_SOCK_ADDR6*)&ep_ptr->remote_ia_address, ipa) );\r
-    }\r
-#endif\r
-\r
-    dapl_os_memcpy( (void*)&cm_ptr->dst_ip_addr,\r
-                    (void*)&cr_ptr->ib_cm_handle->dst_ip_addr,\r
-                    sizeof(DAT_SOCK_ADDR6) );\r
-\r
-    /* get h_al and connection ID from CR CM object, h_qp already set */\r
-    cm_ptr->ib_cm.cid = cr_ptr->ib_cm_handle->ib_cm.cid; \r
-    cm_ptr->ib_cm.h_al = cr_ptr->ib_cm_handle->ib_cm.h_al;\r
-    dapls_cm_release(cr_ptr->ib_cm_handle);\r
-\r
-    cr_ptr->ib_cm_handle = cm_ptr; /* for dapli_get_sp_ep() upcall */\r
-\r
-    ep_ptr->cr_ptr        = cr_ptr;\r
-\r
-    dapl_os_memzero ( (void*)&cm_rep, sizeof (ib_cm_rep_t) );\r
-\r
-    cm_rep.h_qp           = ep_ptr->qp_handle;\r
-    cm_rep.qp_type        = IB_QPT_RELIABLE_CONN;\r
-\r
-    if (private_data_size > IB_MAX_REP_PDATA_SIZE) {\r
-       dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                       "--> DsIBAC: private_data_size(%d) > Max(%d)\n",\r
-                       private_data_size, IB_MAX_REP_PDATA_SIZE);\r
-       return DAT_ERROR(DAT_LENGTH_ERROR, DAT_NO_SUBTYPE);\r
-                                 \r
-        }\r
-    cm_rep.p_rep_pdata    = (const uint8_t *)private_data;\r
-    cm_rep.rep_length     = private_data_size;\r
-                            \r
-#if defined(DAPL_DBG) && 0\r
-    dapli_print_private_data( "DsIBAC",\r
-                             (const uint8_t*)private_data,\r
-                             private_data_size );\r
-#endif\r
-\r
-    cm_rep.pfn_cm_rej_cb = dapli_ib_cm_rej_cb;\r
-    cm_rep.pfn_cm_mra_cb = dapli_ib_cm_mra_cb;\r
-    cm_rep.pfn_cm_rtu_cb  = dapli_ib_cm_rtu_cb;\r
-    cm_rep.pfn_cm_lap_cb  = dapli_ib_cm_lap_cb;\r
-    cm_rep.pfn_cm_dreq_cb = dapli_ib_cm_dreq_cb;\r
-\r
-    /*\r
-     * FIXME - Vu\r
-     *         Pay attention to the attributes. \r
-     *         Some of them are desirably set by DAT consumers\r
-     */\r
-    /*\r
-     * We enable the qp associate with this connection ep all the access right\r
-     * We enable the flow_ctrl, retry till success\r
-     * We will limit the access right and flow_ctrl upon DAT consumers \r
-     * requirements\r
-     */\r
-    cm_rep.access_ctrl =\r
-               IB_AC_LOCAL_WRITE|IB_AC_RDMA_WRITE|IB_AC_MW_BIND|IB_AC_ATOMIC;\r
-\r
-    if ((ep_ptr->param.ep_attr.max_rdma_read_in > 0) \r
-               || (ep_ptr->param.ep_attr.max_rdma_read_out > 0))\r
-    {\r
-       cm_rep.access_ctrl |= IB_AC_RDMA_READ;\r
-    }\r
-\r
-    cm_rep.sq_depth          = 0;\r
-    cm_rep.rq_depth          = 0;\r
-    cm_rep.init_depth        = (uint8_t)ep_ptr->param.ep_attr.max_rdma_read_out;\r
-    cm_rep.flow_ctrl         = TRUE;\r
-    cm_rep.flags             = 0;\r
-    cm_rep.failover_accepted = IB_FAILOVER_ACCEPT_UNSUPPORTED;\r
-    cm_rep.target_ack_delay  = 14;\r
-    cm_rep.rnr_nak_timeout   = IB_RNR_NAK_TIMEOUT;\r
-    cm_rep.rnr_retry_cnt     = IB_RNR_RETRY_CNT;\r
-    cm_rep.pp_recv_failure   = NULL;\r
-    cm_rep.p_recv_wr         = NULL;\r
-     \r
-    dapl_dbg_log (DAPL_DBG_TYPE_CM,\r
-                 "--> DsIBAC: cm_rep: acc %x init %d qp_type %x req_count %d\n",\r
-                cm_rep.access_ctrl, cm_rep.init_depth,cm_rep.qp_type,\r
-                 dapls_cb_pending(&ep_ptr->req_buffer));\r
-\r
-    ib_status = ib_cm_rep ( cm_ptr->ib_cm, &cm_rep );\r
-\r
-    if (ib_status != IB_SUCCESS)\r
-    {\r
-       dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
-                       "--> DsIBAC: EP %lx QP %lx CR reply failed '%s'\n",\r
-                       ep_ptr, ep_ptr->qp_handle, ib_get_err_str(ib_status) );\r
-    }\r
\r
-    return ( dapl_ib_status_convert ( ib_status ) );\r
-}\r
-\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
- *\r
- * Output:\r
- *         none\r
- *\r
- * Returns:\r
- *         void\r
- *\r
- */\r
-void\r
-dapls_ib_disconnect_clean (\r
-        IN  DAPL_EP                     *ep_ptr,\r
-        IN  DAT_BOOLEAN                 active,\r
-        IN  const ib_cm_events_t        ib_cm_event )\r
-{\r
-    DAPL_IA            *ia_ptr;\r
-    ib_qp_attr_t       qp_attr;\r
-    ib_api_status_t     ib_status;\r
-\r
-    dapl_dbg_log ( DAPL_DBG_TYPE_CM, "%s(%s): cm_event: %s \n", __FUNCTION__,\r
-                   (active?"A":"P"), dapli_ib_cm_event_str(ib_cm_event));\r
-\r
-    ia_ptr = ep_ptr->header.owner_ia;\r
-    \r
-    if ( ia_ptr == NULL || ia_ptr->header.magic != DAPL_MAGIC_IA )\r
-    {\r
-        dapl_dbg_log ( DAPL_DBG_TYPE_CM,\r
-                       ">>>DSCONN_CLEAN(%s): cm_event: %s Invalid IA_ptr\n",\r
-                       (active?"Act":"Pas"),dapli_ib_cm_event_str(ib_cm_event));\r
-        return;\r
-    }\r
-    dapl_os_assert ( ep_ptr->header.magic == DAPL_MAGIC_EP );\r
-    \r
-    ep_ptr->sent_discreq = DAT_FALSE;\r
-    ep_ptr->recv_discreq = DAT_FALSE;\r
-\r
-    /* \r
-     * Query the QP to get the current state */\r
-    ib_status = ib_query_qp ( ep_ptr->qp_handle, &qp_attr );\r
-                       \r
-    if ( ib_status != IB_SUCCESS )\r
-    {\r
-           dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
-                       ">>>DSCONN_CLEAN(%s): Query QP failed = %s\n",\r
-                       (active?"Act":"Pas"),ib_get_err_str(ib_status) );\r
-       return;\r
-    }\r
-    \r
-    ep_ptr->qp_state = qp_attr.state;\r
-\r
-    dapl_dbg_log ( DAPL_DBG_TYPE_CM, ">>>DSCONN_CLEAN(%s): cm_event: %d "\r
-                   "ep_ptr %lx ep_state %s qp_state %#x\n", \r
-                   (active?"A":"P"), ib_cm_event, ep_ptr,\r
-                   dapl_get_ep_state_str(ep_ptr->param.ep_state),\r
-                   ep_ptr->qp_state );\r
-\r
-    if ( ep_ptr->qp_state != IB_QPS_ERROR &&\r
-         ep_ptr->qp_state != IB_QPS_RESET &&\r
-         ep_ptr->qp_state != IB_QPS_INIT )\r
-    {\r
-        ep_ptr->qp_state = IB_QPS_ERROR;\r
-        dapls_modify_qp_state_to_error (ep_ptr->qp_handle);\r
-    }\r
-}\r
-\r
-\r
-#ifdef NOT_USED\r
-/*\r
- * dapls_ib_cr_handoff\r
- *\r
- * Hand off the connection request to another service point  \r
- *\r
- * Input:\r
- *        cr_handle                DAT_CR_HANDLE\r
- *        handoff_serv_id          DAT_CONN_QUAL\r
- *\r
- * Output:\r
- *         none\r
- *\r
- * Returns:\r
- *         DAT_SUCCESS\r
- *         DAT_INVALID_PARAMETER\r
- *\r
- */\r
-DAT_RETURN \r
-dapls_ib_cr_handoff (\r
-        IN  DAT_CR_HANDLE      cr_handle,\r
-        IN  DAT_CONN_QUAL      handoff_serv_id )\r
-{\r
-    DAPL_CR                *cr_ptr;\r
-    ib_api_status_t        ib_status;\r
-    \r
-    cr_ptr = (DAPL_CR *) cr_handle;\r
-\r
-    if (cr_ptr->ib_cm_handle->ib_cm.cid == 0xFFFFFFFF)\r
-    {\r
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
-                       "--> DsCH: CR = %lx invalid cm handle\n", cr_ptr);\r
-        return DAT_INVALID_PARAMETER;\r
-    }\r
-\r
-    if (cr_ptr->sp_ptr == DAPL_IB_INVALID_HANDLE)\r
-    {\r
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
-                       "--> DsCH: CR = %lx invalid psp handle\n", cr_ptr);\r
-        return DAT_INVALID_PARAMETER;\r
-    }\r
-\r
-    ib_status = ib_cm_handoff (cr_ptr->ib_cm_handle->ib_cm, handoff_serv_id);\r
-\r
-    if (ib_status != IB_SUCCESS)\r
-    {\r
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
-                       "--> DsCH: CR = %lx handoff failed = %s\n", \r
-                       cr_ptr, ib_get_err_str(ib_status) );\r
-\r
-        return dapl_ib_status_convert (ib_status);\r
-    }\r
-\r
-    dapl_dbg_log ( DAPL_DBG_TYPE_CM,\r
-                   "--> %s(): remove CR %lx from SP %lx Queue\n",\r
-                   __FUNCTION__, cr_ptr, cr_ptr->sp_ptr);\r
-    /* Remove the CR from the queue */\r
-    dapl_sp_remove_cr (cr_ptr->sp_ptr, cr_ptr);\r
-\r
-    /*\r
-     * If this SP has been removed from service, free it\r
-     * up after the last CR is removed\r
-     */\r
-    dapl_os_lock (&cr_ptr->sp_ptr->header.lock);\r
-    if ( cr_ptr->sp_ptr->listening != DAT_TRUE && \r
-         cr_ptr->sp_ptr->cr_list_count == 0 &&\r
-         cr_ptr->sp_ptr->state != DAPL_SP_STATE_FREE )\r
-    {\r
-        dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
-                      "--> DsCH: CR = %lx disconnect dump SP = %lx \n", \r
-                      cr_ptr, cr_ptr->sp_ptr);\r
-        /* Decrement the ref count on the EVD */\r
-        if (cr_ptr->sp_ptr->evd_handle)\r
-        {\r
-            dapl_os_atomic_dec (& ((DAPL_EVD *)cr_ptr->sp_ptr->evd_handle)->evd_ref_count);\r
-            cr_ptr->sp_ptr->evd_handle = NULL;\r
-        }\r
-        cr_ptr->sp_ptr->state = DAPL_SP_STATE_FREE;\r
-        dapl_os_unlock (&cr_ptr->sp_ptr->header.lock);\r
-        (void)dapls_ib_remove_conn_listener ( cr_ptr->sp_ptr->header.owner_ia,\r
-                                              cr_ptr->sp_ptr );\r
-        dapls_ia_unlink_sp ( (DAPL_IA *)cr_ptr->sp_ptr->header.owner_ia,\r
-                             cr_ptr->sp_ptr );\r
-        dapls_sp_free_sp ( cr_ptr->sp_ptr );\r
-    }\r
-    else\r
-    {\r
-        dapl_os_unlock (&cr_ptr->sp_ptr->header.lock);\r
-    }\r
-\r
-    /*\r
-     * Clean up and dispose of the resource\r
-     */\r
-    dapls_cr_free (cr_ptr);\r
-\r
-    return (DAT_SUCCESS);\r
-}\r
-#endif\r
-\r
-int\r
-dapls_ib_private_data_size (\r
-       IN      DAPL_HCA                *hca_ptr)\r
-{\r
-    return IB_MAX_REQ_PDATA_SIZE;\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
-\r
+
+/*
+ * Copyright (c) 2005-2007 Intel Corporation. All rights reserved.
+ * Copyright (c) 2002, Network Appliance, Inc. All rights reserved. 
+ * 
+ * This Software is licensed under the terms of the "Common Public
+ * License" a copy of which is in the file LICENSE.txt in the root
+ * directory. The license is also available from the Open Source
+ * Initiative, see http://www.opensource.org/licenses/cpl.php.
+ *
+ */
+
+/**********************************************************************
+ * 
+ * MODULE: dapl_ibal_cm.c
+ *
+ * PURPOSE: IB Connection routines for access to IBAL APIs
+ *
+ * $Id: dapl_ibal_cm.c 584 2007-02-07 13:12:18Z sleybo $
+ *
+ **********************************************************************/
+
+#include "dapl.h"
+#include "dapl_adapter_util.h"
+#include "dapl_evd_util.h"
+#include "dapl_cr_util.h"
+#include "dapl_sp_util.h"
+#include "dapl_ep_util.h"
+#include "dapl_ia_util.h"
+#include "dapl_ibal_util.h"
+#include "dapl_name_service.h"
+#include "dapl_ibal_name_service.h"
+#include "dapl_cookie.h"
+
+#define IB_INFINITE_SERVICE_LEASE   0xFFFFFFFF
+#define  DAPL_ATS_SERVICE_ID        ATS_SERVICE_ID //0x10000CE100415453
+#define  DAPL_ATS_NAME              ATS_NAME
+#define  HCA_IPV6_ADDRESS_LENGTH    16
+
+/* until dapl_ibal_util.h define of IB_INVALID_HANDLE which overlaps the
+ * Windows ib_types.h typedef enu ib_api_status_t IB_INVALID_HANDLE is fixed.
+ */
+#undef IB_INVALID_HANDLE
+#define DAPL_IB_INVALID_HANDLE NULL
+
+int g_dapl_loopback_connection = 0;
+extern dapl_ibal_root_t        dapl_ibal_root;
+
+/*
+ * Prototypes
+ */
+
+char *
+dapli_ib_cm_event_str(ib_cm_events_t e)
+{
+#ifdef DBG
+    char        *cp;
+    static char *event_str[13] = {
+        "IB_CME_CONNECTED",
+        "IB_CME_DISCONNECTED",
+        "IB_CME_DISCONNECTED_ON_LINK_DOWN",
+        "IB_CME_CONNECTION_REQUEST_PENDING",
+        "IB_CME_CONNECTION_REQUEST_PENDING_PRIVATE_DATA",
+        "IB_CME_DESTINATION_REJECT",
+        "IB_CME_DESTINATION_REJECT_PRIVATE_DATA",
+        "IB_CME_DESTINATION_UNREACHABLE",
+        "IB_CME_TOO_MANY_CONNECTION_REQUESTS",
+        "IB_CME_LOCAL_FAILURE",
+        "IB_CME_REPLY_RECEIVED",
+        "IB_CME_REPLY_RECEIVED_PRIVATE_DATA",
+        "IB_CM_LOCAL_FAILURE"
+    };
+
+    if (e > IB_CM_LOCAL_FAILURE || e < IB_CME_CONNECTED)
+       cp =  "BAD EVENT";
+    else
+        cp = event_str[e];
+
+    return cp;
+#else
+    static char num[8];
+    sprintf(num,"%d",e);
+    return num;
+#endif
+}
+
+
+#if defined(DAPL_DBG)
+
+void dapli_print_private_data( char *prefix, const uint8_t *pd, int len )
+{
+    int i;
+            
+    if ( !pd || len <= 0 )
+       return;
+
+    dapl_log ( DAPL_DBG_TYPE_CM, "--> %s: private_data(len %d)\n    ",prefix,len);
+
+    if (len > IB_MAX_REP_PDATA_SIZE)
+    {
+       dapl_log ( DAPL_DBG_TYPE_ERR,
+               "    Private data size(%d) > Max(%d), ignored.\n    ",
+                                       len,DAPL_MAX_PRIVATE_DATA_SIZE);
+       len = IB_MAX_REP_PDATA_SIZE;
+    }
+
+    for ( i = 0 ; i < len; i++ )
+    {
+       dapl_log ( DAPL_DBG_TYPE_CM, "%2x ", pd[i]);
+       if ( ((i+1) % 5) == 0 ) 
+           dapl_log ( DAPL_DBG_TYPE_CM, "\n    ");
+    }
+   dapl_log ( DAPL_DBG_TYPE_CM, "\n");
+}
+#endif
+
+/* EP-CM linking support */
+dp_ib_cm_handle_t ibal_cm_alloc(void)
+{
+       dp_ib_cm_handle_t cm_ptr;
+
+       /* Allocate CM, init lock, and initialize */
+       if ((cm_ptr = dapl_os_alloc(sizeof(*cm_ptr))) == NULL)
+               return NULL;
+
+       (void)dapl_os_memzero(cm_ptr, sizeof(*cm_ptr));
+       cm_ptr->ref_count = 1;
+
+       if (dapl_os_lock_init(&cm_ptr->lock)) {
+               dapl_os_free(cm_ptr, sizeof(*cm_ptr));
+               return NULL;
+       }
+
+       dapl_llist_init_entry((DAPL_LLIST_ENTRY *)&cm_ptr->list_entry);
+       
+       return cm_ptr;
+}
+
+/* free CM object resources */
+static void ibal_cm_dealloc(dp_ib_cm_handle_t cm_ptr) 
+{
+       dapl_os_assert(!cm_ptr->ref_count);
+       dapl_os_lock_destroy(&cm_ptr->lock);
+       dapl_os_free(cm_ptr, sizeof(*cm_ptr));
+}
+
+void dapls_cm_acquire(dp_ib_cm_handle_t cm_ptr)
+{
+       dapl_os_lock(&cm_ptr->lock);
+       cm_ptr->ref_count++;
+       dapl_os_unlock(&cm_ptr->lock);
+}
+
+void dapls_cm_release(dp_ib_cm_handle_t cm_ptr)
+{
+       dapl_os_lock(&cm_ptr->lock);
+       cm_ptr->ref_count--;
+       if (cm_ptr->ref_count) {
+                dapl_os_unlock(&cm_ptr->lock);
+               return;
+       }
+       dapl_os_unlock(&cm_ptr->lock);
+       ibal_cm_dealloc(cm_ptr);
+}
+
+/* blocking: called from user thread dapl_ep_free() only */
+void dapls_cm_free(dp_ib_cm_handle_t cm_ptr)
+{
+       dapl_ep_unlink_cm(cm_ptr->ep, cm_ptr);
+
+       /* final reference, alloc */
+       dapls_cm_release(cm_ptr);
+}
+
+static void 
+dapli_ib_cm_apr_cb (
+        IN    ib_cm_apr_rec_t          *p_cm_apr_rec )
+{
+    UNUSED_PARAM( p_cm_apr_rec );
+
+    dapl_dbg_log (DAPL_DBG_TYPE_CM, 
+                  "--> DiCAcb: CM callback APR (Alternate Path Request)\n");
+}
+
+static void 
+dapli_ib_cm_lap_cb (
+        IN    ib_cm_lap_rec_t          *p_cm_lap_rec )
+{
+    UNUSED_PARAM( p_cm_lap_rec );
+
+    dapl_dbg_log (DAPL_DBG_TYPE_CM, 
+                  "--> DiCLcb: CM callback LAP (Load Alternate Path)\n");
+}
+
+/*
+ * Connection Disconnect Request callback
+ * We received a DREQ, return a DREP (disconnect reply).
+ */
+
+static void 
+dapli_ib_cm_dreq_cb (
+        IN    ib_cm_dreq_rec_t          *p_cm_dreq_rec )
+{
+    ib_cm_drep_t        cm_drep;
+    DAPL_EP             *ep_ptr;
+    int                        bail=10;
+    dp_ib_cm_handle_t  cm_ptr;
+    
+    dapl_os_assert (p_cm_dreq_rec);
+
+    ep_ptr  = (DAPL_EP * __ptr64) p_cm_dreq_rec->qp_context;
+    if ( DAPL_BAD_PTR(ep_ptr) )
+    {
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR, 
+                      "--> %s: BAD_PTR EP %lx\n", __FUNCTION__, ep_ptr);
+        return;
+    }
+    if ( ep_ptr->header.magic != DAPL_MAGIC_EP  )
+    {
+        if ( ep_ptr->header.magic == DAPL_MAGIC_INVALID )
+            return;
+
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                      "--> %s: EP %p BAD_EP_MAGIC %x != wanted %x\n",
+                      __FUNCTION__, ep_ptr, ep_ptr->header.magic,
+                      DAPL_MAGIC_EP );
+        return;
+    }
+    cm_ptr = dapl_get_cm_from_ep(ep_ptr);
+    if (!cm_ptr)
+    {
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                      "--> %s: !CM_PTR on EP %p\n", __FUNCTION__, ep_ptr);
+        return;
+    }
+    dapl_os_assert(cm_ptr->ib_cm.h_qp == p_cm_dreq_rec->h_cm_dreq.h_qp);
+
+    dapl_dbg_log (DAPL_DBG_TYPE_CM, 
+                  "--> %s() EP %p, %s sent_discreq %s\n",
+                  __FUNCTION__,ep_ptr,
+                  dapl_get_ep_state_str(ep_ptr->param.ep_state),
+                  (ep_ptr->sent_discreq == DAT_TRUE ? "TRUE":"FALSE"));
+
+    dapl_os_lock (&ep_ptr->header.lock);
+    if ( ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED
+         /*|| ( ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECT_PENDING
+           && ep_ptr->sent_discreq == DAT_TRUE)*/ )
+    {
+        dapl_os_unlock (&ep_ptr->header.lock);
+        dapl_dbg_log (DAPL_DBG_TYPE_CM, 
+                      "--> DiCDcb: EP %lx QP %lx already Disconnected\n",
+                      ep_ptr, ep_ptr->qp_handle);
+        return;
+    }
+
+    ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECT_PENDING;
+    ep_ptr->recv_discreq = DAT_TRUE;
+    dapl_os_unlock (&ep_ptr->header.lock);
+
+    dapl_os_memzero (&cm_drep, sizeof(ib_cm_drep_t));
+
+    /* Could fail if we received reply from other side, no need to retry */
+    /* Wait for any send ops in process holding reference */
+    while (dapls_cb_pending(&ep_ptr->req_buffer) && bail-- > 0 )
+    {
+       dapl_dbg_log (DAPL_DBG_TYPE_CM, 
+                  "--> DiCDcb: WAIT for EP=%lx req_count(%d) != 0\n", 
+                  ep_ptr, dapls_cb_pending(&ep_ptr->req_buffer));
+       dapl_os_sleep_usec (100);
+    }
+
+    ib_cm_drep (p_cm_dreq_rec->h_cm_dreq, &cm_drep);
+
+    /* CM puts QP in reset state */
+    ep_ptr->qp_state = IB_QPS_RESET;
+          
+    if (ep_ptr->cr_ptr)
+    {
+        /* passive side */
+        dapls_cr_callback ( cm_ptr,
+                            IB_CME_DISCONNECTED,
+                            (void * __ptr64) p_cm_dreq_rec->p_dreq_pdata,
+                           IB_DREQ_PDATA_SIZE,
+                            (void *) (((DAPL_CR *) ep_ptr->cr_ptr)->sp_ptr) );
+    }
+    else
+    {
+        /* active side */
+        dapl_evd_connection_callback (
+                                  cm_ptr,
+                                  IB_CME_DISCONNECTED,
+                                  (void * __ptr64)
+                                  p_cm_dreq_rec->p_dreq_pdata,
+                                 IB_DREQ_PDATA_SIZE,
+                                  p_cm_dreq_rec->qp_context );
+    }
+}
+
+/*
+ * Connection Disconnect Reply callback
+ * We sent a DREQ and received a DREP.
+ */
+
+static void 
+dapli_ib_cm_drep_cb (
+        IN    ib_cm_drep_rec_t          *p_cm_drep_rec )
+{
+    DAPL_EP            *ep_ptr;
+    dp_ib_cm_handle_t  cm_ptr;
+    
+    dapl_os_assert (p_cm_drep_rec != NULL);
+
+    ep_ptr  = (DAPL_EP * __ptr64) p_cm_drep_rec->qp_context;
+
+    if (p_cm_drep_rec->cm_status)
+    {
+         dapl_dbg_log (DAPL_DBG_TYPE_CM,
+                  "--> %s: DREP cm_status(%s) EP=%p\n", __FUNCTION__,
+                  ib_get_err_str(p_cm_drep_rec->cm_status), ep_ptr); 
+    }
+
+    if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )
+    {
+         dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                  "--> %s: BAD EP Handle EP=%lx\n", __FUNCTION__,ep_ptr); 
+        return;
+    }
+    cm_ptr = dapl_get_cm_from_ep(ep_ptr);
+    if (!cm_ptr)
+    {
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                      "--> %s: !CM_PTR on EP %p\n", __FUNCTION__, ep_ptr);
+        return;
+    }
+    dapl_os_assert(cm_ptr->ib_cm.h_qp == p_cm_drep_rec->h_qp);
+    
+    dapl_dbg_log (DAPL_DBG_TYPE_CM, 
+       "--> DiCDpcb: EP %p state %s cm_hdl %p\n",ep_ptr,
+                  dapl_get_ep_state_str(ep_ptr->param.ep_state),
+                  cm_ptr);
+
+    if ( ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED )
+    {
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR, 
+                      "--> DiCDpcb: EP %lx QP %lx already Disconnected\n",
+                      ep_ptr, ep_ptr->qp_handle);
+        return;
+    }
+
+    if (ep_ptr->cr_ptr)
+    {
+        /* passive connection side */
+        dapls_cr_callback ( cm_ptr,
+                            IB_CME_DISCONNECTED,
+                           (void * __ptr64) p_cm_drep_rec->p_drep_pdata,
+                          IB_DREP_PDATA_SIZE,
+                           (void *) (((DAPL_CR *) ep_ptr->cr_ptr)->sp_ptr) );
+    }
+    else
+    {
+        /* active connection side */
+        dapl_evd_connection_callback (
+                                   cm_ptr,
+                                   IB_CME_DISCONNECTED,
+                                   (void * __ptr64) p_cm_drep_rec->p_drep_pdata,
+                                  IB_DREP_PDATA_SIZE,
+                                   p_cm_drep_rec->qp_context );
+    }
+}
+
+/*
+ * CM reply callback
+ */
+
+static void 
+dapli_ib_cm_rep_cb (
+        IN    ib_cm_rep_rec_t          *p_cm_rep_rec )
+{
+    ib_api_status_t     ib_status; 
+    ib_cm_rtu_t         cm_rtu;
+    uint8_t             cm_cb_op;
+    DAPL_PRIVATE        *prd_ptr;
+    DAPL_EP             *ep_ptr;
+    dapl_ibal_ca_t      *p_ca;
+    dp_ib_cm_handle_t  cm_ptr;
+        
+    dapl_os_assert (p_cm_rep_rec != NULL);
+
+    ep_ptr  = (DAPL_EP * __ptr64) p_cm_rep_rec->qp_context;
+
+    if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )
+    {
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: EP %lx invalid or FREED\n",
+                      __FUNCTION__, ep_ptr);
+        return;
+    }
+    cm_ptr = dapl_get_cm_from_ep(ep_ptr);
+    if (!cm_ptr)
+    {
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                      "--> %s: !CM_PTR on EP %p\n", __FUNCTION__, ep_ptr);
+        return;
+    }
+    dapl_os_assert(cm_ptr->ib_cm.h_qp == p_cm_rep_rec->h_cm_rep.h_qp);
+
+    dapl_dbg_log (DAPL_DBG_TYPE_CM, 
+                  "--> DiCRpcb: EP %lx local_max_rdma_read_in %d\n", 
+                  ep_ptr, p_cm_rep_rec->resp_res);
+
+    p_ca   = (dapl_ibal_ca_t *) 
+             ep_ptr->header.owner_ia->hca_ptr->ib_hca_handle;
+
+    dapl_os_memzero (&cm_rtu, sizeof ( ib_cm_rtu_t ));
+    cm_rtu.pfn_cm_apr_cb  = dapli_ib_cm_apr_cb;
+    cm_rtu.pfn_cm_dreq_cb = dapli_ib_cm_dreq_cb;
+    cm_rtu.p_rtu_pdata    = NULL;
+    cm_rtu.access_ctrl = 
+               IB_AC_LOCAL_WRITE|IB_AC_RDMA_WRITE|IB_AC_MW_BIND|IB_AC_ATOMIC;
+    if ((ep_ptr->param.ep_attr.max_rdma_read_in > 0) || 
+               (ep_ptr->param.ep_attr.max_rdma_read_out > 0))
+    {
+       cm_rtu.access_ctrl |= IB_AC_RDMA_READ;
+    }
+           
+    cm_rtu.rq_depth       = 0;
+    cm_rtu.sq_depth       = 0;
+       
+    ib_status = ib_cm_rtu (p_cm_rep_rec->h_cm_rep, &cm_rtu);
+
+    if (ib_status == IB_SUCCESS)
+    {
+        cm_cb_op = IB_CME_CONNECTED;
+        dapl_dbg_log (DAPL_DBG_TYPE_CM, 
+                  "--> DiCRpcb: EP %lx Connected req_count %d\n", 
+                  ep_ptr, dapls_cb_pending(&ep_ptr->req_buffer));
+    }
+    else
+    {
+        cm_cb_op = IB_CME_LOCAL_FAILURE;
+    }
+
+    prd_ptr = (DAPL_PRIVATE * __ptr64) p_cm_rep_rec->p_rep_pdata;
+
+#if defined(DAPL_DBG) && 0
+    dapli_print_private_data( "DiCRpcb",
+                             prd_ptr->private_data,
+                             IB_MAX_REP_PDATA_SIZE);
+#endif
+
+    dapl_evd_connection_callback ( 
+                            cm_ptr,
+                            cm_cb_op,
+                            (void *) prd_ptr,
+                           IB_REP_PDATA_SIZE,
+                            (void * __ptr64) p_cm_rep_rec->qp_context);
+}
+
+
+static void 
+dapli_ib_cm_rej_cb (
+        IN    ib_cm_rej_rec_t          *p_cm_rej_rec )
+{
+    DAPL_EP         *ep_ptr;
+    ib_cm_events_t  cm_event;
+    dp_ib_cm_handle_t  cm_ptr;
+
+    dapl_os_assert (p_cm_rej_rec);
+
+    ep_ptr = (DAPL_EP * __ptr64) p_cm_rej_rec->qp_context;
+
+    if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )
+    {
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: EP %lx invalid or FREED\n",
+                      __FUNCTION__, ep_ptr);
+        return;
+    }
+    cm_ptr = dapl_get_cm_from_ep(ep_ptr);
+    if (!cm_ptr)
+    {
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR, 
+                      "--> %s: !CM_PTR on EP %p\n", __FUNCTION__, ep_ptr);
+        return;
+    }
+    dapl_os_assert(cm_ptr->ib_cm.h_qp == p_cm_rej_rec->h_qp);
+
+    dapl_dbg_log (DAPL_DBG_TYPE_CM, 
+                  "--> DiCRjcb: EP = %lx QP = %lx rej reason = 0x%x\n", 
+                  ep_ptr,ep_ptr->qp_handle,CL_NTOH16(p_cm_rej_rec->rej_status));
+
+    switch (p_cm_rej_rec->rej_status)
+    {
+        case IB_REJ_INSUF_RESOURCES:
+        case IB_REJ_INSUF_QP:
+        case IB_REJ_INVALID_COMM_ID:
+        case IB_REJ_INVALID_COMM_INSTANCE:
+        case IB_REJ_INVALID_PKT_RATE:
+        case IB_REJ_INVALID_ALT_GID:
+        case IB_REJ_INVALID_ALT_LID:
+        case IB_REJ_INVALID_ALT_SL:
+        case IB_REJ_INVALID_ALT_TRAFFIC_CLASS:
+        case IB_REJ_INVALID_ALT_PKT_RATE:
+        case IB_REJ_INVALID_ALT_HOP_LIMIT:
+        case IB_REJ_INVALID_ALT_FLOW_LBL:
+        case IB_REJ_INVALID_GID:
+        case IB_REJ_INVALID_LID:
+        case IB_REJ_INVALID_SID:
+        case IB_REJ_INVALID_SL:
+        case IB_REJ_INVALID_TRAFFIC_CLASS:
+        case IB_REJ_PORT_REDIRECT:
+        case IB_REJ_INVALID_MTU:
+        case IB_REJ_INSUFFICIENT_RESP_RES:
+        case IB_REJ_INVALID_CLASS_VER:
+        case IB_REJ_INVALID_FLOW_LBL:
+            cm_event = IB_CME_DESTINATION_REJECT;
+            break;
+
+        case IB_REJ_TIMEOUT:
+            cm_event = IB_CME_DESTINATION_UNREACHABLE;
+            dapl_dbg_log (DAPL_DBG_TYPE_CM, "--> DiCRjcb: CR TIMEOUT\n");
+            break;
+
+        case IB_REJ_USER_DEFINED:
+            cm_event = IB_CME_DESTINATION_REJECT;
+            dapl_dbg_log (DAPL_DBG_TYPE_CM, 
+                               "--> DiCRjcb: user defined rej reason %s\n",
+                               p_cm_rej_rec->p_ari);
+            break;
+
+        default:
+            cm_event = IB_CME_LOCAL_FAILURE;
+            dapl_dbg_log (DAPL_DBG_TYPE_CM, 
+                               "--> DiCRjcb: with unknown status %x\n", 
+                               p_cm_rej_rec->rej_status);
+            break;
+     }
+
+    /* FIXME - Vu
+     * We do not take care off the user defined rej reason with additional 
+     * rejection information (p_ari)
+     */
+
+    if (ep_ptr->cr_ptr)
+    {
+        dapls_cr_callback ( cm_ptr,
+                            cm_event,
+                            (void * __ptr64) p_cm_rej_rec->p_rej_pdata,
+                           IB_REJ_PDATA_SIZE,
+                            (void *) ((DAPL_CR *) ep_ptr->cr_ptr)->sp_ptr);
+    }
+    else
+    {
+        dapl_evd_connection_callback (
+                                   cm_ptr,
+                                   cm_event,
+                                   (void * __ptr64) p_cm_rej_rec->p_rej_pdata,
+                                  IB_REJ_PDATA_SIZE,
+                                   (void * __ptr64) p_cm_rej_rec->qp_context );
+    }
+
+}
+
+
+
+static void 
+dapli_ib_cm_req_cb ( IN  ib_cm_req_rec_t  *p_cm_req_rec )
+{
+    DAPL_SP              *sp_ptr;
+    DAT_SOCK_ADDR6       dest_ia_addr;
+    dp_ib_cm_handle_t    cm_ptr;
+
+    dapl_os_assert (p_cm_req_rec);
+
+    sp_ptr = (DAPL_SP * __ptr64) p_cm_req_rec->context;
+
+    dapl_os_assert (sp_ptr);
+
+    /*
+     * The context pointer could have been cleaned up in a racing
+     * CM callback, check to see if we should just exit here
+     */
+    if (sp_ptr->header.magic == DAPL_MAGIC_INVALID)
+    {
+        dapl_dbg_log (DAPL_DBG_TYPE_CM,
+                     "%s: BAD-Magic in SP %lx, racing CM callback?\n",
+                      __FUNCTION__, sp_ptr );
+       return;
+    }
+
+    dapl_os_assert ( sp_ptr->header.magic == DAPL_MAGIC_PSP || 
+                     sp_ptr->header.magic == DAPL_MAGIC_RSP );
+
+    /* preserve ibal's connection handle storage so we have a consistent
+     * pointer value. The reasons this is done dynamically instead of a static
+     * allocation in an end_point is the pointer value is set in the SP list
+     * of CR's here and searched for from disconnect callbacks. If the pointer
+     * value changes, you never find the CR on the sp list...
+     * EP struct deallocation is where this memory is released or prior in the
+     * error case.
+     */
+    cm_ptr = ibal_cm_alloc();
+    if (!cm_ptr)
+    {
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
+                       "%s: FAILED to alloc IB CM handle storage?\n",
+                       __FUNCTION__);
+        return;
+    }
+
+    /*
+     * Save the cm_srvc_handle to avoid the race condition between
+     * the return of the ib_cm_listen and the notification of a conn req
+     */
+    if (sp_ptr->cm_srvc_handle != p_cm_req_rec->h_cm_listen)
+    {
+        dapl_dbg_log (DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK, 
+                           "--> DiCRqcb: cm_service_handle is changed\n"); 
+        sp_ptr->cm_srvc_handle = p_cm_req_rec->h_cm_listen;
+    }
+
+    dapl_os_memzero (&dest_ia_addr, sizeof (dest_ia_addr));
+
+#ifdef NO_NAME_SERVICE
+
+    {
+        DAPL_PRIVATE *prd_ptr;
+        
+        prd_ptr = (DAPL_PRIVATE *)p_cm_req_rec->p_req_pdata;
+
+        dapl_os_memcpy ((void *)&dest_ia_addr,
+                        (void *)&prd_ptr->hca_address,
+                        sizeof (DAT_SOCK_ADDR6));        
+    }
+    
+#else
+
+    {
+        GID            dest_gid;
+
+        dapl_os_memzero (&dest_gid, sizeof (dest_gid));
+
+        dest_gid.guid = p_cm_req_rec->primary_path.dgid.unicast.interface_id;
+        dest_gid.gid_prefix = p_cm_req_rec->primary_path.dgid.unicast.prefix;
+
+        if (DAT_SUCCESS != dapls_ns_map_ipaddr (
+                                 sp_ptr->header.owner_ia->hca_ptr,
+                                 dest_gid,
+                                 (DAT_IA_ADDRESS_PTR)&dest_ia_addr))
+        {
+            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
+                           "cm_req_cb: SP = %lx failed mapping GID-IPaddr\n",
+                           sp_ptr);
+        }
+    }
+
+#endif /* NO_NAME_SERVICE */
+
+    /* preserve CR cm handle data */
+    dapl_os_memcpy( (void*)&cm_ptr->ib_cm,
+                    (void*)&p_cm_req_rec->h_cm_req,
+                    sizeof(ib_cm_handle_t));
+
+    /* preserve remote IP address */
+    dapl_os_memcpy( (void*)&cm_ptr->dst_ip_addr,
+                    (void*)&dest_ia_addr,
+                    sizeof(dest_ia_addr));
+
+#if defined(DAPL_DBG)
+    {
+        char ipa[20];
+  
+        //rval = ((struct sockaddr_in *) (&dest_ia_addr))->sin_addr.s_addr;
+
+        dapl_dbg_log (DAPL_DBG_TYPE_CM|DAPL_DBG_TYPE_CALLBACK, 
+                      "%s: query SA (CM %lx)->dst_ip_addr: %s\n",
+                      __FUNCTION__,cm_ptr,
+                      dapli_get_ip_addr_str(
+                               (DAT_SOCK_ADDR6*) &cm_ptr->dst_ip_addr, ipa) );
+    }
+#endif
+
+    /* FIXME - Vu
+     * We have NOT used/saved the primary and alternative path record
+     * ie. p_cm_req_rec->p_primary_path and p_cm_req_rec->p_alt_path
+     * We should cache some fields in path record in the Name Service DB
+     * such as: dgid, dlid
+     * Also we do not save resp_res (ie. max_oustanding_rdma_read/atomic)
+     * rnr_retry_cnt and flow_ctrl fields
+     */
+    dapl_dbg_log (DAPL_DBG_TYPE_CM,
+                  "%s: SP %lx max_rdma_read %d PrivateData %lx\n",
+                  __FUNCTION__, sp_ptr, p_cm_req_rec->resp_res,
+                  p_cm_req_rec->p_req_pdata);
+
+    dapls_cr_callback ( cm_ptr,
+                        IB_CME_CONNECTION_REQUEST_PENDING,
+                        (void * __ptr64) p_cm_req_rec->p_req_pdata,
+                                               IB_REQ_PDATA_SIZE,
+                        (void * __ptr64) sp_ptr );
+}
+
+
+static void 
+dapli_ib_cm_mra_cb (
+        IN    ib_cm_mra_rec_t          *p_cm_mra_rec )
+{
+       UNUSED_PARAM( p_cm_mra_rec );
+       dapl_dbg_log (DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK, 
+                       "--> DiCMcb: CM callback MRA\n");
+}
+
+static void 
+dapli_ib_cm_rtu_cb (
+        IN    ib_cm_rtu_rec_t          *p_cm_rtu_rec )
+{
+    DAPL_EP            *ep_ptr;
+    dp_ib_cm_handle_t  cm_ptr;
+
+    dapl_os_assert (p_cm_rtu_rec != NULL);
+   
+    ep_ptr = (DAPL_EP * __ptr64) p_cm_rtu_rec->qp_context;
+
+    if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )
+    {
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: EP %lx invalid or FREED\n",
+                      __FUNCTION__, ep_ptr);
+        return;
+    }
+    cm_ptr = dapl_get_cm_from_ep(ep_ptr);
+    if (!cm_ptr)
+    {
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                      "--> %s: !CM_PTR on EP %p\n", __FUNCTION__, ep_ptr);
+        return;
+    }
+    dapl_os_assert(cm_ptr->ib_cm.h_qp == p_cm_rtu_rec->h_qp);
+
+    dapl_dbg_log (DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK, 
+                  "--> DiCRucb: EP %lx QP %lx CR %lx\n",
+                  ep_ptr, ep_ptr->qp_handle, ep_ptr->cr_ptr); 
+
+    if (ep_ptr->cr_ptr)
+    {
+        DAPL_SP  *sp_ptr;
+
+        sp_ptr = ((DAPL_CR *) ep_ptr->cr_ptr)->sp_ptr;
+
+        /* passive connection side */
+        dapls_cr_callback ( cm_ptr,
+                            IB_CME_CONNECTED,
+                            (void * __ptr64) p_cm_rtu_rec->p_rtu_pdata,
+                            IB_RTU_PDATA_SIZE,
+                            (void *) sp_ptr);
+                            
+    }
+    else
+    {
+        dapl_evd_connection_callback ( 
+                            cm_ptr,
+                            IB_CME_CONNECTED,
+                            (void * __ptr64) p_cm_rtu_rec->p_rtu_pdata,
+                           IB_RTU_PDATA_SIZE,
+                            (void *) ep_ptr);
+    }
+}
+
+/*
+ * 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      *remote_address )
+{
+
+    DAPL_HEADER        *header;
+    dp_ib_cm_handle_t  cm;
+    char               ipa[20];
+    char               *rtype;
+
+    header = (DAPL_HEADER *)dat_handle;
+
+    if (header->magic == DAPL_MAGIC_EP) 
+    {
+       cm = dapl_get_cm_from_ep((DAPL_EP *)dat_handle);
+       rtype = "EP";
+    }
+    else if (header->magic == DAPL_MAGIC_CR) 
+    {
+       cm = ((DAPL_CR *) dat_handle)->ib_cm_handle;
+       rtype = "CR";
+    }
+    else 
+    {
+        dapl_dbg_log ( DAPL_DBG_TYPE_CM,
+                       "%s: hdr->magic %x, dat_handle(%lx)\n",
+                       __FUNCTION__, header->magic, dat_handle );
+       return DAT_INVALID_HANDLE;
+    }
+
+    dapl_os_memcpy( remote_address, &cm->dst_ip_addr, sizeof(DAT_SOCK_ADDR6) );
+
+    dapl_dbg_log ( DAPL_DBG_TYPE_CM, "%s: returns %s remote Addrs %s\n",
+                   __FUNCTION__, rtype,
+                   dapli_get_ip_addr_str((DAT_SOCK_ADDR6*)remote_address,ipa) );
+
+    return DAT_SUCCESS;
+}
+
+
+/*
+ * 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           remote_ia_address,
+        IN        DAT_CONN_QUAL                remote_conn_qual,
+        IN        DAT_COUNT                    private_data_size,
+        IN        DAT_PVOID                    private_data )
+{
+    DAPL_EP                      *ep_ptr;
+    DAPL_IA                      *ia_ptr;
+    ib_api_status_t              ib_status;
+    dapl_ibal_port_t             *p_active_port;
+    dapl_ibal_ca_t               *p_ca;
+    ib_cm_req_t                  cm_req;
+    ib_path_rec_t                path_rec;
+    GID                          dest_GID;
+    ib_query_req_t               query_req;
+    ib_gid_pair_t                gid_pair;
+    ib_service_record_t          service_rec;
+    int                          retry_cnt;
+    DAT_RETURN                   dat_status;
+
+    ep_ptr         = (DAPL_EP *) ep_handle;
+    ia_ptr         = ep_ptr->header.owner_ia;
+    ep_ptr->cr_ptr = NULL;
+    retry_cnt      = 0;
+    dat_status     = DAT_SUCCESS;
+
+    p_ca = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;
+
+    /*
+     * We are using the first active port in the list for
+     * communication. We have to get back here when we decide to support
+     * fail-over and high-availability.
+     */
+    p_active_port = dapli_ibal_get_port ( p_ca,
+                                          (uint8_t)ia_ptr->hca_ptr->port_num );
+
+    if (NULL == p_active_port)
+    {
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"--> DsC: Port %d not available %d\n",
+                       ia_ptr->hca_ptr->port_num, __LINE__ );
+        return (DAT_INVALID_STATE);
+    }
+
+    dapl_os_memzero (&dest_GID, sizeof (GID));
+    dapl_os_memzero (&cm_req, sizeof (ib_cm_req_t));
+    dapl_os_memzero (&path_rec, sizeof (ib_path_rec_t));
+    dapl_os_memzero (&service_rec, sizeof (ib_service_record_t));
+    dapl_os_memzero (&query_req, sizeof (ib_query_req_t));
+    dapl_os_memzero (&gid_pair, sizeof (ib_gid_pair_t));
+    dapl_os_memzero (&ep_ptr->remote_ia_address, sizeof (DAT_SOCK_ADDR6));
+
+    dapl_os_memcpy (&ep_ptr->remote_ia_address, 
+                    remote_ia_address, 
+                    sizeof (ep_ptr->remote_ia_address));
+
+
+#ifdef NO_NAME_SERVICE
+
+    if (DAT_SUCCESS !=
+        (dat_status = dapls_ns_lookup_address (
+                                         ia_ptr,
+                                         remote_ia_address,
+                                         &dest_GID         )))
+    {
+        /*
+         * Remote address not in the table, this is a
+         * strange return code!
+         */
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"--> DsC: exits status = %x\n", dat_status);
+        return dat_status;
+    }
+
+    dest_GID.guid = CL_HTON64 (dest_GID.guid);
+    dest_GID.gid_prefix = CL_HTON64 (dest_GID.gid_prefix);
+
+#else
+
+    /*
+     * We query the SA to get the dest_gid with the 
+     * {uDAPL_svc_id, IP-address} as the key to get GID.
+     */
+    if (DAT_SUCCESS !=
+        (dat_status = dapls_ns_map_gid (ia_ptr->hca_ptr, 
+                                        remote_ia_address,
+                                        &dest_GID)))
+        
+    {
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR, "--> DsC: fail to map remote_ia_addr "
+                       "(sa_family %d) to gid\n",
+                       remote_ia_address->sa_family); 
+        return dat_status;
+    }
+#endif /* NO_NAME_SERVICE */
+
+    gid_pair.dest_gid.unicast.interface_id = dest_GID.guid;
+    gid_pair.dest_gid.unicast.prefix       = dest_GID.gid_prefix;
+
+    dapl_dbg_log (DAPL_DBG_TYPE_CM, 
+                  "dapls_ib_connect: EP %lx QP %lx SERVER GID{0x" F64x
+                  ", 0x" F64x "}\n", 
+                  ep_ptr, ep_ptr->qp_handle,
+                  cl_hton64 (gid_pair.dest_gid.unicast.prefix),
+                  cl_hton64 (gid_pair.dest_gid.unicast.interface_id));
+
+    gid_pair.src_gid = p_active_port->p_attr->p_gid_table[0];
+/*
+    if ((gid_pair.src_gid.unicast.interface_id == 
+         gid_pair.dest_gid.unicast.interface_id   ) &&
+        (gid_pair.src_gid.unicast.prefix == 
+         gid_pair.dest_gid.unicast.prefix   ))
+    {
+        path_rec.dgid     = gid_pair.dest_gid;
+        path_rec.sgid     = gid_pair.src_gid;
+        path_rec.slid     = path_rec.dlid = p_active_port->p_attr->lid;
+        path_rec.pkey     = p_active_port->p_attr->p_pkey_table[0];
+        path_rec.mtu      = p_active_port->p_attr->mtu;
+               path_rec.pkt_life = 18;  // 1 sec
+               path_rec.rate     = IB_PATH_RECORD_RATE_10_GBS;
+       
+       }
+    else
+    {
+  */
+        /*
+         * Query SA to get the path record from pair of GIDs
+         */
+        dapl_os_memzero (&query_req, sizeof (ib_query_req_t));
+        query_req.query_type      = IB_QUERY_PATH_REC_BY_GIDS;
+        query_req.p_query_input   = (void *) &gid_pair;
+        query_req.flags           = IB_FLAGS_SYNC;  
+        query_req.timeout_ms      = 1 * 1000;       /* 1 second */
+        query_req.retry_cnt       = 3;
+        /* query SA using this port */
+        query_req.port_guid       = p_active_port->p_attr->port_guid;
+        query_req.query_context   = (void *) &path_rec;
+        query_req.pfn_query_cb    = dapli_ib_sa_query_cb;
+        ib_status = ib_query (dapl_ibal_root.h_al, &query_req, NULL);
+
+        if ((ib_status != IB_SUCCESS) || (!path_rec.dlid))
+        {
+            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"--> DsC: EP %lx QP %lx query "
+                           "pair_gids status = %s\n", 
+                           ep_ptr, ep_ptr->qp_handle,ib_get_err_str(ib_status));
+            return DAT_INVALID_PARAMETER;
+        }
+
+    //}
+
+       /*
+        * Tavor has a HW bug that causes bandwidth with 2K MTU to be less than
+        * with 1K MTU.  Cap the MTU based on device ID to compensate for this.
+        */
+       if( (p_ca->p_ca_attr->dev_id == 0x5A44) &&
+               (ib_path_rec_mtu( &path_rec ) > IB_MTU_LEN_1024) )
+       {
+            /* Local endpoint is Tavor - cap MTU to 1K for extra bandwidth. */
+            path_rec.mtu &= IB_PATH_REC_SELECTOR_MASK;
+            path_rec.mtu |= IB_MTU_LEN_1024;
+       }
+
+       /* 
+     * prepare the Service ID from conn_qual 
+     */
+    cm_req.svc_id           = remote_conn_qual;
+    cm_req.p_primary_path   = &path_rec;
+    cm_req.p_alt_path       = NULL;
+    cm_req.h_qp             = ep_ptr->qp_handle;
+    cm_req.qp_type          = IB_QPT_RELIABLE_CONN;
+    cm_req.p_req_pdata      = (uint8_t *) private_data;
+    cm_req.req_length       = (uint8_t)
+                               min(private_data_size,IB_MAX_REQ_PDATA_SIZE);
+    /* cm retry to send this request messages, IB max of 4 bits */
+    cm_req.max_cm_retries   = 15; /* timer outside of call, s/be infinite */
+    /* qp retry to send any wr */
+    cm_req.retry_cnt        = 5;
+    /* max num of oustanding RDMA read/atomic support */
+    cm_req.resp_res         = (uint8_t)ep_ptr->param.ep_attr.max_rdma_read_in;
+    /* max num of oustanding RDMA read/atomic will use */
+    cm_req.init_depth       = (uint8_t)ep_ptr->param.ep_attr.max_rdma_read_out;
+
+    /* time wait before retrying a pkt after receiving a RNR NAK */
+    cm_req.rnr_nak_timeout  = IB_RNR_NAK_TIMEOUT;
+    
+       /* 
+     * number of time local QP should retry after receiving RNR NACK before
+     * reporting an error
+     */
+    cm_req.rnr_retry_cnt       = IB_RNR_RETRY_CNT;
+
+    cm_req.remote_resp_timeout = 16;   /* 250ms */
+    cm_req.local_resp_timeout  = 16;   /* 250ms */
+    
+    cm_req.flow_ctrl           = TRUE;
+    cm_req.flags               = 0;
+    /*
+     * We do not use specific data buffer to check for specific connection
+     */
+    cm_req.p_compare_buffer    = NULL;
+    cm_req.compare_offset      = 0;
+    cm_req.compare_length      = 0;
+
+    dapl_dbg_log (DAPL_DBG_TYPE_CM, "--> DsConn: EP=%lx QP=%lx rio=%d,%d pl=%d "
+                  "mtu=%d slid=%#x dlid=%#x\n", 
+                  ep_ptr, ep_ptr->qp_handle,  cm_req.resp_res, 
+                  cm_req.init_depth, ib_path_rec_pkt_life(&path_rec),
+                  ib_path_rec_mtu(&path_rec),
+                  cm_req.p_primary_path->slid,
+                  cm_req.p_primary_path->dlid);
+
+    /*
+     * We do not support peer_to_peer; therefore, we set pfn_cm_req_cb = NULL
+     */
+    cm_req.pfn_cm_req_cb       = NULL;
+    cm_req.pfn_cm_rep_cb       = dapli_ib_cm_rep_cb;
+    cm_req.pfn_cm_rej_cb       = dapli_ib_cm_rej_cb;
+    /* callback when a message received acknowledgement is received */
+    cm_req.pfn_cm_mra_cb       = dapli_ib_cm_mra_cb;
+
+    ib_status = ib_cm_req (&cm_req);
+    
+    if ( ib_status != IB_SUCCESS )
+    {
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
+                       "--> DsC: EP %lx QP %lx conn_request failed = %s\n", 
+                       ep_ptr, ep_ptr->qp_handle, ib_get_err_str(ib_status));
+
+        return  (dapl_ib_status_convert (ib_status));
+    }
+
+    return DAT_SUCCESS;
+}
+
+
+/*
+ * dapls_ib_disconnect
+ *
+ * Disconnect an EP
+ *
+ * Input:
+ *        ep_handle,
+ *        disconnect_flags
+ *           DAT_CLOSE_ABRUPT_FLAG - no callback
+ *           DAT_CLOSE_GRACEFUL_FLAG - callback desired.
+ *
+ * Output:
+ *         none
+ *
+ * Returns:
+ *        DAT_SUCCESS
+ *        DAT_INSUFFICIENT_RESOURCES
+ *        DAT_INVALID_PARAMETER
+ *
+ */
+DAT_RETURN
+dapls_ib_disconnect ( IN   DAPL_EP           *ep_ptr,
+                      IN   DAT_CLOSE_FLAGS   disconnect_flags )
+{
+    ib_api_status_t    ib_status = IB_SUCCESS;
+    ib_cm_dreq_t       cm_dreq;
+    dp_ib_cm_handle_t  cm_ptr;
+
+    dapl_os_assert(ep_ptr);
+
+    if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )
+    {
+         dapl_dbg_log (DAPL_DBG_TYPE_CM,
+                  "--> %s: BAD EP Magic EP=%lx\n", __FUNCTION__,ep_ptr); 
+        return DAT_SUCCESS;
+    }
+    cm_ptr = dapl_get_cm_from_ep(ep_ptr);
+    if (!cm_ptr)
+    {
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR, 
+                      "--> %s: !CM_PTR on EP %p\n", __FUNCTION__, ep_ptr);
+        return DAT_SUCCESS;
+    }
+    dapl_dbg_log (DAPL_DBG_TYPE_CM,
+       "--> %s() EP %p %s rx_drq %d tx_drq %d Close %s\n", __FUNCTION__,
+       ep_ptr, dapl_get_ep_state_str(ep_ptr->param.ep_state),
+                  ep_ptr->recv_discreq, ep_ptr->sent_discreq,
+       (disconnect_flags == DAT_CLOSE_ABRUPT_FLAG ? "Abrupt":"Graceful"));
+
+    if ( disconnect_flags == DAT_CLOSE_ABRUPT_FLAG )
+    {
+       if ( ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED )
+        return DAT_SUCCESS;
+
+       if ( ep_ptr->param.ep_state != DAT_EP_STATE_DISCONNECT_PENDING )
+    {
+           dapl_dbg_log(DAPL_DBG_TYPE_CM,
+                       "%s() calling legacy_post_disconnect()\n",__FUNCTION__);
+            dapl_ep_legacy_post_disconnect(ep_ptr, disconnect_flags);
+            return DAT_SUCCESS;
+       }
+    }
+
+    dapl_os_memzero(&cm_dreq, sizeof(ib_cm_dreq_t));
+
+    cm_dreq.qp_type        = IB_QPT_RELIABLE_CONN;
+    cm_dreq.h_qp           = ep_ptr->qp_handle;
+    cm_dreq.pfn_cm_drep_cb = dapli_ib_cm_drep_cb;
+    
+    /* 
+     * Currently we do not send any disconnect private data to
+     * the other endpoint because DAT 2.0 does not support it.  
+     */
+    cm_dreq.p_dreq_pdata   = NULL;
+    cm_dreq.flags          = IB_FLAGS_SYNC;
+
+    /*
+     * still need to send DREQ (disconnect request)?
+     */
+    if ( (ep_ptr->recv_discreq == DAT_FALSE)
+          && (ep_ptr->sent_discreq == DAT_FALSE)
+         && (ep_ptr->qp_state != IB_QPS_RESET) )
+    {
+        ep_ptr->sent_discreq = DAT_TRUE;
+        ib_status = ib_cm_dreq ( &cm_dreq );
+
+       if ( ib_status == IB_SUCCESS )
+           dapl_dbg_log (DAPL_DBG_TYPE_CM,
+                       "--> DsD: EP %p  DREQ SENT\n", ep_ptr);
+
+       /* tolerate INVALID_STATE error as the other side can race ahead and
+        * generate a DREQ before we do.
+        */
+       if ( ib_status == IB_INVALID_STATE || ib_status == IB_INVALID_HANDLE )
+       {
+           ib_status = IB_SUCCESS;
+       }
+       else if (ib_status)
+       {
+           dapl_dbg_log(DAPL_DBG_TYPE_ERR,
+                       "%s() EP %p ib_cm_dreq() status %s\n",
+                       __FUNCTION__,ep_ptr,ib_get_err_str(ib_status));
+       }
+    }
+    return ib_status;
+}
+
+
+/*
+ * 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_INVALID_PARAMETER
+ *
+ */
+DAT_RETURN
+dapls_ib_setup_conn_listener (
+        IN  DAPL_IA               *ia_ptr,
+        IN  DAT_UINT64            ServiceID,
+        IN  DAPL_SP               *sp_ptr )
+{
+    ib_api_status_t               ib_status;
+    ib_cm_listen_t                cm_listen;
+    dapl_ibal_ca_t                *p_ca;
+    dapl_ibal_port_t              *p_active_port;
+
+    p_ca = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;
+
+    /*
+     * We are using the first active port in the list for
+     * communication. We have to get back here when we decide to support
+     * fail-over and high-availability.
+     */
+    p_active_port = dapli_ibal_get_port( p_ca,
+                                       (uint8_t)ia_ptr->hca_ptr->port_num );
+
+    if (NULL == p_active_port)
+    {
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"%s: SP %lx port %d not available\n",
+                __FUNCTION__, sp_ptr, ia_ptr->hca_ptr->port_num );
+        return (DAT_INVALID_STATE);
+    }
+
+    if (p_active_port->p_attr->lid == 0)
+    {
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
+                       "--> DsSCL: SP %lx SID 0x" F64x " port %d\n", 
+                       sp_ptr, cl_hton64(ServiceID),
+                       p_active_port->p_attr->port_num);
+        return (DAT_INVALID_STATE);
+    }
+
+    dapl_dbg_log (DAPL_DBG_TYPE_CM,
+         "%s: SP %lx port %d GID{0x" F64x ", 0x" F64x "} and SID 0x" F64x "\n", 
+         __FUNCTION__,
+         sp_ptr, p_active_port->p_attr->port_num,
+         cl_hton64 (p_active_port->p_attr->p_gid_table[0].unicast.prefix),
+         cl_hton64 (p_active_port->p_attr->p_gid_table[0].unicast.interface_id),
+         cl_hton64 (ServiceID));
+    
+    dapl_os_memzero (&cm_listen, sizeof (ib_cm_listen_t));
+
+    /*
+     * Listen for all request on  this specific CA
+     */
+    cm_listen.ca_guid = (p_ca->p_ca_attr->ca_guid);
+    cm_listen.svc_id  = ServiceID;
+    cm_listen.qp_type = IB_QPT_RELIABLE_CONN; 
+
+    /*
+     * We do not use specific data buffer to check for specific connection
+     */
+    cm_listen.p_compare_buffer = NULL;//(uint8_t*)&sp_ptr->conn_qual;
+    cm_listen.compare_offset   = 0;//IB_MAX_REQ_PDATA_SIZE - sizeof(DAT_CONN_QUAL);
+    cm_listen.compare_length   = 0;//sizeof(DAT_CONN_QUAL);
+
+    /*
+     * We can pick a port here for communication and the others are reserved
+     * for fail-over / high-availability - TBD
+     */
+    cm_listen.port_guid     = p_active_port->p_attr->port_guid;
+    cm_listen.lid           = p_active_port->p_attr->lid;
+    cm_listen.pkey          = p_active_port->p_attr->p_pkey_table[0];
+
+    /*
+     * Register request or mra callback functions
+     */
+    cm_listen.pfn_cm_req_cb = dapli_ib_cm_req_cb;
+
+    ib_status = ib_cm_listen ( dapl_ibal_root.h_al,
+                               &cm_listen,
+                               (void *) sp_ptr,
+                               &sp_ptr->cm_srvc_handle );
+
+    if (ib_status != IB_SUCCESS)
+    {
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
+                       "%s: SP %lx SID 0x" F64x " listen failed %s\n", 
+                       __FUNCTION__, sp_ptr, cl_hton64 (ServiceID),
+                       ib_get_err_str(ib_status));
+    }
+
+    return dapl_ib_status_convert (ib_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_PARAMETER
+ *
+ */
+DAT_RETURN
+dapls_ib_remove_conn_listener (
+        IN  DAPL_IA        *ia_ptr,
+        IN  DAPL_SP        *sp_ptr )
+{
+    ib_api_status_t        ib_status;
+    DAT_RETURN             dat_status = DAT_SUCCESS;
+       
+    UNUSED_PARAM( ia_ptr );
+
+    dapl_os_assert ( sp_ptr );
+
+    dapl_os_assert ( sp_ptr->header.magic == DAPL_MAGIC_PSP ||
+         sp_ptr->header.magic == DAPL_MAGIC_RSP );
+
+    dapl_dbg_log ( DAPL_DBG_TYPE_CM, "%s() cm_srvc_handle %lx\n",
+                   __FUNCTION__, sp_ptr->cm_srvc_handle );
+
+    if (sp_ptr->cm_srvc_handle)
+    {
+        ib_status = ib_cm_cancel ( sp_ptr->cm_srvc_handle, 
+                                   NULL );
+        
+        if (ib_status != IB_SUCCESS)
+        {
+            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
+                           "--> DsRCL: SP %lx ib_cm_cancel failed(0x%x) %s\n", 
+                           sp_ptr, sp_ptr->cm_srvc_handle,
+                           ib_get_err_str(ib_status));
+            sp_ptr->cm_srvc_handle = NULL;
+            return (DAT_INVALID_PARAMETER);
+        }
+
+        sp_ptr->cm_srvc_handle = NULL;
+    }
+
+    return dat_status;
+}
+
+/*
+ * dapls_ib_reject_connection
+ *
+ * Perform necessary steps to reject a connection
+ *
+ * Input:
+ *        cr_handle
+ *
+ * Output:
+ *         none
+ *
+ * Returns:
+ *         DAT_SUCCESS
+ *        DAT_INSUFFICIENT_RESOURCES
+ *        DAT_INVALID_PARAMETER
+ *
+ */
+DAT_RETURN
+dapls_ib_reject_connection ( IN  dp_ib_cm_handle_t   ib_cm_handle,
+                             IN  int                 reject_reason,
+                             IN  DAT_COUNT           private_data_size,
+                             IN  const DAT_PVOID     private_data)
+{
+    ib_api_status_t        ib_status;
+    ib_cm_rej_t            cm_rej;
+    static char            *rej_table[] =
+    {
+        "INVALID_REJ_REASON",
+        "INVALID_REJ_REASON",
+        "INVALID_REJ_REASON",
+        "INVALID_REJ_REASON",
+        "INVALID_REJ_REASON",
+        "IB_CME_DESTINATION_REJECT",
+        "IB_CME_DESTINATION_REJECT_PRIVATE_DATA",
+        "IB_CME_DESTINATION_UNREACHABLE",
+        "IB_CME_TOO_MANY_CONNECTION_REQUESTS",
+        "IB_CME_LOCAL_FAILURE",
+        "IB_CM_LOCAL_FAILURE"
+    };
+
+#define REJ_TABLE_SIZE  IB_CM_LOCAL_FAILURE
+
+    reject_reason = __min( reject_reason & 0xff, REJ_TABLE_SIZE);
+
+    cm_rej.rej_status   = IB_REJ_USER_DEFINED;
+    cm_rej.p_ari        = (ib_ari_t *)&rej_table[reject_reason]; 
+    cm_rej.ari_length   = (uint8_t)strlen (rej_table[reject_reason]);
+
+    cm_rej.p_rej_pdata  = private_data;
+    cm_rej.rej_length   = private_data_size;
+
+#if defined(DAPL_DBG) && 0
+    dapli_print_private_data("DsRjC",private_data,private_data_size);
+#endif
+
+    ib_status = ib_cm_rej(ib_cm_handle->ib_cm, &cm_rej);
+
+    if (ib_status != IB_SUCCESS)
+    {
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
+                       "--> DsRjC: cm_handle %p reject failed %s\n", 
+                       ib_cm_handle, ib_get_err_str(ib_status) );
+    }
+
+    return ( dapl_ib_status_convert ( ib_status ) );
+}
+
+
+
+#if 0
+static void
+dapli_query_qp( ib_qp_handle_t qp_handle, ib_qp_attr_t  *qpa )
+{
+    ib_api_status_t        ib_status;
+    
+    ib_status = ib_query_qp ( qp_handle, qpa );
+    if (ib_status != IB_SUCCESS)
+    {
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"ib_query_qp(%lx) '%s'\n",
+                qp_handle, ib_get_err_str(ib_status) );
+    }
+    else
+    {
+        dapl_dbg_log ( DAPL_DBG_TYPE_CM, "--> QP(%lx) state %s "
+                       "type %d init %d acc %x\n",
+                       qp_handle,
+                       ib_get_port_state_str(qpa->state),
+                       qpa->qp_type,
+                       qpa->init_depth,
+                       qpa->access_ctrl );
+    }
+}
+#endif
+
+
+/*
+ * 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_INVALID_PARAMETER
+ *
+ */
+DAT_RETURN
+dapls_ib_accept_connection (
+        IN        DAT_CR_HANDLE            cr_handle,
+        IN        DAT_EP_HANDLE            ep_handle,
+        IN        DAT_COUNT                private_data_size,
+        IN const  DAT_PVOID                private_data )
+{
+    DAPL_CR                *cr_ptr;
+    DAPL_EP                *ep_ptr;
+    DAPL_IA                *ia_ptr;
+    DAT_RETURN             dat_status;
+    ib_api_status_t        ib_status;
+    dapl_ibal_ca_t         *p_ca;
+    dapl_ibal_port_t       *p_active_port;
+    ib_cm_rep_t            cm_rep;
+    ib_qp_attr_t           qpa;
+    dp_ib_cm_handle_t      cm_ptr;
+
+    cr_ptr = (DAPL_CR *) cr_handle;
+    ep_ptr = (DAPL_EP *) ep_handle;
+    ia_ptr = ep_ptr->header.owner_ia;
+
+    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, ep_ptr );
+
+        if ( dat_status != DAT_SUCCESS)
+        {
+            /* This is not a great error code, but all the spec allows */
+            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
+                           "-->  DsIBAC: CR %lx EP %lx alloc QP failed 0x%x\n",
+                           cr_ptr, ep_ptr, dat_status );
+            return (dat_status);
+        }
+    }
+
+    p_ca = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;
+    p_active_port = dapli_ibal_get_port ( p_ca,
+                                          (uint8_t)ia_ptr->hca_ptr->port_num );
+    if (NULL == p_active_port)
+    {
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
+                       "--> DsIBAC: CR %lx EP %lx port %d is not available\n",
+                       cr_ptr, ep_ptr, ia_ptr->hca_ptr->port_num);
+        return (DAT_INVALID_STATE);
+    }
+
+    cr_ptr->param.local_ep_handle = ep_handle;
+
+    /*
+     * assume ownership, in that once the EP is released the dynamic
+     * memory containing the IBAL CM handle (ib_cm_handle_t) struct will
+     * be released; see dapl_ep_dealloc().
+     */
+   
+    /* EP-CM, save/release CR CM object, use EP CM object already linked */
+    cm_ptr = dapl_get_cm_from_ep(ep_ptr);
+    if (!cm_ptr) {
+       dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
+                       "--> DsIBAC: CM linking to EP %p not available\n",
+                       ep_ptr);
+       return (DAT_INVALID_STATE);
+    }
+     
+    /* set remote IP addr fields. IP addr data is deduced from Connection
+     * Request record (gid/lib) and stashed away for use here. DAPL 1.1
+     * had an interface for passing the IP info down, interface went away
+     * in 2.0?
+     */
+    dapl_os_memcpy( (void*)&ep_ptr->remote_ia_address,
+                    (void*)&cr_ptr->ib_cm_handle->dst_ip_addr,
+                    sizeof(DAT_SOCK_ADDR6) );
+
+    dapl_os_memcpy( (void*)&cr_ptr->remote_ia_address,
+                    (void*)&ep_ptr->remote_ia_address,
+                    sizeof(DAT_SOCK_ADDR6) );
+
+#if defined(DAPL_DBG)
+    {
+        char ipa[20];
+
+        dapl_dbg_log (DAPL_DBG_TYPE_CM|DAPL_DBG_TYPE_CALLBACK, 
+                      "%s: EP(%lx) RemoteAddr: %s\n",
+                      __FUNCTION__, ep_ptr,
+                     dapli_get_ip_addr_str(
+                            (DAT_SOCK_ADDR6*)&ep_ptr->remote_ia_address, ipa) );
+    }
+#endif
+
+    dapl_os_memcpy( (void*)&cm_ptr->dst_ip_addr,
+                    (void*)&cr_ptr->ib_cm_handle->dst_ip_addr,
+                    sizeof(DAT_SOCK_ADDR6) );
+
+    /* get h_al and connection ID from CR CM object, h_qp already set */
+    cm_ptr->ib_cm.cid = cr_ptr->ib_cm_handle->ib_cm.cid; 
+    cm_ptr->ib_cm.h_al = cr_ptr->ib_cm_handle->ib_cm.h_al;
+    dapls_cm_release(cr_ptr->ib_cm_handle);
+
+    cr_ptr->ib_cm_handle = cm_ptr; /* for dapli_get_sp_ep() upcall */
+
+    ep_ptr->cr_ptr        = cr_ptr;
+
+    dapl_os_memzero ( (void*)&cm_rep, sizeof (ib_cm_rep_t) );
+
+    cm_rep.h_qp           = ep_ptr->qp_handle;
+    cm_rep.qp_type        = IB_QPT_RELIABLE_CONN;
+
+    if (private_data_size > IB_MAX_REP_PDATA_SIZE) {
+       dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                       "--> DsIBAC: private_data_size(%d) > Max(%d)\n",
+                       private_data_size, IB_MAX_REP_PDATA_SIZE);
+       return DAT_ERROR(DAT_LENGTH_ERROR, DAT_NO_SUBTYPE);
+                                 
+        }
+    cm_rep.p_rep_pdata    = (const uint8_t *)private_data;
+    cm_rep.rep_length     = private_data_size;
+                            
+#if defined(DAPL_DBG) && 0
+    dapli_print_private_data( "DsIBAC",
+                             (const uint8_t*)private_data,
+                             private_data_size );
+#endif
+
+    cm_rep.pfn_cm_rej_cb = dapli_ib_cm_rej_cb;
+    cm_rep.pfn_cm_mra_cb = dapli_ib_cm_mra_cb;
+    cm_rep.pfn_cm_rtu_cb  = dapli_ib_cm_rtu_cb;
+    cm_rep.pfn_cm_lap_cb  = dapli_ib_cm_lap_cb;
+    cm_rep.pfn_cm_dreq_cb = dapli_ib_cm_dreq_cb;
+
+    /*
+     * FIXME - Vu
+     *         Pay attention to the attributes. 
+     *         Some of them are desirably set by DAT consumers
+     */
+    /*
+     * We enable the qp associate with this connection ep all the access right
+     * We enable the flow_ctrl, retry till success
+     * We will limit the access right and flow_ctrl upon DAT consumers 
+     * requirements
+     */
+    cm_rep.access_ctrl =
+               IB_AC_LOCAL_WRITE|IB_AC_RDMA_WRITE|IB_AC_MW_BIND|IB_AC_ATOMIC;
+
+    if ((ep_ptr->param.ep_attr.max_rdma_read_in > 0) 
+               || (ep_ptr->param.ep_attr.max_rdma_read_out > 0))
+    {
+       cm_rep.access_ctrl |= IB_AC_RDMA_READ;
+    }
+
+    cm_rep.sq_depth          = 0;
+    cm_rep.rq_depth          = 0;
+    cm_rep.init_depth        = (uint8_t)ep_ptr->param.ep_attr.max_rdma_read_out;
+    cm_rep.flow_ctrl         = TRUE;
+    cm_rep.flags             = 0;
+    cm_rep.failover_accepted = IB_FAILOVER_ACCEPT_UNSUPPORTED;
+    cm_rep.target_ack_delay  = 14;
+    cm_rep.rnr_nak_timeout   = IB_RNR_NAK_TIMEOUT;
+    cm_rep.rnr_retry_cnt     = IB_RNR_RETRY_CNT;
+    cm_rep.pp_recv_failure   = NULL;
+    cm_rep.p_recv_wr         = NULL;
+     
+    dapl_dbg_log (DAPL_DBG_TYPE_CM,
+                 "--> DsIBAC: cm_rep: acc %x init %d qp_type %x req_count %d\n",
+                cm_rep.access_ctrl, cm_rep.init_depth,cm_rep.qp_type,
+                 dapls_cb_pending(&ep_ptr->req_buffer));
+
+    ib_status = ib_cm_rep ( cm_ptr->ib_cm, &cm_rep );
+
+    if (ib_status != IB_SUCCESS)
+    {
+       dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
+                       "--> DsIBAC: EP %lx QP %lx CR reply failed '%s'\n",
+                       ep_ptr, ep_ptr->qp_handle, ib_get_err_str(ib_status) );
+    }
+    return ( dapl_ib_status_convert ( ib_status ) );
+}
+
+
+
+/*
+ * 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
+ *
+ * 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 )
+{
+    DAPL_IA            *ia_ptr;
+    ib_qp_attr_t       qp_attr;
+    ib_api_status_t     ib_status;
+
+    dapl_dbg_log ( DAPL_DBG_TYPE_CM, "%s(%s): cm_event: %s \n", __FUNCTION__,
+                   (active?"A":"P"), dapli_ib_cm_event_str(ib_cm_event));
+
+    ia_ptr = ep_ptr->header.owner_ia;
+    
+    if ( ia_ptr == NULL || ia_ptr->header.magic != DAPL_MAGIC_IA )
+    {
+        dapl_dbg_log ( DAPL_DBG_TYPE_CM,
+                       ">>>DSCONN_CLEAN(%s): cm_event: %s Invalid IA_ptr\n",
+                       (active?"Act":"Pas"),dapli_ib_cm_event_str(ib_cm_event));
+        return;
+    }
+    dapl_os_assert ( ep_ptr->header.magic == DAPL_MAGIC_EP );
+    
+    ep_ptr->sent_discreq = DAT_FALSE;
+    ep_ptr->recv_discreq = DAT_FALSE;
+
+    /* 
+     * Query the QP to get the current state */
+    ib_status = ib_query_qp ( ep_ptr->qp_handle, &qp_attr );
+                       
+    if ( ib_status != IB_SUCCESS )
+    {
+           dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
+                       ">>>DSCONN_CLEAN(%s): Query QP failed = %s\n",
+                       (active?"Act":"Pas"),ib_get_err_str(ib_status) );
+       return;
+    }
+    
+    ep_ptr->qp_state = qp_attr.state;
+
+    dapl_dbg_log ( DAPL_DBG_TYPE_CM, ">>>DSCONN_CLEAN(%s): cm_event: %d "
+                   "ep_ptr %lx ep_state %s qp_state %#x\n", 
+                   (active?"A":"P"), ib_cm_event, ep_ptr,
+                   dapl_get_ep_state_str(ep_ptr->param.ep_state),
+                   ep_ptr->qp_state );
+
+    if ( ep_ptr->qp_state != IB_QPS_ERROR &&
+         ep_ptr->qp_state != IB_QPS_RESET &&
+         ep_ptr->qp_state != IB_QPS_INIT )
+    {
+        ep_ptr->qp_state = IB_QPS_ERROR;
+        dapls_modify_qp_state_to_error (ep_ptr->qp_handle);
+    }
+}
+
+
+#ifdef NOT_USED
+/*
+ * dapls_ib_cr_handoff
+ *
+ * Hand off the connection request to another service point  
+ *
+ * Input:
+ *        cr_handle                DAT_CR_HANDLE
+ *        handoff_serv_id          DAT_CONN_QUAL
+ *
+ * Output:
+ *         none
+ *
+ * Returns:
+ *         DAT_SUCCESS
+ *         DAT_INVALID_PARAMETER
+ *
+ */
+DAT_RETURN 
+dapls_ib_cr_handoff (
+        IN  DAT_CR_HANDLE      cr_handle,
+        IN  DAT_CONN_QUAL      handoff_serv_id )
+{
+    DAPL_CR                *cr_ptr;
+    ib_api_status_t        ib_status;
+    
+    cr_ptr = (DAPL_CR *) cr_handle;
+
+    if (cr_ptr->ib_cm_handle->ib_cm.cid == 0xFFFFFFFF)
+    {
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
+                       "--> DsCH: CR = %lx invalid cm handle\n", cr_ptr);
+        return DAT_INVALID_PARAMETER;
+    }
+
+    if (cr_ptr->sp_ptr == DAPL_IB_INVALID_HANDLE)
+    {
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
+                       "--> DsCH: CR = %lx invalid psp handle\n", cr_ptr);
+        return DAT_INVALID_PARAMETER;
+    }
+
+    ib_status = ib_cm_handoff (cr_ptr->ib_cm_handle->ib_cm, handoff_serv_id);
+
+    if (ib_status != IB_SUCCESS)
+    {
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
+                       "--> DsCH: CR = %lx handoff failed = %s\n", 
+                       cr_ptr, ib_get_err_str(ib_status) );
+
+        return dapl_ib_status_convert (ib_status);
+    }
+
+    dapl_dbg_log ( DAPL_DBG_TYPE_CM,
+                   "--> %s(): remove CR %lx from SP %lx Queue\n",
+                   __FUNCTION__, cr_ptr, cr_ptr->sp_ptr);
+    /* Remove the CR from the queue */
+    dapl_sp_remove_cr (cr_ptr->sp_ptr, cr_ptr);
+
+    /*
+     * If this SP has been removed from service, free it
+     * up after the last CR is removed
+     */
+    dapl_os_lock (&cr_ptr->sp_ptr->header.lock);
+    if ( cr_ptr->sp_ptr->listening != DAT_TRUE && 
+         cr_ptr->sp_ptr->cr_list_count == 0 &&
+         cr_ptr->sp_ptr->state != DAPL_SP_STATE_FREE )
+    {
+        dapl_dbg_log (DAPL_DBG_TYPE_CM, 
+                      "--> DsCH: CR = %lx disconnect dump SP = %lx \n", 
+                      cr_ptr, cr_ptr->sp_ptr);
+        /* Decrement the ref count on the EVD */
+        if (cr_ptr->sp_ptr->evd_handle)
+        {
+            dapl_os_atomic_dec (& ((DAPL_EVD *)cr_ptr->sp_ptr->evd_handle)->evd_ref_count);
+            cr_ptr->sp_ptr->evd_handle = NULL;
+        }
+        cr_ptr->sp_ptr->state = DAPL_SP_STATE_FREE;
+        dapl_os_unlock (&cr_ptr->sp_ptr->header.lock);
+        (void)dapls_ib_remove_conn_listener ( cr_ptr->sp_ptr->header.owner_ia,
+                                              cr_ptr->sp_ptr );
+        dapls_ia_unlink_sp ( (DAPL_IA *)cr_ptr->sp_ptr->header.owner_ia,
+                             cr_ptr->sp_ptr );
+        dapls_sp_free_sp ( cr_ptr->sp_ptr );
+    }
+    else
+    {
+        dapl_os_unlock (&cr_ptr->sp_ptr->header.lock);
+    }
+
+    /*
+     * Clean up and dispose of the resource
+     */
+    dapls_cr_free (cr_ptr);
+
+    return (DAT_SUCCESS);
+}
+#endif
+
+int
+dapls_ib_private_data_size (
+       IN      DAPL_HCA                *hca_ptr)
+{
+    return IB_MAX_REQ_PDATA_SIZE;
+}
+
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 8
+ * End:
+ */
+
index eff6d11445462776963f35acfc9d963f7a80b837..f52f5daf62609327db4d56a65510e89470a852dd 100644 (file)
-\r
-/*\r
- * Copyright (c) 2005-2007 Intel Corporation. All rights reserved.\r
- * Copyright (c) 2002, Network Appliance, Inc. All rights reserved. \r
- * \r
- * This Software is licensed under the terms of the "Common Public\r
- * License" a copy of which is in the file LICENSE.txt in the root\r
- * directory. The license is also available from the Open Source\r
- * Initiative, see http://www.opensource.org/licenses/cpl.php.\r
- *\r
- */\r
-\r
-/**********************************************************************\r
- * \r
- * MODULE: dapl_ibal_qp.c\r
- *\r
- * PURPOSE: IB QP routines  for access to IBAL APIs\r
- *\r
- * $Id: dapl_ibal_qp.c 33 2005-07-11 19:51:17Z ftillier $\r
- *\r
- **********************************************************************/\r
-\r
-#include "dapl.h"\r
-#include "dapl_adapter_util.h"\r
-#include "dapl_evd_util.h"\r
-#include "dapl_ibal_util.h"\r
-#include "dapl_ep_util.h"\r
-\r
-#define DAPL_IBAL_QKEY              0\r
-#define DAPL_IBAL_START_PSN         0\r
-\r
-extern DAT_RETURN\r
-dapls_ib_cq_late_alloc ( IN  ib_pd_handle_t        pd_handle,\r
-                         IN  DAPL_EVD              *evd_ptr );\r
-\r
-static void\r
-dapli_ib_qp_async_error_cb( IN  ib_async_event_rec_t* p_err_rec )\r
-{\r
-       DAPL_EP                 *ep_ptr = (DAPL_EP *)p_err_rec->context;\r
-       DAPL_EVD                *evd_ptr;\r
-       DAPL_IA                 *ia_ptr;\r
-       dapl_ibal_ca_t          *p_ca;\r
-        dapl_ibal_evd_cb_t     *evd_cb;\r
-\r
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DiQpAEC QP event %s qp ctx %p\n", \r
-               ib_get_async_event_str(p_err_rec->code), p_err_rec->context);\r
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DiQpAEC qp_handle %p qpn %u\n", \r
-               ((DAPL_EP *)p_err_rec->context)->qp_handle, \r
-               ((DAPL_EP *)p_err_rec->context)->qpn);\r
-\r
-       /*\r
-        * Verify handles EP, EVD, and hca_handle\r
-        */\r
-       if (DAPL_BAD_HANDLE (ep_ptr, DAPL_MAGIC_EP ) ||\r
-           DAPL_BAD_HANDLE (ep_ptr->param.connect_evd_handle, DAPL_MAGIC_EVD))\r
-       {\r
-               dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                               "--> DiQpAEC: invalid EP %p \n", ep_ptr);\r
-               return;\r
-       }\r
-       ia_ptr = ep_ptr->header.owner_ia;\r
-       evd_ptr = ia_ptr->async_error_evd;\r
-\r
-       if (DAPL_BAD_HANDLE (evd_ptr, DAPL_MAGIC_EVD) ||\r
-           ! (evd_ptr->evd_flags & DAT_EVD_ASYNC_FLAG))\r
-       {\r
-               dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                               "--> DiQpAEC: invalid EVD %p \n", evd_ptr);\r
-               return;\r
-       }\r
-       p_ca = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;\r
-       if (p_ca == NULL)\r
-       {\r
-               dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                               "--> DiQpAEC: can't find %s HCA\n", \r
-                               (ia_ptr->header.provider)->device_name);\r
-               return;\r
-       }\r
-\r
-       /* find QP error callback using ia_ptr for context */\r
-       evd_cb = dapli_find_evd_cb_by_context (ia_ptr, p_ca);\r
-       if ((evd_cb == NULL) || (evd_cb->pfn_async_qp_err_cb == NULL))\r
-       {\r
-               dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                       "--> DiQpAEC: no ERROR cb on p_ca %p found\n", p_ca);\r
-               return;\r
-       }\r
-\r
-       dapl_os_lock (&ep_ptr->header.lock);\r
-       ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECT_PENDING;\r
-       dapl_os_unlock (&ep_ptr->header.lock);\r
-\r
-       /* force disconnect, QP error state, to insure DTO's get flushed */\r
-       dapls_ib_disconnect ( ep_ptr, DAT_CLOSE_ABRUPT_FLAG );\r
-       \r
-       /* maps to dapl_evd_qp_async_error_callback(), context is EP */\r
-       evd_cb->pfn_async_qp_err_cb(    (ib_hca_handle_t)p_ca, \r
-                                    ep_ptr->qp_handle,\r
-                                       (ib_error_record_t*)&p_err_rec->code,\r
-                                    ep_ptr );\r
-}\r
-\r
-/*\r
- * dapls_ib_qp_alloc\r
- *\r
- * Alloc a QP\r
- *\r
- * Input:\r
- *        *ia_ptr                pointer to DAPL IA\r
- *        *ep_ptr                pointer to DAPL EP\r
- *        *ep_ctx_ptr            pointer to DAPL EP context\r
- *\r
- * Output:\r
- *         none\r
- *\r
- * Returns:\r
- *        DAT_SUCCESS\r
- *        DAT_INSUFFICIENT_RESOURCES\r
- *\r
- */\r
-DAT_RETURN\r
-dapls_ib_qp_alloc (\r
-        IN  DAPL_IA                *ia_ptr,\r
-        IN  DAPL_EP                *ep_ptr,\r
-       IN  DAPL_EP                *ep_ctx_ptr)\r
-{\r
-    DAT_EP_ATTR           *attr;\r
-    DAPL_EVD              *recv_evd_ptr, *request_evd_ptr;\r
-    DAT_RETURN            dat_status;\r
-    ib_api_status_t       ib_status;\r
-    ib_qp_create_t        qp_create;\r
-    ib_pd_handle_t        ib_pd_handle;\r
-    ib_cq_handle_t        cq_recv;\r
-    ib_cq_handle_t        cq_send;\r
-    dapl_ibal_ca_t        *p_ca;\r
-    dapl_ibal_port_t      *p_active_port;\r
-    ib_qp_attr_t          qp_attr;\r
-    dp_ib_cm_handle_t     cm_ptr;\r
-\r
-    attr = &ep_ptr->param.ep_attr;\r
-\r
-    dapl_os_assert ( ep_ptr->param.pz_handle != NULL );\r
-\r
-    ib_pd_handle    = ((DAPL_PZ *)ep_ptr->param.pz_handle)->pd_handle;\r
-    dapl_os_assert(ib_pd_handle);\r
-    recv_evd_ptr    = (DAPL_EVD *) ep_ptr->param.recv_evd_handle;\r
-    request_evd_ptr = (DAPL_EVD *) ep_ptr->param.request_evd_handle;\r
-    \r
-    cq_recv = IB_INVALID_HANDLE;\r
-    cq_send = IB_INVALID_HANDLE;\r
-\r
-    dapl_os_assert ( recv_evd_ptr != DAT_HANDLE_NULL );\r
-    {\r
-        cq_recv = (ib_cq_handle_t) recv_evd_ptr->ib_cq_handle;\r
-        \r
-        if ((cq_recv == IB_INVALID_HANDLE) && \r
-            ( 0 != (recv_evd_ptr->evd_flags & ~DAT_EVD_SOFTWARE_FLAG) ))\r
-        {\r
-            dat_status = dapls_ib_cq_late_alloc ( ib_pd_handle, recv_evd_ptr);\r
-            if (dat_status != DAT_SUCCESS)\r
-            {\r
-                dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                              "--> %s: failed to create CQ\n","DsQA");\r
-                return (dat_status);\r
-            }\r
-\r
-            dat_status = dapls_set_cq_notify (ia_ptr, recv_evd_ptr);\r
-\r
-            if (dat_status != DAT_SUCCESS)\r
-            {\r
-                dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                              "--> %s: failed to enable notify CQ\n","DsQA");\r
-                return (dat_status);\r
-            }\r
-        \r
-            cq_recv = (ib_cq_handle_t) recv_evd_ptr->ib_cq_handle;\r
-            dapl_dbg_log (DAPL_DBG_TYPE_EP, \r
-                          "--> DsQA: alloc_recv_CQ = %p\n", cq_recv); \r
-        \r
-        }\r
-    }\r
-\r
-    dapl_os_assert ( request_evd_ptr != DAT_HANDLE_NULL );\r
-    {\r
-        cq_send = (ib_cq_handle_t) request_evd_ptr->ib_cq_handle;\r
-        \r
-        if ((cq_send == IB_INVALID_HANDLE) && \r
-            ( 0 != (request_evd_ptr->evd_flags & ~DAT_EVD_SOFTWARE_FLAG) ))\r
-        {\r
-            dat_status = dapls_ib_cq_late_alloc (ib_pd_handle, request_evd_ptr);\r
-            if (dat_status != DAT_SUCCESS)\r
-            {\r
-                dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                              "--> %s: failed to create CQ\n","DsQA");\r
-                return (dat_status);\r
-            }\r
-\r
-            dat_status = dapls_set_cq_notify (ia_ptr, request_evd_ptr);\r
-\r
-            if (dat_status != DAT_SUCCESS)\r
-            {\r
-                dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                              "--> %s: failed to enable notify CQ\n","DsQA");\r
-                return (dat_status);\r
-            }\r
-\r
-            cq_send = (ib_cq_handle_t) request_evd_ptr->ib_cq_handle;\r
-            dapl_dbg_log (DAPL_DBG_TYPE_EP, \r
-                          "--> DsQA: alloc_send_CQ = %p\n", cq_send); \r
-        }\r
-    }\r
-\r
-    /*\r
-     * Get the CA structure\r
-     */\r
-    p_ca = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;\r
-\r
-    dapl_os_memzero (&qp_create, sizeof (qp_create));\r
-    qp_create.qp_type     = IB_QPT_RELIABLE_CONN;\r
-    qp_create.sq_depth    = attr->max_request_dtos;\r
-    qp_create.rq_depth    = attr->max_recv_dtos;\r
-    qp_create.sq_sge      = attr->max_recv_iov;\r
-    qp_create.rq_sge      = attr->max_request_iov;                       \r
-    qp_create.h_sq_cq     = cq_send;\r
-    qp_create.h_rq_cq     = cq_recv;\r
-    qp_create.sq_signaled = FALSE;\r
-\r
-    dapl_dbg_log (DAPL_DBG_TYPE_EP, \r
-                  "--> DsQA: sqd,iov=%d,%d rqd,iov=%d,%d\n", \r
-                  attr->max_request_dtos, attr->max_request_iov,\r
-                  attr->max_recv_dtos, attr->max_recv_iov); \r
-    \r
-    ib_status = ib_create_qp ( \r
-                       ib_pd_handle,\r
-                       &qp_create,\r
-                       (void *) ep_ctx_ptr /* context */,\r
-                       dapli_ib_qp_async_error_cb,\r
-                       &ep_ptr->qp_handle);\r
-\r
-    if (ib_status != IB_SUCCESS)\r
-    {\r
-       dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> DsQA: Create QP failed = %s\n",\r
-                      ib_get_err_str(ib_status));\r
-       return (DAT_INSUFFICIENT_RESOURCES);\r
-    }\r
-    /* EP-CM linking */\r
-    cm_ptr = ibal_cm_alloc();\r
-    if (!cm_ptr) \r
-    {\r
-       dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> DsQA: Create CM failed\n");\r
-       return (DAT_INSUFFICIENT_RESOURCES);\r
-    }\r
-    cm_ptr->ib_cm.h_qp = ep_ptr->qp_handle;\r
-    cm_ptr->ep = ep_ptr;\r
-    dapl_ep_link_cm(ep_ptr, cm_ptr); \r
-\r
-    dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsQA: EP=%p, tEVD=%p, rEVD=%p QP=%p\n",\r
-                  ep_ptr, ep_ptr->param.request_evd_handle,\r
-                  ep_ptr->param.recv_evd_handle,\r
-                  ep_ptr->qp_handle ); \r
-\r
-    ep_ptr->qp_state = IB_QPS_RESET;\r
-\r
-    p_active_port = dapli_ibal_get_port(p_ca,(uint8_t)ia_ptr->hca_ptr->port_num);\r
-\r
-    if (NULL == p_active_port)\r
-    {\r
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                      "--> DsQA: Port %d is not available = %d\n",\r
-                      ia_ptr->hca_ptr->port_num, __LINE__);\r
-        return (DAT_INVALID_STATE);\r
-    }\r
-\r
-    ib_status = dapls_modify_qp_state_to_init ( ep_ptr->qp_handle, \r
-                                               &ep_ptr->param.ep_attr,\r
-                                                p_active_port );\r
-\r
-    if ( ib_status != IB_SUCCESS )\r
-    {\r
-       dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                      "--> DsQA: Change QP state to INIT failed = %s\n",\r
-                      ib_get_err_str(ib_status));\r
-       return (DAT_INVALID_HANDLE);\r
-    }\r
-    ib_status = ib_query_qp ( ep_ptr->qp_handle, &qp_attr );\r
-\r
-    ep_ptr->qp_state = qp_attr.state;\r
-    ep_ptr->qpn = qp_attr.num;\r
-    \r
-    dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsQAQA: EP:%p new_QP %p state %s\n",\r
-                  ep_ptr,\r
-                  ep_ptr->qp_handle,\r
-                  ib_get_port_state_str(ep_ptr->qp_state));\r
-\r
-    return (DAT_SUCCESS);\r
-}\r
-\r
-\r
-/*\r
- * dapls_ib_qp_free\r
- *\r
- * Free a QP\r
- *\r
- * Input:\r
- *        *ia_ptr                pointer to IA structure\r
- *        *ep_ptr                pointer to EP structure\r
- *\r
- * Output:\r
- *         none\r
- *\r
- * Returns:\r
- *         none\r
- *\r
- */\r
-DAT_RETURN\r
-dapls_ib_qp_free (\r
-        IN  DAPL_IA                *ia_ptr,\r
-        IN  DAPL_EP                *ep_ptr )\r
-{\r
-\r
-       ib_qp_handle_t          qp_handle;\r
-       UNREFERENCED_PARAMETER(ia_ptr);\r
-\r
-       dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsQF: free %p, state %s\n", \r
-                      ep_ptr->qp_handle,\r
-                      ib_get_port_state_str(ep_ptr->qp_state));\r
-\r
-       if (( ep_ptr->qp_handle != IB_INVALID_HANDLE ) &&\r
-           ( ep_ptr->qp_state != DAPL_QP_STATE_UNATTACHED ))\r
-       {\r
-               qp_handle = ep_ptr->qp_handle;\r
-               ep_ptr->qp_handle = IB_INVALID_HANDLE;\r
-               ep_ptr->qp_state = DAPL_QP_STATE_UNATTACHED;\r
-               ib_destroy_qp ( qp_handle, NULL /* callback */);\r
-               dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsQF: freed QP %p\n",\r
-                               qp_handle ); \r
-       }\r
-\r
-    return DAT_SUCCESS;\r
-}\r
-\r
-\r
-/*\r
- * dapls_ib_qp_modify\r
- *\r
- * Set the QP to the parameters specified in an EP_PARAM\r
- *\r
- * We can't be sure what state the QP is in so we first obtain the state\r
- * from the driver. The EP_PARAM structure that is provided has been\r
- * sanitized such that only non-zero values are valid.\r
- *\r
- * Input:\r
- *        *ia_ptr                pointer to DAPL IA\r
- *        *ep_ptr                pointer to DAPL EP\r
- *        *ep_attr               pointer to DAT EP attribute\r
- *\r
- * Output:\r
- *         none\r
- *\r
- * Returns:\r
- *         DAT_SUCCESS\r
- *        DAT_INSUFFICIENT_RESOURCES\r
- *        DAT_INVALID_PARAMETER\r
- *\r
- */\r
-DAT_RETURN\r
-dapls_ib_qp_modify (\r
-        IN  DAPL_IA                        *ia_ptr,\r
-        IN  DAPL_EP                        *ep_ptr,\r
-        IN  DAT_EP_ATTR                    *ep_attr )\r
-{\r
-    ib_qp_attr_t                  qp_attr;\r
-    ib_api_status_t               ib_status;\r
-    ib_qp_handle_t                qp_handle;\r
-    ib_qp_state_t                 qp_state;\r
-    ib_qp_mod_t                   qp_mod;\r
-    ib_av_attr_t                  *p_av_attr;\r
-    ib_qp_opts_t                  *p_qp_opts;\r
-    uint32_t                      *p_sq_depth, *p_rq_depth;\r
-    DAT_BOOLEAN                   need_modify;\r
-    DAT_RETURN                    dat_status;\r
-\r
-    qp_handle     = ep_ptr->qp_handle;\r
-    need_modify   = DAT_FALSE;\r
-    dat_status    = DAT_SUCCESS;\r
-    if ( ia_ptr == NULL || ia_ptr->header.magic != DAPL_MAGIC_IA )\r
-    {\r
-       dat_status = DAT_INVALID_HANDLE;\r
-       goto bail;\r
-    }\r
-    /* \r
-     * Query the QP to get the current state.\r
-     */\r
-    ib_status = ib_query_qp ( qp_handle, &qp_attr );\r
-                       \r
-    if ( ib_status != IB_SUCCESS )\r
-    {\r
-       dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> DsIQM: Query QP failed = %s\n",\r
-                       ib_get_err_str(ib_status));\r
-        dat_status = DAT_INTERNAL_ERROR;\r
-        goto bail;\r
-    }\r
-\r
-    qp_state = qp_attr.state;\r
-\r
-    dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsIQM: modify qp state=%d\n",qp_state);\r
-    /*\r
-     * Check if we have the right qp_state or not\r
-     */\r
-    if ( (qp_state != IB_QPS_RTR ) && (qp_state != IB_QPS_RTS ) )\r
-    {\r
-       dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
-                      "--> DsIQM: postpone to modify qp to EP values later\n");\r
-        dat_status = DAT_SUCCESS;\r
-        goto bail;\r
-    }\r
-\r
-    dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));\r
-\r
-    if (qp_state == IB_QPS_RTR)\r
-    {\r
-        p_av_attr   = &qp_mod.state.rtr.primary_av;\r
-        p_qp_opts   = &qp_mod.state.rtr.opts;\r
-        p_sq_depth  = &qp_mod.state.rtr.sq_depth;\r
-        p_rq_depth  = &qp_mod.state.rtr.rq_depth;\r
-    }\r
-    else\r
-    {\r
-        /*\r
-        * RTS does not have primary_av field\r
-        */\r
-        p_av_attr   = &qp_mod.state.rts.alternate_av;\r
-        p_qp_opts   = &qp_mod.state.rts.opts;\r
-        p_sq_depth  = &qp_mod.state.rts.sq_depth;\r
-        p_rq_depth  = &qp_mod.state.rts.rq_depth;\r
-    }\r
-\r
-    if ( (ep_attr->max_recv_dtos > 0) &&\r
-               ((DAT_UINT32)ep_attr->max_recv_dtos != qp_attr.rq_depth) )\r
-    {\r
-       dapl_dbg_log (DAPL_DBG_TYPE_EP,"--> DsIQM: rq_depth modified (%d,%d)\n",\r
-                       qp_attr.rq_depth, ep_attr->max_recv_dtos);\r
-\r
-        *p_rq_depth = ep_attr->max_recv_dtos;\r
-        *p_qp_opts |= IB_MOD_QP_RQ_DEPTH;\r
-        need_modify = DAT_TRUE;\r
-    }\r
-\r
-    if ( (ep_attr->max_request_dtos > 0) &&\r
-               ((DAT_UINT32)ep_attr->max_request_dtos != qp_attr.sq_depth) ) \r
-    {\r
-       dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
-                       "--> DsIQM: sq_depth modified (%d,%d)\n",\r
-                       qp_attr.sq_depth, ep_attr->max_request_dtos);\r
-\r
-        *p_sq_depth = ep_attr->max_request_dtos;\r
-        *p_qp_opts |= IB_MOD_QP_SQ_DEPTH;\r
-        need_modify = DAT_TRUE;\r
-    }\r
-\r
-    qp_mod.req_state  = qp_state;\r
-\r
-    if ( need_modify == DAT_TRUE )\r
-    {\r
-       ib_status = ib_modify_qp (qp_handle, &qp_mod);\r
-        if ( ib_status != IB_SUCCESS)\r
-        {\r
-           dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: ib_status = %d\n",\r
-                          "DsIQM", ib_status);\r
-           dat_status = DAT_INTERNAL_ERROR;\r
-        }\r
-    }\r
-\r
-bail:\r
-\r
-    return dat_status;\r
-}\r
-\r
-\r
-ib_api_status_t \r
-dapls_modify_qp_state_to_error ( ib_qp_handle_t  qp_handle )\r
-{\r
-    ib_qp_mod_t      qp_mod;\r
-    ib_api_status_t  ib_status;\r
-\r
-    dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsIQM_Err: QP state change --> Err\n");\r
-\r
-    dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));\r
-\r
-    qp_mod.req_state  = IB_QPS_ERROR;\r
-\r
-    ib_status = ib_modify_qp (qp_handle, &qp_mod);\r
-\r
-    return (ib_status);\r
-}\r
-\r
-\r
-ib_api_status_t \r
-dapls_modify_qp_state_to_reset ( ib_qp_handle_t  qp_handle )\r
-{\r
-    ib_qp_mod_t      qp_mod;\r
-    ib_api_status_t  ib_status;\r
-\r
-    dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsIQM_RESET: QP state change\n");\r
-\r
-    dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));\r
-\r
-    qp_mod.req_state  = IB_QPS_RESET;\r
-\r
-    ib_status = ib_modify_qp (qp_handle, &qp_mod);\r
-\r
-    return (ib_status);\r
-}\r
-\r
-\r
-ib_api_status_t \r
-dapls_modify_qp_state_to_init (\r
-        IN    ib_qp_handle_t         qp_handle,\r
-        IN    DAT_EP_ATTR            *p_attr,\r
-        IN    dapl_ibal_port_t       *p_port )\r
-{\r
-    ib_qp_mod_t                   qp_mod;\r
-    ib_api_status_t               ib_status;\r
-\r
-    dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));\r
-\r
-    qp_mod.req_state               = IB_QPS_INIT;\r
-    qp_mod.state.init.primary_port = p_port->p_attr->port_num;\r
-    qp_mod.state.init.qkey         = DAPL_IBAL_QKEY;\r
-    qp_mod.state.init.pkey_index   = 0;\r
-    qp_mod.state.init.access_ctrl = IB_AC_LOCAL_WRITE |\r
-                                       IB_AC_RDMA_WRITE |\r
-                                       IB_AC_MW_BIND |\r
-                                       IB_AC_ATOMIC;\r
-    if ((p_attr->max_rdma_read_in > 0) || (p_attr->max_rdma_read_out > 0))\r
-    {\r
-       qp_mod.state.init.access_ctrl |= IB_AC_RDMA_READ;\r
-    }\r
-    ib_status = ib_modify_qp (qp_handle, &qp_mod);\r
-\r
-    dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsIQM_INIT: QP(%p) state change, %s\n",\r
-                  qp_handle, ib_get_err_str(ib_status));\r
-\r
-    return (ib_status);\r
-}\r
-\r
-\r
-ib_api_status_t \r
-dapls_modify_qp_state_to_rtr (\r
-        ib_qp_handle_t          qp_handle,\r
-        ib_net32_t              dest_qp,\r
-        ib_lid_t                dest_lid,\r
-        dapl_ibal_port_t        *p_port)\r
-{\r
-    ib_qp_mod_t                 qp_mod;\r
-    ib_api_status_t             ib_status;\r
-\r
-    dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));\r
-\r
-    qp_mod.req_state                        = IB_QPS_RTR;\r
-    qp_mod.state.rtr.rq_psn                 = DAPL_IBAL_START_PSN;\r
-    qp_mod.state.rtr.dest_qp                = dest_qp;\r
-    qp_mod.state.rtr.primary_av.port_num    = p_port->p_attr->port_num;\r
-    qp_mod.state.rtr.primary_av.sl          = 0;\r
-    qp_mod.state.rtr.primary_av.dlid        = dest_lid;\r
-    qp_mod.state.rtr.primary_av.grh_valid   = 0; /* FALSE */\r
-    qp_mod.state.rtr.primary_av.static_rate = IB_PATH_RECORD_RATE_10_GBS;\r
-    qp_mod.state.rtr.primary_av.path_bits   = 0;\r
-    qp_mod.state.rtr.primary_av.conn.path_mtu = p_port->p_attr->mtu;\r
-    qp_mod.state.rtr.primary_av.conn.local_ack_timeout = 7;\r
-    qp_mod.state.rtr.primary_av.conn.seq_err_retry_cnt = 7;\r
-    qp_mod.state.rtr.primary_av.conn.rnr_retry_cnt = IB_RNR_RETRY_CNT;\r
-    qp_mod.state.rtr.resp_res               = 4; // in-flight RDMAs\r
-    qp_mod.state.rtr.rnr_nak_timeout        = IB_RNR_NAK_TIMEOUT;\r
\r
-    ib_status = ib_modify_qp (qp_handle, &qp_mod);\r
-    \r
-    dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsIQM_RTR: QP(%p) state change %s\n",\r
-                  qp_handle, ib_get_err_str(ib_status));\r
-\r
-    return (ib_status);\r
-}\r
-\r
-ib_api_status_t \r
-dapls_modify_qp_state_to_rts ( ib_qp_handle_t  qp_handle )\r
-{\r
-    ib_qp_mod_t        qp_mod;\r
-    ib_api_status_t    ib_status;\r
-\r
-    dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));\r
-\r
-    qp_mod.req_state                   = IB_QPS_RTS;\r
-    qp_mod.state.rts.sq_psn            = DAPL_IBAL_START_PSN;\r
-    qp_mod.state.rts.retry_cnt         = 7;\r
-    qp_mod.state.rts.rnr_retry_cnt     = IB_RNR_RETRY_CNT;\r
-    qp_mod.state.rtr.rnr_nak_timeout   = IB_RNR_NAK_TIMEOUT;\r
-    qp_mod.state.rts.local_ack_timeout = 7;\r
-    qp_mod.state.rts.init_depth        = 4; \r
-\r
-    ib_status = ib_modify_qp (qp_handle, &qp_mod);\r
-\r
-    dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsIQM_RTS: QP(%p) state change %s\n",\r
-                  qp_handle, ib_get_err_str(ib_status));\r
-\r
-    return (ib_status);\r
-}\r
-\r
-\r
-/*\r
- * dapls_ib_reinit_ep\r
- *\r
- * Move the QP to INIT state again.\r
- *\r
- * Input:\r
- *     ep_ptr          DAPL_EP\r
- *\r
- * Output:\r
- *     none\r
- *\r
- * Returns:\r
- *     void\r
- *\r
- */\r
-void\r
-dapls_ib_reinit_ep ( IN DAPL_EP  *ep_ptr )\r
-{\r
-    DAPL_IA                  *ia_ptr;\r
-    ib_api_status_t          ib_status;\r
-    dapl_ibal_ca_t           *p_ca;\r
-    dapl_ibal_port_t         *p_active_port;\r
-       \r
-    dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
-                  "--> DsIQM_REINIT: EP(%p) QP(%p) state change\n", \r
-                  ep_ptr, ep_ptr->qp_handle );\r
-\r
-    if ( ep_ptr->param.ep_state != DAT_EP_STATE_DISCONNECTED )\r
-    {\r
-       dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> DsIRE: EP invalid state(%d)\n",\r
-                      ep_ptr->param.ep_state);\r
-       return /*DAT_INVALID_STATE*/;\r
-    }\r
-\r
-    ia_ptr = ep_ptr->header.owner_ia;\r
-\r
-    /* Re-create QP if cleaned up, alloc will return init state */\r
-    if ( ep_ptr->qp_handle == IB_INVALID_HANDLE )\r
-    {\r
-        dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
-                      "--> DsIRE: !EP(%p)->qp_handle, re-create QP\n",ep_ptr);\r
-        ib_status = dapls_ib_qp_alloc ( ia_ptr, ep_ptr, ep_ptr );\r
-        if ( ib_status != IB_SUCCESS )\r
-        {\r
-            dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                      "--> DsIRE: failed to move qp to RESET status = %s\n", \r
-                      ib_get_err_str(ib_status));\r
-        }\r
-        return /*ib_status*/;\r
-    }\r
-\r
-    ib_status = dapls_modify_qp_state_to_reset (ep_ptr->qp_handle);\r
-\r
-    if ( ib_status != IB_SUCCESS )\r
-    {\r
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                      "--> DsIRE: failed to move qp to RESET status = %s\n", \r
-                      ib_get_err_str(ib_status));\r
-        return /*DAT_INTERNAL_ERROR*/;\r
-    }\r
-\r
-    ep_ptr->qp_state = IB_QPS_RESET;\r
-\r
-    p_ca   = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;\r
-    p_active_port = dapli_ibal_get_port ( p_ca,\r
-                                          (uint8_t)ia_ptr->hca_ptr->port_num );\r
-    if (NULL == p_active_port)\r
-    {\r
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                     "--> DsIRE: Port %d is not available = %d\n",\r
-                     ia_ptr->hca_ptr->port_num, __LINE__);\r
-        return /*DAT_INTERNAL_ERROR*/;\r
-    }\r
-\r
-       /* May fail if QP still RESET and in timewait, keep in reset state */\r
-    ib_status = dapls_modify_qp_state_to_init ( ep_ptr->qp_handle,\r
-                                                &ep_ptr->param.ep_attr,\r
-                                                p_active_port);\r
-    if ( ib_status != IB_SUCCESS )\r
-    {\r
-        ep_ptr->qp_state = IB_QPS_RESET;\r
-\r
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
-                      "--> DsIRE: failed to move qp to INIT status %s\n", \r
-                      ib_get_err_str(ib_status));\r
-        return /*DAT_INTERNAL_ERROR*/;\r
-    }\r
-    ep_ptr->qp_state = IB_QPS_INIT;\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
-\r
+
+/*
+ * Copyright (c) 2005-2007 Intel Corporation. All rights reserved.
+ * Copyright (c) 2002, Network Appliance, Inc. All rights reserved. 
+ * 
+ * This Software is licensed under the terms of the "Common Public
+ * License" a copy of which is in the file LICENSE.txt in the root
+ * directory. The license is also available from the Open Source
+ * Initiative, see http://www.opensource.org/licenses/cpl.php.
+ *
+ */
+
+/**********************************************************************
+ * 
+ * MODULE: dapl_ibal_qp.c
+ *
+ * PURPOSE: IB QP routines  for access to IBAL APIs
+ *
+ * $Id: dapl_ibal_qp.c 33 2005-07-11 19:51:17Z ftillier $
+ *
+ **********************************************************************/
+
+#include "dapl.h"
+#include "dapl_adapter_util.h"
+#include "dapl_evd_util.h"
+#include "dapl_ibal_util.h"
+#include "dapl_ep_util.h"
+
+#define DAPL_IBAL_QKEY              0
+#define DAPL_IBAL_START_PSN         0
+
+extern DAT_RETURN
+dapls_ib_cq_late_alloc ( IN  ib_pd_handle_t        pd_handle,
+                         IN  DAPL_EVD              *evd_ptr );
+
+static void
+dapli_ib_qp_async_error_cb( IN  ib_async_event_rec_t* p_err_rec )
+{
+       DAPL_EP                 *ep_ptr = (DAPL_EP *)p_err_rec->context;
+       DAPL_EVD                *evd_ptr;
+       DAPL_IA                 *ia_ptr;
+       dapl_ibal_ca_t          *p_ca;
+        dapl_ibal_evd_cb_t     *evd_cb;
+
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DiQpAEC QP event %s qp ctx %p\n", 
+               ib_get_async_event_str(p_err_rec->code), p_err_rec->context);
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DiQpAEC qp_handle %p qpn %u\n", 
+               ((DAPL_EP *)p_err_rec->context)->qp_handle, 
+               ((DAPL_EP *)p_err_rec->context)->qpn);
+
+       /*
+        * Verify handles EP, EVD, and hca_handle
+        */
+       if (DAPL_BAD_HANDLE (ep_ptr, DAPL_MAGIC_EP ) ||
+           DAPL_BAD_HANDLE (ep_ptr->param.connect_evd_handle, DAPL_MAGIC_EVD))
+       {
+               dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                               "--> DiQpAEC: invalid EP %p \n", ep_ptr);
+               return;
+       }
+       ia_ptr = ep_ptr->header.owner_ia;
+       evd_ptr = ia_ptr->async_error_evd;
+
+       if (DAPL_BAD_HANDLE (evd_ptr, DAPL_MAGIC_EVD) ||
+           ! (evd_ptr->evd_flags & DAT_EVD_ASYNC_FLAG))
+       {
+               dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                               "--> DiQpAEC: invalid EVD %p \n", evd_ptr);
+               return;
+       }
+       p_ca = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;
+       if (p_ca == NULL)
+       {
+               dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                               "--> DiQpAEC: can't find %s HCA\n", 
+                               (ia_ptr->header.provider)->device_name);
+               return;
+       }
+
+       /* find QP error callback using ia_ptr for context */
+       evd_cb = dapli_find_evd_cb_by_context (ia_ptr, p_ca);
+       if ((evd_cb == NULL) || (evd_cb->pfn_async_qp_err_cb == NULL))
+       {
+               dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                       "--> DiQpAEC: no ERROR cb on p_ca %p found\n", p_ca);
+               return;
+       }
+
+       dapl_os_lock (&ep_ptr->header.lock);
+       ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECT_PENDING;
+       dapl_os_unlock (&ep_ptr->header.lock);
+
+       /* force disconnect, QP error state, to insure DTO's get flushed */
+       dapls_ib_disconnect ( ep_ptr, DAT_CLOSE_ABRUPT_FLAG );
+       
+       /* maps to dapl_evd_qp_async_error_callback(), context is EP */
+       evd_cb->pfn_async_qp_err_cb(    (ib_hca_handle_t)p_ca, 
+                                    ep_ptr->qp_handle,
+                                       (ib_error_record_t*)&p_err_rec->code,
+                                    ep_ptr );
+}
+
+/*
+ * dapls_ib_qp_alloc
+ *
+ * Alloc a QP
+ *
+ * Input:
+ *        *ia_ptr                pointer to DAPL IA
+ *        *ep_ptr                pointer to DAPL EP
+ *        *ep_ctx_ptr            pointer to DAPL EP context
+ *
+ * Output:
+ *         none
+ *
+ * Returns:
+ *        DAT_SUCCESS
+ *        DAT_INSUFFICIENT_RESOURCES
+ *
+ */
+DAT_RETURN
+dapls_ib_qp_alloc (
+        IN  DAPL_IA                *ia_ptr,
+        IN  DAPL_EP                *ep_ptr,
+       IN  DAPL_EP                *ep_ctx_ptr)
+{
+    DAT_EP_ATTR           *attr;
+    DAPL_EVD              *recv_evd_ptr, *request_evd_ptr;
+    DAT_RETURN            dat_status;
+    ib_api_status_t       ib_status;
+    ib_qp_create_t        qp_create;
+    ib_pd_handle_t        ib_pd_handle;
+    ib_cq_handle_t        cq_recv;
+    ib_cq_handle_t        cq_send;
+    dapl_ibal_ca_t        *p_ca;
+    dapl_ibal_port_t      *p_active_port;
+    ib_qp_attr_t          qp_attr;
+    dp_ib_cm_handle_t     cm_ptr;
+
+    attr = &ep_ptr->param.ep_attr;
+
+    dapl_os_assert ( ep_ptr->param.pz_handle != NULL );
+
+    ib_pd_handle    = ((DAPL_PZ *)ep_ptr->param.pz_handle)->pd_handle;
+    dapl_os_assert(ib_pd_handle);
+    recv_evd_ptr    = (DAPL_EVD *) ep_ptr->param.recv_evd_handle;
+    request_evd_ptr = (DAPL_EVD *) ep_ptr->param.request_evd_handle;
+    
+    cq_recv = IB_INVALID_HANDLE;
+    cq_send = IB_INVALID_HANDLE;
+
+    dapl_os_assert ( recv_evd_ptr != DAT_HANDLE_NULL );
+    {
+        cq_recv = (ib_cq_handle_t) recv_evd_ptr->ib_cq_handle;
+        
+        if ((cq_recv == IB_INVALID_HANDLE) && 
+            ( 0 != (recv_evd_ptr->evd_flags & ~DAT_EVD_SOFTWARE_FLAG) ))
+        {
+            dat_status = dapls_ib_cq_late_alloc ( ib_pd_handle, recv_evd_ptr);
+            if (dat_status != DAT_SUCCESS)
+            {
+                dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                              "--> %s: failed to create CQ\n","DsQA");
+                return (dat_status);
+            }
+
+            dat_status = dapls_set_cq_notify (ia_ptr, recv_evd_ptr);
+
+            if (dat_status != DAT_SUCCESS)
+            {
+                dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                              "--> %s: failed to enable notify CQ\n","DsQA");
+                return (dat_status);
+            }
+        
+            cq_recv = (ib_cq_handle_t) recv_evd_ptr->ib_cq_handle;
+            dapl_dbg_log (DAPL_DBG_TYPE_EP, 
+                          "--> DsQA: alloc_recv_CQ = %p\n", cq_recv); 
+        
+        }
+    }
+
+    dapl_os_assert ( request_evd_ptr != DAT_HANDLE_NULL );
+    {
+        cq_send = (ib_cq_handle_t) request_evd_ptr->ib_cq_handle;
+        
+        if ((cq_send == IB_INVALID_HANDLE) && 
+            ( 0 != (request_evd_ptr->evd_flags & ~DAT_EVD_SOFTWARE_FLAG) ))
+        {
+            dat_status = dapls_ib_cq_late_alloc (ib_pd_handle, request_evd_ptr);
+            if (dat_status != DAT_SUCCESS)
+            {
+                dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                              "--> %s: failed to create CQ\n","DsQA");
+                return (dat_status);
+            }
+
+            dat_status = dapls_set_cq_notify (ia_ptr, request_evd_ptr);
+
+            if (dat_status != DAT_SUCCESS)
+            {
+                dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                              "--> %s: failed to enable notify CQ\n","DsQA");
+                return (dat_status);
+            }
+
+            cq_send = (ib_cq_handle_t) request_evd_ptr->ib_cq_handle;
+            dapl_dbg_log (DAPL_DBG_TYPE_EP, 
+                          "--> DsQA: alloc_send_CQ = %p\n", cq_send); 
+        }
+    }
+
+    /*
+     * Get the CA structure
+     */
+    p_ca = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;
+
+    dapl_os_memzero (&qp_create, sizeof (qp_create));
+    qp_create.qp_type     = IB_QPT_RELIABLE_CONN;
+    qp_create.sq_depth    = attr->max_request_dtos;
+    qp_create.rq_depth    = attr->max_recv_dtos;
+    qp_create.sq_sge      = attr->max_recv_iov;
+    qp_create.rq_sge      = attr->max_request_iov;                       
+    qp_create.h_sq_cq     = cq_send;
+    qp_create.h_rq_cq     = cq_recv;
+    qp_create.sq_signaled = FALSE;
+
+    dapl_dbg_log (DAPL_DBG_TYPE_EP, 
+                  "--> DsQA: sqd,iov=%d,%d rqd,iov=%d,%d\n", 
+                  attr->max_request_dtos, attr->max_request_iov,
+                  attr->max_recv_dtos, attr->max_recv_iov); 
+    
+    ib_status = ib_create_qp ( 
+                       ib_pd_handle,
+                       &qp_create,
+                       (void *) ep_ctx_ptr /* context */,
+                       dapli_ib_qp_async_error_cb,
+                       &ep_ptr->qp_handle);
+
+    if (ib_status != IB_SUCCESS)
+    {
+       dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> DsQA: Create QP failed = %s\n",
+                      ib_get_err_str(ib_status));
+       return (DAT_INSUFFICIENT_RESOURCES);
+    }
+    /* EP-CM linking */
+    cm_ptr = ibal_cm_alloc();
+    if (!cm_ptr) 
+    {
+       dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> DsQA: Create CM failed\n");
+       return (DAT_INSUFFICIENT_RESOURCES);
+    }
+    cm_ptr->ib_cm.h_qp = ep_ptr->qp_handle;
+    cm_ptr->ep = ep_ptr;
+    dapl_ep_link_cm(ep_ptr, cm_ptr); 
+
+    dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsQA: EP=%p, tEVD=%p, rEVD=%p QP=%p\n",
+                  ep_ptr, ep_ptr->param.request_evd_handle,
+                  ep_ptr->param.recv_evd_handle,
+                  ep_ptr->qp_handle ); 
+
+    ep_ptr->qp_state = IB_QPS_RESET;
+
+    p_active_port = dapli_ibal_get_port(p_ca,(uint8_t)ia_ptr->hca_ptr->port_num);
+
+    if (NULL == p_active_port)
+    {
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                      "--> DsQA: Port %d is not available = %d\n",
+                      ia_ptr->hca_ptr->port_num, __LINE__);
+        return (DAT_INVALID_STATE);
+    }
+
+    ib_status = dapls_modify_qp_state_to_init ( ep_ptr->qp_handle, 
+                                               &ep_ptr->param.ep_attr,
+                                                p_active_port );
+
+    if ( ib_status != IB_SUCCESS )
+    {
+       dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                      "--> DsQA: Change QP state to INIT failed = %s\n",
+                      ib_get_err_str(ib_status));
+       return (DAT_INVALID_HANDLE);
+    }
+    ib_status = ib_query_qp ( ep_ptr->qp_handle, &qp_attr );
+
+    ep_ptr->qp_state = qp_attr.state;
+    ep_ptr->qpn = qp_attr.num;
+    
+    dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsQAQA: EP:%p new_QP %p state %s\n",
+                  ep_ptr,
+                  ep_ptr->qp_handle,
+                  ib_get_port_state_str(ep_ptr->qp_state));
+
+    return (DAT_SUCCESS);
+}
+
+
+/*
+ * dapls_ib_qp_free
+ *
+ * Free a QP
+ *
+ * Input:
+ *        *ia_ptr                pointer to IA structure
+ *        *ep_ptr                pointer to EP structure
+ *
+ * Output:
+ *         none
+ *
+ * Returns:
+ *         none
+ *
+ */
+DAT_RETURN
+dapls_ib_qp_free (
+        IN  DAPL_IA                *ia_ptr,
+        IN  DAPL_EP                *ep_ptr )
+{
+
+       ib_qp_handle_t          qp_handle;
+       UNREFERENCED_PARAMETER(ia_ptr);
+
+       dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsQF: free %p, state %s\n", 
+                      ep_ptr->qp_handle,
+                      ib_get_port_state_str(ep_ptr->qp_state));
+
+       if (( ep_ptr->qp_handle != IB_INVALID_HANDLE ) &&
+           ( ep_ptr->qp_state != DAPL_QP_STATE_UNATTACHED ))
+       {
+               qp_handle = ep_ptr->qp_handle;
+               ep_ptr->qp_handle = IB_INVALID_HANDLE;
+               ep_ptr->qp_state = DAPL_QP_STATE_UNATTACHED;
+               ib_destroy_qp ( qp_handle, NULL /* callback */);
+               dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsQF: freed QP %p\n",
+                               qp_handle ); 
+       }
+
+    return DAT_SUCCESS;
+}
+
+
+/*
+ * dapls_ib_qp_modify
+ *
+ * Set the QP to the parameters specified in an EP_PARAM
+ *
+ * We can't be sure what state the QP is in so we first obtain the state
+ * from the driver. The EP_PARAM structure that is provided has been
+ * sanitized such that only non-zero values are valid.
+ *
+ * Input:
+ *        *ia_ptr                pointer to DAPL IA
+ *        *ep_ptr                pointer to DAPL EP
+ *        *ep_attr               pointer to DAT EP attribute
+ *
+ * Output:
+ *         none
+ *
+ * Returns:
+ *         DAT_SUCCESS
+ *        DAT_INSUFFICIENT_RESOURCES
+ *        DAT_INVALID_PARAMETER
+ *
+ */
+DAT_RETURN
+dapls_ib_qp_modify (
+        IN  DAPL_IA                        *ia_ptr,
+        IN  DAPL_EP                        *ep_ptr,
+        IN  DAT_EP_ATTR                    *ep_attr )
+{
+    ib_qp_attr_t                  qp_attr;
+    ib_api_status_t               ib_status;
+    ib_qp_handle_t                qp_handle;
+    ib_qp_state_t                 qp_state;
+    ib_qp_mod_t                   qp_mod;
+    ib_av_attr_t                  *p_av_attr;
+    ib_qp_opts_t                  *p_qp_opts;
+    uint32_t                      *p_sq_depth, *p_rq_depth;
+    DAT_BOOLEAN                   need_modify;
+    DAT_RETURN                    dat_status;
+
+    qp_handle     = ep_ptr->qp_handle;
+    need_modify   = DAT_FALSE;
+    dat_status    = DAT_SUCCESS;
+    if ( ia_ptr == NULL || ia_ptr->header.magic != DAPL_MAGIC_IA )
+    {
+       dat_status = DAT_INVALID_HANDLE;
+       goto bail;
+    }
+    /* 
+     * Query the QP to get the current state.
+     */
+    ib_status = ib_query_qp ( qp_handle, &qp_attr );
+                       
+    if ( ib_status != IB_SUCCESS )
+    {
+       dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> DsIQM: Query QP failed = %s\n",
+                       ib_get_err_str(ib_status));
+        dat_status = DAT_INTERNAL_ERROR;
+        goto bail;
+    }
+
+    qp_state = qp_attr.state;
+
+    dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsIQM: modify qp state=%d\n",qp_state);
+    /*
+     * Check if we have the right qp_state or not
+     */
+    if ( (qp_state != IB_QPS_RTR ) && (qp_state != IB_QPS_RTS ) )
+    {
+       dapl_dbg_log (DAPL_DBG_TYPE_EP,
+                      "--> DsIQM: postpone to modify qp to EP values later\n");
+        dat_status = DAT_SUCCESS;
+        goto bail;
+    }
+
+    dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));
+
+    if (qp_state == IB_QPS_RTR)
+    {
+        p_av_attr   = &qp_mod.state.rtr.primary_av;
+        p_qp_opts   = &qp_mod.state.rtr.opts;
+        p_sq_depth  = &qp_mod.state.rtr.sq_depth;
+        p_rq_depth  = &qp_mod.state.rtr.rq_depth;
+    }
+    else
+    {
+        /*
+        * RTS does not have primary_av field
+        */
+        p_av_attr   = &qp_mod.state.rts.alternate_av;
+        p_qp_opts   = &qp_mod.state.rts.opts;
+        p_sq_depth  = &qp_mod.state.rts.sq_depth;
+        p_rq_depth  = &qp_mod.state.rts.rq_depth;
+    }
+
+    if ( (ep_attr->max_recv_dtos > 0) &&
+               ((DAT_UINT32)ep_attr->max_recv_dtos != qp_attr.rq_depth) )
+    {
+       dapl_dbg_log (DAPL_DBG_TYPE_EP,"--> DsIQM: rq_depth modified (%d,%d)\n",
+                       qp_attr.rq_depth, ep_attr->max_recv_dtos);
+
+        *p_rq_depth = ep_attr->max_recv_dtos;
+        *p_qp_opts |= IB_MOD_QP_RQ_DEPTH;
+        need_modify = DAT_TRUE;
+    }
+
+    if ( (ep_attr->max_request_dtos > 0) &&
+               ((DAT_UINT32)ep_attr->max_request_dtos != qp_attr.sq_depth) ) 
+    {
+       dapl_dbg_log (DAPL_DBG_TYPE_EP,
+                       "--> DsIQM: sq_depth modified (%d,%d)\n",
+                       qp_attr.sq_depth, ep_attr->max_request_dtos);
+
+        *p_sq_depth = ep_attr->max_request_dtos;
+        *p_qp_opts |= IB_MOD_QP_SQ_DEPTH;
+        need_modify = DAT_TRUE;
+    }
+
+    qp_mod.req_state  = qp_state;
+
+    if ( need_modify == DAT_TRUE )
+    {
+       ib_status = ib_modify_qp (qp_handle, &qp_mod);
+        if ( ib_status != IB_SUCCESS)
+        {
+           dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: ib_status = %d\n",
+                          "DsIQM", ib_status);
+           dat_status = DAT_INTERNAL_ERROR;
+        }
+    }
+
+bail:
+
+    return dat_status;
+}
+
+
+ib_api_status_t 
+dapls_modify_qp_state_to_error ( ib_qp_handle_t  qp_handle )
+{
+    ib_qp_mod_t      qp_mod;
+    ib_api_status_t  ib_status;
+
+    dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsIQM_Err: QP state change --> Err\n");
+
+    dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));
+
+    qp_mod.req_state  = IB_QPS_ERROR;
+
+    ib_status = ib_modify_qp (qp_handle, &qp_mod);
+
+    return (ib_status);
+}
+
+
+ib_api_status_t 
+dapls_modify_qp_state_to_reset ( ib_qp_handle_t  qp_handle )
+{
+    ib_qp_mod_t      qp_mod;
+    ib_api_status_t  ib_status;
+
+    dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsIQM_RESET: QP state change\n");
+
+    dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));
+
+    qp_mod.req_state  = IB_QPS_RESET;
+
+    ib_status = ib_modify_qp (qp_handle, &qp_mod);
+
+    return (ib_status);
+}
+
+
+ib_api_status_t 
+dapls_modify_qp_state_to_init (
+        IN    ib_qp_handle_t         qp_handle,
+        IN    DAT_EP_ATTR            *p_attr,
+        IN    dapl_ibal_port_t       *p_port )
+{
+    ib_qp_mod_t                   qp_mod;
+    ib_api_status_t               ib_status;
+
+    dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));
+
+    qp_mod.req_state               = IB_QPS_INIT;
+    qp_mod.state.init.primary_port = p_port->p_attr->port_num;
+    qp_mod.state.init.qkey         = DAPL_IBAL_QKEY;
+    qp_mod.state.init.pkey_index   = 0;
+    qp_mod.state.init.access_ctrl = IB_AC_LOCAL_WRITE |
+                                       IB_AC_RDMA_WRITE |
+                                       IB_AC_MW_BIND |
+                                       IB_AC_ATOMIC;
+    if ((p_attr->max_rdma_read_in > 0) || (p_attr->max_rdma_read_out > 0))
+    {
+       qp_mod.state.init.access_ctrl |= IB_AC_RDMA_READ;
+    }
+    ib_status = ib_modify_qp (qp_handle, &qp_mod);
+
+    dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsIQM_INIT: QP(%p) state change, %s\n",
+                  qp_handle, ib_get_err_str(ib_status));
+
+    return (ib_status);
+}
+
+
+ib_api_status_t 
+dapls_modify_qp_state_to_rtr (
+        ib_qp_handle_t          qp_handle,
+        ib_net32_t              dest_qp,
+        ib_lid_t                dest_lid,
+        dapl_ibal_port_t        *p_port)
+{
+    ib_qp_mod_t                 qp_mod;
+    ib_api_status_t             ib_status;
+
+    dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));
+
+    qp_mod.req_state                        = IB_QPS_RTR;
+    qp_mod.state.rtr.rq_psn                 = DAPL_IBAL_START_PSN;
+    qp_mod.state.rtr.dest_qp                = dest_qp;
+    qp_mod.state.rtr.primary_av.port_num    = p_port->p_attr->port_num;
+    qp_mod.state.rtr.primary_av.sl          = 0;
+    qp_mod.state.rtr.primary_av.dlid        = dest_lid;
+    qp_mod.state.rtr.primary_av.grh_valid   = 0; /* FALSE */
+    qp_mod.state.rtr.primary_av.static_rate = IB_PATH_RECORD_RATE_10_GBS;
+    qp_mod.state.rtr.primary_av.path_bits   = 0;
+    qp_mod.state.rtr.primary_av.conn.path_mtu = p_port->p_attr->mtu;
+    qp_mod.state.rtr.primary_av.conn.local_ack_timeout = 7;
+    qp_mod.state.rtr.primary_av.conn.seq_err_retry_cnt = 7;
+    qp_mod.state.rtr.primary_av.conn.rnr_retry_cnt = IB_RNR_RETRY_CNT;
+    qp_mod.state.rtr.resp_res               = 4; // in-flight RDMAs
+    qp_mod.state.rtr.rnr_nak_timeout        = IB_RNR_NAK_TIMEOUT;
+    ib_status = ib_modify_qp (qp_handle, &qp_mod);
+    
+    dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsIQM_RTR: QP(%p) state change %s\n",
+                  qp_handle, ib_get_err_str(ib_status));
+
+    return (ib_status);
+}
+
+ib_api_status_t 
+dapls_modify_qp_state_to_rts ( ib_qp_handle_t  qp_handle )
+{
+    ib_qp_mod_t        qp_mod;
+    ib_api_status_t    ib_status;
+
+    dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));
+
+    qp_mod.req_state                   = IB_QPS_RTS;
+    qp_mod.state.rts.sq_psn            = DAPL_IBAL_START_PSN;
+    qp_mod.state.rts.retry_cnt         = 7;
+    qp_mod.state.rts.rnr_retry_cnt     = IB_RNR_RETRY_CNT;
+    qp_mod.state.rtr.rnr_nak_timeout   = IB_RNR_NAK_TIMEOUT;
+    qp_mod.state.rts.local_ack_timeout = 7;
+    qp_mod.state.rts.init_depth        = 4; 
+
+    ib_status = ib_modify_qp (qp_handle, &qp_mod);
+
+    dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsIQM_RTS: QP(%p) state change %s\n",
+                  qp_handle, ib_get_err_str(ib_status));
+
+    return (ib_status);
+}
+
+
+/*
+ * dapls_ib_reinit_ep
+ *
+ * Move the QP to INIT state again.
+ *
+ * Input:
+ *     ep_ptr          DAPL_EP
+ *
+ * Output:
+ *     none
+ *
+ * Returns:
+ *     void
+ *
+ */
+void
+dapls_ib_reinit_ep ( IN DAPL_EP  *ep_ptr )
+{
+    DAPL_IA                  *ia_ptr;
+    ib_api_status_t          ib_status;
+    dapl_ibal_ca_t           *p_ca;
+    dapl_ibal_port_t         *p_active_port;
+       
+    dapl_dbg_log (DAPL_DBG_TYPE_EP,
+                  "--> DsIQM_REINIT: EP(%p) QP(%p) state change\n", 
+                  ep_ptr, ep_ptr->qp_handle );
+
+    if ( ep_ptr->param.ep_state != DAT_EP_STATE_DISCONNECTED )
+    {
+       dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> DsIRE: EP invalid state(%d)\n",
+                      ep_ptr->param.ep_state);
+       return /*DAT_INVALID_STATE*/;
+    }
+
+    ia_ptr = ep_ptr->header.owner_ia;
+
+    /* Re-create QP if cleaned up, alloc will return init state */
+    if ( ep_ptr->qp_handle == IB_INVALID_HANDLE )
+    {
+        dapl_dbg_log (DAPL_DBG_TYPE_EP,
+                      "--> DsIRE: !EP(%p)->qp_handle, re-create QP\n",ep_ptr);
+        ib_status = dapls_ib_qp_alloc ( ia_ptr, ep_ptr, ep_ptr );
+        if ( ib_status != IB_SUCCESS )
+        {
+            dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                      "--> DsIRE: failed to move qp to RESET status = %s\n", 
+                      ib_get_err_str(ib_status));
+        }
+        return /*ib_status*/;
+    }
+
+    ib_status = dapls_modify_qp_state_to_reset (ep_ptr->qp_handle);
+
+    if ( ib_status != IB_SUCCESS )
+    {
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                      "--> DsIRE: failed to move qp to RESET status = %s\n", 
+                      ib_get_err_str(ib_status));
+        return /*DAT_INTERNAL_ERROR*/;
+    }
+
+    ep_ptr->qp_state = IB_QPS_RESET;
+
+    p_ca   = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;
+    p_active_port = dapli_ibal_get_port ( p_ca,
+                                          (uint8_t)ia_ptr->hca_ptr->port_num );
+    if (NULL == p_active_port)
+    {
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                     "--> DsIRE: Port %d is not available = %d\n",
+                     ia_ptr->hca_ptr->port_num, __LINE__);
+        return /*DAT_INTERNAL_ERROR*/;
+    }
+
+       /* May fail if QP still RESET and in timewait, keep in reset state */
+    ib_status = dapls_modify_qp_state_to_init ( ep_ptr->qp_handle,
+                                                &ep_ptr->param.ep_attr,
+                                                p_active_port);
+    if ( ib_status != IB_SUCCESS )
+    {
+        ep_ptr->qp_state = IB_QPS_RESET;
+
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+                      "--> DsIRE: failed to move qp to INIT status %s\n", 
+                      ib_get_err_str(ib_status));
+        return /*DAT_INTERNAL_ERROR*/;
+    }
+    ep_ptr->qp_state = IB_QPS_INIT;
+}
+
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 8
+ * End:
+ */
+
index d5d6b4c4478f31ad8821b164e6f1ebb67de408b0..e28bdbe47e47508b29a95c2729eeb30cf79193da 100644 (file)
-\r
-/*\r
- * Copyright (c) 2005-2007 Intel Corporation. All rights reserved.\r
- * Copyright (c) 2002, Network Appliance, Inc. All rights reserved. \r
- * \r
- * This Software is licensed under the terms of the "Common Public\r
- * License" a copy of which is in the file LICENSE.txt in the root\r
- * directory. The license is also available from the Open Source\r
- * Initiative, see http://www.opensource.org/licenses/cpl.php.\r
- *\r
- */\r
-\r
-/**********************************************************************\r
- * \r
- * MODULE: dapl_ibal_util.h\r
- *\r
- * PURPOSE: Utility defs & routines for access to openib-windows IBAL APIs\r
- *\r
- * $Id: dapl_ibal_util.h 33 2005-07-11 19:51:17Z ftillier $\r
- *\r
- **********************************************************************/\r
-\r
-#ifndef _DAPL_IBAL_UTIL_H_\r
-#define _DAPL_IBAL_UTIL_H_\r
-\r
-#include <iba/ib_al.h>\r
-#include <complib/cl_spinlock.h>\r
-#include <complib/cl_qlist.h>\r
-#include <complib/cl_atomic.h>\r
-\r
-#ifdef DAT_EXTENSIONS\r
-#include <dat2\dat_ib_extensions.h>\r
-#endif\r
-\r
-/*\r
- * Typedefs to map IBAL types to more generic 'ib' types\r
- */\r
-#ifdef SOCK_CM\r
-typedef  struct ib_cm_handle           *dp_ib_cm_handle_t;\r
-typedef  struct ib_cm_handle           *ib_cm_srvc_handle_t;\r
-#else\r
-\r
-/* EP-CM linking requires list_entry, protected ref counting */\r
-typedef struct dapl_ibal_cm\r
-{ \r
-       struct dapl_llist_entry list_entry;\r
-       DAPL_OS_LOCK            lock;\r
-       int                     ref_count;\r
-       DAT_SOCK_ADDR6          dst_ip_addr; \r
-       ib_cm_handle_t          ib_cm;  /* h_al, h_qp, cid */\r
-       DAPL_EP                 *ep;\r
-\r
-} dapl_ibal_cm_t;\r
-\r
-typedef  dapl_ibal_cm_t                *dp_ib_cm_handle_t;\r
-typedef  ib_listen_handle_t            ib_cm_srvc_handle_t;\r
-\r
-/* EP-CM linking prototypes */\r
-extern void dapls_cm_acquire(dp_ib_cm_handle_t cm_ptr);\r
-extern void dapls_cm_release(dp_ib_cm_handle_t cm_ptr);\r
-extern void dapls_cm_free(dp_ib_cm_handle_t cm_ptr);\r
-extern dp_ib_cm_handle_t ibal_cm_alloc(void);\r
-\r
-#endif\r
-\r
-typedef  ib_net64_t                    IB_HCA_NAME;\r
-typedef  ib_ca_handle_t                ib_hca_handle_t;\r
-typedef  DAT_PVOID                     ib_cqd_handle_t;\r
-typedef  ib_async_event_rec_t          ib_error_record_t;\r
-typedef  ib_wr_type_t                  ib_send_op_type_t;\r
-typedef  ib_wc_t                       ib_work_completion_t;\r
-typedef  uint32_t                      ib_hca_port_t;\r
-typedef  uint32_t                      ib_uint32_t;\r
-typedef  ib_local_ds_t                 ib_data_segment_t;\r
-\r
-typedef  unsigned __int3264            cl_dev_handle_t;\r
-\r
-\r
-typedef void (*ib_async_handler_t)(\r
-    IN    ib_hca_handle_t    ib_hca_handle,\r
-    IN    ib_error_record_t  *err_code,\r
-    IN    void               *context);\r
-\r
-typedef void (*ib_async_qp_handler_t)(\r
-    IN    ib_hca_handle_t    ib_hca_handle,\r
-    IN    ib_qp_handle_t     ib_qp_handle,\r
-    IN    ib_error_record_t  *err_code,\r
-    IN    void               *context);\r
-\r
-typedef void (*ib_async_cq_handler_t)(\r
-    IN    ib_hca_handle_t    ib_hca_handle,\r
-    IN    ib_cq_handle_t     ib_cq_handle,\r
-    IN    ib_error_record_t  *err_code,\r
-    IN    void               *context);\r
-\r
-typedef ib_net64_t   ib_guid_t;\r
-typedef ib_net16_t   ib_lid_t;\r
-typedef boolean_t    ib_bool_t;\r
-\r
-typedef struct _GID\r
-{\r
-    uint64_t gid_prefix;\r
-    uint64_t guid;\r
-} GID;\r
-\r
-typedef enum \r
-{\r
-    IB_CME_CONNECTED,\r
-    IB_CME_DISCONNECTED,\r
-    IB_CME_DISCONNECTED_ON_LINK_DOWN,\r
-    IB_CME_CONNECTION_REQUEST_PENDING,\r
-    IB_CME_CONNECTION_REQUEST_PENDING_PRIVATE_DATA,\r
-    IB_CME_DESTINATION_REJECT,\r
-    IB_CME_DESTINATION_REJECT_PRIVATE_DATA,\r
-    IB_CME_DESTINATION_UNREACHABLE,\r
-    IB_CME_TOO_MANY_CONNECTION_REQUESTS,\r
-    IB_CME_LOCAL_FAILURE,\r
-    IB_CME_REPLY_RECEIVED,\r
-    IB_CME_REPLY_RECEIVED_PRIVATE_DATA,\r
-    IB_CM_LOCAL_FAILURE\r
-} ib_cm_events_t;\r
-\r
-\r
-typedef enum\r
-{\r
-    IB_NOTIFY_ON_NEXT_COMP,\r
-    IB_NOTIFY_ON_SOLIC_COMP\r
-} ib_notification_type_t;\r
-\r
-typedef struct _ib_hca_name\r
-{\r
-    DAT_NAME_PTR hca_name[DAT_NAME_MAX_LENGTH];\r
-} ib_hca_name_t;\r
-\r
-\r
-#define          IB_INVALID_HANDLE             NULL\r
-#define          true                          TRUE\r
-#define          false                         FALSE\r
-\r
-#define          IB_MAX_REQ_PDATA_SIZE      92\r
-#define          IB_MAX_REP_PDATA_SIZE      196\r
-#define          IB_MAX_REJ_PDATA_SIZE      148\r
-#define          IB_MAX_DREQ_PDATA_SIZE     220\r
-#define          IB_MAX_DREP_PDATA_SIZE     224\r
-\r
-\r
-/* Resource Not Ready\r
-       1-6 is an actual retry count which is decremented to zero before\r
-        an error condition is set.\r
-    7 is 'magic' in that it implies Infinite retry, just keeps trying.\r
-*/\r
-#define                IB_RNR_RETRY_CNT   7\r
-\r
-/*\r
-IB 1.2 spec, page 331, table 45, RNR NAK timeout encoding (5-bits)\r
\r
-00000=655.36ms(milliseconds)\r
-00001=0.01ms\r
-00010=0.02ms\r
-00011=0.03ms\r
-00100=0.04ms\r
-00101=0.06ms\r
-00110=0.08ms\r
-00111=0.12ms\r
-\r
-11100=163.84ms 28d\r
-11101=245.76ms 29d\r
-11110=327.68ms 30d\r
-11111=491.52ms 31d\r
-*/\r
-#define                IB_RNR_NAK_TIMEOUT   0\r
-\r
-\r
-typedef void\r
-(*dapl_ibal_pfn_destructor_t)(\r
-    IN    void*    context );\r
-\r
-typedef struct _dapl_ibal_refs\r
-{\r
-    atomic32_t                      count;        // number of references\r
-    void*                         context;     // context for destructor\r
-    dapl_ibal_pfn_destructor_t    destructor;   // called when reference goes to zero\r
-\r
-} dapl_ibal_refs_t;\r
-\r
-\r
-typedef struct _dapl_ibal_root\r
-{\r
-    ib_al_handle_t        h_al;        // handle to Access Layer\r
-    cl_spinlock_t         ca_lock;     // CA list lock\r
-    cl_qlist_t            ca_head;     // list head of CAs\r
-    boolean_t             shutdown;    // when true, driver is shutting down\r
-    boolean_t             initialized;    // when true, lib is initialized \r
-\r
-} dapl_ibal_root_t;\r
-\r
-\r
-typedef struct _dapl_ibal_ca\r
-{\r
-    cl_list_item_t    next;        // peer CA list\r
-    ib_ca_handle_t    h_ca;        // handle to open CA\r
-    ib_ca_attr_t      *p_ca_attr;  // CA attributes\r
-    uint32_t          ca_attr_size;// size of ca attribute\r
-    dapl_ibal_refs_t  refs;        // reference counting\r
-    cl_spinlock_t     port_lock;   // port list lock\r
-    cl_qlist_t        port_head;   // port list head for this CA\r
-    cl_spinlock_t     evd_cb_lock; // EVD async error cb list lock\r
-    cl_qlist_t        evd_cb_head; // EVD async error cb list head for this CA\r
-    cl_dev_handle_t   mlnx_device;\r
-    DAT_PVOID         *ia_ptr;     // hook for CA async callbacks\r
-} dapl_ibal_ca_t;\r
-\r
-\r
-typedef struct _dapl_ibal_port\r
-{\r
-    cl_list_item_t    next;            // peer CA list\r
-    dapl_ibal_ca_t    *ca;             // pointer to parent CA\r
-    ib_port_attr_t    *p_attr;         // port attributes\r
-    dapl_ibal_refs_t  refs;            // reference counting\r
-} dapl_ibal_port_t;\r
-\r
-typedef struct _dapl_ibal_evd_cb\r
-{\r
-    cl_list_item_t     next;        // peer CA list\r
-    ib_async_handler_t pfn_async_err_cb;\r
-    ib_async_qp_handler_t  pfn_async_qp_err_cb;\r
-    ib_async_cq_handler_t  pfn_async_cq_err_cb;\r
-    void               *context;\r
-} dapl_ibal_evd_cb_t;\r
-\r
-/*\r
- * Definitions to map DTO OPs to IBAL Work-Request ops.\r
- */\r
-#define    OP_BAD_OPCODE      0\r
-#define    OP_RDMA_READ       WR_RDMA_READ\r
-#define    OP_RDMA_WRITE      WR_RDMA_WRITE\r
-#define    OP_SEND            WR_SEND\r
-#define    OP_COMP_AND_SWAP   WR_COMPARE_SWAP\r
-#define    OP_FETCH_AND_ADD   WR_FETCH_ADD\r
-\r
-#define    OP_RECEIVE         8                /* (8)  */\r
-#define    OP_BIND_MW         9                /* no-equivalent */\r
-#define    OP_RDMA_WRITE_IMM  10       /* RDMA_WRITE+Immediate data */\r
-#define    OP_RECEIVE_IMM     11       /* no-equivalent */\r
-\r
-/*\r
- * Definitions to map QP state\r
- */\r
-#define IB_QP_STATE_RESET    IB_QPS_RESET\r
-#define IB_QP_STATE_INIT     IB_QPS_INIT\r
-#define IB_QP_STATE_RTR      IB_QPS_RTR\r
-#define IB_QP_STATE_RTS      IB_QPS_RTS\r
-#define IB_QP_STATE_SQE      IB_QPS_SQERR\r
-#define IB_QP_STATE_SQD      IB_QPS_SQD\r
-#define IB_QP_STATE_ERROR    IB_QPS_ERROR\r
-\r
-/*\r
- * Definitions to map Memory OPs\r
- */\r
-#define IB_ACCESS_LOCAL_WRITE      IB_AC_LOCAL_WRITE\r
-#define IB_ACCESS_REMOTE_READ      IB_AC_RDMA_READ\r
-#define IB_ACCESS_REMOTE_WRITE     IB_AC_RDMA_WRITE\r
-#define IB_ACCESS_REMOTE_ATOMIC    IB_AC_ATOMIC\r
-#define IB_ACCESS_MEM_WINDOW_BIND  IB_AC_MW_BIND\r
-\r
-/*\r
- * CQE status \r
- */\r
-enum _dapl_comp_status\r
-{\r
-       IB_COMP_ST_SUCCESS              = IB_WCS_SUCCESS,\r
-       IB_COMP_ST_LOCAL_LEN_ERR        = IB_WCS_LOCAL_LEN_ERR,\r
-       IB_COMP_ST_LOCAL_OP_ERR         = IB_WCS_LOCAL_OP_ERR,\r
-       IB_COMP_ST_LOCAL_PROTECT_ERR    = IB_WCS_LOCAL_PROTECTION_ERR,\r
-       IB_COMP_ST_WR_FLUSHED_ERR       = IB_WCS_WR_FLUSHED_ERR,\r
-       IB_COMP_ST_MW_BIND_ERR          = IB_WCS_MEM_WINDOW_BIND_ERR,\r
-       IB_COMP_ST_REM_ACC_ERR          = IB_WCS_REM_ACCESS_ERR,\r
-       IB_COMP_ST_REM_OP_ERR           = IB_WCS_REM_OP_ERR,\r
-       IB_COMP_ST_RNR_COUNTER          = IB_WCS_RNR_RETRY_ERR,\r
-       IB_COMP_ST_TRANSP_COUNTER       = IB_WCS_TIMEOUT_RETRY_ERR,\r
-       IB_COMP_ST_REM_REQ_ERR          = IB_WCS_REM_INVALID_REQ_ERR,\r
-       IB_COMP_ST_BAD_RESPONSE_ERR     = IB_WCS_UNMATCHED_RESPONSE,\r
-       IB_COMP_ST_EE_STATE_ERR,\r
-       IB_COMP_ST_EE_CTX_NO_ERR\r
-};\r
-\r
-\r
-/*\r
- * Macro to check the state of an EP/QP\r
- */\r
-#define DAPLIB_NEEDS_INIT(ep)  ((ep)->qp_state == IB_QPS_ERROR)\r
-\r
-\r
-/*\r
- * Resolve IBAL return codes to their DAPL equivelent.\r
- * Do not return invalid Handles, the user is not able\r
- * to deal with them.\r
- */\r
-STATIC _INLINE_ DAT_RETURN \r
-dapl_ib_status_convert (\r
-    IN     int32_t     ib_status)\r
-{\r
-    switch ( ib_status )\r
-    {\r
-    case IB_SUCCESS:\r
-    {\r
-        return DAT_SUCCESS;\r
-    }\r
-    case IB_INSUFFICIENT_RESOURCES:\r
-    case IB_INSUFFICIENT_MEMORY:\r
-    case IB_RESOURCE_BUSY:\r
-    {\r
-        return DAT_INSUFFICIENT_RESOURCES;\r
-    }\r
-    case IB_INVALID_CA_HANDLE:\r
-    case IB_INVALID_CQ_HANDLE:\r
-    case IB_INVALID_QP_HANDLE:\r
-    case IB_INVALID_PD_HANDLE:\r
-    case IB_INVALID_MR_HANDLE:\r
-    case IB_INVALID_MW_HANDLE:\r
-    case IB_INVALID_AL_HANDLE:\r
-    case IB_INVALID_AV_HANDLE:\r
-    {\r
-        return DAT_INVALID_HANDLE;\r
-    }\r
-    case IB_INVALID_PKEY:\r
-    {\r
-        return DAT_PROTECTION_VIOLATION;\r
-    }\r
-    case IB_INVALID_LKEY:\r
-    case IB_INVALID_RKEY:\r
-    case IB_INVALID_PERMISSION:\r
-    {\r
-        return DAT_PRIVILEGES_VIOLATION;\r
-    }\r
-    case IB_INVALID_MAX_WRS:\r
-    case IB_INVALID_MAX_SGE:\r
-    case IB_INVALID_CQ_SIZE:\r
-    case IB_INVALID_SETTING:\r
-    case IB_INVALID_SERVICE_TYPE:\r
-    case IB_INVALID_GID:\r
-    case IB_INVALID_LID:\r
-    case IB_INVALID_GUID:\r
-    case IB_INVALID_PARAMETER:\r
-    {\r
-        return DAT_INVALID_PARAMETER;\r
-    }\r
-    case IB_INVALID_QP_STATE:\r
-    case IB_INVALID_APM_STATE:\r
-    case IB_INVALID_PORT_STATE:\r
-    case IB_INVALID_STATE:\r
-    {\r
-        return DAT_INVALID_STATE;\r
-    }\r
-    case IB_NOT_FOUND:\r
-    {\r
-        return DAT_QUEUE_EMPTY;\r
-    }\r
-    case IB_OVERFLOW:\r
-    {\r
-        return DAT_QUEUE_FULL;\r
-    }\r
-    case IB_UNSUPPORTED:\r
-    {\r
-        return DAT_NOT_IMPLEMENTED;\r
-    }\r
-    case IB_TIMEOUT:\r
-    {\r
-        return DAT_TIMEOUT_EXPIRED;\r
-    }\r
-    case IB_CANCELED:\r
-    {\r
-        return DAT_ABORT;\r
-    }\r
-    default:\r
-    {\r
-        return DAT_INTERNAL_ERROR;\r
-    }\r
-    }\r
-}\r
-   \r
-#define TAKE_LOCK( lock ) \\r
-        cl_spinlock_acquire( &(lock) )\r
-\r
-#define RELEASE_LOCK( lock ) \\r
-        cl_spinlock_release( &(lock) )\r
-\r
-#define LOCK_INSERT_HEAD( lock, head, item ) \\r
-{ \\r
-        TAKE_LOCK( lock ); \\r
-        cl_qlist_insert_head( &head, (cl_list_item_t*)(&item) ); \\r
-        RELEASE_LOCK( lock ); \\r
-}\r
-\r
-#define LOCK_INSERT_TAIL( lock, tail, item ) \\r
-{ \\r
-        TAKE_LOCK( lock ); \\r
-        cl_qlist_insert_tail( &tail, (cl_list_item_t*)(&item) ); \\r
-        RELEASE_LOCK( lock ); \\r
-}\r
-\r
-#define INIT_REFERENCE( p_ref, n, con, destruct ) \\r
-{ \\r
-        (p_ref)->count = n; \\r
-        (p_ref)->context = con; \\r
-        (p_ref)->destructor = destruct; \\r
-}\r
-\r
-#define TAKE_REFERENCE( p_ref ) \\r
-        cl_atomic_inc( &(p_ref)->count )\r
-\r
-#define REMOVE_REFERENCE( p_ref ) \\r
-{ \\r
-        if ( cl_atomic_dec( &(p_ref)->count ) == 0 ) \\r
-            if ( (p_ref)->destructor ) \\r
-                (p_ref)->destructor( (p_ref)->context ); \\r
-}\r
-\r
-/* \r
- * dapl_llist_entry in dapl.h but dapl.h depends on provider \r
- * typedef's in this file first. move dapl_llist_entry out of dapl.h\r
- */\r
-struct ib_llist_entry\r
-{\r
-    struct dapl_llist_entry    *flink;\r
-    struct dapl_llist_entry    *blink;\r
-    void                       *data;\r
-    struct dapl_llist_entry    *list_head;\r
-};\r
-\r
-#ifdef SOCK_CM\r
-\r
-typedef enum\r
-{\r
-       IB_THREAD_INIT,\r
-       IB_THREAD_RUN,\r
-       IB_THREAD_CANCEL,\r
-       IB_THREAD_EXIT\r
-\r
-} ib_thread_state_t;\r
-\r
-typedef enum scm_state \r
-{\r
-       SCM_INIT,\r
-       SCM_LISTEN,\r
-       SCM_CONN_PENDING,\r
-       SCM_ACCEPTING,\r
-       SCM_ACCEPTED,\r
-       SCM_REJECTED,\r
-       SCM_CONNECTED,\r
-       SCM_DISCONNECTED,\r
-       SCM_DESTROY\r
-\r
-} SCM_STATE;\r
-\r
-#endif /* SOCK_CM */\r
-\r
-typedef struct _ib_hca_transport\r
-{ \r
-#ifdef SOCK_CM\r
-    int                                max_inline_send;\r
-    ib_thread_state_t          cr_state;       /* CR thread */\r
-    DAPL_OS_THREAD             thread;         /* CR thread */\r
-    DAPL_OS_LOCK               lock;           /* CR serialization */\r
-    struct ib_llist_entry      *list;          /* Connection Requests */\r
-#endif\r
-    struct dapl_hca            *d_hca;\r
-    DAPL_OS_WAIT_OBJECT                wait_object;\r
-    DAPL_ATOMIC                        handle_ref_count; /* # of ia_opens on handle */\r
-    ib_cqd_handle_t            ib_cqd_handle;    /* cq domain handle */\r
-\r
-    /* Name service support */\r
-    void                       *name_service_handle;\r
-\r
-} ib_hca_transport_t;\r
-\r
-/* provider specfic fields for shared memory support */\r
-typedef uint32_t ib_shm_transport_t;\r
-\r
-#ifdef SOCK_CM\r
-\r
-/* inline send rdma threshold */\r
-#define        INLINE_SEND_DEFAULT     128\r
-\r
-/* CM mappings use SOCKETS */\r
-\r
-/* destination info exchanged between dapl, define wire protocol version */\r
-#define DSCM_VER 2\r
-\r
-typedef struct _ib_qp_cm\r
-{ \r
-       ib_net16_t      ver;\r
-       ib_net16_t      rej;\r
-       ib_net16_t              lid;\r
-       ib_net16_t              port;\r
-       ib_net32_t      qpn;\r
-       ib_net32_t              p_size;\r
-       DAT_SOCK_ADDR6          ia_address;\r
-       GID             gid;\r
-\r
-} ib_qp_cm_t;\r
-\r
-struct ib_cm_handle\r
-{ \r
-       struct ib_llist_entry   entry;\r
-       DAPL_OS_LOCK            lock;\r
-       SCM_STATE               state;\r
-       int                     socket;\r
-       int                     l_socket; \r
-       struct dapl_hca         *hca;\r
-       DAT_HANDLE              sp;     \r
-       DAT_HANDLE              cr;\r
-       struct dapl_ep          *ep;\r
-       ib_qp_cm_t              dst;\r
-       unsigned char           p_data[256];\r
-};\r
-\r
-DAT_RETURN dapli_init_sock_cm ( IN DAPL_HCA  *hca_ptr );\r
-\r
-#endif /* SOCK_CM */\r
-\r
-/*\r
- * Prototype\r
- */\r
-\r
-extern ib_api_status_t \r
-dapls_modify_qp_state_to_error (\r
-        ib_qp_handle_t                qp_handle );\r
-\r
-extern ib_api_status_t \r
-dapls_modify_qp_state_to_reset (\r
-    ib_qp_handle_t);\r
-\r
-extern ib_api_status_t \r
-dapls_modify_qp_state_to_init ( \r
-    ib_qp_handle_t, DAT_EP_ATTR *, dapl_ibal_port_t *);\r
-\r
-extern ib_api_status_t \r
-dapls_modify_qp_state_to_rtr (\r
-    ib_qp_handle_t, ib_net32_t, ib_lid_t, dapl_ibal_port_t *);\r
-\r
-extern ib_api_status_t \r
-dapls_modify_qp_state_to_rts (\r
-    ib_qp_handle_t);\r
-\r
-extern void\r
-dapli_ibal_ca_async_error_callback(\r
-    IN    ib_async_event_rec_t* p_err_rec );\r
-\r
-extern dapl_ibal_port_t *\r
-dapli_ibal_get_port (\r
-    IN   dapl_ibal_ca_t    *p_ca,\r
-    IN   uint8_t           port_num);\r
-\r
-extern int32_t dapls_ib_init (void);\r
-extern int32_t dapls_ib_release (void);\r
-\r
-extern dapl_ibal_evd_cb_t *\r
-dapli_find_evd_cb_by_context(\r
-    IN    void           *context,\r
-    IN    dapl_ibal_ca_t *ca);\r
-\r
-extern IB_HCA_NAME\r
-dapl_ib_convert_name(IN  char    *name);\r
-\r
-STATIC _INLINE_ int32_t\r
-dapli_ibal_convert_privileges (IN  DAT_MEM_PRIV_FLAGS  privileges )\r
-{\r
-    int32_t value = DAT_MEM_PRIV_NONE_FLAG;\r
-\r
-    /*\r
-     *    if (DAT_MEM_PRIV_LOCAL_READ_FLAG & privileges)\r
-     *       do nothing\r
-     */\r
-    if (DAT_MEM_PRIV_LOCAL_WRITE_FLAG & privileges)\r
-       value |= IB_ACCESS_LOCAL_WRITE;\r
-\r
-    if (DAT_MEM_PRIV_REMOTE_WRITE_FLAG & privileges)\r
-       value |= IB_ACCESS_REMOTE_WRITE;\r
-\r
-    if (DAT_MEM_PRIV_REMOTE_READ_FLAG & privileges)\r
-       value |= IB_ACCESS_REMOTE_READ;\r
-\r
-#ifdef DAT_EXTENSIONS\r
-    if (DAT_IB_MEM_PRIV_REMOTE_ATOMIC & privileges) \r
-        value |= IB_ACCESS_REMOTE_ATOMIC;\r
-#endif\r
-\r
-#ifdef DAPL_DBG\r
-    if (value == DAT_MEM_PRIV_NONE_FLAG)\r
-    {\r
-       dapl_dbg_log(DAPL_DBG_TYPE_ERR,"%s() Unknown DAT_MEM_PRIV_ 0x%x\n",\r
-                     __FUNCTION__,privileges);\r
-    }\r
-#endif\r
-    return value;\r
-}\r
-\r
-#define dapl_rmr_convert_privileges(p) dapli_ibal_convert_privileges(p)\r
-#define dapl_lmr_convert_privileges(p) dapli_ibal_convert_privileges(p)\r
-\r
-#endif /*  _DAPL_IBAL_UTIL_H_ */\r
+
+/*
+ * Copyright (c) 2005-2007 Intel Corporation. All rights reserved.
+ * Copyright (c) 2002, Network Appliance, Inc. All rights reserved. 
+ * 
+ * This Software is licensed under the terms of the "Common Public
+ * License" a copy of which is in the file LICENSE.txt in the root
+ * directory. The license is also available from the Open Source
+ * Initiative, see http://www.opensource.org/licenses/cpl.php.
+ *
+ */
+
+/**********************************************************************
+ * 
+ * MODULE: dapl_ibal_util.h
+ *
+ * PURPOSE: Utility defs & routines for access to openib-windows IBAL APIs
+ *
+ * $Id: dapl_ibal_util.h 33 2005-07-11 19:51:17Z ftillier $
+ *
+ **********************************************************************/
+
+#ifndef _DAPL_IBAL_UTIL_H_
+#define _DAPL_IBAL_UTIL_H_
+
+#include <iba/ib_al.h>
+#include <complib/cl_spinlock.h>
+#include <complib/cl_qlist.h>
+#include <complib/cl_atomic.h>
+
+#ifdef DAT_EXTENSIONS
+#include <dat2\dat_ib_extensions.h>
+#endif
+
+/*
+ * Typedefs to map IBAL types to more generic 'ib' types
+ */
+#ifdef SOCK_CM
+typedef  struct ib_cm_handle           *dp_ib_cm_handle_t;
+typedef  struct ib_cm_handle           *ib_cm_srvc_handle_t;
+#else
+
+/* EP-CM linking requires list_entry, protected ref counting */
+typedef struct dapl_ibal_cm
+{ 
+       struct dapl_llist_entry list_entry;
+       DAPL_OS_LOCK            lock;
+       int                     ref_count;
+       DAT_SOCK_ADDR6          dst_ip_addr; 
+       ib_cm_handle_t          ib_cm;  /* h_al, h_qp, cid */
+       DAPL_EP                 *ep;
+
+} dapl_ibal_cm_t;
+
+typedef  dapl_ibal_cm_t                *dp_ib_cm_handle_t;
+typedef  ib_listen_handle_t            ib_cm_srvc_handle_t;
+
+/* EP-CM linking prototypes */
+extern void dapls_cm_acquire(dp_ib_cm_handle_t cm_ptr);
+extern void dapls_cm_release(dp_ib_cm_handle_t cm_ptr);
+extern void dapls_cm_free(dp_ib_cm_handle_t cm_ptr);
+extern dp_ib_cm_handle_t ibal_cm_alloc(void);
+
+#endif
+
+typedef  ib_net64_t                    IB_HCA_NAME;
+typedef  ib_ca_handle_t                ib_hca_handle_t;
+typedef  DAT_PVOID                     ib_cqd_handle_t;
+typedef  ib_async_event_rec_t          ib_error_record_t;
+typedef  ib_wr_type_t                  ib_send_op_type_t;
+typedef  ib_wc_t                       ib_work_completion_t;
+typedef  uint32_t                      ib_hca_port_t;
+typedef  uint32_t                      ib_uint32_t;
+typedef  ib_local_ds_t                 ib_data_segment_t;
+
+typedef  unsigned __int3264            cl_dev_handle_t;
+
+
+typedef void (*ib_async_handler_t)(
+    IN    ib_hca_handle_t    ib_hca_handle,
+    IN    ib_error_record_t  *err_code,
+    IN    void               *context);
+
+typedef void (*ib_async_qp_handler_t)(
+    IN    ib_hca_handle_t    ib_hca_handle,
+    IN    ib_qp_handle_t     ib_qp_handle,
+    IN    ib_error_record_t  *err_code,
+    IN    void               *context);
+
+typedef void (*ib_async_cq_handler_t)(
+    IN    ib_hca_handle_t    ib_hca_handle,
+    IN    ib_cq_handle_t     ib_cq_handle,
+    IN    ib_error_record_t  *err_code,
+    IN    void               *context);
+
+typedef ib_net64_t   ib_guid_t;
+typedef ib_net16_t   ib_lid_t;
+typedef boolean_t    ib_bool_t;
+
+typedef struct _GID
+{
+    uint64_t gid_prefix;
+    uint64_t guid;
+} GID;
+
+typedef enum 
+{
+    IB_CME_CONNECTED,
+    IB_CME_DISCONNECTED,
+    IB_CME_DISCONNECTED_ON_LINK_DOWN,
+    IB_CME_CONNECTION_REQUEST_PENDING,
+    IB_CME_CONNECTION_REQUEST_PENDING_PRIVATE_DATA,
+    IB_CME_DESTINATION_REJECT,
+    IB_CME_DESTINATION_REJECT_PRIVATE_DATA,
+    IB_CME_DESTINATION_UNREACHABLE,
+    IB_CME_TOO_MANY_CONNECTION_REQUESTS,
+    IB_CME_LOCAL_FAILURE,
+    IB_CME_REPLY_RECEIVED,
+    IB_CME_REPLY_RECEIVED_PRIVATE_DATA,
+    IB_CM_LOCAL_FAILURE
+} ib_cm_events_t;
+
+
+typedef enum
+{
+    IB_NOTIFY_ON_NEXT_COMP,
+    IB_NOTIFY_ON_SOLIC_COMP
+} ib_notification_type_t;
+
+typedef struct _ib_hca_name
+{
+    DAT_NAME_PTR hca_name[DAT_NAME_MAX_LENGTH];
+} ib_hca_name_t;
+
+
+#define          IB_INVALID_HANDLE             NULL
+#define          true                          TRUE
+#define          false                         FALSE
+
+#define          IB_MAX_REQ_PDATA_SIZE      92
+#define          IB_MAX_REP_PDATA_SIZE      196
+#define          IB_MAX_REJ_PDATA_SIZE      148
+#define          IB_MAX_DREQ_PDATA_SIZE     220
+#define          IB_MAX_DREP_PDATA_SIZE     224
+
+
+/* Resource Not Ready
+       1-6 is an actual retry count which is decremented to zero before
+        an error condition is set.
+    7 is 'magic' in that it implies Infinite retry, just keeps trying.
+*/
+#define                IB_RNR_RETRY_CNT   7
+
+/*
+IB 1.2 spec, page 331, table 45, RNR NAK timeout encoding (5-bits)
+00000=655.36ms(milliseconds)
+00001=0.01ms
+00010=0.02ms
+00011=0.03ms
+00100=0.04ms
+00101=0.06ms
+00110=0.08ms
+00111=0.12ms
+
+11100=163.84ms 28d
+11101=245.76ms 29d
+11110=327.68ms 30d
+11111=491.52ms 31d
+*/
+#define                IB_RNR_NAK_TIMEOUT   0
+
+
+typedef void
+(*dapl_ibal_pfn_destructor_t)(
+    IN    void*    context );
+
+typedef struct _dapl_ibal_refs
+{
+    atomic32_t                      count;        // number of references
+    void*                         context;     // context for destructor
+    dapl_ibal_pfn_destructor_t    destructor;   // called when reference goes to zero
+
+} dapl_ibal_refs_t;
+
+
+typedef struct _dapl_ibal_root
+{
+    ib_al_handle_t        h_al;        // handle to Access Layer
+    cl_spinlock_t         ca_lock;     // CA list lock
+    cl_qlist_t            ca_head;     // list head of CAs
+    boolean_t             shutdown;    // when true, driver is shutting down
+    boolean_t             initialized;    // when true, lib is initialized 
+
+} dapl_ibal_root_t;
+
+
+typedef struct _dapl_ibal_ca
+{
+    cl_list_item_t    next;        // peer CA list
+    ib_ca_handle_t    h_ca;        // handle to open CA
+    ib_ca_attr_t      *p_ca_attr;  // CA attributes
+    uint32_t          ca_attr_size;// size of ca attribute
+    dapl_ibal_refs_t  refs;        // reference counting
+    cl_spinlock_t     port_lock;   // port list lock
+    cl_qlist_t        port_head;   // port list head for this CA
+    cl_spinlock_t     evd_cb_lock; // EVD async error cb list lock
+    cl_qlist_t        evd_cb_head; // EVD async error cb list head for this CA
+    cl_dev_handle_t   mlnx_device;
+    DAT_PVOID         *ia_ptr;     // hook for CA async callbacks
+} dapl_ibal_ca_t;
+
+
+typedef struct _dapl_ibal_port
+{
+    cl_list_item_t    next;            // peer CA list
+    dapl_ibal_ca_t    *ca;             // pointer to parent CA
+    ib_port_attr_t    *p_attr;         // port attributes
+    dapl_ibal_refs_t  refs;            // reference counting
+} dapl_ibal_port_t;
+
+typedef struct _dapl_ibal_evd_cb
+{
+    cl_list_item_t     next;        // peer CA list
+    ib_async_handler_t pfn_async_err_cb;
+    ib_async_qp_handler_t  pfn_async_qp_err_cb;
+    ib_async_cq_handler_t  pfn_async_cq_err_cb;
+    void               *context;
+} dapl_ibal_evd_cb_t;
+
+/*
+ * Definitions to map DTO OPs to IBAL Work-Request ops.
+ */
+#define    OP_BAD_OPCODE      0
+#define    OP_RDMA_READ       WR_RDMA_READ
+#define    OP_RDMA_WRITE      WR_RDMA_WRITE
+#define    OP_SEND            WR_SEND
+#define    OP_COMP_AND_SWAP   WR_COMPARE_SWAP
+#define    OP_FETCH_AND_ADD   WR_FETCH_ADD
+
+#define    OP_RECEIVE         8                /* (8)  */
+#define    OP_BIND_MW         9                /* no-equivalent */
+#define    OP_RDMA_WRITE_IMM  10       /* RDMA_WRITE+Immediate data */
+#define    OP_RECEIVE_IMM     11       /* no-equivalent */
+
+/*
+ * Definitions to map QP state
+ */
+#define IB_QP_STATE_RESET    IB_QPS_RESET
+#define IB_QP_STATE_INIT     IB_QPS_INIT
+#define IB_QP_STATE_RTR      IB_QPS_RTR
+#define IB_QP_STATE_RTS      IB_QPS_RTS
+#define IB_QP_STATE_SQE      IB_QPS_SQERR
+#define IB_QP_STATE_SQD      IB_QPS_SQD
+#define IB_QP_STATE_ERROR    IB_QPS_ERROR
+
+/*
+ * Definitions to map Memory OPs
+ */
+#define IB_ACCESS_LOCAL_WRITE      IB_AC_LOCAL_WRITE
+#define IB_ACCESS_REMOTE_READ      IB_AC_RDMA_READ
+#define IB_ACCESS_REMOTE_WRITE     IB_AC_RDMA_WRITE
+#define IB_ACCESS_REMOTE_ATOMIC    IB_AC_ATOMIC
+#define IB_ACCESS_MEM_WINDOW_BIND  IB_AC_MW_BIND
+
+/*
+ * CQE status 
+ */
+enum _dapl_comp_status
+{
+       IB_COMP_ST_SUCCESS              = IB_WCS_SUCCESS,
+       IB_COMP_ST_LOCAL_LEN_ERR        = IB_WCS_LOCAL_LEN_ERR,
+       IB_COMP_ST_LOCAL_OP_ERR         = IB_WCS_LOCAL_OP_ERR,
+       IB_COMP_ST_LOCAL_PROTECT_ERR    = IB_WCS_LOCAL_PROTECTION_ERR,
+       IB_COMP_ST_WR_FLUSHED_ERR       = IB_WCS_WR_FLUSHED_ERR,
+       IB_COMP_ST_MW_BIND_ERR          = IB_WCS_MEM_WINDOW_BIND_ERR,
+       IB_COMP_ST_REM_ACC_ERR          = IB_WCS_REM_ACCESS_ERR,
+       IB_COMP_ST_REM_OP_ERR           = IB_WCS_REM_OP_ERR,
+       IB_COMP_ST_RNR_COUNTER          = IB_WCS_RNR_RETRY_ERR,
+       IB_COMP_ST_TRANSP_COUNTER       = IB_WCS_TIMEOUT_RETRY_ERR,
+       IB_COMP_ST_REM_REQ_ERR          = IB_WCS_REM_INVALID_REQ_ERR,
+       IB_COMP_ST_BAD_RESPONSE_ERR     = IB_WCS_UNMATCHED_RESPONSE,
+       IB_COMP_ST_EE_STATE_ERR,
+       IB_COMP_ST_EE_CTX_NO_ERR
+};
+
+
+/*
+ * Macro to check the state of an EP/QP
+ */
+#define DAPLIB_NEEDS_INIT(ep)  ((ep)->qp_state == IB_QPS_ERROR)
+
+
+/*
+ * Resolve IBAL return codes to their DAPL equivelent.
+ * Do not return invalid Handles, the user is not able
+ * to deal with them.
+ */
+STATIC _INLINE_ DAT_RETURN 
+dapl_ib_status_convert (
+    IN     int32_t     ib_status)
+{
+    switch ( ib_status )
+    {
+    case IB_SUCCESS:
+    {
+        return DAT_SUCCESS;
+    }
+    case IB_INSUFFICIENT_RESOURCES:
+    case IB_INSUFFICIENT_MEMORY:
+    case IB_RESOURCE_BUSY:
+    {
+        return DAT_INSUFFICIENT_RESOURCES;
+    }
+    case IB_INVALID_CA_HANDLE:
+    case IB_INVALID_CQ_HANDLE:
+    case IB_INVALID_QP_HANDLE:
+    case IB_INVALID_PD_HANDLE:
+    case IB_INVALID_MR_HANDLE:
+    case IB_INVALID_MW_HANDLE:
+    case IB_INVALID_AL_HANDLE:
+    case IB_INVALID_AV_HANDLE:
+    {
+        return DAT_INVALID_HANDLE;
+    }
+    case IB_INVALID_PKEY:
+    {
+        return DAT_PROTECTION_VIOLATION;
+    }
+    case IB_INVALID_LKEY:
+    case IB_INVALID_RKEY:
+    case IB_INVALID_PERMISSION:
+    {
+        return DAT_PRIVILEGES_VIOLATION;
+    }
+    case IB_INVALID_MAX_WRS:
+    case IB_INVALID_MAX_SGE:
+    case IB_INVALID_CQ_SIZE:
+    case IB_INVALID_SETTING:
+    case IB_INVALID_SERVICE_TYPE:
+    case IB_INVALID_GID:
+    case IB_INVALID_LID:
+    case IB_INVALID_GUID:
+    case IB_INVALID_PARAMETER:
+    {
+        return DAT_INVALID_PARAMETER;
+    }
+    case IB_INVALID_QP_STATE:
+    case IB_INVALID_APM_STATE:
+    case IB_INVALID_PORT_STATE:
+    case IB_INVALID_STATE:
+    {
+        return DAT_INVALID_STATE;
+    }
+    case IB_NOT_FOUND:
+    {
+        return DAT_QUEUE_EMPTY;
+    }
+    case IB_OVERFLOW:
+    {
+        return DAT_QUEUE_FULL;
+    }
+    case IB_UNSUPPORTED:
+    {
+        return DAT_NOT_IMPLEMENTED;
+    }
+    case IB_TIMEOUT:
+    {
+        return DAT_TIMEOUT_EXPIRED;
+    }
+    case IB_CANCELED:
+    {
+        return DAT_ABORT;
+    }
+    default:
+    {
+        return DAT_INTERNAL_ERROR;
+    }
+    }
+}
+   
+#define TAKE_LOCK( lock ) \
+        cl_spinlock_acquire( &(lock) )
+
+#define RELEASE_LOCK( lock ) \
+        cl_spinlock_release( &(lock) )
+
+#define LOCK_INSERT_HEAD( lock, head, item ) \
+{ \
+        TAKE_LOCK( lock ); \
+        cl_qlist_insert_head( &head, (cl_list_item_t*)(&item) ); \
+        RELEASE_LOCK( lock ); \
+}
+
+#define LOCK_INSERT_TAIL( lock, tail, item ) \
+{ \
+        TAKE_LOCK( lock ); \
+        cl_qlist_insert_tail( &tail, (cl_list_item_t*)(&item) ); \
+        RELEASE_LOCK( lock ); \
+}
+
+#define INIT_REFERENCE( p_ref, n, con, destruct ) \
+{ \
+        (p_ref)->count = n; \
+        (p_ref)->context = con; \
+        (p_ref)->destructor = destruct; \
+}
+
+#define TAKE_REFERENCE( p_ref ) \
+        cl_atomic_inc( &(p_ref)->count )
+
+#define REMOVE_REFERENCE( p_ref ) \
+{ \
+        if ( cl_atomic_dec( &(p_ref)->count ) == 0 ) \
+            if ( (p_ref)->destructor ) \
+                (p_ref)->destructor( (p_ref)->context ); \
+}
+
+/* 
+ * dapl_llist_entry in dapl.h but dapl.h depends on provider 
+ * typedef's in this file first. move dapl_llist_entry out of dapl.h
+ */
+struct ib_llist_entry
+{
+    struct dapl_llist_entry    *flink;
+    struct dapl_llist_entry    *blink;
+    void                       *data;
+    struct dapl_llist_entry    *list_head;
+};
+
+#ifdef SOCK_CM
+
+typedef enum
+{
+       IB_THREAD_INIT,
+       IB_THREAD_RUN,
+       IB_THREAD_CANCEL,
+       IB_THREAD_EXIT
+
+} ib_thread_state_t;
+
+typedef enum scm_state 
+{
+       SCM_INIT,
+       SCM_LISTEN,
+       SCM_CONN_PENDING,
+       SCM_ACCEPTING,
+       SCM_ACCEPTED,
+       SCM_REJECTED,
+       SCM_CONNECTED,
+       SCM_DISCONNECTED,
+       SCM_DESTROY
+
+} SCM_STATE;
+
+#endif /* SOCK_CM */
+
+typedef struct _ib_hca_transport
+{ 
+#ifdef SOCK_CM
+    int                                max_inline_send;
+    ib_thread_state_t          cr_state;       /* CR thread */
+    DAPL_OS_THREAD             thread;         /* CR thread */
+    DAPL_OS_LOCK               lock;           /* CR serialization */
+    struct ib_llist_entry      *list;          /* Connection Requests */
+#endif
+    struct dapl_hca            *d_hca;
+    DAPL_OS_WAIT_OBJECT                wait_object;
+    DAPL_ATOMIC                        handle_ref_count; /* # of ia_opens on handle */
+    ib_cqd_handle_t            ib_cqd_handle;    /* cq domain handle */
+
+    /* Name service support */
+    void                       *name_service_handle;
+
+} ib_hca_transport_t;
+
+/* provider specfic fields for shared memory support */
+typedef uint32_t ib_shm_transport_t;
+
+#ifdef SOCK_CM
+
+/* inline send rdma threshold */
+#define        INLINE_SEND_DEFAULT     128
+
+/* CM mappings use SOCKETS */
+
+/* destination info exchanged between dapl, define wire protocol version */
+#define DSCM_VER 2
+
+typedef struct _ib_qp_cm
+{ 
+       ib_net16_t      ver;
+       ib_net16_t      rej;
+       ib_net16_t              lid;
+       ib_net16_t              port;
+       ib_net32_t      qpn;
+       ib_net32_t              p_size;
+       DAT_SOCK_ADDR6          ia_address;
+       GID             gid;
+
+} ib_qp_cm_t;
+
+struct ib_cm_handle
+{ 
+       struct ib_llist_entry   entry;
+       DAPL_OS_LOCK            lock;
+       SCM_STATE               state;
+       int                     socket;
+       int                     l_socket; 
+       struct dapl_hca         *hca;
+       DAT_HANDLE              sp;     
+       DAT_HANDLE              cr;
+       struct dapl_ep          *ep;
+       ib_qp_cm_t              dst;
+       unsigned char           p_data[256];
+};
+
+DAT_RETURN dapli_init_sock_cm ( IN DAPL_HCA  *hca_ptr );
+
+#endif /* SOCK_CM */
+
+/*
+ * Prototype
+ */
+
+extern ib_api_status_t 
+dapls_modify_qp_state_to_error (
+        ib_qp_handle_t                qp_handle );
+
+extern ib_api_status_t 
+dapls_modify_qp_state_to_reset (
+    ib_qp_handle_t);
+
+extern ib_api_status_t 
+dapls_modify_qp_state_to_init ( 
+    ib_qp_handle_t, DAT_EP_ATTR *, dapl_ibal_port_t *);
+
+extern ib_api_status_t 
+dapls_modify_qp_state_to_rtr (
+    ib_qp_handle_t, ib_net32_t, ib_lid_t, dapl_ibal_port_t *);
+
+extern ib_api_status_t 
+dapls_modify_qp_state_to_rts (
+    ib_qp_handle_t);
+
+extern void
+dapli_ibal_ca_async_error_callback(
+    IN    ib_async_event_rec_t* p_err_rec );
+
+extern dapl_ibal_port_t *
+dapli_ibal_get_port (
+    IN   dapl_ibal_ca_t    *p_ca,
+    IN   uint8_t           port_num);
+
+extern int32_t dapls_ib_init (void);
+extern int32_t dapls_ib_release (void);
+
+extern dapl_ibal_evd_cb_t *
+dapli_find_evd_cb_by_context(
+    IN    void           *context,
+    IN    dapl_ibal_ca_t *ca);
+
+extern IB_HCA_NAME
+dapl_ib_convert_name(IN  char    *name);
+
+STATIC _INLINE_ int32_t
+dapli_ibal_convert_privileges (IN  DAT_MEM_PRIV_FLAGS  privileges )
+{
+    int32_t value = DAT_MEM_PRIV_NONE_FLAG;
+
+    /*
+     *    if (DAT_MEM_PRIV_LOCAL_READ_FLAG & privileges)
+     *       do nothing
+     */
+    if (DAT_MEM_PRIV_LOCAL_WRITE_FLAG & privileges)
+       value |= IB_ACCESS_LOCAL_WRITE;
+
+    if (DAT_MEM_PRIV_REMOTE_WRITE_FLAG & privileges)
+       value |= IB_ACCESS_REMOTE_WRITE;
+
+    if (DAT_MEM_PRIV_REMOTE_READ_FLAG & privileges)
+       value |= IB_ACCESS_REMOTE_READ;
+
+#ifdef DAT_EXTENSIONS
+    if (DAT_IB_MEM_PRIV_REMOTE_ATOMIC & privileges) 
+        value |= IB_ACCESS_REMOTE_ATOMIC;
+#endif
+
+#ifdef DAPL_DBG
+    if (value == DAT_MEM_PRIV_NONE_FLAG)
+    {
+       dapl_dbg_log(DAPL_DBG_TYPE_ERR,"%s() Unknown DAT_MEM_PRIV_ 0x%x\n",
+                     __FUNCTION__,privileges);
+    }
+#endif
+    return value;
+}
+
+#define dapl_rmr_convert_privileges(p) dapli_ibal_convert_privileges(p)
+#define dapl_lmr_convert_privileges(p) dapli_ibal_convert_privileges(p)
+
+#endif /*  _DAPL_IBAL_UTIL_H_ */
index e26e1c04945f5b18686b8157794b4343ce988c21..a0c062738d0f515cf8ff058257ea466b25b9f995 100644 (file)
@@ -1,7 +1,7 @@
-#
-# DO NOT EDIT THIS FILE!!!  Edit .\sources. if you want to add a new source
-# file to this component.  This file merely indirects to the real make file
-# that is shared by all the driver components of the OpenIB Windows project.
-#
-
-!INCLUDE ..\..\..\..\inc\openib.def
+#\r
+# DO NOT EDIT THIS FILE!!!  Edit .\sources. if you want to add a new source\r
+# file to this component.  This file merely indirects to the real make file\r
+# that is shared by all the driver components of the OpenIB Windows project.\r
+#\r
+\r
+!INCLUDE ..\..\..\..\inc\openib.def\r
index 464608472a98479338d0738f203663f9dbd70077..e5fc1ace17c696daf1894e2271634d131da1f8fd 100644 (file)
@@ -1,48 +1,48 @@
-/*\r
- * Copyright (c) 2007 Intel Corporation.  All rights reserved.\r
- *\r
- * This software is available to you under the OpenIB.org BSD license\r
- * below:\r
- *\r
- *     Redistribution and use in source and binary forms, with or\r
- *     without modification, are permitted provided that the following\r
- *     conditions are met:\r
- *\r
- *      - Redistributions of source code must retain the above\r
- *        copyright notice, this list of conditions and the following\r
- *        disclaimer.\r
- *\r
- *      - Redistributions in binary form must reproduce the above\r
- *        copyright notice, this list of conditions and the following\r
- *        disclaimer in the documentation and/or other materials\r
- *        provided with the distribution.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- * SOFTWARE.\r
- *\r
- * $Id$\r
- */\r
-\r
-\r
-#include <oib_ver.h>\r
-\r
-#define VER_FILETYPE                   VFT_DLL\r
-#define VER_FILESUBTYPE                        VFT2_UNKNOWN\r
-\r
-#if DBG\r
-#define VER_FILEDESCRIPTION_STR                "Direct Access Provider Library v2.0 (IBAL) (Debug)"\r
-#define VER_INTERNALNAME_STR           "dapl2d.dll"\r
-#define VER_ORIGINALFILENAME_STR       "dapl2d.dll"\r
-#else\r
-#define VER_FILEDESCRIPTION_STR                "Direct Access Provider Library v2.0 (IBAL)"\r
-#define VER_INTERNALNAME_STR           "dapl2.dll"\r
-#define VER_ORIGINALFILENAME_STR       "dapl2.dll"\r
-#endif\r
-\r
-#include <common.ver>\r
+/*
+ * Copyright (c) 2007 Intel Corporation.  All rights reserved.
+ *
+ * This software is available to you under the OpenIB.org BSD license
+ * below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * $Id$
+ */
+
+
+#include <oib_ver.h>
+
+#define VER_FILETYPE                   VFT_DLL
+#define VER_FILESUBTYPE                        VFT2_UNKNOWN
+
+#if DBG
+#define VER_FILEDESCRIPTION_STR                "Direct Access Provider Library v2.0 (IBAL) (Debug)"
+#define VER_INTERNALNAME_STR           "dapl2d.dll"
+#define VER_ORIGINALFILENAME_STR       "dapl2d.dll"
+#else
+#define VER_FILEDESCRIPTION_STR                "Direct Access Provider Library v2.0 (IBAL)"
+#define VER_INTERNALNAME_STR           "dapl2.dll"
+#define VER_ORIGINALFILENAME_STR       "dapl2.dll"
+#endif
+
+#include <common.ver>
index 4439ec58fab456a4879682d48e1049a6f3679ea3..8dab61e639e6677ee726a8c9fcb3606ff3c3e277 100644 (file)
-/*\r
- * Copyright (c) 2002-2005, Network Appliance, 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
- *    in the file LICENSE.txt in the root directory. The license is also\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 in the file\r
- *    LICENSE2.txt in the root directory. The license is also available from\r
- *    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 in the file LICENSE3.txt in the root directory. The \r
- *    license is also 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.h\r
- *\r
- * PURPOSE: defines common data structures for the DAPL reference implemenation\r
- *\r
- * Description: This file describes the working data structures used within\r
- *              DAPL RI.\r
- *\r
- *\r
- * $Id: dapl.h 1317 2005-04-25 17:29:42Z jlentini $\r
- **********************************************************************/\r
-\r
-#ifndef _DAPL_H_\r
-#define _DAPL_H_\r
-\r
-#if defined(__KERNEL__)\r
-#include <dat2/kdat.h>\r
-#else\r
-#include <dat2/udat.h>\r
-#endif /* defined(__KERNEL__) */\r
-#include <dat2/dat_registry.h>\r
-#include "dapl_osd.h"\r
-#include "dapl_debug.h"\r
-\r
-\r
-\r
-/*********************************************************************\r
- *                                                                   *\r
- * Enumerations                                                      *\r
- *                                                                   *\r
- *********************************************************************/\r
-\r
-typedef enum dapl_magic\r
-{\r
-    /* magic number values for verification & debug */\r
-    DAPL_MAGIC_IA      = 0xCafeF00d,\r
-    DAPL_MAGIC_EVD     = 0xFeedFace,\r
-    DAPL_MAGIC_EP      = 0xDeadBabe,\r
-    DAPL_MAGIC_LMR     = 0xBeefCafe,\r
-    DAPL_MAGIC_RMR      = 0xABadCafe,\r
-    DAPL_MAGIC_PZ      = 0xDeafBeef,\r
-    DAPL_MAGIC_PSP     = 0xBeadeD0c,\r
-    DAPL_MAGIC_RSP     = 0xFab4Feed,\r
-    DAPL_MAGIC_SRQ     = 0xC001Babe,\r
-    DAPL_MAGIC_CR      = 0xBe12Cee1,\r
-    DAPL_MAGIC_CR_DESTROYED = 0xB12bDead,\r
-    DAPL_MAGIC_CNO     = 0xDeadF00d,\r
-    DAPL_MAGIC_INVALID  = 0xFFFFFFFF\r
-} DAPL_MAGIC;\r
-\r
-typedef enum dapl_evd_state\r
-{\r
-    DAPL_EVD_STATE_TERMINAL,\r
-    DAPL_EVD_STATE_INITIAL,\r
-    DAPL_EVD_STATE_OPEN,\r
-    DAPL_EVD_STATE_WAITED,\r
-    DAPL_EVD_STATE_DEAD        = 0xDEAD\r
-} DAPL_EVD_STATE;\r
-\r
-typedef enum dapl_evd_completion\r
-{\r
-    DAPL_EVD_STATE_INIT,\r
-    DAPL_EVD_STATE_SOLICITED_WAIT,\r
-    DAPL_EVD_STATE_THRESHOLD,\r
-    DAPL_EVD_STATE_UNSIGNALLED\r
-} DAPL_EVD_COMPLETION;\r
-\r
-typedef enum dapl_cno_state\r
-{\r
-    DAPL_CNO_STATE_UNTRIGGERED,\r
-    DAPL_CNO_STATE_TRIGGERED,\r
-    DAPL_CNO_STATE_DEAD = 0xDeadFeed,\r
-} DAPL_CNO_STATE;\r
-\r
-typedef enum dapl_qp_state\r
-{\r
-    DAPL_QP_STATE_UNCONNECTED,\r
-    DAPL_QP_STATE_RESERVED,\r
-    DAPL_QP_STATE_PASSIVE_CONNECTION_PENDING,\r
-    DAPL_QP_STATE_ACTIVE_CONNECTION_PENDING,\r
-    DAPL_QP_STATE_TENTATIVE_CONNECTION_PENDING,\r
-    DAPL_QP_STATE_CONNECTED,\r
-    DAPL_QP_STATE_DISCONNECT_PENDING,\r
-    DAPL_QP_STATE_ERROR,\r
-    DAPL_QP_STATE_NOT_REUSABLE,\r
-    DAPL_QP_STATE_FREE\r
-} DAPL_QP_STATE;\r
-\r
-\r
-/*********************************************************************\r
- *                                                                   *\r
- * Constants                                                         *\r
- *                                                                   *\r
- *********************************************************************/\r
-\r
-/*\r
- * number of HCAs allowed\r
- */\r
-#define DAPL_MAX_HCA_COUNT             4\r
-\r
-/*\r
- * Configures the RMR bind evd restriction\r
- */\r
-\r
-#define DAPL_RMR_BIND_EVD_RESTRICTION  DAT_RMR_EVD_SAME_AS_REQUEST_EVD\r
-\r
-/*\r
- * special qp_state indicating the EP does not have a QP attached yet\r
- */\r
-#define DAPL_QP_STATE_UNATTACHED       0xFFF0\r
-\r
-#define DAPL_MAX_PRIVATE_DATA_SIZE     256\r
-\r
-/*********************************************************************\r
- *                                                                   *\r
- * Macros                                                            *\r
- *                                                                   *\r
- *********************************************************************/\r
-\r
-#if defined (sun) || defined(__sun) || defined(_sun_) || defined (__solaris__) \r
-#define DAPL_BAD_PTR(a) ((unsigned long)(a) & 3)\r
-#elif defined(__linux__)\r
-#define DAPL_BAD_PTR(a) ((unsigned long)(a) & 3)\r
-#elif defined(_WIN64)\r
-#define DAPL_BAD_PTR(a) ((unsigned long)((DAT_UINT64)(a)) & 3)\r
-#elif defined(_WIN32)\r
-#define DAPL_BAD_PTR(a) ((unsigned long)((DAT_UINT64)(a)) & 3)\r
-#endif\r
-\r
-/*\r
- * Simple macro to verify a handle is bad. Conditions:\r
- * - pointer is NULL\r
- * - pointer is not word aligned\r
- * - pointer's magic number is wrong\r
- */\r
-\r
-#define DAPL_BAD_HANDLE(h, magicNum) (                         \\r
-           ((h) == NULL) ||                                    \\r
-           DAPL_BAD_PTR(h) ||                                  \\r
-           (((DAPL_HEADER *)(h))->magic != (magicNum)))\r
-\r
-#define DAPL_MIN(a, b)        ((a < b) ? (a) : (b))\r
-#define DAPL_MAX(a, b)        ((a > b) ? (a) : (b))\r
-\r
-#if NDEBUG > 0\r
-#define DEBUG_IS_BAD_HANDLE(h, magicNum) (DAPL_BAD_HANDLE(h, magicNum))\r
-#else\r
-#define DEBUG_IS_BAD_HANDLE(h, magicNum) (0)\r
-#endif\r
-\r
-#define DAT_ERROR(Type, SubType) ((DAT_RETURN)(DAT_CLASS_ERROR | Type | SubType))\r
-\r
-/*********************************************************************\r
- *                                                                   *\r
- * Typedefs                                                          *\r
- *                                                                   *\r
- *********************************************************************/\r
-\r
-typedef struct dapl_llist_entry                DAPL_LLIST_ENTRY;\r
-typedef DAPL_LLIST_ENTRY *             DAPL_LLIST_HEAD;\r
-typedef struct dapl_ring_buffer                DAPL_RING_BUFFER;\r
-typedef struct dapl_cookie_buffer      DAPL_COOKIE_BUFFER;\r
-\r
-typedef struct dapl_hash_table          DAPL_HASH_TABLE;\r
-typedef struct dapl_hash_table *        DAPL_HASH_TABLEP;\r
-typedef DAT_UINT64                      DAPL_HASH_KEY;\r
-typedef void *                          DAPL_HASH_DATA;\r
-\r
-typedef struct dapl_hca                        DAPL_HCA;\r
-\r
-typedef struct dapl_header             DAPL_HEADER;\r
-\r
-typedef struct dapl_ia                 DAPL_IA;\r
-typedef struct dapl_cno                        DAPL_CNO;\r
-typedef struct dapl_evd                DAPL_EVD;\r
-typedef struct dapl_ep                         DAPL_EP;\r
-typedef struct dapl_srq                        DAPL_SRQ;\r
-typedef struct dapl_pz                 DAPL_PZ;\r
-typedef struct dapl_lmr                        DAPL_LMR;\r
-typedef struct dapl_rmr                        DAPL_RMR;\r
-typedef struct dapl_sp                 DAPL_SP;\r
-typedef struct dapl_cr                 DAPL_CR;\r
-\r
-typedef struct dapl_cookie             DAPL_COOKIE;\r
-typedef struct dapl_dto_cookie         DAPL_DTO_COOKIE;\r
-typedef struct dapl_rmr_cookie         DAPL_RMR_COOKIE;\r
-\r
-typedef struct dapl_private            DAPL_PRIVATE;\r
-\r
-\r
-\r
-/*********************************************************************\r
- *                                                                   *\r
- * Structures                                                        *\r
- *                                                                   *\r
- *********************************************************************/\r
-\r
-struct dapl_llist_entry\r
-{\r
-    struct dapl_llist_entry    *flink;\r
-    struct dapl_llist_entry    *blink;\r
-    void                       *data;\r
-    DAPL_LLIST_HEAD            *list_head; /* for consistency checking */\r
-};\r
-\r
-struct dapl_ring_buffer\r
-{\r
-    void               **base;         /* base of element array */\r
-    DAT_COUNT          lim;            /* mask, number of entries - 1 */\r
-    DAPL_ATOMIC                head;           /* head pointer index */\r
-    DAPL_ATOMIC                tail;           /* tail pointer index */\r
-};\r
-\r
-struct dapl_cookie_buffer\r
-{\r
-    DAPL_COOKIE                *pool;\r
-    DAT_COUNT          pool_size;\r
-    DAPL_ATOMIC                head;\r
-    DAPL_ATOMIC                tail;\r
-};\r
-\r
-#ifdef IBAPI\r
-#include "dapl_ibapi_util.h"\r
-#elif VAPI\r
-#include "dapl_vapi_util.h"\r
-#elif __OPENIB__\r
-#include "dapl_openib_util.h"\r
-#include "dapl_openib_cm.h"\r
-#elif DUMMY\r
-#include "dapl_dummy_util.h"\r
-#elif OPENIB\r
-#include "dapl_ib_util.h"\r
-#else /* windows - IBAL and/or IBAL+Sock_CM */\r
-#include "dapl_ibal_util.h"\r
-#endif\r
-\r
-struct dapl_hca\r
-{\r
-    DAPL_OS_LOCK       lock;\r
-    DAPL_LLIST_HEAD    ia_list_head;      /* list of all open IAs */\r
-    DAPL_ATOMIC                handle_ref_count;  /* count of ia_opens on handle */\r
-    DAPL_EVD           *async_evd;\r
-    DAPL_EVD           *async_error_evd;\r
-    DAT_SOCK_ADDR6     hca_address;       /* local address of HCA*/\r
-    char               *name;             /* provider name */\r
-    ib_hca_handle_t    ib_hca_handle;\r
-    unsigned long       port_num;         /* physical port number */\r
-    ib_hca_transport_t  ib_trans;         /* Values specific transport API */\r
-    /* Memory Subsystem Support */\r
-    DAPL_HASH_TABLE    *lmr_hash_table;\r
-    /* Limits & useful HCA attributes */\r
-    DAT_IA_ATTR                ia_attr;\r
-};\r
-\r
-/* DAPL Objects always have the following header */\r
-struct dapl_header\r
-{\r
-    DAT_PROVIDER       *provider;      /* required by DAT - must be first */\r
-    DAPL_MAGIC         magic;          /* magic number for verification */\r
-    DAT_HANDLE_TYPE    handle_type;    /* struct type */\r
-    DAPL_IA            *owner_ia;      /* ia which owns this stuct */\r
-    DAPL_LLIST_ENTRY   ia_list_entry;  /* link entry on ia struct */\r
-    DAT_CONTEXT                user_context;   /* user context - opaque to DAPL */\r
-    DAPL_OS_LOCK       lock;           /* lock - in header for easier macros */\r
-};\r
-\r
-/* DAPL_IA maps to DAT_IA_HANDLE */\r
-struct dapl_ia\r
-{\r
-    DAPL_HEADER                header;\r
-    DAPL_HCA           *hca_ptr;\r
-    DAPL_EVD           *async_error_evd;\r
-    DAT_BOOLEAN                cleanup_async_error_evd;\r
-\r
-    DAPL_LLIST_ENTRY   hca_ia_list_entry;      /* HCAs list of IAs */\r
-    DAPL_LLIST_HEAD    ep_list_head;           /* EP queue */\r
-    DAPL_LLIST_HEAD    lmr_list_head;          /* LMR queue */\r
-    DAPL_LLIST_HEAD    rmr_list_head;          /* RMR queue */\r
-    DAPL_LLIST_HEAD    pz_list_head;           /* PZ queue */\r
-    DAPL_LLIST_HEAD    evd_list_head;          /* EVD queue */\r
-    DAPL_LLIST_HEAD    cno_list_head;          /* CNO queue */\r
-    DAPL_LLIST_HEAD    psp_list_head;          /* PSP queue */\r
-    DAPL_LLIST_HEAD    rsp_list_head;          /* RSP queue */\r
-    DAPL_LLIST_HEAD    srq_list_head;          /* SRQ queue */\r
-#ifdef DAPL_COUNTERS\r
-    void               *cntrs;\r
-#endif\r
-};\r
-\r
-/* DAPL_CNO maps to DAT_CNO_HANDLE */\r
-struct dapl_cno\r
-{\r
-    DAPL_HEADER        header;\r
-\r
-    /* A CNO cannot be freed while it is referenced elsewhere.  */\r
-    DAPL_ATOMIC                        cno_ref_count;\r
-    DAPL_CNO_STATE             cno_state;\r
-\r
-    DAT_COUNT                  cno_waiters;\r
-    DAPL_EVD                   *cno_evd_triggered;\r
-#if defined(__KERNEL__)\r
-    DAT_UPCALL_OBJECT          cno_upcall;\r
-    DAT_UPCALL_POLICY          cno_upcall_policy;\r
-#else\r
-    DAT_OS_WAIT_PROXY_AGENT    cno_wait_agent;\r
-#endif /* defined(__KERNEL__) */\r
-\r
-    DAPL_OS_WAIT_OBJECT                cno_wait_object;\r
-};\r
-\r
-/* DAPL_EVD maps to DAT_EVD_HANDLE */\r
-struct dapl_evd\r
-{\r
-    DAPL_HEADER                header;\r
-\r
-    DAPL_EVD_STATE     evd_state;\r
-    DAT_EVD_FLAGS      evd_flags;\r
-    DAT_BOOLEAN                evd_enabled; /* For attached CNO.  */\r
-    DAT_BOOLEAN                evd_waitable; /* EVD state.  */\r
-\r
-    /* Derived from evd_flags; see dapls_evd_internal_create.  */\r
-    DAT_BOOLEAN                evd_producer_locking_needed;\r
-\r
-    /* Every EVD has a CQ unless it is a SOFTWARE_EVENT only EVD */\r
-    ib_cq_handle_t     ib_cq_handle;\r
-\r
-    /* An Event Dispatcher cannot be freed while\r
-     * it is referenced elsewhere.\r
-     */\r
-    DAPL_ATOMIC                evd_ref_count;\r
-\r
-    /* Set if there has been a catastrophic overflow */\r
-    DAT_BOOLEAN                catastrophic_overflow;\r
-\r
-    /* the actual events */\r
-    DAT_COUNT          qlen;\r
-    DAT_EVENT          *events;\r
-    DAPL_RING_BUFFER   free_event_queue;\r
-    DAPL_RING_BUFFER   pending_event_queue;\r
-\r
-    /* CQ Completions are not placed into 'deferred_events'\r
-     ** rather they are simply left on the Completion Queue\r
-     ** and the fact that there was a notification is flagged.\r
-     */\r
-    DAT_BOOLEAN                cq_notified;\r
-    DAPL_OS_TICKS      cq_notified_when;\r
-\r
-    DAT_COUNT          cno_active_count;\r
-    DAPL_CNO           *cno_ptr;\r
-\r
-    DAPL_OS_WAIT_OBJECT        wait_object;\r
-\r
-    DAT_COUNT          threshold;\r
-    DAPL_EVD_COMPLETION        completion_type;\r
-\r
-#ifdef DAPL_COUNTERS\r
-    void               *cntrs;\r
-#endif\r
-};\r
-\r
-/* DAPL_PRIVATE used to pass private data in a connection */\r
-struct dapl_private\r
-{\r
-#ifdef IBHOSTS_NAMING\r
-    DAT_SOCK_ADDR6             hca_address;    /* local address of HCA*/\r
-#endif /* IBHOSTS_NAMING */\r
-    unsigned char              private_data[DAPL_MAX_PRIVATE_DATA_SIZE];\r
-};\r
-\r
-/* uDAPL timer entry, used to queue timeouts */\r
-struct dapl_timer_entry\r
-{\r
-    DAPL_LLIST_ENTRY           list_entry;     /* link entry on ia struct */\r
-    DAPL_OS_TIMEVAL            expires;\r
-    void                       (*function) (uintptr_t);\r
-    void                       *data;\r
-};\r
-\r
-#ifdef DAPL_DBG_IO_TRC\r
-\r
-#define DBG_IO_TRC_QLEN   32           /* length of trace buffer        */\r
-#define DBG_IO_TRC_IOV 3               /* iov elements we keep track of */\r
-\r
-struct io_buf_track\r
-{\r
-    Ib_send_op_type            op_type;\r
-    DAPL_COOKIE                        *cookie;\r
-    DAT_LMR_TRIPLET            iov[DBG_IO_TRC_IOV];\r
-    DAT_RMR_TRIPLET            remote_iov;\r
-    unsigned int               done;   /* count to track completion ordering */\r
-    int                                status;\r
-    void                       *wqe;\r
-};\r
-\r
-#endif /* DAPL_DBG_IO_TRC */\r
-\r
-/* DAPL_EP maps to DAT_EP_HANDLE */\r
-struct dapl_ep\r
-{\r
-    DAPL_HEADER                        header;\r
-    /* What the DAT Consumer asked for */\r
-    DAT_EP_PARAM               param;\r
-\r
-    /* The RC Queue Pair (IBM OS API) */\r
-    ib_qp_handle_t             qp_handle;\r
-    unsigned int               qpn;    /* qp number */\r
-    ib_qp_state_t              qp_state;\r
-\r
-    /* communications manager handle (IBM OS API) */\r
-   // dp_ib_cm_handle_t                cm_handle;\r
-\r
-    /* Add support for multiple CM object ownership */\r
-    DAPL_LLIST_HEAD            cm_list_head;   \r
-\r
-    /* store the remote IA address here, reference from the param\r
-     * struct which only has a pointer, no storage\r
-     */\r
-    DAT_SOCK_ADDR6             remote_ia_address;\r
-\r
-    /* For passive connections we maintain a back pointer to the CR */\r
-    void *                     cr_ptr;\r
-\r
-    /* pointer to connection timer, if set */\r
-    struct dapl_timer_entry    *cxn_timer;\r
-\r
-    /* private data container */\r
-    DAPL_PRIVATE               private;\r
-\r
-    /* DTO data */\r
-    DAPL_ATOMIC                        req_count;\r
-    DAPL_ATOMIC                        recv_count;\r
-\r
-    DAPL_COOKIE_BUFFER req_buffer;\r
-    DAPL_COOKIE_BUFFER recv_buffer;\r
-\r
-#ifdef DAPL_DBG_IO_TRC\r
-    int                        ibt_dumped;\r
-    struct io_buf_track *ibt_base;\r
-    DAPL_RING_BUFFER   ibt_queue;\r
-#endif /* DAPL_DBG_IO_TRC */\r
-#if defined(_WIN32) || defined(_WIN64)\r
-    DAT_BOOLEAN         recv_discreq;\r
-    DAT_BOOLEAN         sent_discreq;\r
-#endif\r
-#ifdef DAPL_COUNTERS\r
-    void               *cntrs;\r
-#endif\r
-};\r
-\r
-/* DAPL_SRQ maps to DAT_SRQ_HANDLE */\r
-struct dapl_srq\r
-{\r
-    DAPL_HEADER                header;\r
-    DAT_SRQ_PARAM      param;\r
-    DAPL_ATOMIC                srq_ref_count;\r
-    DAPL_COOKIE_BUFFER recv_buffer;\r
-    DAPL_ATOMIC                recv_count;\r
-};\r
-\r
-/* DAPL_PZ maps to DAT_PZ_HANDLE */\r
-struct dapl_pz\r
-{\r
-    DAPL_HEADER                header;\r
-    ib_pd_handle_t     pd_handle;\r
-    DAPL_ATOMIC                pz_ref_count;\r
-};\r
-\r
-/* DAPL_LMR maps to DAT_LMR_HANDLE */\r
-struct dapl_lmr\r
-{\r
-    DAPL_HEADER                header;\r
-    DAT_LMR_PARAM      param;\r
-    ib_mr_handle_t     mr_handle;\r
-    DAPL_ATOMIC                lmr_ref_count;\r
-#if !defined(__KDAPL__)\r
-    char               shmid[DAT_LMR_COOKIE_SIZE]; /* shared memory ID */\r
-    ib_shm_transport_t ib_trans;       /* provider specific data */\r
-#endif /* !__KDAPL__ */\r
-};\r
-\r
-/* DAPL_RMR maps to DAT_RMR_HANDLE */\r
-struct dapl_rmr\r
-{\r
-    DAPL_HEADER                header;\r
-    DAT_RMR_PARAM      param;\r
-    DAPL_EP             *ep;\r
-    DAPL_PZ             *pz;\r
-    DAPL_LMR            *lmr;\r
-    ib_mw_handle_t     mw_handle;\r
-};\r
-\r
-/* SP types, indicating the state and queue */\r
-typedef enum dapl_sp_state\r
-{\r
-    DAPL_SP_STATE_FREE,\r
-    DAPL_SP_STATE_PSP_LISTENING,\r
-    DAPL_SP_STATE_PSP_PENDING,\r
-    DAPL_SP_STATE_RSP_LISTENING,\r
-    DAPL_SP_STATE_RSP_PENDING\r
-} DAPL_SP_STATE;\r
-\r
-/* DAPL_SP maps to DAT_PSP_HANDLE and DAT_RSP_HANDLE */\r
-struct dapl_sp\r
-{\r
-    DAPL_HEADER                header;\r
-    DAPL_SP_STATE      state;          /* type and queue of the SP */\r
-\r
-    /* PSP/RSP PARAM fields */\r
-    DAT_CONN_QUAL       conn_qual;\r
-    DAT_EVD_HANDLE      evd_handle;\r
-    DAT_PSP_FLAGS       psp_flags;\r
-    DAT_EP_HANDLE       ep_handle;\r
-\r
-     /* maintenence fields */\r
-    DAT_BOOLEAN                listening;      /* PSP is registered & active */\r
-    ib_cm_srvc_handle_t        cm_srvc_handle; /* Used by Mellanox CM */\r
-    DAPL_LLIST_HEAD    cr_list_head;   /* CR pending queue */\r
-    DAT_COUNT          cr_list_count;  /* count of CRs on queue */\r
-#if defined(_VENDOR_IBAL_)\r
-    DAPL_OS_WAIT_OBJECT wait_object;    /* cancel & destroy. */\r
-#endif\r
-};\r
-\r
-/* DAPL_CR maps to DAT_CR_HANDLE */\r
-struct dapl_cr\r
-{\r
-    DAPL_HEADER                header;\r
-\r
-    /* for convenience the data is kept as a DAT_CR_PARAM.\r
-     * however, the "local_endpoint" field is always NULL\r
-     * so this wastes a pointer. This is probably ok to\r
-     * simplify code, espedially dat_cr_query.\r
-     */\r
-    DAT_CR_PARAM       param;\r
-    /* IB specific fields */\r
-    dp_ib_cm_handle_t  ib_cm_handle;\r
-\r
-    DAT_SOCK_ADDR6     remote_ia_address;\r
-    /* Assuming that the maximum private data size is small.\r
-     * If it gets large, use of a pointer may be appropriate.\r
-     */\r
-    unsigned char      private_data[DAPL_MAX_PRIVATE_DATA_SIZE];\r
-    /*\r
-     * Need to be able to associate the CR back to the PSP for\r
-     * dapl_cr_reject.\r
-     */\r
-    DAPL_SP            *sp_ptr;\r
-};\r
-\r
-typedef enum dapl_dto_type\r
-{\r
-    DAPL_DTO_TYPE_SEND,\r
-    DAPL_DTO_TYPE_RECV,\r
-    DAPL_DTO_TYPE_RDMA_WRITE,\r
-    DAPL_DTO_TYPE_RDMA_READ,\r
-#ifdef DAT_EXTENSIONS\r
-    DAPL_DTO_TYPE_EXTENSION,\r
-#endif\r
-} DAPL_DTO_TYPE;\r
-\r
-typedef enum dapl_cookie_type\r
-{\r
-    DAPL_COOKIE_TYPE_NULL,\r
-    DAPL_COOKIE_TYPE_DTO,\r
-    DAPL_COOKIE_TYPE_RMR,\r
-} DAPL_COOKIE_TYPE;\r
-\r
-/* DAPL_DTO_COOKIE used as context for DTO WQEs */\r
-struct dapl_dto_cookie\r
-{\r
-    DAPL_DTO_TYPE              type;\r
-    DAT_DTO_COOKIE             cookie;\r
-    DAT_COUNT                  size;   /* used for SEND and RDMA write */\r
-};\r
-\r
-/* DAPL_RMR_COOKIE used as context for bind WQEs */\r
-struct dapl_rmr_cookie\r
-{\r
-    DAPL_RMR                   *rmr;\r
-    DAT_RMR_COOKIE              cookie;\r
-};\r
-\r
-/* DAPL_COOKIE used as context for WQEs */\r
-struct dapl_cookie\r
-{\r
-    DAPL_COOKIE_TYPE           type; /* Must be first, to define struct.  */\r
-    DAPL_EP                    *ep;\r
-    DAT_COUNT                  index;\r
-    union\r
-    {\r
-       DAPL_DTO_COOKIE         dto;\r
-       DAPL_RMR_COOKIE         rmr;\r
-    } val;\r
-};\r
-\r
-/*\r
- * Private Data operations. Used to obtain the size of the private\r
- * data from the provider layer.\r
- */\r
-typedef enum dapl_private_data_op\r
-{\r
-    DAPL_PDATA_CONN_REQ  = 0,          /* connect request    */\r
-    DAPL_PDATA_CONN_REP  = 1,          /* connect reply      */\r
-    DAPL_PDATA_CONN_REJ  = 2,          /* connect reject     */\r
-    DAPL_PDATA_CONN_DREQ = 3,          /* disconnect request */\r
-    DAPL_PDATA_CONN_DREP = 4,          /* disconnect reply   */\r
-} DAPL_PDATA_OP;\r
-\r
-\r
-/*\r
- * Generic HCA name field\r
- */\r
-#define DAPL_HCA_NAME_MAX_LEN 260\r
-typedef char DAPL_HCA_NAME[DAPL_HCA_NAME_MAX_LEN+1];\r
-\r
-#ifdef IBHOSTS_NAMING\r
-\r
-/*\r
- * Simple mapping table to match IP addresses to GIDs. Loaded\r
- * by dapl_init.\r
- */\r
-typedef struct _dapl_gid_map_table\r
-{\r
-    uint32_t           ip_address;\r
-    ib_gid_t           gid;\r
-} DAPL_GID_MAP;\r
-\r
-#endif /* IBHOSTS_NAMING */\r
-\r
-/*\r
- * IBTA defined reason for reject message: See IBTA 1.1 specification,\r
- * 12.6.7.2 REJECTION REASON section.\r
- */\r
-#define IB_CM_REJ_REASON_CONSUMER_REJ            0x001C\r
-\r
-\r
-#if defined(DAPL_DBG_IO_TRC)\r
-/*********************************************************************\r
- *                                                                   *\r
- * Debug I/O tracing support prototypes                              *\r
- *                                                                   *\r
- *********************************************************************/\r
-/*\r
- * I/O tracing support\r
- */\r
-void dapls_io_trc_alloc (\r
-    DAPL_EP                    *ep_ptr);\r
-\r
-void dapls_io_trc_update_completion (\r
-    DAPL_EP                    *ep_ptr,\r
-    DAPL_COOKIE                        *cookie,\r
-    ib_uint32_t                        ib_status );\r
-\r
-void dapls_io_trc_dump (\r
-    DAPL_EP                    *ep_ptr,\r
-    ib_work_completion_t       *cqe_ptr,\r
-    ib_uint32_t                        ib_status);\r
-\r
-#else /* DAPL_DBG_IO_TRC */\r
-\r
-#define dapls_io_trc_alloc(a)\r
-#define dapls_io_trc_update_completion(a, b, c)\r
-#define dapls_io_trc_dump(a, b, c)\r
-\r
-#endif /* DAPL_DBG_IO_TRC */\r
-\r
-\r
-/*********************************************************************\r
- *                                                                   *\r
- * Function Prototypes                                               *\r
- *                                                                   *\r
- *********************************************************************/\r
-\r
-typedef void (*DAPL_CONNECTION_STATE_HANDLER) (\r
-       IN      DAPL_EP *,\r
-       IN      ib_cm_events_t,\r
-       IN      const void *,\r
-       OUT     DAT_EVENT *);\r
-\r
-/*\r
- * DAT Mandated functions\r
- */\r
-\r
-extern DAT_RETURN DAT_API dapl_ia_open (\r
-       IN      const DAT_NAME_PTR,     /* name */\r
-       IN      DAT_COUNT,              /* asynch_evd_qlen */\r
-       INOUT   DAT_EVD_HANDLE *,       /* asynch_evd_handle */\r
-       OUT     DAT_IA_HANDLE *);       /* ia_handle */\r
-\r
-extern DAT_RETURN DAT_API dapl_ia_close (\r
-       IN      DAT_IA_HANDLE,          /* ia_handle */\r
-       IN      DAT_CLOSE_FLAGS );      /* ia_flags */\r
-\r
-\r
-extern DAT_RETURN DAT_API dapl_ia_query (\r
-       IN      DAT_IA_HANDLE,          /* ia handle */\r
-       OUT     DAT_EVD_HANDLE *,       /* async_evd_handle */\r
-       IN      DAT_IA_ATTR_MASK,       /* ia_params_mask */\r
-       OUT     DAT_IA_ATTR *,          /* ia_params */\r
-       IN      DAT_PROVIDER_ATTR_MASK, /* provider_params_mask */\r
-       OUT     DAT_PROVIDER_ATTR * );  /* provider_params */\r
-\r
-\r
-/* helper functions */\r
-\r
-extern DAT_RETURN DAT_API dapl_set_consumer_context (\r
-       IN      DAT_HANDLE,                     /* dat handle */\r
-       IN      DAT_CONTEXT);                   /* context */\r
-\r
-extern DAT_RETURN DAT_API dapl_get_consumer_context (\r
-       IN      DAT_HANDLE,                     /* dat handle */\r
-       OUT     DAT_CONTEXT * );                /* context */\r
-\r
-extern DAT_RETURN DAT_API dapl_get_handle_type (\r
-       IN      DAT_HANDLE,\r
-       OUT     DAT_HANDLE_TYPE * );\r
-\r
-/* CNO functions */\r
-\r
-#if !defined(__KERNEL__)\r
-extern DAT_RETURN DAT_API dapl_cno_create (\r
-       IN      DAT_IA_HANDLE,                  /* ia_handle */\r
-       IN      DAT_OS_WAIT_PROXY_AGENT,        /* agent */\r
-       OUT     DAT_CNO_HANDLE *);              /* cno_handle */\r
-\r
-extern DAT_RETURN DAT_API dapl_cno_modify_agent (\r
-       IN      DAT_CNO_HANDLE,                 /* cno_handle */\r
-       IN      DAT_OS_WAIT_PROXY_AGENT);       /* agent */\r
-\r
-extern DAT_RETURN DAT_API dapl_cno_query (\r
-       IN      DAT_CNO_HANDLE,         /* cno_handle */\r
-       IN      DAT_CNO_PARAM_MASK,     /* cno_param_mask */\r
-       OUT     DAT_CNO_PARAM * );      /* cno_param */\r
-\r
-extern DAT_RETURN DAT_API dapl_cno_free (\r
-       IN      DAT_CNO_HANDLE);        /* cno_handle */\r
-\r
-extern DAT_RETURN DAT_API dapl_cno_wait (\r
-       IN      DAT_CNO_HANDLE,         /* cno_handle */\r
-       IN      DAT_TIMEOUT,            /* timeout */\r
-       OUT     DAT_EVD_HANDLE *);      /* evd_handle */\r
-\r
-extern DAT_RETURN DAT_API dapl_cno_fd_create (\r
-       IN      DAT_IA_HANDLE,          /* ia_handle            */\r
-       OUT     DAT_FD *,               /* file_descriptor      */\r
-       OUT     DAT_CNO_HANDLE *);      /* cno_handle           */\r
-\r
-extern DAT_RETURN DAT_API dapl_cno_trigger (\r
-       IN      DAT_CNO_HANDLE,         /* cno_handle */\r
-       OUT     DAT_EVD_HANDLE *);      /* evd_handle */\r
-\r
-#endif /* !defined(__KERNEL__) */\r
-\r
-/* CR Functions */\r
-\r
-extern DAT_RETURN DAT_API dapl_cr_query (\r
-       IN      DAT_CR_HANDLE,          /* cr_handle */\r
-       IN      DAT_CR_PARAM_MASK,      /* cr_args_mask */\r
-       OUT     DAT_CR_PARAM * );       /* cwr_args */\r
-\r
-extern DAT_RETURN DAT_API dapl_cr_accept (\r
-       IN      DAT_CR_HANDLE,          /* cr_handle */\r
-       IN      DAT_EP_HANDLE,          /* ep_handle */\r
-       IN      DAT_COUNT,              /* private_data_size */\r
-       IN      const DAT_PVOID );      /* private_data */\r
-\r
-extern DAT_RETURN DAT_API dapl_cr_reject (\r
-       IN      DAT_CR_HANDLE,          /* cr_handle            */\r
-       IN      DAT_COUNT,              /* private_data_size    */\r
-       IN      const DAT_PVOID );      /* private_data         */\r
-\r
-extern DAT_RETURN DAT_API dapl_cr_handoff (\r
-       IN DAT_CR_HANDLE,               /* cr_handle */\r
-       IN DAT_CONN_QUAL);              /* handoff */\r
-\r
-/* EVD Functions */\r
-\r
-#if defined(__KERNEL__)\r
-extern DAT_RETURN DAT_API dapl_ia_memtype_hint (\r
-       IN    DAT_IA_HANDLE,            /* ia_handle */\r
-       IN    DAT_MEM_TYPE,             /* mem_type */\r
-       IN    DAT_VLEN,                 /* length */\r
-       IN    DAT_MEM_OPT,              /* mem_optimization */\r
-       OUT   DAT_VLEN *,               /* suggested_length */\r
-       OUT   DAT_VADDR *);             /* suggested_alignment */\r
-\r
-extern DAT_RETURN DAT_API dapl_evd_kcreate (\r
-       IN      DAT_IA_HANDLE,          /* ia_handle */\r
-       IN      DAT_COUNT,              /* evd_min_qlen */\r
-       IN      DAT_UPCALL_POLICY,      /* upcall_policy */\r
-       IN      const DAT_UPCALL_OBJECT *, /* upcall */\r
-       IN      DAT_EVD_FLAGS,          /* evd_flags */\r
-       OUT     DAT_EVD_HANDLE * );     /* evd_handle */\r
-\r
-extern DAT_RETURN DAT_API dapl_evd_kquery (\r
-       IN      DAT_EVD_HANDLE,         /* evd_handle */\r
-       IN      DAT_EVD_PARAM_MASK,     /* evd_args_mask */\r
-       OUT     DAT_EVD_PARAM * );      /* evd_args */\r
-\r
-#else\r
-extern DAT_RETURN DAT_API dapl_evd_create (\r
-       IN      DAT_IA_HANDLE,          /* ia_handle */\r
-       IN      DAT_COUNT,              /* evd_min_qlen */\r
-       IN      DAT_CNO_HANDLE,         /* cno_handle */\r
-       IN      DAT_EVD_FLAGS,          /* evd_flags */\r
-       OUT     DAT_EVD_HANDLE * );     /* evd_handle */\r
-\r
-extern DAT_RETURN DAT_API dapl_evd_query (\r
-       IN      DAT_EVD_HANDLE,         /* evd_handle */\r
-       IN      DAT_EVD_PARAM_MASK,     /* evd_args_mask */\r
-       OUT     DAT_EVD_PARAM * );      /* evd_args */\r
-#endif /* defined(__KERNEL__) */\r
-\r
-#if defined(__KERNEL__)\r
-extern DAT_RETURN DAT_API dapl_evd_modify_upcall (\r
-       IN      DAT_EVD_HANDLE,         /* evd_handle */\r
-       IN      DAT_UPCALL_POLICY,      /* upcall_policy */\r
-       IN      const DAT_UPCALL_OBJECT * ); /* upcall */\r
-\r
-#else\r
-\r
-extern DAT_RETURN DAT_API dapl_evd_modify_cno (\r
-       IN      DAT_EVD_HANDLE,         /* evd_handle */\r
-       IN      DAT_CNO_HANDLE);        /* cno_handle */\r
-#endif\r
-\r
-extern DAT_RETURN DAT_API dapl_evd_enable (\r
-       IN      DAT_EVD_HANDLE);        /* evd_handle */\r
-\r
-extern DAT_RETURN DAT_API dapl_evd_disable (\r
-       IN      DAT_EVD_HANDLE);        /* evd_handle */\r
-\r
-#if !defined(__KERNEL__)\r
-extern DAT_RETURN DAT_API dapl_evd_wait (\r
-       IN      DAT_EVD_HANDLE,         /* evd_handle */\r
-       IN      DAT_TIMEOUT,            /* timeout */\r
-       IN      DAT_COUNT,              /* threshold */\r
-       OUT     DAT_EVENT *,            /* event */\r
-       OUT     DAT_COUNT *);           /* nmore */\r
-#endif /* !defined(__KERNEL__) */\r
-\r
-extern DAT_RETURN DAT_API dapl_evd_resize (\r
-       IN      DAT_EVD_HANDLE,         /* evd_handle */\r
-       IN      DAT_COUNT );            /* evd_qlen */\r
-\r
-extern DAT_RETURN DAT_API dapl_evd_post_se (\r
-       DAT_EVD_HANDLE,                 /* evd_handle */\r
-       const DAT_EVENT * );            /* event */\r
-\r
-extern DAT_RETURN DAT_API dapl_evd_dequeue (\r
-       IN      DAT_EVD_HANDLE,         /* evd_handle */\r
-       OUT     DAT_EVENT * );          /* event */\r
-\r
-extern DAT_RETURN DAT_API dapl_evd_free (\r
-       IN      DAT_EVD_HANDLE );\r
-\r
-extern DAT_RETURN DAT_API\r
-dapl_evd_set_unwaitable (\r
-       IN      DAT_EVD_HANDLE  evd_handle );\r
-\r
-extern DAT_RETURN DAT_API\r
-dapl_evd_clear_unwaitable (\r
-       IN      DAT_EVD_HANDLE  evd_handle );\r
-\r
-/* EP functions */\r
-\r
-extern DAT_RETURN DAT_API dapl_ep_create (\r
-       IN      DAT_IA_HANDLE,          /* ia_handle */\r
-       IN      DAT_PZ_HANDLE,          /* pz_handle */\r
-       IN      DAT_EVD_HANDLE,         /* in_dto_completion_evd_handle */\r
-       IN      DAT_EVD_HANDLE,         /* out_dto_completion_evd_handle */\r
-       IN      DAT_EVD_HANDLE,         /* connect_evd_handle */\r
-       IN      const DAT_EP_ATTR *,    /* ep_parameters */\r
-       OUT     DAT_EP_HANDLE * );      /* ep_handle */\r
-\r
-extern DAT_RETURN DAT_API dapl_ep_query (\r
-       IN      DAT_EP_HANDLE,          /* ep_handle */\r
-       IN      DAT_EP_PARAM_MASK,      /* ep_args_mask */\r
-       OUT     DAT_EP_PARAM * );       /* ep_args */\r
-\r
-extern DAT_RETURN DAT_API dapl_ep_modify (\r
-       IN      DAT_EP_HANDLE,          /* ep_handle */\r
-       IN      DAT_EP_PARAM_MASK,      /* ep_args_mask */\r
-       IN      const DAT_EP_PARAM * ); /* ep_args */\r
-\r
-extern DAT_RETURN DAT_API dapl_ep_connect (\r
-       IN      DAT_EP_HANDLE,          /* ep_handle */\r
-       IN      DAT_IA_ADDRESS_PTR,     /* remote_ia_address */\r
-       IN      DAT_CONN_QUAL,          /* remote_conn_qual */\r
-       IN      DAT_TIMEOUT,            /* timeout */\r
-       IN      DAT_COUNT,              /* private_data_size */\r
-       IN      const DAT_PVOID,        /* private_data  */\r
-       IN      DAT_QOS,                /* quality_of_service */\r
-       IN      DAT_CONNECT_FLAGS );    /* connect_flags */\r
-\r
-extern DAT_RETURN DAT_API dapl_ep_common_connect (\r
-       IN      DAT_EP_HANDLE ep,               /* ep_handle            */\r
-       IN      DAT_IA_ADDRESS_PTR remote_addr, /* remote_ia_address    */\r
-       IN      DAT_TIMEOUT timeout,            /* timeout              */\r
-       IN      DAT_COUNT pdata_size,           /* private_data_size    */\r
-       IN      const DAT_PVOID pdata   );      /* private_data         */\r
-\r
-extern DAT_RETURN DAT_API dapl_ep_dup_connect (\r
-       IN      DAT_EP_HANDLE,          /* ep_handle */\r
-       IN      DAT_EP_HANDLE,          /* ep_dup_handle */\r
-       IN      DAT_TIMEOUT,            /* timeout*/\r
-       IN      DAT_COUNT,              /* private_data_size */\r
-       IN      const DAT_PVOID,        /* private_data */\r
-       IN      DAT_QOS);               /* quality_of_service */\r
-\r
-extern DAT_RETURN DAT_API dapl_ep_disconnect (\r
-       IN      DAT_EP_HANDLE,          /* ep_handle */\r
-       IN      DAT_CLOSE_FLAGS );      /* close_flags */\r
-\r
-extern DAT_RETURN DAT_API dapl_ep_post_send (\r
-       IN      DAT_EP_HANDLE,          /* ep_handle */\r
-       IN      DAT_COUNT,              /* num_segments */\r
-       IN      DAT_LMR_TRIPLET *,      /* local_iov */\r
-       IN      DAT_DTO_COOKIE,         /* user_cookie */\r
-       IN      DAT_COMPLETION_FLAGS ); /* completion_flags */\r
-\r
-extern DAT_RETURN DAT_API dapl_ep_post_recv (\r
-       IN      DAT_EP_HANDLE,          /* ep_handle */\r
-       IN      DAT_COUNT,              /* num_segments */\r
-       IN      DAT_LMR_TRIPLET *,      /* local_iov */\r
-       IN      DAT_DTO_COOKIE,         /* user_cookie */\r
-       IN      DAT_COMPLETION_FLAGS ); /* completion_flags */\r
-\r
-extern DAT_RETURN DAT_API dapl_ep_post_rdma_read (\r
-       IN      DAT_EP_HANDLE,           /* ep_handle */\r
-       IN      DAT_COUNT,               /* num_segments */\r
-       IN      DAT_LMR_TRIPLET *,       /* local_iov */\r
-       IN      DAT_DTO_COOKIE,          /* user_cookie */\r
-       IN      const DAT_RMR_TRIPLET *, /* remote_iov */\r
-       IN      DAT_COMPLETION_FLAGS );  /* completion_flags */\r
-\r
-extern DAT_RETURN DAT_API dapl_ep_post_rdma_read_to_rmr (\r
-       IN      DAT_EP_HANDLE,          /* ep_handle            */\r
-       IN      const DAT_RMR_TRIPLET *,/* local_iov            */\r
-       IN      DAT_DTO_COOKIE,         /* user_cookie          */\r
-       IN      const DAT_RMR_TRIPLET *,/* remote_iov           */\r
-       IN      DAT_COMPLETION_FLAGS);  /* completion_flags     */\r
-\r
-extern DAT_RETURN DAT_API dapl_ep_post_rdma_write (\r
-       IN      DAT_EP_HANDLE,           /* ep_handle */\r
-       IN      DAT_COUNT,               /* num_segments */\r
-       IN      DAT_LMR_TRIPLET *,       /* local_iov */\r
-       IN      DAT_DTO_COOKIE,          /* user_cookie */\r
-       IN      const DAT_RMR_TRIPLET *, /* remote_iov */\r
-       IN      DAT_COMPLETION_FLAGS );  /* completion_flags */\r
-\r
-extern DAT_RETURN DAT_API dapl_ep_post_send_with_invalidate (\r
-       IN      DAT_EP_HANDLE,          /* ep_handle            */\r
-       IN      DAT_COUNT,              /* num_segments         */\r
-       IN      DAT_LMR_TRIPLET *,      /* local_iov            */\r
-       IN      DAT_DTO_COOKIE,         /* user_cookie          */\r
-       IN      DAT_COMPLETION_FLAGS,   /* completion_flags     */\r
-       IN      DAT_BOOLEAN,            /* invalidate_flag      */\r
-       IN      DAT_RMR_CONTEXT);      /* RMR context          */\r
-\r
-extern DAT_RETURN DAT_API dapl_ep_get_status (\r
-       IN      DAT_EP_HANDLE,          /* ep_handle */\r
-       OUT     DAT_EP_STATE *,         /* ep_state */\r
-       OUT     DAT_BOOLEAN *,          /* in_dto_idle */\r
-       OUT     DAT_BOOLEAN * );        /* out_dto_idle */\r
-\r
-extern DAT_RETURN DAT_API dapl_ep_free (\r
-       IN      DAT_EP_HANDLE);         /* ep_handle */\r
-\r
-extern DAT_RETURN DAT_API dapl_ep_reset (\r
-       IN      DAT_EP_HANDLE);         /* ep_handle */\r
-\r
-extern DAT_RETURN DAT_API dapl_ep_create_with_srq (\r
-        IN      DAT_IA_HANDLE,          /* ia_handle            */\r
-        IN      DAT_PZ_HANDLE,          /* pz_handle            */\r
-        IN      DAT_EVD_HANDLE,         /* recv_evd_handle      */\r
-        IN      DAT_EVD_HANDLE,         /* request_evd_handle   */\r
-        IN      DAT_EVD_HANDLE,         /* connect_evd_handle   */\r
-        IN      DAT_SRQ_HANDLE,         /* srq_handle           */\r
-        IN      const DAT_EP_ATTR *,    /* ep_attributes        */\r
-        OUT     DAT_EP_HANDLE *);       /* ep_handle            */\r
-\r
-extern DAT_RETURN DAT_API dapl_ep_recv_query (\r
-        IN      DAT_EP_HANDLE,          /* ep_handle            */\r
-        OUT     DAT_COUNT *,            /* nbufs_allocated      */\r
-        OUT     DAT_COUNT *);           /* bufs_alloc_span      */\r
-\r
-extern DAT_RETURN DAT_API dapl_ep_set_watermark (\r
-        IN      DAT_EP_HANDLE,          /* ep_handle            */\r
-        IN      DAT_COUNT,              /* soft_high_watermark  */\r
-        IN      DAT_COUNT);             /* hard_high_watermark  */\r
-\r
-/* LMR functions */\r
-\r
-#if defined(__KERNEL__)\r
-extern DAT_RETURN DAT_API dapl_lmr_kcreate (\r
-       IN      DAT_IA_HANDLE,          /* ia_handle */\r
-       IN      DAT_MEM_TYPE,           /* mem_type */\r
-       IN      DAT_REGION_DESCRIPTION, /* region_description */\r
-       IN      DAT_VLEN,               /* length */\r
-       IN      DAT_PZ_HANDLE,          /* pz_handle */\r
-       IN      DAT_MEM_PRIV_FLAGS,     /* privileges */\r
-       IN      DAT_VA_TYPE,            /* va_type */\r
-       IN      DAT_MEM_OPT,            /* optimization */\r
-       OUT     DAT_LMR_HANDLE *,       /* lmr_handle */\r
-       OUT     DAT_LMR_CONTEXT *,      /* lmr_context */\r
-       OUT     DAT_RMR_CONTEXT *,      /* rmr_context          */\r
-       OUT     DAT_VLEN *,             /* registered_length */\r
-       OUT     DAT_VADDR * );          /* registered_address */\r
-#else\r
-extern DAT_RETURN DAT_API dapl_lmr_create (\r
-       IN      DAT_IA_HANDLE,          /* ia_handle */\r
-       IN      DAT_MEM_TYPE,           /* mem_type */\r
-       IN      DAT_REGION_DESCRIPTION, /* region_description */\r
-       IN      DAT_VLEN,               /* length */\r
-       IN      DAT_PZ_HANDLE,          /* pz_handle */\r
-       IN      DAT_MEM_PRIV_FLAGS,     /* privileges */\r
-       IN      DAT_VA_TYPE,            /* va_type */\r
-       OUT     DAT_LMR_HANDLE *,       /* lmr_handle */\r
-       OUT     DAT_LMR_CONTEXT *,      /* lmr_context */\r
-       OUT     DAT_RMR_CONTEXT *,      /* rmr_context          */\r
-       OUT     DAT_VLEN *,             /* registered_length */\r
-       OUT     DAT_VADDR * );          /* registered_address */\r
-#endif /* defined(__KERNEL__) */\r
-\r
-extern DAT_RETURN DAT_API dapl_lmr_query (\r
-       IN      DAT_LMR_HANDLE,\r
-       IN      DAT_LMR_PARAM_MASK,\r
-       OUT     DAT_LMR_PARAM *);\r
-\r
-extern DAT_RETURN DAT_API dapl_lmr_free (\r
-       IN      DAT_LMR_HANDLE);\r
-\r
-extern DAT_RETURN DAT_API dapl_lmr_sync_rdma_read (\r
-       IN      DAT_IA_HANDLE,          /* ia_handle            */\r
-       IN      const DAT_LMR_TRIPLET *, /* local_segments      */\r
-       IN      DAT_VLEN);              /* num_segments         */\r
-\r
-extern DAT_RETURN DAT_API dapl_lmr_sync_rdma_write (\r
-       IN      DAT_IA_HANDLE,          /* ia_handle            */\r
-       IN      const DAT_LMR_TRIPLET *, /* local_segments      */\r
-       IN      DAT_VLEN);              /* num_segments         */\r
-\r
-/* RMR Functions */\r
-\r
-extern DAT_RETURN DAT_API dapl_rmr_create (\r
-       IN      DAT_PZ_HANDLE,          /* pz_handle */\r
-       OUT     DAT_RMR_HANDLE *);      /* rmr_handle */\r
-\r
-extern DAT_RETURN DAT_API dapl_rmr_create_for_ep (\r
-       IN      DAT_PZ_HANDLE pz_handle,        /* pz_handle    */\r
-       OUT     DAT_RMR_HANDLE *rmr_handle);    /* rmr_handle   */\r
-\r
-extern DAT_RETURN DAT_API dapl_rmr_query (\r
-       IN      DAT_RMR_HANDLE,         /* rmr_handle */\r
-       IN      DAT_RMR_PARAM_MASK,     /* rmr_args_mask */\r
-       OUT     DAT_RMR_PARAM *);       /* rmr_args */\r
-\r
-extern DAT_RETURN DAT_API dapl_rmr_bind (\r
-       IN      DAT_RMR_HANDLE,          /* rmr_handle */\r
-       IN      DAT_LMR_HANDLE,          /* lmr_handle */\r
-       IN      const DAT_LMR_TRIPLET *, /* lmr_triplet */\r
-       IN      DAT_MEM_PRIV_FLAGS,      /* mem_priv */\r
-       IN      DAT_VA_TYPE,             /* va_type */\r
-       IN      DAT_EP_HANDLE,           /* ep_handle */\r
-       IN      DAT_RMR_COOKIE,          /* user_cookie */\r
-       IN      DAT_COMPLETION_FLAGS,    /* completion_flags */\r
-       INOUT   DAT_RMR_CONTEXT * );     /* context */\r
-\r
-extern DAT_RETURN DAT_API dapl_rmr_free (\r
-       IN      DAT_RMR_HANDLE);\r
-\r
-/* PSP Functions */\r
-\r
-extern DAT_RETURN DAT_API dapl_psp_create (\r
-       IN      DAT_IA_HANDLE,          /* ia_handle */\r
-       IN      DAT_CONN_QUAL,          /* conn_qual */\r
-       IN      DAT_EVD_HANDLE,         /* evd_handle */\r
-       IN      DAT_PSP_FLAGS,          /* psp_flags */\r
-       OUT     DAT_PSP_HANDLE * );     /* psp_handle */\r
-\r
-extern DAT_RETURN DAT_API dapl_psp_create_any (\r
-       IN      DAT_IA_HANDLE,          /* ia_handle */\r
-       OUT     DAT_CONN_QUAL *,        /* conn_qual */\r
-       IN      DAT_EVD_HANDLE,         /* evd_handle */\r
-       IN      DAT_PSP_FLAGS,          /* psp_flags */\r
-       OUT     DAT_PSP_HANDLE *);      /* psp_handle */\r
-\r
-extern DAT_RETURN DAT_API dapl_psp_query (\r
-       IN      DAT_PSP_HANDLE,\r
-       IN      DAT_PSP_PARAM_MASK,\r
-       OUT     DAT_PSP_PARAM * );\r
-\r
-extern DAT_RETURN DAT_API dapl_psp_free (\r
-       IN      DAT_PSP_HANDLE );       /* psp_handle */\r
-\r
-/* RSP Functions */\r
-\r
-extern DAT_RETURN DAT_API dapl_rsp_create (\r
-       IN      DAT_IA_HANDLE,          /* ia_handle */\r
-       IN      DAT_CONN_QUAL,          /* conn_qual */\r
-       IN      DAT_EP_HANDLE,          /* ep_handle */\r
-       IN      DAT_EVD_HANDLE,         /* evd_handle */\r
-       OUT     DAT_RSP_HANDLE * );     /* rsp_handle */\r
-\r
-extern DAT_RETURN DAT_API dapl_rsp_query (\r
-       IN      DAT_RSP_HANDLE,\r
-       IN      DAT_RSP_PARAM_MASK,\r
-       OUT     DAT_RSP_PARAM * );\r
-\r
-extern DAT_RETURN DAT_API dapl_rsp_free (\r
-       IN      DAT_RSP_HANDLE );       /* rsp_handle */\r
-\r
-/* PZ Functions */\r
-\r
-extern DAT_RETURN DAT_API dapl_pz_create (\r
-       IN      DAT_IA_HANDLE,          /* ia_handle */\r
-       OUT     DAT_PZ_HANDLE * );      /* pz_handle */\r
-\r
-extern DAT_RETURN DAT_API dapl_pz_query (\r
-       IN      DAT_PZ_HANDLE,          /* pz_handle */\r
-       IN      DAT_PZ_PARAM_MASK,      /* pz_args_mask */\r
-       OUT     DAT_PZ_PARAM * );       /* pz_args */\r
-\r
-extern DAT_RETURN DAT_API dapl_pz_free (\r
-       IN      DAT_PZ_HANDLE );        /* pz_handle */\r
-\r
-/* SRQ functions */\r
-\r
-extern DAT_RETURN DAT_API dapl_srq_create (\r
-        IN      DAT_IA_HANDLE,          /* ia_handle            */\r
-        IN      DAT_PZ_HANDLE,          /* pz_handle            */\r
-        IN      DAT_SRQ_ATTR *,         /* srq_attr             */\r
-        OUT     DAT_SRQ_HANDLE *);      /* srq_handle           */\r
-\r
-extern DAT_RETURN DAT_API dapl_srq_free (\r
-       IN      DAT_SRQ_HANDLE);        /* srq_handle           */\r
-\r
-extern DAT_RETURN DAT_API dapl_srq_post_recv (\r
-       IN      DAT_SRQ_HANDLE,         /* srq_handle           */\r
-       IN      DAT_COUNT,              /* num_segments         */\r
-       IN      DAT_LMR_TRIPLET *,      /* local_iov            */\r
-       IN      DAT_DTO_COOKIE);        /* user_cookie          */\r
-\r
-extern DAT_RETURN DAT_API dapl_srq_query (\r
-       IN      DAT_SRQ_HANDLE,         /* srq_handle           */\r
-       IN      DAT_SRQ_PARAM_MASK,     /* srq_param_mask       */\r
-       OUT     DAT_SRQ_PARAM *);       /* srq_param            */\r
-\r
-extern DAT_RETURN DAT_API dapl_srq_resize (\r
-       IN      DAT_SRQ_HANDLE,         /* srq_handle           */\r
-       IN      DAT_COUNT);             /* srq_max_recv_dto     */\r
-\r
-extern DAT_RETURN DAT_API dapl_srq_set_lw (\r
-       IN      DAT_SRQ_HANDLE,         /* srq_handle           */\r
-       IN      DAT_COUNT);             /* low_watermark        */\r
-\r
-/* CSP functions */\r
-extern DAT_RETURN DAT_API dapl_csp_create (\r
-       IN      DAT_IA_HANDLE,          /* ia_handle      */\r
-       IN      DAT_COMM *,             /* communicator   */\r
-       IN      DAT_IA_ADDRESS_PTR,     /* address        */\r
-       IN      DAT_EVD_HANDLE,         /* evd_handle     */\r
-       OUT     DAT_CSP_HANDLE *);      /* csp_handle     */\r
-\r
-extern DAT_RETURN DAT_API dapl_csp_query (\r
-       IN      DAT_CSP_HANDLE,         /* csp_handle     */\r
-       IN      DAT_CSP_PARAM_MASK,     /* csp_param_mask */\r
-       OUT     DAT_CSP_PARAM *);       /* csp_param      */\r
-\r
-extern DAT_RETURN DAT_API dapl_csp_free (\r
-       IN      DAT_CSP_HANDLE);        /* csp_handle     */\r
-\r
-/* HA functions */\r
-DAT_RETURN DAT_API dapl_ia_ha (\r
-       IN       DAT_IA_HANDLE,         /* ia_handle */\r
-       IN const DAT_NAME_PTR,          /* provider  */\r
-       OUT      DAT_BOOLEAN *);        /* answer    */\r
-\r
-#ifdef DAT_EXTENSIONS\r
-#include <stdarg.h>\r
-extern DAT_RETURN DAT_API dapl_extensions (\r
-       IN      DAT_HANDLE,             /* handle */\r
-       IN      DAT_EXTENDED_OP,        /* extended op */\r
-       IN      va_list);               /* argument list */\r
-#endif\r
-\r
-/*\r
- * DAPL internal utility function prototpyes\r
- */\r
-\r
-extern void dapl_llist_init_head (\r
-    DAPL_LLIST_HEAD *  head);\r
-\r
-extern void dapl_llist_init_entry (\r
-    DAPL_LLIST_ENTRY *         entry);\r
-\r
-extern DAT_BOOLEAN dapl_llist_is_empty (\r
-    DAPL_LLIST_HEAD *  head);\r
-\r
-extern void dapl_llist_add_head (\r
-    DAPL_LLIST_HEAD *  head,\r
-    DAPL_LLIST_ENTRY *         entry,\r
-    void *             data);\r
-\r
-extern void dapl_llist_add_tail (\r
-    DAPL_LLIST_HEAD *   head,\r
-    DAPL_LLIST_ENTRY *  entry,\r
-    void *             data);\r
-\r
-extern void dapl_llist_add_entry (\r
-    DAPL_LLIST_HEAD * head,\r
-    DAPL_LLIST_ENTRY * entry,\r
-    DAPL_LLIST_ENTRY * new_entry,\r
-    void * data);\r
-\r
-extern void * dapl_llist_remove_head (\r
-    DAPL_LLIST_HEAD *  head);\r
-\r
-extern void * dapl_llist_remove_tail (\r
-    DAPL_LLIST_HEAD *  head);\r
-\r
-extern void * dapl_llist_remove_entry (\r
-    DAPL_LLIST_HEAD *  head,\r
-    DAPL_LLIST_ENTRY * entry);\r
-\r
-extern void * dapl_llist_peek_head (\r
-    DAPL_LLIST_HEAD *  head);\r
-\r
-extern void * dapl_llist_next_entry (\r
-    IN    DAPL_LLIST_HEAD      *head,\r
-    IN    DAPL_LLIST_ENTRY     *cur_ent);\r
-\r
-extern void dapl_llist_debug_print_list (\r
-    DAPL_LLIST_HEAD *  head);\r
-\r
-\r
-#endif\r
+/*
+ * Copyright (c) 2002-2005, Network Appliance, 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
+ *    in the file LICENSE.txt in the root directory. The license is also
+ *    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 in the file
+ *    LICENSE2.txt in the root directory. The license is also 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 in the file LICENSE3.txt in the root directory. The 
+ *    license is also 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.h
+ *
+ * PURPOSE: defines common data structures for the DAPL reference implemenation
+ *
+ * Description: This file describes the working data structures used within
+ *              DAPL RI.
+ *
+ *
+ * $Id: dapl.h 1317 2005-04-25 17:29:42Z jlentini $
+ **********************************************************************/
+
+#ifndef _DAPL_H_
+#define _DAPL_H_
+
+#if defined(__KERNEL__)
+#include <dat2/kdat.h>
+#else
+#include <dat2/udat.h>
+#endif /* defined(__KERNEL__) */
+#include <dat2/dat_registry.h>
+#include "dapl_osd.h"
+#include "dapl_debug.h"
+
+
+
+/*********************************************************************
+ *                                                                   *
+ * Enumerations                                                      *
+ *                                                                   *
+ *********************************************************************/
+
+typedef enum dapl_magic
+{
+    /* magic number values for verification & debug */
+    DAPL_MAGIC_IA      = 0xCafeF00d,
+    DAPL_MAGIC_EVD     = 0xFeedFace,
+    DAPL_MAGIC_EP      = 0xDeadBabe,
+    DAPL_MAGIC_LMR     = 0xBeefCafe,
+    DAPL_MAGIC_RMR      = 0xABadCafe,
+    DAPL_MAGIC_PZ      = 0xDeafBeef,
+    DAPL_MAGIC_PSP     = 0xBeadeD0c,
+    DAPL_MAGIC_RSP     = 0xFab4Feed,
+    DAPL_MAGIC_SRQ     = 0xC001Babe,
+    DAPL_MAGIC_CR      = 0xBe12Cee1,
+    DAPL_MAGIC_CR_DESTROYED = 0xB12bDead,
+    DAPL_MAGIC_CNO     = 0xDeadF00d,
+    DAPL_MAGIC_INVALID  = 0xFFFFFFFF
+} DAPL_MAGIC;
+
+typedef enum dapl_evd_state
+{
+    DAPL_EVD_STATE_TERMINAL,
+    DAPL_EVD_STATE_INITIAL,
+    DAPL_EVD_STATE_OPEN,
+    DAPL_EVD_STATE_WAITED,
+    DAPL_EVD_STATE_DEAD        = 0xDEAD
+} DAPL_EVD_STATE;
+
+typedef enum dapl_evd_completion
+{
+    DAPL_EVD_STATE_INIT,
+    DAPL_EVD_STATE_SOLICITED_WAIT,
+    DAPL_EVD_STATE_THRESHOLD,
+    DAPL_EVD_STATE_UNSIGNALLED
+} DAPL_EVD_COMPLETION;
+
+typedef enum dapl_cno_state
+{
+    DAPL_CNO_STATE_UNTRIGGERED,
+    DAPL_CNO_STATE_TRIGGERED,
+    DAPL_CNO_STATE_DEAD = 0xDeadFeed,
+} DAPL_CNO_STATE;
+
+typedef enum dapl_qp_state
+{
+    DAPL_QP_STATE_UNCONNECTED,
+    DAPL_QP_STATE_RESERVED,
+    DAPL_QP_STATE_PASSIVE_CONNECTION_PENDING,
+    DAPL_QP_STATE_ACTIVE_CONNECTION_PENDING,
+    DAPL_QP_STATE_TENTATIVE_CONNECTION_PENDING,
+    DAPL_QP_STATE_CONNECTED,
+    DAPL_QP_STATE_DISCONNECT_PENDING,
+    DAPL_QP_STATE_ERROR,
+    DAPL_QP_STATE_NOT_REUSABLE,
+    DAPL_QP_STATE_FREE
+} DAPL_QP_STATE;
+
+
+/*********************************************************************
+ *                                                                   *
+ * Constants                                                         *
+ *                                                                   *
+ *********************************************************************/
+
+/*
+ * number of HCAs allowed
+ */
+#define DAPL_MAX_HCA_COUNT             4
+
+/*
+ * Configures the RMR bind evd restriction
+ */
+
+#define DAPL_RMR_BIND_EVD_RESTRICTION  DAT_RMR_EVD_SAME_AS_REQUEST_EVD
+
+/*
+ * special qp_state indicating the EP does not have a QP attached yet
+ */
+#define DAPL_QP_STATE_UNATTACHED       0xFFF0
+
+#define DAPL_MAX_PRIVATE_DATA_SIZE     256
+
+/*********************************************************************
+ *                                                                   *
+ * Macros                                                            *
+ *                                                                   *
+ *********************************************************************/
+
+#if defined (sun) || defined(__sun) || defined(_sun_) || defined (__solaris__) 
+#define DAPL_BAD_PTR(a) ((unsigned long)(a) & 3)
+#elif defined(__linux__)
+#define DAPL_BAD_PTR(a) ((unsigned long)(a) & 3)
+#elif defined(_WIN64)
+#define DAPL_BAD_PTR(a) ((unsigned long)((DAT_UINT64)(a)) & 3)
+#elif defined(_WIN32)
+#define DAPL_BAD_PTR(a) ((unsigned long)((DAT_UINT64)(a)) & 3)
+#endif
+
+/*
+ * Simple macro to verify a handle is bad. Conditions:
+ * - pointer is NULL
+ * - pointer is not word aligned
+ * - pointer's magic number is wrong
+ */
+
+#define DAPL_BAD_HANDLE(h, magicNum) (                         \
+           ((h) == NULL) ||                                    \
+           DAPL_BAD_PTR(h) ||                                  \
+           (((DAPL_HEADER *)(h))->magic != (magicNum)))
+
+#define DAPL_MIN(a, b)        ((a < b) ? (a) : (b))
+#define DAPL_MAX(a, b)        ((a > b) ? (a) : (b))
+
+#if NDEBUG > 0
+#define DEBUG_IS_BAD_HANDLE(h, magicNum) (DAPL_BAD_HANDLE(h, magicNum))
+#else
+#define DEBUG_IS_BAD_HANDLE(h, magicNum) (0)
+#endif
+
+#define DAT_ERROR(Type, SubType) ((DAT_RETURN)(DAT_CLASS_ERROR | Type | SubType))
+
+/*********************************************************************
+ *                                                                   *
+ * Typedefs                                                          *
+ *                                                                   *
+ *********************************************************************/
+
+typedef struct dapl_llist_entry                DAPL_LLIST_ENTRY;
+typedef DAPL_LLIST_ENTRY *             DAPL_LLIST_HEAD;
+typedef struct dapl_ring_buffer                DAPL_RING_BUFFER;
+typedef struct dapl_cookie_buffer      DAPL_COOKIE_BUFFER;
+
+typedef struct dapl_hash_table          DAPL_HASH_TABLE;
+typedef struct dapl_hash_table *        DAPL_HASH_TABLEP;
+typedef DAT_UINT64                      DAPL_HASH_KEY;
+typedef void *                          DAPL_HASH_DATA;
+
+typedef struct dapl_hca                        DAPL_HCA;
+
+typedef struct dapl_header             DAPL_HEADER;
+
+typedef struct dapl_ia                 DAPL_IA;
+typedef struct dapl_cno                        DAPL_CNO;
+typedef struct dapl_evd                DAPL_EVD;
+typedef struct dapl_ep                         DAPL_EP;
+typedef struct dapl_srq                        DAPL_SRQ;
+typedef struct dapl_pz                 DAPL_PZ;
+typedef struct dapl_lmr                        DAPL_LMR;
+typedef struct dapl_rmr                        DAPL_RMR;
+typedef struct dapl_sp                 DAPL_SP;
+typedef struct dapl_cr                 DAPL_CR;
+
+typedef struct dapl_cookie             DAPL_COOKIE;
+typedef struct dapl_dto_cookie         DAPL_DTO_COOKIE;
+typedef struct dapl_rmr_cookie         DAPL_RMR_COOKIE;
+
+typedef struct dapl_private            DAPL_PRIVATE;
+
+
+
+/*********************************************************************
+ *                                                                   *
+ * Structures                                                        *
+ *                                                                   *
+ *********************************************************************/
+
+struct dapl_llist_entry
+{
+    struct dapl_llist_entry    *flink;
+    struct dapl_llist_entry    *blink;
+    void                       *data;
+    DAPL_LLIST_HEAD            *list_head; /* for consistency checking */
+};
+
+struct dapl_ring_buffer
+{
+    void               **base;         /* base of element array */
+    DAT_COUNT          lim;            /* mask, number of entries - 1 */
+    DAPL_ATOMIC                head;           /* head pointer index */
+    DAPL_ATOMIC                tail;           /* tail pointer index */
+};
+
+struct dapl_cookie_buffer
+{
+    DAPL_COOKIE                *pool;
+    DAT_COUNT          pool_size;
+    DAPL_ATOMIC                head;
+    DAPL_ATOMIC                tail;
+};
+
+#ifdef IBAPI
+#include "dapl_ibapi_util.h"
+#elif VAPI
+#include "dapl_vapi_util.h"
+#elif __OPENIB__
+#include "dapl_openib_util.h"
+#include "dapl_openib_cm.h"
+#elif DUMMY
+#include "dapl_dummy_util.h"
+#elif OPENIB
+#include "dapl_ib_util.h"
+#else /* windows - IBAL and/or IBAL+Sock_CM */
+#include "dapl_ibal_util.h"
+#endif
+
+struct dapl_hca
+{
+    DAPL_OS_LOCK       lock;
+    DAPL_LLIST_HEAD    ia_list_head;      /* list of all open IAs */
+    DAPL_ATOMIC                handle_ref_count;  /* count of ia_opens on handle */
+    DAPL_EVD           *async_evd;
+    DAPL_EVD           *async_error_evd;
+    DAT_SOCK_ADDR6     hca_address;       /* local address of HCA*/
+    char               *name;             /* provider name */
+    ib_hca_handle_t    ib_hca_handle;
+    unsigned long       port_num;         /* physical port number */
+    ib_hca_transport_t  ib_trans;         /* Values specific transport API */
+    /* Memory Subsystem Support */
+    DAPL_HASH_TABLE    *lmr_hash_table;
+    /* Limits & useful HCA attributes */
+    DAT_IA_ATTR                ia_attr;
+};
+
+/* DAPL Objects always have the following header */
+struct dapl_header
+{
+    DAT_PROVIDER       *provider;      /* required by DAT - must be first */
+    DAPL_MAGIC         magic;          /* magic number for verification */
+    DAT_HANDLE_TYPE    handle_type;    /* struct type */
+    DAPL_IA            *owner_ia;      /* ia which owns this stuct */
+    DAPL_LLIST_ENTRY   ia_list_entry;  /* link entry on ia struct */
+    DAT_CONTEXT                user_context;   /* user context - opaque to DAPL */
+    DAPL_OS_LOCK       lock;           /* lock - in header for easier macros */
+};
+
+/* DAPL_IA maps to DAT_IA_HANDLE */
+struct dapl_ia
+{
+    DAPL_HEADER                header;
+    DAPL_HCA           *hca_ptr;
+    DAPL_EVD           *async_error_evd;
+    DAT_BOOLEAN                cleanup_async_error_evd;
+
+    DAPL_LLIST_ENTRY   hca_ia_list_entry;      /* HCAs list of IAs */
+    DAPL_LLIST_HEAD    ep_list_head;           /* EP queue */
+    DAPL_LLIST_HEAD    lmr_list_head;          /* LMR queue */
+    DAPL_LLIST_HEAD    rmr_list_head;          /* RMR queue */
+    DAPL_LLIST_HEAD    pz_list_head;           /* PZ queue */
+    DAPL_LLIST_HEAD    evd_list_head;          /* EVD queue */
+    DAPL_LLIST_HEAD    cno_list_head;          /* CNO queue */
+    DAPL_LLIST_HEAD    psp_list_head;          /* PSP queue */
+    DAPL_LLIST_HEAD    rsp_list_head;          /* RSP queue */
+    DAPL_LLIST_HEAD    srq_list_head;          /* SRQ queue */
+#ifdef DAPL_COUNTERS
+    void               *cntrs;
+#endif
+};
+
+/* DAPL_CNO maps to DAT_CNO_HANDLE */
+struct dapl_cno
+{
+    DAPL_HEADER        header;
+
+    /* A CNO cannot be freed while it is referenced elsewhere.  */
+    DAPL_ATOMIC                        cno_ref_count;
+    DAPL_CNO_STATE             cno_state;
+
+    DAT_COUNT                  cno_waiters;
+    DAPL_EVD                   *cno_evd_triggered;
+#if defined(__KERNEL__)
+    DAT_UPCALL_OBJECT          cno_upcall;
+    DAT_UPCALL_POLICY          cno_upcall_policy;
+#else
+    DAT_OS_WAIT_PROXY_AGENT    cno_wait_agent;
+#endif /* defined(__KERNEL__) */
+
+    DAPL_OS_WAIT_OBJECT                cno_wait_object;
+};
+
+/* DAPL_EVD maps to DAT_EVD_HANDLE */
+struct dapl_evd
+{
+    DAPL_HEADER                header;
+
+    DAPL_EVD_STATE     evd_state;
+    DAT_EVD_FLAGS      evd_flags;
+    DAT_BOOLEAN                evd_enabled; /* For attached CNO.  */
+    DAT_BOOLEAN                evd_waitable; /* EVD state.  */
+
+    /* Derived from evd_flags; see dapls_evd_internal_create.  */
+    DAT_BOOLEAN                evd_producer_locking_needed;
+
+    /* Every EVD has a CQ unless it is a SOFTWARE_EVENT only EVD */
+    ib_cq_handle_t     ib_cq_handle;
+
+    /* An Event Dispatcher cannot be freed while
+     * it is referenced elsewhere.
+     */
+    DAPL_ATOMIC                evd_ref_count;
+
+    /* Set if there has been a catastrophic overflow */
+    DAT_BOOLEAN                catastrophic_overflow;
+
+    /* the actual events */
+    DAT_COUNT          qlen;
+    DAT_EVENT          *events;
+    DAPL_RING_BUFFER   free_event_queue;
+    DAPL_RING_BUFFER   pending_event_queue;
+
+    /* CQ Completions are not placed into 'deferred_events'
+     ** rather they are simply left on the Completion Queue
+     ** and the fact that there was a notification is flagged.
+     */
+    DAT_BOOLEAN                cq_notified;
+    DAPL_OS_TICKS      cq_notified_when;
+
+    DAT_COUNT          cno_active_count;
+    DAPL_CNO           *cno_ptr;
+
+    DAPL_OS_WAIT_OBJECT        wait_object;
+
+    DAT_COUNT          threshold;
+    DAPL_EVD_COMPLETION        completion_type;
+
+#ifdef DAPL_COUNTERS
+    void               *cntrs;
+#endif
+};
+
+/* DAPL_PRIVATE used to pass private data in a connection */
+struct dapl_private
+{
+#ifdef IBHOSTS_NAMING
+    DAT_SOCK_ADDR6             hca_address;    /* local address of HCA*/
+#endif /* IBHOSTS_NAMING */
+    unsigned char              private_data[DAPL_MAX_PRIVATE_DATA_SIZE];
+};
+
+/* uDAPL timer entry, used to queue timeouts */
+struct dapl_timer_entry
+{
+    DAPL_LLIST_ENTRY           list_entry;     /* link entry on ia struct */
+    DAPL_OS_TIMEVAL            expires;
+    void                       (*function) (uintptr_t);
+    void                       *data;
+};
+
+#ifdef DAPL_DBG_IO_TRC
+
+#define DBG_IO_TRC_QLEN   32           /* length of trace buffer        */
+#define DBG_IO_TRC_IOV 3               /* iov elements we keep track of */
+
+struct io_buf_track
+{
+    Ib_send_op_type            op_type;
+    DAPL_COOKIE                        *cookie;
+    DAT_LMR_TRIPLET            iov[DBG_IO_TRC_IOV];
+    DAT_RMR_TRIPLET            remote_iov;
+    unsigned int               done;   /* count to track completion ordering */
+    int                                status;
+    void                       *wqe;
+};
+
+#endif /* DAPL_DBG_IO_TRC */
+
+/* DAPL_EP maps to DAT_EP_HANDLE */
+struct dapl_ep
+{
+    DAPL_HEADER                        header;
+    /* What the DAT Consumer asked for */
+    DAT_EP_PARAM               param;
+
+    /* The RC Queue Pair (IBM OS API) */
+    ib_qp_handle_t             qp_handle;
+    unsigned int               qpn;    /* qp number */
+    ib_qp_state_t              qp_state;
+
+    /* communications manager handle (IBM OS API) */
+   // dp_ib_cm_handle_t                cm_handle;
+
+    /* Add support for multiple CM object ownership */
+    DAPL_LLIST_HEAD            cm_list_head;   
+
+    /* store the remote IA address here, reference from the param
+     * struct which only has a pointer, no storage
+     */
+    DAT_SOCK_ADDR6             remote_ia_address;
+
+    /* For passive connections we maintain a back pointer to the CR */
+    void *                     cr_ptr;
+
+    /* pointer to connection timer, if set */
+    struct dapl_timer_entry    *cxn_timer;
+
+    /* private data container */
+    DAPL_PRIVATE               private;
+
+    /* DTO data */
+    DAPL_ATOMIC                        req_count;
+    DAPL_ATOMIC                        recv_count;
+
+    DAPL_COOKIE_BUFFER req_buffer;
+    DAPL_COOKIE_BUFFER recv_buffer;
+
+#ifdef DAPL_DBG_IO_TRC
+    int                        ibt_dumped;
+    struct io_buf_track *ibt_base;
+    DAPL_RING_BUFFER   ibt_queue;
+#endif /* DAPL_DBG_IO_TRC */
+#if defined(_WIN32) || defined(_WIN64)
+    DAT_BOOLEAN         recv_discreq;
+    DAT_BOOLEAN         sent_discreq;
+#endif
+#ifdef DAPL_COUNTERS
+    void               *cntrs;
+#endif
+};
+
+/* DAPL_SRQ maps to DAT_SRQ_HANDLE */
+struct dapl_srq
+{
+    DAPL_HEADER                header;
+    DAT_SRQ_PARAM      param;
+    DAPL_ATOMIC                srq_ref_count;
+    DAPL_COOKIE_BUFFER recv_buffer;
+    DAPL_ATOMIC                recv_count;
+};
+
+/* DAPL_PZ maps to DAT_PZ_HANDLE */
+struct dapl_pz
+{
+    DAPL_HEADER                header;
+    ib_pd_handle_t     pd_handle;
+    DAPL_ATOMIC                pz_ref_count;
+};
+
+/* DAPL_LMR maps to DAT_LMR_HANDLE */
+struct dapl_lmr
+{
+    DAPL_HEADER                header;
+    DAT_LMR_PARAM      param;
+    ib_mr_handle_t     mr_handle;
+    DAPL_ATOMIC                lmr_ref_count;
+#if !defined(__KDAPL__)
+    char               shmid[DAT_LMR_COOKIE_SIZE]; /* shared memory ID */
+    ib_shm_transport_t ib_trans;       /* provider specific data */
+#endif /* !__KDAPL__ */
+};
+
+/* DAPL_RMR maps to DAT_RMR_HANDLE */
+struct dapl_rmr
+{
+    DAPL_HEADER                header;
+    DAT_RMR_PARAM      param;
+    DAPL_EP             *ep;
+    DAPL_PZ             *pz;
+    DAPL_LMR            *lmr;
+    ib_mw_handle_t     mw_handle;
+};
+
+/* SP types, indicating the state and queue */
+typedef enum dapl_sp_state
+{
+    DAPL_SP_STATE_FREE,
+    DAPL_SP_STATE_PSP_LISTENING,
+    DAPL_SP_STATE_PSP_PENDING,
+    DAPL_SP_STATE_RSP_LISTENING,
+    DAPL_SP_STATE_RSP_PENDING
+} DAPL_SP_STATE;
+
+/* DAPL_SP maps to DAT_PSP_HANDLE and DAT_RSP_HANDLE */
+struct dapl_sp
+{
+    DAPL_HEADER                header;
+    DAPL_SP_STATE      state;          /* type and queue of the SP */
+
+    /* PSP/RSP PARAM fields */
+    DAT_CONN_QUAL       conn_qual;
+    DAT_EVD_HANDLE      evd_handle;
+    DAT_PSP_FLAGS       psp_flags;
+    DAT_EP_HANDLE       ep_handle;
+
+     /* maintenence fields */
+    DAT_BOOLEAN                listening;      /* PSP is registered & active */
+    ib_cm_srvc_handle_t        cm_srvc_handle; /* Used by Mellanox CM */
+    DAPL_LLIST_HEAD    cr_list_head;   /* CR pending queue */
+    DAT_COUNT          cr_list_count;  /* count of CRs on queue */
+#if defined(_VENDOR_IBAL_)
+    DAPL_OS_WAIT_OBJECT wait_object;    /* cancel & destroy. */
+#endif
+};
+
+/* DAPL_CR maps to DAT_CR_HANDLE */
+struct dapl_cr
+{
+    DAPL_HEADER                header;
+
+    /* for convenience the data is kept as a DAT_CR_PARAM.
+     * however, the "local_endpoint" field is always NULL
+     * so this wastes a pointer. This is probably ok to
+     * simplify code, espedially dat_cr_query.
+     */
+    DAT_CR_PARAM       param;
+    /* IB specific fields */
+    dp_ib_cm_handle_t  ib_cm_handle;
+
+    DAT_SOCK_ADDR6     remote_ia_address;
+    /* Assuming that the maximum private data size is small.
+     * If it gets large, use of a pointer may be appropriate.
+     */
+    unsigned char      private_data[DAPL_MAX_PRIVATE_DATA_SIZE];
+    /*
+     * Need to be able to associate the CR back to the PSP for
+     * dapl_cr_reject.
+     */
+    DAPL_SP            *sp_ptr;
+};
+
+typedef enum dapl_dto_type
+{
+    DAPL_DTO_TYPE_SEND,
+    DAPL_DTO_TYPE_RECV,
+    DAPL_DTO_TYPE_RDMA_WRITE,
+    DAPL_DTO_TYPE_RDMA_READ,
+#ifdef DAT_EXTENSIONS
+    DAPL_DTO_TYPE_EXTENSION,
+#endif
+} DAPL_DTO_TYPE;
+
+typedef enum dapl_cookie_type
+{
+    DAPL_COOKIE_TYPE_NULL,
+    DAPL_COOKIE_TYPE_DTO,
+    DAPL_COOKIE_TYPE_RMR,
+} DAPL_COOKIE_TYPE;
+
+/* DAPL_DTO_COOKIE used as context for DTO WQEs */
+struct dapl_dto_cookie
+{
+    DAPL_DTO_TYPE              type;
+    DAT_DTO_COOKIE             cookie;
+    DAT_COUNT                  size;   /* used for SEND and RDMA write */
+};
+
+/* DAPL_RMR_COOKIE used as context for bind WQEs */
+struct dapl_rmr_cookie
+{
+    DAPL_RMR                   *rmr;
+    DAT_RMR_COOKIE              cookie;
+};
+
+/* DAPL_COOKIE used as context for WQEs */
+struct dapl_cookie
+{
+    DAPL_COOKIE_TYPE           type; /* Must be first, to define struct.  */
+    DAPL_EP                    *ep;
+    DAT_COUNT                  index;
+    union
+    {
+       DAPL_DTO_COOKIE         dto;
+       DAPL_RMR_COOKIE         rmr;
+    } val;
+};
+
+/*
+ * Private Data operations. Used to obtain the size of the private
+ * data from the provider layer.
+ */
+typedef enum dapl_private_data_op
+{
+    DAPL_PDATA_CONN_REQ  = 0,          /* connect request    */
+    DAPL_PDATA_CONN_REP  = 1,          /* connect reply      */
+    DAPL_PDATA_CONN_REJ  = 2,          /* connect reject     */
+    DAPL_PDATA_CONN_DREQ = 3,          /* disconnect request */
+    DAPL_PDATA_CONN_DREP = 4,          /* disconnect reply   */
+} DAPL_PDATA_OP;
+
+
+/*
+ * Generic HCA name field
+ */
+#define DAPL_HCA_NAME_MAX_LEN 260
+typedef char DAPL_HCA_NAME[DAPL_HCA_NAME_MAX_LEN+1];
+
+#ifdef IBHOSTS_NAMING
+
+/*
+ * Simple mapping table to match IP addresses to GIDs. Loaded
+ * by dapl_init.
+ */
+typedef struct _dapl_gid_map_table
+{
+    uint32_t           ip_address;
+    ib_gid_t           gid;
+} DAPL_GID_MAP;
+
+#endif /* IBHOSTS_NAMING */
+
+/*
+ * IBTA defined reason for reject message: See IBTA 1.1 specification,
+ * 12.6.7.2 REJECTION REASON section.
+ */
+#define IB_CM_REJ_REASON_CONSUMER_REJ            0x001C
+
+
+#if defined(DAPL_DBG_IO_TRC)
+/*********************************************************************
+ *                                                                   *
+ * Debug I/O tracing support prototypes                              *
+ *                                                                   *
+ *********************************************************************/
+/*
+ * I/O tracing support
+ */
+void dapls_io_trc_alloc (
+    DAPL_EP                    *ep_ptr);
+
+void dapls_io_trc_update_completion (
+    DAPL_EP                    *ep_ptr,
+    DAPL_COOKIE                        *cookie,
+    ib_uint32_t                        ib_status );
+
+void dapls_io_trc_dump (
+    DAPL_EP                    *ep_ptr,
+    ib_work_completion_t       *cqe_ptr,
+    ib_uint32_t                        ib_status);
+
+#else /* DAPL_DBG_IO_TRC */
+
+#define dapls_io_trc_alloc(a)
+#define dapls_io_trc_update_completion(a, b, c)
+#define dapls_io_trc_dump(a, b, c)
+
+#endif /* DAPL_DBG_IO_TRC */
+
+
+/*********************************************************************
+ *                                                                   *
+ * Function Prototypes                                               *
+ *                                                                   *
+ *********************************************************************/
+
+typedef void (*DAPL_CONNECTION_STATE_HANDLER) (
+       IN      DAPL_EP *,
+       IN      ib_cm_events_t,
+       IN      const void *,
+       OUT     DAT_EVENT *);
+
+/*
+ * DAT Mandated functions
+ */
+
+extern DAT_RETURN DAT_API dapl_ia_open (
+       IN      const DAT_NAME_PTR,     /* name */
+       IN      DAT_COUNT,              /* asynch_evd_qlen */
+       INOUT   DAT_EVD_HANDLE *,       /* asynch_evd_handle */
+       OUT     DAT_IA_HANDLE *);       /* ia_handle */
+
+extern DAT_RETURN DAT_API dapl_ia_close (
+       IN      DAT_IA_HANDLE,          /* ia_handle */
+       IN      DAT_CLOSE_FLAGS );      /* ia_flags */
+
+
+extern DAT_RETURN DAT_API dapl_ia_query (
+       IN      DAT_IA_HANDLE,          /* ia handle */
+       OUT     DAT_EVD_HANDLE *,       /* async_evd_handle */
+       IN      DAT_IA_ATTR_MASK,       /* ia_params_mask */
+       OUT     DAT_IA_ATTR *,          /* ia_params */
+       IN      DAT_PROVIDER_ATTR_MASK, /* provider_params_mask */
+       OUT     DAT_PROVIDER_ATTR * );  /* provider_params */
+
+
+/* helper functions */
+
+extern DAT_RETURN DAT_API dapl_set_consumer_context (
+       IN      DAT_HANDLE,                     /* dat handle */
+       IN      DAT_CONTEXT);                   /* context */
+
+extern DAT_RETURN DAT_API dapl_get_consumer_context (
+       IN      DAT_HANDLE,                     /* dat handle */
+       OUT     DAT_CONTEXT * );                /* context */
+
+extern DAT_RETURN DAT_API dapl_get_handle_type (
+       IN      DAT_HANDLE,
+       OUT     DAT_HANDLE_TYPE * );
+
+/* CNO functions */
+
+#if !defined(__KERNEL__)
+extern DAT_RETURN DAT_API dapl_cno_create (
+       IN      DAT_IA_HANDLE,                  /* ia_handle */
+       IN      DAT_OS_WAIT_PROXY_AGENT,        /* agent */
+       OUT     DAT_CNO_HANDLE *);              /* cno_handle */
+
+extern DAT_RETURN DAT_API dapl_cno_modify_agent (
+       IN      DAT_CNO_HANDLE,                 /* cno_handle */
+       IN      DAT_OS_WAIT_PROXY_AGENT);       /* agent */
+
+extern DAT_RETURN DAT_API dapl_cno_query (
+       IN      DAT_CNO_HANDLE,         /* cno_handle */
+       IN      DAT_CNO_PARAM_MASK,     /* cno_param_mask */
+       OUT     DAT_CNO_PARAM * );      /* cno_param */
+
+extern DAT_RETURN DAT_API dapl_cno_free (
+       IN      DAT_CNO_HANDLE);        /* cno_handle */
+
+extern DAT_RETURN DAT_API dapl_cno_wait (
+       IN      DAT_CNO_HANDLE,         /* cno_handle */
+       IN      DAT_TIMEOUT,            /* timeout */
+       OUT     DAT_EVD_HANDLE *);      /* evd_handle */
+
+extern DAT_RETURN DAT_API dapl_cno_fd_create (
+       IN      DAT_IA_HANDLE,          /* ia_handle            */
+       OUT     DAT_FD *,               /* file_descriptor      */
+       OUT     DAT_CNO_HANDLE *);      /* cno_handle           */
+
+extern DAT_RETURN DAT_API dapl_cno_trigger (
+       IN      DAT_CNO_HANDLE,         /* cno_handle */
+       OUT     DAT_EVD_HANDLE *);      /* evd_handle */
+
+#endif /* !defined(__KERNEL__) */
+
+/* CR Functions */
+
+extern DAT_RETURN DAT_API dapl_cr_query (
+       IN      DAT_CR_HANDLE,          /* cr_handle */
+       IN      DAT_CR_PARAM_MASK,      /* cr_args_mask */
+       OUT     DAT_CR_PARAM * );       /* cwr_args */
+
+extern DAT_RETURN DAT_API dapl_cr_accept (
+       IN      DAT_CR_HANDLE,          /* cr_handle */
+       IN      DAT_EP_HANDLE,          /* ep_handle */
+       IN      DAT_COUNT,              /* private_data_size */
+       IN      const DAT_PVOID );      /* private_data */
+
+extern DAT_RETURN DAT_API dapl_cr_reject (
+       IN      DAT_CR_HANDLE,          /* cr_handle            */
+       IN      DAT_COUNT,              /* private_data_size    */
+       IN      const DAT_PVOID );      /* private_data         */
+
+extern DAT_RETURN DAT_API dapl_cr_handoff (
+       IN DAT_CR_HANDLE,               /* cr_handle */
+       IN DAT_CONN_QUAL);              /* handoff */
+
+/* EVD Functions */
+
+#if defined(__KERNEL__)
+extern DAT_RETURN DAT_API dapl_ia_memtype_hint (
+       IN    DAT_IA_HANDLE,            /* ia_handle */
+       IN    DAT_MEM_TYPE,             /* mem_type */
+       IN    DAT_VLEN,                 /* length */
+       IN    DAT_MEM_OPT,              /* mem_optimization */
+       OUT   DAT_VLEN *,               /* suggested_length */
+       OUT   DAT_VADDR *);             /* suggested_alignment */
+
+extern DAT_RETURN DAT_API dapl_evd_kcreate (
+       IN      DAT_IA_HANDLE,          /* ia_handle */
+       IN      DAT_COUNT,              /* evd_min_qlen */
+       IN      DAT_UPCALL_POLICY,      /* upcall_policy */
+       IN      const DAT_UPCALL_OBJECT *, /* upcall */
+       IN      DAT_EVD_FLAGS,          /* evd_flags */
+       OUT     DAT_EVD_HANDLE * );     /* evd_handle */
+
+extern DAT_RETURN DAT_API dapl_evd_kquery (
+       IN      DAT_EVD_HANDLE,         /* evd_handle */
+       IN      DAT_EVD_PARAM_MASK,     /* evd_args_mask */
+       OUT     DAT_EVD_PARAM * );      /* evd_args */
+
+#else
+extern DAT_RETURN DAT_API dapl_evd_create (
+       IN      DAT_IA_HANDLE,          /* ia_handle */
+       IN      DAT_COUNT,              /* evd_min_qlen */
+       IN      DAT_CNO_HANDLE,         /* cno_handle */
+       IN      DAT_EVD_FLAGS,          /* evd_flags */
+       OUT     DAT_EVD_HANDLE * );     /* evd_handle */
+
+extern DAT_RETURN DAT_API dapl_evd_query (
+       IN      DAT_EVD_HANDLE,         /* evd_handle */
+       IN      DAT_EVD_PARAM_MASK,     /* evd_args_mask */
+       OUT     DAT_EVD_PARAM * );      /* evd_args */
+#endif /* defined(__KERNEL__) */
+
+#if defined(__KERNEL__)
+extern DAT_RETURN DAT_API dapl_evd_modify_upcall (
+       IN      DAT_EVD_HANDLE,         /* evd_handle */
+       IN      DAT_UPCALL_POLICY,      /* upcall_policy */
+       IN      const DAT_UPCALL_OBJECT * ); /* upcall */
+
+#else
+
+extern DAT_RETURN DAT_API dapl_evd_modify_cno (
+       IN      DAT_EVD_HANDLE,         /* evd_handle */
+       IN      DAT_CNO_HANDLE);        /* cno_handle */
+#endif
+
+extern DAT_RETURN DAT_API dapl_evd_enable (
+       IN      DAT_EVD_HANDLE);        /* evd_handle */
+
+extern DAT_RETURN DAT_API dapl_evd_disable (
+       IN      DAT_EVD_HANDLE);        /* evd_handle */
+
+#if !defined(__KERNEL__)
+extern DAT_RETURN DAT_API dapl_evd_wait (
+       IN      DAT_EVD_HANDLE,         /* evd_handle */
+       IN      DAT_TIMEOUT,            /* timeout */
+       IN      DAT_COUNT,              /* threshold */
+       OUT     DAT_EVENT *,            /* event */
+       OUT     DAT_COUNT *);           /* nmore */
+#endif /* !defined(__KERNEL__) */
+
+extern DAT_RETURN DAT_API dapl_evd_resize (
+       IN      DAT_EVD_HANDLE,         /* evd_handle */
+       IN      DAT_COUNT );            /* evd_qlen */
+
+extern DAT_RETURN DAT_API dapl_evd_post_se (
+       DAT_EVD_HANDLE,                 /* evd_handle */
+       const DAT_EVENT * );            /* event */
+
+extern DAT_RETURN DAT_API dapl_evd_dequeue (
+       IN      DAT_EVD_HANDLE,         /* evd_handle */
+       OUT     DAT_EVENT * );          /* event */
+
+extern DAT_RETURN DAT_API dapl_evd_free (
+       IN      DAT_EVD_HANDLE );
+
+extern DAT_RETURN DAT_API
+dapl_evd_set_unwaitable (
+       IN      DAT_EVD_HANDLE  evd_handle );
+
+extern DAT_RETURN DAT_API
+dapl_evd_clear_unwaitable (
+       IN      DAT_EVD_HANDLE  evd_handle );
+
+/* EP functions */
+
+extern DAT_RETURN DAT_API dapl_ep_create (
+       IN      DAT_IA_HANDLE,          /* ia_handle */
+       IN      DAT_PZ_HANDLE,          /* pz_handle */
+       IN      DAT_EVD_HANDLE,         /* in_dto_completion_evd_handle */
+       IN      DAT_EVD_HANDLE,         /* out_dto_completion_evd_handle */
+       IN      DAT_EVD_HANDLE,         /* connect_evd_handle */
+       IN      const DAT_EP_ATTR *,    /* ep_parameters */
+       OUT     DAT_EP_HANDLE * );      /* ep_handle */
+
+extern DAT_RETURN DAT_API dapl_ep_query (
+       IN      DAT_EP_HANDLE,          /* ep_handle */
+       IN      DAT_EP_PARAM_MASK,      /* ep_args_mask */
+       OUT     DAT_EP_PARAM * );       /* ep_args */
+
+extern DAT_RETURN DAT_API dapl_ep_modify (
+       IN      DAT_EP_HANDLE,          /* ep_handle */
+       IN      DAT_EP_PARAM_MASK,      /* ep_args_mask */
+       IN      const DAT_EP_PARAM * ); /* ep_args */
+
+extern DAT_RETURN DAT_API dapl_ep_connect (
+       IN      DAT_EP_HANDLE,          /* ep_handle */
+       IN      DAT_IA_ADDRESS_PTR,     /* remote_ia_address */
+       IN      DAT_CONN_QUAL,          /* remote_conn_qual */
+       IN      DAT_TIMEOUT,            /* timeout */
+       IN      DAT_COUNT,              /* private_data_size */
+       IN      const DAT_PVOID,        /* private_data  */
+       IN      DAT_QOS,                /* quality_of_service */
+       IN      DAT_CONNECT_FLAGS );    /* connect_flags */
+
+extern DAT_RETURN DAT_API dapl_ep_common_connect (
+       IN      DAT_EP_HANDLE ep,               /* ep_handle            */
+       IN      DAT_IA_ADDRESS_PTR remote_addr, /* remote_ia_address    */
+       IN      DAT_TIMEOUT timeout,            /* timeout              */
+       IN      DAT_COUNT pdata_size,           /* private_data_size    */
+       IN      const DAT_PVOID pdata   );      /* private_data         */
+
+extern DAT_RETURN DAT_API dapl_ep_dup_connect (
+       IN      DAT_EP_HANDLE,          /* ep_handle */
+       IN      DAT_EP_HANDLE,          /* ep_dup_handle */
+       IN      DAT_TIMEOUT,            /* timeout*/
+       IN      DAT_COUNT,              /* private_data_size */
+       IN      const DAT_PVOID,        /* private_data */
+       IN      DAT_QOS);               /* quality_of_service */
+
+extern DAT_RETURN DAT_API dapl_ep_disconnect (
+       IN      DAT_EP_HANDLE,          /* ep_handle */
+       IN      DAT_CLOSE_FLAGS );      /* close_flags */
+
+extern DAT_RETURN DAT_API dapl_ep_post_send (
+       IN      DAT_EP_HANDLE,          /* ep_handle */
+       IN      DAT_COUNT,              /* num_segments */
+       IN      DAT_LMR_TRIPLET *,      /* local_iov */
+       IN      DAT_DTO_COOKIE,         /* user_cookie */
+       IN      DAT_COMPLETION_FLAGS ); /* completion_flags */
+
+extern DAT_RETURN DAT_API dapl_ep_post_recv (
+       IN      DAT_EP_HANDLE,          /* ep_handle */
+       IN      DAT_COUNT,              /* num_segments */
+       IN      DAT_LMR_TRIPLET *,      /* local_iov */
+       IN      DAT_DTO_COOKIE,         /* user_cookie */
+       IN      DAT_COMPLETION_FLAGS ); /* completion_flags */
+
+extern DAT_RETURN DAT_API dapl_ep_post_rdma_read (
+       IN      DAT_EP_HANDLE,           /* ep_handle */
+       IN      DAT_COUNT,               /* num_segments */
+       IN      DAT_LMR_TRIPLET *,       /* local_iov */
+       IN      DAT_DTO_COOKIE,          /* user_cookie */
+       IN      const DAT_RMR_TRIPLET *, /* remote_iov */
+       IN      DAT_COMPLETION_FLAGS );  /* completion_flags */
+
+extern DAT_RETURN DAT_API dapl_ep_post_rdma_read_to_rmr (
+       IN      DAT_EP_HANDLE,          /* ep_handle            */
+       IN      const DAT_RMR_TRIPLET *,/* local_iov            */
+       IN      DAT_DTO_COOKIE,         /* user_cookie          */
+       IN      const DAT_RMR_TRIPLET *,/* remote_iov           */
+       IN      DAT_COMPLETION_FLAGS);  /* completion_flags     */
+
+extern DAT_RETURN DAT_API dapl_ep_post_rdma_write (
+       IN      DAT_EP_HANDLE,           /* ep_handle */
+       IN      DAT_COUNT,               /* num_segments */
+       IN      DAT_LMR_TRIPLET *,       /* local_iov */
+       IN      DAT_DTO_COOKIE,          /* user_cookie */
+       IN      const DAT_RMR_TRIPLET *, /* remote_iov */
+       IN      DAT_COMPLETION_FLAGS );  /* completion_flags */
+
+extern DAT_RETURN DAT_API dapl_ep_post_send_with_invalidate (
+       IN      DAT_EP_HANDLE,          /* ep_handle            */
+       IN      DAT_COUNT,              /* num_segments         */
+       IN      DAT_LMR_TRIPLET *,      /* local_iov            */
+       IN      DAT_DTO_COOKIE,         /* user_cookie          */
+       IN      DAT_COMPLETION_FLAGS,   /* completion_flags     */
+       IN      DAT_BOOLEAN,            /* invalidate_flag      */
+       IN      DAT_RMR_CONTEXT);      /* RMR context          */
+
+extern DAT_RETURN DAT_API dapl_ep_get_status (
+       IN      DAT_EP_HANDLE,          /* ep_handle */
+       OUT     DAT_EP_STATE *,         /* ep_state */
+       OUT     DAT_BOOLEAN *,          /* in_dto_idle */
+       OUT     DAT_BOOLEAN * );        /* out_dto_idle */
+
+extern DAT_RETURN DAT_API dapl_ep_free (
+       IN      DAT_EP_HANDLE);         /* ep_handle */
+
+extern DAT_RETURN DAT_API dapl_ep_reset (
+       IN      DAT_EP_HANDLE);         /* ep_handle */
+
+extern DAT_RETURN DAT_API dapl_ep_create_with_srq (
+        IN      DAT_IA_HANDLE,          /* ia_handle            */
+        IN      DAT_PZ_HANDLE,          /* pz_handle            */
+        IN      DAT_EVD_HANDLE,         /* recv_evd_handle      */
+        IN      DAT_EVD_HANDLE,         /* request_evd_handle   */
+        IN      DAT_EVD_HANDLE,         /* connect_evd_handle   */
+        IN      DAT_SRQ_HANDLE,         /* srq_handle           */
+        IN      const DAT_EP_ATTR *,    /* ep_attributes        */
+        OUT     DAT_EP_HANDLE *);       /* ep_handle            */
+
+extern DAT_RETURN DAT_API dapl_ep_recv_query (
+        IN      DAT_EP_HANDLE,          /* ep_handle            */
+        OUT     DAT_COUNT *,            /* nbufs_allocated      */
+        OUT     DAT_COUNT *);           /* bufs_alloc_span      */
+
+extern DAT_RETURN DAT_API dapl_ep_set_watermark (
+        IN      DAT_EP_HANDLE,          /* ep_handle            */
+        IN      DAT_COUNT,              /* soft_high_watermark  */
+        IN      DAT_COUNT);             /* hard_high_watermark  */
+
+/* LMR functions */
+
+#if defined(__KERNEL__)
+extern DAT_RETURN DAT_API dapl_lmr_kcreate (
+       IN      DAT_IA_HANDLE,          /* ia_handle */
+       IN      DAT_MEM_TYPE,           /* mem_type */
+       IN      DAT_REGION_DESCRIPTION, /* region_description */
+       IN      DAT_VLEN,               /* length */
+       IN      DAT_PZ_HANDLE,          /* pz_handle */
+       IN      DAT_MEM_PRIV_FLAGS,     /* privileges */
+       IN      DAT_VA_TYPE,            /* va_type */
+       IN      DAT_MEM_OPT,            /* optimization */
+       OUT     DAT_LMR_HANDLE *,       /* lmr_handle */
+       OUT     DAT_LMR_CONTEXT *,      /* lmr_context */
+       OUT     DAT_RMR_CONTEXT *,      /* rmr_context          */
+       OUT     DAT_VLEN *,             /* registered_length */
+       OUT     DAT_VADDR * );          /* registered_address */
+#else
+extern DAT_RETURN DAT_API dapl_lmr_create (
+       IN      DAT_IA_HANDLE,          /* ia_handle */
+       IN      DAT_MEM_TYPE,           /* mem_type */
+       IN      DAT_REGION_DESCRIPTION, /* region_description */
+       IN      DAT_VLEN,               /* length */
+       IN      DAT_PZ_HANDLE,          /* pz_handle */
+       IN      DAT_MEM_PRIV_FLAGS,     /* privileges */
+       IN      DAT_VA_TYPE,            /* va_type */
+       OUT     DAT_LMR_HANDLE *,       /* lmr_handle */
+       OUT     DAT_LMR_CONTEXT *,      /* lmr_context */
+       OUT     DAT_RMR_CONTEXT *,      /* rmr_context          */
+       OUT     DAT_VLEN *,             /* registered_length */
+       OUT     DAT_VADDR * );          /* registered_address */
+#endif /* defined(__KERNEL__) */
+
+extern DAT_RETURN DAT_API dapl_lmr_query (
+       IN      DAT_LMR_HANDLE,
+       IN      DAT_LMR_PARAM_MASK,
+       OUT     DAT_LMR_PARAM *);
+
+extern DAT_RETURN DAT_API dapl_lmr_free (
+       IN      DAT_LMR_HANDLE);
+
+extern DAT_RETURN DAT_API dapl_lmr_sync_rdma_read (
+       IN      DAT_IA_HANDLE,          /* ia_handle            */
+       IN      const DAT_LMR_TRIPLET *, /* local_segments      */
+       IN      DAT_VLEN);              /* num_segments         */
+
+extern DAT_RETURN DAT_API dapl_lmr_sync_rdma_write (
+       IN      DAT_IA_HANDLE,          /* ia_handle            */
+       IN      const DAT_LMR_TRIPLET *, /* local_segments      */
+       IN      DAT_VLEN);              /* num_segments         */
+
+/* RMR Functions */
+
+extern DAT_RETURN DAT_API dapl_rmr_create (
+       IN      DAT_PZ_HANDLE,          /* pz_handle */
+       OUT     DAT_RMR_HANDLE *);      /* rmr_handle */
+
+extern DAT_RETURN DAT_API dapl_rmr_create_for_ep (
+       IN      DAT_PZ_HANDLE pz_handle,        /* pz_handle    */
+       OUT     DAT_RMR_HANDLE *rmr_handle);    /* rmr_handle   */
+
+extern DAT_RETURN DAT_API dapl_rmr_query (
+       IN      DAT_RMR_HANDLE,         /* rmr_handle */
+       IN      DAT_RMR_PARAM_MASK,     /* rmr_args_mask */
+       OUT     DAT_RMR_PARAM *);       /* rmr_args */
+
+extern DAT_RETURN DAT_API dapl_rmr_bind (
+       IN      DAT_RMR_HANDLE,          /* rmr_handle */
+       IN      DAT_LMR_HANDLE,          /* lmr_handle */
+       IN      const DAT_LMR_TRIPLET *, /* lmr_triplet */
+       IN      DAT_MEM_PRIV_FLAGS,      /* mem_priv */
+       IN      DAT_VA_TYPE,             /* va_type */
+       IN      DAT_EP_HANDLE,           /* ep_handle */
+       IN      DAT_RMR_COOKIE,          /* user_cookie */
+       IN      DAT_COMPLETION_FLAGS,    /* completion_flags */
+       INOUT   DAT_RMR_CONTEXT * );     /* context */
+
+extern DAT_RETURN DAT_API dapl_rmr_free (
+       IN      DAT_RMR_HANDLE);
+
+/* PSP Functions */
+
+extern DAT_RETURN DAT_API dapl_psp_create (
+       IN      DAT_IA_HANDLE,          /* ia_handle */
+       IN      DAT_CONN_QUAL,          /* conn_qual */
+       IN      DAT_EVD_HANDLE,         /* evd_handle */
+       IN      DAT_PSP_FLAGS,          /* psp_flags */
+       OUT     DAT_PSP_HANDLE * );     /* psp_handle */
+
+extern DAT_RETURN DAT_API dapl_psp_create_any (
+       IN      DAT_IA_HANDLE,          /* ia_handle */
+       OUT     DAT_CONN_QUAL *,        /* conn_qual */
+       IN      DAT_EVD_HANDLE,         /* evd_handle */
+       IN      DAT_PSP_FLAGS,          /* psp_flags */
+       OUT     DAT_PSP_HANDLE *);      /* psp_handle */
+
+extern DAT_RETURN DAT_API dapl_psp_query (
+       IN      DAT_PSP_HANDLE,
+       IN      DAT_PSP_PARAM_MASK,
+       OUT     DAT_PSP_PARAM * );
+
+extern DAT_RETURN DAT_API dapl_psp_free (
+       IN      DAT_PSP_HANDLE );       /* psp_handle */
+
+/* RSP Functions */
+
+extern DAT_RETURN DAT_API dapl_rsp_create (
+       IN      DAT_IA_HANDLE,          /* ia_handle */
+       IN      DAT_CONN_QUAL,          /* conn_qual */
+       IN      DAT_EP_HANDLE,          /* ep_handle */
+       IN      DAT_EVD_HANDLE,         /* evd_handle */
+       OUT     DAT_RSP_HANDLE * );     /* rsp_handle */
+
+extern DAT_RETURN DAT_API dapl_rsp_query (
+       IN      DAT_RSP_HANDLE,
+       IN      DAT_RSP_PARAM_MASK,
+       OUT     DAT_RSP_PARAM * );
+
+extern DAT_RETURN DAT_API dapl_rsp_free (
+       IN      DAT_RSP_HANDLE );       /* rsp_handle */
+
+/* PZ Functions */
+
+extern DAT_RETURN DAT_API dapl_pz_create (
+       IN      DAT_IA_HANDLE,          /* ia_handle */
+       OUT     DAT_PZ_HANDLE * );      /* pz_handle */
+
+extern DAT_RETURN DAT_API dapl_pz_query (
+       IN      DAT_PZ_HANDLE,          /* pz_handle */
+       IN      DAT_PZ_PARAM_MASK,      /* pz_args_mask */
+       OUT     DAT_PZ_PARAM * );       /* pz_args */
+
+extern DAT_RETURN DAT_API dapl_pz_free (
+       IN      DAT_PZ_HANDLE );        /* pz_handle */
+
+/* SRQ functions */
+
+extern DAT_RETURN DAT_API dapl_srq_create (
+        IN      DAT_IA_HANDLE,          /* ia_handle            */
+        IN      DAT_PZ_HANDLE,          /* pz_handle            */
+        IN      DAT_SRQ_ATTR *,         /* srq_attr             */
+        OUT     DAT_SRQ_HANDLE *);      /* srq_handle           */
+
+extern DAT_RETURN DAT_API dapl_srq_free (
+       IN      DAT_SRQ_HANDLE);        /* srq_handle           */
+
+extern DAT_RETURN DAT_API dapl_srq_post_recv (
+       IN      DAT_SRQ_HANDLE,         /* srq_handle           */
+       IN      DAT_COUNT,              /* num_segments         */
+       IN      DAT_LMR_TRIPLET *,      /* local_iov            */
+       IN      DAT_DTO_COOKIE);        /* user_cookie          */
+
+extern DAT_RETURN DAT_API dapl_srq_query (
+       IN      DAT_SRQ_HANDLE,         /* srq_handle           */
+       IN      DAT_SRQ_PARAM_MASK,     /* srq_param_mask       */
+       OUT     DAT_SRQ_PARAM *);       /* srq_param            */
+
+extern DAT_RETURN DAT_API dapl_srq_resize (
+       IN      DAT_SRQ_HANDLE,         /* srq_handle           */
+       IN      DAT_COUNT);             /* srq_max_recv_dto     */
+
+extern DAT_RETURN DAT_API dapl_srq_set_lw (
+       IN      DAT_SRQ_HANDLE,         /* srq_handle           */
+       IN      DAT_COUNT);             /* low_watermark        */
+
+/* CSP functions */
+extern DAT_RETURN DAT_API dapl_csp_create (
+       IN      DAT_IA_HANDLE,          /* ia_handle      */
+       IN      DAT_COMM *,             /* communicator   */
+       IN      DAT_IA_ADDRESS_PTR,     /* address        */
+       IN      DAT_EVD_HANDLE,         /* evd_handle     */
+       OUT     DAT_CSP_HANDLE *);      /* csp_handle     */
+
+extern DAT_RETURN DAT_API dapl_csp_query (
+       IN      DAT_CSP_HANDLE,         /* csp_handle     */
+       IN      DAT_CSP_PARAM_MASK,     /* csp_param_mask */
+       OUT     DAT_CSP_PARAM *);       /* csp_param      */
+
+extern DAT_RETURN DAT_API dapl_csp_free (
+       IN      DAT_CSP_HANDLE);        /* csp_handle     */
+
+/* HA functions */
+DAT_RETURN DAT_API dapl_ia_ha (
+       IN       DAT_IA_HANDLE,         /* ia_handle */
+       IN const DAT_NAME_PTR,          /* provider  */
+       OUT      DAT_BOOLEAN *);        /* answer    */
+
+#ifdef DAT_EXTENSIONS
+#include <stdarg.h>
+extern DAT_RETURN DAT_API dapl_extensions (
+       IN      DAT_HANDLE,             /* handle */
+       IN      DAT_EXTENDED_OP,        /* extended op */
+       IN      va_list);               /* argument list */
+#endif
+
+/*
+ * DAPL internal utility function prototpyes
+ */
+
+extern void dapl_llist_init_head (
+    DAPL_LLIST_HEAD *  head);
+
+extern void dapl_llist_init_entry (
+    DAPL_LLIST_ENTRY *         entry);
+
+extern DAT_BOOLEAN dapl_llist_is_empty (
+    DAPL_LLIST_HEAD *  head);
+
+extern void dapl_llist_add_head (
+    DAPL_LLIST_HEAD *  head,
+    DAPL_LLIST_ENTRY *         entry,
+    void *             data);
+
+extern void dapl_llist_add_tail (
+    DAPL_LLIST_HEAD *   head,
+    DAPL_LLIST_ENTRY *  entry,
+    void *             data);
+
+extern void dapl_llist_add_entry (
+    DAPL_LLIST_HEAD * head,
+    DAPL_LLIST_ENTRY * entry,
+    DAPL_LLIST_ENTRY * new_entry,
+    void * data);
+
+extern void * dapl_llist_remove_head (
+    DAPL_LLIST_HEAD *  head);
+
+extern void * dapl_llist_remove_tail (
+    DAPL_LLIST_HEAD *  head);
+
+extern void * dapl_llist_remove_entry (
+    DAPL_LLIST_HEAD *  head,
+    DAPL_LLIST_ENTRY * entry);
+
+extern void * dapl_llist_peek_head (
+    DAPL_LLIST_HEAD *  head);
+
+extern void * dapl_llist_next_entry (
+    IN    DAPL_LLIST_HEAD      *head,
+    IN    DAPL_LLIST_ENTRY     *cur_ent);
+
+extern void dapl_llist_debug_print_list (
+    DAPL_LLIST_HEAD *  head);
+
+
+#endif
index 1e846aae4a17e5352c2ff8dd1e4843324caf6049..503df965633d067f88b979ab3147dfea03ee848d 100644 (file)
@@ -209,18 +209,13 @@ void dapls_cm_acquire(dp_ib_cm_handle_t conn)
 void dapls_cm_release(dp_ib_cm_handle_t conn)
 {
        dapl_os_lock(&conn->lock);
-       conn->ref_count--;\r
-       if (conn->ref_count) {\r
-                dapl_os_unlock(&conn->lock);\r
-               return;\r
-       }\r
-       if (conn->cm_id) {
-               if (conn->cm_id->qp)
-                       rdma_destroy_qp(conn->cm_id);
-               rdma_destroy_id(conn->cm_id);
-       }\r
-       dapl_os_unlock(&conn->lock);\r
-       dapli_cm_dealloc(conn);\r
+       conn->ref_count--;
+       if (conn->ref_count) {
+                dapl_os_unlock(&conn->lock);
+               return;
+       }
+       dapl_os_unlock(&conn->lock);
+       dapli_cm_dealloc(conn);
 }
 
 /* BLOCKING: called from dapl_ep_free, EP link will be last ref */
@@ -235,10 +230,14 @@ void dapls_cm_free(dp_ib_cm_handle_t conn)
        /* Destroy cm_id, wait until EP is last ref */
        dapl_os_lock(&conn->lock);
        if (conn->cm_id) {
-               if (conn->cm_id->qp)
-                       rdma_destroy_qp(conn->cm_id);
-               rdma_destroy_id(conn->cm_id);
+               struct rdma_cm_id *cm_id = conn->cm_id;
+
+               if (cm_id->qp)
+                       rdma_destroy_qp(cm_id);
                conn->cm_id = NULL;
+               dapl_os_unlock(&conn->lock);
+               rdma_destroy_id(cm_id); /* blocking, event processing */
+               dapl_os_lock(&conn->lock);
        }
 
        /* EP linking is last reference */
@@ -640,6 +639,17 @@ dapls_ib_disconnect(IN DAPL_EP * ep_ptr, IN DAT_CLOSE_FLAGS close_flags)
        /* no graceful half-pipe disconnect option */
        rdma_disconnect(conn->cm_id);
 
+       /* ABRUPT close, wait for callback and DISCONNECTED state */
+       if (close_flags == DAT_CLOSE_ABRUPT_FLAG) {
+               dapl_os_lock(&ep_ptr->header.lock);
+               while (ep_ptr->param.ep_state != DAT_EP_STATE_DISCONNECTED) {
+                       dapl_os_unlock(&ep_ptr->header.lock);
+                       dapl_os_sleep_usec(10000);
+                       dapl_os_lock(&ep_ptr->header.lock);
+               }
+               dapl_os_unlock(&ep_ptr->header.lock);
+       }
+
        /* 
         * DAT event notification occurs from the callback
         * Note: will fire even if DREQ goes unanswered on timeout 
@@ -759,6 +769,7 @@ dapls_ib_setup_conn_listener(IN DAPL_IA * ia_ptr,
        return DAT_SUCCESS;
 
 bail:
+       rdma_destroy_id(conn->cm_id);
        dapls_cm_release(conn);
        return dat_status;
 }
@@ -791,8 +802,13 @@ dapls_ib_remove_conn_listener(IN DAPL_IA * ia_ptr, IN DAPL_SP * sp_ptr)
 
        if (conn != IB_INVALID_HANDLE) {
                sp_ptr->cm_srvc_handle = NULL;
+               if (conn->cm_id) {
+                       rdma_destroy_id(conn->cm_id);
+                       conn->cm_id = NULL;
+               }
                dapls_cm_release(conn);
        }
+               
        return DAT_SUCCESS;
 }
 
@@ -869,6 +885,7 @@ dapls_ib_accept_connection(IN DAT_CR_HANDLE cr_handle,
                dapl_ep_unlink_cm(ep_ptr, ep_conn);
                ep_conn->cm_id->qp = NULL;
                ep_conn->ep = NULL;
+               rdma_destroy_id(ep_conn->cm_id);
                dapls_cm_release(ep_conn);
 
                /* add new CM to EP linking, qp_handle unchanged */
@@ -912,6 +929,7 @@ bail:
        rdma_reject(cr_conn->cm_id, NULL, 0);
 
        /* no EP linking, ok to destroy */
+       rdma_destroy_id(cr_conn->cm_id);
        dapls_cm_release(cr_conn);
        return dat_status;
 }
@@ -974,6 +992,7 @@ dapls_ib_reject_connection(IN dp_ib_cm_handle_t cm_handle,
                          cm_handle->p_data, offset + private_data_size);
 
        /* no EP linking, ok to destroy */
+       rdma_destroy_id(cm_handle->cm_id);
        dapls_cm_release(cm_handle);
        return dapl_convert_errno(ret, "reject");
 }
@@ -1067,6 +1086,13 @@ void dapli_cma_event_cb(void)
 
                dapls_cm_acquire(conn);
                
+               /* destroying cm_id, consumer thread blocking waiting for ACK */
+               if (conn->cm_id == NULL) {
+                       dapls_cm_release(conn);
+                       rdma_ack_cm_event(event);
+                       return;
+               }
+
                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);
index 96061b3a80cdd88165e272464552eee37e1cf98b..471bd7ffe51cfac5208f0620674377148d304db2 100644 (file)
 #define IB_MAX_AT_RETRY                3
 
 /* CMA private data areas, use CMA max with known transport definitions */
+#ifndef RDMA_MAX_PRIVATE_DATA
+#if defined(_WIN64) || defined(_WIN32)
+#define RDMA_MAX_PRIVATE_DATA 64 
+#else
+#define RDMA_MAX_PRIVATE_DATA 256
+#endif
+#endif
+
 #define CMA_PDATA_HDR          36
 #define        IB_MAX_REQ_PDATA_SIZE   DAPL_MIN((92-CMA_PDATA_HDR),RDMA_MAX_PRIVATE_DATA)
 #define        IB_MAX_REP_PDATA_SIZE   DAPL_MIN((196-CMA_PDATA_HDR),RDMA_MAX_PRIVATE_DATA)
@@ -113,7 +121,9 @@ typedef struct _ib_hca_transport
        uint8_t                 tclass;
        uint8_t                 mtu;
        DAT_NAMED_ATTR          named_attr;
-
+       uint8_t                 sl;
+       uint16_t                pkey;
+       int                     pkey_idx;
 } ib_hca_transport_t;
 
 /* prototypes */
index 12593cf4b38b92a0f038235dd844c2f8e874c726..e4ff22eb79633e55052e67c2fcbe6218abf6f6e0 100644 (file)
@@ -54,51 +54,10 @@ DAPL_OS_LOCK g_hca_lock;
 struct dapl_llist_entry *g_hca_list;
 
 #if defined(_WIN64) || defined(_WIN32)
-#include "..\..\..\..\..\etc\user\comp_channel.cpp"
 #include <rdma\winverbs.h>
 
 static COMP_SET ufds;
 
-static int getipaddr_netdev(char *name, char *addr, int addr_len)
-{
-       IWVProvider *prov;
-       WV_DEVICE_ADDRESS devaddr;
-       struct addrinfo *res, *ai;
-       HRESULT hr;
-       int index;
-
-       if (strncmp(name, "rdma_dev", 8)) {
-               return EINVAL;
-       }
-
-       index = atoi(name + 8);
-
-       hr = WvGetObject(&IID_IWVProvider, (LPVOID *) &prov);
-       if (FAILED(hr)) {
-               return hr;
-       }
-
-       hr = getaddrinfo("..localmachine", NULL, NULL, &res);
-       if (hr) {
-               goto release;
-       }
-
-       for (ai = res; ai; ai = ai->ai_next) {
-               hr = prov->lpVtbl->TranslateAddress(prov, ai->ai_addr, &devaddr);
-               if (SUCCEEDED(hr) && (ai->ai_addrlen <= addr_len) && (index-- == 0)) {
-                       memcpy(addr, ai->ai_addr, ai->ai_addrlen);
-                       goto free;
-               }
-       }
-       hr = ENODEV;
-
-free:
-       freeaddrinfo(res);
-release:
-       prov->lpVtbl->Release(prov);
-       return hr;
-}
-
 static int dapls_os_init(void)
 {
        return CompSetInit(&ufds);
@@ -133,6 +92,7 @@ static int dapls_thread_signal(void)
        return 0;
 }
 #else                          // _WIN64 || WIN32
+
 int g_ib_pipe[2];
 
 static int dapls_os_init(void)
@@ -146,43 +106,6 @@ static void dapls_os_release(void)
        /* close pipe? */
 }
 
-/* Get IP address using network device name */
-static int getipaddr_netdev(char *name, char *addr, int addr_len)
-{
-       struct ifreq ifr;
-       int skfd, ret, len;
-
-       /* Fill in the structure */
-       snprintf(ifr.ifr_name, IFNAMSIZ, "%s", name);
-       ifr.ifr_hwaddr.sa_family = ARPHRD_INFINIBAND;
-
-       /* Create a socket fd */
-       skfd = socket(PF_INET, SOCK_STREAM, 0);
-       ret = ioctl(skfd, SIOCGIFADDR, &ifr);
-       if (ret)
-               goto bail;
-
-       switch (ifr.ifr_addr.sa_family) {
-#ifdef AF_INET6
-       case AF_INET6:
-               len = sizeof(struct sockaddr_in6);
-               break;
-#endif
-       case AF_INET:
-       default:
-               len = sizeof(struct sockaddr);
-               break;
-       }
-
-       if (len <= addr_len)
-               memcpy(addr, &ifr.ifr_addr, len);
-       else
-               ret = EINVAL;
-
-      bail:
-       close(skfd);
-       return ret;
-}
 
 static int dapls_config_fd(int fd)
 {
@@ -223,39 +146,39 @@ static int dapls_thread_signal(void)
 /* Get IP address using network name, address, or device name */
 static int getipaddr(char *name, char *addr, int len)
 {
-       struct addrinfo *res;
-
-       /* assume netdev for first attempt, then network and address type */
-       if (getipaddr_netdev(name, addr, len)) {
-               if (getaddrinfo(name, NULL, NULL, &res)) {
-                       dapl_log(DAPL_DBG_TYPE_ERR,
-                                " open_hca: getaddr_netdev ERROR:"
-                                " %s. Is %s configured?\n",
-                                strerror(errno), name);
-                       return 1;
-               } else {
-                       if (len >= res->ai_addrlen)
-                               memcpy(addr, res->ai_addr, res->ai_addrlen);
-                       else {
-                               freeaddrinfo(res);
-                               return 1;
-                       }
-                       freeaddrinfo(res);
-               }
-       }
-
-       dapl_dbg_log(
-               DAPL_DBG_TYPE_UTIL,
-               " getipaddr: family %d port %d addr %d.%d.%d.%d\n",
-               ((struct sockaddr_in *)addr)->sin_family,
-               ((struct sockaddr_in *)addr)->sin_port,
-               ((struct sockaddr_in *)addr)->sin_addr.s_addr >> 0 & 0xff,
-               ((struct sockaddr_in *)addr)->sin_addr.s_addr >> 8 & 0xff,
-               ((struct sockaddr_in *)addr)->sin_addr.s_addr >> 16 & 0xff,
-               ((struct sockaddr_in *)addr)->sin_addr.
-                s_addr >> 24 & 0xff);
-
-       return 0;
+        struct addrinfo *res;
+
+        /* assume netdev for first attempt, then network and address type */
+        if (getipaddr_netdev(name, addr, len)) {
+                if (getaddrinfo(name, NULL, NULL, &res)) {
+                        dapl_log(DAPL_DBG_TYPE_ERR,
+                                 " open_hca: getaddr_netdev ERROR:"
+                                 " %s. Is %s configured?\n",
+                                 strerror(errno), name);
+                        return 1;
+                } else {
+                        if (len >= res->ai_addrlen)
+                                memcpy(addr, res->ai_addr, res->ai_addrlen);
+                        else {
+                                freeaddrinfo(res);
+                                return 1;
+                        }
+                        freeaddrinfo(res);
+                }
+        }
+
+        dapl_dbg_log(
+                DAPL_DBG_TYPE_UTIL,
+                " getipaddr: family %d port %d addr %d.%d.%d.%d\n",
+                ((struct sockaddr_in *)addr)->sin_family,
+                ((struct sockaddr_in *)addr)->sin_port,
+                ((struct sockaddr_in *)addr)->sin_addr.s_addr >> 0 & 0xff,
+                ((struct sockaddr_in *)addr)->sin_addr.s_addr >> 8 & 0xff,
+                ((struct sockaddr_in *)addr)->sin_addr.s_addr >> 16 & 0xff,
+                ((struct sockaddr_in *)addr)->sin_addr.
+                 s_addr >> 24 & 0xff);
+
+        return 0;
 }
 
 /*
@@ -273,9 +196,10 @@ static int getipaddr(char *name, char *addr, int len)
  *     0 success, -1 error
  *
  */
+DAT_UINT32 g_parent = 0;
 int32_t dapls_ib_init(void)
 {
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " dapl_ib_init: \n");
+       g_parent = dapl_os_getpid();
 
        /* initialize hca_list lock */
        dapl_os_lock_init(&g_hca_lock);
@@ -291,7 +215,10 @@ int32_t dapls_ib_init(void)
 
 int32_t dapls_ib_release(void)
 {
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " dapl_ib_release: \n");
+       /* only parent will cleanup */
+       if (dapl_os_getpid() != g_parent)
+               return 0;
+
        dapli_ib_thread_destroy();
        if (g_cm_events != NULL)
                rdma_destroy_event_channel(g_cm_events);
index c537df3dcd10836ae6043cfed941d342ddce2b3c..a67018b5d2cb26be3b8b5b0ba702b3042d74b723 100644 (file)
@@ -2,7 +2,6 @@
 #define OPENIB_OSD_H
 
 #include <rdma/rdma_cma.h>
-#include <rdma/rdma_cma_abi.h>
 #include <byteswap.h>
 #include <sys/poll.h>
 
index 3e32fabf132d7b6a27e06ee0792ffafa7aba0769..d3cf2e054ac6d746c447f995254f4a9337719d9b 100644 (file)
@@ -166,7 +166,7 @@ typedef uint16_t            ib_hca_port_t;
 #define DCM_TCLASS     0
 
 /* DAPL uCM timers, default queue sizes */
-#define DCM_RETRY_CNT   10 
+#define DCM_RETRY_CNT   15 
 #define DCM_REP_TIME    800    /* reply timeout in m_secs */
 #define DCM_RTU_TIME    400    /* rtu timeout in m_secs */
 #define DCM_QP_SIZE     500     /* uCM tx, rx qp size */
@@ -299,7 +299,8 @@ int32_t     dapls_ib_release(void);
 /* util.c */
 enum ibv_mtu dapl_ib_mtu(int mtu);
 char *dapl_ib_mtu_str(enum ibv_mtu mtu);
-DAT_RETURN getlocalipaddr(DAT_SOCK_ADDR *addr, int addr_len);
+int getipaddr_netdev(char *name, char *addr, int addr_len);
+DAT_RETURN getlocalipaddr(char *addr, int addr_len);
 
 /* qp.c */
 DAT_RETURN dapls_modify_qp_ud(IN DAPL_HCA *hca, IN ib_qp_handle_t qp);
index 15c1dae530a92770658e712296350df085fa1c82..179eef0e2906d315c9ea1c98f00a69b4d6aaea5e 100644 (file)
@@ -182,8 +182,8 @@ dapls_ib_qp_alloc(IN DAPL_IA * ia_ptr,
        }
 #endif
        dapl_dbg_log(DAPL_DBG_TYPE_EP,
-                    " qp_alloc: qpn %p sq %d,%d rq %d,%d\n",
-                    ep_ptr->qp_handle->qp_num,
+                    " qp_alloc: qpn %p type %d sq %d,%d rq %d,%d\n",
+                    ep_ptr->qp_handle->qp_num, ep_ptr->qp_handle->qp_type,
                     qp_create.cap.max_send_wr, qp_create.cap.max_send_sge,
                     qp_create.cap.max_recv_wr, qp_create.cap.max_recv_sge);
 
@@ -422,7 +422,7 @@ dapls_modify_qp_state(IN ib_qp_handle_t             qp_handle,
                        qp_attr.ah_attr.grh.traffic_class =
                                ia_ptr->hca_ptr->ib_trans.tclass;
                }
-               qp_attr.ah_attr.sl = 0;
+               qp_attr.ah_attr.sl = ia_ptr->hca_ptr->ib_trans.sl;
                qp_attr.ah_attr.src_path_bits = 0;
                qp_attr.ah_attr.port_num = ia_ptr->hca_ptr->port_num;
 
@@ -489,7 +489,7 @@ dapls_modify_qp_state(IN ib_qp_handle_t             qp_handle,
                        qp_attr.qkey = DAT_UD_QKEY;
                }
 
-               qp_attr.pkey_index = 0;
+               qp_attr.pkey_index = ia_ptr->hca_ptr->ib_trans.pkey_idx;
                qp_attr.port_num = ia_ptr->hca_ptr->port_num;
 
                dapl_dbg_log(DAPL_DBG_TYPE_EP,
@@ -519,7 +519,7 @@ dapls_modify_qp_ud(IN DAPL_HCA *hca, IN ib_qp_handle_t qp)
        /* modify QP, setup and prepost buffers */
        dapl_os_memzero((void *)&qp_attr, sizeof(qp_attr));
        qp_attr.qp_state = IBV_QPS_INIT;
-        qp_attr.pkey_index = 0;
+        qp_attr.pkey_index = hca->ib_trans.pkey_idx;
         qp_attr.port_num = hca->port_num;
         qp_attr.qkey = DAT_UD_QKEY;
        if (ibv_modify_qp(qp, &qp_attr, 
@@ -561,8 +561,11 @@ dapls_create_ah(IN DAPL_HCA                *hca,
        struct ibv_qp_attr qp_attr;
        ib_ah_handle_t  ah;
 
-       if (qp->qp_type != IBV_QPT_UD)
+       if (qp->qp_type != IBV_QPT_UD) {
+               dapl_log(DAPL_DBG_TYPE_ERR, 
+                        " create_ah ERR: QP_type != UD\n");
                return NULL;
+       }
 
        dapl_os_memzero((void *)&qp_attr, sizeof(qp_attr));
        qp_attr.qp_state = IBV_QP_STATE;
@@ -579,7 +582,7 @@ dapls_create_ah(IN DAPL_HCA         *hca,
                qp_attr.ah_attr.grh.hop_limit = hca->ib_trans.hop_limit;
                qp_attr.ah_attr.grh.traffic_class = hca->ib_trans.tclass;
        }
-       qp_attr.ah_attr.sl = 0;
+       qp_attr.ah_attr.sl = hca->ib_trans.sl;
        qp_attr.ah_attr.src_path_bits = 0;
        qp_attr.ah_attr.port_num = hca->port_num;
 
index 704d85ad29c529aa132663415f7ef03a7f25a167..a69261fe7f6523fe6647029e7ce2d5add14af5be 100644 (file)
 
 int g_dapl_loopback_connection = 0;
 
+#if defined(_WIN64) || defined(_WIN32)
+#include "..\..\..\..\..\etc\user\comp_channel.cpp"
+#include <rdma\winverbs.h>
+
+int getipaddr_netdev(char *name, char *addr, int addr_len)
+{
+       IWVProvider *prov;
+       WV_DEVICE_ADDRESS devaddr;
+       struct addrinfo *res, *ai;
+       HRESULT hr;
+       int index;
+
+       if (strncmp(name, "rdma_dev", 8)) {
+               return EINVAL;
+       }
+
+       index = atoi(name + 8);
+
+       hr = WvGetObject(&IID_IWVProvider, (LPVOID *) &prov);
+       if (FAILED(hr)) {
+               return hr;
+       }
+
+       hr = getaddrinfo("..localmachine", NULL, NULL, &res);
+       if (hr) {
+               goto release;
+       }
+
+       for (ai = res; ai; ai = ai->ai_next) {
+               hr = prov->lpVtbl->TranslateAddress(prov, ai->ai_addr, &devaddr);
+               if (SUCCEEDED(hr) && (ai->ai_addrlen <= addr_len) && (index-- == 0)) {
+                       memcpy(addr, ai->ai_addr, ai->ai_addrlen);
+                       goto free;
+               }
+       }
+       hr = ENODEV;
+
+free:
+       freeaddrinfo(res);
+release:
+       prov->lpVtbl->Release(prov);
+       return hr;
+}
+
+#else                          // _WIN64 || WIN32
+
+/* Get IP address using network device name */
+int getipaddr_netdev(char *name, char *addr, int addr_len)
+{
+       struct ifreq ifr;
+       int skfd, ret, len;
+
+       /* Fill in the structure */
+       snprintf(ifr.ifr_name, IFNAMSIZ, "%s", name);
+       ifr.ifr_hwaddr.sa_family = ARPHRD_INFINIBAND;
+
+       /* Create a socket fd */
+       skfd = socket(PF_INET, SOCK_STREAM, 0);
+       ret = ioctl(skfd, SIOCGIFADDR, &ifr);
+       if (ret)
+               goto bail;
+
+       switch (ifr.ifr_addr.sa_family) {
+#ifdef AF_INET6
+       case AF_INET6:
+               len = sizeof(struct sockaddr_in6);
+               break;
+#endif
+       case AF_INET:
+       default:
+               len = sizeof(struct sockaddr);
+               break;
+       }
+
+       if (len <= addr_len)
+               memcpy(addr, &ifr.ifr_addr, len);
+       else
+               ret = EINVAL;
+
+      bail:
+       close(skfd);
+       return ret;
+}
+#endif
+
 enum ibv_mtu dapl_ib_mtu(int mtu)
 {
        switch (mtu) {
@@ -67,12 +152,26 @@ char *dapl_ib_mtu_str(enum ibv_mtu mtu)
        }
 }
 
-DAT_RETURN getlocalipaddr(DAT_SOCK_ADDR * addr, int addr_len)
+DAT_RETURN getlocalipaddr(char *addr, int addr_len)
 {
        struct sockaddr_in *sin;
        struct addrinfo *res, hint, *ai;
        int ret;
        char hostname[256];
+       char *netdev = getenv("DAPL_SCM_NETDEV");
+
+       /* use provided netdev instead of default hostname */
+       if (netdev != NULL) {
+               ret = getipaddr_netdev(netdev, addr, addr_len);
+               if (ret) {                      
+                       dapl_log(DAPL_DBG_TYPE_ERR,
+                                " getlocalipaddr: DAPL_SCM_NETDEV provided %s"
+                               " but not configured on system? ERR = %s\n",
+                               netdev, strerror(ret));
+                       return dapl_convert_errno(ret, "getlocalipaddr");
+               } else 
+                       return DAT_SUCCESS;
+       }
 
        if (addr_len < sizeof(*sin)) {
                return DAT_INTERNAL_ERROR;
@@ -222,14 +321,59 @@ DAT_RETURN dapls_ib_query_hca(IN DAPL_HCA * hca_ptr,
                hca_ptr->ib_trans.named_attr.value =
                    dapl_ib_mtu_str(hca_ptr->ib_trans.mtu);
 
+               if (hca_ptr->ib_hca_handle->device->transport_type != IBV_TRANSPORT_IB)
+                       goto skip_ib;
+
+               /* set SL, PKEY values, defaults = 0 */
+               hca_ptr->ib_trans.pkey_idx = 0;
+               hca_ptr->ib_trans.pkey = dapl_os_get_env_val("DAPL_IB_PKEY", 0);
+               hca_ptr->ib_trans.sl = dapl_os_get_env_val("DAPL_IB_SL", 0);
+
+               /* index provided, get pkey; pkey provided, get index */
+               if (hca_ptr->ib_trans.pkey) {
+                       int i; uint16_t pkey = 0;
+                       for (i=0; i < dev_attr.max_pkeys; i++) {
+                               if (ibv_query_pkey(hca_ptr->ib_hca_handle,
+                                                  hca_ptr->port_num,
+                                                  i, &pkey)) {
+                                       i = dev_attr.max_pkeys;
+                                       break;
+                               }
+                               if (pkey == hca_ptr->ib_trans.pkey) {
+                                       hca_ptr->ib_trans.pkey_idx = i;
+                                       break;
+                               }
+                       }
+                       if (i == dev_attr.max_pkeys) {
+                               dapl_log(DAPL_DBG_TYPE_WARN,
+                                        " Warning: new pkey(%d), query (%s)"
+                                        " err or key !found, using defaults\n",
+                                        hca_ptr->ib_trans.pkey, strerror(errno));
+                       }
+               }
+skip_ib:
+
+#ifdef DEFINE_ATTR_LINK_LAYER
+#ifndef _OPENIB_CMA_
+               if (port_attr.link_layer == IBV_LINK_LAYER_ETHERNET)
+                       hca_ptr->ib_trans.global = 1;
+
+               dapl_log(DAPL_DBG_TYPE_UTIL,
+                        " query_hca: port.link_layer = 0x%x\n", 
+                        port_attr.link_layer);
+#endif
+#endif
                dapl_log(DAPL_DBG_TYPE_UTIL,
                             " query_hca: (%x.%x) eps %d, sz %d evds %d,"
-                            " sz %d mtu %d\n",
+                            " sz %d mtu %d - pkey %d p_idx %d sl %d\n",
                             ia_attr->hardware_version_major,
                             ia_attr->hardware_version_minor,
                             ia_attr->max_eps, ia_attr->max_dto_per_ep,
                             ia_attr->max_evds, ia_attr->max_evd_qlen,
-                            128 << hca_ptr->ib_trans.mtu);
+                            128 << hca_ptr->ib_trans.mtu,
+                            hca_ptr->ib_trans.pkey,
+                            hca_ptr->ib_trans.pkey_idx,
+                            hca_ptr->ib_trans.sl);
 
                dapl_log(DAPL_DBG_TYPE_UTIL,
                             " query_hca: msg %llu rdma %llu iov %d lmr %d rmr %d"
index 2129e2771773cc15a60af93ac8172d8e9529246e..80b405a7a93dbbdb98714b5786af0f1a21920699 100644 (file)
@@ -41,9 +41,11 @@ TARGETLIBS= \
        $(SDK_LIB_PATH)\ws2_32.lib \\r
 !if $(FREEBUILD)\r
        $(TARGETPATH)\*\dat2.lib \\r
+       $(TARGETPATH)\*\winverbs.lib \\r
        $(TARGETPATH)\*\libibverbs.lib\r
 !else\r
        $(TARGETPATH)\*\dat2d.lib \\r
+       $(TARGETPATH)\*\winverbs.lib \\r
        $(TARGETPATH)\*\libibverbsd.lib\r
 !endif\r
 \r
index 69f31818ef9980558e70ac81a776dd4024123d63..ce0d9616ae10092bf28c53a529dce739aa113c10 100644 (file)
-/*\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:            uDAPL\r
- *\r
- *   Filename:          dapl_ib_cm.c\r
- *\r
- *   Author:            Arlin Davis\r
- *\r
- *   Created:           3/10/2005\r
- *\r
- *   Description: \r
- *\r
- *   The uDAPL openib provider - connection management\r
- *\r
- ****************************************************************************\r
- *                Source Control System Information\r
- *\r
- *    $Id: $\r
- *\r
- *     Copyright (c) 2005 Intel Corporation.  All rights reserved.\r
- *\r
- **************************************************************************/\r
-\r
-#if defined(_WIN32)\r
-#define FD_SETSIZE 1024\r
-#define DAPL_FD_SETSIZE FD_SETSIZE\r
-#endif\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_ep_util.h"\r
-#include "dapl_osd.h"\r
-\r
-#if defined(_WIN32) || defined(_WIN64)\r
-enum DAPL_FD_EVENTS {\r
-       DAPL_FD_READ = 0x1,\r
-       DAPL_FD_WRITE = 0x2,\r
-       DAPL_FD_ERROR = 0x4\r
-};\r
-\r
-static int dapl_config_socket(DAPL_SOCKET s)\r
-{\r
-       unsigned long nonblocking = 1;\r
-       int ret, opt = 1;\r
-\r
-       ret = ioctlsocket(s, FIONBIO, &nonblocking);\r
-\r
-       /* no delay for small packets */\r
-       if (!ret)\r
-               ret = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, \r
-                                (char *)&opt, sizeof(opt));\r
-       return ret;\r
-}\r
-\r
-static int dapl_connect_socket(DAPL_SOCKET s, struct sockaddr *addr,\r
-                              int addrlen)\r
-{\r
-       int err;\r
-\r
-       err = connect(s, addr, addrlen);\r
-       if (err == SOCKET_ERROR)\r
-               err = WSAGetLastError();\r
-       return (err == WSAEWOULDBLOCK) ? EAGAIN : err;\r
-}\r
-\r
-struct dapl_fd_set {\r
-       struct fd_set set[3];\r
-};\r
-\r
-static struct dapl_fd_set *dapl_alloc_fd_set(void)\r
-{\r
-       return dapl_os_alloc(sizeof(struct dapl_fd_set));\r
-}\r
-\r
-static void dapl_fd_zero(struct dapl_fd_set *set)\r
-{\r
-       FD_ZERO(&set->set[0]);\r
-       FD_ZERO(&set->set[1]);\r
-       FD_ZERO(&set->set[2]);\r
-}\r
-\r
-static int dapl_fd_set(DAPL_SOCKET s, struct dapl_fd_set *set,\r
-                      enum DAPL_FD_EVENTS event)\r
-{\r
-       FD_SET(s, &set->set[(event == DAPL_FD_READ) ? 0 : 1]);\r
-       FD_SET(s, &set->set[2]);\r
-       return 0;\r
-}\r
-\r
-static enum DAPL_FD_EVENTS dapl_poll(DAPL_SOCKET s, enum DAPL_FD_EVENTS event)\r
-{\r
-       struct fd_set rw_fds;\r
-       struct fd_set err_fds;\r
-       struct timeval tv;\r
-       int ret;\r
-\r
-       FD_ZERO(&rw_fds);\r
-       FD_ZERO(&err_fds);\r
-       FD_SET(s, &rw_fds);\r
-       FD_SET(s, &err_fds);\r
-\r
-       tv.tv_sec = 0;\r
-       tv.tv_usec = 0;\r
-\r
-       if (event == DAPL_FD_READ)\r
-               ret = select(1, &rw_fds, NULL, &err_fds, &tv);\r
-       else\r
-               ret = select(1, NULL, &rw_fds, &err_fds, &tv);\r
-\r
-       if (ret == 0)\r
-               return 0;\r
-       else if (ret == SOCKET_ERROR)\r
-               return DAPL_FD_ERROR;\r
-       else if (FD_ISSET(s, &rw_fds))\r
-               return event;\r
-       else\r
-               return DAPL_FD_ERROR;\r
-}\r
-\r
-static int dapl_select(struct dapl_fd_set *set)\r
-{\r
-       int ret;\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_CM, " dapl_select: sleep\n");\r
-       ret = select(0, &set->set[0], &set->set[1], &set->set[2], NULL);\r
-       dapl_dbg_log(DAPL_DBG_TYPE_CM, " dapl_select: wakeup\n");\r
-\r
-       if (ret == SOCKET_ERROR)\r
-               dapl_dbg_log(DAPL_DBG_TYPE_THREAD,\r
-                            " dapl_select: error 0x%x\n", WSAGetLastError());\r
-\r
-       return ret;\r
-}\r
-\r
-static int dapl_socket_errno(void)\r
-{\r
-       int err;\r
-\r
-       err = WSAGetLastError();\r
-       switch (err) {\r
-       case WSAEACCES:\r
-       case WSAEADDRINUSE:\r
-               return EADDRINUSE;\r
-       case WSAECONNRESET:\r
-               return ECONNRESET;\r
-       default:\r
-               return err;\r
-       }\r
-}\r
-#else                          // _WIN32 || _WIN64\r
-enum DAPL_FD_EVENTS {\r
-       DAPL_FD_READ = POLLIN,\r
-       DAPL_FD_WRITE = POLLOUT,\r
-       DAPL_FD_ERROR = POLLERR\r
-};\r
-\r
-static int dapl_config_socket(DAPL_SOCKET s)\r
-{\r
-       int ret, opt = 1;\r
-\r
-       /* non-blocking */\r
-       ret = fcntl(s, F_GETFL);\r
-       if (ret >= 0)\r
-               ret = fcntl(s, F_SETFL, ret | O_NONBLOCK);\r
-\r
-       /* no delay for small packets */\r
-       if (!ret)\r
-               ret = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, \r
-                                (char *)&opt, sizeof(opt));\r
-       return ret;\r
-}\r
-\r
-static int dapl_connect_socket(DAPL_SOCKET s, struct sockaddr *addr,\r
-                              int addrlen)\r
-{\r
-       int ret;\r
-\r
-       ret = connect(s, addr, addrlen);\r
-\r
-       return (errno == EINPROGRESS) ? EAGAIN : ret;\r
-}\r
-\r
-struct dapl_fd_set {\r
-       int index;\r
-       struct pollfd set[DAPL_FD_SETSIZE];\r
-};\r
-\r
-static struct dapl_fd_set *dapl_alloc_fd_set(void)\r
-{\r
-       return dapl_os_alloc(sizeof(struct dapl_fd_set));\r
-}\r
-\r
-static void dapl_fd_zero(struct dapl_fd_set *set)\r
-{\r
-       set->index = 0;\r
-}\r
-\r
-static int dapl_fd_set(DAPL_SOCKET s, struct dapl_fd_set *set,\r
-                      enum DAPL_FD_EVENTS event)\r
-{\r
-       if (set->index == DAPL_FD_SETSIZE - 1) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        "SCM ERR: cm_thread exceeded FD_SETSIZE %d\n",\r
-                        set->index + 1);\r
-               return -1;\r
-       }\r
-\r
-       set->set[set->index].fd = s;\r
-       set->set[set->index].revents = 0;\r
-       set->set[set->index++].events = event;\r
-       return 0;\r
-}\r
-\r
-static enum DAPL_FD_EVENTS dapl_poll(DAPL_SOCKET s, enum DAPL_FD_EVENTS event)\r
-{\r
-       struct pollfd fds;\r
-       int ret;\r
-\r
-       fds.fd = s;\r
-       fds.events = event;\r
-       fds.revents = 0;\r
-       ret = poll(&fds, 1, 0);\r
-       dapl_log(DAPL_DBG_TYPE_THREAD, " dapl_poll: fd=%d ret=%d, evnts=0x%x\n",\r
-                s, ret, fds.revents);\r
-       if (ret == 0)\r
-               return 0;\r
-       else if (ret < 0 || (fds.revents & (POLLERR | POLLHUP | POLLNVAL))) \r
-               return DAPL_FD_ERROR;\r
-       else \r
-               return event;\r
-}\r
-\r
-static int dapl_select(struct dapl_fd_set *set)\r
-{\r
-       int ret;\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_THREAD, " dapl_select: sleep, fds=%d\n", set->index);\r
-       ret = poll(set->set, set->index, -1);\r
-       dapl_dbg_log(DAPL_DBG_TYPE_THREAD, " dapl_select: wakeup, ret=0x%x\n", ret);\r
-       return ret;\r
-}\r
-\r
-#define dapl_socket_errno() errno\r
-#endif\r
-\r
-static void dapli_cm_thread_signal(dp_ib_cm_handle_t cm_ptr) \r
-{\r
-       send(cm_ptr->hca->ib_trans.scm[1], "w", sizeof "w", 0);\r
-}\r
-\r
-static void dapli_cm_free(dp_ib_cm_handle_t cm_ptr) \r
-{\r
-       dapl_os_lock(&cm_ptr->lock);\r
-       cm_ptr->state = DCM_FREE;\r
-       dapl_os_unlock(&cm_ptr->lock);\r
-       dapli_cm_thread_signal(cm_ptr);\r
-}\r
-\r
-static void dapli_cm_dealloc(dp_ib_cm_handle_t cm_ptr) \r
-{\r
-       dapl_os_assert(!cm_ptr->ref_count);\r
-       \r
-       if (cm_ptr->socket != DAPL_INVALID_SOCKET) {\r
-               shutdown(cm_ptr->socket, SHUT_RDWR);\r
-               closesocket(cm_ptr->socket);\r
-       }\r
-       if (cm_ptr->ah) \r
-               ibv_destroy_ah(cm_ptr->ah);\r
-       \r
-       dapl_os_lock_destroy(&cm_ptr->lock);\r
-       dapl_os_wait_object_destroy(&cm_ptr->event);\r
-       dapl_os_free(cm_ptr, sizeof(*cm_ptr));\r
-}\r
-\r
-void dapls_cm_acquire(dp_ib_cm_handle_t cm_ptr)\r
-{\r
-       dapl_os_lock(&cm_ptr->lock);\r
-       cm_ptr->ref_count++;\r
-       dapl_os_unlock(&cm_ptr->lock);\r
-}\r
-\r
-void dapls_cm_release(dp_ib_cm_handle_t cm_ptr)\r
-{\r
-       dapl_os_lock(&cm_ptr->lock);\r
-       cm_ptr->ref_count--;\r
-       if (cm_ptr->ref_count) {\r
-                dapl_os_unlock(&cm_ptr->lock);\r
-               return;\r
-       }\r
-       dapl_os_unlock(&cm_ptr->lock);\r
-       dapli_cm_dealloc(cm_ptr);\r
-}\r
-\r
-static dp_ib_cm_handle_t dapli_cm_alloc(DAPL_EP *ep_ptr)\r
-{\r
-       dp_ib_cm_handle_t cm_ptr;\r
-\r
-       /* Allocate CM, init lock, and initialize */\r
-       if ((cm_ptr = dapl_os_alloc(sizeof(*cm_ptr))) == NULL)\r
-               return NULL;\r
-\r
-       (void)dapl_os_memzero(cm_ptr, sizeof(*cm_ptr));\r
-       if (dapl_os_lock_init(&cm_ptr->lock))\r
-               goto bail;\r
-\r
-       if (dapl_os_wait_object_init(&cm_ptr->event)) {\r
-               dapl_os_lock_destroy(&cm_ptr->lock);\r
-               goto bail;\r
-       }\r
-       dapl_llist_init_entry((DAPL_LLIST_ENTRY *)&cm_ptr->list_entry);\r
-       dapl_llist_init_entry((DAPL_LLIST_ENTRY *)&cm_ptr->local_entry);\r
-\r
-       cm_ptr->msg.ver = htons(DCM_VER);\r
-       cm_ptr->socket = DAPL_INVALID_SOCKET;\r
-       dapls_cm_acquire(cm_ptr);\r
-               \r
-       /* Link EP and CM */\r
-       if (ep_ptr != NULL) {\r
-               dapl_ep_link_cm(ep_ptr, cm_ptr); /* ref++ */\r
-               cm_ptr->ep = ep_ptr;\r
-               cm_ptr->hca = ((DAPL_IA *)ep_ptr->param.ia_handle)->hca_ptr;\r
-       }\r
-       return cm_ptr;\r
-bail:\r
-       dapl_os_free(cm_ptr, sizeof(*cm_ptr));\r
-       return NULL;\r
-}\r
-\r
-/* queue socket for processing CM work */\r
-static void dapli_cm_queue(dp_ib_cm_handle_t cm_ptr)\r
-{\r
-       /* add to work queue for cr thread processing */\r
-       dapl_os_lock(&cm_ptr->hca->ib_trans.lock);\r
-       dapls_cm_acquire(cm_ptr);\r
-       dapl_llist_add_tail(&cm_ptr->hca->ib_trans.list,\r
-                           (DAPL_LLIST_ENTRY *)&cm_ptr->local_entry, cm_ptr);\r
-       dapl_os_unlock(&cm_ptr->hca->ib_trans.lock);\r
-       dapli_cm_thread_signal(cm_ptr);\r
-}\r
-\r
-/* called with local LIST lock */\r
-static void dapli_cm_dequeue(dp_ib_cm_handle_t cm_ptr)\r
-{\r
-       /* Remove from work queue, cr thread processing */\r
-       dapl_llist_remove_entry(&cm_ptr->hca->ib_trans.list,\r
-                               (DAPL_LLIST_ENTRY *)&cm_ptr->local_entry);\r
-       dapls_cm_release(cm_ptr);\r
-}\r
-\r
-/* BLOCKING: called from dapl_ep_free, EP link will be last ref */\r
-void dapls_cm_free(dp_ib_cm_handle_t cm_ptr)\r
-{\r
-       dapl_log(DAPL_DBG_TYPE_CM,\r
-                " cm_free: cm %p %s ep %p refs=%d\n", \r
-                cm_ptr, dapl_cm_state_str(cm_ptr->state),\r
-                cm_ptr->ep, cm_ptr->ref_count);\r
-       \r
-       /* free from internal workq, wait until EP is last ref */\r
-       dapl_os_lock(&cm_ptr->lock);\r
-       cm_ptr->state = DCM_FREE;\r
-       while (cm_ptr->ref_count != 1) {\r
-               dapl_os_unlock(&cm_ptr->lock);\r
-               dapl_os_sleep_usec(10000);\r
-               dapl_os_lock(&cm_ptr->lock);\r
-       }\r
-       dapl_os_unlock(&cm_ptr->lock);\r
-\r
-       /* unlink, dequeue from EP. Final ref so release will destroy */\r
-       dapl_ep_unlink_cm(cm_ptr->ep, cm_ptr);\r
-}\r
-\r
-/*\r
- * ACTIVE/PASSIVE: called from CR thread or consumer via ep_disconnect\r
- *                 or from ep_free. \r
- */\r
-DAT_RETURN dapli_socket_disconnect(dp_ib_cm_handle_t cm_ptr)\r
-{\r
-       DAT_UINT32 disc_data = htonl(0xdead);\r
-\r
-       dapl_os_lock(&cm_ptr->lock);\r
-       if (cm_ptr->state != DCM_CONNECTED || \r
-           cm_ptr->state == DCM_DISCONNECTED) {\r
-               dapl_os_unlock(&cm_ptr->lock);\r
-               return DAT_SUCCESS;\r
-       }\r
-       cm_ptr->state = DCM_DISCONNECTED;\r
-       dapl_os_unlock(&cm_ptr->lock);\r
-       \r
-       /* send disc date, close socket, schedule destroy */\r
-       dapls_modify_qp_state(cm_ptr->ep->qp_handle, IBV_QPS_ERR, 0,0,0);\r
-       send(cm_ptr->socket, (char *)&disc_data, sizeof(disc_data), 0);\r
-\r
-       /* disconnect events for RC's only */\r
-       if (cm_ptr->ep->param.ep_attr.service_type == DAT_SERVICE_TYPE_RC) {\r
-               if (cm_ptr->ep->cr_ptr) {\r
-                       dapls_cr_callback(cm_ptr,\r
-                                         IB_CME_DISCONNECTED,\r
-                                         NULL, 0, cm_ptr->sp);\r
-               } else {\r
-                       dapl_evd_connection_callback(cm_ptr,\r
-                                                    IB_CME_DISCONNECTED,\r
-                                                    NULL, 0, cm_ptr->ep);\r
-               }\r
-       }\r
-       \r
-       /* release from workq */\r
-       dapli_cm_free(cm_ptr);\r
-\r
-       /* scheduled destroy via disconnect clean in callback */\r
-       return DAT_SUCCESS;\r
-}\r
-\r
-/*\r
- * ACTIVE: socket connected, send QP information to peer \r
- */\r
-static void dapli_socket_connected(dp_ib_cm_handle_t cm_ptr, int err)\r
-{\r
-       int len, exp;\r
-       struct iovec iov[2];\r
-       struct dapl_ep *ep_ptr = cm_ptr->ep;\r
-\r
-       if (err) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        " CONN_PENDING: %s ERR %s -> %s %d\n",\r
-                        err == -1 ? "POLL" : "SOCKOPT",\r
-                        err == -1 ? strerror(errno) : strerror(err), \r
-                        inet_ntoa(((struct sockaddr_in *)\r
-                               &cm_ptr->addr)->sin_addr), \r
-                        ntohs(((struct sockaddr_in *)\r
-                               &cm_ptr->addr)->sin_port));\r
-               goto bail;\r
-       }\r
-\r
-       cm_ptr->state = DCM_REP_PENDING;\r
-\r
-       /* send qp info and pdata to remote peer */\r
-       exp = sizeof(ib_cm_msg_t) - DCM_MAX_PDATA_SIZE;\r
-       iov[0].iov_base = (void *)&cm_ptr->msg;\r
-       iov[0].iov_len = exp;\r
-       if (cm_ptr->msg.p_size) {\r
-               iov[1].iov_base = cm_ptr->msg.p_data;\r
-               iov[1].iov_len = ntohs(cm_ptr->msg.p_size);\r
-               len = writev(cm_ptr->socket, iov, 2);\r
-       } else {\r
-               len = writev(cm_ptr->socket, iov, 1);\r
-       }\r
-\r
-       if (len != (exp + ntohs(cm_ptr->msg.p_size))) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        " CONN_PENDING len ERR %s, wcnt=%d(%d) -> %s\n",\r
-                        strerror(errno), len, \r
-                        exp + ntohs(cm_ptr->msg.p_size), \r
-                        inet_ntoa(((struct sockaddr_in *)\r
-                                  ep_ptr->param.\r
-                                  remote_ia_address_ptr)->sin_addr));\r
-               goto bail;\r
-       }\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
-                    " CONN_PENDING: sending SRC lid=0x%x,"\r
-                    " qpn=0x%x, psize=%d\n",\r
-                    ntohs(cm_ptr->msg.saddr.ib.lid),\r
-                    ntohl(cm_ptr->msg.saddr.ib.qpn), \r
-                    ntohs(cm_ptr->msg.p_size));\r
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
-                    " CONN_PENDING: SRC GID subnet %016llx id %016llx\n",\r
-                    (unsigned long long)\r
-                    htonll(*(uint64_t*)&cm_ptr->msg.saddr.ib.gid[0]),\r
-                    (unsigned long long)\r
-                    htonll(*(uint64_t*)&cm_ptr->msg.saddr.ib.gid[8]));\r
-       return;\r
-\r
-bail:\r
-       /* mark CM object for cleanup */\r
-       dapli_cm_free(cm_ptr);\r
-       dapl_evd_connection_callback(NULL, IB_CME_LOCAL_FAILURE, NULL, 0, ep_ptr);\r
-}\r
-\r
-/*\r
- * ACTIVE: Create socket, connect, defer exchange QP information to CR thread\r
- * to avoid blocking. \r
- */\r
-static DAT_RETURN\r
-dapli_socket_connect(DAPL_EP * ep_ptr,\r
-                    DAT_IA_ADDRESS_PTR r_addr,\r
-                    DAT_CONN_QUAL r_qual, DAT_COUNT p_size, DAT_PVOID p_data)\r
-{\r
-       dp_ib_cm_handle_t cm_ptr;\r
-       int ret;\r
-       socklen_t sl;\r
-       DAPL_IA *ia_ptr = ep_ptr->header.owner_ia;\r
-       DAT_RETURN dat_ret = DAT_INSUFFICIENT_RESOURCES;\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_EP, " connect: r_qual %d p_size=%d\n",\r
-                    r_qual, p_size);\r
-\r
-       cm_ptr = dapli_cm_alloc(ep_ptr);\r
-       if (cm_ptr == NULL)\r
-               return dat_ret;\r
-\r
-       /* create, connect, sockopt, and exchange QP information */\r
-       if ((cm_ptr->socket =\r
-            socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == DAPL_INVALID_SOCKET) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        " connect: socket create ERR %s\n", strerror(errno));\r
-               goto bail;\r
-       }\r
-\r
-       ret = dapl_config_socket(cm_ptr->socket);\r
-       if (ret < 0) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        " connect: config socket %d ERR %d %s\n",\r
-                        cm_ptr->socket, ret, strerror(dapl_socket_errno()));\r
-               dat_ret = DAT_INTERNAL_ERROR;\r
-               goto bail;\r
-       }\r
-\r
-       /* save remote address */\r
-       dapl_os_memcpy(&cm_ptr->addr, r_addr, sizeof(*r_addr));\r
-\r
-#ifdef DAPL_DBG\r
-       /* DBG: Active PID [0], PASSIVE PID [2]*/\r
-       *(uint16_t*)&cm_ptr->msg.resv[0] = htons((uint16_t)dapl_os_getpid()); \r
-       *(uint16_t*)&cm_ptr->msg.resv[2] = ((struct sockaddr_in *)&cm_ptr->addr)->sin_port;\r
-#endif\r
-       ((struct sockaddr_in *)&cm_ptr->addr)->sin_port = htons(r_qual + 1000);\r
-       ret = dapl_connect_socket(cm_ptr->socket, (struct sockaddr *)&cm_ptr->addr,\r
-                                 sizeof(cm_ptr->addr));\r
-       if (ret && ret != EAGAIN) {\r
-               dat_ret = DAT_INVALID_ADDRESS;\r
-               goto bail;\r
-       }\r
-\r
-       /* REQ: QP info in msg.saddr, IA address in msg.daddr, and pdata */\r
-       cm_ptr->hca = ia_ptr->hca_ptr;\r
-       cm_ptr->msg.op = ntohs(DCM_REQ);\r
-       cm_ptr->msg.saddr.ib.qpn = htonl(ep_ptr->qp_handle->qp_num);\r
-       cm_ptr->msg.saddr.ib.qp_type = ep_ptr->qp_handle->qp_type;\r
-       cm_ptr->msg.saddr.ib.lid = ia_ptr->hca_ptr->ib_trans.lid;\r
-       dapl_os_memcpy(&cm_ptr->msg.saddr.ib.gid[0], \r
-                      &ia_ptr->hca_ptr->ib_trans.gid, 16);\r
-       \r
-       /* get local address information from socket */\r
-       sl = sizeof(cm_ptr->msg.daddr.so);\r
-       if (getsockname(cm_ptr->socket, (struct sockaddr *)&cm_ptr->msg.daddr.so, &sl)) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                       " connect getsockname ERROR: %s -> %s r_qual %d\n",\r
-                       strerror(errno), \r
-                       inet_ntoa(((struct sockaddr_in *)r_addr)->sin_addr),\r
-                       (unsigned int)r_qual);;\r
-       }\r
-\r
-       if (p_size) {\r
-               cm_ptr->msg.p_size = htons(p_size);\r
-               dapl_os_memcpy(cm_ptr->msg.p_data, p_data, p_size);\r
-       }\r
-\r
-       /* connected or pending, either way results via async event */\r
-       if (ret == 0)\r
-               dapli_socket_connected(cm_ptr, 0);\r
-       else\r
-               cm_ptr->state = DCM_CONN_PENDING;\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_EP, " connect: p_data=%p %p\n",\r
-                    cm_ptr->msg.p_data, cm_ptr->msg.p_data);\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_EP,\r
-                    " connect: %s r_qual %d pending, p_sz=%d, %d %d ...\n",\r
-                    inet_ntoa(((struct sockaddr_in *)&cm_ptr->addr)->sin_addr), \r
-                    (unsigned int)r_qual, ntohs(cm_ptr->msg.p_size),\r
-                    cm_ptr->msg.p_data[0], cm_ptr->msg.p_data[1]);\r
-\r
-       /* queue up on work thread */\r
-       dapli_cm_queue(cm_ptr);\r
-       return DAT_SUCCESS;\r
-bail:\r
-       dapl_log(DAPL_DBG_TYPE_ERR,\r
-                " connect ERROR: %s -> %s r_qual %d\n",\r
-                strerror(errno), \r
-                inet_ntoa(((struct sockaddr_in *)r_addr)->sin_addr),\r
-                (unsigned int)r_qual);\r
-\r
-       /* Never queued, destroy */\r
-       dapls_cm_release(cm_ptr);\r
-       return dat_ret;\r
-}\r
-\r
-/*\r
- * ACTIVE: exchange QP information, called from CR thread\r
- */\r
-static void dapli_socket_connect_rtu(dp_ib_cm_handle_t cm_ptr)\r
-{\r
-       DAPL_EP *ep_ptr = cm_ptr->ep;\r
-       int len, exp = sizeof(ib_cm_msg_t) - DCM_MAX_PDATA_SIZE;\r
-       ib_cm_events_t event = IB_CME_LOCAL_FAILURE;\r
-       socklen_t sl;\r
-\r
-       /* read DST information into cm_ptr, overwrite SRC info */\r
-       dapl_dbg_log(DAPL_DBG_TYPE_EP, " connect_rtu: recv peer QP data\n");\r
-\r
-       len = recv(cm_ptr->socket, (char *)&cm_ptr->msg, exp, 0);\r
-       if (len != exp || ntohs(cm_ptr->msg.ver) != DCM_VER) {\r
-               dapl_log(DAPL_DBG_TYPE_WARN,\r
-                        " CONN_RTU read: sk %d ERR %s, rcnt=%d, v=%d -> %s PORT L-%x R-%x PID L-%x R-%x\n",\r
-                        cm_ptr->socket, strerror(errno), len, ntohs(cm_ptr->msg.ver),\r
-                        inet_ntoa(((struct sockaddr_in *)&cm_ptr->addr)->sin_addr),\r
-                        ntohs(((struct sockaddr_in *)&cm_ptr->msg.daddr.so)->sin_port),\r
-                        ntohs(((struct sockaddr_in *)&cm_ptr->addr)->sin_port),\r
-                        ntohs(*(uint16_t*)&cm_ptr->msg.resv[0]),\r
-                        ntohs(*(uint16_t*)&cm_ptr->msg.resv[2]));\r
-\r
-               /* Retry; corner case where server tcp stack resets under load */\r
-               if (dapl_socket_errno() == ECONNRESET) {\r
-                       closesocket(cm_ptr->socket);\r
-                       cm_ptr->socket = DAPL_INVALID_SOCKET;\r
-                       dapli_socket_connect(cm_ptr->ep, (DAT_IA_ADDRESS_PTR)&cm_ptr->addr, \r
-                                            ntohs(((struct sockaddr_in *)&cm_ptr->addr)->sin_port) - 1000,\r
-                                            ntohs(cm_ptr->msg.p_size), &cm_ptr->msg.p_data);\r
-                       dapl_ep_unlink_cm(cm_ptr->ep, cm_ptr);\r
-                       dapli_cm_free(cm_ptr);\r
-                       return;\r
-               }\r
-               goto bail;\r
-       }\r
-\r
-       /* keep the QP, address info in network order */\r
-       \r
-       /* save remote address information, in msg.daddr */\r
-       dapl_os_memcpy(&ep_ptr->remote_ia_address,\r
-                      &cm_ptr->msg.daddr.so,\r
-                      sizeof(union dcm_addr));\r
-\r
-       /* save local address information from socket */\r
-       sl = sizeof(cm_ptr->addr);\r
-       getsockname(cm_ptr->socket,(struct sockaddr *)&cm_ptr->addr, &sl);\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_EP,\r
-                    " CONN_RTU: DST %s %d lid=0x%x,"\r
-                    " qpn=0x%x, qp_type=%d, psize=%d\n",\r
-                    inet_ntoa(((struct sockaddr_in *)\r
-                               &cm_ptr->msg.daddr.so)->sin_addr),\r
-                    ntohs(((struct sockaddr_in *)\r
-                               &cm_ptr->msg.daddr.so)->sin_port),\r
-                    ntohs(cm_ptr->msg.saddr.ib.lid),\r
-                    ntohl(cm_ptr->msg.saddr.ib.qpn), \r
-                    cm_ptr->msg.saddr.ib.qp_type, \r
-                    ntohs(cm_ptr->msg.p_size));\r
-\r
-       /* validate private data size before reading */\r
-       if (ntohs(cm_ptr->msg.p_size) > DCM_MAX_PDATA_SIZE) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        " CONN_RTU read: psize (%d) wrong -> %s\n",\r
-                        ntohs(cm_ptr->msg.p_size), \r
-                        inet_ntoa(((struct sockaddr_in *)\r
-                                  ep_ptr->param.\r
-                                  remote_ia_address_ptr)->sin_addr));\r
-               goto bail;\r
-       }\r
-\r
-       /* read private data into cm_handle if any present */\r
-       dapl_dbg_log(DAPL_DBG_TYPE_EP," CONN_RTU: read private data\n");\r
-       exp = ntohs(cm_ptr->msg.p_size);\r
-       if (exp) {\r
-               len = recv(cm_ptr->socket, cm_ptr->msg.p_data, exp, 0);\r
-               if (len != exp) {\r
-                       dapl_log(DAPL_DBG_TYPE_ERR,\r
-                                " CONN_RTU read pdata: ERR %s, rcnt=%d -> %s\n",\r
-                                strerror(errno), len,\r
-                                inet_ntoa(((struct sockaddr_in *)\r
-                                           ep_ptr->param.\r
-                                           remote_ia_address_ptr)->sin_addr));\r
-                       goto bail;\r
-               }\r
-       }\r
-\r
-       /* check for consumer or protocol stack reject */\r
-       if (ntohs(cm_ptr->msg.op) == DCM_REP)\r
-               event = IB_CME_CONNECTED;\r
-       else if (ntohs(cm_ptr->msg.op) == DCM_REJ_USER) \r
-               event = IB_CME_DESTINATION_REJECT_PRIVATE_DATA;\r
-       else  \r
-               event = IB_CME_DESTINATION_REJECT;\r
-       \r
-       if (event != IB_CME_CONNECTED) {\r
-               dapl_log(DAPL_DBG_TYPE_CM,\r
-                        " CONN_RTU: reject from %s %x\n",\r
-                        inet_ntoa(((struct sockaddr_in *)\r
-                                   &cm_ptr->msg.daddr.so)->sin_addr),\r
-                        ntohs(((struct sockaddr_in *)\r
-                                &cm_ptr->msg.daddr.so)->sin_port));\r
-               goto bail;\r
-       }\r
-\r
-       /* modify QP to RTR and then to RTS with remote info */\r
-       if (dapls_modify_qp_state(ep_ptr->qp_handle,\r
-                                 IBV_QPS_RTR, \r
-                                 cm_ptr->msg.saddr.ib.qpn,\r
-                                 cm_ptr->msg.saddr.ib.lid,\r
-                                 (ib_gid_handle_t)cm_ptr->msg.saddr.ib.gid) != DAT_SUCCESS) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        " CONN_RTU: QPS_RTR ERR %s (%d,%d,%x,%x,%x) -> %s %x\n",\r
-                        strerror(errno), ep_ptr->qp_handle->qp_type,\r
-                        ep_ptr->qp_state, ep_ptr->qp_handle->qp_num,\r
-                        ntohl(cm_ptr->msg.saddr.ib.qpn), \r
-                        ntohs(cm_ptr->msg.saddr.ib.lid),\r
-                        inet_ntoa(((struct sockaddr_in *)\r
-                                   &cm_ptr->msg.daddr.so)->sin_addr),\r
-                        ntohs(((struct sockaddr_in *)\r
-                                &cm_ptr->msg.daddr.so)->sin_port));\r
-               goto bail;\r
-       }\r
-       if (dapls_modify_qp_state(ep_ptr->qp_handle,\r
-                                 IBV_QPS_RTS, \r
-                                 cm_ptr->msg.saddr.ib.qpn,\r
-                                 cm_ptr->msg.saddr.ib.lid,\r
-                                 NULL) != DAT_SUCCESS) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        " CONN_RTU: QPS_RTS ERR %s (%d,%d,%x,%x,%x) -> %s %x\n",\r
-                        strerror(errno), ep_ptr->qp_handle->qp_type,\r
-                        ep_ptr->qp_state, ep_ptr->qp_handle->qp_num,\r
-                        ntohl(cm_ptr->msg.saddr.ib.qpn), \r
-                        ntohs(cm_ptr->msg.saddr.ib.lid),\r
-                        inet_ntoa(((struct sockaddr_in *)\r
-                                   &cm_ptr->msg.daddr.so)->sin_addr),\r
-                        ntohs(((struct sockaddr_in *)\r
-                                &cm_ptr->msg.daddr.so)->sin_port));\r
-               goto bail;\r
-       }\r
-       dapl_dbg_log(DAPL_DBG_TYPE_EP, " connect_rtu: send RTU\n");\r
-\r
-       /* complete handshake after final QP state change, Just ver+op */\r
-       cm_ptr->state = DCM_CONNECTED;\r
-       cm_ptr->msg.op = ntohs(DCM_RTU);\r
-       if (send(cm_ptr->socket, (char *)&cm_ptr->msg, 4, 0) == -1) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        " CONN_RTU: write error = %s\n", strerror(errno));\r
-               goto bail;\r
-       }\r
-       /* post the event with private data */\r
-       event = IB_CME_CONNECTED;\r
-       dapl_dbg_log(DAPL_DBG_TYPE_EP, " ACTIVE: connected!\n");\r
-\r
-#ifdef DAT_EXTENSIONS\r
-ud_bail:\r
-       if (cm_ptr->msg.saddr.ib.qp_type == IBV_QPT_UD) {\r
-               DAT_IB_EXTENSION_EVENT_DATA xevent;\r
-               ib_pd_handle_t pd_handle = \r
-                       ((DAPL_PZ *)ep_ptr->param.pz_handle)->pd_handle;\r
-\r
-               if (event == IB_CME_CONNECTED) {\r
-                       cm_ptr->ah = dapls_create_ah(cm_ptr->hca, pd_handle,\r
-                                                    ep_ptr->qp_handle,\r
-                                                    cm_ptr->msg.saddr.ib.lid, \r
-                                                    NULL);\r
-                       if (cm_ptr->ah) {\r
-                               /* post UD extended EVENT */\r
-                               xevent.status = 0;\r
-                               xevent.type = DAT_IB_UD_REMOTE_AH;\r
-                               xevent.remote_ah.ah = cm_ptr->ah;\r
-                               xevent.remote_ah.qpn = ntohl(cm_ptr->msg.saddr.ib.qpn);\r
-                               dapl_os_memcpy(&xevent.remote_ah.ia_addr,\r
-                                               &ep_ptr->remote_ia_address,\r
-                                               sizeof(union dcm_addr));\r
-                               event = DAT_IB_UD_CONNECTION_EVENT_ESTABLISHED;\r
-\r
-                               dapl_log(DAPL_DBG_TYPE_CM, \r
-                                       " CONN_RTU: UD AH %p for lid 0x%x"\r
-                                       " qpn 0x%x\n", \r
-                                       cm_ptr->ah, \r
-                                       ntohs(cm_ptr->msg.saddr.ib.lid),\r
-                                       ntohl(cm_ptr->msg.saddr.ib.qpn));\r
-       \r
-                       } else \r
-                               event = DAT_IB_UD_CONNECTION_ERROR_EVENT;\r
-                       \r
-               } else if (event == IB_CME_LOCAL_FAILURE) {\r
-                       event = DAT_IB_UD_CONNECTION_ERROR_EVENT;\r
-               } else  \r
-                       event = DAT_IB_UD_CONNECTION_REJECT_EVENT;\r
-\r
-               dapls_evd_post_connection_event_ext(\r
-                               (DAPL_EVD *) ep_ptr->param.connect_evd_handle,\r
-                               event,\r
-                               (DAT_EP_HANDLE) ep_ptr,\r
-                               (DAT_COUNT) exp,\r
-                               (DAT_PVOID *) cm_ptr->msg.p_data,\r
-                               (DAT_PVOID *) &xevent);\r
-\r
-               /* cleanup and release from local list */\r
-               dapli_cm_free(cm_ptr);\r
-       \r
-       } else\r
-#endif\r
-       {\r
-               dapl_evd_connection_callback(cm_ptr, event, cm_ptr->msg.p_data,\r
-                                            DCM_MAX_PDATA_SIZE, ep_ptr);\r
-       }\r
-       return;\r
-\r
-bail:\r
-\r
-#ifdef DAT_EXTENSIONS\r
-       if (cm_ptr->msg.saddr.ib.qp_type == IBV_QPT_UD) \r
-               goto ud_bail;\r
-#endif\r
-       /* close socket, and post error event */\r
-       cm_ptr->state = DCM_REJECTED;\r
-       dapl_evd_connection_callback(NULL, event, cm_ptr->msg.p_data,\r
-                                    DCM_MAX_PDATA_SIZE, ep_ptr);\r
-       dapli_cm_free(cm_ptr);\r
-}\r
-\r
-/*\r
- * PASSIVE: Create socket, listen, accept, exchange QP information \r
- */\r
-DAT_RETURN\r
-dapli_socket_listen(DAPL_IA * ia_ptr, DAT_CONN_QUAL serviceID, DAPL_SP * sp_ptr)\r
-{\r
-       struct sockaddr_in addr;\r
-       ib_cm_srvc_handle_t cm_ptr = NULL;\r
-       DAT_RETURN dat_status = DAT_SUCCESS;\r
-       int opt = 1;\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
-                    " setup listen(ia_ptr %p ServiceID %d sp_ptr %p)\n",\r
-                    ia_ptr, serviceID, sp_ptr);\r
-\r
-       cm_ptr = dapli_cm_alloc(NULL);\r
-       if (cm_ptr == NULL)\r
-               return DAT_INSUFFICIENT_RESOURCES;\r
-\r
-       cm_ptr->sp = sp_ptr;\r
-       cm_ptr->hca = ia_ptr->hca_ptr;\r
-\r
-       /* bind, listen, set sockopt, accept, exchange data */\r
-       if ((cm_ptr->socket =\r
-            socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == DAPL_INVALID_SOCKET) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR, " ERR: listen socket create: %s\n",\r
-                        strerror(errno));\r
-               dat_status = DAT_INSUFFICIENT_RESOURCES;\r
-               goto bail;\r
-       }\r
-\r
-       setsockopt(cm_ptr->socket, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt));\r
-       addr.sin_port = htons(serviceID + 1000);\r
-       addr.sin_family = AF_INET;\r
-       addr.sin_addr = ((struct sockaddr_in *) &ia_ptr->hca_ptr->hca_address)->sin_addr;\r
-\r
-       if ((bind(cm_ptr->socket, (struct sockaddr *)&addr, sizeof(addr)) < 0)\r
-           || (listen(cm_ptr->socket, 128) < 0)) {\r
-               dapl_log(DAPL_DBG_TYPE_CM,\r
-                        " listen: ERROR %s on port %d\n",\r
-                        strerror(errno), serviceID + 1000);\r
-               if (dapl_socket_errno() == EADDRINUSE)\r
-                       dat_status = DAT_CONN_QUAL_IN_USE;\r
-               else\r
-                       dat_status = DAT_CONN_QUAL_UNAVAILABLE;\r
-               goto bail;\r
-       }\r
-\r
-       /* set cm_handle for this service point, save listen socket */\r
-       sp_ptr->cm_srvc_handle = cm_ptr;\r
-       dapl_os_memcpy(&cm_ptr->addr, &addr, sizeof(addr)); \r
-\r
-       /* queue up listen socket to process inbound CR's */\r
-       cm_ptr->state = DCM_LISTEN;\r
-       dapli_cm_queue(cm_ptr);\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
-                    " setup listen: port %d cr %p s_fd %d\n",\r
-                    serviceID + 1000, cm_ptr, cm_ptr->socket);\r
-\r
-       return dat_status;\r
-bail:\r
-       /* Never queued, destroy here */\r
-       dapls_cm_release(cm_ptr);\r
-       return dat_status;\r
-}\r
-\r
-/*\r
- * PASSIVE: accept socket \r
- */\r
-static void dapli_socket_accept(ib_cm_srvc_handle_t cm_ptr)\r
-{\r
-       dp_ib_cm_handle_t acm_ptr;\r
-       int ret, len, opt = 1;\r
-       socklen_t sl;\r
-\r
-       /* \r
-        * Accept all CR's on this port to avoid half-connection (SYN_RCV)\r
-        * stalls with many to one connection storms\r
-        */\r
-       do {\r
-               /* Allocate accept CM and initialize */\r
-               if ((acm_ptr = dapli_cm_alloc(NULL)) == NULL)\r
-                       return;\r
-\r
-               acm_ptr->sp = cm_ptr->sp;\r
-               acm_ptr->hca = cm_ptr->hca;\r
-\r
-               len = sizeof(union dcm_addr);\r
-               acm_ptr->socket = accept(cm_ptr->socket,\r
-                                       (struct sockaddr *)\r
-                                       &acm_ptr->msg.daddr.so,\r
-                                       (socklen_t *) &len);\r
-               if (acm_ptr->socket == DAPL_INVALID_SOCKET) {\r
-                       dapl_log(DAPL_DBG_TYPE_ERR,\r
-                               " ACCEPT: ERR %s on FD %d l_cr %p\n",\r
-                               strerror(errno), cm_ptr->socket, cm_ptr);\r
-                       dapls_cm_release(acm_ptr);\r
-                       return;\r
-               }\r
-               dapl_dbg_log(DAPL_DBG_TYPE_CM, " accepting from %s %x\n",\r
-                            inet_ntoa(((struct sockaddr_in *)\r
-                                       &acm_ptr->msg.daddr.so)->sin_addr),\r
-                            ntohs(((struct sockaddr_in *)\r
-                                       &acm_ptr->msg.daddr.so)->sin_port));\r
-\r
-               /* no delay for small packets */\r
-               ret = setsockopt(acm_ptr->socket, IPPROTO_TCP, TCP_NODELAY,\r
-                          (char *)&opt, sizeof(opt));\r
-               if (ret)\r
-                       dapl_log(DAPL_DBG_TYPE_ERR,\r
-                                " ACCEPT: NODELAY setsockopt: 0x%x 0x%x %s\n",\r
-                                ret, dapl_socket_errno(), strerror(dapl_socket_errno()));\r
-               \r
-               /* get local address information from socket */\r
-               sl = sizeof(acm_ptr->addr);\r
-               getsockname(acm_ptr->socket, (struct sockaddr *)&acm_ptr->addr, &sl);\r
-               acm_ptr->state = DCM_ACCEPTING;\r
-               dapli_cm_queue(acm_ptr);\r
-       \r
-       } while (dapl_poll(cm_ptr->socket, DAPL_FD_READ) == DAPL_FD_READ);\r
-}\r
-\r
-/*\r
- * PASSIVE: receive peer QP information, private data, post cr_event \r
- */\r
-static void dapli_socket_accept_data(ib_cm_srvc_handle_t acm_ptr)\r
-{\r
-       int len, exp = sizeof(ib_cm_msg_t) - DCM_MAX_PDATA_SIZE;\r
-       void *p_data = NULL;\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_EP, " socket accepted, read QP data\n");\r
-\r
-       /* read in DST QP info, IA address. check for private data */\r
-       len = recv(acm_ptr->socket, (char *)&acm_ptr->msg, exp, 0);\r
-       if (len != exp || ntohs(acm_ptr->msg.ver) != DCM_VER) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        " ACCEPT read: ERR %s, rcnt=%d, ver=%d\n",\r
-                        strerror(errno), len, ntohs(acm_ptr->msg.ver));\r
-               goto bail;\r
-       }\r
-\r
-       /* keep the QP, address info in network order */\r
-\r
-       /* validate private data size before reading */\r
-       exp = ntohs(acm_ptr->msg.p_size);\r
-       if (exp > DCM_MAX_PDATA_SIZE) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                            " accept read: psize (%d) wrong\n",\r
-                            acm_ptr->msg.p_size);\r
-               goto bail;\r
-       }\r
-\r
-       /* read private data into cm_handle if any present */\r
-       if (exp) {\r
-               len = recv(acm_ptr->socket, acm_ptr->msg.p_data, exp, 0);\r
-               if (len != exp) {\r
-                       dapl_log(DAPL_DBG_TYPE_ERR,\r
-                                " accept read pdata: ERR %s, rcnt=%d\n",\r
-                                strerror(errno), len);\r
-                       goto bail;\r
-               }\r
-               p_data = acm_ptr->msg.p_data;\r
-       }\r
-\r
-       acm_ptr->state = DCM_ACCEPTING_DATA;\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
-                    " ACCEPT: DST %s %x lid=0x%x, qpn=0x%x, psz=%d\n",\r
-                    inet_ntoa(((struct sockaddr_in *)\r
-                               &acm_ptr->msg.daddr.so)->sin_addr), \r
-                    ntohs(((struct sockaddr_in *)\r
-                            &acm_ptr->msg.daddr.so)->sin_port),\r
-                    ntohs(acm_ptr->msg.saddr.ib.lid), \r
-                    ntohl(acm_ptr->msg.saddr.ib.qpn), exp);\r
-\r
-#ifdef DAT_EXTENSIONS\r
-       if (acm_ptr->msg.saddr.ib.qp_type == IBV_QPT_UD) {\r
-               DAT_IB_EXTENSION_EVENT_DATA xevent;\r
-\r
-               /* post EVENT, modify_qp created ah */\r
-               xevent.status = 0;\r
-               xevent.type = DAT_IB_UD_CONNECT_REQUEST;\r
-\r
-               dapls_evd_post_cr_event_ext(acm_ptr->sp,\r
-                                           DAT_IB_UD_CONNECTION_REQUEST_EVENT,\r
-                                           acm_ptr,\r
-                                           (DAT_COUNT) exp,\r
-                                           (DAT_PVOID *) acm_ptr->msg.p_data,\r
-                                           (DAT_PVOID *) &xevent);\r
-       } else\r
-#endif\r
-               /* trigger CR event and return SUCCESS */\r
-               dapls_cr_callback(acm_ptr,\r
-                                 IB_CME_CONNECTION_REQUEST_PENDING,\r
-                                 p_data, exp, acm_ptr->sp);\r
-       return;\r
-bail:\r
-       /* mark for destroy, active will see socket close as rej */\r
-       dapli_cm_free(acm_ptr);\r
-       return;\r
-}\r
-\r
-/*\r
- * PASSIVE: consumer accept, send local QP information, private data, \r
- * queue on work thread to receive RTU information to avoid blocking\r
- * user thread. \r
- */\r
-static DAT_RETURN\r
-dapli_socket_accept_usr(DAPL_EP * ep_ptr,\r
-                       DAPL_CR * cr_ptr, DAT_COUNT p_size, DAT_PVOID p_data)\r
-{\r
-       DAPL_IA *ia_ptr = ep_ptr->header.owner_ia;\r
-       dp_ib_cm_handle_t cm_ptr = cr_ptr->ib_cm_handle;\r
-       ib_cm_msg_t local;\r
-       struct iovec iov[2];\r
-       int len, exp = sizeof(ib_cm_msg_t) - DCM_MAX_PDATA_SIZE;\r
-       DAT_RETURN ret = DAT_INTERNAL_ERROR;\r
-       socklen_t sl;\r
-\r
-       if (p_size > DCM_MAX_PDATA_SIZE) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        " accept_usr: psize(%d) too large\n", p_size);\r
-               return DAT_LENGTH_ERROR;\r
-       }\r
-\r
-       /* must have a accepted socket */\r
-       if (cm_ptr->socket == DAPL_INVALID_SOCKET) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        " accept_usr: cm socket invalid\n");\r
-               goto bail;\r
-       }\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
-                    " ACCEPT_USR: remote lid=0x%x"\r
-                    " qpn=0x%x qp_type %d, psize=%d\n",\r
-                    ntohs(cm_ptr->msg.saddr.ib.lid),\r
-                    ntohl(cm_ptr->msg.saddr.ib.qpn), \r
-                    cm_ptr->msg.saddr.ib.qp_type, \r
-                    ntohs(cm_ptr->msg.p_size));\r
-\r
-#ifdef DAT_EXTENSIONS\r
-       if (cm_ptr->msg.saddr.ib.qp_type == IBV_QPT_UD &&\r
-           ep_ptr->qp_handle->qp_type != IBV_QPT_UD) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        " ACCEPT_USR: ERR remote QP is UD,"\r
-                        ", but local QP is not\n");\r
-               ret = (DAT_INVALID_HANDLE | DAT_INVALID_HANDLE_EP);\r
-               goto bail;\r
-       }\r
-#endif\r
-\r
-       /* modify QP to RTR and then to RTS with remote info already read */\r
-       if (dapls_modify_qp_state(ep_ptr->qp_handle,\r
-                                 IBV_QPS_RTR, \r
-                                 cm_ptr->msg.saddr.ib.qpn,\r
-                                 cm_ptr->msg.saddr.ib.lid,\r
-                                 (ib_gid_handle_t)cm_ptr->msg.saddr.ib.gid) != DAT_SUCCESS) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        " ACCEPT_USR: QPS_RTR ERR %s -> %s\n",\r
-                        strerror(errno), \r
-                        inet_ntoa(((struct sockaddr_in *)\r
-                                    &cm_ptr->msg.daddr.so)->sin_addr));\r
-               goto bail;\r
-       }\r
-       if (dapls_modify_qp_state(ep_ptr->qp_handle,\r
-                                 IBV_QPS_RTS, \r
-                                 cm_ptr->msg.saddr.ib.qpn,\r
-                                 cm_ptr->msg.saddr.ib.lid,\r
-                                 NULL) != DAT_SUCCESS) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        " ACCEPT_USR: QPS_RTS ERR %s -> %s\n",\r
-                        strerror(errno), \r
-                        inet_ntoa(((struct sockaddr_in *)\r
-                                    &cm_ptr->msg.daddr.so)->sin_addr));\r
-               goto bail;\r
-       }\r
-\r
-       /* save remote address information */\r
-       dapl_os_memcpy(&ep_ptr->remote_ia_address,\r
-                      &cm_ptr->msg.daddr.so,\r
-                      sizeof(union dcm_addr));\r
-\r
-       /* send our QP info, IA address, pdata. Don't overwrite dst data */\r
-       local.ver = htons(DCM_VER);\r
-       local.op = htons(DCM_REP);\r
-       local.saddr.ib.qpn = htonl(ep_ptr->qp_handle->qp_num);\r
-       local.saddr.ib.qp_type = ep_ptr->qp_handle->qp_type;\r
-       local.saddr.ib.lid = ia_ptr->hca_ptr->ib_trans.lid;\r
-       dapl_os_memcpy(&local.saddr.ib.gid[0], \r
-                      &ia_ptr->hca_ptr->ib_trans.gid, 16);\r
-       \r
-       /* Get local address information from socket */\r
-       sl = sizeof(local.daddr.so);\r
-       getsockname(cm_ptr->socket, (struct sockaddr *)&local.daddr.so, &sl);\r
-\r
-#ifdef DAPL_DBG\r
-       /* DBG: Active PID [0], PASSIVE PID [2] */\r
-       *(uint16_t*)&cm_ptr->msg.resv[2] = htons((uint16_t)dapl_os_getpid()); \r
-       dapl_os_memcpy(local.resv, cm_ptr->msg.resv, 4); \r
-#endif\r
-       cm_ptr->hca = ia_ptr->hca_ptr;\r
-       cm_ptr->state = DCM_ACCEPTED;\r
-\r
-       /* Link CM to EP, already queued on work thread */\r
-       dapl_ep_link_cm(ep_ptr, cm_ptr);\r
-       cm_ptr->ep = ep_ptr;\r
-\r
-       local.p_size = htons(p_size);\r
-       iov[0].iov_base = (void *)&local;\r
-       iov[0].iov_len = exp;\r
-       \r
-       if (p_size) {\r
-               iov[1].iov_base = p_data;\r
-               iov[1].iov_len = p_size;\r
-               len = writev(cm_ptr->socket, iov, 2);\r
-       } else \r
-               len = writev(cm_ptr->socket, iov, 1);\r
-       \r
-       if (len != (p_size + exp)) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        " ACCEPT_USR: ERR %s, wcnt=%d -> %s\n",\r
-                        strerror(errno), len, \r
-                        inet_ntoa(((struct sockaddr_in *)\r
-                                  &cm_ptr->msg.daddr.so)->sin_addr));\r
-               dapl_ep_unlink_cm(ep_ptr, cm_ptr);\r
-               cm_ptr->ep = NULL;\r
-               goto bail;\r
-       }\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
-                    " ACCEPT_USR: local lid=0x%x qpn=0x%x psz=%d\n",\r
-                    ntohs(local.saddr.ib.lid),\r
-                    ntohl(local.saddr.ib.qpn), ntohs(local.p_size));\r
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
-                    " ACCEPT_USR: SRC GID subnet %016llx id %016llx\n",\r
-                    (unsigned long long)\r
-                    htonll(*(uint64_t*)&local.saddr.ib.gid[0]),\r
-                    (unsigned long long)\r
-                    htonll(*(uint64_t*)&local.saddr.ib.gid[8]));\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_EP, " PASSIVE: accepted!\n");\r
-\r
-       return DAT_SUCCESS;\r
-bail:\r
-       /* schedule cleanup from workq */\r
-       dapli_cm_free(cm_ptr);\r
-       return ret;\r
-}\r
-\r
-/*\r
- * PASSIVE: read RTU from active peer, post CONN event\r
- */\r
-static void dapli_socket_accept_rtu(dp_ib_cm_handle_t cm_ptr)\r
-{\r
-       int len;\r
-       ib_cm_events_t event = IB_CME_CONNECTED;\r
-\r
-       /* complete handshake after final QP state change, VER and OP */\r
-       len = recv(cm_ptr->socket, (char *)&cm_ptr->msg, 4, 0);\r
-       if (len != 4 || ntohs(cm_ptr->msg.op) != DCM_RTU) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        " ACCEPT_RTU: rcv ERR, rcnt=%d op=%x\n",\r
-                        len, ntohs(cm_ptr->msg.op),\r
-                        inet_ntoa(((struct sockaddr_in *)\r
-                                   &cm_ptr->msg.daddr.so)->sin_addr));\r
-               event = IB_CME_DESTINATION_REJECT;\r
-               goto bail;\r
-       }\r
-\r
-       /* save state and reference to EP, queue for disc event */\r
-       cm_ptr->state = DCM_CONNECTED;\r
-\r
-       /* final data exchange if remote QP state is good to go */\r
-       dapl_dbg_log(DAPL_DBG_TYPE_EP, " PASSIVE: connected!\n");\r
-\r
-#ifdef DAT_EXTENSIONS\r
-ud_bail:\r
-       if (cm_ptr->msg.saddr.ib.qp_type == IBV_QPT_UD) {\r
-               DAT_IB_EXTENSION_EVENT_DATA xevent;\r
-\r
-               ib_pd_handle_t pd_handle = \r
-                       ((DAPL_PZ *)cm_ptr->ep->param.pz_handle)->pd_handle;\r
-               \r
-               if (event == IB_CME_CONNECTED) {\r
-                       cm_ptr->ah = dapls_create_ah(cm_ptr->hca, pd_handle,\r
-                                               cm_ptr->ep->qp_handle,\r
-                                               cm_ptr->msg.saddr.ib.lid, \r
-                                               NULL);\r
-                       if (cm_ptr->ah) { \r
-                               /* post EVENT, modify_qp created ah */\r
-                               xevent.status = 0;\r
-                               xevent.type = DAT_IB_UD_PASSIVE_REMOTE_AH;\r
-                               xevent.remote_ah.ah = cm_ptr->ah;\r
-                               xevent.remote_ah.qpn = ntohl(cm_ptr->msg.saddr.ib.qpn);\r
-                               dapl_os_memcpy(&xevent.remote_ah.ia_addr,\r
-                                       &cm_ptr->msg.daddr.so,\r
-                                       sizeof(union dcm_addr));\r
-                               event = DAT_IB_UD_CONNECTION_EVENT_ESTABLISHED;\r
-                       } else \r
-                               event = DAT_IB_UD_CONNECTION_ERROR_EVENT;\r
-               } else \r
-                       event = DAT_IB_UD_CONNECTION_ERROR_EVENT;\r
-\r
-               dapl_log(DAPL_DBG_TYPE_CM, \r
-                       " CONN_RTU: UD AH %p for lid 0x%x qpn 0x%x\n", \r
-                       cm_ptr->ah, ntohs(cm_ptr->msg.saddr.ib.lid),\r
-                       ntohl(cm_ptr->msg.saddr.ib.qpn));\r
-\r
-               dapls_evd_post_connection_event_ext(\r
-                               (DAPL_EVD *) \r
-                               cm_ptr->ep->param.connect_evd_handle,\r
-                               event,\r
-                               (DAT_EP_HANDLE) cm_ptr->ep,\r
-                               (DAT_COUNT) ntohs(cm_ptr->msg.p_size),\r
-                               (DAT_PVOID *) cm_ptr->msg.p_data,\r
-                               (DAT_PVOID *) &xevent);\r
-\r
-                /* cleanup and release from local list, still on EP list */\r
-               dapli_cm_free(cm_ptr);\r
-                \r
-       } else \r
-#endif\r
-       {\r
-               dapls_cr_callback(cm_ptr, event, NULL, 0, cm_ptr->sp);\r
-       }\r
-       return;\r
-      \r
-bail:\r
-#ifdef DAT_EXTENSIONS\r
-       if (cm_ptr->msg.saddr.ib.qp_type == IBV_QPT_UD) \r
-               goto ud_bail;\r
-#endif\r
-       cm_ptr->state = DCM_REJECTED;\r
-       dapls_cr_callback(cm_ptr, event, NULL, 0, cm_ptr->sp);\r
-       dapli_cm_free(cm_ptr);\r
-}\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\r
-dapls_ib_connect(IN DAT_EP_HANDLE ep_handle,\r
-                IN DAT_IA_ADDRESS_PTR remote_ia_address,\r
-                IN DAT_CONN_QUAL remote_conn_qual,\r
-                IN DAT_COUNT private_data_size, IN void *private_data)\r
-{\r
-       DAPL_EP *ep_ptr = (DAPL_EP *) ep_handle;\r
-       \r
-       dapl_dbg_log(DAPL_DBG_TYPE_EP,\r
-                    " connect(ep_handle %p ....)\n", ep_handle);\r
-\r
-       return (dapli_socket_connect(ep_ptr, remote_ia_address,\r
-                                    remote_conn_qual,\r
-                                    private_data_size, private_data));\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
-DAT_RETURN\r
-dapls_ib_disconnect(IN DAPL_EP * ep_ptr, IN DAT_CLOSE_FLAGS close_flags)\r
-{\r
-       dp_ib_cm_handle_t cm_ptr = dapl_get_cm_from_ep(ep_ptr);\r
-\r
-       if (ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED ||\r
-               ep_ptr->param.ep_attr.service_type != DAT_SERVICE_TYPE_RC) {\r
-               return DAT_SUCCESS;\r
-       } \r
-       \r
-       /* RC. Transition to error state to flush queue */\r
-        dapls_modify_qp_state(ep_ptr->qp_handle, IBV_QPS_ERR, 0, 0, 0);\r
-\r
-       return (dapli_socket_disconnect(cm_ptr));\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. It is also called if dat_ep_connect\r
- * times out using the consumer supplied timeout value.\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
-       if (ib_cm_event == IB_CME_TIMEOUT) {\r
-               dp_ib_cm_handle_t cm_ptr = dapl_get_cm_from_ep(ep_ptr);\r
-\r
-               dapl_log(DAPL_DBG_TYPE_WARN,\r
-                       "dapls_ib_disc_clean: CONN_TIMEOUT ep %p cm %p %s\n",\r
-                       ep_ptr, cm_ptr, dapl_cm_state_str(cm_ptr->state));\r
-               \r
-               /* schedule release of socket and local resources */\r
-               dapli_cm_free(cm_ptr);\r
-       }\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
-       return (dapli_socket_listen(ia_ptr, ServiceID, sp_ptr));\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 cm_ptr = sp_ptr->cm_srvc_handle;\r
-\r
-       /* free cm_srvc_handle, release will cleanup */\r
-       if (cm_ptr != NULL) {\r
-               /* cr_thread will free */\r
-               sp_ptr->cm_srvc_handle = NULL;\r
-               dapli_cm_free(cm_ptr);\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;\r
-       DAPL_EP *ep_ptr;\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_EP,\r
-                    "dapls_ib_accept_connection(cr %p ep %p prd %p,%d)\n",\r
-                    cr_handle, ep_handle, p_data, p_size);\r
-\r
-       cr_ptr = (DAPL_CR *) cr_handle;\r
-       ep_ptr = (DAPL_EP *) ep_handle;\r
-\r
-       /* allocate and attach a QP if necessary */\r
-       if (ep_ptr->qp_state == DAPL_QP_STATE_UNATTACHED) {\r
-               DAT_RETURN status;\r
-               status = dapls_ib_qp_alloc(ep_ptr->header.owner_ia,\r
-                                          ep_ptr, ep_ptr);\r
-               if (status != DAT_SUCCESS)\r
-                       return status;\r
-       }\r
-       return (dapli_socket_accept_usr(ep_ptr, cr_ptr, p_size, p_data));\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_ptr,\r
-                          IN int reason,\r
-                          IN DAT_COUNT psize, IN const DAT_PVOID pdata)\r
-{\r
-       struct iovec iov[2];\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_EP,\r
-                    " reject(cm %p reason %x, pdata %p, psize %d)\n",\r
-                    cm_ptr, reason, pdata, psize);\r
-\r
-        if (psize > DCM_MAX_PDATA_SIZE)\r
-                return DAT_LENGTH_ERROR;\r
-\r
-       /* write reject data to indicate reject */\r
-       cm_ptr->msg.op = htons(DCM_REJ_USER);\r
-       cm_ptr->msg.p_size = htons(psize);\r
-       \r
-       iov[0].iov_base = (void *)&cm_ptr->msg;\r
-       iov[0].iov_len = sizeof(ib_cm_msg_t) - DCM_MAX_PDATA_SIZE;\r
-       if (psize) {\r
-               iov[1].iov_base = pdata;\r
-               iov[1].iov_len = psize;\r
-               writev(cm_ptr->socket, iov, 2);\r
-       } else {\r
-               writev(cm_ptr->socket, iov, 1);\r
-       }\r
-\r
-       /* release and cleanup CM object */\r
-       dapli_cm_free(cm_ptr);\r
-       return DAT_SUCCESS;\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,\r
-                       OUT DAT_SOCK_ADDR6 * remote_ia_address)\r
-{\r
-       DAPL_HEADER *header;\r
-       dp_ib_cm_handle_t conn;\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_EP,\r
-                    "dapls_ib_cm_remote_addr(dat_handle %p, ....)\n",\r
-                    dat_handle);\r
-\r
-       header = (DAPL_HEADER *) dat_handle;\r
-\r
-       if (header->magic == DAPL_MAGIC_EP)\r
-               conn = dapl_get_cm_from_ep((DAPL_EP *) dat_handle);\r
-       else if (header->magic == DAPL_MAGIC_CR)\r
-               conn = ((DAPL_CR *) dat_handle)->ib_cm_handle;\r
-       else\r
-               return DAT_INVALID_HANDLE;\r
-\r
-       dapl_os_memcpy(remote_ia_address,\r
-                      &conn->msg.daddr.so, sizeof(DAT_SOCK_ADDR6));\r
-\r
-       return DAT_SUCCESS;\r
-}\r
-\r
-int dapls_ib_private_data_size(\r
-       IN DAPL_HCA *hca_ptr)\r
-{\r
-       return DCM_MAX_PDATA_SIZE;\r
-}\r
-\r
-/* outbound/inbound CR processing thread to avoid blocking applications */\r
-void cr_thread(void *arg)\r
-{\r
-       struct dapl_hca *hca_ptr = arg;\r
-       dp_ib_cm_handle_t cr, next_cr;\r
-       int opt, ret;\r
-       socklen_t opt_len;\r
-       char rbuf[2];\r
-       struct dapl_fd_set *set;\r
-       enum DAPL_FD_EVENTS event;\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " cr_thread: ENTER hca %p\n", hca_ptr);\r
-       set = dapl_alloc_fd_set();\r
-       if (!set)\r
-               goto out;\r
-\r
-       dapl_os_lock(&hca_ptr->ib_trans.lock);\r
-       hca_ptr->ib_trans.cr_state = IB_THREAD_RUN;\r
-\r
-       while (1) {\r
-               dapl_fd_zero(set);\r
-               dapl_fd_set(hca_ptr->ib_trans.scm[0], set, DAPL_FD_READ);\r
-\r
-               if (!dapl_llist_is_empty(&hca_ptr->ib_trans.list))\r
-                       next_cr = dapl_llist_peek_head(&hca_ptr->ib_trans.list);\r
-               else\r
-                       next_cr = NULL;\r
-\r
-               while (next_cr) {\r
-                       cr = next_cr;\r
-                       next_cr = dapl_llist_next_entry(&hca_ptr->ib_trans.list,\r
-                                                       (DAPL_LLIST_ENTRY *) \r
-                                                       &cr->local_entry);\r
-                       dapls_cm_acquire(cr); /* hold thread ref */\r
-                       dapl_os_lock(&cr->lock);\r
-                       if (cr->state == DCM_FREE || \r
-                           hca_ptr->ib_trans.cr_state != IB_THREAD_RUN) {\r
-                               dapl_log(DAPL_DBG_TYPE_CM, \r
-                                        " CM FREE: %p ep=%p st=%s sck=%d refs=%d\n", \r
-                                        cr, cr->ep, dapl_cm_state_str(cr->state), \r
-                                        cr->socket, cr->ref_count);\r
-\r
-                               if (cr->socket != DAPL_INVALID_SOCKET) {\r
-                                       shutdown(cr->socket, SHUT_RDWR);\r
-                                       closesocket(cr->socket);\r
-                                       cr->socket = DAPL_INVALID_SOCKET;\r
-                               }\r
-                               dapl_os_unlock(&cr->lock);\r
-                               dapls_cm_release(cr); /* release alloc ref */\r
-                               dapli_cm_dequeue(cr); /* release workq ref */\r
-                               dapls_cm_release(cr); /* release thread ref */\r
-                               continue;\r
-                       }\r
-\r
-                       event = (cr->state == DCM_CONN_PENDING) ?\r
-                                       DAPL_FD_WRITE : DAPL_FD_READ;\r
-\r
-                       if (dapl_fd_set(cr->socket, set, event)) {\r
-                               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                                        " cr_thread: fd_set ERR st=%d fd %d"\r
-                                        " -> %s\n", cr->state, cr->socket,\r
-                                        inet_ntoa(((struct sockaddr_in *)\r
-                                               &cr->msg.daddr.so)->sin_addr));\r
-                               dapl_os_unlock(&cr->lock);\r
-                               dapls_cm_release(cr); /* release ref */\r
-                               continue;\r
-                       }\r
-                       dapl_os_unlock(&cr->lock);\r
-                       dapl_os_unlock(&hca_ptr->ib_trans.lock);\r
-                       \r
-                       ret = dapl_poll(cr->socket, event);\r
-\r
-                       dapl_dbg_log(DAPL_DBG_TYPE_THREAD,\r
-                                    " poll ret=0x%x %s sck=%d\n",\r
-                                    ret, dapl_cm_state_str(cr->state), \r
-                                    cr->socket);\r
-\r
-                       /* data on listen, qp exchange, and on disc req */\r
-                       if ((ret == DAPL_FD_READ) || \r
-                           (cr->state != DCM_CONN_PENDING && ret == DAPL_FD_ERROR)) {\r
-                               if (cr->socket != DAPL_INVALID_SOCKET) {\r
-                                       switch (cr->state) {\r
-                                       case DCM_LISTEN:\r
-                                               dapli_socket_accept(cr);\r
-                                               break;\r
-                                       case DCM_ACCEPTING:\r
-                                               dapli_socket_accept_data(cr);\r
-                                               break;\r
-                                       case DCM_ACCEPTED:\r
-                                               dapli_socket_accept_rtu(cr);\r
-                                               break;\r
-                                       case DCM_REP_PENDING:\r
-                                               dapli_socket_connect_rtu(cr);\r
-                                               break;\r
-                                       case DCM_CONNECTED:\r
-                                               dapli_socket_disconnect(cr);\r
-                                               break;\r
-                                       default:\r
-                                               break;\r
-                                       }\r
-                               }\r
-                       /* ASYNC connections, writable, readable, error; check status */\r
-                       } else if (ret == DAPL_FD_WRITE ||\r
-                                  (cr->state == DCM_CONN_PENDING && \r
-                                   ret == DAPL_FD_ERROR)) {\r
-\r
-                               if (ret == DAPL_FD_ERROR)\r
-                                       dapl_log(DAPL_DBG_TYPE_ERR, " CONN_PENDING - FD_ERROR\n");\r
-                               \r
-                               opt = 0;\r
-                               opt_len = sizeof(opt);\r
-                               ret = getsockopt(cr->socket, SOL_SOCKET,\r
-                                                SO_ERROR, (char *)&opt,\r
-                                                &opt_len);\r
-                               if (!ret && !opt)\r
-                                       dapli_socket_connected(cr, opt);\r
-                               else\r
-                                       dapli_socket_connected(cr, opt ? opt : dapl_socket_errno());\r
-                       } \r
-\r
-                       dapls_cm_release(cr); /* release ref */\r
-                       dapl_os_lock(&hca_ptr->ib_trans.lock);\r
-               }\r
-\r
-               /* set to exit and all resources destroyed */\r
-               if ((hca_ptr->ib_trans.cr_state != IB_THREAD_RUN) &&\r
-                   (dapl_llist_is_empty(&hca_ptr->ib_trans.list)))\r
-                       break;\r
-\r
-               dapl_os_unlock(&hca_ptr->ib_trans.lock);\r
-               dapl_select(set);\r
-\r
-               /* if pipe used to wakeup, consume */\r
-               while (dapl_poll(hca_ptr->ib_trans.scm[0], \r
-                                DAPL_FD_READ) == DAPL_FD_READ) {\r
-                       if (recv(hca_ptr->ib_trans.scm[0], rbuf, 2, 0) == -1)\r
-                               dapl_log(DAPL_DBG_TYPE_THREAD,\r
-                                        " cr_thread: read pipe error = %s\n",\r
-                                        strerror(errno));\r
-               }\r
-               dapl_os_lock(&hca_ptr->ib_trans.lock);\r
-               \r
-               /* set to exit and all resources destroyed */\r
-               if ((hca_ptr->ib_trans.cr_state != IB_THREAD_RUN) &&\r
-                   (dapl_llist_is_empty(&hca_ptr->ib_trans.list)))\r
-                       break;\r
-       }\r
-\r
-       dapl_os_unlock(&hca_ptr->ib_trans.lock);\r
-       dapl_os_free(set, sizeof(struct dapl_fd_set));\r
-out:\r
-       hca_ptr->ib_trans.cr_state = IB_THREAD_EXIT;\r
-       dapl_dbg_log(DAPL_DBG_TYPE_THREAD, " cr_thread(hca %p) exit\n", hca_ptr);\r
-}\r
-\r
-\r
-#ifdef DAPL_COUNTERS\r
-/* Debug aid: List all Connections in process and state */\r
-void dapls_print_cm_list(IN DAPL_IA *ia_ptr)\r
-{\r
-       /* Print in process CR's for this IA, if debug type set */\r
-       int i = 0;\r
-       dp_ib_cm_handle_t cr, next_cr;\r
-\r
-       dapl_os_lock(&ia_ptr->hca_ptr->ib_trans.lock);\r
-       if (!dapl_llist_is_empty((DAPL_LLIST_HEAD*)\r
-                                &ia_ptr->hca_ptr->ib_trans.list))\r
-                                next_cr = dapl_llist_peek_head((DAPL_LLIST_HEAD*)\r
-                                &ia_ptr->hca_ptr->ib_trans.list);\r
-       else\r
-               next_cr = NULL;\r
-\r
-        printf("\n DAPL IA CONNECTIONS IN PROCESS:\n");\r
-       while (next_cr) {\r
-               cr = next_cr;\r
-               next_cr = dapl_llist_next_entry((DAPL_LLIST_HEAD*)\r
-                                &ia_ptr->hca_ptr->ib_trans.list,\r
-                               (DAPL_LLIST_ENTRY*)&cr->local_entry);\r
-\r
-               printf( "  CONN[%d]: sp %p ep %p sock %d %s %s %s %s %s %s PORT L-%x R-%x PID L-%x R-%x\n",\r
-                       i, cr->sp, cr->ep, cr->socket,\r
-                       cr->msg.saddr.ib.qp_type == IBV_QPT_RC ? "RC" : "UD",\r
-                       dapl_cm_state_str(cr->state), dapl_cm_op_str(ntohs(cr->msg.op)),\r
-                       ntohs(cr->msg.op) == DCM_REQ ? /* local address */\r
-                               inet_ntoa(((struct sockaddr_in *)&cr->msg.daddr.so)->sin_addr) :\r
-                               inet_ntoa(((struct sockaddr_in *)&cr->addr)->sin_addr),\r
-                       cr->sp ? "<-" : "->",\r
-                               ntohs(cr->msg.op) == DCM_REQ ? /* remote address */\r
-                               inet_ntoa(((struct sockaddr_in *)&cr->addr)->sin_addr) :\r
-                               inet_ntoa(((struct sockaddr_in *)&cr->msg.daddr.so)->sin_addr),\r
-\r
-                       ntohs(cr->msg.op) == DCM_REQ ? /* local port */\r
-                               ntohs(((struct sockaddr_in *)&cr->msg.daddr.so)->sin_port) :\r
-                               ntohs(((struct sockaddr_in *)&cr->addr)->sin_port),\r
-\r
-                       ntohs(cr->msg.op) == DCM_REQ ? /* remote port */\r
-                               ntohs(((struct sockaddr_in *)&cr->addr)->sin_port) :\r
-                               ntohs(((struct sockaddr_in *)&cr->msg.daddr.so)->sin_port),\r
-\r
-                       cr->sp ? ntohs(*(uint16_t*)&cr->msg.resv[2]) : ntohs(*(uint16_t*)&cr->msg.resv[0]),\r
-                       cr->sp ? ntohs(*(uint16_t*)&cr->msg.resv[0]) : ntohs(*(uint16_t*)&cr->msg.resv[2]));\r
-\r
-               i++;\r
-       }\r
-       printf("\n");\r
-       dapl_os_unlock(&ia_ptr->hca_ptr->ib_trans.lock);\r
-}\r
-#endif\r
+/*
+ * 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:            uDAPL
+ *
+ *   Filename:          dapl_ib_cm.c
+ *
+ *   Author:            Arlin Davis
+ *
+ *   Created:           3/10/2005
+ *
+ *   Description: 
+ *
+ *   The uDAPL openib provider - connection management
+ *
+ ****************************************************************************
+ *                Source Control System Information
+ *
+ *    $Id: $
+ *
+ *     Copyright (c) 2005 Intel Corporation.  All rights reserved.
+ *
+ **************************************************************************/
+
+#if defined(_WIN32)
+#define FD_SETSIZE 1024
+#define DAPL_FD_SETSIZE FD_SETSIZE
+#endif
+
+#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_ep_util.h"
+#include "dapl_osd.h"
+
+/* forward declarations */
+static DAT_RETURN
+dapli_socket_connect(DAPL_EP * ep_ptr,
+                    DAT_IA_ADDRESS_PTR r_addr,
+                    DAT_CONN_QUAL r_qual, DAT_COUNT p_size, DAT_PVOID p_data);
+
+#ifdef DAPL_DBG
+/* Check for EP linking to IA and proper connect state */
+void dapli_ep_check(DAPL_EP *ep)
+{
+       DAPL_IA *ia_ptr = ep->header.owner_ia;
+       DAPL_EP *ep_ptr, *next_ep_ptr;
+       int found = 0;
+
+       dapl_os_lock(&ia_ptr->header.lock);
+       ep_ptr = (dapl_llist_is_empty (&ia_ptr->ep_list_head)
+               ? NULL : dapl_llist_peek_head (&ia_ptr->ep_list_head));
+
+       while (ep_ptr != NULL) {
+               next_ep_ptr = 
+                       dapl_llist_next_entry(&ia_ptr->ep_list_head,
+                                             &ep_ptr->header.ia_list_entry);
+               if (ep == ep_ptr) {
+                       found++;
+                       if ((ep->cr_ptr && ep->param.ep_state 
+                               != DAT_EP_STATE_COMPLETION_PENDING) ||
+                           (!ep->cr_ptr && ep->param.ep_state 
+                               != DAT_EP_STATE_ACTIVE_CONNECTION_PENDING))
+                               goto err;
+                       else 
+                               goto match;
+               }
+               ep_ptr = next_ep_ptr;
+       }
+err:
+       dapl_log(DAPL_DBG_TYPE_ERR,
+                " dapli_ep_check ERR: %s %s ep=%p state=%d magic=0x%x\n", 
+                ep->cr_ptr ? "PASSIVE":"ACTIVE", 
+                found ? "WRONG_STATE":"NOT_FOUND" ,
+                ep, ep->param.ep_state, ep->header.magic);
+match:
+       dapl_os_unlock(&ia_ptr->header.lock);
+       return;
+}
+#else
+#define dapli_ep_check(ep)
+#endif
+
+#if defined(_WIN32) || defined(_WIN64)
+enum DAPL_FD_EVENTS {
+       DAPL_FD_READ = 0x1,
+       DAPL_FD_WRITE = 0x2,
+       DAPL_FD_ERROR = 0x4
+};
+
+static int dapl_config_socket(DAPL_SOCKET s)
+{
+       unsigned long nonblocking = 1;
+       int ret, opt = 1;
+
+       ret = ioctlsocket(s, FIONBIO, &nonblocking);
+
+       /* no delay for small packets */
+       if (!ret)
+               ret = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, 
+                                (char *)&opt, sizeof(opt));
+       return ret;
+}
+
+static int dapl_connect_socket(DAPL_SOCKET s, struct sockaddr *addr,
+                              int addrlen)
+{
+       int err;
+
+       err = connect(s, addr, addrlen);
+       if (err == SOCKET_ERROR)
+               err = WSAGetLastError();
+       return (err == WSAEWOULDBLOCK) ? EAGAIN : err;
+}
+
+struct dapl_fd_set {
+       struct fd_set set[3];
+};
+
+static struct dapl_fd_set *dapl_alloc_fd_set(void)
+{
+       return dapl_os_alloc(sizeof(struct dapl_fd_set));
+}
+
+static void dapl_fd_zero(struct dapl_fd_set *set)
+{
+       FD_ZERO(&set->set[0]);
+       FD_ZERO(&set->set[1]);
+       FD_ZERO(&set->set[2]);
+}
+
+static int dapl_fd_set(DAPL_SOCKET s, struct dapl_fd_set *set,
+                      enum DAPL_FD_EVENTS event)
+{
+       FD_SET(s, &set->set[(event == DAPL_FD_READ) ? 0 : 1]);
+       FD_SET(s, &set->set[2]);
+       return 0;
+}
+
+static enum DAPL_FD_EVENTS dapl_poll(DAPL_SOCKET s, enum DAPL_FD_EVENTS event)
+{
+       struct fd_set rw_fds;
+       struct fd_set err_fds;
+       struct timeval tv;
+       int ret;
+
+       FD_ZERO(&rw_fds);
+       FD_ZERO(&err_fds);
+       FD_SET(s, &rw_fds);
+       FD_SET(s, &err_fds);
+
+       tv.tv_sec = 0;
+       tv.tv_usec = 0;
+
+       if (event == DAPL_FD_READ)
+               ret = select(1, &rw_fds, NULL, &err_fds, &tv);
+       else
+               ret = select(1, NULL, &rw_fds, &err_fds, &tv);
+
+       if (ret == 0)
+               return 0;
+       else if (ret == SOCKET_ERROR)
+               return DAPL_FD_ERROR;
+       else if (FD_ISSET(s, &rw_fds))
+               return event;
+       else
+               return DAPL_FD_ERROR;
+}
+
+static int dapl_select(struct dapl_fd_set *set)
+{
+       int ret;
+
+       dapl_dbg_log(DAPL_DBG_TYPE_CM, " dapl_select: sleep\n");
+       ret = select(0, &set->set[0], &set->set[1], &set->set[2], NULL);
+       dapl_dbg_log(DAPL_DBG_TYPE_CM, " dapl_select: wakeup\n");
+
+       if (ret == SOCKET_ERROR)
+               dapl_dbg_log(DAPL_DBG_TYPE_THREAD,
+                            " dapl_select: error 0x%x\n", WSAGetLastError());
+
+       return ret;
+}
+
+static int dapl_socket_errno(void)
+{
+       int err;
+
+       err = WSAGetLastError();
+       switch (err) {
+       case WSAEACCES:
+       case WSAEADDRINUSE:
+               return EADDRINUSE;
+       case WSAECONNRESET:
+               return ECONNRESET;
+       default:
+               return err;
+       }
+}
+#else                          // _WIN32 || _WIN64
+enum DAPL_FD_EVENTS {
+       DAPL_FD_READ = POLLIN,
+       DAPL_FD_WRITE = POLLOUT,
+       DAPL_FD_ERROR = POLLERR
+};
+
+static int dapl_config_socket(DAPL_SOCKET s)
+{
+       int ret, opt = 1;
+
+       /* non-blocking */
+       ret = fcntl(s, F_GETFL);
+       if (ret >= 0)
+               ret = fcntl(s, F_SETFL, ret | O_NONBLOCK);
+
+       /* no delay for small packets */
+       if (!ret)
+               ret = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, 
+                                (char *)&opt, sizeof(opt));
+       return ret;
+}
+
+static int dapl_connect_socket(DAPL_SOCKET s, struct sockaddr *addr,
+                              int addrlen)
+{
+       int ret;
+
+       ret = connect(s, addr, addrlen);
+
+       return (errno == EINPROGRESS) ? EAGAIN : ret;
+}
+
+struct dapl_fd_set {
+       int index;
+       struct pollfd set[DAPL_FD_SETSIZE];
+};
+
+static struct dapl_fd_set *dapl_alloc_fd_set(void)
+{
+       return dapl_os_alloc(sizeof(struct dapl_fd_set));
+}
+
+static void dapl_fd_zero(struct dapl_fd_set *set)
+{
+       set->index = 0;
+}
+
+static int dapl_fd_set(DAPL_SOCKET s, struct dapl_fd_set *set,
+                      enum DAPL_FD_EVENTS event)
+{
+       if (set->index == DAPL_FD_SETSIZE - 1) {
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                        "SCM ERR: cm_thread exceeded FD_SETSIZE %d\n",
+                        set->index + 1);
+               return -1;
+       }
+
+       set->set[set->index].fd = s;
+       set->set[set->index].revents = 0;
+       set->set[set->index++].events = event;
+       return 0;
+}
+
+static enum DAPL_FD_EVENTS dapl_poll(DAPL_SOCKET s, enum DAPL_FD_EVENTS event)
+{
+       struct pollfd fds;
+       int ret;
+
+       fds.fd = s;
+       fds.events = event;
+       fds.revents = 0;
+       ret = poll(&fds, 1, 0);
+       dapl_log(DAPL_DBG_TYPE_THREAD, " dapl_poll: fd=%d ret=%d, evnts=0x%x\n",
+                s, ret, fds.revents);
+       if (ret == 0)
+               return 0;
+       else if (ret < 0 || (fds.revents & (POLLERR | POLLHUP | POLLNVAL))) 
+               return DAPL_FD_ERROR;
+       else 
+               return event;
+}
+
+static int dapl_select(struct dapl_fd_set *set)
+{
+       int ret;
+
+       dapl_dbg_log(DAPL_DBG_TYPE_THREAD, " dapl_select: sleep, fds=%d\n", set->index);
+       ret = poll(set->set, set->index, -1);
+       dapl_dbg_log(DAPL_DBG_TYPE_THREAD, " dapl_select: wakeup, ret=0x%x\n", ret);
+       return ret;
+}
+
+#define dapl_socket_errno() errno
+#endif
+
+static void dapli_cm_thread_signal(dp_ib_cm_handle_t cm_ptr) 
+{
+       if (cm_ptr->hca)
+               send(cm_ptr->hca->ib_trans.scm[1], "w", sizeof "w", 0);
+}
+
+static void dapli_cm_free(dp_ib_cm_handle_t cm_ptr) 
+{
+       dapl_os_lock(&cm_ptr->lock);
+       cm_ptr->state = DCM_FREE;
+       dapl_os_unlock(&cm_ptr->lock);
+       dapli_cm_thread_signal(cm_ptr);
+}
+
+static void dapli_cm_dealloc(dp_ib_cm_handle_t cm_ptr) 
+{
+       dapl_os_assert(!cm_ptr->ref_count);
+       
+       if (cm_ptr->socket != DAPL_INVALID_SOCKET) {
+               shutdown(cm_ptr->socket, SHUT_RDWR);
+               closesocket(cm_ptr->socket);
+       }
+       if (cm_ptr->ah) 
+               ibv_destroy_ah(cm_ptr->ah);
+       
+       dapl_os_lock_destroy(&cm_ptr->lock);
+       dapl_os_wait_object_destroy(&cm_ptr->event);
+       dapl_os_free(cm_ptr, sizeof(*cm_ptr));
+}
+
+void dapls_cm_acquire(dp_ib_cm_handle_t cm_ptr)
+{
+       dapl_os_lock(&cm_ptr->lock);
+       cm_ptr->ref_count++;
+       dapl_os_unlock(&cm_ptr->lock);
+}
+
+void dapls_cm_release(dp_ib_cm_handle_t cm_ptr)
+{
+       dapl_os_lock(&cm_ptr->lock);
+       cm_ptr->ref_count--;
+       if (cm_ptr->ref_count) {
+                dapl_os_unlock(&cm_ptr->lock);
+               return;
+       }
+       dapl_os_unlock(&cm_ptr->lock);
+       dapli_cm_dealloc(cm_ptr);
+}
+
+static dp_ib_cm_handle_t dapli_cm_alloc(DAPL_EP *ep_ptr)
+{
+       dp_ib_cm_handle_t cm_ptr;
+
+       /* Allocate CM, init lock, and initialize */
+       if ((cm_ptr = dapl_os_alloc(sizeof(*cm_ptr))) == NULL)
+               return NULL;
+
+       (void)dapl_os_memzero(cm_ptr, sizeof(*cm_ptr));
+       if (dapl_os_lock_init(&cm_ptr->lock))
+               goto bail;
+
+       if (dapl_os_wait_object_init(&cm_ptr->event)) {
+               dapl_os_lock_destroy(&cm_ptr->lock);
+               goto bail;
+       }
+       dapl_llist_init_entry((DAPL_LLIST_ENTRY *)&cm_ptr->list_entry);
+       dapl_llist_init_entry((DAPL_LLIST_ENTRY *)&cm_ptr->local_entry);
+
+       cm_ptr->msg.ver = htons(DCM_VER);
+       cm_ptr->socket = DAPL_INVALID_SOCKET;
+       dapls_cm_acquire(cm_ptr);
+               
+       /* Link EP and CM */
+       if (ep_ptr != NULL) {
+               dapl_ep_link_cm(ep_ptr, cm_ptr); /* ref++ */
+               cm_ptr->ep = ep_ptr;
+               cm_ptr->hca = ((DAPL_IA *)ep_ptr->param.ia_handle)->hca_ptr;
+       }
+       return cm_ptr;
+bail:
+       dapl_os_free(cm_ptr, sizeof(*cm_ptr));
+       return NULL;
+}
+
+/* queue socket for processing CM work */
+static void dapli_cm_queue(dp_ib_cm_handle_t cm_ptr)
+{
+       /* add to work queue for cr thread processing */
+       dapl_os_lock(&cm_ptr->hca->ib_trans.lock);
+       dapls_cm_acquire(cm_ptr);
+       dapl_llist_add_tail(&cm_ptr->hca->ib_trans.list,
+                           (DAPL_LLIST_ENTRY *)&cm_ptr->local_entry, cm_ptr);
+       dapl_os_unlock(&cm_ptr->hca->ib_trans.lock);
+       dapli_cm_thread_signal(cm_ptr);
+}
+
+/* called with local LIST lock */
+static void dapli_cm_dequeue(dp_ib_cm_handle_t cm_ptr)
+{
+       /* Remove from work queue, cr thread processing */
+       dapl_llist_remove_entry(&cm_ptr->hca->ib_trans.list,
+                               (DAPL_LLIST_ENTRY *)&cm_ptr->local_entry);
+       dapls_cm_release(cm_ptr);
+}
+
+/* BLOCKING: called from dapl_ep_free, EP link will be last ref */
+void dapls_cm_free(dp_ib_cm_handle_t cm_ptr)
+{
+       dapl_log(DAPL_DBG_TYPE_CM,
+                " cm_free: cm %p %s ep %p refs=%d\n", 
+                cm_ptr, dapl_cm_state_str(cm_ptr->state),
+                cm_ptr->ep, cm_ptr->ref_count);
+       
+       /* free from internal workq, wait until EP is last ref */
+       dapl_os_lock(&cm_ptr->lock);
+       cm_ptr->state = DCM_FREE;
+       while (cm_ptr->ref_count != 1) {
+               dapli_cm_thread_signal(cm_ptr);
+               dapl_os_unlock(&cm_ptr->lock);
+               dapl_os_sleep_usec(10000);
+               dapl_os_lock(&cm_ptr->lock);
+       }
+       dapl_os_unlock(&cm_ptr->lock);
+
+       /* unlink, dequeue from EP. Final ref so release will destroy */
+       dapl_ep_unlink_cm(cm_ptr->ep, cm_ptr);
+}
+
+/*
+ * ACTIVE/PASSIVE: called from CR thread or consumer via ep_disconnect
+ *                 or from ep_free. 
+ */
+DAT_RETURN dapli_socket_disconnect(dp_ib_cm_handle_t cm_ptr)
+{
+       DAT_UINT32 disc_data = htonl(0xdead);
+
+       dapl_os_lock(&cm_ptr->lock);
+       if (cm_ptr->state != DCM_CONNECTED || 
+           cm_ptr->state == DCM_DISCONNECTED) {
+               dapl_os_unlock(&cm_ptr->lock);
+               return DAT_SUCCESS;
+       }
+       cm_ptr->state = DCM_DISCONNECTED;
+       dapl_os_unlock(&cm_ptr->lock);
+       
+       /* send disc date, close socket, schedule destroy */
+       send(cm_ptr->socket, (char *)&disc_data, sizeof(disc_data), 0);
+
+       /* disconnect events for RC's only */
+       if (cm_ptr->ep->param.ep_attr.service_type == DAT_SERVICE_TYPE_RC) {
+               dapl_os_lock(&cm_ptr->ep->header.lock);
+               dapls_modify_qp_state(cm_ptr->ep->qp_handle, IBV_QPS_ERR, 0,0,0);
+               dapl_os_unlock(&cm_ptr->ep->header.lock);
+               if (cm_ptr->ep->cr_ptr) {
+                       dapls_cr_callback(cm_ptr,
+                                         IB_CME_DISCONNECTED,
+                                         NULL, 0, cm_ptr->sp);
+               } else {
+                       dapl_evd_connection_callback(cm_ptr,
+                                                    IB_CME_DISCONNECTED,
+                                                    NULL, 0, cm_ptr->ep);
+               }
+       }
+       
+       /* release from workq */
+       dapli_cm_free(cm_ptr);
+
+       /* scheduled destroy via disconnect clean in callback */
+       return DAT_SUCCESS;
+}
+
+/*
+ * ACTIVE: socket connected, send QP information to peer 
+ */
+static void dapli_socket_connected(dp_ib_cm_handle_t cm_ptr, int err)
+{
+       int len, exp;
+       struct iovec iov[2];
+       struct dapl_ep *ep_ptr = cm_ptr->ep;
+
+       if (err) {
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                        " CONN_PENDING: %s ERR %s -> %s %d - %s\n",
+                        err == -1 ? "POLL" : "SOCKOPT",
+                        err == -1 ? strerror(dapl_socket_errno()) : strerror(err), 
+                        inet_ntoa(((struct sockaddr_in *)
+                               &cm_ptr->addr)->sin_addr), 
+                        ntohs(((struct sockaddr_in *)
+                               &cm_ptr->addr)->sin_port),
+                        err == ETIMEDOUT ? "RETRYING...":"ABORTING");
+
+               /* retry a timeout */
+               if (err == ETIMEDOUT) {
+                       closesocket(cm_ptr->socket);
+                       cm_ptr->socket = DAPL_INVALID_SOCKET;
+                       dapli_socket_connect(cm_ptr->ep, (DAT_IA_ADDRESS_PTR)&cm_ptr->addr, 
+                                            ntohs(((struct sockaddr_in *)&cm_ptr->addr)->sin_port) - 1000,
+                                            ntohs(cm_ptr->msg.p_size), &cm_ptr->msg.p_data);
+                       dapl_ep_unlink_cm(cm_ptr->ep, cm_ptr);
+                       dapli_cm_free(cm_ptr);
+                       return;
+               }
+
+               goto bail;
+       }
+
+       dapl_os_lock(&cm_ptr->lock);
+       cm_ptr->state = DCM_REP_PENDING;
+       dapl_os_unlock(&cm_ptr->lock);
+
+       /* send qp info and pdata to remote peer */
+       exp = sizeof(ib_cm_msg_t) - DCM_MAX_PDATA_SIZE;
+       iov[0].iov_base = (void *)&cm_ptr->msg;
+       iov[0].iov_len = exp;
+       if (cm_ptr->msg.p_size) {
+               iov[1].iov_base = cm_ptr->msg.p_data;
+               iov[1].iov_len = ntohs(cm_ptr->msg.p_size);
+               len = writev(cm_ptr->socket, iov, 2);
+       } else {
+               len = writev(cm_ptr->socket, iov, 1);
+       }
+
+       if (len != (exp + ntohs(cm_ptr->msg.p_size))) {
+               int err = dapl_socket_errno();
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                        " CONN_PENDING len ERR 0x%x %s, wcnt=%d(%d) -> %s\n",
+                        err, strerror(err), len, 
+                        exp + ntohs(cm_ptr->msg.p_size), 
+                        inet_ntoa(((struct sockaddr_in *)
+                                  ep_ptr->param.
+                                  remote_ia_address_ptr)->sin_addr));
+               goto bail;
+       }
+
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,
+                    " CONN_PENDING: sending SRC lid=0x%x,"
+                    " qpn=0x%x, psize=%d\n",
+                    ntohs(cm_ptr->msg.saddr.ib.lid),
+                    ntohl(cm_ptr->msg.saddr.ib.qpn), 
+                    ntohs(cm_ptr->msg.p_size));
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,
+                    " CONN_PENDING: SRC GID subnet %016llx id %016llx\n",
+                    (unsigned long long)
+                    htonll(*(uint64_t*)&cm_ptr->msg.saddr.ib.gid[0]),
+                    (unsigned long long)
+                    htonll(*(uint64_t*)&cm_ptr->msg.saddr.ib.gid[8]));
+       return;
+
+bail:
+       /* mark CM object for cleanup */
+       dapli_cm_free(cm_ptr);
+       dapl_evd_connection_callback(NULL, IB_CME_LOCAL_FAILURE, NULL, 0, ep_ptr);
+}
+
+/*
+ * ACTIVE: Create socket, connect, defer exchange QP information to CR thread
+ * to avoid blocking. 
+ */
+static DAT_RETURN
+dapli_socket_connect(DAPL_EP * ep_ptr,
+                    DAT_IA_ADDRESS_PTR r_addr,
+                    DAT_CONN_QUAL r_qual, DAT_COUNT p_size, DAT_PVOID p_data)
+{
+       dp_ib_cm_handle_t cm_ptr;
+       int ret;
+       socklen_t sl;
+       DAPL_IA *ia_ptr = ep_ptr->header.owner_ia;
+       DAT_RETURN dat_ret = DAT_INSUFFICIENT_RESOURCES;
+
+       dapl_dbg_log(DAPL_DBG_TYPE_EP, " connect: r_qual %d p_size=%d\n",
+                    r_qual, p_size);
+
+       cm_ptr = dapli_cm_alloc(ep_ptr);
+       if (cm_ptr == NULL)
+               return dat_ret;
+
+       /* create, connect, sockopt, and exchange QP information */
+       if ((cm_ptr->socket =
+            socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == DAPL_INVALID_SOCKET) {
+               int err = dapl_socket_errno();
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                        " connect: socket create ERR 0x%x %s\n", 
+                        err, strerror(err));
+               goto bail;
+       }
+
+       ret = dapl_config_socket(cm_ptr->socket);
+       if (ret < 0) {
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                        " connect: config socket %d RET %d ERR 0x%x %s\n",
+                        cm_ptr->socket, ret, 
+                        dapl_socket_errno(), strerror(dapl_socket_errno()));
+               dat_ret = DAT_INTERNAL_ERROR;
+               goto bail;
+       }
+
+       /* save remote address */
+       dapl_os_memcpy(&cm_ptr->addr, r_addr, sizeof(*r_addr));
+
+#ifdef DAPL_DBG
+       /* DBG: Active PID [0], PASSIVE PID [2]*/
+       *(uint16_t*)&cm_ptr->msg.resv[0] = htons((uint16_t)dapl_os_getpid()); 
+       *(uint16_t*)&cm_ptr->msg.resv[2] = ((struct sockaddr_in *)&cm_ptr->addr)->sin_port;
+#endif
+       ((struct sockaddr_in *)&cm_ptr->addr)->sin_port = htons(r_qual + 1000);
+       ret = dapl_connect_socket(cm_ptr->socket, (struct sockaddr *)&cm_ptr->addr,
+                                 sizeof(cm_ptr->addr));
+       if (ret && ret != EAGAIN) {
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                        " connect: dapl_connect_socket RET %d ERR 0x%x %s\n",
+                        ret, dapl_socket_errno(), 
+                        strerror(dapl_socket_errno()));
+               dat_ret = DAT_INVALID_ADDRESS;
+               goto bail;
+       }
+
+       /* REQ: QP info in msg.saddr, IA address in msg.daddr, and pdata */
+       cm_ptr->hca = ia_ptr->hca_ptr;
+       cm_ptr->msg.op = ntohs(DCM_REQ);
+       cm_ptr->msg.saddr.ib.qpn = htonl(ep_ptr->qp_handle->qp_num);
+       cm_ptr->msg.saddr.ib.qp_type = ep_ptr->qp_handle->qp_type;
+       cm_ptr->msg.saddr.ib.lid = ia_ptr->hca_ptr->ib_trans.lid;
+       dapl_os_memcpy(&cm_ptr->msg.saddr.ib.gid[0], 
+                      &ia_ptr->hca_ptr->ib_trans.gid, 16);
+       
+       /* get local address information from socket */
+       sl = sizeof(cm_ptr->msg.daddr.so);
+       if (getsockname(cm_ptr->socket, (struct sockaddr *)&cm_ptr->msg.daddr.so, &sl)) {
+               int err = dapl_socket_errno();
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                       " connect getsockname ERROR: 0x%x %s -> %s r_qual %d\n",
+                       err, strerror(err), 
+                       inet_ntoa(((struct sockaddr_in *)r_addr)->sin_addr),
+                       (unsigned int)r_qual);;
+       }
+
+       if (p_size) {
+               cm_ptr->msg.p_size = htons(p_size);
+               dapl_os_memcpy(cm_ptr->msg.p_data, p_data, p_size);
+       }
+
+       /* connected or pending, either way results via async event */
+       if (ret == 0)
+               dapli_socket_connected(cm_ptr, 0);
+       else
+               cm_ptr->state = DCM_CONN_PENDING;
+
+       dapl_dbg_log(DAPL_DBG_TYPE_EP, " connect: p_data=%p %p\n",
+                    cm_ptr->msg.p_data, cm_ptr->msg.p_data);
+
+       dapl_dbg_log(DAPL_DBG_TYPE_EP,
+                    " connect: %s r_qual %d pending, p_sz=%d, %d %d ...\n",
+                    inet_ntoa(((struct sockaddr_in *)&cm_ptr->addr)->sin_addr), 
+                    (unsigned int)r_qual, ntohs(cm_ptr->msg.p_size),
+                    cm_ptr->msg.p_data[0], cm_ptr->msg.p_data[1]);
+
+       /* queue up on work thread */
+       dapli_cm_queue(cm_ptr);
+       return DAT_SUCCESS;
+bail:
+       dapl_log(DAPL_DBG_TYPE_ERR,
+                " connect ERROR: -> %s r_qual %d\n",
+                inet_ntoa(((struct sockaddr_in *)r_addr)->sin_addr),
+                (unsigned int)r_qual);
+
+       /* Never queued, destroy */
+       dapls_cm_release(cm_ptr);
+       return dat_ret;
+}
+
+/*
+ * ACTIVE: exchange QP information, called from CR thread
+ */
+static void dapli_socket_connect_rtu(dp_ib_cm_handle_t cm_ptr)
+{
+       DAPL_EP *ep_ptr = cm_ptr->ep;
+       int len, exp = sizeof(ib_cm_msg_t) - DCM_MAX_PDATA_SIZE;
+       ib_cm_events_t event = IB_CME_LOCAL_FAILURE;
+       socklen_t sl;
+
+       /* read DST information into cm_ptr, overwrite SRC info */
+       dapl_dbg_log(DAPL_DBG_TYPE_EP, " connect_rtu: recv peer QP data\n");
+
+       len = recv(cm_ptr->socket, (char *)&cm_ptr->msg, exp, 0);
+       if (len != exp || ntohs(cm_ptr->msg.ver) != DCM_VER) {
+               int err = dapl_socket_errno();
+               dapl_log(DAPL_DBG_TYPE_WARN,
+                        " CONN_RTU read: sk %d ERR 0x%x, rcnt=%d, v=%d -> %s PORT L-%x R-%x PID L-%x R-%x\n",
+                        cm_ptr->socket, err, len, ntohs(cm_ptr->msg.ver),
+                        inet_ntoa(((struct sockaddr_in *)&cm_ptr->addr)->sin_addr),
+                        ntohs(((struct sockaddr_in *)&cm_ptr->msg.daddr.so)->sin_port),
+                        ntohs(((struct sockaddr_in *)&cm_ptr->addr)->sin_port),
+                        ntohs(*(uint16_t*)&cm_ptr->msg.resv[0]),
+                        ntohs(*(uint16_t*)&cm_ptr->msg.resv[2]));
+
+               /* Retry; corner case where server tcp stack resets under load */
+               if (err == ECONNRESET) {
+                       closesocket(cm_ptr->socket);
+                       cm_ptr->socket = DAPL_INVALID_SOCKET;
+                       dapli_socket_connect(cm_ptr->ep, (DAT_IA_ADDRESS_PTR)&cm_ptr->addr, 
+                                            ntohs(((struct sockaddr_in *)&cm_ptr->addr)->sin_port) - 1000,
+                                            ntohs(cm_ptr->msg.p_size), &cm_ptr->msg.p_data);
+                       dapl_ep_unlink_cm(cm_ptr->ep, cm_ptr);
+                       dapli_cm_free(cm_ptr);
+                       return;
+               }
+               goto bail;
+       }
+
+       /* keep the QP, address info in network order */
+       
+       /* save remote address information, in msg.daddr */
+       dapl_os_memcpy(&ep_ptr->remote_ia_address,
+                      &cm_ptr->msg.daddr.so,
+                      sizeof(union dcm_addr));
+
+       /* save local address information from socket */
+       sl = sizeof(cm_ptr->addr);
+       getsockname(cm_ptr->socket,(struct sockaddr *)&cm_ptr->addr, &sl);
+
+       dapl_dbg_log(DAPL_DBG_TYPE_EP,
+                    " CONN_RTU: DST %s %d lid=0x%x,"
+                    " qpn=0x%x, qp_type=%d, psize=%d\n",
+                    inet_ntoa(((struct sockaddr_in *)
+                               &cm_ptr->msg.daddr.so)->sin_addr),
+                    ntohs(((struct sockaddr_in *)
+                               &cm_ptr->msg.daddr.so)->sin_port),
+                    ntohs(cm_ptr->msg.saddr.ib.lid),
+                    ntohl(cm_ptr->msg.saddr.ib.qpn), 
+                    cm_ptr->msg.saddr.ib.qp_type, 
+                    ntohs(cm_ptr->msg.p_size));
+
+       /* validate private data size before reading */
+       if (ntohs(cm_ptr->msg.p_size) > DCM_MAX_PDATA_SIZE) {
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                        " CONN_RTU read: psize (%d) wrong -> %s\n",
+                        ntohs(cm_ptr->msg.p_size), 
+                        inet_ntoa(((struct sockaddr_in *)
+                                  ep_ptr->param.
+                                  remote_ia_address_ptr)->sin_addr));
+               goto bail;
+       }
+
+       /* read private data into cm_handle if any present */
+       dapl_dbg_log(DAPL_DBG_TYPE_EP," CONN_RTU: read private data\n");
+       exp = ntohs(cm_ptr->msg.p_size);
+       if (exp) {
+               len = recv(cm_ptr->socket, cm_ptr->msg.p_data, exp, 0);
+               if (len != exp) {
+                       int err = dapl_socket_errno();
+                       dapl_log(DAPL_DBG_TYPE_ERR,
+                                " CONN_RTU read pdata: ERR 0x%x %s, rcnt=%d -> %s\n",
+                                err, strerror(err), len,
+                                inet_ntoa(((struct sockaddr_in *)
+                                           ep_ptr->param.
+                                           remote_ia_address_ptr)->sin_addr));
+                       goto bail;
+               }
+       }
+
+       /* check for consumer or protocol stack reject */
+       if (ntohs(cm_ptr->msg.op) == DCM_REP)
+               event = IB_CME_CONNECTED;
+       else if (ntohs(cm_ptr->msg.op) == DCM_REJ_USER) 
+               event = IB_CME_DESTINATION_REJECT_PRIVATE_DATA;
+       else  
+               event = IB_CME_DESTINATION_REJECT;
+       
+       if (event != IB_CME_CONNECTED) {
+               dapl_log(DAPL_DBG_TYPE_CM,
+                        " CONN_RTU: reject from %s %x\n",
+                        inet_ntoa(((struct sockaddr_in *)
+                                   &cm_ptr->msg.daddr.so)->sin_addr),
+                        ntohs(((struct sockaddr_in *)
+                                &cm_ptr->msg.daddr.so)->sin_port));
+               goto bail;
+       }
+
+       /* modify QP to RTR and then to RTS with remote info */
+       dapl_os_lock(&ep_ptr->header.lock);
+       if (dapls_modify_qp_state(ep_ptr->qp_handle,
+                                 IBV_QPS_RTR, 
+                                 cm_ptr->msg.saddr.ib.qpn,
+                                 cm_ptr->msg.saddr.ib.lid,
+                                 (ib_gid_handle_t)cm_ptr->msg.saddr.ib.gid) != DAT_SUCCESS) {
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                        " CONN_RTU: QPS_RTR ERR %s (%d,%d,%x,%x,%x) -> %s %x\n",
+                        strerror(errno), ep_ptr->qp_handle->qp_type,
+                        ep_ptr->qp_state, ep_ptr->qp_handle->qp_num,
+                        ntohl(cm_ptr->msg.saddr.ib.qpn), 
+                        ntohs(cm_ptr->msg.saddr.ib.lid),
+                        inet_ntoa(((struct sockaddr_in *)
+                                   &cm_ptr->msg.daddr.so)->sin_addr),
+                        ntohs(((struct sockaddr_in *)
+                                &cm_ptr->msg.daddr.so)->sin_port));
+               dapl_os_unlock(&ep_ptr->header.lock);
+               goto bail;
+       }
+       if (dapls_modify_qp_state(ep_ptr->qp_handle,
+                                 IBV_QPS_RTS, 
+                                 cm_ptr->msg.saddr.ib.qpn,
+                                 cm_ptr->msg.saddr.ib.lid,
+                                 NULL) != DAT_SUCCESS) {
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                        " CONN_RTU: QPS_RTS ERR %s (%d,%d,%x,%x,%x) -> %s %x\n",
+                        strerror(errno), ep_ptr->qp_handle->qp_type,
+                        ep_ptr->qp_state, ep_ptr->qp_handle->qp_num,
+                        ntohl(cm_ptr->msg.saddr.ib.qpn), 
+                        ntohs(cm_ptr->msg.saddr.ib.lid),
+                        inet_ntoa(((struct sockaddr_in *)
+                                   &cm_ptr->msg.daddr.so)->sin_addr),
+                        ntohs(((struct sockaddr_in *)
+                                &cm_ptr->msg.daddr.so)->sin_port));
+               dapl_os_unlock(&ep_ptr->header.lock);
+               goto bail;
+       }
+       dapl_os_unlock(&ep_ptr->header.lock);
+       dapl_dbg_log(DAPL_DBG_TYPE_EP, " connect_rtu: send RTU\n");
+
+       /* complete handshake after final QP state change, Just ver+op */
+       dapl_os_lock(&cm_ptr->lock);
+       cm_ptr->state = DCM_CONNECTED;
+       dapl_os_unlock(&cm_ptr->lock);
+
+       cm_ptr->msg.op = ntohs(DCM_RTU);
+       if (send(cm_ptr->socket, (char *)&cm_ptr->msg, 4, 0) == -1) {
+               int err = dapl_socket_errno();
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                        " CONN_RTU: write ERR = 0x%x %s\n", 
+                        err, strerror(err));
+               goto bail;
+       }
+       /* post the event with private data */
+       event = IB_CME_CONNECTED;
+       dapl_dbg_log(DAPL_DBG_TYPE_EP, " ACTIVE: connected!\n");
+
+#ifdef DAT_EXTENSIONS
+ud_bail:
+       if (cm_ptr->msg.saddr.ib.qp_type == IBV_QPT_UD) {
+               DAT_IB_EXTENSION_EVENT_DATA xevent;
+               ib_pd_handle_t pd_handle = 
+                       ((DAPL_PZ *)ep_ptr->param.pz_handle)->pd_handle;
+
+               if (event == IB_CME_CONNECTED) {
+                       cm_ptr->ah = dapls_create_ah(cm_ptr->hca, pd_handle,
+                                                    ep_ptr->qp_handle,
+                                                    cm_ptr->msg.saddr.ib.lid, 
+                                                    NULL);
+                       if (cm_ptr->ah) {
+                               /* post UD extended EVENT */
+                               xevent.status = 0;
+                               xevent.type = DAT_IB_UD_REMOTE_AH;
+                               xevent.remote_ah.ah = cm_ptr->ah;
+                               xevent.remote_ah.qpn = ntohl(cm_ptr->msg.saddr.ib.qpn);
+                               dapl_os_memcpy(&xevent.remote_ah.ia_addr,
+                                               &ep_ptr->remote_ia_address,
+                                               sizeof(union dcm_addr));
+                               event = DAT_IB_UD_CONNECTION_EVENT_ESTABLISHED;
+
+                               dapl_log(DAPL_DBG_TYPE_CM, 
+                                       " CONN_RTU: UD AH %p for lid 0x%x"
+                                       " qpn 0x%x\n", 
+                                       cm_ptr->ah, 
+                                       ntohs(cm_ptr->msg.saddr.ib.lid),
+                                       ntohl(cm_ptr->msg.saddr.ib.qpn));
+       
+                       } else 
+                               event = DAT_IB_UD_CONNECTION_ERROR_EVENT;
+                       
+               } else if (event == IB_CME_LOCAL_FAILURE) {
+                       event = DAT_IB_UD_CONNECTION_ERROR_EVENT;
+               } else  
+                       event = DAT_IB_UD_CONNECTION_REJECT_EVENT;
+
+               dapls_evd_post_connection_event_ext(
+                               (DAPL_EVD *) ep_ptr->param.connect_evd_handle,
+                               event,
+                               (DAT_EP_HANDLE) ep_ptr,
+                               (DAT_COUNT) exp,
+                               (DAT_PVOID *) cm_ptr->msg.p_data,
+                               (DAT_PVOID *) &xevent);
+
+               /* cleanup and release from local list */
+               dapli_cm_free(cm_ptr);
+       
+       } else
+#endif
+       {
+               dapli_ep_check(cm_ptr->ep);
+               dapl_evd_connection_callback(cm_ptr, event, cm_ptr->msg.p_data,
+                                            DCM_MAX_PDATA_SIZE, ep_ptr);
+       }
+       return;
+
+bail:
+
+#ifdef DAT_EXTENSIONS
+       if (cm_ptr->msg.saddr.ib.qp_type == IBV_QPT_UD) 
+               goto ud_bail;
+#endif
+       /* close socket, and post error event */
+       dapl_os_lock(&cm_ptr->lock);
+       cm_ptr->state = DCM_REJECTED;
+       dapl_os_unlock(&cm_ptr->lock);
+
+       dapl_evd_connection_callback(NULL, event, cm_ptr->msg.p_data,
+                                    DCM_MAX_PDATA_SIZE, ep_ptr);
+       dapli_cm_free(cm_ptr);
+}
+
+/*
+ * PASSIVE: Create socket, listen, accept, exchange QP information 
+ */
+DAT_RETURN
+dapli_socket_listen(DAPL_IA * ia_ptr, DAT_CONN_QUAL serviceID, DAPL_SP * sp_ptr)
+{
+       struct sockaddr_in addr;
+       ib_cm_srvc_handle_t cm_ptr = NULL;
+       DAT_RETURN dat_status = DAT_SUCCESS;
+       int opt = 1;
+
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,
+                    " setup listen(ia_ptr %p ServiceID %d sp_ptr %p)\n",
+                    ia_ptr, serviceID, sp_ptr);
+
+       cm_ptr = dapli_cm_alloc(NULL);
+       if (cm_ptr == NULL)
+               return DAT_INSUFFICIENT_RESOURCES;
+
+       cm_ptr->sp = sp_ptr;
+       cm_ptr->hca = ia_ptr->hca_ptr;
+
+       /* bind, listen, set sockopt, accept, exchange data */
+       if ((cm_ptr->socket =
+            socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == DAPL_INVALID_SOCKET) {
+               int err = dapl_socket_errno();
+               dapl_log(DAPL_DBG_TYPE_ERR, 
+                        " listen: socket create: ERR 0x%x %s\n",
+                        err, strerror(err));
+               dat_status = DAT_INSUFFICIENT_RESOURCES;
+               goto bail;
+       }
+
+       setsockopt(cm_ptr->socket, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt));
+       addr.sin_port = htons(serviceID + 1000);
+       addr.sin_family = AF_INET;
+       addr.sin_addr = ((struct sockaddr_in *) &ia_ptr->hca_ptr->hca_address)->sin_addr;
+
+       if ((bind(cm_ptr->socket, (struct sockaddr *)&addr, sizeof(addr)) < 0)
+           || (listen(cm_ptr->socket, 128) < 0)) {
+               int err = dapl_socket_errno();
+               dapl_log(DAPL_DBG_TYPE_CM,
+                        " listen: ERROR 0x%x %s on port %d\n",
+                        err, strerror(err), serviceID + 1000);
+               if (err == EADDRINUSE)
+                       dat_status = DAT_CONN_QUAL_IN_USE;
+               else
+                       dat_status = DAT_CONN_QUAL_UNAVAILABLE;
+               goto bail;
+       }
+
+       /* set cm_handle for this service point, save listen socket */
+       sp_ptr->cm_srvc_handle = cm_ptr;
+       dapl_os_memcpy(&cm_ptr->addr, &addr, sizeof(addr)); 
+
+       /* queue up listen socket to process inbound CR's */
+       cm_ptr->state = DCM_LISTEN;
+       dapli_cm_queue(cm_ptr);
+
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,
+                    " setup listen: port %d cr %p s_fd %d\n",
+                    serviceID + 1000, cm_ptr, cm_ptr->socket);
+
+       return dat_status;
+bail:
+       /* Never queued, destroy here */
+       dapls_cm_release(cm_ptr);
+       return dat_status;
+}
+
+/*
+ * PASSIVE: accept socket 
+ */
+static void dapli_socket_accept(ib_cm_srvc_handle_t cm_ptr)
+{
+       dp_ib_cm_handle_t acm_ptr;
+       int ret, len, opt = 1;
+       socklen_t sl;
+
+       /* 
+        * Accept all CR's on this port to avoid half-connection (SYN_RCV)
+        * stalls with many to one connection storms
+        */
+       do {
+               /* Allocate accept CM and initialize */
+               if ((acm_ptr = dapli_cm_alloc(NULL)) == NULL)
+                       return;
+
+               acm_ptr->sp = cm_ptr->sp;
+               acm_ptr->hca = cm_ptr->hca;
+
+               len = sizeof(union dcm_addr);
+               acm_ptr->socket = accept(cm_ptr->socket,
+                                       (struct sockaddr *)
+                                       &acm_ptr->msg.daddr.so,
+                                       (socklen_t *) &len);
+               if (acm_ptr->socket == DAPL_INVALID_SOCKET) {
+                       int err = dapl_socket_errno();
+                       dapl_log(DAPL_DBG_TYPE_ERR,
+                               " ACCEPT: ERR 0x%x %s on FD %d l_cr %p\n",
+                               err, strerror(err), cm_ptr->socket, cm_ptr);
+                       dapls_cm_release(acm_ptr);
+                       return;
+               }
+               dapl_dbg_log(DAPL_DBG_TYPE_CM, " accepting from %s %x\n",
+                            inet_ntoa(((struct sockaddr_in *)
+                                       &acm_ptr->msg.daddr.so)->sin_addr),
+                            ntohs(((struct sockaddr_in *)
+                                       &acm_ptr->msg.daddr.so)->sin_port));
+
+               /* no delay for small packets */
+               ret = setsockopt(acm_ptr->socket, IPPROTO_TCP, TCP_NODELAY,
+                          (char *)&opt, sizeof(opt));
+               if (ret) {
+                       int err = dapl_socket_errno();
+                       dapl_log(DAPL_DBG_TYPE_ERR,
+                                " ACCEPT: NODELAY setsockopt:"
+                                " RET %d ERR 0x%x %s\n",
+                                ret, err, strerror(err));
+               }
+
+               /* get local address information from socket */
+               sl = sizeof(acm_ptr->addr);
+               getsockname(acm_ptr->socket, (struct sockaddr *)&acm_ptr->addr, &sl);
+               acm_ptr->state = DCM_ACCEPTING;
+               dapli_cm_queue(acm_ptr);
+       
+       } while (dapl_poll(cm_ptr->socket, DAPL_FD_READ) == DAPL_FD_READ);
+}
+
+/*
+ * PASSIVE: receive peer QP information, private data, post cr_event 
+ */
+static void dapli_socket_accept_data(ib_cm_srvc_handle_t acm_ptr)
+{
+       int len, exp = sizeof(ib_cm_msg_t) - DCM_MAX_PDATA_SIZE;
+       void *p_data = NULL;
+
+       dapl_dbg_log(DAPL_DBG_TYPE_EP, " socket accepted, read QP data\n");
+
+       /* read in DST QP info, IA address. check for private data */
+       len = recv(acm_ptr->socket, (char *)&acm_ptr->msg, exp, 0);
+       if (len != exp || ntohs(acm_ptr->msg.ver) != DCM_VER) {
+               int err = dapl_socket_errno();
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                        " ACCEPT read: ERR 0x%x %s, rcnt=%d, ver=%d\n",
+                        err, strerror(err), len, ntohs(acm_ptr->msg.ver));
+               goto bail;
+       }
+
+       /* keep the QP, address info in network order */
+
+       /* validate private data size before reading */
+       exp = ntohs(acm_ptr->msg.p_size);
+       if (exp > DCM_MAX_PDATA_SIZE) {
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                            " accept read: psize (%d) wrong\n",
+                            acm_ptr->msg.p_size);
+               goto bail;
+       }
+
+       /* read private data into cm_handle if any present */
+       if (exp) {
+               len = recv(acm_ptr->socket, acm_ptr->msg.p_data, exp, 0);
+               if (len != exp) {
+                       int err = dapl_socket_errno();
+                       dapl_log(DAPL_DBG_TYPE_ERR,
+                                " accept read pdata: ERR 0x%x %s, rcnt=%d\n",
+                                err, strerror(err), len);
+                       goto bail;
+               }
+               p_data = acm_ptr->msg.p_data;
+       }
+       dapl_os_lock(&acm_ptr->lock);
+       acm_ptr->state = DCM_ACCEPTING_DATA;
+       dapl_os_unlock(&acm_ptr->lock);
+
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,
+                    " ACCEPT: DST %s %x lid=0x%x, qpn=0x%x, psz=%d\n",
+                    inet_ntoa(((struct sockaddr_in *)
+                               &acm_ptr->msg.daddr.so)->sin_addr), 
+                    ntohs(((struct sockaddr_in *)
+                            &acm_ptr->msg.daddr.so)->sin_port),
+                    ntohs(acm_ptr->msg.saddr.ib.lid), 
+                    ntohl(acm_ptr->msg.saddr.ib.qpn), exp);
+
+#ifdef DAT_EXTENSIONS
+       if (acm_ptr->msg.saddr.ib.qp_type == IBV_QPT_UD) {
+               DAT_IB_EXTENSION_EVENT_DATA xevent;
+
+               /* post EVENT, modify_qp created ah */
+               xevent.status = 0;
+               xevent.type = DAT_IB_UD_CONNECT_REQUEST;
+
+               dapls_evd_post_cr_event_ext(acm_ptr->sp,
+                                           DAT_IB_UD_CONNECTION_REQUEST_EVENT,
+                                           acm_ptr,
+                                           (DAT_COUNT) exp,
+                                           (DAT_PVOID *) acm_ptr->msg.p_data,
+                                           (DAT_PVOID *) &xevent);
+       } else
+#endif
+               /* trigger CR event and return SUCCESS */
+               dapls_cr_callback(acm_ptr,
+                                 IB_CME_CONNECTION_REQUEST_PENDING,
+                                 p_data, exp, acm_ptr->sp);
+       return;
+bail:
+       /* mark for destroy, active will see socket close as rej */
+       dapli_cm_free(acm_ptr);
+       return;
+}
+
+/*
+ * PASSIVE: consumer accept, send local QP information, private data, 
+ * queue on work thread to receive RTU information to avoid blocking
+ * user thread. 
+ */
+static DAT_RETURN
+dapli_socket_accept_usr(DAPL_EP * ep_ptr,
+                       DAPL_CR * cr_ptr, DAT_COUNT p_size, DAT_PVOID p_data)
+{
+       DAPL_IA *ia_ptr = ep_ptr->header.owner_ia;
+       dp_ib_cm_handle_t cm_ptr = cr_ptr->ib_cm_handle;
+       ib_cm_msg_t local;
+       struct iovec iov[2];
+       int len, exp = sizeof(ib_cm_msg_t) - DCM_MAX_PDATA_SIZE;
+       DAT_RETURN ret = DAT_INTERNAL_ERROR;
+       socklen_t sl;
+
+       if (p_size > DCM_MAX_PDATA_SIZE) {
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                        " accept_usr: psize(%d) too large\n", p_size);
+               return DAT_LENGTH_ERROR;
+       }
+
+       /* must have a accepted socket */
+       if (cm_ptr->socket == DAPL_INVALID_SOCKET) {
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                        " accept_usr: cm socket invalid\n");
+               goto bail;
+       }
+
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,
+                    " ACCEPT_USR: remote lid=0x%x"
+                    " qpn=0x%x qp_type %d, psize=%d\n",
+                    ntohs(cm_ptr->msg.saddr.ib.lid),
+                    ntohl(cm_ptr->msg.saddr.ib.qpn), 
+                    cm_ptr->msg.saddr.ib.qp_type, 
+                    ntohs(cm_ptr->msg.p_size));
+
+#ifdef DAT_EXTENSIONS
+       if (cm_ptr->msg.saddr.ib.qp_type == IBV_QPT_UD &&
+           ep_ptr->qp_handle->qp_type != IBV_QPT_UD) {
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                        " ACCEPT_USR: ERR remote QP is UD,"
+                        ", but local QP is not\n");
+               ret = (DAT_INVALID_HANDLE | DAT_INVALID_HANDLE_EP);
+               goto bail;
+       }
+#endif
+
+       /* modify QP to RTR and then to RTS with remote info already read */
+       dapl_os_lock(&ep_ptr->header.lock);
+       if (dapls_modify_qp_state(ep_ptr->qp_handle,
+                                 IBV_QPS_RTR, 
+                                 cm_ptr->msg.saddr.ib.qpn,
+                                 cm_ptr->msg.saddr.ib.lid,
+                                 (ib_gid_handle_t)cm_ptr->msg.saddr.ib.gid) != DAT_SUCCESS) {
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                        " ACCEPT_USR: QPS_RTR ERR %s -> %s\n",
+                        strerror(errno), 
+                        inet_ntoa(((struct sockaddr_in *)
+                                    &cm_ptr->msg.daddr.so)->sin_addr));
+               dapl_os_unlock(&ep_ptr->header.lock);
+               goto bail;
+       }
+       if (dapls_modify_qp_state(ep_ptr->qp_handle,
+                                 IBV_QPS_RTS, 
+                                 cm_ptr->msg.saddr.ib.qpn,
+                                 cm_ptr->msg.saddr.ib.lid,
+                                 NULL) != DAT_SUCCESS) {
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                        " ACCEPT_USR: QPS_RTS ERR %s -> %s\n",
+                        strerror(errno), 
+                        inet_ntoa(((struct sockaddr_in *)
+                                    &cm_ptr->msg.daddr.so)->sin_addr));
+               dapl_os_unlock(&ep_ptr->header.lock);
+               goto bail;
+       }
+       dapl_os_unlock(&ep_ptr->header.lock);
+
+       /* save remote address information */
+       dapl_os_memcpy(&ep_ptr->remote_ia_address,
+                      &cm_ptr->msg.daddr.so,
+                      sizeof(union dcm_addr));
+
+       /* send our QP info, IA address, pdata. Don't overwrite dst data */
+       local.ver = htons(DCM_VER);
+       local.op = htons(DCM_REP);
+       local.saddr.ib.qpn = htonl(ep_ptr->qp_handle->qp_num);
+       local.saddr.ib.qp_type = ep_ptr->qp_handle->qp_type;
+       local.saddr.ib.lid = ia_ptr->hca_ptr->ib_trans.lid;
+       dapl_os_memcpy(&local.saddr.ib.gid[0], 
+                      &ia_ptr->hca_ptr->ib_trans.gid, 16);
+       
+       /* Get local address information from socket */
+       sl = sizeof(local.daddr.so);
+       getsockname(cm_ptr->socket, (struct sockaddr *)&local.daddr.so, &sl);
+
+#ifdef DAPL_DBG
+       /* DBG: Active PID [0], PASSIVE PID [2] */
+       *(uint16_t*)&cm_ptr->msg.resv[2] = htons((uint16_t)dapl_os_getpid()); 
+       dapl_os_memcpy(local.resv, cm_ptr->msg.resv, 4); 
+#endif
+       cm_ptr->hca = ia_ptr->hca_ptr;
+       dapl_os_lock(&cm_ptr->lock);
+       cm_ptr->state = DCM_ACCEPTED;
+       dapl_os_unlock(&cm_ptr->lock);
+
+       /* Link CM to EP, already queued on work thread */
+       dapl_ep_link_cm(ep_ptr, cm_ptr);
+       cm_ptr->ep = ep_ptr;
+
+       local.p_size = htons(p_size);
+       iov[0].iov_base = (void *)&local;
+       iov[0].iov_len = exp;
+       
+       if (p_size) {
+               iov[1].iov_base = p_data;
+               iov[1].iov_len = p_size;
+               len = writev(cm_ptr->socket, iov, 2);
+       } else 
+               len = writev(cm_ptr->socket, iov, 1);
+       
+       if (len != (p_size + exp)) {
+               int err = dapl_socket_errno();
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                        " ACCEPT_USR: ERR 0x%x %s, wcnt=%d -> %s\n",
+                        err, strerror(err), len, 
+                        inet_ntoa(((struct sockaddr_in *)
+                                  &cm_ptr->msg.daddr.so)->sin_addr));
+               dapl_ep_unlink_cm(ep_ptr, cm_ptr);
+               cm_ptr->ep = NULL;
+               goto bail;
+       }
+
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,
+                    " ACCEPT_USR: local lid=0x%x qpn=0x%x psz=%d\n",
+                    ntohs(local.saddr.ib.lid),
+                    ntohl(local.saddr.ib.qpn), ntohs(local.p_size));
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,
+                    " ACCEPT_USR: SRC GID subnet %016llx id %016llx\n",
+                    (unsigned long long)
+                    htonll(*(uint64_t*)&local.saddr.ib.gid[0]),
+                    (unsigned long long)
+                    htonll(*(uint64_t*)&local.saddr.ib.gid[8]));
+
+       dapl_dbg_log(DAPL_DBG_TYPE_EP, " PASSIVE: accepted!\n");
+
+       return DAT_SUCCESS;
+bail:
+       /* schedule cleanup from workq */
+       dapli_cm_free(cm_ptr);
+       return ret;
+}
+
+/*
+ * PASSIVE: read RTU from active peer, post CONN event
+ */
+static void dapli_socket_accept_rtu(dp_ib_cm_handle_t cm_ptr)
+{
+       int len;
+       ib_cm_events_t event = IB_CME_CONNECTED;
+
+       /* complete handshake after final QP state change, VER and OP */
+       len = recv(cm_ptr->socket, (char *)&cm_ptr->msg, 4, 0);
+       if (len != 4 || ntohs(cm_ptr->msg.op) != DCM_RTU) {
+               dapl_log(DAPL_DBG_TYPE_ERR,
+                        " ACCEPT_RTU: rcv ERR, rcnt=%d op=%x\n",
+                        len, ntohs(cm_ptr->msg.op),
+                        inet_ntoa(((struct sockaddr_in *)
+                                   &cm_ptr->msg.daddr.so)->sin_addr));
+               event = IB_CME_DESTINATION_REJECT;
+               goto bail;
+       }
+
+       /* save state and reference to EP, queue for disc event */
+       dapl_os_lock(&cm_ptr->lock);
+       cm_ptr->state = DCM_CONNECTED;
+       dapl_os_unlock(&cm_ptr->lock);
+
+       /* final data exchange if remote QP state is good to go */
+       dapl_dbg_log(DAPL_DBG_TYPE_EP, " PASSIVE: connected!\n");
+
+#ifdef DAT_EXTENSIONS
+ud_bail:
+       if (cm_ptr->msg.saddr.ib.qp_type == IBV_QPT_UD) {
+               DAT_IB_EXTENSION_EVENT_DATA xevent;
+
+               ib_pd_handle_t pd_handle = 
+                       ((DAPL_PZ *)cm_ptr->ep->param.pz_handle)->pd_handle;
+               
+               if (event == IB_CME_CONNECTED) {
+                       cm_ptr->ah = dapls_create_ah(cm_ptr->hca, pd_handle,
+                                               cm_ptr->ep->qp_handle,
+                                               cm_ptr->msg.saddr.ib.lid, 
+                                               NULL);
+                       if (cm_ptr->ah) { 
+                               /* post EVENT, modify_qp created ah */
+                               xevent.status = 0;
+                               xevent.type = DAT_IB_UD_PASSIVE_REMOTE_AH;
+                               xevent.remote_ah.ah = cm_ptr->ah;
+                               xevent.remote_ah.qpn = ntohl(cm_ptr->msg.saddr.ib.qpn);
+                               dapl_os_memcpy(&xevent.remote_ah.ia_addr,
+                                       &cm_ptr->msg.daddr.so,
+                                       sizeof(union dcm_addr));
+                               event = DAT_IB_UD_CONNECTION_EVENT_ESTABLISHED;
+                       } else 
+                               event = DAT_IB_UD_CONNECTION_ERROR_EVENT;
+               } else 
+                       event = DAT_IB_UD_CONNECTION_ERROR_EVENT;
+
+               dapl_log(DAPL_DBG_TYPE_CM, 
+                       " CONN_RTU: UD AH %p for lid 0x%x qpn 0x%x\n", 
+                       cm_ptr->ah, ntohs(cm_ptr->msg.saddr.ib.lid),
+                       ntohl(cm_ptr->msg.saddr.ib.qpn));
+
+               dapls_evd_post_connection_event_ext(
+                               (DAPL_EVD *) 
+                               cm_ptr->ep->param.connect_evd_handle,
+                               event,
+                               (DAT_EP_HANDLE) cm_ptr->ep,
+                               (DAT_COUNT) ntohs(cm_ptr->msg.p_size),
+                               (DAT_PVOID *) cm_ptr->msg.p_data,
+                               (DAT_PVOID *) &xevent);
+
+                /* cleanup and release from local list, still on EP list */
+               dapli_cm_free(cm_ptr);
+                
+       } else 
+#endif
+       {
+               dapli_ep_check(cm_ptr->ep);
+               dapls_cr_callback(cm_ptr, event, NULL, 0, cm_ptr->sp);
+       }
+       return;
+      
+bail:
+#ifdef DAT_EXTENSIONS
+       if (cm_ptr->msg.saddr.ib.qp_type == IBV_QPT_UD) 
+               goto ud_bail;
+#endif
+       dapl_os_lock(&cm_ptr->lock);
+       cm_ptr->state = DCM_REJECTED;
+       dapl_os_unlock(&cm_ptr->lock);
+
+       dapls_cr_callback(cm_ptr, event, NULL, 0, cm_ptr->sp);
+       dapli_cm_free(cm_ptr);
+}
+
+/*
+ * 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 remote_ia_address,
+                IN DAT_CONN_QUAL remote_conn_qual,
+                IN DAT_COUNT private_data_size, IN void *private_data)
+{
+       DAPL_EP *ep_ptr = (DAPL_EP *) ep_handle;
+       
+       dapl_dbg_log(DAPL_DBG_TYPE_EP,
+                    " connect(ep_handle %p ....)\n", ep_handle);
+
+       return (dapli_socket_connect(ep_ptr, remote_ia_address,
+                                    remote_conn_qual,
+                                    private_data_size, private_data));
+}
+
+/*
+ * 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 cm_ptr = dapl_get_cm_from_ep(ep_ptr);
+
+       dapl_os_lock(&ep_ptr->header.lock);
+       if (ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED ||
+           ep_ptr->param.ep_attr.service_type != DAT_SERVICE_TYPE_RC ||
+           cm_ptr == NULL) {
+               dapl_os_unlock(&ep_ptr->header.lock);
+               return DAT_SUCCESS;
+       } 
+       dapl_os_unlock(&ep_ptr->header.lock);
+       return (dapli_socket_disconnect(cm_ptr));
+}
+
+/*
+ * 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. It is also called if dat_ep_connect
+ * times out using the consumer supplied timeout value.
+ *
+ * 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)
+{
+       if (ib_cm_event == IB_CME_TIMEOUT) {
+               dp_ib_cm_handle_t cm_ptr;
+
+               if ((cm_ptr = dapl_get_cm_from_ep(ep_ptr)) == NULL)
+                       return;
+
+               dapl_log(DAPL_DBG_TYPE_WARN,
+                       "dapls_ib_disc_clean: CONN_TIMEOUT ep %p cm %p %s\n",
+                       ep_ptr, cm_ptr, dapl_cm_state_str(cm_ptr->state));
+               
+               /* schedule release of socket and local resources */
+               dapli_cm_free(cm_ptr);
+       }
+}
+
+/*
+ * 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)
+{
+       return (dapli_socket_listen(ia_ptr, ServiceID, sp_ptr));
+}
+
+/*
+ * 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 cm_ptr = sp_ptr->cm_srvc_handle;
+
+       /* free cm_srvc_handle, release will cleanup */
+       if (cm_ptr != NULL) {
+               /* cr_thread will free */
+               sp_ptr->cm_srvc_handle = NULL;
+               dapli_cm_free(cm_ptr);
+       }
+       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_EP *ep_ptr;
+
+       dapl_dbg_log(DAPL_DBG_TYPE_EP,
+                    "dapls_ib_accept_connection(cr %p ep %p prd %p,%d)\n",
+                    cr_handle, ep_handle, p_data, p_size);
+
+       cr_ptr = (DAPL_CR *) cr_handle;
+       ep_ptr = (DAPL_EP *) ep_handle;
+
+       /* allocate and attach a QP if necessary */
+       if (ep_ptr->qp_state == DAPL_QP_STATE_UNATTACHED) {
+               DAT_RETURN status;
+               status = dapls_ib_qp_alloc(ep_ptr->header.owner_ia,
+                                          ep_ptr, ep_ptr);
+               if (status != DAT_SUCCESS)
+                       return status;
+       }
+       return (dapli_socket_accept_usr(ep_ptr, cr_ptr, p_size, p_data));
+}
+
+/*
+ * 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_ptr,
+                          IN int reason,
+                          IN DAT_COUNT psize, IN const DAT_PVOID pdata)
+{
+       struct iovec iov[2];
+
+       dapl_dbg_log(DAPL_DBG_TYPE_EP,
+                    " reject(cm %p reason %x, pdata %p, psize %d)\n",
+                    cm_ptr, reason, pdata, psize);
+
+        if (psize > DCM_MAX_PDATA_SIZE)
+                return DAT_LENGTH_ERROR;
+
+       /* write reject data to indicate reject */
+       cm_ptr->msg.op = htons(DCM_REJ_USER);
+       cm_ptr->msg.p_size = htons(psize);
+       
+       iov[0].iov_base = (void *)&cm_ptr->msg;
+       iov[0].iov_len = sizeof(ib_cm_msg_t) - DCM_MAX_PDATA_SIZE;
+       if (psize) {
+               iov[1].iov_base = pdata;
+               iov[1].iov_len = psize;
+               writev(cm_ptr->socket, iov, 2);
+       } else {
+               writev(cm_ptr->socket, iov, 1);
+       }
+
+       /* release and cleanup CM object */
+       dapli_cm_free(cm_ptr);
+       return DAT_SUCCESS;
+}
+
+/*
+ * 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 * remote_ia_address)
+{
+       DAPL_HEADER *header;
+       dp_ib_cm_handle_t conn;
+
+       dapl_dbg_log(DAPL_DBG_TYPE_EP,
+                    "dapls_ib_cm_remote_addr(dat_handle %p, ....)\n",
+                    dat_handle);
+
+       header = (DAPL_HEADER *) dat_handle;
+
+       if (header->magic == DAPL_MAGIC_EP)
+               conn = dapl_get_cm_from_ep((DAPL_EP *) dat_handle);
+       else if (header->magic == DAPL_MAGIC_CR)
+               conn = ((DAPL_CR *) dat_handle)->ib_cm_handle;
+       else
+               return DAT_INVALID_HANDLE;
+
+       dapl_os_memcpy(remote_ia_address,
+                      &conn->msg.daddr.so, sizeof(DAT_SOCK_ADDR6));
+
+       return DAT_SUCCESS;
+}
+
+int dapls_ib_private_data_size(
+       IN DAPL_HCA *hca_ptr)
+{
+       return DCM_MAX_PDATA_SIZE;
+}
+
+/* outbound/inbound CR processing thread to avoid blocking applications */
+void cr_thread(void *arg)
+{
+       struct dapl_hca *hca_ptr = arg;
+       dp_ib_cm_handle_t cr, next_cr;
+       int opt, ret;
+       socklen_t opt_len;
+       char rbuf[2];
+       struct dapl_fd_set *set;
+       enum DAPL_FD_EVENTS event;
+
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " cr_thread: ENTER hca %p\n", hca_ptr);
+       set = dapl_alloc_fd_set();
+       if (!set)
+               goto out;
+
+       dapl_os_lock(&hca_ptr->ib_trans.lock);
+       hca_ptr->ib_trans.cr_state = IB_THREAD_RUN;
+
+       while (1) {
+               dapl_fd_zero(set);
+               dapl_fd_set(hca_ptr->ib_trans.scm[0], set, DAPL_FD_READ);
+
+               if (!dapl_llist_is_empty(&hca_ptr->ib_trans.list))
+                       next_cr = dapl_llist_peek_head(&hca_ptr->ib_trans.list);
+               else
+                       next_cr = NULL;
+
+               while (next_cr) {
+                       cr = next_cr;
+                       next_cr = dapl_llist_next_entry(&hca_ptr->ib_trans.list,
+                                                       (DAPL_LLIST_ENTRY *) 
+                                                       &cr->local_entry);
+                       dapls_cm_acquire(cr); /* hold thread ref */
+                       dapl_os_lock(&cr->lock);
+                       if (cr->state == DCM_FREE || 
+                           hca_ptr->ib_trans.cr_state != IB_THREAD_RUN) {
+                               dapl_log(DAPL_DBG_TYPE_CM, 
+                                        " CM FREE: %p ep=%p st=%s sck=%d refs=%d\n", 
+                                        cr, cr->ep, dapl_cm_state_str(cr->state), 
+                                        cr->socket, cr->ref_count);
+
+                               if (cr->socket != DAPL_INVALID_SOCKET) {
+                                       shutdown(cr->socket, SHUT_RDWR);
+                                       closesocket(cr->socket);
+                                       cr->socket = DAPL_INVALID_SOCKET;
+                               }
+                               dapl_os_unlock(&cr->lock);
+                               dapls_cm_release(cr); /* release alloc ref */
+                               dapli_cm_dequeue(cr); /* release workq ref */
+                               dapls_cm_release(cr); /* release thread ref */
+                               continue;
+                       }
+
+                       event = (cr->state == DCM_CONN_PENDING) ?
+                                       DAPL_FD_WRITE : DAPL_FD_READ;
+
+                       if (dapl_fd_set(cr->socket, set, event)) {
+                               dapl_log(DAPL_DBG_TYPE_ERR,
+                                        " cr_thread: fd_set ERR st=%d fd %d"
+                                        " -> %s\n", cr->state, cr->socket,
+                                        inet_ntoa(((struct sockaddr_in *)
+                                               &cr->msg.daddr.so)->sin_addr));
+                               dapl_os_unlock(&cr->lock);
+                               dapls_cm_release(cr); /* release ref */
+                               continue;
+                       }
+                       dapl_os_unlock(&cr->lock);
+                       dapl_os_unlock(&hca_ptr->ib_trans.lock);
+                       
+                       ret = dapl_poll(cr->socket, event);
+
+                       dapl_dbg_log(DAPL_DBG_TYPE_THREAD,
+                                    " poll ret=0x%x %s sck=%d\n",
+                                    ret, dapl_cm_state_str(cr->state), 
+                                    cr->socket);
+
+                       /* data on listen, qp exchange, and on disc req */
+                       dapl_os_lock(&cr->lock);
+                       if ((ret == DAPL_FD_READ) || 
+                           (cr->state != DCM_CONN_PENDING && ret == DAPL_FD_ERROR)) {
+                               if (cr->socket != DAPL_INVALID_SOCKET) {
+                                       switch (cr->state) {
+                                       case DCM_LISTEN:
+                                               dapl_os_unlock(&cr->lock);
+                                               dapli_socket_accept(cr);
+                                                break;
+                                       case DCM_ACCEPTING:
+                                               dapl_os_unlock(&cr->lock);
+                                               dapli_socket_accept_data(cr);
+                                               break;
+                                       case DCM_ACCEPTED:
+                                               dapl_os_unlock(&cr->lock);
+                                               dapli_socket_accept_rtu(cr);
+                                               break;
+                                       case DCM_REP_PENDING:
+                                               dapl_os_unlock(&cr->lock);
+                                               dapli_socket_connect_rtu(cr);
+                                               break;
+                                       case DCM_CONNECTED:
+                                               dapl_os_unlock(&cr->lock);
+                                               dapli_socket_disconnect(cr);
+                                               break;
+                                       default:
+                                               dapl_os_unlock(&cr->lock);
+                                               break;
+                                       }
+                               } else 
+                                       dapl_os_unlock(&cr->lock);
+
+                       /* ASYNC connections, writable, readable, error; check status */
+                       } else if (ret == DAPL_FD_WRITE ||
+                                  (cr->state == DCM_CONN_PENDING && 
+                                   ret == DAPL_FD_ERROR)) {
+                               
+                               opt = 0;
+                               opt_len = sizeof(opt);
+                               ret = getsockopt(cr->socket, SOL_SOCKET,
+                                                SO_ERROR, (char *)&opt,
+                                                &opt_len);
+                               dapl_os_unlock(&cr->lock);
+                               if (!ret && !opt)
+                                       dapli_socket_connected(cr, opt);
+                               else
+                                       dapli_socket_connected(cr, opt ? opt : dapl_socket_errno());
+                       } else 
+                               dapl_os_unlock(&cr->lock);
+
+                       dapls_cm_release(cr); /* release ref */
+                       dapl_os_lock(&hca_ptr->ib_trans.lock);
+               }
+
+               /* set to exit and all resources destroyed */
+               if ((hca_ptr->ib_trans.cr_state != IB_THREAD_RUN) &&
+                   (dapl_llist_is_empty(&hca_ptr->ib_trans.list)))
+                       break;
+
+               dapl_os_unlock(&hca_ptr->ib_trans.lock);
+               dapl_select(set);
+
+               /* if pipe used to wakeup, consume */
+               while (dapl_poll(hca_ptr->ib_trans.scm[0], 
+                                DAPL_FD_READ) == DAPL_FD_READ) {
+                       if (recv(hca_ptr->ib_trans.scm[0], rbuf, 2, 0) == -1)
+                               dapl_log(DAPL_DBG_TYPE_THREAD,
+                                        " cr_thread: read pipe error = %s\n",
+                                        strerror(errno));
+               }
+               dapl_os_lock(&hca_ptr->ib_trans.lock);
+               
+               /* set to exit and all resources destroyed */
+               if ((hca_ptr->ib_trans.cr_state != IB_THREAD_RUN) &&
+                   (dapl_llist_is_empty(&hca_ptr->ib_trans.list)))
+                       break;
+       }
+
+       dapl_os_unlock(&hca_ptr->ib_trans.lock);
+       dapl_os_free(set, sizeof(struct dapl_fd_set));
+out:
+       hca_ptr->ib_trans.cr_state = IB_THREAD_EXIT;
+       dapl_dbg_log(DAPL_DBG_TYPE_THREAD, " cr_thread(hca %p) exit\n", hca_ptr);
+}
+
+
+#ifdef DAPL_COUNTERS
+/* Debug aid: List all Connections in process and state */
+void dapls_print_cm_list(IN DAPL_IA *ia_ptr)
+{
+       /* Print in process CR's for this IA, if debug type set */
+       int i = 0;
+       dp_ib_cm_handle_t cr, next_cr;
+
+       dapl_os_lock(&ia_ptr->hca_ptr->ib_trans.lock);
+       if (!dapl_llist_is_empty((DAPL_LLIST_HEAD*)
+                                &ia_ptr->hca_ptr->ib_trans.list))
+                                next_cr = dapl_llist_peek_head((DAPL_LLIST_HEAD*)
+                                &ia_ptr->hca_ptr->ib_trans.list);
+       else
+               next_cr = NULL;
+
+        printf("\n DAPL IA CONNECTIONS IN PROCESS:\n");
+       while (next_cr) {
+               cr = next_cr;
+               next_cr = dapl_llist_next_entry((DAPL_LLIST_HEAD*)
+                                &ia_ptr->hca_ptr->ib_trans.list,
+                               (DAPL_LLIST_ENTRY*)&cr->local_entry);
+
+               printf( "  CONN[%d]: sp %p ep %p sock %d %s %s %s %s %s %s PORT L-%x R-%x PID L-%x R-%x\n",
+                       i, cr->sp, cr->ep, cr->socket,
+                       cr->msg.saddr.ib.qp_type == IBV_QPT_RC ? "RC" : "UD",
+                       dapl_cm_state_str(cr->state), dapl_cm_op_str(ntohs(cr->msg.op)),
+                       ntohs(cr->msg.op) == DCM_REQ ? /* local address */
+                               inet_ntoa(((struct sockaddr_in *)&cr->msg.daddr.so)->sin_addr) :
+                               inet_ntoa(((struct sockaddr_in *)&cr->addr)->sin_addr),
+                       cr->sp ? "<-" : "->",
+                               ntohs(cr->msg.op) == DCM_REQ ? /* remote address */
+                               inet_ntoa(((struct sockaddr_in *)&cr->addr)->sin_addr) :
+                               inet_ntoa(((struct sockaddr_in *)&cr->msg.daddr.so)->sin_addr),
+
+                       ntohs(cr->msg.op) == DCM_REQ ? /* local port */
+                               ntohs(((struct sockaddr_in *)&cr->msg.daddr.so)->sin_port) :
+                               ntohs(((struct sockaddr_in *)&cr->addr)->sin_port),
+
+                       ntohs(cr->msg.op) == DCM_REQ ? /* remote port */
+                               ntohs(((struct sockaddr_in *)&cr->addr)->sin_port) :
+                               ntohs(((struct sockaddr_in *)&cr->msg.daddr.so)->sin_port),
+
+                       cr->sp ? ntohs(*(uint16_t*)&cr->msg.resv[2]) : ntohs(*(uint16_t*)&cr->msg.resv[0]),
+                       cr->sp ? ntohs(*(uint16_t*)&cr->msg.resv[0]) : ntohs(*(uint16_t*)&cr->msg.resv[2]));
+
+               i++;
+       }
+       printf("\n");
+       dapl_os_unlock(&ia_ptr->hca_ptr->ib_trans.lock);
+}
+#endif
index 497bc64a5ad91c124474206cce7c4001c848630f..4bb1a4a6a941c6cb3d23ad83c338ab1d84f5f6e1 100644 (file)
@@ -106,6 +106,10 @@ typedef struct _ib_hca_transport
        uint8_t                 mtu;
        DAT_NAMED_ATTR          named_attr;
        DAPL_SOCKET             scm[2];
+       uint8_t                 sl;
+       uint16_t                pkey;
+       int                     pkey_idx;
+
 } ib_hca_transport_t;
 
 /* prototypes */
index eb87a85b977af407df023ebcdff8f6dc2ced030d..4c50f0340d2987a08f0145331ea65ee15427f11d 100644 (file)
@@ -67,7 +67,6 @@ DAT_RETURN  dapli_ib_thread_init(void);
 void dapli_ib_thread_destroy(void);
 
 #if defined(_WIN64) || defined(_WIN32)
-#include "..\..\..\..\..\etc\user\comp_channel.cpp"
 #include <rdma\winverbs.h>
 
 static COMP_SET ufds;
@@ -216,8 +215,11 @@ static void destroy_cr_pipe(IN DAPL_HCA * hca_ptr)
  *     0 success, -1 error
  *
  */
+DAT_UINT32 g_parent = 0;
 int32_t dapls_ib_init(void)
 {
+        g_parent = dapl_os_getpid();
+
        /* initialize hca_list */
        dapl_os_lock_init(&g_hca_lock);
        dapl_llist_init_head(&g_hca_list);
@@ -230,6 +232,10 @@ int32_t dapls_ib_init(void)
 
 int32_t dapls_ib_release(void)
 {
+        /* only parent init will cleanup */
+        if (dapl_os_getpid() != g_parent)
+                return 0;
+       
        dapli_ib_thread_destroy();
        dapls_os_release();
        return 0;
@@ -263,7 +269,7 @@ DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr)
                     " open_hca: %s - %p\n", hca_name, hca_ptr);
 
        /* get the IP address of the device */
-       dat_status = getlocalipaddr((DAT_SOCK_ADDR *) &hca_ptr->hca_address,
+       dat_status = getlocalipaddr((char *)&hca_ptr->hca_address,
                                    sizeof(DAT_SOCK_ADDR6));
        if (dat_status != DAT_SUCCESS)
                return dat_status;
index a2b5dce4b78e2a1813f5e2cc86666c73d88a7873..381afa23cf45623e6728fd7226949dcc5749feac 100644 (file)
@@ -37,9 +37,11 @@ TARGETLIBS= \
        $(SDK_LIB_PATH)\ws2_32.lib \\r
 !if $(FREEBUILD)\r
        $(TARGETPATH)\*\dat2.lib \\r
+       $(TARGETPATH)\*\winverbs.lib \\r
        $(TARGETPATH)\*\libibverbs.lib\r
 !else\r
        $(TARGETPATH)\*\dat2d.lib \\r
+       $(TARGETPATH)\*\winverbsd.lib \\r
        $(TARGETPATH)\*\libibverbsd.lib\r
 !endif\r
 \r
index 2cab529359d25e4d18f91562ce2c6a2d6d1dce64..b874c8b6a8785587285edb1ce5bdabc0bfd992ac 100644 (file)
@@ -165,9 +165,9 @@ static void ucm_check_timers(dp_ib_cm_handle_t cm, int *timer)
                if ((time - cm->timer)/1000 > 
                    (cm->hca->ib_trans.rep_time << cm->retries)) {
                        dapl_log(DAPL_DBG_TYPE_WARN,
-                                " CM_REQ retry %d [lid, port, qpn]:"
+                                " CM_REQ retry %d %p [lid, port, qpn]:"
                                 " %x %x %x -> %x %x %x Time(ms) %llu > %llu\n", 
-                                cm->retries, ntohs(cm->msg.saddr.ib.lid), 
+                                cm, cm->retries, ntohs(cm->msg.saddr.ib.lid), 
                                 ntohs(cm->msg.sport), ntohl(cm->msg.saddr.ib.qpn), 
                                 ntohs(cm->msg.daddr.ib.lid), ntohs(cm->msg.dport),
                                 ntohl(cm->msg.dqpn), (time - cm->timer)/1000, 
@@ -184,7 +184,7 @@ static void ucm_check_timers(dp_ib_cm_handle_t cm, int *timer)
                    (cm->hca->ib_trans.rtu_time << cm->retries)) {
                        dapl_log(DAPL_DBG_TYPE_WARN,
                                 " CM_REPLY retry %d [lid, port, qpn]:"
-                                " %x %x %x -> %x %x %x r_pid %x,%d Time(ms) %llu > %llu\n", 
+                                " %x %x %x -> %x %x %x r_pid %x (%x) Time(ms) %llu > %llu\n", 
                                 cm->retries,
                                 ntohs(cm->msg.saddr.ib.lid), 
                                 ntohs(cm->msg.sport),
@@ -208,7 +208,7 @@ static void ucm_check_timers(dp_ib_cm_handle_t cm, int *timer)
                    (cm->hca->ib_trans.rtu_time << cm->retries)) {
                        dapl_log(DAPL_DBG_TYPE_WARN,
                                 " CM_DREQ retry %d [lid, port, qpn]:"
-                                " %x %x %x -> %x %x %x r_pid %x,%d Time(ms) %llu > %llu\n", 
+                                " %x %x %x -> %x %x %x r_pid %x (%x) Time(ms) %llu > %llu\n", 
                                 cm->retries,
                                 ntohs(cm->msg.saddr.ib.lid), 
                                 ntohs(cm->msg.sport),
@@ -317,7 +317,7 @@ static int ucm_reject(ib_hca_transport_t *tp, ib_cm_msg_t *msg)
        dapl_os_memcpy(&smsg.saddr, &msg->daddr, sizeof(union dcm_addr));
 
        dapl_dbg_log(DAPL_DBG_TYPE_CM, 
-                    " CM reject -> LID %x, QPN %x PORT %d\n", 
+                    " CM reject -> LID %x, QPN %x PORT %x\n", 
                     ntohs(smsg.daddr.ib.lid),
                     ntohl(smsg.dqpn), ntohs(smsg.dport));
 
@@ -354,7 +354,7 @@ static void ucm_process_recv(ib_hca_transport_t *tp,
                if (ntohs(msg->op) == DCM_REP) {
                        dapl_log(DAPL_DBG_TYPE_WARN,
                                " RESEND RTU: op %s st %s [lid, port, qpn]:"
-                               " 0x%x %d 0x%x -> 0x%x %d 0x%x\n", 
+                               " %x %x %x -> %x %x %x\n", 
                                dapl_cm_op_str(ntohs(msg->op)), 
                                dapl_cm_state_str(cm->state),
                                ntohs(msg->saddr.ib.lid), 
@@ -380,7 +380,7 @@ static void ucm_process_recv(ib_hca_transport_t *tp,
                if (ntohs(msg->op) == DCM_DREQ) {
                        dapl_log(DAPL_DBG_TYPE_WARN,
                                " RESEND DREP: op %s st %s [lid, port, qpn]:"
-                               " 0x%x %d 0x%x -> 0x%x %d 0x%x\n", 
+                               " %x %x %x -> %x %x %x\n", 
                                dapl_cm_op_str(ntohs(msg->op)), 
                                dapl_cm_state_str(cm->state),
                                ntohs(msg->saddr.ib.lid), 
@@ -392,13 +392,13 @@ static void ucm_process_recv(ib_hca_transport_t *tp,
                        cm->msg.op = htons(DCM_DREP);
                        ucm_send(&cm->hca->ib_trans, &cm->msg, NULL, 0); 
                        
-               }
-               /* UD reply retried ok to ignore, any other print warning */
-               if (ntohs(msg->op) != DCM_REP) {
+               } else if (ntohs(msg->op) != DCM_DREP){
+                       /* DREP ok to ignore, any other print warning */
                        dapl_log(DAPL_DBG_TYPE_WARN,
-                               " ucm_recv: UNKNOWN operation"
-                               " <- op %d, %s spsp %d sqpn %d\n", 
-                               ntohs(msg->op), dapl_cm_state_str(cm->state),
+                               " ucm_recv: UNEXPECTED MSG on cm %p"
+                               " <- op %s, st %s spsp %x sqpn %x\n", 
+                               cm, dapl_cm_op_str(ntohs(msg->op)),
+                               dapl_cm_state_str(cm->state),
                                ntohs(msg->sport), ntohl(msg->sqpn));
                }
                dapl_os_unlock(&cm->lock);
@@ -406,8 +406,9 @@ static void ucm_process_recv(ib_hca_transport_t *tp,
        default:
                dapl_log(DAPL_DBG_TYPE_WARN,
                                " ucm_recv: UNKNOWN state"
-                               " <- op %d, %s spsp %d sqpn %d\n", 
-                               ntohs(msg->op), dapl_cm_state_str(cm->state), 
+                               " <- op %s, %s spsp %x sqpn %x\n", 
+                               dapl_cm_op_str(ntohs(msg->op)), 
+                               dapl_cm_state_str(cm->state), 
                                ntohs(msg->sport), ntohl(msg->sqpn));
                dapl_os_unlock(&cm->lock);
                break;
@@ -459,8 +460,8 @@ retry_listenq:
                                /* duplicate; bail and throw away */
                                dapl_os_unlock(lock);
                                dapl_log(DAPL_DBG_TYPE_WARN,
-                                        " DUPLICATE: op %s st %s [lid, port, qpn]:"
-                                        " 0x%x %d 0x%x <- 0x%x %d 0x%x\n", 
+                                        " DUPLICATE: cm %p op %s st %s [lid, port, qpn]:"
+                                        " %x %x %x <- %x %x %x\n", cm,
                                         dapl_cm_op_str(ntohs(msg->op)), 
                                         dapl_cm_state_str(cm->state),
                                         ntohs(msg->daddr.ib.lid), 
@@ -469,6 +470,7 @@ retry_listenq:
                                         ntohs(msg->saddr.ib.lid), 
                                         ntohs(msg->sport),
                                         ntohl(msg->saddr.ib.qpn));  
+
                                return NULL;
                        }
                }
@@ -484,13 +486,23 @@ retry_listenq:
        }
 
        /* not match on listenq for valid request, send reject */
-       if (ntohs(msg->op) == DCM_REQ && !found)
+       if (ntohs(msg->op) == DCM_REQ && !found) {
+               dapl_log(DAPL_DBG_TYPE_WARN,
+                       " ucm_recv: NO LISTENER for %s %x %x i%x c%x"
+                       " < %x %x %x, sending reject\n", 
+                       dapl_cm_op_str(ntohs(msg->op)), 
+                       ntohs(msg->daddr.ib.lid), ntohs(msg->dport), 
+                       ntohl(msg->daddr.ib.qpn), ntohl(msg->sqpn),
+                       ntohs(msg->saddr.ib.lid), ntohs(msg->sport), 
+                       ntohl(msg->saddr.ib.qpn));
+
                ucm_reject(tp, msg);
+       }
 
        if (!found) {
                dapl_log(DAPL_DBG_TYPE_WARN,
-                       " ucm_recv: NO MATCH op %s 0x%x %d i0x%x c0x%x"
-                       " < 0x%x %d 0x%x\n", 
+                       " ucm_recv: NO MATCH op %s %x %x i%x c%x"
+                       " < %x %x %x\n", 
                        dapl_cm_op_str(ntohs(msg->op)), 
                        ntohs(msg->daddr.ib.lid), ntohs(msg->dport), 
                        ntohl(msg->daddr.ib.qpn), ntohl(msg->sqpn),
@@ -593,8 +605,9 @@ static int ucm_send(ib_hca_transport_t *tp, ib_cm_msg_t *msg, DAT_PVOID p_data,
         sge.addr = (uintptr_t)smsg;
 
        dapl_dbg_log(DAPL_DBG_TYPE_CM, 
-               " ucm_send: op %d ln %d lid %x c_qpn %x rport %d\n", 
-               ntohs(smsg->op), sge.length, htons(smsg->daddr.ib.lid), 
+               " ucm_send: op %s ln %d lid %x c_qpn %x rport %s\n", 
+               dapl_cm_op_str(ntohs(smsg->op)), 
+               sge.length, htons(smsg->daddr.ib.lid), 
                htonl(smsg->dqpn), htons(smsg->dport));
 
        /* empty slot, then create AH */
@@ -635,26 +648,22 @@ void dapls_cm_acquire(dp_ib_cm_handle_t cm)
 void dapls_cm_release(dp_ib_cm_handle_t cm)
 {
        dapl_os_lock(&cm->lock);
-       cm->ref_count--;\r
-       if (cm->ref_count) {\r
-                dapl_os_unlock(&cm->lock);\r
-               return;\r
-       }\r
+       cm->ref_count--;
+       if (cm->ref_count) {
+                dapl_os_unlock(&cm->lock);
+               return;
+       }
        /* client, release local conn id port */
        if (!cm->sp && cm->msg.sport)
                ucm_free_port(&cm->hca->ib_trans, ntohs(cm->msg.sport));
 
-       /* server, release local conn id port */
-       if (cm->sp && cm->msg.dport)
-               ucm_free_port(&cm->hca->ib_trans, ntohs(cm->msg.dport));
-
        /* clean up any UD address handles */
        if (cm->ah) {
                ibv_destroy_ah(cm->ah);
                cm->ah = NULL;
-       }\r
-       dapl_os_unlock(&cm->lock);\r
-       dapli_cm_dealloc(cm);\r
+       }
+       dapl_os_unlock(&cm->lock);
+       dapli_cm_dealloc(cm);
 }
 
 dp_ib_cm_handle_t dapls_ib_cm_create(DAPL_EP *ep)
@@ -710,6 +719,11 @@ bail:
 /* schedule destruction of CM object */
 void dapli_cm_free(dp_ib_cm_handle_t cm)
 {
+       dapl_log(DAPL_DBG_TYPE_CM,
+                " dapli_cm_free: cm %p %s ep %p refs=%d\n", 
+                cm, dapl_cm_state_str(cm->state),
+                cm->ep, cm->ref_count);
+
        dapl_os_lock(&cm->lock);
        cm->state = DCM_FREE;
        dapls_thread_signal(&cm->hca->ib_trans.signal);
@@ -720,15 +734,18 @@ void dapli_cm_free(dp_ib_cm_handle_t cm)
 void dapls_cm_free(dp_ib_cm_handle_t cm)
 {
        dapl_log(DAPL_DBG_TYPE_CM,
-                " cm_free: cm %p %s ep %p refs=%d\n", 
+                " dapl_cm_free: cm %p %s ep %p refs=%d\n", 
                 cm, dapl_cm_state_str(cm->state),
                 cm->ep, cm->ref_count);
        
        /* free from internal workq, wait until EP is last ref */
        dapl_os_lock(&cm->lock);
-       cm->state = DCM_FREE;
+       if (cm->state != DCM_FREE) 
+               cm->state = DCM_FREE;
+       
        while (cm->ref_count != 1) {
                dapl_os_unlock(&cm->lock);
+               dapls_thread_signal(&cm->hca->ib_trans.signal);
                dapl_os_sleep_usec(10000);
                dapl_os_lock(&cm->lock);
        }
@@ -804,8 +821,6 @@ static void ucm_disconnect_final(dp_ib_cm_handle_t cm)
        else
                dapl_evd_connection_callback(cm, IB_CME_DISCONNECTED, NULL, 0, cm->ep);
 
-       /* free local resources, EP ref will prevent destory until dat_ep_free */
-       dapls_cm_release(cm);
 }
 
 /*
@@ -815,6 +830,7 @@ static void ucm_disconnect_final(dp_ib_cm_handle_t cm)
 DAT_RETURN dapli_cm_disconnect(dp_ib_cm_handle_t cm)
 {
        int finalize = 1;
+       int wakeup = 0;
 
        dapl_os_lock(&cm->lock);
        switch (cm->state) {
@@ -826,8 +842,8 @@ DAT_RETURN dapli_cm_disconnect(dp_ib_cm_handle_t cm)
                /* send DREQ, event after DREP or DREQ timeout */
                cm->state = DCM_DISC_PENDING;
                cm->msg.op = htons(DCM_DREQ);
-               finalize = 0; /* wait for DREP, wakeup timer thread */
-               dapls_thread_signal(&cm->hca->ib_trans.signal);
+               finalize = 0; /* wait for DREP, wakeup timer after DREQ sent */
+               wakeup = 1;
                break;
        case DCM_DISC_PENDING:
                /* DREQ timeout, resend until retries exhausted */
@@ -835,7 +851,7 @@ DAT_RETURN dapli_cm_disconnect(dp_ib_cm_handle_t cm)
                if (cm->retries >= cm->hca->ib_trans.retries) {
                        dapl_log(DAPL_DBG_TYPE_ERR, 
                                " CM_DREQ: RETRIES EXHAUSTED:"
-                               " 0x%x %d 0x%x -> 0x%x %d 0x%x\n",
+                               " %x %x %x -> %x %x %x\n",
                                htons(cm->msg.saddr.ib.lid), 
                                htonl(cm->msg.saddr.ib.qpn), 
                                htons(cm->msg.sport), 
@@ -850,10 +866,29 @@ DAT_RETURN dapli_cm_disconnect(dp_ib_cm_handle_t cm)
                if (cm->ep->qp_handle->qp_type != IBV_QPT_UD) 
                        dapls_modify_qp_state(cm->ep->qp_handle, IBV_QPS_ERR,0,0,0);
 
-               /* DREQ received, send DREP and schedule event */
+               /* DREQ received, send DREP and schedule event, finalize */
                cm->msg.op = htons(DCM_DREP);
                break;
+       case DCM_DISCONNECTED:
+               dapl_os_unlock(&cm->lock);
+               return DAT_SUCCESS;
        default:
+               dapl_log(DAPL_DBG_TYPE_WARN, 
+                       "  disconnect UNKNOWN state: ep %p cm %p %s %s"
+                       "  %x %x %x %s %x %x %x r_pid %x (%x)\n",
+                       cm->ep, cm,
+                       cm->msg.saddr.ib.qp_type == IBV_QPT_RC ? "RC" : "UD",
+                       dapl_cm_state_str(cm->state),
+                       ntohs(cm->msg.saddr.ib.lid),
+                       ntohs(cm->msg.sport),
+                       ntohl(cm->msg.saddr.ib.qpn),    
+                       cm->sp ? "<-" : "->",
+                       ntohs(cm->msg.daddr.ib.lid),
+                       ntohs(cm->msg.dport),
+                       ntohl(cm->msg.daddr.ib.qpn),
+                       ntohs(cm->msg.op) == DCM_REQ ? 0 : ntohl(*(DAT_UINT32*)cm->msg.resv), 
+                       ntohs(cm->msg.op) == DCM_REQ ? 0 : ntohl(*(DAT_UINT32*)cm->msg.resv)); 
+
                dapl_os_unlock(&cm->lock);
                return DAT_SUCCESS;
        }
@@ -861,6 +896,9 @@ DAT_RETURN dapli_cm_disconnect(dp_ib_cm_handle_t cm)
        dapl_os_get_time(&cm->timer); /* reply expected */
        ucm_send(&cm->hca->ib_trans, &cm->msg, NULL, 0); 
        dapl_os_unlock(&cm->lock);
+       
+       if (wakeup)
+               dapls_thread_signal(&cm->hca->ib_trans.signal);
 
        if (finalize) 
                ucm_disconnect_final(cm);
@@ -876,8 +914,8 @@ DAT_RETURN
 dapli_cm_connect(DAPL_EP *ep, dp_ib_cm_handle_t cm)
 {
        dapl_log(DAPL_DBG_TYPE_EP, 
-                " connect: lid %x i_qpn %x lport %d p_sz=%d -> "
-                " lid %x c_qpn %x rport %d\n",
+                " connect: lid %x i_qpn %x lport %x p_sz=%d -> "
+                " lid %x c_qpn %x rport %x\n",
                 htons(cm->msg.saddr.ib.lid), htonl(cm->msg.saddr.ib.qpn),
                 htons(cm->msg.sport), htons(cm->msg.p_size),
                 htons(cm->msg.daddr.ib.lid), htonl(cm->msg.dqpn),
@@ -892,7 +930,7 @@ dapli_cm_connect(DAPL_EP *ep, dp_ib_cm_handle_t cm)
        if (cm->retries == cm->hca->ib_trans.retries) {
                dapl_log(DAPL_DBG_TYPE_ERR, 
                        " CM_REQ: RETRIES EXHAUSTED:"
-                        " 0x%x %d 0x%x -> 0x%x %d 0x%x\n",
+                        " 0x%x %x 0x%x -> 0x%x %x 0x%x\n",
                         htons(cm->msg.saddr.ib.lid), 
                         htonl(cm->msg.saddr.ib.qpn), 
                         htons(cm->msg.sport), 
@@ -933,7 +971,7 @@ dapli_cm_connect(DAPL_EP *ep, dp_ib_cm_handle_t cm)
 
 bail:
        dapl_log(DAPL_DBG_TYPE_WARN, 
-                " connect: ERR %s -> cm_lid %d cm_qpn %d r_psp %d p_sz=%d\n",
+                " connect: ERR %s -> cm_lid %x cm_qpn %x r_psp %x p_sz=%d\n",
                 strerror(errno), htons(cm->msg.daddr.ib.lid), 
                 htonl(cm->msg.dqpn), htons(cm->msg.dport), 
                 htonl(cm->msg.p_size));
@@ -954,8 +992,9 @@ static void ucm_connect_rtu(dp_ib_cm_handle_t cm, ib_cm_msg_t *msg)
        if (cm->state != DCM_REP_PENDING) {
                dapl_log(DAPL_DBG_TYPE_WARN, 
                         " CONN_RTU: UNEXPECTED state:"
-                        " op %d, st %s <- lid %d sqpn %d sport %d\n", 
-                        ntohs(msg->op), dapl_cm_state_str(cm->state), 
+                        " op %s, st %s <- lid %x sqpn %x sport %x\n", 
+                        dapl_cm_op_str(ntohs(msg->op)), 
+                        dapl_cm_state_str(cm->state), 
                         ntohs(msg->saddr.ib.lid), ntohl(msg->saddr.ib.qpn), 
                         ntohs(msg->sport));
                dapl_os_unlock(&cm->lock);
@@ -973,7 +1012,7 @@ static void ucm_connect_rtu(dp_ib_cm_handle_t cm, ib_cm_msg_t *msg)
                if (ntohs(msg->p_size) > DCM_MAX_PDATA_SIZE) {
                        dapl_log(DAPL_DBG_TYPE_WARN, 
                                 " CONN_RTU: invalid p_size %d:"
-                                " st %s <- lid %d sqpn %d spsp %d\n", 
+                                " st %s <- lid %x sqpn %x spsp %x\n", 
                                 ntohs(msg->p_size), 
                                 dapl_cm_state_str(cm->state), 
                                 ntohs(msg->saddr.ib.lid), 
@@ -988,7 +1027,7 @@ static void ucm_connect_rtu(dp_ib_cm_handle_t cm, ib_cm_msg_t *msg)
                
        dapl_dbg_log(DAPL_DBG_TYPE_CM,
                     " CONN_RTU: DST lid=%x,"
-                    " iqp=%x, qp_type=%d, port=%d psize=%d\n",
+                    " iqp=%x, qp_type=%d, port=%x psize=%d\n",
                     ntohs(cm->msg.daddr.ib.lid),
                     ntohl(cm->msg.daddr.ib.qpn), cm->msg.daddr.ib.qp_type,
                     ntohs(msg->sport), ntohs(msg->p_size));
@@ -1001,6 +1040,16 @@ static void ucm_connect_rtu(dp_ib_cm_handle_t cm, ib_cm_msg_t *msg)
                event = IB_CME_DESTINATION_REJECT;
        
        if (event != IB_CME_CONNECTED) {
+               dapl_log(DAPL_DBG_TYPE_CM, 
+                        " ACTIVE: CM_REQ REJECTED:"
+                        " cm %p op %s, st %s dlid %x iqp %x port %x <-"
+                        " slid %x iqp %x port %x\n", cm,
+                        dapl_cm_op_str(ntohs(msg->op)), 
+                        dapl_cm_state_str(cm->state), 
+                        ntohs(msg->daddr.ib.lid), ntohl(msg->daddr.ib.qpn), 
+                        ntohs(msg->dport), ntohs(msg->saddr.ib.lid), 
+                        ntohl(msg->saddr.ib.qpn), ntohs(msg->sport));
+
                cm->state = DCM_REJECTED;
                dapl_os_unlock(&cm->lock);
 
@@ -1086,7 +1135,7 @@ ud_bail:
                        &xevent.remote_ah.ia_addr)->ib.qpn = cm->msg.dqpn;
 
                dapl_dbg_log(DAPL_DBG_TYPE_EP,
-                            " ACTIVE: UD xevent ah %p qpn 0x%x lid 0x%x\n",
+                            " ACTIVE: UD xevent ah %p qpn %x lid %x\n",
                             xevent.remote_ah.ah, xevent.remote_ah.qpn, lid);
                dapl_dbg_log(DAPL_DBG_TYPE_EP,
                             " ACTIVE: UD xevent ia_addr qp_type %d"
@@ -1114,10 +1163,6 @@ ud_bail:
                                (DAT_COUNT)ntohs(cm->msg.p_size),
                                (DAT_PVOID *)cm->msg.p_data,
                                (DAT_PVOID *)&xevent);
-
-               /* release cm_ptr, EP refs will prevent destroy */
-               dapli_cm_free(cm);
-                               
        } else
 #endif
        {
@@ -1150,6 +1195,7 @@ static void ucm_accept(ib_cm_srvc_handle_t cm, ib_cm_msg_t *msg)
        /* dest CM info from CR msg, source CM info from listen */
        acm->sp = cm->sp;
        acm->hca = cm->hca;
+       acm->msg.op = msg->op;
        acm->msg.dport = msg->sport;
        acm->msg.dqpn = msg->sqpn;
        acm->msg.sport = cm->msg.sport; 
@@ -1160,7 +1206,7 @@ static void ucm_accept(ib_cm_srvc_handle_t cm, ib_cm_msg_t *msg)
        dapl_os_memcpy(&acm->msg.daddr, &msg->saddr, sizeof(union dcm_addr));
        
        dapl_log(DAPL_DBG_TYPE_CM,
-                " accept: DST port=%d lid=%x, iqp=%x, psize=%d\n",
+                " accept: DST port=%x lid=%x, iqp=%x, psize=%d\n",
                 ntohs(acm->msg.dport), ntohs(acm->msg.daddr.ib.lid), 
                 htonl(acm->msg.daddr.ib.qpn), htons(acm->msg.p_size));
 
@@ -1216,8 +1262,9 @@ static void ucm_accept_rtu(dp_ib_cm_handle_t cm, ib_cm_msg_t *msg)
        if ((ntohs(msg->op) != DCM_RTU) || (cm->state != DCM_RTU_PENDING)) {
                dapl_log(DAPL_DBG_TYPE_WARN, 
                         " accept_rtu: UNEXPECTED op, state:"
-                        " op %d, st %s <- lid %x iqp %x sport %d\n", 
-                        ntohs(msg->op), dapl_cm_state_str(cm->state), 
+                        " op %s, st %s <- lid %x iqp %x sport %x\n", 
+                        dapl_cm_op_str(ntohs(msg->op)), 
+                        dapl_cm_state_str(cm->state), 
                         ntohs(msg->saddr.ib.lid), ntohl(msg->saddr.ib.qpn), 
                         ntohs(msg->sport));
                dapl_os_unlock(&cm->lock);
@@ -1260,7 +1307,7 @@ static void ucm_accept_rtu(dp_ib_cm_handle_t cm, ib_cm_msg_t *msg)
                        &xevent.remote_ah.ia_addr)->ib.qpn = cm->msg.dqpn;
 
                dapl_dbg_log(DAPL_DBG_TYPE_EP,
-                            " PASSIVE: UD xevent ah %p qpn 0x%x lid 0x%x\n",
+                            " PASSIVE: UD xevent ah %p qpn %x lid %x\n",
                             xevent.remote_ah.ah, xevent.remote_ah.qpn, lid);
                dapl_dbg_log(DAPL_DBG_TYPE_EP,
                             " PASSIVE: UD xevent ia_addr qp_type %d"
@@ -1281,10 +1328,6 @@ static void ucm_accept_rtu(dp_ib_cm_handle_t cm, ib_cm_msg_t *msg)
                                (DAT_COUNT)ntohs(cm->msg.p_size),
                                (DAT_PVOID *)cm->msg.p_data,
                                (DAT_PVOID *)&xevent);
-
-                /* done with CM object, EP ref will hold object for pdata */
-               dapli_cm_free(cm);
-               
        } else {
 #endif
                dapls_cr_callback(cm, IB_CME_CONNECTED, NULL, 0, cm->sp);
@@ -1302,14 +1345,17 @@ static int ucm_reply(dp_ib_cm_handle_t cm)
 {
        dapl_os_lock(&cm->lock);
        if (cm->state != DCM_RTU_PENDING) {
+               dapl_log(DAPL_DBG_TYPE_ERR, 
+                        " CM_REPLY: wrong state %s",
+                        dapl_cm_state_str(cm->state));
                dapl_os_unlock(&cm->lock);
                return -1;
        }
 
        if (cm->retries == cm->hca->ib_trans.retries) {
                dapl_log(DAPL_DBG_TYPE_ERR, 
-                        " CM_REPLY: RETRIES EXHAUSTED"
-                        " 0x%x %d 0x%x -> 0x%x %d 0x%x\n",
+                       " CM_REPLY: RETRIES EXHAUSTED (lid port qpn)"
+                        " %x %x %x -> %x %x %x\n",
                         htons(cm->msg.saddr.ib.lid), 
                         htons(cm->msg.sport), 
                         htonl(cm->msg.saddr.ib.qpn), 
@@ -1375,6 +1421,7 @@ dapli_accept_usr(DAPL_EP *ep, DAPL_CR *cr, DAT_COUNT p_size, DAT_PVOID p_data)
                dapl_os_unlock(&cm->lock);
                return DAT_INVALID_STATE;
        }
+       dapl_os_unlock(&cm->lock);
 
        dapl_dbg_log(DAPL_DBG_TYPE_CM,
                     " ACCEPT_USR: remote lid=%x"
@@ -1401,6 +1448,7 @@ dapli_accept_usr(DAPL_EP *ep, DAPL_CR *cr, DAT_COUNT p_size, DAT_PVOID p_data)
 #endif
 
        /* modify QP to RTR and then to RTS with remote info already read */
+       dapl_os_lock(&ep->header.lock);
        if (dapls_modify_qp_state(ep->qp_handle,
                                  IBV_QPS_RTR, 
                                  cm->msg.daddr.ib.qpn,
@@ -1410,7 +1458,7 @@ dapli_accept_usr(DAPL_EP *ep, DAPL_CR *cr, DAT_COUNT p_size, DAT_PVOID p_data)
                         " ACCEPT_USR: QPS_RTR ERR %s -> lid %x qpn %x\n",
                         strerror(errno), ntohs(cm->msg.daddr.ib.lid),
                         ntohl(cm->msg.daddr.ib.qpn));
-               dapl_os_unlock(&cm->lock);
+               dapl_os_unlock(&ep->header.lock);
                goto bail;
        }
        if (dapls_modify_qp_state(ep->qp_handle,
@@ -1422,9 +1470,10 @@ dapli_accept_usr(DAPL_EP *ep, DAPL_CR *cr, DAT_COUNT p_size, DAT_PVOID p_data)
                         " ACCEPT_USR: QPS_RTS ERR %s -> lid %x qpn %x\n",
                         strerror(errno), ntohs(cm->msg.daddr.ib.lid),
                         ntohl(cm->msg.daddr.ib.qpn));
-               dapl_os_unlock(&cm->lock);
+               dapl_os_unlock(&ep->header.lock);
                goto bail;
        }
+       dapl_os_unlock(&ep->header.lock);
 
        /* save remote address information */
        dapl_os_memcpy(&ep->remote_ia_address,
@@ -1449,12 +1498,14 @@ dapli_accept_usr(DAPL_EP *ep, DAPL_CR *cr, DAT_COUNT p_size, DAT_PVOID p_data)
        dapl_ep_link_cm(ep, cm);
        cm->ep = ep;
        cm->hca = ia->hca_ptr;
-       cm->state = DCM_RTU_PENDING;
+       
+       dapl_os_lock(&cm->lock);
        dapl_os_get_time(&cm->timer); /* RTU expected */
+       cm->state = DCM_RTU_PENDING;
        dapl_os_unlock(&cm->lock);
 
        if (ucm_reply(cm)) {
-               dapl_ep_link_cm(ep, cm);
+               dapl_ep_unlink_cm(ep, cm);
                goto bail;
        }
        dapl_dbg_log(DAPL_DBG_TYPE_CM, " PASSIVE: accepted!\n");
@@ -1540,15 +1591,29 @@ dapls_ib_disconnect(IN DAPL_EP *ep_ptr, IN DAT_CLOSE_FLAGS close_flags)
 {
        dp_ib_cm_handle_t cm_ptr = dapl_get_cm_from_ep(ep_ptr);
 
+       dapl_os_lock(&ep_ptr->header.lock);
        if (ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED ||
-               ep_ptr->param.ep_attr.service_type != DAT_SERVICE_TYPE_RC) {
+           ep_ptr->param.ep_attr.service_type != DAT_SERVICE_TYPE_RC ||
+           cm_ptr == NULL) {
+               dapl_os_unlock(&ep_ptr->header.lock);
                return DAT_SUCCESS;
        } 
+       dapl_os_unlock(&ep_ptr->header.lock);
        
-       /* RC. Transition to error state to flush queue */
-        dapls_modify_qp_state(ep_ptr->qp_handle, IBV_QPS_ERR, 0, 0, 0);
+       dapli_cm_disconnect(cm_ptr);
+
+        /* ABRUPT close, wait for callback and DISCONNECTED state */
+        if (close_flags == DAT_CLOSE_ABRUPT_FLAG) {
+                dapl_os_lock(&ep_ptr->header.lock);
+                while (ep_ptr->param.ep_state != DAT_EP_STATE_DISCONNECTED) {
+                        dapl_os_unlock(&ep_ptr->header.lock);
+                        dapl_os_sleep_usec(10000);
+                        dapl_os_lock(&ep_ptr->header.lock);
+                }
+                dapl_os_unlock(&ep_ptr->header.lock);
+        }
 
-       return (dapli_cm_disconnect(cm_ptr));
+       return DAT_SUCCESS;
 }
 
 /*
@@ -1575,7 +1640,19 @@ dapls_ib_disconnect_clean(IN DAPL_EP *ep,
                          IN DAT_BOOLEAN active,
                          IN const ib_cm_events_t ib_cm_event)
 {
-       /* nothing to cleanup */
+       if (ib_cm_event == IB_CME_TIMEOUT) {
+               dp_ib_cm_handle_t cm_ptr;
+
+               if ((cm_ptr = dapl_get_cm_from_ep(ep)) == NULL)
+                       return;
+
+               dapl_log(DAPL_DBG_TYPE_WARN,
+                       "dapls_ib_disc_clean: CONN_TIMEOUT ep %p cm %p %s\n",
+                       ep, cm_ptr, dapl_cm_state_str(cm_ptr->state));
+               
+               /* schedule release of socket and local resources */
+               dapli_cm_free(cm_ptr);
+       }
 }
 
 /*
@@ -1606,13 +1683,13 @@ dapls_ib_setup_conn_listener(IN DAPL_IA *ia,
        ib_cm_srvc_handle_t cm = NULL;
 
        dapl_dbg_log(DAPL_DBG_TYPE_EP,
-                    " listen(ia %p ServiceID %d sp %p)\n",
+                    " listen(ia %p ServiceID %x sp %p)\n",
                     ia, sid, sp);
 
        /* reserve local port, then allocate CM object */
        if (!ucm_get_port(&ia->hca_ptr->ib_trans, (uint16_t)sid)) {
                dapl_dbg_log(DAPL_DBG_TYPE_WARN,
-                            " listen: ERROR %s on conn_qual 0x%x\n",
+                            " listen: ERROR %s on conn_qual %x\n",
                             strerror(errno), sid);
                return DAT_CONN_QUAL_IN_USE;
        }
@@ -1667,11 +1744,12 @@ dapls_ib_remove_conn_listener(IN DAPL_IA *ia, IN DAPL_SP *sp)
        /* free cm_srvc_handle and port, and mark CM for cleanup */
        if (cm) {
                dapl_dbg_log(DAPL_DBG_TYPE_EP,
-                    " remove_listener(ia %p sp %p cm %p psp=%d)\n",
+                    " remove_listener(ia %p sp %p cm %p psp=%x)\n",
                     ia, sp, cm, ntohs(cm->msg.dport));
 
                sp->cm_srvc_handle = NULL;
                dapli_dequeue_listen(cm);  
+               ucm_free_port(&cm->hca->ib_trans, ntohs(cm->msg.sport));
                dapls_cm_release(cm);  /* last ref, dealloc */
        }
        return DAT_SUCCESS;
@@ -1751,6 +1829,17 @@ dapls_ib_reject_connection(IN dp_ib_cm_handle_t cm,
 
        /* cr_thread will destroy CR, update saddr lid, gid, qp_type info */
        dapl_os_lock(&cm->lock);
+       dapl_log(DAPL_DBG_TYPE_CM, 
+                " PASSIVE: REJECTING CM_REQ:"
+                " cm %p op %s, st %s slid %x iqp %x port %x ->"
+                " dlid %x iqp %x port %x\n", cm,
+                dapl_cm_op_str(ntohs(cm->msg.op)), 
+                dapl_cm_state_str(cm->state), 
+                ntohs(cm->hca->ib_trans.addr.ib.lid), 
+                ntohl(cm->msg.saddr.ib.qpn), 
+                ntohs(cm->msg.sport), ntohs(cm->msg.daddr.ib.lid), 
+                ntohl(cm->msg.daddr.ib.qpn), ntohs(cm->msg.dport));
+
        cm->state = DCM_REJECTED;
        cm->msg.saddr.ib.lid = cm->hca->ib_trans.addr.ib.lid; 
        cm->msg.saddr.ib.qp_type = cm->msg.daddr.ib.qp_type;
@@ -1984,6 +2073,7 @@ out:
 #endif
 
 #ifdef DAPL_COUNTERS
+static char _ctr_host_[128];
 /* Debug aid: List all Connections in process and state */
 void dapls_print_cm_list(IN DAPL_IA *ia_ptr)
 {
@@ -2003,13 +2093,16 @@ void dapls_print_cm_list(IN DAPL_IA *ia_ptr)
        else
                next_cm = NULL;
 
-        printf("\n DAPL IA LISTEN/CONNECTIONS IN PROCESS:\n");
+       gethostname(_ctr_host_, sizeof(_ctr_host_));
+       printf("\n [%s:%x] DAPL IA LISTEN/CONNECTIONS IN PROCESS:\n", 
+               _ctr_host_ , dapl_os_getpid());
+
        while (next_cm) {
                cm = next_cm;
                next_cm = dapl_llist_next_entry((DAPL_LLIST_HEAD*)list,
                                                (DAPL_LLIST_ENTRY*)&cm->local_entry);
 
-               printf( "  LISTEN[%d]: sp %p %s uCM_QP: 0x%x %d 0x%x l_pid %x,%d\n",
+               printf( "  LISTEN[%d]: sp %p %s uCM_QP: %x %x %x l_pid %x (%x)\n",
                        i, cm->sp, dapl_cm_state_str(cm->state),
                        ntohs(cm->msg.saddr.ib.lid), ntohs(cm->msg.sport),
                        ntohl(cm->msg.sqpn), ntohl(*(DAT_UINT32*)cm->msg.resv), 
@@ -2034,7 +2127,7 @@ void dapls_print_cm_list(IN DAPL_IA *ia_ptr)
                                                (DAPL_LLIST_ENTRY*)&cm->local_entry);
 
                printf( "  CONN[%d]: ep %p cm %p %s %s"
-                       "  %x %x %x %s %x %x %x r_pid %x,%d\n",
+                       "  %x %x %x %s %x %x %x r_pid %x (%x)\n",
                        i, cm->ep, cm,
                        cm->msg.saddr.ib.qp_type == IBV_QPT_RC ? "RC" : "UD",
                        dapl_cm_state_str(cm->state),
index de17f040203506af7aae1e05daebc141439ea926..25ce963e4df45d51a399685ccf6e578752155636 100644 (file)
@@ -114,6 +114,9 @@ typedef struct _ib_hca_transport
        struct ibv_ah           **ah;  
        DAPL_OS_LOCK            plock;
        uint8_t                 *sid;  /* Sevice IDs, port space, bitarray? */
+       uint8_t                 sl;
+       uint16_t                pkey;
+       int                     pkey_idx;
 
 } ib_hca_transport_t;
 
index 1f324b352deeaeea560a5d5b9a94b6a3fe29cf0d..1959c767896f43a65e0afb9af06a0eda4a8c73fc 100644 (file)
@@ -37,17 +37,16 @@ static void ucm_service_destroy(IN DAPL_HCA *hca);
 static int  ucm_service_create(IN DAPL_HCA *hca);
 
 #if defined (_WIN32)
-#include "..\..\..\..\..\etc\user\comp_channel.cpp"
 #include <rdma\winverbs.h>
 
 static int32_t create_os_signal(IN DAPL_HCA * hca_ptr)
 {
-       return CompSetInit(&hca_ptr->ib_trans.signal.set);\r
+       return CompSetInit(&hca_ptr->ib_trans.signal.set);
 }
 
 static void destroy_os_signal(IN DAPL_HCA * hca_ptr)
 {
-       CompSetCleanup(&hca_ptr->ib_trans.signal.set);\r
+       CompSetCleanup(&hca_ptr->ib_trans.signal.set);
 }
 
 static int dapls_config_verbs(struct ibv_context *verbs)
index 849f4fe73adc8bc20b0202574326f569b0d17af0..f1d50164a9cc50ee58a2b523eff6204a64e5a440 100644 (file)
@@ -128,32 +128,6 @@ dapli_lmr_create_virtual(IN DAPL_IA * ia,
                goto bail;
        }
 
-       /* if the LMR context is already in the hash table */
-       dat_status = dapls_hash_search(ia->hca_ptr->lmr_hash_table,
-                                      lmr->param.lmr_context, NULL);
-       if (dat_status == DAT_SUCCESS) {
-               (void)dapls_ib_mr_deregister(lmr);
-               dapl_lmr_dealloc(lmr);
-
-               dat_status =
-                   DAT_ERROR(DAT_INVALID_STATE, DAT_INVALID_STATE_LMR_IN_USE);
-               goto bail;
-       }
-
-       dat_status = dapls_hash_insert(ia->hca_ptr->lmr_hash_table,
-                                      lmr->param.lmr_context, lmr);
-       if (dat_status != DAT_SUCCESS) {
-               (void)dapls_ib_mr_deregister(lmr);
-               dapl_lmr_dealloc(lmr);
-
-               /* The value returned by dapls_hash_insert(.) is not    */
-               /* returned to the consumer because the spec. requires */
-               /* that dat_lmr_create(.) return only certain values.  */
-               dat_status =
-                   DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY);
-               goto bail;
-       }
-
        dapl_os_atomic_inc(&pz->pz_ref_count);
        *lmr_handle = (DAT_LMR_HANDLE) lmr;
 
@@ -189,7 +163,6 @@ dapli_lmr_create_lmr(IN DAPL_IA * ia,
        DAPL_LMR *lmr;
        DAT_REGION_DESCRIPTION reg_desc;
        DAT_RETURN dat_status;
-       DAPL_HASH_DATA hash_lmr;
 
        dapl_dbg_log(DAPL_DBG_TYPE_API,
                     "dapl_lmr_create_lmr (%p, %p, %p, %x, %x, %p, %p, %p, %p)\n",
@@ -199,14 +172,6 @@ dapli_lmr_create_lmr(IN DAPL_IA * ia,
                     lmr_handle,
                     lmr_context, registered_length, registered_address);
 
-       dat_status = dapls_hash_search(ia->hca_ptr->lmr_hash_table,
-                                      original_lmr->param.lmr_context,
-                                      &hash_lmr);
-       if (dat_status != DAT_SUCCESS) {
-               dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2);
-               goto bail;
-       }
-       lmr = (DAPL_LMR *) hash_lmr;
        reg_desc.for_lmr_handle = (DAT_LMR_HANDLE) original_lmr;
 
        lmr = dapl_lmr_alloc(ia,
@@ -228,32 +193,6 @@ dapli_lmr_create_lmr(IN DAPL_IA * ia,
                goto bail;
        }
 
-       /* if the LMR context is already in the hash table */
-       dat_status = dapls_hash_search(ia->hca_ptr->lmr_hash_table,
-                                      lmr->param.lmr_context, NULL);
-       if (dat_status == DAT_SUCCESS) {
-               dapls_ib_mr_deregister(lmr);
-               dapl_lmr_dealloc(lmr);
-
-               dat_status =
-                   DAT_ERROR(DAT_INVALID_STATE, DAT_INVALID_STATE_LMR_IN_USE);
-               goto bail;
-       }
-
-       dat_status = dapls_hash_insert(ia->hca_ptr->lmr_hash_table,
-                                      lmr->param.lmr_context, lmr);
-       if (dat_status != DAT_SUCCESS) {
-               dapls_ib_mr_deregister(lmr);
-               dapl_lmr_dealloc(lmr);
-
-               /* The value returned by dapls_hash_insert(.) is not    */
-               /* returned to the consumer because the spec. requires */
-               /* that dat_lmr_create(.) return only certain values.  */
-               dat_status =
-                   DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY);
-               goto bail;
-       }
-
        dapl_os_atomic_inc(&pz->pz_ref_count);
        *lmr_handle = (DAT_LMR_HANDLE) lmr;
 
@@ -328,32 +267,6 @@ dapli_lmr_create_shared(IN DAPL_IA * ia,
                goto bail;
        }
 
-       /* if the LMR context is already in the hash table */
-       dat_status = dapls_hash_search(ia->hca_ptr->lmr_hash_table,
-                                      lmr->param.lmr_context, NULL);
-       if (DAT_SUCCESS == dat_status) {
-               (void)dapls_ib_mr_deregister(lmr);
-               dapl_lmr_dealloc(lmr);
-
-               dat_status =
-                   DAT_ERROR(DAT_INVALID_STATE, DAT_INVALID_STATE_LMR_IN_USE);
-               goto bail;
-       }
-
-       dat_status = dapls_hash_insert(ia->hca_ptr->lmr_hash_table,
-                                      lmr->param.lmr_context, lmr);
-       if (dat_status != DAT_SUCCESS) {
-               (void)dapls_ib_mr_deregister(lmr);
-               dapl_lmr_dealloc(lmr);
-
-               /* The value returned by dapls_hash_insert(.) is not    */
-               /* returned to the consumer because the spec. requires */
-               /* that dat_lmr_create(.) return only certain values.  */
-               dat_status =
-                   DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY);
-               goto bail;
-       }
-
        dapl_os_atomic_inc(&pz->pz_ref_count);
        *lmr_handle = (DAT_LMR_HANDLE) lmr;
 
index 6dee66834d6427473a1cbd3c7d44f0f61ddfb841..e64ec814b4545e01d60bb1bd94408169a51c3d61 100644 (file)
@@ -45,18 +45,64 @@ entry is termed Static Registration.
         - ia params, IA specific parameters - device name and port
         - platform params, (not used) 
 .PP
-.SH Example netdev entries for OpenFabrics rdma_cm providers, both v1.2 and v2.0 
+.SH OpenFabrics RDMA providers: 
 \br 
+    Provider options for both 1.2 and 2.0, each using different CM services
+
+        1. cma - OpenFabrics rdma_cm    - uses rdma_cm services for connections
+                                        - requires IPoIB and SA/SM services for IB
+                                        - netdev used for device name, without port designation (ia_params) 
+                                        - Supports any transport rdma_cm supports including IB, iWARP, RoCEE
+                                        - libdaplcma.so (1.2), libdaplofa (2.0)
+
+        2. scm - uDAPL socket based CM  - exchanges CM information over sockets 
+                                        - eliminates the need for rdma_cm, IPoIB, and SA for IB
+                                        - verbs device used for device name with port designation (ia_param)
+                                        - Supports IB, RoCEE. Doesn't support iWARP
+                                        - libdaplscm.so (1.2), libdaploscm (2.0)
+
+        3. ucm - uDAPL unreliable IB CM - exchanges CM information via IB UD QP's
+                                        - eliminates the need for sockets or rdma_cm
+                                        - verbs device used for device name with port designation (ia_param)
+                                        - Supports IB only, no name service. 
+                                        - libdaplucm.so (1.2), libdaploucm (2.0)
+.PP
+.SH Example entries for each OpenFabrics provider 
+\br 
+
+        1. cma - OpenFarbrics rdma_cm (v1.2 and v2.0 examples)
+
         OpenIB-cma u1.2 nonthreadsafe default libdaplcma.so.1 dapl.1.2 "ib0 0" ""
         ofa-v2-ib0 u2.0 nonthreadsafe default libdaplofa.so.2 dapl.2.0 "ib0 0" ""
+        ofa-v2-iwarp u2.0 nonthreadsafe default libdaplofa.so.2 dapl.2.0 "eth2 0" ""
+        ofa-v2-cma-roe-eth2 u2.0 nonthreadsafe default libdaplofa.so.2 dapl.2.0 "eth2 0" ""
+        ofa-v2-cma-roe-eth3 u2.0 nonthreadsafe default libdaplofa.so.2 dapl.2.0 "eth3 0" ""
 
-        NOTE: The OpenFabrics providers use <ia_params> to specify the device with one of the following:
+        NOTE: The OpenFabrics CMA providers use <ia_params> to specify the device with one of the following:
               network address, network hostname, or netdev name; along with port number.
 
-              The OpenIB- and ofa-v2- IA names are unique mappings. Reserved for OpenFabrics providers. 
+        2. scm - uDAPL socket based CM (v1.2 and v2.0 examples)
+
+        OpenIB-mlx4_0-1 u1.2 nonthreadsafe default libdaplscm.so.1 dapl.1.2 "mlx4_0 1" ""
+        OpenIB-ipath0-1 u1.2 nonthreadsafe default libdaplscm.so.1 dapl.1.2 "ipath0 1" ""
+        ofa-v2-mlx4_0-1 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 "mlx4_0 1" ""
+        ofa-v2-mlx4_0-2 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 "mlx4_0 2" ""
+        ofa-v2-mlx4_1-1 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 "mlx4_1 1" ""
+        ofa-v2-ehca0-1 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 "ehca0 1" ""
+        ofa-v2-scm-roe-mlx4_0-1 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 "mlx4_0 1" ""
+
+        3. ucm - uDAPL unreliable IB CM  (not supported in 1.2, v2.0 examples)
+
+        ofa-v2-mlx4_0-1u u2.0 nonthreadsafe default libdaploucm.so.2 dapl.2.0 "mlx4_0 1" ""
+        ofa-v2-mlx4_0-2u u2.0 nonthreadsafe default libdaploucm.so.2 dapl.2.0 "mlx4_0 2" ""
+        ofa-v2-ipath0-1u u2.0 nonthreadsafe default libdaploucm.so.2 dapl.2.0 "ipath0 1" ""
+        ofa-v2-ehca0-1u u2.0 nonthreadsafe default libdaploucm.so.2 dapl.2.0 "ehca0 1" ""
+
+        Note: OpenIB- and ofa-v2- IA names are unique mappings, reserved for OpenFabrics providers.
+.PP
+The default location for this configuration file is /etc/dat.conf.
 .PP
-The default location for this configuration file is /etc/dat.conf. 
 The file location may be overridden with the environment variable DAT_OVERRIDE=/your_own_directory/your_dat.conf. 
 .PP
-.SH "SEE ALSO"
+.SH "SEE ALSO" rdma_cm verbs socket
 .PP
index de038c5ebb60a27e0ac838b8ed68b768c1a77958..898f9cc4090188f1bfa0f61e9240bb6326b677dc 100644 (file)
@@ -37,7 +37,7 @@
 
 struct started_server
 {
-    char            devicename[80];
+    char            devicename[256];
     struct started_server *next;
 };