]> git.openfabrics.org - ~shefty/rdma-win.git/commitdiff
[DAPL2] Fix socket CM completion handling and CNQ handling; Windows variants. Add...
authorstansmith <stansmith@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 4 Aug 2009 17:13:27 +0000 (17:13 +0000)
committerstansmith <stansmith@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 4 Aug 2009 17:13:27 +0000 (17:13 +0000)
#include <ws2tcpip.h> for IPv4 & IPv6 user application support (VC env vs. WDK).

git-svn-id: svn://openib.tc.cornell.edu/gen1@2326 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

19 files changed:
branches/WOF2-1/ulp/dapl2/dapl/common/dapl_adapter_util.h
branches/WOF2-1/ulp/dapl2/dapl/common/dapl_evd_dto_callb.c
branches/WOF2-1/ulp/dapl2/dapl/common/dapl_evd_util.c
branches/WOF2-1/ulp/dapl2/dapl/ibal/dapl_ibal_cq.c
branches/WOF2-1/ulp/dapl2/dapl/ibal/dapl_ibal_util.c
branches/WOF2-1/ulp/dapl2/dapl/ibal/dapl_ibal_util.h
branches/WOF2-1/ulp/dapl2/dapl/include/dapl.h
branches/WOF2-1/ulp/dapl2/dapl/openib_cma/dapl_ib_util.h
branches/WOF2-1/ulp/dapl2/dapl/openib_cma/device.c
branches/WOF2-1/ulp/dapl2/dapl/openib_common/cq.c
branches/WOF2-1/ulp/dapl2/dapl/openib_common/dapl_ib_common.h
branches/WOF2-1/ulp/dapl2/dapl/openib_common/qp.c
branches/WOF2-1/ulp/dapl2/dapl/openib_common/util.c
branches/WOF2-1/ulp/dapl2/dapl/openib_scm/dapl_ib_util.h
branches/WOF2-1/ulp/dapl2/dapl/openib_scm/device.c
branches/WOF2-1/ulp/dapl2/dapl/udapl/dapl_evd_set_unwaitable.c
branches/WOF2-1/ulp/dapl2/dapl/udapl/dapl_evd_wait.c
branches/WOF2-1/ulp/dapl2/dat/include/dat2/dat_platform_specific.h
branches/WOF2-1/ulp/dapl2/test/dtest/dtest.c

index 1a8b7ccb4a6d60c41e57b5e895e7c72487911764..e408d338fa2c84e23f84339c24a2a00a1862e458 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 2f0d1060225b74fb4c85ae042d6cd6c6c4bd8110..65fa9e74d97cd50e29bec4c23d14f797c1d18259 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 2cfd693b7697b8218a3e7153dfcb5f6bbe4895af..7756af1da2f33d330dd323f80b1fd962eced52bb 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 28de045c21b1adce0dd98ac77451ae885b8cd5f1..11ad8add6750bdfcb028bc62bab094531ef1ddb8 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 ad4acf0e3f2389b9a696cdffffa19b098a8b40e6..5f73086c7cf8ecf8bd559f06630a439d31e80c59 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
+}\r
+\r
+\r
+void\r
+dapli_ibal_ca_async_error_callback( IN ib_async_event_rec_t  *p_err_rec )\r
+{\r
+    dapl_ibal_ca_t     *p_ca = (dapl_ibal_ca_t*)((void *)p_err_rec->context);\r
+    dapl_ibal_evd_cb_t *evd_cb;\r
+    DAPL_IA            *ia_ptr;\r
+                       \r
+    dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                       "--> DiCaAEC: CA error %d for context %p\n", \r
+                       p_err_rec->code, p_err_rec->context);\r
+\r
+    if (p_ca == NULL)\r
+    {\r
+               dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> DiCaAEC: invalid p_ca"\r
+                              "(%p)in async event rec\n",p_ca);\r
+       return;\r
+    }\r
+       \r
+    ia_ptr = (DAPL_IA*)p_ca->ia_ptr;\r
+    if (ia_ptr == NULL)\r
+    {\r
+               dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
+                              "--> DiCaAEC: invalid ia_ptr in %p ca \n", p_ca );\r
+       return;\r
+    }\r
+\r
+    if (ia_ptr->async_error_evd == NULL)\r
+    {\r
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
+                      "--> DiCqAEC: can't find async_error_evd on %s HCA\n", \r
+                      (ia_ptr->header.provider)->device_name );\r
+        return;\r
+    }\r
+\r
+    /* find QP error callback using p_ca for context */\r
+    evd_cb = dapli_find_evd_cb_by_context (ia_ptr->async_error_evd, p_ca);\r
+    if ((evd_cb == NULL) || (evd_cb->pfn_async_err_cb == NULL))\r
+    {\r
+       dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
+                              "--> DiCaAEC: no ERROR cb on %p found \n", p_ca);\r
+       return;\r
+    }\r
+\r
+    /* maps to dapl_evd_un_async_error_callback(), context is async_evd */\r
+    evd_cb->pfn_async_err_cb( (ib_hca_handle_t)p_ca, \r
+                              (ib_error_record_t*)&p_err_rec->code, \r
+                              ia_ptr->async_error_evd );\r
+\r
+}\r
+\r
+\r
+static dapl_ibal_port_t *\r
+dapli_alloc_port(\r
+    IN    dapl_ibal_ca_t    *ca,\r
+    IN    ib_port_attr_t    *ib_port )\r
+{\r
+    dapl_ibal_port_t    *p_port = NULL;\r
+\r
+    if (ca->h_ca == NULL )\r
+    {\r
+       return NULL;\r
+    }\r
+\r
+    /*\r
+     *  Allocate the port structure memory.  This will also deal with the\r
+     *  copying ib_port_attr_t including GID and P_Key tables\r
+     */\r
+    p_port = dapl_os_alloc ( sizeof(dapl_ibal_port_t ) );\r
+\r
+    if ( p_port )\r
+    {\r
+        dapl_os_memzero (p_port, sizeof(dapl_ibal_port_t ) );\r
+\r
+        /*\r
+         *  We're good to go after initializing reference.\r
+         */\r
+        INIT_REFERENCE( &p_port->refs, 1, p_port, NULL /* pfn_destructor */ );\r
+               \r
+               p_port->p_attr = ib_port;\r
+    }\r
+    return ( p_port );\r
+}\r
+\r
+static void\r
+dapli_add_active_port(\r
+    IN dapl_ibal_ca_t   *ca )\r
+{\r
+    dapl_ibal_port_t     *p_port;\r
+    ib_port_attr_t       *p_port_attr;\r
+    ib_ca_attr_t         *p_ca_attr;\r
+    int                  i;\r
+\r
+    p_ca_attr = ca->p_ca_attr;\r
+\r
+    dapl_os_assert (p_ca_attr != NULL);\r
+\r
+    for (i = 0; i < p_ca_attr->num_ports; i++)\r
+    {\r
+        p_port_attr = &p_ca_attr->p_port_attr[i];\r
+\r
+        {\r
+            p_port = dapli_alloc_port( ca, p_port_attr );\r
+            if ( p_port )\r
+            {\r
+                TAKE_REFERENCE (&ca->refs);\r
+\r
+                /*\r
+                 *  Record / update attribues\r
+                 */\r
+                p_port->p_attr = p_port_attr;\r
+\r
+                /*\r
+                 *  Remember the parant CA keeping the reference we took above\r
+                 */\r
+                p_port->ca = ca;\r
+\r
+                /*\r
+                 *  We're good to go - Add the new port to the list on the CA\r
+                 */\r
+                LOCK_INSERT_TAIL( ca->port_lock, ca->port_head, p_port->next );\r
+            }\r
+            else\r
+            {\r
+                dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                               "--> %s: Could not allocate dapl_ibal_port_t\n",\r
+                               "DiAAP");\r
+            }\r
+        }\r
+       dapl_dbg_log( DAPL_DBG_TYPE_UTIL,\r
+                      "--> DiAAP: Port %d logical link %s lid = %#x\n",\r
+                      p_port_attr->port_num,\r
+                      ( p_port_attr->link_state != IB_LINK_ACTIVE\r
+                           ?  "DOWN": "UP" ),\r
+                      CL_HTON16(p_port_attr->lid) );\r
+\r
+    } /* for loop */\r
+}\r
+\r
+static dapl_ibal_ca_t *\r
+dapli_alloc_ca(\r
+    IN    ib_al_handle_t  h_al,\r
+    IN    ib_net64_t      ca_guid)\r
+{\r
+    dapl_ibal_ca_t         *p_ca;\r
+    ib_api_status_t        status;\r
+    uint32_t               attr_size;\r
+\r
+    /*\r
+     *  Allocate the CA structure\r
+     */\r
+    p_ca = dapl_os_alloc( sizeof(dapl_ibal_ca_t) );\r
+    dapl_os_memzero (p_ca, sizeof(dapl_ibal_ca_t) );\r
+\r
+    if ( p_ca )\r
+    {\r
+        /*\r
+         *  Now we pass dapli_ibal_ca_async_error_callback as the \r
+         *  async error callback\r
+         */\r
+        status = ib_open_ca( h_al,\r
+                             ca_guid,\r
+                             dapli_ibal_ca_async_error_callback,\r
+                             p_ca,\r
+                             &p_ca->h_ca );\r
+        if ( status != IB_SUCCESS )\r
+        {\r
+            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                           "--> DiAC: ib_open_ca returned %s\n",\r
+                           ib_get_err_str(status));\r
+            dapl_os_free (p_ca, sizeof (dapl_ibal_ca_t));\r
+            return (NULL);\r
+        }\r
+\r
+        /*\r
+         *  Get port list lock and list head initialized\r
+         */\r
+        if (( dapli_init_ca_port_list( p_ca ) != CL_SUCCESS ) ||\r
+            ( dapli_init_ca_evd_cb_list( p_ca ) != CL_SUCCESS ))\r
+        { \r
+            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                           "--> %s: dapli_init_ca_port_list returned failed\n",\r
+                           "DiAC");\r
+            goto close_and_free_ca;\r
+        }\r
+\r
+        attr_size = 0;\r
+        status = ib_query_ca (p_ca->h_ca, NULL, &attr_size);\r
+        if (status != IB_INSUFFICIENT_MEMORY)\r
+        {\r
+            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                          "--> DiAC: ib_query_ca returned failed status = %d\n",\r
+                          status);\r
+            goto close_and_free_ca;\r
+        }\r
+\r
+        p_ca->p_ca_attr = dapl_os_alloc ((int)attr_size);\r
+        if (p_ca->p_ca_attr == NULL)\r
+        {\r
+            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                           "--> %s: dapli_alloc_ca failed to alloc memory\n",\r
+                           "DiAC");\r
+            goto close_and_free_ca;\r
+        }\r
+\r
+        status = ib_query_ca (\r
+                          p_ca->h_ca,\r
+                          p_ca->p_ca_attr,\r
+                          &attr_size);\r
+        if (status != IB_SUCCESS)\r
+        {\r
+            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                           "--> ib_query_ca returned failed status = %d\n",\r
+                           status);\r
+            dapl_os_free (p_ca->p_ca_attr, (int)attr_size);\r
+            goto close_and_free_ca;\r
+        }\r
+       \r
+        p_ca->ca_attr_size = attr_size;\r
+\r
+        INIT_REFERENCE( &p_ca->refs, 1, p_ca, NULL /* pfn_destructor */ );\r
+\r
+        dapli_add_active_port (p_ca);\r
+\r
+        /*\r
+         *  We're good to go\r
+         */\r
+        return ( p_ca );\r
+    }\r
+    else\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                       "--> %s: Error allocating CA structure\n","DiAC");\r
+        return ( NULL );\r
+    }\r
+\r
+close_and_free_ca:\r
+   /*\r
+    *  Close the CA.\r
+    */\r
+   (void) ib_close_ca ( p_ca->h_ca, NULL /* callback */);\r
+   dapl_os_free (p_ca, sizeof (dapl_ibal_ca_t));\r
+\r
+    /*\r
+     *  If we get here, there was an initialization failure\r
+     */\r
+    return ( NULL );\r
+}\r
+\r
+\r
+static dapl_ibal_ca_t *\r
+dapli_add_ca (\r
+    IN   ib_al_handle_t    h_al,\r
+    IN   ib_net64_t        ca_guid )\r
+{\r
+    dapl_ibal_ca_t     *p_ca;\r
+\r
+    /*\r
+     *  Allocate a CA structure\r
+     */\r
+    p_ca = dapli_alloc_ca( h_al, ca_guid );\r
+    if ( p_ca )\r
+    {\r
+        /*\r
+         *  Add the new CA to the list\r
+         */\r
+        LOCK_INSERT_TAIL( dapl_ibal_root.ca_lock, \r
+                          dapl_ibal_root.ca_head, p_ca->next );\r
+    }\r
+    else\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                       "--> %s: Could not allocate dapl_ibal_ca_t "\r
+                       " for CA guid " F64x "\n","DiAA",ca_guid);\r
+    }\r
+\r
+    return ( p_ca );\r
+}\r
+\r
+\r
+int32_t\r
+dapls_ib_init (void)\r
+{\r
+    ib_api_status_t status;\r
+\r
+    /*\r
+     * Initialize the root structure\r
+     */\r
+    if ( dapli_init_root_ca_list (&dapl_ibal_root) == CL_SUCCESS )\r
+    {\r
+        /*\r
+         * Register with the access layer\r
+         */\r
+        status = ib_open_al (&dapl_ibal_root.h_al);\r
+\r
+        if (status == IB_SUCCESS)\r
+        {\r
+            intn_t             guid_count;\r
+\r
+            status = ib_get_ca_guids ( dapl_ibal_root.h_al,\r
+                                       NULL,\r
+                                       &(size_t)guid_count );\r
+            if (status != IB_INSUFFICIENT_MEMORY)\r
+            {\r
+                dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                               "--> %s: ib_get_ca_guids failed = %d\n",\r
+                               __FUNCTION__,status);\r
+                return -1;\r
+            }\r
+\r
+            if (guid_count == 0)\r
+            {\r
+                dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                               "--> %s: found NO HCA in the system\n",\r
+                               __FUNCTION__);\r
+                return -1;\r
+            }\r
+\r
+            if (guid_count > DAPL_IBAL_MAX_CA)\r
+            {\r
+                guid_count = DAPL_IBAL_MAX_CA;\r
+            }\r
+\r
+            gp_ibal_ca_guid_tbl = (ib_net64_t*)\r
+                                  dapl_os_alloc ( (int)(guid_count * \r
+                                                  sizeof (ib_net64_t)) );\r
+\r
+            if (gp_ibal_ca_guid_tbl == NULL)\r
+            {\r
+                dapl_dbg_log ( DAPL_DBG_TYPE_ERR, "--> %s() can not alloc "\r
+                               "gp_ibal_ca_guid_tbl\n", __FUNCTION__);\r
+                        \r
+                return -1;\r
+            }\r
+\r
+            status = ib_get_ca_guids ( dapl_ibal_root.h_al, \r
+                                       gp_ibal_ca_guid_tbl, \r
+                                       &(size_t)guid_count );\r
+                            \r
+\r
+            if ( status != IB_SUCCESS )\r
+            {\r
+                dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                               "--> %s: ib_get_ca_guids failed '%s'\n", \r
+                               __FUNCTION__, ib_get_err_str(status) );\r
+                return -1;\r
+            }\r
+\r
+            dapl_dbg_log ( DAPL_DBG_TYPE_UTIL, \r
+                           "--> %s: Success open AL & found %d HCA avail,\n",\r
+                           __FUNCTION__, guid_count);\r
+            return 0;\r
+        }\r
+        else\r
+        {        \r
+            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                           "--> %s: ib_open_al() failed '%s'\n",\r
+                           __FUNCTION__, ib_get_err_str(status) );\r
+            /*\r
+             * Undo CA list\r
+             */\r
+            dapli_destroy_root_ca_list (&dapl_ibal_root);\r
+        }\r
+    }\r
+    return -1;\r
+}\r
+\r
+\r
+int32_t dapls_ib_release (void)\r
+{\r
+    dapl_ibal_root.shutdown = TRUE;\r
+\r
+    dapli_shutdown_ca_access();\r
+\r
+    /*\r
+     * If shutdown not complete, wait for it\r
+     */\r
+    if (dapl_ibal_root.shutdown)\r
+    {\r
+        dapl_dbg_log (DAPL_DBG_TYPE_UTIL, \r
+                        "--> DsIR: timeout waiting for completion\n");\r
+    }\r
+\r
+    if ( dapl_ibal_root.h_al != NULL )\r
+    {\r
+        (void) ib_close_al (dapl_ibal_root.h_al);\r
+       dapl_dbg_log (DAPL_DBG_TYPE_UTIL, "--> DsIR: ib_close_al() returns\n");\r
+        dapl_ibal_root.h_al = NULL;\r
+    }\r
+#ifdef DBG\r
+    dapl_dbg_log (DAPL_DBG_TYPE_UTIL, "--> %s: Exit\n",__FUNCTION__);\r
+#endif\r
+\r
+    return 0;\r
+}\r
+\r
+\r
+/*\r
+ * dapls_ib_enum_hcas\r
+ *\r
+ * Enumerate all HCAs on the system\r
+ *\r
+ * Input:\r
+ *     none\r
+ *\r
+ * Output:\r
+ *     hca_names       Array of hca names\r
+ *     total_hca_count \r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *\r
+ */\r
+DAT_RETURN\r
+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
+    intn_t             guid_count;\r
+    ib_api_status_t    ib_status;\r
+    UNREFERENCED_PARAMETER(vendor);\r
+\r
+    ib_status = ib_get_ca_guids (dapl_ibal_root.h_al, NULL, &(size_t)guid_count);\r
+    if (ib_status != IB_INSUFFICIENT_MEMORY)\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                       "--> DsIEH: ib_get_ca_guids failed '%s'\n",\r
+                       ib_get_err_str(ib_status) );\r
+        return dapl_ib_status_convert (ib_status);\r
+    }\r
+\r
+    if (guid_count == 0)\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                       "--> %s: ib_get_ca_guids no HCA in the system\n",\r
+                       "DsIEH");\r
+        return (DAT_PROVIDER_NOT_FOUND);\r
+    }\r
+\r
+    if (guid_count > DAPL_IBAL_MAX_CA)\r
+    {\r
+        guid_count = DAPL_IBAL_MAX_CA;\r
+    }\r
+\r
+    gp_ibal_ca_guid_tbl = (ib_net64_t *)dapl_os_alloc ((int)(guid_count * sizeof (ib_net64_t)) );\r
+\r
+    if (gp_ibal_ca_guid_tbl == NULL)\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                       "--> %s: can not alloc resources @line%d\n", "DsIEH",\r
+                       __LINE__);\r
+        return (DAT_INSUFFICIENT_RESOURCES);\r
+    }\r
+\r
+    ib_status = ib_get_ca_guids ( dapl_ibal_root.h_al,\r
+                                  gp_ibal_ca_guid_tbl,\r
+                                  &(size_t)guid_count);\r
+\r
+    if (ib_status != IB_SUCCESS)\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                       "--> DsIEH: ib_get_ca_guids failed status = %s\n", \r
+                       ib_get_err_str(ib_status) );\r
+        return dapl_ib_status_convert (ib_status);\r
+    }\r
+\r
+    *hca_names = (DAPL_HCA_NAME*)\r
+                     dapl_os_alloc ((int)(guid_count * sizeof (DAPL_HCA_NAME)));\r
+\r
+    if (*hca_names == NULL)\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                       "--> %s: can not alloc resources @line%d\n",\r
+                       "DsIEH", __LINE__);\r
+        return (DAT_INSUFFICIENT_RESOURCES);\r
+    }\r
+\r
+    dapl_os_memcpy (*hca_names, \r
+                    dapl_ibal_hca_name_array, \r
+                    (int)(guid_count * sizeof (DAPL_HCA_NAME)) );\r
+\r
+    *total_hca_count = (DAT_COUNT)guid_count;\r
+\r
+    {\r
+        int i;\r
+\r
+        for (i = 0; i < guid_count; i++)\r
+            dapl_dbg_log (DAPL_DBG_TYPE_UTIL, "--> DsIEH: %d) hca_names = %s\n",\r
+                          i, dapl_ibal_hca_name_array[i]);\r
+    }\r
+\r
+    return (DAT_SUCCESS);\r
+}\r
+\r
+\r
+\r
+IB_HCA_NAME\r
+dapl_ib_convert_name(\r
+    IN  char    *name)\r
+{\r
+    int                i;\r
+\r
+    if (gp_ibal_ca_guid_tbl  == NULL)\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                       "--> DICN: found no HCA with name %s\n", name );\r
+        return 0;\r
+    }\r
+\r
+    for (i = 0; i < DAPL_IBAL_MAX_CA; i++)\r
+    {\r
+        if (strcmp (name, dapl_ibal_hca_name_array[i]) == 0)\r
+        {\r
+            break;\r
+        }\r
+    }\r
+\r
+    if (i >= DAPL_IBAL_MAX_CA)\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                       "--> DICN: can't find any HCA with name %s\n", name);\r
+        return 0;\r
+    }\r
+   \r
+    return (gp_ibal_ca_guid_tbl[i]);\r
+}\r
+\r
+\r
+/*\r
+ * dapls_ib_open_hca\r
+ *\r
+ * Open HCA\r
+ *\r
+ * Input:\r
+ *      *hca_name         pointer to provider device name\r
+ *      *ib_hca_handle_p  pointer to provide HCA handle\r
+ *\r
+ * Output:\r
+ *      none\r
+ *\r
+ * Return:\r
+ *      DAT_SUCCESS\r
+ *      DAT_INSUFFICIENT_RESOURCES\r
+ *\r
+ */\r
+DAT_RETURN dapls_ib_open_hca ( IN  char         *hca_name,\r
+                               IN  DAPL_HCA     *p_hca )\r
+{\r
+    dapl_ibal_ca_t     *p_ca;\r
+    IB_HCA_NAME        ca_guid;\r
+\r
+    dapl_dbg_log (DAPL_DBG_TYPE_UTIL," open_hca: %s - %p\n", hca_name, p_hca);\r
+\r
+    if (gp_ibal_ca_guid_tbl  == NULL)\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR, "--> DsIOH: found no HCA with ca_guid"\r
+                       F64x "\n", hca_name);\r
+        return (DAT_PROVIDER_NOT_FOUND);\r
+    }\r
+\r
+    ca_guid = dapl_ib_convert_name(hca_name);\r
+\r
+    p_ca = dapli_add_ca (dapl_ibal_root.h_al, ca_guid);\r
+\r
+    if (p_ca == NULL)\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                     "--> DsIOH: can not create ca for '%s' guid " F64x "\n",\r
+                     hca_name, ca_guid);\r
+        return (DAT_INSUFFICIENT_RESOURCES);\r
+    }\r
+\r
+    p_hca->ib_hca_handle = (ib_hca_handle_t) p_ca;\r
+    p_hca->ib_trans.d_hca = p_hca; // back-link\r
+\r
+    /* initialize hca wait object for uAT event */\r
+    dapl_os_wait_object_init(&p_hca->ib_trans.wait_object);\r
+\r
+#if SOCK_CM\r
+    {\r
+       DAT_RETURN    dat_status;\r
+\r
+       dat_status = dapli_init_sock_cm(p_hca);\r
+       if ( dat_status != DAT_SUCCESS )\r
+       {\r
+               dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
+                               " %s() failed to init sock_CM\n", __FUNCTION__);\r
+               return DAT_INTERNAL_ERROR;\r
+       }\r
+\r
+       /* initialize cr_list lock */\r
+       dat_status = dapl_os_lock_init(&p_hca->ib_trans.lock);\r
+       if (dat_status != DAT_SUCCESS)\r
+       {\r
+               dapl_dbg_log (DAPL_DBG_TYPE_ERR, " %s() failed to init lock\n",\r
+                               __FUNCTION__);\r
+               return DAT_INTERNAL_ERROR;\r
+       }\r
+\r
+       /* initialize CM list for listens on this HCA */\r
+       dapl_llist_init_head((DAPL_LLIST_HEAD*)&p_hca->ib_trans.list);\r
+    }\r
+#endif\r
+\r
+    return (DAT_SUCCESS);\r
+}\r
+\r
+\r
+/*\r
+ * dapls_ib_close_hca\r
+ *\r
+ * Open HCA\r
+ *\r
+ * Input:\r
+ *      ib_hca_handle   provide HCA handle\r
+ *\r
+ * Output:\r
+ *      none\r
+ *\r
+ * Return:\r
+ *      DAT_SUCCESS\r
+ *      DAT_INSUFFICIENT_RESOURCES\r
+ *\r
+ */\r
+DAT_RETURN dapls_ib_close_hca ( IN  DAPL_HCA  *p_hca )\r
+{\r
+    dapl_ibal_ca_t     *p_ca;\r
+   \r
+    p_ca =  (dapl_ibal_ca_t *) p_hca->ib_hca_handle;\r
+   \r
+#if SOCK_CM\r
+#endif\r
+    /*\r
+     * Remove it from the list\r
+     */\r
+    TAKE_LOCK (dapl_ibal_root.ca_lock);\r
+    {\r
+        cl_qlist_remove_item (&dapl_ibal_root.ca_head, &p_ca->next);\r
+    }\r
+    RELEASE_LOCK (dapl_ibal_root.ca_lock);\r
+\r
+    dapli_shutdown_port_access (p_ca);\r
\r
+    /*\r
+     * Remove the constructor reference\r
+     */\r
+    REMOVE_REFERENCE (&p_ca->refs);\r
+\r
+    cl_spinlock_destroy (&p_ca->port_lock);\r
+    cl_spinlock_destroy (&p_ca->evd_cb_lock);\r
+\r
+    if (p_ca->p_ca_attr)\r
+        dapl_os_free (p_ca->p_ca_attr, sizeof (ib_ca_attr_t));\r
+\r
+    (void) ib_close_ca (p_ca->h_ca, NULL /* close_callback */);\r
+\r
+    p_hca->ib_hca_handle = IB_INVALID_HANDLE;\r
+    dapl_os_free (p_ca, sizeof (dapl_ibal_ca_t));\r
+\r
+    return (DAT_SUCCESS);\r
+}\r
+\r
+\r
+\r
+/*\r
+ * dapl_ib_pd_alloc\r
+ *\r
+ * Alloc a PD\r
+ *\r
+ * Input:\r
+ *     ia_handle               IA handle\r
+ *     PZ_ptr                  pointer to PZEVD struct\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_pd_alloc (\r
+        IN  DAPL_IA                 *ia,\r
+        IN  DAPL_PZ                 *pz)\r
+{\r
+    ib_api_status_t         ib_status;\r
+    dapl_ibal_ca_t          *p_ca;\r
+\r
+    p_ca = (dapl_ibal_ca_t *) ia->hca_ptr->ib_hca_handle;\r
+\r
+    ib_status = ib_alloc_pd (\r
+                              p_ca->h_ca,\r
+                              IB_PDT_NORMAL,\r
+                              ia,\r
+                              &pz->pd_handle );\r
+\r
+    return dapl_ib_status_convert (ib_status);\r
+}\r
+\r
+\r
+/*\r
+ * dapl_ib_pd_free\r
+ *\r
+ * Free a PD\r
+ *\r
+ * Input:\r
+ *     PZ_ptr                  pointer to PZ struct\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_pd_free (\r
+        IN  DAPL_PZ                 *pz)\r
+{\r
+    ib_api_status_t                 ib_status;\r
+\r
+    ib_status = ib_dealloc_pd (pz->pd_handle, /* destroy_callback */ NULL);\r
+\r
+    pz->pd_handle = IB_INVALID_HANDLE;\r
+\r
+    return dapl_ib_status_convert (ib_status);\r
+}\r
+\r
+\r
+/*\r
+ * dapl_ib_mr_register\r
+ *\r
+ * Register a virtual memory region\r
+ *\r
+ * Input:\r
+ *     ia_handle               IA handle\r
+ *     lmr                     pointer to dapl_lmr struct\r
+ *     virt_addr               virtual address of beginning of mem region\r
+ *     length                  length of memory region\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_mr_register (\r
+        IN  DAPL_IA                 *ia,\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
+    ib_api_status_t     ib_status;\r
+    ib_mr_handle_t      mr_handle;\r
+    ib_mr_create_t      mr_create;\r
+    uint32_t            l_key, r_key; \r
+\r
+    if ( ia == NULL || ia->header.magic != DAPL_MAGIC_IA )\r
+    {\r
+        return DAT_INVALID_HANDLE;\r
+    }\r
+\r
+    /* IBAL does not support */\r
+    if (va_type == DAT_VA_TYPE_ZB) {\r
+        dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+                    "--> va_type == DAT_VA_TYPE_ZB: NOT SUPPORTED\n");    \r
+        return DAT_ERROR (DAT_NOT_IMPLEMENTED, DAT_NO_SUBTYPE);  \r
+    }\r
+\r
+    mr_create.vaddr         = (void *) virt_addr;\r
+    mr_create.length        = (size_t)length;\r
+    mr_create.access_ctrl   = dapl_lmr_convert_privileges (privileges);\r
+    mr_create.access_ctrl   |= IB_AC_MW_BIND;\r
+   \r
+    if (lmr->param.mem_type == DAT_MEM_TYPE_SHARED_VIRTUAL)\r
+    {\r
+        ib_status = ib_reg_shmid (\r
+                          ((DAPL_PZ *)lmr->param.pz_handle)->pd_handle,\r
+                          (const uint8_t*)lmr->shmid,\r
+                          &mr_create,\r
+                          (uint64_t *)&virt_addr,\r
+                          &l_key,\r
+                          &r_key,\r
+                          &mr_handle);\r
+    }\r
+    else \r
+    {\r
+        ib_status = ib_reg_mem ( ((DAPL_PZ *)lmr->param.pz_handle)->pd_handle,\r
+                                 &mr_create,\r
+                                 &l_key,\r
+                                 &r_key,\r
+                                 &mr_handle );\r
+    }\r
+    \r
+    if (ib_status != IB_SUCCESS)\r
+    {\r
+        return (dapl_ib_status_convert (ib_status));\r
+    }\r
+    \r
+    /* DAT/DAPL expects context in host order */\r
+    l_key = cl_ntoh32(l_key);\r
+    r_key = cl_ntoh32(r_key);\r
+\r
+    dapl_dbg_log (DAPL_DBG_TYPE_UTIL, "--> DsIMR: lmr (%p) lkey = 0x%x "\r
+                  "r_key= %#x mr_handle %p vaddr 0x%LX len 0x%LX\n", \r
+                  lmr, l_key, r_key, mr_handle, virt_addr, length);\r
+\r
+    lmr->param.lmr_context = l_key;\r
+    lmr->param.rmr_context = r_key;\r
+    lmr->param.registered_size = length;\r
+    lmr->param.registered_address = (DAT_VADDR)virt_addr;\r
+    lmr->mr_handle         = mr_handle;\r
+\r
+    return (DAT_SUCCESS);\r
+}\r
+\r
+\r
+/*\r
+ * dapl_ib_mr_deregister\r
+ *\r
+ * Free a memory region\r
+ *\r
+ * Input:\r
+ *     lmr                     pointer to dapl_lmr struct\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_mr_deregister (\r
+        IN  DAPL_LMR                *lmr)\r
+{\r
+    ib_api_status_t                ib_status;\r
+\r
+    ib_status = ib_dereg_mr (lmr->mr_handle);\r
+\r
+    if (ib_status != IB_SUCCESS)\r
+    {\r
+        return dapl_ib_status_convert (ib_status);\r
+    }\r
+\r
+    lmr->param.lmr_context = 0;\r
+    lmr->mr_handle         = IB_INVALID_HANDLE;\r
+\r
+    return (DAT_SUCCESS);\r
+}\r
+\r
+\r
+/*\r
+ * dapl_ib_mr_register_shared\r
+ *\r
+ * Register a virtual memory region\r
+ *\r
+ * Input:\r
+ *     ia_handle               IA handle\r
+ *     lmr                     pointer to dapl_lmr struct\r
+ *     virt_addr               virtual address of beginning of mem region\r
+ *     length                  length of memory region\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_mr_register_shared (\r
+        IN  DAPL_IA                  *ia,\r
+        IN  DAPL_LMR                 *lmr,\r
+        IN  DAT_MEM_PRIV_FLAGS       privileges,\r
+        IN  DAT_VA_TYPE              va_type )\r
+{\r
+    DAT_VADDR                   virt_addr;\r
+    ib_mr_handle_t              mr_handle;\r
+    ib_api_status_t             ib_status;\r
+    ib_mr_handle_t              new_mr_handle;\r
+    ib_access_t                 access_ctrl;\r
+    uint32_t                    l_key, r_key; \r
+    ib_mr_create_t      mr_create;\r
+    if ( ia == NULL || ia->header.magic != DAPL_MAGIC_IA )\r
+    {\r
+        return DAT_INVALID_HANDLE;\r
+    }\r
+\r
+    /* IBAL does not support?? */\r
+    if (va_type == DAT_VA_TYPE_ZB) {\r
+        dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+           " va_type == DAT_VA_TYPE_ZB: NOT SUPPORTED\n");    \r
+        return DAT_ERROR (DAT_NOT_IMPLEMENTED, DAT_NO_SUBTYPE);  \r
+    }\r
+\r
+    virt_addr = dapl_mr_get_address (lmr->param.region_desc,\r
+                                     lmr->param.mem_type);\r
+\r
+    access_ctrl   = dapl_lmr_convert_privileges (privileges);\r
+    access_ctrl  |= IB_AC_MW_BIND;\r
+\r
+    mr_create.vaddr         = (void *) virt_addr;\r
+    mr_create.access_ctrl   = access_ctrl;\r
+    mr_handle = (ib_mr_handle_t) lmr->mr_handle;\r
+\r
+    dapl_dbg_log (DAPL_DBG_TYPE_UTIL, \r
+                       "--> DsIMRS: orig mr_handle %p vaddr %p\n", \r
+                       mr_handle, virt_addr);\r
+\r
+    if (lmr->param.mem_type == DAT_MEM_TYPE_SHARED_VIRTUAL)\r
+    {\r
+        ib_status = ib_reg_shmid ( ((DAPL_PZ *)lmr->param.pz_handle)->pd_handle,\r
+                                   (const uint8_t*)lmr->shmid,\r
+                                   &mr_create,\r
+                                   &virt_addr,\r
+                                   &l_key,\r
+                                   &r_key,\r
+                                   &new_mr_handle );\r
+    }\r
+    else\r
+    { \r
+\r
+        ib_status = ib_reg_shared ( mr_handle,\r
+                                   ((DAPL_PZ *)lmr->param.pz_handle)->pd_handle,\r
+                                   access_ctrl,\r
+                                   /* in/out */(DAT_UINT64 *)&virt_addr,\r
+                                   &l_key,\r
+                                   &r_key,\r
+                                   &new_mr_handle );\r
+    }\r
+\r
+    if (ib_status != IB_SUCCESS)\r
+    {\r
+        return dapl_ib_status_convert (ib_status);\r
+    }\r
+    /*\r
+     * FIXME - Vu\r
+     *    What if virt_addr as an OUTPUT having the actual virtual address\r
+     *    assigned to the register region\r
+     */\r
+\r
+    /* DAT/DAPL expects context to be in host order */\r
+    l_key = cl_ntoh32(l_key);\r
+    r_key = cl_ntoh32(r_key);\r
+\r
+    dapl_dbg_log (DAPL_DBG_TYPE_UTIL, "--> DsIMRS: lmr (%p) lkey = 0x%x "\r
+                  "new mr_handle %p vaddr %p\n",\r
+                  lmr, l_key, new_mr_handle, virt_addr);\r
+\r
+    lmr->param.lmr_context = l_key;\r
+    lmr->param.rmr_context = r_key;\r
+    lmr->param.registered_address = (DAT_VADDR) (uintptr_t) virt_addr;\r
+    lmr->mr_handle         = new_mr_handle;\r
+\r
+    return (DAT_SUCCESS);\r
+}\r
+\r
+\r
+/*\r
+ * dapls_ib_mw_alloc\r
+ *\r
+ * Bind a protection domain to a memory window\r
+ *\r
+ * Input:\r
+ *     rmr                     Initialized rmr to hold binding handles\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_mw_alloc ( IN  DAPL_RMR    *rmr )\r
+{\r
+    ib_api_status_t     ib_status;\r
+    uint32_t            r_key;\r
+    ib_mw_handle_t      mw_handle;\r
+\r
+    ib_status = ib_create_mw (\r
+                  ((DAPL_PZ *)rmr->param.pz_handle)->pd_handle,\r
+                  &r_key,\r
+                  &mw_handle);\r
+\r
+    if (ib_status != IB_SUCCESS)\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                       "--> DsIMA: create MW failed = %s\n",\r
+                       ib_get_err_str(ib_status) );\r
+        return dapl_ib_status_convert (ib_status);\r
+    }\r
+\r
+    rmr->mw_handle         = mw_handle;\r
+    rmr->param.rmr_context = (DAT_RMR_CONTEXT) cl_ntoh32(r_key);\r
+\r
+    dapl_dbg_log (DAPL_DBG_TYPE_UTIL, \r
+                       "--> DsIMA: mw_handle %p r_key = 0x%x\n", \r
+                        mw_handle, rmr->param.rmr_context);\r
+\r
+    return (DAT_SUCCESS);\r
+}\r
+\r
+\r
+/*\r
+ * dapls_ib_mw_free\r
+ *\r
+ * Release bindings of a protection domain to a memory window\r
+ *\r
+ * Input:\r
+ *     rmr                     Initialized rmr to hold binding handles\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_mw_free (\r
+        IN  DAPL_RMR                         *rmr)\r
+{\r
+    ib_api_status_t         ib_status;\r
+\r
+    dapl_dbg_log (DAPL_DBG_TYPE_UTIL, \r
+                       "--> DsIMF: mw_handle %p\n", rmr->mw_handle);\r
+\r
+    ib_status = ib_destroy_mw (rmr->mw_handle);\r
+\r
+    if (ib_status != IB_SUCCESS)\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR, "--> DsIMF: Free MW failed = %s\n",\r
+                       ib_get_err_str(ib_status));\r
+        return dapl_ib_status_convert (ib_status);\r
+    }\r
+\r
+    rmr->param.rmr_context = 0;\r
+    rmr->mw_handle         = IB_INVALID_HANDLE;\r
+\r
+    return (DAT_SUCCESS);\r
+}\r
+\r
+/*\r
+ * dapls_ib_mw_bind\r
+ *\r
+ * Bind a protection domain to a memory window\r
+ *\r
+ * Input:\r
+ *     rmr                     Initialized rmr to hold binding handles\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *\r
+ */\r
+DAT_RETURN\r
+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  ib_bool_t               is_signaled)\r
+{\r
+    ib_api_status_t       ib_status;\r
+    ib_bind_wr_t          bind_wr_prop;\r
+    uint32_t              new_rkey;\r
+    \r
+    bind_wr_prop.local_ds.vaddr   = virtual_address;\r
+    bind_wr_prop.local_ds.length  = (uint32_t)length;\r
+    bind_wr_prop.local_ds.lkey    = cl_hton32(lmr->param.lmr_context);\r
+    bind_wr_prop.current_rkey     = cl_hton32(rmr->param.rmr_context);\r
+    bind_wr_prop.access_ctrl      = dapl_rmr_convert_privileges (mem_priv);\r
+    bind_wr_prop.send_opt         = (is_signaled == TRUE) ? \r
+                                    IB_SEND_OPT_SIGNALED : 0;\r
+    bind_wr_prop.wr_id            = (uint64_t) ((uintptr_t) cookie);\r
+    bind_wr_prop.h_mr             = lmr->mr_handle;\r
+\r
+    dapl_dbg_log (DAPL_DBG_TYPE_UTIL, "--> DsIMB: mr_handle %p, mw_handle %p "\r
+                  "vaddr %#I64x length %#I64x\n", \r
+                  lmr->mr_handle, rmr->mw_handle, virtual_address, length);\r
+\r
+    ib_status = ib_bind_mw (\r
+                    rmr->mw_handle,\r
+                    ep->qp_handle,\r
+                    &bind_wr_prop,\r
+                    &new_rkey);\r
+\r
+    if (ib_status != IB_SUCCESS)\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR, "--> DsIMB: Bind MW failed = %s\n", \r
+                       ib_get_err_str(ib_status));\r
+        return (dapl_ib_status_convert (ib_status));\r
+    }\r
+\r
+    rmr->param.rmr_context      = (DAT_RMR_CONTEXT) cl_ntoh32(new_rkey);\r
+\r
+    dapl_dbg_log (DAPL_DBG_TYPE_UTIL,\r
+                       "--> DsIMB: new_rkey = 0x%x\n", rmr->param.rmr_context);\r
+\r
+    return (DAT_SUCCESS);\r
+}\r
+\r
+/*\r
+ * dapls_ib_mw_unbind\r
+ *\r
+ * Unbind a memory window\r
+ *\r
+ * Input:\r
+ *     rmr                     Initialized rmr to hold binding handles\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_mw_unbind (\r
+       IN  DAPL_RMR            *rmr,\r
+       IN  DAPL_EP             *ep,\r
+       IN  DAPL_COOKIE         *cookie,\r
+       IN  ib_bool_t           is_signaled)\r
+{\r
+    ib_api_status_t       ib_status;\r
+    ib_bind_wr_t          bind_wr_prop;\r
+    uint32_t              new_rkey;\r
+    \r
+    bind_wr_prop.local_ds.vaddr   = 0;\r
+    bind_wr_prop.local_ds.length  = 0;\r
+    bind_wr_prop.local_ds.lkey    = 0;\r
+    bind_wr_prop.access_ctrl      = 0;\r
+    bind_wr_prop.send_opt         = (is_signaled == TRUE) ? \r
+                                    IB_SEND_OPT_SIGNALED : 0;\r
+    bind_wr_prop.wr_id            = (uint64_t) ((uintptr_t) cookie);\r
+\r
+    dapl_dbg_log (DAPL_DBG_TYPE_UTIL, \r
+                       "--> DsIMU: mw_handle = %p\n", rmr->mw_handle);\r
+\r
+    ib_status = ib_bind_mw (\r
+                    rmr->mw_handle,\r
+                    ep->qp_handle,\r
+                    &bind_wr_prop,\r
+                    &new_rkey);\r
+\r
+    if (ib_status != IB_SUCCESS)\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR, "--> DsIMU: Unbind MW failed = %s\n", \r
+                ib_get_err_str(ib_status));\r
+        return (dapl_ib_status_convert (ib_status));\r
+    }\r
+\r
+    rmr->param.rmr_context      = (DAT_RMR_CONTEXT) cl_ntoh32(new_rkey);\r
+\r
+    dapl_dbg_log (DAPL_DBG_TYPE_UTIL, \r
+                  "--> DsIMU: unbind new_rkey 0x%x\n", rmr->param.rmr_context);\r
+\r
+    return (DAT_SUCCESS);\r
+}\r
+\r
+\r
+/*\r
+ * dapls_ib_setup_async_callback\r
+ *\r
+ * Set up an asynchronous callbacks of various kinds\r
+ *\r
+ * Input:\r
+ *     ia_handle               IA handle\r
+ *     handler_type            type of handler to set up\r
+ *     callback_handle         handle param for completion callbacks\r
+ *     callback                callback routine pointer\r
+ *     context                 argument for callback routine\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *     DAT_INVALID_PARAMETER\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_setup_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
+    dapl_ibal_ca_t     *p_ca;\r
+    dapl_ibal_evd_cb_t *evd_cb;\r
+\r
+    dapl_dbg_log (DAPL_DBG_TYPE_UTIL,\r
+                  " setup_async_cb: ia %p type %d hdl %p cb %p ctx %p\n",\r
+                  ia_ptr, handler_type, evd_ptr, callback, context);\r
+\r
+    p_ca = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;\r
+\r
+    if (p_ca == NULL)\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR, "--> DsISAC: can't find %s HCA\n", \r
+                       (ia_ptr->header.provider)->device_name);\r
+        return (DAT_INVALID_HANDLE);\r
+    }\r
+   \r
+    if (handler_type != DAPL_ASYNC_CQ_COMPLETION)\r
+    {\r
+        evd_cb = dapli_find_evd_cb_by_context (context, p_ca);\r
+           \r
+        if (evd_cb == NULL)\r
+        {\r
+            /* \r
+             * No record for this evd. We allocate one\r
+             */\r
+            evd_cb = dapl_os_alloc (sizeof (dapl_ibal_evd_cb_t));\r
+            dapl_os_memzero (evd_cb, sizeof(dapl_ibal_evd_cb_t));\r
+\r
+            if (evd_cb == NULL)\r
+            {\r
+                dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                               "--> %s: can't alloc res\n","DsISAC"); \r
+                return (DAT_INSUFFICIENT_RESOURCES);\r
+            }\r
+        \r
+            evd_cb->context          = context;\r
+        \r
+            /*\r
+             *  Add the new EVD CB to the list\r
+             */\r
+            LOCK_INSERT_TAIL( p_ca->evd_cb_lock, \r
+                              p_ca->evd_cb_head,\r
+                              evd_cb->next );\r
+        }\r
+\r
+        switch (handler_type)\r
+        {\r
+            case DAPL_ASYNC_UNAFILIATED:\r
+                evd_cb->pfn_async_err_cb = callback;\r
+                break;\r
+            case DAPL_ASYNC_CQ_ERROR:\r
+                evd_cb->pfn_async_cq_err_cb = callback;\r
+                break;\r
+            case DAPL_ASYNC_QP_ERROR:\r
+                evd_cb->pfn_async_qp_err_cb = callback;\r
+                break;\r
+            default:\r
+                break;\r
+        }\r
+\r
+    }\r
+\r
+    return DAT_SUCCESS;\r
+}\r
+\r
+\r
+/*\r
+ * dapls_ib_query_gid\r
+ *\r
+ * Query the hca for the gid of the 1st active port.\r
+ *\r
+ * Input:\r
+ *     hca_handl               hca handle      \r
+ *     ep_attr                 attribute of the ep\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INVALID_HANDLE\r
+ *     DAT_INVALID_PARAMETER\r
+ */\r
+\r
+DAT_RETURN\r
+dapls_ib_query_gid( IN  DAPL_HCA       *hca_ptr,\r
+                   IN  GID             *gid )\r
+{\r
+    dapl_ibal_ca_t    *p_ca;\r
+    ib_ca_attr_t      *p_hca_attr;\r
+    ib_api_status_t   ib_status;\r
+    ib_hca_port_t     port_num;\r
+\r
+    p_ca = (dapl_ibal_ca_t *) hca_ptr->ib_hca_handle;\r
+\r
+    if (p_ca == NULL)\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                       "%s() invalid hca_ptr %p", __FUNCTION__, hca_ptr);\r
+        return DAT_INVALID_HANDLE;\r
+    }\r
+\r
+    ib_status = ib_query_ca (\r
+                          p_ca->h_ca,\r
+                          p_ca->p_ca_attr,\r
+                          &p_ca->ca_attr_size);\r
+    if (ib_status != IB_SUCCESS)\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                       "%s() ib_query_ca returned failed status = %s\n", \r
+                       ib_get_err_str(ib_status));\r
+        return dapl_ib_status_convert (ib_status);\r
+    }\r
+\r
+    p_hca_attr = p_ca->p_ca_attr;\r
+    port_num = hca_ptr->port_num - 1;\r
+\r
+    gid->gid_prefix = p_hca_attr->p_port_attr[port_num].p_gid_table->unicast.prefix;\r
+    gid->guid = p_hca_attr->p_port_attr[port_num].p_gid_table->unicast.interface_id;\r
+    return DAT_SUCCESS;\r
+}\r
+\r
+\r
+/*\r
+ * dapls_ib_query_hca\r
+ *\r
+ * Query the hca attribute\r
+ *\r
+ * Input:\r
+ *     hca_handl               hca handle      \r
+ *     ep_attr                 attribute of the ep\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INVALID_PARAMETER\r
+ */\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
+    ib_ca_attr_t      *p_hca_attr;\r
+    dapl_ibal_ca_t    *p_ca;\r
+    ib_api_status_t   ib_status;\r
+    ib_hca_port_t     port_num;\r
+    GID gid;\r
+    DAT_SOCK_ADDR6      *p_sock_addr;\r
+    DAT_RETURN dat_status = DAT_SUCCESS;\r
+    port_num = hca_ptr->port_num;\r
+\r
+    p_ca = (dapl_ibal_ca_t *) hca_ptr->ib_hca_handle;\r
+\r
+    if (p_ca == NULL)\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,  "--> %s: invalid handle %p",\r
+                       "DsIQH", hca_ptr);\r
+        return (DAT_INVALID_HANDLE);\r
+    }\r
+\r
+    ib_status = ib_query_ca (\r
+                          p_ca->h_ca,\r
+                          p_ca->p_ca_attr,\r
+                          &p_ca->ca_attr_size);\r
+    if (ib_status != IB_SUCCESS)\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                       "--> DsIQH: ib_query_ca returned failed status = %s\n", \r
+                       ib_get_err_str(ib_status));\r
+        return (dapl_ib_status_convert (ib_status));\r
+    }\r
+\r
+    p_hca_attr = p_ca->p_ca_attr;\r
+\r
+    if (ip_addr != NULL)\r
+    {\r
+       p_sock_addr = dapl_os_alloc(sizeof(DAT_SOCK_ADDR6));\r
+       if ( !p_sock_addr )\r
+       {\r
+               dat_status = DAT_INSUFFICIENT_RESOURCES;\r
+               dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                                       " Query Hca alloc Err: status %d\n",\r
+                                       dat_status);\r
+               return dat_status;\r
+       }\r
+       dapl_os_memzero(p_sock_addr, sizeof(DAT_SOCK_ADDR6));\r
+\r
+       gid.gid_prefix = p_hca_attr->p_port_attr[port_num-1].p_gid_table->unicast.prefix;\r
+       gid.guid = p_hca_attr->p_port_attr[port_num-1].p_gid_table->unicast.interface_id;\r
+       \r
+       dat_status = dapls_ns_map_ipaddr( hca_ptr,\r
+                                          gid,\r
+                                          (DAT_IA_ADDRESS_PTR)p_sock_addr);\r
+       \r
+       if ( dat_status != DAT_SUCCESS )\r
+       {\r
+            dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
+                          " SA Query for local IP failed= %d\n", dat_status );\r
+                       /* what to do next ? */\r
+       }\r
+       else\r
+       {\r
+           dapl_dbg_log (DAPL_DBG_TYPE_CM, "SA query GID for IP: ");\r
+            dapl_dbg_log ( DAPL_DBG_TYPE_CM, "%0d:%d:%d:%d\n", \r
+               (uint8_t)((DAT_IA_ADDRESS_PTR )p_sock_addr)->sa_data[2]&0xff,\r
+               (uint8_t)((DAT_IA_ADDRESS_PTR )p_sock_addr)->sa_data[3]&0xff,\r
+               (uint8_t)((DAT_IA_ADDRESS_PTR )p_sock_addr)->sa_data[4]&0xff,\r
+               (uint8_t)((DAT_IA_ADDRESS_PTR )p_sock_addr)->sa_data[5]&0xff);\r
+        }\r
+\r
+        hca_ptr->hca_address = *p_sock_addr;\r
+\r
+        /* if structure address not from our hca_ptr */\r
+        if ( ip_addr  != &hca_ptr->hca_address )\r
+        {\r
+            *ip_addr = *p_sock_addr;\r
+        }\r
+\r
+       dapl_os_free (p_sock_addr, sizeof(DAT_SOCK_ADDR6));\r
+\r
+    } /* ip_addr != NULL */\r
+\r
+    if ( ia_attr != NULL )\r
+    {\r
+        dapl_os_memzero( ia_attr->adapter_name,\r
+                         (int)sizeof(ia_attr->adapter_name ));\r
+        dapl_os_memcpy(ia_attr->adapter_name,\r
+                        DAT_ADAPTER_NAME, \r
+                        min ( (int)dapl_os_strlen(DAT_ADAPTER_NAME),\r
+                              (int)(DAT_NAME_MAX_LENGTH)-1 ) );\r
+\r
+        dapl_os_memzero ( ia_attr->vendor_name,\r
+                          (int)sizeof(ia_attr->vendor_name) );\r
+        dapl_os_memcpy ( ia_attr->vendor_name, \r
+                         DAT_VENDOR_NAME,\r
+                        min ( (int)dapl_os_strlen(DAT_VENDOR_NAME),\r
+                              (int)(DAT_NAME_MAX_LENGTH)-1 ) );\r
+        \r
+        /* FIXME : Vu\r
+         *         this value should be revisited\r
+         *         It can be set by DAT consumers\r
+         */\r
+        ia_attr->ia_address_ptr           = (DAT_PVOID)&hca_ptr->hca_address;\r
+        ia_attr->hardware_version_major   = p_hca_attr->dev_id;\r
+        ia_attr->hardware_version_minor   = p_hca_attr->revision;\r
+        ia_attr->max_eps                  = p_hca_attr->max_qps;\r
+        ia_attr->max_dto_per_ep           = p_hca_attr->max_wrs;\r
+        ia_attr->max_rdma_read_per_ep     = p_hca_attr->max_qp_resp_res;\r
+        ia_attr->max_evds                 = p_hca_attr->max_cqs;\r
+        ia_attr->max_evd_qlen             = p_hca_attr->max_cqes;\r
+        ia_attr->max_iov_segments_per_dto = p_hca_attr->max_sges;\r
+        ia_attr->max_lmrs                 = p_hca_attr->init_regions;\r
+        ia_attr->max_lmr_block_size       = p_hca_attr->init_region_size;\r
+        ia_attr->max_rmrs                 = p_hca_attr->init_windows;\r
+        ia_attr->max_lmr_virtual_address  = p_hca_attr->max_addr_handles;\r
+        ia_attr->max_rmr_target_address   = p_hca_attr->max_addr_handles;\r
+        ia_attr->max_pzs                  = p_hca_attr->max_pds;\r
+        /*\r
+         * DAT spec does not tie max_mtu_size with IB MTU\r
+         *\r
+        ia_attr->max_mtu_size             = \r
+                        dapl_ibal_mtu_table[p_hca_attr->p_port_attr->mtu];\r
+        */\r
+        ia_attr->max_mtu_size             = \r
+                        p_hca_attr->p_port_attr->max_msg_size;\r
+        ia_attr->max_rdma_size            = \r
+                        p_hca_attr->p_port_attr->max_msg_size;\r
+        ia_attr->num_transport_attr       = 0;\r
+        ia_attr->transport_attr           = NULL;\r
+        ia_attr->num_vendor_attr          = 0;\r
+        ia_attr->vendor_attr              = NULL;\r
+        ia_attr->max_iov_segments_per_rdma_read = p_hca_attr->max_sges;\r
+\r
+#ifdef DAT_EXTENSIONS\r
+        ia_attr->extension_supported = DAT_EXTENSION_IB;\r
+        ia_attr->extension_version = DAT_IB_EXTENSION_VERSION;\r
+#endif\r
+       \r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, \r
+               " --> DsIMU_qHCA: (ver=%x) ep %d ep_q %d evd %d evd_q %d\n", \r
+                       ia_attr->hardware_version_major,\r
+                       ia_attr->max_eps, ia_attr->max_dto_per_ep,\r
+                       ia_attr->max_evds, ia_attr->max_evd_qlen );\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, \r
+               " --> DsIMU_qHCA: mtu %llu rdma %llu iov %d lmr %d rmr %d"\r
+               " rdma_io %d\n", \r
+                       ia_attr->max_mtu_size, ia_attr->max_rdma_size,\r
+                       ia_attr->max_iov_segments_per_dto, ia_attr->max_lmrs, \r
+                       ia_attr->max_rmrs, ia_attr->max_rdma_read_per_ep );\r
+    }\r
+\r
+    if ( ep_attr != NULL )\r
+    {\r
+       (void) dapl_os_memzero(ep_attr, sizeof(*ep_attr)); \r
+        /*\r
+         * DAT spec does not tie max_mtu_size with IB MTU\r
+         *\r
+        ep_attr->max_mtu_size     = \r
+                        dapl_ibal_mtu_table[p_hca_attr->p_port_attr->mtu];\r
+         */\r
+        ep_attr->max_mtu_size     = p_hca_attr->p_port_attr->max_msg_size;\r
+        ep_attr->max_rdma_size    = p_hca_attr->p_port_attr->max_msg_size;\r
+        ep_attr->max_recv_dtos    = p_hca_attr->max_wrs;\r
+        ep_attr->max_request_dtos = p_hca_attr->max_wrs;\r
+        ep_attr->max_recv_iov     = p_hca_attr->max_sges;\r
+        ep_attr->max_request_iov  = p_hca_attr->max_sges;\r
+        ep_attr->max_rdma_read_in = p_hca_attr->max_qp_resp_res;\r
+        ep_attr->max_rdma_read_out= p_hca_attr->max_qp_resp_res;\r
+       \r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, \r
+               " --> DsIMU_qHCA: msg %llu dto %d iov %d rdma i%d,o%d\n", \r
+                       ep_attr->max_mtu_size,\r
+                       ep_attr->max_recv_dtos, ep_attr->max_recv_iov,\r
+                       ep_attr->max_rdma_read_in, ep_attr->max_rdma_read_out);\r
+    }\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+\r
+DAT_RETURN\r
+dapls_ib_completion_poll ( IN DAPL_HCA                *p_hca,\r
+                           IN DAPL_EVD                *p_evd,\r
+                           IN ib_work_completion_t   *cqe_ptr )\r
+{\r
+    ib_api_status_t        ib_status;\r
+    ib_work_completion_t   *cqe_filled;\r
+\r
+    /*\r
+     * FIXME - Vu\r
+     *     Now we only poll for one cqe. We can poll for more than\r
+     *     one completions later for better. However, this requires\r
+     *     to change the logic in dapl_evd_dto_callback function\r
+     *     to process more than one completion.\r
+     */\r
+    cqe_ptr->p_next = NULL;\r
+    cqe_filled      = NULL;\r
+\r
+    if  ( !p_hca->ib_hca_handle )\r
+    {\r
+        return DAT_INVALID_HANDLE;\r
+    }\r
+\r
+    ib_status = ib_poll_cq (p_evd->ib_cq_handle, &cqe_ptr, &cqe_filled);\r
+\r
+    if ( ib_status == IB_INVALID_CQ_HANDLE )\r
+    {\r
+        ib_status = IB_NOT_FOUND;\r
+    }\r
+\r
+    return dapl_ib_status_convert (ib_status);\r
+}\r
+\r
+\r
+DAT_RETURN\r
+dapls_ib_completion_notify ( IN ib_hca_handle_t         hca_handle,\r
+                             IN DAPL_EVD                *p_evd,\r
+                             IN ib_notification_type_t  type )\r
+{\r
+    ib_api_status_t        ib_status;\r
+    DAT_BOOLEAN            solic_notify;\r
+\r
+    if  ( !hca_handle )\r
+    {\r
+        return DAT_INVALID_HANDLE;\r
+    }\r
+    solic_notify = (type == IB_NOTIFY_ON_SOLIC_COMP) ? DAT_TRUE : DAT_FALSE; \r
+    ib_status = ib_rearm_cq ( p_evd->ib_cq_handle, solic_notify );\r
+\r
+    return dapl_ib_status_convert (ib_status);\r
+}\r
+\r
+DAT_RETURN\r
+dapls_evd_dto_wakeup (\r
+       IN DAPL_EVD                     *evd_ptr)\r
+{\r
+       return dapl_os_wait_object_wakeup(&evd_ptr->wait_object);\r
+}\r
+\r
+DAT_RETURN\r
+dapls_evd_dto_wait (\r
+       IN DAPL_EVD                     *evd_ptr,\r
+       IN uint32_t                     timeout)\r
+{\r
+       return dapl_os_wait_object_wait(&evd_ptr->wait_object, timeout);\r
+}\r
+\r
+/*\r
+ * dapls_ib_get_async_event\r
+ *\r
+ * Translate an asynchronous event type to the DAT event.\r
+ * Note that different providers have different sets of errors.\r
+ *\r
+ * Input:\r
+ *     cause_ptr               provider event cause\r
+ *\r
+ * Output:\r
+ *     async_event             DAT mapping of error\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_NOT_IMPLEMENTED     Caller is not interested this event\r
+ */\r
+\r
+DAT_RETURN dapls_ib_get_async_event(\r
+       IN  ib_async_event_rec_t        *cause_ptr,\r
+       OUT DAT_EVENT_NUMBER            *async_event)\r
+{\r
+    ib_async_event_t           event_id;\r
+    DAT_RETURN                 dat_status;\r
+\r
+    dat_status = DAT_SUCCESS;\r
+    event_id = cause_ptr->code;\r
+\r
+    dapl_dbg_log (DAPL_DBG_TYPE_WARN, "--> DsAE: event_id = %d%d\n", event_id);\r
+\r
+    switch (event_id )\r
+    {\r
+        case IB_AE_SQ_ERROR:\r
+        case IB_AE_SQ_DRAINED:\r
+        case IB_AE_RQ_ERROR:\r
+       {\r
+           *async_event = DAT_ASYNC_ERROR_EP_BROKEN;\r
+           break;\r
+       }\r
+\r
+       /* INTERNAL errors */\r
+        case IB_AE_QP_FATAL:\r
+       case IB_AE_CQ_ERROR:\r
+       case IB_AE_LOCAL_FATAL:\r
+       case IB_AE_WQ_REQ_ERROR:\r
+       case IB_AE_WQ_ACCESS_ERROR:\r
+       {\r
+           *async_event = DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR;\r
+           break;\r
+       }\r
+\r
+       /* CATASTROPHIC errors */\r
+       case IB_AE_FLOW_CTRL_ERROR:\r
+       case IB_AE_BUF_OVERRUN:\r
+       {\r
+           *async_event = DAT_ASYNC_ERROR_IA_CATASTROPHIC;\r
+           break;\r
+       }\r
+\r
+       default:\r
+       {\r
+           /*\r
+            * Errors we are not interested in reporting:\r
+            * IB_AE_QP_APM\r
+            * IB_AE_PKEY_TRAP\r
+            * IB_AE_QKEY_TRAP\r
+            * IB_AE_MKEY_TRAP\r
+            * IB_AE_PORT_TRAP\r
+            * IB_AE_QP_APM_ERROR\r
+            * IB_AE_PORT_ACTIVE\r
+            * ...\r
+            */\r
+           dat_status = DAT_NOT_IMPLEMENTED;\r
+       }\r
+\r
+    }\r
+  \r
+    return dat_status;\r
+}\r
+\r
+/*\r
+ * dapls_ib_get_dto_status\r
+ *\r
+ * Return the DAT status of a DTO operation\r
+ *\r
+ * Input:\r
+ *     cqe_ptr                 pointer to completion queue entry\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     Value from ib_status_map table above\r
+ */\r
+\r
+DAT_DTO_COMPLETION_STATUS\r
+dapls_ib_get_dto_status(\r
+       IN ib_work_completion_t         *cqe_ptr)\r
+{\r
+    ib_uint32_t    ib_status;\r
+\r
+    ib_status = DAPL_GET_CQE_STATUS (cqe_ptr);\r
+\r
+    switch (ib_status)\r
+    {\r
+    case IB_COMP_ST_SUCCESS :\r
+       return  DAT_DTO_SUCCESS;\r
+\r
+    case IB_COMP_ST_LOCAL_LEN_ERR:\r
+       return DAT_DTO_ERR_LOCAL_LENGTH;\r
+\r
+    case IB_COMP_ST_LOCAL_OP_ERR:\r
+       return DAT_DTO_ERR_LOCAL_EP;\r
+\r
+    case IB_COMP_ST_LOCAL_PROTECT_ERR:\r
+       return DAT_DTO_ERR_LOCAL_PROTECTION;\r
+\r
+    case IB_COMP_ST_WR_FLUSHED_ERR:    \r
+       return DAT_DTO_ERR_FLUSHED;\r
+\r
+    case IB_COMP_ST_MW_BIND_ERR:\r
+       return DAT_RMR_OPERATION_FAILED;\r
+\r
+    case IB_COMP_ST_REM_ACC_ERR:\r
+       return DAT_DTO_ERR_REMOTE_ACCESS;\r
+\r
+    case IB_COMP_ST_REM_OP_ERR:\r
+       return DAT_DTO_ERR_REMOTE_RESPONDER;\r
+\r
+    case IB_COMP_ST_RNR_COUNTER:\r
+       return DAT_DTO_ERR_RECEIVER_NOT_READY;\r
+\r
+    case IB_COMP_ST_TRANSP_COUNTER:\r
+       return DAT_DTO_ERR_TRANSPORT;\r
+\r
+    case IB_COMP_ST_REM_REQ_ERR:\r
+       return DAT_DTO_ERR_REMOTE_RESPONDER;\r
+\r
+    case IB_COMP_ST_BAD_RESPONSE_ERR:\r
+       return DAT_DTO_ERR_BAD_RESPONSE;\r
+\r
+    case IB_COMP_ST_EE_STATE_ERR:\r
+    case IB_COMP_ST_EE_CTX_NO_ERR:\r
+       return DAT_DTO_ERR_TRANSPORT;\r
+\r
+    default:\r
+#ifdef DAPL_DBG\r
+    dapl_dbg_log (DAPL_DBG_TYPE_ERR,"%s() unknown IB_COMP_ST %x(0x%x)\n",\r
+                  __FUNCTION__,ib_status,ib_status);\r
+#endif\r
+       return DAT_DTO_FAILURE;\r
+    }\r
+}\r
+\r
+\r
+/*\r
+ * Map all IBAPI DTO completion codes to the DAT equivelent.\r
+ *\r
+ * dapls_ib_get_dat_event\r
+ *\r
+ * Return a DAT connection event given a provider CM event.\r
+ *\r
+ * N.B.        Some architectures combine async and CM events into a\r
+ *     generic async event. In that case, dapls_ib_get_dat_event()\r
+ *     and dapls_ib_get_async_event() should be entry points that\r
+ *     call into a common routine.\r
+ *\r
+ * Input:\r
+ *     ib_cm_event     event provided to the dapl callback routine\r
+ *     active          switch indicating active or passive connection\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_EVENT_NUMBER of translated provider value\r
+ */\r
+\r
+DAT_EVENT_NUMBER\r
+dapls_ib_get_dat_event (\r
+       IN    const ib_cm_events_t      ib_cm_event,\r
+       IN    DAT_BOOLEAN               active)\r
+{\r
+    DAT_EVENT_NUMBER           dat_event_num = 0;\r
+    UNREFERENCED_PARAMETER (active);\r
+\r
+    switch ( ib_cm_event)\r
+    {\r
+      case IB_CME_CONNECTED:\r
+          dat_event_num = DAT_CONNECTION_EVENT_ESTABLISHED;\r
+          break;\r
+      case IB_CME_DISCONNECTED:\r
+           dat_event_num = DAT_CONNECTION_EVENT_DISCONNECTED;\r
+           break;\r
+      case IB_CME_DISCONNECTED_ON_LINK_DOWN:\r
+           dat_event_num = DAT_CONNECTION_EVENT_DISCONNECTED;\r
+           break;\r
+      case IB_CME_CONNECTION_REQUEST_PENDING:\r
+           dat_event_num = DAT_CONNECTION_REQUEST_EVENT;\r
+           break;\r
+      case IB_CME_CONNECTION_REQUEST_PENDING_PRIVATE_DATA:\r
+           dat_event_num = DAT_CONNECTION_REQUEST_EVENT;\r
+           break;\r
+      case IB_CME_DESTINATION_REJECT:\r
+           dat_event_num = DAT_CONNECTION_EVENT_NON_PEER_REJECTED;\r
+           break;\r
+      case IB_CME_DESTINATION_REJECT_PRIVATE_DATA:\r
+           dat_event_num = DAT_CONNECTION_EVENT_PEER_REJECTED;\r
+           break;\r
+      case IB_CME_DESTINATION_UNREACHABLE:\r
+           dat_event_num = DAT_CONNECTION_EVENT_UNREACHABLE;\r
+           break;\r
+      case IB_CME_TOO_MANY_CONNECTION_REQUESTS:\r
+           dat_event_num = DAT_CONNECTION_EVENT_NON_PEER_REJECTED;\r
+           break;\r
+      case IB_CME_LOCAL_FAILURE:\r
+          dat_event_num = DAT_CONNECTION_EVENT_BROKEN;\r
+           break;\r
+      case IB_CME_REPLY_RECEIVED:\r
+      case IB_CME_REPLY_RECEIVED_PRIVATE_DATA:\r
+      default:\r
+           break;\r
+    }\r
+#if 0\r
+    dapl_dbg_log (DAPL_DBG_TYPE_CM,\r
+                 " dapls_ib_get_dat_event: event translation: (%s) "\r
+                 "ib_event 0x%x dat_event 0x%x\n",\r
+                 active ? "active" : "passive",\r
+                 ib_cm_event,\r
+                 dat_event_num);\r
+#endif\r
+    return dat_event_num;\r
+}\r
+\r
+\r
+/*\r
+ * dapls_ib_get_dat_event\r
+ *\r
+ * Return a DAT connection event given a provider CM event.\r
+ *\r
+ * N.B.        Some architectures combine async and CM events into a\r
+ *     generic async event. In that case, dapls_ib_get_cm_event()\r
+ *     and dapls_ib_get_async_event() should be entry points that\r
+ *     call into a common routine.\r
+ *\r
+ *     WARNING: In this implementation, there are multiple CM\r
+ *     events that map to a single DAT event. Be very careful\r
+ *     with provider routines that depend on this reverse mapping,\r
+ *     they may have to accomodate more CM events than they\r
+ *     'naturally' would.\r
+ *\r
+ * Input:\r
+ *     dat_event_num   DAT event we need an equivelent CM event for\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     ib_cm_event of translated DAPL value\r
+ */\r
+ib_cm_events_t\r
+dapls_ib_get_cm_event (\r
+       IN    DAT_EVENT_NUMBER          dat_event_num)\r
+{\r
+    ib_cm_events_t     ib_cm_event = 0;\r
+\r
+    switch (dat_event_num)\r
+    {\r
+        case DAT_CONNECTION_EVENT_ESTABLISHED:\r
+             ib_cm_event = IB_CME_CONNECTED;\r
+             break;\r
+        case DAT_CONNECTION_EVENT_DISCONNECTED:\r
+             ib_cm_event = IB_CME_DISCONNECTED;\r
+             break;\r
+        case DAT_CONNECTION_REQUEST_EVENT:\r
+             ib_cm_event =  IB_CME_CONNECTION_REQUEST_PENDING;\r
+             break;\r
+        case DAT_CONNECTION_EVENT_NON_PEER_REJECTED:\r
+             ib_cm_event = IB_CME_DESTINATION_REJECT;\r
+             break;\r
+        case DAT_CONNECTION_EVENT_PEER_REJECTED:\r
+             ib_cm_event = IB_CME_DESTINATION_REJECT_PRIVATE_DATA;\r
+             break;\r
+        case DAT_CONNECTION_EVENT_UNREACHABLE:\r
+             ib_cm_event = IB_CME_DESTINATION_UNREACHABLE;\r
+             break;\r
+        case DAT_CONNECTION_EVENT_BROKEN:\r
+             ib_cm_event = IB_CME_LOCAL_FAILURE;\r
+             break;\r
+        default:\r
+             break;\r
+    }\r
+\r
+    return ib_cm_event;\r
+}\r
+\r
+\r
+\r
+/*\r
+ * dapls_set_provider_specific_attr\r
+ *\r
+ * Input:\r
+ *     attr_ptr        Pointer provider specific attributes\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     void\r
+ */\r
+\r
+#ifdef DAT_EXTENSIONS\r
+static DAT_NAMED_ATTR  ib_attrs[] = {\r
+    {\r
+       "DAT_EXTENSION_INTERFACE", "TRUE"\r
+    },\r
+    {\r
+       DAT_IB_ATTR_FETCH_AND_ADD, "TRUE"\r
+    },\r
+    {\r
+       DAT_IB_ATTR_CMP_AND_SWAP, "TRUE"\r
+    },\r
+    {\r
+       DAT_IB_ATTR_IMMED_DATA, "TRUE"\r
+    },\r
+};\r
+#define SPEC_ATTR_SIZE( x )    (sizeof( x ) / sizeof( DAT_NAMED_ATTR))\r
+#else\r
+static DAT_NAMED_ATTR  *ib_attrs = NULL;\r
+#define SPEC_ATTR_SIZE( x )    0\r
+#endif\r
+\r
+void dapls_query_provider_specific_attr(\r
+       IN      DAPL_IA                         *ia_ptr,\r
+       IN      DAT_PROVIDER_ATTR       *attr_ptr )\r
+{\r
+    attr_ptr->num_provider_specific_attr = SPEC_ATTR_SIZE(ib_attrs);\r
+    attr_ptr->provider_specific_attr     = ib_attrs;\r
+}\r
+\r
+\r
+DAT_RETURN dapls_ns_map_gid (\r
+       IN  DAPL_HCA            *hca_ptr,\r
+       IN  DAT_IA_ADDRESS_PTR  remote_ia_address,\r
+       OUT GID                 *gid)\r
+{\r
+    return (dapls_ib_ns_map_gid (hca_ptr, remote_ia_address, gid));\r
+}\r
+\r
+DAT_RETURN dapls_ns_map_ipaddr (\r
+       IN  DAPL_HCA            *hca_ptr,\r
+       IN  GID                 gid,\r
+       OUT DAT_IA_ADDRESS_PTR  remote_ia_address)\r
+{\r
+    return (dapls_ib_ns_map_ipaddr (hca_ptr, gid, remote_ia_address));\r
+}\r
+\r
+\r
+#ifdef NOT_USED\r
+/*\r
+ * dapls_ib_post_recv - defered.until QP ! in init state.\r
+ *\r
+ * Provider specific Post RECV function\r
+ */\r
+\r
+DAT_RETURN \r
+dapls_ib_post_recv_defered (\r
+       IN  DAPL_EP                     *ep_ptr,\r
+       IN  DAPL_COOKIE                 *cookie,\r
+       IN  DAT_COUNT                   num_segments,\r
+       IN  DAT_LMR_TRIPLET             *local_iov)\r
+{\r
+    ib_api_status_t     ib_status;\r
+    ib_recv_wr_t       *recv_wr, *rwr;\r
+    ib_local_ds_t       *ds_array_p;\r
+    DAT_COUNT           i, total_len;\r
+\r
+    if (ep_ptr->qp_state != IB_QPS_INIT)\r
+    {\r
+        dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsPR: BAD QP state(%s), not init? "\r
+                      "EP %p QP %p cookie %p, num_seg %d\n", \r
+                      ib_get_port_state_str(ep_ptr->qp_state), ep_ptr,\r
+                      ep_ptr->qp_handle, cookie, num_segments);\r
+       return (DAT_INSUFFICIENT_RESOURCES);\r
+    }\r
+\r
+    recv_wr = dapl_os_alloc (sizeof(ib_recv_wr_t)\r
+                             + (num_segments*sizeof(ib_local_ds_t)));\r
+    if (NULL == recv_wr)\r
+    {\r
+       return (DAT_INSUFFICIENT_RESOURCES);\r
+    }\r
+\r
+    dapl_os_memzero(recv_wr, sizeof(ib_recv_wr_t));\r
+    recv_wr->wr_id        = (DAT_UINT64) cookie;\r
+    recv_wr->num_ds       = num_segments;\r
+\r
+    ds_array_p = (ib_local_ds_t*)(recv_wr+1);\r
+\r
+    recv_wr->ds_array     = ds_array_p;\r
+\r
+    //total_len = 0;\r
+\r
+    for (total_len = i = 0; i < num_segments; i++, ds_array_p++)\r
+    {\r
+        ds_array_p->length = (uint32_t)local_iov[i].segment_length;\r
+        ds_array_p->lkey  = cl_hton32(local_iov[i].lmr_context);\r
+        ds_array_p->vaddr = local_iov[i].virtual_address;\r
+        total_len        += ds_array_p->length;\r
+    }\r
+\r
+    if (cookie != NULL)\r
+    {\r
+       cookie->val.dto.size = total_len;\r
+\r
+        dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
+                      "--> DsPR: EP = %p QP = %p cookie= %p, num_seg= %d\n", \r
+                      ep_ptr, ep_ptr->qp_handle, cookie, num_segments);\r
+    }\r
+\r
+    recv_wr->p_next = NULL;\r
+\r
+    /* find last defered recv work request, link new on the end */\r
+    rwr=ep_ptr->cm_post;\r
+    if (rwr == NULL)\r
+    {\r
+        ep_ptr->cm_post = (void*)recv_wr;\r
+        i = 1;\r
+    }\r
+    else\r
+    {\r
+        for(i=2; rwr->p_next; rwr=rwr->p_next) i++;\r
+        rwr->p_next = recv_wr;\r
+    }\r
+\r
+    dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsPR: %s() EP %p QP %p cookie %p "\r
+                  "num_seg %d Tdefered %d\n", \r
+                  __FUNCTION__, ep_ptr, ep_ptr->qp_handle, cookie, num_segments,\r
+                  i);\r
+\r
+    return DAT_SUCCESS;\r
+}\r
+#endif\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 52dd879c501060587b81323b2a97af22e225b4d4..2e34a6ca00ea915193bceb70f9e790cb26e4da06 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.h
- *
- * PURPOSE: Utility defs & routines for access to openib-windows IBAL APIs
- *
- * $Id: dapl_ibal_util.h 33 2005-07-11 19:51:17Z ftillier $
- *
- **********************************************************************/
-
-#ifndef _DAPL_IBAL_UTIL_H_
-#define _DAPL_IBAL_UTIL_H_
-
-#include <iba/ib_al.h>
-#include <complib/cl_spinlock.h>
-#include <complib/cl_qlist.h>
-#include <complib/cl_atomic.h>
-
-#ifdef DAT_EXTENSIONS
-#include <dat2\dat_ib_extensions.h>
-#endif
-
-/*
- * Typedefs to map IBAL types to more generic 'ib' types
- */
-#ifdef SOCK_CM
-typedef  struct ib_cm_handle           *dp_ib_cm_handle_t;
-typedef  struct ib_cm_handle           *ib_cm_srvc_handle_t;
-#else
-typedef  ib_cm_handle_t                *dp_ib_cm_handle_t;
-typedef  ib_listen_handle_t            ib_cm_srvc_handle_t;
-#endif
-
-typedef  ib_net64_t                    IB_HCA_NAME;
-typedef  ib_ca_handle_t                ib_hca_handle_t;
-typedef  DAT_PVOID                     ib_cqd_handle_t;
-typedef  ib_async_event_rec_t          ib_error_record_t;
-typedef  ib_wr_type_t                  ib_send_op_type_t;
-typedef  ib_wc_t                       ib_work_completion_t;
-typedef  uint32_t                      ib_hca_port_t;
-typedef  uint32_t                      ib_uint32_t;
-typedef  uint32_t                      ib_comp_handle_t;
-typedef  ib_local_ds_t                 ib_data_segment_t;
-
-typedef  unsigned __int3264            cl_dev_handle_t;
-
-
-typedef void (*ib_async_handler_t)(
-    IN    ib_hca_handle_t    ib_hca_handle,
-    IN    ib_error_record_t  *err_code,
-    IN    void               *context);
-
-typedef void (*ib_async_qp_handler_t)(
-    IN    ib_hca_handle_t    ib_hca_handle,
-    IN    ib_qp_handle_t     ib_qp_handle,
-    IN    ib_error_record_t  *err_code,
-    IN    void               *context);
-
-typedef void (*ib_async_cq_handler_t)(
-    IN    ib_hca_handle_t    ib_hca_handle,
-    IN    ib_cq_handle_t     ib_cq_handle,
-    IN    ib_error_record_t  *err_code,
-    IN    void               *context);
-
-typedef ib_net64_t   ib_guid_t;
-typedef ib_net16_t   ib_lid_t;
-typedef boolean_t    ib_bool_t;
-
-typedef struct _GID
-{
-    uint64_t gid_prefix;
-    uint64_t guid;
-} GID;
-
-typedef enum 
-{
-    IB_CME_CONNECTED,
-    IB_CME_DISCONNECTED,
-    IB_CME_DISCONNECTED_ON_LINK_DOWN,
-    IB_CME_CONNECTION_REQUEST_PENDING,
-    IB_CME_CONNECTION_REQUEST_PENDING_PRIVATE_DATA,
-    IB_CME_DESTINATION_REJECT,
-    IB_CME_DESTINATION_REJECT_PRIVATE_DATA,
-    IB_CME_DESTINATION_UNREACHABLE,
-    IB_CME_TOO_MANY_CONNECTION_REQUESTS,
-    IB_CME_LOCAL_FAILURE,
-    IB_CME_REPLY_RECEIVED,
-    IB_CME_REPLY_RECEIVED_PRIVATE_DATA,
-    IB_CM_LOCAL_FAILURE
-} ib_cm_events_t;
-
-
-typedef enum
-{
-    IB_NOTIFY_ON_NEXT_COMP,
-    IB_NOTIFY_ON_SOLIC_COMP
-} ib_notification_type_t;
-
-typedef struct _ib_hca_name
-{
-    DAT_NAME_PTR hca_name[DAT_NAME_MAX_LENGTH];
-} ib_hca_name_t;
-
-
-#define          IB_INVALID_HANDLE             NULL
-#define          true                          TRUE
-#define          false                         FALSE
-
-#define          IB_MAX_REQ_PDATA_SIZE      92
-#define          IB_MAX_REP_PDATA_SIZE      196
-#define          IB_MAX_REJ_PDATA_SIZE      148
-#define          IB_MAX_DREQ_PDATA_SIZE     220
-#define          IB_MAX_DREP_PDATA_SIZE     224
-
-
-/* Resource Not Ready
-       1-6 is an actual retry count which is decremented to zero before
-        an error condition is set.
-    7 is 'magic' in that it implies Infinite retry, just keeps trying.
-*/
-#define                IB_RNR_RETRY_CNT   7
-
-/*
-IB 1.2 spec, page 331, table 45, RNR NAK timeout encoding (5-bits)
-00000=655.36ms(milliseconds)
-00001=0.01ms
-00010=0.02ms
-00011=0.03ms
-00100=0.04ms
-00101=0.06ms
-00110=0.08ms
-00111=0.12ms
-
-11100=163.84ms 28d
-11101=245.76ms 29d
-11110=327.68ms 30d
-11111=491.52ms 31d
-*/
-#define                IB_RNR_NAK_TIMEOUT   0
-
-
-typedef void
-(*dapl_ibal_pfn_destructor_t)(
-    IN    void*    context );
-
-typedef struct _dapl_ibal_refs
-{
-    atomic32_t                      count;        // number of references
-    void*                         context;     // context for destructor
-    dapl_ibal_pfn_destructor_t    destructor;   // called when reference goes to zero
-
-} dapl_ibal_refs_t;
-
-
-typedef struct _dapl_ibal_root
-{
-    ib_al_handle_t        h_al;        // handle to Access Layer
-    cl_spinlock_t         ca_lock;     // CA list lock
-    cl_qlist_t            ca_head;     // list head of CAs
-    boolean_t             shutdown;    // when true, driver is shutting down
-    boolean_t             initialized;    // when true, lib is initialized 
-
-} dapl_ibal_root_t;
-
-
-typedef struct _dapl_ibal_ca
-{
-    cl_list_item_t    next;        // peer CA list
-    ib_ca_handle_t    h_ca;        // handle to open CA
-    ib_ca_attr_t      *p_ca_attr;  // CA attributes
-    uint32_t          ca_attr_size;// size of ca attribute
-    dapl_ibal_refs_t  refs;        // reference counting
-    cl_spinlock_t     port_lock;   // port list lock
-    cl_qlist_t        port_head;   // port list head for this CA
-    cl_spinlock_t     evd_cb_lock; // EVD async error cb list lock
-    cl_qlist_t        evd_cb_head; // EVD async error cb list head for this CA
-    cl_dev_handle_t   mlnx_device;
-    DAT_PVOID         *ia_ptr;     // hook for CA async callbacks
-} dapl_ibal_ca_t;
-
-
-typedef struct _dapl_ibal_port
-{
-    cl_list_item_t    next;            // peer CA list
-    dapl_ibal_ca_t    *ca;             // pointer to parent CA
-    ib_port_attr_t    *p_attr;         // port attributes
-    dapl_ibal_refs_t  refs;            // reference counting
-} dapl_ibal_port_t;
-
-typedef struct _dapl_ibal_evd_cb
-{
-    cl_list_item_t     next;        // peer CA list
-    ib_async_handler_t pfn_async_err_cb;
-    ib_async_qp_handler_t  pfn_async_qp_err_cb;
-    ib_async_cq_handler_t  pfn_async_cq_err_cb;
-    void               *context;
-} dapl_ibal_evd_cb_t;
-
-/*
- * Definitions to map DTO OPs to IBAL Work-Request ops.
- */
-#define    OP_BAD_OPCODE      0
-#define    OP_RDMA_READ       WR_RDMA_READ
-#define    OP_RDMA_WRITE      WR_RDMA_WRITE
-#define    OP_SEND            WR_SEND
-#define    OP_COMP_AND_SWAP   WR_COMPARE_SWAP
-#define    OP_FETCH_AND_ADD   WR_FETCH_ADD
-
-#define    OP_RECEIVE         8                /* (8)  */
-#define    OP_BIND_MW         9                /* no-equivalent */
-#define    OP_RDMA_WRITE_IMM  10       /* RDMA_WRITE+Immediate data */
-#define    OP_RECEIVE_IMM     11       /* no-equivalent */
-
-/*
- * Definitions to map QP state
- */
-#define IB_QP_STATE_RESET    IB_QPS_RESET
-#define IB_QP_STATE_INIT     IB_QPS_INIT
-#define IB_QP_STATE_RTR      IB_QPS_RTR
-#define IB_QP_STATE_RTS      IB_QPS_RTS
-#define IB_QP_STATE_SQE      IB_QPS_SQERR
-#define IB_QP_STATE_SQD      IB_QPS_SQD
-#define IB_QP_STATE_ERROR    IB_QPS_ERROR
-
-/*
- * Definitions to map Memory OPs
- */
-#define IB_ACCESS_LOCAL_WRITE      IB_AC_LOCAL_WRITE
-#define IB_ACCESS_REMOTE_READ      IB_AC_RDMA_READ
-#define IB_ACCESS_REMOTE_WRITE     IB_AC_RDMA_WRITE
-#define IB_ACCESS_REMOTE_ATOMIC    IB_AC_ATOMIC
-#define IB_ACCESS_MEM_WINDOW_BIND  IB_AC_MW_BIND
-
-/*
- * CQE status 
- */
-enum _dapl_comp_status
-{
-       IB_COMP_ST_SUCCESS              = IB_WCS_SUCCESS,
-       IB_COMP_ST_LOCAL_LEN_ERR        = IB_WCS_LOCAL_LEN_ERR,
-       IB_COMP_ST_LOCAL_OP_ERR         = IB_WCS_LOCAL_OP_ERR,
-       IB_COMP_ST_LOCAL_PROTECT_ERR    = IB_WCS_LOCAL_PROTECTION_ERR,
-       IB_COMP_ST_WR_FLUSHED_ERR       = IB_WCS_WR_FLUSHED_ERR,
-       IB_COMP_ST_MW_BIND_ERR          = IB_WCS_MEM_WINDOW_BIND_ERR,
-       IB_COMP_ST_REM_ACC_ERR          = IB_WCS_REM_ACCESS_ERR,
-       IB_COMP_ST_REM_OP_ERR           = IB_WCS_REM_OP_ERR,
-       IB_COMP_ST_RNR_COUNTER          = IB_WCS_RNR_RETRY_ERR,
-       IB_COMP_ST_TRANSP_COUNTER       = IB_WCS_TIMEOUT_RETRY_ERR,
-       IB_COMP_ST_REM_REQ_ERR          = IB_WCS_REM_INVALID_REQ_ERR,
-       IB_COMP_ST_BAD_RESPONSE_ERR     = IB_WCS_UNMATCHED_RESPONSE,
-       IB_COMP_ST_EE_STATE_ERR,
-       IB_COMP_ST_EE_CTX_NO_ERR
-};
-
-
-/*
- * Macro to check the state of an EP/QP
- */
-#define DAPLIB_NEEDS_INIT(ep)  ((ep)->qp_state == IB_QPS_ERROR)
-
-
-/*
- * Resolve IBAL return codes to their DAPL equivelent.
- * Do not return invalid Handles, the user is not able
- * to deal with them.
- */
-STATIC _INLINE_ DAT_RETURN 
-dapl_ib_status_convert (
-    IN     int32_t     ib_status)
-{
-    switch ( ib_status )
-    {
-    case IB_SUCCESS:
-    {
-        return DAT_SUCCESS;
-    }
-    case IB_INSUFFICIENT_RESOURCES:
-    case IB_INSUFFICIENT_MEMORY:
-    case IB_RESOURCE_BUSY:
-    {
-        return DAT_INSUFFICIENT_RESOURCES;
-    }
-    case IB_INVALID_CA_HANDLE:
-    case IB_INVALID_CQ_HANDLE:
-    case IB_INVALID_QP_HANDLE:
-    case IB_INVALID_PD_HANDLE:
-    case IB_INVALID_MR_HANDLE:
-    case IB_INVALID_MW_HANDLE:
-    case IB_INVALID_AL_HANDLE:
-    case IB_INVALID_AV_HANDLE:
-    {
-        return DAT_INVALID_HANDLE;
-    }
-    case IB_INVALID_PKEY:
-    {
-        return DAT_PROTECTION_VIOLATION;
-    }
-    case IB_INVALID_LKEY:
-    case IB_INVALID_RKEY:
-    case IB_INVALID_PERMISSION:
-    {
-        return DAT_PRIVILEGES_VIOLATION;
-    }
-    case IB_INVALID_MAX_WRS:
-    case IB_INVALID_MAX_SGE:
-    case IB_INVALID_CQ_SIZE:
-    case IB_INVALID_SETTING:
-    case IB_INVALID_SERVICE_TYPE:
-    case IB_INVALID_GID:
-    case IB_INVALID_LID:
-    case IB_INVALID_GUID:
-    case IB_INVALID_PARAMETER:
-    {
-        return DAT_INVALID_PARAMETER;
-    }
-    case IB_INVALID_QP_STATE:
-    case IB_INVALID_APM_STATE:
-    case IB_INVALID_PORT_STATE:
-    case IB_INVALID_STATE:
-    {
-        return DAT_INVALID_STATE;
-    }
-    case IB_NOT_FOUND:
-    {
-        return DAT_QUEUE_EMPTY;
-    }
-    case IB_OVERFLOW:
-    {
-        return DAT_QUEUE_FULL;
-    }
-    case IB_UNSUPPORTED:
-    {
-        return DAT_NOT_IMPLEMENTED;
-    }
-    case IB_TIMEOUT:
-    {
-        return DAT_TIMEOUT_EXPIRED;
-    }
-    case IB_CANCELED:
-    {
-        return DAT_ABORT;
-    }
-    default:
-    {
-        return DAT_INTERNAL_ERROR;
-    }
-    }
-}
-   
-#define TAKE_LOCK( lock ) \
-        cl_spinlock_acquire( &(lock) )
-
-#define RELEASE_LOCK( lock ) \
-        cl_spinlock_release( &(lock) )
-
-#define LOCK_INSERT_HEAD( lock, head, item ) \
-{ \
-        TAKE_LOCK( lock ); \
-        cl_qlist_insert_head( &head, (cl_list_item_t*)(&item) ); \
-        RELEASE_LOCK( lock ); \
-}
-
-#define LOCK_INSERT_TAIL( lock, tail, item ) \
-{ \
-        TAKE_LOCK( lock ); \
-        cl_qlist_insert_tail( &tail, (cl_list_item_t*)(&item) ); \
-        RELEASE_LOCK( lock ); \
-}
-
-#define INIT_REFERENCE( p_ref, n, con, destruct ) \
-{ \
-        (p_ref)->count = n; \
-        (p_ref)->context = con; \
-        (p_ref)->destructor = destruct; \
-}
-
-#define TAKE_REFERENCE( p_ref ) \
-        cl_atomic_inc( &(p_ref)->count )
-
-#define REMOVE_REFERENCE( p_ref ) \
-{ \
-        if ( cl_atomic_dec( &(p_ref)->count ) == 0 ) \
-            if ( (p_ref)->destructor ) \
-                (p_ref)->destructor( (p_ref)->context ); \
-}
-
-/* 
- * dapl_llist_entry in dapl.h but dapl.h depends on provider 
- * typedef's in this file first. move dapl_llist_entry out of dapl.h
- */
-struct ib_llist_entry
-{
-    struct dapl_llist_entry    *flink;
-    struct dapl_llist_entry    *blink;
-    void                       *data;
-    struct dapl_llist_entry    *list_head;
-};
-
-#ifdef SOCK_CM
-
-typedef enum
-{
-       IB_THREAD_INIT,
-       IB_THREAD_RUN,
-       IB_THREAD_CANCEL,
-       IB_THREAD_EXIT
-
-} ib_thread_state_t;
-
-typedef enum scm_state 
-{
-       SCM_INIT,
-       SCM_LISTEN,
-       SCM_CONN_PENDING,
-       SCM_ACCEPTING,
-       SCM_ACCEPTED,
-       SCM_REJECTED,
-       SCM_CONNECTED,
-       SCM_DISCONNECTED,
-       SCM_DESTROY
-
-} SCM_STATE;
-
-#endif /* SOCK_CM */
-
-typedef struct _ib_hca_transport
-{ 
-#ifdef SOCK_CM
-    int                                max_inline_send;
-    ib_thread_state_t          cr_state;       /* CR thread */
-    DAPL_OS_THREAD             thread;         /* CR thread */
-    DAPL_OS_LOCK               lock;           /* CR serialization */
-    struct ib_llist_entry      *list;          /* Connection Requests */
-#endif
-    struct dapl_hca            *d_hca;
-    DAPL_OS_WAIT_OBJECT                wait_object;
-    DAPL_ATOMIC                        handle_ref_count; /* # of ia_opens on handle */
-    ib_cqd_handle_t            ib_cqd_handle;    /* cq domain handle */
-
-    /* Name service support */
-    void                       *name_service_handle;
-
-} ib_hca_transport_t;
-
-/* provider specfic fields for shared memory support */
-typedef uint32_t ib_shm_transport_t;
-
-#ifdef SOCK_CM
-
-/* inline send rdma threshold */
-#define        INLINE_SEND_DEFAULT     128
-
-/* CM mappings use SOCKETS */
-
-/* destination info exchanged between dapl, define wire protocol version */
-#define DSCM_VER 2
-
-typedef struct _ib_qp_cm
-{ 
-       ib_net16_t      ver;
-       ib_net16_t      rej;
-       ib_net16_t              lid;
-       ib_net16_t              port;
-       ib_net32_t      qpn;
-       ib_net32_t              p_size;
-       DAT_SOCK_ADDR6          ia_address;
-       GID             gid;
-
-} ib_qp_cm_t;
-
-struct ib_cm_handle
-{ 
-       struct ib_llist_entry   entry;
-       DAPL_OS_LOCK            lock;
-       SCM_STATE               state;
-       int                     socket;
-       int                     l_socket; 
-       struct dapl_hca         *hca;
-       DAT_HANDLE              sp;     
-       DAT_HANDLE              cr;
-       struct dapl_ep          *ep;
-       ib_qp_cm_t              dst;
-       unsigned char           p_data[256];
-};
-
-DAT_RETURN dapli_init_sock_cm ( IN DAPL_HCA  *hca_ptr );
-
-#endif /* SOCK_CM */
-
-/*
- * Prototype
- */
-
-extern ib_api_status_t 
-dapls_modify_qp_state_to_error (
-        ib_qp_handle_t                qp_handle );
-
-extern ib_api_status_t 
-dapls_modify_qp_state_to_reset (
-    ib_qp_handle_t);
-
-extern ib_api_status_t 
-dapls_modify_qp_state_to_init ( 
-    ib_qp_handle_t, DAT_EP_ATTR *, dapl_ibal_port_t *);
-
-extern ib_api_status_t 
-dapls_modify_qp_state_to_rtr (
-    ib_qp_handle_t, ib_net32_t, ib_lid_t, dapl_ibal_port_t *);
-
-extern ib_api_status_t 
-dapls_modify_qp_state_to_rts (
-    ib_qp_handle_t);
-
-extern void
-dapli_ibal_ca_async_error_callback(
-    IN    ib_async_event_rec_t* p_err_rec );
-
-extern dapl_ibal_port_t *
-dapli_ibal_get_port (
-    IN   dapl_ibal_ca_t    *p_ca,
-    IN   uint8_t           port_num);
-
-extern int32_t dapls_ib_init (void);
-extern int32_t dapls_ib_release (void);
-
-extern dapl_ibal_evd_cb_t *
-dapli_find_evd_cb_by_context(
-    IN    void           *context,
-    IN    dapl_ibal_ca_t *ca);
-
-extern IB_HCA_NAME
-dapl_ib_convert_name(IN  char    *name);
-
-
-STATIC _INLINE_ int32_t
-dapli_ibal_convert_privileges (IN  DAT_MEM_PRIV_FLAGS  privileges )
-{
-    int32_t value = DAT_MEM_PRIV_NONE_FLAG;
-
-    /*
-     *    if (DAT_MEM_PRIV_LOCAL_READ_FLAG & privileges)
-     *       do nothing
-     */
-    if (DAT_MEM_PRIV_LOCAL_WRITE_FLAG & privileges)
-       value |= IB_ACCESS_LOCAL_WRITE;
-
-    if (DAT_MEM_PRIV_REMOTE_WRITE_FLAG & privileges)
-       value |= IB_ACCESS_REMOTE_WRITE;
-
-    if (DAT_MEM_PRIV_REMOTE_READ_FLAG & privileges)
-       value |= IB_ACCESS_REMOTE_READ;
-
-#ifdef DAT_EXTENSIONS
-    if (DAT_IB_MEM_PRIV_REMOTE_ATOMIC & privileges) 
-        value |= IB_ACCESS_REMOTE_ATOMIC;
-#endif
-
-#ifdef DAPL_DBG
-    if (value == DAT_MEM_PRIV_NONE_FLAG)
-    {
-       dapl_dbg_log(DAPL_DBG_TYPE_ERR,"%s() Unknown DAT_MEM_PRIV_ 0x%x\n",
-                     __FUNCTION__,privileges);
-    }
-#endif
-    return value;
-}
-
-#define dapl_rmr_convert_privileges(p) dapli_ibal_convert_privileges(p)
-#define dapl_lmr_convert_privileges(p) dapli_ibal_convert_privileges(p)
-
-#endif /*  _DAPL_IBAL_UTIL_H_ */
+\r
+/*\r
+ * Copyright (c) 2005-2007 Intel Corporation. All rights reserved.\r
+ * Copyright (c) 2002, Network Appliance, Inc. All rights reserved. \r
+ * \r
+ * This Software is licensed under the terms of the "Common Public\r
+ * License" a copy of which is in the file LICENSE.txt in the root\r
+ * directory. The license is also available from the Open Source\r
+ * Initiative, see http://www.opensource.org/licenses/cpl.php.\r
+ *\r
+ */\r
+\r
+/**********************************************************************\r
+ * \r
+ * MODULE: dapl_ibal_util.h\r
+ *\r
+ * PURPOSE: Utility defs & routines for access to openib-windows IBAL APIs\r
+ *\r
+ * $Id: dapl_ibal_util.h 33 2005-07-11 19:51:17Z ftillier $\r
+ *\r
+ **********************************************************************/\r
+\r
+#ifndef _DAPL_IBAL_UTIL_H_\r
+#define _DAPL_IBAL_UTIL_H_\r
+\r
+#include <iba/ib_al.h>\r
+#include <complib/cl_spinlock.h>\r
+#include <complib/cl_qlist.h>\r
+#include <complib/cl_atomic.h>\r
+\r
+#ifdef DAT_EXTENSIONS\r
+#include <dat2\dat_ib_extensions.h>\r
+#endif\r
+\r
+/*\r
+ * Typedefs to map IBAL types to more generic 'ib' types\r
+ */\r
+#ifdef SOCK_CM\r
+typedef  struct ib_cm_handle           *dp_ib_cm_handle_t;\r
+typedef  struct ib_cm_handle           *ib_cm_srvc_handle_t;\r
+#else\r
+typedef  ib_cm_handle_t                *dp_ib_cm_handle_t;\r
+typedef  ib_listen_handle_t            ib_cm_srvc_handle_t;\r
+#endif\r
+\r
+typedef  ib_net64_t                    IB_HCA_NAME;\r
+typedef  ib_ca_handle_t                ib_hca_handle_t;\r
+typedef  DAT_PVOID                     ib_cqd_handle_t;\r
+typedef  ib_async_event_rec_t          ib_error_record_t;\r
+typedef  ib_wr_type_t                  ib_send_op_type_t;\r
+typedef  ib_wc_t                       ib_work_completion_t;\r
+typedef  uint32_t                      ib_hca_port_t;\r
+typedef  uint32_t                      ib_uint32_t;\r
+typedef  ib_local_ds_t                 ib_data_segment_t;\r
+\r
+typedef  unsigned __int3264            cl_dev_handle_t;\r
+\r
+\r
+typedef void (*ib_async_handler_t)(\r
+    IN    ib_hca_handle_t    ib_hca_handle,\r
+    IN    ib_error_record_t  *err_code,\r
+    IN    void               *context);\r
+\r
+typedef void (*ib_async_qp_handler_t)(\r
+    IN    ib_hca_handle_t    ib_hca_handle,\r
+    IN    ib_qp_handle_t     ib_qp_handle,\r
+    IN    ib_error_record_t  *err_code,\r
+    IN    void               *context);\r
+\r
+typedef void (*ib_async_cq_handler_t)(\r
+    IN    ib_hca_handle_t    ib_hca_handle,\r
+    IN    ib_cq_handle_t     ib_cq_handle,\r
+    IN    ib_error_record_t  *err_code,\r
+    IN    void               *context);\r
+\r
+typedef ib_net64_t   ib_guid_t;\r
+typedef ib_net16_t   ib_lid_t;\r
+typedef boolean_t    ib_bool_t;\r
+\r
+typedef struct _GID\r
+{\r
+    uint64_t gid_prefix;\r
+    uint64_t guid;\r
+} GID;\r
+\r
+typedef enum \r
+{\r
+    IB_CME_CONNECTED,\r
+    IB_CME_DISCONNECTED,\r
+    IB_CME_DISCONNECTED_ON_LINK_DOWN,\r
+    IB_CME_CONNECTION_REQUEST_PENDING,\r
+    IB_CME_CONNECTION_REQUEST_PENDING_PRIVATE_DATA,\r
+    IB_CME_DESTINATION_REJECT,\r
+    IB_CME_DESTINATION_REJECT_PRIVATE_DATA,\r
+    IB_CME_DESTINATION_UNREACHABLE,\r
+    IB_CME_TOO_MANY_CONNECTION_REQUESTS,\r
+    IB_CME_LOCAL_FAILURE,\r
+    IB_CME_REPLY_RECEIVED,\r
+    IB_CME_REPLY_RECEIVED_PRIVATE_DATA,\r
+    IB_CM_LOCAL_FAILURE\r
+} ib_cm_events_t;\r
+\r
+\r
+typedef enum\r
+{\r
+    IB_NOTIFY_ON_NEXT_COMP,\r
+    IB_NOTIFY_ON_SOLIC_COMP\r
+} ib_notification_type_t;\r
+\r
+typedef struct _ib_hca_name\r
+{\r
+    DAT_NAME_PTR hca_name[DAT_NAME_MAX_LENGTH];\r
+} ib_hca_name_t;\r
+\r
+\r
+#define          IB_INVALID_HANDLE             NULL\r
+#define          true                          TRUE\r
+#define          false                         FALSE\r
+\r
+#define          IB_MAX_REQ_PDATA_SIZE      92\r
+#define          IB_MAX_REP_PDATA_SIZE      196\r
+#define          IB_MAX_REJ_PDATA_SIZE      148\r
+#define          IB_MAX_DREQ_PDATA_SIZE     220\r
+#define          IB_MAX_DREP_PDATA_SIZE     224\r
+\r
+\r
+/* Resource Not Ready\r
+       1-6 is an actual retry count which is decremented to zero before\r
+        an error condition is set.\r
+    7 is 'magic' in that it implies Infinite retry, just keeps trying.\r
+*/\r
+#define                IB_RNR_RETRY_CNT   7\r
+\r
+/*\r
+IB 1.2 spec, page 331, table 45, RNR NAK timeout encoding (5-bits)\r
\r
+00000=655.36ms(milliseconds)\r
+00001=0.01ms\r
+00010=0.02ms\r
+00011=0.03ms\r
+00100=0.04ms\r
+00101=0.06ms\r
+00110=0.08ms\r
+00111=0.12ms\r
+\r
+11100=163.84ms 28d\r
+11101=245.76ms 29d\r
+11110=327.68ms 30d\r
+11111=491.52ms 31d\r
+*/\r
+#define                IB_RNR_NAK_TIMEOUT   0\r
+\r
+\r
+typedef void\r
+(*dapl_ibal_pfn_destructor_t)(\r
+    IN    void*    context );\r
+\r
+typedef struct _dapl_ibal_refs\r
+{\r
+    atomic32_t                      count;        // number of references\r
+    void*                         context;     // context for destructor\r
+    dapl_ibal_pfn_destructor_t    destructor;   // called when reference goes to zero\r
+\r
+} dapl_ibal_refs_t;\r
+\r
+\r
+typedef struct _dapl_ibal_root\r
+{\r
+    ib_al_handle_t        h_al;        // handle to Access Layer\r
+    cl_spinlock_t         ca_lock;     // CA list lock\r
+    cl_qlist_t            ca_head;     // list head of CAs\r
+    boolean_t             shutdown;    // when true, driver is shutting down\r
+    boolean_t             initialized;    // when true, lib is initialized \r
+\r
+} dapl_ibal_root_t;\r
+\r
+\r
+typedef struct _dapl_ibal_ca\r
+{\r
+    cl_list_item_t    next;        // peer CA list\r
+    ib_ca_handle_t    h_ca;        // handle to open CA\r
+    ib_ca_attr_t      *p_ca_attr;  // CA attributes\r
+    uint32_t          ca_attr_size;// size of ca attribute\r
+    dapl_ibal_refs_t  refs;        // reference counting\r
+    cl_spinlock_t     port_lock;   // port list lock\r
+    cl_qlist_t        port_head;   // port list head for this CA\r
+    cl_spinlock_t     evd_cb_lock; // EVD async error cb list lock\r
+    cl_qlist_t        evd_cb_head; // EVD async error cb list head for this CA\r
+    cl_dev_handle_t   mlnx_device;\r
+    DAT_PVOID         *ia_ptr;     // hook for CA async callbacks\r
+} dapl_ibal_ca_t;\r
+\r
+\r
+typedef struct _dapl_ibal_port\r
+{\r
+    cl_list_item_t    next;            // peer CA list\r
+    dapl_ibal_ca_t    *ca;             // pointer to parent CA\r
+    ib_port_attr_t    *p_attr;         // port attributes\r
+    dapl_ibal_refs_t  refs;            // reference counting\r
+} dapl_ibal_port_t;\r
+\r
+typedef struct _dapl_ibal_evd_cb\r
+{\r
+    cl_list_item_t     next;        // peer CA list\r
+    ib_async_handler_t pfn_async_err_cb;\r
+    ib_async_qp_handler_t  pfn_async_qp_err_cb;\r
+    ib_async_cq_handler_t  pfn_async_cq_err_cb;\r
+    void               *context;\r
+} dapl_ibal_evd_cb_t;\r
+\r
+/*\r
+ * Definitions to map DTO OPs to IBAL Work-Request ops.\r
+ */\r
+#define    OP_BAD_OPCODE      0\r
+#define    OP_RDMA_READ       WR_RDMA_READ\r
+#define    OP_RDMA_WRITE      WR_RDMA_WRITE\r
+#define    OP_SEND            WR_SEND\r
+#define    OP_COMP_AND_SWAP   WR_COMPARE_SWAP\r
+#define    OP_FETCH_AND_ADD   WR_FETCH_ADD\r
+\r
+#define    OP_RECEIVE         8                /* (8)  */\r
+#define    OP_BIND_MW         9                /* no-equivalent */\r
+#define    OP_RDMA_WRITE_IMM  10       /* RDMA_WRITE+Immediate data */\r
+#define    OP_RECEIVE_IMM     11       /* no-equivalent */\r
+\r
+/*\r
+ * Definitions to map QP state\r
+ */\r
+#define IB_QP_STATE_RESET    IB_QPS_RESET\r
+#define IB_QP_STATE_INIT     IB_QPS_INIT\r
+#define IB_QP_STATE_RTR      IB_QPS_RTR\r
+#define IB_QP_STATE_RTS      IB_QPS_RTS\r
+#define IB_QP_STATE_SQE      IB_QPS_SQERR\r
+#define IB_QP_STATE_SQD      IB_QPS_SQD\r
+#define IB_QP_STATE_ERROR    IB_QPS_ERROR\r
+\r
+/*\r
+ * Definitions to map Memory OPs\r
+ */\r
+#define IB_ACCESS_LOCAL_WRITE      IB_AC_LOCAL_WRITE\r
+#define IB_ACCESS_REMOTE_READ      IB_AC_RDMA_READ\r
+#define IB_ACCESS_REMOTE_WRITE     IB_AC_RDMA_WRITE\r
+#define IB_ACCESS_REMOTE_ATOMIC    IB_AC_ATOMIC\r
+#define IB_ACCESS_MEM_WINDOW_BIND  IB_AC_MW_BIND\r
+\r
+/*\r
+ * CQE status \r
+ */\r
+enum _dapl_comp_status\r
+{\r
+       IB_COMP_ST_SUCCESS              = IB_WCS_SUCCESS,\r
+       IB_COMP_ST_LOCAL_LEN_ERR        = IB_WCS_LOCAL_LEN_ERR,\r
+       IB_COMP_ST_LOCAL_OP_ERR         = IB_WCS_LOCAL_OP_ERR,\r
+       IB_COMP_ST_LOCAL_PROTECT_ERR    = IB_WCS_LOCAL_PROTECTION_ERR,\r
+       IB_COMP_ST_WR_FLUSHED_ERR       = IB_WCS_WR_FLUSHED_ERR,\r
+       IB_COMP_ST_MW_BIND_ERR          = IB_WCS_MEM_WINDOW_BIND_ERR,\r
+       IB_COMP_ST_REM_ACC_ERR          = IB_WCS_REM_ACCESS_ERR,\r
+       IB_COMP_ST_REM_OP_ERR           = IB_WCS_REM_OP_ERR,\r
+       IB_COMP_ST_RNR_COUNTER          = IB_WCS_RNR_RETRY_ERR,\r
+       IB_COMP_ST_TRANSP_COUNTER       = IB_WCS_TIMEOUT_RETRY_ERR,\r
+       IB_COMP_ST_REM_REQ_ERR          = IB_WCS_REM_INVALID_REQ_ERR,\r
+       IB_COMP_ST_BAD_RESPONSE_ERR     = IB_WCS_UNMATCHED_RESPONSE,\r
+       IB_COMP_ST_EE_STATE_ERR,\r
+       IB_COMP_ST_EE_CTX_NO_ERR\r
+};\r
+\r
+\r
+/*\r
+ * Macro to check the state of an EP/QP\r
+ */\r
+#define DAPLIB_NEEDS_INIT(ep)  ((ep)->qp_state == IB_QPS_ERROR)\r
+\r
+\r
+/*\r
+ * Resolve IBAL return codes to their DAPL equivelent.\r
+ * Do not return invalid Handles, the user is not able\r
+ * to deal with them.\r
+ */\r
+STATIC _INLINE_ DAT_RETURN \r
+dapl_ib_status_convert (\r
+    IN     int32_t     ib_status)\r
+{\r
+    switch ( ib_status )\r
+    {\r
+    case IB_SUCCESS:\r
+    {\r
+        return DAT_SUCCESS;\r
+    }\r
+    case IB_INSUFFICIENT_RESOURCES:\r
+    case IB_INSUFFICIENT_MEMORY:\r
+    case IB_RESOURCE_BUSY:\r
+    {\r
+        return DAT_INSUFFICIENT_RESOURCES;\r
+    }\r
+    case IB_INVALID_CA_HANDLE:\r
+    case IB_INVALID_CQ_HANDLE:\r
+    case IB_INVALID_QP_HANDLE:\r
+    case IB_INVALID_PD_HANDLE:\r
+    case IB_INVALID_MR_HANDLE:\r
+    case IB_INVALID_MW_HANDLE:\r
+    case IB_INVALID_AL_HANDLE:\r
+    case IB_INVALID_AV_HANDLE:\r
+    {\r
+        return DAT_INVALID_HANDLE;\r
+    }\r
+    case IB_INVALID_PKEY:\r
+    {\r
+        return DAT_PROTECTION_VIOLATION;\r
+    }\r
+    case IB_INVALID_LKEY:\r
+    case IB_INVALID_RKEY:\r
+    case IB_INVALID_PERMISSION:\r
+    {\r
+        return DAT_PRIVILEGES_VIOLATION;\r
+    }\r
+    case IB_INVALID_MAX_WRS:\r
+    case IB_INVALID_MAX_SGE:\r
+    case IB_INVALID_CQ_SIZE:\r
+    case IB_INVALID_SETTING:\r
+    case IB_INVALID_SERVICE_TYPE:\r
+    case IB_INVALID_GID:\r
+    case IB_INVALID_LID:\r
+    case IB_INVALID_GUID:\r
+    case IB_INVALID_PARAMETER:\r
+    {\r
+        return DAT_INVALID_PARAMETER;\r
+    }\r
+    case IB_INVALID_QP_STATE:\r
+    case IB_INVALID_APM_STATE:\r
+    case IB_INVALID_PORT_STATE:\r
+    case IB_INVALID_STATE:\r
+    {\r
+        return DAT_INVALID_STATE;\r
+    }\r
+    case IB_NOT_FOUND:\r
+    {\r
+        return DAT_QUEUE_EMPTY;\r
+    }\r
+    case IB_OVERFLOW:\r
+    {\r
+        return DAT_QUEUE_FULL;\r
+    }\r
+    case IB_UNSUPPORTED:\r
+    {\r
+        return DAT_NOT_IMPLEMENTED;\r
+    }\r
+    case IB_TIMEOUT:\r
+    {\r
+        return DAT_TIMEOUT_EXPIRED;\r
+    }\r
+    case IB_CANCELED:\r
+    {\r
+        return DAT_ABORT;\r
+    }\r
+    default:\r
+    {\r
+        return DAT_INTERNAL_ERROR;\r
+    }\r
+    }\r
+}\r
+   \r
+#define TAKE_LOCK( lock ) \\r
+        cl_spinlock_acquire( &(lock) )\r
+\r
+#define RELEASE_LOCK( lock ) \\r
+        cl_spinlock_release( &(lock) )\r
+\r
+#define LOCK_INSERT_HEAD( lock, head, item ) \\r
+{ \\r
+        TAKE_LOCK( lock ); \\r
+        cl_qlist_insert_head( &head, (cl_list_item_t*)(&item) ); \\r
+        RELEASE_LOCK( lock ); \\r
+}\r
+\r
+#define LOCK_INSERT_TAIL( lock, tail, item ) \\r
+{ \\r
+        TAKE_LOCK( lock ); \\r
+        cl_qlist_insert_tail( &tail, (cl_list_item_t*)(&item) ); \\r
+        RELEASE_LOCK( lock ); \\r
+}\r
+\r
+#define INIT_REFERENCE( p_ref, n, con, destruct ) \\r
+{ \\r
+        (p_ref)->count = n; \\r
+        (p_ref)->context = con; \\r
+        (p_ref)->destructor = destruct; \\r
+}\r
+\r
+#define TAKE_REFERENCE( p_ref ) \\r
+        cl_atomic_inc( &(p_ref)->count )\r
+\r
+#define REMOVE_REFERENCE( p_ref ) \\r
+{ \\r
+        if ( cl_atomic_dec( &(p_ref)->count ) == 0 ) \\r
+            if ( (p_ref)->destructor ) \\r
+                (p_ref)->destructor( (p_ref)->context ); \\r
+}\r
+\r
+/* \r
+ * dapl_llist_entry in dapl.h but dapl.h depends on provider \r
+ * typedef's in this file first. move dapl_llist_entry out of dapl.h\r
+ */\r
+struct ib_llist_entry\r
+{\r
+    struct dapl_llist_entry    *flink;\r
+    struct dapl_llist_entry    *blink;\r
+    void                       *data;\r
+    struct dapl_llist_entry    *list_head;\r
+};\r
+\r
+#ifdef SOCK_CM\r
+\r
+typedef enum\r
+{\r
+       IB_THREAD_INIT,\r
+       IB_THREAD_RUN,\r
+       IB_THREAD_CANCEL,\r
+       IB_THREAD_EXIT\r
+\r
+} ib_thread_state_t;\r
+\r
+typedef enum scm_state \r
+{\r
+       SCM_INIT,\r
+       SCM_LISTEN,\r
+       SCM_CONN_PENDING,\r
+       SCM_ACCEPTING,\r
+       SCM_ACCEPTED,\r
+       SCM_REJECTED,\r
+       SCM_CONNECTED,\r
+       SCM_DISCONNECTED,\r
+       SCM_DESTROY\r
+\r
+} SCM_STATE;\r
+\r
+#endif /* SOCK_CM */\r
+\r
+typedef struct _ib_hca_transport\r
+{ \r
+#ifdef SOCK_CM\r
+    int                                max_inline_send;\r
+    ib_thread_state_t          cr_state;       /* CR thread */\r
+    DAPL_OS_THREAD             thread;         /* CR thread */\r
+    DAPL_OS_LOCK               lock;           /* CR serialization */\r
+    struct ib_llist_entry      *list;          /* Connection Requests */\r
+#endif\r
+    struct dapl_hca            *d_hca;\r
+    DAPL_OS_WAIT_OBJECT                wait_object;\r
+    DAPL_ATOMIC                        handle_ref_count; /* # of ia_opens on handle */\r
+    ib_cqd_handle_t            ib_cqd_handle;    /* cq domain handle */\r
+\r
+    /* Name service support */\r
+    void                       *name_service_handle;\r
+\r
+} ib_hca_transport_t;\r
+\r
+/* provider specfic fields for shared memory support */\r
+typedef uint32_t ib_shm_transport_t;\r
+\r
+#ifdef SOCK_CM\r
+\r
+/* inline send rdma threshold */\r
+#define        INLINE_SEND_DEFAULT     128\r
+\r
+/* CM mappings use SOCKETS */\r
+\r
+/* destination info exchanged between dapl, define wire protocol version */\r
+#define DSCM_VER 2\r
+\r
+typedef struct _ib_qp_cm\r
+{ \r
+       ib_net16_t      ver;\r
+       ib_net16_t      rej;\r
+       ib_net16_t              lid;\r
+       ib_net16_t              port;\r
+       ib_net32_t      qpn;\r
+       ib_net32_t              p_size;\r
+       DAT_SOCK_ADDR6          ia_address;\r
+       GID             gid;\r
+\r
+} ib_qp_cm_t;\r
+\r
+struct ib_cm_handle\r
+{ \r
+       struct ib_llist_entry   entry;\r
+       DAPL_OS_LOCK            lock;\r
+       SCM_STATE               state;\r
+       int                     socket;\r
+       int                     l_socket; \r
+       struct dapl_hca         *hca;\r
+       DAT_HANDLE              sp;     \r
+       DAT_HANDLE              cr;\r
+       struct dapl_ep          *ep;\r
+       ib_qp_cm_t              dst;\r
+       unsigned char           p_data[256];\r
+};\r
+\r
+DAT_RETURN dapli_init_sock_cm ( IN DAPL_HCA  *hca_ptr );\r
+\r
+#endif /* SOCK_CM */\r
+\r
+/*\r
+ * Prototype\r
+ */\r
+\r
+extern ib_api_status_t \r
+dapls_modify_qp_state_to_error (\r
+        ib_qp_handle_t                qp_handle );\r
+\r
+extern ib_api_status_t \r
+dapls_modify_qp_state_to_reset (\r
+    ib_qp_handle_t);\r
+\r
+extern ib_api_status_t \r
+dapls_modify_qp_state_to_init ( \r
+    ib_qp_handle_t, DAT_EP_ATTR *, dapl_ibal_port_t *);\r
+\r
+extern ib_api_status_t \r
+dapls_modify_qp_state_to_rtr (\r
+    ib_qp_handle_t, ib_net32_t, ib_lid_t, dapl_ibal_port_t *);\r
+\r
+extern ib_api_status_t \r
+dapls_modify_qp_state_to_rts (\r
+    ib_qp_handle_t);\r
+\r
+extern void\r
+dapli_ibal_ca_async_error_callback(\r
+    IN    ib_async_event_rec_t* p_err_rec );\r
+\r
+extern dapl_ibal_port_t *\r
+dapli_ibal_get_port (\r
+    IN   dapl_ibal_ca_t    *p_ca,\r
+    IN   uint8_t           port_num);\r
+\r
+extern int32_t dapls_ib_init (void);\r
+extern int32_t dapls_ib_release (void);\r
+\r
+extern dapl_ibal_evd_cb_t *\r
+dapli_find_evd_cb_by_context(\r
+    IN    void           *context,\r
+    IN    dapl_ibal_ca_t *ca);\r
+\r
+extern IB_HCA_NAME\r
+dapl_ib_convert_name(IN  char    *name);\r
+\r
+\r
+STATIC _INLINE_ int32_t\r
+dapli_ibal_convert_privileges (IN  DAT_MEM_PRIV_FLAGS  privileges )\r
+{\r
+    int32_t value = DAT_MEM_PRIV_NONE_FLAG;\r
+\r
+    /*\r
+     *    if (DAT_MEM_PRIV_LOCAL_READ_FLAG & privileges)\r
+     *       do nothing\r
+     */\r
+    if (DAT_MEM_PRIV_LOCAL_WRITE_FLAG & privileges)\r
+       value |= IB_ACCESS_LOCAL_WRITE;\r
+\r
+    if (DAT_MEM_PRIV_REMOTE_WRITE_FLAG & privileges)\r
+       value |= IB_ACCESS_REMOTE_WRITE;\r
+\r
+    if (DAT_MEM_PRIV_REMOTE_READ_FLAG & privileges)\r
+       value |= IB_ACCESS_REMOTE_READ;\r
+\r
+#ifdef DAT_EXTENSIONS\r
+    if (DAT_IB_MEM_PRIV_REMOTE_ATOMIC & privileges) \r
+        value |= IB_ACCESS_REMOTE_ATOMIC;\r
+#endif\r
+\r
+#ifdef DAPL_DBG\r
+    if (value == DAT_MEM_PRIV_NONE_FLAG)\r
+    {\r
+       dapl_dbg_log(DAPL_DBG_TYPE_ERR,"%s() Unknown DAT_MEM_PRIV_ 0x%x\n",\r
+                     __FUNCTION__,privileges);\r
+    }\r
+#endif\r
+    return value;\r
+}\r
+\r
+#define dapl_rmr_convert_privileges(p) dapli_ibal_convert_privileges(p)\r
+#define dapl_lmr_convert_privileges(p) dapli_ibal_convert_privileges(p)\r
+\r
+#endif /*  _DAPL_IBAL_UTIL_H_ */\r
index b13c96311f0e80e809c3a57d9adb919841ee04bb..1a3099e504da83d2d9ab9c288c54e9957910fc4a 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.h
- *
- * PURPOSE: defines common data structures for the DAPL reference implemenation
- *
- * Description: This file describes the working data structures used within
- *              DAPL RI.
- *
- *
- * $Id: dapl.h 1317 2005-04-25 17:29:42Z jlentini $
- **********************************************************************/
-
-#ifndef _DAPL_H_
-#define _DAPL_H_
-
-#if defined(__KERNEL__)
-#include <dat2/kdat.h>
-#else
-#include <dat2/udat.h>
-#endif /* defined(__KERNEL__) */
-#include <dat2/dat_registry.h>
-#include "dapl_osd.h"
-#include "dapl_debug.h"
-
-
-
-/*********************************************************************
- *                                                                   *
- * Enumerations                                                      *
- *                                                                   *
- *********************************************************************/
-
-typedef enum dapl_magic
-{
-    /* magic number values for verification & debug */
-    DAPL_MAGIC_IA      = 0xCafeF00d,
-    DAPL_MAGIC_EVD     = 0xFeedFace,
-    DAPL_MAGIC_EP      = 0xDeadBabe,
-    DAPL_MAGIC_LMR     = 0xBeefCafe,
-    DAPL_MAGIC_RMR      = 0xABadCafe,
-    DAPL_MAGIC_PZ      = 0xDeafBeef,
-    DAPL_MAGIC_PSP     = 0xBeadeD0c,
-    DAPL_MAGIC_RSP     = 0xFab4Feed,
-    DAPL_MAGIC_SRQ     = 0xC001Babe,
-    DAPL_MAGIC_CR      = 0xBe12Cee1,
-    DAPL_MAGIC_CR_DESTROYED = 0xB12bDead,
-    DAPL_MAGIC_CNO     = 0xDeadF00d,
-    DAPL_MAGIC_INVALID  = 0xFFFFFFFF
-} DAPL_MAGIC;
-
-typedef enum dapl_evd_state
-{
-    DAPL_EVD_STATE_TERMINAL,
-    DAPL_EVD_STATE_INITIAL,
-    DAPL_EVD_STATE_OPEN,
-    DAPL_EVD_STATE_WAITED,
-    DAPL_EVD_STATE_DEAD        = 0xDEAD
-} DAPL_EVD_STATE;
-
-typedef enum dapl_evd_completion
-{
-    DAPL_EVD_STATE_INIT,
-    DAPL_EVD_STATE_SOLICITED_WAIT,
-    DAPL_EVD_STATE_THRESHOLD,
-    DAPL_EVD_STATE_UNSIGNALLED
-} DAPL_EVD_COMPLETION;
-
-typedef enum dapl_cno_state
-{
-    DAPL_CNO_STATE_UNTRIGGERED,
-    DAPL_CNO_STATE_TRIGGERED,
-    DAPL_CNO_STATE_DEAD = 0xDeadFeed,
-} DAPL_CNO_STATE;
-
-typedef enum dapl_qp_state
-{
-    DAPL_QP_STATE_UNCONNECTED,
-    DAPL_QP_STATE_RESERVED,
-    DAPL_QP_STATE_PASSIVE_CONNECTION_PENDING,
-    DAPL_QP_STATE_ACTIVE_CONNECTION_PENDING,
-    DAPL_QP_STATE_TENTATIVE_CONNECTION_PENDING,
-    DAPL_QP_STATE_CONNECTED,
-    DAPL_QP_STATE_DISCONNECT_PENDING,
-    DAPL_QP_STATE_ERROR,
-    DAPL_QP_STATE_NOT_REUSABLE,
-    DAPL_QP_STATE_FREE
-} DAPL_QP_STATE;
-
-
-/*********************************************************************
- *                                                                   *
- * Constants                                                         *
- *                                                                   *
- *********************************************************************/
-
-/*
- * number of HCAs allowed
- */
-#define DAPL_MAX_HCA_COUNT             4
-
-/*
- * Configures the RMR bind evd restriction
- */
-
-#define DAPL_RMR_BIND_EVD_RESTRICTION  DAT_RMR_EVD_SAME_AS_REQUEST_EVD
-
-/*
- * special qp_state indicating the EP does not have a QP attached yet
- */
-#define DAPL_QP_STATE_UNATTACHED       0xFFF0
-
-#define DAPL_MAX_PRIVATE_DATA_SIZE     256
-
-/*********************************************************************
- *                                                                   *
- * Macros                                                            *
- *                                                                   *
- *********************************************************************/
-
-#if defined (sun) || defined(__sun) || defined(_sun_) || defined (__solaris__) 
-#define DAPL_BAD_PTR(a) ((unsigned long)(a) & 3)
-#elif defined(__linux__)
-#define DAPL_BAD_PTR(a) ((unsigned long)(a) & 3)
-#elif defined(_WIN64)
-#define DAPL_BAD_PTR(a) ((unsigned long)((DAT_UINT64)(a)) & 3)
-#elif defined(_WIN32)
-#define DAPL_BAD_PTR(a) ((unsigned long)((DAT_UINT64)(a)) & 3)
-#endif
-
-/*
- * Simple macro to verify a handle is bad. Conditions:
- * - pointer is NULL
- * - pointer is not word aligned
- * - pointer's magic number is wrong
- */
-
-#define DAPL_BAD_HANDLE(h, magicNum) (                         \
-           ((h) == NULL) ||                                    \
-           DAPL_BAD_PTR(h) ||                                  \
-           (((DAPL_HEADER *)(h))->magic != (magicNum)))
-
-#define DAPL_MIN(a, b)        ((a < b) ? (a) : (b))
-#define DAPL_MAX(a, b)        ((a > b) ? (a) : (b))
-
-#if NDEBUG > 0
-#define DEBUG_IS_BAD_HANDLE(h, magicNum) (DAPL_BAD_HANDLE(h, magicNum))
-#else
-#define DEBUG_IS_BAD_HANDLE(h, magicNum) (0)
-#endif
-
-#define DAT_ERROR(Type, SubType) ((DAT_RETURN)(DAT_CLASS_ERROR | Type | SubType))
-
-/*********************************************************************
- *                                                                   *
- * Typedefs                                                          *
- *                                                                   *
- *********************************************************************/
-
-typedef struct dapl_llist_entry                DAPL_LLIST_ENTRY;
-typedef DAPL_LLIST_ENTRY *             DAPL_LLIST_HEAD;
-typedef struct dapl_ring_buffer                DAPL_RING_BUFFER;
-typedef struct dapl_cookie_buffer      DAPL_COOKIE_BUFFER;
-
-typedef struct dapl_hash_table          DAPL_HASH_TABLE;
-typedef struct dapl_hash_table *        DAPL_HASH_TABLEP;
-typedef DAT_UINT64                      DAPL_HASH_KEY;
-typedef void *                          DAPL_HASH_DATA;
-
-typedef struct dapl_hca                        DAPL_HCA;
-
-typedef struct dapl_header             DAPL_HEADER;
-
-typedef struct dapl_ia                 DAPL_IA;
-typedef struct dapl_cno                        DAPL_CNO;
-typedef struct dapl_evd                DAPL_EVD;
-typedef struct dapl_ep                         DAPL_EP;
-typedef struct dapl_srq                        DAPL_SRQ;
-typedef struct dapl_pz                 DAPL_PZ;
-typedef struct dapl_lmr                        DAPL_LMR;
-typedef struct dapl_rmr                        DAPL_RMR;
-typedef struct dapl_sp                 DAPL_SP;
-typedef struct dapl_cr                 DAPL_CR;
-
-typedef struct dapl_cookie             DAPL_COOKIE;
-typedef struct dapl_dto_cookie         DAPL_DTO_COOKIE;
-typedef struct dapl_rmr_cookie         DAPL_RMR_COOKIE;
-
-typedef struct dapl_private            DAPL_PRIVATE;
-
-
-
-/*********************************************************************
- *                                                                   *
- * Structures                                                        *
- *                                                                   *
- *********************************************************************/
-
-struct dapl_llist_entry
-{
-    struct dapl_llist_entry    *flink;
-    struct dapl_llist_entry    *blink;
-    void                       *data;
-    DAPL_LLIST_HEAD            *list_head; /* for consistency checking */
-};
-
-struct dapl_ring_buffer
-{
-    void               **base;         /* base of element array */
-    DAT_COUNT          lim;            /* mask, number of entries - 1 */
-    DAPL_ATOMIC                head;           /* head pointer index */
-    DAPL_ATOMIC                tail;           /* tail pointer index */
-};
-
-struct dapl_cookie_buffer
-{
-    DAPL_COOKIE                *pool;
-    DAT_COUNT          pool_size;
-    DAPL_ATOMIC                head;
-    DAPL_ATOMIC                tail;
-};
-
-#ifdef IBAPI
-#include "dapl_ibapi_util.h"
-#elif VAPI
-#include "dapl_vapi_util.h"
-#elif __OPENIB__
-#include "dapl_openib_util.h"
-#include "dapl_openib_cm.h"
-#elif DUMMY
-#include "dapl_dummy_util.h"
-#elif OPENIB
-#include "dapl_ib_util.h"
-#else /* windows - IBAL and/or IBAL+Sock_CM */
-#include "dapl_ibal_util.h"
-#endif
-
-struct dapl_hca
-{
-    DAPL_OS_LOCK       lock;
-    DAPL_LLIST_HEAD    ia_list_head;      /* list of all open IAs */
-    DAPL_ATOMIC                handle_ref_count;  /* count of ia_opens on handle */
-    DAPL_EVD           *async_evd;
-    DAPL_EVD           *async_error_evd;
-    DAT_SOCK_ADDR6     hca_address;       /* local address of HCA*/
-    char               *name;             /* provider name */
-    ib_hca_handle_t    ib_hca_handle;
-    unsigned long       port_num;         /* physical port number */
-    ib_hca_transport_t  ib_trans;         /* Values specific transport API */
-    /* Memory Subsystem Support */
-    DAPL_HASH_TABLE    *lmr_hash_table;
-    /* Limits & useful HCA attributes */
-    DAT_IA_ATTR                ia_attr;
-};
-
-/* DAPL Objects always have the following header */
-struct dapl_header
-{
-    DAT_PROVIDER       *provider;      /* required by DAT - must be first */
-    DAPL_MAGIC         magic;          /* magic number for verification */
-    DAT_HANDLE_TYPE    handle_type;    /* struct type */
-    DAPL_IA            *owner_ia;      /* ia which owns this stuct */
-    DAPL_LLIST_ENTRY   ia_list_entry;  /* link entry on ia struct */
-    DAT_CONTEXT                user_context;   /* user context - opaque to DAPL */
-    DAPL_OS_LOCK       lock;           /* lock - in header for easier macros */
-};
-
-/* DAPL_IA maps to DAT_IA_HANDLE */
-struct dapl_ia
-{
-    DAPL_HEADER                header;
-    DAPL_HCA           *hca_ptr;
-    DAPL_EVD           *async_error_evd;
-    DAT_BOOLEAN                cleanup_async_error_evd;
-
-    DAPL_LLIST_ENTRY   hca_ia_list_entry;      /* HCAs list of IAs */
-    DAPL_LLIST_HEAD    ep_list_head;           /* EP queue */
-    DAPL_LLIST_HEAD    lmr_list_head;          /* LMR queue */
-    DAPL_LLIST_HEAD    rmr_list_head;          /* RMR queue */
-    DAPL_LLIST_HEAD    pz_list_head;           /* PZ queue */
-    DAPL_LLIST_HEAD    evd_list_head;          /* EVD queue */
-    DAPL_LLIST_HEAD    cno_list_head;          /* CNO queue */
-    DAPL_LLIST_HEAD    psp_list_head;          /* PSP queue */
-    DAPL_LLIST_HEAD    rsp_list_head;          /* RSP queue */
-    DAPL_LLIST_HEAD    srq_list_head;          /* SRQ queue */
-#ifdef DAPL_COUNTERS
-    void               *cntrs;
-#endif
-};
-
-/* DAPL_CNO maps to DAT_CNO_HANDLE */
-struct dapl_cno
-{
-    DAPL_HEADER        header;
-
-    /* A CNO cannot be freed while it is referenced elsewhere.  */
-    DAPL_ATOMIC                        cno_ref_count;
-    DAPL_CNO_STATE             cno_state;
-
-    DAT_COUNT                  cno_waiters;
-    DAPL_EVD                   *cno_evd_triggered;
-#if defined(__KERNEL__)
-    DAT_UPCALL_OBJECT          cno_upcall;
-    DAT_UPCALL_POLICY          cno_upcall_policy;
-#else
-    DAT_OS_WAIT_PROXY_AGENT    cno_wait_agent;
-#endif /* defined(__KERNEL__) */
-
-    DAPL_OS_WAIT_OBJECT                cno_wait_object;
-};
-
-/* DAPL_EVD maps to DAT_EVD_HANDLE */
-struct dapl_evd
-{
-    DAPL_HEADER                header;
-
-    DAPL_EVD_STATE     evd_state;
-    DAT_EVD_FLAGS      evd_flags;
-    DAT_BOOLEAN                evd_enabled; /* For attached CNO.  */
-    DAT_BOOLEAN                evd_waitable; /* EVD state.  */
-
-    /* Derived from evd_flags; see dapls_evd_internal_create.  */
-    DAT_BOOLEAN                evd_producer_locking_needed;
-
-    /* Every EVD has a CQ unless it is a SOFTWARE_EVENT only EVD */
-    ib_cq_handle_t     ib_cq_handle;
-
-    /* Mellanox Specific completion handle for registration/de-registration */
-    ib_comp_handle_t    ib_comp_handle;
-
-    /* An Event Dispatcher cannot be freed while
-     * it is referenced elsewhere.
-     */
-    DAPL_ATOMIC                evd_ref_count;
-
-    /* Set if there has been a catastrophic overflow */
-    DAT_BOOLEAN                catastrophic_overflow;
-
-    /* the actual events */
-    DAT_COUNT          qlen;
-    DAT_EVENT          *events;
-    DAPL_RING_BUFFER   free_event_queue;
-    DAPL_RING_BUFFER   pending_event_queue;
-
-    /* CQ Completions are not placed into 'deferred_events'
-     ** rather they are simply left on the Completion Queue
-     ** and the fact that there was a notification is flagged.
-     */
-    DAT_BOOLEAN                cq_notified;
-    DAPL_OS_TICKS      cq_notified_when;
-
-    DAT_COUNT          cno_active_count;
-    DAPL_CNO           *cno_ptr;
-
-    DAPL_OS_WAIT_OBJECT wait_object;
-
-#ifdef CQ_WAIT_OBJECT
-    /* Some providers support a direct CQ wait object */
-    ib_wait_obj_handle_t       cq_wait_obj_handle;
-#endif
-
-    DAT_COUNT          threshold;
-    DAPL_EVD_COMPLETION        completion_type;
-
-#ifdef DAPL_COUNTERS
-    void               *cntrs;
-#endif
-};
-
-/* DAPL_PRIVATE used to pass private data in a connection */
-struct dapl_private
-{
-#ifdef IBHOSTS_NAMING
-    DAT_SOCK_ADDR6             hca_address;    /* local address of HCA*/
-#endif /* IBHOSTS_NAMING */
-    unsigned char              private_data[DAPL_MAX_PRIVATE_DATA_SIZE];
-};
-
-/* uDAPL timer entry, used to queue timeouts */
-struct dapl_timer_entry
-{
-    DAPL_LLIST_ENTRY           list_entry;     /* link entry on ia struct */
-    DAPL_OS_TIMEVAL            expires;
-    void                       (*function) (uintptr_t);
-    void                       *data;
-};
-
-#ifdef DAPL_DBG_IO_TRC
-
-#define DBG_IO_TRC_QLEN   32           /* length of trace buffer        */
-#define DBG_IO_TRC_IOV 3               /* iov elements we keep track of */
-
-struct io_buf_track
-{
-    Ib_send_op_type            op_type;
-    DAPL_COOKIE                        *cookie;
-    DAT_LMR_TRIPLET            iov[DBG_IO_TRC_IOV];
-    DAT_RMR_TRIPLET            remote_iov;
-    unsigned int               done;   /* count to track completion ordering */
-    int                                status;
-    void                       *wqe;
-};
-
-#endif /* DAPL_DBG_IO_TRC */
-
-/* DAPL_EP maps to DAT_EP_HANDLE */
-struct dapl_ep
-{
-    DAPL_HEADER                        header;
-    /* What the DAT Consumer asked for */
-    DAT_EP_PARAM               param;
-
-    /* The RC Queue Pair (IBM OS API) */
-    ib_qp_handle_t             qp_handle;
-    unsigned int               qpn;    /* qp number */
-    ib_qp_state_t              qp_state;
-
-    /* communications manager handle (IBM OS API) */
-    dp_ib_cm_handle_t          cm_handle;
-
-    /* store the remote IA address here, reference from the param
-     * struct which only has a pointer, no storage
-     */
-    DAT_SOCK_ADDR6             remote_ia_address;
-
-    /* For passive connections we maintain a back pointer to the CR */
-    void *                     cr_ptr;
-
-    /* pointer to connection timer, if set */
-    struct dapl_timer_entry    *cxn_timer;
-
-    /* private data container */
-    DAPL_PRIVATE               private;
-
-    /* DTO data */
-    DAPL_ATOMIC                        req_count;
-    DAPL_ATOMIC                        recv_count;
-
-    DAPL_COOKIE_BUFFER req_buffer;
-    DAPL_COOKIE_BUFFER recv_buffer;
-
-#ifdef DAPL_DBG_IO_TRC
-    int                        ibt_dumped;
-    struct io_buf_track *ibt_base;
-    DAPL_RING_BUFFER   ibt_queue;
-#endif /* DAPL_DBG_IO_TRC */
-#if defined(_WIN32) || defined(_WIN64)
-    DAT_BOOLEAN         recv_discreq;
-    DAT_BOOLEAN         sent_discreq;
-    dp_ib_cm_handle_t   ibal_cm_handle;
-#endif
-#ifdef DAPL_COUNTERS
-    void               *cntrs;
-#endif
-};
-
-/* DAPL_SRQ maps to DAT_SRQ_HANDLE */
-struct dapl_srq
-{
-    DAPL_HEADER                header;
-    DAT_SRQ_PARAM      param;
-    DAPL_ATOMIC                srq_ref_count;
-    DAPL_COOKIE_BUFFER recv_buffer;
-    DAPL_ATOMIC                recv_count;
-};
-
-/* DAPL_PZ maps to DAT_PZ_HANDLE */
-struct dapl_pz
-{
-    DAPL_HEADER                header;
-    ib_pd_handle_t     pd_handle;
-    DAPL_ATOMIC                pz_ref_count;
-};
-
-/* DAPL_LMR maps to DAT_LMR_HANDLE */
-struct dapl_lmr
-{
-    DAPL_HEADER                header;
-    DAT_LMR_PARAM      param;
-    ib_mr_handle_t     mr_handle;
-    DAPL_ATOMIC                lmr_ref_count;
-#if !defined(__KDAPL__)
-    char               shmid[DAT_LMR_COOKIE_SIZE]; /* shared memory ID */
-    ib_shm_transport_t ib_trans;       /* provider specific data */
-#endif /* !__KDAPL__ */
-};
-
-/* DAPL_RMR maps to DAT_RMR_HANDLE */
-struct dapl_rmr
-{
-    DAPL_HEADER                header;
-    DAT_RMR_PARAM      param;
-    DAPL_EP             *ep;
-    DAPL_PZ             *pz;
-    DAPL_LMR            *lmr;
-    ib_mw_handle_t     mw_handle;
-};
-
-/* SP types, indicating the state and queue */
-typedef enum dapl_sp_state
-{
-    DAPL_SP_STATE_FREE,
-    DAPL_SP_STATE_PSP_LISTENING,
-    DAPL_SP_STATE_PSP_PENDING,
-    DAPL_SP_STATE_RSP_LISTENING,
-    DAPL_SP_STATE_RSP_PENDING
-} DAPL_SP_STATE;
-
-/* DAPL_SP maps to DAT_PSP_HANDLE and DAT_RSP_HANDLE */
-struct dapl_sp
-{
-    DAPL_HEADER                header;
-    DAPL_SP_STATE      state;          /* type and queue of the SP */
-
-    /* PSP/RSP PARAM fields */
-    DAT_CONN_QUAL       conn_qual;
-    DAT_EVD_HANDLE      evd_handle;
-    DAT_PSP_FLAGS       psp_flags;
-    DAT_EP_HANDLE       ep_handle;
-
-     /* maintenence fields */
-    DAT_BOOLEAN                listening;      /* PSP is registered & active */
-    ib_cm_srvc_handle_t        cm_srvc_handle; /* Used by Mellanox CM */
-    DAPL_LLIST_HEAD    cr_list_head;   /* CR pending queue */
-    DAT_COUNT          cr_list_count;  /* count of CRs on queue */
-#if defined(_VENDOR_IBAL_)
-    DAPL_OS_WAIT_OBJECT wait_object;    /* cancel & destroy. */
-#endif
-};
-
-/* DAPL_CR maps to DAT_CR_HANDLE */
-struct dapl_cr
-{
-    DAPL_HEADER                header;
-
-    /* for convenience the data is kept as a DAT_CR_PARAM.
-     * however, the "local_endpoint" field is always NULL
-     * so this wastes a pointer. This is probably ok to
-     * simplify code, espedially dat_cr_query.
-     */
-    DAT_CR_PARAM       param;
-    /* IB specific fields */
-    dp_ib_cm_handle_t  ib_cm_handle;
-
-    DAT_SOCK_ADDR6     remote_ia_address;
-    /* Assuming that the maximum private data size is small.
-     * If it gets large, use of a pointer may be appropriate.
-     */
-    unsigned char      private_data[DAPL_MAX_PRIVATE_DATA_SIZE];
-    /*
-     * Need to be able to associate the CR back to the PSP for
-     * dapl_cr_reject.
-     */
-    DAPL_SP            *sp_ptr;
-};
-
-typedef enum dapl_dto_type
-{
-    DAPL_DTO_TYPE_SEND,
-    DAPL_DTO_TYPE_RECV,
-    DAPL_DTO_TYPE_RDMA_WRITE,
-    DAPL_DTO_TYPE_RDMA_READ,
-#ifdef DAT_EXTENSIONS
-    DAPL_DTO_TYPE_EXTENSION,
-#endif
-} DAPL_DTO_TYPE;
-
-typedef enum dapl_cookie_type
-{
-    DAPL_COOKIE_TYPE_NULL,
-    DAPL_COOKIE_TYPE_DTO,
-    DAPL_COOKIE_TYPE_RMR,
-} DAPL_COOKIE_TYPE;
-
-/* DAPL_DTO_COOKIE used as context for DTO WQEs */
-struct dapl_dto_cookie
-{
-    DAPL_DTO_TYPE              type;
-    DAT_DTO_COOKIE             cookie;
-    DAT_COUNT                  size;   /* used for SEND and RDMA write */
-};
-
-/* DAPL_RMR_COOKIE used as context for bind WQEs */
-struct dapl_rmr_cookie
-{
-    DAPL_RMR                   *rmr;
-    DAT_RMR_COOKIE              cookie;
-};
-
-/* DAPL_COOKIE used as context for WQEs */
-struct dapl_cookie
-{
-    DAPL_COOKIE_TYPE           type; /* Must be first, to define struct.  */
-    DAPL_EP                    *ep;
-    DAT_COUNT                  index;
-    union
-    {
-       DAPL_DTO_COOKIE         dto;
-       DAPL_RMR_COOKIE         rmr;
-    } val;
-};
-
-/*
- * Private Data operations. Used to obtain the size of the private
- * data from the provider layer.
- */
-typedef enum dapl_private_data_op
-{
-    DAPL_PDATA_CONN_REQ  = 0,          /* connect request    */
-    DAPL_PDATA_CONN_REP  = 1,          /* connect reply      */
-    DAPL_PDATA_CONN_REJ  = 2,          /* connect reject     */
-    DAPL_PDATA_CONN_DREQ = 3,          /* disconnect request */
-    DAPL_PDATA_CONN_DREP = 4,          /* disconnect reply   */
-} DAPL_PDATA_OP;
-
-
-/*
- * Generic HCA name field
- */
-#define DAPL_HCA_NAME_MAX_LEN 260
-typedef char DAPL_HCA_NAME[DAPL_HCA_NAME_MAX_LEN+1];
-
-#ifdef IBHOSTS_NAMING
-
-/*
- * Simple mapping table to match IP addresses to GIDs. Loaded
- * by dapl_init.
- */
-typedef struct _dapl_gid_map_table
-{
-    uint32_t           ip_address;
-    ib_gid_t           gid;
-} DAPL_GID_MAP;
-
-#endif /* IBHOSTS_NAMING */
-
-/*
- * IBTA defined reason for reject message: See IBTA 1.1 specification,
- * 12.6.7.2 REJECTION REASON section.
- */
-#define IB_CM_REJ_REASON_CONSUMER_REJ            0x001C
-
-
-#if defined(DAPL_DBG_IO_TRC)
-/*********************************************************************
- *                                                                   *
- * Debug I/O tracing support prototypes                              *
- *                                                                   *
- *********************************************************************/
-/*
- * I/O tracing support
- */
-void dapls_io_trc_alloc (
-    DAPL_EP                    *ep_ptr);
-
-void dapls_io_trc_update_completion (
-    DAPL_EP                    *ep_ptr,
-    DAPL_COOKIE                        *cookie,
-    ib_uint32_t                        ib_status );
-
-void dapls_io_trc_dump (
-    DAPL_EP                    *ep_ptr,
-    ib_work_completion_t       *cqe_ptr,
-    ib_uint32_t                        ib_status);
-
-#else /* DAPL_DBG_IO_TRC */
-
-#define dapls_io_trc_alloc(a)
-#define dapls_io_trc_update_completion(a, b, c)
-#define dapls_io_trc_dump(a, b, c)
-
-#endif /* DAPL_DBG_IO_TRC */
-
-
-/*********************************************************************
- *                                                                   *
- * Function Prototypes                                               *
- *                                                                   *
- *********************************************************************/
-
-typedef void (*DAPL_CONNECTION_STATE_HANDLER) (
-       IN      DAPL_EP *,
-       IN      ib_cm_events_t,
-       IN      const void *,
-       OUT     DAT_EVENT *);
-
-/*
- * DAT Mandated functions
- */
-
-extern DAT_RETURN DAT_API dapl_ia_open (
-       IN      const DAT_NAME_PTR,     /* name */
-       IN      DAT_COUNT,              /* asynch_evd_qlen */
-       INOUT   DAT_EVD_HANDLE *,       /* asynch_evd_handle */
-       OUT     DAT_IA_HANDLE *);       /* ia_handle */
-
-extern DAT_RETURN DAT_API dapl_ia_close (
-       IN      DAT_IA_HANDLE,          /* ia_handle */
-       IN      DAT_CLOSE_FLAGS );      /* ia_flags */
-
-
-extern DAT_RETURN DAT_API dapl_ia_query (
-       IN      DAT_IA_HANDLE,          /* ia handle */
-       OUT     DAT_EVD_HANDLE *,       /* async_evd_handle */
-       IN      DAT_IA_ATTR_MASK,       /* ia_params_mask */
-       OUT     DAT_IA_ATTR *,          /* ia_params */
-       IN      DAT_PROVIDER_ATTR_MASK, /* provider_params_mask */
-       OUT     DAT_PROVIDER_ATTR * );  /* provider_params */
-
-
-/* helper functions */
-
-extern DAT_RETURN DAT_API dapl_set_consumer_context (
-       IN      DAT_HANDLE,                     /* dat handle */
-       IN      DAT_CONTEXT);                   /* context */
-
-extern DAT_RETURN DAT_API dapl_get_consumer_context (
-       IN      DAT_HANDLE,                     /* dat handle */
-       OUT     DAT_CONTEXT * );                /* context */
-
-extern DAT_RETURN DAT_API dapl_get_handle_type (
-       IN      DAT_HANDLE,
-       OUT     DAT_HANDLE_TYPE * );
-
-/* CNO functions */
-
-#if !defined(__KERNEL__)
-extern DAT_RETURN DAT_API dapl_cno_create (
-       IN      DAT_IA_HANDLE,                  /* ia_handle */
-       IN      DAT_OS_WAIT_PROXY_AGENT,        /* agent */
-       OUT     DAT_CNO_HANDLE *);              /* cno_handle */
-
-extern DAT_RETURN DAT_API dapl_cno_modify_agent (
-       IN      DAT_CNO_HANDLE,                 /* cno_handle */
-       IN      DAT_OS_WAIT_PROXY_AGENT);       /* agent */
-
-extern DAT_RETURN DAT_API dapl_cno_query (
-       IN      DAT_CNO_HANDLE,         /* cno_handle */
-       IN      DAT_CNO_PARAM_MASK,     /* cno_param_mask */
-       OUT     DAT_CNO_PARAM * );      /* cno_param */
-
-extern DAT_RETURN DAT_API dapl_cno_free (
-       IN      DAT_CNO_HANDLE);        /* cno_handle */
-
-extern DAT_RETURN DAT_API dapl_cno_wait (
-       IN      DAT_CNO_HANDLE,         /* cno_handle */
-       IN      DAT_TIMEOUT,            /* timeout */
-       OUT     DAT_EVD_HANDLE *);      /* evd_handle */
-
-extern DAT_RETURN DAT_API dapl_cno_fd_create (
-       IN      DAT_IA_HANDLE,          /* ia_handle            */
-       OUT     DAT_FD *,               /* file_descriptor      */
-       OUT     DAT_CNO_HANDLE *);      /* cno_handle           */
-
-extern DAT_RETURN DAT_API dapl_cno_trigger (
-       IN      DAT_CNO_HANDLE,         /* cno_handle */
-       OUT     DAT_EVD_HANDLE *);      /* evd_handle */
-
-#endif /* !defined(__KERNEL__) */
-
-/* CR Functions */
-
-extern DAT_RETURN DAT_API dapl_cr_query (
-       IN      DAT_CR_HANDLE,          /* cr_handle */
-       IN      DAT_CR_PARAM_MASK,      /* cr_args_mask */
-       OUT     DAT_CR_PARAM * );       /* cwr_args */
-
-extern DAT_RETURN DAT_API dapl_cr_accept (
-       IN      DAT_CR_HANDLE,          /* cr_handle */
-       IN      DAT_EP_HANDLE,          /* ep_handle */
-       IN      DAT_COUNT,              /* private_data_size */
-       IN      const DAT_PVOID );      /* private_data */
-
-extern DAT_RETURN DAT_API dapl_cr_reject (
-       IN      DAT_CR_HANDLE,          /* cr_handle            */
-       IN      DAT_COUNT,              /* private_data_size    */
-       IN      const DAT_PVOID );      /* private_data         */
-
-extern DAT_RETURN DAT_API dapl_cr_handoff (
-       IN DAT_CR_HANDLE,               /* cr_handle */
-       IN DAT_CONN_QUAL);              /* handoff */
-
-/* EVD Functions */
-
-#if defined(__KERNEL__)
-extern DAT_RETURN DAT_API dapl_ia_memtype_hint (
-       IN    DAT_IA_HANDLE,            /* ia_handle */
-       IN    DAT_MEM_TYPE,             /* mem_type */
-       IN    DAT_VLEN,                 /* length */
-       IN    DAT_MEM_OPT,              /* mem_optimization */
-       OUT   DAT_VLEN *,               /* suggested_length */
-       OUT   DAT_VADDR *);             /* suggested_alignment */
-
-extern DAT_RETURN DAT_API dapl_evd_kcreate (
-       IN      DAT_IA_HANDLE,          /* ia_handle */
-       IN      DAT_COUNT,              /* evd_min_qlen */
-       IN      DAT_UPCALL_POLICY,      /* upcall_policy */
-       IN      const DAT_UPCALL_OBJECT *, /* upcall */
-       IN      DAT_EVD_FLAGS,          /* evd_flags */
-       OUT     DAT_EVD_HANDLE * );     /* evd_handle */
-
-extern DAT_RETURN DAT_API dapl_evd_kquery (
-       IN      DAT_EVD_HANDLE,         /* evd_handle */
-       IN      DAT_EVD_PARAM_MASK,     /* evd_args_mask */
-       OUT     DAT_EVD_PARAM * );      /* evd_args */
-
-#else
-extern DAT_RETURN DAT_API dapl_evd_create (
-       IN      DAT_IA_HANDLE,          /* ia_handle */
-       IN      DAT_COUNT,              /* evd_min_qlen */
-       IN      DAT_CNO_HANDLE,         /* cno_handle */
-       IN      DAT_EVD_FLAGS,          /* evd_flags */
-       OUT     DAT_EVD_HANDLE * );     /* evd_handle */
-
-extern DAT_RETURN DAT_API dapl_evd_query (
-       IN      DAT_EVD_HANDLE,         /* evd_handle */
-       IN      DAT_EVD_PARAM_MASK,     /* evd_args_mask */
-       OUT     DAT_EVD_PARAM * );      /* evd_args */
-#endif /* defined(__KERNEL__) */
-
-#if defined(__KERNEL__)
-extern DAT_RETURN DAT_API dapl_evd_modify_upcall (
-       IN      DAT_EVD_HANDLE,         /* evd_handle */
-       IN      DAT_UPCALL_POLICY,      /* upcall_policy */
-       IN      const DAT_UPCALL_OBJECT * ); /* upcall */
-
-#else
-
-extern DAT_RETURN DAT_API dapl_evd_modify_cno (
-       IN      DAT_EVD_HANDLE,         /* evd_handle */
-       IN      DAT_CNO_HANDLE);        /* cno_handle */
-#endif
-
-extern DAT_RETURN DAT_API dapl_evd_enable (
-       IN      DAT_EVD_HANDLE);        /* evd_handle */
-
-extern DAT_RETURN DAT_API dapl_evd_disable (
-       IN      DAT_EVD_HANDLE);        /* evd_handle */
-
-#if !defined(__KERNEL__)
-extern DAT_RETURN DAT_API dapl_evd_wait (
-       IN      DAT_EVD_HANDLE,         /* evd_handle */
-       IN      DAT_TIMEOUT,            /* timeout */
-       IN      DAT_COUNT,              /* threshold */
-       OUT     DAT_EVENT *,            /* event */
-       OUT     DAT_COUNT *);           /* nmore */
-#endif /* !defined(__KERNEL__) */
-
-extern DAT_RETURN DAT_API dapl_evd_resize (
-       IN      DAT_EVD_HANDLE,         /* evd_handle */
-       IN      DAT_COUNT );            /* evd_qlen */
-
-extern DAT_RETURN DAT_API dapl_evd_post_se (
-       DAT_EVD_HANDLE,                 /* evd_handle */
-       const DAT_EVENT * );            /* event */
-
-extern DAT_RETURN DAT_API dapl_evd_dequeue (
-       IN      DAT_EVD_HANDLE,         /* evd_handle */
-       OUT     DAT_EVENT * );          /* event */
-
-extern DAT_RETURN DAT_API dapl_evd_free (
-       IN      DAT_EVD_HANDLE );
-
-extern DAT_RETURN DAT_API
-dapl_evd_set_unwaitable (
-       IN      DAT_EVD_HANDLE  evd_handle );
-
-extern DAT_RETURN DAT_API
-dapl_evd_clear_unwaitable (
-       IN      DAT_EVD_HANDLE  evd_handle );
-
-/* EP functions */
-
-extern DAT_RETURN DAT_API dapl_ep_create (
-       IN      DAT_IA_HANDLE,          /* ia_handle */
-       IN      DAT_PZ_HANDLE,          /* pz_handle */
-       IN      DAT_EVD_HANDLE,         /* in_dto_completion_evd_handle */
-       IN      DAT_EVD_HANDLE,         /* out_dto_completion_evd_handle */
-       IN      DAT_EVD_HANDLE,         /* connect_evd_handle */
-       IN      const DAT_EP_ATTR *,    /* ep_parameters */
-       OUT     DAT_EP_HANDLE * );      /* ep_handle */
-
-extern DAT_RETURN DAT_API dapl_ep_query (
-       IN      DAT_EP_HANDLE,          /* ep_handle */
-       IN      DAT_EP_PARAM_MASK,      /* ep_args_mask */
-       OUT     DAT_EP_PARAM * );       /* ep_args */
-
-extern DAT_RETURN DAT_API dapl_ep_modify (
-       IN      DAT_EP_HANDLE,          /* ep_handle */
-       IN      DAT_EP_PARAM_MASK,      /* ep_args_mask */
-       IN      const DAT_EP_PARAM * ); /* ep_args */
-
-extern DAT_RETURN DAT_API dapl_ep_connect (
-       IN      DAT_EP_HANDLE,          /* ep_handle */
-       IN      DAT_IA_ADDRESS_PTR,     /* remote_ia_address */
-       IN      DAT_CONN_QUAL,          /* remote_conn_qual */
-       IN      DAT_TIMEOUT,            /* timeout */
-       IN      DAT_COUNT,              /* private_data_size */
-       IN      const DAT_PVOID,        /* private_data  */
-       IN      DAT_QOS,                /* quality_of_service */
-       IN      DAT_CONNECT_FLAGS );    /* connect_flags */
-
-extern DAT_RETURN DAT_API dapl_ep_common_connect (
-       IN      DAT_EP_HANDLE ep,               /* ep_handle            */
-       IN      DAT_IA_ADDRESS_PTR remote_addr, /* remote_ia_address    */
-       IN      DAT_TIMEOUT timeout,            /* timeout              */
-       IN      DAT_COUNT pdata_size,           /* private_data_size    */
-       IN      const DAT_PVOID pdata   );      /* private_data         */
-
-extern DAT_RETURN DAT_API dapl_ep_dup_connect (
-       IN      DAT_EP_HANDLE,          /* ep_handle */
-       IN      DAT_EP_HANDLE,          /* ep_dup_handle */
-       IN      DAT_TIMEOUT,            /* timeout*/
-       IN      DAT_COUNT,              /* private_data_size */
-       IN      const DAT_PVOID,        /* private_data */
-       IN      DAT_QOS);               /* quality_of_service */
-
-extern DAT_RETURN DAT_API dapl_ep_disconnect (
-       IN      DAT_EP_HANDLE,          /* ep_handle */
-       IN      DAT_CLOSE_FLAGS );      /* close_flags */
-
-extern DAT_RETURN DAT_API dapl_ep_post_send (
-       IN      DAT_EP_HANDLE,          /* ep_handle */
-       IN      DAT_COUNT,              /* num_segments */
-       IN      DAT_LMR_TRIPLET *,      /* local_iov */
-       IN      DAT_DTO_COOKIE,         /* user_cookie */
-       IN      DAT_COMPLETION_FLAGS ); /* completion_flags */
-
-extern DAT_RETURN DAT_API dapl_ep_post_recv (
-       IN      DAT_EP_HANDLE,          /* ep_handle */
-       IN      DAT_COUNT,              /* num_segments */
-       IN      DAT_LMR_TRIPLET *,      /* local_iov */
-       IN      DAT_DTO_COOKIE,         /* user_cookie */
-       IN      DAT_COMPLETION_FLAGS ); /* completion_flags */
-
-extern DAT_RETURN DAT_API dapl_ep_post_rdma_read (
-       IN      DAT_EP_HANDLE,           /* ep_handle */
-       IN      DAT_COUNT,               /* num_segments */
-       IN      DAT_LMR_TRIPLET *,       /* local_iov */
-       IN      DAT_DTO_COOKIE,          /* user_cookie */
-       IN      const DAT_RMR_TRIPLET *, /* remote_iov */
-       IN      DAT_COMPLETION_FLAGS );  /* completion_flags */
-
-extern DAT_RETURN DAT_API dapl_ep_post_rdma_read_to_rmr (
-       IN      DAT_EP_HANDLE,          /* ep_handle            */
-       IN      const DAT_RMR_TRIPLET *,/* local_iov            */
-       IN      DAT_DTO_COOKIE,         /* user_cookie          */
-       IN      const DAT_RMR_TRIPLET *,/* remote_iov           */
-       IN      DAT_COMPLETION_FLAGS);  /* completion_flags     */
-
-extern DAT_RETURN DAT_API dapl_ep_post_rdma_write (
-       IN      DAT_EP_HANDLE,           /* ep_handle */
-       IN      DAT_COUNT,               /* num_segments */
-       IN      DAT_LMR_TRIPLET *,       /* local_iov */
-       IN      DAT_DTO_COOKIE,          /* user_cookie */
-       IN      const DAT_RMR_TRIPLET *, /* remote_iov */
-       IN      DAT_COMPLETION_FLAGS );  /* completion_flags */
-
-extern DAT_RETURN DAT_API dapl_ep_post_send_with_invalidate (
-       IN      DAT_EP_HANDLE,          /* ep_handle            */
-       IN      DAT_COUNT,              /* num_segments         */
-       IN      DAT_LMR_TRIPLET *,      /* local_iov            */
-       IN      DAT_DTO_COOKIE,         /* user_cookie          */
-       IN      DAT_COMPLETION_FLAGS,   /* completion_flags     */
-       IN      DAT_BOOLEAN,            /* invalidate_flag      */
-       IN      DAT_RMR_CONTEXT);      /* RMR context          */
-
-extern DAT_RETURN DAT_API dapl_ep_get_status (
-       IN      DAT_EP_HANDLE,          /* ep_handle */
-       OUT     DAT_EP_STATE *,         /* ep_state */
-       OUT     DAT_BOOLEAN *,          /* in_dto_idle */
-       OUT     DAT_BOOLEAN * );        /* out_dto_idle */
-
-extern DAT_RETURN DAT_API dapl_ep_free (
-       IN      DAT_EP_HANDLE);         /* ep_handle */
-
-extern DAT_RETURN DAT_API dapl_ep_reset (
-       IN      DAT_EP_HANDLE);         /* ep_handle */
-
-extern DAT_RETURN DAT_API dapl_ep_create_with_srq (
-        IN      DAT_IA_HANDLE,          /* ia_handle            */
-        IN      DAT_PZ_HANDLE,          /* pz_handle            */
-        IN      DAT_EVD_HANDLE,         /* recv_evd_handle      */
-        IN      DAT_EVD_HANDLE,         /* request_evd_handle   */
-        IN      DAT_EVD_HANDLE,         /* connect_evd_handle   */
-        IN      DAT_SRQ_HANDLE,         /* srq_handle           */
-        IN      const DAT_EP_ATTR *,    /* ep_attributes        */
-        OUT     DAT_EP_HANDLE *);       /* ep_handle            */
-
-extern DAT_RETURN DAT_API dapl_ep_recv_query (
-        IN      DAT_EP_HANDLE,          /* ep_handle            */
-        OUT     DAT_COUNT *,            /* nbufs_allocated      */
-        OUT     DAT_COUNT *);           /* bufs_alloc_span      */
-
-extern DAT_RETURN DAT_API dapl_ep_set_watermark (
-        IN      DAT_EP_HANDLE,          /* ep_handle            */
-        IN      DAT_COUNT,              /* soft_high_watermark  */
-        IN      DAT_COUNT);             /* hard_high_watermark  */
-
-/* LMR functions */
-
-#if defined(__KERNEL__)
-extern DAT_RETURN DAT_API dapl_lmr_kcreate (
-       IN      DAT_IA_HANDLE,          /* ia_handle */
-       IN      DAT_MEM_TYPE,           /* mem_type */
-       IN      DAT_REGION_DESCRIPTION, /* region_description */
-       IN      DAT_VLEN,               /* length */
-       IN      DAT_PZ_HANDLE,          /* pz_handle */
-       IN      DAT_MEM_PRIV_FLAGS,     /* privileges */
-       IN      DAT_VA_TYPE,            /* va_type */
-       IN      DAT_MEM_OPT,            /* optimization */
-       OUT     DAT_LMR_HANDLE *,       /* lmr_handle */
-       OUT     DAT_LMR_CONTEXT *,      /* lmr_context */
-       OUT     DAT_RMR_CONTEXT *,      /* rmr_context          */
-       OUT     DAT_VLEN *,             /* registered_length */
-       OUT     DAT_VADDR * );          /* registered_address */
-#else
-extern DAT_RETURN DAT_API dapl_lmr_create (
-       IN      DAT_IA_HANDLE,          /* ia_handle */
-       IN      DAT_MEM_TYPE,           /* mem_type */
-       IN      DAT_REGION_DESCRIPTION, /* region_description */
-       IN      DAT_VLEN,               /* length */
-       IN      DAT_PZ_HANDLE,          /* pz_handle */
-       IN      DAT_MEM_PRIV_FLAGS,     /* privileges */
-       IN      DAT_VA_TYPE,            /* va_type */
-       OUT     DAT_LMR_HANDLE *,       /* lmr_handle */
-       OUT     DAT_LMR_CONTEXT *,      /* lmr_context */
-       OUT     DAT_RMR_CONTEXT *,      /* rmr_context          */
-       OUT     DAT_VLEN *,             /* registered_length */
-       OUT     DAT_VADDR * );          /* registered_address */
-#endif /* defined(__KERNEL__) */
-
-extern DAT_RETURN DAT_API dapl_lmr_query (
-       IN      DAT_LMR_HANDLE,
-       IN      DAT_LMR_PARAM_MASK,
-       OUT     DAT_LMR_PARAM *);
-
-extern DAT_RETURN DAT_API dapl_lmr_free (
-       IN      DAT_LMR_HANDLE);
-
-extern DAT_RETURN DAT_API dapl_lmr_sync_rdma_read (
-       IN      DAT_IA_HANDLE,          /* ia_handle            */
-       IN      const DAT_LMR_TRIPLET *, /* local_segments      */
-       IN      DAT_VLEN);              /* num_segments         */
-
-extern DAT_RETURN DAT_API dapl_lmr_sync_rdma_write (
-       IN      DAT_IA_HANDLE,          /* ia_handle            */
-       IN      const DAT_LMR_TRIPLET *, /* local_segments      */
-       IN      DAT_VLEN);              /* num_segments         */
-
-/* RMR Functions */
-
-extern DAT_RETURN DAT_API dapl_rmr_create (
-       IN      DAT_PZ_HANDLE,          /* pz_handle */
-       OUT     DAT_RMR_HANDLE *);      /* rmr_handle */
-
-extern DAT_RETURN DAT_API dapl_rmr_create_for_ep (
-       IN      DAT_PZ_HANDLE pz_handle,        /* pz_handle    */
-       OUT     DAT_RMR_HANDLE *rmr_handle);    /* rmr_handle   */
-
-extern DAT_RETURN DAT_API dapl_rmr_query (
-       IN      DAT_RMR_HANDLE,         /* rmr_handle */
-       IN      DAT_RMR_PARAM_MASK,     /* rmr_args_mask */
-       OUT     DAT_RMR_PARAM *);       /* rmr_args */
-
-extern DAT_RETURN DAT_API dapl_rmr_bind (
-       IN      DAT_RMR_HANDLE,          /* rmr_handle */
-       IN      DAT_LMR_HANDLE,          /* lmr_handle */
-       IN      const DAT_LMR_TRIPLET *, /* lmr_triplet */
-       IN      DAT_MEM_PRIV_FLAGS,      /* mem_priv */
-       IN      DAT_VA_TYPE,             /* va_type */
-       IN      DAT_EP_HANDLE,           /* ep_handle */
-       IN      DAT_RMR_COOKIE,          /* user_cookie */
-       IN      DAT_COMPLETION_FLAGS,    /* completion_flags */
-       INOUT   DAT_RMR_CONTEXT * );     /* context */
-
-extern DAT_RETURN DAT_API dapl_rmr_free (
-       IN      DAT_RMR_HANDLE);
-
-/* PSP Functions */
-
-extern DAT_RETURN DAT_API dapl_psp_create (
-       IN      DAT_IA_HANDLE,          /* ia_handle */
-       IN      DAT_CONN_QUAL,          /* conn_qual */
-       IN      DAT_EVD_HANDLE,         /* evd_handle */
-       IN      DAT_PSP_FLAGS,          /* psp_flags */
-       OUT     DAT_PSP_HANDLE * );     /* psp_handle */
-
-extern DAT_RETURN DAT_API dapl_psp_create_any (
-       IN      DAT_IA_HANDLE,          /* ia_handle */
-       OUT     DAT_CONN_QUAL *,        /* conn_qual */
-       IN      DAT_EVD_HANDLE,         /* evd_handle */
-       IN      DAT_PSP_FLAGS,          /* psp_flags */
-       OUT     DAT_PSP_HANDLE *);      /* psp_handle */
-
-extern DAT_RETURN DAT_API dapl_psp_query (
-       IN      DAT_PSP_HANDLE,
-       IN      DAT_PSP_PARAM_MASK,
-       OUT     DAT_PSP_PARAM * );
-
-extern DAT_RETURN DAT_API dapl_psp_free (
-       IN      DAT_PSP_HANDLE );       /* psp_handle */
-
-/* RSP Functions */
-
-extern DAT_RETURN DAT_API dapl_rsp_create (
-       IN      DAT_IA_HANDLE,          /* ia_handle */
-       IN      DAT_CONN_QUAL,          /* conn_qual */
-       IN      DAT_EP_HANDLE,          /* ep_handle */
-       IN      DAT_EVD_HANDLE,         /* evd_handle */
-       OUT     DAT_RSP_HANDLE * );     /* rsp_handle */
-
-extern DAT_RETURN DAT_API dapl_rsp_query (
-       IN      DAT_RSP_HANDLE,
-       IN      DAT_RSP_PARAM_MASK,
-       OUT     DAT_RSP_PARAM * );
-
-extern DAT_RETURN DAT_API dapl_rsp_free (
-       IN      DAT_RSP_HANDLE );       /* rsp_handle */
-
-/* PZ Functions */
-
-extern DAT_RETURN DAT_API dapl_pz_create (
-       IN      DAT_IA_HANDLE,          /* ia_handle */
-       OUT     DAT_PZ_HANDLE * );      /* pz_handle */
-
-extern DAT_RETURN DAT_API dapl_pz_query (
-       IN      DAT_PZ_HANDLE,          /* pz_handle */
-       IN      DAT_PZ_PARAM_MASK,      /* pz_args_mask */
-       OUT     DAT_PZ_PARAM * );       /* pz_args */
-
-extern DAT_RETURN DAT_API dapl_pz_free (
-       IN      DAT_PZ_HANDLE );        /* pz_handle */
-
-/* SRQ functions */
-
-extern DAT_RETURN DAT_API dapl_srq_create (
-        IN      DAT_IA_HANDLE,          /* ia_handle            */
-        IN      DAT_PZ_HANDLE,          /* pz_handle            */
-        IN      DAT_SRQ_ATTR *,         /* srq_attr             */
-        OUT     DAT_SRQ_HANDLE *);      /* srq_handle           */
-
-extern DAT_RETURN DAT_API dapl_srq_free (
-       IN      DAT_SRQ_HANDLE);        /* srq_handle           */
-
-extern DAT_RETURN DAT_API dapl_srq_post_recv (
-       IN      DAT_SRQ_HANDLE,         /* srq_handle           */
-       IN      DAT_COUNT,              /* num_segments         */
-       IN      DAT_LMR_TRIPLET *,      /* local_iov            */
-       IN      DAT_DTO_COOKIE);        /* user_cookie          */
-
-extern DAT_RETURN DAT_API dapl_srq_query (
-       IN      DAT_SRQ_HANDLE,         /* srq_handle           */
-       IN      DAT_SRQ_PARAM_MASK,     /* srq_param_mask       */
-       OUT     DAT_SRQ_PARAM *);       /* srq_param            */
-
-extern DAT_RETURN DAT_API dapl_srq_resize (
-       IN      DAT_SRQ_HANDLE,         /* srq_handle           */
-       IN      DAT_COUNT);             /* srq_max_recv_dto     */
-
-extern DAT_RETURN DAT_API dapl_srq_set_lw (
-       IN      DAT_SRQ_HANDLE,         /* srq_handle           */
-       IN      DAT_COUNT);             /* low_watermark        */
-
-/* CSP functions */
-extern DAT_RETURN DAT_API dapl_csp_create (
-       IN      DAT_IA_HANDLE,          /* ia_handle      */
-       IN      DAT_COMM *,             /* communicator   */
-       IN      DAT_IA_ADDRESS_PTR,     /* address        */
-       IN      DAT_EVD_HANDLE,         /* evd_handle     */
-       OUT     DAT_CSP_HANDLE *);      /* csp_handle     */
-
-extern DAT_RETURN DAT_API dapl_csp_query (
-       IN      DAT_CSP_HANDLE,         /* csp_handle     */
-       IN      DAT_CSP_PARAM_MASK,     /* csp_param_mask */
-       OUT     DAT_CSP_PARAM *);       /* csp_param      */
-
-extern DAT_RETURN DAT_API dapl_csp_free (
-       IN      DAT_CSP_HANDLE);        /* csp_handle     */
-
-/* HA functions */
-DAT_RETURN DAT_API dapl_ia_ha (
-       IN       DAT_IA_HANDLE,         /* ia_handle */
-       IN const DAT_NAME_PTR,          /* provider  */
-       OUT      DAT_BOOLEAN *);        /* answer    */
-
-#ifdef DAT_EXTENSIONS
-#include <stdarg.h>
-extern DAT_RETURN DAT_API dapl_extensions (
-       IN      DAT_HANDLE,             /* handle */
-       IN      DAT_EXTENDED_OP,        /* extended op */
-       IN      va_list);               /* argument list */
-#endif
-
-/*
- * DAPL internal utility function prototpyes
- */
-
-extern void dapl_llist_init_head (
-    DAPL_LLIST_HEAD *  head);
-
-extern void dapl_llist_init_entry (
-    DAPL_LLIST_ENTRY *         entry);
-
-extern DAT_BOOLEAN dapl_llist_is_empty (
-    DAPL_LLIST_HEAD *  head);
-
-extern void dapl_llist_add_head (
-    DAPL_LLIST_HEAD *  head,
-    DAPL_LLIST_ENTRY *         entry,
-    void *             data);
-
-extern void dapl_llist_add_tail (
-    DAPL_LLIST_HEAD *   head,
-    DAPL_LLIST_ENTRY *  entry,
-    void *             data);
-
-extern void dapl_llist_add_entry (
-    DAPL_LLIST_HEAD * head,
-    DAPL_LLIST_ENTRY * entry,
-    DAPL_LLIST_ENTRY * new_entry,
-    void * data);
-
-extern void * dapl_llist_remove_head (
-    DAPL_LLIST_HEAD *  head);
-
-extern void * dapl_llist_remove_tail (
-    DAPL_LLIST_HEAD *  head);
-
-extern void * dapl_llist_remove_entry (
-    DAPL_LLIST_HEAD *  head,
-    DAPL_LLIST_ENTRY * entry);
-
-extern void * dapl_llist_peek_head (
-    DAPL_LLIST_HEAD *  head);
-
-extern void * dapl_llist_next_entry (
-    IN    DAPL_LLIST_HEAD      *head,
-    IN    DAPL_LLIST_ENTRY     *cur_ent);
-
-extern void dapl_llist_debug_print_list (
-    DAPL_LLIST_HEAD *  head);
-
-
-#endif
+/*\r
+ * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.\r
+ *\r
+ * This Software is licensed under one of the following licenses:\r
+ *\r
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is\r
+ *    in the file LICENSE.txt in the root directory. The license is also\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/cpl.php.\r
+ *\r
+ * 2) under the terms of the "The BSD License" a copy of which is in the file\r
+ *    LICENSE2.txt in the root directory. The license is also available from\r
+ *    the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/bsd-license.php.\r
+ *\r
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a \r
+ *    copy of which is in the file LICENSE3.txt in the root directory. The \r
+ *    license is also available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/gpl-license.php.\r
+ *\r
+ * Licensee has the right to choose one of the above licenses.\r
+ *\r
+ * Redistributions of source code must retain the above copyright\r
+ * notice and one of the license notices.\r
+ *\r
+ * Redistributions in binary form must reproduce both the above copyright\r
+ * notice, one of the license notices in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ */\r
+\r
+/**********************************************************************\r
+ *\r
+ * MODULE: dapl.h\r
+ *\r
+ * PURPOSE: defines common data structures for the DAPL reference implemenation\r
+ *\r
+ * Description: This file describes the working data structures used within\r
+ *              DAPL RI.\r
+ *\r
+ *\r
+ * $Id: dapl.h 1317 2005-04-25 17:29:42Z jlentini $\r
+ **********************************************************************/\r
+\r
+#ifndef _DAPL_H_\r
+#define _DAPL_H_\r
+\r
+#if defined(__KERNEL__)\r
+#include <dat2/kdat.h>\r
+#else\r
+#include <dat2/udat.h>\r
+#endif /* defined(__KERNEL__) */\r
+#include <dat2/dat_registry.h>\r
+#include "dapl_osd.h"\r
+#include "dapl_debug.h"\r
+\r
+\r
+\r
+/*********************************************************************\r
+ *                                                                   *\r
+ * Enumerations                                                      *\r
+ *                                                                   *\r
+ *********************************************************************/\r
+\r
+typedef enum dapl_magic\r
+{\r
+    /* magic number values for verification & debug */\r
+    DAPL_MAGIC_IA      = 0xCafeF00d,\r
+    DAPL_MAGIC_EVD     = 0xFeedFace,\r
+    DAPL_MAGIC_EP      = 0xDeadBabe,\r
+    DAPL_MAGIC_LMR     = 0xBeefCafe,\r
+    DAPL_MAGIC_RMR      = 0xABadCafe,\r
+    DAPL_MAGIC_PZ      = 0xDeafBeef,\r
+    DAPL_MAGIC_PSP     = 0xBeadeD0c,\r
+    DAPL_MAGIC_RSP     = 0xFab4Feed,\r
+    DAPL_MAGIC_SRQ     = 0xC001Babe,\r
+    DAPL_MAGIC_CR      = 0xBe12Cee1,\r
+    DAPL_MAGIC_CR_DESTROYED = 0xB12bDead,\r
+    DAPL_MAGIC_CNO     = 0xDeadF00d,\r
+    DAPL_MAGIC_INVALID  = 0xFFFFFFFF\r
+} DAPL_MAGIC;\r
+\r
+typedef enum dapl_evd_state\r
+{\r
+    DAPL_EVD_STATE_TERMINAL,\r
+    DAPL_EVD_STATE_INITIAL,\r
+    DAPL_EVD_STATE_OPEN,\r
+    DAPL_EVD_STATE_WAITED,\r
+    DAPL_EVD_STATE_DEAD        = 0xDEAD\r
+} DAPL_EVD_STATE;\r
+\r
+typedef enum dapl_evd_completion\r
+{\r
+    DAPL_EVD_STATE_INIT,\r
+    DAPL_EVD_STATE_SOLICITED_WAIT,\r
+    DAPL_EVD_STATE_THRESHOLD,\r
+    DAPL_EVD_STATE_UNSIGNALLED\r
+} DAPL_EVD_COMPLETION;\r
+\r
+typedef enum dapl_cno_state\r
+{\r
+    DAPL_CNO_STATE_UNTRIGGERED,\r
+    DAPL_CNO_STATE_TRIGGERED,\r
+    DAPL_CNO_STATE_DEAD = 0xDeadFeed,\r
+} DAPL_CNO_STATE;\r
+\r
+typedef enum dapl_qp_state\r
+{\r
+    DAPL_QP_STATE_UNCONNECTED,\r
+    DAPL_QP_STATE_RESERVED,\r
+    DAPL_QP_STATE_PASSIVE_CONNECTION_PENDING,\r
+    DAPL_QP_STATE_ACTIVE_CONNECTION_PENDING,\r
+    DAPL_QP_STATE_TENTATIVE_CONNECTION_PENDING,\r
+    DAPL_QP_STATE_CONNECTED,\r
+    DAPL_QP_STATE_DISCONNECT_PENDING,\r
+    DAPL_QP_STATE_ERROR,\r
+    DAPL_QP_STATE_NOT_REUSABLE,\r
+    DAPL_QP_STATE_FREE\r
+} DAPL_QP_STATE;\r
+\r
+\r
+/*********************************************************************\r
+ *                                                                   *\r
+ * Constants                                                         *\r
+ *                                                                   *\r
+ *********************************************************************/\r
+\r
+/*\r
+ * number of HCAs allowed\r
+ */\r
+#define DAPL_MAX_HCA_COUNT             4\r
+\r
+/*\r
+ * Configures the RMR bind evd restriction\r
+ */\r
+\r
+#define DAPL_RMR_BIND_EVD_RESTRICTION  DAT_RMR_EVD_SAME_AS_REQUEST_EVD\r
+\r
+/*\r
+ * special qp_state indicating the EP does not have a QP attached yet\r
+ */\r
+#define DAPL_QP_STATE_UNATTACHED       0xFFF0\r
+\r
+#define DAPL_MAX_PRIVATE_DATA_SIZE     256\r
+\r
+/*********************************************************************\r
+ *                                                                   *\r
+ * Macros                                                            *\r
+ *                                                                   *\r
+ *********************************************************************/\r
+\r
+#if defined (sun) || defined(__sun) || defined(_sun_) || defined (__solaris__) \r
+#define DAPL_BAD_PTR(a) ((unsigned long)(a) & 3)\r
+#elif defined(__linux__)\r
+#define DAPL_BAD_PTR(a) ((unsigned long)(a) & 3)\r
+#elif defined(_WIN64)\r
+#define DAPL_BAD_PTR(a) ((unsigned long)((DAT_UINT64)(a)) & 3)\r
+#elif defined(_WIN32)\r
+#define DAPL_BAD_PTR(a) ((unsigned long)((DAT_UINT64)(a)) & 3)\r
+#endif\r
+\r
+/*\r
+ * Simple macro to verify a handle is bad. Conditions:\r
+ * - pointer is NULL\r
+ * - pointer is not word aligned\r
+ * - pointer's magic number is wrong\r
+ */\r
+\r
+#define DAPL_BAD_HANDLE(h, magicNum) (                         \\r
+           ((h) == NULL) ||                                    \\r
+           DAPL_BAD_PTR(h) ||                                  \\r
+           (((DAPL_HEADER *)(h))->magic != (magicNum)))\r
+\r
+#define DAPL_MIN(a, b)        ((a < b) ? (a) : (b))\r
+#define DAPL_MAX(a, b)        ((a > b) ? (a) : (b))\r
+\r
+#if NDEBUG > 0\r
+#define DEBUG_IS_BAD_HANDLE(h, magicNum) (DAPL_BAD_HANDLE(h, magicNum))\r
+#else\r
+#define DEBUG_IS_BAD_HANDLE(h, magicNum) (0)\r
+#endif\r
+\r
+#define DAT_ERROR(Type, SubType) ((DAT_RETURN)(DAT_CLASS_ERROR | Type | SubType))\r
+\r
+/*********************************************************************\r
+ *                                                                   *\r
+ * Typedefs                                                          *\r
+ *                                                                   *\r
+ *********************************************************************/\r
+\r
+typedef struct dapl_llist_entry                DAPL_LLIST_ENTRY;\r
+typedef DAPL_LLIST_ENTRY *             DAPL_LLIST_HEAD;\r
+typedef struct dapl_ring_buffer                DAPL_RING_BUFFER;\r
+typedef struct dapl_cookie_buffer      DAPL_COOKIE_BUFFER;\r
+\r
+typedef struct dapl_hash_table          DAPL_HASH_TABLE;\r
+typedef struct dapl_hash_table *        DAPL_HASH_TABLEP;\r
+typedef DAT_UINT64                      DAPL_HASH_KEY;\r
+typedef void *                          DAPL_HASH_DATA;\r
+\r
+typedef struct dapl_hca                        DAPL_HCA;\r
+\r
+typedef struct dapl_header             DAPL_HEADER;\r
+\r
+typedef struct dapl_ia                 DAPL_IA;\r
+typedef struct dapl_cno                        DAPL_CNO;\r
+typedef struct dapl_evd                DAPL_EVD;\r
+typedef struct dapl_ep                         DAPL_EP;\r
+typedef struct dapl_srq                        DAPL_SRQ;\r
+typedef struct dapl_pz                 DAPL_PZ;\r
+typedef struct dapl_lmr                        DAPL_LMR;\r
+typedef struct dapl_rmr                        DAPL_RMR;\r
+typedef struct dapl_sp                 DAPL_SP;\r
+typedef struct dapl_cr                 DAPL_CR;\r
+\r
+typedef struct dapl_cookie             DAPL_COOKIE;\r
+typedef struct dapl_dto_cookie         DAPL_DTO_COOKIE;\r
+typedef struct dapl_rmr_cookie         DAPL_RMR_COOKIE;\r
+\r
+typedef struct dapl_private            DAPL_PRIVATE;\r
+\r
+\r
+\r
+/*********************************************************************\r
+ *                                                                   *\r
+ * Structures                                                        *\r
+ *                                                                   *\r
+ *********************************************************************/\r
+\r
+struct dapl_llist_entry\r
+{\r
+    struct dapl_llist_entry    *flink;\r
+    struct dapl_llist_entry    *blink;\r
+    void                       *data;\r
+    DAPL_LLIST_HEAD            *list_head; /* for consistency checking */\r
+};\r
+\r
+struct dapl_ring_buffer\r
+{\r
+    void               **base;         /* base of element array */\r
+    DAT_COUNT          lim;            /* mask, number of entries - 1 */\r
+    DAPL_ATOMIC                head;           /* head pointer index */\r
+    DAPL_ATOMIC                tail;           /* tail pointer index */\r
+};\r
+\r
+struct dapl_cookie_buffer\r
+{\r
+    DAPL_COOKIE                *pool;\r
+    DAT_COUNT          pool_size;\r
+    DAPL_ATOMIC                head;\r
+    DAPL_ATOMIC                tail;\r
+};\r
+\r
+#ifdef IBAPI\r
+#include "dapl_ibapi_util.h"\r
+#elif VAPI\r
+#include "dapl_vapi_util.h"\r
+#elif __OPENIB__\r
+#include "dapl_openib_util.h"\r
+#include "dapl_openib_cm.h"\r
+#elif DUMMY\r
+#include "dapl_dummy_util.h"\r
+#elif OPENIB\r
+#include "dapl_ib_util.h"\r
+#else /* windows - IBAL and/or IBAL+Sock_CM */\r
+#include "dapl_ibal_util.h"\r
+#endif\r
+\r
+struct dapl_hca\r
+{\r
+    DAPL_OS_LOCK       lock;\r
+    DAPL_LLIST_HEAD    ia_list_head;      /* list of all open IAs */\r
+    DAPL_ATOMIC                handle_ref_count;  /* count of ia_opens on handle */\r
+    DAPL_EVD           *async_evd;\r
+    DAPL_EVD           *async_error_evd;\r
+    DAT_SOCK_ADDR6     hca_address;       /* local address of HCA*/\r
+    char               *name;             /* provider name */\r
+    ib_hca_handle_t    ib_hca_handle;\r
+    unsigned long       port_num;         /* physical port number */\r
+    ib_hca_transport_t  ib_trans;         /* Values specific transport API */\r
+    /* Memory Subsystem Support */\r
+    DAPL_HASH_TABLE    *lmr_hash_table;\r
+    /* Limits & useful HCA attributes */\r
+    DAT_IA_ATTR                ia_attr;\r
+};\r
+\r
+/* DAPL Objects always have the following header */\r
+struct dapl_header\r
+{\r
+    DAT_PROVIDER       *provider;      /* required by DAT - must be first */\r
+    DAPL_MAGIC         magic;          /* magic number for verification */\r
+    DAT_HANDLE_TYPE    handle_type;    /* struct type */\r
+    DAPL_IA            *owner_ia;      /* ia which owns this stuct */\r
+    DAPL_LLIST_ENTRY   ia_list_entry;  /* link entry on ia struct */\r
+    DAT_CONTEXT                user_context;   /* user context - opaque to DAPL */\r
+    DAPL_OS_LOCK       lock;           /* lock - in header for easier macros */\r
+};\r
+\r
+/* DAPL_IA maps to DAT_IA_HANDLE */\r
+struct dapl_ia\r
+{\r
+    DAPL_HEADER                header;\r
+    DAPL_HCA           *hca_ptr;\r
+    DAPL_EVD           *async_error_evd;\r
+    DAT_BOOLEAN                cleanup_async_error_evd;\r
+\r
+    DAPL_LLIST_ENTRY   hca_ia_list_entry;      /* HCAs list of IAs */\r
+    DAPL_LLIST_HEAD    ep_list_head;           /* EP queue */\r
+    DAPL_LLIST_HEAD    lmr_list_head;          /* LMR queue */\r
+    DAPL_LLIST_HEAD    rmr_list_head;          /* RMR queue */\r
+    DAPL_LLIST_HEAD    pz_list_head;           /* PZ queue */\r
+    DAPL_LLIST_HEAD    evd_list_head;          /* EVD queue */\r
+    DAPL_LLIST_HEAD    cno_list_head;          /* CNO queue */\r
+    DAPL_LLIST_HEAD    psp_list_head;          /* PSP queue */\r
+    DAPL_LLIST_HEAD    rsp_list_head;          /* RSP queue */\r
+    DAPL_LLIST_HEAD    srq_list_head;          /* SRQ queue */\r
+#ifdef DAPL_COUNTERS\r
+    void               *cntrs;\r
+#endif\r
+};\r
+\r
+/* DAPL_CNO maps to DAT_CNO_HANDLE */\r
+struct dapl_cno\r
+{\r
+    DAPL_HEADER        header;\r
+\r
+    /* A CNO cannot be freed while it is referenced elsewhere.  */\r
+    DAPL_ATOMIC                        cno_ref_count;\r
+    DAPL_CNO_STATE             cno_state;\r
+\r
+    DAT_COUNT                  cno_waiters;\r
+    DAPL_EVD                   *cno_evd_triggered;\r
+#if defined(__KERNEL__)\r
+    DAT_UPCALL_OBJECT          cno_upcall;\r
+    DAT_UPCALL_POLICY          cno_upcall_policy;\r
+#else\r
+    DAT_OS_WAIT_PROXY_AGENT    cno_wait_agent;\r
+#endif /* defined(__KERNEL__) */\r
+\r
+    DAPL_OS_WAIT_OBJECT                cno_wait_object;\r
+};\r
+\r
+/* DAPL_EVD maps to DAT_EVD_HANDLE */\r
+struct dapl_evd\r
+{\r
+    DAPL_HEADER                header;\r
+\r
+    DAPL_EVD_STATE     evd_state;\r
+    DAT_EVD_FLAGS      evd_flags;\r
+    DAT_BOOLEAN                evd_enabled; /* For attached CNO.  */\r
+    DAT_BOOLEAN                evd_waitable; /* EVD state.  */\r
+\r
+    /* Derived from evd_flags; see dapls_evd_internal_create.  */\r
+    DAT_BOOLEAN                evd_producer_locking_needed;\r
+\r
+    /* Every EVD has a CQ unless it is a SOFTWARE_EVENT only EVD */\r
+    ib_cq_handle_t     ib_cq_handle;\r
+\r
+    /* An Event Dispatcher cannot be freed while\r
+     * it is referenced elsewhere.\r
+     */\r
+    DAPL_ATOMIC                evd_ref_count;\r
+\r
+    /* Set if there has been a catastrophic overflow */\r
+    DAT_BOOLEAN                catastrophic_overflow;\r
+\r
+    /* the actual events */\r
+    DAT_COUNT          qlen;\r
+    DAT_EVENT          *events;\r
+    DAPL_RING_BUFFER   free_event_queue;\r
+    DAPL_RING_BUFFER   pending_event_queue;\r
+\r
+    /* CQ Completions are not placed into 'deferred_events'\r
+     ** rather they are simply left on the Completion Queue\r
+     ** and the fact that there was a notification is flagged.\r
+     */\r
+    DAT_BOOLEAN                cq_notified;\r
+    DAPL_OS_TICKS      cq_notified_when;\r
+\r
+    DAT_COUNT          cno_active_count;\r
+    DAPL_CNO           *cno_ptr;\r
+\r
+    DAPL_OS_WAIT_OBJECT        wait_object;\r
+\r
+    DAT_COUNT          threshold;\r
+    DAPL_EVD_COMPLETION        completion_type;\r
+\r
+#ifdef DAPL_COUNTERS\r
+    void               *cntrs;\r
+#endif\r
+};\r
+\r
+/* DAPL_PRIVATE used to pass private data in a connection */\r
+struct dapl_private\r
+{\r
+#ifdef IBHOSTS_NAMING\r
+    DAT_SOCK_ADDR6             hca_address;    /* local address of HCA*/\r
+#endif /* IBHOSTS_NAMING */\r
+    unsigned char              private_data[DAPL_MAX_PRIVATE_DATA_SIZE];\r
+};\r
+\r
+/* uDAPL timer entry, used to queue timeouts */\r
+struct dapl_timer_entry\r
+{\r
+    DAPL_LLIST_ENTRY           list_entry;     /* link entry on ia struct */\r
+    DAPL_OS_TIMEVAL            expires;\r
+    void                       (*function) (uintptr_t);\r
+    void                       *data;\r
+};\r
+\r
+#ifdef DAPL_DBG_IO_TRC\r
+\r
+#define DBG_IO_TRC_QLEN   32           /* length of trace buffer        */\r
+#define DBG_IO_TRC_IOV 3               /* iov elements we keep track of */\r
+\r
+struct io_buf_track\r
+{\r
+    Ib_send_op_type            op_type;\r
+    DAPL_COOKIE                        *cookie;\r
+    DAT_LMR_TRIPLET            iov[DBG_IO_TRC_IOV];\r
+    DAT_RMR_TRIPLET            remote_iov;\r
+    unsigned int               done;   /* count to track completion ordering */\r
+    int                                status;\r
+    void                       *wqe;\r
+};\r
+\r
+#endif /* DAPL_DBG_IO_TRC */\r
+\r
+/* DAPL_EP maps to DAT_EP_HANDLE */\r
+struct dapl_ep\r
+{\r
+    DAPL_HEADER                        header;\r
+    /* What the DAT Consumer asked for */\r
+    DAT_EP_PARAM               param;\r
+\r
+    /* The RC Queue Pair (IBM OS API) */\r
+    ib_qp_handle_t             qp_handle;\r
+    unsigned int               qpn;    /* qp number */\r
+    ib_qp_state_t              qp_state;\r
+\r
+    /* communications manager handle (IBM OS API) */\r
+    dp_ib_cm_handle_t          cm_handle;\r
+\r
+    /* store the remote IA address here, reference from the param\r
+     * struct which only has a pointer, no storage\r
+     */\r
+    DAT_SOCK_ADDR6             remote_ia_address;\r
+\r
+    /* For passive connections we maintain a back pointer to the CR */\r
+    void *                     cr_ptr;\r
+\r
+    /* pointer to connection timer, if set */\r
+    struct dapl_timer_entry    *cxn_timer;\r
+\r
+    /* private data container */\r
+    DAPL_PRIVATE               private;\r
+\r
+    /* DTO data */\r
+    DAPL_ATOMIC                        req_count;\r
+    DAPL_ATOMIC                        recv_count;\r
+\r
+    DAPL_COOKIE_BUFFER req_buffer;\r
+    DAPL_COOKIE_BUFFER recv_buffer;\r
+\r
+#ifdef DAPL_DBG_IO_TRC\r
+    int                        ibt_dumped;\r
+    struct io_buf_track *ibt_base;\r
+    DAPL_RING_BUFFER   ibt_queue;\r
+#endif /* DAPL_DBG_IO_TRC */\r
+#if defined(_WIN32) || defined(_WIN64)\r
+    DAT_BOOLEAN         recv_discreq;\r
+    DAT_BOOLEAN         sent_discreq;\r
+    dp_ib_cm_handle_t   ibal_cm_handle;\r
+#endif\r
+#ifdef DAPL_COUNTERS\r
+    void               *cntrs;\r
+#endif\r
+};\r
+\r
+/* DAPL_SRQ maps to DAT_SRQ_HANDLE */\r
+struct dapl_srq\r
+{\r
+    DAPL_HEADER                header;\r
+    DAT_SRQ_PARAM      param;\r
+    DAPL_ATOMIC                srq_ref_count;\r
+    DAPL_COOKIE_BUFFER recv_buffer;\r
+    DAPL_ATOMIC                recv_count;\r
+};\r
+\r
+/* DAPL_PZ maps to DAT_PZ_HANDLE */\r
+struct dapl_pz\r
+{\r
+    DAPL_HEADER                header;\r
+    ib_pd_handle_t     pd_handle;\r
+    DAPL_ATOMIC                pz_ref_count;\r
+};\r
+\r
+/* DAPL_LMR maps to DAT_LMR_HANDLE */\r
+struct dapl_lmr\r
+{\r
+    DAPL_HEADER                header;\r
+    DAT_LMR_PARAM      param;\r
+    ib_mr_handle_t     mr_handle;\r
+    DAPL_ATOMIC                lmr_ref_count;\r
+#if !defined(__KDAPL__)\r
+    char               shmid[DAT_LMR_COOKIE_SIZE]; /* shared memory ID */\r
+    ib_shm_transport_t ib_trans;       /* provider specific data */\r
+#endif /* !__KDAPL__ */\r
+};\r
+\r
+/* DAPL_RMR maps to DAT_RMR_HANDLE */\r
+struct dapl_rmr\r
+{\r
+    DAPL_HEADER                header;\r
+    DAT_RMR_PARAM      param;\r
+    DAPL_EP             *ep;\r
+    DAPL_PZ             *pz;\r
+    DAPL_LMR            *lmr;\r
+    ib_mw_handle_t     mw_handle;\r
+};\r
+\r
+/* SP types, indicating the state and queue */\r
+typedef enum dapl_sp_state\r
+{\r
+    DAPL_SP_STATE_FREE,\r
+    DAPL_SP_STATE_PSP_LISTENING,\r
+    DAPL_SP_STATE_PSP_PENDING,\r
+    DAPL_SP_STATE_RSP_LISTENING,\r
+    DAPL_SP_STATE_RSP_PENDING\r
+} DAPL_SP_STATE;\r
+\r
+/* DAPL_SP maps to DAT_PSP_HANDLE and DAT_RSP_HANDLE */\r
+struct dapl_sp\r
+{\r
+    DAPL_HEADER                header;\r
+    DAPL_SP_STATE      state;          /* type and queue of the SP */\r
+\r
+    /* PSP/RSP PARAM fields */\r
+    DAT_CONN_QUAL       conn_qual;\r
+    DAT_EVD_HANDLE      evd_handle;\r
+    DAT_PSP_FLAGS       psp_flags;\r
+    DAT_EP_HANDLE       ep_handle;\r
+\r
+     /* maintenence fields */\r
+    DAT_BOOLEAN                listening;      /* PSP is registered & active */\r
+    ib_cm_srvc_handle_t        cm_srvc_handle; /* Used by Mellanox CM */\r
+    DAPL_LLIST_HEAD    cr_list_head;   /* CR pending queue */\r
+    DAT_COUNT          cr_list_count;  /* count of CRs on queue */\r
+#if defined(_VENDOR_IBAL_)\r
+    DAPL_OS_WAIT_OBJECT wait_object;    /* cancel & destroy. */\r
+#endif\r
+};\r
+\r
+/* DAPL_CR maps to DAT_CR_HANDLE */\r
+struct dapl_cr\r
+{\r
+    DAPL_HEADER                header;\r
+\r
+    /* for convenience the data is kept as a DAT_CR_PARAM.\r
+     * however, the "local_endpoint" field is always NULL\r
+     * so this wastes a pointer. This is probably ok to\r
+     * simplify code, espedially dat_cr_query.\r
+     */\r
+    DAT_CR_PARAM       param;\r
+    /* IB specific fields */\r
+    dp_ib_cm_handle_t  ib_cm_handle;\r
+\r
+    DAT_SOCK_ADDR6     remote_ia_address;\r
+    /* Assuming that the maximum private data size is small.\r
+     * If it gets large, use of a pointer may be appropriate.\r
+     */\r
+    unsigned char      private_data[DAPL_MAX_PRIVATE_DATA_SIZE];\r
+    /*\r
+     * Need to be able to associate the CR back to the PSP for\r
+     * dapl_cr_reject.\r
+     */\r
+    DAPL_SP            *sp_ptr;\r
+};\r
+\r
+typedef enum dapl_dto_type\r
+{\r
+    DAPL_DTO_TYPE_SEND,\r
+    DAPL_DTO_TYPE_RECV,\r
+    DAPL_DTO_TYPE_RDMA_WRITE,\r
+    DAPL_DTO_TYPE_RDMA_READ,\r
+#ifdef DAT_EXTENSIONS\r
+    DAPL_DTO_TYPE_EXTENSION,\r
+#endif\r
+} DAPL_DTO_TYPE;\r
+\r
+typedef enum dapl_cookie_type\r
+{\r
+    DAPL_COOKIE_TYPE_NULL,\r
+    DAPL_COOKIE_TYPE_DTO,\r
+    DAPL_COOKIE_TYPE_RMR,\r
+} DAPL_COOKIE_TYPE;\r
+\r
+/* DAPL_DTO_COOKIE used as context for DTO WQEs */\r
+struct dapl_dto_cookie\r
+{\r
+    DAPL_DTO_TYPE              type;\r
+    DAT_DTO_COOKIE             cookie;\r
+    DAT_COUNT                  size;   /* used for SEND and RDMA write */\r
+};\r
+\r
+/* DAPL_RMR_COOKIE used as context for bind WQEs */\r
+struct dapl_rmr_cookie\r
+{\r
+    DAPL_RMR                   *rmr;\r
+    DAT_RMR_COOKIE              cookie;\r
+};\r
+\r
+/* DAPL_COOKIE used as context for WQEs */\r
+struct dapl_cookie\r
+{\r
+    DAPL_COOKIE_TYPE           type; /* Must be first, to define struct.  */\r
+    DAPL_EP                    *ep;\r
+    DAT_COUNT                  index;\r
+    union\r
+    {\r
+       DAPL_DTO_COOKIE         dto;\r
+       DAPL_RMR_COOKIE         rmr;\r
+    } val;\r
+};\r
+\r
+/*\r
+ * Private Data operations. Used to obtain the size of the private\r
+ * data from the provider layer.\r
+ */\r
+typedef enum dapl_private_data_op\r
+{\r
+    DAPL_PDATA_CONN_REQ  = 0,          /* connect request    */\r
+    DAPL_PDATA_CONN_REP  = 1,          /* connect reply      */\r
+    DAPL_PDATA_CONN_REJ  = 2,          /* connect reject     */\r
+    DAPL_PDATA_CONN_DREQ = 3,          /* disconnect request */\r
+    DAPL_PDATA_CONN_DREP = 4,          /* disconnect reply   */\r
+} DAPL_PDATA_OP;\r
+\r
+\r
+/*\r
+ * Generic HCA name field\r
+ */\r
+#define DAPL_HCA_NAME_MAX_LEN 260\r
+typedef char DAPL_HCA_NAME[DAPL_HCA_NAME_MAX_LEN+1];\r
+\r
+#ifdef IBHOSTS_NAMING\r
+\r
+/*\r
+ * Simple mapping table to match IP addresses to GIDs. Loaded\r
+ * by dapl_init.\r
+ */\r
+typedef struct _dapl_gid_map_table\r
+{\r
+    uint32_t           ip_address;\r
+    ib_gid_t           gid;\r
+} DAPL_GID_MAP;\r
+\r
+#endif /* IBHOSTS_NAMING */\r
+\r
+/*\r
+ * IBTA defined reason for reject message: See IBTA 1.1 specification,\r
+ * 12.6.7.2 REJECTION REASON section.\r
+ */\r
+#define IB_CM_REJ_REASON_CONSUMER_REJ            0x001C\r
+\r
+\r
+#if defined(DAPL_DBG_IO_TRC)\r
+/*********************************************************************\r
+ *                                                                   *\r
+ * Debug I/O tracing support prototypes                              *\r
+ *                                                                   *\r
+ *********************************************************************/\r
+/*\r
+ * I/O tracing support\r
+ */\r
+void dapls_io_trc_alloc (\r
+    DAPL_EP                    *ep_ptr);\r
+\r
+void dapls_io_trc_update_completion (\r
+    DAPL_EP                    *ep_ptr,\r
+    DAPL_COOKIE                        *cookie,\r
+    ib_uint32_t                        ib_status );\r
+\r
+void dapls_io_trc_dump (\r
+    DAPL_EP                    *ep_ptr,\r
+    ib_work_completion_t       *cqe_ptr,\r
+    ib_uint32_t                        ib_status);\r
+\r
+#else /* DAPL_DBG_IO_TRC */\r
+\r
+#define dapls_io_trc_alloc(a)\r
+#define dapls_io_trc_update_completion(a, b, c)\r
+#define dapls_io_trc_dump(a, b, c)\r
+\r
+#endif /* DAPL_DBG_IO_TRC */\r
+\r
+\r
+/*********************************************************************\r
+ *                                                                   *\r
+ * Function Prototypes                                               *\r
+ *                                                                   *\r
+ *********************************************************************/\r
+\r
+typedef void (*DAPL_CONNECTION_STATE_HANDLER) (\r
+       IN      DAPL_EP *,\r
+       IN      ib_cm_events_t,\r
+       IN      const void *,\r
+       OUT     DAT_EVENT *);\r
+\r
+/*\r
+ * DAT Mandated functions\r
+ */\r
+\r
+extern DAT_RETURN DAT_API dapl_ia_open (\r
+       IN      const DAT_NAME_PTR,     /* name */\r
+       IN      DAT_COUNT,              /* asynch_evd_qlen */\r
+       INOUT   DAT_EVD_HANDLE *,       /* asynch_evd_handle */\r
+       OUT     DAT_IA_HANDLE *);       /* ia_handle */\r
+\r
+extern DAT_RETURN DAT_API dapl_ia_close (\r
+       IN      DAT_IA_HANDLE,          /* ia_handle */\r
+       IN      DAT_CLOSE_FLAGS );      /* ia_flags */\r
+\r
+\r
+extern DAT_RETURN DAT_API dapl_ia_query (\r
+       IN      DAT_IA_HANDLE,          /* ia handle */\r
+       OUT     DAT_EVD_HANDLE *,       /* async_evd_handle */\r
+       IN      DAT_IA_ATTR_MASK,       /* ia_params_mask */\r
+       OUT     DAT_IA_ATTR *,          /* ia_params */\r
+       IN      DAT_PROVIDER_ATTR_MASK, /* provider_params_mask */\r
+       OUT     DAT_PROVIDER_ATTR * );  /* provider_params */\r
+\r
+\r
+/* helper functions */\r
+\r
+extern DAT_RETURN DAT_API dapl_set_consumer_context (\r
+       IN      DAT_HANDLE,                     /* dat handle */\r
+       IN      DAT_CONTEXT);                   /* context */\r
+\r
+extern DAT_RETURN DAT_API dapl_get_consumer_context (\r
+       IN      DAT_HANDLE,                     /* dat handle */\r
+       OUT     DAT_CONTEXT * );                /* context */\r
+\r
+extern DAT_RETURN DAT_API dapl_get_handle_type (\r
+       IN      DAT_HANDLE,\r
+       OUT     DAT_HANDLE_TYPE * );\r
+\r
+/* CNO functions */\r
+\r
+#if !defined(__KERNEL__)\r
+extern DAT_RETURN DAT_API dapl_cno_create (\r
+       IN      DAT_IA_HANDLE,                  /* ia_handle */\r
+       IN      DAT_OS_WAIT_PROXY_AGENT,        /* agent */\r
+       OUT     DAT_CNO_HANDLE *);              /* cno_handle */\r
+\r
+extern DAT_RETURN DAT_API dapl_cno_modify_agent (\r
+       IN      DAT_CNO_HANDLE,                 /* cno_handle */\r
+       IN      DAT_OS_WAIT_PROXY_AGENT);       /* agent */\r
+\r
+extern DAT_RETURN DAT_API dapl_cno_query (\r
+       IN      DAT_CNO_HANDLE,         /* cno_handle */\r
+       IN      DAT_CNO_PARAM_MASK,     /* cno_param_mask */\r
+       OUT     DAT_CNO_PARAM * );      /* cno_param */\r
+\r
+extern DAT_RETURN DAT_API dapl_cno_free (\r
+       IN      DAT_CNO_HANDLE);        /* cno_handle */\r
+\r
+extern DAT_RETURN DAT_API dapl_cno_wait (\r
+       IN      DAT_CNO_HANDLE,         /* cno_handle */\r
+       IN      DAT_TIMEOUT,            /* timeout */\r
+       OUT     DAT_EVD_HANDLE *);      /* evd_handle */\r
+\r
+extern DAT_RETURN DAT_API dapl_cno_fd_create (\r
+       IN      DAT_IA_HANDLE,          /* ia_handle            */\r
+       OUT     DAT_FD *,               /* file_descriptor      */\r
+       OUT     DAT_CNO_HANDLE *);      /* cno_handle           */\r
+\r
+extern DAT_RETURN DAT_API dapl_cno_trigger (\r
+       IN      DAT_CNO_HANDLE,         /* cno_handle */\r
+       OUT     DAT_EVD_HANDLE *);      /* evd_handle */\r
+\r
+#endif /* !defined(__KERNEL__) */\r
+\r
+/* CR Functions */\r
+\r
+extern DAT_RETURN DAT_API dapl_cr_query (\r
+       IN      DAT_CR_HANDLE,          /* cr_handle */\r
+       IN      DAT_CR_PARAM_MASK,      /* cr_args_mask */\r
+       OUT     DAT_CR_PARAM * );       /* cwr_args */\r
+\r
+extern DAT_RETURN DAT_API dapl_cr_accept (\r
+       IN      DAT_CR_HANDLE,          /* cr_handle */\r
+       IN      DAT_EP_HANDLE,          /* ep_handle */\r
+       IN      DAT_COUNT,              /* private_data_size */\r
+       IN      const DAT_PVOID );      /* private_data */\r
+\r
+extern DAT_RETURN DAT_API dapl_cr_reject (\r
+       IN      DAT_CR_HANDLE,          /* cr_handle            */\r
+       IN      DAT_COUNT,              /* private_data_size    */\r
+       IN      const DAT_PVOID );      /* private_data         */\r
+\r
+extern DAT_RETURN DAT_API dapl_cr_handoff (\r
+       IN DAT_CR_HANDLE,               /* cr_handle */\r
+       IN DAT_CONN_QUAL);              /* handoff */\r
+\r
+/* EVD Functions */\r
+\r
+#if defined(__KERNEL__)\r
+extern DAT_RETURN DAT_API dapl_ia_memtype_hint (\r
+       IN    DAT_IA_HANDLE,            /* ia_handle */\r
+       IN    DAT_MEM_TYPE,             /* mem_type */\r
+       IN    DAT_VLEN,                 /* length */\r
+       IN    DAT_MEM_OPT,              /* mem_optimization */\r
+       OUT   DAT_VLEN *,               /* suggested_length */\r
+       OUT   DAT_VADDR *);             /* suggested_alignment */\r
+\r
+extern DAT_RETURN DAT_API dapl_evd_kcreate (\r
+       IN      DAT_IA_HANDLE,          /* ia_handle */\r
+       IN      DAT_COUNT,              /* evd_min_qlen */\r
+       IN      DAT_UPCALL_POLICY,      /* upcall_policy */\r
+       IN      const DAT_UPCALL_OBJECT *, /* upcall */\r
+       IN      DAT_EVD_FLAGS,          /* evd_flags */\r
+       OUT     DAT_EVD_HANDLE * );     /* evd_handle */\r
+\r
+extern DAT_RETURN DAT_API dapl_evd_kquery (\r
+       IN      DAT_EVD_HANDLE,         /* evd_handle */\r
+       IN      DAT_EVD_PARAM_MASK,     /* evd_args_mask */\r
+       OUT     DAT_EVD_PARAM * );      /* evd_args */\r
+\r
+#else\r
+extern DAT_RETURN DAT_API dapl_evd_create (\r
+       IN      DAT_IA_HANDLE,          /* ia_handle */\r
+       IN      DAT_COUNT,              /* evd_min_qlen */\r
+       IN      DAT_CNO_HANDLE,         /* cno_handle */\r
+       IN      DAT_EVD_FLAGS,          /* evd_flags */\r
+       OUT     DAT_EVD_HANDLE * );     /* evd_handle */\r
+\r
+extern DAT_RETURN DAT_API dapl_evd_query (\r
+       IN      DAT_EVD_HANDLE,         /* evd_handle */\r
+       IN      DAT_EVD_PARAM_MASK,     /* evd_args_mask */\r
+       OUT     DAT_EVD_PARAM * );      /* evd_args */\r
+#endif /* defined(__KERNEL__) */\r
+\r
+#if defined(__KERNEL__)\r
+extern DAT_RETURN DAT_API dapl_evd_modify_upcall (\r
+       IN      DAT_EVD_HANDLE,         /* evd_handle */\r
+       IN      DAT_UPCALL_POLICY,      /* upcall_policy */\r
+       IN      const DAT_UPCALL_OBJECT * ); /* upcall */\r
+\r
+#else\r
+\r
+extern DAT_RETURN DAT_API dapl_evd_modify_cno (\r
+       IN      DAT_EVD_HANDLE,         /* evd_handle */\r
+       IN      DAT_CNO_HANDLE);        /* cno_handle */\r
+#endif\r
+\r
+extern DAT_RETURN DAT_API dapl_evd_enable (\r
+       IN      DAT_EVD_HANDLE);        /* evd_handle */\r
+\r
+extern DAT_RETURN DAT_API dapl_evd_disable (\r
+       IN      DAT_EVD_HANDLE);        /* evd_handle */\r
+\r
+#if !defined(__KERNEL__)\r
+extern DAT_RETURN DAT_API dapl_evd_wait (\r
+       IN      DAT_EVD_HANDLE,         /* evd_handle */\r
+       IN      DAT_TIMEOUT,            /* timeout */\r
+       IN      DAT_COUNT,              /* threshold */\r
+       OUT     DAT_EVENT *,            /* event */\r
+       OUT     DAT_COUNT *);           /* nmore */\r
+#endif /* !defined(__KERNEL__) */\r
+\r
+extern DAT_RETURN DAT_API dapl_evd_resize (\r
+       IN      DAT_EVD_HANDLE,         /* evd_handle */\r
+       IN      DAT_COUNT );            /* evd_qlen */\r
+\r
+extern DAT_RETURN DAT_API dapl_evd_post_se (\r
+       DAT_EVD_HANDLE,                 /* evd_handle */\r
+       const DAT_EVENT * );            /* event */\r
+\r
+extern DAT_RETURN DAT_API dapl_evd_dequeue (\r
+       IN      DAT_EVD_HANDLE,         /* evd_handle */\r
+       OUT     DAT_EVENT * );          /* event */\r
+\r
+extern DAT_RETURN DAT_API dapl_evd_free (\r
+       IN      DAT_EVD_HANDLE );\r
+\r
+extern DAT_RETURN DAT_API\r
+dapl_evd_set_unwaitable (\r
+       IN      DAT_EVD_HANDLE  evd_handle );\r
+\r
+extern DAT_RETURN DAT_API\r
+dapl_evd_clear_unwaitable (\r
+       IN      DAT_EVD_HANDLE  evd_handle );\r
+\r
+/* EP functions */\r
+\r
+extern DAT_RETURN DAT_API dapl_ep_create (\r
+       IN      DAT_IA_HANDLE,          /* ia_handle */\r
+       IN      DAT_PZ_HANDLE,          /* pz_handle */\r
+       IN      DAT_EVD_HANDLE,         /* in_dto_completion_evd_handle */\r
+       IN      DAT_EVD_HANDLE,         /* out_dto_completion_evd_handle */\r
+       IN      DAT_EVD_HANDLE,         /* connect_evd_handle */\r
+       IN      const DAT_EP_ATTR *,    /* ep_parameters */\r
+       OUT     DAT_EP_HANDLE * );      /* ep_handle */\r
+\r
+extern DAT_RETURN DAT_API dapl_ep_query (\r
+       IN      DAT_EP_HANDLE,          /* ep_handle */\r
+       IN      DAT_EP_PARAM_MASK,      /* ep_args_mask */\r
+       OUT     DAT_EP_PARAM * );       /* ep_args */\r
+\r
+extern DAT_RETURN DAT_API dapl_ep_modify (\r
+       IN      DAT_EP_HANDLE,          /* ep_handle */\r
+       IN      DAT_EP_PARAM_MASK,      /* ep_args_mask */\r
+       IN      const DAT_EP_PARAM * ); /* ep_args */\r
+\r
+extern DAT_RETURN DAT_API dapl_ep_connect (\r
+       IN      DAT_EP_HANDLE,          /* ep_handle */\r
+       IN      DAT_IA_ADDRESS_PTR,     /* remote_ia_address */\r
+       IN      DAT_CONN_QUAL,          /* remote_conn_qual */\r
+       IN      DAT_TIMEOUT,            /* timeout */\r
+       IN      DAT_COUNT,              /* private_data_size */\r
+       IN      const DAT_PVOID,        /* private_data  */\r
+       IN      DAT_QOS,                /* quality_of_service */\r
+       IN      DAT_CONNECT_FLAGS );    /* connect_flags */\r
+\r
+extern DAT_RETURN DAT_API dapl_ep_common_connect (\r
+       IN      DAT_EP_HANDLE ep,               /* ep_handle            */\r
+       IN      DAT_IA_ADDRESS_PTR remote_addr, /* remote_ia_address    */\r
+       IN      DAT_TIMEOUT timeout,            /* timeout              */\r
+       IN      DAT_COUNT pdata_size,           /* private_data_size    */\r
+       IN      const DAT_PVOID pdata   );      /* private_data         */\r
+\r
+extern DAT_RETURN DAT_API dapl_ep_dup_connect (\r
+       IN      DAT_EP_HANDLE,          /* ep_handle */\r
+       IN      DAT_EP_HANDLE,          /* ep_dup_handle */\r
+       IN      DAT_TIMEOUT,            /* timeout*/\r
+       IN      DAT_COUNT,              /* private_data_size */\r
+       IN      const DAT_PVOID,        /* private_data */\r
+       IN      DAT_QOS);               /* quality_of_service */\r
+\r
+extern DAT_RETURN DAT_API dapl_ep_disconnect (\r
+       IN      DAT_EP_HANDLE,          /* ep_handle */\r
+       IN      DAT_CLOSE_FLAGS );      /* close_flags */\r
+\r
+extern DAT_RETURN DAT_API dapl_ep_post_send (\r
+       IN      DAT_EP_HANDLE,          /* ep_handle */\r
+       IN      DAT_COUNT,              /* num_segments */\r
+       IN      DAT_LMR_TRIPLET *,      /* local_iov */\r
+       IN      DAT_DTO_COOKIE,         /* user_cookie */\r
+       IN      DAT_COMPLETION_FLAGS ); /* completion_flags */\r
+\r
+extern DAT_RETURN DAT_API dapl_ep_post_recv (\r
+       IN      DAT_EP_HANDLE,          /* ep_handle */\r
+       IN      DAT_COUNT,              /* num_segments */\r
+       IN      DAT_LMR_TRIPLET *,      /* local_iov */\r
+       IN      DAT_DTO_COOKIE,         /* user_cookie */\r
+       IN      DAT_COMPLETION_FLAGS ); /* completion_flags */\r
+\r
+extern DAT_RETURN DAT_API dapl_ep_post_rdma_read (\r
+       IN      DAT_EP_HANDLE,           /* ep_handle */\r
+       IN      DAT_COUNT,               /* num_segments */\r
+       IN      DAT_LMR_TRIPLET *,       /* local_iov */\r
+       IN      DAT_DTO_COOKIE,          /* user_cookie */\r
+       IN      const DAT_RMR_TRIPLET *, /* remote_iov */\r
+       IN      DAT_COMPLETION_FLAGS );  /* completion_flags */\r
+\r
+extern DAT_RETURN DAT_API dapl_ep_post_rdma_read_to_rmr (\r
+       IN      DAT_EP_HANDLE,          /* ep_handle            */\r
+       IN      const DAT_RMR_TRIPLET *,/* local_iov            */\r
+       IN      DAT_DTO_COOKIE,         /* user_cookie          */\r
+       IN      const DAT_RMR_TRIPLET *,/* remote_iov           */\r
+       IN      DAT_COMPLETION_FLAGS);  /* completion_flags     */\r
+\r
+extern DAT_RETURN DAT_API dapl_ep_post_rdma_write (\r
+       IN      DAT_EP_HANDLE,           /* ep_handle */\r
+       IN      DAT_COUNT,               /* num_segments */\r
+       IN      DAT_LMR_TRIPLET *,       /* local_iov */\r
+       IN      DAT_DTO_COOKIE,          /* user_cookie */\r
+       IN      const DAT_RMR_TRIPLET *, /* remote_iov */\r
+       IN      DAT_COMPLETION_FLAGS );  /* completion_flags */\r
+\r
+extern DAT_RETURN DAT_API dapl_ep_post_send_with_invalidate (\r
+       IN      DAT_EP_HANDLE,          /* ep_handle            */\r
+       IN      DAT_COUNT,              /* num_segments         */\r
+       IN      DAT_LMR_TRIPLET *,      /* local_iov            */\r
+       IN      DAT_DTO_COOKIE,         /* user_cookie          */\r
+       IN      DAT_COMPLETION_FLAGS,   /* completion_flags     */\r
+       IN      DAT_BOOLEAN,            /* invalidate_flag      */\r
+       IN      DAT_RMR_CONTEXT);      /* RMR context          */\r
+\r
+extern DAT_RETURN DAT_API dapl_ep_get_status (\r
+       IN      DAT_EP_HANDLE,          /* ep_handle */\r
+       OUT     DAT_EP_STATE *,         /* ep_state */\r
+       OUT     DAT_BOOLEAN *,          /* in_dto_idle */\r
+       OUT     DAT_BOOLEAN * );        /* out_dto_idle */\r
+\r
+extern DAT_RETURN DAT_API dapl_ep_free (\r
+       IN      DAT_EP_HANDLE);         /* ep_handle */\r
+\r
+extern DAT_RETURN DAT_API dapl_ep_reset (\r
+       IN      DAT_EP_HANDLE);         /* ep_handle */\r
+\r
+extern DAT_RETURN DAT_API dapl_ep_create_with_srq (\r
+        IN      DAT_IA_HANDLE,          /* ia_handle            */\r
+        IN      DAT_PZ_HANDLE,          /* pz_handle            */\r
+        IN      DAT_EVD_HANDLE,         /* recv_evd_handle      */\r
+        IN      DAT_EVD_HANDLE,         /* request_evd_handle   */\r
+        IN      DAT_EVD_HANDLE,         /* connect_evd_handle   */\r
+        IN      DAT_SRQ_HANDLE,         /* srq_handle           */\r
+        IN      const DAT_EP_ATTR *,    /* ep_attributes        */\r
+        OUT     DAT_EP_HANDLE *);       /* ep_handle            */\r
+\r
+extern DAT_RETURN DAT_API dapl_ep_recv_query (\r
+        IN      DAT_EP_HANDLE,          /* ep_handle            */\r
+        OUT     DAT_COUNT *,            /* nbufs_allocated      */\r
+        OUT     DAT_COUNT *);           /* bufs_alloc_span      */\r
+\r
+extern DAT_RETURN DAT_API dapl_ep_set_watermark (\r
+        IN      DAT_EP_HANDLE,          /* ep_handle            */\r
+        IN      DAT_COUNT,              /* soft_high_watermark  */\r
+        IN      DAT_COUNT);             /* hard_high_watermark  */\r
+\r
+/* LMR functions */\r
+\r
+#if defined(__KERNEL__)\r
+extern DAT_RETURN DAT_API dapl_lmr_kcreate (\r
+       IN      DAT_IA_HANDLE,          /* ia_handle */\r
+       IN      DAT_MEM_TYPE,           /* mem_type */\r
+       IN      DAT_REGION_DESCRIPTION, /* region_description */\r
+       IN      DAT_VLEN,               /* length */\r
+       IN      DAT_PZ_HANDLE,          /* pz_handle */\r
+       IN      DAT_MEM_PRIV_FLAGS,     /* privileges */\r
+       IN      DAT_VA_TYPE,            /* va_type */\r
+       IN      DAT_MEM_OPT,            /* optimization */\r
+       OUT     DAT_LMR_HANDLE *,       /* lmr_handle */\r
+       OUT     DAT_LMR_CONTEXT *,      /* lmr_context */\r
+       OUT     DAT_RMR_CONTEXT *,      /* rmr_context          */\r
+       OUT     DAT_VLEN *,             /* registered_length */\r
+       OUT     DAT_VADDR * );          /* registered_address */\r
+#else\r
+extern DAT_RETURN DAT_API dapl_lmr_create (\r
+       IN      DAT_IA_HANDLE,          /* ia_handle */\r
+       IN      DAT_MEM_TYPE,           /* mem_type */\r
+       IN      DAT_REGION_DESCRIPTION, /* region_description */\r
+       IN      DAT_VLEN,               /* length */\r
+       IN      DAT_PZ_HANDLE,          /* pz_handle */\r
+       IN      DAT_MEM_PRIV_FLAGS,     /* privileges */\r
+       IN      DAT_VA_TYPE,            /* va_type */\r
+       OUT     DAT_LMR_HANDLE *,       /* lmr_handle */\r
+       OUT     DAT_LMR_CONTEXT *,      /* lmr_context */\r
+       OUT     DAT_RMR_CONTEXT *,      /* rmr_context          */\r
+       OUT     DAT_VLEN *,             /* registered_length */\r
+       OUT     DAT_VADDR * );          /* registered_address */\r
+#endif /* defined(__KERNEL__) */\r
+\r
+extern DAT_RETURN DAT_API dapl_lmr_query (\r
+       IN      DAT_LMR_HANDLE,\r
+       IN      DAT_LMR_PARAM_MASK,\r
+       OUT     DAT_LMR_PARAM *);\r
+\r
+extern DAT_RETURN DAT_API dapl_lmr_free (\r
+       IN      DAT_LMR_HANDLE);\r
+\r
+extern DAT_RETURN DAT_API dapl_lmr_sync_rdma_read (\r
+       IN      DAT_IA_HANDLE,          /* ia_handle            */\r
+       IN      const DAT_LMR_TRIPLET *, /* local_segments      */\r
+       IN      DAT_VLEN);              /* num_segments         */\r
+\r
+extern DAT_RETURN DAT_API dapl_lmr_sync_rdma_write (\r
+       IN      DAT_IA_HANDLE,          /* ia_handle            */\r
+       IN      const DAT_LMR_TRIPLET *, /* local_segments      */\r
+       IN      DAT_VLEN);              /* num_segments         */\r
+\r
+/* RMR Functions */\r
+\r
+extern DAT_RETURN DAT_API dapl_rmr_create (\r
+       IN      DAT_PZ_HANDLE,          /* pz_handle */\r
+       OUT     DAT_RMR_HANDLE *);      /* rmr_handle */\r
+\r
+extern DAT_RETURN DAT_API dapl_rmr_create_for_ep (\r
+       IN      DAT_PZ_HANDLE pz_handle,        /* pz_handle    */\r
+       OUT     DAT_RMR_HANDLE *rmr_handle);    /* rmr_handle   */\r
+\r
+extern DAT_RETURN DAT_API dapl_rmr_query (\r
+       IN      DAT_RMR_HANDLE,         /* rmr_handle */\r
+       IN      DAT_RMR_PARAM_MASK,     /* rmr_args_mask */\r
+       OUT     DAT_RMR_PARAM *);       /* rmr_args */\r
+\r
+extern DAT_RETURN DAT_API dapl_rmr_bind (\r
+       IN      DAT_RMR_HANDLE,          /* rmr_handle */\r
+       IN      DAT_LMR_HANDLE,          /* lmr_handle */\r
+       IN      const DAT_LMR_TRIPLET *, /* lmr_triplet */\r
+       IN      DAT_MEM_PRIV_FLAGS,      /* mem_priv */\r
+       IN      DAT_VA_TYPE,             /* va_type */\r
+       IN      DAT_EP_HANDLE,           /* ep_handle */\r
+       IN      DAT_RMR_COOKIE,          /* user_cookie */\r
+       IN      DAT_COMPLETION_FLAGS,    /* completion_flags */\r
+       INOUT   DAT_RMR_CONTEXT * );     /* context */\r
+\r
+extern DAT_RETURN DAT_API dapl_rmr_free (\r
+       IN      DAT_RMR_HANDLE);\r
+\r
+/* PSP Functions */\r
+\r
+extern DAT_RETURN DAT_API dapl_psp_create (\r
+       IN      DAT_IA_HANDLE,          /* ia_handle */\r
+       IN      DAT_CONN_QUAL,          /* conn_qual */\r
+       IN      DAT_EVD_HANDLE,         /* evd_handle */\r
+       IN      DAT_PSP_FLAGS,          /* psp_flags */\r
+       OUT     DAT_PSP_HANDLE * );     /* psp_handle */\r
+\r
+extern DAT_RETURN DAT_API dapl_psp_create_any (\r
+       IN      DAT_IA_HANDLE,          /* ia_handle */\r
+       OUT     DAT_CONN_QUAL *,        /* conn_qual */\r
+       IN      DAT_EVD_HANDLE,         /* evd_handle */\r
+       IN      DAT_PSP_FLAGS,          /* psp_flags */\r
+       OUT     DAT_PSP_HANDLE *);      /* psp_handle */\r
+\r
+extern DAT_RETURN DAT_API dapl_psp_query (\r
+       IN      DAT_PSP_HANDLE,\r
+       IN      DAT_PSP_PARAM_MASK,\r
+       OUT     DAT_PSP_PARAM * );\r
+\r
+extern DAT_RETURN DAT_API dapl_psp_free (\r
+       IN      DAT_PSP_HANDLE );       /* psp_handle */\r
+\r
+/* RSP Functions */\r
+\r
+extern DAT_RETURN DAT_API dapl_rsp_create (\r
+       IN      DAT_IA_HANDLE,          /* ia_handle */\r
+       IN      DAT_CONN_QUAL,          /* conn_qual */\r
+       IN      DAT_EP_HANDLE,          /* ep_handle */\r
+       IN      DAT_EVD_HANDLE,         /* evd_handle */\r
+       OUT     DAT_RSP_HANDLE * );     /* rsp_handle */\r
+\r
+extern DAT_RETURN DAT_API dapl_rsp_query (\r
+       IN      DAT_RSP_HANDLE,\r
+       IN      DAT_RSP_PARAM_MASK,\r
+       OUT     DAT_RSP_PARAM * );\r
+\r
+extern DAT_RETURN DAT_API dapl_rsp_free (\r
+       IN      DAT_RSP_HANDLE );       /* rsp_handle */\r
+\r
+/* PZ Functions */\r
+\r
+extern DAT_RETURN DAT_API dapl_pz_create (\r
+       IN      DAT_IA_HANDLE,          /* ia_handle */\r
+       OUT     DAT_PZ_HANDLE * );      /* pz_handle */\r
+\r
+extern DAT_RETURN DAT_API dapl_pz_query (\r
+       IN      DAT_PZ_HANDLE,          /* pz_handle */\r
+       IN      DAT_PZ_PARAM_MASK,      /* pz_args_mask */\r
+       OUT     DAT_PZ_PARAM * );       /* pz_args */\r
+\r
+extern DAT_RETURN DAT_API dapl_pz_free (\r
+       IN      DAT_PZ_HANDLE );        /* pz_handle */\r
+\r
+/* SRQ functions */\r
+\r
+extern DAT_RETURN DAT_API dapl_srq_create (\r
+        IN      DAT_IA_HANDLE,          /* ia_handle            */\r
+        IN      DAT_PZ_HANDLE,          /* pz_handle            */\r
+        IN      DAT_SRQ_ATTR *,         /* srq_attr             */\r
+        OUT     DAT_SRQ_HANDLE *);      /* srq_handle           */\r
+\r
+extern DAT_RETURN DAT_API dapl_srq_free (\r
+       IN      DAT_SRQ_HANDLE);        /* srq_handle           */\r
+\r
+extern DAT_RETURN DAT_API dapl_srq_post_recv (\r
+       IN      DAT_SRQ_HANDLE,         /* srq_handle           */\r
+       IN      DAT_COUNT,              /* num_segments         */\r
+       IN      DAT_LMR_TRIPLET *,      /* local_iov            */\r
+       IN      DAT_DTO_COOKIE);        /* user_cookie          */\r
+\r
+extern DAT_RETURN DAT_API dapl_srq_query (\r
+       IN      DAT_SRQ_HANDLE,         /* srq_handle           */\r
+       IN      DAT_SRQ_PARAM_MASK,     /* srq_param_mask       */\r
+       OUT     DAT_SRQ_PARAM *);       /* srq_param            */\r
+\r
+extern DAT_RETURN DAT_API dapl_srq_resize (\r
+       IN      DAT_SRQ_HANDLE,         /* srq_handle           */\r
+       IN      DAT_COUNT);             /* srq_max_recv_dto     */\r
+\r
+extern DAT_RETURN DAT_API dapl_srq_set_lw (\r
+       IN      DAT_SRQ_HANDLE,         /* srq_handle           */\r
+       IN      DAT_COUNT);             /* low_watermark        */\r
+\r
+/* CSP functions */\r
+extern DAT_RETURN DAT_API dapl_csp_create (\r
+       IN      DAT_IA_HANDLE,          /* ia_handle      */\r
+       IN      DAT_COMM *,             /* communicator   */\r
+       IN      DAT_IA_ADDRESS_PTR,     /* address        */\r
+       IN      DAT_EVD_HANDLE,         /* evd_handle     */\r
+       OUT     DAT_CSP_HANDLE *);      /* csp_handle     */\r
+\r
+extern DAT_RETURN DAT_API dapl_csp_query (\r
+       IN      DAT_CSP_HANDLE,         /* csp_handle     */\r
+       IN      DAT_CSP_PARAM_MASK,     /* csp_param_mask */\r
+       OUT     DAT_CSP_PARAM *);       /* csp_param      */\r
+\r
+extern DAT_RETURN DAT_API dapl_csp_free (\r
+       IN      DAT_CSP_HANDLE);        /* csp_handle     */\r
+\r
+/* HA functions */\r
+DAT_RETURN DAT_API dapl_ia_ha (\r
+       IN       DAT_IA_HANDLE,         /* ia_handle */\r
+       IN const DAT_NAME_PTR,          /* provider  */\r
+       OUT      DAT_BOOLEAN *);        /* answer    */\r
+\r
+#ifdef DAT_EXTENSIONS\r
+#include <stdarg.h>\r
+extern DAT_RETURN DAT_API dapl_extensions (\r
+       IN      DAT_HANDLE,             /* handle */\r
+       IN      DAT_EXTENDED_OP,        /* extended op */\r
+       IN      va_list);               /* argument list */\r
+#endif\r
+\r
+/*\r
+ * DAPL internal utility function prototpyes\r
+ */\r
+\r
+extern void dapl_llist_init_head (\r
+    DAPL_LLIST_HEAD *  head);\r
+\r
+extern void dapl_llist_init_entry (\r
+    DAPL_LLIST_ENTRY *         entry);\r
+\r
+extern DAT_BOOLEAN dapl_llist_is_empty (\r
+    DAPL_LLIST_HEAD *  head);\r
+\r
+extern void dapl_llist_add_head (\r
+    DAPL_LLIST_HEAD *  head,\r
+    DAPL_LLIST_ENTRY *         entry,\r
+    void *             data);\r
+\r
+extern void dapl_llist_add_tail (\r
+    DAPL_LLIST_HEAD *   head,\r
+    DAPL_LLIST_ENTRY *  entry,\r
+    void *             data);\r
+\r
+extern void dapl_llist_add_entry (\r
+    DAPL_LLIST_HEAD * head,\r
+    DAPL_LLIST_ENTRY * entry,\r
+    DAPL_LLIST_ENTRY * new_entry,\r
+    void * data);\r
+\r
+extern void * dapl_llist_remove_head (\r
+    DAPL_LLIST_HEAD *  head);\r
+\r
+extern void * dapl_llist_remove_tail (\r
+    DAPL_LLIST_HEAD *  head);\r
+\r
+extern void * dapl_llist_remove_entry (\r
+    DAPL_LLIST_HEAD *  head,\r
+    DAPL_LLIST_ENTRY * entry);\r
+\r
+extern void * dapl_llist_peek_head (\r
+    DAPL_LLIST_HEAD *  head);\r
+\r
+extern void * dapl_llist_next_entry (\r
+    IN    DAPL_LLIST_HEAD      *head,\r
+    IN    DAPL_LLIST_ENTRY     *cur_ent);\r
+\r
+extern void dapl_llist_debug_print_list (\r
+    DAPL_LLIST_HEAD *  head);\r
+\r
+\r
+#endif\r
index f466c0680813be0c83dc388c91b6b1923da487bb..698ee52756ae671b2c0a237784b03ca2ec4b20ca 100644 (file)
-/*
- * Copyright (c) 2005-2009 Intel Corporation.  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.
- */
-/* 
- * Definitions specific to OpenIB CMA provider.
- *   Connection manager - rdma_cma, provided in separate library.
- */
-#ifndef _DAPL_IB_UTIL_H_
-#define _DAPL_IB_UTIL_H_
-#define _OPENIB_CMA_ 
-
-#include <infiniband/verbs.h>
-#include <rdma/rdma_cma.h>
-#include "openib_osd.h"
-#include "dapl_ib_common.h"
-
-#define IB_RC_RETRY_COUNT      7
-#define IB_RNR_RETRY_COUNT     7
-#define IB_CM_RESPONSE_TIMEOUT  23     /* 16 sec */
-#define IB_CM_RETRIES           15     /* 240 sec total default */
-#define IB_ARP_TIMEOUT         4000    /* 4 sec */
-#define IB_ARP_RETRY_COUNT     15      /* 60 sec total */
-#define IB_ROUTE_TIMEOUT       4000    /* 4 sec */
-#define IB_ROUTE_RETRY_COUNT   15      /* 60 sec total */
-#define IB_MAX_AT_RETRY                3
-
-/* CMA private data areas */
-#define CMA_PDATA_HDR          36
-#define        IB_MAX_REQ_PDATA_SIZE   (92-CMA_PDATA_HDR)
-#define        IB_MAX_REP_PDATA_SIZE   (196-CMA_PDATA_HDR)
-#define        IB_MAX_REJ_PDATA_SIZE   (148-CMA_PDATA_HDR)
-#define        IB_MAX_DREQ_PDATA_SIZE  (220-CMA_PDATA_HDR)
-#define        IB_MAX_DREP_PDATA_SIZE  (224-CMA_PDATA_HDR)
-#define        IWARP_MAX_PDATA_SIZE    (512-CMA_PDATA_HDR)
-
-struct dapl_cm_id {
-       DAPL_OS_LOCK                    lock;
-       int                             destroy;
-       int                             arp_retries;
-       int                             arp_timeout;
-       int                             route_retries;
-       int                             route_timeout;
-       int                             in_callback;
-       struct rdma_cm_id               *cm_id;
-       struct dapl_hca                 *hca;
-       struct dapl_sp                  *sp;
-       struct dapl_ep                  *ep;
-       struct rdma_conn_param          params;
-       DAT_SOCK_ADDR6                  r_addr;
-       int                             p_len;
-       unsigned char                   p_data[256]; /* dapl max private data size */
-       ib_qp_cm_t                      dst; /* dapls_modify_qp_state */
-       struct ibv_ah                   *ah; /* dapls_modify_qp_state */
-};
-
-typedef struct dapl_cm_id      *dp_ib_cm_handle_t;
-typedef struct dapl_cm_id      *ib_cm_srvc_handle_t;
-
-/* ib_hca_transport_t, specific to this implementation */
-typedef struct _ib_hca_transport
-{ 
-       struct dapl_llist_entry entry;
-       int                     destroy;
-       struct dapl_hca         *d_hca;
-       struct rdma_cm_id       *cm_id;
-       struct ibv_comp_channel *ib_cq;
-       ib_cq_handle_t          ib_cq_empty;
-       int                     max_inline_send;
-       ib_async_handler_t      async_unafiliated;
-       void                    *async_un_ctx;
-       ib_async_cq_handler_t   async_cq_error;
-       ib_async_dto_handler_t  async_cq;
-       ib_async_qp_handler_t   async_qp_error;
-       uint8_t                 max_cm_timeout;
-       uint8_t                 max_cm_retries;
-       /* device attributes */
-       int                     rd_atom_in;
-       int                     rd_atom_out;
-       struct  ibv_device      *ib_dev;
-       /* dapls_modify_qp_state */
-       uint16_t                lid;
-       uint8_t                 ack_timer;
-       uint8_t                 ack_retry;
-       uint8_t                 rnr_timer;
-       uint8_t                 rnr_retry;
-       uint8_t                 global;
-       uint8_t                 hop_limit;
-       uint8_t                 tclass;
-       uint8_t                 mtu;
-       DAT_NAMED_ATTR          named_attr;
-
-} ib_hca_transport_t;
-
-/* prototypes */
-void dapli_thread(void *arg);
-DAT_RETURN  dapli_ib_thread_init(void);
-void dapli_ib_thread_destroy(void);
-void dapli_cma_event_cb(void);
-void dapli_async_event_cb(struct _ib_hca_transport *hca);
-dp_ib_cm_handle_t dapls_ib_cm_create(DAPL_EP *ep);
-void dapls_ib_cm_free(dp_ib_cm_handle_t cm, DAPL_EP *ep);
-DAT_RETURN dapls_modify_qp_state(IN ib_qp_handle_t qp_handle,
-                                IN ib_qp_state_t qp_state,
-                                IN dp_ib_cm_handle_t cm);
-
-STATIC _INLINE_ void dapls_print_cm_list(IN DAPL_IA * ia_ptr)
-{
-       return;
-}
-
-#endif /*  _DAPL_IB_UTIL_H_ */
+/*\r
+ * Copyright (c) 2005-2009 Intel Corporation.  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
+ * Definitions specific to OpenIB CMA provider.\r
+ *   Connection manager - rdma_cma, provided in separate library.\r
+ */\r
+#ifndef _DAPL_IB_UTIL_H_\r
+#define _DAPL_IB_UTIL_H_\r
+#define _OPENIB_CMA_ \r
+\r
+#include <infiniband/verbs.h>\r
+#include <rdma/rdma_cma.h>\r
+#include "openib_osd.h"\r
+#include "dapl_ib_common.h"\r
+\r
+#define IB_RC_RETRY_COUNT      7\r
+#define IB_RNR_RETRY_COUNT     7\r
+#define IB_CM_RESPONSE_TIMEOUT  23     /* 16 sec */\r
+#define IB_CM_RETRIES           15     /* 240 sec total default */\r
+#define IB_ARP_TIMEOUT         4000    /* 4 sec */\r
+#define IB_ARP_RETRY_COUNT     15      /* 60 sec total */\r
+#define IB_ROUTE_TIMEOUT       4000    /* 4 sec */\r
+#define IB_ROUTE_RETRY_COUNT   15      /* 60 sec total */\r
+#define IB_MAX_AT_RETRY                3\r
+\r
+/* CMA private data areas */\r
+#define CMA_PDATA_HDR          36\r
+#define        IB_MAX_REQ_PDATA_SIZE   (92-CMA_PDATA_HDR)\r
+#define        IB_MAX_REP_PDATA_SIZE   (196-CMA_PDATA_HDR)\r
+#define        IB_MAX_REJ_PDATA_SIZE   (148-CMA_PDATA_HDR)\r
+#define        IB_MAX_DREQ_PDATA_SIZE  (220-CMA_PDATA_HDR)\r
+#define        IB_MAX_DREP_PDATA_SIZE  (224-CMA_PDATA_HDR)\r
+#define        IWARP_MAX_PDATA_SIZE    (512-CMA_PDATA_HDR)\r
+\r
+struct dapl_cm_id {\r
+       DAPL_OS_LOCK                    lock;\r
+       int                             destroy;\r
+       int                             arp_retries;\r
+       int                             arp_timeout;\r
+       int                             route_retries;\r
+       int                             route_timeout;\r
+       int                             in_callback;\r
+       struct rdma_cm_id               *cm_id;\r
+       struct dapl_hca                 *hca;\r
+       struct dapl_sp                  *sp;\r
+       struct dapl_ep                  *ep;\r
+       struct rdma_conn_param          params;\r
+       DAT_SOCK_ADDR6                  r_addr;\r
+       int                             p_len;\r
+       unsigned char                   p_data[256]; /* dapl max private data size */\r
+       ib_qp_cm_t                      dst; /* dapls_modify_qp_state */\r
+       struct ibv_ah                   *ah; /* dapls_modify_qp_state */\r
+};\r
+\r
+typedef struct dapl_cm_id      *dp_ib_cm_handle_t;\r
+typedef struct dapl_cm_id      *ib_cm_srvc_handle_t;\r
+\r
+/* ib_hca_transport_t, specific to this implementation */\r
+typedef struct _ib_hca_transport\r
+{ \r
+       struct dapl_llist_entry entry;\r
+       int                     destroy;\r
+       struct rdma_cm_id       *cm_id;\r
+       struct ibv_comp_channel *ib_cq;\r
+       ib_cq_handle_t          ib_cq_empty;\r
+       int                     max_inline_send;\r
+       ib_async_handler_t      async_unafiliated;\r
+       void                    *async_un_ctx;\r
+       ib_async_cq_handler_t   async_cq_error;\r
+       ib_async_dto_handler_t  async_cq;\r
+       ib_async_qp_handler_t   async_qp_error;\r
+       uint8_t                 max_cm_timeout;\r
+       uint8_t                 max_cm_retries;\r
+       /* device attributes */\r
+       int                     rd_atom_in;\r
+       int                     rd_atom_out;\r
+       struct  ibv_context     *ib_ctx;\r
+       struct  ibv_device      *ib_dev;\r
+       /* dapls_modify_qp_state */\r
+       uint16_t                lid;\r
+       uint8_t                 ack_timer;\r
+       uint8_t                 ack_retry;\r
+       uint8_t                 rnr_timer;\r
+       uint8_t                 rnr_retry;\r
+       uint8_t                 global;\r
+       uint8_t                 hop_limit;\r
+       uint8_t                 tclass;\r
+       uint8_t                 mtu;\r
+       DAT_NAMED_ATTR          named_attr;\r
+\r
+} ib_hca_transport_t;\r
+\r
+/* prototypes */\r
+void dapli_thread(void *arg);\r
+DAT_RETURN  dapli_ib_thread_init(void);\r
+void dapli_ib_thread_destroy(void);\r
+void dapli_cma_event_cb(void);\r
+void dapli_async_event_cb(struct _ib_hca_transport *tp);\r
+void dapli_cq_event_cb(struct _ib_hca_transport *tp);\r
+dp_ib_cm_handle_t dapls_ib_cm_create(DAPL_EP *ep);\r
+void dapls_ib_cm_free(dp_ib_cm_handle_t cm, DAPL_EP *ep);\r
+DAT_RETURN dapls_modify_qp_state(IN ib_qp_handle_t qp_handle,\r
+                                IN ib_qp_state_t qp_state,\r
+                                IN dp_ib_cm_handle_t cm);\r
+\r
+STATIC _INLINE_ void dapls_print_cm_list(IN DAPL_IA * ia_ptr)\r
+{\r
+       return;\r
+}\r
+\r
+#endif /*  _DAPL_IB_UTIL_H_ */\r
index 3c9d13543544aaccf14a393e623cfdc2bd7a83ae..0e7396ef7509b1ad169fbc0229948be406c0dc9e 100644 (file)
@@ -123,6 +123,12 @@ static int dapls_config_verbs(struct ibv_context *verbs)
        return 0;\r
 }\r
 \r
+static int dapls_config_comp_channel(struct ibv_comp_channel *channel)\r
+{\r
+       channel->comp_channel.Milliseconds = 0;\r
+       return 0;\r
+}\r
+\r
 static int dapls_thread_signal(void)\r
 {\r
        CompManagerCancel(windata.comp_mgr);\r
@@ -205,6 +211,11 @@ static int dapls_config_verbs(struct ibv_context *verbs)
        return dapls_config_fd(verbs->async_fd);\r
 }\r
 \r
+static int dapls_config_comp_channel(struct ibv_comp_channel *channel)\r
+{\r
+       return dapls_config_fd(channel->fd);\r
+}\r
+\r
 static int dapls_thread_signal(void)\r
 {\r
        return write(g_ib_pipe[1], "w", sizeof "w");\r
@@ -334,10 +345,6 @@ DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr)
        dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
                     " open_hca: RDMA channel created (%p)\n", g_cm_events);\r
 \r
-       dat_status = dapli_ib_thread_init();\r
-       if (dat_status != DAT_SUCCESS)\r
-               return dat_status;\r
-\r
        /* HCA name will be hostname or IP address */\r
        if (getipaddr((char *)hca_name,\r
                      (char *)&hca_ptr->hca_address, \r
@@ -357,6 +364,7 @@ DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr)
                dapl_log(DAPL_DBG_TYPE_ERR,\r
                         " open_hca: rdma_bind ERR %s."\r
                         " Is %s configured?\n", strerror(errno), hca_name);\r
+               rdma_destroy_id(cm_id);\r
                return DAT_INVALID_ADDRESS;\r
        }\r
 \r
@@ -366,6 +374,7 @@ DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr)
        dapls_config_verbs(cm_id->verbs);\r
        hca_ptr->port_num = cm_id->port_num;\r
        hca_ptr->ib_trans.ib_dev = cm_id->verbs->device;\r
+       hca_ptr->ib_trans.ib_ctx = cm_id->verbs;\r
        gid = &cm_id->route.addr.addr.ibaddr.sgid;\r
 \r
        dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
@@ -374,6 +383,21 @@ DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr)
                     (unsigned long long)ntohll(gid->global.subnet_prefix),\r
                     (unsigned long long)ntohll(gid->global.interface_id));\r
 \r
+       /* support for EVD's with CNO's: one channel via thread */\r
+       hca_ptr->ib_trans.ib_cq =\r
+           ibv_create_comp_channel(hca_ptr->ib_hca_handle);\r
+       if (hca_ptr->ib_trans.ib_cq == NULL) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " open_hca: ibv_create_comp_channel ERR %s\n",\r
+                        strerror(errno));\r
+               rdma_destroy_id(cm_id);\r
+               return DAT_INTERNAL_ERROR;\r
+       }\r
+       if (dapls_config_comp_channel(hca_ptr->ib_trans.ib_cq)) {\r
+               rdma_destroy_id(cm_id);\r
+               return DAT_INTERNAL_ERROR;\r
+       }\r
+\r
        /* set inline max with env or default, get local lid and gid 0 */\r
        if (hca_ptr->ib_hca_handle->device->transport_type\r
            == IBV_TRANSPORT_IWARP)\r
@@ -395,14 +419,17 @@ DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr)
        /* set default IB MTU */\r
        hca_ptr->ib_trans.mtu = dapl_ib_mtu(2048);\r
 \r
+       dat_status = dapli_ib_thread_init();\r
+       if (dat_status != DAT_SUCCESS)\r
+               return dat_status;\r
        /* \r
         * Put new hca_transport on list for async and CQ event processing \r
         * Wakeup work thread to add to polling list\r
         */\r
-       dapl_llist_init_entry((DAPL_LLIST_ENTRY *) & hca_ptr->ib_trans.entry);\r
+       dapl_llist_init_entry((DAPL_LLIST_ENTRY *) &hca_ptr->ib_trans.entry);\r
        dapl_os_lock(&g_hca_lock);\r
        dapl_llist_add_tail(&g_hca_list,\r
-                           (DAPL_LLIST_ENTRY *) & hca_ptr->ib_trans.entry,\r
+                           (DAPL_LLIST_ENTRY *) &hca_ptr->ib_trans.entry,\r
                            &hca_ptr->ib_trans.entry);\r
        if (dapls_thread_signal() == -1)\r
                dapl_log(DAPL_DBG_TYPE_UTIL,\r
@@ -425,7 +452,6 @@ DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr)
                     &hca_ptr->hca_address)->sin_addr.s_addr >> 24 & 0xff, \r
                     hca_ptr->ib_trans.max_inline_send);\r
 \r
-       hca_ptr->ib_trans.d_hca = hca_ptr;\r
        return DAT_SUCCESS;\r
 }\r
 \r
@@ -574,105 +600,6 @@ bail:
                     " ib_thread_destroy(%d) exit\n", dapl_os_getpid());\r
 }\r
 \r
-void dapli_async_event_cb(struct _ib_hca_transport *hca)\r
-{\r
-       struct ibv_async_event event;\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " async_event(%p)\n", hca);\r
-\r
-       if (hca->destroy)\r
-               return;\r
-\r
-       if (!ibv_get_async_event(hca->cm_id->verbs, &event)) {\r
-\r
-               switch (event.event_type) {\r
-               case IBV_EVENT_CQ_ERR:\r
-               {\r
-                       struct dapl_ep *evd_ptr =\r
-                               event.element.cq->cq_context;\r
-\r
-                       dapl_log(DAPL_DBG_TYPE_ERR,\r
-                                "dapl async_event CQ (%p) ERR %d\n",\r
-                                evd_ptr, event.event_type);\r
-\r
-                       /* report up if async callback still setup */\r
-                       if (hca->async_cq_error)\r
-                               hca->async_cq_error(hca->cm_id->verbs,\r
-                                                       event.element.cq,\r
-                                                       &event,\r
-                                                       (void *)evd_ptr);\r
-                       break;\r
-               }\r
-               case IBV_EVENT_COMM_EST:\r
-               {\r
-                       /* Received msgs on connected QP before RTU */\r
-                       dapl_log(DAPL_DBG_TYPE_UTIL,\r
-                                " async_event COMM_EST(%p) rdata beat RTU\n",\r
-                                event.element.qp);\r
-\r
-                       break;\r
-               }\r
-               case IBV_EVENT_QP_FATAL:\r
-               case IBV_EVENT_QP_REQ_ERR:\r
-               case IBV_EVENT_QP_ACCESS_ERR:\r
-               case IBV_EVENT_QP_LAST_WQE_REACHED:\r
-               case IBV_EVENT_SRQ_ERR:\r
-               case IBV_EVENT_SRQ_LIMIT_REACHED:\r
-               case IBV_EVENT_SQ_DRAINED:\r
-               {\r
-                       struct dapl_ep *ep_ptr =\r
-                               event.element.qp->qp_context;\r
-\r
-                       dapl_log(DAPL_DBG_TYPE_ERR,\r
-                                "dapl async_event QP (%p) ERR %d\n",\r
-                                ep_ptr, event.event_type);\r
-\r
-                       /* report up if async callback still setup */\r
-                       if (hca->async_qp_error)\r
-                               hca->async_qp_error(hca->cm_id->verbs,\r
-                                                   ep_ptr->qp_handle,\r
-                                                   &event,\r
-                                                   (void *)ep_ptr);\r
-                       break;\r
-               }\r
-               case IBV_EVENT_PATH_MIG:\r
-               case IBV_EVENT_PATH_MIG_ERR:\r
-               case IBV_EVENT_DEVICE_FATAL:\r
-               case IBV_EVENT_PORT_ACTIVE:\r
-               case IBV_EVENT_PORT_ERR:\r
-               case IBV_EVENT_LID_CHANGE:\r
-               case IBV_EVENT_PKEY_CHANGE:\r
-               case IBV_EVENT_SM_CHANGE:\r
-               {\r
-                       dapl_log(DAPL_DBG_TYPE_WARN,\r
-                                "dapl async_event: DEV ERR %d\n",\r
-                                event.event_type);\r
-\r
-                       /* report up if async callback still setup */\r
-                       if (hca->async_unafiliated)\r
-                               hca->async_unafiliated(hca->cm_id->\r
-                                                       verbs, &event,\r
-                                                       hca->\r
-                                                       async_un_ctx);\r
-                       break;\r
-               }\r
-               case IBV_EVENT_CLIENT_REREGISTER:\r
-                       /* no need to report this event this time */\r
-                       dapl_log(DAPL_DBG_TYPE_UTIL,\r
-                                " async_event: IBV_CLIENT_REREGISTER\n");\r
-                       break;\r
-\r
-               default:\r
-                       dapl_log(DAPL_DBG_TYPE_WARN,\r
-                                "dapl async_event: %d UNKNOWN\n",\r
-                                event.event_type);\r
-                       break;\r
-\r
-               }\r
-               ibv_ack_async_event(&event);\r
-       }\r
-}\r
-\r
 #if defined(_WIN64) || defined(_WIN32)\r
 /* work thread for uAT, uCM, CQ, and async events */\r
 void dapli_thread(void *arg)\r
@@ -721,6 +648,7 @@ void dapli_thread(void *arg)
                                dapl_os_unlock(&g_hca_lock);\r
                                uhca[idx]->destroy = 2;\r
                        } else {\r
+                               dapli_cq_event_cb(uhca[idx]);\r
                                dapli_async_event_cb(uhca[idx]);\r
                        }\r
                }\r
@@ -732,6 +660,7 @@ void dapli_thread(void *arg)
        dapl_os_unlock(&g_hca_lock);\r
 }\r
 #else                          // _WIN64 || WIN32\r
+\r
 /* work thread for uAT, uCM, CQ, and async events */\r
 void dapli_thread(void *arg)\r
 {\r
@@ -771,7 +700,13 @@ void dapli_thread(void *arg)
                while (hca) {\r
 \r
                        /* uASYNC events */\r
-                       ufds[++idx].fd = hca->cm_id->verbs->async_fd;\r
+                       ufds[++idx].fd = hca->ib_ctx->async_fd;\r
+                       ufds[idx].events = POLLIN;\r
+                       ufds[idx].revents = 0;\r
+                       uhca[idx] = hca;\r
+\r
+                       /* CQ events are non-direct with CNO's */\r
+                       ufds[++idx].fd = hca->ib_cq->fd;\r
                        ufds[idx].events = POLLIN;\r
                        ufds[idx].revents = 0;\r
                        uhca[idx] = hca;\r
@@ -809,9 +744,10 @@ void dapli_thread(void *arg)
                if (ufds[1].revents == POLLIN)\r
                        dapli_cma_event_cb();\r
 \r
-               /* check and process ASYNC events, per device */\r
+               /* check and process CQ and ASYNC events, per device */\r
                for (idx = 2; idx < fds; idx++) {\r
                        if (ufds[idx].revents == POLLIN) {\r
+                               dapli_cq_event_cb(uhca[idx]);\r
                                dapli_async_event_cb(uhca[idx]);\r
                        }\r
                }\r
@@ -824,7 +760,7 @@ void dapli_thread(void *arg)
                                         strerror(errno));\r
 \r
                        /* cleanup any device on list marked for destroy */\r
-                       for (idx = 2; idx < fds; idx++) {\r
+                       for (idx = 3; idx < fds; idx++) {\r
                                if (uhca[idx] && uhca[idx]->destroy == 1) {\r
                                        dapl_os_lock(&g_hca_lock);\r
                                        dapl_llist_remove_entry(\r
index aedfd7129d0df0778b607d6228207574988c9e54..451ecc418ee86932b51d2e08c88108f20ec491b4 100644 (file)
@@ -175,17 +175,27 @@ DAT_RETURN
 dapls_ib_cq_alloc(IN DAPL_IA * ia_ptr,\r
                  IN DAPL_EVD * evd_ptr, IN DAT_COUNT * cqlen)\r
 {\r
-       struct ibv_comp_channel *channel = evd_ptr->cq_wait_obj_handle;\r
+       struct ibv_comp_channel *channel;\r
+       DAT_RETURN ret;\r
 \r
        dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
                     "dapls_ib_cq_alloc: evd %p cqlen=%d \n", evd_ptr, *cqlen);\r
 \r
-       /* Call IB verbs to create CQ */\r
+       if (!evd_ptr->cno_ptr)\r
+               channel = ibv_create_comp_channel(ia_ptr->hca_ptr->ib_hca_handle);\r
+       else\r
+               channel = ia_ptr->hca_ptr->ib_trans.ib_cq;\r
+\r
+       if (!channel)\r
+               return DAT_INSUFFICIENT_RESOURCES;\r
+\r
        evd_ptr->ib_cq_handle = ibv_create_cq(ia_ptr->hca_ptr->ib_hca_handle,\r
                                              *cqlen, evd_ptr, channel, 0);\r
 \r
-       if (evd_ptr->ib_cq_handle == IB_INVALID_HANDLE)\r
-               return DAT_INSUFFICIENT_RESOURCES;\r
+       if (evd_ptr->ib_cq_handle == IB_INVALID_HANDLE) {\r
+               ret = DAT_INSUFFICIENT_RESOURCES;\r
+               goto err;\r
+       }\r
 \r
        /* arm cq for events */\r
        dapls_set_cq_notify(ia_ptr, evd_ptr);\r
@@ -198,17 +208,21 @@ dapls_ib_cq_alloc(IN DAPL_IA * ia_ptr,
                     evd_ptr->ib_cq_handle, *cqlen);\r
 \r
        return DAT_SUCCESS;\r
+\r
+err:\r
+       if (!evd_ptr->cno_ptr)\r
+               ibv_destroy_comp_channel(channel);\r
+       return ret;\r
 }\r
 \r
 /*\r
- * dapl_ib_cq_resize\r
+ * dapls_ib_cq_free\r
  *\r
- * Alloc a CQ\r
+ * destroy 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
@@ -218,50 +232,125 @@ dapls_ib_cq_alloc(IN DAPL_IA * ia_ptr,
  *     DAT_INVALID_PARAMETER\r
  *\r
  */\r
+DAT_RETURN dapls_ib_cq_free(IN DAPL_IA * ia_ptr, IN DAPL_EVD * evd_ptr)\r
+{\r
+       DAT_EVENT event;\r
+       ib_work_completion_t wc;\r
+       struct ibv_comp_channel *channel;\r
+\r
+       if (evd_ptr->ib_cq_handle != IB_INVALID_HANDLE) {\r
+               /* pull off CQ and EVD entries and toss */\r
+               while (ibv_poll_cq(evd_ptr->ib_cq_handle, 1, &wc) == 1) ;\r
+               while (dapl_evd_dequeue(evd_ptr, &event) == DAT_SUCCESS) ;\r
+\r
+               channel = evd_ptr->ib_cq_handle->channel;\r
+               if (ibv_destroy_cq(evd_ptr->ib_cq_handle))\r
+                       return (dapl_convert_errno(errno, "ibv_destroy_cq"));\r
+               if (!evd_ptr->cno_ptr)\r
+                       ibv_destroy_comp_channel(channel);\r
+               evd_ptr->ib_cq_handle = IB_INVALID_HANDLE;\r
+       }\r
+       return DAT_SUCCESS;\r
+}\r
+\r
 DAT_RETURN\r
-dapls_ib_cq_resize(IN DAPL_IA * ia_ptr,\r
-                  IN DAPL_EVD * evd_ptr, IN DAT_COUNT * cqlen)\r
+dapls_evd_dto_wakeup(IN DAPL_EVD * evd_ptr)\r
 {\r
-       ib_cq_handle_t new_cq;\r
-       struct ibv_comp_channel *channel = evd_ptr->cq_wait_obj_handle;\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " cq_object_wakeup: evd=%p\n", evd_ptr);\r
 \r
-       /* IB verbs DOES support resize. REDO THIS.\r
-        * Try to re-create CQ\r
-        * with new size. Can only be done if QP is not attached. \r
-        * destroy EBUSY == QP still attached.\r
-        */\r
+       /* no wake up mechanism */\r
+       return DAT_SUCCESS;\r
+}\r
 \r
-       /* Call IB verbs to create CQ */\r
-       new_cq = ibv_create_cq(ia_ptr->hca_ptr->ib_hca_handle, *cqlen,\r
-                              evd_ptr, channel, 0);\r
+#if defined(_WIN32)\r
+static int\r
+dapls_wait_comp_channel(IN struct ibv_comp_channel *channel, IN uint32_t timeout)\r
+{\r
+       channel->comp_channel.Milliseconds =\r
+               (timeout == DAT_TIMEOUT_INFINITE) ? INFINITE : timeout / 1000;\r
+       return 0;\r
+}\r
 \r
-       if (new_cq == IB_INVALID_HANDLE)\r
-               return DAT_INSUFFICIENT_RESOURCES;\r
+#else // WIN32\r
+\r
+static int\r
+dapls_wait_comp_channel(IN struct ibv_comp_channel *channel, IN uint32_t timeout)\r
+{\r
+       int status, timeout_ms;\r
+       struct pollfd cq_fd = {\r
+               .fd = channel->fd,\r
+               .events = POLLIN,\r
+               .revents = 0\r
+       };\r
+\r
+       /* uDAPL timeout values in usecs */\r
+       timeout_ms = (timeout == DAT_TIMEOUT_INFINITE) ? -1 : timeout / 1000;\r
+       status = poll(&cq_fd, 1, timeout_ms);\r
+       if (status > 0)\r
+               return 0;\r
+       else if (status == 0)\r
+               return ETIMEDOUT;\r
+       else\r
+               return status;\r
+}\r
+#endif\r
 \r
-       /* destroy the original and replace if successful */\r
-       if (ibv_destroy_cq(evd_ptr->ib_cq_handle)) {\r
-               ibv_destroy_cq(new_cq);\r
-               return (dapl_convert_errno(errno, "resize_cq"));\r
+DAT_RETURN\r
+dapls_evd_dto_wait(IN DAPL_EVD * evd_ptr, IN uint32_t timeout)\r
+{\r
+       struct ibv_comp_channel *channel = evd_ptr->ib_cq_handle->channel;\r
+       struct ibv_cq *ibv_cq = NULL;\r
+       void *context;\r
+       int status;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " cq_object_wait: EVD %p time %d\n",\r
+                    evd_ptr, timeout);\r
+\r
+       status = dapls_wait_comp_channel(channel, timeout);\r
+       if (!status) {\r
+               if (!ibv_get_cq_event(channel, &ibv_cq, &context)) {\r
+                       ibv_ack_cq_events(ibv_cq, 1);\r
+               }\r
        }\r
 \r
-       /* update EVD with new cq handle and size */\r
-       evd_ptr->ib_cq_handle = new_cq;\r
-       *cqlen = new_cq->cqe;\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " cq_object_wait: RET evd %p ibv_cq %p %s\n",\r
+                    evd_ptr, ibv_cq, strerror(errno));\r
 \r
-       /* arm cq for events */\r
-       dapls_set_cq_notify(ia_ptr, evd_ptr);\r
+       return dapl_convert_errno(status, "cq_wait_object_wait");\r
+}\r
 \r
-       return DAT_SUCCESS;\r
+void dapli_cq_event_cb(struct _ib_hca_transport *tp)\r
+{\r
+       /* check all comp events on this device */\r
+       struct dapl_evd *evd = NULL;\r
+       struct ibv_cq   *ibv_cq = NULL;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL," dapli_cq_event_cb(%p)\n", tp);\r
+\r
+       while (!ibv_get_cq_event(tp->ib_cq, &ibv_cq, (void*)&evd)) {\r
+\r
+               if (!DAPL_BAD_HANDLE(evd, DAPL_MAGIC_EVD)) {\r
+                       /* Both EVD or EVD->CNO event via callback */\r
+                       dapl_evd_dto_callback(tp->ib_ctx, \r
+                                             evd->ib_cq_handle, (void*)evd);\r
+               }\r
+\r
+               ibv_ack_cq_events(ibv_cq, 1);\r
+       } \r
 }\r
 \r
 /*\r
- * dapls_ib_cq_free\r
+ * dapl_ib_cq_resize\r
  *\r
- * destroy a CQ\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
@@ -271,20 +360,27 @@ dapls_ib_cq_resize(IN DAPL_IA * ia_ptr,
  *     DAT_INVALID_PARAMETER\r
  *\r
  */\r
-DAT_RETURN dapls_ib_cq_free(IN DAPL_IA * ia_ptr, IN DAPL_EVD * evd_ptr)\r
+DAT_RETURN\r
+dapls_ib_cq_resize(IN DAPL_IA * ia_ptr,\r
+                  IN DAPL_EVD * evd_ptr, IN DAT_COUNT * cqlen)\r
 {\r
-       DAT_EVENT event;\r
-       ib_work_completion_t wc;\r
+       ib_cq_handle_t old_cq, new_cq;\r
+       DAT_RETURN ret;\r
 \r
-       if (evd_ptr->ib_cq_handle != IB_INVALID_HANDLE) {\r
-               /* pull off CQ and EVD entries and toss */\r
-               while (ibv_poll_cq(evd_ptr->ib_cq_handle, 1, &wc) == 1) ;\r
-               while (dapl_evd_dequeue(evd_ptr, &event) == DAT_SUCCESS) ;\r
-               if (ibv_destroy_cq(evd_ptr->ib_cq_handle))\r
-                       return (dapl_convert_errno(errno, "ibv_destroy_cq"));\r
-               evd_ptr->ib_cq_handle = IB_INVALID_HANDLE;\r
-       }\r
+       old_cq = evd_ptr->ib_cq_handle;\r
+       ret = dapls_ib_cq_alloc(ia_ptr, evd_ptr, cqlen);\r
+       if (ret)\r
+               goto err;\r
+\r
+       new_cq = evd_ptr->ib_cq_handle;\r
+       evd_ptr->ib_cq_handle = old_cq;\r
+       dapls_ib_cq_free(ia_ptr, evd_ptr);\r
+       evd_ptr->ib_cq_handle = new_cq;\r
        return DAT_SUCCESS;\r
+\r
+err:\r
+       evd_ptr->ib_cq_handle = old_cq;\r
+       return ret;\r
 }\r
 \r
 /*\r
@@ -369,119 +465,6 @@ DAT_RETURN dapls_ib_completion_poll(IN DAPL_HCA * hca_ptr,
        return DAT_QUEUE_EMPTY;\r
 }\r
 \r
-/* NEW common wait objects for providers with direct CQ wait objects */\r
-DAT_RETURN\r
-dapls_ib_wait_object_create(IN DAPL_EVD * evd_ptr,\r
-                           IN ib_wait_obj_handle_t * p_cq_wait_obj_handle)\r
-{\r
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
-                    " cq_object_create: (%p,%p)\n",\r
-                    evd_ptr, p_cq_wait_obj_handle);\r
-\r
-       /* set cq_wait object to evd_ptr */\r
-       *p_cq_wait_obj_handle =\r
-           ibv_create_comp_channel(evd_ptr->header.owner_ia->hca_ptr->\r
-                                   ib_hca_handle);\r
-\r
-       return DAT_SUCCESS;\r
-}\r
-\r
-DAT_RETURN\r
-dapls_ib_wait_object_destroy(IN ib_wait_obj_handle_t p_cq_wait_obj_handle)\r
-{\r
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
-                    " cq_object_destroy: wait_obj=%p\n", p_cq_wait_obj_handle);\r
-\r
-       ibv_destroy_comp_channel(p_cq_wait_obj_handle);\r
-\r
-       return DAT_SUCCESS;\r
-}\r
-\r
-DAT_RETURN\r
-dapls_ib_wait_object_wakeup(IN ib_wait_obj_handle_t p_cq_wait_obj_handle)\r
-{\r
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
-                    " cq_object_wakeup: wait_obj=%p\n", p_cq_wait_obj_handle);\r
-\r
-       /* no wake up mechanism */\r
-       return DAT_SUCCESS;\r
-}\r
-\r
-#if defined(_WIN32) || defined(_WIN64)\r
-DAT_RETURN\r
-dapls_ib_wait_object_wait(IN ib_wait_obj_handle_t p_cq_wait_obj_handle,\r
-                         IN uint32_t timeout)\r
-{\r
-       struct dapl_evd *evd_ptr;\r
-       struct ibv_cq *ibv_cq = NULL;\r
-       int status = 0;\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
-                    " cq_object_wait: CQ channel %p time %d\n",\r
-                    p_cq_wait_obj_handle, timeout);\r
-\r
-       /* uDAPL timeout values in usecs */\r
-       p_cq_wait_obj_handle->comp_channel.Milliseconds = timeout / 1000;\r
-\r
-       /* returned event */\r
-       status = ibv_get_cq_event(p_cq_wait_obj_handle, &ibv_cq,\r
-                                 (void *)&evd_ptr);\r
-       if (status == 0) {\r
-               ibv_ack_cq_events(ibv_cq, 1);\r
-       }\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
-                    " cq_object_wait: RET evd %p ibv_cq %p %s\n",\r
-                    evd_ptr, ibv_cq, strerror(errno));\r
-\r
-       return (dapl_convert_errno(status, "cq_wait_object_wait"));\r
-}\r
-#else                  //_WIN32 || _WIN64\r
-DAT_RETURN\r
-dapls_ib_wait_object_wait(IN ib_wait_obj_handle_t p_cq_wait_obj_handle,\r
-                         IN uint32_t timeout)\r
-{\r
-       struct dapl_evd *evd_ptr;\r
-       struct ibv_cq *ibv_cq = NULL;\r
-       int status = 0;\r
-       int timeout_ms = -1;\r
-       struct pollfd cq_fd = {\r
-               .fd = p_cq_wait_obj_handle->fd,\r
-               .events = POLLIN,\r
-               .revents = 0\r
-       };\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
-                    " cq_object_wait: CQ channel %p time %d\n",\r
-                    p_cq_wait_obj_handle, timeout);\r
-\r
-       /* uDAPL timeout values in usecs */\r
-       if (timeout != DAT_TIMEOUT_INFINITE)\r
-               timeout_ms = timeout / 1000;\r
-\r
-       status = poll(&cq_fd, 1, timeout_ms);\r
-\r
-       /* returned event */\r
-       if (status > 0) {\r
-               if (!ibv_get_cq_event(p_cq_wait_obj_handle,\r
-                                     &ibv_cq, (void *)&evd_ptr)) {\r
-                       ibv_ack_cq_events(ibv_cq, 1);\r
-               }\r
-               status = 0;\r
-\r
-               /* timeout */\r
-       } else if (status == 0)\r
-               status = ETIMEDOUT;\r
-\r
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
-                    " cq_object_wait: RET evd %p ibv_cq %p %s\n",\r
-                    evd_ptr, ibv_cq, strerror(errno));\r
-\r
-       return (dapl_convert_errno(status, "cq_wait_object_wait"));\r
-\r
-}\r
-#endif                         //_WIN32 || _WIN64\r
-\r
 /*\r
  * Local variables:\r
  *  c-indent-level: 4\r
index 2ed5ea1a2d823e1c69279739267f9130fb9e29c4..09b37446799ee49b614efb3e713c7f5668fcd05e 100644 (file)
@@ -107,9 +107,6 @@ typedef int                 ib_bool_t;
 typedef union ibv_gid          GID;\r
 typedef char                   *IB_HCA_NAME;\r
 typedef uint16_t               ib_hca_port_t;\r
-typedef uint32_t               ib_comp_handle_t;\r
-\r
-typedef struct ibv_comp_channel *ib_wait_obj_handle_t;\r
 \r
 /* Definitions */\r
 #define IB_INVALID_HANDLE      NULL\r
@@ -211,6 +208,8 @@ typedef uint32_t ib_shm_transport_t;
 /* prototypes */\r
 int32_t        dapls_ib_init(void);\r
 int32_t        dapls_ib_release(void);\r
+\r
+/* util.c */\r
 enum ibv_mtu dapl_ib_mtu(int mtu);\r
 char *dapl_ib_mtu_str(enum ibv_mtu mtu);\r
 DAT_RETURN getlocalipaddr(DAT_SOCK_ADDR *addr, int addr_len);\r
index ffff25b4e365f69ed490081eb20fb491e4881394..3406a11505a48afe7aa6fa554926ab75415837d0 100644 (file)
@@ -77,15 +77,20 @@ dapls_ib_qp_alloc(IN DAPL_IA * ia_ptr,
        else if (!ia_ptr->hca_ptr->ib_trans.ib_cq_empty)\r
                rcv_cq = ia_ptr->hca_ptr->ib_trans.ib_cq_empty;\r
        else {\r
-               struct ibv_comp_channel *channel = \r
-                               rcv_evd->cq_wait_obj_handle;\r
+               struct ibv_comp_channel *channel;\r
+\r
+               channel = ibv_create_comp_channel(ia_ptr->hca_ptr->ib_hca_handle);\r
+               if (!channel)\r
+                       return (dapl_convert_errno(ENOMEM, "create_cq"));\r
                  \r
                /* Call IB verbs to create CQ */\r
                rcv_cq = ibv_create_cq(ia_ptr->hca_ptr->ib_hca_handle,\r
                                       0, NULL, channel, 0);\r
 \r
-               if (rcv_cq == IB_INVALID_HANDLE)\r
+               if (rcv_cq == IB_INVALID_HANDLE) {\r
+                       ibv_destroy_comp_channel(channel);\r
                        return (dapl_convert_errno(ENOMEM, "create_cq"));\r
+               }\r
 \r
                ia_ptr->hca_ptr->ib_trans.ib_cq_empty = rcv_cq;\r
        }\r
index 0922e9baa2e2e35328ff6ad0cc3d18f5e9a2a4c8..449f1d06ffb30b24ae845fca67f0a08fbb87a0ab 100644 (file)
@@ -320,6 +320,104 @@ DAT_RETURN dapls_ib_setup_async_callback(IN DAPL_IA * ia_ptr,
        return DAT_SUCCESS;\r
 }\r
 \r
+void dapli_async_event_cb(struct _ib_hca_transport *hca)\r
+{\r
+       struct ibv_async_event event;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " async_event(%p)\n", hca);\r
+\r
+       if (hca->destroy)\r
+               return;\r
+\r
+       if (!ibv_get_async_event(hca->ib_ctx, &event)) {\r
+\r
+               switch (event.event_type) {\r
+               case IBV_EVENT_CQ_ERR:\r
+               {\r
+                       struct dapl_ep *evd_ptr =\r
+                               event.element.cq->cq_context;\r
+\r
+                       dapl_log(DAPL_DBG_TYPE_ERR,\r
+                                "dapl async_event CQ (%p) ERR %d\n",\r
+                                evd_ptr, event.event_type);\r
+\r
+                       /* report up if async callback still setup */\r
+                       if (hca->async_cq_error)\r
+                               hca->async_cq_error(hca->ib_ctx,\r
+                                                   event.element.cq,\r
+                                                   &event,\r
+                                                   (void *)evd_ptr);\r
+                       break;\r
+               }\r
+               case IBV_EVENT_COMM_EST:\r
+               {\r
+                       /* Received msgs on connected QP before RTU */\r
+                       dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                                " async_event COMM_EST(%p) rdata beat RTU\n",\r
+                                event.element.qp);\r
+\r
+                       break;\r
+               }\r
+               case IBV_EVENT_QP_FATAL:\r
+               case IBV_EVENT_QP_REQ_ERR:\r
+               case IBV_EVENT_QP_ACCESS_ERR:\r
+               case IBV_EVENT_QP_LAST_WQE_REACHED:\r
+               case IBV_EVENT_SRQ_ERR:\r
+               case IBV_EVENT_SRQ_LIMIT_REACHED:\r
+               case IBV_EVENT_SQ_DRAINED:\r
+               {\r
+                       struct dapl_ep *ep_ptr =\r
+                               event.element.qp->qp_context;\r
+\r
+                       dapl_log(DAPL_DBG_TYPE_ERR,\r
+                                "dapl async_event QP (%p) ERR %d\n",\r
+                                ep_ptr, event.event_type);\r
+\r
+                       /* report up if async callback still setup */\r
+                       if (hca->async_qp_error)\r
+                               hca->async_qp_error(hca->ib_ctx,\r
+                                                   ep_ptr->qp_handle,\r
+                                                   &event,\r
+                                                   (void *)ep_ptr);\r
+                       break;\r
+               }\r
+               case IBV_EVENT_PATH_MIG:\r
+               case IBV_EVENT_PATH_MIG_ERR:\r
+               case IBV_EVENT_DEVICE_FATAL:\r
+               case IBV_EVENT_PORT_ACTIVE:\r
+               case IBV_EVENT_PORT_ERR:\r
+               case IBV_EVENT_LID_CHANGE:\r
+               case IBV_EVENT_PKEY_CHANGE:\r
+               case IBV_EVENT_SM_CHANGE:\r
+               {\r
+                       dapl_log(DAPL_DBG_TYPE_WARN,\r
+                                "dapl async_event: DEV ERR %d\n",\r
+                                event.event_type);\r
+\r
+                       /* report up if async callback still setup */\r
+                       if (hca->async_unafiliated)\r
+                               hca->async_unafiliated(hca->ib_ctx, \r
+                                                      &event,  \r
+                                                      hca->async_un_ctx);\r
+                       break;\r
+               }\r
+               case IBV_EVENT_CLIENT_REREGISTER:\r
+                       /* no need to report this event this time */\r
+                       dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                                " async_event: IBV_CLIENT_REREGISTER\n");\r
+                       break;\r
+\r
+               default:\r
+                       dapl_log(DAPL_DBG_TYPE_WARN,\r
+                                "dapl async_event: %d UNKNOWN\n",\r
+                                event.event_type);\r
+                       break;\r
+\r
+               }\r
+               ibv_ack_async_event(&event);\r
+       }\r
+}\r
+\r
 /*\r
  * dapls_set_provider_specific_attr\r
  *\r
index e83c5ae34090eb7965facf2d2b48c1ef90449788..9ed4390077b81c4f90398474ab6a48043d12e246 100644 (file)
@@ -78,8 +78,11 @@ typedef dp_ib_cm_handle_t    ib_cm_srvc_handle_t;
 /* ib_hca_transport_t, specific to this implementation */\r
 typedef struct _ib_hca_transport\r
 { \r
+       struct dapl_llist_entry entry;\r
+       int                     destroy;\r
        union ibv_gid           gid;\r
        struct  ibv_device      *ib_dev;\r
+       struct  ibv_context     *ib_ctx;\r
        ib_cq_handle_t          ib_cq_empty;\r
        DAPL_OS_LOCK            cq_lock;        \r
        int                     max_inline_send;\r
@@ -114,6 +117,8 @@ typedef struct _ib_hca_transport
 void cr_thread(void *arg);\r
 int dapli_cq_thread_init(struct dapl_hca *hca_ptr);\r
 void dapli_cq_thread_destroy(struct dapl_hca *hca_ptr);\r
+void dapli_async_event_cb(struct _ib_hca_transport *tp);\r
+void dapli_cq_event_cb(struct _ib_hca_transport *tp);\r
 DAT_RETURN dapli_socket_disconnect(dp_ib_cm_handle_t cm_ptr);\r
 void dapls_print_cm_list(IN DAPL_IA *ia_ptr);\r
 dp_ib_cm_handle_t dapls_ib_cm_create(DAPL_EP *ep);\r
index 293e028db1178e8e0107f481d56eaabb96952b6d..813993bffc7b8874be8eeba2b54c6b7cf9bea90f 100644 (file)
@@ -57,6 +57,96 @@ static const char rcsid[] = "$Id:  $";
 \r
 #include <stdlib.h>\r
 \r
+ib_thread_state_t g_ib_thread_state = 0;\r
+DAPL_OS_THREAD g_ib_thread;\r
+DAPL_OS_LOCK g_hca_lock;\r
+struct dapl_llist_entry *g_hca_list;\r
+\r
+void dapli_thread(void *arg);\r
+DAT_RETURN  dapli_ib_thread_init(void);\r
+void dapli_ib_thread_destroy(void);\r
+\r
+#if defined(_WIN64) || defined(_WIN32)\r
+#include "..\..\..\..\..\etc\user\comp_channel.cpp"\r
+#include <rdma\winverbs.h>\r
+\r
+struct ibvw_windata windata;\r
+\r
+static int dapls_os_init(void)\r
+{\r
+       return ibvw_get_windata(&windata, IBVW_WINDATA_VERSION);\r
+}\r
+\r
+static void dapls_os_release(void)\r
+{\r
+       if (windata.comp_mgr)\r
+               ibvw_release_windata(&windata, IBVW_WINDATA_VERSION);\r
+       windata.comp_mgr = NULL;\r
+}\r
+\r
+static int dapls_config_verbs(struct ibv_context *verbs)\r
+{\r
+       verbs->channel.Milliseconds = 0;\r
+       return 0;\r
+}\r
+\r
+static int dapls_config_comp_channel(struct ibv_comp_channel *channel)\r
+{\r
+       channel->comp_channel.Milliseconds = 0;\r
+       return 0;\r
+}\r
+\r
+static int dapls_thread_signal(void)\r
+{\r
+       CompManagerCancel(windata.comp_mgr);\r
+       return 0;\r
+}\r
+#else                          // _WIN64 || WIN32\r
+int g_ib_pipe[2];\r
+\r
+static int dapls_os_init(void)\r
+{\r
+       /* create pipe for waking up work thread */\r
+       return pipe(g_ib_pipe);\r
+}\r
+\r
+static void dapls_os_release(void)\r
+{\r
+       /* close pipe? */\r
+}\r
+\r
+static int dapls_config_fd(int fd)\r
+{\r
+       int opts;\r
+\r
+       opts = fcntl(fd, F_GETFL);\r
+       if (opts < 0 || fcntl(fd, F_SETFL, opts | O_NONBLOCK) < 0) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " dapls_config_fd: fcntl on fd %d ERR %d %s\n",\r
+                        fd, opts, strerror(errno));\r
+               return errno;\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+static int dapls_config_verbs(struct ibv_context *verbs)\r
+{\r
+       return dapls_config_fd(verbs->async_fd);\r
+}\r
+\r
+static int dapls_config_comp_channel(struct ibv_comp_channel *channel)\r
+{\r
+       return dapls_config_fd(channel->fd);\r
+}\r
+\r
+static int dapls_thread_signal(void)\r
+{\r
+       return write(g_ib_pipe[1], "w", sizeof "w");\r
+}\r
+#endif\r
+\r
+\r
 static int32_t create_cr_pipe(IN DAPL_HCA * hca_ptr)\r
 {\r
        DAPL_SOCKET listen_socket;\r
@@ -130,35 +220,22 @@ static void destroy_cr_pipe(IN DAPL_HCA * hca_ptr)
  */\r
 int32_t dapls_ib_init(void)\r
 {\r
-       return 0;\r
-}\r
+       /* initialize hca_list */\r
+       dapl_os_lock_init(&g_hca_lock);\r
+       dapl_llist_init_head(&g_hca_list);\r
 \r
-int32_t dapls_ib_release(void)\r
-{\r
-       return 0;\r
-}\r
+       if (dapls_os_init())\r
+               return 1;\r
 \r
-#if defined(_WIN64) || defined(_WIN32)\r
-int dapls_config_comp_channel(struct ibv_comp_channel *channel)\r
-{\r
        return 0;\r
 }\r
-#else                          // _WIN64 || WIN32\r
-int dapls_config_comp_channel(struct ibv_comp_channel *channel)\r
-{\r
-       int opts;\r
-\r
-       opts = fcntl(channel->fd, F_GETFL);     /* uCQ */\r
-       if (opts < 0 || fcntl(channel->fd, F_SETFL, opts | O_NONBLOCK) < 0) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        " dapls_create_comp_channel: fcntl on ib_cq->fd %d ERR %d %s\n",\r
-                        channel->fd, opts, strerror(errno));\r
-               return errno;\r
-       }\r
 \r
+int32_t dapls_ib_release(void)\r
+{\r
+       dapli_ib_thread_destroy();\r
+       dapls_os_release();\r
        return 0;\r
 }\r
-#endif\r
 \r
 /*\r
  * dapls_ib_open_hca\r
@@ -213,7 +290,7 @@ DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr)
                 " open_hca: device %s not found\n", hca_name);\r
        goto err;\r
 \r
-      found:\r
+found:\r
        dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " open_hca: Found dev %s %016llx\n",\r
                     ibv_get_device_name(hca_ptr->ib_trans.ib_dev),\r
                     (unsigned long long)\r
@@ -227,6 +304,8 @@ DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr)
                         strerror(errno));\r
                goto err;\r
        }\r
+       hca_ptr->ib_trans.ib_ctx = hca_ptr->ib_hca_handle;\r
+       dapls_config_verbs(hca_ptr->ib_hca_handle);\r
 \r
        /* get lid for this hca-port, network order */\r
        if (ibv_query_port(hca_ptr->ib_hca_handle,\r
@@ -271,15 +350,8 @@ DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr)
        hca_ptr->ib_trans.mtu =\r
            dapl_ib_mtu(dapl_os_get_env_val("DAPL_IB_MTU", SCM_IB_MTU));\r
 \r
-#ifndef CQ_WAIT_OBJECT\r
-       /* initialize cq_lock */\r
-       dat_status = dapl_os_lock_init(&hca_ptr->ib_trans.cq_lock);\r
-       if (dat_status != DAT_SUCCESS) {\r
-               dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        " open_hca: failed to init cq_lock\n");\r
-               goto bail;\r
-       }\r
-       /* EVD events without direct CQ channels, non-blocking */\r
+\r
+       /* EVD events without direct CQ channels, CNO support */\r
        hca_ptr->ib_trans.ib_cq =\r
            ibv_create_comp_channel(hca_ptr->ib_hca_handle);\r
        if (hca_ptr->ib_trans.ib_cq == NULL) {\r
@@ -288,18 +360,28 @@ DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr)
                         strerror(errno));\r
                goto bail;\r
        }\r
-\r
-       if (dapls_config_comp_channel(hca_ptr->ib_trans.ib_cq)) {\r
-               goto bail;\r
-       }\r
-\r
-       if (dapli_cq_thread_init(hca_ptr)) {\r
+       dapls_config_comp_channel(hca_ptr->ib_trans.ib_cq);\r
+       \r
+       dat_status = dapli_ib_thread_init();\r
+       if (dat_status != DAT_SUCCESS) {\r
                dapl_log(DAPL_DBG_TYPE_ERR,\r
-                        " open_hca: cq_thread_init failed for %s\n",\r
-                        ibv_get_device_name(hca_ptr->ib_trans.ib_dev));\r
+                        " open_hca: failed to init cq thread lock\n");\r
                goto bail;\r
        }\r
-#endif                         /* CQ_WAIT_OBJECT */\r
+       /* \r
+        * Put new hca_transport on list for async and CQ event processing \r
+        * Wakeup work thread to add to polling list\r
+        */\r
+       dapl_llist_init_entry((DAPL_LLIST_ENTRY *)&hca_ptr->ib_trans.entry);\r
+       dapl_os_lock(&g_hca_lock);\r
+       dapl_llist_add_tail(&g_hca_list,\r
+                           (DAPL_LLIST_ENTRY *) &hca_ptr->ib_trans.entry,\r
+                           &hca_ptr->ib_trans.entry);\r
+       if (dapls_thread_signal() == -1)\r
+               dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                        " open_hca: thread wakeup error = %s\n",\r
+                        strerror(errno));\r
+       dapl_os_unlock(&g_hca_lock);\r
 \r
        /* initialize cr_list lock */\r
        dat_status = dapl_os_lock_init(&hca_ptr->ib_trans.lock);\r
@@ -333,7 +415,7 @@ DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr)
 \r
        /* wait for thread */\r
        while (hca_ptr->ib_trans.cr_state != IB_THREAD_RUN) {\r
-               dapl_os_sleep_usec(2000);\r
+               dapl_os_sleep_usec(1000);\r
        }\r
 \r
        dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
@@ -380,33 +462,297 @@ DAT_RETURN dapls_ib_close_hca(IN DAPL_HCA * hca_ptr)
 {\r
        dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " close_hca: %p\n", hca_ptr);\r
 \r
-#ifndef CQ_WAIT_OBJECT\r
-       dapli_cq_thread_destroy(hca_ptr);\r
-       dapl_os_lock_destroy(&hca_ptr->ib_trans.cq_lock);\r
-#endif                         /* CQ_WAIT_OBJECT */\r
-\r
        if (hca_ptr->ib_hca_handle != IB_INVALID_HANDLE) {\r
                if (ibv_close_device(hca_ptr->ib_hca_handle))\r
                        return (dapl_convert_errno(errno, "ib_close_device"));\r
                hca_ptr->ib_hca_handle = IB_INVALID_HANDLE;\r
        }\r
 \r
+       dapl_os_lock(&g_hca_lock);\r
+       if (g_ib_thread_state != IB_THREAD_RUN) {\r
+               dapl_os_unlock(&g_hca_lock);\r
+               return (DAT_SUCCESS);\r
+       }\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
        /* destroy cr_thread and lock */\r
        hca_ptr->ib_trans.cr_state = IB_THREAD_CANCEL;\r
-       if (send(hca_ptr->ib_trans.scm[1], "w", sizeof "w", 0) == -1)\r
-               dapl_log(DAPL_DBG_TYPE_UTIL,\r
-                        " thread_destroy: thread wakeup err = %s\n",\r
-                        strerror(errno));\r
+       send(hca_ptr->ib_trans.scm[1], "w", sizeof "w", 0);\r
        while (hca_ptr->ib_trans.cr_state != IB_THREAD_EXIT) {\r
                dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
                             " close_hca: waiting for cr_thread\n");\r
-               if (send(hca_ptr->ib_trans.scm[1], "w", sizeof "w", 0) == -1)\r
-                       dapl_log(DAPL_DBG_TYPE_UTIL,\r
-                                " thread_destroy: thread wakeup err = %s\n",\r
-                                strerror(errno));\r
-               dapl_os_sleep_usec(2000);\r
+               send(hca_ptr->ib_trans.scm[1], "w", sizeof "w", 0);\r
+               dapl_os_sleep_usec(1000);\r
        }\r
        dapl_os_lock_destroy(&hca_ptr->ib_trans.lock);\r
        destroy_cr_pipe(hca_ptr); /* no longer need pipe */\r
+       \r
+       /* \r
+        * Remove hca from async event processing list\r
+        * Wakeup work thread to remove from polling list\r
+        */\r
+       hca_ptr->ib_trans.destroy = 1;\r
+       if (dapls_thread_signal() == -1)\r
+               dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                        " destroy: thread wakeup error = %s\n",\r
+                        strerror(errno));\r
+\r
+       /* wait for thread to remove HCA references */\r
+       while (hca_ptr->ib_trans.destroy != 2) {\r
+               if (dapls_thread_signal() == -1)\r
+                       dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                                " destroy: thread wakeup error = %s\n",\r
+                                strerror(errno));\r
+               dapl_os_sleep_usec(1000);\r
+       }\r
+\r
        return (DAT_SUCCESS);\r
 }\r
+\r
+DAT_RETURN dapli_ib_thread_init(void)\r
+{\r
+       DAT_RETURN dat_status;\r
+\r
+       dapl_os_lock(&g_hca_lock);\r
+       if (g_ib_thread_state != IB_THREAD_INIT) {\r
+               dapl_os_unlock(&g_hca_lock);\r
+               return DAT_SUCCESS;\r
+       }\r
+\r
+       g_ib_thread_state = IB_THREAD_CREATE;\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
+       /* create thread to process inbound connect request */\r
+       dat_status = dapl_os_thread_create(dapli_thread, NULL, &g_ib_thread);\r
+       if (dat_status != DAT_SUCCESS)\r
+               return (dapl_convert_errno(errno,\r
+                                          "create_thread ERR:"\r
+                                          " check resource limits"));\r
+\r
+       /* wait for thread to start */\r
+       dapl_os_lock(&g_hca_lock);\r
+       while (g_ib_thread_state != IB_THREAD_RUN) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                            " ib_thread_init: waiting for ib_thread\n");\r
+               dapl_os_unlock(&g_hca_lock);\r
+               dapl_os_sleep_usec(1000);\r
+               dapl_os_lock(&g_hca_lock);\r
+       }\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+void dapli_ib_thread_destroy(void)\r
+{\r
+       int retries = 10;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " ib_thread_destroy(%d)\n", dapl_os_getpid());\r
+       /* \r
+        * wait for async thread to terminate. \r
+        * pthread_join would be the correct method\r
+        * but some applications have some issues\r
+        */\r
+\r
+       /* destroy ib_thread, wait for termination, if not already */\r
+       dapl_os_lock(&g_hca_lock);\r
+       if (g_ib_thread_state != IB_THREAD_RUN)\r
+               goto bail;\r
+\r
+       g_ib_thread_state = IB_THREAD_CANCEL;\r
+       if (dapls_thread_signal() == -1)\r
+               dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                        " destroy: thread wakeup error = %s\n",\r
+                        strerror(errno));\r
+       while ((g_ib_thread_state != IB_THREAD_EXIT) && (retries--)) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                            " ib_thread_destroy: waiting for ib_thread\n");\r
+               if (dapls_thread_signal() == -1)\r
+                       dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                                " destroy: thread wakeup error = %s\n",\r
+                                strerror(errno));\r
+               dapl_os_unlock(&g_hca_lock);\r
+               dapl_os_sleep_usec(2000);\r
+               dapl_os_lock(&g_hca_lock);\r
+       }\r
+bail:\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " ib_thread_destroy(%d) exit\n", dapl_os_getpid());\r
+}\r
+\r
+\r
+#if defined(_WIN64) || defined(_WIN32)\r
+/* work thread for uAT, uCM, CQ, and async events */\r
+void dapli_thread(void *arg)\r
+{\r
+       struct _ib_hca_transport *hca;\r
+       struct _ib_hca_transport *uhca[8];\r
+       COMP_CHANNEL *channel;\r
+       int ret, idx, cnt;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " ib_thread(%d,0x%x): ENTER: \n",\r
+                    dapl_os_getpid(), g_ib_thread);\r
+\r
+       dapl_os_lock(&g_hca_lock);\r
+       for (g_ib_thread_state = IB_THREAD_RUN;\r
+            g_ib_thread_state == IB_THREAD_RUN; \r
+            dapl_os_lock(&g_hca_lock)) {\r
+\r
+               idx = 0;\r
+               hca = dapl_llist_is_empty(&g_hca_list) ? NULL :\r
+                     dapl_llist_peek_head(&g_hca_list);\r
+\r
+               while (hca) {\r
+                       uhca[idx++] = hca;\r
+                       hca = dapl_llist_next_entry(&g_hca_list,\r
+                                                   (DAPL_LLIST_ENTRY *)\r
+                                                   &hca->entry);\r
+               }\r
+               cnt = idx;\r
+\r
+               dapl_os_unlock(&g_hca_lock);\r
+               ret = CompManagerPoll(windata.comp_mgr, INFINITE, &channel);\r
+\r
+               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                            " ib_thread(%d) poll_event 0x%x\n",\r
+                            dapl_os_getpid(), ret);\r
+\r
+\r
+               /* check and process ASYNC events, per device */\r
+               for (idx = 0; idx < cnt; idx++) {\r
+                       if (uhca[idx]->destroy == 1) {\r
+                               dapl_os_lock(&g_hca_lock);\r
+                               dapl_llist_remove_entry(&g_hca_list,\r
+                                                       (DAPL_LLIST_ENTRY *)\r
+                                                       &uhca[idx]->entry);\r
+                               dapl_os_unlock(&g_hca_lock);\r
+                               uhca[idx]->destroy = 2;\r
+                       } else {\r
+                               dapli_cq_event_cb(uhca[idx]);\r
+                               dapli_async_event_cb(uhca[idx]);\r
+                       }\r
+               }\r
+       }\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " ib_thread(%d) EXIT\n",\r
+                    dapl_os_getpid());\r
+       g_ib_thread_state = IB_THREAD_EXIT;\r
+       dapl_os_unlock(&g_hca_lock);\r
+}\r
+#else                          // _WIN64 || WIN32\r
+\r
+/* work thread for uAT, uCM, CQ, and async events */\r
+void dapli_thread(void *arg)\r
+{\r
+       struct pollfd ufds[__FD_SETSIZE];\r
+       struct _ib_hca_transport *uhca[__FD_SETSIZE] = { NULL };\r
+       struct _ib_hca_transport *hca;\r
+       int ret, idx, fds;\r
+       char rbuf[2];\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_THREAD,\r
+                    " ib_thread(%d,0x%x): ENTER: pipe %d \n",\r
+                    dapl_os_getpid(), g_ib_thread, g_ib_pipe[0]);\r
+\r
+       /* Poll across pipe, CM, AT never changes */\r
+       dapl_os_lock(&g_hca_lock);\r
+       g_ib_thread_state = IB_THREAD_RUN;\r
+\r
+       ufds[0].fd = g_ib_pipe[0];      /* pipe */\r
+       ufds[0].events = POLLIN;\r
+\r
+       while (g_ib_thread_state == IB_THREAD_RUN) {\r
+\r
+               /* build ufds after pipe and uCMA events */\r
+               ufds[0].revents = 0;\r
+               idx = 0;\r
+\r
+               /*  Walk HCA list and setup async and CQ events */\r
+               if (!dapl_llist_is_empty(&g_hca_list))\r
+                       hca = dapl_llist_peek_head(&g_hca_list);\r
+               else\r
+                       hca = NULL;\r
+\r
+               while (hca) {\r
+\r
+                       /* uASYNC events */\r
+                       ufds[++idx].fd = hca->ib_ctx->async_fd;\r
+                       ufds[idx].events = POLLIN;\r
+                       ufds[idx].revents = 0;\r
+                       uhca[idx] = hca;\r
+\r
+                       /* CQ events are non-direct with CNO's */\r
+                       ufds[++idx].fd = hca->ib_cq->fd;\r
+                       ufds[idx].events = POLLIN;\r
+                       ufds[idx].revents = 0;\r
+                       uhca[idx] = hca;\r
+\r
+                       dapl_dbg_log(DAPL_DBG_TYPE_THREAD,\r
+                                    " ib_thread(%d) poll_fd: hca[%d]=%p,"\r
+                                    " async=%d pipe=%d \n",\r
+                                    dapl_os_getpid(), hca, ufds[idx - 1].fd,\r
+                                    ufds[0].fd);\r
+\r
+                       hca = dapl_llist_next_entry(&g_hca_list,\r
+                                                   (DAPL_LLIST_ENTRY *)\r
+                                                   &hca->entry);\r
+               }\r
+\r
+               /* unlock, and setup poll */\r
+               fds = idx + 1;\r
+               dapl_os_unlock(&g_hca_lock);\r
+               ret = poll(ufds, fds, -1);\r
+               if (ret <= 0) {\r
+                       dapl_dbg_log(DAPL_DBG_TYPE_THREAD,\r
+                                    " ib_thread(%d): ERR %s poll\n",\r
+                                    dapl_os_getpid(), strerror(errno));\r
+                       dapl_os_lock(&g_hca_lock);\r
+                       continue;\r
+               }\r
+\r
+               dapl_dbg_log(DAPL_DBG_TYPE_THREAD,\r
+                            " ib_thread(%d) poll_event: "\r
+                            " async=0x%x pipe=0x%x \n",\r
+                            dapl_os_getpid(), ufds[idx].revents,\r
+                            ufds[0].revents);\r
+\r
+               /* check and process CQ and ASYNC events, per device */\r
+               for (idx = 1; idx < fds; idx++) {\r
+                       if (ufds[idx].revents == POLLIN) {\r
+                               dapli_cq_event_cb(uhca[idx]);\r
+                               dapli_async_event_cb(uhca[idx]);\r
+                       }\r
+               }\r
+\r
+               /* check and process user events, PIPE */\r
+               if (ufds[0].revents == POLLIN) {\r
+                       if (read(g_ib_pipe[0], rbuf, 2) == -1)\r
+                               dapl_log(DAPL_DBG_TYPE_THREAD,\r
+                                        " cr_thread: pipe rd err= %s\n",\r
+                                        strerror(errno));\r
+\r
+                       /* cleanup any device on list marked for destroy */\r
+                       for (idx = 1; idx < fds; idx++) {\r
+                               if (uhca[idx] && uhca[idx]->destroy == 1) {\r
+                                       dapl_os_lock(&g_hca_lock);\r
+                                       dapl_llist_remove_entry(\r
+                                               &g_hca_list,\r
+                                               (DAPL_LLIST_ENTRY*)\r
+                                               &uhca[idx]->entry);\r
+                                       dapl_os_unlock(&g_hca_lock);\r
+                                       uhca[idx]->destroy = 2;\r
+                               }\r
+                       }\r
+               }\r
+               dapl_os_lock(&g_hca_lock);\r
+       }\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_THREAD, " ib_thread(%d) EXIT\n",\r
+                    dapl_os_getpid());\r
+       g_ib_thread_state = IB_THREAD_EXIT;\r
+       dapl_os_unlock(&g_hca_lock);\r
+}\r
+#endif\r
index bf41662ff17aca082eafe53f827012ee62eef5d9..1d2af04cb88b2d8e551e024e30d78a6b80b9c0b5 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_set_unwaitable.c
- *
- * PURPOSE: EVENT management
- * Description: Interfaces in this file are completely described in
- *             the DAPL 1.1 API, Chapter 6, section 3.4.7
- *
- * $Id:$
- **********************************************************************/
-
-#include "dapl.h"
-#include "dapl_adapter_util.h"
-
-/*
- * dapl_evd_set_unwaitable
- *
- * DAPL Requirements Version 1.1, 6.3.4.7
- *
- * Transition the Event Dispatcher into an unwaitable state
- *
- * Input:
- *     evd_handle
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INVALID_HANDLE
- */
-DAT_RETURN DAT_API dapl_evd_set_unwaitable(IN DAT_EVD_HANDLE evd_handle)
-{
-       DAPL_EVD *evd_ptr;
-       DAT_RETURN dat_status;
-
-       evd_ptr = (DAPL_EVD *) evd_handle;
-       dat_status = DAT_SUCCESS;
-
-       if (DAPL_BAD_HANDLE(evd_handle, DAPL_MAGIC_EVD))
-       {
-               dat_status = DAT_ERROR(DAT_INVALID_HANDLE, 0);
-               goto bail;
-       }
-       dapl_os_lock(&evd_ptr->header.lock);
-       evd_ptr->evd_waitable = DAT_FALSE;
-       dapl_os_unlock(&evd_ptr->header.lock);
-
-       /*
-        * If this evd is waiting, wake it up. There is an obvious race
-        * condition here where we may wakeup the waiter before it goes to
-        * sleep; but the wait_object allows this and will do the right
-        * thing.
-        */
-       if (evd_ptr->evd_state == DAPL_EVD_STATE_WAITED) {
-#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);
-       }
-      bail:
-       return dat_status;
-}
-
-/*
- * 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_set_unwaitable.c\r
+ *\r
+ * PURPOSE: EVENT management\r
+ * Description: Interfaces in this file are completely described in\r
+ *             the DAPL 1.1 API, Chapter 6, section 3.4.7\r
+ *\r
+ * $Id:$\r
+ **********************************************************************/\r
+\r
+#include "dapl.h"\r
+#include "dapl_adapter_util.h"\r
+\r
+/*\r
+ * dapl_evd_set_unwaitable\r
+ *\r
+ * DAPL Requirements Version 1.1, 6.3.4.7\r
+ *\r
+ * Transition the Event Dispatcher into an unwaitable state\r
+ *\r
+ * Input:\r
+ *     evd_handle\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INVALID_HANDLE\r
+ */\r
+DAT_RETURN DAT_API dapl_evd_set_unwaitable(IN DAT_EVD_HANDLE evd_handle)\r
+{\r
+       DAPL_EVD *evd_ptr;\r
+       DAT_RETURN dat_status;\r
+\r
+       evd_ptr = (DAPL_EVD *) evd_handle;\r
+       dat_status = DAT_SUCCESS;\r
+\r
+       if (DAPL_BAD_HANDLE(evd_handle, DAPL_MAGIC_EVD))\r
+       {\r
+               dat_status = DAT_ERROR(DAT_INVALID_HANDLE, 0);\r
+               goto bail;\r
+       }\r
+       dapl_os_lock(&evd_ptr->header.lock);\r
+       evd_ptr->evd_waitable = DAT_FALSE;\r
+       dapl_os_unlock(&evd_ptr->header.lock);\r
+\r
+       /*\r
+        * If this evd is waiting, wake it up. There is an obvious race\r
+        * condition here where we may wakeup the waiter before it goes to\r
+        * sleep; but the wait_object allows this and will do the right\r
+        * thing.\r
+        */\r
+       if (evd_ptr->evd_state == DAPL_EVD_STATE_WAITED) {\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
+      bail:\r
+       return dat_status;\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 8d82d63a68cb7f16154d445a0f307f1f2320d970..c7cae025a5d4f54de6ba02055a4ec6fbe889394a 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_wait.c
- *
- * PURPOSE: EVENT management
- *
- * Description: Interfaces in this file are completely defined in 
- *              the uDAPL 1.1 API specification
- *
- * $Id:$
- **********************************************************************/
-
-#include "dapl.h"
-#include "dapl_evd_util.h"
-#include "dapl_ring_buffer_util.h"
-#include "dapl_adapter_util.h"
-
-/*
- * dapl_evd_wait
- *
- * UDAPL Requirements Version xxx, 
- *
- * Wait, up to specified timeout, for notification event on EVD.
- * Then return first available event.
- *
- * Input:
- *     evd_handle
- *     timeout
- *
- * Output:
- *     event
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INVALID_PARAMETER
- *     DAT_INVALID_STATE
- */
-
-DAT_RETURN DAT_API dapl_evd_wait(IN DAT_EVD_HANDLE evd_handle,
-                                IN DAT_TIMEOUT time_out,
-                                IN DAT_COUNT threshold,
-                                OUT DAT_EVENT * event, OUT DAT_COUNT * nmore)
-{
-       DAPL_EVD *evd_ptr;
-       DAT_RETURN dat_status;
-       DAT_EVENT *local_event;
-       DAT_BOOLEAN notify_requested = DAT_FALSE;
-       DAT_BOOLEAN waitable;
-       DAPL_EVD_STATE evd_state;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_API,
-                    "dapl_evd_wait (%p, %d, %d, %p, %p)\n",
-                    evd_handle, time_out, threshold, event, nmore);
-
-       evd_ptr = (DAPL_EVD *) evd_handle;
-       dat_status = DAT_SUCCESS;
-
-       if (DAPL_BAD_HANDLE(evd_ptr, DAPL_MAGIC_EVD)) {
-               /*
-                * We return directly rather than bailing because
-                * bailing attempts to update the evd, and we don't have
-                * one.
-                */
-               dat_status = DAT_ERROR(DAT_INVALID_HANDLE, 0);
-               goto bail;
-       }
-       if (!event) {
-               dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG4);
-               goto bail;
-       }
-       if (!nmore) {
-               dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG5);
-               goto bail;
-       }
-       if (threshold <= 0 ||
-           (threshold > 1
-            && evd_ptr->completion_type != DAPL_EVD_STATE_THRESHOLD)
-           || threshold > evd_ptr->qlen) {
-               dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3);
-               goto bail;
-       }
-       if (evd_ptr->catastrophic_overflow) {
-               dat_status = DAT_ERROR(DAT_INVALID_STATE, 0);
-               goto bail;
-       }
-       DAPL_CNTR(evd_ptr, DCNT_EVD_WAIT);
-
-       dapl_dbg_log(DAPL_DBG_TYPE_EVD,
-                    "dapl_evd_wait: EVD %p, CQ %p\n",
-                    evd_ptr, (void *)evd_ptr->ib_cq_handle);
-
-       /*
-        * Make sure there are no other waiters and the evd is active.
-        * Currently this means only the OPEN state is allowed.
-        * Do this atomically.  We need to take a lock to synchronize
-        * with dapl_evd_dequeue(), but the atomic transition allows
-        * non-locking synchronization with dapl_evd_query() and
-        * dapl_evd_{query,enable,disable,{set,clear}_unwaitable}.
-        */
-
-       dapl_os_lock(&evd_ptr->header.lock);
-       waitable = evd_ptr->evd_waitable;
-
-       dapl_os_assert(sizeof(DAT_COUNT) == sizeof(DAPL_EVD_STATE));
-       evd_state = evd_ptr->evd_state;
-       if (evd_ptr->evd_state == DAPL_EVD_STATE_OPEN)
-               evd_ptr->evd_state = DAPL_EVD_STATE_WAITED;
-
-       if (evd_state != DAPL_EVD_STATE_OPEN) {
-               /* Bogus state, bail out */
-               dat_status = DAT_ERROR(DAT_INVALID_STATE, 0);
-               goto bail;
-       }
-
-       if (!waitable) {
-               /* This EVD is not waitable, reset the state and bail */
-               if (evd_ptr->evd_state == DAPL_EVD_STATE_WAITED)
-                       evd_ptr->evd_state = evd_state;
-
-               dat_status =
-                   DAT_ERROR(DAT_INVALID_STATE,
-                             DAT_INVALID_STATE_EVD_UNWAITABLE);
-               goto bail;
-       }
-
-       /*
-        * We now own the EVD, even though we don't have the lock anymore,
-        * because we're in the WAITED state.
-        */
-
-       evd_ptr->threshold = threshold;
-
-       for (;;) {
-               /*
-                * Ideally we'd just check the number of entries on the CQ, but
-                * we don't have a way to do that.  Because we have to set *nmore
-                * at some point in this routine, we'll need to do this copy
-                * sometime even if threshold == 1.
-                *
-                * For connection evd or async evd, the function checks and
-                * return right away if the ib_cq_handle associate with these evd
-                * equal to IB_INVALID_HANDLE
-                */
-               dapl_os_unlock(&evd_ptr->header.lock);
-               dapls_evd_copy_cq(evd_ptr);
-               dapl_os_lock(&evd_ptr->header.lock);
-
-               if (dapls_rbuf_count(&evd_ptr->pending_event_queue) >=
-                   threshold) {
-                       break;
-               }
-
-               /*
-                * Do not enable the completion notification if this evd is not 
-                * a DTO_EVD or RMR_BIND_EVD
-                */
-               if ((!notify_requested) &&
-                   ((evd_ptr->evd_flags & DAT_EVD_DTO_FLAG) ||
-                    (evd_ptr->evd_flags & DAT_EVD_RMR_BIND_FLAG))) {
-                       dat_status =
-                           dapls_ib_completion_notify(evd_ptr->header.
-                                                      owner_ia->hca_ptr->
-                                                      ib_hca_handle, evd_ptr,
-                                                      (evd_ptr->
-                                                       completion_type ==
-                                                       DAPL_EVD_STATE_SOLICITED_WAIT)
-                                                      ? IB_NOTIFY_ON_SOLIC_COMP
-                                                      :
-                                                      IB_NOTIFY_ON_NEXT_COMP);
-
-                       DAPL_CNTR(evd_ptr, DCNT_EVD_WAIT_NOTIFY);
-                       /* FIXME report error */
-                       dapl_os_assert(dat_status == DAT_SUCCESS);
-
-                       notify_requested = DAT_TRUE;
-
-                       /* Try again.  */
-                       continue;
-               }
-
-               /*
-                * Unused by poster; it has no way to tell how many
-                * items are on the queue without copying them over to the
-                * EVD queue, and we're the only ones allowed to dequeue
-                * from the CQ for synchronization/locking reasons.
-                */
-               evd_ptr->threshold = threshold;
-
-               DAPL_CNTR(evd_ptr, DCNT_EVD_WAIT_BLOCKED);
-               dapl_os_unlock(&evd_ptr->header.lock);
-
-#ifdef CQ_WAIT_OBJECT
-               if (evd_ptr->cq_wait_obj_handle)
-                       dat_status =
-                           dapls_ib_wait_object_wait(evd_ptr->
-                                                     cq_wait_obj_handle,
-                                                     time_out);
-               else
-#endif
-                       dat_status =
-                           dapl_os_wait_object_wait(&evd_ptr->wait_object,
-                                                    time_out);
-
-               dapl_os_lock(&evd_ptr->header.lock);
-
-               /*
-                * FIXME: if the thread loops around and waits again
-                * the time_out value needs to be updated.
-                */
-
-               notify_requested = DAT_FALSE;   /* We've used it up.  */
-
-               /* See if we were awakened by evd_set_unwaitable */
-               if (!evd_ptr->evd_waitable) {
-                       dat_status = DAT_ERROR(DAT_INVALID_STATE, 0);
-               }
-
-               if (dat_status != DAT_SUCCESS) {
-                       /*
-                        * If the status is DAT_TIMEOUT, we'll break out of the
-                        * loop, *not* dequeue an event (because dat_status
-                        * != DAT_SUCCESS), set *nmore (as we should for timeout)
-                        * and return DAT_TIMEOUT.
-                        */
-                       break;
-               }
-       }
-
-       evd_ptr->evd_state = DAPL_EVD_STATE_OPEN;
-
-       if (dat_status == DAT_SUCCESS) {
-               local_event = dapls_rbuf_remove(&evd_ptr->pending_event_queue);
-               *event = *local_event;
-               dapls_rbuf_add(&evd_ptr->free_event_queue, local_event);
-       }
-
-       /*
-        * Valid if dat_status == DAT_SUCCESS || dat_status == DAT_TIMEOUT
-        * Undefined otherwise, so ok to set it.
-        */
-       *nmore = dapls_rbuf_count(&evd_ptr->pending_event_queue);
-
-      bail:
-       dapl_os_unlock(&evd_ptr->header.lock);
-       if (dat_status) {
-               dapl_dbg_log(DAPL_DBG_TYPE_RTN,
-                            "dapl_evd_wait () returns 0x%x\n", dat_status);
-       }
-       return dat_status;
-}
+/*\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_wait.c\r
+ *\r
+ * PURPOSE: EVENT management\r
+ *\r
+ * Description: Interfaces in this file are completely defined in \r
+ *              the uDAPL 1.1 API specification\r
+ *\r
+ * $Id:$\r
+ **********************************************************************/\r
+\r
+#include "dapl.h"\r
+#include "dapl_evd_util.h"\r
+#include "dapl_ring_buffer_util.h"\r
+#include "dapl_adapter_util.h"\r
+\r
+/*\r
+ * dapl_evd_wait\r
+ *\r
+ * UDAPL Requirements Version xxx, \r
+ *\r
+ * Wait, up to specified timeout, for notification event on EVD.\r
+ * Then return first available event.\r
+ *\r
+ * Input:\r
+ *     evd_handle\r
+ *     timeout\r
+ *\r
+ * Output:\r
+ *     event\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INVALID_PARAMETER\r
+ *     DAT_INVALID_STATE\r
+ */\r
+\r
+DAT_RETURN DAT_API dapl_evd_wait(IN DAT_EVD_HANDLE evd_handle,\r
+                                IN DAT_TIMEOUT time_out,\r
+                                IN DAT_COUNT threshold,\r
+                                OUT DAT_EVENT * event, OUT DAT_COUNT * nmore)\r
+{\r
+       DAPL_EVD *evd_ptr;\r
+       DAT_RETURN dat_status;\r
+       DAT_EVENT *local_event;\r
+       DAT_BOOLEAN notify_requested = DAT_FALSE;\r
+       DAT_BOOLEAN waitable;\r
+       DAPL_EVD_STATE evd_state;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_API,\r
+                    "dapl_evd_wait (%p, %d, %d, %p, %p)\n",\r
+                    evd_handle, time_out, threshold, event, nmore);\r
+\r
+       evd_ptr = (DAPL_EVD *) evd_handle;\r
+       dat_status = DAT_SUCCESS;\r
+\r
+       if (DAPL_BAD_HANDLE(evd_ptr, DAPL_MAGIC_EVD)) {\r
+               /*\r
+                * We return directly rather than bailing because\r
+                * bailing attempts to update the evd, and we don't have\r
+                * one.\r
+                */\r
+               dat_status = DAT_ERROR(DAT_INVALID_HANDLE, 0);\r
+               goto bail;\r
+       }\r
+       if (!event) {\r
+               dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG4);\r
+               goto bail;\r
+       }\r
+       if (!nmore) {\r
+               dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG5);\r
+               goto bail;\r
+       }\r
+       if (threshold <= 0 ||\r
+           (threshold > 1\r
+            && evd_ptr->completion_type != DAPL_EVD_STATE_THRESHOLD)\r
+           || threshold > evd_ptr->qlen) {\r
+               dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3);\r
+               goto bail;\r
+       }\r
+       if (evd_ptr->catastrophic_overflow) {\r
+               dat_status = DAT_ERROR(DAT_INVALID_STATE, 0);\r
+               goto bail;\r
+       }\r
+       DAPL_CNTR(evd_ptr, DCNT_EVD_WAIT);\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_EVD,\r
+                    "dapl_evd_wait: EVD %p, CQ %p\n",\r
+                    evd_ptr, (void *)evd_ptr->ib_cq_handle);\r
+\r
+       /*\r
+        * Make sure there are no other waiters and the evd is active.\r
+        * Currently this means only the OPEN state is allowed.\r
+        * Do this atomically.  We need to take a lock to synchronize\r
+        * with dapl_evd_dequeue(), but the atomic transition allows\r
+        * non-locking synchronization with dapl_evd_query() and\r
+        * dapl_evd_{query,enable,disable,{set,clear}_unwaitable}.\r
+        */\r
+\r
+       dapl_os_lock(&evd_ptr->header.lock);\r
+       waitable = evd_ptr->evd_waitable;\r
+\r
+       dapl_os_assert(sizeof(DAT_COUNT) == sizeof(DAPL_EVD_STATE));\r
+       evd_state = evd_ptr->evd_state;\r
+       if (evd_ptr->evd_state == DAPL_EVD_STATE_OPEN)\r
+               evd_ptr->evd_state = DAPL_EVD_STATE_WAITED;\r
+\r
+       if (evd_state != DAPL_EVD_STATE_OPEN) {\r
+               /* Bogus state, bail out */\r
+               dat_status = DAT_ERROR(DAT_INVALID_STATE, 0);\r
+               goto bail;\r
+       }\r
+\r
+       if (!waitable) {\r
+               /* This EVD is not waitable, reset the state and bail */\r
+               if (evd_ptr->evd_state == DAPL_EVD_STATE_WAITED)\r
+                       evd_ptr->evd_state = evd_state;\r
+\r
+               dat_status =\r
+                   DAT_ERROR(DAT_INVALID_STATE,\r
+                             DAT_INVALID_STATE_EVD_UNWAITABLE);\r
+               goto bail;\r
+       }\r
+\r
+       /*\r
+        * We now own the EVD, even though we don't have the lock anymore,\r
+        * because we're in the WAITED state.\r
+        */\r
+\r
+       evd_ptr->threshold = threshold;\r
+\r
+       for (;;) {\r
+               /*\r
+                * Ideally we'd just check the number of entries on the CQ, but\r
+                * we don't have a way to do that.  Because we have to set *nmore\r
+                * at some point in this routine, we'll need to do this copy\r
+                * sometime even if threshold == 1.\r
+                *\r
+                * For connection evd or async evd, the function checks and\r
+                * return right away if the ib_cq_handle associate with these evd\r
+                * equal to IB_INVALID_HANDLE\r
+                */\r
+               dapl_os_unlock(&evd_ptr->header.lock);\r
+               dapls_evd_copy_cq(evd_ptr);\r
+               dapl_os_lock(&evd_ptr->header.lock);\r
+\r
+               if (dapls_rbuf_count(&evd_ptr->pending_event_queue) >=\r
+                   threshold) {\r
+                       break;\r
+               }\r
+\r
+               /*\r
+                * Do not enable the completion notification if this evd is not \r
+                * a DTO_EVD or RMR_BIND_EVD\r
+                */\r
+               if ((!notify_requested) &&\r
+                   (evd_ptr->evd_flags & (DAT_EVD_DTO_FLAG | DAT_EVD_RMR_BIND_FLAG))) {\r
+                       dat_status =\r
+                           dapls_ib_completion_notify(evd_ptr->header.\r
+                                                      owner_ia->hca_ptr->\r
+                                                      ib_hca_handle, evd_ptr,\r
+                                                      (evd_ptr->\r
+                                                       completion_type ==\r
+                                                       DAPL_EVD_STATE_SOLICITED_WAIT)\r
+                                                      ? IB_NOTIFY_ON_SOLIC_COMP\r
+                                                      :\r
+                                                      IB_NOTIFY_ON_NEXT_COMP);\r
+\r
+                       DAPL_CNTR(evd_ptr, DCNT_EVD_WAIT_NOTIFY);\r
+                       /* FIXME report error */\r
+                       dapl_os_assert(dat_status == DAT_SUCCESS);\r
+\r
+                       notify_requested = DAT_TRUE;\r
+\r
+                       /* Try again.  */\r
+                       continue;\r
+               }\r
+\r
+               /*\r
+                * Unused by poster; it has no way to tell how many\r
+                * items are on the queue without copying them over to the\r
+                * EVD queue, and we're the only ones allowed to dequeue\r
+                * from the CQ for synchronization/locking reasons.\r
+                */\r
+               evd_ptr->threshold = threshold;\r
+\r
+               DAPL_CNTR(evd_ptr, DCNT_EVD_WAIT_BLOCKED);\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
+                       dat_status = dapls_evd_dto_wait(evd_ptr, time_out);\r
+               } else {\r
+                       dat_status = dapl_os_wait_object_wait(&evd_ptr->wait_object, time_out);\r
+               }\r
+\r
+               dapl_os_lock(&evd_ptr->header.lock);\r
+\r
+               /*\r
+                * FIXME: if the thread loops around and waits again\r
+                * the time_out value needs to be updated.\r
+                */\r
+\r
+               notify_requested = DAT_FALSE;   /* We've used it up.  */\r
+\r
+               /* See if we were awakened by evd_set_unwaitable */\r
+               if (!evd_ptr->evd_waitable) {\r
+                       dat_status = DAT_ERROR(DAT_INVALID_STATE, 0);\r
+               }\r
+\r
+               if (dat_status != DAT_SUCCESS) {\r
+                       /*\r
+                        * If the status is DAT_TIMEOUT, we'll break out of the\r
+                        * loop, *not* dequeue an event (because dat_status\r
+                        * != DAT_SUCCESS), set *nmore (as we should for timeout)\r
+                        * and return DAT_TIMEOUT.\r
+                        */\r
+                       break;\r
+               }\r
+       }\r
+\r
+       evd_ptr->evd_state = DAPL_EVD_STATE_OPEN;\r
+\r
+       if (dat_status == DAT_SUCCESS) {\r
+               local_event = dapls_rbuf_remove(&evd_ptr->pending_event_queue);\r
+               *event = *local_event;\r
+               dapls_rbuf_add(&evd_ptr->free_event_queue, local_event);\r
+       }\r
+\r
+       /*\r
+        * Valid if dat_status == DAT_SUCCESS || dat_status == DAT_TIMEOUT\r
+        * Undefined otherwise, so ok to set it.\r
+        */\r
+       *nmore = dapls_rbuf_count(&evd_ptr->pending_event_queue);\r
+\r
+      bail:\r
+       dapl_os_unlock(&evd_ptr->header.lock);\r
+       if (dat_status) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_RTN,\r
+                            "dapl_evd_wait () returns 0x%x\n", dat_status);\r
+       }\r
+       return dat_status;\r
+}\r
index 79e8d3afe697506bc49843bcf58f4cc971920bcf..ba4cfbca50ae13a589fe206d904e0129fc94f3f8 100644 (file)
@@ -196,6 +196,9 @@ typedef struct sockaddr_in6     DAT_SOCK_ADDR6; /* Socket address header native
 #elif defined(_MSC_VER) || defined(_WIN32) || defined(_WIN64)
 /* NT. MSC compiler, Win32/64 platform */
 
+#include <winsock2.h>
+#include <ws2tcpip.h>
+
 typedef unsigned __int32        DAT_UINT32;    /* Unsigned host order, 32 bits */
 typedef unsigned __int64        DAT_UINT64;    /* unsigned host order, 64 bits */
 typedef unsigned  long         DAT_UVERYLONG;  /* unsigned longest native to compiler */
index 77d78b2bbf900724a9c9f767ab1b6a278ab680ec..999706f8c3478e21cd0979ce93d6beb0a7f735eb 100644 (file)
-/*
- * Copyright (c) 2005-2008 Intel Corporation.  All rights reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses.  You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- *     Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * $Id: $
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef DAPL_PROVIDER
-#undef DAPL_PROVIDER
-#endif
-
-#if defined(_WIN32) || defined(_WIN64)
-
-#include <windows.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#include <process.h>
-#include <complib/cl_types.h>
-#include "..\..\..\..\etc\user\getopt.c"
-
-#define getpid() ((int)GetCurrentProcessId())
-#define F64x "%I64x"
-
-#ifdef DBG
-#define DAPL_PROVIDER "ibnic0v2d"
-#else
-#define DAPL_PROVIDER "ibnic0v2"
-#endif
-
-#define ntohll _byteswap_uint64
-#define htonll _byteswap_uint64
-
-#else // _WIN32 || _WIN64
-
-#include <endian.h>
-#include <byteswap.h>
-#include <netdb.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <sys/mman.h>
-#include <getopt.h>
-#include <inttypes.h>
-#include <unistd.h>
-
-#define DAPL_PROVIDER "ofa-v2-ib0"
-
-#define F64x "%"PRIx64""
-
-#if __BYTE_ORDER == __BIG_ENDIAN
-#define htonll(x) (x)
-#define ntohll(x) (x)
-#elif __BYTE_ORDER == __LITTLE_ENDIAN
-#define htonll(x)  bswap_64(x)
-#define ntohll(x)  bswap_64(x)
-#endif
-
-#endif // _WIN32 || _WIN64
-
-/* Debug: 1 == connect & close only, otherwise full-meal deal */
-#define CONNECT_ONLY 0
-
-#define MAX_POLLING_CNT 50000
-#define MAX_RDMA_RD    4
-#define MAX_PROCS      1000
-
-/* Header files needed for DAT/uDAPL */
-#include    "dat2/udat.h"
-
-/* definitions */
-#define SERVER_CONN_QUAL  45248
-#define DTO_TIMEOUT       (1000*1000*5)
-#define DTO_FLUSH_TIMEOUT (1000*1000*2)
-#define CONN_TIMEOUT      (1000*1000*10)
-#define SERVER_TIMEOUT    DAT_TIMEOUT_INFINITE
-#define RDMA_BUFFER_SIZE  (64)
-
-/* Global DAT vars */
-static DAT_IA_HANDLE h_ia = DAT_HANDLE_NULL;
-static DAT_PZ_HANDLE h_pz = DAT_HANDLE_NULL;
-static DAT_EP_HANDLE h_ep = DAT_HANDLE_NULL;
-static DAT_PSP_HANDLE h_psp = DAT_HANDLE_NULL;
-static DAT_CR_HANDLE h_cr = DAT_HANDLE_NULL;
-
-static DAT_EVD_HANDLE h_async_evd = DAT_HANDLE_NULL;
-static DAT_EVD_HANDLE h_dto_req_evd = DAT_HANDLE_NULL;
-static DAT_EVD_HANDLE h_dto_rcv_evd = DAT_HANDLE_NULL;
-static DAT_EVD_HANDLE h_cr_evd = DAT_HANDLE_NULL;
-static DAT_EVD_HANDLE h_conn_evd = DAT_HANDLE_NULL;
-static DAT_CNO_HANDLE h_dto_cno = DAT_HANDLE_NULL;
-
-/* RDMA buffers */
-static DAT_LMR_HANDLE h_lmr_send = DAT_HANDLE_NULL;
-static DAT_LMR_HANDLE h_lmr_recv = DAT_HANDLE_NULL;
-static DAT_LMR_CONTEXT lmr_context_send;
-static DAT_LMR_CONTEXT lmr_context_recv;
-static DAT_RMR_CONTEXT rmr_context_send;
-static DAT_RMR_CONTEXT rmr_context_recv;
-static DAT_VLEN registered_size_send;
-static DAT_VLEN registered_size_recv;
-static DAT_VADDR registered_addr_send;
-static DAT_VADDR registered_addr_recv;
-
-/* Initial msg receive buf, RMR exchange, and Rdma-write notification */
-#define MSG_BUF_COUNT     3
-#define MSG_IOV_COUNT     2
-static DAT_RMR_TRIPLET rmr_recv_msg[MSG_BUF_COUNT];
-static DAT_LMR_HANDLE h_lmr_recv_msg = DAT_HANDLE_NULL;
-static DAT_LMR_CONTEXT lmr_context_recv_msg;
-static DAT_RMR_CONTEXT rmr_context_recv_msg;
-static DAT_VLEN registered_size_recv_msg;
-static DAT_VADDR registered_addr_recv_msg;
-
-/* message send buffer */
-static DAT_RMR_TRIPLET rmr_send_msg;
-static DAT_LMR_HANDLE h_lmr_send_msg = DAT_HANDLE_NULL;
-static DAT_LMR_CONTEXT lmr_context_send_msg;
-static DAT_RMR_CONTEXT rmr_context_send_msg;
-static DAT_VLEN registered_size_send_msg;
-static DAT_VADDR registered_addr_send_msg;
-static DAT_EP_ATTR ep_attr;
-char hostname[256] = { 0 };
-char provider[64] = DAPL_PROVIDER;
-char addr_str[INET_ADDRSTRLEN];
-
-/* rdma pointers */
-char *rbuf = NULL;
-char *sbuf = NULL;
-int status;
-
-/* timers */
-double start, stop, total_us, total_sec;
-
-struct dt_time {
-       double total;
-       double open;
-       double reg;
-       double unreg;
-       double pzc;
-       double pzf;
-       double evdc;
-       double evdf;
-       double cnoc;
-       double cnof;
-       double epc;
-       double epf;
-       double rdma_wr;
-       double rdma_rd[MAX_RDMA_RD];
-       double rdma_rd_total;
-       double rtt;
-       double close;
-       double conn;
-};
-
-struct dt_time time;
-
-/* defaults */
-static int failed = 0;
-static int performance_times = 0;
-static int connected = 0;
-static int burst = 10;
-static int server = 1;
-static int verbose = 0;
-static int polling = 0;
-static int poll_count = 0;
-static int rdma_wr_poll_count = 0;
-static int conn_poll_count = 0;
-static int rdma_rd_poll_count[MAX_RDMA_RD] = { 0 };
-static int delay = 0;
-static int buf_len = RDMA_BUFFER_SIZE;
-static int use_cno = 0;
-static int recv_msg_index = 0;
-static int burst_msg_posted = 0;
-static int burst_msg_index = 0;
-
-/* forward prototypes */
-const char *DT_RetToString(DAT_RETURN ret_value);
-const char *DT_EventToSTr(DAT_EVENT_NUMBER event_code);
-void print_usage(void);
-double get_time(void);
-void init_data(void);
-
-DAT_RETURN send_msg(void *data,
-                   DAT_COUNT size,
-                   DAT_LMR_CONTEXT context,
-                   DAT_DTO_COOKIE cookie, DAT_COMPLETION_FLAGS flags);
-
-DAT_RETURN connect_ep(char *hostname, DAT_CONN_QUAL conn_id);
-void disconnect_ep(void);
-DAT_RETURN register_rdma_memory(void);
-DAT_RETURN unregister_rdma_memory(void);
-DAT_RETURN create_events(void);
-DAT_RETURN destroy_events(void);
-DAT_RETURN do_rdma_write_with_msg(void);
-DAT_RETURN do_rdma_read_with_msg(void);
-DAT_RETURN do_ping_pong_msg(void);
-
-#define LOGPRINTF if (verbose) printf
-
-void flush_evds(void)
-{
-       DAT_EVENT event;
-
-       /* Flush async error queue */
-       printf("%d ERR: Checking ASYNC EVD...\n", getpid());
-       while (dat_evd_dequeue(h_async_evd, &event) == DAT_SUCCESS) {
-               printf(" ASYNC EVD ENTRY: handle=%p reason=%d\n",
-                       event.event_data.asynch_error_event_data.dat_handle,
-                       event.event_data.asynch_error_event_data.reason);
-       }
-       /* Flush receive queue */
-       printf("%d ERR: Checking RECEIVE EVD...\n", getpid());
-       while (dat_evd_dequeue(h_dto_rcv_evd, &event) == DAT_SUCCESS) {
-               printf(" RCV EVD ENTRY: op=%d stat=%d ln=%d ck="F64x"\n",
-                       event.event_data.dto_completion_event_data.operation,
-                       event.event_data.dto_completion_event_data.status,
-                       event.event_data.dto_completion_event_data.transfered_length,
-                       event.event_data.dto_completion_event_data.user_cookie.as_64);
-       }
-       /* Flush request queue */
-       printf("%d ERR: Checking REQUEST EVD...\n", getpid());
-       while (dat_evd_dequeue(h_dto_req_evd, &event) == DAT_SUCCESS) {
-               printf(" REQ EVD ENTRY: op=%d stat=%d ln=%d ck="F64x"\n",
-                       event.event_data.dto_completion_event_data.operation,
-                       event.event_data.dto_completion_event_data.status,
-                       event.event_data.dto_completion_event_data.transfered_length,
-                       event.event_data.dto_completion_event_data.user_cookie.as_64);
-       }
-}
-
-int main(int argc, char **argv)
-{
-       int i, c;
-       DAT_RETURN ret;
-       DAT_EP_PARAM ep_param;
-
-       /* parse arguments */
-       while ((c = getopt(argc, argv, "tscvpb:d:B:h:P:")) != -1) {
-               switch (c) {
-               case 't':
-                       performance_times = 1;
-                       fflush(stdout);
-                       break;
-               case 's':
-                       server = 1;
-                       fflush(stdout);
-                       break;
-               case 'c':
-                       use_cno = 1;
-                       printf("%d Creating CNO for DTO EVD's\n", getpid());
-                       fflush(stdout);
-                       break;
-               case 'v':
-                       verbose = 1;
-                       printf("%d Verbose\n", getpid());
-                       fflush(stdout);
-                       break;
-               case 'p':
-                       polling = 1;
-                       printf("%d Polling\n", getpid());
-                       fflush(stdout);
-                       break;
-               case 'B':
-                       burst = atoi(optarg);
-                       break;
-               case 'd':
-                       delay = atoi(optarg);
-                       break;
-               case 'b':
-                       buf_len = atoi(optarg);
-                       break;
-               case 'h':
-                       server = 0;
-                       strcpy(hostname, optarg);
-                       break;
-               case 'P':
-                       strcpy(provider, optarg);
-                       break;
-               default:
-                       print_usage();
-                       exit(-12);
-               }
-       }
-
-#if defined(_WIN32) || defined(_WIN64)
-       {
-               WSADATA wsaData;
-
-               i = WSAStartup(MAKEWORD(2, 2), &wsaData);
-               if (i != 0) {
-                       printf("%s WSAStartup(2.2) failed? (0x%x)\n", argv[0],
-                              i);
-                       fflush(stdout);
-                       exit(1);
-               }
-       }
-#endif
-
-       if (!server) {
-               printf("%d Running as client - %s\n", getpid(), provider);
-       } else {
-               printf("%d Running as server - %s\n", getpid(), provider);
-       }
-       fflush(stdout);
-
-       /* allocate send and receive buffers */
-       if (((rbuf = malloc(buf_len * (burst+1))) == NULL) ||
-           ((sbuf = malloc(buf_len * (burst+1))) == NULL)) {
-               perror("malloc");
-               exit(1);
-       }
-       memset(&time, 0, sizeof(struct dt_time));
-       LOGPRINTF("%d Allocated RDMA buffers (r:%p,s:%p) len %d \n",
-                 getpid(), rbuf, sbuf, buf_len);
-
-       /* dat_ia_open, dat_pz_create */
-       h_async_evd = DAT_HANDLE_NULL;
-       start = get_time();
-       ret = dat_ia_open(provider, 8, &h_async_evd, &h_ia);
-       stop = get_time();
-       time.open += ((stop - start) * 1.0e6);
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d: Error Adaptor open: %s\n",
-                       getpid(), DT_RetToString(ret));
-               exit(1);
-       } else
-               LOGPRINTF("%d Opened Interface Adaptor\n", getpid());
-
-       /* Create Protection Zone */
-       start = get_time();
-       LOGPRINTF("%d Create Protection Zone\n", getpid());
-       ret = dat_pz_create(h_ia, &h_pz);
-       stop = get_time();
-       time.pzc += ((stop - start) * 1.0e6);
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error creating Protection Zone: %s\n",
-                       getpid(), DT_RetToString(ret));
-               exit(1);
-       } else
-               LOGPRINTF("%d Created Protection Zone\n", getpid());
-
-       /* Register memory */
-       LOGPRINTF("%d Register RDMA memory\n", getpid());
-       ret = register_rdma_memory();
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error registering RDMA memory: %s\n",
-                       getpid(), DT_RetToString(ret));
-               goto cleanup;
-       } else
-               LOGPRINTF("%d Register RDMA memory done\n", getpid());
-
-       LOGPRINTF("%d Create events\n", getpid());
-       ret = create_events();
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error creating events: %s\n",
-                       getpid(), DT_RetToString(ret));
-               goto cleanup;
-       } else {
-               LOGPRINTF("%d Create events done\n", getpid());
-       }
-
-       /* create EP */
-       memset(&ep_attr, 0, sizeof(ep_attr));
-       ep_attr.service_type = DAT_SERVICE_TYPE_RC;
-       ep_attr.max_rdma_size = 0x10000;
-       ep_attr.qos = 0;
-       ep_attr.recv_completion_flags = 0;
-       ep_attr.max_recv_dtos = MSG_BUF_COUNT + (burst * 3);
-       ep_attr.max_request_dtos = MSG_BUF_COUNT + (burst * 3) + MAX_RDMA_RD;
-       ep_attr.max_recv_iov = MSG_IOV_COUNT;
-       ep_attr.max_request_iov = MSG_IOV_COUNT;
-       ep_attr.max_rdma_read_in = MAX_RDMA_RD;
-       ep_attr.max_rdma_read_out = MAX_RDMA_RD;
-       ep_attr.request_completion_flags = DAT_COMPLETION_DEFAULT_FLAG;
-       ep_attr.ep_transport_specific_count = 0;
-       ep_attr.ep_transport_specific = NULL;
-       ep_attr.ep_provider_specific_count = 0;
-       ep_attr.ep_provider_specific = NULL;
-
-       start = get_time();
-       ret = dat_ep_create(h_ia, h_pz, h_dto_rcv_evd,
-                           h_dto_req_evd, h_conn_evd, &ep_attr, &h_ep);
-       stop = get_time();
-       time.epc += ((stop - start) * 1.0e6);
-       time.total += time.epc;
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error dat_ep_create: %s\n",
-                       getpid(), DT_RetToString(ret));
-               goto cleanup;
-       } else
-               LOGPRINTF("%d EP created %p \n", getpid(), h_ep);
-
-       /*
-        * register message buffers, establish connection, and
-        * exchange DMA RMR information info via messages
-        */
-       ret = connect_ep(hostname, SERVER_CONN_QUAL);
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error connect_ep: %s\n",
-                       getpid(), DT_RetToString(ret));
-               goto cleanup;
-       } else
-               LOGPRINTF("%d connect_ep complete\n", getpid());
-
-       /* Query EP for local and remote address information, print */
-       ret = dat_ep_query(h_ep, DAT_EP_FIELD_ALL, &ep_param);
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error dat_ep_query: %s\n",
-                       getpid(), DT_RetToString(ret));
-               goto cleanup;
-       } else
-               LOGPRINTF("%d EP queried %p \n", getpid(), h_ep);
-#if defined(_WIN32)
-       printf("\n%d Query EP: LOCAL addr %s port %lld\n", getpid(),
-              inet_ntoa(((struct sockaddr_in *)
-                         ep_param.local_ia_address_ptr)->sin_addr),
-              (ep_param.local_port_qual));
-#else
-       inet_ntop(AF_INET,
-                 &((struct sockaddr_in *)ep_param.local_ia_address_ptr)->
-                 sin_addr, addr_str, sizeof(addr_str));
-       printf("\n%d Query EP: LOCAL addr %s port " F64x "\n", getpid(),
-              addr_str, (ep_param.local_port_qual));
-#endif
-#if defined(_WIN32)
-       printf("%d Query EP: REMOTE addr %s port %lld\n", getpid(),
-              inet_ntoa(((struct sockaddr_in *)
-                         ep_param.local_ia_address_ptr)->sin_addr),
-              (ep_param.remote_port_qual));
-#else
-       inet_ntop(AF_INET,
-                 &((struct sockaddr_in *)ep_param.remote_ia_address_ptr)->
-                 sin_addr, addr_str, sizeof(addr_str));
-       printf("%d Query EP: REMOTE addr %s port " F64x "\n", getpid(),
-              addr_str, (ep_param.remote_port_qual));
-#endif
-       fflush(stdout);
-
-#if CONNECT_ONLY
-#if defined(_WIN32) || defined(_WIN64)
-       Sleep(1 * 1000);
-#else
-       sleep(1);
-#endif
-       goto cleanup;
-#endif
-
-       /*********** RDMA write data *************/
-       ret = do_rdma_write_with_msg();
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error do_rdma_write_with_msg: %s\n",
-                       getpid(), DT_RetToString(ret));
-               goto cleanup;
-       } else
-               LOGPRINTF("%d do_rdma_write_with_msg complete\n", getpid());
-
-       /*********** RDMA read data *************/
-       ret = do_rdma_read_with_msg();
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error do_rdma_read_with_msg: %s\n",
-                       getpid(), DT_RetToString(ret));
-               goto cleanup;
-       } else
-               LOGPRINTF("%d do_rdma_read_with_msg complete\n", getpid());
-
-       /*********** PING PING messages ************/
-       ret = do_ping_pong_msg();
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error do_ping_pong_msg: %s\n",
-                       getpid(), DT_RetToString(ret));
-               goto cleanup;
-       } else {
-               LOGPRINTF("%d do_ping_pong_msg complete\n", getpid());
-               goto complete;
-       }
-
-cleanup:
-       flush_evds();
-       failed++;
-complete:
-
-       /* disconnect and free EP resources */
-       if (h_ep != DAT_HANDLE_NULL) {
-               /* unregister message buffers and tear down connection */
-               LOGPRINTF("%d Disconnect and Free EP %p \n", getpid(), h_ep);
-               disconnect_ep();
-
-               /* free EP */
-               LOGPRINTF("%d Free EP %p \n", getpid(), h_ep);
-               start = get_time();
-               ret = dat_ep_free(h_ep);
-               stop = get_time();
-               time.epf += ((stop - start) * 1.0e6);
-               time.total += time.epf;
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr, "%d Error freeing EP: %s\n",
-                               getpid(), DT_RetToString(ret));
-               } else {
-                       LOGPRINTF("%d Freed EP\n", getpid());
-                       h_ep = DAT_HANDLE_NULL;
-               }
-       }
-
-       /* free EVDs */
-       LOGPRINTF("%d destroy events\n", getpid());
-       ret = destroy_events();
-       if (ret != DAT_SUCCESS)
-               fprintf(stderr, "%d Error destroy_events: %s\n",
-                       getpid(), DT_RetToString(ret));
-       else
-               LOGPRINTF("%d destroy events done\n", getpid());
-
-       ret = unregister_rdma_memory();
-       LOGPRINTF("%d unregister_rdma_memory \n", getpid());
-       if (ret != DAT_SUCCESS)
-               fprintf(stderr, "%d Error unregister_rdma_memory: %s\n",
-                       getpid(), DT_RetToString(ret));
-       else
-               LOGPRINTF("%d unregister_rdma_memory done\n", getpid());
-
-       /* Free protection domain */
-       LOGPRINTF("%d Freeing pz\n", getpid());
-       start = get_time();
-       ret = dat_pz_free(h_pz);
-       stop = get_time();
-       time.pzf += ((stop - start) * 1.0e6);
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error freeing PZ: %s\n",
-                       getpid(), DT_RetToString(ret));
-       } else {
-               LOGPRINTF("%d Freed pz\n", getpid());
-               h_pz = NULL;
-       }
-
-       /* close the device */
-       LOGPRINTF("%d Closing Interface Adaptor\n", getpid());
-       start = get_time();
-       ret = dat_ia_close(h_ia, DAT_CLOSE_ABRUPT_FLAG);
-       stop = get_time();
-       time.close += ((stop - start) * 1.0e6);
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d: Error Adaptor close: %s\n",
-                       getpid(), DT_RetToString(ret));
-       } else
-               LOGPRINTF("%d Closed Interface Adaptor\n", getpid());
-
-       /* free rdma buffers */
-       free(rbuf);
-       free(sbuf);
-
-       printf("\n%d: DAPL Test Complete. %s\n\n",
-              getpid(), failed ? "FAILED" : "PASSED");
-
-       fflush(stderr);
-       fflush(stdout);
-
-       if (!performance_times)
-               exit(0);
-
-       printf("\n%d: DAPL Test Complete.\n\n", getpid());
-       printf("%d: Message RTT: Total=%10.2lf usec, %d bursts, itime=%10.2lf"
-              " usec, pc=%d\n",
-              getpid(), time.rtt, burst, time.rtt / burst, poll_count);
-       printf("%d: RDMA write:  Total=%10.2lf usec, %d bursts, itime=%10.2lf"
-              " usec, pc=%d\n",
-              getpid(), time.rdma_wr, burst,
-              time.rdma_wr / burst, rdma_wr_poll_count);
-       for (i = 0; i < MAX_RDMA_RD; i++) {
-               printf("%d: RDMA read:   Total=%10.2lf usec,   %d bursts, "
-                      "itime=%10.2lf usec, pc=%d\n",
-                      getpid(), time.rdma_rd_total, MAX_RDMA_RD,
-                      time.rdma_rd[i], rdma_rd_poll_count[i]);
-       }
-       printf("%d: open:      %10.2lf usec\n", getpid(), time.open);
-       printf("%d: close:     %10.2lf usec\n", getpid(), time.close);
-       printf("%d: PZ create: %10.2lf usec\n", getpid(), time.pzc);
-       printf("%d: PZ free:   %10.2lf usec\n", getpid(), time.pzf);
-       printf("%d: LMR create:%10.2lf usec\n", getpid(), time.reg);
-       printf("%d: LMR free:  %10.2lf usec\n", getpid(), time.unreg);
-       printf("%d: EVD create:%10.2lf usec\n", getpid(), time.evdc);
-       printf("%d: EVD free:  %10.2lf usec\n", getpid(), time.evdf);
-       if (use_cno) {
-               printf("%d: CNO create:  %10.2lf usec\n", getpid(), time.cnoc);
-               printf("%d: CNO free:    %10.2lf usec\n", getpid(), time.cnof);
-       }
-       printf("%d: EP create: %10.2lf usec\n", getpid(), time.epc);
-       printf("%d: EP free:   %10.2lf usec\n", getpid(), time.epf);
-       if (!server)
-               printf("%d: connect:   %10.2lf usec, poll_cnt=%d\n", 
-                      getpid(), time.conn, conn_poll_count);
-       printf("%d: TOTAL:     %10.2lf usec\n", getpid(), time.total);
-
-#if defined(_WIN32) || defined(_WIN64)
-       WSACleanup();
-#endif
-       return (0);
-}
-
-double get_time(void)
-{
-       struct timeval tp;
-
-       gettimeofday(&tp, NULL);
-       return ((double)tp.tv_sec + (double)tp.tv_usec * 1e-6);
-}
-
-void init_data(void)
-{
-       memset(rbuf, 'a', buf_len);
-       memset(sbuf, 'b', buf_len);
-}
-
-DAT_RETURN
-send_msg(void *data,
-        DAT_COUNT size,
-        DAT_LMR_CONTEXT context,
-        DAT_DTO_COOKIE cookie, DAT_COMPLETION_FLAGS flags)
-{
-       DAT_LMR_TRIPLET iov;
-       DAT_EVENT event;
-       DAT_COUNT nmore;
-       DAT_RETURN ret;
-
-       iov.lmr_context = context;
-#if defined(_WIN32)
-       iov.virtual_address = (DAT_VADDR) data;
-#else
-       iov.virtual_address = (DAT_VADDR) (unsigned long)data;
-#endif
-       iov.segment_length = size;
-
-       LOGPRINTF("%d calling post_send\n", getpid());
-       cookie.as_64 = 0xaaaa;
-       ret = dat_ep_post_send(h_ep, 1, &iov, cookie, flags);
-
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d: ERROR: dat_ep_post_send() %s\n",
-                       getpid(), DT_RetToString(ret));
-               return ret;
-       }
-
-       if (!(flags & DAT_COMPLETION_SUPPRESS_FLAG)) {
-               if (polling) {
-                       printf("%d Polling post send completion...\n",
-                              getpid());
-                       while (dat_evd_dequeue(h_dto_req_evd, &event) ==
-                              DAT_QUEUE_EMPTY) ;
-               } else {
-                       LOGPRINTF("%d waiting for post_send completion event\n",
-                                 getpid());
-                       if (use_cno) {
-                               DAT_EVD_HANDLE evd = DAT_HANDLE_NULL;
-                               ret =
-                                   dat_cno_wait(h_dto_cno, DTO_TIMEOUT, &evd);
-                               LOGPRINTF("%d cno wait return evd_handle=%p\n",
-                                         getpid(), evd);
-                               if (evd != h_dto_req_evd) {
-                                       fprintf(stderr,
-                                               "%d Error waiting on h_dto_cno: evd != h_dto_req_evd\n",
-                                               getpid());
-                                       return (DAT_ABORT);
-                               }
-                       }
-                       /* use wait to dequeue */
-                       ret =
-                           dat_evd_wait(h_dto_req_evd, DTO_TIMEOUT, 1, &event,
-                                        &nmore);
-                       if (ret != DAT_SUCCESS) {
-                               fprintf(stderr,
-                                       "%d: ERROR: DTO dat_evd_wait() %s\n",
-                                       getpid(), DT_RetToString(ret));
-                               return ret;
-                       }
-               }
-
-               /* validate event number, len, cookie, and status */
-               if (event.event_number != DAT_DTO_COMPLETION_EVENT) {
-                       fprintf(stderr, "%d: ERROR: DTO event number %s\n",
-                               getpid(), DT_EventToSTr(event.event_number));
-                       return (DAT_ABORT);
-               }
-
-               if ((event.event_data.dto_completion_event_data.
-                    transfered_length != size)
-                   || (event.event_data.dto_completion_event_data.user_cookie.
-                       as_64 != 0xaaaa)) {
-                       fprintf(stderr,
-                               "%d: ERROR: DTO len %d or cookie " F64x " \n",
-                               getpid(),
-                               event.event_data.dto_completion_event_data.
-                               transfered_length,
-                               event.event_data.dto_completion_event_data.
-                               user_cookie.as_64);
-                       return (DAT_ABORT);
-
-               }
-               if (event.event_data.dto_completion_event_data.status !=
-                   DAT_SUCCESS) {
-                       fprintf(stderr, "%d: ERROR: DTO event status %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (DAT_ABORT);
-               }
-       }
-
-       return DAT_SUCCESS;
-}
-
-DAT_RETURN connect_ep(char *hostname, DAT_CONN_QUAL conn_id)
-{
-       DAT_SOCK_ADDR remote_addr;
-       DAT_RETURN ret;
-       DAT_REGION_DESCRIPTION region;
-       DAT_EVENT event;
-       DAT_COUNT nmore;
-       DAT_LMR_TRIPLET l_iov;
-       DAT_RMR_TRIPLET r_iov;
-       DAT_DTO_COOKIE cookie;
-       int i;
-       unsigned char *buf;
-       DAT_CR_PARAM cr_param = { 0 };
-       unsigned char pdata[48] = { 0 };
-
-       /* Register send message buffer */
-       LOGPRINTF("%d Registering send Message Buffer %p, len %d\n",
-                 getpid(), &rmr_send_msg, (int)sizeof(DAT_RMR_TRIPLET));
-       region.for_va = &rmr_send_msg;
-       ret = dat_lmr_create(h_ia,
-                            DAT_MEM_TYPE_VIRTUAL,
-                            region,
-                            sizeof(DAT_RMR_TRIPLET),
-                            h_pz,
-                            DAT_MEM_PRIV_LOCAL_WRITE_FLAG,
-                            DAT_VA_TYPE_VA,
-                            &h_lmr_send_msg,
-                            &lmr_context_send_msg,
-                            &rmr_context_send_msg,
-                            &registered_size_send_msg,
-                            &registered_addr_send_msg);
-
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error registering send msg buffer: %s\n",
-                       getpid(), DT_RetToString(ret));
-               return (ret);
-       } else
-               LOGPRINTF("%d Registered send Message Buffer %p \n",
-                         getpid(), region.for_va);
-
-       /* Register Receive buffers */
-       LOGPRINTF("%d Registering Receive Message Buffer %p\n",
-                 getpid(), rmr_recv_msg);
-       region.for_va = rmr_recv_msg;
-       ret = dat_lmr_create(h_ia,
-                            DAT_MEM_TYPE_VIRTUAL,
-                            region,
-                            sizeof(DAT_RMR_TRIPLET) * MSG_BUF_COUNT,
-                            h_pz,
-                            DAT_MEM_PRIV_LOCAL_WRITE_FLAG,
-                            DAT_VA_TYPE_VA,
-                            &h_lmr_recv_msg,
-                            &lmr_context_recv_msg,
-                            &rmr_context_recv_msg,
-                            &registered_size_recv_msg,
-                            &registered_addr_recv_msg);
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error registering recv msg buffer: %s\n",
-                       getpid(), DT_RetToString(ret));
-               return (ret);
-       } else
-               LOGPRINTF("%d Registered Receive Message Buffer %p\n",
-                         getpid(), region.for_va);
-
-       for (i = 0; i < MSG_BUF_COUNT; i++) {
-               cookie.as_64 = i;
-               l_iov.lmr_context = lmr_context_recv_msg;
-#if defined(_WIN32)
-               l_iov.virtual_address = (DAT_VADDR) & rmr_recv_msg[i];
-#else
-               l_iov.virtual_address =
-                   (DAT_VADDR) (unsigned long)&rmr_recv_msg[i];
-#endif
-               l_iov.segment_length = sizeof(DAT_RMR_TRIPLET);
-
-               LOGPRINTF("%d Posting Receive Message Buffer %p\n",
-                         getpid(), &rmr_recv_msg[i]);
-               ret = dat_ep_post_recv(h_ep,
-                                      1,
-                                      &l_iov,
-                                      cookie, DAT_COMPLETION_DEFAULT_FLAG);
-
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr,
-                               "%d Error registering recv msg buffer: %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (ret);
-               } else
-                       LOGPRINTF("%d Registered Receive Message Buffer %p\n",
-                                 getpid(), region.for_va);
-
-       }
-
-       /* setup receive rdma buffer to initial string to be overwritten */
-       strcpy((char *)rbuf, "blah, blah, blah\n");
-
-       /* clear event structure */
-       memset(&event, 0, sizeof(DAT_EVENT));
-
-       if (server) {           /* SERVER */
-
-               /* create the service point for server listen */
-               LOGPRINTF("%d Creating service point for listen\n", getpid());
-               ret = dat_psp_create(h_ia,
-                                    conn_id,
-                                    h_cr_evd, DAT_PSP_CONSUMER_FLAG, &h_psp);
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr, "%d Error dat_psp_create: %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (ret);
-               } else
-                       LOGPRINTF("%d dat_psp_created for server listen\n",
-                                 getpid());
-
-               printf("%d Server waiting for connect request on port " F64x
-                      "\n", getpid(), conn_id);
-
-               ret = dat_evd_wait(h_cr_evd, SERVER_TIMEOUT, 1, &event, &nmore);
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr, "%d Error dat_evd_wait: %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (ret);
-               } else
-                       LOGPRINTF("%d dat_evd_wait for cr_evd completed\n",
-                                 getpid());
-
-               if (event.event_number != DAT_CONNECTION_REQUEST_EVENT) {
-                       fprintf(stderr, "%d Error unexpected cr event : %s\n",
-                               getpid(), DT_EventToSTr(event.event_number));
-                       return (DAT_ABORT);
-               }
-               if ((event.event_data.cr_arrival_event_data.conn_qual !=
-                    SERVER_CONN_QUAL)
-                   || (event.event_data.cr_arrival_event_data.sp_handle.
-                       psp_handle != h_psp)) {
-                       fprintf(stderr, "%d Error wrong cr event data : %s\n",
-                               getpid(), DT_EventToSTr(event.event_number));
-                       return (DAT_ABORT);
-               }
-
-               /* use to test rdma_cma timeout logic */
-#if defined(_WIN32) || defined(_WIN64)
-               if (delay)
-                       Sleep(delay * 1000);
-#else
-               if (delay)
-                       sleep(delay);
-#endif
-
-               /* accept connect request from client */
-               h_cr = event.event_data.cr_arrival_event_data.cr_handle;
-               LOGPRINTF("%d Accepting connect request from client\n",
-                         getpid());
-
-               /* private data - check and send it back */
-               dat_cr_query(h_cr, DAT_CSP_FIELD_ALL, &cr_param);
-
-               buf = (unsigned char *)cr_param.private_data;
-               LOGPRINTF("%d CONN REQUEST Private Data %p[0]=%d [47]=%d\n",
-                         getpid(), buf, buf[0], buf[47]);
-               for (i = 0; i < 48; i++) {
-                       if (buf[i] != i + 1) {
-                               fprintf(stderr, "%d Error with CONNECT REQUEST"
-                                       " private data: %p[%d]=%d s/be %d\n",
-                                       getpid(), buf, i, buf[i], i + 1);
-                               dat_cr_reject(h_cr, 0, NULL);
-                               return (DAT_ABORT);
-                       }
-                       buf[i]++;       /* change for trip back */
-               }
-
-#ifdef TEST_REJECT_WITH_PRIVATE_DATA
-               printf("%d REJECT request with 48 bytes of private data\n",
-                      getpid());
-               ret = dat_cr_reject(h_cr, 48, cr_param.private_data);
-               printf("\n%d: DAPL Test Complete. %s\n\n",
-                      getpid(), ret ? "FAILED" : "PASSED");
-               exit(0);
-#endif
-
-               ret = dat_cr_accept(h_cr, h_ep, 48, cr_param.private_data);
-
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr, "%d Error dat_cr_accept: %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (ret);
-               } else
-                       LOGPRINTF("%d dat_cr_accept completed\n", getpid());
-       } else {                /* CLIENT */
-               struct addrinfo *target;
-               int rval;
-
-#if defined(_WIN32) || defined(_WIN64)
-               if ((rval = getaddrinfo(hostname, "ftp", NULL, &target)) != 0) {
-                       printf("\n remote name resolution failed! %s\n",
-                              gai_strerror(rval));
-                       exit(1);
-               }
-               rval = ((struct sockaddr_in *)target->ai_addr)->sin_addr.s_addr;
-#else
-               if (getaddrinfo(hostname, NULL, NULL, &target) != 0) {
-                       perror("\n remote name resolution failed!");
-                       exit(1);
-               }
-               rval = ((struct sockaddr_in *)target->ai_addr)->sin_addr.s_addr;
-#endif
-               printf("%d Server Name: %s \n", getpid(), hostname);
-               printf("%d Server Net Address: %d.%d.%d.%d port " F64x "\n",
-                      getpid(), (rval >> 0) & 0xff, (rval >> 8) & 0xff,
-                      (rval >> 16) & 0xff, (rval >> 24) & 0xff, conn_id);
-
-               remote_addr = *((DAT_IA_ADDRESS_PTR) target->ai_addr);
-               freeaddrinfo(target);
-
-               for (i = 0; i < 48; i++)        /* simple pattern in private data */
-                       pdata[i] = i + 1;
-
-               LOGPRINTF("%d Connecting to server\n", getpid());
-               start = get_time();
-               ret = dat_ep_connect(h_ep,
-                                    &remote_addr,
-                                    conn_id,
-                                    CONN_TIMEOUT,
-                                    48,
-                                    (DAT_PVOID) pdata,
-                                    0, DAT_CONNECT_DEFAULT_FLAG);
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr, "%d Error dat_ep_connect: %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (ret);
-               } else
-                       LOGPRINTF("%d dat_ep_connect completed\n", getpid());
-       }
-
-       printf("%d Waiting for connect response\n", getpid());
-
-       if (polling) 
-               while (DAT_GET_TYPE(dat_evd_dequeue(h_conn_evd, &event)) == 
-                      DAT_QUEUE_EMPTY)
-                       conn_poll_count++;
-       else 
-               ret = dat_evd_wait(h_conn_evd, DAT_TIMEOUT_INFINITE, 
-                                  1, &event, &nmore);
-
-       if (!server) {
-               stop = get_time();
-               time.conn += ((stop - start) * 1.0e6);
-       }
-
-#ifdef TEST_REJECT_WITH_PRIVATE_DATA
-       if (event.event_number != DAT_CONNECTION_EVENT_PEER_REJECTED) {
-               fprintf(stderr, "%d expected conn reject event : %s\n",
-                       getpid(), DT_EventToSTr(event.event_number));
-               return (DAT_ABORT);
-       }
-       /* get the reject private data and validate */
-       buf = (unsigned char *)event.event_data.connect_event_data.private_data;
-       printf("%d Received REJECT with private data %p[0]=%d [47]=%d\n",
-              getpid(), buf, buf[0], buf[47]);
-       for (i = 0; i < 48; i++) {
-               if (buf[i] != i + 2) {
-                       fprintf(stderr, "%d client: Error with REJECT event"
-                               " private data: %p[%d]=%d s/be %d\n",
-                               getpid(), buf, i, buf[i], i + 2);
-                       dat_ep_disconnect(h_ep, DAT_CLOSE_ABRUPT_FLAG);
-                       return (DAT_ABORT);
-               }
-       }
-       printf("\n%d: DAPL Test Complete. PASSED\n\n", getpid());
-       exit(0);
-#endif
-
-       if (event.event_number != DAT_CONNECTION_EVENT_ESTABLISHED) {
-               fprintf(stderr, "%d Error unexpected conn event : 0x%x %s\n",
-                       getpid(), event.event_number,
-                       DT_EventToSTr(event.event_number));
-               return (DAT_ABORT);
-       }
-
-       /* check private data back from server  */
-       if (!server) {
-               buf =
-                   (unsigned char *)event.event_data.connect_event_data.
-                   private_data;
-               LOGPRINTF("%d CONN Private Data %p[0]=%d [47]=%d\n", getpid(),
-                         buf, buf[0], buf[47]);
-               for (i = 0; i < 48; i++) {
-                       if (buf[i] != i + 2) {
-                               fprintf(stderr, "%d Error with CONNECT event"
-                                       " private data: %p[%d]=%d s/be %d\n",
-                                       getpid(), buf, i, buf[i], i + 2);
-                               dat_ep_disconnect(h_ep, DAT_CLOSE_ABRUPT_FLAG);
-                               LOGPRINTF
-                                   ("%d waiting for disconnect event...\n",
-                                    getpid());
-                               dat_evd_wait(h_conn_evd, DAT_TIMEOUT_INFINITE,
-                                            1, &event, &nmore);
-                               return (DAT_ABORT);
-                       }
-               }
-       }
-
-       printf("\n%d CONNECTED!\n\n", getpid());
-       connected = 1;
-
-#if CONNECT_ONLY
-       return 0;
-#endif
-
-       /*
-        *  Setup our remote memory and tell the other side about it
-        */
-       rmr_send_msg.virtual_address = htonll((DAT_VADDR) (uintptr_t) rbuf);
-       rmr_send_msg.segment_length = htonl(RDMA_BUFFER_SIZE);
-       rmr_send_msg.rmr_context = htonl(rmr_context_recv);
-
-       printf("%d Send RMR msg to remote: r_key_ctx=0x%x,va=%p,len=0x%x\n",
-              getpid(), rmr_context_recv, rbuf, RDMA_BUFFER_SIZE);
-
-       ret = send_msg(&rmr_send_msg,
-                      sizeof(DAT_RMR_TRIPLET),
-                      lmr_context_send_msg,
-                      cookie, DAT_COMPLETION_SUPPRESS_FLAG);
-
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error send_msg: %s\n",
-                       getpid(), DT_RetToString(ret));
-               return (ret);
-       } else
-               LOGPRINTF("%d send_msg completed\n", getpid());
-
-       /*
-        *  Wait for remote RMR information for RDMA
-        */
-       if (polling) {
-               printf("%d Polling for remote to send RMR data\n", getpid());
-               while (dat_evd_dequeue(h_dto_rcv_evd, &event) ==
-                      DAT_QUEUE_EMPTY) ;
-       } else {
-               printf("%d Waiting for remote to send RMR data\n", getpid());
-               if (use_cno) {
-                       DAT_EVD_HANDLE evd = DAT_HANDLE_NULL;
-                       ret = dat_cno_wait(h_dto_cno, DTO_TIMEOUT, &evd);
-                       LOGPRINTF("%d cno wait return evd_handle=%p\n",
-                                 getpid(), evd);
-                       if (evd != h_dto_rcv_evd) {
-                               fprintf(stderr,
-                                       "%d Error waiting on h_dto_cno: evd != h_dto_rcv_evd\n",
-                                       getpid());
-                               return (DAT_ABORT);
-                       }
-               }
-               /* use wait to dequeue */
-               ret =
-                   dat_evd_wait(h_dto_rcv_evd, DTO_TIMEOUT, 1, &event, &nmore);
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr,
-                               "%d Error waiting on h_dto_rcv_evd: %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (ret);
-               } else {
-                       LOGPRINTF("%d dat_evd_wait h_dto_rcv_evd completed\n",
-                                 getpid());
-               }
-       }
-
-       printf("%d remote RMR data arrived!\n", getpid());
-
-       if (event.event_number != DAT_DTO_COMPLETION_EVENT) {
-               fprintf(stderr, "%d Error unexpected DTO event : %s\n",
-                       getpid(), DT_EventToSTr(event.event_number));
-               return (DAT_ABORT);
-       }
-       if ((event.event_data.dto_completion_event_data.transfered_length !=
-            sizeof(DAT_RMR_TRIPLET)) ||
-           (event.event_data.dto_completion_event_data.user_cookie.as_64 !=
-            recv_msg_index)) {
-               fprintf(stderr,
-                       "ERR recv event: len=%d cookie=" F64x
-                       " expected %d/%d\n",
-                       (int)event.event_data.dto_completion_event_data.
-                       transfered_length,
-                       event.event_data.dto_completion_event_data.user_cookie.
-                       as_64, (int)sizeof(DAT_RMR_TRIPLET), recv_msg_index);
-               return (DAT_ABORT);
-       }
-
-       /* swap received RMR msg: network order to host order */
-       r_iov = rmr_recv_msg[recv_msg_index];
-       rmr_recv_msg[recv_msg_index].rmr_context = ntohl(r_iov.rmr_context);
-       rmr_recv_msg[recv_msg_index].virtual_address =
-           ntohll(r_iov.virtual_address);
-       rmr_recv_msg[recv_msg_index].segment_length =
-           ntohl(r_iov.segment_length);
-
-       printf("%d Received RMR from remote: "
-              "r_iov: r_key_ctx=%x,va=" F64x ",len=0x%x\n",
-              getpid(), rmr_recv_msg[recv_msg_index].rmr_context,
-              rmr_recv_msg[recv_msg_index].virtual_address,
-              rmr_recv_msg[recv_msg_index].segment_length);
-
-       recv_msg_index++;
-
-       return (DAT_SUCCESS);
-}
-
-void disconnect_ep(void)
-{
-       DAT_RETURN ret;
-       DAT_EVENT event;
-       DAT_COUNT nmore;
-
-       if (connected) {
-
-               /* 
-                * Only the client needs to call disconnect. The server _should_ be able
-                * to just wait on the EVD associated with connection events for a
-                * disconnect request and then exit.
-                */
-               if (!server) {
-                       LOGPRINTF("%d dat_ep_disconnect\n", getpid());
-                       ret = dat_ep_disconnect(h_ep, DAT_CLOSE_DEFAULT);
-                       if (ret != DAT_SUCCESS) {
-                               fprintf(stderr,
-                                       "%d Error dat_ep_disconnect: %s\n",
-                                       getpid(), DT_RetToString(ret));
-                       } else {
-                               LOGPRINTF("%d dat_ep_disconnect completed\n",
-                                         getpid());
-                       }
-               } else {
-                       LOGPRINTF("%d Server waiting for disconnect...\n",
-                                 getpid());
-               }
-
-               ret =
-                   dat_evd_wait(h_conn_evd, DAT_TIMEOUT_INFINITE, 1, &event,
-                                &nmore);
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr, "%d Error dat_evd_wait: %s\n",
-                               getpid(), DT_RetToString(ret));
-               } else {
-                       LOGPRINTF("%d dat_evd_wait for h_conn_evd completed\n",
-                                 getpid());
-               }
-       }
-
-       /* destroy service point */
-       if ((server) && (h_psp != DAT_HANDLE_NULL)) {
-               ret = dat_psp_free(h_psp);
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr, "%d Error dat_psp_free: %s\n",
-                               getpid(), DT_RetToString(ret));
-               } else {
-                       LOGPRINTF("%d dat_psp_free completed\n", getpid());
-               }
-       }
-
-       /* Unregister Send message Buffer */
-       if (h_lmr_send_msg != DAT_HANDLE_NULL) {
-               LOGPRINTF("%d Unregister send message h_lmr %p \n", getpid(),
-                         h_lmr_send_msg);
-               ret = dat_lmr_free(h_lmr_send_msg);
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr,
-                               "%d Error deregistering send msg mr: %s\n",
-                               getpid(), DT_RetToString(ret));
-               } else {
-                       LOGPRINTF("%d Unregistered send message Buffer\n",
-                                 getpid());
-                       h_lmr_send_msg = NULL;
-               }
-       }
-
-       /* Unregister recv message Buffer */
-       if (h_lmr_recv_msg != DAT_HANDLE_NULL) {
-               LOGPRINTF("%d Unregister recv message h_lmr %p \n", getpid(),
-                         h_lmr_recv_msg);
-               ret = dat_lmr_free(h_lmr_recv_msg);
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr,
-                               "%d Error deregistering recv msg mr: %s\n",
-                               getpid(), DT_RetToString(ret));
-               } else {
-                       LOGPRINTF("%d Unregistered recv message Buffer\n",
-                                 getpid());
-                       h_lmr_recv_msg = NULL;
-               }
-       }
-       return;
-}
-
-DAT_RETURN do_rdma_write_with_msg(void)
-{
-       DAT_EVENT event;
-       DAT_COUNT nmore;
-       DAT_LMR_TRIPLET l_iov[MSG_IOV_COUNT];
-       DAT_RMR_TRIPLET r_iov;
-       DAT_DTO_COOKIE cookie;
-       DAT_RETURN ret;
-       int i;
-
-       printf("\n %d RDMA WRITE DATA with SEND MSG\n\n", getpid());
-
-       cookie.as_64 = 0x5555;
-
-       if (recv_msg_index >= MSG_BUF_COUNT)
-               return (DAT_ABORT);
-
-       /* get RMR information from previously received message */
-       r_iov = rmr_recv_msg[recv_msg_index - 1];
-
-       if (server)
-               strcpy((char *)sbuf, "server RDMA write data...");
-       else
-               strcpy((char *)sbuf, "client RDMA write data...");
-
-       for (i = 0; i < MSG_IOV_COUNT; i++) {
-               l_iov[i].lmr_context = lmr_context_send;
-               l_iov[i].segment_length = buf_len / MSG_IOV_COUNT;
-               l_iov[i].virtual_address = (DAT_VADDR) (uintptr_t)
-                   (&sbuf[l_iov[i].segment_length * i]);
-
-               LOGPRINTF("%d rdma_write iov[%d] buf=%p,len=%d\n",
-                         getpid(), i, &sbuf[l_iov[i].segment_length * i],
-                         l_iov[i].segment_length);
-       }
-
-       start = get_time();
-       for (i = 0; i < burst; i++) {
-               cookie.as_64 = 0x9999;
-               ret = dat_ep_post_rdma_write(h_ep,      // ep_handle
-                                            MSG_IOV_COUNT,     // num_segments
-                                            l_iov,     // LMR
-                                            cookie,    // user_cookie
-                                            &r_iov,    // RMR
-                                            DAT_COMPLETION_SUPPRESS_FLAG);
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr,
-                               "%d: ERROR: dat_ep_post_rdma_write() %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (DAT_ABORT);
-               }
-               LOGPRINTF("%d rdma_write # %d completed\n", getpid(), i + 1);
-       }
-
-       /*
-        *  Send RMR information a 2nd time to indicate completion
-        *  NOTE: already swapped to network order in connect_ep
-        */
-       printf("%d Sending RDMA WRITE completion message\n", getpid());
-
-       ret = send_msg(&rmr_send_msg,
-                      sizeof(DAT_RMR_TRIPLET),
-                      lmr_context_send_msg,
-                      cookie, DAT_COMPLETION_SUPPRESS_FLAG);
-
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error send_msg: %s\n",
-                       getpid(), DT_RetToString(ret));
-               return (ret);
-       } else {
-               LOGPRINTF("%d send_msg completed\n", getpid());
-       }
-
-       /*
-        *  Collect first event, write completion or the inbound recv 
-        */
-       if (polling) {
-               while (dat_evd_dequeue(h_dto_rcv_evd, &event) ==
-                      DAT_QUEUE_EMPTY)
-                       rdma_wr_poll_count++;
-       } else {
-               LOGPRINTF("%d waiting for message receive event\n", getpid());
-               if (use_cno) {
-                       DAT_EVD_HANDLE evd = DAT_HANDLE_NULL;
-                       ret = dat_cno_wait(h_dto_cno, DTO_TIMEOUT, &evd);
-                       LOGPRINTF("%d cno wait return evd_handle=%p\n",
-                                 getpid(), evd);
-                       if (evd != h_dto_rcv_evd) {
-                               fprintf(stderr,
-                                       "%d Error waiting on h_dto_cno: "
-                                       "evd != h_dto_rcv_evd\n", getpid());
-                               return (ret);
-                       }
-               }
-               /* use wait to dequeue */
-               ret =
-                   dat_evd_wait(h_dto_rcv_evd, DTO_TIMEOUT, 1, &event, &nmore);
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr, "%d: ERROR: DTO dat_evd_wait() %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (ret);
-               }
-       }
-       stop = get_time();
-       time.rdma_wr = ((stop - start) * 1.0e6);
-
-       /* validate event number and status */
-       printf("%d inbound rdma_write; send message arrived!\n", getpid());
-       if (event.event_number != DAT_DTO_COMPLETION_EVENT) {
-               fprintf(stderr, "%d Error unexpected DTO event : %s\n",
-                       getpid(), DT_EventToSTr(event.event_number));
-               return (DAT_ABORT);
-       }
-
-       if ((event.event_data.dto_completion_event_data.transfered_length !=
-            sizeof(DAT_RMR_TRIPLET))
-           || (event.event_data.dto_completion_event_data.user_cookie.as_64 !=
-               recv_msg_index)) {
-               fprintf(stderr,
-                       "unexpected event data for receive: len=%d cookie=" F64x
-                       " exp %d/%d\n",
-                       (int)event.event_data.dto_completion_event_data.
-                       transfered_length,
-                       event.event_data.dto_completion_event_data.user_cookie.
-                       as_64, (int)sizeof(DAT_RMR_TRIPLET), recv_msg_index);
-
-               return (DAT_ABORT);
-       }
-
-       /* swap received RMR msg: network order to host order */
-       r_iov = rmr_recv_msg[recv_msg_index];
-       rmr_recv_msg[recv_msg_index].virtual_address =
-           ntohll(rmr_recv_msg[recv_msg_index].virtual_address);
-       rmr_recv_msg[recv_msg_index].segment_length =
-           ntohl(rmr_recv_msg[recv_msg_index].segment_length);
-       rmr_recv_msg[recv_msg_index].rmr_context =
-           ntohl(rmr_recv_msg[recv_msg_index].rmr_context);
-
-       printf("%d Received RMR from remote: "
-              "r_iov: r_key_ctx=%x,va=" F64x ",len=0x%x\n",
-              getpid(), rmr_recv_msg[recv_msg_index].rmr_context,
-              rmr_recv_msg[recv_msg_index].virtual_address,
-              rmr_recv_msg[recv_msg_index].segment_length);
-
-       LOGPRINTF("%d inbound rdma_write; send msg event SUCCESS!!\n",
-                 getpid());
-
-       printf("%d %s RDMA write buffer contains: %s\n",
-              getpid(), server ? "SERVER:" : "CLIENT:", rbuf);
-
-       recv_msg_index++;
-
-       return (DAT_SUCCESS);
-}
-
-DAT_RETURN do_rdma_read_with_msg(void)
-{
-       DAT_EVENT event;
-       DAT_COUNT nmore;
-       DAT_LMR_TRIPLET l_iov;
-       DAT_RMR_TRIPLET r_iov;
-       DAT_DTO_COOKIE cookie;
-       DAT_RETURN ret;
-       int i;
-
-       printf("\n %d RDMA READ DATA with SEND MSG\n\n", getpid());
-
-       if (recv_msg_index >= MSG_BUF_COUNT)
-               return (DAT_ABORT);
-
-       /* get RMR information from previously received message */
-       r_iov = rmr_recv_msg[recv_msg_index - 1];
-
-       /* setup rdma read buffer to initial string to be overwritten */
-       strcpy((char *)sbuf, "blah, blah, blah\n");
-
-       if (server)
-               strcpy((char *)rbuf, "server RDMA read data...");
-       else
-               strcpy((char *)rbuf, "client RDMA read data...");
-
-       l_iov.lmr_context = lmr_context_send;
-       l_iov.virtual_address = (DAT_VADDR) (uintptr_t) sbuf;
-       l_iov.segment_length = buf_len;
-
-       for (i = 0; i < MAX_RDMA_RD; i++) {
-               cookie.as_64 = 0x9999;
-               start = get_time();
-               ret = dat_ep_post_rdma_read(h_ep,       // ep_handle
-                                           1,  // num_segments
-                                           &l_iov,     // LMR
-                                           cookie,     // user_cookie
-                                           &r_iov,     // RMR
-                                           DAT_COMPLETION_DEFAULT_FLAG);
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr,
-                               "%d: ERROR: dat_ep_post_rdma_read() %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (DAT_ABORT);
-               }
-
-               if (polling) {
-                       while (dat_evd_dequeue(h_dto_req_evd, &event) ==
-                              DAT_QUEUE_EMPTY)
-                               rdma_rd_poll_count[i]++;
-               } else {
-                       LOGPRINTF("%d waiting for rdma_read completion event\n",
-                                 getpid());
-                       if (use_cno) {
-                               DAT_EVD_HANDLE evd = DAT_HANDLE_NULL;
-                               ret =
-                                   dat_cno_wait(h_dto_cno, DTO_TIMEOUT, &evd);
-                               LOGPRINTF("%d cno wait return evd_handle=%p\n",
-                                         getpid(), evd);
-                               if (evd != h_dto_req_evd) {
-                                       fprintf(stderr,
-                                               "%d Error waiting on h_dto_cno: evd != h_dto_req_evd\n",
-                                               getpid());
-                                       return (DAT_ABORT);
-                               }
-                       }
-                       /* use wait to dequeue */
-                       ret =
-                           dat_evd_wait(h_dto_req_evd, DTO_TIMEOUT, 1, &event,
-                                        &nmore);
-                       if (ret != DAT_SUCCESS) {
-                               fprintf(stderr,
-                                       "%d: ERROR: DTO dat_evd_wait() %s\n",
-                                       getpid(), DT_RetToString(ret));
-                               return ret;
-                       }
-               }
-               /* validate event number, len, cookie, and status */
-               if (event.event_number != DAT_DTO_COMPLETION_EVENT) {
-                       fprintf(stderr, "%d: ERROR: DTO event number %s\n",
-                               getpid(), DT_EventToSTr(event.event_number));
-                       return (DAT_ABORT);
-               }
-               if ((event.event_data.dto_completion_event_data.
-                    transfered_length != buf_len)
-                   || (event.event_data.dto_completion_event_data.user_cookie.
-                       as_64 != 0x9999)) {
-                       fprintf(stderr,
-                               "%d: ERROR: DTO len %d or cookie " F64x "\n",
-                               getpid(),
-                               event.event_data.dto_completion_event_data.
-                               transfered_length,
-                               event.event_data.dto_completion_event_data.
-                               user_cookie.as_64);
-                       return (DAT_ABORT);
-               }
-               if (event.event_data.dto_completion_event_data.status !=
-                   DAT_SUCCESS) {
-                       fprintf(stderr, "%d: ERROR: DTO event status %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (DAT_ABORT);
-               }
-               stop = get_time();
-               time.rdma_rd[i] = ((stop - start) * 1.0e6);
-               time.rdma_rd_total += time.rdma_rd[i];
-
-               LOGPRINTF("%d rdma_read # %d completed\n", getpid(), i + 1);
-       }
-
-       /*
-        *  Send RMR information a 3rd time to indicate completion
-        *  NOTE: already swapped to network order in connect_ep
-        */
-       printf("%d Sending RDMA read completion message\n", getpid());
-
-       ret = send_msg(&rmr_send_msg,
-                      sizeof(DAT_RMR_TRIPLET),
-                      lmr_context_send_msg,
-                      cookie, DAT_COMPLETION_SUPPRESS_FLAG);
-
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error send_msg: %s\n",
-                       getpid(), DT_RetToString(ret));
-               return (ret);
-       } else {
-               LOGPRINTF("%d send_msg completed\n", getpid());
-       }
-
-       /*
-        *  Collect first event, write completion or the inbound recv with immed
-        */
-       printf("%d Waiting for inbound message....\n", getpid());
-       if (polling) {
-               while (dat_evd_dequeue(h_dto_rcv_evd, &event) ==
-                      DAT_QUEUE_EMPTY) ;
-       } else {
-               LOGPRINTF("%d waiting for message receive event\n", getpid());
-               if (use_cno) {
-                       DAT_EVD_HANDLE evd = DAT_HANDLE_NULL;
-                       ret = dat_cno_wait(h_dto_cno, DTO_TIMEOUT, &evd);
-                       LOGPRINTF("%d cno wait return evd_handle=%p\n",
-                                 getpid(), evd);
-                       if (evd != h_dto_rcv_evd) {
-                               fprintf(stderr,
-                                       "%d Error waiting on h_dto_cno: evd != h_dto_rcv_evd\n",
-                                       getpid());
-                               return (ret);
-                       }
-               }
-               /* use wait to dequeue */
-               ret =
-                   dat_evd_wait(h_dto_rcv_evd, DTO_TIMEOUT, 1, &event, &nmore);
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr, "%d: ERROR: DTO dat_evd_wait() %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (ret);
-               }
-       }
-
-       /* validate event number and status */
-       printf("%d inbound rdma_read; send message arrived!\n", getpid());
-       if (event.event_number != DAT_DTO_COMPLETION_EVENT) {
-               fprintf(stderr, "%d Error unexpected DTO event : %s\n",
-                       getpid(), DT_EventToSTr(event.event_number));
-               return (DAT_ABORT);
-       }
-
-       if ((event.event_data.dto_completion_event_data.transfered_length !=
-            sizeof(DAT_RMR_TRIPLET))
-           || (event.event_data.dto_completion_event_data.user_cookie.as_64 !=
-               recv_msg_index)) {
-
-               fprintf(stderr,
-                       "unexpected event data for receive: len=%d cookie=" F64x
-                       " exp %d/%d\n",
-                       (int)event.event_data.dto_completion_event_data.
-                       transfered_length,
-                       event.event_data.dto_completion_event_data.user_cookie.
-                       as_64, (int)sizeof(DAT_RMR_TRIPLET), recv_msg_index);
-
-               return (DAT_ABORT);
-       }
-
-       /* swap received RMR msg: network order to host order */
-       r_iov = rmr_recv_msg[recv_msg_index];
-       rmr_recv_msg[recv_msg_index].virtual_address =
-           ntohll(rmr_recv_msg[recv_msg_index].virtual_address);
-       rmr_recv_msg[recv_msg_index].segment_length =
-           ntohl(rmr_recv_msg[recv_msg_index].segment_length);
-       rmr_recv_msg[recv_msg_index].rmr_context =
-           ntohl(rmr_recv_msg[recv_msg_index].rmr_context);
-
-       printf("%d Received RMR from remote: "
-              "r_iov: r_key_ctx=%x,va=" F64x ",len=0x%x\n",
-              getpid(), rmr_recv_msg[recv_msg_index].rmr_context,
-              rmr_recv_msg[recv_msg_index].virtual_address,
-              rmr_recv_msg[recv_msg_index].segment_length);
-
-       LOGPRINTF("%d inbound rdma_write; send msg event SUCCESS!!\n",
-                 getpid());
-
-       printf("%d %s RCV RDMA read buffer contains: %s\n",
-              getpid(), server ? "SERVER:" : "CLIENT:", sbuf);
-
-       recv_msg_index++;
-
-       return (DAT_SUCCESS);
-}
-
-DAT_RETURN do_ping_pong_msg()
-{
-       DAT_EVENT event;
-       DAT_COUNT nmore;
-       DAT_DTO_COOKIE cookie;
-       DAT_LMR_TRIPLET l_iov;
-       DAT_RETURN ret;
-       int i;
-       char *snd_buf;
-       char *rcv_buf;
-
-       printf("\n %d PING DATA with SEND MSG\n\n", getpid());
-
-       snd_buf = sbuf;
-       rcv_buf = rbuf;
-
-       /* pre-post all buffers */
-       for (i = 0; i < burst; i++) {
-               burst_msg_posted++;
-               cookie.as_64 = i;
-               l_iov.lmr_context = lmr_context_recv;
-               l_iov.virtual_address = (DAT_VADDR) (uintptr_t) rcv_buf;
-               l_iov.segment_length = buf_len;
-
-               LOGPRINTF("%d Pre-posting Receive Message Buffers %p\n",
-                         getpid(), rcv_buf);
-
-               ret = dat_ep_post_recv(h_ep,
-                                      1,
-                                      &l_iov,
-                                      cookie, DAT_COMPLETION_DEFAULT_FLAG);
-
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr,
-                               "%d Error posting recv msg buffer: %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (ret);
-               } else {
-                       LOGPRINTF("%d Posted Receive Message Buffer %p\n",
-                                 getpid(), rcv_buf);
-               }
-
-               /* next buffer */
-               rcv_buf += buf_len;
-       }
-#if defined(_WIN32) || defined(_WIN64)
-       Sleep(1000);
-#else
-       sleep(1);
-#endif
-
-       /* Initialize recv_buf and index to beginning */
-       rcv_buf = rbuf;
-       burst_msg_index = 0;
-
-       /* client ping 0x55, server pong 0xAA in first byte */
-       start = get_time();
-       for (i = 0; i < burst; i++) {
-               /* walk the send and recv buffers */
-               if (!server) {
-                       *snd_buf = 0x55;
-
-                       LOGPRINTF("%d %s SND buffer %p contains: 0x%x len=%d\n",
-                                 getpid(), server ? "SERVER:" : "CLIENT:",
-                                 snd_buf, *snd_buf, buf_len);
-
-                       ret = send_msg(snd_buf,
-                                      buf_len,
-                                      lmr_context_send,
-                                      cookie, DAT_COMPLETION_SUPPRESS_FLAG);
-
-                       if (ret != DAT_SUCCESS) {
-                               fprintf(stderr, "%d Error send_msg: %s\n",
-                                       getpid(), DT_RetToString(ret));
-                               return (ret);
-                       } else {
-                               LOGPRINTF("%d send_msg completed\n", getpid());
-                       }
-               }
-
-               /* Wait for recv message */
-               if (polling) {
-                       poll_count = 0;
-                       LOGPRINTF("%d Polling for message receive event\n",
-                                 getpid());
-                       while (dat_evd_dequeue(h_dto_rcv_evd, &event) ==
-                              DAT_QUEUE_EMPTY)
-                               poll_count++;
-               } else {
-                       LOGPRINTF("%d waiting for message receive event\n",
-                                 getpid());
-                       if (use_cno) {
-                               DAT_EVD_HANDLE evd = DAT_HANDLE_NULL;
-                               ret =
-                                   dat_cno_wait(h_dto_cno, DTO_TIMEOUT, &evd);
-                               LOGPRINTF("%d cno wait return evd_handle=%p\n",
-                                         getpid(), evd);
-                               if (evd != h_dto_rcv_evd) {
-                                       fprintf(stderr,
-                                               "%d Error waiting on h_dto_cno: evd != h_dto_rcv_evd\n",
-                                               getpid());
-                                       return (ret);
-                               }
-                       }
-                       /* use wait to dequeue */
-                       ret =
-                           dat_evd_wait(h_dto_rcv_evd, DTO_TIMEOUT, 1, &event,
-                                        &nmore);
-                       if (ret != DAT_SUCCESS) {
-                               fprintf(stderr,
-                                       "%d: ERROR: DTO dat_evd_wait() %s\n",
-                                       getpid(), DT_RetToString(ret));
-                               return (ret);
-                       }
-               }
-               /* start timer after first message arrives on server */
-               if (i == 0) {
-                       start = get_time();
-               }
-               /* validate event number and status */
-               LOGPRINTF("%d inbound message; message arrived!\n", getpid());
-               if (event.event_number != DAT_DTO_COMPLETION_EVENT) {
-                       fprintf(stderr, "%d Error unexpected DTO event : %s\n",
-                               getpid(), DT_EventToSTr(event.event_number));
-                       return (DAT_ABORT);
-               }
-               if ((event.event_data.dto_completion_event_data.
-                    transfered_length != buf_len)
-                   || (event.event_data.dto_completion_event_data.user_cookie.
-                       as_64 != burst_msg_index)) {
-                       fprintf(stderr,
-                               "ERR: recv event: len=%d cookie=" F64x
-                               " exp %d/%d\n",
-                               (int)event.event_data.dto_completion_event_data.
-                               transfered_length,
-                               event.event_data.dto_completion_event_data.
-                               user_cookie.as_64, (int)buf_len,
-                               (int)burst_msg_index);
-
-                       return (DAT_ABORT);
-               }
-
-               LOGPRINTF("%d %s RCV buffer %p contains: 0x%x len=%d\n",
-                         getpid(), server ? "SERVER:" : "CLIENT:",
-                         rcv_buf, *rcv_buf, buf_len);
-
-               burst_msg_index++;
-
-               /* If server, change data and send it back to client */
-               if (server) {
-                       *snd_buf = 0xaa;
-
-                       LOGPRINTF("%d %s SND buffer %p contains: 0x%x len=%d\n",
-                                 getpid(), server ? "SERVER:" : "CLIENT:",
-                                 snd_buf, *snd_buf, buf_len);
-
-                       ret = send_msg(snd_buf,
-                                      buf_len,
-                                      lmr_context_send,
-                                      cookie, DAT_COMPLETION_SUPPRESS_FLAG);
-
-                       if (ret != DAT_SUCCESS) {
-                               fprintf(stderr, "%d Error send_msg: %s\n",
-                                       getpid(), DT_RetToString(ret));
-                               return (ret);
-                       } else {
-                               LOGPRINTF("%d send_msg completed\n", getpid());
-                       }
-               }
-
-               /* next buffers */
-               rcv_buf += buf_len;
-               snd_buf += buf_len;
-       }
-       stop = get_time();
-       time.rtt = ((stop - start) * 1.0e6);
-
-       return (DAT_SUCCESS);
-}
-
-/* Register RDMA Receive buffer */
-DAT_RETURN register_rdma_memory(void)
-{
-       DAT_RETURN ret;
-       DAT_REGION_DESCRIPTION region;
-
-       region.for_va = rbuf;
-       start = get_time();
-       ret = dat_lmr_create(h_ia,
-                            DAT_MEM_TYPE_VIRTUAL,
-                            region,
-                            buf_len * (burst+1),
-                            h_pz,
-                            DAT_MEM_PRIV_ALL_FLAG,
-                            DAT_VA_TYPE_VA,
-                            &h_lmr_recv,
-                            &lmr_context_recv,
-                            &rmr_context_recv,
-                            &registered_size_recv, &registered_addr_recv);
-       stop = get_time();
-       time.reg += ((stop - start) * 1.0e6);
-       time.total += time.reg;
-
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr,
-                       "%d Error registering Receive RDMA buffer: %s\n",
-                       getpid(), DT_RetToString(ret));
-               return (ret);
-       } else {
-               LOGPRINTF("%d Registered Receive RDMA Buffer %p\n",
-                         getpid(), region.for_va);
-       }
-
-       /* Register RDMA Send buffer */
-       region.for_va = sbuf;
-       ret = dat_lmr_create(h_ia,
-                            DAT_MEM_TYPE_VIRTUAL,
-                            region,
-                            buf_len * (burst + 1),
-                            h_pz,
-                            DAT_MEM_PRIV_ALL_FLAG,
-                            DAT_VA_TYPE_VA,
-                            &h_lmr_send,
-                            &lmr_context_send,
-                            &rmr_context_send,
-                            &registered_size_send, &registered_addr_send);
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error registering send RDMA buffer: %s\n",
-                       getpid(), DT_RetToString(ret));
-               return (ret);
-       } else {
-               LOGPRINTF("%d Registered Send RDMA Buffer %p\n",
-                         getpid(), region.for_va);
-       }
-
-       return DAT_SUCCESS;
-}
-
-/*
- * Unregister RDMA memory
- */
-DAT_RETURN unregister_rdma_memory(void)
-{
-       DAT_RETURN ret;
-
-       /* Unregister Recv Buffer */
-       if (h_lmr_recv != DAT_HANDLE_NULL) {
-               LOGPRINTF("%d Unregister h_lmr %p \n", getpid(), h_lmr_recv);
-               start = get_time();
-               ret = dat_lmr_free(h_lmr_recv);
-               stop = get_time();
-               time.unreg += ((stop - start) * 1.0e6);
-               time.total += time.unreg;
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr, "%d Error deregistering recv mr: %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (ret);
-               } else {
-                       LOGPRINTF("%d Unregistered Recv Buffer\n", getpid());
-                       h_lmr_recv = NULL;
-               }
-       }
-
-       /* Unregister Send Buffer */
-       if (h_lmr_send != DAT_HANDLE_NULL) {
-               LOGPRINTF("%d Unregister h_lmr %p \n", getpid(), h_lmr_send);
-               ret = dat_lmr_free(h_lmr_send);
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr, "%d Error deregistering send mr: %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (ret);
-               } else {
-                       LOGPRINTF("%d Unregistered send Buffer\n", getpid());
-                       h_lmr_send = NULL;
-               }
-       }
-       return DAT_SUCCESS;
-}
-
- /*
-  * Create CNO, CR, CONN, and DTO events
-  */
-DAT_RETURN create_events(void)
-{
-       DAT_RETURN ret;
-       DAT_EVD_PARAM param;
-
-       /* create CNO */
-       if (use_cno) {
-               start = get_time();
-#if defined(_WIN32) || defined(_WIN64)
-               {
-                       DAT_OS_WAIT_PROXY_AGENT pa = { NULL, NULL };
-                       ret = dat_cno_create(h_ia, pa, &h_dto_cno);
-               }
-#else
-               ret =
-                   dat_cno_create(h_ia, DAT_OS_WAIT_PROXY_AGENT_NULL,
-                                  &h_dto_cno);
-#endif
-               stop = get_time();
-               time.cnoc += ((stop - start) * 1.0e6);
-               time.total += time.cnoc;
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr, "%d Error dat_cno_create: %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (ret);
-               } else {
-                       LOGPRINTF("%d cr_evd created, %p\n", getpid(),
-                                 h_dto_cno);
-               }
-       }
-
-       /* create cr EVD */
-       start = get_time();
-       ret =
-           dat_evd_create(h_ia, 10, DAT_HANDLE_NULL, DAT_EVD_CR_FLAG,
-                          &h_cr_evd);
-       stop = get_time();
-       time.evdc += ((stop - start) * 1.0e6);
-       time.total += time.evdc;
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error dat_evd_create: %s\n",
-                       getpid(), DT_RetToString(ret));
-               return (ret);
-       } else {
-               LOGPRINTF("%d cr_evd created %p\n", getpid(), h_cr_evd);
-       }
-
-       /* create conn EVD */
-       ret = dat_evd_create(h_ia,
-                            10,
-                            DAT_HANDLE_NULL,
-                            DAT_EVD_CONNECTION_FLAG, &h_conn_evd);
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error dat_evd_create: %s\n",
-                       getpid(), DT_RetToString(ret));
-               return (ret);
-       } else {
-               LOGPRINTF("%d con_evd created %p\n", getpid(), h_conn_evd);
-       }
-
-       /* create dto SND EVD, with CNO if use_cno was set */
-       ret = dat_evd_create(h_ia,
-                            (MSG_BUF_COUNT + MAX_RDMA_RD + burst) * 2,
-                            h_dto_cno, DAT_EVD_DTO_FLAG, &h_dto_req_evd);
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error dat_evd_create REQ: %s\n",
-                       getpid(), DT_RetToString(ret));
-               return (ret);
-       } else {
-               LOGPRINTF("%d dto_req_evd created %p\n", getpid(),
-                         h_dto_req_evd);
-       }
-
-       /* create dto RCV EVD, with CNO if use_cno was set */
-       ret = dat_evd_create(h_ia,
-                            MSG_BUF_COUNT + burst,
-                            h_dto_cno, DAT_EVD_DTO_FLAG, &h_dto_rcv_evd);
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error dat_evd_create RCV: %s\n",
-                       getpid(), DT_RetToString(ret));
-               return (ret);
-       } else {
-               LOGPRINTF("%d dto_rcv_evd created %p\n", getpid(),
-                         h_dto_rcv_evd);
-       }
-
-       /* query DTO req EVD and check size */
-       ret = dat_evd_query(h_dto_req_evd, DAT_EVD_FIELD_EVD_QLEN, &param);
-       if (ret != DAT_SUCCESS) {
-               fprintf(stderr, "%d Error dat_evd_query request evd: %s\n",
-                       getpid(), DT_RetToString(ret));
-               return (ret);
-       } else if (param.evd_qlen < (MSG_BUF_COUNT + MAX_RDMA_RD + burst) * 2) {
-               fprintf(stderr, "%d Error dat_evd qsize too small: %d < %d\n",
-                       getpid(), param.evd_qlen,
-                       (MSG_BUF_COUNT + MAX_RDMA_RD + burst) * 2);
-               return (ret);
-       }
-
-       LOGPRINTF("%d dto_req_evd QLEN - requested %d and actual %d\n",
-                 getpid(), (MSG_BUF_COUNT + MAX_RDMA_RD + burst) * 2,
-                 param.evd_qlen);
-
-       return DAT_SUCCESS;
-}
-
-/*
- * Destroy CR, CONN, CNO, and DTO events
- */
-
-DAT_RETURN destroy_events(void)
-{
-       DAT_RETURN ret;
-
-       /* free cr EVD */
-       if (h_cr_evd != DAT_HANDLE_NULL) {
-               LOGPRINTF("%d Free cr EVD %p \n", getpid(), h_cr_evd);
-               ret = dat_evd_free(h_cr_evd);
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr, "%d Error freeing cr EVD: %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (ret);
-               } else {
-                       LOGPRINTF("%d Freed cr EVD\n", getpid());
-                       h_cr_evd = DAT_HANDLE_NULL;
-               }
-       }
-
-       /* free conn EVD */
-       if (h_conn_evd != DAT_HANDLE_NULL) {
-               LOGPRINTF("%d Free conn EVD %p \n", getpid(), h_conn_evd);
-               ret = dat_evd_free(h_conn_evd);
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr, "%d Error freeing conn EVD: %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (ret);
-               } else {
-                       LOGPRINTF("%d Freed conn EVD\n", getpid());
-                       h_conn_evd = DAT_HANDLE_NULL;
-               }
-       }
-
-       /* free RCV dto EVD */
-       if (h_dto_rcv_evd != DAT_HANDLE_NULL) {
-               LOGPRINTF("%d Free RCV dto EVD %p \n", getpid(), h_dto_rcv_evd);
-               start = get_time();
-               ret = dat_evd_free(h_dto_rcv_evd);
-               stop = get_time();
-               time.evdf += ((stop - start) * 1.0e6);
-               time.total += time.evdf;
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr, "%d Error freeing dto EVD: %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (ret);
-               } else {
-                       LOGPRINTF("%d Freed dto EVD\n", getpid());
-                       h_dto_rcv_evd = DAT_HANDLE_NULL;
-               }
-       }
-
-       /* free REQ dto EVD */
-       if (h_dto_req_evd != DAT_HANDLE_NULL) {
-               LOGPRINTF("%d Free REQ dto EVD %p \n", getpid(), h_dto_req_evd);
-               ret = dat_evd_free(h_dto_req_evd);
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr, "%d Error freeing dto EVD: %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (ret);
-               } else {
-                       LOGPRINTF("%d Freed dto EVD\n", getpid());
-                       h_dto_req_evd = DAT_HANDLE_NULL;
-               }
-       }
-
-       /* free CNO */
-       if (h_dto_cno != DAT_HANDLE_NULL) {
-               LOGPRINTF("%d Free dto CNO %p \n", getpid(), h_dto_cno);
-               start = get_time();
-               ret = dat_cno_free(h_dto_cno);
-               stop = get_time();
-               time.cnof += ((stop - start) * 1.0e6);
-               time.total += time.cnof;
-               if (ret != DAT_SUCCESS) {
-                       fprintf(stderr, "%d Error freeing dto CNO: %s\n",
-                               getpid(), DT_RetToString(ret));
-                       return (ret);
-               } else {
-                       LOGPRINTF("%d Freed dto CNO\n", getpid());
-                       h_dto_cno = DAT_HANDLE_NULL;
-               }
-       }
-       return DAT_SUCCESS;
-}
-
-/*
- * Map DAT_RETURN values to readable strings,
- * but don't assume the values are zero-based or contiguous.
- */
-char errmsg[512] = { 0 };
-const char *DT_RetToString(DAT_RETURN ret_value)
-{
-       const char *major_msg, *minor_msg;
-
-       dat_strerror(ret_value, &major_msg, &minor_msg);
-
-       strcpy(errmsg, major_msg);
-       strcat(errmsg, " ");
-       strcat(errmsg, minor_msg);
-
-       return errmsg;
-}
-
-/*
- * Map DAT_EVENT_CODE values to readable strings
- */
-const char *DT_EventToSTr(DAT_EVENT_NUMBER event_code)
-{
-       unsigned int i;
-       static struct {
-               const char *name;
-               DAT_RETURN value;
-       } dat_events[] = {
-#   define DATxx(x) { # x, x }
-               DATxx(DAT_DTO_COMPLETION_EVENT),
-                   DATxx(DAT_RMR_BIND_COMPLETION_EVENT),
-                   DATxx(DAT_CONNECTION_REQUEST_EVENT),
-                   DATxx(DAT_CONNECTION_EVENT_ESTABLISHED),
-                   DATxx(DAT_CONNECTION_EVENT_PEER_REJECTED),
-                   DATxx(DAT_CONNECTION_EVENT_NON_PEER_REJECTED),
-                   DATxx(DAT_CONNECTION_EVENT_ACCEPT_COMPLETION_ERROR),
-                   DATxx(DAT_CONNECTION_EVENT_DISCONNECTED),
-                   DATxx(DAT_CONNECTION_EVENT_BROKEN),
-                   DATxx(DAT_CONNECTION_EVENT_TIMED_OUT),
-                   DATxx(DAT_CONNECTION_EVENT_UNREACHABLE),
-                   DATxx(DAT_ASYNC_ERROR_EVD_OVERFLOW),
-                   DATxx(DAT_ASYNC_ERROR_IA_CATASTROPHIC),
-                   DATxx(DAT_ASYNC_ERROR_EP_BROKEN),
-                   DATxx(DAT_ASYNC_ERROR_TIMED_OUT),
-                   DATxx(DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR),
-                   DATxx(DAT_SOFTWARE_EVENT)
-#   undef DATxx
-       };
-#   define NUM_EVENTS (sizeof(dat_events)/sizeof(dat_events[0]))
-
-       for (i = 0; i < NUM_EVENTS; i++) {
-               if (dat_events[i].value == event_code) {
-                       return (dat_events[i].name);
-               }
-       }
-
-       return ("Invalid_DAT_EVENT_NUMBER");
-}
-
-void print_usage(void)
-{
-       printf("\n DAPL USAGE \n\n");
-       printf("s: server\n");
-       printf("t: performance times\n");
-       printf("c: use cno\n");
-       printf("v: verbose\n");
-       printf("p: polling\n");
-       printf("d: delay before accept\n");
-       printf("b: buf length to allocate\n");
-       printf("B: burst count, rdma and msgs \n");
-       printf("h: hostname/address of server, specified on client\n");
-       printf("P: provider name (default = OpenIB-cma)\n");
-       printf("\n");
-}
-
+/*\r
+ * Copyright (c) 2005-2008 Intel Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under a choice of one of two\r
+ * licenses.  You may choose to be licensed under the terms of the GNU\r
+ * General Public License (GPL) Version 2, available from the file\r
+ * COPYING in the main directory of this source tree, or the\r
+ * OpenIB.org BSD license below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id: $\r
+ */\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+#ifdef DAPL_PROVIDER\r
+#undef DAPL_PROVIDER\r
+#endif\r
+\r
+#if defined(_WIN32) || defined(_WIN64)\r
+\r
+#include <windows.h>\r
+#include <winsock2.h>\r
+#include <ws2tcpip.h>\r
+#include <io.h>\r
+#include <process.h>\r
+#include <complib/cl_types.h>\r
+#include "..\..\..\..\etc\user\getopt.c"\r
+\r
+#define getpid() ((int)GetCurrentProcessId())\r
+#define F64x "%I64x"\r
+\r
+#ifdef DBG\r
+#define DAPL_PROVIDER "ibnic0v2d"\r
+#else\r
+#define DAPL_PROVIDER "ibnic0v2"\r
+#endif\r
+\r
+#define ntohll _byteswap_uint64\r
+#define htonll _byteswap_uint64\r
+\r
+#else // _WIN32 || _WIN64\r
+\r
+#include <endian.h>\r
+#include <byteswap.h>\r
+#include <netdb.h>\r
+#include <sys/types.h>\r
+#include <sys/socket.h>\r
+#include <sys/time.h>\r
+#include <netinet/in.h>\r
+#include <netinet/tcp.h>\r
+#include <arpa/inet.h>\r
+#include <sys/mman.h>\r
+#include <getopt.h>\r
+#include <inttypes.h>\r
+#include <unistd.h>\r
+\r
+#define DAPL_PROVIDER "ofa-v2-ib0"\r
+\r
+#define F64x "%"PRIx64""\r
+\r
+#if __BYTE_ORDER == __BIG_ENDIAN\r
+#define htonll(x) (x)\r
+#define ntohll(x) (x)\r
+#elif __BYTE_ORDER == __LITTLE_ENDIAN\r
+#define htonll(x)  bswap_64(x)\r
+#define ntohll(x)  bswap_64(x)\r
+#endif\r
+\r
+#endif // _WIN32 || _WIN64\r
+\r
+/* Debug: 1 == connect & close only, otherwise full-meal deal */\r
+#define CONNECT_ONLY 0\r
+\r
+#define MAX_POLLING_CNT 50000\r
+#define MAX_RDMA_RD    4\r
+#define MAX_PROCS      1000\r
+\r
+/* Header files needed for DAT/uDAPL */\r
+#include    "dat2/udat.h"\r
+\r
+/* definitions */\r
+#define SERVER_CONN_QUAL  45248\r
+#define DTO_TIMEOUT       (1000*1000*5)\r
+#define DTO_FLUSH_TIMEOUT (1000*1000*2)\r
+#define CONN_TIMEOUT      (1000*1000*10)\r
+#define SERVER_TIMEOUT    DAT_TIMEOUT_INFINITE\r
+#define RDMA_BUFFER_SIZE  (64)\r
+\r
+/* Global DAT vars */\r
+static DAT_IA_HANDLE h_ia = DAT_HANDLE_NULL;\r
+static DAT_PZ_HANDLE h_pz = DAT_HANDLE_NULL;\r
+static DAT_EP_HANDLE h_ep = DAT_HANDLE_NULL;\r
+static DAT_PSP_HANDLE h_psp = DAT_HANDLE_NULL;\r
+static DAT_CR_HANDLE h_cr = DAT_HANDLE_NULL;\r
+\r
+static DAT_EVD_HANDLE h_async_evd = DAT_HANDLE_NULL;\r
+static DAT_EVD_HANDLE h_dto_req_evd = DAT_HANDLE_NULL;\r
+static DAT_EVD_HANDLE h_dto_rcv_evd = DAT_HANDLE_NULL;\r
+static DAT_EVD_HANDLE h_cr_evd = DAT_HANDLE_NULL;\r
+static DAT_EVD_HANDLE h_conn_evd = DAT_HANDLE_NULL;\r
+static DAT_CNO_HANDLE h_dto_cno = DAT_HANDLE_NULL;\r
+\r
+/* RDMA buffers */\r
+static DAT_LMR_HANDLE h_lmr_send = DAT_HANDLE_NULL;\r
+static DAT_LMR_HANDLE h_lmr_recv = DAT_HANDLE_NULL;\r
+static DAT_LMR_CONTEXT lmr_context_send;\r
+static DAT_LMR_CONTEXT lmr_context_recv;\r
+static DAT_RMR_CONTEXT rmr_context_send;\r
+static DAT_RMR_CONTEXT rmr_context_recv;\r
+static DAT_VLEN registered_size_send;\r
+static DAT_VLEN registered_size_recv;\r
+static DAT_VADDR registered_addr_send;\r
+static DAT_VADDR registered_addr_recv;\r
+\r
+/* Initial msg receive buf, RMR exchange, and Rdma-write notification */\r
+#define MSG_BUF_COUNT     3\r
+#define MSG_IOV_COUNT     2\r
+static DAT_RMR_TRIPLET rmr_recv_msg[MSG_BUF_COUNT];\r
+static DAT_LMR_HANDLE h_lmr_recv_msg = DAT_HANDLE_NULL;\r
+static DAT_LMR_CONTEXT lmr_context_recv_msg;\r
+static DAT_RMR_CONTEXT rmr_context_recv_msg;\r
+static DAT_VLEN registered_size_recv_msg;\r
+static DAT_VADDR registered_addr_recv_msg;\r
+\r
+/* message send buffer */\r
+static DAT_RMR_TRIPLET rmr_send_msg;\r
+static DAT_LMR_HANDLE h_lmr_send_msg = DAT_HANDLE_NULL;\r
+static DAT_LMR_CONTEXT lmr_context_send_msg;\r
+static DAT_RMR_CONTEXT rmr_context_send_msg;\r
+static DAT_VLEN registered_size_send_msg;\r
+static DAT_VADDR registered_addr_send_msg;\r
+static DAT_EP_ATTR ep_attr;\r
+char hostname[256] = { 0 };\r
+char provider[64] = DAPL_PROVIDER;\r
+char addr_str[INET_ADDRSTRLEN];\r
+\r
+/* rdma pointers */\r
+char *rbuf = NULL;\r
+char *sbuf = NULL;\r
+int status;\r
+\r
+/* timers */\r
+double start, stop, total_us, total_sec;\r
+\r
+struct dt_time {\r
+       double total;\r
+       double open;\r
+       double reg;\r
+       double unreg;\r
+       double pzc;\r
+       double pzf;\r
+       double evdc;\r
+       double evdf;\r
+       double cnoc;\r
+       double cnof;\r
+       double epc;\r
+       double epf;\r
+       double rdma_wr;\r
+       double rdma_rd[MAX_RDMA_RD];\r
+       double rdma_rd_total;\r
+       double rtt;\r
+       double close;\r
+       double conn;\r
+};\r
+\r
+struct dt_time time;\r
+\r
+/* defaults */\r
+static int failed = 0;\r
+static int performance_times = 0;\r
+static int connected = 0;\r
+static int burst = 10;\r
+static int server = 1;\r
+static int verbose = 0;\r
+static int polling = 0;\r
+static int poll_count = 0;\r
+static int rdma_wr_poll_count = 0;\r
+static int conn_poll_count = 0;\r
+static int rdma_rd_poll_count[MAX_RDMA_RD] = { 0 };\r
+static int delay = 0;\r
+static int buf_len = RDMA_BUFFER_SIZE;\r
+static int use_cno = 0;\r
+static int recv_msg_index = 0;\r
+static int burst_msg_posted = 0;\r
+static int burst_msg_index = 0;\r
+\r
+/* forward prototypes */\r
+const char *DT_RetToString(DAT_RETURN ret_value);\r
+const char *DT_EventToSTr(DAT_EVENT_NUMBER event_code);\r
+void print_usage(void);\r
+double get_time(void);\r
+void init_data(void);\r
+\r
+DAT_RETURN send_msg(void *data,\r
+                   DAT_COUNT size,\r
+                   DAT_LMR_CONTEXT context,\r
+                   DAT_DTO_COOKIE cookie, DAT_COMPLETION_FLAGS flags);\r
+\r
+DAT_RETURN connect_ep(char *hostname, DAT_CONN_QUAL conn_id);\r
+void disconnect_ep(void);\r
+DAT_RETURN register_rdma_memory(void);\r
+DAT_RETURN unregister_rdma_memory(void);\r
+DAT_RETURN create_events(void);\r
+DAT_RETURN destroy_events(void);\r
+DAT_RETURN do_rdma_write_with_msg(void);\r
+DAT_RETURN do_rdma_read_with_msg(void);\r
+DAT_RETURN do_ping_pong_msg(void);\r
+\r
+#define LOGPRINTF if (verbose) printf\r
+\r
+void flush_evds(void)\r
+{\r
+       DAT_EVENT event;\r
+\r
+       /* Flush async error queue */\r
+       printf("%d ERR: Checking ASYNC EVD...\n", getpid());\r
+       while (dat_evd_dequeue(h_async_evd, &event) == DAT_SUCCESS) {\r
+               printf(" ASYNC EVD ENTRY: handle=%p reason=%d\n",\r
+                       event.event_data.asynch_error_event_data.dat_handle,\r
+                       event.event_data.asynch_error_event_data.reason);\r
+       }\r
+       /* Flush receive queue */\r
+       printf("%d ERR: Checking RECEIVE EVD...\n", getpid());\r
+       while (dat_evd_dequeue(h_dto_rcv_evd, &event) == DAT_SUCCESS) {\r
+               printf(" RCV EVD ENTRY: op=%d stat=%d ln=%d ck="F64x"\n",\r
+                       event.event_data.dto_completion_event_data.operation,\r
+                       event.event_data.dto_completion_event_data.status,\r
+                       event.event_data.dto_completion_event_data.transfered_length,\r
+                       event.event_data.dto_completion_event_data.user_cookie.as_64);\r
+       }\r
+       /* Flush request queue */\r
+       printf("%d ERR: Checking REQUEST EVD...\n", getpid());\r
+       while (dat_evd_dequeue(h_dto_req_evd, &event) == DAT_SUCCESS) {\r
+               printf(" REQ EVD ENTRY: op=%d stat=%d ln=%d ck="F64x"\n",\r
+                       event.event_data.dto_completion_event_data.operation,\r
+                       event.event_data.dto_completion_event_data.status,\r
+                       event.event_data.dto_completion_event_data.transfered_length,\r
+                       event.event_data.dto_completion_event_data.user_cookie.as_64);\r
+       }\r
+}\r
+\r
+int main(int argc, char **argv)\r
+{\r
+       int i, c;\r
+       DAT_RETURN ret;\r
+       DAT_EP_PARAM ep_param;\r
+\r
+       /* parse arguments */\r
+       while ((c = getopt(argc, argv, "tscvpb:d:B:h:P:")) != -1) {\r
+               switch (c) {\r
+               case 't':\r
+                       performance_times = 1;\r
+                       fflush(stdout);\r
+                       break;\r
+               case 's':\r
+                       server = 1;\r
+                       fflush(stdout);\r
+                       break;\r
+               case 'c':\r
+                       use_cno = 1;\r
+                       printf("%d Creating CNO for DTO EVD's\n", getpid());\r
+                       fflush(stdout);\r
+                       break;\r
+               case 'v':\r
+                       verbose = 1;\r
+                       printf("%d Verbose\n", getpid());\r
+                       fflush(stdout);\r
+                       break;\r
+               case 'p':\r
+                       polling = 1;\r
+                       printf("%d Polling\n", getpid());\r
+                       fflush(stdout);\r
+                       break;\r
+               case 'B':\r
+                       burst = atoi(optarg);\r
+                       break;\r
+               case 'd':\r
+                       delay = atoi(optarg);\r
+                       break;\r
+               case 'b':\r
+                       buf_len = atoi(optarg);\r
+                       break;\r
+               case 'h':\r
+                       server = 0;\r
+                       strcpy(hostname, optarg);\r
+                       break;\r
+               case 'P':\r
+                       strcpy(provider, optarg);\r
+                       break;\r
+               default:\r
+                       print_usage();\r
+                       exit(-12);\r
+               }\r
+       }\r
+\r
+#if defined(_WIN32) || defined(_WIN64)\r
+       {\r
+               WSADATA wsaData;\r
+\r
+               i = WSAStartup(MAKEWORD(2, 2), &wsaData);\r
+               if (i != 0) {\r
+                       printf("%s WSAStartup(2.2) failed? (0x%x)\n", argv[0],\r
+                              i);\r
+                       fflush(stdout);\r
+                       exit(1);\r
+               }\r
+       }\r
+#endif\r
+\r
+       if (!server) {\r
+               printf("%d Running as client - %s\n", getpid(), provider);\r
+       } else {\r
+               printf("%d Running as server - %s\n", getpid(), provider);\r
+       }\r
+       fflush(stdout);\r
+\r
+       /* allocate send and receive buffers */\r
+       if (((rbuf = malloc(buf_len * (burst+1))) == NULL) ||\r
+           ((sbuf = malloc(buf_len * (burst+1))) == NULL)) {\r
+               perror("malloc");\r
+               exit(1);\r
+       }\r
+       memset(&time, 0, sizeof(struct dt_time));\r
+       LOGPRINTF("%d Allocated RDMA buffers (r:%p,s:%p) len %d \n",\r
+                 getpid(), rbuf, sbuf, buf_len);\r
+\r
+       /* dat_ia_open, dat_pz_create */\r
+       h_async_evd = DAT_HANDLE_NULL;\r
+       start = get_time();\r
+       ret = dat_ia_open(provider, 8, &h_async_evd, &h_ia);\r
+       stop = get_time();\r
+       time.open += ((stop - start) * 1.0e6);\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d: Error Adaptor open: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               exit(1);\r
+       } else\r
+               LOGPRINTF("%d Opened Interface Adaptor\n", getpid());\r
+\r
+       /* Create Protection Zone */\r
+       start = get_time();\r
+       LOGPRINTF("%d Create Protection Zone\n", getpid());\r
+       ret = dat_pz_create(h_ia, &h_pz);\r
+       stop = get_time();\r
+       time.pzc += ((stop - start) * 1.0e6);\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error creating Protection Zone: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               exit(1);\r
+       } else\r
+               LOGPRINTF("%d Created Protection Zone\n", getpid());\r
+\r
+       /* Register memory */\r
+       LOGPRINTF("%d Register RDMA memory\n", getpid());\r
+       ret = register_rdma_memory();\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error registering RDMA memory: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               goto cleanup;\r
+       } else\r
+               LOGPRINTF("%d Register RDMA memory done\n", getpid());\r
+\r
+       LOGPRINTF("%d Create events\n", getpid());\r
+       ret = create_events();\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error creating events: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               goto cleanup;\r
+       } else {\r
+               LOGPRINTF("%d Create events done\n", getpid());\r
+       }\r
+\r
+       /* create EP */\r
+       memset(&ep_attr, 0, sizeof(ep_attr));\r
+       ep_attr.service_type = DAT_SERVICE_TYPE_RC;\r
+       ep_attr.max_rdma_size = 0x10000;\r
+       ep_attr.qos = 0;\r
+       ep_attr.recv_completion_flags = 0;\r
+       ep_attr.max_recv_dtos = MSG_BUF_COUNT + (burst * 3);\r
+       ep_attr.max_request_dtos = MSG_BUF_COUNT + (burst * 3) + MAX_RDMA_RD;\r
+       ep_attr.max_recv_iov = MSG_IOV_COUNT;\r
+       ep_attr.max_request_iov = MSG_IOV_COUNT;\r
+       ep_attr.max_rdma_read_in = MAX_RDMA_RD;\r
+       ep_attr.max_rdma_read_out = MAX_RDMA_RD;\r
+       ep_attr.request_completion_flags = DAT_COMPLETION_DEFAULT_FLAG;\r
+       ep_attr.ep_transport_specific_count = 0;\r
+       ep_attr.ep_transport_specific = NULL;\r
+       ep_attr.ep_provider_specific_count = 0;\r
+       ep_attr.ep_provider_specific = NULL;\r
+\r
+       start = get_time();\r
+       ret = dat_ep_create(h_ia, h_pz, h_dto_rcv_evd,\r
+                           h_dto_req_evd, h_conn_evd, &ep_attr, &h_ep);\r
+       stop = get_time();\r
+       time.epc += ((stop - start) * 1.0e6);\r
+       time.total += time.epc;\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error dat_ep_create: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               goto cleanup;\r
+       } else\r
+               LOGPRINTF("%d EP created %p \n", getpid(), h_ep);\r
+\r
+       /*\r
+        * register message buffers, establish connection, and\r
+        * exchange DMA RMR information info via messages\r
+        */\r
+       ret = connect_ep(hostname, SERVER_CONN_QUAL);\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error connect_ep: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               goto cleanup;\r
+       } else\r
+               LOGPRINTF("%d connect_ep complete\n", getpid());\r
+\r
+       /* Query EP for local and remote address information, print */\r
+       ret = dat_ep_query(h_ep, DAT_EP_FIELD_ALL, &ep_param);\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error dat_ep_query: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               goto cleanup;\r
+       } else\r
+               LOGPRINTF("%d EP queried %p \n", getpid(), h_ep);\r
+#if defined(_WIN32)\r
+       printf("\n%d Query EP: LOCAL addr %s port %lld\n", getpid(),\r
+              inet_ntoa(((struct sockaddr_in *)\r
+                         ep_param.local_ia_address_ptr)->sin_addr),\r
+              (ep_param.local_port_qual));\r
+#else\r
+       inet_ntop(AF_INET,\r
+                 &((struct sockaddr_in *)ep_param.local_ia_address_ptr)->\r
+                 sin_addr, addr_str, sizeof(addr_str));\r
+       printf("\n%d Query EP: LOCAL addr %s port " F64x "\n", getpid(),\r
+              addr_str, (ep_param.local_port_qual));\r
+#endif\r
+#if defined(_WIN32)\r
+       printf("%d Query EP: REMOTE addr %s port %lld\n", getpid(),\r
+              inet_ntoa(((struct sockaddr_in *)\r
+                         ep_param.local_ia_address_ptr)->sin_addr),\r
+              (ep_param.remote_port_qual));\r
+#else\r
+       inet_ntop(AF_INET,\r
+                 &((struct sockaddr_in *)ep_param.remote_ia_address_ptr)->\r
+                 sin_addr, addr_str, sizeof(addr_str));\r
+       printf("%d Query EP: REMOTE addr %s port " F64x "\n", getpid(),\r
+              addr_str, (ep_param.remote_port_qual));\r
+#endif\r
+       fflush(stdout);\r
+\r
+#if CONNECT_ONLY\r
+#if defined(_WIN32) || defined(_WIN64)\r
+       Sleep(1 * 1000);\r
+#else\r
+       sleep(1);\r
+#endif\r
+       goto cleanup;\r
+#endif\r
+\r
+       /*********** RDMA write data *************/\r
+       ret = do_rdma_write_with_msg();\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error do_rdma_write_with_msg: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               goto cleanup;\r
+       } else\r
+               LOGPRINTF("%d do_rdma_write_with_msg complete\n", getpid());\r
+\r
+       /*********** RDMA read data *************/\r
+       ret = do_rdma_read_with_msg();\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error do_rdma_read_with_msg: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               goto cleanup;\r
+       } else\r
+               LOGPRINTF("%d do_rdma_read_with_msg complete\n", getpid());\r
+\r
+       /*********** PING PING messages ************/\r
+       ret = do_ping_pong_msg();\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error do_ping_pong_msg: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               goto cleanup;\r
+       } else {\r
+               LOGPRINTF("%d do_ping_pong_msg complete\n", getpid());\r
+               goto complete;\r
+       }\r
+\r
+cleanup:\r
+       flush_evds();\r
+       failed++;\r
+complete:\r
+\r
+       /* disconnect and free EP resources */\r
+       if (h_ep != DAT_HANDLE_NULL) {\r
+               /* unregister message buffers and tear down connection */\r
+               LOGPRINTF("%d Disconnect and Free EP %p \n", getpid(), h_ep);\r
+               disconnect_ep();\r
+\r
+               /* free EP */\r
+               LOGPRINTF("%d Free EP %p \n", getpid(), h_ep);\r
+               start = get_time();\r
+               ret = dat_ep_free(h_ep);\r
+               stop = get_time();\r
+               time.epf += ((stop - start) * 1.0e6);\r
+               time.total += time.epf;\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr, "%d Error freeing EP: %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+               } else {\r
+                       LOGPRINTF("%d Freed EP\n", getpid());\r
+                       h_ep = DAT_HANDLE_NULL;\r
+               }\r
+       }\r
+\r
+       /* free EVDs */\r
+       LOGPRINTF("%d destroy events\n", getpid());\r
+       ret = destroy_events();\r
+       if (ret != DAT_SUCCESS)\r
+               fprintf(stderr, "%d Error destroy_events: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+       else\r
+               LOGPRINTF("%d destroy events done\n", getpid());\r
+\r
+       ret = unregister_rdma_memory();\r
+       LOGPRINTF("%d unregister_rdma_memory \n", getpid());\r
+       if (ret != DAT_SUCCESS)\r
+               fprintf(stderr, "%d Error unregister_rdma_memory: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+       else\r
+               LOGPRINTF("%d unregister_rdma_memory done\n", getpid());\r
+\r
+       /* Free protection domain */\r
+       LOGPRINTF("%d Freeing pz\n", getpid());\r
+       start = get_time();\r
+       ret = dat_pz_free(h_pz);\r
+       stop = get_time();\r
+       time.pzf += ((stop - start) * 1.0e6);\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error freeing PZ: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+       } else {\r
+               LOGPRINTF("%d Freed pz\n", getpid());\r
+               h_pz = NULL;\r
+       }\r
+\r
+       /* close the device */\r
+       LOGPRINTF("%d Closing Interface Adaptor\n", getpid());\r
+       start = get_time();\r
+       ret = dat_ia_close(h_ia, DAT_CLOSE_ABRUPT_FLAG);\r
+       stop = get_time();\r
+       time.close += ((stop - start) * 1.0e6);\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d: Error Adaptor close: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+       } else\r
+               LOGPRINTF("%d Closed Interface Adaptor\n", getpid());\r
+\r
+       /* free rdma buffers */\r
+       free(rbuf);\r
+       free(sbuf);\r
+\r
+       printf("\n%d: DAPL Test Complete. %s\n\n",\r
+              getpid(), failed ? "FAILED" : "PASSED");\r
+\r
+       fflush(stderr);\r
+       fflush(stdout);\r
+\r
+       if (!performance_times)\r
+               exit(0);\r
+\r
+       printf("\n%d: DAPL Test Complete.\n\n", getpid());\r
+       printf("%d: Message RTT: Total=%10.2lf usec, %d bursts, itime=%10.2lf"\r
+              " usec, pc=%d\n",\r
+              getpid(), time.rtt, burst, time.rtt / burst, poll_count);\r
+       printf("%d: RDMA write:  Total=%10.2lf usec, %d bursts, itime=%10.2lf"\r
+              " usec, pc=%d\n",\r
+              getpid(), time.rdma_wr, burst,\r
+              time.rdma_wr / burst, rdma_wr_poll_count);\r
+       for (i = 0; i < MAX_RDMA_RD; i++) {\r
+               printf("%d: RDMA read:   Total=%10.2lf usec,   %d bursts, "\r
+                      "itime=%10.2lf usec, pc=%d\n",\r
+                      getpid(), time.rdma_rd_total, MAX_RDMA_RD,\r
+                      time.rdma_rd[i], rdma_rd_poll_count[i]);\r
+       }\r
+       printf("%d: open:      %10.2lf usec\n", getpid(), time.open);\r
+       printf("%d: close:     %10.2lf usec\n", getpid(), time.close);\r
+       printf("%d: PZ create: %10.2lf usec\n", getpid(), time.pzc);\r
+       printf("%d: PZ free:   %10.2lf usec\n", getpid(), time.pzf);\r
+       printf("%d: LMR create:%10.2lf usec\n", getpid(), time.reg);\r
+       printf("%d: LMR free:  %10.2lf usec\n", getpid(), time.unreg);\r
+       printf("%d: EVD create:%10.2lf usec\n", getpid(), time.evdc);\r
+       printf("%d: EVD free:  %10.2lf usec\n", getpid(), time.evdf);\r
+       if (use_cno) {\r
+               printf("%d: CNO create:  %10.2lf usec\n", getpid(), time.cnoc);\r
+               printf("%d: CNO free:    %10.2lf usec\n", getpid(), time.cnof);\r
+       }\r
+       printf("%d: EP create: %10.2lf usec\n", getpid(), time.epc);\r
+       printf("%d: EP free:   %10.2lf usec\n", getpid(), time.epf);\r
+       if (!server)\r
+               printf("%d: connect:   %10.2lf usec, poll_cnt=%d\n", \r
+                      getpid(), time.conn, conn_poll_count);\r
+       printf("%d: TOTAL:     %10.2lf usec\n", getpid(), time.total);\r
+\r
+#if defined(_WIN32) || defined(_WIN64)\r
+       WSACleanup();\r
+#endif\r
+       return (0);\r
+}\r
+\r
+double get_time(void)\r
+{\r
+       struct timeval tp;\r
+\r
+       gettimeofday(&tp, NULL);\r
+       return ((double)tp.tv_sec + (double)tp.tv_usec * 1e-6);\r
+}\r
+\r
+void init_data(void)\r
+{\r
+       memset(rbuf, 'a', buf_len);\r
+       memset(sbuf, 'b', buf_len);\r
+}\r
+\r
+DAT_RETURN\r
+send_msg(void *data,\r
+        DAT_COUNT size,\r
+        DAT_LMR_CONTEXT context,\r
+        DAT_DTO_COOKIE cookie, DAT_COMPLETION_FLAGS flags)\r
+{\r
+       DAT_LMR_TRIPLET iov;\r
+       DAT_EVENT event;\r
+       DAT_COUNT nmore;\r
+       DAT_RETURN ret;\r
+\r
+       iov.lmr_context = context;\r
+#if defined(_WIN32)\r
+       iov.virtual_address = (DAT_VADDR) data;\r
+#else\r
+       iov.virtual_address = (DAT_VADDR) (unsigned long)data;\r
+#endif\r
+       iov.segment_length = size;\r
+\r
+       LOGPRINTF("%d calling post_send\n", getpid());\r
+       cookie.as_64 = 0xaaaa;\r
+       ret = dat_ep_post_send(h_ep, 1, &iov, cookie, flags);\r
+\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d: ERROR: dat_ep_post_send() %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               return ret;\r
+       }\r
+\r
+       if (!(flags & DAT_COMPLETION_SUPPRESS_FLAG)) {\r
+               if (polling) {\r
+                       printf("%d Polling post send completion...\n",\r
+                              getpid());\r
+                       while (dat_evd_dequeue(h_dto_req_evd, &event) ==\r
+                              DAT_QUEUE_EMPTY) ;\r
+               } else {\r
+                       LOGPRINTF("%d waiting for post_send completion event\n",\r
+                                 getpid());\r
+                       if (use_cno) {\r
+                               DAT_EVD_HANDLE evd = DAT_HANDLE_NULL;\r
+                               ret =\r
+                                   dat_cno_wait(h_dto_cno, DTO_TIMEOUT, &evd);\r
+                               LOGPRINTF("%d cno wait return evd_handle=%p\n",\r
+                                         getpid(), evd);\r
+                               if (evd != h_dto_req_evd) {\r
+                                       /* CNO timeout, already on EVD */\r
+                                       if (evd != NULL)\r
+                                               return (ret);\r
+                               }\r
+                       }\r
+                       /* use wait to dequeue */\r
+                       ret =\r
+                           dat_evd_wait(h_dto_req_evd, DTO_TIMEOUT, 1, &event,\r
+                                        &nmore);\r
+                       if (ret != DAT_SUCCESS) {\r
+                               fprintf(stderr,\r
+                                       "%d: ERROR: DTO dat_evd_wait() %s\n",\r
+                                       getpid(), DT_RetToString(ret));\r
+                               return ret;\r
+                       }\r
+               }\r
+\r
+               /* validate event number, len, cookie, and status */\r
+               if (event.event_number != DAT_DTO_COMPLETION_EVENT) {\r
+                       fprintf(stderr, "%d: ERROR: DTO event number %s\n",\r
+                               getpid(), DT_EventToSTr(event.event_number));\r
+                       return (DAT_ABORT);\r
+               }\r
+\r
+               if ((event.event_data.dto_completion_event_data.\r
+                    transfered_length != size)\r
+                   || (event.event_data.dto_completion_event_data.user_cookie.\r
+                       as_64 != 0xaaaa)) {\r
+                       fprintf(stderr,\r
+                               "%d: ERROR: DTO len %d or cookie " F64x " \n",\r
+                               getpid(),\r
+                               event.event_data.dto_completion_event_data.\r
+                               transfered_length,\r
+                               event.event_data.dto_completion_event_data.\r
+                               user_cookie.as_64);\r
+                       return (DAT_ABORT);\r
+\r
+               }\r
+               if (event.event_data.dto_completion_event_data.status !=\r
+                   DAT_SUCCESS) {\r
+                       fprintf(stderr, "%d: ERROR: DTO event status %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (DAT_ABORT);\r
+               }\r
+       }\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+DAT_RETURN connect_ep(char *hostname, DAT_CONN_QUAL conn_id)\r
+{\r
+       DAT_SOCK_ADDR remote_addr;\r
+       DAT_RETURN ret;\r
+       DAT_REGION_DESCRIPTION region;\r
+       DAT_EVENT event;\r
+       DAT_COUNT nmore;\r
+       DAT_LMR_TRIPLET l_iov;\r
+       DAT_RMR_TRIPLET r_iov;\r
+       DAT_DTO_COOKIE cookie;\r
+       int i;\r
+       unsigned char *buf;\r
+       DAT_CR_PARAM cr_param = { 0 };\r
+       unsigned char pdata[48] = { 0 };\r
+\r
+       /* Register send message buffer */\r
+       LOGPRINTF("%d Registering send Message Buffer %p, len %d\n",\r
+                 getpid(), &rmr_send_msg, (int)sizeof(DAT_RMR_TRIPLET));\r
+       region.for_va = &rmr_send_msg;\r
+       ret = dat_lmr_create(h_ia,\r
+                            DAT_MEM_TYPE_VIRTUAL,\r
+                            region,\r
+                            sizeof(DAT_RMR_TRIPLET),\r
+                            h_pz,\r
+                            DAT_MEM_PRIV_LOCAL_WRITE_FLAG,\r
+                            DAT_VA_TYPE_VA,\r
+                            &h_lmr_send_msg,\r
+                            &lmr_context_send_msg,\r
+                            &rmr_context_send_msg,\r
+                            &registered_size_send_msg,\r
+                            &registered_addr_send_msg);\r
+\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error registering send msg buffer: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               return (ret);\r
+       } else\r
+               LOGPRINTF("%d Registered send Message Buffer %p \n",\r
+                         getpid(), region.for_va);\r
+\r
+       /* Register Receive buffers */\r
+       LOGPRINTF("%d Registering Receive Message Buffer %p\n",\r
+                 getpid(), rmr_recv_msg);\r
+       region.for_va = rmr_recv_msg;\r
+       ret = dat_lmr_create(h_ia,\r
+                            DAT_MEM_TYPE_VIRTUAL,\r
+                            region,\r
+                            sizeof(DAT_RMR_TRIPLET) * MSG_BUF_COUNT,\r
+                            h_pz,\r
+                            DAT_MEM_PRIV_LOCAL_WRITE_FLAG,\r
+                            DAT_VA_TYPE_VA,\r
+                            &h_lmr_recv_msg,\r
+                            &lmr_context_recv_msg,\r
+                            &rmr_context_recv_msg,\r
+                            &registered_size_recv_msg,\r
+                            &registered_addr_recv_msg);\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error registering recv msg buffer: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               return (ret);\r
+       } else\r
+               LOGPRINTF("%d Registered Receive Message Buffer %p\n",\r
+                         getpid(), region.for_va);\r
+\r
+       for (i = 0; i < MSG_BUF_COUNT; i++) {\r
+               cookie.as_64 = i;\r
+               l_iov.lmr_context = lmr_context_recv_msg;\r
+#if defined(_WIN32)\r
+               l_iov.virtual_address = (DAT_VADDR) & rmr_recv_msg[i];\r
+#else\r
+               l_iov.virtual_address =\r
+                   (DAT_VADDR) (unsigned long)&rmr_recv_msg[i];\r
+#endif\r
+               l_iov.segment_length = sizeof(DAT_RMR_TRIPLET);\r
+\r
+               LOGPRINTF("%d Posting Receive Message Buffer %p\n",\r
+                         getpid(), &rmr_recv_msg[i]);\r
+               ret = dat_ep_post_recv(h_ep,\r
+                                      1,\r
+                                      &l_iov,\r
+                                      cookie, DAT_COMPLETION_DEFAULT_FLAG);\r
+\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr,\r
+                               "%d Error registering recv msg buffer: %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (ret);\r
+               } else\r
+                       LOGPRINTF("%d Registered Receive Message Buffer %p\n",\r
+                                 getpid(), region.for_va);\r
+\r
+       }\r
+\r
+       /* setup receive rdma buffer to initial string to be overwritten */\r
+       strcpy((char *)rbuf, "blah, blah, blah\n");\r
+\r
+       /* clear event structure */\r
+       memset(&event, 0, sizeof(DAT_EVENT));\r
+\r
+       if (server) {           /* SERVER */\r
+\r
+               /* create the service point for server listen */\r
+               LOGPRINTF("%d Creating service point for listen\n", getpid());\r
+               ret = dat_psp_create(h_ia,\r
+                                    conn_id,\r
+                                    h_cr_evd, DAT_PSP_CONSUMER_FLAG, &h_psp);\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr, "%d Error dat_psp_create: %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (ret);\r
+               } else\r
+                       LOGPRINTF("%d dat_psp_created for server listen\n",\r
+                                 getpid());\r
+\r
+               printf("%d Server waiting for connect request on port " F64x\r
+                      "\n", getpid(), conn_id);\r
+\r
+               ret = dat_evd_wait(h_cr_evd, SERVER_TIMEOUT, 1, &event, &nmore);\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr, "%d Error dat_evd_wait: %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (ret);\r
+               } else\r
+                       LOGPRINTF("%d dat_evd_wait for cr_evd completed\n",\r
+                                 getpid());\r
+\r
+               if (event.event_number != DAT_CONNECTION_REQUEST_EVENT) {\r
+                       fprintf(stderr, "%d Error unexpected cr event : %s\n",\r
+                               getpid(), DT_EventToSTr(event.event_number));\r
+                       return (DAT_ABORT);\r
+               }\r
+               if ((event.event_data.cr_arrival_event_data.conn_qual !=\r
+                    SERVER_CONN_QUAL)\r
+                   || (event.event_data.cr_arrival_event_data.sp_handle.\r
+                       psp_handle != h_psp)) {\r
+                       fprintf(stderr, "%d Error wrong cr event data : %s\n",\r
+                               getpid(), DT_EventToSTr(event.event_number));\r
+                       return (DAT_ABORT);\r
+               }\r
+\r
+               /* use to test rdma_cma timeout logic */\r
+#if defined(_WIN32) || defined(_WIN64)\r
+               if (delay)\r
+                       Sleep(delay * 1000);\r
+#else\r
+               if (delay)\r
+                       sleep(delay);\r
+#endif\r
+\r
+               /* accept connect request from client */\r
+               h_cr = event.event_data.cr_arrival_event_data.cr_handle;\r
+               LOGPRINTF("%d Accepting connect request from client\n",\r
+                         getpid());\r
+\r
+               /* private data - check and send it back */\r
+               dat_cr_query(h_cr, DAT_CSP_FIELD_ALL, &cr_param);\r
+\r
+               buf = (unsigned char *)cr_param.private_data;\r
+               LOGPRINTF("%d CONN REQUEST Private Data %p[0]=%d [47]=%d\n",\r
+                         getpid(), buf, buf[0], buf[47]);\r
+               for (i = 0; i < 48; i++) {\r
+                       if (buf[i] != i + 1) {\r
+                               fprintf(stderr, "%d Error with CONNECT REQUEST"\r
+                                       " private data: %p[%d]=%d s/be %d\n",\r
+                                       getpid(), buf, i, buf[i], i + 1);\r
+                               dat_cr_reject(h_cr, 0, NULL);\r
+                               return (DAT_ABORT);\r
+                       }\r
+                       buf[i]++;       /* change for trip back */\r
+               }\r
+\r
+#ifdef TEST_REJECT_WITH_PRIVATE_DATA\r
+               printf("%d REJECT request with 48 bytes of private data\n",\r
+                      getpid());\r
+               ret = dat_cr_reject(h_cr, 48, cr_param.private_data);\r
+               printf("\n%d: DAPL Test Complete. %s\n\n",\r
+                      getpid(), ret ? "FAILED" : "PASSED");\r
+               exit(0);\r
+#endif\r
+\r
+               ret = dat_cr_accept(h_cr, h_ep, 48, cr_param.private_data);\r
+\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr, "%d Error dat_cr_accept: %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (ret);\r
+               } else\r
+                       LOGPRINTF("%d dat_cr_accept completed\n", getpid());\r
+       } else {                /* CLIENT */\r
+               struct addrinfo *target;\r
+               int rval;\r
+\r
+#if defined(_WIN32) || defined(_WIN64)\r
+               if ((rval = getaddrinfo(hostname, "ftp", NULL, &target)) != 0) {\r
+                       printf("\n remote name resolution failed! %s\n",\r
+                              gai_strerror(rval));\r
+                       exit(1);\r
+               }\r
+               rval = ((struct sockaddr_in *)target->ai_addr)->sin_addr.s_addr;\r
+#else\r
+               if (getaddrinfo(hostname, NULL, NULL, &target) != 0) {\r
+                       perror("\n remote name resolution failed!");\r
+                       exit(1);\r
+               }\r
+               rval = ((struct sockaddr_in *)target->ai_addr)->sin_addr.s_addr;\r
+#endif\r
+               printf("%d Server Name: %s \n", getpid(), hostname);\r
+               printf("%d Server Net Address: %d.%d.%d.%d port " F64x "\n",\r
+                      getpid(), (rval >> 0) & 0xff, (rval >> 8) & 0xff,\r
+                      (rval >> 16) & 0xff, (rval >> 24) & 0xff, conn_id);\r
+\r
+               remote_addr = *((DAT_IA_ADDRESS_PTR) target->ai_addr);\r
+               freeaddrinfo(target);\r
+\r
+               for (i = 0; i < 48; i++)        /* simple pattern in private data */\r
+                       pdata[i] = i + 1;\r
+\r
+               LOGPRINTF("%d Connecting to server\n", getpid());\r
+               start = get_time();\r
+               ret = dat_ep_connect(h_ep,\r
+                                    &remote_addr,\r
+                                    conn_id,\r
+                                    CONN_TIMEOUT,\r
+                                    48,\r
+                                    (DAT_PVOID) pdata,\r
+                                    0, DAT_CONNECT_DEFAULT_FLAG);\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr, "%d Error dat_ep_connect: %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (ret);\r
+               } else\r
+                       LOGPRINTF("%d dat_ep_connect completed\n", getpid());\r
+       }\r
+\r
+       printf("%d Waiting for connect response\n", getpid());\r
+\r
+       if (polling) \r
+               while (DAT_GET_TYPE(dat_evd_dequeue(h_conn_evd, &event)) == \r
+                      DAT_QUEUE_EMPTY)\r
+                       conn_poll_count++;\r
+       else \r
+               ret = dat_evd_wait(h_conn_evd, DAT_TIMEOUT_INFINITE, \r
+                                  1, &event, &nmore);\r
+\r
+       if (!server) {\r
+               stop = get_time();\r
+               time.conn += ((stop - start) * 1.0e6);\r
+       }\r
+\r
+#ifdef TEST_REJECT_WITH_PRIVATE_DATA\r
+       if (event.event_number != DAT_CONNECTION_EVENT_PEER_REJECTED) {\r
+               fprintf(stderr, "%d expected conn reject event : %s\n",\r
+                       getpid(), DT_EventToSTr(event.event_number));\r
+               return (DAT_ABORT);\r
+       }\r
+       /* get the reject private data and validate */\r
+       buf = (unsigned char *)event.event_data.connect_event_data.private_data;\r
+       printf("%d Received REJECT with private data %p[0]=%d [47]=%d\n",\r
+              getpid(), buf, buf[0], buf[47]);\r
+       for (i = 0; i < 48; i++) {\r
+               if (buf[i] != i + 2) {\r
+                       fprintf(stderr, "%d client: Error with REJECT event"\r
+                               " private data: %p[%d]=%d s/be %d\n",\r
+                               getpid(), buf, i, buf[i], i + 2);\r
+                       dat_ep_disconnect(h_ep, DAT_CLOSE_ABRUPT_FLAG);\r
+                       return (DAT_ABORT);\r
+               }\r
+       }\r
+       printf("\n%d: DAPL Test Complete. PASSED\n\n", getpid());\r
+       exit(0);\r
+#endif\r
+\r
+       if (event.event_number != DAT_CONNECTION_EVENT_ESTABLISHED) {\r
+               fprintf(stderr, "%d Error unexpected conn event : 0x%x %s\n",\r
+                       getpid(), event.event_number,\r
+                       DT_EventToSTr(event.event_number));\r
+               return (DAT_ABORT);\r
+       }\r
+\r
+       /* check private data back from server  */\r
+       if (!server) {\r
+               buf =\r
+                   (unsigned char *)event.event_data.connect_event_data.\r
+                   private_data;\r
+               LOGPRINTF("%d CONN Private Data %p[0]=%d [47]=%d\n", getpid(),\r
+                         buf, buf[0], buf[47]);\r
+               for (i = 0; i < 48; i++) {\r
+                       if (buf[i] != i + 2) {\r
+                               fprintf(stderr, "%d Error with CONNECT event"\r
+                                       " private data: %p[%d]=%d s/be %d\n",\r
+                                       getpid(), buf, i, buf[i], i + 2);\r
+                               dat_ep_disconnect(h_ep, DAT_CLOSE_ABRUPT_FLAG);\r
+                               LOGPRINTF\r
+                                   ("%d waiting for disconnect event...\n",\r
+                                    getpid());\r
+                               dat_evd_wait(h_conn_evd, DAT_TIMEOUT_INFINITE,\r
+                                            1, &event, &nmore);\r
+                               return (DAT_ABORT);\r
+                       }\r
+               }\r
+       }\r
+\r
+       printf("\n%d CONNECTED!\n\n", getpid());\r
+       connected = 1;\r
+\r
+#if CONNECT_ONLY\r
+       return 0;\r
+#endif\r
+\r
+       /*\r
+        *  Setup our remote memory and tell the other side about it\r
+        */\r
+       rmr_send_msg.virtual_address = htonll((DAT_VADDR) (uintptr_t) rbuf);\r
+       rmr_send_msg.segment_length = htonl(RDMA_BUFFER_SIZE);\r
+       rmr_send_msg.rmr_context = htonl(rmr_context_recv);\r
+\r
+       printf("%d Send RMR msg to remote: r_key_ctx=0x%x,va=%p,len=0x%x\n",\r
+              getpid(), rmr_context_recv, rbuf, RDMA_BUFFER_SIZE);\r
+\r
+       ret = send_msg(&rmr_send_msg,\r
+                      sizeof(DAT_RMR_TRIPLET),\r
+                      lmr_context_send_msg,\r
+                      cookie, DAT_COMPLETION_SUPPRESS_FLAG);\r
+\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error send_msg: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               return (ret);\r
+       } else\r
+               LOGPRINTF("%d send_msg completed\n", getpid());\r
+\r
+       /*\r
+        *  Wait for remote RMR information for RDMA\r
+        */\r
+       if (polling) {\r
+               printf("%d Polling for remote to send RMR data\n", getpid());\r
+               while (dat_evd_dequeue(h_dto_rcv_evd, &event) ==\r
+                      DAT_QUEUE_EMPTY) ;\r
+       } else {\r
+               printf("%d Waiting for remote to send RMR data\n", getpid());\r
+               if (use_cno) {\r
+                       DAT_EVD_HANDLE evd = DAT_HANDLE_NULL;\r
+                       ret = dat_cno_wait(h_dto_cno, DTO_TIMEOUT, &evd);\r
+                       LOGPRINTF("%d cno wait return evd_handle=%p\n",\r
+                                 getpid(), evd);\r
+                       if (evd != h_dto_rcv_evd) {\r
+                               /* CNO timeout, already on EVD */\r
+                               if (evd != NULL)\r
+                                       return (ret);\r
+                       }\r
+               }\r
+               /* use wait to dequeue */\r
+               ret =\r
+                   dat_evd_wait(h_dto_rcv_evd, DTO_TIMEOUT, 1, &event, &nmore);\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr,\r
+                               "%d Error waiting on h_dto_rcv_evd: %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (ret);\r
+               } else {\r
+                       LOGPRINTF("%d dat_evd_wait h_dto_rcv_evd completed\n",\r
+                                 getpid());\r
+               }\r
+       }\r
+\r
+       printf("%d remote RMR data arrived!\n", getpid());\r
+\r
+       if (event.event_number != DAT_DTO_COMPLETION_EVENT) {\r
+               fprintf(stderr, "%d Error unexpected DTO event : %s\n",\r
+                       getpid(), DT_EventToSTr(event.event_number));\r
+               return (DAT_ABORT);\r
+       }\r
+       if ((event.event_data.dto_completion_event_data.transfered_length !=\r
+            sizeof(DAT_RMR_TRIPLET)) ||\r
+           (event.event_data.dto_completion_event_data.user_cookie.as_64 !=\r
+            recv_msg_index)) {\r
+               fprintf(stderr,\r
+                       "ERR recv event: len=%d cookie=" F64x\r
+                       " expected %d/%d\n",\r
+                       (int)event.event_data.dto_completion_event_data.\r
+                       transfered_length,\r
+                       event.event_data.dto_completion_event_data.user_cookie.\r
+                       as_64, (int)sizeof(DAT_RMR_TRIPLET), recv_msg_index);\r
+               return (DAT_ABORT);\r
+       }\r
+\r
+       /* swap received RMR msg: network order to host order */\r
+       r_iov = rmr_recv_msg[recv_msg_index];\r
+       rmr_recv_msg[recv_msg_index].rmr_context = ntohl(r_iov.rmr_context);\r
+       rmr_recv_msg[recv_msg_index].virtual_address =\r
+           ntohll(r_iov.virtual_address);\r
+       rmr_recv_msg[recv_msg_index].segment_length =\r
+           ntohl(r_iov.segment_length);\r
+\r
+       printf("%d Received RMR from remote: "\r
+              "r_iov: r_key_ctx=%x,va=" F64x ",len=0x%x\n",\r
+              getpid(), rmr_recv_msg[recv_msg_index].rmr_context,\r
+              rmr_recv_msg[recv_msg_index].virtual_address,\r
+              rmr_recv_msg[recv_msg_index].segment_length);\r
+\r
+       recv_msg_index++;\r
+\r
+       return (DAT_SUCCESS);\r
+}\r
+\r
+void disconnect_ep(void)\r
+{\r
+       DAT_RETURN ret;\r
+       DAT_EVENT event;\r
+       DAT_COUNT nmore;\r
+\r
+       if (connected) {\r
+\r
+               /* \r
+                * Only the client needs to call disconnect. The server _should_ be able\r
+                * to just wait on the EVD associated with connection events for a\r
+                * disconnect request and then exit.\r
+                */\r
+               if (!server) {\r
+                       LOGPRINTF("%d dat_ep_disconnect\n", getpid());\r
+                       ret = dat_ep_disconnect(h_ep, DAT_CLOSE_DEFAULT);\r
+                       if (ret != DAT_SUCCESS) {\r
+                               fprintf(stderr,\r
+                                       "%d Error dat_ep_disconnect: %s\n",\r
+                                       getpid(), DT_RetToString(ret));\r
+                       } else {\r
+                               LOGPRINTF("%d dat_ep_disconnect completed\n",\r
+                                         getpid());\r
+                       }\r
+               } else {\r
+                       LOGPRINTF("%d Server waiting for disconnect...\n",\r
+                                 getpid());\r
+               }\r
+\r
+               ret =\r
+                   dat_evd_wait(h_conn_evd, DAT_TIMEOUT_INFINITE, 1, &event,\r
+                                &nmore);\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr, "%d Error dat_evd_wait: %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+               } else {\r
+                       LOGPRINTF("%d dat_evd_wait for h_conn_evd completed\n",\r
+                                 getpid());\r
+               }\r
+       }\r
+\r
+       /* destroy service point */\r
+       if ((server) && (h_psp != DAT_HANDLE_NULL)) {\r
+               ret = dat_psp_free(h_psp);\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr, "%d Error dat_psp_free: %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+               } else {\r
+                       LOGPRINTF("%d dat_psp_free completed\n", getpid());\r
+               }\r
+       }\r
+\r
+       /* Unregister Send message Buffer */\r
+       if (h_lmr_send_msg != DAT_HANDLE_NULL) {\r
+               LOGPRINTF("%d Unregister send message h_lmr %p \n", getpid(),\r
+                         h_lmr_send_msg);\r
+               ret = dat_lmr_free(h_lmr_send_msg);\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr,\r
+                               "%d Error deregistering send msg mr: %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+               } else {\r
+                       LOGPRINTF("%d Unregistered send message Buffer\n",\r
+                                 getpid());\r
+                       h_lmr_send_msg = NULL;\r
+               }\r
+       }\r
+\r
+       /* Unregister recv message Buffer */\r
+       if (h_lmr_recv_msg != DAT_HANDLE_NULL) {\r
+               LOGPRINTF("%d Unregister recv message h_lmr %p \n", getpid(),\r
+                         h_lmr_recv_msg);\r
+               ret = dat_lmr_free(h_lmr_recv_msg);\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr,\r
+                               "%d Error deregistering recv msg mr: %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+               } else {\r
+                       LOGPRINTF("%d Unregistered recv message Buffer\n",\r
+                                 getpid());\r
+                       h_lmr_recv_msg = NULL;\r
+               }\r
+       }\r
+       return;\r
+}\r
+\r
+DAT_RETURN do_rdma_write_with_msg(void)\r
+{\r
+       DAT_EVENT event;\r
+       DAT_COUNT nmore;\r
+       DAT_LMR_TRIPLET l_iov[MSG_IOV_COUNT];\r
+       DAT_RMR_TRIPLET r_iov;\r
+       DAT_DTO_COOKIE cookie;\r
+       DAT_RETURN ret;\r
+       int i;\r
+\r
+       printf("\n %d RDMA WRITE DATA with SEND MSG\n\n", getpid());\r
+\r
+       cookie.as_64 = 0x5555;\r
+\r
+       if (recv_msg_index >= MSG_BUF_COUNT)\r
+               return (DAT_ABORT);\r
+\r
+       /* get RMR information from previously received message */\r
+       r_iov = rmr_recv_msg[recv_msg_index - 1];\r
+\r
+       if (server)\r
+               strcpy((char *)sbuf, "server RDMA write data...");\r
+       else\r
+               strcpy((char *)sbuf, "client RDMA write data...");\r
+\r
+       for (i = 0; i < MSG_IOV_COUNT; i++) {\r
+               l_iov[i].lmr_context = lmr_context_send;\r
+               l_iov[i].segment_length = buf_len / MSG_IOV_COUNT;\r
+               l_iov[i].virtual_address = (DAT_VADDR) (uintptr_t)\r
+                   (&sbuf[l_iov[i].segment_length * i]);\r
+\r
+               LOGPRINTF("%d rdma_write iov[%d] buf=%p,len=%d\n",\r
+                         getpid(), i, &sbuf[l_iov[i].segment_length * i],\r
+                         l_iov[i].segment_length);\r
+       }\r
+\r
+       start = get_time();\r
+       for (i = 0; i < burst; i++) {\r
+               cookie.as_64 = 0x9999;\r
+               ret = dat_ep_post_rdma_write(h_ep,      // ep_handle\r
+                                            MSG_IOV_COUNT,     // num_segments\r
+                                            l_iov,     // LMR\r
+                                            cookie,    // user_cookie\r
+                                            &r_iov,    // RMR\r
+                                            DAT_COMPLETION_SUPPRESS_FLAG);\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr,\r
+                               "%d: ERROR: dat_ep_post_rdma_write() %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (DAT_ABORT);\r
+               }\r
+               LOGPRINTF("%d rdma_write # %d completed\n", getpid(), i + 1);\r
+       }\r
+\r
+       /*\r
+        *  Send RMR information a 2nd time to indicate completion\r
+        *  NOTE: already swapped to network order in connect_ep\r
+        */\r
+       printf("%d Sending RDMA WRITE completion message\n", getpid());\r
+\r
+       ret = send_msg(&rmr_send_msg,\r
+                      sizeof(DAT_RMR_TRIPLET),\r
+                      lmr_context_send_msg,\r
+                      cookie, DAT_COMPLETION_SUPPRESS_FLAG);\r
+\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error send_msg: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               return (ret);\r
+       } else {\r
+               LOGPRINTF("%d send_msg completed\n", getpid());\r
+       }\r
+\r
+       /*\r
+        *  Collect first event, write completion or the inbound recv \r
+        */\r
+       if (polling) {\r
+               while (dat_evd_dequeue(h_dto_rcv_evd, &event) ==\r
+                      DAT_QUEUE_EMPTY)\r
+                       rdma_wr_poll_count++;\r
+       } else {\r
+               LOGPRINTF("%d waiting for message receive event\n", getpid());\r
+               if (use_cno) {\r
+                       DAT_EVD_HANDLE evd = DAT_HANDLE_NULL;\r
+                       ret = dat_cno_wait(h_dto_cno, DTO_TIMEOUT, &evd);\r
+                       LOGPRINTF("%d cno wait return evd_handle=%p\n",\r
+                                 getpid(), evd);\r
+                       if (evd != h_dto_rcv_evd) {\r
+                               /* CNO timeout, already on EVD */\r
+                               if (evd != NULL)\r
+                                       return (ret);\r
+                       }\r
+               }\r
+               /* use wait to dequeue */\r
+               ret =\r
+                   dat_evd_wait(h_dto_rcv_evd, DTO_TIMEOUT, 1, &event, &nmore);\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr, "%d: ERROR: DTO dat_evd_wait() %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (ret);\r
+               }\r
+       }\r
+       stop = get_time();\r
+       time.rdma_wr = ((stop - start) * 1.0e6);\r
+\r
+       /* validate event number and status */\r
+       printf("%d inbound rdma_write; send message arrived!\n", getpid());\r
+       if (event.event_number != DAT_DTO_COMPLETION_EVENT) {\r
+               fprintf(stderr, "%d Error unexpected DTO event : %s\n",\r
+                       getpid(), DT_EventToSTr(event.event_number));\r
+               return (DAT_ABORT);\r
+       }\r
+\r
+       if ((event.event_data.dto_completion_event_data.transfered_length !=\r
+            sizeof(DAT_RMR_TRIPLET))\r
+           || (event.event_data.dto_completion_event_data.user_cookie.as_64 !=\r
+               recv_msg_index)) {\r
+               fprintf(stderr,\r
+                       "unexpected event data for receive: len=%d cookie=" F64x\r
+                       " exp %d/%d\n",\r
+                       (int)event.event_data.dto_completion_event_data.\r
+                       transfered_length,\r
+                       event.event_data.dto_completion_event_data.user_cookie.\r
+                       as_64, (int)sizeof(DAT_RMR_TRIPLET), recv_msg_index);\r
+\r
+               return (DAT_ABORT);\r
+       }\r
+\r
+       /* swap received RMR msg: network order to host order */\r
+       r_iov = rmr_recv_msg[recv_msg_index];\r
+       rmr_recv_msg[recv_msg_index].virtual_address =\r
+           ntohll(rmr_recv_msg[recv_msg_index].virtual_address);\r
+       rmr_recv_msg[recv_msg_index].segment_length =\r
+           ntohl(rmr_recv_msg[recv_msg_index].segment_length);\r
+       rmr_recv_msg[recv_msg_index].rmr_context =\r
+           ntohl(rmr_recv_msg[recv_msg_index].rmr_context);\r
+\r
+       printf("%d Received RMR from remote: "\r
+              "r_iov: r_key_ctx=%x,va=" F64x ",len=0x%x\n",\r
+              getpid(), rmr_recv_msg[recv_msg_index].rmr_context,\r
+              rmr_recv_msg[recv_msg_index].virtual_address,\r
+              rmr_recv_msg[recv_msg_index].segment_length);\r
+\r
+       LOGPRINTF("%d inbound rdma_write; send msg event SUCCESS!!\n",\r
+                 getpid());\r
+\r
+       printf("%d %s RDMA write buffer contains: %s\n",\r
+              getpid(), server ? "SERVER:" : "CLIENT:", rbuf);\r
+\r
+       recv_msg_index++;\r
+\r
+       return (DAT_SUCCESS);\r
+}\r
+\r
+DAT_RETURN do_rdma_read_with_msg(void)\r
+{\r
+       DAT_EVENT event;\r
+       DAT_COUNT nmore;\r
+       DAT_LMR_TRIPLET l_iov;\r
+       DAT_RMR_TRIPLET r_iov;\r
+       DAT_DTO_COOKIE cookie;\r
+       DAT_RETURN ret;\r
+       int i;\r
+\r
+       printf("\n %d RDMA READ DATA with SEND MSG\n\n", getpid());\r
+\r
+       if (recv_msg_index >= MSG_BUF_COUNT)\r
+               return (DAT_ABORT);\r
+\r
+       /* get RMR information from previously received message */\r
+       r_iov = rmr_recv_msg[recv_msg_index - 1];\r
+\r
+       /* setup rdma read buffer to initial string to be overwritten */\r
+       strcpy((char *)sbuf, "blah, blah, blah\n");\r
+\r
+       if (server)\r
+               strcpy((char *)rbuf, "server RDMA read data...");\r
+       else\r
+               strcpy((char *)rbuf, "client RDMA read data...");\r
+\r
+       l_iov.lmr_context = lmr_context_send;\r
+       l_iov.virtual_address = (DAT_VADDR) (uintptr_t) sbuf;\r
+       l_iov.segment_length = buf_len;\r
+\r
+       for (i = 0; i < MAX_RDMA_RD; i++) {\r
+               cookie.as_64 = 0x9999;\r
+               start = get_time();\r
+               ret = dat_ep_post_rdma_read(h_ep,       // ep_handle\r
+                                           1,  // num_segments\r
+                                           &l_iov,     // LMR\r
+                                           cookie,     // user_cookie\r
+                                           &r_iov,     // RMR\r
+                                           DAT_COMPLETION_DEFAULT_FLAG);\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr,\r
+                               "%d: ERROR: dat_ep_post_rdma_read() %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (DAT_ABORT);\r
+               }\r
+\r
+               if (polling) {\r
+                       while (dat_evd_dequeue(h_dto_req_evd, &event) ==\r
+                              DAT_QUEUE_EMPTY)\r
+                               rdma_rd_poll_count[i]++;\r
+               } else {\r
+                       LOGPRINTF("%d waiting for rdma_read completion event\n",\r
+                                 getpid());\r
+                       if (use_cno) {\r
+                               DAT_EVD_HANDLE evd = DAT_HANDLE_NULL;\r
+                               ret =\r
+                                   dat_cno_wait(h_dto_cno, DTO_TIMEOUT, &evd);\r
+                               LOGPRINTF("%d cno wait return evd_handle=%p\n",\r
+                                         getpid(), evd);\r
+                               if (evd != h_dto_req_evd) {\r
+                                       /* CNO timeout, already on EVD */\r
+                                       if (evd != NULL)\r
+                                               return (ret);\r
+                               }\r
+                       }\r
+                       /* use wait to dequeue */\r
+                       ret =\r
+                           dat_evd_wait(h_dto_req_evd, DTO_TIMEOUT, 1, &event,\r
+                                        &nmore);\r
+                       if (ret != DAT_SUCCESS) {\r
+                               fprintf(stderr,\r
+                                       "%d: ERROR: DTO dat_evd_wait() %s\n",\r
+                                       getpid(), DT_RetToString(ret));\r
+                               return ret;\r
+                       }\r
+               }\r
+               /* validate event number, len, cookie, and status */\r
+               if (event.event_number != DAT_DTO_COMPLETION_EVENT) {\r
+                       fprintf(stderr, "%d: ERROR: DTO event number %s\n",\r
+                               getpid(), DT_EventToSTr(event.event_number));\r
+                       return (DAT_ABORT);\r
+               }\r
+               if ((event.event_data.dto_completion_event_data.\r
+                    transfered_length != buf_len)\r
+                   || (event.event_data.dto_completion_event_data.user_cookie.\r
+                       as_64 != 0x9999)) {\r
+                       fprintf(stderr,\r
+                               "%d: ERROR: DTO len %d or cookie " F64x "\n",\r
+                               getpid(),\r
+                               event.event_data.dto_completion_event_data.\r
+                               transfered_length,\r
+                               event.event_data.dto_completion_event_data.\r
+                               user_cookie.as_64);\r
+                       return (DAT_ABORT);\r
+               }\r
+               if (event.event_data.dto_completion_event_data.status !=\r
+                   DAT_SUCCESS) {\r
+                       fprintf(stderr, "%d: ERROR: DTO event status %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (DAT_ABORT);\r
+               }\r
+               stop = get_time();\r
+               time.rdma_rd[i] = ((stop - start) * 1.0e6);\r
+               time.rdma_rd_total += time.rdma_rd[i];\r
+\r
+               LOGPRINTF("%d rdma_read # %d completed\n", getpid(), i + 1);\r
+       }\r
+\r
+       /*\r
+        *  Send RMR information a 3rd time to indicate completion\r
+        *  NOTE: already swapped to network order in connect_ep\r
+        */\r
+       printf("%d Sending RDMA read completion message\n", getpid());\r
+\r
+       /* give remote chance to process read completes */\r
+       if (use_cno) {\r
+#if defined(_WIN32) || defined(_WIN64)\r
+               Sleep(1000);\r
+#else\r
+               sleep(1);\r
+#endif\r
+       }\r
+\r
+       ret = send_msg(&rmr_send_msg,\r
+                      sizeof(DAT_RMR_TRIPLET),\r
+                      lmr_context_send_msg,\r
+                      cookie, DAT_COMPLETION_SUPPRESS_FLAG);\r
+\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error send_msg: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               return (ret);\r
+       } else {\r
+               LOGPRINTF("%d send_msg completed\n", getpid());\r
+       }\r
+\r
+       /*\r
+        *  Collect first event, write completion or the inbound recv with immed\r
+        */\r
+       printf("%d Waiting for inbound message....\n", getpid());\r
+       if (polling) {\r
+               while (dat_evd_dequeue(h_dto_rcv_evd, &event) ==\r
+                      DAT_QUEUE_EMPTY) ;\r
+       } else {\r
+               LOGPRINTF("%d waiting for message receive event\n", getpid());\r
+               if (use_cno) {\r
+                       DAT_EVD_HANDLE evd = DAT_HANDLE_NULL;\r
+                       \r
+                       ret = dat_cno_wait(h_dto_cno, DTO_TIMEOUT, &evd);\r
+                       LOGPRINTF("%d cno wait return evd_handle=%p\n",\r
+                                 getpid(), evd);\r
+                       if (evd != h_dto_rcv_evd) {\r
+                               /* CNO timeout, already on EVD */\r
+                               if (evd != NULL)\r
+                                       return (ret);\r
+                       }\r
+               }\r
+               /* use wait to dequeue */\r
+               ret =\r
+                   dat_evd_wait(h_dto_rcv_evd, DTO_TIMEOUT, 1, &event, &nmore);\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr, "%d: ERROR: DTO dat_evd_wait() %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (ret);\r
+               }\r
+       }\r
+\r
+       /* validate event number and status */\r
+       printf("%d inbound rdma_read; send message arrived!\n", getpid());\r
+       if (event.event_number != DAT_DTO_COMPLETION_EVENT) {\r
+               fprintf(stderr, "%d Error unexpected DTO event : %s\n",\r
+                       getpid(), DT_EventToSTr(event.event_number));\r
+               return (DAT_ABORT);\r
+       }\r
+\r
+       if ((event.event_data.dto_completion_event_data.transfered_length !=\r
+            sizeof(DAT_RMR_TRIPLET))\r
+           || (event.event_data.dto_completion_event_data.user_cookie.as_64 !=\r
+               recv_msg_index)) {\r
+\r
+               fprintf(stderr,\r
+                       "unexpected event data for receive: len=%d cookie=" F64x\r
+                       " exp %d/%d\n",\r
+                       (int)event.event_data.dto_completion_event_data.\r
+                       transfered_length,\r
+                       event.event_data.dto_completion_event_data.user_cookie.\r
+                       as_64, (int)sizeof(DAT_RMR_TRIPLET), recv_msg_index);\r
+\r
+               return (DAT_ABORT);\r
+       }\r
+\r
+       /* swap received RMR msg: network order to host order */\r
+       r_iov = rmr_recv_msg[recv_msg_index];\r
+       rmr_recv_msg[recv_msg_index].virtual_address =\r
+           ntohll(rmr_recv_msg[recv_msg_index].virtual_address);\r
+       rmr_recv_msg[recv_msg_index].segment_length =\r
+           ntohl(rmr_recv_msg[recv_msg_index].segment_length);\r
+       rmr_recv_msg[recv_msg_index].rmr_context =\r
+           ntohl(rmr_recv_msg[recv_msg_index].rmr_context);\r
+\r
+       printf("%d Received RMR from remote: "\r
+              "r_iov: r_key_ctx=%x,va=" F64x ",len=0x%x\n",\r
+              getpid(), rmr_recv_msg[recv_msg_index].rmr_context,\r
+              rmr_recv_msg[recv_msg_index].virtual_address,\r
+              rmr_recv_msg[recv_msg_index].segment_length);\r
+\r
+       LOGPRINTF("%d inbound rdma_write; send msg event SUCCESS!!\n",\r
+                 getpid());\r
+\r
+       printf("%d %s RCV RDMA read buffer contains: %s\n",\r
+              getpid(), server ? "SERVER:" : "CLIENT:", sbuf);\r
+\r
+       recv_msg_index++;\r
+\r
+       return (DAT_SUCCESS);\r
+}\r
+\r
+DAT_RETURN do_ping_pong_msg()\r
+{\r
+       DAT_EVENT event;\r
+       DAT_COUNT nmore;\r
+       DAT_DTO_COOKIE cookie;\r
+       DAT_LMR_TRIPLET l_iov;\r
+       DAT_RETURN ret;\r
+       int i;\r
+       char *snd_buf;\r
+       char *rcv_buf;\r
+\r
+       printf("\n %d PING DATA with SEND MSG\n\n", getpid());\r
+\r
+       snd_buf = sbuf;\r
+       rcv_buf = rbuf;\r
+\r
+       /* pre-post all buffers */\r
+       for (i = 0; i < burst; i++) {\r
+               burst_msg_posted++;\r
+               cookie.as_64 = i;\r
+               l_iov.lmr_context = lmr_context_recv;\r
+               l_iov.virtual_address = (DAT_VADDR) (uintptr_t) rcv_buf;\r
+               l_iov.segment_length = buf_len;\r
+\r
+               LOGPRINTF("%d Pre-posting Receive Message Buffers %p\n",\r
+                         getpid(), rcv_buf);\r
+\r
+               ret = dat_ep_post_recv(h_ep,\r
+                                      1,\r
+                                      &l_iov,\r
+                                      cookie, DAT_COMPLETION_DEFAULT_FLAG);\r
+\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr,\r
+                               "%d Error posting recv msg buffer: %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (ret);\r
+               } else {\r
+                       LOGPRINTF("%d Posted Receive Message Buffer %p\n",\r
+                                 getpid(), rcv_buf);\r
+               }\r
+\r
+               /* next buffer */\r
+               rcv_buf += buf_len;\r
+       }\r
+#if defined(_WIN32) || defined(_WIN64)\r
+       Sleep(1000);\r
+#else\r
+       sleep(1);\r
+#endif\r
+\r
+       /* Initialize recv_buf and index to beginning */\r
+       rcv_buf = rbuf;\r
+       burst_msg_index = 0;\r
+\r
+       /* client ping 0x55, server pong 0xAA in first byte */\r
+       start = get_time();\r
+       for (i = 0; i < burst; i++) {\r
+               /* walk the send and recv buffers */\r
+               if (!server) {\r
+                       *snd_buf = 0x55;\r
+\r
+                       LOGPRINTF("%d %s SND buffer %p contains: 0x%x len=%d\n",\r
+                                 getpid(), server ? "SERVER:" : "CLIENT:",\r
+                                 snd_buf, *snd_buf, buf_len);\r
+\r
+                       ret = send_msg(snd_buf,\r
+                                      buf_len,\r
+                                      lmr_context_send,\r
+                                      cookie, DAT_COMPLETION_SUPPRESS_FLAG);\r
+\r
+                       if (ret != DAT_SUCCESS) {\r
+                               fprintf(stderr, "%d Error send_msg: %s\n",\r
+                                       getpid(), DT_RetToString(ret));\r
+                               return (ret);\r
+                       } else {\r
+                               LOGPRINTF("%d send_msg completed\n", getpid());\r
+                       }\r
+               }\r
+\r
+               /* Wait for recv message */\r
+               if (polling) {\r
+                       poll_count = 0;\r
+                       LOGPRINTF("%d Polling for message receive event\n",\r
+                                 getpid());\r
+                       while (dat_evd_dequeue(h_dto_rcv_evd, &event) ==\r
+                              DAT_QUEUE_EMPTY)\r
+                               poll_count++;\r
+               } else {\r
+                       LOGPRINTF("%d waiting for message receive event\n",\r
+                                 getpid());\r
+                       if (use_cno) {\r
+                               DAT_EVD_HANDLE evd = DAT_HANDLE_NULL;\r
+                               ret =\r
+                                   dat_cno_wait(h_dto_cno, DTO_TIMEOUT, &evd);\r
+                               LOGPRINTF("%d cno wait return evd_handle=%p\n",\r
+                                         getpid(), evd);\r
+                               if (evd != h_dto_rcv_evd) {\r
+                                       /* CNO timeout, already on EVD */\r
+                                       if (evd != NULL)\r
+                                               return (ret);\r
+                               }\r
+                       }\r
+                       /* use wait to dequeue */\r
+                       ret =\r
+                           dat_evd_wait(h_dto_rcv_evd, DTO_TIMEOUT, 1, &event,\r
+                                        &nmore);\r
+                       if (ret != DAT_SUCCESS) {\r
+                               fprintf(stderr,\r
+                                       "%d: ERROR: DTO dat_evd_wait() %s\n",\r
+                                       getpid(), DT_RetToString(ret));\r
+                               return (ret);\r
+                       }\r
+               }\r
+               /* start timer after first message arrives on server */\r
+               if (i == 0) {\r
+                       start = get_time();\r
+               }\r
+               /* validate event number and status */\r
+               LOGPRINTF("%d inbound message; message arrived!\n", getpid());\r
+               if (event.event_number != DAT_DTO_COMPLETION_EVENT) {\r
+                       fprintf(stderr, "%d Error unexpected DTO event : %s\n",\r
+                               getpid(), DT_EventToSTr(event.event_number));\r
+                       return (DAT_ABORT);\r
+               }\r
+               if ((event.event_data.dto_completion_event_data.\r
+                    transfered_length != buf_len)\r
+                   || (event.event_data.dto_completion_event_data.user_cookie.\r
+                       as_64 != burst_msg_index)) {\r
+                       fprintf(stderr,\r
+                               "ERR: recv event: len=%d cookie=" F64x\r
+                               " exp %d/%d\n",\r
+                               (int)event.event_data.dto_completion_event_data.\r
+                               transfered_length,\r
+                               event.event_data.dto_completion_event_data.\r
+                               user_cookie.as_64, (int)buf_len,\r
+                               (int)burst_msg_index);\r
+\r
+                       return (DAT_ABORT);\r
+               }\r
+\r
+               LOGPRINTF("%d %s RCV buffer %p contains: 0x%x len=%d\n",\r
+                         getpid(), server ? "SERVER:" : "CLIENT:",\r
+                         rcv_buf, *rcv_buf, buf_len);\r
+\r
+               burst_msg_index++;\r
+\r
+               /* If server, change data and send it back to client */\r
+               if (server) {\r
+                       *snd_buf = 0xaa;\r
+\r
+                       LOGPRINTF("%d %s SND buffer %p contains: 0x%x len=%d\n",\r
+                                 getpid(), server ? "SERVER:" : "CLIENT:",\r
+                                 snd_buf, *snd_buf, buf_len);\r
+\r
+                       ret = send_msg(snd_buf,\r
+                                      buf_len,\r
+                                      lmr_context_send,\r
+                                      cookie, DAT_COMPLETION_SUPPRESS_FLAG);\r
+\r
+                       if (ret != DAT_SUCCESS) {\r
+                               fprintf(stderr, "%d Error send_msg: %s\n",\r
+                                       getpid(), DT_RetToString(ret));\r
+                               return (ret);\r
+                       } else {\r
+                               LOGPRINTF("%d send_msg completed\n", getpid());\r
+                       }\r
+               }\r
+\r
+               /* next buffers */\r
+               rcv_buf += buf_len;\r
+               snd_buf += buf_len;\r
+       }\r
+       stop = get_time();\r
+       time.rtt = ((stop - start) * 1.0e6);\r
+\r
+       return (DAT_SUCCESS);\r
+}\r
+\r
+/* Register RDMA Receive buffer */\r
+DAT_RETURN register_rdma_memory(void)\r
+{\r
+       DAT_RETURN ret;\r
+       DAT_REGION_DESCRIPTION region;\r
+\r
+       region.for_va = rbuf;\r
+       start = get_time();\r
+       ret = dat_lmr_create(h_ia,\r
+                            DAT_MEM_TYPE_VIRTUAL,\r
+                            region,\r
+                            buf_len * (burst+1),\r
+                            h_pz,\r
+                            DAT_MEM_PRIV_ALL_FLAG,\r
+                            DAT_VA_TYPE_VA,\r
+                            &h_lmr_recv,\r
+                            &lmr_context_recv,\r
+                            &rmr_context_recv,\r
+                            &registered_size_recv, &registered_addr_recv);\r
+       stop = get_time();\r
+       time.reg += ((stop - start) * 1.0e6);\r
+       time.total += time.reg;\r
+\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr,\r
+                       "%d Error registering Receive RDMA buffer: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               return (ret);\r
+       } else {\r
+               LOGPRINTF("%d Registered Receive RDMA Buffer %p\n",\r
+                         getpid(), region.for_va);\r
+       }\r
+\r
+       /* Register RDMA Send buffer */\r
+       region.for_va = sbuf;\r
+       ret = dat_lmr_create(h_ia,\r
+                            DAT_MEM_TYPE_VIRTUAL,\r
+                            region,\r
+                            buf_len * (burst + 1),\r
+                            h_pz,\r
+                            DAT_MEM_PRIV_ALL_FLAG,\r
+                            DAT_VA_TYPE_VA,\r
+                            &h_lmr_send,\r
+                            &lmr_context_send,\r
+                            &rmr_context_send,\r
+                            &registered_size_send, &registered_addr_send);\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error registering send RDMA buffer: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               return (ret);\r
+       } else {\r
+               LOGPRINTF("%d Registered Send RDMA Buffer %p\n",\r
+                         getpid(), region.for_va);\r
+       }\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * Unregister RDMA memory\r
+ */\r
+DAT_RETURN unregister_rdma_memory(void)\r
+{\r
+       DAT_RETURN ret;\r
+\r
+       /* Unregister Recv Buffer */\r
+       if (h_lmr_recv != DAT_HANDLE_NULL) {\r
+               LOGPRINTF("%d Unregister h_lmr %p \n", getpid(), h_lmr_recv);\r
+               start = get_time();\r
+               ret = dat_lmr_free(h_lmr_recv);\r
+               stop = get_time();\r
+               time.unreg += ((stop - start) * 1.0e6);\r
+               time.total += time.unreg;\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr, "%d Error deregistering recv mr: %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (ret);\r
+               } else {\r
+                       LOGPRINTF("%d Unregistered Recv Buffer\n", getpid());\r
+                       h_lmr_recv = NULL;\r
+               }\r
+       }\r
+\r
+       /* Unregister Send Buffer */\r
+       if (h_lmr_send != DAT_HANDLE_NULL) {\r
+               LOGPRINTF("%d Unregister h_lmr %p \n", getpid(), h_lmr_send);\r
+               ret = dat_lmr_free(h_lmr_send);\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr, "%d Error deregistering send mr: %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (ret);\r
+               } else {\r
+                       LOGPRINTF("%d Unregistered send Buffer\n", getpid());\r
+                       h_lmr_send = NULL;\r
+               }\r
+       }\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+ /*\r
+  * Create CNO, CR, CONN, and DTO events\r
+  */\r
+DAT_RETURN create_events(void)\r
+{\r
+       DAT_RETURN ret;\r
+       DAT_EVD_PARAM param;\r
+\r
+       /* create CNO */\r
+       if (use_cno) {\r
+               start = get_time();\r
+#if defined(_WIN32) || defined(_WIN64)\r
+               {\r
+                       DAT_OS_WAIT_PROXY_AGENT pa = { NULL, NULL };\r
+                       ret = dat_cno_create(h_ia, pa, &h_dto_cno);\r
+               }\r
+#else\r
+               ret =\r
+                   dat_cno_create(h_ia, DAT_OS_WAIT_PROXY_AGENT_NULL,\r
+                                  &h_dto_cno);\r
+#endif\r
+               stop = get_time();\r
+               time.cnoc += ((stop - start) * 1.0e6);\r
+               time.total += time.cnoc;\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr, "%d Error dat_cno_create: %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (ret);\r
+               } else {\r
+                       LOGPRINTF("%d cr_evd created, %p\n", getpid(),\r
+                                 h_dto_cno);\r
+               }\r
+       }\r
+\r
+       /* create cr EVD */\r
+       start = get_time();\r
+       ret =\r
+           dat_evd_create(h_ia, 10, DAT_HANDLE_NULL, DAT_EVD_CR_FLAG,\r
+                          &h_cr_evd);\r
+       stop = get_time();\r
+       time.evdc += ((stop - start) * 1.0e6);\r
+       time.total += time.evdc;\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error dat_evd_create: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               return (ret);\r
+       } else {\r
+               LOGPRINTF("%d cr_evd created %p\n", getpid(), h_cr_evd);\r
+       }\r
+\r
+       /* create conn EVD */\r
+       ret = dat_evd_create(h_ia,\r
+                            10,\r
+                            DAT_HANDLE_NULL,\r
+                            DAT_EVD_CONNECTION_FLAG, &h_conn_evd);\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error dat_evd_create: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               return (ret);\r
+       } else {\r
+               LOGPRINTF("%d con_evd created %p\n", getpid(), h_conn_evd);\r
+       }\r
+\r
+       /* create dto SND EVD, with CNO if use_cno was set */\r
+       ret = dat_evd_create(h_ia,\r
+                            (MSG_BUF_COUNT + MAX_RDMA_RD + burst) * 2,\r
+                            h_dto_cno, DAT_EVD_DTO_FLAG, &h_dto_req_evd);\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error dat_evd_create REQ: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               return (ret);\r
+       } else {\r
+               LOGPRINTF("%d dto_req_evd created %p\n", getpid(),\r
+                         h_dto_req_evd);\r
+       }\r
+\r
+       /* create dto RCV EVD, with CNO if use_cno was set */\r
+       ret = dat_evd_create(h_ia,\r
+                            MSG_BUF_COUNT + burst,\r
+                            h_dto_cno, DAT_EVD_DTO_FLAG, &h_dto_rcv_evd);\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error dat_evd_create RCV: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               return (ret);\r
+       } else {\r
+               LOGPRINTF("%d dto_rcv_evd created %p\n", getpid(),\r
+                         h_dto_rcv_evd);\r
+       }\r
+\r
+       /* query DTO req EVD and check size */\r
+       ret = dat_evd_query(h_dto_req_evd, DAT_EVD_FIELD_EVD_QLEN, &param);\r
+       if (ret != DAT_SUCCESS) {\r
+               fprintf(stderr, "%d Error dat_evd_query request evd: %s\n",\r
+                       getpid(), DT_RetToString(ret));\r
+               return (ret);\r
+       } else if (param.evd_qlen < (MSG_BUF_COUNT + MAX_RDMA_RD + burst) * 2) {\r
+               fprintf(stderr, "%d Error dat_evd qsize too small: %d < %d\n",\r
+                       getpid(), param.evd_qlen,\r
+                       (MSG_BUF_COUNT + MAX_RDMA_RD + burst) * 2);\r
+               return (ret);\r
+       }\r
+\r
+       LOGPRINTF("%d dto_req_evd QLEN - requested %d and actual %d\n",\r
+                 getpid(), (MSG_BUF_COUNT + MAX_RDMA_RD + burst) * 2,\r
+                 param.evd_qlen);\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * Destroy CR, CONN, CNO, and DTO events\r
+ */\r
+\r
+DAT_RETURN destroy_events(void)\r
+{\r
+       DAT_RETURN ret;\r
+\r
+       /* free cr EVD */\r
+       if (h_cr_evd != DAT_HANDLE_NULL) {\r
+               LOGPRINTF("%d Free cr EVD %p \n", getpid(), h_cr_evd);\r
+               ret = dat_evd_free(h_cr_evd);\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr, "%d Error freeing cr EVD: %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (ret);\r
+               } else {\r
+                       LOGPRINTF("%d Freed cr EVD\n", getpid());\r
+                       h_cr_evd = DAT_HANDLE_NULL;\r
+               }\r
+       }\r
+\r
+       /* free conn EVD */\r
+       if (h_conn_evd != DAT_HANDLE_NULL) {\r
+               LOGPRINTF("%d Free conn EVD %p \n", getpid(), h_conn_evd);\r
+               ret = dat_evd_free(h_conn_evd);\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr, "%d Error freeing conn EVD: %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (ret);\r
+               } else {\r
+                       LOGPRINTF("%d Freed conn EVD\n", getpid());\r
+                       h_conn_evd = DAT_HANDLE_NULL;\r
+               }\r
+       }\r
+\r
+       /* free RCV dto EVD */\r
+       if (h_dto_rcv_evd != DAT_HANDLE_NULL) {\r
+               LOGPRINTF("%d Free RCV dto EVD %p \n", getpid(), h_dto_rcv_evd);\r
+               start = get_time();\r
+               ret = dat_evd_free(h_dto_rcv_evd);\r
+               stop = get_time();\r
+               time.evdf += ((stop - start) * 1.0e6);\r
+               time.total += time.evdf;\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr, "%d Error freeing dto EVD: %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (ret);\r
+               } else {\r
+                       LOGPRINTF("%d Freed dto EVD\n", getpid());\r
+                       h_dto_rcv_evd = DAT_HANDLE_NULL;\r
+               }\r
+       }\r
+\r
+       /* free REQ dto EVD */\r
+       if (h_dto_req_evd != DAT_HANDLE_NULL) {\r
+               LOGPRINTF("%d Free REQ dto EVD %p \n", getpid(), h_dto_req_evd);\r
+               ret = dat_evd_free(h_dto_req_evd);\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr, "%d Error freeing dto EVD: %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (ret);\r
+               } else {\r
+                       LOGPRINTF("%d Freed dto EVD\n", getpid());\r
+                       h_dto_req_evd = DAT_HANDLE_NULL;\r
+               }\r
+       }\r
+\r
+       /* free CNO */\r
+       if (h_dto_cno != DAT_HANDLE_NULL) {\r
+               LOGPRINTF("%d Free dto CNO %p \n", getpid(), h_dto_cno);\r
+               start = get_time();\r
+               ret = dat_cno_free(h_dto_cno);\r
+               stop = get_time();\r
+               time.cnof += ((stop - start) * 1.0e6);\r
+               time.total += time.cnof;\r
+               if (ret != DAT_SUCCESS) {\r
+                       fprintf(stderr, "%d Error freeing dto CNO: %s\n",\r
+                               getpid(), DT_RetToString(ret));\r
+                       return (ret);\r
+               } else {\r
+                       LOGPRINTF("%d Freed dto CNO\n", getpid());\r
+                       h_dto_cno = DAT_HANDLE_NULL;\r
+               }\r
+       }\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * Map DAT_RETURN values to readable strings,\r
+ * but don't assume the values are zero-based or contiguous.\r
+ */\r
+char errmsg[512] = { 0 };\r
+const char *DT_RetToString(DAT_RETURN ret_value)\r
+{\r
+       const char *major_msg, *minor_msg;\r
+\r
+       dat_strerror(ret_value, &major_msg, &minor_msg);\r
+\r
+       strcpy(errmsg, major_msg);\r
+       strcat(errmsg, " ");\r
+       strcat(errmsg, minor_msg);\r
+\r
+       return errmsg;\r
+}\r
+\r
+/*\r
+ * Map DAT_EVENT_CODE values to readable strings\r
+ */\r
+const char *DT_EventToSTr(DAT_EVENT_NUMBER event_code)\r
+{\r
+       unsigned int i;\r
+       static struct {\r
+               const char *name;\r
+               DAT_RETURN value;\r
+       } dat_events[] = {\r
+#   define DATxx(x) { # x, x }\r
+               DATxx(DAT_DTO_COMPLETION_EVENT),\r
+                   DATxx(DAT_RMR_BIND_COMPLETION_EVENT),\r
+                   DATxx(DAT_CONNECTION_REQUEST_EVENT),\r
+                   DATxx(DAT_CONNECTION_EVENT_ESTABLISHED),\r
+                   DATxx(DAT_CONNECTION_EVENT_PEER_REJECTED),\r
+                   DATxx(DAT_CONNECTION_EVENT_NON_PEER_REJECTED),\r
+                   DATxx(DAT_CONNECTION_EVENT_ACCEPT_COMPLETION_ERROR),\r
+                   DATxx(DAT_CONNECTION_EVENT_DISCONNECTED),\r
+                   DATxx(DAT_CONNECTION_EVENT_BROKEN),\r
+                   DATxx(DAT_CONNECTION_EVENT_TIMED_OUT),\r
+                   DATxx(DAT_CONNECTION_EVENT_UNREACHABLE),\r
+                   DATxx(DAT_ASYNC_ERROR_EVD_OVERFLOW),\r
+                   DATxx(DAT_ASYNC_ERROR_IA_CATASTROPHIC),\r
+                   DATxx(DAT_ASYNC_ERROR_EP_BROKEN),\r
+                   DATxx(DAT_ASYNC_ERROR_TIMED_OUT),\r
+                   DATxx(DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR),\r
+                   DATxx(DAT_SOFTWARE_EVENT)\r
+#   undef DATxx\r
+       };\r
+#   define NUM_EVENTS (sizeof(dat_events)/sizeof(dat_events[0]))\r
+\r
+       for (i = 0; i < NUM_EVENTS; i++) {\r
+               if (dat_events[i].value == event_code) {\r
+                       return (dat_events[i].name);\r
+               }\r
+       }\r
+\r
+       return ("Invalid_DAT_EVENT_NUMBER");\r
+}\r
+\r
+void print_usage(void)\r
+{\r
+       printf("\n DAPL USAGE \n\n");\r
+       printf("s: server\n");\r
+       printf("t: performance times\n");\r
+       printf("c: use cno\n");\r
+       printf("v: verbose\n");\r
+       printf("p: polling\n");\r
+       printf("d: delay before accept\n");\r
+       printf("b: buf length to allocate\n");\r
+       printf("B: burst count, rdma and msgs \n");\r
+       printf("h: hostname/address of server, specified on client\n");\r
+       printf("P: provider name (default = OpenIB-cma)\n");\r
+       printf("\n");\r
+}\r
+\r