dapl: use private_data_len for mem copies
authorshefty <shefty@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Fri, 29 Jan 2010 05:06:11 +0000 (05:06 +0000)
committershefty <shefty@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Fri, 29 Jan 2010 05:06:11 +0000 (05:06 +0000)
From: Sean Hefty <sean.hefty@intel.com>

When copying private_data out of rdma_cm events, use the
reported private_data_len for the size, and not IB maximums.
This fixes a bug running over the librdmacm on windows, where
DAPL accessed invalid memory.

Signed-off-by: Sean Hefty <sean.hefty@intel.com>
git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@2688 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

12 files changed:
ulp/dapl2/dapl/common/dapl_adapter_util.h
ulp/dapl2/dapl/common/dapl_cr_callback.c
ulp/dapl2/dapl/common/dapl_cr_util.h
ulp/dapl2/dapl/common/dapl_ep_connect.c
ulp/dapl2/dapl/common/dapl_ep_util.c
ulp/dapl2/dapl/common/dapl_evd_connection_callb.c
ulp/dapl2/dapl/common/dapl_evd_util.h
ulp/dapl2/dapl/common/dapl_ia_query.c
ulp/dapl2/dapl/ibal/dapl_ibal_cm.c
ulp/dapl2/dapl/openib_cma/cm.c
ulp/dapl2/dapl/openib_scm/cm.c
ulp/dapl2/dapl/openib_ucm/cm.c

index 97ab42e..4190eb8 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 );
-
-DAT_RETURN
-dapls_evd_dto_wakeup (
-       IN DAPL_EVD                     *evd_ptr);
-
-DAT_RETURN
-dapls_evd_dto_wait (
-       IN DAPL_EVD                     *evd_ptr,
-       IN uint32_t                     timeout);
-
-#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_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 2340489..6268cc6 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: dapls_cr_callback.c
- *
- * PURPOSE: implements passive side connection callbacks
- *
- * Description: Accepts asynchronous callbacks from the Communications Manager
- *              for EVDs that have been specified as the connection_evd.
- *
- * $Id:$
- **********************************************************************/
-
-#include "dapl.h"
-#include "dapl_evd_util.h"
-#include "dapl_cr_util.h"
-#include "dapl_ia_util.h"
-#include "dapl_sp_util.h"
-#include "dapl_ep_util.h"
-#include "dapl_adapter_util.h"
-
-/*
- * Prototypes
- */
-DAT_RETURN dapli_connection_request(IN dp_ib_cm_handle_t ib_cm_handle,
-                                   IN DAPL_SP * sp_ptr,
-                                   IN DAPL_PRIVATE * prd_ptr,
-                                   IN DAPL_EVD * evd_ptr);
-
-DAPL_EP *dapli_get_sp_ep(IN dp_ib_cm_handle_t ib_cm_handle,
-                        IN DAPL_SP * sp_ptr,
-                        IN DAT_EVENT_NUMBER dat_event_num);
-
-/*
- * dapls_cr_callback
- *
- * The callback function registered with verbs for passive side of
- * connection requests. The interface is specified by cm_api.h
- *
- *
- * Input:
- *     ib_cm_handle,           Handle to CM
- *     ib_cm_event             Specific CM event
- *     instant_data            Private data with DAT ADDRESS header
- *     context                 SP pointer
- *
- * Output:
- *     None
- *
- */
-void dapls_cr_callback(IN dp_ib_cm_handle_t ib_cm_handle, IN const ib_cm_events_t ib_cm_event, IN const void *private_data_ptr,        /* event data */
-                      IN const void *context)
-{
-       DAPL_EP *ep_ptr;
-       DAPL_EVD *evd_ptr;
-       DAPL_SP *sp_ptr;
-       DAPL_PRIVATE *prd_ptr;
-       DAT_EVENT_NUMBER dat_event_num;
-       DAT_RETURN dat_status;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK,
-                    "--> dapl_cr_callback! context: %p event: %x cm_handle %p\n",
-                    context, ib_cm_event, (void *)ib_cm_handle);
-
-       /*
-        * Passive side of the connection, context is a SP and
-        * we need to look up the EP.
-        */
-       sp_ptr = (DAPL_SP *) context;
-       /*
-        * The context pointer could have been cleaned up in a racing
-        * CM callback, check to see if we should just exit here
-        */
-       if (sp_ptr->header.magic == DAPL_MAGIC_INVALID) {
-               return;
-       }
-       dapl_os_assert(sp_ptr->header.magic == DAPL_MAGIC_PSP ||
-                      sp_ptr->header.magic == DAPL_MAGIC_RSP);
-
-       /* Obtain the event number from the provider layer */
-       dat_event_num = dapls_ib_get_dat_event(ib_cm_event, DAT_FALSE);
-
-       /*
-        * CONNECT_REQUEST events create an event on the PSP
-        * EVD, which will trigger connection processing. The
-        * sequence is:
-        *    CONNECT_REQUEST         Event to SP
-        *    CONNECTED               Event to EP
-        *    DISCONNECT              Event to EP
-        *
-        * Obtain the EP if required and set an event up on the correct
-        * EVD.
-        */
-       if (dat_event_num == DAT_CONNECTION_REQUEST_EVENT) {
-               ep_ptr = NULL;
-               evd_ptr = sp_ptr->evd_handle;
-       } else {
-               /* see if there is an EP connected with this CM handle */
-               ep_ptr = dapli_get_sp_ep(ib_cm_handle, sp_ptr, dat_event_num);
-
-               /* if we lost a race with the CM just exit. */
-               if (ep_ptr == NULL) {
-                       return;
-               }
-
-               evd_ptr = (DAPL_EVD *) ep_ptr->param.connect_evd_handle;
-               /* if something has happened to our EVD, bail. */
-               if (evd_ptr == NULL) {
-                       return;
-               }
-       }
-
-       prd_ptr = (DAPL_PRIVATE *) private_data_ptr;
-
-       dat_status = DAT_INTERNAL_ERROR;        /* init to ERR */
-
-       switch (dat_event_num) {
-       case DAT_CONNECTION_REQUEST_EVENT:
-               {
-                       /*
-                        * Requests arriving on a disabled SP are immediatly rejected
-                        */
-
-                       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,
-                                            "---> dapls_cr_callback: conn event on down SP\n");
-                               (void)dapls_ib_reject_connection(ib_cm_handle,
-                                                                DAT_CONNECTION_EVENT_UNREACHABLE,
-                                                                0, NULL);
-
-                               return;
-                       }
-
-                       if (sp_ptr->header.handle_type == DAT_HANDLE_TYPE_RSP) {
-                               /*
-                                * RSP connections only allow a single connection. Close
-                                * it down NOW so we reject any further connections.
-                                */
-                               sp_ptr->listening = DAT_FALSE;
-                       }
-                       dapl_os_unlock(&sp_ptr->header.lock);
-
-                       /*
-                        * Only occurs on the passive side of a connection
-                        * dapli_connection_request will post the connection
-                        * event if appropriate.
-                        */
-                       dat_status = dapli_connection_request(ib_cm_handle,
-                                                             sp_ptr,
-                                                             prd_ptr, evd_ptr);
-                       /* Set evd_ptr = NULL so we don't generate an event below */
-                       evd_ptr = NULL;
-
-                       break;
-               }
-       case DAT_CONNECTION_EVENT_ESTABLISHED:
-               {
-                       /* This is just a notification the connection is now
-                        * established, there isn't any private data to deal with.
-                        *
-                        * Update the EP state and cache a copy of the cm handle,
-                        * then let the user know we are ready to go.
-                        */
-                       dapl_os_lock(&ep_ptr->header.lock);
-                       if (ep_ptr->header.magic != DAPL_MAGIC_EP ||
-                           ep_ptr->param.ep_state !=
-                           DAT_EP_STATE_COMPLETION_PENDING) {
-                               /* If someone pulled the plug on the EP or connection,
-                                * just exit
-                                */
-                               dapl_os_unlock(&ep_ptr->header.lock);
-                               dat_status = DAT_SUCCESS;
-                               /* Set evd_ptr = NULL so we don't generate an event below */
-                               evd_ptr = NULL;
-
-                               break;
-                       }
-
-                       ep_ptr->param.ep_state = DAT_EP_STATE_CONNECTED;
-                       ep_ptr->cm_handle = ib_cm_handle;
-                       dapl_os_unlock(&ep_ptr->header.lock);
-
-                       break;
-               }
-       case DAT_CONNECTION_EVENT_DISCONNECTED:
-               {
-                       /*
-                        * EP is now fully disconnected; initiate any post processing
-                        * to reset the underlying QP and get the EP ready for
-                        * another connection
-                        */
-                       dapl_os_lock(&ep_ptr->header.lock);
-                       if (ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED) {
-                               /* The disconnect has already occurred, we are now
-                                * cleaned up and ready to exit
-                                */
-                               dapl_os_unlock(&ep_ptr->header.lock);
-                               return;
-                       }
-                       ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;
-                       dapls_ib_disconnect_clean(ep_ptr, DAT_FALSE,
-                                                 ib_cm_event);
-                       dapl_os_unlock(&ep_ptr->header.lock);
-
-                       break;
-               }
-       case DAT_CONNECTION_EVENT_NON_PEER_REJECTED:
-       case DAT_CONNECTION_EVENT_PEER_REJECTED:
-       case DAT_CONNECTION_EVENT_UNREACHABLE:
-               {
-                       /*
-                        * After posting an accept the requesting node has
-                        * stopped talking.
-                        */
-                       dapl_os_lock(&ep_ptr->header.lock);
-                       ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;
-                       ep_ptr->cm_handle = IB_INVALID_HANDLE;
-                       dapls_ib_disconnect_clean(ep_ptr, DAT_FALSE,
-                                                 ib_cm_event);
-                       dapl_os_unlock(&ep_ptr->header.lock);
-
-                       break;
-               }
-       case DAT_CONNECTION_EVENT_BROKEN:
-               {
-                       dapl_os_lock(&ep_ptr->header.lock);
-                       ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;
-                       dapls_ib_disconnect_clean(ep_ptr, DAT_FALSE,
-                                                 ib_cm_event);
-                       dapl_os_unlock(&ep_ptr->header.lock);
-
-                       break;
-               }
-       default:
-               {
-                       evd_ptr = NULL;
-                       dapl_os_assert(0);      /* shouldn't happen */
-                       break;
-               }
-       }
-
-       if (evd_ptr != NULL) {
-               dat_status = dapls_evd_post_connection_event(evd_ptr,
-                                                            dat_event_num,
-                                                            (DAT_HANDLE)
-                                                            ep_ptr, 0, NULL);
-       }
-
-       if (dat_status != DAT_SUCCESS) {
-               /* The event post failed; take appropriate action.  */
-               (void)dapls_ib_reject_connection(ib_cm_handle,
-                                                DAT_CONNECTION_EVENT_BROKEN,
-                                                0, NULL);
-
-               return;
-       }
-}
-
-/*
- * dapli_connection_request
- *
- * Process a connection request on the Passive side of a connection.
- * Create a CR record and link it on to the SP so we can update it
- * and free it later. Create an EP if specified by the PSP flags.
- *
- * Input:
- *     ib_cm_handle,
- *     sp_ptr
- *     event_ptr
- *     prd_ptr
- *
- * Output:
- *     None
- *
- * Returns
- *     DAT_INSUFFICIENT_RESOURCES
- *     DAT_SUCCESS
- *
- */
-DAT_RETURN
-dapli_connection_request(IN dp_ib_cm_handle_t ib_cm_handle,
-                        IN DAPL_SP * sp_ptr,
-                        IN DAPL_PRIVATE * prd_ptr, IN DAPL_EVD * evd_ptr)
-{
-       DAT_RETURN dat_status;
-
-       DAPL_CR *cr_ptr;
-       DAPL_EP *ep_ptr;
-       DAPL_IA *ia_ptr;
-       DAT_SP_HANDLE sp_handle;
-
-       cr_ptr = dapls_cr_alloc(sp_ptr->header.owner_ia);
-       if (cr_ptr == NULL) {
-               /* Invoking function will call dapls_ib_cm_reject() */
-               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;
-#ifdef IBHOSTS_NAMING
-       /*
-        * Special case: pull the remote HCA address from the private data
-        * prefix. This is a spec violation as it introduces a protocol, but
-        * some implementations may find it necessary for a time.
-        */
-       cr_ptr->remote_ia_address = prd_ptr->hca_address;
-#endif                         /* IBHOSTS_NAMING */
-       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
-        * payload and put them in a local structure
-        */
-
-       /* Private data size will be determined by the provider layer */
-       cr_ptr->param.private_data = cr_ptr->private_data;
-       if (prd_ptr == NULL) {
-               cr_ptr->param.private_data_size = 0;
-       } else {
-               cr_ptr->param.private_data_size =
-                   dapls_ib_private_data_size(prd_ptr, DAPL_PDATA_CONN_REQ,
-                                              sp_ptr->header.owner_ia->
-                                              hca_ptr);
-       }
-       if (cr_ptr->param.private_data_size > 0) {
-               dapl_os_memcpy(cr_ptr->private_data,
-                              prd_ptr->private_data,
-                              DAPL_MIN(cr_ptr->param.private_data_size,
-                                       DAPL_MAX_PRIVATE_DATA_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) {
-               /*
-                * 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);
-
-       /* Post the event.  */
-       /* assign sp_ptr to union to avoid typecast errors from some compilers */
-       sp_handle.psp_handle = (DAT_PSP_HANDLE) sp_ptr;
-
-       dat_status = dapls_evd_post_cr_arrival_event(evd_ptr,
-                                                    DAT_CONNECTION_REQUEST_EVENT,
-                                                    sp_handle,
-                                                    (DAT_IA_ADDRESS_PTR)
-                                                    & sp_ptr->header.owner_ia->
-                                                    hca_ptr->hca_address,
-                                                    sp_ptr->conn_qual,
-                                                    (DAT_CR_HANDLE) cr_ptr);
-
-       if (dat_status != DAT_SUCCESS) {
-               dapls_cr_free(cr_ptr);
-               (void)dapls_ib_reject_connection(ib_cm_handle,
-                                                DAT_CONNECTION_EVENT_BROKEN,
-                                                0, NULL);
-
-               /* Take the CR off the list, we can't use it */
-               dapl_os_lock(&sp_ptr->header.lock);
-               dapl_sp_remove_cr(sp_ptr, cr_ptr);
-               dapl_os_unlock(&sp_ptr->header.lock);
-               return DAT_INSUFFICIENT_RESOURCES;
-       }
-
-       return DAT_SUCCESS;
-}
-
-/*
- * dapli_get_sp_ep
- *
- * Passive side of a connection is now fully established. Clean
- * up resources and obtain the EP pointer associated with a CR in
- * the SP
- *
- * Input:
- *     ib_cm_handle,
- *     sp_ptr
- *     connection_event
- *
- * Output:
- *     none
- *
- * Returns
- *     ep_ptr
- *
- */
-DAPL_EP *dapli_get_sp_ep(IN dp_ib_cm_handle_t ib_cm_handle,
-                        IN DAPL_SP * sp_ptr, IN DAT_EVENT_NUMBER dat_event_num)
-{
-       DAPL_CR *cr_ptr;
-       DAPL_EP *ep_ptr;
-
-       /*
-        * acquire the lock, we may be racing with other threads here
-        */
-       dapl_os_lock(&sp_ptr->header.lock);
-
-       /* Verify under lock that the SP is still valid */
-       if (sp_ptr->header.magic == DAPL_MAGIC_INVALID) {
-               dapl_os_unlock(&sp_ptr->header.lock);
-               return NULL;
-       }
-       /*
-        * There are potentially multiple connections in progress. Need to
-        * go through the list and find the one we are interested
-        * in. There is no guarantee of order. dapl_sp_search_cr
-        * leaves the CR on the SP queue.
-        */
-       cr_ptr = dapl_sp_search_cr(sp_ptr, ib_cm_handle);
-       if (cr_ptr == NULL) {
-               dapl_os_unlock(&sp_ptr->header.lock);
-               return NULL;
-       }
-
-       ep_ptr = (DAPL_EP *) cr_ptr->param.local_ep_handle;
-
-       /* Quick check to ensure our EP is still valid */
-       if ((DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP))) {
-               ep_ptr = NULL;
-       }
-
-       /* The CR record is discarded in all except for the CONNECTED case,
-        * as it will have no further relevance.
-        */
-       if (dat_event_num != DAT_CONNECTION_EVENT_ESTABLISHED) {
-               /* Remove the CR from the queue */
-               dapl_sp_remove_cr(sp_ptr, cr_ptr);
-
-               if (ep_ptr != NULL) {
-                       ep_ptr->cr_ptr = NULL;
-               }
-
-               /*
-                * If this SP has been removed from service, free it
-                * up after the last CR is removed
-                */
-               if (sp_ptr->listening != DAT_TRUE && sp_ptr->cr_list_count == 0
-                   && sp_ptr->state != DAPL_SP_STATE_FREE) {
-                       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                                    "--> dapli_get_sp_ep! disconnect dump sp: %p \n",
-                                    sp_ptr);
-                       /* Decrement the ref count on the EVD */
-                       if (sp_ptr->evd_handle) {
-                               dapl_os_atomic_dec(&
-                                                  ((DAPL_EVD *) sp_ptr->
-                                                   evd_handle)->evd_ref_count);
-                               sp_ptr->evd_handle = NULL;
-                       }
-                       sp_ptr->state = DAPL_SP_STATE_FREE;
-                       dapl_os_unlock(&sp_ptr->header.lock);
-                       (void)dapls_ib_remove_conn_listener(sp_ptr->header.
-                                                           owner_ia, sp_ptr);
-                       dapls_ia_unlink_sp((DAPL_IA *) sp_ptr->header.owner_ia,
-                                          sp_ptr);
-                       dapls_sp_free_sp(sp_ptr);
-                       dapls_cr_free(cr_ptr);
-                       goto skip_unlock;
-               }
-
-               dapl_os_unlock(&sp_ptr->header.lock);
-               /* free memory outside of the lock */
-               dapls_cr_free(cr_ptr);
-       } else {
-               dapl_os_unlock(&sp_ptr->header.lock);
-       }
-
-      skip_unlock:
-       return ep_ptr;
-}
-
-/*
- * Local variables:
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  c-brace-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: dapls_cr_callback.c\r
+ *\r
+ * PURPOSE: implements passive side connection callbacks\r
+ *\r
+ * Description: Accepts asynchronous callbacks from the Communications Manager\r
+ *              for EVDs that have been specified as the connection_evd.\r
+ *\r
+ * $Id:$\r
+ **********************************************************************/\r
+\r
+#include "dapl.h"\r
+#include "dapl_evd_util.h"\r
+#include "dapl_cr_util.h"\r
+#include "dapl_ia_util.h"\r
+#include "dapl_sp_util.h"\r
+#include "dapl_ep_util.h"\r
+#include "dapl_adapter_util.h"\r
+\r
+/*\r
+ * Prototypes\r
+ */\r
+DAT_RETURN dapli_connection_request(IN dp_ib_cm_handle_t ib_cm_handle,\r
+                                   IN DAPL_SP * sp_ptr,\r
+                                   IN DAPL_PRIVATE * prd_ptr,\r
+                                   IN int private_data_size,\r
+                                   IN DAPL_EVD * evd_ptr);\r
+\r
+DAPL_EP *dapli_get_sp_ep(IN dp_ib_cm_handle_t ib_cm_handle,\r
+                        IN DAPL_SP * sp_ptr,\r
+                        IN DAT_EVENT_NUMBER dat_event_num);\r
+\r
+/*\r
+ * dapls_cr_callback\r
+ *\r
+ * The callback function registered with verbs for passive side of\r
+ * connection requests. The interface is specified by cm_api.h\r
+ *\r
+ *\r
+ * Input:\r
+ *     ib_cm_handle,           Handle to CM\r
+ *     ib_cm_event             Specific CM event\r
+ *     instant_data            Private data with DAT ADDRESS header\r
+ *     context                 SP pointer\r
+ *\r
+ * Output:\r
+ *     None\r
+ *\r
+ */\r
+void dapls_cr_callback(IN dp_ib_cm_handle_t ib_cm_handle, IN const ib_cm_events_t ib_cm_event,\r
+                      IN const void *private_data_ptr, IN const int private_data_size,\r
+                      IN const void *context)\r
+{\r
+       DAPL_EP *ep_ptr;\r
+       DAPL_EVD *evd_ptr;\r
+       DAPL_SP *sp_ptr;\r
+       DAPL_PRIVATE *prd_ptr;\r
+       DAT_EVENT_NUMBER dat_event_num;\r
+       DAT_RETURN dat_status;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK,\r
+                    "--> dapl_cr_callback! context: %p event: %x cm_handle %p\n",\r
+                    context, ib_cm_event, (void *)ib_cm_handle);\r
+\r
+       /*\r
+        * Passive side of the connection, context is a SP and\r
+        * we need to look up the EP.\r
+        */\r
+       sp_ptr = (DAPL_SP *) context;\r
+       /*\r
+        * The context pointer could have been cleaned up in a racing\r
+        * CM callback, check to see if we should just exit here\r
+        */\r
+       if (sp_ptr->header.magic == DAPL_MAGIC_INVALID) {\r
+               return;\r
+       }\r
+       dapl_os_assert(sp_ptr->header.magic == DAPL_MAGIC_PSP ||\r
+                      sp_ptr->header.magic == DAPL_MAGIC_RSP);\r
+\r
+       /* Obtain the event number from the provider layer */\r
+       dat_event_num = dapls_ib_get_dat_event(ib_cm_event, DAT_FALSE);\r
+\r
+       /*\r
+        * CONNECT_REQUEST events create an event on the PSP\r
+        * EVD, which will trigger connection processing. The\r
+        * sequence is:\r
+        *    CONNECT_REQUEST         Event to SP\r
+        *    CONNECTED               Event to EP\r
+        *    DISCONNECT              Event to EP\r
+        *\r
+        * Obtain the EP if required and set an event up on the correct\r
+        * EVD.\r
+        */\r
+       if (dat_event_num == DAT_CONNECTION_REQUEST_EVENT) {\r
+               ep_ptr = NULL;\r
+               evd_ptr = sp_ptr->evd_handle;\r
+       } else {\r
+               /* see if there is an EP connected with this CM handle */\r
+               ep_ptr = dapli_get_sp_ep(ib_cm_handle, sp_ptr, dat_event_num);\r
+\r
+               /* if we lost a race with the CM just exit. */\r
+               if (ep_ptr == NULL) {\r
+                       return;\r
+               }\r
+\r
+               evd_ptr = (DAPL_EVD *) ep_ptr->param.connect_evd_handle;\r
+               /* if something has happened to our EVD, bail. */\r
+               if (evd_ptr == NULL) {\r
+                       return;\r
+               }\r
+       }\r
+\r
+       prd_ptr = (DAPL_PRIVATE *) private_data_ptr;\r
+\r
+       dat_status = DAT_INTERNAL_ERROR;        /* init to ERR */\r
+\r
+       switch (dat_event_num) {\r
+       case DAT_CONNECTION_REQUEST_EVENT:\r
+               {\r
+                       /*\r
+                        * Requests arriving on a disabled SP are immediatly rejected\r
+                        */\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
+                                            "---> dapls_cr_callback: conn event on down SP\n");\r
+                               (void)dapls_ib_reject_connection(ib_cm_handle,\r
+                                                                DAT_CONNECTION_EVENT_UNREACHABLE,\r
+                                                                0, NULL);\r
+\r
+                               return;\r
+                       }\r
+\r
+                       if (sp_ptr->header.handle_type == DAT_HANDLE_TYPE_RSP) {\r
+                               /*\r
+                                * RSP connections only allow a single connection. Close\r
+                                * it down NOW so we reject any further connections.\r
+                                */\r
+                               sp_ptr->listening = DAT_FALSE;\r
+                       }\r
+                       dapl_os_unlock(&sp_ptr->header.lock);\r
+\r
+                       /*\r
+                        * Only occurs on the passive side of a connection\r
+                        * dapli_connection_request will post the connection\r
+                        * event if appropriate.\r
+                        */\r
+                       dat_status = dapli_connection_request(ib_cm_handle,\r
+                                                             sp_ptr, prd_ptr, private_data_size, evd_ptr);\r
+                       /* Set evd_ptr = NULL so we don't generate an event below */\r
+                       evd_ptr = NULL;\r
+\r
+                       break;\r
+               }\r
+       case DAT_CONNECTION_EVENT_ESTABLISHED:\r
+               {\r
+                       /* This is just a notification the connection is now\r
+                        * established, there isn't any private data to deal with.\r
+                        *\r
+                        * Update the EP state and cache a copy of the cm handle,\r
+                        * then let the user know we are ready to go.\r
+                        */\r
+                       dapl_os_lock(&ep_ptr->header.lock);\r
+                       if (ep_ptr->header.magic != DAPL_MAGIC_EP ||\r
+                           ep_ptr->param.ep_state !=\r
+                           DAT_EP_STATE_COMPLETION_PENDING) {\r
+                               /* If someone pulled the plug on the EP or connection,\r
+                                * just exit\r
+                                */\r
+                               dapl_os_unlock(&ep_ptr->header.lock);\r
+                               dat_status = DAT_SUCCESS;\r
+                               /* Set evd_ptr = NULL so we don't generate an event below */\r
+                               evd_ptr = NULL;\r
+\r
+                               break;\r
+                       }\r
+\r
+                       ep_ptr->param.ep_state = DAT_EP_STATE_CONNECTED;\r
+                       ep_ptr->cm_handle = ib_cm_handle;\r
+                       dapl_os_unlock(&ep_ptr->header.lock);\r
+\r
+                       break;\r
+               }\r
+       case DAT_CONNECTION_EVENT_DISCONNECTED:\r
+               {\r
+                       /*\r
+                        * EP is now fully disconnected; initiate any post processing\r
+                        * to reset the underlying QP and get the EP ready for\r
+                        * another connection\r
+                        */\r
+                       dapl_os_lock(&ep_ptr->header.lock);\r
+                       if (ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED) {\r
+                               /* The disconnect has already occurred, we are now\r
+                                * cleaned up and ready to exit\r
+                                */\r
+                               dapl_os_unlock(&ep_ptr->header.lock);\r
+                               return;\r
+                       }\r
+                       ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;\r
+                       dapls_ib_disconnect_clean(ep_ptr, DAT_FALSE,\r
+                                                 ib_cm_event);\r
+                       dapl_os_unlock(&ep_ptr->header.lock);\r
+\r
+                       break;\r
+               }\r
+       case DAT_CONNECTION_EVENT_NON_PEER_REJECTED:\r
+       case DAT_CONNECTION_EVENT_PEER_REJECTED:\r
+       case DAT_CONNECTION_EVENT_UNREACHABLE:\r
+               {\r
+                       /*\r
+                        * After posting an accept the requesting node has\r
+                        * stopped talking.\r
+                        */\r
+                       dapl_os_lock(&ep_ptr->header.lock);\r
+                       ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;\r
+                       ep_ptr->cm_handle = IB_INVALID_HANDLE;\r
+                       dapls_ib_disconnect_clean(ep_ptr, DAT_FALSE,\r
+                                                 ib_cm_event);\r
+                       dapl_os_unlock(&ep_ptr->header.lock);\r
+\r
+                       break;\r
+               }\r
+       case DAT_CONNECTION_EVENT_BROKEN:\r
+               {\r
+                       dapl_os_lock(&ep_ptr->header.lock);\r
+                       ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;\r
+                       dapls_ib_disconnect_clean(ep_ptr, DAT_FALSE,\r
+                                                 ib_cm_event);\r
+                       dapl_os_unlock(&ep_ptr->header.lock);\r
+\r
+                       break;\r
+               }\r
+       default:\r
+               {\r
+                       evd_ptr = NULL;\r
+                       dapl_os_assert(0);      /* shouldn't happen */\r
+                       break;\r
+               }\r
+       }\r
+\r
+       if (evd_ptr != NULL) {\r
+               dat_status = dapls_evd_post_connection_event(evd_ptr,\r
+                                                            dat_event_num,\r
+                                                            (DAT_HANDLE)\r
+                                                            ep_ptr, 0, NULL);\r
+       }\r
+\r
+       if (dat_status != DAT_SUCCESS) {\r
+               /* The event post failed; take appropriate action.  */\r
+               (void)dapls_ib_reject_connection(ib_cm_handle,\r
+                                                DAT_CONNECTION_EVENT_BROKEN,\r
+                                                0, NULL);\r
+\r
+               return;\r
+       }\r
+}\r
+\r
+/*\r
+ * dapli_connection_request\r
+ *\r
+ * Process a connection request on the Passive side of a connection.\r
+ * Create a CR record and link it on to the SP so we can update it\r
+ * and free it later. Create an EP if specified by the PSP flags.\r
+ *\r
+ * Input:\r
+ *     ib_cm_handle,\r
+ *     sp_ptr\r
+ *     event_ptr\r
+ *     prd_ptr\r
+ *\r
+ * Output:\r
+ *     None\r
+ *\r
+ * Returns\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *     DAT_SUCCESS\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapli_connection_request(IN dp_ib_cm_handle_t ib_cm_handle,\r
+                        IN DAPL_SP * sp_ptr,\r
+                        IN DAPL_PRIVATE * prd_ptr, IN int private_data_size,\r
+                        IN DAPL_EVD * evd_ptr)\r
+{\r
+       DAT_RETURN dat_status;\r
+\r
+       DAPL_CR *cr_ptr;\r
+       DAPL_EP *ep_ptr;\r
+       DAPL_IA *ia_ptr;\r
+       DAT_SP_HANDLE sp_handle;\r
+\r
+       cr_ptr = dapls_cr_alloc(sp_ptr->header.owner_ia);\r
+       if (cr_ptr == NULL) {\r
+               /* Invoking function will call dapls_ib_cm_reject() */\r
+               return DAT_INSUFFICIENT_RESOURCES;\r
+       }\r
+\r
+       /*\r
+        * Set up the CR\r
+        */\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
+#ifdef IBHOSTS_NAMING\r
+       /*\r
+        * Special case: pull the remote HCA address from the private data\r
+        * prefix. This is a spec violation as it introduces a protocol, but\r
+        * some implementations may find it necessary for a time.\r
+        */\r
+       cr_ptr->remote_ia_address = prd_ptr->hca_address;\r
+#endif                         /* IBHOSTS_NAMING */\r
+       cr_ptr->param.remote_ia_address_ptr =\r
+           (DAT_IA_ADDRESS_PTR) & cr_ptr->remote_ia_address;\r
+       /*\r
+        * Copy the remote address and private data out of the private_data\r
+        * payload and put them in a local structure\r
+        */\r
+\r
+       /* Private data size will be determined by the provider layer */\r
+       cr_ptr->param.private_data = cr_ptr->private_data;\r
+       cr_ptr->param.private_data_size = private_data_size;\r
+       if (cr_ptr->param.private_data_size > 0) {\r
+               dapl_os_memcpy(cr_ptr->private_data,\r
+                              prd_ptr->private_data,\r
+                              DAPL_MIN(cr_ptr->param.private_data_size,\r
+                                       DAPL_MAX_PRIVATE_DATA_SIZE));\r
+       }\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
+               /*\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
+       /* Post the event.  */\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
+       dat_status = dapls_evd_post_cr_arrival_event(evd_ptr,\r
+                                                    DAT_CONNECTION_REQUEST_EVENT,\r
+                                                    sp_handle,\r
+                                                    (DAT_IA_ADDRESS_PTR)\r
+                                                    & sp_ptr->header.owner_ia->\r
+                                                    hca_ptr->hca_address,\r
+                                                    sp_ptr->conn_qual,\r
+                                                    (DAT_CR_HANDLE) cr_ptr);\r
+\r
+       if (dat_status != DAT_SUCCESS) {\r
+               dapls_cr_free(cr_ptr);\r
+               (void)dapls_ib_reject_connection(ib_cm_handle,\r
+                                                DAT_CONNECTION_EVENT_BROKEN,\r
+                                                0, NULL);\r
+\r
+               /* Take the CR off the list, we can't use it */\r
+               dapl_os_lock(&sp_ptr->header.lock);\r
+               dapl_sp_remove_cr(sp_ptr, cr_ptr);\r
+               dapl_os_unlock(&sp_ptr->header.lock);\r
+               return DAT_INSUFFICIENT_RESOURCES;\r
+       }\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * dapli_get_sp_ep\r
+ *\r
+ * Passive side of a connection is now fully established. Clean\r
+ * up resources and obtain the EP pointer associated with a CR in\r
+ * the SP\r
+ *\r
+ * Input:\r
+ *     ib_cm_handle,\r
+ *     sp_ptr\r
+ *     connection_event\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns\r
+ *     ep_ptr\r
+ *\r
+ */\r
+DAPL_EP *dapli_get_sp_ep(IN dp_ib_cm_handle_t ib_cm_handle,\r
+                        IN DAPL_SP * sp_ptr, IN DAT_EVENT_NUMBER dat_event_num)\r
+{\r
+       DAPL_CR *cr_ptr;\r
+       DAPL_EP *ep_ptr;\r
+\r
+       /*\r
+        * acquire the lock, we may be racing with other threads here\r
+        */\r
+       dapl_os_lock(&sp_ptr->header.lock);\r
+\r
+       /* Verify under lock that the SP is still valid */\r
+       if (sp_ptr->header.magic == DAPL_MAGIC_INVALID) {\r
+               dapl_os_unlock(&sp_ptr->header.lock);\r
+               return NULL;\r
+       }\r
+       /*\r
+        * There are potentially multiple connections in progress. Need to\r
+        * go through the list and find the one we are interested\r
+        * in. There is no guarantee of order. dapl_sp_search_cr\r
+        * leaves the CR on the SP queue.\r
+        */\r
+       cr_ptr = dapl_sp_search_cr(sp_ptr, ib_cm_handle);\r
+       if (cr_ptr == NULL) {\r
+               dapl_os_unlock(&sp_ptr->header.lock);\r
+               return NULL;\r
+       }\r
+\r
+       ep_ptr = (DAPL_EP *) cr_ptr->param.local_ep_handle;\r
+\r
+       /* Quick check to ensure our EP is still valid */\r
+       if ((DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP))) {\r
+               ep_ptr = NULL;\r
+       }\r
+\r
+       /* The CR record is discarded in all except for the CONNECTED case,\r
+        * as it will have no further relevance.\r
+        */\r
+       if (dat_event_num != DAT_CONNECTION_EVENT_ESTABLISHED) {\r
+               /* Remove the CR from the queue */\r
+               dapl_sp_remove_cr(sp_ptr, cr_ptr);\r
+\r
+               if (ep_ptr != NULL) {\r
+                       ep_ptr->cr_ptr = NULL;\r
+               }\r
+\r
+               /*\r
+                * If this SP has been removed from service, free it\r
+                * up after the last CR is removed\r
+                */\r
+               if (sp_ptr->listening != DAT_TRUE && sp_ptr->cr_list_count == 0\r
+                   && sp_ptr->state != DAPL_SP_STATE_FREE) {\r
+                       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                                    "--> dapli_get_sp_ep! disconnect dump sp: %p \n",\r
+                                    sp_ptr);\r
+                       /* Decrement the ref count on the EVD */\r
+                       if (sp_ptr->evd_handle) {\r
+                               dapl_os_atomic_dec(&\r
+                                                  ((DAPL_EVD *) sp_ptr->\r
+                                                   evd_handle)->evd_ref_count);\r
+                               sp_ptr->evd_handle = NULL;\r
+                       }\r
+                       sp_ptr->state = DAPL_SP_STATE_FREE;\r
+                       dapl_os_unlock(&sp_ptr->header.lock);\r
+                       (void)dapls_ib_remove_conn_listener(sp_ptr->header.\r
+                                                           owner_ia, sp_ptr);\r
+                       dapls_ia_unlink_sp((DAPL_IA *) sp_ptr->header.owner_ia,\r
+                                          sp_ptr);\r
+                       dapls_sp_free_sp(sp_ptr);\r
+                       dapls_cr_free(cr_ptr);\r
+                       goto skip_unlock;\r
+               }\r
+\r
+               dapl_os_unlock(&sp_ptr->header.lock);\r
+               /* free memory outside of the lock */\r
+               dapls_cr_free(cr_ptr);\r
+       } else {\r
+               dapl_os_unlock(&sp_ptr->header.lock);\r
+       }\r
+\r
+      skip_unlock:\r
+       return ep_ptr;\r
+}\r
+\r
+/*\r
+ * Local variables:\r
+ *  c-indent-level: 4\r
+ *  c-basic-offset: 4\r
+ *  c-brace-offset: -4\r
+ *  tab-width: 8\r
+ * End:\r
+ */\r
index 33aed7c..27bcca9 100644 (file)
@@ -1,58 +1,59 @@
-/*
- * 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.
- */
-
-/**********************************************************************
- * 
- * HEADER: dapl_cr_util.h
- *
- * PURPOSE: Utility defs & routines for the CR data structure
- *
- * $Id:$
- *
- **********************************************************************/
-
-#ifndef _DAPL_CR_UTIL_H_
-#define _DAPL_CR_UTIL_H_
-
-#include "dapl.h" 
-
-DAPL_CR        *
-dapls_cr_alloc (
-       DAPL_IA         *ia_ptr );
-
-void
-dapls_cr_free (
-       IN DAPL_CR              *cr_ptr );
-
-void
-dapls_cr_callback (
-    IN    dp_ib_cm_handle_t     ib_cm_handle,
-    IN    const ib_cm_events_t  ib_cm_event,
-    IN   const void            *instant_data_p,
-    IN    const void           *context);
-
-#endif /* _DAPL_CR_UTIL_H_ */
+/*\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
+ * HEADER: dapl_cr_util.h\r
+ *\r
+ * PURPOSE: Utility defs & routines for the CR data structure\r
+ *\r
+ * $Id:$\r
+ *\r
+ **********************************************************************/\r
+\r
+#ifndef _DAPL_CR_UTIL_H_\r
+#define _DAPL_CR_UTIL_H_\r
+\r
+#include "dapl.h" \r
+\r
+DAPL_CR        *\r
+dapls_cr_alloc (\r
+       DAPL_IA         *ia_ptr );\r
+\r
+void\r
+dapls_cr_free (\r
+       IN DAPL_CR              *cr_ptr );\r
+\r
+void\r
+dapls_cr_callback (\r
+    IN    dp_ib_cm_handle_t     ib_cm_handle,\r
+    IN    const ib_cm_events_t  ib_cm_event,\r
+    IN   const void            *private_data_ptr,\r
+    IN    const int            private_data_size,\r
+    IN    const void           *context);\r
+\r
+#endif /* _DAPL_CR_UTIL_H_ */\r
index 5e4dc41..a14785b 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_ep_connect.c
- *
- * PURPOSE: Endpoint management
- *
- * $Id:$
- **********************************************************************/
-
-#include "dapl.h"
-#include "dapl_ep_util.h"
-#include "dapl_adapter_util.h"
-#include "dapl_evd_util.h"
-#include "dapl_timer_util.h"
-
-/*
- * dapl_ep_connect
- *
- * Request a connection be established between the local Endpoint
- * and a remote Endpoint. This operation is used by the active/client
- * side of a connection
- *
- * Input:
- *     ep_handle
- *     remote_ia_address
- *     remote_conn_qual
- *     timeout
- *     private_data_size
- *     privaet_data
- *     qos
- *     connect_flags
- *
- * Output:
- *     None
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOUCRES
- *     DAT_INVALID_PARAMETER
- *     DAT_MODLE_NOT_SUPPORTED
- */
-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 qos, IN DAT_CONNECT_FLAGS connect_flags)
-{
-       DAPL_EP *ep_ptr;
-       DAPL_EP alloc_ep;
-       DAT_RETURN dat_status;
-       DAT_COUNT req_hdr_size;
-       DAT_UINT32 max_req_pdata_size;
-       void *private_data_ptr;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_API | DAPL_DBG_TYPE_CM,
-                    "dapl_ep_connect (%p, {%u.%u.%u.%u}, %X, %d, %d, %p, %x, %x)\n",
-                    ep_handle,
-                    remote_ia_address->sa_data[2],
-                    remote_ia_address->sa_data[3],
-                    remote_ia_address->sa_data[4],
-                    remote_ia_address->sa_data[5],
-                    remote_conn_qual,
-                    timeout,
-                    private_data_size, private_data, qos, connect_flags);
-
-       dat_status = DAT_SUCCESS;
-       ep_ptr = (DAPL_EP *) ep_handle;
-
-       /*
-        * Verify parameter & state. The connection handle must be good
-        * at this point.
-        */
-       if (DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP)) {
-               dat_status =
-                   DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP);
-               goto bail;
-       }
-
-       if (DAPL_BAD_HANDLE(ep_ptr->param.connect_evd_handle, DAPL_MAGIC_EVD)) {
-               dat_status =
-                   DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EVD_CONN);
-               goto bail;
-       }
-
-       /* Can't do a connection in 0 time, reject outright */
-       if (timeout == 0) {
-               dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG4);
-               goto bail;
-       }
-       DAPL_CNTR(ep_ptr, DCNT_EP_CONNECT);
-
-       /*
-        * If the endpoint needs a QP, associated the QP with it.
-        * This needs to be done carefully, in order to:
-        *  * Avoid allocating under a lock.
-        *  * Not step on data structures being altered by
-        *    routines with which we are racing.
-        * So we:
-        *  * Confirm that a new QP is needed and is not forbidden by the
-        *    current state.
-        *  * Allocate it into a separate EP.
-        *  * Take the EP lock.
-        *  * Reconfirm that the EP is in a state where it needs a QP.
-        *  * Assign the QP and release the lock.
-        */
-       if (ep_ptr->qp_state == DAPL_QP_STATE_UNATTACHED) {
-               if (ep_ptr->param.pz_handle == NULL
-                   || DAPL_BAD_HANDLE(ep_ptr->param.pz_handle, DAPL_MAGIC_PZ))
-               {
-                       dat_status =
-                           DAT_ERROR(DAT_INVALID_STATE,
-                                     DAT_INVALID_STATE_EP_NOTREADY);
-                       goto bail;
-               }
-               alloc_ep = *ep_ptr;
-
-               dat_status = dapls_ib_qp_alloc(ep_ptr->header.owner_ia,
-                                              &alloc_ep, ep_ptr);
-               if (dat_status != DAT_SUCCESS) {
-                       dat_status =
-                           DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
-                                     DAT_RESOURCE_MEMORY);
-                       goto bail;
-               }
-
-               dapl_os_lock(&ep_ptr->header.lock);
-               /*
-                * PZ shouldn't have changed since we're only racing with
-                * dapl_cr_accept()
-                */
-               if (ep_ptr->qp_state != DAPL_QP_STATE_UNATTACHED) {
-                       /* Bail, cleaning up.  */
-                       dapl_os_unlock(&ep_ptr->header.lock);
-                       dat_status = dapls_ib_qp_free(ep_ptr->header.owner_ia,
-                                                     &alloc_ep);
-                       if (dat_status != DAT_SUCCESS) {
-                               dapl_dbg_log(DAPL_DBG_TYPE_WARN,
-                                            "ep_connect: ib_qp_free failed with %x\n",
-                                            dat_status);
-                       }
-                       dat_status =
-                           DAT_ERROR(DAT_INVALID_STATE,
-                                     dapls_ep_state_subtype(ep_ptr));
-                       goto bail;
-               }
-
-               ep_ptr->qp_handle = alloc_ep.qp_handle;
-               ep_ptr->qpn = alloc_ep.qpn;
-               ep_ptr->qp_state = alloc_ep.qp_state;
-
-               dapl_os_unlock(&ep_ptr->header.lock);
-       }
-
-       /*
-        * We do state checks and transitions under lock.
-        * The only code we're racing against is dapl_cr_accept.
-        */
-       dapl_os_lock(&ep_ptr->header.lock);
-
-       /*
-        * Verify the attributes of the EP handle before we connect it. Test
-        * all of the handles to make sure they are currently valid.
-        * Specifically:
-        *   pz_handle              required
-        *   recv_evd_handle        optional, but must be valid
-        *   request_evd_handle     optional, but must be valid
-        *   connect_evd_handle     required
-        */
-       if (ep_ptr->param.pz_handle == NULL
-           || DAPL_BAD_HANDLE(ep_ptr->param.pz_handle, DAPL_MAGIC_PZ)
-           /* test connect handle */
-           || ep_ptr->param.connect_evd_handle == NULL
-           || DAPL_BAD_HANDLE(ep_ptr->param.connect_evd_handle, DAPL_MAGIC_EVD)
-           || !(((DAPL_EVD *) ep_ptr->param.connect_evd_handle)->
-                evd_flags & DAT_EVD_CONNECTION_FLAG)
-           /* test optional completion handles */
-           || (ep_ptr->param.recv_evd_handle != DAT_HANDLE_NULL &&
-               (DAPL_BAD_HANDLE
-                (ep_ptr->param.recv_evd_handle, DAPL_MAGIC_EVD)))
-           || (ep_ptr->param.request_evd_handle != DAT_HANDLE_NULL
-               &&
-               (DAPL_BAD_HANDLE
-                (ep_ptr->param.request_evd_handle, DAPL_MAGIC_EVD)))) {
-               dapl_os_unlock(&ep_ptr->header.lock);
-               dat_status =
-                   DAT_ERROR(DAT_INVALID_STATE, DAT_INVALID_STATE_EP_NOTREADY);
-               goto bail;
-       }
-
-       /* Check both the EP state and the QP state: if we don't have a QP
-        *  we need to attach one now.
-        */
-       if (ep_ptr->qp_state == DAPL_QP_STATE_UNATTACHED) {
-               dat_status = dapls_ib_qp_alloc(ep_ptr->header.owner_ia,
-                                              ep_ptr, ep_ptr);
-
-               if (dat_status != DAT_SUCCESS) {
-                       dapl_os_unlock(&ep_ptr->header.lock);
-                       dat_status =
-                           DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
-                                     DAT_RESOURCE_TEP);
-                       goto bail;
-               }
-       }
-
-       if (ep_ptr->param.ep_state != DAT_EP_STATE_UNCONNECTED &&
-           ep_ptr->param.ep_attr.service_type == DAT_SERVICE_TYPE_RC) {
-               dapl_os_unlock(&ep_ptr->header.lock);
-               dat_status =
-                   DAT_ERROR(DAT_INVALID_STATE,
-                             dapls_ep_state_subtype(ep_ptr));
-               goto bail;
-       }
-
-       if (qos != DAT_QOS_BEST_EFFORT ||
-           connect_flags != DAT_CONNECT_DEFAULT_FLAG) {
-               /*
-                * At this point we only support one QOS level
-                */
-               dapl_os_unlock(&ep_ptr->header.lock);
-               dat_status = DAT_ERROR(DAT_MODEL_NOT_SUPPORTED, 0);
-               goto bail;
-       }
-
-       /*
-        * Verify the private data size doesn't exceed the max
-        * req_hdr_size will evaluate to 0 unless IBHOSTS_NAMING is enabled.
-        */
-       req_hdr_size = (sizeof(DAPL_PRIVATE) - DAPL_MAX_PRIVATE_DATA_SIZE);
-
-       max_req_pdata_size =
-           dapls_ib_private_data_size(NULL, DAPL_PDATA_CONN_REQ,
-                                      ep_ptr->header.owner_ia->hca_ptr);
-
-       if (private_data_size + req_hdr_size > (DAT_COUNT) max_req_pdata_size) {
-               dapl_os_unlock(&ep_ptr->header.lock);
-               dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG5);
-               goto bail;
-       }
-
-       /* transition the state before requesting a connection to avoid
-        * race conditions
-        */
-       ep_ptr->param.ep_state = DAT_EP_STATE_ACTIVE_CONNECTION_PENDING;
-
-       /*
-        * At this point we're committed, and done with the endpoint
-        * except for the connect, so we can drop the lock.
-        */
-       dapl_os_unlock(&ep_ptr->header.lock);
-
-#ifdef IBHOSTS_NAMING
-       /*
-        * Special case: put the remote HCA address into the private data
-        * prefix. This is a spec violation as it introduces a protocol, but
-        * some implementations may find it necessary for a time.
-        * Copy the private data into the EP area so the data is contiguous.
-        * If the provider needs to pad the buffer with NULLs, it happens at
-        * the provider layer.
-        */
-       dapl_os_memcpy(&ep_ptr->hca_address,
-                      &ep_ptr->header.owner_ia->hca_ptr->hca_address,
-                      sizeof(DAT_SOCK_ADDR));
-       dapl_os_memcpy(ep_ptr->private.private_data, private_data,
-                      private_data_size);
-       private_data_ptr = (void *)&ep_ptr->private.private_data;
-#else
-       private_data_ptr = private_data;
-#endif                         /* IBHOSTS_NAMING */
-
-       /* Copy the connection qualifiers */
-       dapl_os_memcpy(ep_ptr->param.remote_ia_address_ptr,
-                      remote_ia_address, sizeof(DAT_SOCK_ADDR));
-       ep_ptr->param.remote_port_qual = remote_conn_qual;
-
-       dat_status = dapls_ib_connect(ep_handle,
-                                     remote_ia_address,
-                                     remote_conn_qual,
-                                     private_data_size + req_hdr_size,
-                                     private_data_ptr);
-
-       if (dat_status != DAT_SUCCESS) {
-               ep_ptr->param.ep_state = DAT_EP_STATE_UNCONNECTED;
-
-               /*
-                * Some implementations provide us with an error code that the
-                * remote destination is unreachable, but DAT doesn't have a
-                * synchronous error code to communicate this. So the provider
-                * layer generates an INTERNAL_ERROR with a subtype; when
-                * this happens, return SUCCESS and generate the event
-                */
-               if (dat_status == DAT_ERROR(DAT_INTERNAL_ERROR, 1)) {
-                       dapls_evd_post_connection_event((DAPL_EVD *) ep_ptr->
-                                                       param.
-                                                       connect_evd_handle,
-                                                       DAT_CONNECTION_EVENT_UNREACHABLE,
-                                                       (DAT_HANDLE) ep_ptr, 0,
-                                                       0);
-                       dat_status = DAT_SUCCESS;
-               }
-       } else {
-               /*
-                * Acquire the lock and recheck the state of the EP; this
-                * thread could have been descheduled after issuing the connect
-                * request and the EP is now connected. Set up a timer if
-                * necessary.
-                */
-               dapl_os_lock(&ep_ptr->header.lock);
-               if (ep_ptr->param.ep_state ==
-                   DAT_EP_STATE_ACTIVE_CONNECTION_PENDING
-                   && timeout != DAT_TIMEOUT_INFINITE) {
-                       ep_ptr->cxn_timer =
-                           (DAPL_OS_TIMER *)
-                           dapl_os_alloc(sizeof(DAPL_OS_TIMER));
-
-                       dapls_timer_set(ep_ptr->cxn_timer,
-                                       dapls_ep_timeout, ep_ptr, timeout);
-               }
-               dapl_os_unlock(&ep_ptr->header.lock);
-       }
-
-      bail:
-       dapl_dbg_log(DAPL_DBG_TYPE_RTN | DAPL_DBG_TYPE_CM,
-                    "dapl_ep_connect () returns 0x%x\n", dat_status);
-
-       return dat_status;
-}
-
-/*
- * dapl_ep_common_connect
- *
- * DAPL Requirements Version 2.0, 6.6.x
- *
- * Requests that a connection be established
- * between the local Endpoint and a remote Endpoint specified by the
- * remote_ia_address. This operation is used by the active/client side
- * Consumer of the Connection establishment model.
- *
- * EP must be properly configured for this operation. The EP Communicator
- * must be specified. As part of the successful completion of this operation,
- * the local Endpoint is bound to a local IA Address if it had these assigned
- * before.
- * 
- * The local IP Address, port and protocol are passed to the remote side of
- * the requested connection and is available to the remote Consumer in the
- * Connection Request of the DAT_CONNECTION_REQUEST_EVENT.
- * 
- * The Consumer-provided private_data is passed to the remote side and is
- * provided to the remote Consumer in the Connection Request. Consumers
- * can encapsulate any local Endpoint attributes that remote Consumers
- * need to know as part of an upper-level protocol.
- *
- * Input:
- *     ep_handle
- *     remote_ia_address
- *     timeout
- *     private_data_size
- *     private_date pointer
- *
- * Output:
- *     none
- * 
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *     DAT_INVALID_PARAMETER
- *     DAT_INVALID_HANDLE
- *     DAT_INVALID_STATE
- *     DAT_MODEL_NOT_SUPPORTED
- */
-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         */
-       return DAT_MODEL_NOT_SUPPORTED;
-}
-
-/*
- * 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_ep_connect.c\r
+ *\r
+ * PURPOSE: Endpoint management\r
+ *\r
+ * $Id:$\r
+ **********************************************************************/\r
+\r
+#include "dapl.h"\r
+#include "dapl_ep_util.h"\r
+#include "dapl_adapter_util.h"\r
+#include "dapl_evd_util.h"\r
+#include "dapl_timer_util.h"\r
+\r
+/*\r
+ * dapl_ep_connect\r
+ *\r
+ * Request a connection be established between the local Endpoint\r
+ * and a remote Endpoint. This operation is used by the active/client\r
+ * side of a connection\r
+ *\r
+ * Input:\r
+ *     ep_handle\r
+ *     remote_ia_address\r
+ *     remote_conn_qual\r
+ *     timeout\r
+ *     private_data_size\r
+ *     privaet_data\r
+ *     qos\r
+ *     connect_flags\r
+ *\r
+ * Output:\r
+ *     None\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOUCRES\r
+ *     DAT_INVALID_PARAMETER\r
+ *     DAT_MODLE_NOT_SUPPORTED\r
+ */\r
+DAT_RETURN DAT_API\r
+dapl_ep_connect(IN DAT_EP_HANDLE ep_handle,\r
+               IN DAT_IA_ADDRESS_PTR remote_ia_address,\r
+               IN DAT_CONN_QUAL remote_conn_qual,\r
+               IN DAT_TIMEOUT timeout,\r
+               IN DAT_COUNT private_data_size,\r
+               IN const DAT_PVOID private_data,\r
+               IN DAT_QOS qos, IN DAT_CONNECT_FLAGS connect_flags)\r
+{\r
+       DAPL_EP *ep_ptr;\r
+       DAPL_EP alloc_ep;\r
+       DAT_RETURN dat_status;\r
+       DAT_COUNT req_hdr_size;\r
+       void *private_data_ptr;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_API | DAPL_DBG_TYPE_CM,\r
+                    "dapl_ep_connect (%p, {%u.%u.%u.%u}, %X, %d, %d, %p, %x, %x)\n",\r
+                    ep_handle,\r
+                    remote_ia_address->sa_data[2],\r
+                    remote_ia_address->sa_data[3],\r
+                    remote_ia_address->sa_data[4],\r
+                    remote_ia_address->sa_data[5],\r
+                    remote_conn_qual,\r
+                    timeout,\r
+                    private_data_size, private_data, qos, connect_flags);\r
+\r
+       dat_status = DAT_SUCCESS;\r
+       ep_ptr = (DAPL_EP *) ep_handle;\r
+\r
+       /*\r
+        * Verify parameter & state. The connection handle must be good\r
+        * at this point.\r
+        */\r
+       if (DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP)) {\r
+               dat_status =\r
+                   DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP);\r
+               goto bail;\r
+       }\r
+\r
+       if (DAPL_BAD_HANDLE(ep_ptr->param.connect_evd_handle, DAPL_MAGIC_EVD)) {\r
+               dat_status =\r
+                   DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EVD_CONN);\r
+               goto bail;\r
+       }\r
+\r
+       /* Can't do a connection in 0 time, reject outright */\r
+       if (timeout == 0) {\r
+               dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG4);\r
+               goto bail;\r
+       }\r
+       DAPL_CNTR(ep_ptr, DCNT_EP_CONNECT);\r
+\r
+       /*\r
+        * If the endpoint needs a QP, associated the QP with it.\r
+        * This needs to be done carefully, in order to:\r
+        *  * Avoid allocating under a lock.\r
+        *  * Not step on data structures being altered by\r
+        *    routines with which we are racing.\r
+        * So we:\r
+        *  * Confirm that a new QP is needed and is not forbidden by the\r
+        *    current state.\r
+        *  * Allocate it into a separate EP.\r
+        *  * Take the EP lock.\r
+        *  * Reconfirm that the EP is in a state where it needs a QP.\r
+        *  * Assign the QP and release the lock.\r
+        */\r
+       if (ep_ptr->qp_state == DAPL_QP_STATE_UNATTACHED) {\r
+               if (ep_ptr->param.pz_handle == NULL\r
+                   || DAPL_BAD_HANDLE(ep_ptr->param.pz_handle, DAPL_MAGIC_PZ))\r
+               {\r
+                       dat_status =\r
+                           DAT_ERROR(DAT_INVALID_STATE,\r
+                                     DAT_INVALID_STATE_EP_NOTREADY);\r
+                       goto bail;\r
+               }\r
+               alloc_ep = *ep_ptr;\r
+\r
+               dat_status = dapls_ib_qp_alloc(ep_ptr->header.owner_ia,\r
+                                              &alloc_ep, ep_ptr);\r
+               if (dat_status != DAT_SUCCESS) {\r
+                       dat_status =\r
+                           DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,\r
+                                     DAT_RESOURCE_MEMORY);\r
+                       goto bail;\r
+               }\r
+\r
+               dapl_os_lock(&ep_ptr->header.lock);\r
+               /*\r
+                * PZ shouldn't have changed since we're only racing with\r
+                * dapl_cr_accept()\r
+                */\r
+               if (ep_ptr->qp_state != DAPL_QP_STATE_UNATTACHED) {\r
+                       /* Bail, cleaning up.  */\r
+                       dapl_os_unlock(&ep_ptr->header.lock);\r
+                       dat_status = dapls_ib_qp_free(ep_ptr->header.owner_ia,\r
+                                                     &alloc_ep);\r
+                       if (dat_status != DAT_SUCCESS) {\r
+                               dapl_dbg_log(DAPL_DBG_TYPE_WARN,\r
+                                            "ep_connect: ib_qp_free failed with %x\n",\r
+                                            dat_status);\r
+                       }\r
+                       dat_status =\r
+                           DAT_ERROR(DAT_INVALID_STATE,\r
+                                     dapls_ep_state_subtype(ep_ptr));\r
+                       goto bail;\r
+               }\r
+\r
+               ep_ptr->qp_handle = alloc_ep.qp_handle;\r
+               ep_ptr->qpn = alloc_ep.qpn;\r
+               ep_ptr->qp_state = alloc_ep.qp_state;\r
+\r
+               dapl_os_unlock(&ep_ptr->header.lock);\r
+       }\r
+\r
+       /*\r
+        * We do state checks and transitions under lock.\r
+        * The only code we're racing against is dapl_cr_accept.\r
+        */\r
+       dapl_os_lock(&ep_ptr->header.lock);\r
+\r
+       /*\r
+        * Verify the attributes of the EP handle before we connect it. Test\r
+        * all of the handles to make sure they are currently valid.\r
+        * Specifically:\r
+        *   pz_handle              required\r
+        *   recv_evd_handle        optional, but must be valid\r
+        *   request_evd_handle     optional, but must be valid\r
+        *   connect_evd_handle     required\r
+        */\r
+       if (ep_ptr->param.pz_handle == NULL\r
+           || DAPL_BAD_HANDLE(ep_ptr->param.pz_handle, DAPL_MAGIC_PZ)\r
+           /* test connect handle */\r
+           || ep_ptr->param.connect_evd_handle == NULL\r
+           || DAPL_BAD_HANDLE(ep_ptr->param.connect_evd_handle, DAPL_MAGIC_EVD)\r
+           || !(((DAPL_EVD *) ep_ptr->param.connect_evd_handle)->\r
+                evd_flags & DAT_EVD_CONNECTION_FLAG)\r
+           /* test optional completion handles */\r
+           || (ep_ptr->param.recv_evd_handle != DAT_HANDLE_NULL &&\r
+               (DAPL_BAD_HANDLE\r
+                (ep_ptr->param.recv_evd_handle, DAPL_MAGIC_EVD)))\r
+           || (ep_ptr->param.request_evd_handle != DAT_HANDLE_NULL\r
+               &&\r
+               (DAPL_BAD_HANDLE\r
+                (ep_ptr->param.request_evd_handle, DAPL_MAGIC_EVD)))) {\r
+               dapl_os_unlock(&ep_ptr->header.lock);\r
+               dat_status =\r
+                   DAT_ERROR(DAT_INVALID_STATE, DAT_INVALID_STATE_EP_NOTREADY);\r
+               goto bail;\r
+       }\r
+\r
+       /* Check both the EP state and the QP state: if we don't have a QP\r
+        *  we need to attach one now.\r
+        */\r
+       if (ep_ptr->qp_state == DAPL_QP_STATE_UNATTACHED) {\r
+               dat_status = dapls_ib_qp_alloc(ep_ptr->header.owner_ia,\r
+                                              ep_ptr, ep_ptr);\r
+\r
+               if (dat_status != DAT_SUCCESS) {\r
+                       dapl_os_unlock(&ep_ptr->header.lock);\r
+                       dat_status =\r
+                           DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,\r
+                                     DAT_RESOURCE_TEP);\r
+                       goto bail;\r
+               }\r
+       }\r
+\r
+       if (ep_ptr->param.ep_state != DAT_EP_STATE_UNCONNECTED &&\r
+           ep_ptr->param.ep_attr.service_type == DAT_SERVICE_TYPE_RC) {\r
+               dapl_os_unlock(&ep_ptr->header.lock);\r
+               dat_status =\r
+                   DAT_ERROR(DAT_INVALID_STATE,\r
+                             dapls_ep_state_subtype(ep_ptr));\r
+               goto bail;\r
+       }\r
+\r
+       if (qos != DAT_QOS_BEST_EFFORT ||\r
+           connect_flags != DAT_CONNECT_DEFAULT_FLAG) {\r
+               /*\r
+                * At this point we only support one QOS level\r
+                */\r
+               dapl_os_unlock(&ep_ptr->header.lock);\r
+               dat_status = DAT_ERROR(DAT_MODEL_NOT_SUPPORTED, 0);\r
+               goto bail;\r
+       }\r
+\r
+       /*\r
+        * Verify the private data size doesn't exceed the max\r
+        * req_hdr_size will evaluate to 0 unless IBHOSTS_NAMING is enabled.\r
+        */\r
+       req_hdr_size = (sizeof(DAPL_PRIVATE) - DAPL_MAX_PRIVATE_DATA_SIZE);\r
+\r
+       /* transition the state before requesting a connection to avoid\r
+        * race conditions\r
+        */\r
+       ep_ptr->param.ep_state = DAT_EP_STATE_ACTIVE_CONNECTION_PENDING;\r
+\r
+       /*\r
+        * At this point we're committed, and done with the endpoint\r
+        * except for the connect, so we can drop the lock.\r
+        */\r
+       dapl_os_unlock(&ep_ptr->header.lock);\r
+\r
+#ifdef IBHOSTS_NAMING\r
+       /*\r
+        * Special case: put the remote HCA address into the private data\r
+        * prefix. This is a spec violation as it introduces a protocol, but\r
+        * some implementations may find it necessary for a time.\r
+        * Copy the private data into the EP area so the data is contiguous.\r
+        * If the provider needs to pad the buffer with NULLs, it happens at\r
+        * the provider layer.\r
+        */\r
+       dapl_os_memcpy(&ep_ptr->hca_address,\r
+                      &ep_ptr->header.owner_ia->hca_ptr->hca_address,\r
+                      sizeof(DAT_SOCK_ADDR));\r
+       dapl_os_memcpy(ep_ptr->private.private_data, private_data,\r
+                      private_data_size);\r
+       private_data_ptr = (void *)&ep_ptr->private.private_data;\r
+#else\r
+       private_data_ptr = private_data;\r
+#endif                         /* IBHOSTS_NAMING */\r
+\r
+       /* Copy the connection qualifiers */\r
+       dapl_os_memcpy(ep_ptr->param.remote_ia_address_ptr,\r
+                      remote_ia_address, sizeof(DAT_SOCK_ADDR));\r
+       ep_ptr->param.remote_port_qual = remote_conn_qual;\r
+\r
+       dat_status = dapls_ib_connect(ep_handle,\r
+                                     remote_ia_address,\r
+                                     remote_conn_qual,\r
+                                     private_data_size + req_hdr_size,\r
+                                     private_data_ptr);\r
+\r
+       if (dat_status != DAT_SUCCESS) {\r
+               ep_ptr->param.ep_state = DAT_EP_STATE_UNCONNECTED;\r
+\r
+               /*\r
+                * Some implementations provide us with an error code that the\r
+                * remote destination is unreachable, but DAT doesn't have a\r
+                * synchronous error code to communicate this. So the provider\r
+                * layer generates an INTERNAL_ERROR with a subtype; when\r
+                * this happens, return SUCCESS and generate the event\r
+                */\r
+               if (dat_status == DAT_ERROR(DAT_INTERNAL_ERROR, 1)) {\r
+                       dapls_evd_post_connection_event((DAPL_EVD *) ep_ptr->\r
+                                                       param.\r
+                                                       connect_evd_handle,\r
+                                                       DAT_CONNECTION_EVENT_UNREACHABLE,\r
+                                                       (DAT_HANDLE) ep_ptr, 0,\r
+                                                       0);\r
+                       dat_status = DAT_SUCCESS;\r
+               }\r
+       } else {\r
+               /*\r
+                * Acquire the lock and recheck the state of the EP; this\r
+                * thread could have been descheduled after issuing the connect\r
+                * request and the EP is now connected. Set up a timer if\r
+                * necessary.\r
+                */\r
+               dapl_os_lock(&ep_ptr->header.lock);\r
+               if (ep_ptr->param.ep_state ==\r
+                   DAT_EP_STATE_ACTIVE_CONNECTION_PENDING\r
+                   && timeout != DAT_TIMEOUT_INFINITE) {\r
+                       ep_ptr->cxn_timer =\r
+                           (DAPL_OS_TIMER *)\r
+                           dapl_os_alloc(sizeof(DAPL_OS_TIMER));\r
+\r
+                       dapls_timer_set(ep_ptr->cxn_timer,\r
+                                       dapls_ep_timeout, ep_ptr, timeout);\r
+               }\r
+               dapl_os_unlock(&ep_ptr->header.lock);\r
+       }\r
+\r
+      bail:\r
+       dapl_dbg_log(DAPL_DBG_TYPE_RTN | DAPL_DBG_TYPE_CM,\r
+                    "dapl_ep_connect () returns 0x%x\n", dat_status);\r
+\r
+       return dat_status;\r
+}\r
+\r
+/*\r
+ * dapl_ep_common_connect\r
+ *\r
+ * DAPL Requirements Version 2.0, 6.6.x\r
+ *\r
+ * Requests that a connection be established\r
+ * between the local Endpoint and a remote Endpoint specified by the\r
+ * remote_ia_address. This operation is used by the active/client side\r
+ * Consumer of the Connection establishment model.\r
+ *\r
+ * EP must be properly configured for this operation. The EP Communicator\r
+ * must be specified. As part of the successful completion of this operation,\r
+ * the local Endpoint is bound to a local IA Address if it had these assigned\r
+ * before.\r
+ * \r
+ * The local IP Address, port and protocol are passed to the remote side of\r
+ * the requested connection and is available to the remote Consumer in the\r
+ * Connection Request of the DAT_CONNECTION_REQUEST_EVENT.\r
+ * \r
+ * The Consumer-provided private_data is passed to the remote side and is\r
+ * provided to the remote Consumer in the Connection Request. Consumers\r
+ * can encapsulate any local Endpoint attributes that remote Consumers\r
+ * need to know as part of an upper-level protocol.\r
+ *\r
+ * Input:\r
+ *     ep_handle\r
+ *     remote_ia_address\r
+ *     timeout\r
+ *     private_data_size\r
+ *     private_date pointer\r
+ *\r
+ * Output:\r
+ *     none\r
+ * \r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *     DAT_INVALID_PARAMETER\r
+ *     DAT_INVALID_HANDLE\r
+ *     DAT_INVALID_STATE\r
+ *     DAT_MODEL_NOT_SUPPORTED\r
+ */\r
+DAT_RETURN DAT_API dapl_ep_common_connect(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)\r
+{                              /* private_data         */\r
+       return DAT_MODEL_NOT_SUPPORTED;\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 a50a6cb..48dee1e 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_ep_util.c
- *
- * PURPOSE: Manage EP Info structure
- *
- * $Id:$
- **********************************************************************/
-
-#include "dapl_ep_util.h"
-#include "dapl_ring_buffer_util.h"
-#include "dapl_cookie.h"
-#include "dapl_adapter_util.h"
-#include "dapl_evd_util.h"
-#include "dapl_cr_util.h"      /* for callback routine */
-
-/*
- * Local definitions
- */
-/*
- * Default number of I/O operations on an end point
- */
-#define IB_IO_DEFAULT  16
-/*
- * Default number of scatter/gather entries available to a single
- * post send/recv
- */
-#define IB_IOV_DEFAULT 4
-
-/*
- * Default number of RDMA operations in progress at a time
- */
-#define IB_RDMA_DEFAULT        4
-
-extern void dapli_ep_default_attrs(IN DAPL_EP * ep_ptr);
-
-char *dapl_get_ep_state_str(DAT_EP_STATE state)
-{
-#ifdef DAPL_DBG
-       static char *state_str[DAT_EP_STATE_CONNECTED_MULTI_PATH + 1] = {
-               "DAT_EP_STATE_UNCONNECTED",     /* quiescent state */
-               "DAT_EP_STATE_UNCONFIGURED_UNCONNECTED",
-               "DAT_EP_STATE_RESERVED",
-               "DAT_EP_STATE_UNCONFIGURED_RESERVED",
-               "DAT_EP_STATE_PASSIVE_CONNECTION_PENDING",
-               "DAT_EP_STATE_UNCONFIGURED_PASSIVE",
-               "DAT_EP_STATE_ACTIVE_CONNECTION_PENDING",
-               "DAT_EP_STATE_TENTATIVE_CONNECTION_PENDING",
-               "DAT_EP_STATE_UNCONFIGURED_TENTATIVE",
-               "DAT_EP_STATE_CONNECTED",
-               "DAT_EP_STATE_DISCONNECT_PENDING",
-               "DAT_EP_STATE_DISCONNECTED",
-               "DAT_EP_STATE_COMPLETION_PENDING",
-               "DAT_EP_STATE_CONNECTED_SINGLE_PATH",
-               "DAT_EP_STATE_CONNECTED_MULTI_PATH"
-       };
-       return state_str[state];
-#else
-       static char buf[12];
-       sprintf(buf, "%d", state);
-       return buf;
-#endif
-}
-
-/*
- * dapl_ep_alloc
- *
- * alloc and initialize an EP INFO struct
- *
- * Input:
- *     IA INFO struct ptr
- *
- * Output:
- *     ep_ptr
- *
- * Returns:
- *     none
- *
- */
-DAPL_EP *dapl_ep_alloc(IN DAPL_IA * ia_ptr, IN const DAT_EP_ATTR * ep_attr)
-{
-       DAPL_EP *ep_ptr;
-
-       /* Allocate EP */
-       ep_ptr =
-           (DAPL_EP *) dapl_os_alloc(sizeof(DAPL_EP) + sizeof(DAT_SOCK_ADDR));
-       if (ep_ptr == NULL) {
-               goto bail;
-       }
-
-       /* zero the structure */
-       dapl_os_memzero(ep_ptr, sizeof(DAPL_EP) + sizeof(DAT_SOCK_ADDR));
-
-#ifdef DAPL_COUNTERS
-       /* Allocate counters */
-       ep_ptr->cntrs =
-           dapl_os_alloc(sizeof(DAT_UINT64) * DCNT_EP_ALL_COUNTERS);
-       if (ep_ptr->cntrs == NULL) {
-               dapl_os_free(ep_ptr, sizeof(DAPL_EP) + sizeof(DAT_SOCK_ADDR));
-               return (NULL);
-       }
-       dapl_os_memzero(ep_ptr->cntrs,
-                       sizeof(DAT_UINT64) * DCNT_EP_ALL_COUNTERS);
-#endif                         /* DAPL_COUNTERS */
-
-       /*
-        * initialize the header
-        */
-       ep_ptr->header.provider = ia_ptr->header.provider;
-       ep_ptr->header.magic = DAPL_MAGIC_EP;
-       ep_ptr->header.handle_type = DAT_HANDLE_TYPE_EP;
-       ep_ptr->header.owner_ia = ia_ptr;
-       ep_ptr->header.user_context.as_64 = 0;
-       ep_ptr->header.user_context.as_ptr = NULL;
-
-       dapl_llist_init_entry(&ep_ptr->header.ia_list_entry);
-       dapl_os_lock_init(&ep_ptr->header.lock);
-
-       /*
-        * Initialize the body
-        */
-       /*
-        * Set up default parameters if the user passed in a NULL
-        */
-       if (ep_attr == NULL) {
-               dapli_ep_default_attrs(ep_ptr);
-       } else {
-               ep_ptr->param.ep_attr = *ep_attr;
-       }
-
-       /*
-        * IBM OS API specific fields
-        */
-       ep_ptr->qp_handle = IB_INVALID_HANDLE;
-       ep_ptr->qpn = 0;
-       ep_ptr->qp_state = DAPL_QP_STATE_UNATTACHED;
-       ep_ptr->cm_handle = IB_INVALID_HANDLE;
-
-       if (DAT_SUCCESS != dapls_cb_create(&ep_ptr->req_buffer,
-                                          ep_ptr,
-                                          ep_ptr->param.ep_attr.
-                                          max_request_dtos)) {
-               dapl_ep_dealloc(ep_ptr);
-               ep_ptr = NULL;
-               goto bail;
-       }
-
-       if (DAT_SUCCESS != dapls_cb_create(&ep_ptr->recv_buffer,
-                                          ep_ptr,
-                                          ep_ptr->param.ep_attr.max_recv_dtos))
-       {
-               dapl_ep_dealloc(ep_ptr);
-               ep_ptr = NULL;
-               goto bail;
-       }
-
-       dapls_io_trc_alloc(ep_ptr);
-
-      bail:
-       return ep_ptr;
-}
-
-/*
- * dapl_ep_dealloc
- *
- * Free the passed in EP structure.
- *
- * Input:
- *     entry point pointer
- *
- * Output:
- *     none
- *
- * Returns:
- *     none
- *
- */
-void dapl_ep_dealloc(IN DAPL_EP * ep_ptr)
-{
-       dapl_os_assert(ep_ptr->header.magic == DAPL_MAGIC_EP);
-
-       ep_ptr->header.magic = DAPL_MAGIC_INVALID;      /* reset magic to prevent reuse */
-
-       dapls_cb_free(&ep_ptr->req_buffer);
-       dapls_cb_free(&ep_ptr->recv_buffer);
-
-       if (NULL != ep_ptr->cxn_timer) {
-               dapl_os_free(ep_ptr->cxn_timer, sizeof(DAPL_OS_TIMER));
-       }
-#if defined(_WIN32) || defined(_WIN64)
-       if (ep_ptr->ibal_cm_handle) {
-               dapl_os_free(ep_ptr->ibal_cm_handle,
-                            sizeof(*ep_ptr->ibal_cm_handle));
-               ep_ptr->ibal_cm_handle = NULL;
-       }
-#endif
-
-#ifdef DAPL_COUNTERS
-       dapl_os_free(ep_ptr->cntrs, sizeof(DAT_UINT64) * DCNT_EP_ALL_COUNTERS);
-#endif                         /* DAPL_COUNTERS */
-
-       dapl_os_free(ep_ptr, sizeof(DAPL_EP) + sizeof(DAT_SOCK_ADDR));
-}
-
-/*
- * dapl_ep_default_attrs
- *
- * Set default values in the parameter fields
- *
- * Input:
- *     entry point pointer
- *
- * Output:
- *     none
- *
- * Returns:
- *     none
- *
- */
-void dapli_ep_default_attrs(IN DAPL_EP * ep_ptr)
-{
-       DAT_EP_ATTR ep_attr_limit;
-       DAT_EP_ATTR *ep_attr;
-       DAT_RETURN dat_status;
-
-       ep_attr = &ep_ptr->param.ep_attr;
-       /* Set up defaults */
-       dapl_os_memzero(ep_attr, sizeof(DAT_EP_ATTR));
-
-       /* mtu and rdma sizes fixed in IB as per IBTA 1.1, 9.4.3, 9.4.4, 9.7.7.  */
-       ep_attr->max_mtu_size = 0x80000000;
-       ep_attr->max_rdma_size = 0x80000000;
-
-       ep_attr->qos = DAT_QOS_BEST_EFFORT;
-       ep_attr->service_type = DAT_SERVICE_TYPE_RC;
-       ep_attr->max_recv_dtos = IB_IO_DEFAULT;
-       ep_attr->max_request_dtos = IB_IO_DEFAULT;
-       ep_attr->max_recv_iov = IB_IOV_DEFAULT;
-       ep_attr->max_request_iov = IB_IOV_DEFAULT;
-       ep_attr->max_rdma_read_in = IB_RDMA_DEFAULT;
-       ep_attr->max_rdma_read_out = IB_RDMA_DEFAULT;
-
-       /*
-        * Configure the EP as a standard completion type, which will be
-        * used by the EVDs. A threshold of 1 is the default state of an
-        * EVD.
-        */
-       ep_attr->request_completion_flags = DAT_COMPLETION_EVD_THRESHOLD_FLAG;
-       ep_attr->recv_completion_flags = DAT_COMPLETION_EVD_THRESHOLD_FLAG;
-       /*
-        * Unspecified defaults:
-        *    - ep_privileges: No RDMA capabilities
-        *    - num_transport_specific_params: none
-        *    - transport_specific_params: none
-        *    - num_provider_specific_params: 0
-        *    - provider_specific_params: 0
-        */
-
-       dat_status = dapls_ib_query_hca(ep_ptr->header.owner_ia->hca_ptr,
-                                       NULL, &ep_attr_limit, NULL);
-       /* check against HCA maximums */
-       if (dat_status == DAT_SUCCESS) {
-               ep_ptr->param.ep_attr.max_mtu_size =
-                   DAPL_MIN(ep_ptr->param.ep_attr.max_mtu_size,
-                            ep_attr_limit.max_mtu_size);
-               ep_ptr->param.ep_attr.max_rdma_size =
-                   DAPL_MIN(ep_ptr->param.ep_attr.max_rdma_size,
-                            ep_attr_limit.max_rdma_size);
-               ep_ptr->param.ep_attr.max_recv_dtos =
-                   DAPL_MIN(ep_ptr->param.ep_attr.max_recv_dtos,
-                            ep_attr_limit.max_recv_dtos);
-               ep_ptr->param.ep_attr.max_request_dtos =
-                   DAPL_MIN(ep_ptr->param.ep_attr.max_request_dtos,
-                            ep_attr_limit.max_request_dtos);
-               ep_ptr->param.ep_attr.max_recv_iov =
-                   DAPL_MIN(ep_ptr->param.ep_attr.max_recv_iov,
-                            ep_attr_limit.max_recv_iov);
-               ep_ptr->param.ep_attr.max_request_iov =
-                   DAPL_MIN(ep_ptr->param.ep_attr.max_request_iov,
-                            ep_attr_limit.max_request_iov);
-               ep_ptr->param.ep_attr.max_rdma_read_in =
-                   DAPL_MIN(ep_ptr->param.ep_attr.max_rdma_read_in,
-                            ep_attr_limit.max_rdma_read_in);
-               ep_ptr->param.ep_attr.max_rdma_read_out =
-                   DAPL_MIN(ep_ptr->param.ep_attr.max_rdma_read_out,
-                            ep_attr_limit.max_rdma_read_out);
-       }
-}
-
-DAT_RETURN dapl_ep_check_recv_completion_flags(DAT_COMPLETION_FLAGS flags)
-{
-
-       /*
-        * InfiniBand will not allow signal suppression for RECV completions,
-        * see the 1.0.1 spec section 10.7.3.1, 10.8.6.
-        * N.B. SIGNALLED has a different meaning in dapl than it does
-        *      in IB; IB SIGNALLED is the same as DAPL SUPPRESS. DAPL
-        *      SIGNALLED simply means the user will not get awakened when
-        *      an EVD completes, even though the dapl handler is invoked.
-        */
-
-       if (flags & DAT_COMPLETION_SUPPRESS_FLAG) {
-               return DAT_INVALID_PARAMETER;
-       }
-
-       return DAT_SUCCESS;
-}
-
-DAT_RETURN dapl_ep_check_request_completion_flags(DAT_COMPLETION_FLAGS flags)
-{
-       return DAT_SUCCESS;
-}
-
-DAT_RETURN
-dapl_ep_post_send_req(IN DAT_EP_HANDLE ep_handle,
-                     IN DAT_COUNT num_segments,
-                     IN DAT_LMR_TRIPLET * local_iov,
-                     IN DAT_DTO_COOKIE user_cookie,
-                     IN const DAT_RMR_TRIPLET * remote_iov,
-                     IN DAT_COMPLETION_FLAGS completion_flags,
-                     IN DAPL_DTO_TYPE dto_type, IN int op_type)
-{
-       DAPL_EP *ep_ptr;
-       DAPL_COOKIE *cookie;
-       DAT_RETURN dat_status;
-
-       if (DAPL_BAD_HANDLE(ep_handle, DAPL_MAGIC_EP)) {
-               dat_status =
-                   DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP);
-               goto bail;
-       }
-
-       ep_ptr = (DAPL_EP *) ep_handle;
-
-       /*
-        * Synchronization ok since this buffer is only used for send
-        * requests, which aren't allowed to race with each other.
-        */
-       dat_status = dapls_dto_cookie_alloc(&ep_ptr->req_buffer,
-                                           dto_type, user_cookie, &cookie);
-       if (dat_status != DAT_SUCCESS) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " dapl_post_req resource ERR:"
-                        " dtos pending = %d, max_dtos %d, max_cb %d hd %d tl %d\n",
-                        dapls_cb_pending(&ep_ptr->req_buffer),
-                        ep_ptr->param.ep_attr.max_request_dtos,
-                        ep_ptr->req_buffer.pool_size,
-                        ep_ptr->req_buffer.head, ep_ptr->req_buffer.tail);
-
-               goto bail;
-       }
-
-       /*
-        * Invoke provider specific routine to post DTO
-        */
-       dat_status = dapls_ib_post_send(ep_ptr,
-                                       op_type,
-                                       cookie,
-                                       num_segments,
-                                       local_iov,
-                                       remote_iov, completion_flags);
-
-       if (dat_status != DAT_SUCCESS) {
-               dapls_cookie_dealloc(&ep_ptr->req_buffer, cookie);
-       }
-
-      bail:
-       return dat_status;
-}
-
-/*
- * dapli_ep_timeout
- *
- * If this routine is invoked before a connection occurs, generate an
- * event
- */
-void dapls_ep_timeout(uintptr_t arg)
-{
-       DAPL_EP *ep_ptr;
-       ib_cm_events_t ib_cm_event;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM, "--> dapls_ep_timeout! ep %lx\n", arg);
-
-       ep_ptr = (DAPL_EP *) arg;
-
-       /* reset the EP state */
-       ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;
-
-       /* Clean up the EP and put the underlying QP into the ERROR state.
-        * The disconnect_clean interface requires the provided dependent 
-        *cm event number.
-        */
-       ib_cm_event = dapls_ib_get_cm_event(DAT_CONNECTION_EVENT_DISCONNECTED);
-       dapls_ib_disconnect_clean(ep_ptr, DAT_TRUE, ib_cm_event);
-
-       (void)dapls_evd_post_connection_event((DAPL_EVD *) ep_ptr->param.
-                                             connect_evd_handle,
-                                             DAT_CONNECTION_EVENT_TIMED_OUT,
-                                             (DAT_HANDLE) ep_ptr, 0, 0);
-}
-
-/*
- * dapls_ep_state_subtype
- *
- * Return the INVALID_STATE connection subtype associated with an
- * INVALID_STATE on an EP. Strictly for error reporting.
- */
-DAT_RETURN_SUBTYPE dapls_ep_state_subtype(IN DAPL_EP * ep_ptr)
-{
-       DAT_RETURN_SUBTYPE dat_status;
-
-       switch (ep_ptr->param.ep_state) {
-       case DAT_EP_STATE_UNCONNECTED:
-               {
-                       dat_status = DAT_INVALID_STATE_EP_UNCONNECTED;
-                       break;
-               }
-       case DAT_EP_STATE_RESERVED:
-               {
-                       dat_status = DAT_INVALID_STATE_EP_RESERVED;
-                       break;
-               }
-       case DAT_EP_STATE_PASSIVE_CONNECTION_PENDING:
-               {
-                       dat_status = DAT_INVALID_STATE_EP_PASSCONNPENDING;
-                       break;
-               }
-       case DAT_EP_STATE_ACTIVE_CONNECTION_PENDING:
-               {
-                       dat_status = DAT_INVALID_STATE_EP_ACTCONNPENDING;
-                       break;
-               }
-       case DAT_EP_STATE_TENTATIVE_CONNECTION_PENDING:
-               {
-                       dat_status = DAT_INVALID_STATE_EP_TENTCONNPENDING;
-                       break;
-               }
-       case DAT_EP_STATE_CONNECTED:
-               {
-                       dat_status = DAT_INVALID_STATE_EP_CONNECTED;
-                       break;
-               }
-       case DAT_EP_STATE_DISCONNECT_PENDING:
-               {
-                       dat_status = DAT_INVALID_STATE_EP_DISCPENDING;
-                       break;
-               }
-       case DAT_EP_STATE_DISCONNECTED:
-               {
-                       dat_status = DAT_INVALID_STATE_EP_DISCONNECTED;
-                       break;
-               }
-       case DAT_EP_STATE_COMPLETION_PENDING:
-               {
-                       dat_status = DAT_INVALID_STATE_EP_COMPLPENDING;
-                       break;
-               }
-
-       default:
-               {
-                       dat_status = 0;
-                       break;
-               }
-       }
-
-       return dat_status;
-}
-
-#ifdef DAPL_DBG_IO_TRC
-/* allocate trace buffer */
-void dapls_io_trc_alloc(DAPL_EP * ep_ptr)
-{
-       DAT_RETURN dat_status;
-       int i;
-       struct io_buf_track *ibt;
-
-       ep_ptr->ibt_dumped = 0; /* bool to control how often we print */
-       dat_status = dapls_rbuf_alloc(&ep_ptr->ibt_queue, DBG_IO_TRC_QLEN);
-       if (dat_status != DAT_SUCCESS) {
-               goto bail;
-       }
-       ibt =
-           (struct io_buf_track *)dapl_os_alloc(sizeof(struct io_buf_track) *
-                                                DBG_IO_TRC_QLEN);
-
-       if (dat_status != DAT_SUCCESS) {
-               dapls_rbuf_destroy(&ep_ptr->ibt_queue);
-               goto bail;
-       }
-       ep_ptr->ibt_base = ibt;
-       dapl_os_memzero(ibt, sizeof(struct io_buf_track) * DBG_IO_TRC_QLEN);
-
-       /* add events to free event queue */
-       for (i = 0; i < DBG_IO_TRC_QLEN; i++) {
-               dapls_rbuf_add(&ep_ptr->ibt_queue, ibt++);
-       }
-      bail:
-       return;
-}
-#endif                         /* DAPL_DBG_IO_TRC */
-
-/*
- * Generate a disconnect event on abruct close for older verbs providers 
- * that do not do it automatically.
- */
-
-void
-dapl_ep_legacy_post_disconnect(DAPL_EP * ep_ptr,
-                              DAT_CLOSE_FLAGS disconnect_flags)
-{
-       ib_cm_events_t ib_cm_event;
-       DAPL_CR *cr_ptr;
-
-       /*
-        * Acquire the lock and make sure we didn't get a callback
-        * that cleaned up.
-        */
-       dapl_os_lock(&ep_ptr->header.lock);
-       if (disconnect_flags == DAT_CLOSE_ABRUPT_FLAG &&
-           ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECT_PENDING) {
-               /*
-                * If this is an ABRUPT close, the provider will not generate
-                * a disconnect message so we do it manually here. Just invoke
-                * the CM callback as it will clean up the appropriate
-                * data structures, reset the state, and generate the event
-                * on the way out. Obtain the provider dependent cm_event to 
-                * pass into the callback for a disconnect.
-                */
-               ib_cm_event =
-                   dapls_ib_get_cm_event(DAT_CONNECTION_EVENT_DISCONNECTED);
-
-               cr_ptr = ep_ptr->cr_ptr;
-               dapl_os_unlock(&ep_ptr->header.lock);
-
-               if (cr_ptr != NULL) {
-                       dapl_dbg_log(DAPL_DBG_TYPE_API | DAPL_DBG_TYPE_CM,
-                                    "    dapl_ep_disconnect force callback on EP %p CM handle %x\n",
-                                    ep_ptr, cr_ptr->ib_cm_handle);
-
-                       dapls_cr_callback(cr_ptr->ib_cm_handle,
-                                         ib_cm_event, NULL, cr_ptr->sp_ptr);
-               } else {
-                       dapl_evd_connection_callback(ep_ptr->cm_handle,
-                                                    ib_cm_event,
-                                                    NULL, (void *)ep_ptr);
-               }
-       } else {
-               dapl_os_unlock(&ep_ptr->header.lock);
-       }
-}
-
-/*
- * 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_ep_util.c\r
+ *\r
+ * PURPOSE: Manage EP Info structure\r
+ *\r
+ * $Id:$\r
+ **********************************************************************/\r
+\r
+#include "dapl_ep_util.h"\r
+#include "dapl_ring_buffer_util.h"\r
+#include "dapl_cookie.h"\r
+#include "dapl_adapter_util.h"\r
+#include "dapl_evd_util.h"\r
+#include "dapl_cr_util.h"      /* for callback routine */\r
+\r
+/*\r
+ * Local definitions\r
+ */\r
+/*\r
+ * Default number of I/O operations on an end point\r
+ */\r
+#define IB_IO_DEFAULT  16\r
+/*\r
+ * Default number of scatter/gather entries available to a single\r
+ * post send/recv\r
+ */\r
+#define IB_IOV_DEFAULT 4\r
+\r
+/*\r
+ * Default number of RDMA operations in progress at a time\r
+ */\r
+#define IB_RDMA_DEFAULT        4\r
+\r
+extern void dapli_ep_default_attrs(IN DAPL_EP * ep_ptr);\r
+\r
+char *dapl_get_ep_state_str(DAT_EP_STATE state)\r
+{\r
+#ifdef DAPL_DBG\r
+       static char *state_str[DAT_EP_STATE_CONNECTED_MULTI_PATH + 1] = {\r
+               "DAT_EP_STATE_UNCONNECTED",     /* quiescent state */\r
+               "DAT_EP_STATE_UNCONFIGURED_UNCONNECTED",\r
+               "DAT_EP_STATE_RESERVED",\r
+               "DAT_EP_STATE_UNCONFIGURED_RESERVED",\r
+               "DAT_EP_STATE_PASSIVE_CONNECTION_PENDING",\r
+               "DAT_EP_STATE_UNCONFIGURED_PASSIVE",\r
+               "DAT_EP_STATE_ACTIVE_CONNECTION_PENDING",\r
+               "DAT_EP_STATE_TENTATIVE_CONNECTION_PENDING",\r
+               "DAT_EP_STATE_UNCONFIGURED_TENTATIVE",\r
+               "DAT_EP_STATE_CONNECTED",\r
+               "DAT_EP_STATE_DISCONNECT_PENDING",\r
+               "DAT_EP_STATE_DISCONNECTED",\r
+               "DAT_EP_STATE_COMPLETION_PENDING",\r
+               "DAT_EP_STATE_CONNECTED_SINGLE_PATH",\r
+               "DAT_EP_STATE_CONNECTED_MULTI_PATH"\r
+       };\r
+       return state_str[state];\r
+#else\r
+       static char buf[12];\r
+       sprintf(buf, "%d", state);\r
+       return buf;\r
+#endif\r
+}\r
+\r
+/*\r
+ * dapl_ep_alloc\r
+ *\r
+ * alloc and initialize an EP INFO struct\r
+ *\r
+ * Input:\r
+ *     IA INFO struct ptr\r
+ *\r
+ * Output:\r
+ *     ep_ptr\r
+ *\r
+ * Returns:\r
+ *     none\r
+ *\r
+ */\r
+DAPL_EP *dapl_ep_alloc(IN DAPL_IA * ia_ptr, IN const DAT_EP_ATTR * ep_attr)\r
+{\r
+       DAPL_EP *ep_ptr;\r
+\r
+       /* Allocate EP */\r
+       ep_ptr =\r
+           (DAPL_EP *) dapl_os_alloc(sizeof(DAPL_EP) + sizeof(DAT_SOCK_ADDR));\r
+       if (ep_ptr == NULL) {\r
+               goto bail;\r
+       }\r
+\r
+       /* zero the structure */\r
+       dapl_os_memzero(ep_ptr, sizeof(DAPL_EP) + sizeof(DAT_SOCK_ADDR));\r
+\r
+#ifdef DAPL_COUNTERS\r
+       /* Allocate counters */\r
+       ep_ptr->cntrs =\r
+           dapl_os_alloc(sizeof(DAT_UINT64) * DCNT_EP_ALL_COUNTERS);\r
+       if (ep_ptr->cntrs == NULL) {\r
+               dapl_os_free(ep_ptr, sizeof(DAPL_EP) + sizeof(DAT_SOCK_ADDR));\r
+               return (NULL);\r
+       }\r
+       dapl_os_memzero(ep_ptr->cntrs,\r
+                       sizeof(DAT_UINT64) * DCNT_EP_ALL_COUNTERS);\r
+#endif                         /* DAPL_COUNTERS */\r
+\r
+       /*\r
+        * initialize the header\r
+        */\r
+       ep_ptr->header.provider = ia_ptr->header.provider;\r
+       ep_ptr->header.magic = DAPL_MAGIC_EP;\r
+       ep_ptr->header.handle_type = DAT_HANDLE_TYPE_EP;\r
+       ep_ptr->header.owner_ia = ia_ptr;\r
+       ep_ptr->header.user_context.as_64 = 0;\r
+       ep_ptr->header.user_context.as_ptr = NULL;\r
+\r
+       dapl_llist_init_entry(&ep_ptr->header.ia_list_entry);\r
+       dapl_os_lock_init(&ep_ptr->header.lock);\r
+\r
+       /*\r
+        * Initialize the body\r
+        */\r
+       /*\r
+        * Set up default parameters if the user passed in a NULL\r
+        */\r
+       if (ep_attr == NULL) {\r
+               dapli_ep_default_attrs(ep_ptr);\r
+       } else {\r
+               ep_ptr->param.ep_attr = *ep_attr;\r
+       }\r
+\r
+       /*\r
+        * IBM OS API specific fields\r
+        */\r
+       ep_ptr->qp_handle = IB_INVALID_HANDLE;\r
+       ep_ptr->qpn = 0;\r
+       ep_ptr->qp_state = DAPL_QP_STATE_UNATTACHED;\r
+       ep_ptr->cm_handle = IB_INVALID_HANDLE;\r
+\r
+       if (DAT_SUCCESS != dapls_cb_create(&ep_ptr->req_buffer,\r
+                                          ep_ptr,\r
+                                          ep_ptr->param.ep_attr.\r
+                                          max_request_dtos)) {\r
+               dapl_ep_dealloc(ep_ptr);\r
+               ep_ptr = NULL;\r
+               goto bail;\r
+       }\r
+\r
+       if (DAT_SUCCESS != dapls_cb_create(&ep_ptr->recv_buffer,\r
+                                          ep_ptr,\r
+                                          ep_ptr->param.ep_attr.max_recv_dtos))\r
+       {\r
+               dapl_ep_dealloc(ep_ptr);\r
+               ep_ptr = NULL;\r
+               goto bail;\r
+       }\r
+\r
+       dapls_io_trc_alloc(ep_ptr);\r
+\r
+      bail:\r
+       return ep_ptr;\r
+}\r
+\r
+/*\r
+ * dapl_ep_dealloc\r
+ *\r
+ * Free the passed in EP structure.\r
+ *\r
+ * Input:\r
+ *     entry point pointer\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     none\r
+ *\r
+ */\r
+void dapl_ep_dealloc(IN DAPL_EP * ep_ptr)\r
+{\r
+       dapl_os_assert(ep_ptr->header.magic == DAPL_MAGIC_EP);\r
+\r
+       ep_ptr->header.magic = DAPL_MAGIC_INVALID;      /* reset magic to prevent reuse */\r
+\r
+       dapls_cb_free(&ep_ptr->req_buffer);\r
+       dapls_cb_free(&ep_ptr->recv_buffer);\r
+\r
+       if (NULL != ep_ptr->cxn_timer) {\r
+               dapl_os_free(ep_ptr->cxn_timer, sizeof(DAPL_OS_TIMER));\r
+       }\r
+#if defined(_WIN32) || defined(_WIN64)\r
+       if (ep_ptr->ibal_cm_handle) {\r
+               dapl_os_free(ep_ptr->ibal_cm_handle,\r
+                            sizeof(*ep_ptr->ibal_cm_handle));\r
+               ep_ptr->ibal_cm_handle = NULL;\r
+       }\r
+#endif\r
+\r
+#ifdef DAPL_COUNTERS\r
+       dapl_os_free(ep_ptr->cntrs, sizeof(DAT_UINT64) * DCNT_EP_ALL_COUNTERS);\r
+#endif                         /* DAPL_COUNTERS */\r
+\r
+       dapl_os_free(ep_ptr, sizeof(DAPL_EP) + sizeof(DAT_SOCK_ADDR));\r
+}\r
+\r
+/*\r
+ * dapl_ep_default_attrs\r
+ *\r
+ * Set default values in the parameter fields\r
+ *\r
+ * Input:\r
+ *     entry point pointer\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     none\r
+ *\r
+ */\r
+void dapli_ep_default_attrs(IN DAPL_EP * ep_ptr)\r
+{\r
+       DAT_EP_ATTR ep_attr_limit;\r
+       DAT_EP_ATTR *ep_attr;\r
+       DAT_RETURN dat_status;\r
+\r
+       ep_attr = &ep_ptr->param.ep_attr;\r
+       /* Set up defaults */\r
+       dapl_os_memzero(ep_attr, sizeof(DAT_EP_ATTR));\r
+\r
+       /* mtu and rdma sizes fixed in IB as per IBTA 1.1, 9.4.3, 9.4.4, 9.7.7.  */\r
+       ep_attr->max_mtu_size = 0x80000000;\r
+       ep_attr->max_rdma_size = 0x80000000;\r
+\r
+       ep_attr->qos = DAT_QOS_BEST_EFFORT;\r
+       ep_attr->service_type = DAT_SERVICE_TYPE_RC;\r
+       ep_attr->max_recv_dtos = IB_IO_DEFAULT;\r
+       ep_attr->max_request_dtos = IB_IO_DEFAULT;\r
+       ep_attr->max_recv_iov = IB_IOV_DEFAULT;\r
+       ep_attr->max_request_iov = IB_IOV_DEFAULT;\r
+       ep_attr->max_rdma_read_in = IB_RDMA_DEFAULT;\r
+       ep_attr->max_rdma_read_out = IB_RDMA_DEFAULT;\r
+\r
+       /*\r
+        * Configure the EP as a standard completion type, which will be\r
+        * used by the EVDs. A threshold of 1 is the default state of an\r
+        * EVD.\r
+        */\r
+       ep_attr->request_completion_flags = DAT_COMPLETION_EVD_THRESHOLD_FLAG;\r
+       ep_attr->recv_completion_flags = DAT_COMPLETION_EVD_THRESHOLD_FLAG;\r
+       /*\r
+        * Unspecified defaults:\r
+        *    - ep_privileges: No RDMA capabilities\r
+        *    - num_transport_specific_params: none\r
+        *    - transport_specific_params: none\r
+        *    - num_provider_specific_params: 0\r
+        *    - provider_specific_params: 0\r
+        */\r
+\r
+       dat_status = dapls_ib_query_hca(ep_ptr->header.owner_ia->hca_ptr,\r
+                                       NULL, &ep_attr_limit, NULL);\r
+       /* check against HCA maximums */\r
+       if (dat_status == DAT_SUCCESS) {\r
+               ep_ptr->param.ep_attr.max_mtu_size =\r
+                   DAPL_MIN(ep_ptr->param.ep_attr.max_mtu_size,\r
+                            ep_attr_limit.max_mtu_size);\r
+               ep_ptr->param.ep_attr.max_rdma_size =\r
+                   DAPL_MIN(ep_ptr->param.ep_attr.max_rdma_size,\r
+                            ep_attr_limit.max_rdma_size);\r
+               ep_ptr->param.ep_attr.max_recv_dtos =\r
+                   DAPL_MIN(ep_ptr->param.ep_attr.max_recv_dtos,\r
+                            ep_attr_limit.max_recv_dtos);\r
+               ep_ptr->param.ep_attr.max_request_dtos =\r
+                   DAPL_MIN(ep_ptr->param.ep_attr.max_request_dtos,\r
+                            ep_attr_limit.max_request_dtos);\r
+               ep_ptr->param.ep_attr.max_recv_iov =\r
+                   DAPL_MIN(ep_ptr->param.ep_attr.max_recv_iov,\r
+                            ep_attr_limit.max_recv_iov);\r
+               ep_ptr->param.ep_attr.max_request_iov =\r
+                   DAPL_MIN(ep_ptr->param.ep_attr.max_request_iov,\r
+                            ep_attr_limit.max_request_iov);\r
+               ep_ptr->param.ep_attr.max_rdma_read_in =\r
+                   DAPL_MIN(ep_ptr->param.ep_attr.max_rdma_read_in,\r
+                            ep_attr_limit.max_rdma_read_in);\r
+               ep_ptr->param.ep_attr.max_rdma_read_out =\r
+                   DAPL_MIN(ep_ptr->param.ep_attr.max_rdma_read_out,\r
+                            ep_attr_limit.max_rdma_read_out);\r
+       }\r
+}\r
+\r
+DAT_RETURN dapl_ep_check_recv_completion_flags(DAT_COMPLETION_FLAGS flags)\r
+{\r
+\r
+       /*\r
+        * InfiniBand will not allow signal suppression for RECV completions,\r
+        * see the 1.0.1 spec section 10.7.3.1, 10.8.6.\r
+        * N.B. SIGNALLED has a different meaning in dapl than it does\r
+        *      in IB; IB SIGNALLED is the same as DAPL SUPPRESS. DAPL\r
+        *      SIGNALLED simply means the user will not get awakened when\r
+        *      an EVD completes, even though the dapl handler is invoked.\r
+        */\r
+\r
+       if (flags & DAT_COMPLETION_SUPPRESS_FLAG) {\r
+               return DAT_INVALID_PARAMETER;\r
+       }\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+DAT_RETURN dapl_ep_check_request_completion_flags(DAT_COMPLETION_FLAGS flags)\r
+{\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+DAT_RETURN\r
+dapl_ep_post_send_req(IN DAT_EP_HANDLE ep_handle,\r
+                     IN DAT_COUNT num_segments,\r
+                     IN DAT_LMR_TRIPLET * local_iov,\r
+                     IN DAT_DTO_COOKIE user_cookie,\r
+                     IN const DAT_RMR_TRIPLET * remote_iov,\r
+                     IN DAT_COMPLETION_FLAGS completion_flags,\r
+                     IN DAPL_DTO_TYPE dto_type, IN int op_type)\r
+{\r
+       DAPL_EP *ep_ptr;\r
+       DAPL_COOKIE *cookie;\r
+       DAT_RETURN dat_status;\r
+\r
+       if (DAPL_BAD_HANDLE(ep_handle, DAPL_MAGIC_EP)) {\r
+               dat_status =\r
+                   DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP);\r
+               goto bail;\r
+       }\r
+\r
+       ep_ptr = (DAPL_EP *) ep_handle;\r
+\r
+       /*\r
+        * Synchronization ok since this buffer is only used for send\r
+        * requests, which aren't allowed to race with each other.\r
+        */\r
+       dat_status = dapls_dto_cookie_alloc(&ep_ptr->req_buffer,\r
+                                           dto_type, user_cookie, &cookie);\r
+       if (dat_status != DAT_SUCCESS) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " dapl_post_req resource ERR:"\r
+                        " dtos pending = %d, max_dtos %d, max_cb %d hd %d tl %d\n",\r
+                        dapls_cb_pending(&ep_ptr->req_buffer),\r
+                        ep_ptr->param.ep_attr.max_request_dtos,\r
+                        ep_ptr->req_buffer.pool_size,\r
+                        ep_ptr->req_buffer.head, ep_ptr->req_buffer.tail);\r
+\r
+               goto bail;\r
+       }\r
+\r
+       /*\r
+        * Invoke provider specific routine to post DTO\r
+        */\r
+       dat_status = dapls_ib_post_send(ep_ptr,\r
+                                       op_type,\r
+                                       cookie,\r
+                                       num_segments,\r
+                                       local_iov,\r
+                                       remote_iov, completion_flags);\r
+\r
+       if (dat_status != DAT_SUCCESS) {\r
+               dapls_cookie_dealloc(&ep_ptr->req_buffer, cookie);\r
+       }\r
+\r
+      bail:\r
+       return dat_status;\r
+}\r
+\r
+/*\r
+ * dapli_ep_timeout\r
+ *\r
+ * If this routine is invoked before a connection occurs, generate an\r
+ * event\r
+ */\r
+void dapls_ep_timeout(uintptr_t arg)\r
+{\r
+       DAPL_EP *ep_ptr;\r
+       ib_cm_events_t ib_cm_event;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM, "--> dapls_ep_timeout! ep %lx\n", arg);\r
+\r
+       ep_ptr = (DAPL_EP *) arg;\r
+\r
+       /* reset the EP state */\r
+       ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;\r
+\r
+       /* Clean up the EP and put the underlying QP into the ERROR state.\r
+        * The disconnect_clean interface requires the provided dependent \r
+        *cm event number.\r
+        */\r
+       ib_cm_event = dapls_ib_get_cm_event(DAT_CONNECTION_EVENT_DISCONNECTED);\r
+       dapls_ib_disconnect_clean(ep_ptr, DAT_TRUE, ib_cm_event);\r
+\r
+       (void)dapls_evd_post_connection_event((DAPL_EVD *) ep_ptr->param.\r
+                                             connect_evd_handle,\r
+                                             DAT_CONNECTION_EVENT_TIMED_OUT,\r
+                                             (DAT_HANDLE) ep_ptr, 0, 0);\r
+}\r
+\r
+/*\r
+ * dapls_ep_state_subtype\r
+ *\r
+ * Return the INVALID_STATE connection subtype associated with an\r
+ * INVALID_STATE on an EP. Strictly for error reporting.\r
+ */\r
+DAT_RETURN_SUBTYPE dapls_ep_state_subtype(IN DAPL_EP * ep_ptr)\r
+{\r
+       DAT_RETURN_SUBTYPE dat_status;\r
+\r
+       switch (ep_ptr->param.ep_state) {\r
+       case DAT_EP_STATE_UNCONNECTED:\r
+               {\r
+                       dat_status = DAT_INVALID_STATE_EP_UNCONNECTED;\r
+                       break;\r
+               }\r
+       case DAT_EP_STATE_RESERVED:\r
+               {\r
+                       dat_status = DAT_INVALID_STATE_EP_RESERVED;\r
+                       break;\r
+               }\r
+       case DAT_EP_STATE_PASSIVE_CONNECTION_PENDING:\r
+               {\r
+                       dat_status = DAT_INVALID_STATE_EP_PASSCONNPENDING;\r
+                       break;\r
+               }\r
+       case DAT_EP_STATE_ACTIVE_CONNECTION_PENDING:\r
+               {\r
+                       dat_status = DAT_INVALID_STATE_EP_ACTCONNPENDING;\r
+                       break;\r
+               }\r
+       case DAT_EP_STATE_TENTATIVE_CONNECTION_PENDING:\r
+               {\r
+                       dat_status = DAT_INVALID_STATE_EP_TENTCONNPENDING;\r
+                       break;\r
+               }\r
+       case DAT_EP_STATE_CONNECTED:\r
+               {\r
+                       dat_status = DAT_INVALID_STATE_EP_CONNECTED;\r
+                       break;\r
+               }\r
+       case DAT_EP_STATE_DISCONNECT_PENDING:\r
+               {\r
+                       dat_status = DAT_INVALID_STATE_EP_DISCPENDING;\r
+                       break;\r
+               }\r
+       case DAT_EP_STATE_DISCONNECTED:\r
+               {\r
+                       dat_status = DAT_INVALID_STATE_EP_DISCONNECTED;\r
+                       break;\r
+               }\r
+       case DAT_EP_STATE_COMPLETION_PENDING:\r
+               {\r
+                       dat_status = DAT_INVALID_STATE_EP_COMPLPENDING;\r
+                       break;\r
+               }\r
+\r
+       default:\r
+               {\r
+                       dat_status = 0;\r
+                       break;\r
+               }\r
+       }\r
+\r
+       return dat_status;\r
+}\r
+\r
+#ifdef DAPL_DBG_IO_TRC\r
+/* allocate trace buffer */\r
+void dapls_io_trc_alloc(DAPL_EP * ep_ptr)\r
+{\r
+       DAT_RETURN dat_status;\r
+       int i;\r
+       struct io_buf_track *ibt;\r
+\r
+       ep_ptr->ibt_dumped = 0; /* bool to control how often we print */\r
+       dat_status = dapls_rbuf_alloc(&ep_ptr->ibt_queue, DBG_IO_TRC_QLEN);\r
+       if (dat_status != DAT_SUCCESS) {\r
+               goto bail;\r
+       }\r
+       ibt =\r
+           (struct io_buf_track *)dapl_os_alloc(sizeof(struct io_buf_track) *\r
+                                                DBG_IO_TRC_QLEN);\r
+\r
+       if (dat_status != DAT_SUCCESS) {\r
+               dapls_rbuf_destroy(&ep_ptr->ibt_queue);\r
+               goto bail;\r
+       }\r
+       ep_ptr->ibt_base = ibt;\r
+       dapl_os_memzero(ibt, sizeof(struct io_buf_track) * DBG_IO_TRC_QLEN);\r
+\r
+       /* add events to free event queue */\r
+       for (i = 0; i < DBG_IO_TRC_QLEN; i++) {\r
+               dapls_rbuf_add(&ep_ptr->ibt_queue, ibt++);\r
+       }\r
+      bail:\r
+       return;\r
+}\r
+#endif                         /* DAPL_DBG_IO_TRC */\r
+\r
+/*\r
+ * Generate a disconnect event on abruct close for older verbs providers \r
+ * that do not do it automatically.\r
+ */\r
+\r
+void\r
+dapl_ep_legacy_post_disconnect(DAPL_EP * ep_ptr,\r
+                              DAT_CLOSE_FLAGS disconnect_flags)\r
+{\r
+       ib_cm_events_t ib_cm_event;\r
+       DAPL_CR *cr_ptr;\r
+\r
+       /*\r
+        * Acquire the lock and make sure we didn't get a callback\r
+        * that cleaned up.\r
+        */\r
+       dapl_os_lock(&ep_ptr->header.lock);\r
+       if (disconnect_flags == DAT_CLOSE_ABRUPT_FLAG &&\r
+           ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECT_PENDING) {\r
+               /*\r
+                * If this is an ABRUPT close, the provider will not generate\r
+                * a disconnect message so we do it manually here. Just invoke\r
+                * the CM callback as it will clean up the appropriate\r
+                * data structures, reset the state, and generate the event\r
+                * on the way out. Obtain the provider dependent cm_event to \r
+                * pass into the callback for a disconnect.\r
+                */\r
+               ib_cm_event =\r
+                   dapls_ib_get_cm_event(DAT_CONNECTION_EVENT_DISCONNECTED);\r
+\r
+               cr_ptr = ep_ptr->cr_ptr;\r
+               dapl_os_unlock(&ep_ptr->header.lock);\r
+\r
+               if (cr_ptr != NULL) {\r
+                       dapl_dbg_log(DAPL_DBG_TYPE_API | DAPL_DBG_TYPE_CM,\r
+                                    "    dapl_ep_disconnect force callback on EP %p CM handle %x\n",\r
+                                    ep_ptr, cr_ptr->ib_cm_handle);\r
+\r
+                       dapls_cr_callback(cr_ptr->ib_cm_handle,\r
+                                         ib_cm_event, NULL, 0, cr_ptr->sp_ptr);\r
+               } else {\r
+                       dapl_evd_connection_callback(ep_ptr->cm_handle,\r
+                                                    ib_cm_event,\r
+                                                    NULL, 0, (void *)ep_ptr);\r
+               }\r
+       } else {\r
+               dapl_os_unlock(&ep_ptr->header.lock);\r
+       }\r
+}\r
+\r
+/*\r
+ * Local variables:\r
+ *  c-indent-level: 4\r
+ *  c-basic-offset: 4\r
+ *  tab-width: 8\r
+ * End:\r
+ */\r
index e2fb93b..841b28d 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_connection_callback.c
- *
- * PURPOSE: implements connection callbacks
- *
- * Description: Accepts asynchronous callbacks from the Communications Manager
- *              for EVDs that have been specified as the connection_evd.
- *
- * $Id:$
- **********************************************************************/
-
-#include "dapl.h"
-#include "dapl_evd_util.h"
-#include "dapl_ep_util.h"
-#include "dapl_timer_util.h"
-
-/*
- * dapl_evd_connection_callback
- *
- * Connection callback function for ACTIVE connection requests; callbacks
- * generated by the Connection Manager in response to issuing a
- * connect call.
- *
- * Input:
- *     ib_cm_handle,
- *     ib_cm_event
- *     private_data_ptr
- *     context (evd)
- *     cr_pp
- *
- * Output:
- *     None
- *
- */
-
-void
-dapl_evd_connection_callback(IN dp_ib_cm_handle_t ib_cm_handle,
-                            IN const ib_cm_events_t ib_cm_event,
-                            IN const void *private_data_ptr,
-                            IN const void *context)
-{
-       DAPL_EP *ep_ptr;
-       DAPL_EVD *evd_ptr;
-       DAPL_PRIVATE *prd_ptr;
-       DAT_EVENT_NUMBER dat_event_num;
-       DAT_RETURN dat_status;
-       int private_data_size;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK,
-                    "--> dapl_evd_connection_callback: ctxt: %p event: %x cm_handle %p\n",
-                    context, ib_cm_event, (void *)ib_cm_handle);
-
-       /*
-        * Determine the type of handle passed back to us in the context
-        * and sort out key parameters.
-        */
-       if (context == NULL
-           || ((DAPL_HEADER *) context)->magic != DAPL_MAGIC_EP) {
-               return;
-       }
-
-       /*
-        * Active side of the connection, context is an EP and
-        * PSP is irrelevant.
-        */
-       ep_ptr = (DAPL_EP *) context;
-       evd_ptr = (DAPL_EVD *) ep_ptr->param.connect_evd_handle;
-       DAPL_CNTR(evd_ptr, DCNT_EVD_CONN_CALLBACK);
-
-       prd_ptr = (DAPL_PRIVATE *) private_data_ptr;
-       private_data_size = 0;
-       /*
-        * All operations effect the EP, so lock it once and unlock
-        * when necessary
-        */
-       dapl_os_lock(&ep_ptr->header.lock);
-
-       /*
-        * If a connection timer has been set up on this EP, cancel it now
-        */
-       if (ep_ptr->cxn_timer != NULL) {
-               dapls_timer_cancel(ep_ptr->cxn_timer);
-               dapl_os_free(ep_ptr->cxn_timer, sizeof(DAPL_OS_TIMER));
-               ep_ptr->cxn_timer = NULL;
-       }
-
-       /* Obtain the event number from the provider layer */
-       dat_event_num = dapls_ib_get_dat_event(ib_cm_event, DAT_FALSE);
-
-       switch (dat_event_num) {
-       case DAT_CONNECTION_EVENT_ESTABLISHED:
-               {
-                       /* If we don't have an EP at this point we are very screwed
-                        * up
-                        */
-                       if (ep_ptr->param.ep_state !=
-                           DAT_EP_STATE_ACTIVE_CONNECTION_PENDING) {
-                               /* If someone pulled the plug on the connection, just
-                                * exit
-                                */
-                               dapl_os_unlock(&ep_ptr->header.lock);
-                               dat_status = DAT_SUCCESS;
-                               break;
-                       }
-                       ep_ptr->param.ep_state = DAT_EP_STATE_CONNECTED;
-                       ep_ptr->cm_handle = ib_cm_handle;
-                       if (prd_ptr == NULL) {
-                               private_data_size = 0;
-                       } else {
-                               private_data_size =
-                                   dapls_ib_private_data_size(prd_ptr,
-                                                              DAPL_PDATA_CONN_REP,
-                                                              ep_ptr->header.
-                                                              owner_ia->
-                                                              hca_ptr);
-                       }
-
-                       if (private_data_size > 0) {
-                               /* copy in the private data */
-                               dapl_os_memcpy(ep_ptr->private.private_data,
-                                              prd_ptr->private_data,
-                                              DAPL_MIN(private_data_size,
-                                                       DAPL_MAX_PRIVATE_DATA_SIZE));
-                       }
-                       dapl_os_unlock(&ep_ptr->header.lock);
-
-                       break;
-               }
-       case DAT_CONNECTION_EVENT_PEER_REJECTED:
-               {
-                       /* peer reject may include private data */
-                       if (prd_ptr != NULL)
-                               private_data_size =
-                                   dapls_ib_private_data_size(prd_ptr,
-                                                              DAPL_PDATA_CONN_REJ,
-                                                              ep_ptr->header.
-                                                              owner_ia->
-                                                              hca_ptr);
-
-                       if (private_data_size > 0)
-                               dapl_os_memcpy(ep_ptr->private.private_data,
-                                              prd_ptr->private_data,
-                                              DAPL_MIN(private_data_size,
-                                                       DAPL_MAX_PRIVATE_DATA_SIZE));
-
-                       dapl_dbg_log(DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK,
-                                    "dapl_evd_connection_callback PEER REJ pd=%p sz=%d\n",
-                                    prd_ptr, private_data_size);
-               }
-       case DAT_CONNECTION_EVENT_DISCONNECTED:
-       case DAT_CONNECTION_EVENT_UNREACHABLE:
-       case DAT_CONNECTION_EVENT_NON_PEER_REJECTED:
-               {
-                       ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;
-                       dapls_ib_disconnect_clean(ep_ptr, DAT_TRUE,
-                                                 ib_cm_event);
-                       dapl_os_unlock(&ep_ptr->header.lock);
-
-                       break;
-               }
-       case DAT_CONNECTION_EVENT_BROKEN:
-       case DAT_CONNECTION_EVENT_TIMED_OUT:
-               {
-                       ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;
-                       dapls_ib_disconnect_clean(ep_ptr, DAT_FALSE,
-                                                 ib_cm_event);
-                       dapl_os_unlock(&ep_ptr->header.lock);
-
-                       break;
-               }
-       case DAT_CONNECTION_REQUEST_EVENT:
-       default:
-               {
-                       dapl_os_unlock(&ep_ptr->header.lock);
-                       evd_ptr = NULL;
-
-                       dapl_os_assert(0);      /* shouldn't happen */
-                       break;
-               }
-       }
-
-       /*
-        * Post the event
-        * If the EP has been freed, the evd_ptr will be NULL
-        */
-       if (evd_ptr != NULL) {
-               dat_status = dapls_evd_post_connection_event(evd_ptr, dat_event_num, (DAT_HANDLE) ep_ptr, private_data_size,    /* CONNECTED or REJECT */
-                                                            ep_ptr->private.
-                                                            private_data);
-
-               if (dat_status != DAT_SUCCESS &&
-                   dat_event_num == DAT_CONNECTION_EVENT_ESTABLISHED) {
-                       /* We can't tell the user we are connected, something
-                        * is wrong locally. Just kill the connection and
-                        * reset the state to DISCONNECTED as we don't
-                        * expect a callback on an ABRUPT disconnect.
-                        */
-                       dapls_ib_disconnect(ep_ptr, DAT_CLOSE_ABRUPT_FLAG);
-                       dapl_os_lock(&ep_ptr->header.lock);
-                       ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;
-                       dapl_os_unlock(&ep_ptr->header.lock);
-               }
-       }
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK,
-                    "dapl_evd_connection_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_connection_callback.c\r
+ *\r
+ * PURPOSE: implements connection callbacks\r
+ *\r
+ * Description: Accepts asynchronous callbacks from the Communications Manager\r
+ *              for EVDs that have been specified as the connection_evd.\r
+ *\r
+ * $Id:$\r
+ **********************************************************************/\r
+\r
+#include "dapl.h"\r
+#include "dapl_evd_util.h"\r
+#include "dapl_ep_util.h"\r
+#include "dapl_timer_util.h"\r
+\r
+/*\r
+ * dapl_evd_connection_callback\r
+ *\r
+ * Connection callback function for ACTIVE connection requests; callbacks\r
+ * generated by the Connection Manager in response to issuing a\r
+ * connect call.\r
+ *\r
+ * Input:\r
+ *     ib_cm_handle,\r
+ *     ib_cm_event\r
+ *     private_data_ptr\r
+ *     context (evd)\r
+ *     cr_pp\r
+ *\r
+ * Output:\r
+ *     None\r
+ *\r
+ */\r
+\r
+void\r
+dapl_evd_connection_callback(IN dp_ib_cm_handle_t ib_cm_handle,\r
+                            IN const ib_cm_events_t ib_cm_event,\r
+                            IN const void *private_data_ptr,\r
+                            IN const int private_data_size,\r
+                            IN const void *context)\r
+{\r
+       DAPL_EP *ep_ptr;\r
+       DAPL_EVD *evd_ptr;\r
+       DAPL_PRIVATE *prd_ptr;\r
+       DAT_EVENT_NUMBER dat_event_num;\r
+       DAT_RETURN dat_status;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK,\r
+                    "--> dapl_evd_connection_callback: ctxt: %p event: %x cm_handle %p\n",\r
+                    context, ib_cm_event, (void *)ib_cm_handle);\r
+\r
+       /*\r
+        * Determine the type of handle passed back to us in the context\r
+        * and sort out key parameters.\r
+        */\r
+       if (context == NULL\r
+           || ((DAPL_HEADER *) context)->magic != DAPL_MAGIC_EP) {\r
+               return;\r
+       }\r
+\r
+       /*\r
+        * Active side of the connection, context is an EP and\r
+        * PSP is irrelevant.\r
+        */\r
+       ep_ptr = (DAPL_EP *) context;\r
+       evd_ptr = (DAPL_EVD *) ep_ptr->param.connect_evd_handle;\r
+       DAPL_CNTR(evd_ptr, DCNT_EVD_CONN_CALLBACK);\r
+\r
+       prd_ptr = (DAPL_PRIVATE *) private_data_ptr;\r
+       /*\r
+        * All operations effect the EP, so lock it once and unlock\r
+        * when necessary\r
+        */\r
+       dapl_os_lock(&ep_ptr->header.lock);\r
+\r
+       /*\r
+        * If a connection timer has been set up on this EP, cancel it now\r
+        */\r
+       if (ep_ptr->cxn_timer != NULL) {\r
+               dapls_timer_cancel(ep_ptr->cxn_timer);\r
+               dapl_os_free(ep_ptr->cxn_timer, sizeof(DAPL_OS_TIMER));\r
+               ep_ptr->cxn_timer = NULL;\r
+       }\r
+\r
+       /* Obtain the event number from the provider layer */\r
+       dat_event_num = dapls_ib_get_dat_event(ib_cm_event, DAT_FALSE);\r
+\r
+       switch (dat_event_num) {\r
+       case DAT_CONNECTION_EVENT_ESTABLISHED:\r
+               {\r
+                       /* If we don't have an EP at this point we are very screwed\r
+                        * up\r
+                        */\r
+                       if (ep_ptr->param.ep_state !=\r
+                           DAT_EP_STATE_ACTIVE_CONNECTION_PENDING) {\r
+                               /* If someone pulled the plug on the connection, just\r
+                                * exit\r
+                                */\r
+                               dapl_os_unlock(&ep_ptr->header.lock);\r
+                               dat_status = DAT_SUCCESS;\r
+                               break;\r
+                       }\r
+                       ep_ptr->param.ep_state = DAT_EP_STATE_CONNECTED;\r
+                       ep_ptr->cm_handle = ib_cm_handle;\r
+\r
+                       if (private_data_size > 0) {\r
+                               /* copy in the private data */\r
+                               dapl_os_memcpy(ep_ptr->private.private_data,\r
+                                              prd_ptr->private_data,\r
+                                              DAPL_MIN(private_data_size,\r
+                                                       DAPL_MAX_PRIVATE_DATA_SIZE));\r
+                       }\r
+                       dapl_os_unlock(&ep_ptr->header.lock);\r
+\r
+                       break;\r
+               }\r
+       case DAT_CONNECTION_EVENT_PEER_REJECTED:\r
+               {\r
+                       /* peer reject may include private data */\r
+\r
+                       if (private_data_size > 0)\r
+                               dapl_os_memcpy(ep_ptr->private.private_data,\r
+                                              prd_ptr->private_data,\r
+                                              DAPL_MIN(private_data_size,\r
+                                                       DAPL_MAX_PRIVATE_DATA_SIZE));\r
+\r
+                       dapl_dbg_log(DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK,\r
+                                    "dapl_evd_connection_callback PEER REJ pd=%p sz=%d\n",\r
+                                    prd_ptr, private_data_size);\r
+               }\r
+       case DAT_CONNECTION_EVENT_DISCONNECTED:\r
+       case DAT_CONNECTION_EVENT_UNREACHABLE:\r
+       case DAT_CONNECTION_EVENT_NON_PEER_REJECTED:\r
+               {\r
+                       ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;\r
+                       dapls_ib_disconnect_clean(ep_ptr, DAT_TRUE,\r
+                                                 ib_cm_event);\r
+                       dapl_os_unlock(&ep_ptr->header.lock);\r
+\r
+                       break;\r
+               }\r
+       case DAT_CONNECTION_EVENT_BROKEN:\r
+       case DAT_CONNECTION_EVENT_TIMED_OUT:\r
+               {\r
+                       ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;\r
+                       dapls_ib_disconnect_clean(ep_ptr, DAT_FALSE,\r
+                                                 ib_cm_event);\r
+                       dapl_os_unlock(&ep_ptr->header.lock);\r
+\r
+                       break;\r
+               }\r
+       case DAT_CONNECTION_REQUEST_EVENT:\r
+       default:\r
+               {\r
+                       dapl_os_unlock(&ep_ptr->header.lock);\r
+                       evd_ptr = NULL;\r
+\r
+                       dapl_os_assert(0);      /* shouldn't happen */\r
+                       break;\r
+               }\r
+       }\r
+\r
+       /*\r
+        * Post the event\r
+        * If the EP has been freed, the evd_ptr will be NULL\r
+        */\r
+       if (evd_ptr != NULL) {\r
+               dat_status = dapls_evd_post_connection_event(evd_ptr, dat_event_num, (DAT_HANDLE) ep_ptr, private_data_size,    /* CONNECTED or REJECT */\r
+                                                            ep_ptr->private.\r
+                                                            private_data);\r
+\r
+               if (dat_status != DAT_SUCCESS &&\r
+                   dat_event_num == DAT_CONNECTION_EVENT_ESTABLISHED) {\r
+                       /* We can't tell the user we are connected, something\r
+                        * is wrong locally. Just kill the connection and\r
+                        * reset the state to DISCONNECTED as we don't\r
+                        * expect a callback on an ABRUPT disconnect.\r
+                        */\r
+                       dapls_ib_disconnect(ep_ptr, DAT_CLOSE_ABRUPT_FLAG);\r
+                       dapl_os_lock(&ep_ptr->header.lock);\r
+                       ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;\r
+                       dapl_os_unlock(&ep_ptr->header.lock);\r
+               }\r
+       }\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK,\r
+                    "dapl_evd_connection_callback () returns\n");\r
+\r
+}\r
+\r
+/*\r
+ * Local variables:\r
+ *  c-indent-level: 4\r
+ *  c-basic-offset: 4\r
+ *  tab-width: 8\r
+ * End:\r
+ */\r
index 2304435..78a75a9 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.
- */
-
-/**********************************************************************
- * 
- * HEADER: dapl_evd_util.h
- *
- * PURPOSE: Utility defs & routines for the EVD data structure
- *
- * $Id:$
- *
- **********************************************************************/
-
-#ifndef _DAPL_EVD_UTIL_H_
-#define _DAPL_EVD_UTIL_H_
-
-#include "dapl.h"
-
-DAT_RETURN
-dapls_evd_internal_create (
-    IN DAPL_IA         *ia_ptr, 
-    IN DAPL_CNO                *cno_ptr,
-    IN DAT_COUNT       min_qlen,
-    IN DAT_EVD_FLAGS   evd_flags,
-    OUT DAPL_EVD       **evd_ptr_ptr) ;
-
-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) ;
-
-DAT_RETURN
-dapls_evd_dealloc ( 
-    IN DAPL_EVD        *evd_ptr) ;
-
-DAT_RETURN dapls_evd_event_realloc (
-    IN DAPL_EVD                *evd_ptr,
-    IN DAT_COUNT       qlen);
-
-/*
- * Each of these functions will retrieve a free event from
- * the specified EVD, fill in the elements of that event, and
- * post the event back to the EVD.  If there is no EVD available,
- * an overflow event will be posted to the async EVD associated
- * with the EVD.
- *
- * DAT_INSUFFICIENT_RESOURCES will be returned on overflow,
- * DAT_SUCCESS otherwise.
- */
-
-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_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_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_RETURN
-dapls_evd_post_software_event (
-    IN DAPL_EVD                                *evd_ptr,
-    IN DAT_EVENT_NUMBER                        event_number,
-    IN DAT_PVOID                       pointer);
-
-DAT_RETURN
-dapls_evd_post_generic_event (
-    IN DAPL_EVD                                *evd_ptr,
-    IN DAT_EVENT_NUMBER                        event_number,
-    IN DAT_EVENT_DATA                  *data);
-
-#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);
-
-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);
-#endif
-
-/*************************************
- * dapl internal callbacks functions *
- *************************************/
-
-/* connection verb callback */
-extern void dapl_evd_connection_callback (
-    IN dp_ib_cm_handle_t       ib_cm_handle,
-    IN const ib_cm_events_t    ib_cm_events,
-    IN const void              *instant_data_p,
-    IN const void *            context );
-
-/* dto verb callback */
-extern void dapl_evd_dto_callback (
-    IN  ib_hca_handle_t        ib_hca_handle, 
-    IN  ib_cq_handle_t                 ib_cq_handle, 
-    IN  void*                  context);
-
-/* async verb callbacks */
-extern void dapl_evd_un_async_error_callback (
-    IN ib_hca_handle_t         ib_hca_handle,
-    IN ib_error_record_t *     cause_ptr,
-    IN void *                  context);
-
-extern void dapl_evd_cq_async_error_callback (
-    IN ib_hca_handle_t         ib_hca_handle,
-    IN ib_cq_handle_t          ib_cq_handle,
-    IN ib_error_record_t *     cause_ptr,
-    IN void *                  context);
-
-extern void dapl_evd_qp_async_error_callback (
-    IN ib_hca_handle_t         ib_hca_handle,
-    IN ib_qp_handle_t          ib_qp_handle,
-    IN ib_error_record_t *     cause_ptr,
-    IN void *                  context);
-
-extern void dapls_evd_copy_cq (
-    DAPL_EVD                   *evd_ptr);
-
-extern DAT_RETURN dapls_evd_cq_poll_to_event (
-    IN DAPL_EVD                *evd_ptr,
-    OUT DAT_EVENT              *event);
-
-#endif
+/*\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
+ * HEADER: dapl_evd_util.h\r
+ *\r
+ * PURPOSE: Utility defs & routines for the EVD data structure\r
+ *\r
+ * $Id:$\r
+ *\r
+ **********************************************************************/\r
+\r
+#ifndef _DAPL_EVD_UTIL_H_\r
+#define _DAPL_EVD_UTIL_H_\r
+\r
+#include "dapl.h"\r
+\r
+DAT_RETURN\r
+dapls_evd_internal_create (\r
+    IN DAPL_IA         *ia_ptr, \r
+    IN DAPL_CNO                *cno_ptr,\r
+    IN DAT_COUNT       min_qlen,\r
+    IN DAT_EVD_FLAGS   evd_flags,\r
+    OUT DAPL_EVD       **evd_ptr_ptr) ;\r
+\r
+DAPL_EVD *\r
+dapls_evd_alloc ( \r
+    IN DAPL_IA         *ia_ptr,\r
+    IN DAPL_CNO                *cno_ptr,\r
+    IN DAT_EVD_FLAGS   evd_flags,\r
+    IN DAT_COUNT       qlen) ;\r
+\r
+DAT_RETURN\r
+dapls_evd_dealloc ( \r
+    IN DAPL_EVD        *evd_ptr) ;\r
+\r
+DAT_RETURN dapls_evd_event_realloc (\r
+    IN DAPL_EVD                *evd_ptr,\r
+    IN DAT_COUNT       qlen);\r
+\r
+/*\r
+ * Each of these functions will retrieve a free event from\r
+ * the specified EVD, fill in the elements of that event, and\r
+ * post the event back to the EVD.  If there is no EVD available,\r
+ * an overflow event will be posted to the async EVD associated\r
+ * with the EVD.\r
+ *\r
+ * DAT_INSUFFICIENT_RESOURCES will be returned on overflow,\r
+ * DAT_SUCCESS otherwise.\r
+ */\r
+\r
+DAT_RETURN\r
+dapls_evd_post_cr_arrival_event (\r
+    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_RETURN\r
+dapls_evd_post_connection_event (\r
+    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_RETURN\r
+dapls_evd_post_async_error_event (\r
+    IN DAPL_EVD                                *evd_ptr,\r
+    IN DAT_EVENT_NUMBER                        event_number,\r
+    IN DAT_IA_HANDLE                   ia_handle);\r
+\r
+DAT_RETURN\r
+dapls_evd_post_software_event (\r
+    IN DAPL_EVD                                *evd_ptr,\r
+    IN DAT_EVENT_NUMBER                        event_number,\r
+    IN DAT_PVOID                       pointer);\r
+\r
+DAT_RETURN\r
+dapls_evd_post_generic_event (\r
+    IN DAPL_EVD                                *evd_ptr,\r
+    IN DAT_EVENT_NUMBER                        event_number,\r
+    IN DAT_EVENT_DATA                  *data);\r
+\r
+#ifdef DAT_EXTENSIONS\r
+DAT_RETURN\r
+dapls_evd_post_cr_event_ext (\r
+    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,\r
+    IN DAT_PVOID                       ext_data);\r
+\r
+DAT_RETURN\r
+dapls_evd_post_connection_event_ext (\r
+    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
+#endif\r
+\r
+/*************************************\r
+ * dapl internal callbacks functions *\r
+ *************************************/\r
+\r
+/* connection verb callback */\r
+extern void dapl_evd_connection_callback (\r
+    IN dp_ib_cm_handle_t       ib_cm_handle,\r
+    IN const ib_cm_events_t    ib_cm_events,\r
+    IN const void              *private_data_ptr,\r
+    IN const int               private_data_size,\r
+    IN const void *            context );\r
+\r
+/* dto verb callback */\r
+extern void dapl_evd_dto_callback (\r
+    IN  ib_hca_handle_t        ib_hca_handle, \r
+    IN  ib_cq_handle_t                 ib_cq_handle, \r
+    IN  void*                  context);\r
+\r
+/* async verb callbacks */\r
+extern void dapl_evd_un_async_error_callback (\r
+    IN ib_hca_handle_t         ib_hca_handle,\r
+    IN ib_error_record_t *     cause_ptr,\r
+    IN void *                  context);\r
+\r
+extern void dapl_evd_cq_async_error_callback (\r
+    IN ib_hca_handle_t         ib_hca_handle,\r
+    IN ib_cq_handle_t          ib_cq_handle,\r
+    IN ib_error_record_t *     cause_ptr,\r
+    IN void *                  context);\r
+\r
+extern void dapl_evd_qp_async_error_callback (\r
+    IN ib_hca_handle_t         ib_hca_handle,\r
+    IN ib_qp_handle_t          ib_qp_handle,\r
+    IN ib_error_record_t *     cause_ptr,\r
+    IN void *                  context);\r
+\r
+extern void dapls_evd_copy_cq (\r
+    DAPL_EVD                   *evd_ptr);\r
+\r
+extern DAT_RETURN dapls_evd_cq_poll_to_event (\r
+    IN DAPL_EVD                *evd_ptr,\r
+    OUT DAT_EVENT              *event);\r
+\r
+#endif\r
index 6fcc4a2..093ed1c 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_ia_query.c
- *
- * PURPOSE: Interface Adapter management
- * Description: Interfaces in this file are completely described in
- *             the DAPL 1.1 API, Chapter 6, section 2
- *
- * $Id:$
- **********************************************************************/
-
-#include "dapl.h"
-#include "dapl_adapter_util.h"
-#include "dapl_vendor.h"
-
-/*
- * dapl_ia_query
- *
- * DAPL Requirements Version xxx, 6.2.1.3
- *
- * Provide the consumer with Interface Adapter and Provider parameters.
- *
- * Input:
- *     ia_handle
- *     ia_mask
- *     provider_mask
- *
- * Output:
- *     async_evd_handle
- *     ia_parameters
- *     provider_parameters
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INVALID_PARAMETER
- */
-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_attr_mask,
-             OUT DAT_IA_ATTR * ia_attr,
-             IN DAT_PROVIDER_ATTR_MASK provider_attr_mask,
-             OUT DAT_PROVIDER_ATTR * provider_attr)
-{
-       DAPL_IA *ia_ptr;
-       DAT_RETURN dat_status;
-       struct evd_merge_type {
-               DAT_BOOLEAN array[6][6];
-       } *evd_merge;
-       DAT_BOOLEAN val;
-       int i;
-       int j;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_API,
-                    "dapl_ia_query (%p, %p, 0x%llx, %p, 0x%x, %p)\n",
-                    ia_handle,
-                    async_evd_handle,
-                    ia_attr_mask, ia_attr, provider_attr_mask, provider_attr);
-
-       ia_ptr = (DAPL_IA *) ia_handle;
-       dat_status = DAT_SUCCESS;
-
-       if (DAPL_BAD_HANDLE(ia_ptr, DAPL_MAGIC_IA)) {
-               dat_status =
-                   DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_IA);
-               goto bail;
-       }
-
-       if (NULL != async_evd_handle) {
-               *async_evd_handle = ia_ptr->async_error_evd;
-       }
-
-       if (ia_attr_mask & DAT_IA_FIELD_ALL) {
-               if (NULL == ia_attr) {
-                       dat_status =
-                           DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG4);
-                       goto bail;
-               }
-
-               /*
-                * Obtain parameters from the HCA.  Protect against multiple
-                * IAs beating on the HCA at the same time.
-                */
-               dat_status =
-                   dapls_ib_query_hca(ia_ptr->hca_ptr, ia_attr, NULL, NULL);
-               if (dat_status != DAT_SUCCESS) {
-                       goto bail;
-               }
-       }
-
-       if (ia_attr_mask & ~DAT_IA_FIELD_ALL) {
-               dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3);
-               goto bail;
-       }
-
-       if (provider_attr_mask & DAT_PROVIDER_FIELD_ALL) {
-               if (NULL == provider_attr) {
-                       dat_status =
-                           DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG6);
-                       goto bail;
-               }
-
-               strncpy(provider_attr->provider_name,
-                       ia_ptr->header.provider->device_name,
-                       DAT_NAME_MAX_LENGTH);
-               provider_attr->provider_version_major = VN_PROVIDER_MAJOR;
-               provider_attr->provider_version_minor = VN_PROVIDER_MINOR;
-               provider_attr->dapl_version_major = DAT_VERSION_MAJOR;
-               provider_attr->dapl_version_minor = DAT_VERSION_MINOR;
-               provider_attr->lmr_mem_types_supported =
-                   DAT_MEM_TYPE_VIRTUAL | DAT_MEM_TYPE_LMR;
-#if VN_MEM_SHARED_VIRTUAL_SUPPORT > 0 && !defined(__KDAPL__)
-               provider_attr->lmr_mem_types_supported |=
-                   DAT_MEM_TYPE_SHARED_VIRTUAL;
-#endif
-               provider_attr->iov_ownership_on_return = DAT_IOV_CONSUMER;
-               provider_attr->dat_qos_supported = DAT_QOS_BEST_EFFORT;
-               provider_attr->completion_flags_supported =
-                   DAT_COMPLETION_DEFAULT_FLAG;
-               provider_attr->is_thread_safe = DAT_FALSE;
-               /*
-                * N.B. The second part of the following equation will evaluate
-                *      to 0 unless IBHOSTS_NAMING is enabled.
-                */
-               provider_attr->max_private_data_size =
-                   dapls_ib_private_data_size(NULL, DAPL_PDATA_CONN_REQ,
-                                              ia_ptr->hca_ptr) -
-                   (sizeof(DAPL_PRIVATE) - DAPL_MAX_PRIVATE_DATA_SIZE);
-               provider_attr->supports_multipath = DAT_FALSE;
-               provider_attr->ep_creator = DAT_PSP_CREATES_EP_NEVER;
-               provider_attr->optimal_buffer_alignment = DAT_OPTIMAL_ALIGNMENT;
-               /* The value of pz_support may vary by transport */
-               provider_attr->num_provider_specific_attr = 0;
-               provider_attr->provider_specific_attr = NULL;
-#if !defined(__KDAPL__)
-               provider_attr->pz_support = DAT_PZ_UNIQUE;
-#endif                         /* !KDAPL */
-
-               /*
-                *  Query for provider specific attributes
-                */
-               dapls_query_provider_specific_attr(ia_ptr, provider_attr);
-
-               /*
-                * Set up evd_stream_merging_supported options. Note there is
-                * one bit per allowable combination, using the ordinal
-                * position of the DAT_EVD_FLAGS as positions in the
-                * array. e.g.
-                * [0][0] is DAT_EVD_SOFTWARE_FLAG | DAT_EVD_SOFTWARE_FLAG,
-                * [0][1] is DAT_EVD_SOFTWARE_FLAG | DAT_EVD_CR_FLAG, and
-                * [2][4] is DAT_EVD_DTO_FLAG | DAT_EVD_RMR_BIND_FLAG
-                *
-                * Most combinations are true, so initialize the array that way.
-                * Then finish by resetting the bad combinations.
-                *
-                * DAT_EVD_ASYNC_FLAG is not supported. InfiniBand only allows
-                * a single asynchronous event handle per HCA, and the first
-                * dat_ia_open forces the creation of the only one that can be
-                * used. We disallow the user from creating an ASYNC EVD here.
-                */
-
-               evd_merge =
-                   (struct evd_merge_type *)&provider_attr->
-                   evd_stream_merging_supported[0][0];
-               val = DAT_TRUE;
-               for (i = 0; i < 6; i++) {
-                       if (i > 4) {
-                               /* ASYNC EVD is 5, so entire row will be 0 */
-                               val = DAT_FALSE;
-                       }
-                       for (j = 0; j < 5; j++) {
-                               evd_merge->array[i][j] = val;
-                       }
-                       /* Set the ASYNC_EVD column to FALSE */
-                       evd_merge->array[i][5] = DAT_FALSE;
-               }
-
-#ifndef DAPL_MERGE_CM_DTO
-               /*
-                * If an implementation supports CM and DTO completions on
-                * the same EVD then DAPL_MERGE_CM_DTO should be set to
-                * skip the following code
-                */
-               /* DAT_EVD_DTO_FLAG | DAT_EVD_CONNECTION_FLAG */
-               evd_merge->array[2][3] = DAT_FALSE;
-               /* DAT_EVD_CONNECTION_FLAG | DAT_EVD_DTO_FLAG */
-               evd_merge->array[3][2] = DAT_FALSE;
-#endif                         /* DAPL_MERGE_CM_DTO */
-       }
-
-      bail:
-       if (dat_status != DAT_SUCCESS) {
-               dapl_dbg_log(DAPL_DBG_TYPE_RTN,
-                            "dapl_ia_query () returns 0x%x\n", dat_status);
-       }
-
-       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_ia_query.c\r
+ *\r
+ * PURPOSE: Interface Adapter management\r
+ * Description: Interfaces in this file are completely described in\r
+ *             the DAPL 1.1 API, Chapter 6, section 2\r
+ *\r
+ * $Id:$\r
+ **********************************************************************/\r
+\r
+#include "dapl.h"\r
+#include "dapl_adapter_util.h"\r
+#include "dapl_vendor.h"\r
+\r
+/*\r
+ * dapl_ia_query\r
+ *\r
+ * DAPL Requirements Version xxx, 6.2.1.3\r
+ *\r
+ * Provide the consumer with Interface Adapter and Provider parameters.\r
+ *\r
+ * Input:\r
+ *     ia_handle\r
+ *     ia_mask\r
+ *     provider_mask\r
+ *\r
+ * Output:\r
+ *     async_evd_handle\r
+ *     ia_parameters\r
+ *     provider_parameters\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INVALID_PARAMETER\r
+ */\r
+DAT_RETURN DAT_API\r
+dapl_ia_query(IN DAT_IA_HANDLE ia_handle,\r
+             OUT DAT_EVD_HANDLE * async_evd_handle,\r
+             IN DAT_IA_ATTR_MASK ia_attr_mask,\r
+             OUT DAT_IA_ATTR * ia_attr,\r
+             IN DAT_PROVIDER_ATTR_MASK provider_attr_mask,\r
+             OUT DAT_PROVIDER_ATTR * provider_attr)\r
+{\r
+       DAPL_IA *ia_ptr;\r
+       DAT_RETURN dat_status;\r
+       struct evd_merge_type {\r
+               DAT_BOOLEAN array[6][6];\r
+       } *evd_merge;\r
+       DAT_BOOLEAN val;\r
+       int i;\r
+       int j;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_API,\r
+                    "dapl_ia_query (%p, %p, 0x%llx, %p, 0x%x, %p)\n",\r
+                    ia_handle,\r
+                    async_evd_handle,\r
+                    ia_attr_mask, ia_attr, provider_attr_mask, provider_attr);\r
+\r
+       ia_ptr = (DAPL_IA *) ia_handle;\r
+       dat_status = DAT_SUCCESS;\r
+\r
+       if (DAPL_BAD_HANDLE(ia_ptr, DAPL_MAGIC_IA)) {\r
+               dat_status =\r
+                   DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_IA);\r
+               goto bail;\r
+       }\r
+\r
+       if (NULL != async_evd_handle) {\r
+               *async_evd_handle = ia_ptr->async_error_evd;\r
+       }\r
+\r
+       if (ia_attr_mask & DAT_IA_FIELD_ALL) {\r
+               if (NULL == ia_attr) {\r
+                       dat_status =\r
+                           DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG4);\r
+                       goto bail;\r
+               }\r
+\r
+               /*\r
+                * Obtain parameters from the HCA.  Protect against multiple\r
+                * IAs beating on the HCA at the same time.\r
+                */\r
+               dat_status =\r
+                   dapls_ib_query_hca(ia_ptr->hca_ptr, ia_attr, NULL, NULL);\r
+               if (dat_status != DAT_SUCCESS) {\r
+                       goto bail;\r
+               }\r
+       }\r
+\r
+       if (ia_attr_mask & ~DAT_IA_FIELD_ALL) {\r
+               dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3);\r
+               goto bail;\r
+       }\r
+\r
+       if (provider_attr_mask & DAT_PROVIDER_FIELD_ALL) {\r
+               if (NULL == provider_attr) {\r
+                       dat_status =\r
+                           DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG6);\r
+                       goto bail;\r
+               }\r
+\r
+               strncpy(provider_attr->provider_name,\r
+                       ia_ptr->header.provider->device_name,\r
+                       DAT_NAME_MAX_LENGTH);\r
+               provider_attr->provider_version_major = VN_PROVIDER_MAJOR;\r
+               provider_attr->provider_version_minor = VN_PROVIDER_MINOR;\r
+               provider_attr->dapl_version_major = DAT_VERSION_MAJOR;\r
+               provider_attr->dapl_version_minor = DAT_VERSION_MINOR;\r
+               provider_attr->lmr_mem_types_supported =\r
+                   DAT_MEM_TYPE_VIRTUAL | DAT_MEM_TYPE_LMR;\r
+#if VN_MEM_SHARED_VIRTUAL_SUPPORT > 0 && !defined(__KDAPL__)\r
+               provider_attr->lmr_mem_types_supported |=\r
+                   DAT_MEM_TYPE_SHARED_VIRTUAL;\r
+#endif\r
+               provider_attr->iov_ownership_on_return = DAT_IOV_CONSUMER;\r
+               provider_attr->dat_qos_supported = DAT_QOS_BEST_EFFORT;\r
+               provider_attr->completion_flags_supported =\r
+                   DAT_COMPLETION_DEFAULT_FLAG;\r
+               provider_attr->is_thread_safe = DAT_FALSE;\r
+               /*\r
+                * N.B. The second part of the following equation will evaluate\r
+                *      to 0 unless IBHOSTS_NAMING is enabled.\r
+                */\r
+               provider_attr->max_private_data_size =\r
+                   dapls_ib_private_data_size(ia_ptr->hca_ptr) -\r
+                   (sizeof(DAPL_PRIVATE) - DAPL_MAX_PRIVATE_DATA_SIZE);\r
+               provider_attr->supports_multipath = DAT_FALSE;\r
+               provider_attr->ep_creator = DAT_PSP_CREATES_EP_NEVER;\r
+               provider_attr->optimal_buffer_alignment = DAT_OPTIMAL_ALIGNMENT;\r
+               /* The value of pz_support may vary by transport */\r
+               provider_attr->num_provider_specific_attr = 0;\r
+               provider_attr->provider_specific_attr = NULL;\r
+#if !defined(__KDAPL__)\r
+               provider_attr->pz_support = DAT_PZ_UNIQUE;\r
+#endif                         /* !KDAPL */\r
+\r
+               /*\r
+                *  Query for provider specific attributes\r
+                */\r
+               dapls_query_provider_specific_attr(ia_ptr, provider_attr);\r
+\r
+               /*\r
+                * Set up evd_stream_merging_supported options. Note there is\r
+                * one bit per allowable combination, using the ordinal\r
+                * position of the DAT_EVD_FLAGS as positions in the\r
+                * array. e.g.\r
+                * [0][0] is DAT_EVD_SOFTWARE_FLAG | DAT_EVD_SOFTWARE_FLAG,\r
+                * [0][1] is DAT_EVD_SOFTWARE_FLAG | DAT_EVD_CR_FLAG, and\r
+                * [2][4] is DAT_EVD_DTO_FLAG | DAT_EVD_RMR_BIND_FLAG\r
+                *\r
+                * Most combinations are true, so initialize the array that way.\r
+                * Then finish by resetting the bad combinations.\r
+                *\r
+                * DAT_EVD_ASYNC_FLAG is not supported. InfiniBand only allows\r
+                * a single asynchronous event handle per HCA, and the first\r
+                * dat_ia_open forces the creation of the only one that can be\r
+                * used. We disallow the user from creating an ASYNC EVD here.\r
+                */\r
+\r
+               evd_merge =\r
+                   (struct evd_merge_type *)&provider_attr->\r
+                   evd_stream_merging_supported[0][0];\r
+               val = DAT_TRUE;\r
+               for (i = 0; i < 6; i++) {\r
+                       if (i > 4) {\r
+                               /* ASYNC EVD is 5, so entire row will be 0 */\r
+                               val = DAT_FALSE;\r
+                       }\r
+                       for (j = 0; j < 5; j++) {\r
+                               evd_merge->array[i][j] = val;\r
+                       }\r
+                       /* Set the ASYNC_EVD column to FALSE */\r
+                       evd_merge->array[i][5] = DAT_FALSE;\r
+               }\r
+\r
+#ifndef DAPL_MERGE_CM_DTO\r
+               /*\r
+                * If an implementation supports CM and DTO completions on\r
+                * the same EVD then DAPL_MERGE_CM_DTO should be set to\r
+                * skip the following code\r
+                */\r
+               /* DAT_EVD_DTO_FLAG | DAT_EVD_CONNECTION_FLAG */\r
+               evd_merge->array[2][3] = DAT_FALSE;\r
+               /* DAT_EVD_CONNECTION_FLAG | DAT_EVD_DTO_FLAG */\r
+               evd_merge->array[3][2] = DAT_FALSE;\r
+#endif                         /* DAPL_MERGE_CM_DTO */\r
+       }\r
+\r
+      bail:\r
+       if (dat_status != DAT_SUCCESS) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_RTN,\r
+                            "dapl_ia_query () returns 0x%x\n", dat_status);\r
+       }\r
+\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 149bcbf..7d42b49 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_cm.c
- *
- * PURPOSE: IB Connection routines for access to IBAL APIs
- *
- * $Id$
- *
- **********************************************************************/
-
-#include "dapl.h"
-#include "dapl_adapter_util.h"
-#include "dapl_evd_util.h"
-#include "dapl_cr_util.h"
-#include "dapl_sp_util.h"
-#include "dapl_ep_util.h"
-#include "dapl_ia_util.h"
-#include "dapl_ibal_util.h"
-#include "dapl_name_service.h"
-#include "dapl_ibal_name_service.h"
-#include "dapl_cookie.h"
-
-#define IB_INFINITE_SERVICE_LEASE   0xFFFFFFFF
-#define  DAPL_ATS_SERVICE_ID        ATS_SERVICE_ID //0x10000CE100415453
-#define  DAPL_ATS_NAME              ATS_NAME
-#define  HCA_IPV6_ADDRESS_LENGTH    16
-
-/* until dapl_ibal_util.h define of IB_INVALID_HANDLE which overlaps the
- * Windows ib_types.h typedef enu ib_api_status_t IB_INVALID_HANDLE is fixed.
- */
-#undef IB_INVALID_HANDLE
-#define DAPL_IB_INVALID_HANDLE NULL
-
-int g_dapl_loopback_connection = 0;
-extern dapl_ibal_root_t        dapl_ibal_root;
-
-/*
- * Prototypes
- */
-
-char *
-dapli_ib_cm_event_str(ib_cm_events_t e)
-{
-#ifdef DBG
-    char        *cp;
-    static char *event_str[13] = {
-        "IB_CME_CONNECTED",
-        "IB_CME_DISCONNECTED",
-        "IB_CME_DISCONNECTED_ON_LINK_DOWN",
-        "IB_CME_CONNECTION_REQUEST_PENDING",
-        "IB_CME_CONNECTION_REQUEST_PENDING_PRIVATE_DATA",
-        "IB_CME_DESTINATION_REJECT",
-        "IB_CME_DESTINATION_REJECT_PRIVATE_DATA",
-        "IB_CME_DESTINATION_UNREACHABLE",
-        "IB_CME_TOO_MANY_CONNECTION_REQUESTS",
-        "IB_CME_LOCAL_FAILURE",
-        "IB_CME_REPLY_RECEIVED",
-        "IB_CME_REPLY_RECEIVED_PRIVATE_DATA",
-        "IB_CM_LOCAL_FAILURE"
-    };
-
-    if (e > IB_CM_LOCAL_FAILURE || e < IB_CME_CONNECTED)
-       cp =  "BAD EVENT";
-    else
-        cp = event_str[e];
-
-    return cp;
-#else
-    static char num[8];
-    sprintf(num,"%d",e);
-    return num;
-#endif
-}
-
-
-#if defined(DAPL_DBG)
-
-void dapli_print_private_data( char *prefix, const uint8_t *pd, int len )
-{
-    int i;
-            
-    if ( !pd || len <= 0 )
-       return;
-
-    dapl_log ( DAPL_DBG_TYPE_CM, "--> %s: private_data:\n    ",prefix);
-
-    if (len > IB_MAX_REP_PDATA_SIZE)
-    {
-       dapl_log ( DAPL_DBG_TYPE_ERR,
-               "    Private data size(%d) > Max(%d), ignored.\n    ",
-                                       len,DAPL_MAX_PRIVATE_DATA_SIZE);
-       len = IB_MAX_REP_PDATA_SIZE;
-    }
-
-    for ( i = 0 ; i < len; i++ )
-    {
-       dapl_log ( DAPL_DBG_TYPE_CM, "%2x ", pd[i]);
-       if ( ((i+1) % 20) == 0 ) 
-           dapl_log ( DAPL_DBG_TYPE_CM, "\n    ");
-    }
-   dapl_log ( DAPL_DBG_TYPE_CM, "\n");
-}
-#endif
-
-
-static void 
-dapli_ib_cm_apr_cb (
-        IN    ib_cm_apr_rec_t          *p_cm_apr_rec )
-{
-    UNUSED_PARAM( p_cm_apr_rec );
-
-    dapl_dbg_log (DAPL_DBG_TYPE_CM, 
-                  "--> DiCAcb: CM callback APR (Alternate Path Request)\n");
-}
-
-static void 
-dapli_ib_cm_lap_cb (
-        IN    ib_cm_lap_rec_t          *p_cm_lap_rec )
-{
-    UNUSED_PARAM( p_cm_lap_rec );
-
-    dapl_dbg_log (DAPL_DBG_TYPE_CM, 
-                  "--> DiCLcb: CM callback LAP (Load Alternate Path)\n");
-}
-
-/*
- * Connection Disconnect Request callback
- * We received a DREQ, return a DREP (disconnect reply).
- */
-
-static void 
-dapli_ib_cm_dreq_cb (
-        IN    ib_cm_dreq_rec_t          *p_cm_dreq_rec )
-{
-    ib_cm_drep_t        cm_drep;
-    DAPL_EP             *ep_ptr;
-    int                        bail=10;
-    
-    dapl_os_assert (p_cm_dreq_rec);
-
-    ep_ptr  = (DAPL_EP * __ptr64) p_cm_dreq_rec->qp_context;
-    if ( DAPL_BAD_PTR(ep_ptr) )
-    {
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR, 
-                      "--> %s: BAD_PTR EP %lx\n", __FUNCTION__, ep_ptr);
-        return;
-    }
-    if ( ep_ptr->header.magic != DAPL_MAGIC_EP  )
-    {
-        if ( ep_ptr->header.magic == DAPL_MAGIC_INVALID )
-            return;
-
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR,
-                      "--> %s: EP %p BAD_EP_MAGIC %x != wanted %x\n",
-                      __FUNCTION__, ep_ptr, ep_ptr->header.magic,
-                      DAPL_MAGIC_EP );
-        return;
-    }
-
-    dapl_dbg_log (DAPL_DBG_TYPE_CM, 
-                  "--> %s() EP %p, %s sent_discreq %s\n",
-                  __FUNCTION__,ep_ptr,
-                  dapl_get_ep_state_str(ep_ptr->param.ep_state),
-                  (ep_ptr->sent_discreq == DAT_TRUE ? "TRUE":"FALSE"));
-
-    dapl_os_lock (&ep_ptr->header.lock);
-    if ( ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED
-         /*|| ( ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECT_PENDING
-           && ep_ptr->sent_discreq == DAT_TRUE)*/ )
-    {
-        dapl_os_unlock (&ep_ptr->header.lock);
-        dapl_dbg_log (DAPL_DBG_TYPE_CM, 
-                      "--> DiCDcb: EP %lx QP %lx already Disconnected\n",
-                      ep_ptr, ep_ptr->qp_handle);
-        return;
-    }
-
-    ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECT_PENDING;
-    ep_ptr->recv_discreq = DAT_TRUE;
-    dapl_os_unlock (&ep_ptr->header.lock);
-
-    dapl_os_memzero (&cm_drep, sizeof(ib_cm_drep_t));
-
-    /* Could fail if we received reply from other side, no need to retry */
-    /* Wait for any send ops in process holding reference */
-    while (dapls_cb_pending(&ep_ptr->req_buffer) && bail-- > 0 )
-    {
-       dapl_dbg_log (DAPL_DBG_TYPE_CM, 
-                  "--> DiCDcb: WAIT for EP=%lx req_count(%d) != 0\n", 
-                  ep_ptr, dapls_cb_pending(&ep_ptr->req_buffer));
-       dapl_os_sleep_usec (100);
-    }
-
-    ib_cm_drep (p_cm_dreq_rec->h_cm_dreq, &cm_drep);
-
-    /* CM puts QP in reset state */
-    ep_ptr->qp_state = IB_QPS_RESET;
-          
-    if (ep_ptr->cr_ptr)
-    {
-        dapl_os_assert(ep_ptr->ibal_cm_handle->cid
-                                             == p_cm_dreq_rec->h_cm_dreq.cid);
-        /* passive side */
-        dapls_cr_callback ( ep_ptr->cm_handle,
-                            IB_CME_DISCONNECTED,
-                            (void * __ptr64) p_cm_dreq_rec->p_dreq_pdata,
-                            (void *) (((DAPL_CR *) ep_ptr->cr_ptr)->sp_ptr) );
-    }
-    else
-    {
-        /* active side */
-        dapl_evd_connection_callback (
-                                  (dp_ib_cm_handle_t) &p_cm_dreq_rec->h_cm_dreq,
-                                  IB_CME_DISCONNECTED,
-                                  (void * __ptr64)
-                                  p_cm_dreq_rec->p_dreq_pdata,
-                                  p_cm_dreq_rec->qp_context );
-    }
-}
-
-/*
- * Connection Disconnect Reply callback
- * We sent a DREQ and received a DREP.
- */
-
-static void 
-dapli_ib_cm_drep_cb (
-        IN    ib_cm_drep_rec_t          *p_cm_drep_rec )
-{
-    DAPL_EP            *ep_ptr;
-    
-    dapl_os_assert (p_cm_drep_rec != NULL);
-
-    ep_ptr  = (DAPL_EP * __ptr64) p_cm_drep_rec->qp_context;
-
-    if (p_cm_drep_rec->cm_status)
-    {
-         dapl_dbg_log (DAPL_DBG_TYPE_CM,
-                  "--> %s: DREP cm_status(%s) EP=%p\n", __FUNCTION__,
-                  ib_get_err_str(p_cm_drep_rec->cm_status), ep_ptr); 
-    }
-
-    if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )
-    {
-         dapl_dbg_log (DAPL_DBG_TYPE_ERR,
-                  "--> %s: BAD EP Handle EP=%lx\n", __FUNCTION__,ep_ptr); 
-        return;
-    }
-    
-    dapl_dbg_log (DAPL_DBG_TYPE_CM, 
-       "--> DiCDpcb: EP %p state %s cm_hdl %p\n",ep_ptr,
-                  dapl_get_ep_state_str(ep_ptr->param.ep_state),
-                  ep_ptr->cm_handle);
-
-    if ( ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED )
-    {
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR, 
-                      "--> DiCDpcb: EP %lx QP %lx already Disconnected\n",
-                      ep_ptr, ep_ptr->qp_handle);
-        return;
-    }
-
-    if (ep_ptr->cm_handle == DAPL_IB_INVALID_HANDLE )
-    {
-         dapl_dbg_log (DAPL_DBG_TYPE_CM,
-                  "--> %s: Invalid EP->CM handle?\n", __FUNCTION__); 
-        return;
-    }
-
-    if (ep_ptr->cr_ptr)
-    {
-        /* passive connection side */
-        dapls_cr_callback ( ep_ptr->cm_handle,
-                            IB_CME_DISCONNECTED,
-                           (void * __ptr64) p_cm_drep_rec->p_drep_pdata,
-                           (void *) (((DAPL_CR *) ep_ptr->cr_ptr)->sp_ptr) );
-    }
-    else
-    {
-        /* active connection side */
-        dapl_evd_connection_callback (
-                                   ep_ptr->cm_handle,
-                                   IB_CME_DISCONNECTED,
-                                   (void * __ptr64) p_cm_drep_rec->p_drep_pdata,
-                                   p_cm_drep_rec->qp_context );
-    }
-}
-
-/*
- * CM reply callback
- */
-
-static void 
-dapli_ib_cm_rep_cb (
-        IN    ib_cm_rep_rec_t          *p_cm_rep_rec )
-{
-    ib_api_status_t     ib_status; 
-    ib_cm_rtu_t         cm_rtu;
-    uint8_t             cm_cb_op;
-    DAPL_PRIVATE        *prd_ptr;
-    DAPL_EP             *ep_ptr;
-    dapl_ibal_ca_t      *p_ca;
-        
-    dapl_os_assert (p_cm_rep_rec != NULL);
-
-    ep_ptr  = (DAPL_EP * __ptr64) p_cm_rep_rec->qp_context;
-
-    if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )
-    {
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: EP %lx invalid or FREED\n",
-                      __FUNCTION__, ep_ptr);
-        return;
-    }
-    dapl_dbg_log (DAPL_DBG_TYPE_CM, 
-                  "--> DiCRpcb: EP = %lx local_max_rdma_read_in %d\n", 
-                  ep_ptr, p_cm_rep_rec->resp_res);
-
-    p_ca   = (dapl_ibal_ca_t *) 
-             ep_ptr->header.owner_ia->hca_ptr->ib_hca_handle;
-
-    dapl_os_memzero (&cm_rtu, sizeof ( ib_cm_rtu_t ));
-    cm_rtu.pfn_cm_apr_cb  = dapli_ib_cm_apr_cb;
-    cm_rtu.pfn_cm_dreq_cb = dapli_ib_cm_dreq_cb;
-    cm_rtu.p_rtu_pdata    = NULL;
-    cm_rtu.access_ctrl = 
-               IB_AC_LOCAL_WRITE|IB_AC_RDMA_WRITE|IB_AC_MW_BIND|IB_AC_ATOMIC;
-    if ((ep_ptr->param.ep_attr.max_rdma_read_in > 0) || 
-               (ep_ptr->param.ep_attr.max_rdma_read_out > 0))
-    {
-       cm_rtu.access_ctrl |= IB_AC_RDMA_READ;
-    }
-           
-    cm_rtu.rq_depth       = 0;
-    cm_rtu.sq_depth       = 0;
-       
-    ib_status = ib_cm_rtu (p_cm_rep_rec->h_cm_rep, &cm_rtu);
-
-    if (ib_status == IB_SUCCESS)
-    {
-        cm_cb_op = IB_CME_CONNECTED;
-        dapl_dbg_log (DAPL_DBG_TYPE_CM, 
-                  "--> DiCRpcb: EP %lx Connected req_count %d\n", 
-                  ep_ptr, dapls_cb_pending(&ep_ptr->req_buffer));
-    }
-    else
-    {
-        cm_cb_op = IB_CME_LOCAL_FAILURE;
-    }
-
-    prd_ptr = (DAPL_PRIVATE * __ptr64) p_cm_rep_rec->p_rep_pdata;
-
-#if defined(DAPL_DBG) && 0
-    dapli_print_private_data( "DiCRpcb",
-                             prd_ptr->private_data,
-                             IB_MAX_REP_PDATA_SIZE);
-#endif
-
-    dapl_evd_connection_callback ( 
-                            (dp_ib_cm_handle_t)&p_cm_rep_rec->h_cm_rep,
-                            cm_cb_op,
-                            (void *) prd_ptr,
-                            (void * __ptr64) p_cm_rep_rec->qp_context);
-}
-
-
-static void 
-dapli_ib_cm_rej_cb (
-        IN    ib_cm_rej_rec_t          *p_cm_rej_rec )
-{
-    DAPL_EP         *ep_ptr;
-    ib_cm_events_t  cm_event;
-
-    dapl_os_assert (p_cm_rej_rec);
-
-    ep_ptr = (DAPL_EP * __ptr64) p_cm_rej_rec->qp_context;
-
-    if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )
-    {
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: EP %lx invalid or FREED\n",
-                      __FUNCTION__, ep_ptr);
-        return;
-    }
-
-    dapl_dbg_log (DAPL_DBG_TYPE_CM, 
-                  "--> DiCRjcb: EP = %lx QP = %lx rej reason = 0x%x\n", 
-                  ep_ptr,ep_ptr->qp_handle,CL_NTOH16(p_cm_rej_rec->rej_status));
-
-    switch (p_cm_rej_rec->rej_status)
-    {
-        case IB_REJ_INSUF_RESOURCES:
-        case IB_REJ_INSUF_QP:
-        case IB_REJ_INVALID_COMM_ID:
-        case IB_REJ_INVALID_COMM_INSTANCE:
-        case IB_REJ_INVALID_PKT_RATE:
-        case IB_REJ_INVALID_ALT_GID:
-        case IB_REJ_INVALID_ALT_LID:
-        case IB_REJ_INVALID_ALT_SL:
-        case IB_REJ_INVALID_ALT_TRAFFIC_CLASS:
-        case IB_REJ_INVALID_ALT_PKT_RATE:
-        case IB_REJ_INVALID_ALT_HOP_LIMIT:
-        case IB_REJ_INVALID_ALT_FLOW_LBL:
-        case IB_REJ_INVALID_GID:
-        case IB_REJ_INVALID_LID:
-        case IB_REJ_INVALID_SID:
-        case IB_REJ_INVALID_SL:
-        case IB_REJ_INVALID_TRAFFIC_CLASS:
-        case IB_REJ_PORT_REDIRECT:
-        case IB_REJ_INVALID_MTU:
-        case IB_REJ_INSUFFICIENT_RESP_RES:
-        case IB_REJ_INVALID_CLASS_VER:
-        case IB_REJ_INVALID_FLOW_LBL:
-            cm_event = IB_CME_DESTINATION_REJECT;
-            break;
-
-        case IB_REJ_TIMEOUT:
-            cm_event = IB_CME_DESTINATION_UNREACHABLE;
-            dapl_dbg_log (DAPL_DBG_TYPE_CM, "--> DiCRjcb: CR TIMEOUT\n");
-            break;
-
-        case IB_REJ_USER_DEFINED:
-            cm_event = IB_CME_DESTINATION_REJECT;
-            dapl_dbg_log (DAPL_DBG_TYPE_CM, 
-                               "--> DiCRjcb: user defined rej reason %s\n",
-                               p_cm_rej_rec->p_ari);
-            break;
-
-        default:
-            cm_event = IB_CME_LOCAL_FAILURE;
-            dapl_dbg_log (DAPL_DBG_TYPE_CM, 
-                               "--> DiCRjcb: with unknown status %x\n", 
-                               p_cm_rej_rec->rej_status);
-            break;
-     }
-
-    /* FIXME - Vu
-     * We do not take care off the user defined rej reason with additional 
-     * rejection information (p_ari)
-     */
-
-    if (ep_ptr->cr_ptr)
-    {
-        dapls_cr_callback ( ep_ptr->cm_handle,
-                            cm_event,
-                            (void * __ptr64) p_cm_rej_rec->p_rej_pdata,
-                            (void *) ((DAPL_CR *) ep_ptr->cr_ptr)->sp_ptr);
-    }
-    else
-    {
-        dapl_evd_connection_callback (
-                                   ep_ptr->cm_handle,
-                                   cm_event,
-                                   (void * __ptr64) p_cm_rej_rec->p_rej_pdata,
-                                   (void * __ptr64) p_cm_rej_rec->qp_context );
-    }
-
-}
-
-
-
-static void 
-dapli_ib_cm_req_cb ( IN  ib_cm_req_rec_t  *p_cm_req_rec )
-{
-    DAPL_SP              *sp_ptr;
-    DAT_SOCK_ADDR6       dest_ia_addr;
-    dp_ib_cm_handle_t    cm_handle;
-
-    struct ibal_cr_data {
-        ib_cm_handle_t   cm_hdl;
-        DAT_SOCK_ADDR6   dst_ip_addr;
-    } *crd;
-
-    dapl_os_assert (p_cm_req_rec);
-
-    sp_ptr = (DAPL_SP * __ptr64) p_cm_req_rec->context;
-
-    dapl_os_assert (sp_ptr);
-
-    /*
-     * The context pointer could have been cleaned up in a racing
-     * CM callback, check to see if we should just exit here
-     */
-    if (sp_ptr->header.magic == DAPL_MAGIC_INVALID)
-    {
-        dapl_dbg_log (DAPL_DBG_TYPE_CM,
-                     "%s: BAD-Magic in SP %lx, racing CM callback?\n",
-                      __FUNCTION__, sp_ptr );
-       return;
-    }
-
-    dapl_os_assert ( sp_ptr->header.magic == DAPL_MAGIC_PSP || 
-                     sp_ptr->header.magic == DAPL_MAGIC_RSP );
-
-    /* preserve ibal's connection handle storage so we have a consistent
-     * pointer value. The reasons this is done dynamically instead of a static
-     * allocation in an end_point is the pointer value is set in the SP list
-     * of CR's here and searched for from disconnect callbacks. If the pointer
-     * value changes, you never find the CR on the sp list...
-     * EP struct deallocation is where this memory is released or prior in the
-     * error case.
-     */
-    crd = dapl_os_alloc ( sizeof(struct ibal_cr_data) );
-    if ( !crd )
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "%s: FAILED to alloc IB CM handle storage?\n",
-                       __FUNCTION__);
-        return;
-    }
-
-    cm_handle = &crd->cm_hdl;
-    dapl_os_memzero ( (void*)crd, sizeof(*crd) );
-
-    /*
-     * Save the cm_srvc_handle to avoid the race condition between
-     * the return of the ib_cm_listen and the notification of a conn req
-     */
-    if (sp_ptr->cm_srvc_handle != p_cm_req_rec->h_cm_listen)
-    {
-        dapl_dbg_log (DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK, 
-                           "--> DiCRqcb: cm_service_handle is changed\n"); 
-        sp_ptr->cm_srvc_handle = p_cm_req_rec->h_cm_listen;
-    }
-
-    dapl_os_memzero (&dest_ia_addr, sizeof (dest_ia_addr));
-
-#ifdef NO_NAME_SERVICE
-
-    {
-        DAPL_PRIVATE *prd_ptr;
-        
-        prd_ptr = (DAPL_PRIVATE *)p_cm_req_rec->p_req_pdata;
-
-        dapl_os_memcpy ((void *)&dest_ia_addr,
-                        (void *)&prd_ptr->hca_address,
-                        sizeof (DAT_SOCK_ADDR6));        
-    }
-    
-#else
-
-    {
-        GID            dest_gid;
-
-        dapl_os_memzero (&dest_gid, sizeof (dest_gid));
-
-        dest_gid.guid = p_cm_req_rec->primary_path.dgid.unicast.interface_id;
-        dest_gid.gid_prefix = p_cm_req_rec->primary_path.dgid.unicast.prefix;
-
-        if (DAT_SUCCESS != dapls_ns_map_ipaddr (
-                                 sp_ptr->header.owner_ia->hca_ptr,
-                                 dest_gid,
-                                 (DAT_IA_ADDRESS_PTR)&dest_ia_addr))
-        {
-            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                           "cm_req_cb: SP = %lx failed mapping GID-IPaddr\n",
-                           sp_ptr);
-        }
-    }
-
-#endif /* NO_NAME_SERVICE */
-
-#if defined(DAPL_DBG)
-    {
-        char ipa[20];
-  
-        //rval = ((struct sockaddr_in *) (&dest_ia_addr))->sin_addr.s_addr;
-
-        dapl_dbg_log (DAPL_DBG_TYPE_CM|DAPL_DBG_TYPE_CALLBACK, 
-                      "%s: query SA for RemoteAddr: %s\n",
-                      __FUNCTION__,
-                      dapli_get_ip_addr_str( (DAT_SOCK_ADDR6*)
-                                                         &dest_ia_addr, ipa) );
-    }
-#endif
-
-    /* preserve CR cm handle data */
-    dapl_os_memcpy( (void*)cm_handle,
-                    (void*)&p_cm_req_rec->h_cm_req,
-                    sizeof(ib_cm_handle_t) );
-
-    /* preserve remote IP address */
-    dapl_os_memcpy( (void*)&crd->dst_ip_addr,
-                    (void*)&dest_ia_addr,
-                    sizeof(dest_ia_addr) );
-
-    /* FIXME - Vu
-     * We have NOT used/saved the primary and alternative path record
-     * ie. p_cm_req_rec->p_primary_path and p_cm_req_rec->p_alt_path
-     * We should cache some fields in path record in the Name Service DB
-     * such as: dgid, dlid
-     * Also we do not save resp_res (ie. max_oustanding_rdma_read/atomic)
-     * rnr_retry_cnt and flow_ctrl fields
-     */
-    dapl_dbg_log (DAPL_DBG_TYPE_CM,
-                  "%s: SP %lx max_rdma_read %d PrivateData %lx\n",
-                  __FUNCTION__, sp_ptr, p_cm_req_rec->resp_res,
-                  p_cm_req_rec->p_req_pdata);
-
-    dapls_cr_callback ( cm_handle,
-                        IB_CME_CONNECTION_REQUEST_PENDING,
-                        (void * __ptr64) p_cm_req_rec->p_req_pdata,
-                        (void * __ptr64) sp_ptr );
-}
-
-
-static void 
-dapli_ib_cm_mra_cb (
-        IN    ib_cm_mra_rec_t          *p_cm_mra_rec )
-{
-       UNUSED_PARAM( p_cm_mra_rec );
-    dapl_dbg_log (DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK, 
-                       "--> DiCMcb: CM callback MRA\n");
-}
-
-static void 
-dapli_ib_cm_rtu_cb (
-        IN    ib_cm_rtu_rec_t          *p_cm_rtu_rec )
-{
-    DAPL_EP         *ep_ptr;
-
-    dapl_os_assert (p_cm_rtu_rec != NULL);
-   
-    ep_ptr = (DAPL_EP * __ptr64) p_cm_rtu_rec->qp_context;
-
-    if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )
-    {
-        dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: EP %lx invalid or FREED\n",
-                      __FUNCTION__, ep_ptr);
-        return;
-    }
-
-    dapl_dbg_log (DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK, 
-                  "--> DiCRucb: EP %lx QP %lx\n", ep_ptr, ep_ptr->qp_handle); 
-
-    if (ep_ptr->cr_ptr)
-    {
-        DAPL_SP  *sp_ptr;
-
-        sp_ptr = ((DAPL_CR *) ep_ptr->cr_ptr)->sp_ptr;
-
-        dapls_cr_callback ( ep_ptr->cm_handle,
-                            IB_CME_CONNECTED,
-                            (void * __ptr64) p_cm_rtu_rec->p_rtu_pdata,
-                            (void *) sp_ptr);
-                            
-    }
-    else
-    {
-        dapl_evd_connection_callback ( 
-                            ep_ptr->cm_handle,
-                            IB_CME_CONNECTED,
-                            (void * __ptr64) p_cm_rtu_rec->p_rtu_pdata,
-                            (void *) ep_ptr);
-    }
-}
-
-/*
- * dapls_ib_cm_remote_addr
- *
- * Obtain the remote IP address given a connection
- *
- * Input:
- *     cr_handle
- *
- * Output:
- *     remote_ia_address: where to place the remote address
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INVALID_HANDLE
- *
- */
-DAT_RETURN
-dapls_ib_cm_remote_addr (
-    IN      DAT_HANDLE          dat_handle,
-    OUT     DAT_SOCK_ADDR6      *remote_address )
-{
-
-    DAPL_HEADER        *header;
-    void               *vp;
-    char               ipa[20];
-
-    header = (DAPL_HEADER *)dat_handle;
-
-    if (header->magic == DAPL_MAGIC_EP) 
-    {
-       vp = &((DAPL_EP *) dat_handle)->remote_ia_address;
-    }
-    else if (header->magic == DAPL_MAGIC_CR) 
-    {
-       vp = &((DAPL_CR *) dat_handle)->remote_ia_address;
-    }
-    else 
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_CM,
-                       "%s: hdr->magic %x, dat_handle(%lx)\n",
-                       __FUNCTION__, header->magic, dat_handle );
-       return DAT_INVALID_HANDLE;
-    }
-
-    dapl_os_memcpy( remote_address, vp, sizeof(DAT_SOCK_ADDR6) );
-
-    dapl_dbg_log ( DAPL_DBG_TYPE_CM, "%s: returns %s\n",
-                   __FUNCTION__,
-                   dapli_get_ip_addr_str((DAT_SOCK_ADDR6*)remote_address,ipa) );
-
-    return DAT_SUCCESS;
-}
-
-
-/*
- * dapls_ib_connect
- *
- * Initiate a connection with the passive listener on another node
- *
- * Input:
- *        ep_handle,
- *        remote_ia_address,
- *        remote_conn_qual,
- *          prd_size                size of private data and structure
- *          prd_prt                pointer to private data structure
- *
- * Output:
- *         none
- *
- * Returns:
- *         DAT_SUCCESS
- *        DAT_INSUFFICIENT_RESOURCES
- *        DAT_INVALID_PARAMETER
- *
- */
-DAT_RETURN
-dapls_ib_connect (
-        IN        DAT_EP_HANDLE                ep_handle,
-        IN        DAT_IA_ADDRESS_PTR           remote_ia_address,
-        IN        DAT_CONN_QUAL                remote_conn_qual,
-        IN        DAT_COUNT                    private_data_size,
-        IN        DAT_PVOID                    private_data )
-{
-    DAPL_EP                      *ep_ptr;
-    DAPL_IA                      *ia_ptr;
-    ib_api_status_t              ib_status;
-    dapl_ibal_port_t             *p_active_port;
-    dapl_ibal_ca_t               *p_ca;
-    ib_cm_req_t                  cm_req;
-    ib_path_rec_t                path_rec;
-    GID                          dest_GID;
-    ib_query_req_t               query_req;
-    ib_gid_pair_t                gid_pair;
-    ib_service_record_t          service_rec;
-    int                          retry_cnt;
-    DAT_RETURN                   dat_status;
-
-    ep_ptr         = (DAPL_EP *) ep_handle;
-    ia_ptr         = ep_ptr->header.owner_ia;
-    ep_ptr->cr_ptr = NULL;
-    retry_cnt      = 0;
-    dat_status     = DAT_SUCCESS;
-
-    p_ca = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;
-
-    /*
-     * We are using the first active port in the list for
-     * communication. We have to get back here when we decide to support
-     * fail-over and high-availability.
-     */
-    p_active_port = dapli_ibal_get_port ( p_ca,
-                                          (uint8_t)ia_ptr->hca_ptr->port_num );
-
-    if (NULL == p_active_port)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"--> DsC: Port %d not available %d\n",
-                       ia_ptr->hca_ptr->port_num, __LINE__ );
-        return (DAT_INVALID_STATE);
-    }
-
-    dapl_os_memzero (&dest_GID, sizeof (GID));
-    dapl_os_memzero (&cm_req, sizeof (ib_cm_req_t));
-    dapl_os_memzero (&path_rec, sizeof (ib_path_rec_t));
-    dapl_os_memzero (&service_rec, sizeof (ib_service_record_t));
-    dapl_os_memzero (&query_req, sizeof (ib_query_req_t));
-    dapl_os_memzero (&gid_pair, sizeof (ib_gid_pair_t));
-    dapl_os_memzero (&ep_ptr->remote_ia_address, sizeof (DAT_SOCK_ADDR6));
-
-    dapl_os_memcpy (&ep_ptr->remote_ia_address, 
-                    remote_ia_address, 
-                    sizeof (ep_ptr->remote_ia_address));
-
-
-#ifdef NO_NAME_SERVICE
-
-    if (DAT_SUCCESS !=
-        (dat_status = dapls_ns_lookup_address (
-                                         ia_ptr,
-                                         remote_ia_address,
-                                         &dest_GID         )))
-    {
-        /*
-         * Remote address not in the table, this is a
-         * strange return code!
-         */
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"--> DsC: exits status = %x\n", dat_status);
-        return dat_status;
-    }
-
-    dest_GID.guid = CL_HTON64 (dest_GID.guid);
-    dest_GID.gid_prefix = CL_HTON64 (dest_GID.gid_prefix);
-
-#else
-
-    /*
-     * We query the SA to get the dest_gid with the 
-     * {uDAPL_svc_id, IP-address} as the key to get GID.
-     */
-    if (DAT_SUCCESS !=
-        (dat_status = dapls_ns_map_gid (ia_ptr->hca_ptr, 
-                                        remote_ia_address,
-                                        &dest_GID)))
-        
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR, "--> DsC: fail to map remote_ia_addr "
-                       "(sa_family %d) to gid\n",
-                       remote_ia_address->sa_family); 
-        return dat_status;
-    }
-#endif /* NO_NAME_SERVICE */
-
-    gid_pair.dest_gid.unicast.interface_id = dest_GID.guid;
-    gid_pair.dest_gid.unicast.prefix       = dest_GID.gid_prefix;
-
-    dapl_dbg_log (DAPL_DBG_TYPE_CM, 
-                  "dapls_ib_connect: EP %lx QP %lx SERVER GID{0x" F64x
-                  ", 0x" F64x "}\n", 
-                  ep_ptr, ep_ptr->qp_handle,
-                  cl_hton64 (gid_pair.dest_gid.unicast.prefix),
-                  cl_hton64 (gid_pair.dest_gid.unicast.interface_id));
-
-    gid_pair.src_gid = p_active_port->p_attr->p_gid_table[0];
-/*
-    if ((gid_pair.src_gid.unicast.interface_id == 
-         gid_pair.dest_gid.unicast.interface_id   ) &&
-        (gid_pair.src_gid.unicast.prefix == 
-         gid_pair.dest_gid.unicast.prefix   ))
-    {
-        path_rec.dgid     = gid_pair.dest_gid;
-        path_rec.sgid     = gid_pair.src_gid;
-        path_rec.slid     = path_rec.dlid = p_active_port->p_attr->lid;
-        path_rec.pkey     = p_active_port->p_attr->p_pkey_table[0];
-        path_rec.mtu      = p_active_port->p_attr->mtu;
-               path_rec.pkt_life = 18;  // 1 sec
-               path_rec.rate     = IB_PATH_RECORD_RATE_10_GBS;
-       
-       }
-    else
-    {
-  */
-        /*
-         * Query SA to get the path record from pair of GIDs
-         */
-        dapl_os_memzero (&query_req, sizeof (ib_query_req_t));
-        query_req.query_type      = IB_QUERY_PATH_REC_BY_GIDS;
-        query_req.p_query_input   = (void *) &gid_pair;
-        query_req.flags           = IB_FLAGS_SYNC;  
-        query_req.timeout_ms      = 1 * 1000;       /* 1 second */
-        query_req.retry_cnt       = 3;
-        /* query SA using this port */
-        query_req.port_guid       = p_active_port->p_attr->port_guid;
-        query_req.query_context   = (void *) &path_rec;
-        query_req.pfn_query_cb    = dapli_ib_sa_query_cb;
-        ib_status = ib_query (dapl_ibal_root.h_al, &query_req, NULL);
-
-        if ((ib_status != IB_SUCCESS) || (!path_rec.dlid))
-        {
-            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"--> DsC: EP %lx QP %lx query "
-                           "pair_gids status = %s\n", 
-                           ep_ptr, ep_ptr->qp_handle,ib_get_err_str(ib_status));
-            return DAT_INVALID_PARAMETER;
-        }
-
-    //}
-
-       /*
-        * Tavor has a HW bug that causes bandwidth with 2K MTU to be less than
-        * with 1K MTU.  Cap the MTU based on device ID to compensate for this.
-        */
-       if( (p_ca->p_ca_attr->dev_id == 0x5A44) &&
-               (ib_path_rec_mtu( &path_rec ) > IB_MTU_LEN_1024) )
-       {
-            /* Local endpoint is Tavor - cap MTU to 1K for extra bandwidth. */
-            path_rec.mtu &= IB_PATH_REC_SELECTOR_MASK;
-            path_rec.mtu |= IB_MTU_LEN_1024;
-       }
-
-       /* 
-     * prepare the Service ID from conn_qual 
-     */
-    cm_req.svc_id           = remote_conn_qual;
-    cm_req.p_primary_path   = &path_rec;
-    cm_req.p_alt_path       = NULL;
-    cm_req.h_qp             = ep_ptr->qp_handle;
-    cm_req.qp_type          = IB_QPT_RELIABLE_CONN;
-    cm_req.p_req_pdata      = (uint8_t *) private_data;
-    cm_req.req_length       = (uint8_t)
-                               min(private_data_size,IB_MAX_REQ_PDATA_SIZE);
-    /* cm retry to send this request messages, IB max of 4 bits */
-    cm_req.max_cm_retries   = 15; /* timer outside of call, s/be infinite */
-    /* qp retry to send any wr */
-    cm_req.retry_cnt        = 5;
-    /* max num of oustanding RDMA read/atomic support */
-    cm_req.resp_res         = (uint8_t)ep_ptr->param.ep_attr.max_rdma_read_in;
-    /* max num of oustanding RDMA read/atomic will use */
-    cm_req.init_depth       = (uint8_t)ep_ptr->param.ep_attr.max_rdma_read_out;
-
-    /* time wait before retrying a pkt after receiving a RNR NAK */
-    cm_req.rnr_nak_timeout  = IB_RNR_NAK_TIMEOUT;
-    
-       /* 
-     * number of time local QP should retry after receiving RNR NACK before
-     * reporting an error
-     */
-    cm_req.rnr_retry_cnt       = IB_RNR_RETRY_CNT;
-
-    cm_req.remote_resp_timeout = 16;   /* 250ms */
-    cm_req.local_resp_timeout  = 16;   /* 250ms */
-    
-    cm_req.flow_ctrl           = TRUE;
-    cm_req.flags               = 0;
-    /*
-     * We do not use specific data buffer to check for specific connection
-     */
-    cm_req.p_compare_buffer    = NULL;
-    cm_req.compare_offset      = 0;
-    cm_req.compare_length      = 0;
-
-    dapl_dbg_log (DAPL_DBG_TYPE_CM, "--> DsConn: EP=%lx QP=%lx rio=%d,%d pl=%d "
-                  "mtu=%d slid=%#x dlid=%#x\n", 
-                  ep_ptr, ep_ptr->qp_handle,  cm_req.resp_res, 
-                  cm_req.init_depth, ib_path_rec_pkt_life(&path_rec),
-                  ib_path_rec_mtu(&path_rec),
-                  cm_req.p_primary_path->slid,
-                  cm_req.p_primary_path->dlid);
-
-    /*
-     * We do not support peer_to_peer; therefore, we set pfn_cm_req_cb = NULL
-     */
-    cm_req.pfn_cm_req_cb       = NULL;
-    cm_req.pfn_cm_rep_cb       = dapli_ib_cm_rep_cb;
-    cm_req.pfn_cm_rej_cb       = dapli_ib_cm_rej_cb;
-    /* callback when a message received acknowledgement is received */
-    cm_req.pfn_cm_mra_cb       = dapli_ib_cm_mra_cb;
-
-    ib_status = ib_cm_req (&cm_req);
-    
-    if ( ib_status != IB_SUCCESS )
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> DsC: EP %lx QP %lx conn_request failed = %s\n", 
-                       ep_ptr, ep_ptr->qp_handle, ib_get_err_str(ib_status));
-
-        return  (dapl_ib_status_convert (ib_status));
-    }
-
-    return DAT_SUCCESS;
-}
-
-
-/*
- * dapls_ib_disconnect
- *
- * Disconnect an EP
- *
- * Input:
- *        ep_handle,
- *        disconnect_flags
- *           DAT_CLOSE_ABRUPT_FLAG - no callback
- *           DAT_CLOSE_GRACEFUL_FLAG - callback desired.
- *
- * Output:
- *         none
- *
- * Returns:
- *        DAT_SUCCESS
- *        DAT_INSUFFICIENT_RESOURCES
- *        DAT_INVALID_PARAMETER
- *
- */
-DAT_RETURN
-dapls_ib_disconnect ( IN   DAPL_EP           *ep_ptr,
-                      IN   DAT_CLOSE_FLAGS   disconnect_flags )
-{
-    ib_api_status_t    ib_status = IB_SUCCESS;
-    ib_cm_dreq_t                   cm_dreq;
-
-    dapl_os_assert(ep_ptr);
-
-    if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )
-    {
-         dapl_dbg_log (DAPL_DBG_TYPE_CM,
-                  "--> %s: BAD EP Magic EP=%lx\n", __FUNCTION__,ep_ptr); 
-        return DAT_SUCCESS;
-    }
-
-    if (ep_ptr->cm_handle == DAPL_IB_INVALID_HANDLE )
-    {
-         dapl_dbg_log (DAPL_DBG_TYPE_CM,
-                  "--> %s: Invalid EP->CM handle, OK.\n", __FUNCTION__); 
-        return DAT_SUCCESS;
-    }
-
-    dapl_dbg_log (DAPL_DBG_TYPE_CM,
-       "--> %s() EP %p %s rx_drq %d tx_drq %d Close %s\n", __FUNCTION__,
-       ep_ptr, dapl_get_ep_state_str(ep_ptr->param.ep_state),
-                  ep_ptr->recv_discreq, ep_ptr->sent_discreq,
-       (disconnect_flags == DAT_CLOSE_ABRUPT_FLAG ? "Abrupt":"Graceful"));
-
-    if ( disconnect_flags == DAT_CLOSE_ABRUPT_FLAG )
-    {
-       if ( ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED )
-        return DAT_SUCCESS;
-
-       if ( ep_ptr->param.ep_state != DAT_EP_STATE_DISCONNECT_PENDING )
-    {
-           dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                       "%s() calling legacy_post_disconnect()\n",__FUNCTION__);
-            dapl_ep_legacy_post_disconnect(ep_ptr, disconnect_flags);
-            return DAT_SUCCESS;
-       }
-    }
-
-    dapl_os_memzero(&cm_dreq, sizeof(ib_cm_dreq_t));
-
-    cm_dreq.qp_type        = IB_QPT_RELIABLE_CONN;
-    cm_dreq.h_qp           = ep_ptr->qp_handle;
-    cm_dreq.pfn_cm_drep_cb = dapli_ib_cm_drep_cb;
-    
-    /* 
-     * Currently we do not send any disconnect private data to
-     * the other endpoint because DAT 2.0 does not support it.  
-     */
-    cm_dreq.p_dreq_pdata   = NULL;
-    cm_dreq.flags          = IB_FLAGS_SYNC;
-
-    /*
-     * still need to send DREQ (disconnect request)?
-     */
-    if ( (ep_ptr->recv_discreq == DAT_FALSE)
-          && (ep_ptr->sent_discreq == DAT_FALSE)
-         && (ep_ptr->qp_state != IB_QPS_RESET) )
-    {
-        ep_ptr->sent_discreq = DAT_TRUE;
-        ib_status = ib_cm_dreq ( &cm_dreq );
-
-       if ( ib_status == IB_SUCCESS )
-           dapl_dbg_log (DAPL_DBG_TYPE_CM,
-                       "--> DsD: EP %p  DREQ SENT\n", ep_ptr);
-
-       /* tolerate INVALID_STATE error as the other side can race ahead and
-        * generate a DREQ before we do.
-        */
-       if ( ib_status == IB_INVALID_STATE || ib_status == IB_INVALID_HANDLE )
-       {
-           ib_status = IB_SUCCESS;
-       }
-       else if (ib_status)
-       {
-           dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                       "%s() EP %p ib_cm_dreq() status %s\n",
-                       __FUNCTION__,ep_ptr,ib_get_err_str(ib_status));
-       }
-    }
-    return ib_status;
-}
-
-
-/*
- * dapl_ib_setup_conn_listener
- *
- * Have the CM set up a connection listener.
- *
- * Input:
- *        ibm_hca_handle           HCA handle
- *        qp_handle                QP handle
- *
- * Output:
- *         none
- *
- * Returns:
- *         DAT_SUCCESS
- *        DAT_INSUFFICIENT_RESOURCES
- *        DAT_INVALID_PARAMETER
- *
- */
-DAT_RETURN
-dapls_ib_setup_conn_listener (
-        IN  DAPL_IA               *ia_ptr,
-        IN  DAT_UINT64            ServiceID,
-        IN  DAPL_SP               *sp_ptr )
-{
-    ib_api_status_t               ib_status;
-    ib_cm_listen_t                cm_listen;
-    dapl_ibal_ca_t                *p_ca;
-    dapl_ibal_port_t              *p_active_port;
-
-    p_ca = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;
-
-    /*
-     * We are using the first active port in the list for
-     * communication. We have to get back here when we decide to support
-     * fail-over and high-availability.
-     */
-    p_active_port = dapli_ibal_get_port( p_ca,
-                                       (uint8_t)ia_ptr->hca_ptr->port_num );
-
-    if (NULL == p_active_port)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"%s: SP %lx port %d not available\n",
-                __FUNCTION__, sp_ptr, ia_ptr->hca_ptr->port_num );
-        return (DAT_INVALID_STATE);
-    }
-
-    if (p_active_port->p_attr->lid == 0)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> DsSCL: SP %lx SID 0x" F64x " port %d\n", 
-                       sp_ptr, cl_hton64(ServiceID),
-                       p_active_port->p_attr->port_num);
-        return (DAT_INVALID_STATE);
-    }
-
-    dapl_dbg_log (DAPL_DBG_TYPE_CM,
-         "%s: SP %lx port %d GID{0x" F64x ", 0x" F64x "} and SID 0x" F64x "\n", 
-         __FUNCTION__,
-         sp_ptr, p_active_port->p_attr->port_num,
-         cl_hton64 (p_active_port->p_attr->p_gid_table[0].unicast.prefix),
-         cl_hton64 (p_active_port->p_attr->p_gid_table[0].unicast.interface_id),
-         cl_hton64 (ServiceID));
-    
-    dapl_os_memzero (&cm_listen, sizeof (ib_cm_listen_t));
-
-    /*
-     * Listen for all request on  this specific CA
-     */
-    cm_listen.ca_guid = (p_ca->p_ca_attr->ca_guid);
-    cm_listen.svc_id  = ServiceID;
-    cm_listen.qp_type = IB_QPT_RELIABLE_CONN; 
-
-    /*
-     * We do not use specific data buffer to check for specific connection
-     */
-    cm_listen.p_compare_buffer = NULL;//(uint8_t*)&sp_ptr->conn_qual;
-    cm_listen.compare_offset   = 0;//IB_MAX_REQ_PDATA_SIZE - sizeof(DAT_CONN_QUAL);
-    cm_listen.compare_length   = 0;//sizeof(DAT_CONN_QUAL);
-
-    /*
-     * We can pick a port here for communication and the others are reserved
-     * for fail-over / high-availability - TBD
-     */
-    cm_listen.port_guid     = p_active_port->p_attr->port_guid;
-    cm_listen.lid           = p_active_port->p_attr->lid;
-    cm_listen.pkey          = p_active_port->p_attr->p_pkey_table[0];
-
-    /*
-     * Register request or mra callback functions
-     */
-    cm_listen.pfn_cm_req_cb = dapli_ib_cm_req_cb;
-
-    ib_status = ib_cm_listen ( dapl_ibal_root.h_al,
-                               &cm_listen,
-                               (void *) sp_ptr,
-                               &sp_ptr->cm_srvc_handle );
-
-    if (ib_status != IB_SUCCESS)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "%s: SP %lx SID 0x" F64x " listen failed %s\n", 
-                       __FUNCTION__, sp_ptr, cl_hton64 (ServiceID),
-                       ib_get_err_str(ib_status));
-    }
-
-    return dapl_ib_status_convert (ib_status);
-}
-
-
-/*
- * dapl_ib_remove_conn_listener
- *
- * Have the CM remove a connection listener.
- *
- * Input:
- *      ia_handle               IA handle
- *      ServiceID               IB Channel Service ID
- *
- * Output:
- *      none
- *
- * Returns:
- *      DAT_SUCCESS
- *      DAT_INVALID_PARAMETER
- *
- */
-DAT_RETURN
-dapls_ib_remove_conn_listener (
-        IN  DAPL_IA        *ia_ptr,
-        IN  DAPL_SP        *sp_ptr )
-{
-    ib_api_status_t        ib_status;
-    DAT_RETURN             dat_status = DAT_SUCCESS;
-       
-    UNUSED_PARAM( ia_ptr );
-
-    dapl_os_assert ( sp_ptr );
-
-    dapl_os_assert ( sp_ptr->header.magic == DAPL_MAGIC_PSP ||
-         sp_ptr->header.magic == DAPL_MAGIC_RSP );
-
-    dapl_dbg_log ( DAPL_DBG_TYPE_CM, "%s() cm_srvc_handle %lx\n",
-                   __FUNCTION__, sp_ptr->cm_srvc_handle );
-
-    if (sp_ptr->cm_srvc_handle)
-    {
-        ib_status = ib_cm_cancel ( sp_ptr->cm_srvc_handle, 
-                                   NULL );
-        
-        if (ib_status != IB_SUCCESS)
-        {
-            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                           "--> DsRCL: SP %lx ib_cm_cancel failed(0x%x) %s\n", 
-                           sp_ptr, sp_ptr->cm_srvc_handle,
-                           ib_get_err_str(ib_status));
-            sp_ptr->cm_srvc_handle = NULL;
-            return (DAT_INVALID_PARAMETER);
-        }
-
-        sp_ptr->cm_srvc_handle = NULL;
-    }
-
-    return dat_status;
-}
-
-/*
- * dapls_ib_reject_connection
- *
- * Perform necessary steps to reject a connection
- *
- * Input:
- *        cr_handle
- *
- * Output:
- *         none
- *
- * Returns:
- *         DAT_SUCCESS
- *        DAT_INSUFFICIENT_RESOURCES
- *        DAT_INVALID_PARAMETER
- *
- */
-DAT_RETURN
-dapls_ib_reject_connection ( IN  dp_ib_cm_handle_t   ib_cm_handle,
-                             IN  int                 reject_reason,
-                             IN  DAT_COUNT           private_data_size,
-                             IN  const DAT_PVOID     private_data)
-{
-    ib_api_status_t        ib_status;
-    ib_cm_rej_t            cm_rej;
-    static char            *rej_table[] =
-    {
-        "INVALID_REJ_REASON",
-        "INVALID_REJ_REASON",
-        "INVALID_REJ_REASON",
-        "INVALID_REJ_REASON",
-        "INVALID_REJ_REASON",
-        "IB_CME_DESTINATION_REJECT",
-        "IB_CME_DESTINATION_REJECT_PRIVATE_DATA",
-        "IB_CME_DESTINATION_UNREACHABLE",
-        "IB_CME_TOO_MANY_CONNECTION_REQUESTS",
-        "IB_CME_LOCAL_FAILURE",
-        "IB_CM_LOCAL_FAILURE"
-    };
-
-#define REJ_TABLE_SIZE  IB_CM_LOCAL_FAILURE
-
-    reject_reason = __min( reject_reason & 0xff, REJ_TABLE_SIZE);
-
-    cm_rej.rej_status   = IB_REJ_USER_DEFINED;
-    cm_rej.p_ari        = (ib_ari_t *)&rej_table[reject_reason]; 
-    cm_rej.ari_length   = (uint8_t)strlen (rej_table[reject_reason]);
-
-    if (private_data_size > 
-       dapls_ib_private_data_size(NULL,DAPL_PDATA_CONN_REJ,NULL))
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> DsRjC: private_data size(%d) > Max(%d)\n", 
-                       private_data_size, IB_MAX_REJ_PDATA_SIZE );
-       return DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3);
-    }
-
-    cm_rej.p_rej_pdata  = private_data;
-    cm_rej.rej_length   = private_data_size;
-
-#if defined(DAPL_DBG) && 0
-    dapli_print_private_data("DsRjC",private_data,private_data_size);
-#endif
-
-    ib_status = ib_cm_rej ( *ib_cm_handle, &cm_rej);
-
-    if (ib_status != IB_SUCCESS)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> DsRjC: cm_handle %lx reject failed %s\n", 
-                       ib_cm_handle, ib_get_err_str(ib_status) );
-    }
-
-    return ( dapl_ib_status_convert ( ib_status ) );
-}
-
-
-
-#if 0
-static void
-dapli_query_qp( ib_qp_handle_t qp_handle, ib_qp_attr_t  *qpa )
-{
-    ib_api_status_t        ib_status;
-    
-    ib_status = ib_query_qp ( qp_handle, qpa );
-    if (ib_status != IB_SUCCESS)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"ib_query_qp(%lx) '%s'\n",
-                qp_handle, ib_get_err_str(ib_status) );
-    }
-    else
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_CM, "--> QP(%lx) state %s "
-                       "type %d init %d acc %x\n",
-                       qp_handle,
-                       ib_get_port_state_str(qpa->state),
-                       qpa->qp_type,
-                       qpa->init_depth,
-                       qpa->access_ctrl );
-    }
-}
-#endif
-
-
-/*
- * dapls_ib_accept_connection
- *
- * Perform necessary steps to accept a connection
- *
- * Input:
- *        cr_handle
- *        ep_handle
- *        private_data_size
- *        private_data
- *
- * Output:
- *         none
- *
- * Returns:
- *         DAT_SUCCESS
- *        DAT_INSUFFICIENT_RESOURCES
- *        DAT_INVALID_PARAMETER
- *
- */
-DAT_RETURN
-dapls_ib_accept_connection (
-        IN        DAT_CR_HANDLE            cr_handle,
-        IN        DAT_EP_HANDLE            ep_handle,
-        IN        DAT_COUNT                private_data_size,
-        IN const  DAT_PVOID                private_data )
-{
-    DAPL_CR                *cr_ptr;
-    DAPL_EP                *ep_ptr;
-    DAPL_IA                *ia_ptr;
-    DAT_RETURN             dat_status;
-    ib_api_status_t        ib_status;
-    dapl_ibal_ca_t         *p_ca;
-    dapl_ibal_port_t       *p_active_port;
-    ib_cm_rep_t            cm_rep;
-    ib_qp_attr_t           qpa;
-
-    cr_ptr = (DAPL_CR *) cr_handle;
-    ep_ptr = (DAPL_EP *) ep_handle;
-    ia_ptr = ep_ptr->header.owner_ia;
-
-    if ( ep_ptr->qp_state == DAPL_QP_STATE_UNATTACHED )
-    {
-        /*
-         * If we are lazy attaching the QP then we may need to
-         * hook it up here. Typically, we run this code only for
-         * DAT_PSP_PROVIDER_FLAG
-         */
-        dat_status = dapls_ib_qp_alloc ( ia_ptr, ep_ptr, ep_ptr );
-
-        if ( dat_status != DAT_SUCCESS)
-        {
-            /* This is not a great error code, but all the spec allows */
-            dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                           "-->  DsIBAC: CR %lx EP %lx alloc QP failed 0x%x\n",
-                           cr_ptr, ep_ptr, dat_status );
-            return (dat_status);
-        }
-    }
-
-    p_ca = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;
-    p_active_port = dapli_ibal_get_port ( p_ca,
-                                          (uint8_t)ia_ptr->hca_ptr->port_num );
-    if (NULL == p_active_port)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> DsIBAC: CR %lx EP %lx port %d is not available\n",
-                       cr_ptr, ep_ptr, ia_ptr->hca_ptr->port_num);
-        return (DAT_INVALID_STATE);
-    }
-
-    cr_ptr->param.local_ep_handle = ep_handle;
-    ep_ptr->cm_handle             = cr_ptr->ib_cm_handle;
-    /*
-     * assume ownership, in that once the EP is released the dynamic
-     * memory containing the IBAL CM handle (ib_cm_handle_t) struct will
-     * be released; see dapl_ep_dealloc().
-     */
-    ep_ptr->ibal_cm_handle        = cr_ptr->ib_cm_handle;
-
-    /* set remote IP addr fields. IP addr data is deduced from Connection
-     * Request record (gid/lib) and stashed away for use here. DAPL 1.1
-     * had an interface for passing the IP info down, interface went away
-     * in 2.0?
-     */
-    dapl_os_memcpy( (void*)&ep_ptr->remote_ia_address,
-                    (void*)(ep_ptr->cm_handle+1),
-                    sizeof(DAT_SOCK_ADDR6) );
-
-    dapl_os_memcpy( (void*)&cr_ptr->remote_ia_address,
-                    (void*)&ep_ptr->remote_ia_address,
-                    sizeof(DAT_SOCK_ADDR6) );
-
-#if defined(DAPL_DBG) && 0
-    {
-        char ipa[20];
-
-        dapl_dbg_log (DAPL_DBG_TYPE_CM|DAPL_DBG_TYPE_CALLBACK, 
-                      "%s: EP(%lx) RemoteAddr: %s\n",
-                      __FUNCTION__, ep_ptr,
-                     dapli_get_ip_addr_str(
-                             (DAT_SOCK_ADDR6*)&ep_ptr->remote_ia_address, ipa));
-    }
-#endif
-
-    ep_ptr->qp_state      = IB_QPS_INIT;
-    ep_ptr->cr_ptr        = cr_ptr;
-
-    dapl_os_memzero ( (void*)&cm_rep, sizeof (ib_cm_rep_t) );
-
-    cm_rep.h_qp           = ep_ptr->qp_handle;
-    cm_rep.qp_type        = IB_QPT_RELIABLE_CONN;
-
-    if (private_data_size > IB_MAX_REP_PDATA_SIZE) {
-       dapl_dbg_log (DAPL_DBG_TYPE_ERR,
-                       "--> DsIBAC: private_data_size(%d) > Max(%d)\n",
-                       private_data_size, IB_MAX_REP_PDATA_SIZE);
-       return DAT_ERROR(DAT_LENGTH_ERROR, DAT_NO_SUBTYPE);
-                                 
-        }
-    cm_rep.p_rep_pdata    = (const uint8_t *)private_data;
-    cm_rep.rep_length     = private_data_size;
-                            
-#if defined(DAPL_DBG) && 0
-    dapli_print_private_data( "DsIBAC",
-                             (const uint8_t*)private_data,
-                             private_data_size );
-#endif
-
-    cm_rep.pfn_cm_rej_cb = dapli_ib_cm_rej_cb;
-    cm_rep.pfn_cm_mra_cb = dapli_ib_cm_mra_cb;
-    cm_rep.pfn_cm_rtu_cb  = dapli_ib_cm_rtu_cb;
-    cm_rep.pfn_cm_lap_cb  = dapli_ib_cm_lap_cb;
-    cm_rep.pfn_cm_dreq_cb = dapli_ib_cm_dreq_cb;
-
-    /*
-     * FIXME - Vu
-     *         Pay attention to the attributes. 
-     *         Some of them are desirably set by DAT consumers
-     */
-    /*
-     * We enable the qp associate with this connection ep all the access right
-     * We enable the flow_ctrl, retry till success
-     * We will limit the access right and flow_ctrl upon DAT consumers 
-     * requirements
-     */
-    cm_rep.access_ctrl =
-               IB_AC_LOCAL_WRITE|IB_AC_RDMA_WRITE|IB_AC_MW_BIND|IB_AC_ATOMIC;
-
-    if ((ep_ptr->param.ep_attr.max_rdma_read_in > 0) 
-               || (ep_ptr->param.ep_attr.max_rdma_read_out > 0))
-    {
-       cm_rep.access_ctrl |= IB_AC_RDMA_READ;
-    }
-
-    cm_rep.sq_depth          = 0;
-    cm_rep.rq_depth          = 0;
-    cm_rep.init_depth        = (uint8_t)ep_ptr->param.ep_attr.max_rdma_read_out;
-    cm_rep.flow_ctrl         = TRUE;
-    cm_rep.flags             = 0;
-    cm_rep.failover_accepted = IB_FAILOVER_ACCEPT_UNSUPPORTED;
-    cm_rep.target_ack_delay  = 14;
-    cm_rep.rnr_nak_timeout   = IB_RNR_NAK_TIMEOUT;
-    cm_rep.rnr_retry_cnt     = IB_RNR_RETRY_CNT;
-    cm_rep.pp_recv_failure   = NULL;
-    cm_rep.p_recv_wr         = NULL;
-     
-    dapl_dbg_log (DAPL_DBG_TYPE_CM,
-                 "--> DsIBAC: cm_rep: acc %x init %d qp_type %x req_count %d\n",
-                cm_rep.access_ctrl, cm_rep.init_depth,cm_rep.qp_type,
-                 dapls_cb_pending(&ep_ptr->req_buffer));
-
-    ib_status = ib_cm_rep ( *ep_ptr->cm_handle, &cm_rep );
-
-    if (ib_status != IB_SUCCESS)
-    {
-       dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> DsIBAC: EP %lx QP %lx CR reply failed '%s'\n",
-                       ep_ptr, ep_ptr->qp_handle, ib_get_err_str(ib_status) );
-
-        /* errors not perculated back to CR callback which allocated the
-         * memory, free it here on error.
-         */
-        dapl_os_free ( (void*)ep_ptr->ibal_cm_handle, sizeof(ib_cm_handle_t) );
-        ep_ptr->ibal_cm_handle = NULL;
-    }
-    return ( dapl_ib_status_convert ( ib_status ) );
-}
-
-
-
-/*
- * dapls_ib_disconnect_clean
- *
- * Clean up outstanding connection data. This routine is invoked
- * after the final disconnect callback has occurred. Only on the
- * ACTIVE side of a connection.
- *
- * Input:
- *        ep_ptr                DAPL_EP
- *
- * Output:
- *         none
- *
- * Returns:
- *         void
- *
- */
-void
-dapls_ib_disconnect_clean (
-        IN  DAPL_EP                     *ep_ptr,
-        IN  DAT_BOOLEAN                 active,
-        IN  const ib_cm_events_t        ib_cm_event )
-{
-    DAPL_IA            *ia_ptr;
-    ib_qp_attr_t       qp_attr;
-    ib_api_status_t     ib_status;
-
-    dapl_dbg_log ( DAPL_DBG_TYPE_CM, "%s(%s): cm_event: %s \n", __FUNCTION__,
-                   (active?"A":"P"), dapli_ib_cm_event_str(ib_cm_event));
-
-    ia_ptr = ep_ptr->header.owner_ia;
-    
-    if ( ia_ptr == NULL || ia_ptr->header.magic != DAPL_MAGIC_IA )
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_CM,
-                       ">>>DSCONN_CLEAN(%s): cm_event: %s Invalid IA_ptr\n",
-                       (active?"Act":"Pas"),dapli_ib_cm_event_str(ib_cm_event));
-        return;
-    }
-    dapl_os_assert ( ep_ptr->header.magic == DAPL_MAGIC_EP );
-    
-    ep_ptr->sent_discreq = DAT_FALSE;
-    ep_ptr->recv_discreq = DAT_FALSE;
-    if ( ep_ptr->ibal_cm_handle )
-    {
-        dapl_os_free ( (void*)ep_ptr->ibal_cm_handle, sizeof(ib_cm_handle_t) );
-    }
-    ep_ptr->ibal_cm_handle = NULL;
-
-    /* 
-     * Query the QP to get the current state */
-    ib_status = ib_query_qp ( ep_ptr->qp_handle, &qp_attr );
-                       
-    if ( ib_status != IB_SUCCESS )
-    {
-           dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       ">>>DSCONN_CLEAN(%s): Query QP failed = %s\n",
-                       (active?"Act":"Pas"),ib_get_err_str(ib_status) );
-       return;
-    }
-    
-    ep_ptr->qp_state = qp_attr.state;
-
-    dapl_dbg_log ( DAPL_DBG_TYPE_CM, ">>>DSCONN_CLEAN(%s): cm_event: %d "
-                   "ep_ptr %lx ep_state %s qp_state %#x\n", 
-                   (active?"A":"P"), ib_cm_event, ep_ptr,
-                   dapl_get_ep_state_str(ep_ptr->param.ep_state),
-                   ep_ptr->qp_state );
-
-    if ( ep_ptr->qp_state != IB_QPS_ERROR &&
-         ep_ptr->qp_state != IB_QPS_RESET &&
-         ep_ptr->qp_state != IB_QPS_INIT )
-    {
-        ep_ptr->qp_state = IB_QPS_ERROR;
-        dapls_modify_qp_state_to_error (ep_ptr->qp_handle);
-    }
-}
-
-
-#ifdef NOT_USED
-/*
- * dapls_ib_cr_handoff
- *
- * Hand off the connection request to another service point  
- *
- * Input:
- *        cr_handle                DAT_CR_HANDLE
- *        handoff_serv_id          DAT_CONN_QUAL
- *
- * Output:
- *         none
- *
- * Returns:
- *         DAT_SUCCESS
- *         DAT_INVALID_PARAMETER
- *
- */
-DAT_RETURN 
-dapls_ib_cr_handoff (
-        IN  DAT_CR_HANDLE      cr_handle,
-        IN  DAT_CONN_QUAL      handoff_serv_id )
-{
-    DAPL_CR                *cr_ptr;
-    ib_api_status_t        ib_status;
-    
-    cr_ptr = (DAPL_CR *) cr_handle;
-
-    if (cr_ptr->ib_cm_handle->cid == 0xFFFFFFFF)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> DsCH: CR = %lx invalid cm handle\n", cr_ptr);
-        return DAT_INVALID_PARAMETER;
-    }
-
-    if (cr_ptr->sp_ptr == DAPL_IB_INVALID_HANDLE)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> DsCH: CR = %lx invalid psp handle\n", cr_ptr);
-        return DAT_INVALID_PARAMETER;
-    }
-
-    ib_status = ib_cm_handoff (*cr_ptr->ib_cm_handle, handoff_serv_id);
-
-    if (ib_status != IB_SUCCESS)
-    {
-        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
-                       "--> DsCH: CR = %lx handoff failed = %s\n", 
-                       cr_ptr, ib_get_err_str(ib_status) );
-
-        return dapl_ib_status_convert (ib_status);
-    }
-
-    dapl_dbg_log ( DAPL_DBG_TYPE_CM,
-                   "--> %s(): remove CR %lx from SP %lx Queue\n",
-                   __FUNCTION__, cr_ptr, cr_ptr->sp_ptr);
-    /* Remove the CR from the queue */
-    dapl_sp_remove_cr (cr_ptr->sp_ptr, cr_ptr);
-
-    /*
-     * If this SP has been removed from service, free it
-     * up after the last CR is removed
-     */
-    dapl_os_lock (&cr_ptr->sp_ptr->header.lock);
-    if ( cr_ptr->sp_ptr->listening != DAT_TRUE && 
-         cr_ptr->sp_ptr->cr_list_count == 0 &&
-         cr_ptr->sp_ptr->state != DAPL_SP_STATE_FREE )
-    {
-        dapl_dbg_log (DAPL_DBG_TYPE_CM, 
-                      "--> DsCH: CR = %lx disconnect dump SP = %lx \n", 
-                      cr_ptr, cr_ptr->sp_ptr);
-        /* Decrement the ref count on the EVD */
-        if (cr_ptr->sp_ptr->evd_handle)
-        {
-            dapl_os_atomic_dec (& ((DAPL_EVD *)cr_ptr->sp_ptr->evd_handle)->evd_ref_count);
-            cr_ptr->sp_ptr->evd_handle = NULL;
-        }
-        cr_ptr->sp_ptr->state = DAPL_SP_STATE_FREE;
-        dapl_os_unlock (&cr_ptr->sp_ptr->header.lock);
-        (void)dapls_ib_remove_conn_listener ( cr_ptr->sp_ptr->header.owner_ia,
-                                              cr_ptr->sp_ptr );
-        dapls_ia_unlink_sp ( (DAPL_IA *)cr_ptr->sp_ptr->header.owner_ia,
-                             cr_ptr->sp_ptr );
-        dapls_sp_free_sp ( cr_ptr->sp_ptr );
-    }
-    else
-    {
-        dapl_os_unlock (&cr_ptr->sp_ptr->header.lock);
-    }
-
-    /*
-     * Clean up and dispose of the resource
-     */
-    dapls_cr_free (cr_ptr);
-
-    return (DAT_SUCCESS);
-}
-#endif
-
-/*
- * dapls_ib_private_data_size
- *
- * Return the size of private data given a connection op type
- *
- * Input:
- *     prd_ptr         private data pointer
- *     conn_op         connection operation type
- *     hca_ptr         hca pointer, needed for transport type
- *
- * If prd_ptr is NULL, this is a query for the max size supported by
- * the provider, otherwise it is the actual size of the private data
- * contained in prd_ptr.
- *
- * Infiniband has fixed size private data, so prd_ptr is ignored.
- *
- * Output:
- *     None
- *
- * Returns:
- *     length of private data
- *
- */
-int
-dapls_ib_private_data_size (
-       IN      DAPL_PRIVATE            *prd_ptr,
-       IN      DAPL_PDATA_OP           conn_op,
-       IN      DAPL_HCA                *hca_ptr)
-{
-    int  size;
-
-    UNUSED_PARAM( prd_ptr );
-    UNUSED_PARAM( hca_ptr );
-
-    switch (conn_op)
-    {
-        case DAPL_PDATA_CONN_REQ:
-       {
-           size = IB_MAX_REQ_PDATA_SIZE;
-           break;
-       }
-        case DAPL_PDATA_CONN_REP:
-       {
-           size = IB_MAX_REP_PDATA_SIZE;
-           break;
-       }
-        case DAPL_PDATA_CONN_REJ:
-       {
-           size = IB_MAX_REJ_PDATA_SIZE;
-           break;
-       }
-        case DAPL_PDATA_CONN_DREQ:
-       {
-           size = IB_MAX_DREQ_PDATA_SIZE;
-           break;
-       }
-        case DAPL_PDATA_CONN_DREP:
-       {
-           size = IB_MAX_DREP_PDATA_SIZE;
-           break;
-       }
-        default:
-       {
-           size = 0;
-       }
-    } /* end case */
-
-#if defined(DAPL_DBG) && 0
-    dapl_dbg_log (DAPL_DBG_TYPE_CM, "%s: returns %d\n", __FUNCTION__, size );
-#endif
-
-    return size;
-}
-
-
-/*
- * Local variables:
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 8
- * End:
- */
-
+\r
+/*\r
+ * Copyright (c) 2005-2007 Intel Corporation. All rights reserved.\r
+ * Copyright (c) 2002, Network Appliance, Inc. All rights reserved. \r
+ * \r
+ * This Software is licensed under the terms of the "Common Public\r
+ * License" a copy of which is in the file LICENSE.txt in the root\r
+ * directory. The license is also available from the Open Source\r
+ * Initiative, see http://www.opensource.org/licenses/cpl.php.\r
+ *\r
+ */\r
+\r
+/**********************************************************************\r
+ * \r
+ * MODULE: dapl_ibal_cm.c\r
+ *\r
+ * PURPOSE: IB Connection routines for access to IBAL APIs\r
+ *\r
+ * $Id$\r
+ *\r
+ **********************************************************************/\r
+\r
+#include "dapl.h"\r
+#include "dapl_adapter_util.h"\r
+#include "dapl_evd_util.h"\r
+#include "dapl_cr_util.h"\r
+#include "dapl_sp_util.h"\r
+#include "dapl_ep_util.h"\r
+#include "dapl_ia_util.h"\r
+#include "dapl_ibal_util.h"\r
+#include "dapl_name_service.h"\r
+#include "dapl_ibal_name_service.h"\r
+#include "dapl_cookie.h"\r
+\r
+#define IB_INFINITE_SERVICE_LEASE   0xFFFFFFFF\r
+#define  DAPL_ATS_SERVICE_ID        ATS_SERVICE_ID //0x10000CE100415453\r
+#define  DAPL_ATS_NAME              ATS_NAME\r
+#define  HCA_IPV6_ADDRESS_LENGTH    16\r
+\r
+/* until dapl_ibal_util.h define of IB_INVALID_HANDLE which overlaps the\r
+ * Windows ib_types.h typedef enu ib_api_status_t IB_INVALID_HANDLE is fixed.\r
+ */\r
+#undef IB_INVALID_HANDLE\r
+#define DAPL_IB_INVALID_HANDLE NULL\r
+\r
+int g_dapl_loopback_connection = 0;\r
+extern dapl_ibal_root_t        dapl_ibal_root;\r
+\r
+/*\r
+ * Prototypes\r
+ */\r
+\r
+char *\r
+dapli_ib_cm_event_str(ib_cm_events_t e)\r
+{\r
+#ifdef DBG\r
+    char        *cp;\r
+    static char *event_str[13] = {\r
+        "IB_CME_CONNECTED",\r
+        "IB_CME_DISCONNECTED",\r
+        "IB_CME_DISCONNECTED_ON_LINK_DOWN",\r
+        "IB_CME_CONNECTION_REQUEST_PENDING",\r
+        "IB_CME_CONNECTION_REQUEST_PENDING_PRIVATE_DATA",\r
+        "IB_CME_DESTINATION_REJECT",\r
+        "IB_CME_DESTINATION_REJECT_PRIVATE_DATA",\r
+        "IB_CME_DESTINATION_UNREACHABLE",\r
+        "IB_CME_TOO_MANY_CONNECTION_REQUESTS",\r
+        "IB_CME_LOCAL_FAILURE",\r
+        "IB_CME_REPLY_RECEIVED",\r
+        "IB_CME_REPLY_RECEIVED_PRIVATE_DATA",\r
+        "IB_CM_LOCAL_FAILURE"\r
+    };\r
+\r
+    if (e > IB_CM_LOCAL_FAILURE || e < IB_CME_CONNECTED)\r
+       cp =  "BAD EVENT";\r
+    else\r
+        cp = event_str[e];\r
+\r
+    return cp;\r
+#else\r
+    static char num[8];\r
+    sprintf(num,"%d",e);\r
+    return num;\r
+#endif\r
+}\r
+\r
+\r
+#if defined(DAPL_DBG)\r
+\r
+void dapli_print_private_data( char *prefix, const uint8_t *pd, int len )\r
+{\r
+    int i;\r
+            \r
+    if ( !pd || len <= 0 )\r
+       return;\r
+\r
+    dapl_log ( DAPL_DBG_TYPE_CM, "--> %s: private_data:\n    ",prefix);\r
+\r
+    if (len > IB_MAX_REP_PDATA_SIZE)\r
+    {\r
+       dapl_log ( DAPL_DBG_TYPE_ERR,\r
+               "    Private data size(%d) > Max(%d), ignored.\n    ",\r
+                                       len,DAPL_MAX_PRIVATE_DATA_SIZE);\r
+       len = IB_MAX_REP_PDATA_SIZE;\r
+    }\r
+\r
+    for ( i = 0 ; i < len; i++ )\r
+    {\r
+       dapl_log ( DAPL_DBG_TYPE_CM, "%2x ", pd[i]);\r
+       if ( ((i+1) % 20) == 0 ) \r
+           dapl_log ( DAPL_DBG_TYPE_CM, "\n    ");\r
+    }\r
+   dapl_log ( DAPL_DBG_TYPE_CM, "\n");\r
+}\r
+#endif\r
+\r
+\r
+static void \r
+dapli_ib_cm_apr_cb (\r
+        IN    ib_cm_apr_rec_t          *p_cm_apr_rec )\r
+{\r
+    UNUSED_PARAM( p_cm_apr_rec );\r
+\r
+    dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
+                  "--> DiCAcb: CM callback APR (Alternate Path Request)\n");\r
+}\r
+\r
+static void \r
+dapli_ib_cm_lap_cb (\r
+        IN    ib_cm_lap_rec_t          *p_cm_lap_rec )\r
+{\r
+    UNUSED_PARAM( p_cm_lap_rec );\r
+\r
+    dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
+                  "--> DiCLcb: CM callback LAP (Load Alternate Path)\n");\r
+}\r
+\r
+/*\r
+ * Connection Disconnect Request callback\r
+ * We received a DREQ, return a DREP (disconnect reply).\r
+ */\r
+\r
+static void \r
+dapli_ib_cm_dreq_cb (\r
+        IN    ib_cm_dreq_rec_t          *p_cm_dreq_rec )\r
+{\r
+    ib_cm_drep_t        cm_drep;\r
+    DAPL_EP             *ep_ptr;\r
+    int                        bail=10;\r
+    \r
+    dapl_os_assert (p_cm_dreq_rec);\r
+\r
+    ep_ptr  = (DAPL_EP * __ptr64) p_cm_dreq_rec->qp_context;\r
+    if ( DAPL_BAD_PTR(ep_ptr) )\r
+    {\r
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR, \r
+                      "--> %s: BAD_PTR EP %lx\n", __FUNCTION__, ep_ptr);\r
+        return;\r
+    }\r
+    if ( ep_ptr->header.magic != DAPL_MAGIC_EP  )\r
+    {\r
+        if ( ep_ptr->header.magic == DAPL_MAGIC_INVALID )\r
+            return;\r
+\r
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
+                      "--> %s: EP %p BAD_EP_MAGIC %x != wanted %x\n",\r
+                      __FUNCTION__, ep_ptr, ep_ptr->header.magic,\r
+                      DAPL_MAGIC_EP );\r
+        return;\r
+    }\r
+\r
+    dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
+                  "--> %s() EP %p, %s sent_discreq %s\n",\r
+                  __FUNCTION__,ep_ptr,\r
+                  dapl_get_ep_state_str(ep_ptr->param.ep_state),\r
+                  (ep_ptr->sent_discreq == DAT_TRUE ? "TRUE":"FALSE"));\r
+\r
+    dapl_os_lock (&ep_ptr->header.lock);\r
+    if ( ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED\r
+         /*|| ( ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECT_PENDING\r
+           && ep_ptr->sent_discreq == DAT_TRUE)*/ )\r
+    {\r
+        dapl_os_unlock (&ep_ptr->header.lock);\r
+        dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
+                      "--> DiCDcb: EP %lx QP %lx already Disconnected\n",\r
+                      ep_ptr, ep_ptr->qp_handle);\r
+        return;\r
+    }\r
+\r
+    ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECT_PENDING;\r
+    ep_ptr->recv_discreq = DAT_TRUE;\r
+    dapl_os_unlock (&ep_ptr->header.lock);\r
+\r
+    dapl_os_memzero (&cm_drep, sizeof(ib_cm_drep_t));\r
+\r
+    /* Could fail if we received reply from other side, no need to retry */\r
+    /* Wait for any send ops in process holding reference */\r
+    while (dapls_cb_pending(&ep_ptr->req_buffer) && bail-- > 0 )\r
+    {\r
+       dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
+                  "--> DiCDcb: WAIT for EP=%lx req_count(%d) != 0\n", \r
+                  ep_ptr, dapls_cb_pending(&ep_ptr->req_buffer));\r
+       dapl_os_sleep_usec (100);\r
+    }\r
+\r
+    ib_cm_drep (p_cm_dreq_rec->h_cm_dreq, &cm_drep);\r
+\r
+    /* CM puts QP in reset state */\r
+    ep_ptr->qp_state = IB_QPS_RESET;\r
+          \r
+    if (ep_ptr->cr_ptr)\r
+    {\r
+        dapl_os_assert(ep_ptr->ibal_cm_handle->cid\r
+                                             == p_cm_dreq_rec->h_cm_dreq.cid);\r
+        /* passive side */\r
+        dapls_cr_callback ( ep_ptr->cm_handle,\r
+                            IB_CME_DISCONNECTED,\r
+                            (void * __ptr64) p_cm_dreq_rec->p_dreq_pdata,\r
+                           IB_DREQ_PDATA_SIZE,\r
+                            (void *) (((DAPL_CR *) ep_ptr->cr_ptr)->sp_ptr) );\r
+    }\r
+    else\r
+    {\r
+        /* active side */\r
+        dapl_evd_connection_callback (\r
+                                  (dp_ib_cm_handle_t) &p_cm_dreq_rec->h_cm_dreq,\r
+                                  IB_CME_DISCONNECTED,\r
+                                  (void * __ptr64)\r
+                                  p_cm_dreq_rec->p_dreq_pdata,\r
+                                 IB_DREQ_PDATA_SIZE,\r
+                                  p_cm_dreq_rec->qp_context );\r
+    }\r
+}\r
+\r
+/*\r
+ * Connection Disconnect Reply callback\r
+ * We sent a DREQ and received a DREP.\r
+ */\r
+\r
+static void \r
+dapli_ib_cm_drep_cb (\r
+        IN    ib_cm_drep_rec_t          *p_cm_drep_rec )\r
+{\r
+    DAPL_EP            *ep_ptr;\r
+    \r
+    dapl_os_assert (p_cm_drep_rec != NULL);\r
+\r
+    ep_ptr  = (DAPL_EP * __ptr64) p_cm_drep_rec->qp_context;\r
+\r
+    if (p_cm_drep_rec->cm_status)\r
+    {\r
+         dapl_dbg_log (DAPL_DBG_TYPE_CM,\r
+                  "--> %s: DREP cm_status(%s) EP=%p\n", __FUNCTION__,\r
+                  ib_get_err_str(p_cm_drep_rec->cm_status), ep_ptr); \r
+    }\r
+\r
+    if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )\r
+    {\r
+         dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
+                  "--> %s: BAD EP Handle EP=%lx\n", __FUNCTION__,ep_ptr); \r
+        return;\r
+    }\r
+    \r
+    dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
+       "--> DiCDpcb: EP %p state %s cm_hdl %p\n",ep_ptr,\r
+                  dapl_get_ep_state_str(ep_ptr->param.ep_state),\r
+                  ep_ptr->cm_handle);\r
+\r
+    if ( ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED )\r
+    {\r
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR, \r
+                      "--> DiCDpcb: EP %lx QP %lx already Disconnected\n",\r
+                      ep_ptr, ep_ptr->qp_handle);\r
+        return;\r
+    }\r
+\r
+    if (ep_ptr->cm_handle == DAPL_IB_INVALID_HANDLE )\r
+    {\r
+         dapl_dbg_log (DAPL_DBG_TYPE_CM,\r
+                  "--> %s: Invalid EP->CM handle?\n", __FUNCTION__); \r
+        return;\r
+    }\r
+\r
+    if (ep_ptr->cr_ptr)\r
+    {\r
+        /* passive connection side */\r
+        dapls_cr_callback ( ep_ptr->cm_handle,\r
+                            IB_CME_DISCONNECTED,\r
+                           (void * __ptr64) p_cm_drep_rec->p_drep_pdata,\r
+                          IB_DREP_PDATA_SIZE,\r
+                           (void *) (((DAPL_CR *) ep_ptr->cr_ptr)->sp_ptr) );\r
+    }\r
+    else\r
+    {\r
+        /* active connection side */\r
+        dapl_evd_connection_callback (\r
+                                   ep_ptr->cm_handle,\r
+                                   IB_CME_DISCONNECTED,\r
+                                   (void * __ptr64) p_cm_drep_rec->p_drep_pdata,\r
+                                  IB_DREP_PDATA_SIZE,\r
+                                   p_cm_drep_rec->qp_context );\r
+    }\r
+}\r
+\r
+/*\r
+ * CM reply callback\r
+ */\r
+\r
+static void \r
+dapli_ib_cm_rep_cb (\r
+        IN    ib_cm_rep_rec_t          *p_cm_rep_rec )\r
+{\r
+    ib_api_status_t     ib_status; \r
+    ib_cm_rtu_t         cm_rtu;\r
+    uint8_t             cm_cb_op;\r
+    DAPL_PRIVATE        *prd_ptr;\r
+    DAPL_EP             *ep_ptr;\r
+    dapl_ibal_ca_t      *p_ca;\r
+        \r
+    dapl_os_assert (p_cm_rep_rec != NULL);\r
+\r
+    ep_ptr  = (DAPL_EP * __ptr64) p_cm_rep_rec->qp_context;\r
+\r
+    if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )\r
+    {\r
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: EP %lx invalid or FREED\n",\r
+                      __FUNCTION__, ep_ptr);\r
+        return;\r
+    }\r
+    dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
+                  "--> DiCRpcb: EP = %lx local_max_rdma_read_in %d\n", \r
+                  ep_ptr, p_cm_rep_rec->resp_res);\r
+\r
+    p_ca   = (dapl_ibal_ca_t *) \r
+             ep_ptr->header.owner_ia->hca_ptr->ib_hca_handle;\r
+\r
+    dapl_os_memzero (&cm_rtu, sizeof ( ib_cm_rtu_t ));\r
+    cm_rtu.pfn_cm_apr_cb  = dapli_ib_cm_apr_cb;\r
+    cm_rtu.pfn_cm_dreq_cb = dapli_ib_cm_dreq_cb;\r
+    cm_rtu.p_rtu_pdata    = NULL;\r
+    cm_rtu.access_ctrl = \r
+               IB_AC_LOCAL_WRITE|IB_AC_RDMA_WRITE|IB_AC_MW_BIND|IB_AC_ATOMIC;\r
+    if ((ep_ptr->param.ep_attr.max_rdma_read_in > 0) || \r
+               (ep_ptr->param.ep_attr.max_rdma_read_out > 0))\r
+    {\r
+       cm_rtu.access_ctrl |= IB_AC_RDMA_READ;\r
+    }\r
+           \r
+    cm_rtu.rq_depth       = 0;\r
+    cm_rtu.sq_depth       = 0;\r
+       \r
+    ib_status = ib_cm_rtu (p_cm_rep_rec->h_cm_rep, &cm_rtu);\r
+\r
+    if (ib_status == IB_SUCCESS)\r
+    {\r
+        cm_cb_op = IB_CME_CONNECTED;\r
+        dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
+                  "--> DiCRpcb: EP %lx Connected req_count %d\n", \r
+                  ep_ptr, dapls_cb_pending(&ep_ptr->req_buffer));\r
+    }\r
+    else\r
+    {\r
+        cm_cb_op = IB_CME_LOCAL_FAILURE;\r
+    }\r
+\r
+    prd_ptr = (DAPL_PRIVATE * __ptr64) p_cm_rep_rec->p_rep_pdata;\r
+\r
+#if defined(DAPL_DBG) && 0\r
+    dapli_print_private_data( "DiCRpcb",\r
+                             prd_ptr->private_data,\r
+                             IB_MAX_REP_PDATA_SIZE);\r
+#endif\r
+\r
+    dapl_evd_connection_callback ( \r
+                            (dp_ib_cm_handle_t)&p_cm_rep_rec->h_cm_rep,\r
+                            cm_cb_op,\r
+                            (void *) prd_ptr,\r
+                           IB_REP_PDATA_SIZE,\r
+                            (void * __ptr64) p_cm_rep_rec->qp_context);\r
+}\r
+\r
+\r
+static void \r
+dapli_ib_cm_rej_cb (\r
+        IN    ib_cm_rej_rec_t          *p_cm_rej_rec )\r
+{\r
+    DAPL_EP         *ep_ptr;\r
+    ib_cm_events_t  cm_event;\r
+\r
+    dapl_os_assert (p_cm_rej_rec);\r
+\r
+    ep_ptr = (DAPL_EP * __ptr64) p_cm_rej_rec->qp_context;\r
+\r
+    if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )\r
+    {\r
+        dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: EP %lx invalid or FREED\n",\r
+                      __FUNCTION__, ep_ptr);\r
+        return;\r
+    }\r
+\r
+    dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
+                  "--> DiCRjcb: EP = %lx QP = %lx rej reason = 0x%x\n", \r
+                  ep_ptr,ep_ptr->qp_handle,CL_NTOH16(p_cm_rej_rec->rej_status));\r
+\r
+    switch (p_cm_rej_rec->rej_status)\r
+    {\r
+        case IB_REJ_INSUF_RESOURCES:\r
+        case IB_REJ_INSUF_QP:\r
+        case IB_REJ_INVALID_COMM_ID:\r
+        case IB_REJ_INVALID_COMM_INSTANCE:\r
+        case IB_REJ_INVALID_PKT_RATE:\r
+        case IB_REJ_INVALID_ALT_GID:\r
+        case IB_REJ_INVALID_ALT_LID:\r
+        case IB_REJ_INVALID_ALT_SL:\r
+        case IB_REJ_INVALID_ALT_TRAFFIC_CLASS:\r
+        case IB_REJ_INVALID_ALT_PKT_RATE:\r
+        case IB_REJ_INVALID_ALT_HOP_LIMIT:\r
+        case IB_REJ_INVALID_ALT_FLOW_LBL:\r
+        case IB_REJ_INVALID_GID:\r
+        case IB_REJ_INVALID_LID:\r
+        case IB_REJ_INVALID_SID:\r
+        case IB_REJ_INVALID_SL:\r
+        case IB_REJ_INVALID_TRAFFIC_CLASS:\r
+        case IB_REJ_PORT_REDIRECT:\r
+        case IB_REJ_INVALID_MTU:\r
+        case IB_REJ_INSUFFICIENT_RESP_RES:\r
+        case IB_REJ_INVALID_CLASS_VER:\r
+        case IB_REJ_INVALID_FLOW_LBL:\r
+            cm_event = IB_CME_DESTINATION_REJECT;\r
+            break;\r
+\r
+        case IB_REJ_TIMEOUT:\r
+            cm_event = IB_CME_DESTINATION_UNREACHABLE;\r
+            dapl_dbg_log (DAPL_DBG_TYPE_CM, "--> DiCRjcb: CR TIMEOUT\n");\r
+            break;\r
+\r
+        case IB_REJ_USER_DEFINED:\r
+            cm_event = IB_CME_DESTINATION_REJECT;\r
+            dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
+                               "--> DiCRjcb: user defined rej reason %s\n",\r
+                               p_cm_rej_rec->p_ari);\r
+            break;\r
+\r
+        default:\r
+            cm_event = IB_CME_LOCAL_FAILURE;\r
+            dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
+                               "--> DiCRjcb: with unknown status %x\n", \r
+                               p_cm_rej_rec->rej_status);\r
+            break;\r
+     }\r
+\r
+    /* FIXME - Vu\r
+     * We do not take care off the user defined rej reason with additional \r
+     * rejection information (p_ari)\r
+     */\r
+\r
+    if (ep_ptr->cr_ptr)\r
+    {\r
+        dapls_cr_callback ( ep_ptr->cm_handle,\r
+                            cm_event,\r
+                            (void * __ptr64) p_cm_rej_rec->p_rej_pdata,\r
+                           IB_REJ_PDATA_SIZE,\r
+                            (void *) ((DAPL_CR *) ep_ptr->cr_ptr)->sp_ptr);\r
+    }\r
+    else\r
+    {\r
+        dapl_evd_connection_callback (\r
+                                   ep_ptr->cm_handle,\r
+                                   cm_event,\r
+                                   (void * __ptr64) p_cm_rej_rec->p_rej_pdata,\r
+                                  IB_REJ_PDATA_SIZE,\r
+                                   (void * __ptr64) p_cm_rej_rec->qp_context );\r
+    }\r
+\r
+}\r
+\r
+\r
+\r
+static void \r
+dapli_ib_cm_req_cb ( IN  ib_cm_req_rec_t  *p_cm_req_rec )\r
+{\r
+    DAPL_SP              *sp_ptr;\r
+    DAT_SOCK_ADDR6       dest_ia_addr;\r
+    dp_ib_cm_handle_t    cm_handle;\r
+\r
+    struct ibal_cr_data {\r
+        ib_cm_handle_t   cm_hdl;\r
+        DAT_SOCK_ADDR6   dst_ip_addr;\r
+    } *crd;\r
+\r
+    dapl_os_assert (p_cm_req_rec);\r
+\r
+    sp_ptr = (DAPL_SP * __ptr64) p_cm_req_rec->context;\r
+\r
+    dapl_os_assert (sp_ptr);\r
+\r
+    /*\r
+     * The context pointer could have been cleaned up in a racing\r
+     * CM callback, check to see if we should just exit here\r
+     */\r
+    if (sp_ptr->header.magic == DAPL_MAGIC_INVALID)\r
+    {\r
+        dapl_dbg_log (DAPL_DBG_TYPE_CM,\r
+                     "%s: BAD-Magic in SP %lx, racing CM callback?\n",\r
+                      __FUNCTION__, sp_ptr );\r
+       return;\r
+    }\r
+\r
+    dapl_os_assert ( sp_ptr->header.magic == DAPL_MAGIC_PSP || \r
+                     sp_ptr->header.magic == DAPL_MAGIC_RSP );\r
+\r
+    /* preserve ibal's connection handle storage so we have a consistent\r
+     * pointer value. The reasons this is done dynamically instead of a static\r
+     * allocation in an end_point is the pointer value is set in the SP list\r
+     * of CR's here and searched for from disconnect callbacks. If the pointer\r
+     * value changes, you never find the CR on the sp list...\r
+     * EP struct deallocation is where this memory is released or prior in the\r
+     * error case.\r
+     */\r
+    crd = dapl_os_alloc ( sizeof(struct ibal_cr_data) );\r
+    if ( !crd )\r
+    {\r
+        dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
+                       "%s: FAILED to alloc IB CM handle storage?\n",\r
+                       __FUNCTION__);\r
+        return;\r
+    }\r
+\r
+    cm_handle = &crd->cm_hdl;\r
+    dapl_os_memzero ( (void*)crd, sizeof(*crd) );\r
+\r
+    /*\r
+     * Save the cm_srvc_handle to avoid the race condition between\r
+     * the return of the ib_cm_listen and the notification of a conn req\r
+     */\r
+    if (sp_ptr->cm_srvc_handle != p_cm_req_rec->h_cm_listen)\r
+    {\r
+        dapl_dbg_log (DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK, \r
+                           "--> DiCRqcb: cm_service_handle is changed\n"); \r
+        sp_ptr->cm_srvc_handle = p_cm_req_rec->h_cm_listen;\r
+    }\r
+\r
+    dapl_os_memzero (&dest_ia_addr, sizeof (dest_ia_addr));\r
+\r
+#ifdef NO_NAME_SERVICE\r
+\r
+    {\r
+        DAPL_PRIVATE *prd_ptr;\r
+        \r
+        prd_ptr = (DAPL_PRIVATE *)p_cm_req_rec->p_req_pdata;\r
+\r
+        dapl_os_memcpy ((void *)&dest_ia_addr,\r
+                        (void *)&prd_ptr->hca_address,\r
+                        sizeof (DAT_SOCK_ADDR6));        \r
+    }\r
+    \r
+#else\r
+\r
+    {\r
+        GID            dest_gid;\r
+\r
+        dapl_os_memzero (&dest_gid, sizeof (dest_gid));\r
+\r
+        dest_gid.guid = p_cm_req_rec->primary_path.dgid.unicast.interface_id;\r
+        dest_gid.gid_prefix = p_cm_req_rec->primary_path.dgid.unicast.prefix;\r
+\r
+        if (DAT_SUCCESS != dapls_ns_map_ipaddr (\r
+                                 sp_ptr->header.owner_ia->hca_ptr,\r