[DAPL2] Sync with OFED DAPL 2.0.21 src release
authorstansmith <stansmith@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Fri, 7 Aug 2009 20:16:36 +0000 (20:16 +0000)
committerstansmith <stansmith@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Fri, 7 Aug 2009 20:16:36 +0000 (20:16 +0000)
git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@2337 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

26 files changed:
ulp/dapl2/ChangeLog
ulp/dapl2/Makefile.am
ulp/dapl2/README.windows
ulp/dapl2/configure.in
ulp/dapl2/dapl.spec.in
ulp/dapl2/dapl/common/dapl_adapter_util.h
ulp/dapl2/dapl/common/dapl_evd_dto_callb.c
ulp/dapl2/dapl/common/dapl_evd_util.c
ulp/dapl2/dapl/ibal/dapl_ibal_cq.c
ulp/dapl2/dapl/ibal/dapl_ibal_util.c
ulp/dapl2/dapl/ibal/dapl_ibal_util.h
ulp/dapl2/dapl/include/dapl.h
ulp/dapl2/dapl/openib_cma/dapl_ib_util.h
ulp/dapl2/dapl/openib_cma/device.c
ulp/dapl2/dapl/openib_common/cq.c
ulp/dapl2/dapl/openib_common/dapl_ib_common.h
ulp/dapl2/dapl/openib_common/qp.c
ulp/dapl2/dapl/openib_common/util.c
ulp/dapl2/dapl/openib_scm/cm.c
ulp/dapl2/dapl/openib_scm/dapl_ib_util.h
ulp/dapl2/dapl/openib_scm/device.c
ulp/dapl2/dapl/udapl/dapl_cno_wait.c
ulp/dapl2/dapl/udapl/dapl_evd_set_unwaitable.c
ulp/dapl2/dapl/udapl/dapl_evd_wait.c
ulp/dapl2/dat/include/dat2/dat_platform_specific.h
ulp/dapl2/test/dtest/dtest.c

index f23b9bf..d688fcb 100644 (file)
@@ -1,3 +1,348 @@
+commit ed4999a26043c9c3c73c792b21d24ced1df1553c\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Tue Aug 4 20:49:09 2009 -0700\r
+\r
+    scm: Fix disconnect. QP's need to move to ERROR state in\r
+    order to flush work requests and notify consumer. Moving to\r
+    RESET removed all requests but did not notify consumer.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 512f1d7a480f06a1fa491d21870e560ad111c4d0\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Tue Aug 4 20:48:03 2009 -0700\r
+\r
+    modify dtest.c to cleanup CNO wait code and consolidate into\r
+    collect_event() call. After waking up from CNO wait the\r
+    consumer must check all EVD's. The EVD's under the CNO\r
+    could be dropped if already triggered or could come in any order.\r
+    DT_RetToString changed to DT_RetToStr and DT_EventToSTr\r
+    changed to DT_EventToStr for consistency.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 024e36975d37a1556bf68145e1573f637d269bfc\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Tue Aug 4 20:47:17 2009 -0700\r
+\r
+    CNO events, once triggered will not be returned during the cno wait.\r
+    Check for triggered state before going to sleep in cno_wait. Reset\r
+    triggered EVD reference after reporting.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 6d6c72a49158d10825929111d6b4df1c6d2bb589\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Sun Aug 2 14:21:09 2009 -0700\r
+\r
+    CNO support broken in both CMA and SCM providers.\r
+    \r
+    CQ thread/callback mechanism was removed by mistake. Still\r
+    need indirect DTO callbacks when CNO is attached to EVD's.\r
+    \r
+    Add CQ event channel to cma provider's thread and add\r
+    to select for rdma_cm and async channels.\r
+    \r
+    For scm provider there is not easy way to add this channel\r
+    to the select across sockets on windows. So, for portablity\r
+    reasons 2 thread is started to process the ASYNC and\r
+    CQ channels for events.\r
+    \r
+    Must disable EVD (evd_endabled=FALSE) during destroy\r
+    to prevent EVD events firing for CNOs and re-arming CQ while\r
+    CQ is being destroyed.\r
+    \r
+    Change dtest to check EVD after CNO timesout.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 6fe8bd1d8f44777211e816b72e0b2a6d22900207\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Thu Jul 30 08:02:30 2009 -0700\r
+\r
+    common osd: include winsock2.h for IPv6 definitions.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit bd26383900d18962aeeff54fa59922009091ecfc\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Wed Jul 29 08:02:15 2009 -0700\r
+\r
+    common osd: include w2tcpip.h for sockaddr_in6 definitions.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit f25544f14554200a6714accef5f761b0269b5819\r
+Author: Sean Hefty <sean.hefty@intel.com>\r
+Date:   Mon Jul 27 15:07:33 2009 -0700\r
+\r
+    DAPL introduced the concept of directly waiting on the CQ for\r
+    events by adding a compile time flag and special handling in the common\r
+    code.  Rather than using the compile time flag and modifying the\r
+    common code, let the provider implement the best way to wait for\r
+    CQ events.\r
+    \r
+    This simplifies the code and allows the common openib providers to\r
+    optimize for Linux and Windows platforms independently, rather than\r
+    assuming a specific implementation for signaling events.\r
+    \r
+    Signed-off-by: Sean Hefty <sean.hefty@intel.com>\r
+\r
+commit 1548405a377d2bd17938df69419e9bcf3364d91a\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Thu Jul 16 12:41:22 2009 -0700\r
+\r
+    dapltest: Implement a malloc() threshold for the completion reaping.\r
+    \r
+    change byte vector allocation to stack in functions:\r
+      DT_handle_send_op, DT_handle_rdma_op & DT_handle_recv_op.\r
+    \r
+    When allocation size is under the threshold, use a stack local\r
+    allocation instead of malloc/free.  Move redundant bzero() to\r
+    be called only in the case of using local stack allocation as\r
+    DT_Mdep_malloc() already does a bzero(). Consolidate error handling\r
+    return and free()check to a single point by using goto.\r
+    \r
+    Signed-off-by: Stan Smith <stan.smith@intel.com>\r
+\r
+commit f6311ca7295230bf9efbcddc639fa8e1065b1f3d\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Thu Jul 16 12:32:09 2009 -0700\r
+\r
+    scm: handle connected state when freeing CM objects\r
+    \r
+    The QP could be freed before being disconnected\r
+    so the provider needs process disconnect before freeing\r
+    the CM object. The disconnect clean will finish\r
+    the destroy process during the disc callback.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 4387359106ce398b29847982883016f7fd48b372\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Wed Jul 8 12:49:43 2009 -0700\r
+\r
+    scm, dtest: changes for winof gettimeofday and FD_SETSIZE settings.\r
+    \r
+    scm changes to set FD_SETSIZE with expected value and\r
+    prevent windows override.\r
+    \r
+    dtest: remove gettimeofday implementation for windows\r
+    specific implemenation etc\user\gtod.c\r
+    \r
+    general EOL cleanup\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 3542a83d8a31f5ac68adf3aa44e3ebf1265068df\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Mon Jul 6 09:24:07 2009 -0700\r
+\r
+    scm: set TCP_NODELAY sockopt on the server side for sends.\r
+    \r
+    scm provider sends small messages from both server and client\r
+    sides. Set NODELAY on both sides to avoid send delays either\r
+    way.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 9d591180392856935b9c3befbab2243dd8daf628\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Thu Jul 2 14:16:52 2009 -0700\r
+\r
+    windows: remove obsolete files in dapl/udapl source tree\r
+    \r
+    SOURCES,makefile,udapl.r,udapl_exports.src,udapl_sources.c\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 85c238ee0a41dd0a4a24b3d422f34674b0183161\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Thu Jul 2 14:11:20 2009 -0700\r
+\r
+    dtestcm: add UD type QP option to test\r
+    \r
+    Add -u for UD type QP's during connection setup.\r
+    Will setup UD QPs and provide remote AH\r
+    in connect establishment event. Measures\r
+    setup/exchange rates.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 89a2211526e37b1db58fc0ea663b330bc19125c8\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Thu Jul 2 14:07:36 2009 -0700\r
+\r
+    scm: destroy QP called before disconnect\r
+    \r
+    Handle the case where QP is destroyed before\r
+    disconnect processing. Windows supports\r
+    reinit_qp during a disconnect call by\r
+    destroying the QP and recreating the\r
+    QO instead of state change from reset\r
+    to init. Call disconnect in destroy\r
+    CM code to handle this unexpected state.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 6eb35b7d69a896c256b1031337d3353575cd07b4\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Thu Jul 2 14:03:12 2009 -0700\r
+\r
+    cma: add support for rdma_cm TIME_WAIT event.\r
+    \r
+    Nothing to process, simply ack the event.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit b6c56b3052ecd3e36c32092ee62ff0c724da5ad4\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Wed Jul 1 07:58:32 2009 -0700\r
+\r
+    scm: remove old udapl_scm code replaced by openib_scm.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 5bbae42a56e1cca678d590ac4c841dd61e839d74\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Wed Jul 1 07:53:18 2009 -0700\r
+\r
+    winof: fix build issues after consolidating cma, scm code base.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 6bd1d931c4d0d4cbafac383f225140120aee4c51\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Wed Jul 1 07:51:59 2009 -0700\r
+\r
+    cma: lock held when exiting as a result of a rdma_create_event_channel failure.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit b8a14ff1cc257defa2f74373d143600f5f471823\r
+Author: Sean Hefty <sean.hefty@intel.com>\r
+Date:   Mon Jun 29 12:34:54 2009 -0700\r
+\r
+    windows: all dlist functions have been moved to the header file.\r
+    remove references to dlist.c\r
+    \r
+    Signed-off-by: Sean Hefty <sean.hefty@intel.com>\r
+\r
+commit 1a081a0a467e4773a641e8edc876a7a4d7a30ca8\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Mon Jun 29 12:13:48 2009 -0700\r
+\r
+    dtestcm windows: add build infrastructure for new dtestcm test suite\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit c37d7a25dca97011ea76e2a541f936d10ca658e0\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Mon Jun 29 08:57:46 2009 -0700\r
+\r
+    openib_common: reorganize provider code base to share common mem, cq, qp, dto functions\r
+    \r
+    add new openib_common directory with cq, qp, util, dto, mem function calls\r
+    and definitions. This basically leaves the unique CM and Device definitions\r
+    and functions to the individual providers directory of openib_scm and openib_cma.\r
+    \r
+    modifications to dapl_cr_accept required. ep->cm_handle is allocated\r
+    and managed entirely in provider so dapl common code should not update\r
+    ep_handle->cm_handle from the cr->cm_handle automatically. The provider\r
+    should determine which cm_handle is required for the accept.\r
+    \r
+    openib_cma defines _OPENIB_CMA_ and openib_scm defines _OPENIB_SCM_ for provider\r
+    specific build needs in common code.\r
+\r
+commit 961a4083ffb646c070137abd33e9ba2ea9482685\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Fri Jun 26 14:45:34 2009 -0700\r
+\r
+    scm: fixes and optimizations for connection scaling\r
+    \r
+    Prioritize accepts on listen ports via FD_READ\r
+    process the accepts ahead of other work to avoid\r
+    socket half_connection (SYN_RECV) stalls.\r
+    \r
+    Fix dapl_poll to return DAPL_FD_ERROR on\r
+    all event error types.\r
+    \r
+    Add new state for socket released, but CR\r
+    not yet destroyed. This enables scm to release\r
+    the socket resources immediately after exchanging\r
+    all QP information. Also, add state to str call.\r
+    \r
+    Only add the CR reference to the EP if it is\r
+    RC type. UD has multiple CR's per EP so when\r
+    a UD EP disconnect_clean was called, from a\r
+    timeout, it destroyed the wrong CR.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit a60a9e1fce5588cb23f41391b48acf04edd82499\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Fri Jun 26 14:31:19 2009 -0700\r
+\r
+    scm: double the default fd_set_size\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 17d5e1692db4ae1eb09aa919d5607f22851d7ec5\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Fri Jun 26 14:28:30 2009 -0700\r
+\r
+    scm: EP reference in CR should be cleared during ep_destroy\r
+    \r
+    The EP reference in the CR should be set to null\r
+    during the EP free call to insure no further\r
+    reference back to a mem freed EP.\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit ebb820364cec9d72285c005a0874e7d459a9ff7d\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Fri Jun 26 14:23:35 2009 -0700\r
+\r
+    dtestx: fix conn establishment event checking\r
+    \r
+    not catching error cases on client side\r
+    when checking for event number and UD type\r
+    && should have been ||\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit 747b793898042e3011fbad4b2d1285d2c040cb13\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Fri Jun 26 14:18:37 2009 -0700\r
+\r
+    dtestcm: new test to measure dapl connection rates.\r
+    \r
+    new test suite added to measure connection\r
+    rates of providers. Used to compare cma, scm,\r
+    and other providers under development.\r
+    \r
+    dtestcm USAGE\r
+    \r
+    s: server\r
+    c: connections (default = 1000)\r
+    b: burst rate of conn_reqs (default = 100)\r
+    m: multi-listens (set to burst setting )\r
+    v: verbose\r
+    w: wait on event (default, polling)\r
+    d: delay before accept\r
+    h: hostname/address of server, specified on client\r
+    P: provider name (default = OpenIB-v2-ib0)\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
+commit d58fbc3a870a060ead882e1d15c6d245cdf39096\r
+Author: Arlin Davis <arlin.r.davis@intel.com>\r
+Date:   Fri Jun 19 20:59:16 2009 -0700\r
+\r
+    Release 2.0.20\r
+    \r
+    Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>\r
+\r
 commit beebe0066b47d7bf476925ff280bad2a3db38324\r
 Author: Arlin Davis <arlin.r.davis@intel.com>\r
 Date:   Fri Jun 19 20:52:51 2009 -0700\r
index 15ef52e..b927334 100644 (file)
@@ -419,12 +419,12 @@ install-exec-hook:
                sed -e '/ofa-v2-.* u2/d' < $(DESTDIR)$(sysconfdir)/dat.conf > /tmp/$$$$ofadapl; \\r
                cp /tmp/$$$$ofadapl $(DESTDIR)$(sysconfdir)/dat.conf; \\r
        fi; \\r
+       echo ofa-v2-mlx4_0-1 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"mlx4_0 1" ""' >> $(DESTDIR)$(sysconfdir)/dat.conf; \\r
+       echo ofa-v2-mlx4_0-2 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"mlx4_0 2" ""' >> $(DESTDIR)$(sysconfdir)/dat.conf; \\r
        echo ofa-v2-ib0 u2.0 nonthreadsafe default libdaplofa.so.2 dapl.2.0 '"ib0 0" ""' >> $(DESTDIR)$(sysconfdir)/dat.conf; \\r
        echo ofa-v2-ib1 u2.0 nonthreadsafe default libdaplofa.so.2 dapl.2.0 '"ib1 0" ""' >> $(DESTDIR)$(sysconfdir)/dat.conf; \\r
        echo ofa-v2-mthca0-1 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"mthca0 1" ""' >> $(DESTDIR)$(sysconfdir)/dat.conf; \\r
        echo ofa-v2-mthca0-2 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"mthca0 2" ""' >> $(DESTDIR)$(sysconfdir)/dat.conf; \\r
-       echo ofa-v2-mlx4_0-1 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"mlx4_0 1" ""' >> $(DESTDIR)$(sysconfdir)/dat.conf; \\r
-       echo ofa-v2-mlx4_0-2 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"mlx4_0 2" ""' >> $(DESTDIR)$(sysconfdir)/dat.conf; \\r
        echo ofa-v2-ipath0-1 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"ipath0 1" ""' >> $(DESTDIR)$(sysconfdir)/dat.conf; \\r
        echo ofa-v2-ipath0-2 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"ipath0 2" ""' >> $(DESTDIR)$(sysconfdir)/dat.conf; \\r
        echo ofa-v2-ehca0-2 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"ehca0 1" ""' >> $(DESTDIR)$(sysconfdir)/dat.conf; \\r
index fafdadc..52964dc 100644 (file)
-[10-17-07] Last update.
-
-==========
-BUILD:
-==========
-
-The default build includes both debug(checked) & non-debug (free) version of
-dat2d.dll and dapl2d.dll uDAPL provider, free versions are dat2.dll & dapl2.dll.
-Included in the build are test suites dtest (simple DAT example), dtestx
-(DAT IB extensions test) and the main DAT/uDAPL tester dapl2test (see dt-svr &
-dt-cli, see manual.htm for details).
-Additionally, DAT v1.1 and/or DAT v2.0 build environments can be installed; see
-manual.htm for details.
-
-Building a free/non-debug version:
-----------------------------------
-Requires Windows Server 2003 DDK & Platform SDK.
-From a DDK command window (free build) for a specific architecture
-(x86, x64, ia64);
-
-cd gen1\trunk\ulp\dapl2
-build -wg
-Binaries are located in gen1\bin\{kernel|user}\os-arch-folder\...
-
-Building debug version:
------------------------
-Same as above except the DDK command window is for a Checked build
-
-
-Installing:
------------
-
-dat2.dll & dapl.dll --> %SystemRoot%
-
-===================
-CONFIGURATION:
-===================
-
-sample C:\dat\dat.conf 
-
-#
-# DAT 1.2 configuration file,
-#
-# Each entry should have the following fields:
-#
-# <ia_name> <api_version> <threadsafety> <default> <lib_path> \
-#           <provider_version> <ia_params> <platform_params>
-#
-# For openib-cma provider you can specify <ia_params> as either:
-#      network address, network hostname, or netdev name and 0 for port
-#
-#
-ibnic0v2 u2.0 nonthreadsafe default C:\Windows\dapl2.dll ri.2.0 "IbalHca0 1" ""
-
-
-=============================
-Bugs/Known issues
-=============================
-
-
-
-=============================
-4.0 SAMPLE uDAPL APPLICATION:
-=============================
-
-There are 2 sample programs provided with this package.
-
-(dapl2/test/dtest/)
-(dapl2/test/dtestx/)
-
-NAME
-      dtest - simple uDAPL send/receive and RDMA test
-
-SYNOPSIS
-      dtest [-P provider] [-b buf size] [-B burst count][-v] [-c] [-p] [-d] [-s]
-
-      dtest [-P provider] [-b buf size] [-B burst count][-v] [-c] [-p] [-d] [-h HOSTNAME]
-
-DESCRIPTION
-      dtest  is a simple test used to exercise and verify the uDAPL interfaces.
-      At least two instantiations of the test must be run. One acts as the
-      server and the other the client. The server side of the test listens for
-      connection requests, until timing out or killed. Upon receipt of a cd
-      connection request, the connection is established, the server and client
-      sides exchange information necessary to perform RDMA writes and reads.
-
-OPTIONS
-       -P=PROVIDER
-          use PROVIDER to specify uDAPL interface using C:\DAT\dat.conf
-          (default ibnic0v2)
-
-       -b=BUFFER_SIZE
-          use buffer size BUFFER_SIZE for RDMA(default 64)
-
-       -B=BURST_COUNT
-          use busrt count BURST_COUNT for interations (default 10)
-
-       -v, verbose output(default off)
-
-       -c, use consumer notification events (default off)
-
-       -p, use polling (default wait for event)
-
-       -d, delay in seconds before close (default off)
-
-       -s, run as server (default - run as server)
-
-       -h=HOSTNAME
-          use HOSTNAME to specify server hostname or IP address (default - none)
-
-EXAMPLES
-       dtest -v -s
-           Starts a server process with debug verbosity using provider ibnic0v2
-
-       dtest -h server1-ib0
-
-           Starts a client process, using ibnic0v2 provider to connect to
-           hostname server1-ib0.
-
-SEE ALSO
-       dapltest(1)
-
-AUTHORS
-       Arlin Davis
-              <ardavis@ichips.intel.com>
-
-BUGS
-
-/dapl/test/dapltest/
-
-NAME
-        dapltest - test for the Direct Access Programming Library (DAPL)
-
-DESCRIPTION
-       Dapltest  is  a  set  of tests developed to exercise, characterize, and
-       verify the DAPL interfaces during development and porting. At least two
-       instantiations of the test must be run. One acts as the server, fielding
-       requests and spawning server-side test threads as needed. Other client(s)
-       connect to the server and issue test requests. The server side of the
-       test, once  invoked, listens  continuously for client connection requests
-       until stopped or killed. Upon receipt of a connection request, the
-       connection is established, the server and client sides swap version
-       numbers to  verify that they are able to communicate, and the client
-       sends the test request to the server. If the version numbers match, and
-       the test request is well-formed, the server spawns  the  threads
-       needed to run the test before awaiting further connections.
-
-USAGE
-       See manual.htm and or dt-svr.bat & dt-cli.bat.
-
-EXAMPLES
-       dapltest -T S -d -D ibnic0v2
-
-           Starts a server process with debug verbosity.
-
-       dapltest -T T -d -s host1-ib0 -D ibnic0v2 -i 100 client SR 4096 2 \
-           server SR 4096 2
-
-           Runs a transaction test, with both sides sending one buffer with
-           two 4KB segments, one hundred times.
-
-       dapltest -T P -d -s host1-ib0 -D ibnic0v2 -i 100 SR 4096 2
-
-           Runs a performance test, with the client sending one buffer with
-           two 4KB segments, one hundred times.
-
-       dapltest -T Q -s host1-ib0 -D ibnic0v2
-
-           Asks the server to clean up and exit.
-
-       dapltest -T L -D ibnic0v2 -d -w 16 -m 1000
-
-           Runs all of the limit tests, setting up 16 complete sets of DAPL
-           objects, and creating at most a thousand instances when trying to
-           exhaust resources.
-
-       dapltest -T T -V -d -t 2 -w 4 -i 55555 -s linux3 -D ibnic0v2 \
-           client RW 4096 1 server RW  2048  4 client SR 1024 4 server SR 4096 \
-           2 client SR 1024 3 -f server SR 2048 1 -f
-
-           Runs a more complicated transaction test, with two thread using four
-           EPs each, sending a more complicated buffer pattern for a larger
-           number of iterations, validating the data received.
-
-       BUGS   (and To Do List)
-
-           Use of CNOs (-Q) is not yet supported.
-
-           Further limit tests could be added.
-
+[10-17-07] Last update.\r
+\r
+==========\r
+BUILD:\r
+==========\r
+\r
+The default build includes both debug(checked) & non-debug (free) version of\r
+dat2d.dll and dapl2d.dll uDAPL provider, free versions are dat2.dll & dapl2.dll.\r
+Included in the build are test suites dtest (simple DAT example), dtestx\r
+(DAT IB extensions test) and the main DAT/uDAPL tester dapl2test (see dt-svr &\r
+dt-cli, see manual.htm for details).\r
+Additionally, DAT v1.1 and/or DAT v2.0 build environments can be installed; see\r
+manual.htm for details.\r
+\r
+Building a free/non-debug version:\r
+----------------------------------\r
+Requires Windows Server 2003 DDK & Platform SDK.\r
+From a DDK command window (free build) for a specific architecture\r
+(x86, x64, ia64);\r
+\r
+cd gen1\trunk\ulp\dapl2\r
+build -wg\r
+Binaries are located in gen1\bin\{kernel|user}\os-arch-folder\...\r
+\r
+Building debug version:\r
+-----------------------\r
+Same as above except the DDK command window is for a Checked build\r
+\r
+\r
+Installing:\r
+-----------\r
+\r
+dat2.dll & dapl.dll --> %SystemRoot%\r
+\r
+===================\r
+CONFIGURATION:\r
+===================\r
+\r
+sample C:\dat\dat.conf \r
+\r
+#\r
+# DAT 1.2 configuration file,\r
+#\r
+# Each entry should have the following fields:\r
+#\r
+# <ia_name> <api_version> <threadsafety> <default> <lib_path> \\r
+#           <provider_version> <ia_params> <platform_params>\r
+#\r
+# For openib-cma provider you can specify <ia_params> as either:\r
+#      network address, network hostname, or netdev name and 0 for port\r
+#\r
+#\r
+ibnic0v2 u2.0 nonthreadsafe default C:\Windows\dapl2.dll ri.2.0 "IbalHca0 1" ""\r
+\r
+\r
+=============================\r
+Bugs/Known issues\r
+=============================\r
+\r
+\r
+\r
+=============================\r
+4.0 SAMPLE uDAPL APPLICATION:\r
+=============================\r
+\r
+There are 2 sample programs provided with this package.\r
+\r
+(dapl2/test/dtest/)\r
+(dapl2/test/dtestx/)\r
+\r
+NAME\r
+      dtest - simple uDAPL send/receive and RDMA test\r
+\r
+SYNOPSIS\r
+      dtest [-P provider] [-b buf size] [-B burst count][-v] [-c] [-p] [-d] [-s]\r
+\r
+      dtest [-P provider] [-b buf size] [-B burst count][-v] [-c] [-p] [-d] [-h HOSTNAME]\r
+\r
+DESCRIPTION\r
+      dtest  is a simple test used to exercise and verify the uDAPL interfaces.\r
+      At least two instantiations of the test must be run. One acts as the\r
+      server and the other the client. The server side of the test listens for\r
+      connection requests, until timing out or killed. Upon receipt of a cd\r
+      connection request, the connection is established, the server and client\r
+      sides exchange information necessary to perform RDMA writes and reads.\r
+\r
+OPTIONS\r
+       -P=PROVIDER\r
+          use PROVIDER to specify uDAPL interface using C:\DAT\dat.conf\r
+          (default ibnic0v2)\r
+\r
+       -b=BUFFER_SIZE\r
+          use buffer size BUFFER_SIZE for RDMA(default 64)\r
+\r
+       -B=BURST_COUNT\r
+          use busrt count BURST_COUNT for interations (default 10)\r
+\r
+       -v, verbose output(default off)\r
+\r
+       -c, use consumer notification events (default off)\r
+\r
+       -p, use polling (default wait for event)\r
+\r
+       -d, delay in seconds before close (default off)\r
+\r
+       -s, run as server (default - run as server)\r
+\r
+       -h=HOSTNAME\r
+          use HOSTNAME to specify server hostname or IP address (default - none)\r
+\r
+EXAMPLES\r
+       dtest -v -s\r
+           Starts a server process with debug verbosity using provider ibnic0v2\r
+\r
+       dtest -h server1-ib0\r
+\r
+           Starts a client process, using ibnic0v2 provider to connect to\r
+           hostname server1-ib0.\r
+\r
+SEE ALSO\r
+       dapltest(1)\r
+\r
+AUTHORS\r
+       Arlin Davis\r
+              <ardavis@ichips.intel.com>\r
+\r
+BUGS\r
+\r
+/dapl/test/dapltest/\r
+\r
+NAME\r
+        dapltest - test for the Direct Access Programming Library (DAPL)\r
+\r
+DESCRIPTION\r
+       Dapltest  is  a  set  of tests developed to exercise, characterize, and\r
+       verify the DAPL interfaces during development and porting. At least two\r
+       instantiations of the test must be run. One acts as the server, fielding\r
+       requests and spawning server-side test threads as needed. Other client(s)\r
+       connect to the server and issue test requests. The server side of the\r
+       test, once  invoked, listens  continuously for client connection requests\r
+       until stopped or killed. Upon receipt of a connection request, the\r
+       connection is established, the server and client sides swap version\r
+       numbers to  verify that they are able to communicate, and the client\r
+       sends the test request to the server. If the version numbers match, and\r
+       the test request is well-formed, the server spawns  the  threads\r
+       needed to run the test before awaiting further connections.\r
+\r
+USAGE\r
+       See manual.htm and or dt-svr.bat & dt-cli.bat.\r
+\r
+EXAMPLES\r
+       dapltest -T S -d -D ibnic0v2\r
+\r
+           Starts a server process with debug verbosity.\r
+\r
+       dapltest -T T -d -s host1-ib0 -D ibnic0v2 -i 100 client SR 4096 2 \\r
+           server SR 4096 2\r
+\r
+           Runs a transaction test, with both sides sending one buffer with\r
+           two 4KB segments, one hundred times.\r
+\r
+       dapltest -T P -d -s host1-ib0 -D ibnic0v2 -i 100 SR 4096 2\r
+\r
+           Runs a performance test, with the client sending one buffer with\r
+           two 4KB segments, one hundred times.\r
+\r
+       dapltest -T Q -s host1-ib0 -D ibnic0v2\r
+\r
+           Asks the server to clean up and exit.\r
+\r
+       dapltest -T L -D ibnic0v2 -d -w 16 -m 1000\r
+\r
+           Runs all of the limit tests, setting up 16 complete sets of DAPL\r
+           objects, and creating at most a thousand instances when trying to\r
+           exhaust resources.\r
+\r
+       dapltest -T T -V -d -t 2 -w 4 -i 55555 -s linux3 -D ibnic0v2 \\r
+           client RW 4096 1 server RW  2048  4 client SR 1024 4 server SR 4096 \\r
+           2 client SR 1024 3 -f server SR 2048 1 -f\r
+\r
+           Runs a more complicated transaction test, with two thread using four\r
+           EPs each, sending a more complicated buffer pattern for a larger\r
+           number of iterations, validating the data received.\r
+\r
+       BUGS   (and To Do List)\r
+\r
+           Use of CNOs (-Q) is not yet supported.\r
+\r
+           Further limit tests could be added.\r
+\r
index 3283dbc..b4cd2b1 100644 (file)
@@ -1,11 +1,11 @@
 dnl Process this file with autoconf to produce a configure script.\r
 \r
 AC_PREREQ(2.57)\r
-AC_INIT(dapl, 2.0.20, general@lists.openfabrics.org)\r
+AC_INIT(dapl, 2.0.21, general@lists.openfabrics.org)\r
 AC_CONFIG_SRCDIR([dat/udat/udat.c])\r
 AC_CONFIG_AUX_DIR(config)\r
 AM_CONFIG_HEADER(config.h)\r
-AM_INIT_AUTOMAKE(dapl, 2.0.20)\r
+AM_INIT_AUTOMAKE(dapl, 2.0.21)\r
 \r
 AM_PROG_LIBTOOL\r
 \r
index 2b74a22..fb7da53 100644 (file)
@@ -96,12 +96,12 @@ if [ -e %{_sysconfdir}/dat.conf ]; then
     sed -e '/ofa-v2-.* u2/d' < %{_sysconfdir}/dat.conf > /tmp/$$ofadapl\r
     mv /tmp/$$ofadapl %{_sysconfdir}/dat.conf\r
 fi\r
+echo ofa-v2-mlx4_0-1 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"mlx4_0 1" ""' >> %{_sysconfdir}/dat.conf\r
+echo ofa-v2-mlx4_0-2 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"mlx4_0 2" ""' >> %{_sysconfdir}/dat.conf\r
 echo ofa-v2-ib0 u2.0 nonthreadsafe default libdaplofa.so.2 dapl.2.0 '"ib0 0" ""' >> %{_sysconfdir}/dat.conf\r
 echo ofa-v2-ib1 u2.0 nonthreadsafe default libdaplofa.so.2 dapl.2.0 '"ib1 0" ""' >> %{_sysconfdir}/dat.conf\r
 echo ofa-v2-mthca0-1 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"mthca0 1" ""' >> %{_sysconfdir}/dat.conf\r
 echo ofa-v2-mthca0-2 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"mthca0 2" ""' >> %{_sysconfdir}/dat.conf\r
-echo ofa-v2-mlx4_0-1 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"mlx4_0 1" ""' >> %{_sysconfdir}/dat.conf\r
-echo ofa-v2-mlx4_0-2 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"mlx4_0 2" ""' >> %{_sysconfdir}/dat.conf\r
 echo ofa-v2-ipath0-1 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"ipath0 1" ""' >> %{_sysconfdir}/dat.conf\r
 echo ofa-v2-ipath0-2 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"ipath0 2" ""' >> %{_sysconfdir}/dat.conf\r
 echo ofa-v2-ehca0-1 u2.0 nonthreadsafe default libdaploscm.so.2 dapl.2.0 '"ehca0 1" ""' >> %{_sysconfdir}/dat.conf\r
@@ -136,6 +136,9 @@ fi
 %{_mandir}/man5/*.5*\r
 \r
 %changelog\r
+* Wed Aug 5 2009 Arlin Davis <ardavis@ichips.intel.com> - 2.0.21\r
+- DAT/DAPL Version 2.0.21 Release 1, WinOF 2.1, OFED 1.4.1+  \r
+\r
 * Fri Jun 19 2009 Arlin Davis <ardavis@ichips.intel.com> - 2.0.20\r
 - DAT/DAPL Version 2.0.20 Release 1, OFED 1.4.1 + UD reject/scaling fixes \r
 \r
index 1a8b7cc..e408d33 100644 (file)
-/*
- * 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.
- */
-
-/**********************************************************************
- * 
- * HEADER: dapl_adapter_util.h
- *
- * PURPOSE: Utility defs & routines for the adapter data structure
- *
- * $Id: dapl_adapter_util.h 1317 2005-04-25 17:29:42Z jlentini $
- *
- **********************************************************************/
-
-#ifndef _DAPL_ADAPTER_UTIL_H_
-#define _DAPL_ADAPTER_UTIL_H_
-
-
-typedef enum async_handler_type
-{
-    DAPL_ASYNC_UNAFILIATED,
-       DAPL_ASYNC_CQ_ERROR,
-       DAPL_ASYNC_CQ_COMPLETION,
-       DAPL_ASYNC_QP_ERROR
-} DAPL_ASYNC_HANDLER_TYPE;
-
-
-int dapls_ib_init (void);
-
-int dapls_ib_release (void);
-
-DAT_RETURN dapls_ib_enum_hcas (
-        IN   const char                 *vendor, 
-       OUT  DAPL_HCA_NAME              **hca_names,
-       OUT  DAT_COUNT                  *total_hca_count);
-
-DAT_RETURN dapls_ib_get_instance_data(
-       IN  DAPL_HCA_NAME hca_name, 
-       OUT char *instance);
-
-DAT_RETURN dapls_ib_open_hca (
-       IN   char                      *namestr,
-       IN   DAPL_HCA                  *hca_ptr);
-
-DAT_RETURN dapls_ib_close_hca (
-       IN   DAPL_HCA                  *hca_ptr);
-
-DAT_RETURN dapls_ib_qp_alloc (
-       IN  DAPL_IA                     *ia_ptr,
-       IN  DAPL_EP                     *ep_ptr,
-       IN  DAPL_EP                     *ep_ctx_ptr);
-
-DAT_RETURN dapls_ib_qp_free (
-       IN  DAPL_IA                     *ia_ptr,
-       IN  DAPL_EP                     *ep_ptr);
-
-DAT_RETURN dapls_ib_qp_modify (
-       IN  DAPL_IA                     *ia_ptr,
-       IN  DAPL_EP                     *ep_ptr,
-       IN  DAT_EP_ATTR                 *ep_attr);
-
-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);
-
-DAT_RETURN dapls_ib_disconnect (
-       IN  DAPL_EP                     *ep_ptr,
-       IN  DAT_CLOSE_FLAGS             close_flags);
-
-DAT_RETURN dapls_ib_setup_conn_listener (
-       IN  DAPL_IA                     *ia_ptr,
-       IN  DAT_UINT64                  ServiceID,
-       IN  DAPL_SP                     *sp_ptr);
-
-DAT_RETURN dapls_ib_remove_conn_listener (
-       IN  DAPL_IA                     *ia_ptr,
-       IN  DAPL_SP                     *sp_ptr);
-
-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);
-
-DAT_RETURN dapls_ib_reject_connection (
-       IN  dp_ib_cm_handle_t           cm_handle,
-       IN  int                         reject_reason,
-       IN  DAT_COUNT                   private_data_size,
-       IN  const DAT_PVOID             private_data);
-
-DAT_RETURN dapls_ib_setup_async_callback (
-       IN  DAPL_IA                     *ia_ptr,
-       IN  DAPL_ASYNC_HANDLER_TYPE     handler_type,
-       IN  DAPL_EVD                    *evd_ptr,
-       IN  ib_async_handler_t          callback,
-       IN  void                        *context);
-
-DAT_RETURN dapls_ib_cq_alloc (
-       IN  DAPL_IA                     *ia_ptr,
-       IN  DAPL_EVD                    *evd_ptr,
-       IN  DAT_COUNT                   *cqlen);
-
-DAT_RETURN dapls_ib_cq_free (
-       IN  DAPL_IA                     *ia_ptr,
-       IN  DAPL_EVD                    *evd_ptr);
-
-DAT_RETURN dapls_set_cq_notify (
-       IN  DAPL_IA                     *ia_ptr,
-       IN  DAPL_EVD                    *evd_ptr);
-
-DAT_RETURN dapls_ib_cq_resize (
-       IN  DAPL_IA                     *ia_ptr,
-       IN  DAPL_EVD                    *evd_ptr,
-       IN  DAT_COUNT                   *cqlen);
-
-DAT_RETURN dapls_ib_pd_alloc (
-       IN  DAPL_IA                     *ia_ptr,
-       IN  DAPL_PZ                     *pz);
-
-DAT_RETURN dapls_ib_pd_free (
-       IN  DAPL_PZ                     *pz);
-
-DAT_RETURN dapls_ib_mr_register (
-       IN  DAPL_IA                     *ia_ptr,
-        IN  DAPL_LMR                   *lmr,
-       IN  DAT_PVOID                   virt_addr,
-       IN  DAT_VLEN                    length,
-       IN  DAT_MEM_PRIV_FLAGS          privileges,
-       IN  DAT_VA_TYPE                 va_type);
-
-#if defined(__KDAPL__)
-DAT_RETURN dapls_ib_mr_register_physical (
-       IN  DAPL_IA                     *ia_ptr,
-       INOUT  DAPL_LMR                 *lmr,
-       IN  DAT_PADDR                   phys_addr,
-       IN  DAT_VLEN                    length,
-       IN  DAT_MEM_PRIV_FLAGS          privileges);
-#endif /* __KDAPL__ */
-
-DAT_RETURN dapls_ib_mr_deregister (
-       IN  DAPL_LMR                    *lmr);
-
-DAT_RETURN dapls_ib_mr_register_shared (
-       IN  DAPL_IA                     *ia_ptr,
-        IN  DAPL_LMR                   *lmr,
-       IN  DAT_MEM_PRIV_FLAGS          privileges,
-       IN  DAT_VA_TYPE                 va_type);
-
-DAT_RETURN dapls_ib_mw_alloc (
-       IN  DAPL_RMR                    *rmr);
-
-DAT_RETURN dapls_ib_mw_free (
-       IN  DAPL_RMR                    *rmr);
-
-DAT_RETURN dapls_ib_mw_bind (
-       IN  DAPL_RMR                    *rmr,
-       IN  DAPL_LMR                    *lmr,
-       IN  DAPL_EP                     *ep,
-       IN  DAPL_COOKIE                 *cookie,
-       IN  DAT_VADDR                   virtual_address,
-       IN  DAT_VLEN                    length,
-       IN  DAT_MEM_PRIV_FLAGS          mem_priv,
-       IN  DAT_BOOLEAN                 is_signaled);
-
-DAT_RETURN dapls_ib_mw_unbind (
-       IN  DAPL_RMR                    *rmr,
-       IN  DAPL_EP                     *ep,
-       IN  DAPL_COOKIE                 *cookie,
-       IN  DAT_BOOLEAN                 is_signaled);
-
-DAT_RETURN dapls_ib_query_hca (
-       IN  DAPL_HCA                    *hca_ptr,
-       OUT DAT_IA_ATTR                 *ia_attr,
-       OUT DAT_EP_ATTR                 *ep_attr,
-       OUT DAT_SOCK_ADDR6              *ip_addr);
-
-DAT_RETURN dapls_ib_completion_poll (
-       IN  DAPL_HCA                    *hca_ptr,
-       IN  DAPL_EVD                    *evd_ptr,
-       IN  ib_work_completion_t        *cqe_ptr);
-
-DAT_RETURN dapls_ib_completion_notify (
-       IN  ib_hca_handle_t             hca_handle,
-       IN  DAPL_EVD                    *evd_ptr,
-       IN  ib_notification_type_t      type);
-
-DAT_DTO_COMPLETION_STATUS dapls_ib_get_dto_status (
-       IN  ib_work_completion_t        *cqe_ptr);
-
-void dapls_ib_reinit_ep (
-       IN  DAPL_EP                     *ep_ptr);
-
-void dapls_ib_disconnect_clean (
-       IN  DAPL_EP                     *ep_ptr,
-       IN  DAT_BOOLEAN                 passive,
-       IN  const ib_cm_events_t        ib_cm_event);
-
-DAT_RETURN dapls_ib_get_async_event (
-       IN  ib_error_record_t           *cause_ptr,
-       OUT DAT_EVENT_NUMBER            *async_event);
-
-DAT_EVENT_NUMBER dapls_ib_get_dat_event (
-       IN  const ib_cm_events_t        ib_cm_event,
-       IN  DAT_BOOLEAN                 active);
-
-ib_cm_events_t dapls_ib_get_cm_event (
-       IN  DAT_EVENT_NUMBER            dat_event_num);
-
-DAT_RETURN dapls_ib_cm_remote_addr (
-       IN  DAT_HANDLE                  dat_handle,
-       OUT DAT_SOCK_ADDR6              *remote_ia_address);
-
-int dapls_ib_private_data_size (
-       IN  DAPL_PRIVATE                *prd_ptr,
-       IN  DAPL_PDATA_OP               conn_op,
-       IN  DAPL_HCA                    *hca_ptr);
-
-void 
-dapls_query_provider_specific_attr(
-       IN DAPL_IA                      *ia_ptr,
-       IN DAT_PROVIDER_ATTR            *attr_ptr );
-
-#ifdef CQ_WAIT_OBJECT
-DAT_RETURN
-dapls_ib_wait_object_create (
-       IN DAPL_EVD                     *evd_ptr,
-       IN ib_wait_obj_handle_t         *p_cq_wait_obj_handle);
-
-DAT_RETURN
-dapls_ib_wait_object_destroy (
-       IN ib_wait_obj_handle_t         cq_wait_obj_handle);
-
-DAT_RETURN
-dapls_ib_wait_object_wakeup (
-       IN ib_wait_obj_handle_t         cq_wait_obj_handle);
-
-DAT_RETURN
-dapls_ib_wait_object_wait (
-       IN ib_wait_obj_handle_t         cq_wait_obj_handle,
-       IN uint32_t                     timeout);
-#endif
-
-#ifdef DAT_EXTENSIONS
-void
-dapls_cqe_to_event_extension(
-       IN DAPL_EP                      *ep_ptr,
-       IN DAPL_COOKIE                  *cookie,
-       IN ib_work_completion_t         *cqe_ptr,
-       IN DAT_EVENT                    *event_ptr);
-#endif
-
-/*
- * Values for provider DAT_NAMED_ATTR
- */
-#define IB_QP_STATE            1       /* QP state change request */
-
-
-#ifdef IBAPI
-#include "dapl_ibapi_dto.h"
-#elif VAPI
-#include "dapl_vapi_dto.h"
-#elif __OPENIB__
-#include "dapl_openib_dto.h"
-#elif DUMMY
-#include "dapl_dummy_dto.h"
-#elif OPENIB
-#include "dapl_ib_dto.h"
-#else
-#include "dapl_ibal_dto.h"
-#endif
-
-
-#endif /*  _DAPL_ADAPTER_UTIL_H_ */
+/*\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
+ * HEADER: dapl_adapter_util.h\r
+ *\r
+ * PURPOSE: Utility defs & routines for the adapter data structure\r
+ *\r
+ * $Id: dapl_adapter_util.h 1317 2005-04-25 17:29:42Z jlentini $\r
+ *\r
+ **********************************************************************/\r
+\r
+#ifndef _DAPL_ADAPTER_UTIL_H_\r
+#define _DAPL_ADAPTER_UTIL_H_\r
+\r
+\r
+typedef enum async_handler_type\r
+{\r
+    DAPL_ASYNC_UNAFILIATED,\r
+       DAPL_ASYNC_CQ_ERROR,\r
+       DAPL_ASYNC_CQ_COMPLETION,\r
+       DAPL_ASYNC_QP_ERROR\r
+} DAPL_ASYNC_HANDLER_TYPE;\r
+\r
+\r
+int dapls_ib_init (void);\r
+\r
+int dapls_ib_release (void);\r
+\r
+DAT_RETURN dapls_ib_enum_hcas (\r
+        IN   const char                 *vendor, \r
+       OUT  DAPL_HCA_NAME              **hca_names,\r
+       OUT  DAT_COUNT                  *total_hca_count);\r
+\r
+DAT_RETURN dapls_ib_get_instance_data(\r
+       IN  DAPL_HCA_NAME hca_name, \r
+       OUT char *instance);\r
+\r
+DAT_RETURN dapls_ib_open_hca (\r
+       IN   char                      *namestr,\r
+       IN   DAPL_HCA                  *hca_ptr);\r
+\r
+DAT_RETURN dapls_ib_close_hca (\r
+       IN   DAPL_HCA                  *hca_ptr);\r
+\r
+DAT_RETURN 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_RETURN dapls_ib_qp_free (\r
+       IN  DAPL_IA                     *ia_ptr,\r
+       IN  DAPL_EP                     *ep_ptr);\r
+\r
+DAT_RETURN 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
+DAT_RETURN 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
+DAT_RETURN dapls_ib_disconnect (\r
+       IN  DAPL_EP                     *ep_ptr,\r
+       IN  DAT_CLOSE_FLAGS             close_flags);\r
+\r
+DAT_RETURN dapls_ib_setup_conn_listener (\r
+       IN  DAPL_IA                     *ia_ptr,\r
+       IN  DAT_UINT64                  ServiceID,\r
+       IN  DAPL_SP                     *sp_ptr);\r
+\r
+DAT_RETURN dapls_ib_remove_conn_listener (\r
+       IN  DAPL_IA                     *ia_ptr,\r
+       IN  DAPL_SP                     *sp_ptr);\r
+\r
+DAT_RETURN 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
+DAT_RETURN dapls_ib_reject_connection (\r
+       IN  dp_ib_cm_handle_t           cm_handle,\r
+       IN  int                         reject_reason,\r
+       IN  DAT_COUNT                   private_data_size,\r
+       IN  const DAT_PVOID             private_data);\r
+\r
+DAT_RETURN dapls_ib_setup_async_callback (\r
+       IN  DAPL_IA                     *ia_ptr,\r
+       IN  DAPL_ASYNC_HANDLER_TYPE     handler_type,\r
+       IN  DAPL_EVD                    *evd_ptr,\r
+       IN  ib_async_handler_t          callback,\r
+       IN  void                        *context);\r
+\r
+DAT_RETURN dapls_ib_cq_alloc (\r
+       IN  DAPL_IA                     *ia_ptr,\r
+       IN  DAPL_EVD                    *evd_ptr,\r
+       IN  DAT_COUNT                   *cqlen);\r
+\r
+DAT_RETURN dapls_ib_cq_free (\r
+       IN  DAPL_IA                     *ia_ptr,\r
+       IN  DAPL_EVD                    *evd_ptr);\r
+\r
+DAT_RETURN dapls_set_cq_notify (\r
+       IN  DAPL_IA                     *ia_ptr,\r
+       IN  DAPL_EVD                    *evd_ptr);\r
+\r
+DAT_RETURN dapls_ib_cq_resize (\r
+       IN  DAPL_IA                     *ia_ptr,\r
+       IN  DAPL_EVD                    *evd_ptr,\r
+       IN  DAT_COUNT                   *cqlen);\r
+\r
+DAT_RETURN dapls_ib_pd_alloc (\r
+       IN  DAPL_IA                     *ia_ptr,\r
+       IN  DAPL_PZ                     *pz);\r
+\r
+DAT_RETURN dapls_ib_pd_free (\r
+       IN  DAPL_PZ                     *pz);\r
+\r
+DAT_RETURN dapls_ib_mr_register (\r
+       IN  DAPL_IA                     *ia_ptr,\r
+        IN  DAPL_LMR                   *lmr,\r
+       IN  DAT_PVOID                   virt_addr,\r
+       IN  DAT_VLEN                    length,\r
+       IN  DAT_MEM_PRIV_FLAGS          privileges,\r
+       IN  DAT_VA_TYPE                 va_type);\r
+\r
+#if defined(__KDAPL__)\r
+DAT_RETURN dapls_ib_mr_register_physical (\r
+       IN  DAPL_IA                     *ia_ptr,\r
+       INOUT  DAPL_LMR                 *lmr,\r
+       IN  DAT_PADDR                   phys_addr,\r
+       IN  DAT_VLEN                    length,\r
+       IN  DAT_MEM_PRIV_FLAGS          privileges);\r
+#endif /* __KDAPL__ */\r
+\r
+DAT_RETURN dapls_ib_mr_deregister (\r
+       IN  DAPL_LMR                    *lmr);\r
+\r
+DAT_RETURN dapls_ib_mr_register_shared (\r
+       IN  DAPL_IA                     *ia_ptr,\r
+        IN  DAPL_LMR                   *lmr,\r
+       IN  DAT_MEM_PRIV_FLAGS          privileges,\r
+       IN  DAT_VA_TYPE                 va_type);\r
+\r
+DAT_RETURN dapls_ib_mw_alloc (\r
+       IN  DAPL_RMR                    *rmr);\r
+\r
+DAT_RETURN dapls_ib_mw_free (\r
+       IN  DAPL_RMR                    *rmr);\r
+\r
+DAT_RETURN dapls_ib_mw_bind (\r
+       IN  DAPL_RMR                    *rmr,\r
+       IN  DAPL_LMR                    *lmr,\r
+       IN  DAPL_EP                     *ep,\r
+       IN  DAPL_COOKIE                 *cookie,\r
+       IN  DAT_VADDR                   virtual_address,\r
+       IN  DAT_VLEN                    length,\r
+       IN  DAT_MEM_PRIV_FLAGS          mem_priv,\r
+       IN  DAT_BOOLEAN                 is_signaled);\r
+\r
+DAT_RETURN dapls_ib_mw_unbind (\r
+       IN  DAPL_RMR                    *rmr,\r
+       IN  DAPL_EP                     *ep,\r
+       IN  DAPL_COOKIE                 *cookie,\r
+       IN  DAT_BOOLEAN                 is_signaled);\r
+\r
+DAT_RETURN dapls_ib_query_hca (\r
+       IN  DAPL_HCA                    *hca_ptr,\r
+       OUT DAT_IA_ATTR                 *ia_attr,\r
+       OUT DAT_EP_ATTR                 *ep_attr,\r
+       OUT DAT_SOCK_ADDR6              *ip_addr);\r
+\r
+DAT_RETURN dapls_ib_completion_poll (\r
+       IN  DAPL_HCA                    *hca_ptr,\r
+       IN  DAPL_EVD                    *evd_ptr,\r
+       IN  ib_work_completion_t        *cqe_ptr);\r
+\r
+DAT_RETURN dapls_ib_completion_notify (\r
+       IN  ib_hca_handle_t             hca_handle,\r
+       IN  DAPL_EVD                    *evd_ptr,\r
+       IN  ib_notification_type_t      type);\r
+\r
+DAT_DTO_COMPLETION_STATUS dapls_ib_get_dto_status (\r
+       IN  ib_work_completion_t        *cqe_ptr);\r
+\r
+void dapls_ib_reinit_ep (\r
+       IN  DAPL_EP                     *ep_ptr);\r
+\r
+void dapls_ib_disconnect_clean (\r
+       IN  DAPL_EP                     *ep_ptr,\r
+       IN  DAT_BOOLEAN                 passive,\r
+       IN  const ib_cm_events_t        ib_cm_event);\r
+\r
+DAT_RETURN dapls_ib_get_async_event (\r
+       IN  ib_error_record_t           *cause_ptr,\r
+       OUT DAT_EVENT_NUMBER            *async_event);\r
+\r
+DAT_EVENT_NUMBER dapls_ib_get_dat_event (\r
+       IN  const ib_cm_events_t        ib_cm_event,\r
+       IN  DAT_BOOLEAN                 active);\r
+\r
+ib_cm_events_t dapls_ib_get_cm_event (\r
+       IN  DAT_EVENT_NUMBER            dat_event_num);\r
+\r
+DAT_RETURN dapls_ib_cm_remote_addr (\r
+       IN  DAT_HANDLE                  dat_handle,\r
+       OUT DAT_SOCK_ADDR6              *remote_ia_address);\r
+\r
+int dapls_ib_private_data_size (\r
+       IN  DAPL_PRIVATE                *prd_ptr,\r
+       IN  DAPL_PDATA_OP               conn_op,\r
+       IN  DAPL_HCA                    *hca_ptr);\r
+\r
+void \r
+dapls_query_provider_specific_attr(\r
+       IN DAPL_IA                      *ia_ptr,\r
+       IN DAT_PROVIDER_ATTR            *attr_ptr );\r
+\r
+DAT_RETURN\r
+dapls_evd_dto_wakeup (\r
+       IN DAPL_EVD                     *evd_ptr);\r
+\r
+DAT_RETURN\r
+dapls_evd_dto_wait (\r
+       IN DAPL_EVD                     *evd_ptr,\r
+       IN uint32_t                     timeout);\r
+\r
+#ifdef DAT_EXTENSIONS\r
+void\r
+dapls_cqe_to_event_extension(\r
+       IN DAPL_EP                      *ep_ptr,\r
+       IN DAPL_COOKIE                  *cookie,\r
+       IN ib_work_completion_t         *cqe_ptr,\r
+       IN DAT_EVENT                    *event_ptr);\r
+#endif\r
+\r
+/*\r
+ * Values for provider DAT_NAMED_ATTR\r
+ */\r
+#define IB_QP_STATE            1       /* QP state change request */\r
+\r
+\r
+#ifdef IBAPI\r
+#include "dapl_ibapi_dto.h"\r
+#elif VAPI\r
+#include "dapl_vapi_dto.h"\r
+#elif __OPENIB__\r
+#include "dapl_openib_dto.h"\r
+#elif DUMMY\r
+#include "dapl_dummy_dto.h"\r
+#elif OPENIB\r
+#include "dapl_ib_dto.h"\r
+#else\r
+#include "dapl_ibal_dto.h"\r
+#endif\r
+\r
+\r
+#endif /*  _DAPL_ADAPTER_UTIL_H_ */\r
index 2f0d106..65fa9e7 100644 (file)
-/*
- * 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_evd_dto_callback.c
- *
- * PURPOSE: implements DTO callbacks from verbs
- *
- * $Id:$
- **********************************************************************/
-
-#include "dapl.h"
-#include "dapl_evd_util.h"
-#include "dapl_cno_util.h"
-#include "dapl_cookie.h"
-#include "dapl_adapter_util.h"
-
-/*********************************************************************
- *                                                                   *
- * Function Prototypes                                               *
- *                                                                   *
- *********************************************************************/
-
-/*********************************************************************
- *                                                                   *
- * Function Definitions                                              *
- *                                                                   *
- *********************************************************************/
-
-/*
- * dapl_evd_dto_callback
- *
- * Input:
- *     hca_handle_in, 
- *     cq_handle_in, 
- *      user_context_cq_p
- *
- * Output:
- *     none
- *
- * This is invoked for both DTO and MW bind completions. Strictly 
- * speaking it is an event callback rather than just a DTO callback. 
- *
- */
-
-void
-dapl_evd_dto_callback(IN ib_hca_handle_t hca_handle,
-                     IN ib_cq_handle_t cq_handle, IN void *user_context)
-{
-       DAPL_EVD *evd_ptr;
-       DAT_RETURN dat_status;
-       DAPL_EVD_STATE state;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,
-                    "dapl_evd_dto_callback(%p, %p, %p)\n",
-                    hca_handle, cq_handle, user_context);
-
-       evd_ptr = (DAPL_EVD *) user_context;
-       DAPL_CNTR(evd_ptr, DCNT_EVD_DTO_CALLBACK);
-
-       dapl_os_assert(hca_handle ==
-                      evd_ptr->header.owner_ia->hca_ptr->ib_hca_handle);
-       dapl_os_assert(evd_ptr->ib_cq_handle == cq_handle);
-       dapl_os_assert(evd_ptr->header.magic == DAPL_MAGIC_EVD);
-
-       /* Read once.  */
-       state = *(volatile DAPL_EVD_STATE *)&evd_ptr->evd_state;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_EVD,
-                    "-- dapl_evd_dto_callback: CQ %p, state %x\n",
-                    (void *)evd_ptr->ib_cq_handle, state);
-
-       /*
-        * This function does not dequeue from the CQ; only the consumer
-        * can do that. Instead, it wakes up waiters if any exist.
-        * It rearms the completion only if completions should always occur
-        * (specifically if a CNO is associated with the EVD and the
-        * EVD is enabled.
-        */
-
-       if (state == DAPL_EVD_STATE_WAITED) {
-               /*
-                * If we could, it would be best to avoid this wakeup
-                * (and the context switch) unless the number of events/CQs
-                * waiting for the waiter was its threshold.  We don't
-                * currently have the ability to determine that without
-                * dequeueing the events, and we can't do that for
-                * synchronization reasons (racing with the waiter waking
-                * up and dequeuing, sparked by other callbacks).
-                */
-
-               /*
-                * We don't need to worry about taking the lock for the
-                * wakeup because wakeups are sticky.
-                */
-#ifdef CQ_WAIT_OBJECT
-               if (evd_ptr->cq_wait_obj_handle)
-                       dapls_ib_wait_object_wakeup(evd_ptr->
-                                                   cq_wait_obj_handle);
-               else
-#endif
-                       dapl_os_wait_object_wakeup(&evd_ptr->wait_object);
-
-       } else if (state == DAPL_EVD_STATE_OPEN) {
-               DAPL_CNO *cno = evd_ptr->cno_ptr;
-               if (evd_ptr->evd_enabled && (evd_ptr->cno_ptr != NULL)) {
-                       /*
-                        * Re-enable callback, *then* trigger.
-                        * This guarantees we won't miss any events.
-                        */
-                       dat_status = dapls_ib_completion_notify(hca_handle,
-                                                               evd_ptr,
-                                                               IB_NOTIFY_ON_NEXT_COMP);
-
-                       if (DAT_SUCCESS != dat_status) {
-                               (void)dapls_evd_post_async_error_event(evd_ptr->
-                                                                      header.
-                                                                      owner_ia->
-                                                                      async_error_evd,
-                                                                      DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR,
-                                                                      (DAT_IA_HANDLE)
-                                                                      evd_ptr->
-                                                                      header.
-                                                                      owner_ia);
-                       }
-
-                       dapl_internal_cno_trigger(cno, evd_ptr);
-               }
-       }
-       dapl_dbg_log(DAPL_DBG_TYPE_RTN, "dapl_evd_dto_callback () returns\n");
-}
-
-/*
- * Local variables:
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 8
- * End:
- */
+/*\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_evd_dto_callback.c\r
+ *\r
+ * PURPOSE: implements DTO callbacks from verbs\r
+ *\r
+ * $Id:$\r
+ **********************************************************************/\r
+\r
+#include "dapl.h"\r
+#include "dapl_evd_util.h"\r
+#include "dapl_cno_util.h"\r
+#include "dapl_cookie.h"\r
+#include "dapl_adapter_util.h"\r
+\r
+/*********************************************************************\r
+ *                                                                   *\r
+ * Function Prototypes                                               *\r
+ *                                                                   *\r
+ *********************************************************************/\r
+\r
+/*********************************************************************\r
+ *                                                                   *\r
+ * Function Definitions                                              *\r
+ *                                                                   *\r
+ *********************************************************************/\r
+\r
+/*\r
+ * dapl_evd_dto_callback\r
+ *\r
+ * Input:\r
+ *     hca_handle_in, \r
+ *     cq_handle_in, \r
+ *      user_context_cq_p\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * This is invoked for both DTO and MW bind completions. Strictly \r
+ * speaking it is an event callback rather than just a DTO callback. \r
+ *\r
+ */\r
+\r
+void\r
+dapl_evd_dto_callback(IN ib_hca_handle_t hca_handle,\r
+                     IN ib_cq_handle_t cq_handle, IN void *user_context)\r
+{\r
+       DAPL_EVD *evd_ptr;\r
+       DAT_RETURN dat_status;\r
+       DAPL_EVD_STATE state;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,\r
+                    "dapl_evd_dto_callback(%p, %p, %p)\n",\r
+                    hca_handle, cq_handle, user_context);\r
+\r
+       evd_ptr = (DAPL_EVD *) user_context;\r
+       DAPL_CNTR(evd_ptr, DCNT_EVD_DTO_CALLBACK);\r
+\r
+       dapl_os_assert(hca_handle ==\r
+                      evd_ptr->header.owner_ia->hca_ptr->ib_hca_handle);\r
+       dapl_os_assert(evd_ptr->ib_cq_handle == cq_handle);\r
+       dapl_os_assert(evd_ptr->header.magic == DAPL_MAGIC_EVD);\r
+\r
+       /* Read once.  */\r
+       state = *(volatile DAPL_EVD_STATE *)&evd_ptr->evd_state;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_EVD,\r
+                    "-- dapl_evd_dto_callback: CQ %p, state %x\n",\r
+                    (void *)evd_ptr->ib_cq_handle, state);\r
+\r
+       /*\r
+        * This function does not dequeue from the CQ; only the consumer\r
+        * can do that. Instead, it wakes up waiters if any exist.\r
+        * It rearms the completion only if completions should always occur\r
+        * (specifically if a CNO is associated with the EVD and the\r
+        * EVD is enabled.\r
+        */\r
+\r
+       if (state == DAPL_EVD_STATE_WAITED) {\r
+               /*\r
+                * If we could, it would be best to avoid this wakeup\r
+                * (and the context switch) unless the number of events/CQs\r
+                * waiting for the waiter was its threshold.  We don't\r
+                * currently have the ability to determine that without\r
+                * dequeueing the events, and we can't do that for\r
+                * synchronization reasons (racing with the waiter waking\r
+                * up and dequeuing, sparked by other callbacks).\r
+                */\r
+\r
+               /*\r
+                * We don't need to worry about taking the lock for the\r
+                * wakeup because wakeups are sticky.\r
+                */\r
+               dapls_evd_dto_wakeup(evd_ptr);\r
+\r
+       } else if (state == DAPL_EVD_STATE_OPEN) {\r
+               DAPL_CNO *cno = evd_ptr->cno_ptr;\r
+               if (evd_ptr->evd_enabled && (evd_ptr->cno_ptr != NULL)) {\r
+                       /*\r
+                        * Re-enable callback, *then* trigger.\r
+                        * This guarantees we won't miss any events.\r
+                        */\r
+                       dat_status = dapls_ib_completion_notify(hca_handle,\r
+                                                               evd_ptr,\r
+                                                               IB_NOTIFY_ON_NEXT_COMP);\r
+\r
+                       if (DAT_SUCCESS != dat_status) {\r
+                               (void)dapls_evd_post_async_error_event(evd_ptr->\r
+                                                                      header.\r
+                                                                      owner_ia->\r
+                                                                      async_error_evd,\r
+                                                                      DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR,\r
+                                                                      (DAT_IA_HANDLE)\r
+                                                                      evd_ptr->\r
+                                                                      header.\r
+                                                                      owner_ia);\r
+                       }\r
+\r
+                       dapl_internal_cno_trigger(cno, evd_ptr);\r
+               }\r
+       }\r
+       dapl_dbg_log(DAPL_DBG_TYPE_RTN, "dapl_evd_dto_callback () returns\n");\r
+}\r
+\r
+/*\r
+ * Local variables:\r
+ *  c-indent-level: 4\r
+ *  c-basic-offset: 4\r
+ *  tab-width: 8\r
+ * End:\r
+ */\r
index 2cfd693..7756af1 100644 (file)
-/*
- * 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_evd_util.c
- *
- * PURPOSE: Manage EVD Info structure
- *
- * $Id: dapl_evd_util.c 1410 2006-07-19 17:12:02Z ardavis $
- **********************************************************************/
-
-#include "dapl_evd_util.h"
-#include "dapl_ia_util.h"
-#include "dapl_cno_util.h"
-#include "dapl_ring_buffer_util.h"
-#include "dapl_adapter_util.h"
-#include "dapl_cookie.h"
-#include "dapl.h"
-#include "dapl_cr_util.h"
-#include "dapl_sp_util.h"
-#include "dapl_ep_util.h"
-
-STATIC _INLINE_ void dapli_evd_eh_print_cqe(IN ib_work_completion_t * cqe);
-
-DAT_RETURN dapli_evd_event_alloc(IN DAPL_EVD * evd_ptr, IN DAT_COUNT qlen);
-
-char *dapl_event_str(IN DAT_EVENT_NUMBER event_num)
-{
-#if defined(DAPL_DBG)
-       struct dat_event_str {
-               char *str;
-               DAT_EVENT_NUMBER num;
-       };
-       static struct dat_event_str events[] = {
-               {"DAT_DTO_COMPLETION_EVENT", DAT_DTO_COMPLETION_EVENT},
-               {"DAT_RMR_BIND_COMPLETION_EVENT",
-                DAT_RMR_BIND_COMPLETION_EVENT},
-               {"DAT_CONNECTION_REQUEST_EVENT", DAT_CONNECTION_REQUEST_EVENT},
-               {"DAT_CONNECTION_EVENT_ESTABLISHED",
-                DAT_CONNECTION_EVENT_ESTABLISHED},
-               {"DAT_CONNECTION_EVENT_PEER_REJECTED",
-                DAT_CONNECTION_EVENT_PEER_REJECTED},
-               {"DAT_CONNECTION_EVENT_NON_PEER_REJECTED",
-                DAT_CONNECTION_EVENT_NON_PEER_REJECTED},
-               {"DAT_CONNECTION_EVENT_ACCEPT_COMPLETION_ERROR",
-                DAT_CONNECTION_EVENT_ACCEPT_COMPLETION_ERROR},
-               {"DAT_CONNECTION_EVENT_DISCONNECTED",
-                DAT_CONNECTION_EVENT_DISCONNECTED},
-               {"DAT_CONNECTION_EVENT_BROKEN", DAT_CONNECTION_EVENT_BROKEN},
-               {"DAT_CONNECTION_EVENT_TIMED_OUT",
-                DAT_CONNECTION_EVENT_TIMED_OUT},
-               {"DAT_CONNECTION_EVENT_UNREACHABLE",
-                DAT_CONNECTION_EVENT_UNREACHABLE},
-               {"DAT_ASYNC_ERROR_EVD_OVERFLOW", DAT_ASYNC_ERROR_EVD_OVERFLOW},
-               {"DAT_ASYNC_ERROR_IA_CATASTROPHIC",
-                DAT_ASYNC_ERROR_IA_CATASTROPHIC},
-               {"DAT_ASYNC_ERROR_EP_BROKEN", DAT_ASYNC_ERROR_EP_BROKEN},
-               {"DAT_ASYNC_ERROR_TIMED_OUT", DAT_ASYNC_ERROR_TIMED_OUT},
-               {"DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR",
-                DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR},
-               {"DAT_HA_DOWN_TO_1", DAT_HA_DOWN_TO_1},
-               {"DAT_HA_UP_TO_MULTI_PATH", DAT_HA_UP_TO_MULTI_PATH},
-               {"DAT_SOFTWARE_EVENT", DAT_SOFTWARE_EVENT},
-#ifdef DAT_EXTENSIONS
-               {"DAT_EXTENSION_EVENT", DAT_EXTENSION_EVENT},
-               {"DAT_IB_EXTENSION_RANGE_BASE", DAT_IB_EXTENSION_RANGE_BASE},
-               {"DAT_IB_UD_CONNECTION_REQUEST_EVENT",
-                DAT_IB_EXTENSION_RANGE_BASE + 1},
-               {"DAT_IB_UD_CONNECTION_EVENT_ESTABLISHED",
-                DAT_IB_EXTENSION_RANGE_BASE + 2},
-               {"DAT_IW_EXTENSION_RANGE_BASE", DAT_IW_EXTENSION_RANGE_BASE},
-#endif                         /* DAT_EXTENSIONS */
-               {NULL, 0},
-       };
-       int i;
-
-       for (i = 0; events[i].str; i++) {
-               if (events[i].num == event_num)
-                       return events[i].str;
-       }
-       return "Unknown DAT event?";
-#else
-       static char str[16];
-       sprintf(str, "%x", event_num);
-       return str;
-#endif
-}
-
-/*
- * dapls_evd_internal_create
- *
- * actually create the evd.  this is called after all parameter checking
- * has been performed in dapl_ep_create.  it is also called from dapl_ia_open
- * to create the default async evd.
- *
- * Input:
- *     ia_ptr
- *     cno_ptr
- *     qlen
- *     evd_flags
- *
- * Output:
- *     evd_ptr_ptr
- *
- * Returns:
- *     none
- *
- */
-
-DAT_RETURN
-dapls_evd_internal_create(DAPL_IA * ia_ptr,
-                         DAPL_CNO * cno_ptr,
-                         DAT_COUNT min_qlen,
-                         DAT_EVD_FLAGS evd_flags, DAPL_EVD ** evd_ptr_ptr)
-{
-       DAPL_EVD *evd_ptr;
-       DAT_COUNT cq_len;
-       DAT_RETURN dat_status;
-
-       dat_status = DAT_SUCCESS;
-       *evd_ptr_ptr = NULL;
-       cq_len = min_qlen;
-
-       evd_ptr = dapls_evd_alloc(ia_ptr, cno_ptr, evd_flags, min_qlen);
-       if (!evd_ptr) {
-               dat_status =
-                   DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY);
-               goto bail;
-       }
-
-       /*
-        * If we are dealing with event streams besides a CQ event stream,
-        * be conservative and set producer side locking.  Otherwise, no.
-        */
-       evd_ptr->evd_producer_locking_needed =
-           ((evd_flags & ~(DAT_EVD_DTO_FLAG | DAT_EVD_RMR_BIND_FLAG)) != 0);
-
-       /* Before we setup any callbacks, transition state to OPEN.  */
-       evd_ptr->evd_state = DAPL_EVD_STATE_OPEN;
-
-       if (evd_flags & DAT_EVD_ASYNC_FLAG) {
-               /*
-                * There is no cq associate with async evd. Set it to invalid
-                */
-               evd_ptr->ib_cq_handle = IB_INVALID_HANDLE;
-
-       } else if (0 != (evd_flags & ~(DAT_EVD_SOFTWARE_FLAG
-                                      | DAT_EVD_CONNECTION_FLAG
-                                      | DAT_EVD_CR_FLAG))) {
-#if defined(_VENDOR_IBAL_)
-               /* 
-                * The creation of CQ required a PD (PZ) associated with it and
-                * we do not have a PD here; therefore, the work-around is that we
-                * will postpone the creation of the cq till the creation of QP which
-                * this cq will associate with.
-                */
-               evd_ptr->ib_cq_handle = IB_INVALID_HANDLE;
-#else
-               dat_status = dapls_ib_cq_alloc(ia_ptr, evd_ptr, &cq_len);
-               if (dat_status != DAT_SUCCESS) {
-                       goto bail;
-               }
-
-               /* Now reset the cq_len in the attributes, it may have changed */
-               evd_ptr->qlen = cq_len;
-
-               dat_status =
-                   dapls_ib_setup_async_callback(ia_ptr,
-                                                 DAPL_ASYNC_CQ_COMPLETION,
-                                                 evd_ptr,
-                                                 (ib_async_handler_t)
-                                                 dapl_evd_dto_callback,
-                                                 evd_ptr);
-               if (dat_status != DAT_SUCCESS) {
-                       goto bail;
-               }
-
-               dat_status = dapls_set_cq_notify(ia_ptr, evd_ptr);
-
-               if (dat_status != DAT_SUCCESS) {
-                       goto bail;
-               }
-#endif                         /* _VENDOR_IBAL_ */
-       }
-
-       /* We now have an accurate count of events, so allocate them into
-        * the EVD
-        */
-       dat_status = dapli_evd_event_alloc(evd_ptr, cq_len);
-       if (dat_status != DAT_SUCCESS) {
-               goto bail;
-       }
-
-       dapl_ia_link_evd(ia_ptr, evd_ptr);
-       *evd_ptr_ptr = evd_ptr;
-
-      bail:
-       if (dat_status != DAT_SUCCESS) {
-               if (evd_ptr) {
-                       dapls_evd_dealloc(evd_ptr);
-               }
-       }
-
-       return dat_status;
-}
-
-/*
- * dapls_evd_alloc
- *
- * alloc and initialize an EVD struct
- *
- * Input:
- *     ia
- *
- * Output:
- *     evd_ptr
- *
- * Returns:
- *     none
- *
- */
-DAPL_EVD *dapls_evd_alloc(IN DAPL_IA * ia_ptr,
-                         IN DAPL_CNO * cno_ptr,
-                         IN DAT_EVD_FLAGS evd_flags, IN DAT_COUNT qlen)
-{
-       DAPL_EVD *evd_ptr;
-
-       /* Allocate EVD */
-       evd_ptr = (DAPL_EVD *) dapl_os_alloc(sizeof(DAPL_EVD));
-       if (!evd_ptr) {
-               goto bail;
-       }
-
-       /* zero the structure */
-       dapl_os_memzero(evd_ptr, sizeof(DAPL_EVD));
-
-#ifdef DAPL_COUNTERS
-       /* Allocate counters */
-       evd_ptr->cntrs =
-           dapl_os_alloc(sizeof(DAT_UINT64) * DCNT_EVD_ALL_COUNTERS);
-       if (evd_ptr->cntrs == NULL) {
-               dapl_os_free(evd_ptr, sizeof(DAPL_EVD));
-               return (NULL);
-       }
-       dapl_os_memzero(evd_ptr->cntrs,
-                       sizeof(DAT_UINT64) * DCNT_EVD_ALL_COUNTERS);
-#endif                         /* DAPL_COUNTERS */
-
-       /*
-        * initialize the header
-        */
-       evd_ptr->header.provider = ia_ptr->header.provider;
-       evd_ptr->header.magic = DAPL_MAGIC_EVD;
-       evd_ptr->header.handle_type = DAT_HANDLE_TYPE_EVD;
-       evd_ptr->header.owner_ia = ia_ptr;
-       evd_ptr->header.user_context.as_64 = 0;
-       evd_ptr->header.user_context.as_ptr = NULL;
-       dapl_llist_init_entry(&evd_ptr->header.ia_list_entry);
-       dapl_os_lock_init(&evd_ptr->header.lock);
-
-       /*
-        * Initialize the body
-        */
-       evd_ptr->evd_state = DAPL_EVD_STATE_INITIAL;
-       evd_ptr->evd_flags = evd_flags;
-       evd_ptr->evd_enabled = DAT_TRUE;
-       evd_ptr->evd_waitable = DAT_TRUE;
-       evd_ptr->evd_producer_locking_needed = 1;       /* Conservative value.  */
-       evd_ptr->ib_cq_handle = IB_INVALID_HANDLE;
-       dapl_os_atomic_set(&evd_ptr->evd_ref_count, 0);
-       evd_ptr->catastrophic_overflow = DAT_FALSE;
-       evd_ptr->qlen = qlen;
-       evd_ptr->completion_type = DAPL_EVD_STATE_THRESHOLD;    /* FIXME: should be DAPL_EVD_STATE_INIT */
-       dapl_os_wait_object_init(&evd_ptr->wait_object);
-
-#ifdef CQ_WAIT_OBJECT
-       /* Create CQ wait object; no CNO and data stream type */
-       if ((cno_ptr == NULL) &&
-           ((evd_flags & ~(DAT_EVD_DTO_FLAG | DAT_EVD_RMR_BIND_FLAG)) == 0)) {
-               dapls_ib_wait_object_create(evd_ptr,
-                                           &evd_ptr->cq_wait_obj_handle);
-               if (evd_ptr->cq_wait_obj_handle == NULL) {
-                       dapl_os_free(evd_ptr, sizeof(DAPL_EVD));
-                       evd_ptr = NULL;
-                       goto bail;
-               }
-       }
-#endif
-
-       evd_ptr->cno_active_count = 0;
-       if (cno_ptr != NULL) {
-               /* Take a reference count on the CNO */
-               dapl_os_atomic_inc(&cno_ptr->cno_ref_count);
-       }
-       evd_ptr->cno_ptr = cno_ptr;
-
-      bail:
-       return evd_ptr;
-}
-
-/*
- * dapls_evd_event_alloc
- *
- * alloc events into an EVD.
- *
- * Input:
- *     evd_ptr
- *     qlen
- *
- * Output:
- *     NONE
- *
- * Returns:
- *     DAT_SUCCESS
- *     ERROR
- *
- */
-DAT_RETURN dapli_evd_event_alloc(IN DAPL_EVD * evd_ptr, IN DAT_COUNT qlen)
-{
-       DAT_EVENT *event_ptr;
-       DAT_COUNT i;
-       DAT_RETURN dat_status;
-
-       dat_status = DAT_SUCCESS;
-
-       /* Allocate EVENTs */
-       event_ptr =
-           (DAT_EVENT *) dapl_os_alloc(evd_ptr->qlen * sizeof(DAT_EVENT));
-       if (event_ptr == NULL) {
-               dat_status =
-                   DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY);
-               goto bail;
-       }
-       evd_ptr->events = event_ptr;
-
-       /* allocate free event queue */
-       dat_status = dapls_rbuf_alloc(&evd_ptr->free_event_queue, qlen);
-       if (dat_status != DAT_SUCCESS) {
-               goto bail;
-       }
-
-       /* allocate pending event queue */
-       dat_status = dapls_rbuf_alloc(&evd_ptr->pending_event_queue, qlen);
-       if (dat_status != DAT_SUCCESS) {
-               goto bail;
-       }
-
-       /* add events to free event queue */
-       for (i = 0; i < evd_ptr->qlen; i++) {
-               dapls_rbuf_add(&evd_ptr->free_event_queue, (void *)event_ptr);
-               event_ptr++;
-       }
-
-       evd_ptr->cq_notified = DAT_FALSE;
-       evd_ptr->cq_notified_when = 0;
-       evd_ptr->threshold = 0;
-
-      bail:
-       return dat_status;
-}
-
-/*
- * dapls_evd_event_realloc
- *
- * realloc events into an EVD.
- *
- * Input:
- *     evd_ptr
- *     qlen
- *
- * Output:
- *     NONE
- *
- * Returns:
- *     DAT_SUCCESS
- *     ERROR
- *
- */
-DAT_RETURN dapls_evd_event_realloc(IN DAPL_EVD * evd_ptr, IN DAT_COUNT qlen)
-{
-       DAT_EVENT *events;
-       DAT_COUNT old_qlen;
-       DAT_COUNT i;
-       intptr_t diff;
-       DAT_RETURN dat_status;
-
-       /* Allocate EVENTs */
-       events = (DAT_EVENT *) dapl_os_realloc(evd_ptr->events,
-                                              qlen * sizeof(DAT_EVENT));
-       if (NULL == events) {
-               dat_status =
-                   DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY);
-               goto bail;
-       }
-
-       diff = events - evd_ptr->events;
-       evd_ptr->events = events;
-
-       old_qlen = evd_ptr->qlen;
-       evd_ptr->qlen = qlen;
-
-       /* reallocate free event queue */
-       dat_status = dapls_rbuf_realloc(&evd_ptr->free_event_queue, qlen);
-       if (dat_status != DAT_SUCCESS) {
-               goto bail;
-       }
-       dapls_rbuf_adjust(&evd_ptr->free_event_queue, diff);
-
-       /* reallocate pending event queue */
-       dat_status = dapls_rbuf_realloc(&evd_ptr->pending_event_queue, qlen);
-       if (dat_status != DAT_SUCCESS) {
-               goto bail;
-       }
-       dapls_rbuf_adjust(&evd_ptr->pending_event_queue, diff);
-
-       /*
-        * add new events to free event queue. 
-        */
-       for (i = old_qlen; i < qlen; i++) {
-               dapls_rbuf_add(&evd_ptr->free_event_queue, (void *)&events[i]);
-       }
-
-      bail:
-       return dat_status;
-}
-
-/*
- * dapls_evd_dealloc
- *
- * Free the passed in EVD structure. If an error occurs, this function
- * will clean up all of the internal data structures and report the
- * error.
- *
- * Input:
- *     evd_ptr
- *
- * Output:
- *     none
- *
- * Returns:
- *     status
- *
- */
-DAT_RETURN dapls_evd_dealloc(IN DAPL_EVD * evd_ptr)
-{
-       DAT_RETURN dat_status;
-       DAPL_IA *ia_ptr;
-
-       dat_status = DAT_SUCCESS;
-
-       dapl_os_assert(evd_ptr->header.magic == DAPL_MAGIC_EVD);
-       dapl_os_assert(dapl_os_atomic_read(&evd_ptr->evd_ref_count) == 0);
-
-       /*
-        * Destroy the CQ first, to keep any more callbacks from coming
-        * up from it.
-        */
-       if (evd_ptr->ib_cq_handle != IB_INVALID_HANDLE) {
-               ia_ptr = evd_ptr->header.owner_ia;
-
-               dat_status = dapls_ib_cq_free(ia_ptr, evd_ptr);
-               if (dat_status != DAT_SUCCESS) {
-                       goto bail;
-               }
-       }
-
-       /*
-        * We should now be safe to invalidate the EVD; reset the
-        * magic to prevent reuse.
-        */
-       evd_ptr->header.magic = DAPL_MAGIC_INVALID;
-
-       /* Release reference on the CNO if it exists */
-       if (evd_ptr->cno_ptr != NULL) {
-               dapl_os_atomic_dec(&evd_ptr->cno_ptr->cno_ref_count);
-               evd_ptr->cno_ptr = NULL;
-       }
-
-       /* If the ring buffer allocation failed, then the dapls_rbuf_destroy   */
-       /* function will detect that the ring buffer's internal data (ex. base */
-       /* pointer) are invalid and will handle the situation appropriately    */
-       dapls_rbuf_destroy(&evd_ptr->free_event_queue);
-       dapls_rbuf_destroy(&evd_ptr->pending_event_queue);
-
-       if (evd_ptr->events) {
-               dapl_os_free(evd_ptr->events,
-                            evd_ptr->qlen * sizeof(DAT_EVENT));
-       }
-
-       dapl_os_wait_object_destroy(&evd_ptr->wait_object);
-
-#ifdef CQ_WAIT_OBJECT
-       if (evd_ptr->cq_wait_obj_handle) {
-               dapls_ib_wait_object_destroy(evd_ptr->cq_wait_obj_handle);
-       }
-#endif
-
-#ifdef DAPL_COUNTERS
-       dapl_os_free(evd_ptr->cntrs,
-                    sizeof(DAT_UINT64) * DCNT_EVD_ALL_COUNTERS);
-#endif                         /* DAPL_COUNTERS */
-
-       dapl_os_free(evd_ptr, sizeof(DAPL_EVD));
-
-      bail:
-       return dat_status;
-}
-
-STATIC _INLINE_ char *DAPL_GET_DTO_OP_STR(int op)
-{
-       static char *dto_ops[] = {
-               "OP_SEND",
-               "OP_RECEIVE",
-               "OP_RDMA_WRITE",
-               "OP_RDMA_READ"
-       };
-       return ((op < 0 || op > 3) ? "Invalid DTO OP?" : dto_ops[op]);
-}
-
-#if !defined(DAPL_GET_CQE_OP_STR)
-#define DAPL_GET_CQE_OP_STR(e) "Unknown CEQ OP String?"
-#endif
-#if !defined(DAPL_GET_CQE_VENDOR_ERR)
-#define DAPL_GET_CQE_VENDOR_ERR(e) 0
-#endif
-
-/*
- * dapli_evd_eh_print_cqe
- *
- * Input:
- *     cqe_ptr
- *
- * Output:
- *     none
- *
- * Prints out a CQE for debug purposes
- *
- */
-
-void dapli_evd_eh_print_cqe(IN ib_work_completion_t * cqe_ptr)
-{
-#ifdef DAPL_DBG
-       dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,
-                    "\t >>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<\n");
-       dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,
-                    "\t dapl_evd_dto_callback : CQE \n");
-       dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,
-                    "\t\t work_req_id %lli\n", DAPL_GET_CQE_WRID(cqe_ptr));
-       if (DAPL_GET_CQE_STATUS(cqe_ptr) == 0) {
-               dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,
-                            "\t\t op_type: %s\n",
-                            DAPL_GET_CQE_OP_STR(cqe_ptr));
-               dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,
-                            "\t\t bytes_num %d\n",
-                            DAPL_GET_CQE_BYTESNUM(cqe_ptr));
-       }
-       dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,
-                    "\t\t status %d vendor_err 0x%x\n",
-                    DAPL_GET_CQE_STATUS(cqe_ptr),
-                    DAPL_GET_CQE_VENDOR_ERR(cqe_ptr));
-       dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,
-                    "\t >>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<\n");
-#endif
-       return;
-}
-
-/*
- * Event posting code follows.
- */
-
-/*
- * These next two functions (dapli_evd_get_event and dapli_evd_post_event)
- * are a pair.  They are always called together, from one of the functions
- * at the end of this file (dapl_evd_post_*_event).
- *
- * Note that if producer side locking is enabled, the first one takes the
- * EVD lock and the second releases it.
- */
-
-/* dapli_evd_get_event
- *
- * Get an event struct from the evd.  The caller should fill in the event
- * and call dapl_evd_post_event.
- *
- * If there are no events available, an overflow event is generated to the
- * async EVD handler.
- *
- * If this EVD required producer locking, a successful return implies
- * that the lock is held.
- *
- * Input:
- *     evd_ptr
- *
- * Output:
- *     event
- *
- */
-
-static DAT_EVENT *dapli_evd_get_event(DAPL_EVD * evd_ptr)
-{
-       DAT_EVENT *event;
-
-       if (evd_ptr->evd_producer_locking_needed) {
-               dapl_os_lock(&evd_ptr->header.lock);
-       }
-
-       event = (DAT_EVENT *) dapls_rbuf_remove(&evd_ptr->free_event_queue);
-
-       /* Release the lock if it was taken and the call failed.  */
-       if (!event && evd_ptr->evd_producer_locking_needed) {
-               dapl_os_unlock(&evd_ptr->header.lock);
-       }
-
-       return event;
-}
-
-/* dapli_evd_post_event
- *
- * Post the <event> to the evd.  If possible, invoke the evd's CNO.
- * Otherwise post the event on the pending queue.
- *
- * If producer side locking is required, the EVD lock must be held upon
- * entry to this function.
- *
- * Input:
- *     evd_ptr
- *     event
- *
- * Output:
- *     none
- *
- */
-
-static void
-dapli_evd_post_event(IN DAPL_EVD * evd_ptr, IN const DAT_EVENT * event_ptr)
-{
-       DAT_RETURN dat_status;
-       DAPL_CNO *cno_to_trigger = NULL;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_EVD, "%s: Called with event %s\n",
-                    __FUNCTION__, dapl_event_str(event_ptr->event_number));
-
-       dat_status = dapls_rbuf_add(&evd_ptr->pending_event_queue,
-                                   (void *)event_ptr);
-       dapl_os_assert(dat_status == DAT_SUCCESS);
-
-       dapl_os_assert(evd_ptr->evd_state == DAPL_EVD_STATE_WAITED
-                      || evd_ptr->evd_state == DAPL_EVD_STATE_OPEN);
-
-       if (evd_ptr->evd_state == DAPL_EVD_STATE_OPEN) {
-               /* No waiter.  Arrange to trigger a CNO if it exists.  */
-
-               if (evd_ptr->evd_enabled) {
-                       cno_to_trigger = evd_ptr->cno_ptr;
-               }
-               if (evd_ptr->evd_producer_locking_needed) {
-                       dapl_os_unlock(&evd_ptr->header.lock);
-               }
-       } else {
-               /*
-                * We're in DAPL_EVD_STATE_WAITED.  Take the lock if
-                * we don't have it, recheck, and signal.
-                */
-               if (!evd_ptr->evd_producer_locking_needed) {
-                       dapl_os_lock(&evd_ptr->header.lock);
-               }
-
-               if (evd_ptr->evd_state == DAPL_EVD_STATE_WAITED
-                   && (dapls_rbuf_count(&evd_ptr->pending_event_queue)
-                       >= evd_ptr->threshold)) {
-                       dapl_os_unlock(&evd_ptr->header.lock);
-
-#ifdef CQ_WAIT_OBJECT
-                       if (evd_ptr->cq_wait_obj_handle)
-                               dapls_ib_wait_object_wakeup(evd_ptr->
-                                                           cq_wait_obj_handle);
-                       else
-#endif
-                               dapl_os_wait_object_wakeup(&evd_ptr->
-                                                          wait_object);
-               } else {
-                       dapl_os_unlock(&evd_ptr->header.lock);
-               }
-       }
-
-       if (cno_to_trigger != NULL) {
-               dapl_internal_cno_trigger(cno_to_trigger, evd_ptr);
-       }
-}
-
-/* dapli_evd_post_event_nosignal
- *
- * Post the <event> to the evd.  Do not do any wakeup processing.
- * This function should only be called if it is known that there are
- * no waiters that it is appropriate to wakeup on this EVD.  An example
- * of such a situation is during internal dat_evd_wait() processing.
- *
- * If producer side locking is required, the EVD lock must be held upon
- * entry to this function.
- *
- * Input:
- *     evd_ptr
- *     event
- *
- * Output:
- *     none
- *
- */
-
-static void
-dapli_evd_post_event_nosignal(IN DAPL_EVD * evd_ptr,
-                             IN const DAT_EVENT * event_ptr)
-{
-       DAT_RETURN dat_status;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_EVD, "%s: Called with event %s\n",
-                    __FUNCTION__, dapl_event_str(event_ptr->event_number));
-
-       dat_status = dapls_rbuf_add(&evd_ptr->pending_event_queue,
-                                   (void *)event_ptr);
-       dapl_os_assert(dat_status == DAT_SUCCESS);
-
-       dapl_os_assert(evd_ptr->evd_state == DAPL_EVD_STATE_WAITED
-                      || evd_ptr->evd_state == DAPL_EVD_STATE_OPEN);
-
-       if (evd_ptr->evd_producer_locking_needed) {
-               dapl_os_unlock(&evd_ptr->header.lock);
-       }
-}
-
-/* dapli_evd_format_overflow_event
- *
- * format an overflow event for posting
- *
- * Input:
- *     evd_ptr
- *     event_ptr
- *
- * Output:
- *     none
- *
- */
-static void
-dapli_evd_format_overflow_event(IN DAPL_EVD * evd_ptr,
-                               OUT DAT_EVENT * event_ptr)
-{
-       DAPL_IA *ia_ptr;
-
-       ia_ptr = evd_ptr->header.owner_ia;
-
-       event_ptr->evd_handle = (DAT_EVD_HANDLE) evd_ptr;
-       event_ptr->event_number = DAT_ASYNC_ERROR_EVD_OVERFLOW;
-       event_ptr->event_data.asynch_error_event_data.dat_handle =
-           (DAT_HANDLE) ia_ptr;
-}
-
-/* dapli_evd_post_overflow_event
- *
- * post an overflow event
- *
- * Input:
- *     async_evd_ptr
- *     evd_ptr
- *
- * Output:
- *     none
- *
- */
-static void
-dapli_evd_post_overflow_event(IN DAPL_EVD * async_evd_ptr,
-                             IN DAPL_EVD * overflow_evd_ptr)
-{
-       DAT_EVENT *overflow_event;
-
-       /* The overflow_evd_ptr mght be the same as evd.
-        * In that case we've got a catastrophic overflow.
-        */
-       dapl_log(DAPL_DBG_TYPE_WARN,
-                " WARNING: overflow event on EVD %p/n", overflow_evd_ptr);
-
-       if (async_evd_ptr == overflow_evd_ptr) {
-               async_evd_ptr->catastrophic_overflow = DAT_TRUE;
-               async_evd_ptr->evd_state = DAPL_EVD_STATE_DEAD;
-               return;
-       }
-
-       overflow_event = dapli_evd_get_event(overflow_evd_ptr);
-       if (!overflow_event) {
-               /* this is not good */
-               overflow_evd_ptr->catastrophic_overflow = DAT_TRUE;
-               overflow_evd_ptr->evd_state = DAPL_EVD_STATE_DEAD;
-               return;
-       }
-       dapli_evd_format_overflow_event(overflow_evd_ptr, overflow_event);
-       dapli_evd_post_event(overflow_evd_ptr, overflow_event);
-
-       return;
-}
-
-static DAT_EVENT *dapli_evd_get_and_init_event(IN DAPL_EVD * evd_ptr,
-                                              IN DAT_EVENT_NUMBER event_number)
-{
-       DAT_EVENT *event_ptr;
-
-       event_ptr = dapli_evd_get_event(evd_ptr);
-       if (NULL == event_ptr) {
-               dapli_evd_post_overflow_event(evd_ptr->header.owner_ia->
-                                             async_error_evd, evd_ptr);
-       } else {
-               event_ptr->evd_handle = (DAT_EVD_HANDLE) evd_ptr;
-               event_ptr->event_number = event_number;
-       }
-
-       return event_ptr;
-}
-
-DAT_RETURN
-dapls_evd_post_cr_arrival_event(IN DAPL_EVD * evd_ptr,
-                               IN DAT_EVENT_NUMBER event_number,
-                               IN DAT_SP_HANDLE sp_handle,
-                               DAT_IA_ADDRESS_PTR ia_address_ptr,
-                               DAT_CONN_QUAL conn_qual,
-                               DAT_CR_HANDLE cr_handle)
-{
-       DAT_EVENT *event_ptr;
-       event_ptr = dapli_evd_get_and_init_event(evd_ptr, event_number);
-       /*
-        * Note event lock may be held on successful return
-        * to be released by dapli_evd_post_event(), if provider side locking
-        * is needed.
-        */
-
-       if (event_ptr == NULL) {
-               return DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
-                                DAT_RESOURCE_MEMORY);
-       }
-
-       event_ptr->event_data.cr_arrival_event_data.sp_handle = sp_handle;
-       event_ptr->event_data.cr_arrival_event_data.local_ia_address_ptr
-           = ia_address_ptr;
-       event_ptr->event_data.cr_arrival_event_data.conn_qual = conn_qual;
-       event_ptr->event_data.cr_arrival_event_data.cr_handle = cr_handle;
-
-       dapli_evd_post_event(evd_ptr, event_ptr);
-
-       return DAT_SUCCESS;
-}
-
-DAT_RETURN
-dapls_evd_post_connection_event(IN DAPL_EVD * evd_ptr,
-                               IN DAT_EVENT_NUMBER event_number,
-                               IN DAT_EP_HANDLE ep_handle,
-                               IN DAT_COUNT private_data_size,
-                               IN DAT_PVOID private_data)
-{
-       DAT_EVENT *event_ptr;
-       event_ptr = dapli_evd_get_and_init_event(evd_ptr, event_number);
-       /*
-        * Note event lock may be held on successful return
-        * to be released by dapli_evd_post_event(), if provider side locking
-        * is needed.
-        */
-
-       if (event_ptr == NULL) {
-               return DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
-                                DAT_RESOURCE_MEMORY);
-       }
-
-       event_ptr->event_data.connect_event_data.ep_handle = ep_handle;
-       event_ptr->event_data.connect_event_data.private_data_size
-           = private_data_size;
-       event_ptr->event_data.connect_event_data.private_data = private_data;
-
-       dapli_evd_post_event(evd_ptr, event_ptr);
-
-       return DAT_SUCCESS;
-}
-
-DAT_RETURN
-dapls_evd_post_async_error_event(IN DAPL_EVD * evd_ptr,
-                                IN DAT_EVENT_NUMBER event_number,
-                                IN DAT_IA_HANDLE ia_handle)
-{
-       DAT_EVENT *event_ptr;
-       event_ptr = dapli_evd_get_and_init_event(evd_ptr, event_number);
-       /*
-        * Note event lock may be held on successful return
-        * to be released by dapli_evd_post_event(), if provider side locking
-        * is needed.
-        */
-       dapl_log(DAPL_DBG_TYPE_WARN,
-                " WARNING: async event - %s evd=%p/n",
-                dapl_event_str(event_number), evd_ptr);
-
-       if (event_ptr == NULL) {
-               return DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
-                                DAT_RESOURCE_MEMORY);
-       }
-
-       event_ptr->event_data.asynch_error_event_data.dat_handle =
-           (DAT_HANDLE) ia_handle;
-
-       dapli_evd_post_event(evd_ptr, event_ptr);
-
-       return DAT_SUCCESS;
-}
-
-DAT_RETURN
-dapls_evd_post_software_event(IN DAPL_EVD * evd_ptr,
-                             IN DAT_EVENT_NUMBER event_number,
-                             IN DAT_PVOID pointer)
-{
-       DAT_EVENT *event_ptr;
-       event_ptr = dapli_evd_get_and_init_event(evd_ptr, event_number);
-       /*
-        * Note event lock may be held on successful return
-        * to be released by dapli_evd_post_event(), if provider side locking
-        * is needed.
-        */
-
-       if (event_ptr == NULL) {
-               return DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
-                                DAT_RESOURCE_MEMORY);
-       }
-
-       event_ptr->event_data.software_event_data.pointer = pointer;
-
-       dapli_evd_post_event(evd_ptr, event_ptr);
-
-       return DAT_SUCCESS;
-}
-
-/*
- * dapls_evd_post_generic_event
- *
- * Post a generic event type. Not used by all providers
- *
- * Input:
- *     evd_ptr
- *     event_number
- *     data
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *
- */
-DAT_RETURN
-dapls_evd_post_generic_event(IN DAPL_EVD * evd_ptr,
-                            IN DAT_EVENT_NUMBER event_number,
-                            IN DAT_EVENT_DATA * data)
-{
-       DAT_EVENT *event_ptr;
-
-       event_ptr = dapli_evd_get_and_init_event(evd_ptr, event_number);
-       /*
-        * Note event lock may be held on successful return
-        * to be released by dapli_evd_post_event(), if provider side locking
-        * is needed.
-        */
-
-       if (event_ptr == NULL) {
-               return DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
-                                DAT_RESOURCE_MEMORY);
-       }
-
-       event_ptr->event_data = *data;
-
-       dapli_evd_post_event(evd_ptr, event_ptr);
-
-       return DAT_SUCCESS;
-}
-
-#ifdef DAT_EXTENSIONS
-DAT_RETURN
-dapls_evd_post_cr_event_ext(IN DAPL_SP * sp_ptr,
-                           IN DAT_EVENT_NUMBER event_number,
-                           IN dp_ib_cm_handle_t ib_cm_handle,
-                           IN DAT_COUNT p_size,
-                           IN DAT_PVOID p_data, IN DAT_PVOID ext_data)
-{
-       DAPL_CR *cr_ptr;
-       DAPL_EP *ep_ptr;
-       DAT_EVENT *event_ptr;
-       DAT_SP_HANDLE sp_handle;
-
-       dapl_os_lock(&sp_ptr->header.lock);
-       if (sp_ptr->listening == DAT_FALSE) {
-               dapl_os_unlock(&sp_ptr->header.lock);
-               dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                            "---> post_cr_event_ext: conn event on down SP\n");
-               (void)dapls_ib_reject_connection(ib_cm_handle,
-                                                DAT_CONNECTION_EVENT_UNREACHABLE,
-                                                0, NULL);
-               return DAT_CONN_QUAL_UNAVAILABLE;
-       }
-
-       /*
-        * RSP connections only allow a single connection. Close
-        * it down NOW so we reject any further connections.
-        */
-       if (sp_ptr->header.handle_type == DAT_HANDLE_TYPE_RSP)
-               sp_ptr->listening = DAT_FALSE;
-
-       dapl_os_unlock(&sp_ptr->header.lock);
-
-       /* allocate new connect request */
-       cr_ptr = dapls_cr_alloc(sp_ptr->header.owner_ia);
-       if (cr_ptr == NULL)
-               return DAT_INSUFFICIENT_RESOURCES;
-
-       /* Set up the CR */
-       cr_ptr->sp_ptr = sp_ptr;        /* maintain sp_ptr in case of reject */
-       cr_ptr->param.remote_port_qual = 0;
-       cr_ptr->ib_cm_handle = ib_cm_handle;
-       cr_ptr->param.remote_ia_address_ptr =
-           (DAT_IA_ADDRESS_PTR) & cr_ptr->remote_ia_address;
-
-       /*
-        * Copy the remote address and private data out of the private_data
-        */
-       cr_ptr->param.private_data = cr_ptr->private_data;
-       cr_ptr->param.private_data_size = p_size;
-       if (p_size)
-               dapl_os_memcpy(cr_ptr->private_data, p_data, p_size);
-
-       /* EP will be NULL unless RSP service point */
-       ep_ptr = (DAPL_EP *) sp_ptr->ep_handle;
-
-       if (sp_ptr->psp_flags == DAT_PSP_PROVIDER_FLAG) {
-               DAPL_IA *ia_ptr;
-               /*
-                * Never true for RSP connections
-                *
-                * Create an EP for the user. If we can't allocate an
-                * EP we are out of resources and need to tell the
-                * requestor that we cant help them.
-                */
-               ia_ptr = sp_ptr->header.owner_ia;
-               ep_ptr = dapl_ep_alloc(ia_ptr, NULL);
-               if (ep_ptr == NULL) {
-                       dapls_cr_free(cr_ptr);
-                       /* Invoking function will call dapls_ib_cm_reject() */
-                       return DAT_INSUFFICIENT_RESOURCES;
-               }
-               ep_ptr->param.ia_handle = ia_ptr;
-               ep_ptr->param.local_ia_address_ptr =
-                   (DAT_IA_ADDRESS_PTR) & ia_ptr->hca_ptr->hca_address;
-
-               /* Link the EP onto the IA */
-               dapl_ia_link_ep(ia_ptr, ep_ptr);
-       }
-
-       cr_ptr->param.local_ep_handle = ep_ptr;
-
-       if (ep_ptr != NULL) {
-               /* Assign valid EP fields: RSP and PSP_PROVIDER_FLAG only */
-               if (sp_ptr->psp_flags == DAT_PSP_PROVIDER_FLAG) {
-                       ep_ptr->param.ep_state =
-                           DAT_EP_STATE_TENTATIVE_CONNECTION_PENDING;
-               } else {
-                       /* RSP */
-                       dapl_os_assert(sp_ptr->header.handle_type ==
-                                      DAT_HANDLE_TYPE_RSP);
-                       ep_ptr->param.ep_state =
-                           DAT_EP_STATE_PASSIVE_CONNECTION_PENDING;
-               }
-               ep_ptr->cm_handle = ib_cm_handle;
-       }
-
-       /* link the CR onto the SP so we can pick it up later */
-       dapl_sp_link_cr(sp_ptr, cr_ptr);
-
-       /* assign sp_ptr to union to avoid typecast errors from some compilers */
-       sp_handle.psp_handle = (DAT_PSP_HANDLE) sp_ptr;
-
-       /* Post the event.  */
-
-       /*
-        * Note event lock may be held on successful return
-        * to be released by dapli_evd_post_event(), if provider side locking
-        * is needed.
-        */
-       event_ptr = dapli_evd_get_and_init_event(sp_ptr->evd_handle,
-                                                event_number);
-       if (event_ptr == NULL)
-               return DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
-                                DAT_RESOURCE_MEMORY);
-
-       event_ptr->event_data.cr_arrival_event_data.sp_handle = sp_handle;
-       event_ptr->event_data.cr_arrival_event_data.local_ia_address_ptr =
-           (DAT_IA_ADDRESS_PTR) & sp_ptr->header.owner_ia->hca_ptr->
-           hca_address;
-       event_ptr->event_data.cr_arrival_event_data.conn_qual =
-           sp_ptr->conn_qual;
-       event_ptr->event_data.cr_arrival_event_data.cr_handle =
-           (DAT_HANDLE) cr_ptr;
-
-       dapl_os_memcpy(&event_ptr->event_extension_data[0], ext_data, 64);
-
-       dapli_evd_post_event(sp_ptr->evd_handle, event_ptr);
-
-       return DAT_SUCCESS;
-}
-
-DAT_RETURN
-dapls_evd_post_connection_event_ext(IN DAPL_EVD * evd_ptr,
-                                   IN DAT_EVENT_NUMBER event_number,
-                                   IN DAT_EP_HANDLE ep_handle,
-                                   IN DAT_COUNT private_data_size,
-                                   IN DAT_PVOID private_data,
-                                   IN DAT_PVOID ext_data)
-{
-       DAT_EVENT *event_ptr;
-       event_ptr = dapli_evd_get_and_init_event(evd_ptr, event_number);
-       /*
-        * Note event lock may be held on successful return
-        * to be released by dapli_evd_post_event(), if provider side locking
-        * is needed.
-        */
-       if (event_ptr == NULL)
-               return DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
-                                DAT_RESOURCE_MEMORY);
-
-       event_ptr->event_data.connect_event_data.ep_handle = ep_handle;
-       event_ptr->event_data.connect_event_data.private_data_size
-           = private_data_size;
-       event_ptr->event_data.connect_event_data.private_data = private_data;
-
-       dapl_os_memcpy(&event_ptr->event_extension_data[0], ext_data, 64);
-
-       dapli_evd_post_event(evd_ptr, event_ptr);
-
-       return DAT_SUCCESS;
-}
-#endif
-
-/*
- * dapli_evd_cqe_to_event
- *
- * Convert a CQE into an event structure.
- *
- * Input:
- *     evd_ptr
- *     cqe_ptr
- *
- * Output:
- *     event_ptr
- *
- * Returns:
- *     none
- *
- */
-static void
-dapli_evd_cqe_to_event(IN DAPL_EVD * evd_ptr,
-                      IN void *cqe_ptr, OUT DAT_EVENT * event_ptr)
-{
-       DAPL_EP *ep_ptr;
-       DAPL_COOKIE *cookie;
-       DAT_DTO_COMPLETION_STATUS dto_status;
-       DAPL_COOKIE_BUFFER *buffer;
-
-       /*
-        * All that can be relied on if the status is bad is the status
-        * and WRID.
-        */
-       dto_status = dapls_ib_get_dto_status(cqe_ptr);
-
-       cookie = (DAPL_COOKIE *) (uintptr_t) DAPL_GET_CQE_WRID(cqe_ptr);
-       dapl_os_assert((NULL != cookie));
-
-       ep_ptr = cookie->ep;
-       dapl_os_assert((NULL != ep_ptr));
-       if (ep_ptr->header.magic != DAPL_MAGIC_EP) {
-               /* ep may have been freed, just return */
-               return;
-       }
-
-       dapls_io_trc_update_completion(ep_ptr, cookie, dto_status);
-
-       event_ptr->evd_handle = (DAT_EVD_HANDLE) evd_ptr;
-
-       switch (cookie->type) {
-       case DAPL_COOKIE_TYPE_DTO:
-               {
-#ifdef DAT_EXTENSIONS
-                       /* Extended via request post or message receive */
-                       if ((cookie->val.dto.type == DAPL_DTO_TYPE_EXTENSION) ||
-                           (cookie->val.dto.type == DAPL_DTO_TYPE_RECV &&
-                            DAPL_GET_CQE_OPTYPE(cqe_ptr) != OP_RECEIVE)) {
-                               dapls_cqe_to_event_extension(ep_ptr, cookie,
-                                                            cqe_ptr,
-                                                            event_ptr);
-                               if (cookie->val.dto.type == DAPL_DTO_TYPE_RECV)
-                                       dapls_cookie_dealloc(&ep_ptr->
-                                                            recv_buffer,
-                                                            cookie);
-                               else
-                                       dapls_cookie_dealloc(&ep_ptr->
-                                                            req_buffer,
-                                                            cookie);
-                               break;
-                       }
-#endif
-
-                       if (DAPL_DTO_TYPE_RECV == cookie->val.dto.type)
-                               buffer = &ep_ptr->recv_buffer;
-                       else
-                               buffer = &ep_ptr->req_buffer;
-
-                       event_ptr->event_number = DAT_DTO_COMPLETION_EVENT;
-                       event_ptr->event_data.dto_completion_event_data.
-                           ep_handle = cookie->ep;
-                       event_ptr->event_data.dto_completion_event_data.
-                           user_cookie = cookie->val.dto.cookie;
-                       event_ptr->event_data.dto_completion_event_data.status =
-                           dto_status;
-
-                       if (cookie->val.dto.type == DAPL_DTO_TYPE_SEND ||
-                           cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_WRITE) {
-                               /* Get size from DTO; CQE value may be off.  */
-                               event_ptr->event_data.dto_completion_event_data.
-                                   transfered_length = cookie->val.dto.size;
-                       } else {
-                               event_ptr->event_data.dto_completion_event_data.
-                                   transfered_length =
-                                   DAPL_GET_CQE_BYTESNUM(cqe_ptr);
-                       }
-
-                       dapls_cookie_dealloc(buffer, cookie);
-                       break;
-               }
-
-       case DAPL_COOKIE_TYPE_RMR:
-               {
-                       event_ptr->event_number = DAT_RMR_BIND_COMPLETION_EVENT;
-
-                       event_ptr->event_data.rmr_completion_event_data.
-                           rmr_handle = cookie->val.rmr.rmr;
-                       event_ptr->event_data.rmr_completion_event_data.
-                           user_cookie = cookie->val.rmr.cookie;
-                       if (dto_status == DAT_DTO_SUCCESS) {
-                               event_ptr->event_data.rmr_completion_event_data.
-                                   status = DAT_RMR_BIND_SUCCESS;
-                               dapl_os_assert((DAPL_GET_CQE_OPTYPE(cqe_ptr)) ==
-                                              OP_BIND_MW);
-                       } else {
-                               dapl_dbg_log(DAPL_DBG_TYPE_DTO_COMP_ERR,
-                                            " MW bind completion ERROR: %d: op %#x ep: %p\n",
-                                            dto_status,
-                                            DAPL_GET_CQE_OPTYPE(cqe_ptr),
-                                            ep_ptr);
-                               event_ptr->event_data.rmr_completion_event_data.
-                                   status = DAT_RMR_OPERATION_FAILED;
-                               dapl_os_atomic_dec(&cookie->val.rmr.rmr->lmr->
-                                                  lmr_ref_count);
-                       }
-
-                       dapls_cookie_dealloc(&ep_ptr->req_buffer, cookie);
-                       break;
-               }
-       default:
-               {
-                       dapl_os_assert(!"Invalid Operation type");
-                       break;
-               }
-       }                       /* end switch */
-
-       /*
-        * Most error DTO ops result in disconnecting the EP. See
-        * IBTA Vol 1.1, Chapter 10,Table 68, for expected effect on
-        * state.
-        */
-       if ((dto_status != DAT_DTO_SUCCESS) &&
-           (dto_status != DAT_DTO_ERR_FLUSHED)) {
-               DAPL_EVD *evd_ptr;
-
-               /*
-                * If we are connected, generate disconnect and generate an
-                * event. We may be racing with other disconnect ops, so we
-                * need to check. We may also be racing CM connection events,
-                * requiring us to check for connection pending states too.
-                */
-               dapl_os_lock(&ep_ptr->header.lock);
-               if (ep_ptr->param.ep_state == DAT_EP_STATE_CONNECTED ||
-                   ep_ptr->param.ep_state ==
-                   DAT_EP_STATE_ACTIVE_CONNECTION_PENDING
-                   || ep_ptr->param.ep_state ==
-                   DAT_EP_STATE_PASSIVE_CONNECTION_PENDING
-                   || ep_ptr->param.ep_state ==
-                   DAT_EP_STATE_COMPLETION_PENDING)
-               {
-                       ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;
-                       dapl_os_unlock(&ep_ptr->header.lock);
-                       dapls_io_trc_dump(ep_ptr, cqe_ptr, dto_status);
-
-                       /* Let the other side know we have disconnected */
-                       (void)dapls_ib_disconnect(ep_ptr,
-                                                 DAT_CLOSE_ABRUPT_FLAG);
-
-                       /* ... and clean up the local side */
-                       evd_ptr = (DAPL_EVD *) ep_ptr->param.connect_evd_handle;
-                       if (evd_ptr != NULL) {
-                               dapls_evd_post_connection_event(evd_ptr,
-                                                               DAT_CONNECTION_EVENT_BROKEN,
-                                                               (DAT_HANDLE)
-                                                               ep_ptr, 0, 0);
-                       }
-               } else {
-                       dapl_os_unlock(&ep_ptr->header.lock);
-               }
-
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        "DTO completion ERR: status %d, op %s, vendor_err 0x%x - %s\n",
-                        DAPL_GET_CQE_STATUS(cqe_ptr),
-                        DAPL_GET_DTO_OP_STR(cookie->val.dto.type),
-                        DAPL_GET_CQE_VENDOR_ERR(cqe_ptr),
-                        inet_ntoa(((struct sockaddr_in *)&ep_ptr->
-                                   remote_ia_address)->sin_addr));
-       }
-}
-
-/*
- * dapls_evd_copy_cq
- *
- * Copy all entries on a CQ associated with the EVD onto that EVD
- * Up to caller to handle races, if any.  Note that no EVD waiters will
- * be awoken by this copy.
- *
- * Input:
- *     evd_ptr
- *
- * Output:
- *     None
- *
- * Returns:
- *     none
- *
- */
-void dapls_evd_copy_cq(DAPL_EVD * evd_ptr)
-{
-       ib_work_completion_t cur_cqe;
-       DAT_RETURN dat_status;
-       DAT_EVENT *event;
-
-       if (evd_ptr->ib_cq_handle == IB_INVALID_HANDLE) {
-               /* Nothing to do if no CQ.  */
-               return;
-       }
-
-       while (1) {
-               dat_status =
-                   dapls_ib_completion_poll(evd_ptr->header.owner_ia->hca_ptr,
-                                            evd_ptr, &cur_cqe);
-
-               if (dat_status != DAT_SUCCESS) {
-                       break;
-               }
-
-               /* For debugging.  */
-               dapli_evd_eh_print_cqe(&cur_cqe);
-
-               /*
-                * Can use DAT_DTO_COMPLETION_EVENT because dapli_evd_cqe_to_event
-                * will overwrite.
-                */
-
-               event =
-                   dapli_evd_get_and_init_event(evd_ptr,
-                                                DAT_DTO_COMPLETION_EVENT);
-               if (event == NULL) {
-                       /* We've already attempted the overflow post; return.  */
-                       return;
-               }
-
-               dapli_evd_cqe_to_event(evd_ptr, &cur_cqe, event);
-
-               dapli_evd_post_event_nosignal(evd_ptr, event);
-       }
-
-       if (DAT_GET_TYPE(dat_status) != DAT_QUEUE_EMPTY) {
-               dapl_dbg_log(DAPL_DBG_TYPE_EVD,
-                            "dapls_evd_copy_cq: dapls_ib_completion_poll returned 0x%x\n",
-                            dat_status);
-               dapl_os_assert(!"Bad return from dapls_ib_completion_poll");
-       }
-}
-
-/*
- * dapls_evd_cq_poll_to_event
- *
- * Attempt to dequeue a single CQE from a CQ and turn it into
- * an event.
- *
- * Input:
- *     evd_ptr
- *
- * Output:
- *     event
- *
- * Returns:
- *     Status of operation
- *
- */
-DAT_RETURN
-dapls_evd_cq_poll_to_event(IN DAPL_EVD * evd_ptr, OUT DAT_EVENT * event)
-{
-       DAT_RETURN dat_status;
-       ib_work_completion_t cur_cqe;
-
-       dat_status = dapls_ib_completion_poll(evd_ptr->header.owner_ia->hca_ptr,
-                                             evd_ptr, &cur_cqe);
-       if (dat_status == DAT_SUCCESS) {
-               /* For debugging.  */
-               dapli_evd_eh_print_cqe(&cur_cqe);
-
-               dapli_evd_cqe_to_event(evd_ptr, &cur_cqe, event);
-       }
-
-       return dat_status;
-}
-
-#ifdef DAPL_DBG_IO_TRC
-/*
- * Update I/O completions in the I/O trace buffer. I/O is posted to
- * the buffer, then we find it here using the cookie and mark it
- * completed with the completion status
- */
-void
-dapls_io_trc_update_completion(DAPL_EP * ep_ptr,
-                              DAPL_COOKIE * cookie,
-                              DAT_DTO_COMPLETION_STATUS dto_status)
-{
-       int i;
-       static unsigned int c_cnt = 1;
-
-       for (i = 0; i < DBG_IO_TRC_QLEN; i++) {
-               if (ep_ptr->ibt_base[i].cookie == cookie) {
-                       ep_ptr->ibt_base[i].status = dto_status;
-                       ep_ptr->ibt_base[i].done = c_cnt++;
-               }
-       }
-}
-
-/*
- * Dump the I/O trace buffers
- */
-void
-dapls_io_trc_dump(DAPL_EP * ep_ptr,
-                 void *cqe_ptr, DAT_DTO_COMPLETION_STATUS dto_status)
-{
-       struct io_buf_track *ibt;
-       int i;
-       int cnt;
-
-       dapl_os_printf("DISCONNECTING: dto_status     = %x\n", dto_status);
-       dapl_os_printf("               OpType        = %x\n",
-                      DAPL_GET_CQE_OPTYPE(cqe_ptr));
-       dapl_os_printf("               Bytes         = %x\n",
-                      DAPL_GET_CQE_BYTESNUM(cqe_ptr));
-       dapl_os_printf("               WRID (cookie) = %llx\n",
-                      DAPL_GET_CQE_WRID(cqe_ptr));
-
-       if (ep_ptr->ibt_dumped == 0) {
-
-               dapl_os_printf("EP %p (qpn %d) I/O trace buffer\n",
-                              ep_ptr, ep_ptr->qpn);
-
-               ep_ptr->ibt_dumped = 1;
-               ibt =
-                   (struct io_buf_track *)dapls_rbuf_remove(&ep_ptr->
-                                                            ibt_queue);
-               cnt = DBG_IO_TRC_QLEN;
-               while (ibt != NULL && cnt > 0) {
-                       dapl_os_printf
-                           ("%2d. %3s (%2d, %d) OP: %x cookie %p wqe %p rmv_target_addr %llx rmv_rmr_context %x\n",
-                            cnt, ibt->done == 0 ? "WRK" : "DON", ibt->status,
-                            ibt->done, ibt->op_type, ibt->cookie, ibt->wqe,
-                            ibt->remote_iov.target_address,
-                            ibt->remote_iov.rmr_context);
-                       for (i = 0; i < 3; i++) {
-                               if (ibt->iov[i].segment_length != 0) {
-                                       dapl_os_printf
-                                           ("     (%4llx, %8x, %8llx)\n",
-                                            ibt->iov[i].segment_length,
-                                            ibt->iov[i].lmr_context,
-                                            ibt->iov[i].virtual_address);
-                               }
-                       }
-                       ibt =
-                           (struct io_buf_track *)dapls_rbuf_remove(&ep_ptr->
-                                                                    ibt_queue);
-                       cnt--;
-               }
-       }
-}
-#endif                         /* DAPL_DBG_IO_TRC */
-
-/*
- * Local variables:
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 8
- * End:
- */
+/*\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_evd_util.c\r
+ *\r
+ * PURPOSE: Manage EVD Info structure\r
+ *\r
+ * $Id: dapl_evd_util.c 1410 2006-07-19 17:12:02Z ardavis $\r
+ **********************************************************************/\r
+\r
+#include "dapl_evd_util.h"\r
+#include "dapl_ia_util.h"\r
+#include "dapl_cno_util.h"\r
+#include "dapl_ring_buffer_util.h"\r
+#include "dapl_adapter_util.h"\r
+#include "dapl_cookie.h"\r
+#include "dapl.h"\r
+#include "dapl_cr_util.h"\r
+#include "dapl_sp_util.h"\r
+#include "dapl_ep_util.h"\r
+\r
+STATIC _INLINE_ void dapli_evd_eh_print_cqe(IN ib_work_completion_t * cqe);\r
+\r
+DAT_RETURN dapli_evd_event_alloc(IN DAPL_EVD * evd_ptr, IN DAT_COUNT qlen);\r
+\r
+char *dapl_event_str(IN DAT_EVENT_NUMBER event_num)\r
+{\r
+#if defined(DAPL_DBG)\r
+       struct dat_event_str {\r
+               char *str;\r
+               DAT_EVENT_NUMBER num;\r
+       };\r
+       static struct dat_event_str events[] = {\r
+               {"DAT_DTO_COMPLETION_EVENT", DAT_DTO_COMPLETION_EVENT},\r
+               {"DAT_RMR_BIND_COMPLETION_EVENT",\r
+                DAT_RMR_BIND_COMPLETION_EVENT},\r
+               {"DAT_CONNECTION_REQUEST_EVENT", DAT_CONNECTION_REQUEST_EVENT},\r
+               {"DAT_CONNECTION_EVENT_ESTABLISHED",\r
+                DAT_CONNECTION_EVENT_ESTABLISHED},\r
+               {"DAT_CONNECTION_EVENT_PEER_REJECTED",\r
+                DAT_CONNECTION_EVENT_PEER_REJECTED},\r
+               {"DAT_CONNECTION_EVENT_NON_PEER_REJECTED",\r
+                DAT_CONNECTION_EVENT_NON_PEER_REJECTED},\r
+               {"DAT_CONNECTION_EVENT_ACCEPT_COMPLETION_ERROR",\r
+                DAT_CONNECTION_EVENT_ACCEPT_COMPLETION_ERROR},\r
+               {"DAT_CONNECTION_EVENT_DISCONNECTED",\r
+                DAT_CONNECTION_EVENT_DISCONNECTED},\r
+               {"DAT_CONNECTION_EVENT_BROKEN", DAT_CONNECTION_EVENT_BROKEN},\r
+               {"DAT_CONNECTION_EVENT_TIMED_OUT",\r
+                DAT_CONNECTION_EVENT_TIMED_OUT},\r
+               {"DAT_CONNECTION_EVENT_UNREACHABLE",\r
+                DAT_CONNECTION_EVENT_UNREACHABLE},\r
+               {"DAT_ASYNC_ERROR_EVD_OVERFLOW", DAT_ASYNC_ERROR_EVD_OVERFLOW},\r
+               {"DAT_ASYNC_ERROR_IA_CATASTROPHIC",\r
+                DAT_ASYNC_ERROR_IA_CATASTROPHIC},\r
+               {"DAT_ASYNC_ERROR_EP_BROKEN", DAT_ASYNC_ERROR_EP_BROKEN},\r
+               {"DAT_ASYNC_ERROR_TIMED_OUT", DAT_ASYNC_ERROR_TIMED_OUT},\r
+               {"DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR",\r
+                DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR},\r
+               {"DAT_HA_DOWN_TO_1", DAT_HA_DOWN_TO_1},\r
+               {"DAT_HA_UP_TO_MULTI_PATH", DAT_HA_UP_TO_MULTI_PATH},\r
+               {"DAT_SOFTWARE_EVENT", DAT_SOFTWARE_EVENT},\r
+#ifdef DAT_EXTENSIONS\r
+               {"DAT_EXTENSION_EVENT", DAT_EXTENSION_EVENT},\r
+               {"DAT_IB_EXTENSION_RANGE_BASE", DAT_IB_EXTENSION_RANGE_BASE},\r
+               {"DAT_IB_UD_CONNECTION_REQUEST_EVENT",\r
+                DAT_IB_EXTENSION_RANGE_BASE + 1},\r
+               {"DAT_IB_UD_CONNECTION_EVENT_ESTABLISHED",\r
+                DAT_IB_EXTENSION_RANGE_BASE + 2},\r
+               {"DAT_IW_EXTENSION_RANGE_BASE", DAT_IW_EXTENSION_RANGE_BASE},\r
+#endif                         /* DAT_EXTENSIONS */\r
+               {NULL, 0},\r
+       };\r
+       int i;\r
+\r
+       for (i = 0; events[i].str; i++) {\r
+               if (events[i].num == event_num)\r
+                       return events[i].str;\r
+       }\r
+       return "Unknown DAT event?";\r
+#else\r
+       static char str[16];\r
+       sprintf(str, "%x", event_num);\r
+       return str;\r
+#endif\r
+}\r
+\r
+/*\r
+ * dapls_evd_internal_create\r
+ *\r
+ * actually create the evd.  this is called after all parameter checking\r
+ * has been performed in dapl_ep_create.  it is also called from dapl_ia_open\r
+ * to create the default async evd.\r
+ *\r
+ * Input:\r
+ *     ia_ptr\r
+ *     cno_ptr\r
+ *     qlen\r
+ *     evd_flags\r
+ *\r
+ * Output:\r
+ *     evd_ptr_ptr\r
+ *\r
+ * Returns:\r
+ *     none\r
+ *\r
+ */\r
+\r
+DAT_RETURN\r
+dapls_evd_internal_create(DAPL_IA * ia_ptr,\r
+                         DAPL_CNO * cno_ptr,\r
+                         DAT_COUNT min_qlen,\r
+                         DAT_EVD_FLAGS evd_flags, DAPL_EVD ** evd_ptr_ptr)\r
+{\r
+       DAPL_EVD *evd_ptr;\r
+       DAT_COUNT cq_len;\r
+       DAT_RETURN dat_status;\r
+\r
+       dat_status = DAT_SUCCESS;\r
+       *evd_ptr_ptr = NULL;\r
+       cq_len = min_qlen;\r
+\r
+       evd_ptr = dapls_evd_alloc(ia_ptr, cno_ptr, evd_flags, min_qlen);\r
+       if (!evd_ptr) {\r
+               dat_status =\r
+                   DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY);\r
+               goto bail;\r
+       }\r
+\r
+       /*\r
+        * If we are dealing with event streams besides a CQ event stream,\r
+        * be conservative and set producer side locking.  Otherwise, no.\r
+        */\r
+       evd_ptr->evd_producer_locking_needed =\r
+           !(evd_flags & (DAT_EVD_DTO_FLAG | DAT_EVD_RMR_BIND_FLAG));\r
+\r
+       /* Before we setup any callbacks, transition state to OPEN.  */\r
+       evd_ptr->evd_state = DAPL_EVD_STATE_OPEN;\r
+\r
+       if (evd_flags & DAT_EVD_ASYNC_FLAG) {\r
+               /*\r
+                * There is no cq associate with async evd. Set it to invalid\r
+                */\r
+               evd_ptr->ib_cq_handle = IB_INVALID_HANDLE;\r
+\r
+       } else if (0 != (evd_flags & ~(DAT_EVD_SOFTWARE_FLAG\r
+                                      | DAT_EVD_CONNECTION_FLAG\r
+                                      | DAT_EVD_CR_FLAG))) {\r
+#if defined(_VENDOR_IBAL_)\r
+               /* \r
+                * The creation of CQ required a PD (PZ) associated with it and\r
+                * we do not have a PD here; therefore, the work-around is that we\r
+                * will postpone the creation of the cq till the creation of QP which\r
+                * this cq will associate with.\r
+                */\r
+               evd_ptr->ib_cq_handle = IB_INVALID_HANDLE;\r
+#else\r
+               dat_status = dapls_ib_cq_alloc(ia_ptr, evd_ptr, &cq_len);\r
+               if (dat_status != DAT_SUCCESS) {\r
+                       goto bail;\r
+               }\r
+\r
+               /* Now reset the cq_len in the attributes, it may have changed */\r
+               evd_ptr->qlen = cq_len;\r
+\r
+               dat_status =\r
+                   dapls_ib_setup_async_callback(ia_ptr,\r
+                                                 DAPL_ASYNC_CQ_COMPLETION,\r
+                                                 evd_ptr,\r
+                                                 (ib_async_handler_t)\r
+                                                 dapl_evd_dto_callback,\r
+                                                 evd_ptr);\r
+               if (dat_status != DAT_SUCCESS) {\r
+                       goto bail;\r
+               }\r
+\r
+               dat_status = dapls_set_cq_notify(ia_ptr, evd_ptr);\r
+\r
+               if (dat_status != DAT_SUCCESS) {\r
+                       goto bail;\r
+               }\r
+#endif                         /* _VENDOR_IBAL_ */\r
+       }\r
+\r
+       /* We now have an accurate count of events, so allocate them into\r
+        * the EVD\r
+        */\r
+       dat_status = dapli_evd_event_alloc(evd_ptr, cq_len);\r
+       if (dat_status != DAT_SUCCESS) {\r
+               goto bail;\r
+       }\r
+\r
+       dapl_ia_link_evd(ia_ptr, evd_ptr);\r
+       *evd_ptr_ptr = evd_ptr;\r
+\r
+      bail:\r
+       if (dat_status != DAT_SUCCESS) {\r
+               if (evd_ptr) {\r
+                       dapls_evd_dealloc(evd_ptr);\r
+               }\r
+       }\r
+\r
+       return dat_status;\r
+}\r
+\r
+/*\r
+ * dapls_evd_alloc\r
+ *\r
+ * alloc and initialize an EVD struct\r
+ *\r
+ * Input:\r
+ *     ia\r
+ *\r
+ * Output:\r
+ *     evd_ptr\r
+ *\r
+ * Returns:\r
+ *     none\r
+ *\r
+ */\r
+DAPL_EVD *dapls_evd_alloc(IN DAPL_IA * ia_ptr,\r
+                         IN DAPL_CNO * cno_ptr,\r
+                         IN DAT_EVD_FLAGS evd_flags, IN DAT_COUNT qlen)\r
+{\r
+       DAPL_EVD *evd_ptr;\r
+\r
+       /* Allocate EVD */\r
+       evd_ptr = (DAPL_EVD *) dapl_os_alloc(sizeof(DAPL_EVD));\r
+       if (!evd_ptr) {\r
+               goto bail;\r
+       }\r
+\r
+       /* zero the structure */\r
+       dapl_os_memzero(evd_ptr, sizeof(DAPL_EVD));\r
+\r
+#ifdef DAPL_COUNTERS\r
+       /* Allocate counters */\r
+       evd_ptr->cntrs =\r
+           dapl_os_alloc(sizeof(DAT_UINT64) * DCNT_EVD_ALL_COUNTERS);\r
+       if (evd_ptr->cntrs == NULL) {\r
+               dapl_os_free(evd_ptr, sizeof(DAPL_EVD));\r
+               return (NULL);\r
+       }\r
+       dapl_os_memzero(evd_ptr->cntrs,\r
+                       sizeof(DAT_UINT64) * DCNT_EVD_ALL_COUNTERS);\r
+#endif                         /* DAPL_COUNTERS */\r
+\r
+       /*\r
+        * initialize the header\r
+        */\r
+       evd_ptr->header.provider = ia_ptr->header.provider;\r
+       evd_ptr->header.magic = DAPL_MAGIC_EVD;\r
+       evd_ptr->header.handle_type = DAT_HANDLE_TYPE_EVD;\r
+       evd_ptr->header.owner_ia = ia_ptr;\r
+       evd_ptr->header.user_context.as_64 = 0;\r
+       evd_ptr->header.user_context.as_ptr = NULL;\r
+       dapl_llist_init_entry(&evd_ptr->header.ia_list_entry);\r
+       dapl_os_lock_init(&evd_ptr->header.lock);\r
+\r
+       /*\r
+        * Initialize the body\r
+        */\r
+       evd_ptr->evd_state = DAPL_EVD_STATE_INITIAL;\r
+       evd_ptr->evd_flags = evd_flags;\r
+       evd_ptr->evd_enabled = DAT_TRUE;\r
+       evd_ptr->evd_waitable = DAT_TRUE;\r
+       evd_ptr->evd_producer_locking_needed = 1;       /* Conservative value.  */\r
+       evd_ptr->ib_cq_handle = IB_INVALID_HANDLE;\r
+       dapl_os_atomic_set(&evd_ptr->evd_ref_count, 0);\r
+       evd_ptr->catastrophic_overflow = DAT_FALSE;\r
+       evd_ptr->qlen = qlen;\r
+       evd_ptr->completion_type = DAPL_EVD_STATE_THRESHOLD;    /* FIXME: should be DAPL_EVD_STATE_INIT */\r
+       dapl_os_wait_object_init(&evd_ptr->wait_object);\r
+\r
+       evd_ptr->cno_active_count = 0;\r
+       if (cno_ptr != NULL) {\r
+               /* Take a reference count on the CNO */\r
+               dapl_os_atomic_inc(&cno_ptr->cno_ref_count);\r
+       }\r
+       evd_ptr->cno_ptr = cno_ptr;\r
+\r
+      bail:\r
+       return evd_ptr;\r
+}\r
+\r
+/*\r
+ * dapls_evd_event_alloc\r
+ *\r
+ * alloc events into an EVD.\r
+ *\r
+ * Input:\r
+ *     evd_ptr\r
+ *     qlen\r
+ *\r
+ * Output:\r
+ *     NONE\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     ERROR\r
+ *\r
+ */\r
+DAT_RETURN dapli_evd_event_alloc(IN DAPL_EVD * evd_ptr, IN DAT_COUNT qlen)\r
+{\r
+       DAT_EVENT *event_ptr;\r
+       DAT_COUNT i;\r
+       DAT_RETURN dat_status;\r
+\r
+       dat_status = DAT_SUCCESS;\r
+\r
+       /* Allocate EVENTs */\r
+       event_ptr =\r
+           (DAT_EVENT *) dapl_os_alloc(evd_ptr->qlen * sizeof(DAT_EVENT));\r
+       if (event_ptr == NULL) {\r
+               dat_status =\r
+                   DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY);\r
+               goto bail;\r
+       }\r
+       evd_ptr->events = event_ptr;\r
+\r
+       /* allocate free event queue */\r
+       dat_status = dapls_rbuf_alloc(&evd_ptr->free_event_queue, qlen);\r
+       if (dat_status != DAT_SUCCESS) {\r
+               goto bail;\r
+       }\r
+\r
+       /* allocate pending event queue */\r
+       dat_status = dapls_rbuf_alloc(&evd_ptr->pending_event_queue, qlen);\r
+       if (dat_status != DAT_SUCCESS) {\r
+               goto bail;\r
+       }\r
+\r
+       /* add events to free event queue */\r
+       for (i = 0; i < evd_ptr->qlen; i++) {\r
+               dapls_rbuf_add(&evd_ptr->free_event_queue, (void *)event_ptr);\r
+               event_ptr++;\r
+       }\r
+\r
+       evd_ptr->cq_notified = DAT_FALSE;\r
+       evd_ptr->cq_notified_when = 0;\r
+       evd_ptr->threshold = 0;\r
+\r
+      bail:\r
+       return dat_status;\r
+}\r
+\r
+/*\r
+ * dapls_evd_event_realloc\r
+ *\r
+ * realloc events into an EVD.\r
+ *\r
+ * Input:\r
+ *     evd_ptr\r
+ *     qlen\r
+ *\r
+ * Output:\r
+ *     NONE\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     ERROR\r
+ *\r
+ */\r
+DAT_RETURN dapls_evd_event_realloc(IN DAPL_EVD * evd_ptr, IN DAT_COUNT qlen)\r
+{\r
+       DAT_EVENT *events;\r
+       DAT_COUNT old_qlen;\r
+       DAT_COUNT i;\r
+       intptr_t diff;\r
+       DAT_RETURN dat_status;\r
+\r
+       /* Allocate EVENTs */\r
+       events = (DAT_EVENT *) dapl_os_realloc(evd_ptr->events,\r
+                                              qlen * sizeof(DAT_EVENT));\r
+       if (NULL == events) {\r
+               dat_status =\r
+                   DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY);\r
+               goto bail;\r
+       }\r
+\r
+       diff = events - evd_ptr->events;\r
+       evd_ptr->events = events;\r
+\r
+       old_qlen = evd_ptr->qlen;\r
+       evd_ptr->qlen = qlen;\r
+\r
+       /* reallocate free event queue */\r
+       dat_status = dapls_rbuf_realloc(&evd_ptr->free_event_queue, qlen);\r
+       if (dat_status != DAT_SUCCESS) {\r
+               goto bail;\r
+       }\r
+       dapls_rbuf_adjust(&evd_ptr->free_event_queue, diff);\r
+\r
+       /* reallocate pending event queue */\r
+       dat_status = dapls_rbuf_realloc(&evd_ptr->pending_event_queue, qlen);\r
+       if (dat_status != DAT_SUCCESS) {\r
+               goto bail;\r
+       }\r
+       dapls_rbuf_adjust(&evd_ptr->pending_event_queue, diff);\r
+\r
+       /*\r
+        * add new events to free event queue. \r
+        */\r
+       for (i = old_qlen; i < qlen; i++) {\r
+               dapls_rbuf_add(&evd_ptr->free_event_queue, (void *)&events[i]);\r
+       }\r
+\r
+      bail:\r
+       return dat_status;\r
+}\r
+\r
+/*\r
+ * dapls_evd_dealloc\r
+ *\r
+ * Free the passed in EVD structure. If an error occurs, this function\r
+ * will clean up all of the internal data structures and report the\r
+ * error.\r
+ *\r
+ * Input:\r
+ *     evd_ptr\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     status\r
+ *\r
+ */\r
+DAT_RETURN dapls_evd_dealloc(IN DAPL_EVD * evd_ptr)\r
+{\r
+       DAT_RETURN dat_status;\r
+       DAPL_IA *ia_ptr;\r
+\r
+       dat_status = DAT_SUCCESS;\r
+\r
+       dapl_os_assert(evd_ptr->header.magic == DAPL_MAGIC_EVD);\r
+       dapl_os_assert(dapl_os_atomic_read(&evd_ptr->evd_ref_count) == 0);\r
+\r
+       /*\r
+        * Destroy the CQ first, to keep any more callbacks from coming\r
+        * up from it.\r
+        */\r
+       evd_ptr->evd_enabled = DAT_FALSE;\r
+       if (evd_ptr->ib_cq_handle != IB_INVALID_HANDLE) {\r
+               ia_ptr = evd_ptr->header.owner_ia;\r
+\r
+               dat_status = dapls_ib_cq_free(ia_ptr, evd_ptr);\r
+               if (dat_status != DAT_SUCCESS) {\r
+                       goto bail;\r
+               }\r
+       }\r
+\r
+       /*\r
+        * We should now be safe to invalidate the EVD; reset the\r
+        * magic to prevent reuse.\r
+        */\r
+       evd_ptr->header.magic = DAPL_MAGIC_INVALID;\r
+\r
+       /* Release reference on the CNO if it exists */\r
+       if (evd_ptr->cno_ptr != NULL) {\r
+               dapl_os_atomic_dec(&evd_ptr->cno_ptr->cno_ref_count);\r
+               evd_ptr->cno_ptr = NULL;\r
+       }\r
+\r
+       /* If the ring buffer allocation failed, then the dapls_rbuf_destroy   */\r
+       /* function will detect that the ring buffer's internal data (ex. base */\r
+       /* pointer) are invalid and will handle the situation appropriately    */\r
+       dapls_rbuf_destroy(&evd_ptr->free_event_queue);\r
+       dapls_rbuf_destroy(&evd_ptr->pending_event_queue);\r
+\r
+       if (evd_ptr->events) {\r
+               dapl_os_free(evd_ptr->events,\r
+                            evd_ptr->qlen * sizeof(DAT_EVENT));\r
+       }\r
+\r
+       dapl_os_wait_object_destroy(&evd_ptr->wait_object);\r
+\r
+#ifdef DAPL_COUNTERS\r
+       dapl_os_free(evd_ptr->cntrs,\r
+                    sizeof(DAT_UINT64) * DCNT_EVD_ALL_COUNTERS);\r
+#endif                         /* DAPL_COUNTERS */\r
+\r
+       dapl_os_free(evd_ptr, sizeof(DAPL_EVD));\r
+\r
+      bail:\r
+       return dat_status;\r
+}\r
+\r
+STATIC _INLINE_ char *DAPL_GET_DTO_OP_STR(int op)\r
+{\r
+       static char *dto_ops[] = {\r
+               "OP_SEND",\r
+               "OP_RECEIVE",\r
+               "OP_RDMA_WRITE",\r
+               "OP_RDMA_READ"\r
+       };\r
+       return ((op < 0 || op > 3) ? "Invalid DTO OP?" : dto_ops[op]);\r
+}\r
+\r
+#if !defined(DAPL_GET_CQE_OP_STR)\r
+#define DAPL_GET_CQE_OP_STR(e) "Unknown CEQ OP String?"\r
+#endif\r
+#if !defined(DAPL_GET_CQE_VENDOR_ERR)\r
+#define DAPL_GET_CQE_VENDOR_ERR(e) 0\r
+#endif\r
+\r
+/*\r
+ * dapli_evd_eh_print_cqe\r
+ *\r
+ * Input:\r
+ *     cqe_ptr\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Prints out a CQE for debug purposes\r
+ *\r
+ */\r
+\r
+void dapli_evd_eh_print_cqe(IN ib_work_completion_t * cqe_ptr)\r
+{\r
+#ifdef DAPL_DBG\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,\r
+                    "\t >>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<\n");\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,\r
+                    "\t dapl_evd_dto_callback : CQE \n");\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,\r
+                    "\t\t work_req_id %lli\n", DAPL_GET_CQE_WRID(cqe_ptr));\r
+       if (DAPL_GET_CQE_STATUS(cqe_ptr) == 0) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,\r
+                            "\t\t op_type: %s\n",\r
+                            DAPL_GET_CQE_OP_STR(cqe_ptr));\r
+               dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,\r
+                            "\t\t bytes_num %d\n",\r
+                            DAPL_GET_CQE_BYTESNUM(cqe_ptr));\r
+       }\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,\r
+                    "\t\t status %d vendor_err 0x%x\n",\r
+                    DAPL_GET_CQE_STATUS(cqe_ptr),\r
+                    DAPL_GET_CQE_VENDOR_ERR(cqe_ptr));\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,\r
+                    "\t >>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<\n");\r
+#endif\r
+       return;\r
+}\r
+\r
+/*\r
+ * Event posting code follows.\r
+ */\r
+\r
+/*\r
+ * These next two functions (dapli_evd_get_event and dapli_evd_post_event)\r
+ * are a pair.  They are always called together, from one of the functions\r
+ * at the end of this file (dapl_evd_post_*_event).\r
+ *\r
+ * Note that if producer side locking is enabled, the first one takes the\r
+ * EVD lock and the second releases it.\r
+ */\r
+\r
+/* dapli_evd_get_event\r
+ *\r
+ * Get an event struct from the evd.  The caller should fill in the event\r
+ * and call dapl_evd_post_event.\r
+ *\r
+ * If there are no events available, an overflow event is generated to the\r
+ * async EVD handler.\r
+ *\r
+ * If this EVD required producer locking, a successful return implies\r
+ * that the lock is held.\r
+ *\r
+ * Input:\r
+ *     evd_ptr\r
+ *\r
+ * Output:\r
+ *     event\r
+ *\r
+ */\r
+\r
+static DAT_EVENT *dapli_evd_get_event(DAPL_EVD * evd_ptr)\r
+{\r
+       DAT_EVENT *event;\r
+\r
+       if (evd_ptr->evd_producer_locking_needed) {\r
+               dapl_os_lock(&evd_ptr->header.lock);\r
+       }\r
+\r
+       event = (DAT_EVENT *) dapls_rbuf_remove(&evd_ptr->free_event_queue);\r
+\r
+       /* Release the lock if it was taken and the call failed.  */\r
+       if (!event && evd_ptr->evd_producer_locking_needed) {\r
+               dapl_os_unlock(&evd_ptr->header.lock);\r
+       }\r
+\r
+       return event;\r
+}\r
+\r
+/* dapli_evd_post_event\r
+ *\r
+ * Post the <event> to the evd.  If possible, invoke the evd's CNO.\r
+ * Otherwise post the event on the pending queue.\r
+ *\r
+ * If producer side locking is required, the EVD lock must be held upon\r
+ * entry to this function.\r
+ *\r
+ * Input:\r
+ *     evd_ptr\r
+ *     event\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ */\r
+\r
+static void\r
+dapli_evd_post_event(IN DAPL_EVD * evd_ptr, IN const DAT_EVENT * event_ptr)\r
+{\r
+       DAT_RETURN dat_status;\r
+       DAPL_CNO *cno_to_trigger = NULL;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_EVD, "%s: Called with event %s\n",\r
+                    __FUNCTION__, dapl_event_str(event_ptr->event_number));\r
+\r
+       dat_status = dapls_rbuf_add(&evd_ptr->pending_event_queue,\r
+                                   (void *)event_ptr);\r
+       dapl_os_assert(dat_status == DAT_SUCCESS);\r
+\r
+       dapl_os_assert(evd_ptr->evd_state == DAPL_EVD_STATE_WAITED\r
+                      || evd_ptr->evd_state == DAPL_EVD_STATE_OPEN);\r
+\r
+       if (evd_ptr->evd_state == DAPL_EVD_STATE_OPEN) {\r
+               /* No waiter.  Arrange to trigger a CNO if it exists.  */\r
+\r
+               if (evd_ptr->evd_enabled) {\r
+                       cno_to_trigger = evd_ptr->cno_ptr;\r
+               }\r
+               if (evd_ptr->evd_producer_locking_needed) {\r
+                       dapl_os_unlock(&evd_ptr->header.lock);\r
+               }\r
+       } else {\r
+               /*\r
+                * We're in DAPL_EVD_STATE_WAITED.  Take the lock if\r
+                * we don't have it, recheck, and signal.\r
+                */\r
+               if (!evd_ptr->evd_producer_locking_needed) {\r
+                       dapl_os_lock(&evd_ptr->header.lock);\r
+               }\r
+\r
+               if (evd_ptr->evd_state == DAPL_EVD_STATE_WAITED\r
+                   && (dapls_rbuf_count(&evd_ptr->pending_event_queue)\r
+                       >= evd_ptr->threshold)) {\r
+                       dapl_os_unlock(&evd_ptr->header.lock);\r
+\r
+                       if (evd_ptr->evd_flags & (DAT_EVD_DTO_FLAG | DAT_EVD_RMR_BIND_FLAG)) {\r
+                               dapls_evd_dto_wakeup(evd_ptr);\r
+                       } else {\r
+                               dapl_os_wait_object_wakeup(&evd_ptr->wait_object);\r
+                       }\r
+\r
+               } else {\r
+                       dapl_os_unlock(&evd_ptr->header.lock);\r
+               }\r
+       }\r
+\r
+       if (cno_to_trigger != NULL) {\r
+               dapl_internal_cno_trigger(cno_to_trigger, evd_ptr);\r
+       }\r
+}\r
+\r
+/* dapli_evd_post_event_nosignal\r
+ *\r
+ * Post the <event> to the evd.  Do not do any wakeup processing.\r
+ * This function should only be called if it is known that there are\r
+ * no waiters that it is appropriate to wakeup on this EVD.  An example\r
+ * of such a situation is during internal dat_evd_wait() processing.\r
+ *\r
+ * If producer side locking is required, the EVD lock must be held upon\r
+ * entry to this function.\r
+ *\r
+ * Input:\r
+ *     evd_ptr\r
+ *     event\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ */\r
+\r
+static void\r
+dapli_evd_post_event_nosignal(IN DAPL_EVD * evd_ptr,\r
+                             IN const DAT_EVENT * event_ptr)\r
+{\r
+       DAT_RETURN dat_status;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_EVD, "%s: Called with event %s\n",\r
+                    __FUNCTION__, dapl_event_str(event_ptr->event_number));\r
+\r
+       dat_status = dapls_rbuf_add(&evd_ptr->pending_event_queue,\r
+                                   (void *)event_ptr);\r
+       dapl_os_assert(dat_status == DAT_SUCCESS);\r
+\r
+       dapl_os_assert(evd_ptr->evd_state == DAPL_EVD_STATE_WAITED\r
+                      || evd_ptr->evd_state == DAPL_EVD_STATE_OPEN);\r
+\r
+       if (evd_ptr->evd_producer_locking_needed) {\r
+               dapl_os_unlock(&evd_ptr->header.lock);\r
+       }\r
+}\r
+\r
+/* dapli_evd_format_overflow_event\r
+ *\r
+ * format an overflow event for posting\r
+ *\r
+ * Input:\r
+ *     evd_ptr\r
+ *     event_ptr\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ */\r
+static void\r
+dapli_evd_format_overflow_event(IN DAPL_EVD * evd_ptr,\r
+                               OUT DAT_EVENT * event_ptr)\r
+{\r
+       DAPL_IA *ia_ptr;\r
+\r
+       ia_ptr = evd_ptr->header.owner_ia;\r
+\r
+       event_ptr->evd_handle = (DAT_EVD_HANDLE) evd_ptr;\r
+       event_ptr->event_number = DAT_ASYNC_ERROR_EVD_OVERFLOW;\r
+       event_ptr->event_data.asynch_error_event_data.dat_handle =\r
+           (DAT_HANDLE) ia_ptr;\r
+}\r
+\r
+/* dapli_evd_post_overflow_event\r
+ *\r
+ * post an overflow event\r
+ *\r
+ * Input:\r
+ *     async_evd_ptr\r
+ *     evd_ptr\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ */\r
+static void\r
+dapli_evd_post_overflow_event(IN DAPL_EVD * async_evd_ptr,\r
+                             IN DAPL_EVD * overflow_evd_ptr)\r
+{\r
+       DAT_EVENT *overflow_event;\r
+\r
+       /* The overflow_evd_ptr mght be the same as evd.\r
+        * In that case we've got a catastrophic overflow.\r
+        */\r
+       dapl_log(DAPL_DBG_TYPE_WARN,\r
+                " WARNING: overflow event on EVD %p/n", overflow_evd_ptr);\r
+\r
+       if (async_evd_ptr == overflow_evd_ptr) {\r
+               async_evd_ptr->catastrophic_overflow = DAT_TRUE;\r
+               async_evd_ptr->evd_state = DAPL_EVD_STATE_DEAD;\r
+               return;\r
+       }\r
+\r
+       overflow_event = dapli_evd_get_event(overflow_evd_ptr);\r
+       if (!overflow_event) {\r
+               /* this is not good */\r
+               overflow_evd_ptr->catastrophic_overflow = DAT_TRUE;\r
+               overflow_evd_ptr->evd_state = DAPL_EVD_STATE_DEAD;\r
+               return;\r
+       }\r
+       dapli_evd_format_overflow_event(overflow_evd_ptr, overflow_event);\r
+       dapli_evd_post_event(overflow_evd_ptr, overflow_event);\r
+\r
+       return;\r
+}\r
+\r
+static DAT_EVENT *dapli_evd_get_and_init_event(IN DAPL_EVD * evd_ptr,\r
+                                              IN DAT_EVENT_NUMBER event_number)\r
+{\r
+       DAT_EVENT *event_ptr;\r
+\r
+       event_ptr = dapli_evd_get_event(evd_ptr);\r
+       if (NULL == event_ptr) {\r
+               dapli_evd_post_overflow_event(evd_ptr->header.owner_ia->\r
+                                             async_error_evd, evd_ptr);\r
+       } else {\r
+               event_ptr->evd_handle = (DAT_EVD_HANDLE) evd_ptr;\r
+               event_ptr->event_number = event_number;\r
+       }\r
+\r
+       return event_ptr;\r
+}\r
+\r
+DAT_RETURN\r
+dapls_evd_post_cr_arrival_event(IN DAPL_EVD * evd_ptr,\r
+                               IN DAT_EVENT_NUMBER event_number,\r
+                               IN DAT_SP_HANDLE sp_handle,\r
+                               DAT_IA_ADDRESS_PTR ia_address_ptr,\r
+                               DAT_CONN_QUAL conn_qual,\r
+                               DAT_CR_HANDLE cr_handle)\r
+{\r
+       DAT_EVENT *event_ptr;\r
+       event_ptr = dapli_evd_get_and_init_event(evd_ptr, event_number);\r
+       /*\r
+        * Note event lock may be held on successful return\r
+        * to be released by dapli_evd_post_event(), if provider side locking\r
+        * is needed.\r
+        */\r
+\r
+       if (event_ptr == NULL) {\r
+               return DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,\r
+                                DAT_RESOURCE_MEMORY);\r
+       }\r
+\r
+       event_ptr->event_data.cr_arrival_event_data.sp_handle = sp_handle;\r
+       event_ptr->event_data.cr_arrival_event_data.local_ia_address_ptr\r
+           = ia_address_ptr;\r
+       event_ptr->event_data.cr_arrival_event_data.conn_qual = conn_qual;\r
+       event_ptr->event_data.cr_arrival_event_data.cr_handle = cr_handle;\r
+\r
+       dapli_evd_post_event(evd_ptr, event_ptr);\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+DAT_RETURN\r
+dapls_evd_post_connection_event(IN DAPL_EVD * evd_ptr,\r
+                               IN DAT_EVENT_NUMBER event_number,\r
+                               IN DAT_EP_HANDLE ep_handle,\r
+                               IN DAT_COUNT private_data_size,\r
+                               IN DAT_PVOID private_data)\r
+{\r
+       DAT_EVENT *event_ptr;\r
+       event_ptr = dapli_evd_get_and_init_event(evd_ptr, event_number);\r
+       /*\r
+        * Note event lock may be held on successful return\r
+        * to be released by dapli_evd_post_event(), if provider side locking\r
+        * is needed.\r
+        */\r
+\r
+       if (event_ptr == NULL) {\r
+               return DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,\r
+                                DAT_RESOURCE_MEMORY);\r
+       }\r
+\r
+       event_ptr->event_data.connect_event_data.ep_handle = ep_handle;\r
+       event_ptr->event_data.connect_event_data.private_data_size\r
+           = private_data_size;\r
+       event_ptr->event_data.connect_event_data.private_data = private_data;\r
+\r
+       dapli_evd_post_event(evd_ptr, event_ptr);\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+DAT_RETURN\r
+dapls_evd_post_async_error_event(IN DAPL_EVD * evd_ptr,\r
+                                IN DAT_EVENT_NUMBER event_number,\r
+                                IN DAT_IA_HANDLE ia_handle)\r
+{\r
+       DAT_EVENT *event_ptr;\r
+       event_ptr = dapli_evd_get_and_init_event(evd_ptr, event_number);\r
+       /*\r
+        * Note event lock may be held on successful return\r
+        * to be released by dapli_evd_post_event(), if provider side locking\r
+        * is needed.\r
+        */\r
+       dapl_log(DAPL_DBG_TYPE_WARN,\r
+                " WARNING: async event - %s evd=%p/n",\r
+                dapl_event_str(event_number), evd_ptr);\r
+\r
+       if (event_ptr == NULL) {\r
+               return DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,\r
+                                DAT_RESOURCE_MEMORY);\r
+       }\r
+\r
+       event_ptr->event_data.asynch_error_event_data.dat_handle =\r
+           (DAT_HANDLE) ia_handle;\r
+\r
+       dapli_evd_post_event(evd_ptr, event_ptr);\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+DAT_RETURN\r
+dapls_evd_post_software_event(IN DAPL_EVD * evd_ptr,\r
+                             IN DAT_EVENT_NUMBER event_number,\r
+                             IN DAT_PVOID pointer)\r
+{\r
+       DAT_EVENT *event_ptr;\r
+       event_ptr = dapli_evd_get_and_init_event(evd_ptr, event_number);\r
+       /*\r
+        * Note event lock may be held on successful return\r
+        * to be released by dapli_evd_post_event(), if provider side locking\r
+        * is needed.\r
+        */\r
+\r
+       if (event_ptr == NULL) {\r
+               return DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,\r
+                                DAT_RESOURCE_MEMORY);\r
+       }\r
+\r
+       event_ptr->event_data.software_event_data.pointer = pointer;\r
+\r
+       dapli_evd_post_event(evd_ptr, event_ptr);\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * dapls_evd_post_generic_event\r
+ *\r
+ * Post a generic event type. Not used by all providers\r
+ *\r
+ * Input:\r
+ *     evd_ptr\r
+ *     event_number\r
+ *     data\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_evd_post_generic_event(IN DAPL_EVD * evd_ptr,\r
+                            IN DAT_EVENT_NUMBER event_number,\r
+                            IN DAT_EVENT_DATA * data)\r
+{\r
+       DAT_EVENT *event_ptr;\r
+\r
+       event_ptr = dapli_evd_get_and_init_event(evd_ptr, event_number);\r
+       /*\r
+        * Note event lock may be held on successful return\r
+        * to be released by dapli_evd_post_event(), if provider side locking\r
+        * is needed.\r
+        */\r
+\r
+       if (event_ptr == NULL) {\r
+               return DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,\r
+                                DAT_RESOURCE_MEMORY);\r
+       }\r
+\r
+       event_ptr->event_data = *data;\r
+\r
+       dapli_evd_post_event(evd_ptr, event_ptr);\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+#ifdef DAT_EXTENSIONS\r
+DAT_RETURN\r
+dapls_evd_post_cr_event_ext(IN DAPL_SP * sp_ptr,\r
+                           IN DAT_EVENT_NUMBER event_number,\r
+                           IN dp_ib_cm_handle_t ib_cm_handle,\r
+                           IN DAT_COUNT p_size,\r
+                           IN DAT_PVOID p_data, IN DAT_PVOID ext_data)\r
+{\r
+       DAPL_CR *cr_ptr;\r
+       DAPL_EP *ep_ptr;\r
+       DAT_EVENT *event_ptr;\r
+       DAT_SP_HANDLE sp_handle;\r
+\r
+       dapl_os_lock(&sp_ptr->header.lock);\r
+       if (sp_ptr->listening == DAT_FALSE) {\r
+               dapl_os_unlock(&sp_ptr->header.lock);\r
+               dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                            "---> post_cr_event_ext: conn event on down SP\n");\r
+               (void)dapls_ib_reject_connection(ib_cm_handle,\r
+                                                DAT_CONNECTION_EVENT_UNREACHABLE,\r
+                                                0, NULL);\r
+               return DAT_CONN_QUAL_UNAVAILABLE;\r
+       }\r
+\r
+       /*\r
+        * RSP connections only allow a single connection. Close\r
+        * it down NOW so we reject any further connections.\r
+        */\r
+       if (sp_ptr->header.handle_type == DAT_HANDLE_TYPE_RSP)\r
+               sp_ptr->listening = DAT_FALSE;\r
+\r
+       dapl_os_unlock(&sp_ptr->header.lock);\r
+\r
+       /* allocate new connect request */\r
+       cr_ptr = dapls_cr_alloc(sp_ptr->header.owner_ia);\r
+       if (cr_ptr == NULL)\r
+               return DAT_INSUFFICIENT_RESOURCES;\r
+\r
+       /* Set up the CR */\r
+       cr_ptr->sp_ptr = sp_ptr;        /* maintain sp_ptr in case of reject */\r
+       cr_ptr->param.remote_port_qual = 0;\r
+       cr_ptr->ib_cm_handle = ib_cm_handle;\r
+       cr_ptr->param.remote_ia_address_ptr =\r
+           (DAT_IA_ADDRESS_PTR) & cr_ptr->remote_ia_address;\r
+\r
+       /*\r
+        * Copy the remote address and private data out of the private_data\r
+        */\r
+       cr_ptr->param.private_data = cr_ptr->private_data;\r
+       cr_ptr->param.private_data_size = p_size;\r
+       if (p_size)\r
+               dapl_os_memcpy(cr_ptr->private_data, p_data, p_size);\r
+\r
+       /* EP will be NULL unless RSP service point */\r
+       ep_ptr = (DAPL_EP *) sp_ptr->ep_handle;\r
+\r
+       if (sp_ptr->psp_flags == DAT_PSP_PROVIDER_FLAG) {\r
+               DAPL_IA *ia_ptr;\r
+               /*\r
+                * Never true for RSP connections\r
+                *\r
+                * Create an EP for the user. If we can't allocate an\r
+                * EP we are out of resources and need to tell the\r
+                * requestor that we cant help them.\r
+                */\r
+               ia_ptr = sp_ptr->header.owner_ia;\r
+               ep_ptr = dapl_ep_alloc(ia_ptr, NULL);\r
+               if (ep_ptr == NULL) {\r
+                       dapls_cr_free(cr_ptr);\r
+                       /* Invoking function will call dapls_ib_cm_reject() */\r
+                       return DAT_INSUFFICIENT_RESOURCES;\r
+               }\r
+               ep_ptr->param.ia_handle = ia_ptr;\r
+               ep_ptr->param.local_ia_address_ptr =\r
+                   (DAT_IA_ADDRESS_PTR) & ia_ptr->hca_ptr->hca_address;\r
+\r
+               /* Link the EP onto the IA */\r
+               dapl_ia_link_ep(ia_ptr, ep_ptr);\r
+       }\r
+\r
+       cr_ptr->param.local_ep_handle = ep_ptr;\r
+\r
+       if (ep_ptr != NULL) {\r
+               /* Assign valid EP fields: RSP and PSP_PROVIDER_FLAG only */\r
+               if (sp_ptr->psp_flags == DAT_PSP_PROVIDER_FLAG) {\r
+                       ep_ptr->param.ep_state =\r
+                           DAT_EP_STATE_TENTATIVE_CONNECTION_PENDING;\r
+               } else {\r
+                       /* RSP */\r
+                       dapl_os_assert(sp_ptr->header.handle_type ==\r
+                                      DAT_HANDLE_TYPE_RSP);\r
+                       ep_ptr->param.ep_state =\r
+                           DAT_EP_STATE_PASSIVE_CONNECTION_PENDING;\r
+               }\r
+               ep_ptr->cm_handle = ib_cm_handle;\r
+       }\r
+\r
+       /* link the CR onto the SP so we can pick it up later */\r
+       dapl_sp_link_cr(sp_ptr, cr_ptr);\r
+\r
+       /* assign sp_ptr to union to avoid typecast errors from some compilers */\r
+       sp_handle.psp_handle = (DAT_PSP_HANDLE) sp_ptr;\r
+\r
+       /* Post the event.  */\r
+\r
+       /*\r
+        * Note event lock may be held on successful return\r
+        * to be released by dapli_evd_post_event(), if provider side locking\r
+        * is needed.\r
+        */\r
+       event_ptr = dapli_evd_get_and_init_event(sp_ptr->evd_handle,\r
+                                                event_number);\r
+       if (event_ptr == NULL)\r
+               return DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,\r
+                                DAT_RESOURCE_MEMORY);\r
+\r
+       event_ptr->event_data.cr_arrival_event_data.sp_handle = sp_handle;\r
+       event_ptr->event_data.cr_arrival_event_data.local_ia_address_ptr =\r
+           (DAT_IA_ADDRESS_PTR) & sp_ptr->header.owner_ia->hca_ptr->\r
+           hca_address;\r
+       event_ptr->event_data.cr_arrival_event_data.conn_qual =\r
+           sp_ptr->conn_qual;\r
+       event_ptr->event_data.cr_arrival_event_data.cr_handle =\r
+           (DAT_HANDLE) cr_ptr;\r
+\r
+       dapl_os_memcpy(&event_ptr->event_extension_data[0], ext_data, 64);\r
+\r
+       dapli_evd_post_event(sp_ptr->evd_handle, event_ptr);\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+DAT_RETURN\r
+dapls_evd_post_connection_event_ext(IN DAPL_EVD * evd_ptr,\r
+                                   IN DAT_EVENT_NUMBER event_number,\r
+                                   IN DAT_EP_HANDLE ep_handle,\r
+                                   IN DAT_COUNT private_data_size,\r
+                                   IN DAT_PVOID private_data,\r
+                                   IN DAT_PVOID ext_data)\r
+{\r
+       DAT_EVENT *event_ptr;\r
+       event_ptr = dapli_evd_get_and_init_event(evd_ptr, event_number);\r
+       /*\r
+        * Note event lock may be held on successful return\r
+        * to be released by dapli_evd_post_event(), if provider side locking\r
+        * is needed.\r
+        */\r
+       if (event_ptr == NULL)\r
+               return DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,\r
+                                DAT_RESOURCE_MEMORY);\r
+\r
+       event_ptr->event_data.connect_event_data.ep_handle = ep_handle;\r
+       event_ptr->event_data.connect_event_data.private_data_size\r
+           = private_data_size;\r
+       event_ptr->event_data.connect_event_data.private_data = private_data;\r
+\r
+       dapl_os_memcpy(&event_ptr->event_extension_data[0], ext_data, 64);\r
+\r
+       dapli_evd_post_event(evd_ptr, event_ptr);\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+#endif\r
+\r
+/*\r
+ * dapli_evd_cqe_to_event\r
+ *\r
+ * Convert a CQE into an event structure.\r
+ *\r
+ * Input:\r
+ *     evd_ptr\r
+ *     cqe_ptr\r
+ *\r
+ * Output:\r
+ *     event_ptr\r
+ *\r
+ * Returns:\r
+ *     none\r
+ *\r
+ */\r
+static void\r
+dapli_evd_cqe_to_event(IN DAPL_EVD * evd_ptr,\r
+                      IN void *cqe_ptr, OUT DAT_EVENT * event_ptr)\r
+{\r
+       DAPL_EP *ep_ptr;\r
+       DAPL_COOKIE *cookie;\r
+       DAT_DTO_COMPLETION_STATUS dto_status;\r
+       DAPL_COOKIE_BUFFER *buffer;\r
+\r
+       /*\r
+        * All that can be relied on if the status is bad is the status\r
+        * and WRID.\r
+        */\r
+       dto_status = dapls_ib_get_dto_status(cqe_ptr);\r
+\r
+       cookie = (DAPL_COOKIE *) (uintptr_t) DAPL_GET_CQE_WRID(cqe_ptr);\r
+       dapl_os_assert((NULL != cookie));\r
+\r
+       ep_ptr = cookie->ep;\r
+       dapl_os_assert((NULL != ep_ptr));\r
+       if (ep_ptr->header.magic != DAPL_MAGIC_EP) {\r
+               /* ep may have been freed, just return */\r
+               return;\r
+       }\r
+\r
+       dapls_io_trc_update_completion(ep_ptr, cookie, dto_status);\r
+\r
+       event_ptr->evd_handle = (DAT_EVD_HANDLE) evd_ptr;\r
+\r
+       switch (cookie->type) {\r
+       case DAPL_COOKIE_TYPE_DTO:\r
+               {\r
+#ifdef DAT_EXTENSIONS\r
+                       /* Extended via request post or message receive */\r
+                       if ((cookie->val.dto.type == DAPL_DTO_TYPE_EXTENSION) ||\r
+                           (cookie->val.dto.type == DAPL_DTO_TYPE_RECV &&\r
+                            DAPL_GET_CQE_OPTYPE(cqe_ptr) != OP_RECEIVE)) {\r
+                               dapls_cqe_to_event_extension(ep_ptr, cookie,\r
+                                                            cqe_ptr,\r
+                                                            event_ptr);\r
+                               if (cookie->val.dto.type == DAPL_DTO_TYPE_RECV)\r
+                                       dapls_cookie_dealloc(&ep_ptr->\r
+                                                            recv_buffer,\r
+                                                            cookie);\r
+                               else\r
+                                       dapls_cookie_dealloc(&ep_ptr->\r
+                                                            req_buffer,\r
+                                                            cookie);\r
+                               break;\r
+                       }\r
+#endif\r
+\r
+                       if (DAPL_DTO_TYPE_RECV == cookie->val.dto.type)\r
+                               buffer = &ep_ptr->recv_buffer;\r
+                       else\r
+                               buffer = &ep_ptr->req_buffer;\r
+\r
+                       event_ptr->event_number = DAT_DTO_COMPLETION_EVENT;\r
+                       event_ptr->event_data.dto_completion_event_data.\r
+                           ep_handle = cookie->ep;\r
+                       event_ptr->event_data.dto_completion_event_data.\r
+                           user_cookie = cookie->val.dto.cookie;\r
+                       event_ptr->event_data.dto_completion_event_data.status =\r
+                           dto_status;\r
+\r
+                       if (cookie->val.dto.type == DAPL_DTO_TYPE_SEND ||\r
+                           cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_WRITE) {\r
+                               /* Get size from DTO; CQE value may be off.  */\r
+                               event_ptr->event_data.dto_completion_event_data.\r
+                                   transfered_length = cookie->val.dto.size;\r
+                       } else {\r
+                               event_ptr->event_data.dto_completion_event_data.\r
+                                   transfered_length =\r
+                                   DAPL_GET_CQE_BYTESNUM(cqe_ptr);\r
+                       }\r
+\r
+                       dapls_cookie_dealloc(buffer, cookie);\r
+                       break;\r
+               }\r
+\r
+       case DAPL_COOKIE_TYPE_RMR:\r
+               {\r
+                       event_ptr->event_number = DAT_RMR_BIND_COMPLETION_EVENT;\r
+\r
+                       event_ptr->event_data.rmr_completion_event_data.\r
+                           rmr_handle = cookie->val.rmr.rmr;\r
+                       event_ptr->event_data.rmr_completion_event_data.\r
+                           user_cookie = cookie->val.rmr.cookie;\r
+                       if (dto_status == DAT_DTO_SUCCESS) {\r
+                               event_ptr->event_data.rmr_completion_event_data.\r
+                                   status = DAT_RMR_BIND_SUCCESS;\r
+                               dapl_os_assert((DAPL_GET_CQE_OPTYPE(cqe_ptr)) ==\r
+                                              OP_BIND_MW);\r
+                       } else {\r
+                               dapl_dbg_log(DAPL_DBG_TYPE_DTO_COMP_ERR,\r
+                                            " MW bind completion ERROR: %d: op %#x ep: %p\n",\r
+                                            dto_status,\r
+                                            DAPL_GET_CQE_OPTYPE(cqe_ptr),\r
+                                            ep_ptr);\r
+                               event_ptr->event_data.rmr_completion_event_data.\r
+                                   status = DAT_RMR_OPERATION_FAILED;\r
+                               dapl_os_atomic_dec(&cookie->val.rmr.rmr->lmr->\r
+                                                  lmr_ref_count);\r
+                       }\r
+\r
+                       dapls_cookie_dealloc(&ep_ptr->req_buffer, cookie);\r
+                       break;\r
+               }\r
+       default:\r
+               {\r
+                       dapl_os_assert(!"Invalid Operation type");\r
+                       break;\r
+               }\r
+       }                       /* end switch */\r
+\r
+       /*\r
+        * Most error DTO ops result in disconnecting the EP. See\r
+        * IBTA Vol 1.1, Chapter 10,Table 68, for expected effect on\r
+        * state.\r
+        */\r
+       if ((dto_status != DAT_DTO_SUCCESS) &&\r
+           (dto_status != DAT_DTO_ERR_FLUSHED)) {\r
+               DAPL_EVD *evd_ptr;\r
+\r
+               /*\r
+                * If we are connected, generate disconnect and generate an\r
+                * event. We may be racing with other disconnect ops, so we\r
+                * need to check. We may also be racing CM connection events,\r
+                * requiring us to check for connection pending states too.\r
+                */\r
+               dapl_os_lock(&ep_ptr->header.lock);\r
+               if (ep_ptr->param.ep_state == DAT_EP_STATE_CONNECTED ||\r
+                   ep_ptr->param.ep_state ==\r
+                   DAT_EP_STATE_ACTIVE_CONNECTION_PENDING\r
+                   || ep_ptr->param.ep_state ==\r
+                   DAT_EP_STATE_PASSIVE_CONNECTION_PENDING\r
+                   || ep_ptr->param.ep_state ==\r
+                   DAT_EP_STATE_COMPLETION_PENDING)\r
+               {\r
+                       ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;\r
+                       dapl_os_unlock(&ep_ptr->header.lock);\r
+                       dapls_io_trc_dump(ep_ptr, cqe_ptr, dto_status);\r
+\r
+                       /* Let the other side know we have disconnected */\r
+                       (void)dapls_ib_disconnect(ep_ptr,\r
+                                                 DAT_CLOSE_ABRUPT_FLAG);\r
+\r
+                       /* ... and clean up the local side */\r
+                       evd_ptr = (DAPL_EVD *) ep_ptr->param.connect_evd_handle;\r
+                       if (evd_ptr != NULL) {\r
+                               dapls_evd_post_connection_event(evd_ptr,\r
+                                                               DAT_CONNECTION_EVENT_BROKEN,\r
+                                                               (DAT_HANDLE)\r
+                                                               ep_ptr, 0, 0);\r
+                       }\r
+               } else {\r
+                       dapl_os_unlock(&ep_ptr->header.lock);\r
+               }\r
+\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        "DTO completion ERR: status %d, op %s, vendor_err 0x%x - %s\n",\r
+                        DAPL_GET_CQE_STATUS(cqe_ptr),\r
+                        DAPL_GET_DTO_OP_STR(cookie->val.dto.type),\r
+                        DAPL_GET_CQE_VENDOR_ERR(cqe_ptr),\r
+                        inet_ntoa(((struct sockaddr_in *)&ep_ptr->\r
+                                   remote_ia_address)->sin_addr));\r
+       }\r
+}\r
+\r
+/*\r
+ * dapls_evd_copy_cq\r
+ *\r
+ * Copy all entries on a CQ associated with the EVD onto that EVD\r
+ * Up to caller to handle races, if any.  Note that no EVD waiters will\r
+ * be awoken by this copy.\r
+ *\r
+ * Input:\r
+ *     evd_ptr\r
+ *\r
+ * Output:\r
+ *     None\r
+ *\r
+ * Returns:\r
+ *     none\r
+ *\r
+ */\r
+void dapls_evd_copy_cq(DAPL_EVD * evd_ptr)\r
+{\r
+       ib_work_completion_t cur_cqe;\r
+       DAT_RETURN dat_status;\r
+       DAT_EVENT *event;\r
+\r
+       if (evd_ptr->ib_cq_handle == IB_INVALID_HANDLE) {\r
+               /* Nothing to do if no CQ.  */\r
+               return;\r
+       }\r
+\r
+       while (1) {\r
+               dat_status =\r
+                   dapls_ib_completion_poll(evd_ptr->header.owner_ia->hca_ptr,\r
+                                            evd_ptr, &cur_cqe);\r
+\r
+               if (dat_status != DAT_SUCCESS) {\r
+                       break;\r
+               }\r
+\r
+               /* For debugging.  */\r
+               dapli_evd_eh_print_cqe(&cur_cqe);\r
+\r
+               /*\r
+                * Can use DAT_DTO_COMPLETION_EVENT because dapli_evd_cqe_to_event\r
+                * will overwrite.\r
+                */\r
+\r
+               event =\r
+                   dapli_evd_get_and_init_event(evd_ptr,\r
+                                                DAT_DTO_COMPLETION_EVENT);\r
+               if (event == NULL) {\r
+                       /* We've already attempted the overflow post; return.  */\r
+                       return;\r
+               }\r
+\r
+               dapli_evd_cqe_to_event(evd_ptr, &cur_cqe, event);\r
+\r
+               dapli_evd_post_event_nosignal(evd_ptr, event);\r
+       }\r
+\r
+       if (DAT_GET_TYPE(dat_status) != DAT_QUEUE_EMPTY) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_EVD,\r
+                            "dapls_evd_copy_cq: dapls_ib_completion_poll returned 0x%x\n",\r
+                            dat_status);\r
+               dapl_os_assert(!"Bad return from dapls_ib_completion_poll");\r
+       }\r
+}\r
+\r
+/*\r
+ * dapls_evd_cq_poll_to_event\r
+ *\r
+ * Attempt to dequeue a single CQE from a CQ and turn it into\r
+ * an event.\r
+ *\r
+ * Input:\r
+ *     evd_ptr\r
+ *\r
+ * Output:\r
+ *     event\r
+ *\r
+ * Returns:\r
+ *     Status of operation\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_evd_cq_poll_to_event(IN DAPL_EVD * evd_ptr, OUT DAT_EVENT * event)\r
+{\r
+       DAT_RETURN dat_status;\r
+       ib_work_completion_t cur_cqe;\r
+\r
+       dat_status = dapls_ib_completion_poll(evd_ptr->header.owner_ia->hca_ptr,\r
+                                             evd_ptr, &cur_cqe);\r
+       if (dat_status == DAT_SUCCESS) {\r
+               /* For debugging.  */\r
+               dapli_evd_eh_print_cqe(&cur_cqe);\r
+\r
+               dapli_evd_cqe_to_event(evd_ptr, &cur_cqe, event);\r
+       }\r
+\r
+       return dat_status;\r
+}\r
+\r
+#ifdef DAPL_DBG_IO_TRC\r
+/*\r
+ * Update I/O completions in the I/O trace buffer. I/O is posted to\r
+ * the buffer, then we find it here using the cookie and mark it\r
+ * completed with the completion status\r
+ */\r
+void\r
+dapls_io_trc_update_completion(DAPL_EP * ep_ptr,\r
+                              DAPL_COOKIE * cookie,\r
+                              DAT_DTO_COMPLETION_STATUS dto_status)\r
+{\r
+       int i;\r
+       static unsigned int c_cnt = 1;\r
+\r
+       for (i = 0; i < DBG_IO_TRC_QLEN; i++) {\r
+               if (ep_ptr->ibt_base[i].cookie == cookie) {\r
+                       ep_ptr->ibt_base[i].status = dto_status;\r
+                       ep_ptr->ibt_base[i].done = c_cnt++;\r
+               }\r
+       }\r
+}\r
+\r
+/*\r
+ * Dump the I/O trace buffers\r
+ */\r
+void\r
+dapls_io_trc_dump(DAPL_EP * ep_ptr,\r
+                 void *cqe_ptr, DAT_DTO_COMPLETION_STATUS dto_status)\r
+{\r
+       struct io_buf_track *ibt;\r
+       int i;\r
+       int cnt;\r
+\r
+       dapl_os_printf("DISCONNECTING: dto_status     = %x\n", dto_status);\r
+       dapl_os_printf("               OpType        = %x\n",\r
+                      DAPL_GET_CQE_OPTYPE(cqe_ptr));\r
+       dapl_os_printf("               Bytes         = %x\n",\r
+                      DAPL_GET_CQE_BYTESNUM(cqe_ptr));\r
+       dapl_os_printf("               WRID (cookie) = %llx\n",\r
+                      DAPL_GET_CQE_WRID(cqe_ptr));\r
+\r
+       if (ep_ptr->ibt_dumped == 0) {\r
+\r
+               dapl_os_printf("EP %p (qpn %d) I/O trace buffer\n",\r
+                              ep_ptr, ep_ptr->qpn);\r
+\r
+               ep_ptr->ibt_dumped = 1;\r
+               ibt =\r
+                   (struct io_buf_track *)dapls_rbuf_remove(&ep_ptr->\r
+                                                            ibt_queue);\r
+               cnt = DBG_IO_TRC_QLEN;\r
+               while (ibt != NULL && cnt > 0) {\r
+                       dapl_os_printf\r
+                           ("%2d. %3s (%2d, %d) OP: %x cookie %p wqe %p rmv_target_addr %llx rmv_rmr_context %x\n",\r
+                            cnt, ibt->done == 0 ? "WRK" : "DON", ibt->status,\r
+                            ibt->done, ibt->op_type, ibt->cookie, ibt->wqe,\r
+                            ibt->remote_iov.target_address,\r
+                            ibt->remote_iov.rmr_context);\r
+                       for (i = 0; i < 3; i++) {\r
+                               if (ibt->iov[i].segment_length != 0) {\r
+                                       dapl_os_printf\r
+                                           ("     (%4llx, %8x, %8llx)\n",\r
+                                            ibt->iov[i].segment_length,\r
+                                            ibt->iov[i].lmr_context,\r
+                                            ibt->iov[i].virtual_address);\r
+                               }\r
+                       }\r
+                       ibt =\r
+                           (struct io_buf_track *)dapls_rbuf_remove(&ep_ptr->\r
+                                                                    ibt_queue);\r
+                       cnt--;\r
+               }\r
+       }\r
+}\r
+#endif                         /* DAPL_DBG_IO_TRC */\r
+\r
+/*\r
+ * Local variables:\r
+ *  c-indent-level: 4\r
+ *  c-basic-offset: 4\r
+ *  tab-width: 8\r
+ * End:\r
+ */\r
index 28de045..11ad8ad 100644 (file)
-
-/*
- * Copyright (c) 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_cq.c
- *
- * PURPOSE: CQ (Completion Qeueu) access routine using IBAL APIs
- *
- * $Id$
- *
- **********************************************************************/
-
-#include "dapl.h"
-#include "dapl_adapter_util.h"
-#include "dapl_evd_util.h"
-#include "dapl_cr_util.h"
-#include "dapl_lmr_util.h"
-#include "dapl_rmr_util.h"
-#include "dapl_cookie.h"
-#include "dapl_ring_buffer_util.h"
-
-#ifndef NO_NAME_SERVICE
-#include "dapl_name_service.h"
-#endif /* NO_NAME_SERVICE */
-
-
-static void
-dapli_ibal_cq_async_error_callback ( IN  ib_async_event_rec_t  *p_err_rec )
-{
-    DAPL_EVD           *evd_ptr = (DAPL_EVD*)((void *)p_err_rec->context);
-    DAPL_EVD           *async_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,
-           "--> DiCqAEC: CQ error %d for EVD context %lx\n", 
-            p_err_rec->code, p_err_rec->context);
-
-    if (DAPL_BAD_HANDLE (evd_ptr, DAPL_MAGIC_EVD))
-    {
-       dapl_dbg_log (DAPL_DBG_TYPE_ERR,
-                      "--> DiCqAEC: invalid EVD %lx\n", evd_ptr);
-       return;
-    }
-               
-    ia_ptr = evd_ptr->header.owner_ia;
-    async_evd_ptr = ia_ptr->async_error_evd;
-    if (async_evd_ptr == NULL)
-    {
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DiCqAEC: can't find async_error_evd on %s HCA\n", 
-                (ia_ptr->header.provider)->device_name );
-        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,"--> DiCqAEC: can't find %s HCA\n", 
-                (ia_ptr->header.provider)->device_name);
-        return;
-    }
-
-    /* find CQ error callback using ia_ptr for context */
-    evd_cb = dapli_find_evd_cb_by_context ( async_evd_ptr, p_ca );
-    if ((evd_cb == NULL) || (evd_cb->pfn_async_cq_err_cb == NULL))
-    {
-       dapl_dbg_log (DAPL_DBG_TYPE_ERR,
-                      "--> DiCqAEC: no ERROR cb on %lx found \n", p_ca);
-       return;
-    }
-
-    /* maps to dapl_evd_cq_async_error_callback(), context is EVD */
-    evd_cb->pfn_async_cq_err_cb( (ib_hca_handle_t)p_ca, 
-                                evd_ptr->ib_cq_handle,
-                                (ib_error_record_t*)&p_err_rec->code,
-                                evd_ptr );
-
-}
-
-
-/*
- * dapli_ibal_cq_competion_callback
- *
- * Completion callback for a CQ
- *
- * Input:
- *     cq_context               User context
- *
- * Output:
- *     none
- *
- * Returns:
- */
-static void
-dapli_ib_cq_completion_cb (
-        IN   const   ib_cq_handle_t   h_cq,
-        IN   void                     *cq_context )
-{
-    DAPL_EVD           *evd_ptr;
-    dapl_ibal_ca_t     *p_ca;
-
-    evd_ptr = (DAPL_EVD *) cq_context;
-
-    dapl_dbg_log (DAPL_DBG_TYPE_CALLBACK, 
-                  "--> DiICCC: cq_completion_cb evd %lx CQ %lx\n", 
-                  evd_ptr, evd_ptr->ib_cq_handle);
-
-    dapl_os_assert (evd_ptr != DAT_HANDLE_NULL);
-
-    p_ca = (dapl_ibal_ca_t *) evd_ptr->header.owner_ia->hca_ptr->ib_hca_handle;
-
-    dapl_os_assert( h_cq == evd_ptr->ib_cq_handle );
-
-    dapl_evd_dto_callback ( (ib_hca_handle_t) p_ca, h_cq, cq_context);
-}
-
-
-/*
- * dapl_ib_cq_late_alloc
- *
- * Alloc a CQ
- *
- * Input:
- *     ia_handle               IA handle
- *     evd_ptr                 pointer to EVD struct
- *     cqlen                   minimum QLen
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *
- */
-DAT_RETURN
-dapls_ib_cq_late_alloc (
-       IN  ib_pd_handle_t        pd_handle,
-        IN  DAPL_EVD              *evd_ptr )
-{
-    ib_cq_create_t  cq_create;
-    ib_api_status_t ib_status;
-    DAT_RETURN      dat_status;
-    dapl_ibal_ca_t  *ibal_ca;
-    
-    dat_status            = DAT_SUCCESS;
-    cq_create.size        = evd_ptr->qlen;
-    
-    ibal_ca = (dapl_ibal_ca_t*)evd_ptr->header.owner_ia->hca_ptr->ib_hca_handle;
-       
-#ifdef CQ_WAIT_OBJECT
-    if (evd_ptr->cq_wait_obj_handle)
-    {
-        cq_create.h_wait_obj  = evd_ptr->cq_wait_obj_handle;
-        cq_create.pfn_comp_cb = NULL;
-    }
-    else 
-#endif
-    {
-        cq_create.h_wait_obj  = NULL;
-        cq_create.pfn_comp_cb = dapli_ib_cq_completion_cb;
-    }
-
-    ib_status = ib_create_cq (
-                        (ib_ca_handle_t)ibal_ca->h_ca,
-                        &cq_create,
-                        evd_ptr /* context */,
-                        dapli_ibal_cq_async_error_callback,
-                        &evd_ptr->ib_cq_handle);
-
-    dat_status = dapl_ib_status_convert (ib_status);
-
-    if ( dat_status != DAT_SUCCESS )
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> DsICLA: failed to create CQ for EVD %lx\n",evd_ptr);
-        goto bail;
-    }
-
-    dapl_dbg_log (DAPL_DBG_TYPE_UTIL, 
-                  "--> DsCQ_alloc: pd=%lx cq=%lx CQsz=%d EVD->Qln=%d\n",
-                  pd_handle, evd_ptr->ib_cq_handle,
-                  cq_create.size, evd_ptr->qlen);
-
-    /*
-     * As long as the CQ size is >= the evd size, then things are OK; sez Arlin.
-     */
-    if ( cq_create.size < (uint32_t)evd_ptr->qlen )
-    {
-        dapl_dbg_log (DAPL_DBG_TYPE_UTIL, 
-                      "--> DsCQ_alloc: created CQ size(%d) < evd->qlen(%d)?\n",
-                      cq_create.size, evd_ptr->qlen);
-       dat_status = dapl_ib_status_convert (IB_INVALID_CQ_SIZE);
-    }
-    
-bail: 
-    return dat_status;
-}
-
-/*
- * dapl_ib_cq_alloc
- *
- * Alloc a CQ
- *
- * Input:
- *     ia_handle               IA handle
- *     evd_ptr                 pointer to EVD struct
- *     cqlen                   minimum QLen
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *
- */
-
-#if 0
-
-/* windows delays CQ creation as a PD (Protection Domain) is required
- * and we do not have one at this juncture. The follow code is for future 
- * reference only.
- */
-
-DAT_RETURN
-dapls_ib_cq_alloc (
-       IN  DAPL_IA             *ia_ptr,
-       IN  DAPL_EVD            *evd_ptr,
-       IN  DAT_COUNT           *cqlen )
-{
-     dapl_dbg_log ( DAPL_DBG_TYPE_UTIL, 
-               "dapls_ib_cq_alloc: evd %lx cqlen=%d \n", evd_ptr, *cqlen );
-
-     struct ibv_comp_channel *channel = ia_ptr->hca_ptr->ib_trans.ib_cq;
-
-#ifdef CQ_WAIT_OBJECT
-     if (evd_ptr->cq_wait_obj_handle)
-       channel = evd_ptr->cq_wait_obj_handle;
-#endif
-
-     /* Call IB verbs to create CQ */
-     evd_ptr->ib_cq_handle = ibv_create_cq(ia_ptr->hca_ptr->ib_hca_handle,
-                                           *cqlen,
-                                           evd_ptr,
-                                           channel,
-                                           0);
-       
-     if (evd_ptr->ib_cq_handle == IB_INVALID_HANDLE) 
-         return        DAT_INSUFFICIENT_RESOURCES;
-
-     /* arm cq for events */
-     dapls_set_cq_notify(ia_ptr, evd_ptr);
-       
-        /* update with returned cq entry size */
-     *cqlen = evd_ptr->ib_cq_handle->cqe;
-
-     dapl_dbg_log ( DAPL_DBG_TYPE_UTIL,
-                    "dapls_ib_cq_alloc: new_cq %lx cqlen=%d \n", 
-                    evd_ptr->ib_cq_handle, *cqlen );
-
-     return DAT_SUCCESS;
-}
-#endif
-
-
-/*
- * dapl_ib_cq_free
- *
- * Dealloc a CQ
- *
- * Input:
- *     ia_handle               IA handle
- *     evd_ptr                 pointer to EVD struct
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INVALID_HANDLE
- *     DAT_INSUFFICIENT_RESOURCES
- *
- */
-DAT_RETURN
-dapls_ib_cq_free (
-        IN  DAPL_IA                *ia_ptr,
-        IN  DAPL_EVD                *evd_ptr)
-{
-    ib_api_status_t             ib_status;
-       
-       if ( ia_ptr == NULL || ia_ptr->header.magic != DAPL_MAGIC_IA )
-       {
-               return DAT_INVALID_HANDLE;
-       }
-
-    ib_status = ib_destroy_cq (evd_ptr->ib_cq_handle, 
-                               /* destroy_callback */ NULL);
-                     
-    return dapl_ib_status_convert (ib_status);
-}
-
-/*
- * dapls_cq_resize
- *
- * Resize CQ completion notifications
- *
- * Input:
- *     ia_handle               IA handle
- *     evd_ptr                 pointer to EVD struct
- *     cqlen                   minimum QLen 
- *
- * Output:
- *     cqlen                   may round up for optimal memory boundaries 
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INVALID_HANDLE
- *     DAT_INSUFFICIENT_RESOURCES
- *
- */
-
-DAT_RETURN
-dapls_ib_cq_resize (
-         IN  DAPL_IA             *ia_ptr,
-         IN  DAPL_EVD            *evd_ptr,
-         IN  DAT_COUNT           *cqlen )
-{
-    ib_api_status_t             ib_status = IB_SUCCESS;
-
-    if ( ia_ptr == NULL || ia_ptr->header.magic != DAPL_MAGIC_IA )
-    {
-       return DAT_INVALID_HANDLE;
-    }
-    /* 
-     * Resize CQ only if CQ handle is valid, may be delayed waiting
-     * for PZ allocation with IBAL 
-     */
-#if defined(_VENDOR_IBAL_)
-    if ( evd_ptr->ib_cq_handle != IB_INVALID_HANDLE ) 
-#endif /* _VENDOR_IBAL_ */
-    {
-       ib_status = ib_modify_cq ( evd_ptr->ib_cq_handle, 
-                                      (uint32_t *)cqlen );
-       dapl_dbg_log (DAPL_DBG_TYPE_EVD,
-                      "ib_modify_cq ( new cqlen = %d, status=%d ) \n",
-                      *cqlen, ib_status );
-    }          
-    return dapl_ib_status_convert (ib_status);
-}
-
-
-/*
- * dapl_set_cq_notify
- *
- * Set up CQ completion notifications
- *
- * Input:
- *     ia_handle               IA handle
- *     evd_ptr                 pointer to EVD struct
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INVALID_HANDLE
- *     DAT_INSUFFICIENT_RESOURCES
- *
- */
-DAT_RETURN
-dapls_set_cq_notify (
-    IN  DAPL_IA            *ia_ptr,
-    IN  DAPL_EVD           *evd_ptr )
-{
-    ib_api_status_t             ib_status;
-       if ( ia_ptr == NULL || ia_ptr->header.magic != DAPL_MAGIC_IA )
-       {
-               return DAT_INVALID_HANDLE;
-       }
-    ib_status = ib_rearm_cq ( 
-                         evd_ptr->ib_cq_handle,
-                         FALSE /* next event but not solicited event */ );
-
-    return dapl_ib_status_convert (ib_status);
-}
-
-
-/*
- * dapls_ib_cqd_create
- *
- * Set up CQ notification event thread
- *
- * Input:
- *     ia_handle       HCA handle
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INVALID_HANDLE
- *     DAT_INSUFFICIENT_RESOURCES
- *
- */
-DAT_RETURN
-dapls_ib_cqd_create ( IN  DAPL_HCA  *p_hca )
-{
-    /*
-     * We do not have CQD concept
-     */
-    p_hca->ib_trans.ib_cqd_handle = IB_INVALID_HANDLE;
-
-    return DAT_SUCCESS;
-}
-
-
-/*
- * dapl_cqd_destroy
- *
- * Destroy CQ notification event thread
- *
- * Input:
- *     ia_handle               IA handle
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INVALID_HANDLE
- *     DAT_INSUFFICIENT_RESOURCES
- *
- */
-DAT_RETURN
-dapls_ib_cqd_destroy ( IN  DAPL_HCA  *p_hca )
-{
-    p_hca->ib_trans.ib_cqd_handle = IB_INVALID_HANDLE;
-    return (DAT_SUCCESS);
-}
-
-
-
-DAT_RETURN
-dapls_ib_n_completions_notify (
-        IN ib_hca_handle_t    hca_handle,
-        IN ib_cq_handle_t     cq_handle,
-        IN uint32_t           n_cqes )
-{
-    ib_api_status_t        ib_status;
-    UNREFERENCED_PARAMETER(hca_handle);
-
-    ib_status = ib_rearm_n_cq ( 
-                         cq_handle,
-                         n_cqes );
-
-    return dapl_ib_status_convert (ib_status);
-}
-
-
-DAT_RETURN
-dapls_ib_peek_cq (
-        IN ib_cq_handle_t cq_handle,
-        OUT uint32_t* p_n_cqes)
-{
-    ib_api_status_t        ib_status;
-
-    ib_status = ib_peek_cq ( cq_handle, p_n_cqes );
-
-    return dapl_ib_status_convert (ib_status);
-}
-
-
-/*
- * Local variables:
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 8
- * End:
- */
-
+\r
+/*\r
+ * Copyright (c) 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_cq.c\r
+ *\r
+ * PURPOSE: CQ (Completion Qeueu) access routine using IBAL APIs\r
+ *\r
+ * $Id$\r
+ *\r
+ **********************************************************************/\r
+\r
+#include "dapl.h"\r
+#include "dapl_adapter_util.h"\r
+#include "dapl_evd_util.h"\r
+#include "dapl_cr_util.h"\r
+#include "dapl_lmr_util.h"\r
+#include "dapl_rmr_util.h"\r
+#include "dapl_cookie.h"\r
+#include "dapl_ring_buffer_util.h"\r
+\r
+#ifndef NO_NAME_SERVICE\r
+#include "dapl_name_service.h"\r
+#endif /* NO_NAME_SERVICE */\r
+\r
+\r
+static void\r
+dapli_ibal_cq_async_error_callback ( IN  ib_async_event_rec_t  *p_err_rec )\r
+{\r
+    DAPL_EVD           *evd_ptr = (DAPL_EVD*)((void *)p_err_rec->context);\r
+    DAPL_EVD           *async_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,\r
+           "--> DiCqAEC: CQ error %d for EVD context %lx\n", \r
+            p_err_rec->code, p_err_rec->context);\r
+\r
+    if (DAPL_BAD_HANDLE (evd_ptr, DAPL_MAGIC_EVD))\r
+    {\r
+       dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
+                      "--> DiCqAEC: invalid EVD %lx\n", evd_ptr);\r
+       return;\r
+    }\r
+               \r
+    ia_ptr = evd_ptr->header.owner_ia;\r
+    async_evd_ptr = ia_ptr->async_error_evd;\r
+    if (async_evd_ptr == NULL)\r
+    {\r
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DiCqAEC: can't find async_error_evd on %s HCA\n", \r
+                (ia_ptr->header.provider)->device_name );\r
+        return;\r
+    }\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,"--> DiCqAEC: can't find %s HCA\n", \r
+                (ia_ptr->header.provider)->device_name);\r
+        return;\r
+    }\r
+\r
+    /* find CQ error callback using ia_ptr for context */\r
+    evd_cb = dapli_find_evd_cb_by_context ( async_evd_ptr, p_ca );\r
+    if ((evd_cb == NULL) || (evd_cb->pfn_async_cq_err_cb == NULL))\r
+    {\r
+       dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
+                      "--> DiCqAEC: no ERROR cb on %lx found \n", p_ca);\r
+       return;\r
+    }\r
+\r
+    /* maps to dapl_evd_cq_async_error_callback(), context is EVD */\r
+    evd_cb->pfn_async_cq_err_cb( (ib_hca_handle_t)p_ca, \r
+                                evd_ptr->ib_cq_handle,\r
+                                (ib_error_record_t*)&p_err_rec->code,\r
+                                evd_ptr );\r
+\r
+}\r
+\r
+\r
+/*\r
+ * dapli_ibal_cq_competion_callback\r
+ *\r
+ * Completion callback for a CQ\r
+ *\r
+ * Input:\r
+ *     cq_context               User context\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ */\r
+static void\r
+dapli_ib_cq_completion_cb (\r
+        IN   const   ib_cq_handle_t   h_cq,\r
+        IN   void                     *cq_context )\r
+{\r
+    DAPL_EVD           *evd_ptr;\r
+    dapl_ibal_ca_t     *p_ca;\r
+\r
+    evd_ptr = (DAPL_EVD *) cq_context;\r
+\r
+    dapl_dbg_log (DAPL_DBG_TYPE_CALLBACK, \r
+                  "--> DiICCC: cq_completion_cb evd %lx CQ %lx\n", \r
+                  evd_ptr, evd_ptr->ib_cq_handle);\r
+\r
+    dapl_os_assert (evd_ptr != DAT_HANDLE_NULL);\r
+\r
+    p_ca = (dapl_ibal_ca_t *) evd_ptr->header.owner_ia->hca_ptr->ib_hca_handle;\r
+\r
+    dapl_os_assert( h_cq == evd_ptr->ib_cq_handle );\r
+\r
+    dapl_evd_dto_callback ( (ib_hca_handle_t) p_ca, h_cq, cq_context);\r
+}\r
+\r
+\r
+/*\r
+ * dapl_ib_cq_late_alloc\r
+ *\r
+ * Alloc a CQ\r
+ *\r
+ * Input:\r
+ *     ia_handle               IA handle\r
+ *     evd_ptr                 pointer to EVD struct\r
+ *     cqlen                   minimum QLen\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_cq_late_alloc (\r
+       IN  ib_pd_handle_t        pd_handle,\r
+        IN  DAPL_EVD              *evd_ptr )\r
+{\r
+    ib_cq_create_t  cq_create;\r
+    ib_api_status_t ib_status;\r
+    DAT_RETURN      dat_status;\r
+    dapl_ibal_ca_t  *ibal_ca;\r
+    \r
+    dat_status            = DAT_SUCCESS;\r
+    cq_create.size        = evd_ptr->qlen;\r
+    \r
+    ibal_ca = (dapl_ibal_ca_t*)evd_ptr->header.owner_ia->hca_ptr->ib_hca_handle;\r
+       \r
+    cq_create.h_wait_obj  = NULL;\r
+    cq_create.pfn_comp_cb = dapli_ib_cq_completion_cb;\r
+\r
+    ib_status = ib_create_cq (\r
+                        (ib_ca_handle_t)ibal_ca->h_ca,\r
+                        &cq_create,\r
+                        evd_ptr /* context */,\r
+                        dapli_ibal_cq_async_error_callback,\r
+                        &evd_ptr->ib_cq_handle);\r
+\r
+    dat_status = dapl_ib_status_convert (ib_status);\r
+\r
+    if ( dat_status != DAT_SUCCESS )\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                       "--> DsICLA: failed to create CQ for EVD %lx\n",evd_ptr);\r
+        goto bail;\r
+    }\r
+\r
+    dapl_dbg_log (DAPL_DBG_TYPE_UTIL, \r
+                  "--> DsCQ_alloc: pd=%lx cq=%lx CQsz=%d EVD->Qln=%d\n",\r
+                  pd_handle, evd_ptr->ib_cq_handle,\r
+                  cq_create.size, evd_ptr->qlen);\r
+\r
+    /*\r
+     * As long as the CQ size is >= the evd size, then things are OK; sez Arlin.\r
+     */\r
+    if ( cq_create.size < (uint32_t)evd_ptr->qlen )\r
+    {\r
+        dapl_dbg_log (DAPL_DBG_TYPE_UTIL, \r
+                      "--> DsCQ_alloc: created CQ size(%d) < evd->qlen(%d)?\n",\r
+                      cq_create.size, evd_ptr->qlen);\r
+       dat_status = dapl_ib_status_convert (IB_INVALID_CQ_SIZE);\r
+    }\r
+    \r
+bail: \r
+    return dat_status;\r
+}\r
+\r
+/*\r
+ * dapl_ib_cq_alloc\r
+ *\r
+ * Alloc a CQ\r
+ *\r
+ * Input:\r
+ *     ia_handle               IA handle\r
+ *     evd_ptr                 pointer to EVD struct\r
+ *     cqlen                   minimum QLen\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *\r
+ */\r
+\r
+\r
+/*\r
+ * dapl_ib_cq_free\r
+ *\r
+ * Dealloc a CQ\r
+ *\r
+ * Input:\r
+ *     ia_handle               IA handle\r
+ *     evd_ptr                 pointer to EVD struct\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INVALID_HANDLE\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_cq_free (\r
+        IN  DAPL_IA                *ia_ptr,\r
+        IN  DAPL_EVD                *evd_ptr)\r
+{\r
+    ib_api_status_t             ib_status;\r
+       \r
+       if ( ia_ptr == NULL || ia_ptr->header.magic != DAPL_MAGIC_IA )\r
+       {\r
+               return DAT_INVALID_HANDLE;\r
+       }\r
+\r
+    ib_status = ib_destroy_cq (evd_ptr->ib_cq_handle, \r
+                               /* destroy_callback */ NULL);\r
+                     \r
+    return dapl_ib_status_convert (ib_status);\r
+}\r
+\r
+/*\r
+ * dapls_cq_resize\r
+ *\r
+ * Resize CQ completion notifications\r
+ *\r
+ * Input:\r
+ *     ia_handle               IA handle\r
+ *     evd_ptr                 pointer to EVD struct\r
+ *     cqlen                   minimum QLen \r
+ *\r
+ * Output:\r
+ *     cqlen                   may round up for optimal memory boundaries \r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INVALID_HANDLE\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *\r
+ */\r
+\r
+DAT_RETURN\r
+dapls_ib_cq_resize (\r
+         IN  DAPL_IA             *ia_ptr,\r
+         IN  DAPL_EVD            *evd_ptr,\r
+         IN  DAT_COUNT           *cqlen )\r
+{\r
+    ib_api_status_t             ib_status = IB_SUCCESS;\r
+\r
+    if ( ia_ptr == NULL || ia_ptr->header.magic != DAPL_MAGIC_IA )\r
+    {\r
+       return DAT_INVALID_HANDLE;\r
+    }\r
+    /* \r
+     * Resize CQ only if CQ handle is valid, may be delayed waiting\r
+     * for PZ allocation with IBAL \r
+     */\r
+#if defined(_VENDOR_IBAL_)\r
+    if ( evd_ptr->ib_cq_handle != IB_INVALID_HANDLE ) \r
+#endif /* _VENDOR_IBAL_ */\r
+    {\r
+       ib_status = ib_modify_cq ( evd_ptr->ib_cq_handle, \r
+                                      (uint32_t *)cqlen );\r
+       dapl_dbg_log (DAPL_DBG_TYPE_EVD,\r
+                      "ib_modify_cq ( new cqlen = %d, status=%d ) \n",\r
+                      *cqlen, ib_status );\r
+    }          \r
+    return dapl_ib_status_convert (ib_status);\r
+}\r
+\r
+\r
+/*\r
+ * dapl_set_cq_notify\r
+ *\r
+ * Set up CQ completion notifications\r
+ *\r
+ * Input:\r
+ *     ia_handle               IA handle\r
+ *     evd_ptr                 pointer to EVD struct\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INVALID_HANDLE\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_set_cq_notify (\r
+    IN  DAPL_IA            *ia_ptr,\r
+    IN  DAPL_EVD           *evd_ptr )\r
+{\r
+    ib_api_status_t             ib_status;\r
+       if ( ia_ptr == NULL || ia_ptr->header.magic != DAPL_MAGIC_IA )\r
+       {\r
+               return DAT_INVALID_HANDLE;\r
+       }\r
+    ib_status = ib_rearm_cq ( \r
+                         evd_ptr->ib_cq_handle,\r
+                         FALSE /* next event but not solicited event */ );\r
+\r
+    return dapl_ib_status_convert (ib_status);\r
+}\r
+\r
+\r
+/*\r
+ * dapls_ib_cqd_create\r
+ *\r
+ * Set up CQ notification event thread\r
+ *\r
+ * Input:\r
+ *     ia_handle       HCA handle\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INVALID_HANDLE\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_cqd_create ( IN  DAPL_HCA  *p_hca )\r
+{\r
+    /*\r
+     * We do not have CQD concept\r
+     */\r
+    p_hca->ib_trans.ib_cqd_handle = IB_INVALID_HANDLE;\r
+\r
+    return DAT_SUCCESS;\r
+}\r
+\r
+\r
+/*\r
+ * dapl_cqd_destroy\r
+ *\r
+ * Destroy CQ notification event thread\r
+ *\r
+ * Input:\r
+ *     ia_handle               IA handle\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INVALID_HANDLE\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_cqd_destroy ( IN  DAPL_HCA  *p_hca )\r
+{\r
+    p_hca->ib_trans.ib_cqd_handle = IB_INVALID_HANDLE;\r
+    return (DAT_SUCCESS);\r
+}\r
+\r
+\r
+\r
+DAT_RETURN\r
+dapls_ib_n_completions_notify (\r
+        IN ib_hca_handle_t    hca_handle,\r
+        IN ib_cq_handle_t     cq_handle,\r
+        IN uint32_t           n_cqes )\r
+{\r
+    ib_api_status_t        ib_status;\r
+    UNREFERENCED_PARAMETER(hca_handle);\r
+\r
+    ib_status = ib_rearm_n_cq ( \r
+                         cq_handle,\r
+                         n_cqes );\r
+\r
+    return dapl_ib_status_convert (ib_status);\r
+}\r
+\r
+\r
+DAT_RETURN\r
+dapls_ib_peek_cq (\r
+        IN ib_cq_handle_t cq_handle,\r
+        OUT uint32_t* p_n_cqes)\r
+{\r
+    ib_api_status_t        ib_status;\r
+\r
+    ib_status = ib_peek_cq ( cq_handle, p_n_cqes );\r
+\r
+    return dapl_ib_status_convert (ib_status);\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
index ad4acf0..5f73086 100644 (file)
-/*
- * 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.c
- *
- * PURPOSE: Utility routines for access to IBAL APIs
- *
- * $Id: dapl_ibal_util.c 33 2005-07-11 19:51:17Z ftillier $
- *
- **********************************************************************/
-
-#include "dapl.h"
-#include "dapl_adapter_util.h"
-#include "dapl_evd_util.h"
-#include "dapl_cr_util.h"
-#include "dapl_lmr_util.h"
-#include "dapl_rmr_util.h"
-#include "dapl_cookie.h"
-#include "dapl_ring_buffer_util.h"
-
-#ifdef DAT_EXTENSIONS
-#include <dat2\dat_ib_extensions.h>
-#endif
-
-#ifndef NO_NAME_SERVICE
-#include "dapl_name_service.h"
-#endif /* NO_NAME_SERVICE */
-
-#include "dapl_ibal_name_service.h"
-
-#define DAPL_IBAL_MAX_CA 4
-#define DAT_ADAPTER_NAME "InfiniHost (Tavor)"
-#define DAT_VENDOR_NAME  "Mellanox Technolgy Inc."
-
-/*
- *  Root data structure for DAPL_IIBA.
- */
-dapl_ibal_root_t        dapl_ibal_root;
-DAPL_HCA_NAME           dapl_ibal_hca_name_array [DAPL_IBAL_MAX_CA] = 
-                            {"IbalHca0", "IbalHca1", "IbalHca2", "IbalHca3"};
-ib_net64_t              *gp_ibal_ca_guid_tbl = NULL;
-
-/*
- * DAT spec does not tie max_mtu_size with IB MTU
- *
-static ib_net32_t dapl_ibal_mtu_table[6] = {0, 256, 512, 1024, 2048, 4096};
- */
-    
-int g_loopback_connection = 0;
-
-
-static cl_status_t
-dapli_init_root_ca_list(
-    IN    dapl_ibal_root_t *root )
-{
-    cl_status_t status;
-
-    cl_qlist_init (&root->ca_head);
-    status = cl_spinlock_init (&root->ca_lock);
-
-    if (status == CL_SUCCESS)
-    {
-        /*
-         * Get the time ready to go but don't start here
-         */
-        root->shutdown = FALSE;
-        root->initialized = TRUE;
-    }
-    else
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> DiIRCL: cl_spinlock_init returned %d\n", status );
-        root->initialized = FALSE;
-    }
-    
-    root->h_al = NULL;
-
-    return (status);
-}
-
-
-static cl_status_t
-dapli_destroy_root_ca_list(
-    IN    dapl_ibal_root_t *root )
-{
-
-    root->initialized = FALSE;
-
-    /* 
-     * At this point the lock should not be necessary
-     */
-    if (!cl_is_qlist_empty (&root->ca_head) )
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> Destroying nonempty ca list (%s)\n", "DiDRCL");
-    }
-    cl_spinlock_destroy (&root->ca_lock);
-
-    return CL_SUCCESS;
-}
-
-
-static void
-dapli_shutdown_port_access(
-    IN    dapl_ibal_ca_t    *ca )
-{
-    dapl_ibal_port_t    *p_port;
-
-    TAKE_LOCK( ca->port_lock );
-    {
-        while ( ! cl_is_qlist_empty( &ca->port_head ) )
-        {
-            p_port = (dapl_ibal_port_t *)cl_qlist_remove_head( &ca->port_head );
-            RELEASE_LOCK( ca->port_lock );
-            {
-                REMOVE_REFERENCE( &p_port->refs );
-                REMOVE_REFERENCE( &p_port->ca->refs );
-
-                dapl_os_free (p_port, sizeof (dapl_ibal_port_t));
-            }
-            TAKE_LOCK( ca->port_lock );
-        }
-    }
-    RELEASE_LOCK( ca->port_lock );
-}
-
-
-static void dapli_shutdown_ca_access (void)
-{
-    dapl_ibal_ca_t  *ca;
-
-    if ( dapl_ibal_root.initialized == FALSE )
-    {
-        goto destroy_root;
-    }
-
-    TAKE_LOCK (dapl_ibal_root.ca_lock);
-    {
-        while ( ! cl_is_qlist_empty (&dapl_ibal_root.ca_head) )
-        {
-            ca = (dapl_ibal_ca_t *)
-                                 cl_qlist_remove_head (&dapl_ibal_root.ca_head);
-
-            if (ca->p_ca_attr)
-            {
-                dapl_os_free (ca->p_ca_attr, sizeof (ib_ca_attr_t));
-            }
-
-
-            RELEASE_LOCK (dapl_ibal_root.ca_lock);
-            {
-                dapli_shutdown_port_access (ca);
-                REMOVE_REFERENCE (&ca->refs);
-            }
-            TAKE_LOCK (dapl_ibal_root.ca_lock);
-        }
-    }
-    RELEASE_LOCK (dapl_ibal_root.ca_lock);
-
-destroy_root:
-    /*
-     * Destroy the root CA list and list lock
-     */
-    dapli_destroy_root_ca_list (&dapl_ibal_root);
-
-    /*
-     * Signal we're all done and wake any waiter
-     */
-    dapl_ibal_root.shutdown = FALSE;
-}
-
-
-dapl_ibal_evd_cb_t *
-dapli_find_evd_cb_by_context(
-    IN    void           *context,
-    IN    dapl_ibal_ca_t *ca)
-{
-    dapl_ibal_evd_cb_t *evd_cb = NULL;
-
-    TAKE_LOCK( ca->evd_cb_lock );
-
-    evd_cb = (dapl_ibal_evd_cb_t *) cl_qlist_head( &ca->evd_cb_head );
-    while ( &evd_cb->next != cl_qlist_end( &ca->evd_cb_head ) )
-    {
-        if ( context == evd_cb->context)
-        {
-            goto found;
-        }
-
-        /*
-         *  Try again
-         */
-        evd_cb = (dapl_ibal_evd_cb_t *) cl_qlist_next( &evd_cb->next );
-    }
-    /*
-     *  No joy
-     */
-    evd_cb = NULL;
-
-found:
-
-    RELEASE_LOCK( ca->evd_cb_lock );
-
-    return ( evd_cb );
-}
-
-
-static cl_status_t
-dapli_init_ca_evd_cb_list(
-    IN    dapl_ibal_ca_t    *ca )
-{
-    cl_status_t    status;
-
-    cl_qlist_init( &ca->evd_cb_head );
-    status = cl_spinlock_init( &ca->evd_cb_lock );
-    if ( status != CL_SUCCESS )
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR, "--> DiICECL: cl_spinlock_init returned %d\n", status);
-    return ( status );
-}
-
-
-static cl_status_t
-dapli_init_ca_port_list(
-    IN    dapl_ibal_ca_t    *ca )
-{
-    cl_status_t    status;
-
-    cl_qlist_init( &ca->port_head );
-    status = cl_spinlock_init( &ca->port_lock );
-    if ( status != CL_SUCCESS )
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> DiICPL: cl_spinlock_init returned %d\n", status );
-    return ( status );
-}
-
-dapl_ibal_port_t  *
-dapli_ibal_get_port (
-    IN   dapl_ibal_ca_t    *p_ca,
-    IN   uint8_t           port_num)
-{
-    cl_list_item_t    *p_active_port = NULL;
-    
-    TAKE_LOCK (p_ca->port_lock);
-    for ( p_active_port = cl_qlist_head( &p_ca->port_head );
-          p_active_port != cl_qlist_end ( &p_ca->port_head);
-          p_active_port =  cl_qlist_next ( p_active_port ) )
-    {
-        if (((dapl_ibal_port_t *)p_active_port)->p_attr->port_num == port_num)
-            break;     
-    }
-    RELEASE_LOCK (p_ca->port_lock);
-
-    return (dapl_ibal_port_t *)p_active_port;
-}
-
-
-void
-dapli_ibal_ca_async_error_callback( IN ib_async_event_rec_t  *p_err_rec )
-{
-    dapl_ibal_ca_t     *p_ca = (dapl_ibal_ca_t*)((void *)p_err_rec->context);
-    dapl_ibal_evd_cb_t *evd_cb;
-    DAPL_IA            *ia_ptr;
-                       
-    dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> DiCaAEC: CA error %d for context %p\n", 
-                       p_err_rec->code, p_err_rec->context);
-
-    if (p_ca == NULL)
-    {
-               dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> DiCaAEC: invalid p_ca"
-                              "(%p)in async event rec\n",p_ca);
-       return;
-    }
-       
-    ia_ptr = (DAPL_IA*)p_ca->ia_ptr;
-    if (ia_ptr == NULL)
-    {
-               dapl_dbg_log (DAPL_DBG_TYPE_ERR,
-                              "--> DiCaAEC: invalid ia_ptr in %p ca \n", p_ca );
-       return;
-    }
-
-    if (ia_ptr->async_error_evd == NULL)
-    {
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR,
-                      "--> DiCqAEC: can't find async_error_evd on %s HCA\n", 
-                      (ia_ptr->header.provider)->device_name );
-        return;
-    }
-
-    /* find QP error callback using p_ca for context */
-    evd_cb = dapli_find_evd_cb_by_context (ia_ptr->async_error_evd, p_ca);
-    if ((evd_cb == NULL) || (evd_cb->pfn_async_err_cb == NULL))
-    {
-       dapl_dbg_log (DAPL_DBG_TYPE_ERR,
-                              "--> DiCaAEC: no ERROR cb on %p found \n", p_ca);
-       return;
-    }
-
-    /* maps to dapl_evd_un_async_error_callback(), context is async_evd */
-    evd_cb->pfn_async_err_cb( (ib_hca_handle_t)p_ca, 
-                              (ib_error_record_t*)&p_err_rec->code, 
-                              ia_ptr->async_error_evd );
-
-}
-
-
-static dapl_ibal_port_t *
-dapli_alloc_port(
-    IN    dapl_ibal_ca_t    *ca,
-    IN    ib_port_attr_t    *ib_port )
-{
-    dapl_ibal_port_t    *p_port = NULL;
-
-    if (ca->h_ca == NULL )
-    {
-       return NULL;
-    }
-
-    /*
-     *  Allocate the port structure memory.  This will also deal with the
-     *  copying ib_port_attr_t including GID and P_Key tables
-     */
-    p_port = dapl_os_alloc ( sizeof(dapl_ibal_port_t ) );
-
-    if ( p_port )
-    {
-        dapl_os_memzero (p_port, sizeof(dapl_ibal_port_t ) );
-
-        /*
-         *  We're good to go after initializing reference.
-         */
-        INIT_REFERENCE( &p_port->refs, 1, p_port, NULL /* pfn_destructor */ );
-               
-               p_port->p_attr = ib_port;
-    }
-    return ( p_port );
-}
-
-static void
-dapli_add_active_port(
-    IN dapl_ibal_ca_t   *ca )
-{
-    dapl_ibal_port_t     *p_port;
-    ib_port_attr_t       *p_port_attr;
-    ib_ca_attr_t         *p_ca_attr;
-    int                  i;
-
-    p_ca_attr = ca->p_ca_attr;
-
-    dapl_os_assert (p_ca_attr != NULL);
-
-    for (i = 0; i < p_ca_attr->num_ports; i++)
-    {
-        p_port_attr = &p_ca_attr->p_port_attr[i];
-
-        {
-            p_port = dapli_alloc_port( ca, p_port_attr );
-            if ( p_port )
-            {
-                TAKE_REFERENCE (&ca->refs);
-
-                /*
-                 *  Record / update attribues
-                 */
-                p_port->p_attr = p_port_attr;
-
-                /*
-                 *  Remember the parant CA keeping the reference we took above
-                 */
-                p_port->ca = ca;
-
-                /*
-                 *  We're good to go - Add the new port to the list on the CA
-                 */
-                LOCK_INSERT_TAIL( ca->port_lock, ca->port_head, p_port->next );
-            }
-            else
-            {
-                dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                               "--> %s: Could not allocate dapl_ibal_port_t\n",
-                               "DiAAP");
-            }
-        }
-       dapl_dbg_log( DAPL_DBG_TYPE_UTIL,
-                      "--> DiAAP: Port %d logical link %s lid = %#x\n",
-                      p_port_attr->port_num,
-                      ( p_port_attr->link_state != IB_LINK_ACTIVE
-                           ?  "DOWN": "UP" ),
-                      CL_HTON16(p_port_attr->lid) );
-
-    } /* for loop */
-}
-
-static dapl_ibal_ca_t *
-dapli_alloc_ca(
-    IN    ib_al_handle_t  h_al,
-    IN    ib_net64_t      ca_guid)
-{
-    dapl_ibal_ca_t         *p_ca;
-    ib_api_status_t        status;
-    uint32_t               attr_size;
-
-    /*
-     *  Allocate the CA structure
-     */
-    p_ca = dapl_os_alloc( sizeof(dapl_ibal_ca_t) );
-    dapl_os_memzero (p_ca, sizeof(dapl_ibal_ca_t) );
-
-    if ( p_ca )
-    {
-        /*
-         *  Now we pass dapli_ibal_ca_async_error_callback as the 
-         *  async error callback
-         */
-        status = ib_open_ca( h_al,
-                             ca_guid,
-                             dapli_ibal_ca_async_error_callback,
-                             p_ca,
-                             &p_ca->h_ca );
-        if ( status != IB_SUCCESS )
-        {
-            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                           "--> DiAC: ib_open_ca returned %s\n",
-                           ib_get_err_str(status));
-            dapl_os_free (p_ca, sizeof (dapl_ibal_ca_t));
-            return (NULL);
-        }
-
-        /*
-         *  Get port list lock and list head initialized
-         */
-        if (( dapli_init_ca_port_list( p_ca ) != CL_SUCCESS ) ||
-            ( dapli_init_ca_evd_cb_list( p_ca ) != CL_SUCCESS ))
-        { 
-            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                           "--> %s: dapli_init_ca_port_list returned failed\n",
-                           "DiAC");
-            goto close_and_free_ca;
-        }
-
-        attr_size = 0;
-        status = ib_query_ca (p_ca->h_ca, NULL, &attr_size);
-        if (status != IB_INSUFFICIENT_MEMORY)
-        {
-            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                          "--> DiAC: ib_query_ca returned failed status = %d\n",
-                          status);
-            goto close_and_free_ca;
-        }
-
-        p_ca->p_ca_attr = dapl_os_alloc ((int)attr_size);
-        if (p_ca->p_ca_attr == NULL)
-        {
-            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                           "--> %s: dapli_alloc_ca failed to alloc memory\n",
-                           "DiAC");
-            goto close_and_free_ca;
-        }
-
-        status = ib_query_ca (
-                          p_ca->h_ca,
-                          p_ca->p_ca_attr,
-                          &attr_size);
-        if (status != IB_SUCCESS)
-        {
-            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                           "--> ib_query_ca returned failed status = %d\n",
-                           status);
-            dapl_os_free (p_ca->p_ca_attr, (int)attr_size);
-            goto close_and_free_ca;
-        }
-       
-        p_ca->ca_attr_size = attr_size;
-
-        INIT_REFERENCE( &p_ca->refs, 1, p_ca, NULL /* pfn_destructor */ );
-
-        dapli_add_active_port (p_ca);
-
-        /*
-         *  We're good to go
-         */
-        return ( p_ca );
-    }
-    else
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> %s: Error allocating CA structure\n","DiAC");
-        return ( NULL );
-    }
-
-close_and_free_ca:
-   /*
-    *  Close the CA.
-    */
-   (void) ib_close_ca ( p_ca->h_ca, NULL /* callback */);
-   dapl_os_free (p_ca, sizeof (dapl_ibal_ca_t));
-
-    /*
-     *  If we get here, there was an initialization failure
-     */
-    return ( NULL );
-}
-
-
-static dapl_ibal_ca_t *
-dapli_add_ca (
-    IN   ib_al_handle_t    h_al,
-    IN   ib_net64_t        ca_guid )
-{
-    dapl_ibal_ca_t     *p_ca;
-
-    /*
-     *  Allocate a CA structure
-     */
-    p_ca = dapli_alloc_ca( h_al, ca_guid );
-    if ( p_ca )
-    {
-        /*
-         *  Add the new CA to the list
-         */
-        LOCK_INSERT_TAIL( dapl_ibal_root.ca_lock, 
-                          dapl_ibal_root.ca_head, p_ca->next );
-    }
-    else
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> %s: Could not allocate dapl_ibal_ca_t "
-                       " for CA guid " F64x "\n","DiAA",ca_guid);
-    }
-
-    return ( p_ca );
-}
-
-
-int32_t
-dapls_ib_init (void)
-{
-    ib_api_status_t status;
-
-    /*
-     * Initialize the root structure
-     */
-    if ( dapli_init_root_ca_list (&dapl_ibal_root) == CL_SUCCESS )
-    {
-        /*
-         * Register with the access layer
-         */
-        status = ib_open_al (&dapl_ibal_root.h_al);
-
-        if (status == IB_SUCCESS)
-        {
-            intn_t             guid_count;
-
-            status = ib_get_ca_guids ( dapl_ibal_root.h_al,
-                                       NULL,
-                                       &(size_t)guid_count );
-            if (status != IB_INSUFFICIENT_MEMORY)
-            {
-                dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                               "--> %s: ib_get_ca_guids failed = %d\n",
-                               __FUNCTION__,status);
-                return -1;
-            }
-
-            if (guid_count == 0)
-            {
-                dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                               "--> %s: found NO HCA in the system\n",
-                               __FUNCTION__);
-                return -1;
-            }
-
-            if (guid_count > DAPL_IBAL_MAX_CA)
-            {
-                guid_count = DAPL_IBAL_MAX_CA;
-            }
-
-            gp_ibal_ca_guid_tbl = (ib_net64_t*)
-                                  dapl_os_alloc ( (int)(guid_count * 
-                                                  sizeof (ib_net64_t)) );
-
-            if (gp_ibal_ca_guid_tbl == NULL)
-            {
-                dapl_dbg_log ( DAPL_DBG_TYPE_ERR, "--> %s() can not alloc "
-                               "gp_ibal_ca_guid_tbl\n", __FUNCTION__);
-                        
-                return -1;
-            }
-
-            status = ib_get_ca_guids ( dapl_ibal_root.h_al, 
-                                       gp_ibal_ca_guid_tbl, 
-                                       &(size_t)guid_count );
-                            
-
-            if ( status != IB_SUCCESS )
-            {
-                dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                               "--> %s: ib_get_ca_guids failed '%s'\n", 
-                               __FUNCTION__, ib_get_err_str(status) );
-                return -1;
-            }
-
-            dapl_dbg_log ( DAPL_DBG_TYPE_UTIL, 
-                           "--> %s: Success open AL & found %d HCA avail,\n",
-                           __FUNCTION__, guid_count);
-            return 0;
-        }
-        else
-        {        
-            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                           "--> %s: ib_open_al() failed '%s'\n",
-                           __FUNCTION__, ib_get_err_str(status) );
-            /*
-             * Undo CA list
-             */
-            dapli_destroy_root_ca_list (&dapl_ibal_root);
-        }
-    }
-    return -1;
-}
-
-
-int32_t dapls_ib_release (void)
-{
-    dapl_ibal_root.shutdown = TRUE;
-
-    dapli_shutdown_ca_access();
-
-    /*
-     * If shutdown not complete, wait for it
-     */
-    if (dapl_ibal_root.shutdown)
-    {
-        dapl_dbg_log (DAPL_DBG_TYPE_UTIL, 
-                        "--> DsIR: timeout waiting for completion\n");
-    }
-
-    if ( dapl_ibal_root.h_al != NULL )
-    {
-        (void) ib_close_al (dapl_ibal_root.h_al);
-       dapl_dbg_log (DAPL_DBG_TYPE_UTIL, "--> DsIR: ib_close_al() returns\n");
-        dapl_ibal_root.h_al = NULL;
-    }
-#ifdef DBG
-    dapl_dbg_log (DAPL_DBG_TYPE_UTIL, "--> %s: Exit\n",__FUNCTION__);
-#endif
-
-    return 0;
-}
-
-
-/*
- * dapls_ib_enum_hcas
- *
- * Enumerate all HCAs on the system
- *
- * Input:
- *     none
- *
- * Output:
- *     hca_names       Array of hca names
- *     total_hca_count 
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *
- */
-DAT_RETURN
-dapls_ib_enum_hcas (
-        IN   const char          *vendor,
-        OUT  DAPL_HCA_NAME       **hca_names,
-        OUT  DAT_COUNT           *total_hca_count )
-{
-    intn_t             guid_count;
-    ib_api_status_t    ib_status;
-    UNREFERENCED_PARAMETER(vendor);
-
-    ib_status = ib_get_ca_guids (dapl_ibal_root.h_al, NULL, &(size_t)guid_count);
-    if (ib_status != IB_INSUFFICIENT_MEMORY)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> DsIEH: ib_get_ca_guids failed '%s'\n",
-                       ib_get_err_str(ib_status) );
-        return dapl_ib_status_convert (ib_status);
-    }
-
-    if (guid_count == 0)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> %s: ib_get_ca_guids no HCA in the system\n",
-                       "DsIEH");
-        return (DAT_PROVIDER_NOT_FOUND);
-    }
-
-    if (guid_count > DAPL_IBAL_MAX_CA)
-    {
-        guid_count = DAPL_IBAL_MAX_CA;
-    }
-
-    gp_ibal_ca_guid_tbl = (ib_net64_t *)dapl_os_alloc ((int)(guid_count * sizeof (ib_net64_t)) );
-
-    if (gp_ibal_ca_guid_tbl == NULL)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> %s: can not alloc resources @line%d\n", "DsIEH",
-                       __LINE__);
-        return (DAT_INSUFFICIENT_RESOURCES);
-    }
-
-    ib_status = ib_get_ca_guids ( dapl_ibal_root.h_al,
-                                  gp_ibal_ca_guid_tbl,
-                                  &(size_t)guid_count);
-
-    if (ib_status != IB_SUCCESS)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> DsIEH: ib_get_ca_guids failed status = %s\n", 
-                       ib_get_err_str(ib_status) );
-        return dapl_ib_status_convert (ib_status);
-    }
-
-    *hca_names = (DAPL_HCA_NAME*)
-                     dapl_os_alloc ((int)(guid_count * sizeof (DAPL_HCA_NAME)));
-
-    if (*hca_names == NULL)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> %s: can not alloc resources @line%d\n",
-                       "DsIEH", __LINE__);
-        return (DAT_INSUFFICIENT_RESOURCES);
-    }
-
-    dapl_os_memcpy (*hca_names, 
-                    dapl_ibal_hca_name_array, 
-                    (int)(guid_count * sizeof (DAPL_HCA_NAME)) );
-
-    *total_hca_count = (DAT_COUNT)guid_count;
-
-    {
-        int i;
-
-        for (i = 0; i < guid_count; i++)
-            dapl_dbg_log (DAPL_DBG_TYPE_UTIL, "--> DsIEH: %d) hca_names = %s\n",
-                          i, dapl_ibal_hca_name_array[i]);
-    }
-
-    return (DAT_SUCCESS);
-}
-
-
-
-IB_HCA_NAME
-dapl_ib_convert_name(
-    IN  char    *name)
-{
-    int                i;
-
-    if (gp_ibal_ca_guid_tbl  == NULL)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> DICN: found no HCA with name %s\n", name );
-        return 0;
-    }
-
-    for (i = 0; i < DAPL_IBAL_MAX_CA; i++)
-    {
-        if (strcmp (name, dapl_ibal_hca_name_array[i]) == 0)
-        {
-            break;
-        }
-    }
-
-    if (i >= DAPL_IBAL_MAX_CA)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> DICN: can't find any HCA with name %s\n", name);
-        return 0;
-    }
-   
-    return (gp_ibal_ca_guid_tbl[i]);
-}
-
-
-/*
- * dapls_ib_open_hca
- *
- * Open HCA
- *
- * Input:
- *      *hca_name         pointer to provider device name
- *      *ib_hca_handle_p  pointer to provide HCA handle
- *
- * Output:
- *      none
- *
- * Return:
- *      DAT_SUCCESS
- *      DAT_INSUFFICIENT_RESOURCES
- *
- */
-DAT_RETURN dapls_ib_open_hca ( IN  char         *hca_name,
-                               IN  DAPL_HCA     *p_hca )
-{
-    dapl_ibal_ca_t     *p_ca;
-    IB_HCA_NAME        ca_guid;
-
-    dapl_dbg_log (DAPL_DBG_TYPE_UTIL," open_hca: %s - %p\n", hca_name, p_hca);
-
-    if (gp_ibal_ca_guid_tbl  == NULL)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR, "--> DsIOH: found no HCA with ca_guid"
-                       F64x "\n", hca_name);
-        return (DAT_PROVIDER_NOT_FOUND);
-    }
-
-    ca_guid = dapl_ib_convert_name(hca_name);
-
-    p_ca = dapli_add_ca (dapl_ibal_root.h_al, ca_guid);
-
-    if (p_ca == NULL)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                     "--> DsIOH: can not create ca for '%s' guid " F64x "\n",
-                     hca_name, ca_guid);
-        return (DAT_INSUFFICIENT_RESOURCES);
-    }
-
-    p_hca->ib_hca_handle = (ib_hca_handle_t) p_ca;
-    p_hca->ib_trans.d_hca = p_hca; // back-link
-
-    /* initialize hca wait object for uAT event */
-    dapl_os_wait_object_init(&p_hca->ib_trans.wait_object);
-
-#if SOCK_CM
-    {
-       DAT_RETURN    dat_status;
-
-       dat_status = dapli_init_sock_cm(p_hca);
-       if ( dat_status != DAT_SUCCESS )
-       {
-               dapl_dbg_log (DAPL_DBG_TYPE_ERR,
-                               " %s() failed to init sock_CM\n", __FUNCTION__);
-               return DAT_INTERNAL_ERROR;
-       }
-
-       /* initialize cr_list lock */
-       dat_status = dapl_os_lock_init(&p_hca->ib_trans.lock);
-       if (dat_status != DAT_SUCCESS)
-       {
-               dapl_dbg_log (DAPL_DBG_TYPE_ERR, " %s() failed to init lock\n",
-                               __FUNCTION__);
-               return DAT_INTERNAL_ERROR;
-       }
-
-       /* initialize CM list for listens on this HCA */
-       dapl_llist_init_head((DAPL_LLIST_HEAD*)&p_hca->ib_trans.list);
-    }
-#endif
-
-    return (DAT_SUCCESS);
-}
-
-
-/*
- * dapls_ib_close_hca
- *
- * Open HCA
- *
- * Input:
- *      ib_hca_handle   provide HCA handle
- *
- * Output:
- *      none
- *
- * Return:
- *      DAT_SUCCESS
- *      DAT_INSUFFICIENT_RESOURCES
- *
- */
-DAT_RETURN dapls_ib_close_hca ( IN  DAPL_HCA  *p_hca )
-{
-    dapl_ibal_ca_t     *p_ca;
-   
-    p_ca =  (dapl_ibal_ca_t *) p_hca->ib_hca_handle;
-   
-#if SOCK_CM
-#endif
-    /*
-     * Remove it from the list
-     */
-    TAKE_LOCK (dapl_ibal_root.ca_lock);
-    {
-        cl_qlist_remove_item (&dapl_ibal_root.ca_head, &p_ca->next);
-    }
-    RELEASE_LOCK (dapl_ibal_root.ca_lock);
-
-    dapli_shutdown_port_access (p_ca);
-    /*
-     * Remove the constructor reference
-     */
-    REMOVE_REFERENCE (&p_ca->refs);
-
-    cl_spinlock_destroy (&p_ca->port_lock);
-    cl_spinlock_destroy (&p_ca->evd_cb_lock);
-
-    if (p_ca->p_ca_attr)
-        dapl_os_free (p_ca->p_ca_attr, sizeof (ib_ca_attr_t));
-
-    (void) ib_close_ca (p_ca->h_ca, NULL /* close_callback */);
-
-    p_hca->ib_hca_handle = IB_INVALID_HANDLE;
-    dapl_os_free (p_ca, sizeof (dapl_ibal_ca_t));
-
-    return (DAT_SUCCESS);
-}
-
-
-
-/*
- * dapl_ib_pd_alloc
- *
- * Alloc a PD
- *
- * Input:
- *     ia_handle               IA handle
- *     PZ_ptr                  pointer to PZEVD struct
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *
- */
-DAT_RETURN
-dapls_ib_pd_alloc (
-        IN  DAPL_IA                 *ia,
-        IN  DAPL_PZ                 *pz)
-{
-    ib_api_status_t         ib_status;
-    dapl_ibal_ca_t          *p_ca;
-
-    p_ca = (dapl_ibal_ca_t *) ia->hca_ptr->ib_hca_handle;
-
-    ib_status = ib_alloc_pd (
-                              p_ca->h_ca,
-                              IB_PDT_NORMAL,
-                              ia,
-                              &pz->pd_handle );
-
-    return dapl_ib_status_convert (ib_status);
-}
-
-
-/*
- * dapl_ib_pd_free
- *
- * Free a PD
- *
- * Input:
- *     PZ_ptr                  pointer to PZ struct
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *
- */
-DAT_RETURN
-dapls_ib_pd_free (
-        IN  DAPL_PZ                 *pz)
-{
-    ib_api_status_t                 ib_status;
-
-    ib_status = ib_dealloc_pd (pz->pd_handle, /* destroy_callback */ NULL);
-
-    pz->pd_handle = IB_INVALID_HANDLE;
-
-    return dapl_ib_status_convert (ib_status);
-}
-
-
-/*
- * dapl_ib_mr_register
- *
- * Register a virtual memory region
- *
- * Input:
- *     ia_handle               IA handle
- *     lmr                     pointer to dapl_lmr struct
- *     virt_addr               virtual address of beginning of mem region
- *     length                  length of memory region
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *
- */
-DAT_RETURN
-dapls_ib_mr_register (
-        IN  DAPL_IA                 *ia,
-        IN  DAPL_LMR                *lmr,
-        IN  DAT_PVOID                virt_addr,
-        IN  DAT_VLEN                length,
-        IN  DAT_MEM_PRIV_FLAGS      privileges,
-        IN  DAT_VA_TYPE             va_type)
-{
-    ib_api_status_t     ib_status;
-    ib_mr_handle_t      mr_handle;
-    ib_mr_create_t      mr_create;
-    uint32_t            l_key, r_key; 
-
-    if ( ia == NULL || ia->header.magic != DAPL_MAGIC_IA )
-    {
-        return DAT_INVALID_HANDLE;
-    }
-
-    /* IBAL does not support */
-    if (va_type == DAT_VA_TYPE_ZB) {
-        dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                    "--> va_type == DAT_VA_TYPE_ZB: NOT SUPPORTED\n");    
-        return DAT_ERROR (DAT_NOT_IMPLEMENTED, DAT_NO_SUBTYPE);  
-    }
-
-    mr_create.vaddr         = (void *) virt_addr;
-    mr_create.length        = (size_t)length;
-    mr_create.access_ctrl   = dapl_lmr_convert_privileges (privileges);
-    mr_create.access_ctrl   |= IB_AC_MW_BIND;
-   
-    if (lmr->param.mem_type == DAT_MEM_TYPE_SHARED_VIRTUAL)
-    {
-        ib_status = ib_reg_shmid (
-                          ((DAPL_PZ *)lmr->param.pz_handle)->pd_handle,
-                          (const uint8_t*)lmr->shmid,
-                          &mr_create,
-                          (uint64_t *)&virt_addr,
-                          &l_key,
-                          &r_key,
-                          &mr_handle);
-    }
-    else 
-    {
-        ib_status = ib_reg_mem ( ((DAPL_PZ *)lmr->param.pz_handle)->pd_handle,
-                                 &mr_create,
-                                 &l_key,
-                                 &r_key,
-                                 &mr_handle );
-    }
-    
-    if (ib_status != IB_SUCCESS)
-    {
-        return (dapl_ib_status_convert (ib_status));
-    }
-    
-    /* DAT/DAPL expects context in host order */
-    l_key = cl_ntoh32(l_key);
-    r_key = cl_ntoh32(r_key);
-
-    dapl_dbg_log (DAPL_DBG_TYPE_UTIL, "--> DsIMR: lmr (%p) lkey = 0x%x "
-                  "r_key= %#x mr_handle %p vaddr 0x%LX len 0x%LX\n", 
-                  lmr, l_key, r_key, mr_handle, virt_addr, length);
-
-    lmr->param.lmr_context = l_key;
-    lmr->param.rmr_context = r_key;
-    lmr->param.registered_size = length;
-    lmr->param.registered_address = (DAT_VADDR)virt_addr;
-    lmr->mr_handle         = mr_handle;
-
-    return (DAT_SUCCESS);
-}
-
-
-/*
- * dapl_ib_mr_deregister
- *
- * Free a memory region
- *
- * Input:
- *     lmr                     pointer to dapl_lmr struct
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *
- */
-DAT_RETURN
-dapls_ib_mr_deregister (
-        IN  DAPL_LMR                *lmr)
-{
-    ib_api_status_t                ib_status;
-
-    ib_status = ib_dereg_mr (lmr->mr_handle);
-
-    if (ib_status != IB_SUCCESS)
-    {
-        return dapl_ib_status_convert (ib_status);
-    }
-
-    lmr->param.lmr_context = 0;
-    lmr->mr_handle         = IB_INVALID_HANDLE;
-
-    return (DAT_SUCCESS);
-}
-
-
-/*
- * dapl_ib_mr_register_shared
- *
- * Register a virtual memory region
- *
- * Input:
- *     ia_handle               IA handle
- *     lmr                     pointer to dapl_lmr struct
- *     virt_addr               virtual address of beginning of mem region
- *     length                  length of memory region
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *
- */
-DAT_RETURN
-dapls_ib_mr_register_shared (
-        IN  DAPL_IA                  *ia,
-        IN  DAPL_LMR                 *lmr,
-        IN  DAT_MEM_PRIV_FLAGS       privileges,
-        IN  DAT_VA_TYPE              va_type )
-{
-    DAT_VADDR                   virt_addr;
-    ib_mr_handle_t              mr_handle;
-    ib_api_status_t             ib_status;
-    ib_mr_handle_t              new_mr_handle;
-    ib_access_t                 access_ctrl;
-    uint32_t                    l_key, r_key; 
-    ib_mr_create_t      mr_create;
-    if ( ia == NULL || ia->header.magic != DAPL_MAGIC_IA )
-    {
-        return DAT_INVALID_HANDLE;
-    }
-
-    /* IBAL does not support?? */
-    if (va_type == DAT_VA_TYPE_ZB) {
-        dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-           " va_type == DAT_VA_TYPE_ZB: NOT SUPPORTED\n");    
-        return DAT_ERROR (DAT_NOT_IMPLEMENTED, DAT_NO_SUBTYPE);  
-    }
-
-    virt_addr = dapl_mr_get_address (lmr->param.region_desc,
-                                     lmr->param.mem_type);
-
-    access_ctrl   = dapl_lmr_convert_privileges (privileges);
-    access_ctrl  |= IB_AC_MW_BIND;
-
-    mr_create.vaddr         = (void *) virt_addr;
-    mr_create.access_ctrl   = access_ctrl;
-    mr_handle = (ib_mr_handle_t) lmr->mr_handle;
-
-    dapl_dbg_log (DAPL_DBG_TYPE_UTIL, 
-                       "--> DsIMRS: orig mr_handle %p vaddr %p\n", 
-                       mr_handle, virt_addr);
-
-    if (lmr->param.mem_type == DAT_MEM_TYPE_SHARED_VIRTUAL)
-    {
-        ib_status = ib_reg_shmid ( ((DAPL_PZ *)lmr->param.pz_handle)->pd_handle,
-                                   (const uint8_t*)lmr->shmid,
-                                   &mr_create,
-                                   &virt_addr,
-                                   &l_key,
-                                   &r_key,
-                                   &new_mr_handle );
-    }
-    else
-    { 
-
-        ib_status = ib_reg_shared ( mr_handle,
-                                   ((DAPL_PZ *)lmr->param.pz_handle)->pd_handle,
-                                   access_ctrl,
-                                   /* in/out */(DAT_UINT64 *)&virt_addr,
-                                   &l_key,
-                                   &r_key,
-                                   &new_mr_handle );
-    }
-
-    if (ib_status != IB_SUCCESS)
-    {
-        return dapl_ib_status_convert (ib_status);
-    }
-    /*
-     * FIXME - Vu
-     *    What if virt_addr as an OUTPUT having the actual virtual address
-     *    assigned to the register region
-     */
-
-    /* DAT/DAPL expects context to be in host order */
-    l_key = cl_ntoh32(l_key);
-    r_key = cl_ntoh32(r_key);
-
-    dapl_dbg_log (DAPL_DBG_TYPE_UTIL, "--> DsIMRS: lmr (%p) lkey = 0x%x "
-                  "new mr_handle %p vaddr %p\n",
-                  lmr, l_key, new_mr_handle, virt_addr);
-
-    lmr->param.lmr_context = l_key;
-    lmr->param.rmr_context = r_key;
-    lmr->param.registered_address = (DAT_VADDR) (uintptr_t) virt_addr;
-    lmr->mr_handle         = new_mr_handle;
-
-    return (DAT_SUCCESS);
-}
-
-
-/*
- * dapls_ib_mw_alloc
- *
- * Bind a protection domain to a memory window
- *
- * Input:
- *     rmr                     Initialized rmr to hold binding handles
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *
- */
-DAT_RETURN
-dapls_ib_mw_alloc ( IN  DAPL_RMR    *rmr )
-{
-    ib_api_status_t     ib_status;
-    uint32_t            r_key;
-    ib_mw_handle_t      mw_handle;
-
-    ib_status = ib_create_mw (
-                  ((DAPL_PZ *)rmr->param.pz_handle)->pd_handle,
-                  &r_key,
-                  &mw_handle);
-
-    if (ib_status != IB_SUCCESS)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> DsIMA: create MW failed = %s\n",
-                       ib_get_err_str(ib_status) );
-        return dapl_ib_status_convert (ib_status);
-    }
-
-    rmr->mw_handle         = mw_handle;
-    rmr->param.rmr_context = (DAT_RMR_CONTEXT) cl_ntoh32(r_key);
-
-    dapl_dbg_log (DAPL_DBG_TYPE_UTIL, 
-                       "--> DsIMA: mw_handle %p r_key = 0x%x\n", 
-                        mw_handle, rmr->param.rmr_context);
-
-    return (DAT_SUCCESS);
-}
-
-
-/*
- * dapls_ib_mw_free
- *
- * Release bindings of a protection domain to a memory window
- *
- * Input:
- *     rmr                     Initialized rmr to hold binding handles
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *
- */
-DAT_RETURN
-dapls_ib_mw_free (
-        IN  DAPL_RMR                         *rmr)
-{
-    ib_api_status_t         ib_status;
-
-    dapl_dbg_log (DAPL_DBG_TYPE_UTIL, 
-                       "--> DsIMF: mw_handle %p\n", rmr->mw_handle);
-
-    ib_status = ib_destroy_mw (rmr->mw_handle);
-
-    if (ib_status != IB_SUCCESS)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR, "--> DsIMF: Free MW failed = %s\n",
-                       ib_get_err_str(ib_status));
-        return dapl_ib_status_convert (ib_status);
-    }
-
-    rmr->param.rmr_context = 0;
-    rmr->mw_handle         = IB_INVALID_HANDLE;
-
-    return (DAT_SUCCESS);
-}
-
-/*
- * dapls_ib_mw_bind
- *
- * Bind a protection domain to a memory window
- *
- * Input:
- *     rmr                     Initialized rmr to hold binding handles
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *
- */
-DAT_RETURN
-dapls_ib_mw_bind (
-        IN  DAPL_RMR                *rmr,
-        IN  DAPL_LMR                *lmr,
-        IN  DAPL_EP                 *ep,
-        IN  DAPL_COOKIE             *cookie,
-        IN  DAT_VADDR               virtual_address,
-        IN  DAT_VLEN                length,
-        IN  DAT_MEM_PRIV_FLAGS      mem_priv,
-        IN  ib_bool_t               is_signaled)
-{
-    ib_api_status_t       ib_status;
-    ib_bind_wr_t          bind_wr_prop;
-    uint32_t              new_rkey;
-    
-    bind_wr_prop.local_ds.vaddr   = virtual_address;
-    bind_wr_prop.local_ds.length  = (uint32_t)length;
-    bind_wr_prop.local_ds.lkey    = cl_hton32(lmr->param.lmr_context);
-    bind_wr_prop.current_rkey     = cl_hton32(rmr->param.rmr_context);
-    bind_wr_prop.access_ctrl      = dapl_rmr_convert_privileges (mem_priv);
-    bind_wr_prop.send_opt         = (is_signaled == TRUE) ? 
-                                    IB_SEND_OPT_SIGNALED : 0;
-    bind_wr_prop.wr_id            = (uint64_t) ((uintptr_t) cookie);
-    bind_wr_prop.h_mr             = lmr->mr_handle;
-
-    dapl_dbg_log (DAPL_DBG_TYPE_UTIL, "--> DsIMB: mr_handle %p, mw_handle %p "
-                  "vaddr %#I64x length %#I64x\n", 
-                  lmr->mr_handle, rmr->mw_handle, virtual_address, length);
-
-    ib_status = ib_bind_mw (
-                    rmr->mw_handle,
-                    ep->qp_handle,
-                    &bind_wr_prop,
-                    &new_rkey);
-
-    if (ib_status != IB_SUCCESS)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR, "--> DsIMB: Bind MW failed = %s\n", 
-                       ib_get_err_str(ib_status));
-        return (dapl_ib_status_convert (ib_status));
-    }
-
-    rmr->param.rmr_context      = (DAT_RMR_CONTEXT) cl_ntoh32(new_rkey);
-
-    dapl_dbg_log (DAPL_DBG_TYPE_UTIL,
-                       "--> DsIMB: new_rkey = 0x%x\n", rmr->param.rmr_context);
-
-    return (DAT_SUCCESS);
-}
-
-/*
- * dapls_ib_mw_unbind
- *
- * Unbind a memory window
- *
- * Input:
- *     rmr                     Initialized rmr to hold binding handles
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *
- */
-DAT_RETURN
-dapls_ib_mw_unbind (
-       IN  DAPL_RMR            *rmr,
-       IN  DAPL_EP             *ep,
-       IN  DAPL_COOKIE         *cookie,
-       IN  ib_bool_t           is_signaled)
-{
-    ib_api_status_t       ib_status;
-    ib_bind_wr_t          bind_wr_prop;
-    uint32_t              new_rkey;
-    
-    bind_wr_prop.local_ds.vaddr   = 0;
-    bind_wr_prop.local_ds.length  = 0;
-    bind_wr_prop.local_ds.lkey    = 0;
-    bind_wr_prop.access_ctrl      = 0;
-    bind_wr_prop.send_opt         = (is_signaled == TRUE) ? 
-                                    IB_SEND_OPT_SIGNALED : 0;
-    bind_wr_prop.wr_id            = (uint64_t) ((uintptr_t) cookie);
-
-    dapl_dbg_log (DAPL_DBG_TYPE_UTIL, 
-                       "--> DsIMU: mw_handle = %p\n", rmr->mw_handle);
-
-    ib_status = ib_bind_mw (
-                    rmr->mw_handle,
-                    ep->qp_handle,
-                    &bind_wr_prop,
-                    &new_rkey);
-
-    if (ib_status != IB_SUCCESS)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR, "--> DsIMU: Unbind MW failed = %s\n", 
-                ib_get_err_str(ib_status));
-        return (dapl_ib_status_convert (ib_status));
-    }
-
-    rmr->param.rmr_context      = (DAT_RMR_CONTEXT) cl_ntoh32(new_rkey);
-
-    dapl_dbg_log (DAPL_DBG_TYPE_UTIL, 
-                  "--> DsIMU: unbind new_rkey 0x%x\n", rmr->param.rmr_context);
-
-    return (DAT_SUCCESS);
-}
-
-
-/*
- * dapls_ib_setup_async_callback
- *
- * Set up an asynchronous callbacks of various kinds
- *
- * Input:
- *     ia_handle               IA handle
- *     handler_type            type of handler to set up
- *     callback_handle         handle param for completion callbacks
- *     callback                callback routine pointer
- *     context                 argument for callback routine
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *     DAT_INVALID_PARAMETER
- *
- */
-DAT_RETURN
-dapls_ib_setup_async_callback (
-        IN  DAPL_IA                     *ia_ptr,
-        IN  DAPL_ASYNC_HANDLER_TYPE     handler_type,
-        IN  DAPL_EVD                    *evd_ptr,
-        IN  ib_async_handler_t          callback,
-        IN  void                        *context )
-{
-    dapl_ibal_ca_t     *p_ca;
-    dapl_ibal_evd_cb_t *evd_cb;
-
-    dapl_dbg_log (DAPL_DBG_TYPE_UTIL,
-                  " setup_async_cb: ia %p type %d hdl %p cb %p ctx %p\n",
-                  ia_ptr, handler_type, evd_ptr, callback, context);
-
-    p_ca = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;
-
-    if (p_ca == NULL)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR, "--> DsISAC: can't find %s HCA\n", 
-                       (ia_ptr->header.provider)->device_name);
-        return (DAT_INVALID_HANDLE);
-    }
-   
-    if (handler_type != DAPL_ASYNC_CQ_COMPLETION)
-    {
-        evd_cb = dapli_find_evd_cb_by_context (context, p_ca);
-           
-        if (evd_cb == NULL)
-        {
-            /* 
-             * No record for this evd. We allocate one
-             */
-            evd_cb = dapl_os_alloc (sizeof (dapl_ibal_evd_cb_t));
-            dapl_os_memzero (evd_cb, sizeof(dapl_ibal_evd_cb_t));
-
-            if (evd_cb == NULL)
-            {
-                dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                               "--> %s: can't alloc res\n","DsISAC"); 
-                return (DAT_INSUFFICIENT_RESOURCES);
-            }
-        
-            evd_cb->context          = context;
-        
-            /*
-             *  Add the new EVD CB to the list
-             */
-            LOCK_INSERT_TAIL( p_ca->evd_cb_lock, 
-                              p_ca->evd_cb_head,
-                              evd_cb->next );
-        }
-
-        switch (handler_type)
-        {
-            case DAPL_ASYNC_UNAFILIATED:
-                evd_cb->pfn_async_err_cb = callback;
-                break;
-            case DAPL_ASYNC_CQ_ERROR:
-                evd_cb->pfn_async_cq_err_cb = callback;
-                break;
-            case DAPL_ASYNC_QP_ERROR:
-                evd_cb->pfn_async_qp_err_cb = callback;
-                break;
-            default:
-                break;
-        }
-
-    }
-
-    return DAT_SUCCESS;
-}
-
-
-/*
- * dapls_ib_query_gid
- *
- * Query the hca for the gid of the 1st active port.
- *
- * Input:
- *     hca_handl               hca handle      
- *     ep_attr                 attribute of the ep
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INVALID_HANDLE
- *     DAT_INVALID_PARAMETER
- */
-
-DAT_RETURN
-dapls_ib_query_gid( IN  DAPL_HCA       *hca_ptr,
-                   IN  GID             *gid )
-{
-    dapl_ibal_ca_t    *p_ca;
-    ib_ca_attr_t      *p_hca_attr;
-    ib_api_status_t   ib_status;
-    ib_hca_port_t     port_num;
-
-    p_ca = (dapl_ibal_ca_t *) hca_ptr->ib_hca_handle;
-
-    if (p_ca == NULL)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "%s() invalid hca_ptr %p", __FUNCTION__, hca_ptr);
-        return DAT_INVALID_HANDLE;
-    }
-
-    ib_status = ib_query_ca (
-                          p_ca->h_ca,
-                          p_ca->p_ca_attr,
-                          &p_ca->ca_attr_size);
-    if (ib_status != IB_SUCCESS)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "%s() ib_query_ca returned failed status = %s\n", 
-                       ib_get_err_str(ib_status));
-        return dapl_ib_status_convert (ib_status);
-    }
-
-    p_hca_attr = p_ca->p_ca_attr;
-    port_num = hca_ptr->port_num - 1;
-
-    gid->gid_prefix = p_hca_attr->p_port_attr[port_num].p_gid_table->unicast.prefix;
-    gid->guid = p_hca_attr->p_port_attr[port_num].p_gid_table->unicast.interface_id;
-    return DAT_SUCCESS;
-}
-
-
-/*
- * dapls_ib_query_hca
- *
- * Query the hca attribute
- *
- * Input:
- *     hca_handl               hca handle      
- *     ep_attr                 attribute of the ep
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INVALID_PARAMETER
- */
-
-DAT_RETURN dapls_ib_query_hca (
-       IN  DAPL_HCA                       *hca_ptr,
-        OUT DAT_IA_ATTR                    *ia_attr,
-        OUT DAT_EP_ATTR                    *ep_attr,
-       OUT DAT_SOCK_ADDR6                 *ip_addr)
-{
-    ib_ca_attr_t      *p_hca_attr;
-    dapl_ibal_ca_t    *p_ca;
-    ib_api_status_t   ib_status;
-    ib_hca_port_t     port_num;
-    GID gid;
-    DAT_SOCK_ADDR6      *p_sock_addr;
-    DAT_RETURN dat_status = DAT_SUCCESS;
-    port_num = hca_ptr->port_num;
-
-    p_ca = (dapl_ibal_ca_t *) hca_ptr->ib_hca_handle;
-
-    if (p_ca == NULL)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,  "--> %s: invalid handle %p",
-                       "DsIQH", hca_ptr);
-        return (DAT_INVALID_HANDLE);
-    }
-
-    ib_status = ib_query_ca (
-                          p_ca->h_ca,
-                          p_ca->p_ca_attr,
-                          &p_ca->ca_attr_size);
-    if (ib_status != IB_SUCCESS)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> DsIQH: ib_query_ca returned failed status = %s\n", 
-                       ib_get_err_str(ib_status));
-        return (dapl_ib_status_convert (ib_status));
-    }
-
-    p_hca_attr = p_ca->p_ca_attr;
-
-    if (ip_addr != NULL)
-    {
-       p_sock_addr = dapl_os_alloc(sizeof(DAT_SOCK_ADDR6));
-       if ( !p_sock_addr )
-       {
-               dat_status = DAT_INSUFFICIENT_RESOURCES;
-               dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                                       " Query Hca alloc Err: status %d\n",
-                                       dat_status);
-               return dat_status;
-       }
-       dapl_os_memzero(p_sock_addr, sizeof(DAT_SOCK_ADDR6));
-
-       gid.gid_prefix = p_hca_attr->p_port_attr[port_num-1].p_gid_table->unicast.prefix;
-       gid.guid = p_hca_attr->p_port_attr[port_num-1].p_gid_table->unicast.interface_id;
-       
-       dat_status = dapls_ns_map_ipaddr( hca_ptr,
-                                          gid,
-                                          (DAT_IA_ADDRESS_PTR)p_sock_addr);
-       
-       if ( dat_status != DAT_SUCCESS )
-       {
-            dapl_dbg_log (DAPL_DBG_TYPE_ERR,
-                          " SA Query for local IP failed= %d\n", dat_status );
-                       /* what to do next ? */
-       }
-       else
-       {
-           dapl_dbg_log (DAPL_DBG_TYPE_CM, "SA query GID for IP: ");
-            dapl_dbg_log ( DAPL_DBG_TYPE_CM, "%0d:%d:%d:%d\n", 
-               (uint8_t)((DAT_IA_ADDRESS_PTR )p_sock_addr)->sa_data[2]&0xff,
-               (uint8_t)((DAT_IA_ADDRESS_PTR )p_sock_addr)->sa_data[3]&0xff,
-               (uint8_t)((DAT_IA_ADDRESS_PTR )p_sock_addr)->sa_data[4]&0xff,
-               (uint8_t)((DAT_IA_ADDRESS_PTR )p_sock_addr)->sa_data[5]&0xff);
-        }
-
-        hca_ptr->hca_address = *p_sock_addr;
-
-        /* if structure address not from our hca_ptr */
-        if ( ip_addr  != &hca_ptr->hca_address )
-        {
-            *ip_addr = *p_sock_addr;
-        }
-
-       dapl_os_free (p_sock_addr, sizeof(DAT_SOCK_ADDR6));
-
-    } /* ip_addr != NULL */
-
-    if ( ia_attr != NULL )
-    {
-        dapl_os_memzero( ia_attr->adapter_name,
-                         (int)sizeof(ia_attr->adapter_name ));
-        dapl_os_memcpy(ia_attr->adapter_name,
-                        DAT_ADAPTER_NAME, 
-                        min ( (int)dapl_os_strlen(DAT_ADAPTER_NAME),
-                              (int)(DAT_NAME_MAX_LENGTH)-1 ) );
-
-        dapl_os_memzero ( ia_attr->vendor_name,
-                          (int)sizeof(ia_attr->vendor_name) );
-        dapl_os_memcpy ( ia_attr->vendor_name, 
-                         DAT_VENDOR_NAME,
-                        min ( (int)dapl_os_strlen(DAT_VENDOR_NAME),
-                              (int)(DAT_NAME_MAX_LENGTH)-1 ) );
-        
-        /* FIXME : Vu
-         *         this value should be revisited
-         *         It can be set by DAT consumers
-         */
-        ia_attr->ia_address_ptr           = (DAT_PVOID)&hca_ptr->hca_address;
-        ia_attr->hardware_version_major   = p_hca_attr->dev_id;
-        ia_attr->hardware_version_minor   = p_hca_attr->revision;
-        ia_attr->max_eps                  = p_hca_attr->max_qps;
-        ia_attr->max_dto_per_ep           = p_hca_attr->max_wrs;
-        ia_attr->max_rdma_read_per_ep     = p_hca_attr->max_qp_resp_res;
-        ia_attr->max_evds                 = p_hca_attr->max_cqs;
-        ia_attr->max_evd_qlen             = p_hca_attr->max_cqes;
-        ia_attr->max_iov_segments_per_dto = p_hca_attr->max_sges;
-        ia_attr->max_lmrs                 = p_hca_attr->init_regions;
-        ia_attr->max_lmr_block_size       = p_hca_attr->init_region_size;
-        ia_attr->max_rmrs                 = p_hca_attr->init_windows;
-        ia_attr->max_lmr_virtual_address  = p_hca_attr->max_addr_handles;
-        ia_attr->max_rmr_target_address   = p_hca_attr->max_addr_handles;
-        ia_attr->max_pzs                  = p_hca_attr->max_pds;
-        /*
-         * DAT spec does not tie max_mtu_size with IB MTU
-         *
-        ia_attr->max_mtu_size             = 
-                        dapl_ibal_mtu_table[p_hca_attr->p_port_attr->mtu];
-        */
-        ia_attr->max_mtu_size             = 
-                        p_hca_attr->p_port_attr->max_msg_size;
-        ia_attr->max_rdma_size            = 
-                        p_hca_attr->p_port_attr->max_msg_size;
-        ia_attr->num_transport_attr       = 0;
-        ia_attr->transport_attr           = NULL;
-        ia_attr->num_vendor_attr          = 0;
-        ia_attr->vendor_attr              = NULL;
-        ia_attr->max_iov_segments_per_rdma_read = p_hca_attr->max_sges;
-
-#ifdef DAT_EXTENSIONS
-        ia_attr->extension_supported = DAT_EXTENSION_IB;
-        ia_attr->extension_version = DAT_IB_EXTENSION_VERSION;
-#endif
-       
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, 
-               " --> DsIMU_qHCA: (ver=%x) ep %d ep_q %d evd %d evd_q %d\n", 
-                       ia_attr->hardware_version_major,
-                       ia_attr->max_eps, ia_attr->max_dto_per_ep,
-                       ia_attr->max_evds, ia_attr->max_evd_qlen );
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, 
-               " --> DsIMU_qHCA: mtu %llu rdma %llu iov %d lmr %d rmr %d"
-               " rdma_io %d\n", 
-                       ia_attr->max_mtu_size, ia_attr->max_rdma_size,
-                       ia_attr->max_iov_segments_per_dto, ia_attr->max_lmrs, 
-                       ia_attr->max_rmrs, ia_attr->max_rdma_read_per_ep );
-    }
-
-    if ( ep_attr != NULL )
-    {
-       (void) dapl_os_memzero(ep_attr, sizeof(*ep_attr)); 
-        /*
-         * DAT spec does not tie max_mtu_size with IB MTU
-         *
-        ep_attr->max_mtu_size     = 
-                        dapl_ibal_mtu_table[p_hca_attr->p_port_attr->mtu];
-         */
-        ep_attr->max_mtu_size     = p_hca_attr->p_port_attr->max_msg_size;
-        ep_attr->max_rdma_size    = p_hca_attr->p_port_attr->max_msg_size;
-        ep_attr->max_recv_dtos    = p_hca_attr->max_wrs;
-        ep_attr->max_request_dtos = p_hca_attr->max_wrs;
-        ep_attr->max_recv_iov     = p_hca_attr->max_sges;
-        ep_attr->max_request_iov  = p_hca_attr->max_sges;
-        ep_attr->max_rdma_read_in = p_hca_attr->max_qp_resp_res;
-        ep_attr->max_rdma_read_out= p_hca_attr->max_qp_resp_res;
-       
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, 
-               " --> DsIMU_qHCA: msg %llu dto %d iov %d rdma i%d,o%d\n", 
-                       ep_attr->max_mtu_size,
-                       ep_attr->max_recv_dtos, ep_attr->max_recv_iov,
-                       ep_attr->max_rdma_read_in, ep_attr->max_rdma_read_out);
-    }
-       return DAT_SUCCESS;
-}
-
-
-DAT_RETURN
-dapls_ib_completion_poll ( IN DAPL_HCA                *p_hca,
-                           IN DAPL_EVD                *p_evd,
-                           IN ib_work_completion_t   *cqe_ptr )
-{
-    ib_api_status_t        ib_status;
-    ib_work_completion_t   *cqe_filled;
-
-    /*
-     * FIXME - Vu
-     *     Now we only poll for one cqe. We can poll for more than
-     *     one completions later for better. However, this requires
-     *     to change the logic in dapl_evd_dto_callback function
-     *     to process more than one completion.
-     */
-    cqe_ptr->p_next = NULL;
-    cqe_filled      = NULL;
-
-    if  ( !p_hca->ib_hca_handle )
-    {
-        return DAT_INVALID_HANDLE;
-    }
-
-    ib_status = ib_poll_cq (p_evd->ib_cq_handle, &cqe_ptr, &cqe_filled);
-
-    if ( ib_status == IB_INVALID_CQ_HANDLE )
-    {
-        ib_status = IB_NOT_FOUND;
-    }
-
-    return dapl_ib_status_convert (ib_status);
-}
-
-
-DAT_RETURN
-dapls_ib_completion_notify ( IN ib_hca_handle_t         hca_handle,
-                             IN DAPL_EVD                *p_evd,
-                             IN ib_notification_type_t  type )
-{
-    ib_api_status_t        ib_status;
-    DAT_BOOLEAN            solic_notify;
-
-    if  ( !hca_handle )
-    {
-        return DAT_INVALID_HANDLE;
-    }
-    solic_notify = (type == IB_NOTIFY_ON_SOLIC_COMP) ? DAT_TRUE : DAT_FALSE; 
-    ib_status = ib_rearm_cq ( p_evd->ib_cq_handle, solic_notify );
-
-    return dapl_ib_status_convert (ib_status);
-}
-
-
-
-DAT_RETURN
-dapls_ib_wait_object_create (
-        IN cl_waitobj_handle_t* p_cq_wait_obj_handle)
-{
-    cl_status_t        cl_status;
-
-    cl_status = cl_waitobj_create (FALSE /* auto_reset */, p_cq_wait_obj_handle);
-
-    if (cl_status == CL_SUCCESS)
-        return DAT_SUCCESS;
-
-    return DAT_INTERNAL_ERROR;
-}
-
-
-DAT_RETURN
-dapls_ib_wait_object_destroy (
-        IN cl_waitobj_handle_t    cq_wait_obj_handle)
-{
-    cl_status_t        cl_status;
-
-    cl_status = cl_waitobj_destroy (cq_wait_obj_handle);
-
-    if (cl_status == CL_SUCCESS)
-        return DAT_SUCCESS;
-
-    return DAT_INTERNAL_ERROR;
-}
-
-
-DAT_RETURN
-dapls_ib_wait_object_wakeup (
-        IN cl_waitobj_handle_t    cq_wait_obj_handle)
-{
-    cl_status_t        cl_status;
-
-    cl_status = cl_waitobj_signal (cq_wait_obj_handle);
-
-    if (cl_status == CL_SUCCESS)
-        return DAT_SUCCESS;
-
-    return DAT_INTERNAL_ERROR;
-}
-
-
-DAT_RETURN
-dapls_ib_wait_object_wait (
-        IN cl_waitobj_handle_t cq_wait_obj_handle,
-        IN uint32_t timeout)
-{
-    cl_status_t        cl_status;
-
-    cl_status = cl_waitobj_wait_on (cq_wait_obj_handle, timeout, TRUE ); 
-
-    switch (cl_status)
-    {
-        case CL_SUCCESS: 
-            return DAT_SUCCESS;
-
-        case CL_TIMEOUT: 
-            dapl_dbg_log (DAPL_DBG_TYPE_ERR,
-                         "--> wait_object_wait: cl_timeout: %d\n", timeout);
-            return DAT_TIMEOUT_EXPIRED;
-
-        case CL_NOT_DONE: 
-            return DAT_SUCCESS;
-
-        default: 
-            dapl_dbg_log (DAPL_DBG_TYPE_ERR,
-                         "--> wait_object_wait: cl_error: %d\n", cl_status);
-            return DAT_INTERNAL_ERROR;
-    }
-}
-
-
-/*
- * dapls_ib_get_async_event
- *
- * Translate an asynchronous event type to the DAT event.
- * Note that different providers have different sets of errors.
- *
- * Input:
- *     cause_ptr               provider event cause
- *
- * Output:
- *     async_event             DAT mapping of error
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_NOT_IMPLEMENTED     Caller is not interested this event
- */
-
-DAT_RETURN dapls_ib_get_async_event(
-       IN  ib_async_event_rec_t        *cause_ptr,
-       OUT DAT_EVENT_NUMBER            *async_event)
-{
-    ib_async_event_t           event_id;
-    DAT_RETURN                 dat_status;
-
-    dat_status = DAT_SUCCESS;
-    event_id = cause_ptr->code;
-
-    dapl_dbg_log (DAPL_DBG_TYPE_WARN, "--> DsAE: event_id = %d%d\n", event_id);
-
-    switch (event_id )
-    {
-        case IB_AE_SQ_ERROR:
-        case IB_AE_SQ_DRAINED:
-        case IB_AE_RQ_ERROR:
-       {
-           *async_event = DAT_ASYNC_ERROR_EP_BROKEN;
-           break;
-       }
-
-       /* INTERNAL errors */
-        case IB_AE_QP_FATAL:
-       case IB_AE_CQ_ERROR:
-       case IB_AE_LOCAL_FATAL:
-       case IB_AE_WQ_REQ_ERROR:
-       case IB_AE_WQ_ACCESS_ERROR:
-       {
-           *async_event = DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR;
-           break;
-       }
-
-       /* CATASTROPHIC errors */
-       case IB_AE_FLOW_CTRL_ERROR:
-       case IB_AE_BUF_OVERRUN:
-       {
-           *async_event = DAT_ASYNC_ERROR_IA_CATASTROPHIC;
-           break;
-       }
-
-       default:
-       {
-           /*
-            * Errors we are not interested in reporting:
-            * IB_AE_QP_APM
-            * IB_AE_PKEY_TRAP
-            * IB_AE_QKEY_TRAP
-            * IB_AE_MKEY_TRAP
-            * IB_AE_PORT_TRAP
-            * IB_AE_QP_APM_ERROR
-            * IB_AE_PORT_ACTIVE
-            * ...
-            */
-           dat_status = DAT_NOT_IMPLEMENTED;
-       }
-
-    }
-  
-    return dat_status;
-}
-
-/*
- * dapls_ib_get_dto_status
- *
- * Return the DAT status of a DTO operation
- *
- * Input:
- *     cqe_ptr                 pointer to completion queue entry
- *
- * Output:
- *     none
- *
- * Returns:
- *     Value from ib_status_map table above
- */
-
-DAT_DTO_COMPLETION_STATUS
-dapls_ib_get_dto_status(
-       IN ib_work_completion_t         *cqe_ptr)
-{
-    ib_uint32_t    ib_status;
-
-    ib_status = DAPL_GET_CQE_STATUS (cqe_ptr);
-
-    switch (ib_status)
-    {
-    case IB_COMP_ST_SUCCESS :
-       return  DAT_DTO_SUCCESS;
-
-    case IB_COMP_ST_LOCAL_LEN_ERR:
-       return DAT_DTO_ERR_LOCAL_LENGTH;
-
-    case IB_COMP_ST_LOCAL_OP_ERR:
-       return DAT_DTO_ERR_LOCAL_EP;
-
-    case IB_COMP_ST_LOCAL_PROTECT_ERR:
-       return DAT_DTO_ERR_LOCAL_PROTECTION;
-
-    case IB_COMP_ST_WR_FLUSHED_ERR:    
-       return DAT_DTO_ERR_FLUSHED;
-
-    case IB_COMP_ST_MW_BIND_ERR:
-       return DAT_RMR_OPERATION_FAILED;
-
-    case IB_COMP_ST_REM_ACC_ERR:
-       return DAT_DTO_ERR_REMOTE_ACCESS;
-
-    case IB_COMP_ST_REM_OP_ERR:
-       return DAT_DTO_ERR_REMOTE_RESPONDER;
-
-    case IB_COMP_ST_RNR_COUNTER:
-       return DAT_DTO_ERR_RECEIVER_NOT_READY;
-
-    case IB_COMP_ST_TRANSP_COUNTER:
-       return DAT_DTO_ERR_TRANSPORT;
-
-    case IB_COMP_ST_REM_REQ_ERR:
-       return DAT_DTO_ERR_REMOTE_RESPONDER;
-
-    case IB_COMP_ST_BAD_RESPONSE_ERR:
-       return DAT_DTO_ERR_BAD_RESPONSE;
-
-    case IB_COMP_ST_EE_STATE_ERR:
-    case IB_COMP_ST_EE_CTX_NO_ERR:
-       return DAT_DTO_ERR_TRANSPORT;
-
-    default:
-#ifdef DAPL_DBG
-    dapl_dbg_log (DAPL_DBG_TYPE_ERR,"%s() unknown IB_COMP_ST %x(0x%x)\n",
-                  __FUNCTION__,ib_status,ib_status);
-#endif
-       return DAT_DTO_FAILURE;
-    }
-}
-
-
-/*
- * Map all IBAPI DTO completion codes to the DAT equivelent.
- *
- * dapls_ib_get_dat_event
- *
- * Return a DAT connection event given a provider CM event.
- *
- * N.B.        Some architectures combine async and CM events into a
- *     generic async event. In that case, dapls_ib_get_dat_event()
- *     and dapls_ib_get_async_event() should be entry points that
- *     call into a common routine.
- *
- * Input:
- *     ib_cm_event     event provided to the dapl callback routine
- *     active          switch indicating active or passive connection
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_EVENT_NUMBER of translated provider value
- */
-
-DAT_EVENT_NUMBER
-dapls_ib_get_dat_event (
-       IN    const ib_cm_events_t      ib_cm_event,
-       IN    DAT_BOOLEAN               active)
-{
-    DAT_EVENT_NUMBER           dat_event_num = 0;
-    UNREFERENCED_PARAMETER (active);
-
-    switch ( ib_cm_event)
-    {
-      case IB_CME_CONNECTED:
-          dat_event_num = DAT_CONNECTION_EVENT_ESTABLISHED;
-          break;
-      case IB_CME_DISCONNECTED:
-           dat_event_num = DAT_CONNECTION_EVENT_DISCONNECTED;
-           break;
-      case IB_CME_DISCONNECTED_ON_LINK_DOWN:
-           dat_event_num = DAT_CONNECTION_EVENT_DISCONNECTED;
-           break;
-      case IB_CME_CONNECTION_REQUEST_PENDING:
-           dat_event_num = DAT_CONNECTION_REQUEST_EVENT;
-           break;
-      case IB_CME_CONNECTION_REQUEST_PENDING_PRIVATE_DATA:
-           dat_event_num = DAT_CONNECTION_REQUEST_EVENT;
-           break;
-      case IB_CME_DESTINATION_REJECT:
-           dat_event_num = DAT_CONNECTION_EVENT_NON_PEER_REJECTED;
-           break;
-      case IB_CME_DESTINATION_REJECT_PRIVATE_DATA:
-           dat_event_num = DAT_CONNECTION_EVENT_PEER_REJECTED;
-           break;
-      case IB_CME_DESTINATION_UNREACHABLE:
-           dat_event_num = DAT_CONNECTION_EVENT_UNREACHABLE;
-           break;
-      case IB_CME_TOO_MANY_CONNECTION_REQUESTS:
-           dat_event_num = DAT_CONNECTION_EVENT_NON_PEER_REJECTED;
-           break;
-      case IB_CME_LOCAL_FAILURE:
-          dat_event_num = DAT_CONNECTION_EVENT_BROKEN;
-           break;
-      case IB_CME_REPLY_RECEIVED:
-      case IB_CME_REPLY_RECEIVED_PRIVATE_DATA:
-      default:
-           break;
-    }
-#if 0
-    dapl_dbg_log (DAPL_DBG_TYPE_CM,
-                 " dapls_ib_get_dat_event: event translation: (%s) "
-                 "ib_event 0x%x dat_event 0x%x\n",
-                 active ? "active" : "passive",
-                 ib_cm_event,
-                 dat_event_num);
-#endif
-    return dat_event_num;
-}
-
-
-/*
- * dapls_ib_get_dat_event
- *
- * Return a DAT connection event given a provider CM event.
- *
- * N.B.        Some architectures combine async and CM events into a
- *     generic async event. In that case, dapls_ib_get_cm_event()
- *     and dapls_ib_get_async_event() should be entry points that
- *     call into a common routine.
- *
- *     WARNING: In this implementation, there are multiple CM
- *     events that map to a single DAT event. Be very careful
- *     with provider routines that depend on this reverse mapping,
- *     they may have to accomodate more CM events than they
- *     'naturally' would.
- *
- * Input:
- *     dat_event_num   DAT event we need an equivelent CM event for
- *
- * Output:
- *     none
- *
- * Returns:
- *     ib_cm_event of translated DAPL value
- */
-ib_cm_events_t
-dapls_ib_get_cm_event (
-       IN    DAT_EVENT_NUMBER          dat_event_num)
-{
-    ib_cm_events_t     ib_cm_event = 0;
-
-    switch (dat_event_num)
-    {
-        case DAT_CONNECTION_EVENT_ESTABLISHED:
-             ib_cm_event = IB_CME_CONNECTED;
-             break;
-        case DAT_CONNECTION_EVENT_DISCONNECTED:
-             ib_cm_event = IB_CME_DISCONNECTED;
-             break;
-        case DAT_CONNECTION_REQUEST_EVENT:
-             ib_cm_event =  IB_CME_CONNECTION_REQUEST_PENDING;
-             break;
-        case DAT_CONNECTION_EVENT_NON_PEER_REJECTED:
-             ib_cm_event = IB_CME_DESTINATION_REJECT;
-             break;
-        case DAT_CONNECTION_EVENT_PEER_REJECTED:
-             ib_cm_event = IB_CME_DESTINATION_REJECT_PRIVATE_DATA;
-             break;
-        case DAT_CONNECTION_EVENT_UNREACHABLE:
-             ib_cm_event = IB_CME_DESTINATION_UNREACHABLE;
-             break;
-        case DAT_CONNECTION_EVENT_BROKEN:
-             ib_cm_event = IB_CME_LOCAL_FAILURE;
-             break;
-        default:
-             break;
-    }
-
-    return ib_cm_event;
-}
-
-
-
-/*
- * dapls_set_provider_specific_attr
- *
- * Input:
- *     attr_ptr        Pointer provider specific attributes
- *
- * Output:
- *     none
- *
- * Returns:
- *     void
- */
-
-#ifdef DAT_EXTENSIONS
-static DAT_NAMED_ATTR  ib_attrs[] = {
-    {
-       "DAT_EXTENSION_INTERFACE", "TRUE"
-    },
-    {
-       DAT_IB_ATTR_FETCH_AND_ADD, "TRUE"
-    },
-    {
-       DAT_IB_ATTR_CMP_AND_SWAP, "TRUE"
-    },
-    {
-       DAT_IB_ATTR_IMMED_DATA, "TRUE"
-    },
-};
-#define SPEC_ATTR_SIZE( x )    (sizeof( x ) / sizeof( DAT_NAMED_ATTR))
-#else
-static DAT_NAMED_ATTR  *ib_attrs = NULL;
-#define SPEC_ATTR_SIZE( x )    0
-#endif
-
-void dapls_query_provider_specific_attr(
-       IN      DAPL_IA                         *ia_ptr,
-       IN      DAT_PROVIDER_ATTR       *attr_ptr )
-{
-    attr_ptr->num_provider_specific_attr = SPEC_ATTR_SIZE(ib_attrs);
-    attr_ptr->provider_specific_attr     = ib_attrs;
-}
-
-
-DAT_RETURN dapls_ns_map_gid (
-       IN  DAPL_HCA            *hca_ptr,
-       IN  DAT_IA_ADDRESS_PTR  remote_ia_address,
-       OUT GID                 *gid)
-{
-    return (dapls_ib_ns_map_gid (hca_ptr, remote_ia_address, gid));
-}
-
-DAT_RETURN dapls_ns_map_ipaddr (
-       IN  DAPL_HCA            *hca_ptr,
-       IN  GID                 gid,
-       OUT DAT_IA_ADDRESS_PTR  remote_ia_address)
-{
-    return (dapls_ib_ns_map_ipaddr (hca_ptr, gid, remote_ia_address));
-}
-
-
-#ifdef NOT_USED
-/*
- * dapls_ib_post_recv - defered.until QP ! in init state.
- *
- * Provider specific Post RECV function
- */
-
-DAT_RETURN 
-dapls_ib_post_recv_defered (
-       IN  DAPL_EP                     *ep_ptr,
-       IN  DAPL_COOKIE                 *cookie,
-       IN  DAT_COUNT                   num_segments,
-       IN  DAT_LMR_TRIPLET             *local_iov)
-{
-    ib_api_status_t     ib_status;
-    ib_recv_wr_t       *recv_wr, *rwr;
-    ib_local_ds_t       *ds_array_p;
-    DAT_COUNT           i, total_len;
-
-    if (ep_ptr->qp_state != IB_QPS_INIT)
-    {
-        dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsPR: BAD QP state(%s), not init? "
-                      "EP %p QP %p cookie %p, num_seg %d\n", 
-                      ib_get_port_state_str(ep_ptr->qp_state), ep_ptr,
-                      ep_ptr->qp_handle, cookie, num_segments);
-       return (DAT_INSUFFICIENT_RESOURCES);
-    }
-
-    recv_wr = dapl_os_alloc (sizeof(ib_recv_wr_t)
-                             + (num_segments*sizeof(ib_local_ds_t)));
-    if (NULL == recv_wr)
-    {
-       return (DAT_INSUFFICIENT_RESOURCES);
-    }
-
-    dapl_os_memzero(recv_wr, sizeof(ib_recv_wr_t));
-    recv_wr->wr_id        = (DAT_UINT64) cookie;
-    recv_wr->num_ds       = num_segments;
-
-    ds_array_p = (ib_local_ds_t*)(recv_wr+1);
-
-    recv_wr->ds_array     = ds_array_p;
-
-    //total_len = 0;
-
-    for (total_len = i = 0; i < num_segments; i++, ds_array_p++)
-    {
-        ds_array_p->length = (uint32_t)local_iov[i].segment_length;
-        ds_array_p->lkey  = cl_hton32(local_iov[i].lmr_context);
-        ds_array_p->vaddr = local_iov[i].virtual_address;
-        total_len        += ds_array_p->length;
-    }
-
-    if (cookie != NULL)
-    {
-       cookie->val.dto.size = total_len;
-
-        dapl_dbg_log (DAPL_DBG_TYPE_EP,
-                      "--> DsPR: EP = %p QP = %p cookie= %p, num_seg= %d\n", 
-                      ep_ptr, ep_ptr->qp_handle, cookie, num_segments);
-    }
-
-    recv_wr->p_next = NULL;
-
-    /* find last defered recv work request, link new on the end */
-    rwr=ep_ptr->cm_post;
-    if (rwr == NULL)
-    {
-        ep_ptr->cm_post = (void*)recv_wr;
-        i = 1;
-    }
-    else
-    {
-        for(i=2; rwr->p_next; rwr=rwr->p_next) i++;
-        rwr->p_next = recv_wr;
-    }
-
-    dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsPR: %s() EP %p QP %p cookie %p "
-                  "num_seg %d Tdefered %d\n", 
-                  __FUNCTION__, ep_ptr, ep_ptr->qp_handle, cookie, num_segments,
-                  i);
-
-    return DAT_SUCCESS;
-}
-#endif
-
-/*
- * Local variables:
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 8
- * End:
- */
-
+/*\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.c\r
+ *\r
+ * PURPOSE: Utility routines for access to IBAL APIs\r
+ *\r
+ * $Id: dapl_ibal_util.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_cr_util.h"\r
+#include "dapl_lmr_util.h"\r
+#include "dapl_rmr_util.h"\r
+#include "dapl_cookie.h"\r
+#include "dapl_ring_buffer_util.h"\r
+\r
+#ifdef DAT_EXTENSIONS\r
+#include <dat2\dat_ib_extensions.h>\r
+#endif\r
+\r
+#ifndef NO_NAME_SERVICE\r
+#include "dapl_name_service.h"\r
+#endif /* NO_NAME_SERVICE */\r
+\r
+#include "dapl_ibal_name_service.h"\r
+\r
+#define DAPL_IBAL_MAX_CA 4\r
+#define DAT_ADAPTER_NAME "InfiniHost (Tavor)"\r
+#define DAT_VENDOR_NAME  "Mellanox Technolgy Inc."\r
+\r
+/*\r
+ *  Root data structure for DAPL_IIBA.\r
+ */\r
+dapl_ibal_root_t        dapl_ibal_root;\r
+DAPL_HCA_NAME           dapl_ibal_hca_name_array [DAPL_IBAL_MAX_CA] = \r
+                            {"IbalHca0", "IbalHca1", "IbalHca2", "IbalHca3"};\r
+ib_net64_t              *gp_ibal_ca_guid_tbl = NULL;\r
+\r
+/*\r
+ * DAT spec does not tie max_mtu_size with IB MTU\r
+ *\r
+static ib_net32_t dapl_ibal_mtu_table[6] = {0, 256, 512, 1024, 2048, 4096};\r
+ */\r
+    \r
+int g_loopback_connection = 0;\r
+\r
+\r
+static cl_status_t\r
+dapli_init_root_ca_list(\r
+    IN    dapl_ibal_root_t *root )\r
+{\r
+    cl_status_t status;\r
+\r
+    cl_qlist_init (&root->ca_head);\r
+    status = cl_spinlock_init (&root->ca_lock);\r
+\r
+    if (status == CL_SUCCESS)\r
+    {\r
+        /*\r
+         * Get the time ready to go but don't start here\r
+         */\r
+        root->shutdown = FALSE;\r
+        root->initialized = TRUE;\r
+    }\r
+    else\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                       "--> DiIRCL: cl_spinlock_init returned %d\n", status );\r
+        root->initialized = FALSE;\r
+    }\r
+    \r
+    root->h_al = NULL;\r
+\r
+    return (status);\r
+}\r
+\r
+\r
+static cl_status_t\r
+dapli_destroy_root_ca_list(\r
+    IN    dapl_ibal_root_t *root )\r
+{\r
+\r
+    root->initialized = FALSE;\r
+\r
+    /* \r
+     * At this point the lock should not be necessary\r
+     */\r
+    if (!cl_is_qlist_empty (&root->ca_head) )\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                       "--> Destroying nonempty ca list (%s)\n", "DiDRCL");\r
+    }\r
+    cl_spinlock_destroy (&root->ca_lock);\r
+\r
+    return CL_SUCCESS;\r
+}\r
+\r
+\r
+static void\r
+dapli_shutdown_port_access(\r
+    IN    dapl_ibal_ca_t    *ca )\r
+{\r
+    dapl_ibal_port_t    *p_port;\r
+\r
+    TAKE_LOCK( ca->port_lock );\r
+    {\r
+        while ( ! cl_is_qlist_empty( &ca->port_head ) )\r
+        {\r
+            p_port = (dapl_ibal_port_t *)cl_qlist_remove_head( &ca->port_head );\r
+            RELEASE_LOCK( ca->port_lock );\r
+            {\r
+                REMOVE_REFERENCE( &p_port->refs );\r
+                REMOVE_REFERENCE( &p_port->ca->refs );\r
+\r
+                dapl_os_free (p_port, sizeof (dapl_ibal_port_t));\r
+            }\r
+            TAKE_LOCK( ca->port_lock );\r
+        }\r
+    }\r
+    RELEASE_LOCK( ca->port_lock );\r
+}\r
+\r
+\r
+static void dapli_shutdown_ca_access (void)\r
+{\r
+    dapl_ibal_ca_t  *ca;\r
+\r
+    if ( dapl_ibal_root.initialized == FALSE )\r
+    {\r
+        goto destroy_root;\r
+    }\r
+\r
+    TAKE_LOCK (dapl_ibal_root.ca_lock);\r
+    {\r
+        while ( ! cl_is_qlist_empty (&dapl_ibal_root.ca_head) )\r
+        {\r
+            ca = (dapl_ibal_ca_t *)\r
+                                 cl_qlist_remove_head (&dapl_ibal_root.ca_head);\r
+\r
+            if (ca->p_ca_attr)\r
+            {\r
+                dapl_os_free (ca->p_ca_attr, sizeof (ib_ca_attr_t));\r
+            }\r
+\r
+\r
+            RELEASE_LOCK (dapl_ibal_root.ca_lock);\r
+            {\r
+                dapli_shutdown_port_access (ca);\r
+                REMOVE_REFERENCE (&ca->refs);\r
+            }\r
+            TAKE_LOCK (dapl_ibal_root.ca_lock);\r
+        }\r
+    }\r
+    RELEASE_LOCK (dapl_ibal_root.ca_lock);\r
+\r
+destroy_root:\r
+    /*\r
+     * Destroy the root CA list and list lock\r
+     */\r
+    dapli_destroy_root_ca_list (&dapl_ibal_root);\r
+\r
+    /*\r
+     * Signal we're all done and wake any waiter\r
+     */\r
+    dapl_ibal_root.shutdown = FALSE;\r
+}\r
+\r
+\r
+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
+    dapl_ibal_evd_cb_t *evd_cb = NULL;\r
+\r
+    TAKE_LOCK( ca->evd_cb_lock );\r
+\r
+    evd_cb = (dapl_ibal_evd_cb_t *) cl_qlist_head( &ca->evd_cb_head );\r
+    while ( &evd_cb->next != cl_qlist_end( &ca->evd_cb_head ) )\r
+    {\r
+        if ( context == evd_cb->context)\r
+        {\r
+            goto found;\r
+        }\r
+\r
+        /*\r
+         *  Try again\r
+         */\r
+        evd_cb = (dapl_ibal_evd_cb_t *) cl_qlist_next( &evd_cb->next );\r
+    }\r
+    /*\r
+     *  No joy\r
+     */\r
+    evd_cb = NULL;\r
+\r
+found:\r
+\r
+    RELEASE_LOCK( ca->evd_cb_lock );\r
+\r
+    return ( evd_cb );\r
+}\r
+\r
+\r
+static cl_status_t\r
+dapli_init_ca_evd_cb_list(\r
+    IN    dapl_ibal_ca_t    *ca )\r
+{\r
+    cl_status_t    status;\r
+\r
+    cl_qlist_init( &ca->evd_cb_head );\r
+    status = cl_spinlock_init( &ca->evd_cb_lock );\r
+    if ( status != CL_SUCCESS )\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR, "--> DiICECL: cl_spinlock_init returned %d\n", status);\r
+    return ( status );\r
+}\r
+\r
+\r
+static cl_status_t\r
+dapli_init_ca_port_list(\r
+    IN    dapl_ibal_ca_t    *ca )\r
+{\r
+    cl_status_t    status;\r
+\r
+    cl_qlist_init( &ca->port_head );\r
+    status = cl_spinlock_init( &ca->port_lock );\r
+    if ( status != CL_SUCCESS )\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                       "--> DiICPL: cl_spinlock_init returned %d\n", status );\r
+    return ( status );\r
+}\r
+\r
+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
+    cl_list_item_t    *p_active_port = NULL;\r
+    \r
+    TAKE_LOCK (p_ca->port_lock);\r
+    for ( p_active_port = cl_qlist_head( &p_ca->port_head );\r
+          p_active_port != cl_qlist_end ( &p_ca->port_head);\r
+          p_active_port =  cl_qlist_next ( p_active_port ) )\r
+    {\r
+        if (((dapl_ibal_port_t *)p_active_port)->p_attr->port_num == port_num)\r
+            break;     \r
+    }\r
+    RELEASE_LOCK (p_ca->port_lock);\r
+\r
+    return (dapl_ibal_port_t *)p_active_port;\r