[DAPL2] code reorganization to support common functions between providers: add/delete...
authorstansmith <stansmith@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Wed, 1 Jul 2009 23:29:30 +0000 (23:29 +0000)
committerstansmith <stansmith@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Wed, 1 Jul 2009 23:29:30 +0000 (23:29 +0000)
git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@2275 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

22 files changed:
ulp/dapl2/dapl/openib_cma/cm.c [moved from ulp/dapl2/dapl/openib_cma/dapl_ib_cm.c with 91% similarity]
ulp/dapl2/dapl/openib_cma/dapl_ib_dto.h [deleted file]
ulp/dapl2/dapl/openib_cma/dapl_ib_extensions.c [deleted file]
ulp/dapl2/dapl/openib_cma/dapl_ib_qp.c [deleted file]
ulp/dapl2/dapl/openib_cma/device.c [moved from ulp/dapl2/dapl/openib_cma/dapl_ib_util.c with 58% similarity]
ulp/dapl2/dapl/openib_common.c [new file with mode: 0644]
ulp/dapl2/dapl/openib_common/cq.c [moved from ulp/dapl2/dapl/openib_cma/dapl_ib_cq.c with 65% similarity]
ulp/dapl2/dapl/openib_common/dapl_ib_common.h [new file with mode: 0644]
ulp/dapl2/dapl/openib_common/dapl_ib_dto.h [moved from ulp/dapl2/dapl/openib_scm/dapl_ib_dto.h with 95% similarity]
ulp/dapl2/dapl/openib_common/ib_extensions.c [moved from ulp/dapl2/dapl/openib_scm/dapl_ib_extensions.c with 96% similarity]
ulp/dapl2/dapl/openib_common/mem.c [moved from ulp/dapl2/dapl/openib_cma/dapl_ib_mem.c with 92% similarity]
ulp/dapl2/dapl/openib_common/qp.c [moved from ulp/dapl2/dapl/openib_scm/dapl_ib_qp.c with 81% similarity]
ulp/dapl2/dapl/openib_common/util.c [new file with mode: 0644]
ulp/dapl2/dapl/openib_scm/cm.c [moved from ulp/dapl2/dapl/openib_scm/dapl_ib_cm.c with 75% similarity]
ulp/dapl2/dapl/openib_scm/dapl_ib_cq.c [deleted file]
ulp/dapl2/dapl/openib_scm/dapl_ib_mem.c [deleted file]
ulp/dapl2/dapl/openib_scm/device.c [moved from ulp/dapl2/dapl/openib_scm/dapl_ib_util.c with 54% similarity]
ulp/dapl2/test/dtest/dtestcm.c [new file with mode: 0644]
ulp/dapl2/test/dtest/windows/dtestcm/SOURCES [new file with mode: 0644]
ulp/dapl2/test/dtest/windows/dtestcm/dtestcm.c [new file with mode: 0644]
ulp/dapl2/test/dtest/windows/dtestcm/dtestcm.rc [new file with mode: 0644]
ulp/dapl2/test/dtest/windows/dtestcm/makefile [new file with mode: 0644]

similarity index 91%
rename from ulp/dapl2/dapl/openib_cma/dapl_ib_cm.c
rename to ulp/dapl2/dapl/openib_cma/cm.c
index 946cfbd..163aa58 100644 (file)
-/*
- * Copyright (c) 2005 Voltaire Inc.  All rights reserved.
- * Copyright (c) 2005-2007 Intel Corporation. All rights reserved.
- * Copyright (c) 2004-2005, Mellanox Technologies, Inc. All rights reserved. 
- * Copyright (c) 2003 Topspin Corporation.  All rights reserved. 
- * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
- *
- * This Software is licensed under one of the following licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- *
- * 2) under the terms of the "The BSD License" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- *
- * Licensee has the right to choose one of the above licenses.
- *
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/**********************************************************************
- *
- * MODULE: dapl_ib_cm.c
- *
- * PURPOSE: The OFED provider - uCMA, name and route resolution
- *
- * $Id: $
- *
- **********************************************************************/
-
-#include "dapl.h"
-#include "dapl_adapter_util.h"
-#include "dapl_evd_util.h"
-#include "dapl_cr_util.h"
-#include "dapl_name_service.h"
-#include "dapl_ib_util.h"
-#include "dapl_vendor.h"
-#include "dapl_osd.h"
-
-extern struct rdma_event_channel *g_cm_events;
-
-/* local prototypes */
-static struct dapl_cm_id *dapli_req_recv(struct dapl_cm_id *conn,
-                                        struct rdma_cm_event *event);
-static void dapli_cm_active_cb(struct dapl_cm_id *conn,
-                              struct rdma_cm_event *event);
-static void dapli_cm_passive_cb(struct dapl_cm_id *conn,
-                               struct rdma_cm_event *event);
-static void dapli_addr_resolve(struct dapl_cm_id *conn);
-static void dapli_route_resolve(struct dapl_cm_id *conn);
-
-/* cma requires 16 bit SID, in network order */
-#define IB_PORT_MOD 32001
-#define IB_PORT_BASE (65535 - IB_PORT_MOD)
-#define SID_TO_PORT(SID) \
-    (SID > 0xffff ? \
-    htons((unsigned short)((SID % IB_PORT_MOD) + IB_PORT_BASE)) :\
-    htons((unsigned short)SID))
-
-#define PORT_TO_SID(p) ntohs(p)
-
-/* private data header to validate consumer rejects versus abnormal events */
-struct dapl_pdata_hdr {
-       DAT_UINT32 version;
-};
-
-static void dapli_addr_resolve(struct dapl_cm_id *conn)
-{
-       int ret;
-#ifdef DAPL_DBG
-       struct rdma_addr *ipaddr = &conn->cm_id->route.addr;
-#endif
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " addr_resolve: cm_id %p SRC %x DST %x\n",
-                    conn->cm_id, ntohl(((struct sockaddr_in *)
-                                        &ipaddr->src_addr)->sin_addr.s_addr),
-                    ntohl(((struct sockaddr_in *)
-                           &ipaddr->dst_addr)->sin_addr.s_addr));
-
-       ret = rdma_resolve_route(conn->cm_id, conn->route_timeout);
-       if (ret) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " dapl_cma_connect: rdma_resolve_route ERR 0x%x %s\n",
-                        ret, strerror(errno));
-               dapl_evd_connection_callback(conn,
-                                            IB_CME_LOCAL_FAILURE,
-                                            NULL, conn->ep);
-       }
-}
-
-static void dapli_route_resolve(struct dapl_cm_id *conn)
-{
-       int ret;
-#ifdef DAPL_DBG
-       struct rdma_addr *ipaddr = &conn->cm_id->route.addr;
-       struct ib_addr *ibaddr = &conn->cm_id->route.addr.addr.ibaddr;
-#endif
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " route_resolve: cm_id %p SRC %x DST %x PORT %d\n",
-                    conn->cm_id, ntohl(((struct sockaddr_in *)
-                                        &ipaddr->src_addr)->sin_addr.s_addr),
-                    ntohl(((struct sockaddr_in *)
-                           &ipaddr->dst_addr)->sin_addr.s_addr),
-                    ntohs(((struct sockaddr_in *)
-                           &ipaddr->dst_addr)->sin_port));
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " route_resolve: SRC GID subnet %016llx id %016llx\n",
-                    (unsigned long long)
-                    ntohll(ibaddr->sgid.global.subnet_prefix),
-                    (unsigned long long)
-                    ntohll(ibaddr->sgid.global.interface_id));
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " route_resolve: DST GID subnet %016llx id %016llx\n",
-                    (unsigned long long)
-                    ntohll(ibaddr->dgid.global.subnet_prefix),
-                    (unsigned long long)
-                    ntohll(ibaddr->dgid.global.interface_id));
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " route_resolve: cm_id %p pdata %p plen %d rr %d ind %d\n",
-                    conn->cm_id,
-                    conn->params.private_data,
-                    conn->params.private_data_len,
-                    conn->params.responder_resources,
-                    conn->params.initiator_depth);
-
-       ret = rdma_connect(conn->cm_id, &conn->params);
-       if (ret) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " dapl_cma_connect: rdma_connect ERR %d %s\n",
-                        ret, strerror(errno));
-               goto bail;
-       }
-       return;
-
-      bail:
-       dapl_evd_connection_callback(conn,
-                                    IB_CME_LOCAL_FAILURE, NULL, conn->ep);
-}
-
-/* 
- * Called from consumer thread via dat_ep_free().
- * CANNOT be called from the async event processing thread
- * dapli_cma_event_cb() since a cm_id reference is held and
- * a deadlock will occur.
- */
-void dapli_destroy_conn(struct dapl_cm_id *conn)
-{
-       struct rdma_cm_id *cm_id;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " destroy_conn: conn %p id %d\n", conn, conn->cm_id);
-
-       dapl_os_lock(&conn->lock);
-       conn->destroy = 1;
-
-       if (conn->ep) {
-               conn->ep->cm_handle = IB_INVALID_HANDLE;
-               conn->ep->qp_handle = IB_INVALID_HANDLE;
-       }
-
-       cm_id = conn->cm_id;
-       conn->cm_id = NULL;
-       dapl_os_unlock(&conn->lock);
-
-       /* 
-        * rdma_destroy_id will force synchronization with async CM event 
-        * thread since it blocks until the in-process event reference
-        * is cleared during our event processing call exit.
-        */
-       if (cm_id) {
-               if (cm_id->qp)
-                       rdma_destroy_qp(cm_id);
-
-               rdma_destroy_id(cm_id);
-       }
-       dapl_os_free(conn, sizeof(*conn));
-}
-
-static struct dapl_cm_id *dapli_req_recv(struct dapl_cm_id *conn,
-                                        struct rdma_cm_event *event)
-{
-       struct dapl_cm_id *new_conn;
-#ifdef DAPL_DBG
-       struct rdma_addr *ipaddr = &event->id->route.addr;
-#endif
-
-       if (conn->sp == NULL) {
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                            " dapli_rep_recv: on invalid listen " "handle\n");
-               return NULL;
-       }
-
-       /* allocate new cm_id and merge listen parameters */
-       new_conn = dapl_os_alloc(sizeof(*new_conn));
-       if (new_conn) {
-               (void)dapl_os_memzero(new_conn, sizeof(*new_conn));
-               dapl_os_lock_init(&new_conn->lock);
-               new_conn->cm_id = event->id;    /* provided by uCMA */
-               event->id->context = new_conn;  /* update CM_ID context */
-               new_conn->sp = conn->sp;
-               new_conn->hca = conn->hca;
-
-               /* Get requesters connect data, setup for accept */
-               new_conn->params.responder_resources =
-                   DAPL_MIN(event->param.conn.responder_resources,
-                            conn->hca->ib_trans.max_rdma_rd_in);
-               new_conn->params.initiator_depth =
-                   DAPL_MIN(event->param.conn.initiator_depth,
-                            conn->hca->ib_trans.max_rdma_rd_out);
-
-               new_conn->params.flow_control = event->param.conn.flow_control;
-               new_conn->params.rnr_retry_count =
-                   event->param.conn.rnr_retry_count;
-               new_conn->params.retry_count = event->param.conn.retry_count;
-
-               /* save private data */
-               if (event->param.conn.private_data_len) {
-                       dapl_os_memcpy(new_conn->p_data,
-                                      event->param.conn.private_data,
-                                      event->param.conn.private_data_len);
-                       new_conn->params.private_data = new_conn->p_data;
-                       new_conn->params.private_data_len =
-                           event->param.conn.private_data_len;
-               }
-
-               dapl_dbg_log(DAPL_DBG_TYPE_CM, " passive_cb: "
-                            "REQ: SP %p PORT %d LID %d "
-                            "NEW CONN %p ID %p pD %p,%d\n",
-                            new_conn->sp, ntohs(((struct sockaddr_in *)
-                                                 &ipaddr->src_addr)->sin_port),
-                            event->listen_id, new_conn, event->id,
-                            event->param.conn.private_data,
-                            event->param.conn.private_data_len);
-
-               dapl_dbg_log(DAPL_DBG_TYPE_CM, " passive_cb: "
-                            "REQ: IP SRC %x PORT %d DST %x PORT %d "
-                            "rr %d init %d\n", ntohl(((struct sockaddr_in *)
-                                                      &ipaddr->src_addr)->
-                                                     sin_addr.s_addr),
-                            ntohs(((struct sockaddr_in *)
-                                   &ipaddr->src_addr)->sin_port),
-                            ntohl(((struct sockaddr_in *)
-                                   &ipaddr->dst_addr)->sin_addr.s_addr),
-                            ntohs(((struct sockaddr_in *)
-                                   &ipaddr->dst_addr)->sin_port),
-                            new_conn->params.responder_resources,
-                            new_conn->params.initiator_depth);
-       }
-       return new_conn;
-}
-
-static void dapli_cm_active_cb(struct dapl_cm_id *conn,
-                              struct rdma_cm_event *event)
-{
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " active_cb: conn %p id %d event %d\n",
-                    conn, conn->cm_id, event->event);
-
-       dapl_os_lock(&conn->lock);
-       if (conn->destroy) {
-               dapl_os_unlock(&conn->lock);
-               return;
-       }
-       dapl_os_unlock(&conn->lock);
-
-       /* There is a chance that we can get events after
-        * the consumer calls disconnect in a pending state
-        * since the IB CM and uDAPL states are not shared.
-        * In some cases, IB CM could generate either a DCONN
-        * or CONN_ERR after the consumer returned from
-        * dapl_ep_disconnect with a DISCONNECTED event
-        * already queued. Check state here and bail to
-        * avoid any events after a disconnect.
-        */
-       if (DAPL_BAD_HANDLE(conn->ep, DAPL_MAGIC_EP))
-               return;
-
-       dapl_os_lock(&conn->ep->header.lock);
-       if (conn->ep->param.ep_state == DAT_EP_STATE_DISCONNECTED) {
-               dapl_os_unlock(&conn->ep->header.lock);
-               return;
-       }
-       if (event->event == RDMA_CM_EVENT_DISCONNECTED)
-               conn->ep->param.ep_state = DAT_EP_STATE_DISCONNECTED;
-
-       dapl_os_unlock(&conn->ep->header.lock);
-
-       switch (event->event) {
-       case RDMA_CM_EVENT_UNREACHABLE:
-       case RDMA_CM_EVENT_CONNECT_ERROR:
-               {
-                       dapl_log(DAPL_DBG_TYPE_WARN,
-                                "dapl_cma_active: CONN_ERR event=0x%x"
-                                " status=%d %s DST %s, %d\n",
-                                event->event, event->status,
-                                (event->status == -ETIMEDOUT) ? "TIMEOUT" : "",
-                                inet_ntoa(((struct sockaddr_in *)
-                                           &conn->cm_id->route.addr.dst_addr)->
-                                          sin_addr),
-                                ntohs(((struct sockaddr_in *)
-                                       &conn->cm_id->route.addr.dst_addr)->
-                                      sin_port));
-
-                       /* per DAT SPEC provider always returns UNREACHABLE */
-                       dapl_evd_connection_callback(conn,
-                                                    IB_CME_DESTINATION_UNREACHABLE,
-                                                    NULL, conn->ep);
-                       break;
-               }
-       case RDMA_CM_EVENT_REJECTED:
-               {
-                       ib_cm_events_t cm_event;
-                       unsigned char *pdata = NULL;
-
-                       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                                    " dapli_cm_active_handler: REJECTED reason=%d\n",
-                                    event->status);
-
-                       /* valid REJ from consumer will always contain private data */
-                       if (event->status == 28 &&
-                           event->param.conn.private_data_len) {
-                               cm_event =
-                                   IB_CME_DESTINATION_REJECT_PRIVATE_DATA;
-                               pdata =
-                                   (unsigned char *)event->param.conn.
-                                   private_data +
-                                   sizeof(struct dapl_pdata_hdr);
-                       } else {
-                               cm_event = IB_CME_DESTINATION_REJECT;
-                               dapl_log(DAPL_DBG_TYPE_WARN,
-                                        "dapl_cma_active: non-consumer REJ,"
-                                        " reason=%d, DST %s, %d\n",
-                                        event->status,
-                                        inet_ntoa(((struct sockaddr_in *)
-                                                   &conn->cm_id->route.addr.
-                                                   dst_addr)->sin_addr),
-                                        ntohs(((struct sockaddr_in *)
-                                               &conn->cm_id->route.addr.
-                                               dst_addr)->sin_port));
-                       }
-                       dapl_evd_connection_callback(conn, cm_event, pdata,
-                                                    conn->ep);
-                       break;
-               }
-       case RDMA_CM_EVENT_ESTABLISHED:
-               dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                            " active_cb: cm_id %d PORT %d CONNECTED to %s!\n",
-                            conn->cm_id, ntohs(((struct sockaddr_in *)
-                                                &conn->cm_id->route.addr.
-                                                dst_addr)->sin_port),
-                            inet_ntoa(((struct sockaddr_in *)
-                                       &conn->cm_id->route.addr.dst_addr)->
-                                      sin_addr));
-
-               /* setup local and remote ports for ep query */
-               conn->ep->param.remote_port_qual =
-                   PORT_TO_SID(rdma_get_dst_port(conn->cm_id));
-               conn->ep->param.local_port_qual =
-                   PORT_TO_SID(rdma_get_src_port(conn->cm_id));
-
-               dapl_evd_connection_callback(conn, IB_CME_CONNECTED,
-                                            event->param.conn.private_data,
-                                            conn->ep);
-               break;
-
-       case RDMA_CM_EVENT_DISCONNECTED:
-               rdma_disconnect(conn->cm_id);   /* required for DREP */
-               /* validate EP handle */
-               if (!DAPL_BAD_HANDLE(conn->ep, DAPL_MAGIC_EP))
-                       dapl_evd_connection_callback(conn,
-                                                    IB_CME_DISCONNECTED,
-                                                    NULL, conn->ep);
-               break;
-       default:
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                            " dapli_cm_active_cb_handler: Unexpected CM "
-                            "event %d on ID 0x%p\n", event->event,
-                            conn->cm_id);
-               break;
-       }
-
-       return;
-}
-
-static void dapli_cm_passive_cb(struct dapl_cm_id *conn,
-                               struct rdma_cm_event *event)
-{
-       struct dapl_cm_id *new_conn;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " passive_cb: conn %p id %d event %d\n",
-                    conn, event->id, event->event);
-
-       dapl_os_lock(&conn->lock);
-       if (conn->destroy) {
-               dapl_os_unlock(&conn->lock);
-               return;
-       }
-       dapl_os_unlock(&conn->lock);
-
-       switch (event->event) {
-       case RDMA_CM_EVENT_CONNECT_REQUEST:
-               /* create new conn object with new conn_id from event */
-               new_conn = dapli_req_recv(conn, event);
-
-               if (new_conn)
-                       dapls_cr_callback(new_conn,
-                                         IB_CME_CONNECTION_REQUEST_PENDING,
-                                         event->param.conn.private_data,
-                                         new_conn->sp);
-               break;
-       case RDMA_CM_EVENT_UNREACHABLE:
-       case RDMA_CM_EVENT_CONNECT_ERROR:
-               dapl_log(DAPL_DBG_TYPE_WARN,
-                        "dapl_cm_passive: CONN_ERR event=0x%x status=%d %s,"
-                        " DST %s,%d\n",
-                        event->event, event->status,
-                        (event->status == -ETIMEDOUT) ? "TIMEOUT" : "",
-                        inet_ntoa(((struct sockaddr_in *)
-                                   &conn->cm_id->route.addr.dst_addr)->
-                                  sin_addr), ntohs(((struct sockaddr_in *)
-                                                    &conn->cm_id->route.addr.
-                                                    dst_addr)->sin_port));
-
-               dapls_cr_callback(conn, IB_CME_DESTINATION_UNREACHABLE,
-                                 NULL, conn->sp);
-               break;
-
-       case RDMA_CM_EVENT_REJECTED:
-               {
-                       /* will alwasys be abnormal NON-consumer from active side */
-                       dapl_log(DAPL_DBG_TYPE_WARN,
-                                "dapl_cm_passive: non-consumer REJ, reason=%d,"
-                                " DST %s, %d\n",
-                                event->status,
-                                inet_ntoa(((struct sockaddr_in *)
-                                           &conn->cm_id->route.addr.dst_addr)->
-                                          sin_addr),
-                                ntohs(((struct sockaddr_in *)
-                                       &conn->cm_id->route.addr.dst_addr)->
-                                      sin_port));
-
-                       dapls_cr_callback(conn, IB_CME_DESTINATION_REJECT,
-                                         NULL, conn->sp);
-                       break;
-               }
-       case RDMA_CM_EVENT_ESTABLISHED:
-               dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                            " passive_cb: cm_id %p PORT %d CONNECTED from 0x%x!\n",
-                            conn->cm_id, ntohs(((struct sockaddr_in *)
-                                                &conn->cm_id->route.addr.
-                                                src_addr)->sin_port),
-                            ntohl(((struct sockaddr_in *)
-                                   &conn->cm_id->route.addr.dst_addr)->
-                                  sin_addr.s_addr));
-
-               dapls_cr_callback(conn, IB_CME_CONNECTED, NULL, conn->sp);
-
-               break;
-       case RDMA_CM_EVENT_DISCONNECTED:
-               rdma_disconnect(conn->cm_id);   /* required for DREP */
-               /* validate SP handle context */
-               if (!DAPL_BAD_HANDLE(conn->sp, DAPL_MAGIC_PSP) ||
-                   !DAPL_BAD_HANDLE(conn->sp, DAPL_MAGIC_RSP))
-                       dapls_cr_callback(conn,
-                                         IB_CME_DISCONNECTED, NULL, conn->sp);
-               break;
-       default:
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR, " passive_cb: "
-                            "Unexpected CM event %d on ID 0x%p\n",
-                            event->event, conn->cm_id);
-               break;
-       }
-
-       return;
-}
-
-/************************ DAPL provider entry points **********************/
-
-/*
- * dapls_ib_connect
- *
- * Initiate a connection with the passive listener on another node
- *
- * Input:
- *     ep_handle,
- *     remote_ia_address,
- *     remote_conn_qual,
- *     prd_size                size of private data and structure
- *     prd_prt                 pointer to private data structure
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *     DAT_INVALID_PARAMETER
- *
- */
-DAT_RETURN dapls_ib_connect(IN DAT_EP_HANDLE ep_handle,
-                           IN DAT_IA_ADDRESS_PTR r_addr,
-                           IN DAT_CONN_QUAL r_qual,
-                           IN DAT_COUNT p_size, IN void *p_data)
-{
-       struct dapl_ep *ep_ptr = ep_handle;
-       struct dapl_cm_id *conn;
-       int ret;
-
-       /* Sanity check */
-       if (NULL == ep_ptr)
-               return DAT_SUCCESS;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " connect: rSID 0x%llx rPort %d, pdata %p, ln %d\n",
-                    r_qual, ntohs(SID_TO_PORT(r_qual)), p_data, p_size);
-
-       /* rdma conn and cm_id pre-bound; reference via qp_handle */
-       conn = ep_ptr->cm_handle = ep_ptr->qp_handle;
-
-       /* Setup QP/CM parameters and private data in cm_id */
-       (void)dapl_os_memzero(&conn->params, sizeof(conn->params));
-       conn->params.responder_resources =
-           ep_ptr->param.ep_attr.max_rdma_read_in;
-       conn->params.initiator_depth = ep_ptr->param.ep_attr.max_rdma_read_out;
-       conn->params.flow_control = 1;
-       conn->params.rnr_retry_count = IB_RNR_RETRY_COUNT;
-       conn->params.retry_count = IB_RC_RETRY_COUNT;
-       if (p_size) {
-               dapl_os_memcpy(conn->p_data, p_data, p_size);
-               conn->params.private_data = conn->p_data;
-               conn->params.private_data_len = p_size;
-       }
-
-       /* copy in remote address, need a copy for retry attempts */
-       dapl_os_memcpy(&conn->r_addr, r_addr, sizeof(*r_addr));
-
-       /* Resolve remote address, src already bound during QP create */
-       ((struct sockaddr_in *)&conn->r_addr)->sin_port = SID_TO_PORT(r_qual);
-       ((struct sockaddr_in *)&conn->r_addr)->sin_family = AF_INET;
-
-       ret = rdma_resolve_addr(conn->cm_id, NULL,
-                               (struct sockaddr *)&conn->r_addr,
-                               conn->arp_timeout);
-       if (ret) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " dapl_cma_connect: rdma_resolve_addr ERR 0x%x %s\n",
-                        ret, strerror(errno));
-               return dapl_convert_errno(errno, "ib_connect");
-       }
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " connect: resolve_addr: cm_id %p -> %s port %d\n",
-                    conn->cm_id,
-                    inet_ntoa(((struct sockaddr_in *)&conn->r_addr)->sin_addr),
-                    ((struct sockaddr_in *)&conn->r_addr)->sin_port);
-
-       return DAT_SUCCESS;
-}
-
-/*
- * dapls_ib_disconnect
- *
- * Disconnect an EP
- *
- * Input:
- *     ep_handle,
- *     disconnect_flags
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *
- */
-DAT_RETURN
-dapls_ib_disconnect(IN DAPL_EP * ep_ptr, IN DAT_CLOSE_FLAGS close_flags)
-{
-       dp_ib_cm_handle_t conn = ep_ptr->cm_handle;
-       int ret;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " disconnect(ep %p, conn %p, id %d flags %x)\n",
-                    ep_ptr, conn, (conn ? conn->cm_id : 0), close_flags);
-
-       if ((conn == IB_INVALID_HANDLE) || (conn->cm_id == NULL))
-               return DAT_SUCCESS;
-
-       /* no graceful half-pipe disconnect option */
-       ret = rdma_disconnect(conn->cm_id);
-       if (ret)
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                            " disconnect: ID %p ret 0x%x\n",
-                            ep_ptr->cm_handle, ret);
-
-       /* 
-        * DAT event notification occurs from the callback
-        * Note: will fire even if DREQ goes unanswered on timeout 
-        */
-       return DAT_SUCCESS;
-}
-
-/*
- * dapls_ib_disconnect_clean
- *
- * Clean up outstanding connection data. This routine is invoked
- * after the final disconnect callback has occurred. Only on the
- * ACTIVE side of a connection.
- *
- * Input:
- *     ep_ptr          DAPL_EP
- *     active          Indicates active side of connection
- *
- * Output:
- *     none
- *
- * Returns:
- *     void
- *
- */
-void
-dapls_ib_disconnect_clean(IN DAPL_EP * ep_ptr,
-                         IN DAT_BOOLEAN active,
-                         IN const ib_cm_events_t ib_cm_event)
-{
-       /* nothing to do */
-       return;
-}
-
-/*
- * dapl_ib_setup_conn_listener
- *
- * Have the CM set up a connection listener.
- *
- * Input:
- *     ibm_hca_handle          HCA handle
- *     qp_handle                       QP handle
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *     DAT_INTERNAL_ERROR
- *     DAT_CONN_QUAL_UNAVAILBLE
- *     DAT_CONN_QUAL_IN_USE
- *
- */
-DAT_RETURN
-dapls_ib_setup_conn_listener(IN DAPL_IA * ia_ptr,
-                            IN DAT_UINT64 ServiceID, IN DAPL_SP * sp_ptr)
-{
-       DAT_RETURN dat_status = DAT_SUCCESS;
-       ib_cm_srvc_handle_t conn;
-       DAT_SOCK_ADDR6 addr;    /* local binding address */
-
-       /* Allocate CM and initialize lock */
-       if ((conn = dapl_os_alloc(sizeof(*conn))) == NULL)
-               return DAT_INSUFFICIENT_RESOURCES;
-
-       dapl_os_memzero(conn, sizeof(*conn));
-       dapl_os_lock_init(&conn->lock);
-
-       /* create CM_ID, bind to local device, create QP */
-       if (rdma_create_id
-           (g_cm_events, &conn->cm_id, (void *)conn, RDMA_PS_TCP)) {
-               dapl_os_free(conn, sizeof(*conn));
-               return (dapl_convert_errno(errno, "setup_listener"));
-       }
-
-       /* open identifies the local device; per DAT specification */
-       /* Get family and address then set port to consumer's ServiceID */
-       dapl_os_memcpy(&addr, &ia_ptr->hca_ptr->hca_address, sizeof(addr));
-       ((struct sockaddr_in *)&addr)->sin_port = SID_TO_PORT(ServiceID);
-
-       if (rdma_bind_addr(conn->cm_id, (struct sockaddr *)&addr)) {
-               if ((errno == EBUSY) || (errno == EADDRINUSE))
-                       dat_status = DAT_CONN_QUAL_IN_USE;
-               else
-                       dat_status =
-                           dapl_convert_errno(errno, "setup_listener");
-               goto bail;
-       }
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " listen(ia_ptr %p SID 0x%llx Port %d sp %p conn %p id %d)\n",
-                    ia_ptr, ServiceID, ntohs(SID_TO_PORT(ServiceID)),
-                    sp_ptr, conn, conn->cm_id);
-
-       sp_ptr->cm_srvc_handle = conn;
-       conn->sp = sp_ptr;
-       conn->hca = ia_ptr->hca_ptr;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_EP,
-                    " listen(conn=%p cm_id=%d)\n",
-                    sp_ptr->cm_srvc_handle, conn->cm_id);
-
-       if (rdma_listen(conn->cm_id, 0)) {      /* max cma backlog */
-
-               if ((errno == EBUSY) || (errno == EADDRINUSE))
-                       dat_status = DAT_CONN_QUAL_IN_USE;
-               else
-                       dat_status =
-                           dapl_convert_errno(errno, "setup_listener");
-               goto bail;
-       }
-
-       /* success */
-       return DAT_SUCCESS;
-
-      bail:
-       rdma_destroy_id(conn->cm_id);
-       dapl_os_free(conn, sizeof(*conn));
-       return dat_status;
-}
-
-/*
- * dapl_ib_remove_conn_listener
- *
- * Have the CM remove a connection listener.
- *
- * Input:
- *     ia_handle               IA handle
- *     ServiceID               IB Channel Service ID
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INVALID_STATE
- *
- */
-DAT_RETURN
-dapls_ib_remove_conn_listener(IN DAPL_IA * ia_ptr, IN DAPL_SP * sp_ptr)
-{
-       ib_cm_srvc_handle_t conn = sp_ptr->cm_srvc_handle;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " remove_listen(ia_ptr %p sp_ptr %p cm_ptr %p)\n",
-                    ia_ptr, sp_ptr, conn);
-
-       if (conn != IB_INVALID_HANDLE) {
-               sp_ptr->cm_srvc_handle = NULL;
-               dapli_destroy_conn(conn);
-       }
-       return DAT_SUCCESS;
-}
-
-/*
- * dapls_ib_accept_connection
- *
- * Perform necessary steps to accept a connection
- *
- * Input:
- *     cr_handle
- *     ep_handle
- *     private_data_size
- *     private_data
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *     DAT_INTERNAL_ERROR
- *
- */
-DAT_RETURN
-dapls_ib_accept_connection(IN DAT_CR_HANDLE cr_handle,
-                          IN DAT_EP_HANDLE ep_handle,
-                          IN DAT_COUNT p_size, IN const DAT_PVOID p_data)
-{
-       DAPL_CR *cr_ptr = (DAPL_CR *) cr_handle;
-       DAPL_EP *ep_ptr = (DAPL_EP *) ep_handle;
-       DAPL_IA *ia_ptr = ep_ptr->header.owner_ia;
-       struct dapl_cm_id *cr_conn = cr_ptr->ib_cm_handle;
-       int ret;
-       DAT_RETURN dat_status;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " accept(cr %p conn %p, id %p, p_data %p, p_sz=%d)\n",
-                    cr_ptr, cr_conn, cr_conn->cm_id, p_data, p_size);
-
-       /* Obtain size of private data structure & contents */
-       if (p_size > IB_MAX_REP_PDATA_SIZE) {
-               dat_status = DAT_ERROR(DAT_LENGTH_ERROR, DAT_NO_SUBTYPE);
-               goto bail;
-       }
-
-       if (ep_ptr->qp_state == DAPL_QP_STATE_UNATTACHED) {
-               /* 
-                * If we are lazy attaching the QP then we may need to
-                * hook it up here. Typically, we run this code only for
-                * DAT_PSP_PROVIDER_FLAG
-                */
-               dat_status = dapls_ib_qp_alloc(ia_ptr, ep_ptr, NULL);
-               if (dat_status != DAT_SUCCESS) {
-                       dapl_log(DAPL_DBG_TYPE_ERR,
-                                " dapl_cma_accept: qp_alloc ERR %d\n",
-                                dat_status);
-                       goto bail;
-               }
-       }
-
-       /* 
-        * Validate device and port in EP cm_id against inbound 
-        * CR cm_id. The pre-allocated EP cm_id is already bound to 
-        * a local device (cm_id and QP) when created. Move the QP
-        * to the new cm_id only if device and port numbers match.
-        */
-       if (ep_ptr->qp_handle->cm_id->verbs == cr_conn->cm_id->verbs &&
-           ep_ptr->qp_handle->cm_id->port_num == cr_conn->cm_id->port_num) {
-               /* move QP to new cr_conn, remove QP ref in EP cm_id */
-               cr_conn->cm_id->qp = ep_ptr->qp_handle->cm_id->qp;
-               ep_ptr->qp_handle->cm_id->qp = NULL;
-               dapli_destroy_conn(ep_ptr->qp_handle);
-       } else {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " dapl_cma_accept: ERR dev(%p!=%p) or"
-                        " port mismatch(%d!=%d)\n",
-                        ep_ptr->qp_handle->cm_id->verbs, cr_conn->cm_id->verbs,
-                        ntohs(ep_ptr->qp_handle->cm_id->port_num),
-                        ntohs(cr_conn->cm_id->port_num));
-               dat_status = DAT_INTERNAL_ERROR;
-               goto bail;
-       }
-
-       cr_ptr->param.local_ep_handle = ep_handle;
-       cr_conn->params.private_data = p_data;
-       cr_conn->params.private_data_len = p_size;
-
-       ret = rdma_accept(cr_conn->cm_id, &cr_conn->params);
-       if (ret) {
-               dapl_log(DAPL_DBG_TYPE_ERR, " dapl_cma_accept: ERR %d %s\n",
-                        ret, strerror(errno));
-               dat_status = dapl_convert_errno(ret, "accept");
-               goto bail;
-       }
-
-       /* save accepted conn and EP reference */
-       ep_ptr->qp_handle = cr_conn;
-       ep_ptr->cm_handle = cr_conn;
-       cr_conn->ep = ep_ptr;
-
-       /* setup local and remote ports for ep query */
-       /* Note: port qual in network order */
-       ep_ptr->param.remote_port_qual =
-           PORT_TO_SID(rdma_get_dst_port(cr_conn->cm_id));
-       ep_ptr->param.local_port_qual =
-           PORT_TO_SID(rdma_get_src_port(cr_conn->cm_id));
-
-       return DAT_SUCCESS;
-      bail:
-       rdma_reject(cr_conn->cm_id, NULL, 0);
-       dapli_destroy_conn(cr_conn);
-       return dat_status;
-}
-
-/*
- * dapls_ib_reject_connection
- *
- * Reject a connection
- *
- * Input:
- *     cr_handle
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INTERNAL_ERROR
- *
- */
-DAT_RETURN
-dapls_ib_reject_connection(IN dp_ib_cm_handle_t cm_handle,
-                          IN int reason,
-                          IN DAT_COUNT private_data_size,
-                          IN const DAT_PVOID private_data)
-{
-       int ret;
-       int offset = sizeof(struct dapl_pdata_hdr);
-       struct dapl_pdata_hdr pdata_hdr;
-
-       memset(&pdata_hdr, 0, sizeof pdata_hdr);
-       pdata_hdr.version = htonl((DAT_VERSION_MAJOR << 24) |
-                                 (DAT_VERSION_MINOR << 16) |
-                                 (VN_PROVIDER_MAJOR << 8) |
-                                 (VN_PROVIDER_MINOR));
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " reject: handle %p reason %x, ver=%x, data %p, sz=%d\n",
-                    cm_handle, reason, ntohl(pdata_hdr.version),
-                    private_data, private_data_size);
-
-       if (cm_handle == IB_INVALID_HANDLE) {
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                            " reject: invalid handle: reason %d\n", reason);
-               return DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_CR);
-       }
-
-       if (private_data_size >
-           dapls_ib_private_data_size(NULL, DAPL_PDATA_CONN_REJ,
-                                      cm_handle->hca))
-               return DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3);
-
-       /* setup pdata_hdr and users data, in CR pdata buffer */
-       dapl_os_memcpy(cm_handle->p_data, &pdata_hdr, offset);
-       if (private_data_size)
-               dapl_os_memcpy(cm_handle->p_data + offset,
-                              private_data, private_data_size);
-
-       /*
-        * Always some private data with reject so active peer can
-        * determine real application reject from an abnormal 
-        * application termination
-        */
-       ret = rdma_reject(cm_handle->cm_id,
-                         cm_handle->p_data, offset + private_data_size);
-
-       dapli_destroy_conn(cm_handle);
-       return dapl_convert_errno(ret, "reject");
-}
-
-/*
- * dapls_ib_cm_remote_addr
- *
- * Obtain the remote IP address given a connection
- *
- * Input:
- *     cr_handle
- *
- * Output:
- *     remote_ia_address: where to place the remote address
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INVALID_HANDLE
- *
- */
-DAT_RETURN
-dapls_ib_cm_remote_addr(IN DAT_HANDLE dat_handle, OUT DAT_SOCK_ADDR6 * raddr)
-{
-       DAPL_HEADER *header;
-       dp_ib_cm_handle_t ib_cm_handle;
-       struct rdma_addr *ipaddr;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_EP,
-                    " remote_addr(cm_handle=%p, r_addr=%p)\n",
-                    dat_handle, raddr);
-
-       header = (DAPL_HEADER *) dat_handle;
-
-       if (header->magic == DAPL_MAGIC_EP)
-               ib_cm_handle = ((DAPL_EP *) dat_handle)->cm_handle;
-       else if (header->magic == DAPL_MAGIC_CR)
-               ib_cm_handle = ((DAPL_CR *) dat_handle)->ib_cm_handle;
-       else
-               return DAT_INVALID_HANDLE;
-
-       /* get remote IP address from cm_id route */
-       ipaddr = &ib_cm_handle->cm_id->route.addr;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                    " remote_addr: conn %p id %p SRC %x DST %x PORT %d\n",
-                    ib_cm_handle, ib_cm_handle->cm_id,
-                    ntohl(((struct sockaddr_in *)
-                           &ipaddr->src_addr)->sin_addr.s_addr),
-                    ntohl(((struct sockaddr_in *)
-                           &ipaddr->dst_addr)->sin_addr.s_addr),
-                    ntohs(((struct sockaddr_in *)
-                           &ipaddr->dst_addr)->sin_port));
-
-       dapl_os_memcpy(raddr, &ipaddr->dst_addr, sizeof(DAT_SOCK_ADDR));
-       return DAT_SUCCESS;
-}
-
-/*
- * dapls_ib_private_data_size
- *
- * Return the size of private data given a connection op type
- *
- * Input:
- *     prd_ptr         private data pointer
- *     conn_op         connection operation type
- *      hca_ptr         hca pointer, needed for transport type
- *
- * If prd_ptr is NULL, this is a query for the max size supported by
- * the provider, otherwise it is the actual size of the private data
- * contained in prd_ptr.
- *
- *
- * Output:
- *     None
- *
- * Returns:
- *     length of private data
- *
- */
-int dapls_ib_private_data_size(IN DAPL_PRIVATE * prd_ptr,
-                              IN DAPL_PDATA_OP conn_op, IN DAPL_HCA * hca_ptr)
-{
-       int size;
-
-       if (hca_ptr->ib_hca_handle->device->transport_type
-           == IBV_TRANSPORT_IWARP)
-               return (IWARP_MAX_PDATA_SIZE - sizeof(struct dapl_pdata_hdr));
-
-       switch (conn_op) {
-
-       case DAPL_PDATA_CONN_REQ:
-               size = IB_MAX_REQ_PDATA_SIZE;
-               break;
-       case DAPL_PDATA_CONN_REP:
-               size = IB_MAX_REP_PDATA_SIZE;
-               break;
-       case DAPL_PDATA_CONN_REJ:
-               size = IB_MAX_REJ_PDATA_SIZE - sizeof(struct dapl_pdata_hdr);
-               break;
-       case DAPL_PDATA_CONN_DREQ:
-               size = IB_MAX_DREQ_PDATA_SIZE;
-               break;
-       case DAPL_PDATA_CONN_DREP:
-               size = IB_MAX_DREP_PDATA_SIZE;
-               break;
-       default:
-               size = 0;
-
-       }                       /* end case */
-
-       return size;
-}
-
-/*
- * Map all CMA event codes to the DAT equivelent.
- */
-#define DAPL_IB_EVENT_CNT      13
-
-static struct ib_cm_event_map {
-       const ib_cm_events_t ib_cm_event;
-       DAT_EVENT_NUMBER dat_event_num;
-} ib_cm_event_map[DAPL_IB_EVENT_CNT] = {
-       /* 00 */  {
-       IB_CME_CONNECTED, DAT_CONNECTION_EVENT_ESTABLISHED},
-           /* 01 */  {
-       IB_CME_DISCONNECTED, DAT_CONNECTION_EVENT_DISCONNECTED},
-           /* 02 */  {
-       IB_CME_DISCONNECTED_ON_LINK_DOWN,
-                   DAT_CONNECTION_EVENT_DISCONNECTED},
-           /* 03 */  {
-       IB_CME_CONNECTION_REQUEST_PENDING, DAT_CONNECTION_REQUEST_EVENT},
-           /* 04 */  {
-       IB_CME_CONNECTION_REQUEST_PENDING_PRIVATE_DATA,
-                   DAT_CONNECTION_REQUEST_EVENT},
-           /* 05 */  {
-       IB_CME_CONNECTION_REQUEST_ACKED, DAT_CONNECTION_REQUEST_EVENT},
-           /* 06 */  {
-       IB_CME_DESTINATION_REJECT,
-                   DAT_CONNECTION_EVENT_NON_PEER_REJECTED},
-           /* 07 */  {
-       IB_CME_DESTINATION_REJECT_PRIVATE_DATA,
-                   DAT_CONNECTION_EVENT_PEER_REJECTED},
-           /* 08 */  {
-       IB_CME_DESTINATION_UNREACHABLE, DAT_CONNECTION_EVENT_UNREACHABLE},
-           /* 09 */  {
-       IB_CME_TOO_MANY_CONNECTION_REQUESTS,
-                   DAT_CONNECTION_EVENT_NON_PEER_REJECTED},
-           /* 10 */  {
-       IB_CME_LOCAL_FAILURE, DAT_CONNECTION_EVENT_BROKEN},
-           /* 11 */  {
-       IB_CME_BROKEN, DAT_CONNECTION_EVENT_BROKEN},
-           /* 12 */  {
-IB_CME_TIMEOUT, DAT_CONNECTION_EVENT_TIMED_OUT},};
-
-/*
- * dapls_ib_get_cm_event
- *
- * Return a DAT connection event given a provider CM event.
- *
- * Input:
- *     dat_event_num   DAT event we need an equivelent CM event for
- *
- * Output:
- *     none
- *
- * Returns:
- *     ib_cm_event of translated DAPL value
- */
-DAT_EVENT_NUMBER
-dapls_ib_get_dat_event(IN const ib_cm_events_t ib_cm_event,
-                      IN DAT_BOOLEAN active)
-{
-       DAT_EVENT_NUMBER dat_event_num;
-       int i;
-
-       active = active;
-
-       dat_event_num = 0;
-       for (i = 0; i < DAPL_IB_EVENT_CNT; i++) {
-               if (ib_cm_event == ib_cm_event_map[i].ib_cm_event) {
-                       dat_event_num = ib_cm_event_map[i].dat_event_num;
-                       break;
-               }
-       }
-       dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,
-                    "dapls_ib_get_dat_event: event(%s) ib=0x%x dat=0x%x\n",
-                    active ? "active" : "passive", ib_cm_event, dat_event_num);
-
-       return dat_event_num;
-}
-
-/*
- * dapls_ib_get_dat_event
- *
- * Return a DAT connection event given a provider CM event.
- * 
- * Input:
- *     ib_cm_event     event provided to the dapl callback routine
- *     active          switch indicating active or passive connection
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_EVENT_NUMBER of translated provider value
- */
-ib_cm_events_t dapls_ib_get_cm_event(IN DAT_EVENT_NUMBER dat_event_num)
-{
-       ib_cm_events_t ib_cm_event;
-       int i;
-
-       ib_cm_event = 0;
-       for (i = 0; i < DAPL_IB_EVENT_CNT; i++) {
-               if (dat_event_num == ib_cm_event_map[i].dat_event_num) {
-                       ib_cm_event = ib_cm_event_map[i].ib_cm_event;
-                       break;
-               }
-       }
-       return ib_cm_event;
-}
-
-void dapli_cma_event_cb(void)
-{
-       struct rdma_cm_event *event;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " cm_event()\n");
-
-       /* process one CM event, fairness */
-       if (!rdma_get_cm_event(g_cm_events, &event)) {
-               struct dapl_cm_id *conn;
-
-               /* set proper conn from cm_id context */
-               if (event->event == RDMA_CM_EVENT_CONNECT_REQUEST)
-                       conn = (struct dapl_cm_id *)event->listen_id->context;
-               else
-                       conn = (struct dapl_cm_id *)event->id->context;
-
-               dapl_dbg_log(DAPL_DBG_TYPE_CM,
-                            " cm_event: EVENT=%d ID=%p LID=%p CTX=%p\n",
-                            event->event, event->id, event->listen_id, conn);
-
-               switch (event->event) {
-               case RDMA_CM_EVENT_ADDR_RESOLVED:
-                       dapli_addr_resolve(conn);
-                       break;
-
-               case RDMA_CM_EVENT_ROUTE_RESOLVED:
-                       dapli_route_resolve(conn);
-                       break;
-
-               case RDMA_CM_EVENT_ADDR_ERROR:
-                       dapl_log(DAPL_DBG_TYPE_WARN,
-                                "dapl_cma_active: CM ADDR ERROR: ->"
-                                " DST %s retry (%d)..\n",
-                                inet_ntoa(((struct sockaddr_in *)
-                                           &conn->r_addr)->sin_addr),
-                                conn->arp_retries);
-
-                       /* retry address resolution */
-                       if ((--conn->arp_retries) &&
-                           (event->status == -ETIMEDOUT)) {
-                               int ret;
-                               ret = rdma_resolve_addr(conn->cm_id, NULL,
-                                                       (struct sockaddr *)
-                                                       &conn->r_addr,
-                                                       conn->arp_timeout);
-                               if (!ret)
-                                       break;
-                               else {
-                                       dapl_dbg_log(DAPL_DBG_TYPE_WARN,
-                                                    " ERROR: rdma_resolve_addr = "
-                                                    "%d %s\n",
-                                                    ret, strerror(errno));
-                               }
-                       }
-                       /* retries exhausted or resolve_addr failed */
-                       dapl_log(DAPL_DBG_TYPE_ERR,
-                                "dapl_cma_active: ARP_ERR, retries(%d)"
-                                " exhausted -> DST %s,%d\n",
-                                IB_ARP_RETRY_COUNT,
-                                inet_ntoa(((struct sockaddr_in *)
-                                           &conn->cm_id->route.addr.dst_addr)->
-                                          sin_addr),
-                                ntohs(((struct sockaddr_in *)
-                                       &conn->cm_id->route.addr.dst_addr)->
-                                      sin_port));
-
-                       dapl_evd_connection_callback(conn,
-                                                    IB_CME_DESTINATION_UNREACHABLE,
-                                                    NULL, conn->ep);
-                       break;
-
-               case RDMA_CM_EVENT_ROUTE_ERROR:
-                       dapl_log(DAPL_DBG_TYPE_WARN,
-                                "dapl_cma_active: CM ROUTE ERROR: ->"
-                                " DST %s retry (%d)..\n",
-                                inet_ntoa(((struct sockaddr_in *)
-                                           &conn->r_addr)->sin_addr),
-                                conn->route_retries);
-
-                       /* retry route resolution */
-                       if ((--conn->route_retries) &&
-                           (event->status == -ETIMEDOUT))
-                               dapli_addr_resolve(conn);
-                       else {
-                               dapl_log(DAPL_DBG_TYPE_ERR,
-                                        "dapl_cma_active: PATH_RECORD_ERR,"
-                                        " retries(%d) exhausted, DST %s,%d\n",
-                                        IB_ROUTE_RETRY_COUNT,
-                                        inet_ntoa(((struct sockaddr_in *)
-                                                   &conn->cm_id->route.addr.
-                                                   dst_addr)->sin_addr),
-                                        ntohs(((struct sockaddr_in *)
-                                               &conn->cm_id->route.addr.
-                                               dst_addr)->sin_port));
-
-                               dapl_evd_connection_callback(conn,
-                                                            IB_CME_DESTINATION_UNREACHABLE,
-                                                            NULL, conn->ep);
-                       }
-                       break;
-
-               case RDMA_CM_EVENT_DEVICE_REMOVAL:
-                       dapl_evd_connection_callback(conn,
-                                                    IB_CME_LOCAL_FAILURE,
-                                                    NULL, conn->ep);
-                       break;
-               case RDMA_CM_EVENT_CONNECT_REQUEST:
-               case RDMA_CM_EVENT_CONNECT_ERROR:
-               case RDMA_CM_EVENT_UNREACHABLE:
-               case RDMA_CM_EVENT_REJECTED:
-               case RDMA_CM_EVENT_ESTABLISHED:
-               case RDMA_CM_EVENT_DISCONNECTED:
-                       /* passive or active */
-                       if (conn->sp)
-                               dapli_cm_passive_cb(conn, event);
-                       else
-                               dapli_cm_active_cb(conn, event);
-                       break;
-               case RDMA_CM_EVENT_CONNECT_RESPONSE:
-               default:
-                       dapl_dbg_log(DAPL_DBG_TYPE_WARN,
-                                    " cm_event: UNEXPECTED EVENT=%p ID=%p CTX=%p\n",
-                                    event->event, event->id,
-                                    event->id->context);
-                       break;
-               }
-               /* ack event, unblocks destroy_cm_id in consumer threads */
-               rdma_ack_cm_event(event);
-       }
-}
-
-/*
- * Local variables:
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 8
- * End:
- */
+/*\r
+ * Copyright (c) 2005 Voltaire Inc.  All rights reserved.\r
+ * Copyright (c) 2005-2007 Intel Corporation. All rights reserved.\r
+ * Copyright (c) 2004-2005, Mellanox Technologies, Inc. All rights reserved. \r
+ * Copyright (c) 2003 Topspin Corporation.  All rights reserved. \r
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.\r
+ *\r
+ * This Software is licensed under one of the following licenses:\r
+ *\r
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/cpl.php.\r
+ *\r
+ * 2) under the terms of the "The BSD License" a copy of which is\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/bsd-license.php.\r
+ *\r
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a\r
+ *    copy of which is available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/gpl-license.php.\r
+ *\r
+ * Licensee has the right to choose one of the above licenses.\r
+ *\r
+ * Redistributions of source code must retain the above copyright\r
+ * notice and one of the license notices.\r
+ *\r
+ * Redistributions in binary form must reproduce both the above copyright\r
+ * notice, one of the license notices in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ */\r
+\r
+/**********************************************************************\r
+ *\r
+ * MODULE: dapl_ib_cm.c\r
+ *\r
+ * PURPOSE: The OFED provider - uCMA, name and route resolution\r
+ *\r
+ * $Id: $\r
+ *\r
+ **********************************************************************/\r
+\r
+#include "dapl.h"\r
+#include "dapl_adapter_util.h"\r
+#include "dapl_evd_util.h"\r
+#include "dapl_cr_util.h"\r
+#include "dapl_name_service.h"\r
+#include "dapl_ib_util.h"\r
+#include "dapl_vendor.h"\r
+#include "dapl_osd.h"\r
+\r
+extern struct rdma_event_channel *g_cm_events;\r
+\r
+/* local prototypes */\r
+static struct dapl_cm_id *dapli_req_recv(struct dapl_cm_id *conn,\r
+                                        struct rdma_cm_event *event);\r
+static void dapli_cm_active_cb(struct dapl_cm_id *conn,\r
+                              struct rdma_cm_event *event);\r
+static void dapli_cm_passive_cb(struct dapl_cm_id *conn,\r
+                               struct rdma_cm_event *event);\r
+static void dapli_addr_resolve(struct dapl_cm_id *conn);\r
+static void dapli_route_resolve(struct dapl_cm_id *conn);\r
+\r
+/* cma requires 16 bit SID, in network order */\r
+#define IB_PORT_MOD 32001\r
+#define IB_PORT_BASE (65535 - IB_PORT_MOD)\r
+#define SID_TO_PORT(SID) \\r
+    (SID > 0xffff ? \\r
+    htons((unsigned short)((SID % IB_PORT_MOD) + IB_PORT_BASE)) :\\r
+    htons((unsigned short)SID))\r
+\r
+#define PORT_TO_SID(p) ntohs(p)\r
+\r
+/* private data header to validate consumer rejects versus abnormal events */\r
+struct dapl_pdata_hdr {\r
+       DAT_UINT32 version;\r
+};\r
+\r
+static void dapli_addr_resolve(struct dapl_cm_id *conn)\r
+{\r
+       int ret;\r
+#ifdef DAPL_DBG\r
+       struct rdma_addr *ipaddr = &conn->cm_id->route.addr;\r
+#endif\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " addr_resolve: cm_id %p SRC %x DST %x\n",\r
+                    conn->cm_id, ntohl(((struct sockaddr_in *)\r
+                                        &ipaddr->src_addr)->sin_addr.s_addr),\r
+                    ntohl(((struct sockaddr_in *)\r
+                           &ipaddr->dst_addr)->sin_addr.s_addr));\r
+\r
+       ret = rdma_resolve_route(conn->cm_id, conn->route_timeout);\r
+       if (ret) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " dapl_cma_connect: rdma_resolve_route ERR 0x%x %s\n",\r
+                        ret, strerror(errno));\r
+               dapl_evd_connection_callback(conn,\r
+                                            IB_CME_LOCAL_FAILURE,\r
+                                            NULL, conn->ep);\r
+       }\r
+}\r
+\r
+static void dapli_route_resolve(struct dapl_cm_id *conn)\r
+{\r
+       int ret;\r
+#ifdef DAPL_DBG\r
+       struct rdma_addr *ipaddr = &conn->cm_id->route.addr;\r
+       struct ib_addr *ibaddr = &conn->cm_id->route.addr.addr.ibaddr;\r
+#endif\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " route_resolve: cm_id %p SRC %x DST %x PORT %d\n",\r
+                    conn->cm_id, ntohl(((struct sockaddr_in *)\r
+                                        &ipaddr->src_addr)->sin_addr.s_addr),\r
+                    ntohl(((struct sockaddr_in *)\r
+                           &ipaddr->dst_addr)->sin_addr.s_addr),\r
+                    ntohs(((struct sockaddr_in *)\r
+                           &ipaddr->dst_addr)->sin_port));\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " route_resolve: SRC GID subnet %016llx id %016llx\n",\r
+                    (unsigned long long)\r
+                    ntohll(ibaddr->sgid.global.subnet_prefix),\r
+                    (unsigned long long)\r
+                    ntohll(ibaddr->sgid.global.interface_id));\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " route_resolve: DST GID subnet %016llx id %016llx\n",\r
+                    (unsigned long long)\r
+                    ntohll(ibaddr->dgid.global.subnet_prefix),\r
+                    (unsigned long long)\r
+                    ntohll(ibaddr->dgid.global.interface_id));\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " route_resolve: cm_id %p pdata %p plen %d rr %d ind %d\n",\r
+                    conn->cm_id,\r
+                    conn->params.private_data,\r
+                    conn->params.private_data_len,\r
+                    conn->params.responder_resources,\r
+                    conn->params.initiator_depth);\r
+\r
+       ret = rdma_connect(conn->cm_id, &conn->params);\r
+       if (ret) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " dapl_cma_connect: rdma_connect ERR %d %s\n",\r
+                        ret, strerror(errno));\r
+               goto bail;\r
+       }\r
+       return;\r
+\r
+      bail:\r
+       dapl_evd_connection_callback(conn,\r
+                                    IB_CME_LOCAL_FAILURE, NULL, conn->ep);\r
+}\r
+\r
+dp_ib_cm_handle_t dapls_ib_cm_create(DAPL_EP *ep)\r
+{\r
+       dp_ib_cm_handle_t conn;\r
+       struct rdma_cm_id *cm_id;\r
+\r
+       /* Allocate CM and initialize lock */\r
+       if ((conn = dapl_os_alloc(sizeof(*conn))) == NULL)\r
+               return NULL;\r
+\r
+       dapl_os_memzero(conn, sizeof(*conn));\r
+       dapl_os_lock_init(&conn->lock);\r
+\r
+       /* create CM_ID, bind to local device, create QP */\r
+       if (rdma_create_id(g_cm_events, &cm_id, (void *)conn, RDMA_PS_TCP)) {\r
+               dapl_os_free(conn, sizeof(*conn));\r
+               return NULL;\r
+       }\r
+       conn->cm_id = cm_id;\r
+\r
+       /* setup timers for address and route resolution */\r
+       conn->arp_timeout = dapl_os_get_env_val("DAPL_CM_ARP_TIMEOUT_MS",\r
+                                               IB_ARP_TIMEOUT);\r
+       conn->arp_retries = dapl_os_get_env_val("DAPL_CM_ARP_RETRY_COUNT",\r
+                                               IB_ARP_RETRY_COUNT);\r
+       conn->route_timeout = dapl_os_get_env_val("DAPL_CM_ROUTE_TIMEOUT_MS",\r
+                                                 IB_ROUTE_TIMEOUT);\r
+       conn->route_retries = dapl_os_get_env_val("DAPL_CM_ROUTE_RETRY_COUNT",\r
+                                                 IB_ROUTE_RETRY_COUNT);\r
+       if (ep != NULL) {\r
+               conn->ep = ep;\r
+               conn->hca = ((DAPL_IA *)ep->param.ia_handle)->hca_ptr;\r
+       }\r
+\r
+       return conn;\r
+}\r
+\r
+/* \r
+ * Called from consumer thread via dat_ep_free().\r
+ * CANNOT be called from the async event processing thread\r
+ * dapli_cma_event_cb() since a cm_id reference is held and\r
+ * a deadlock will occur.\r
+ */\r
+\r
+void dapls_ib_cm_free(dp_ib_cm_handle_t conn, DAPL_EP *ep)\r
+{\r
+       struct rdma_cm_id *cm_id;\r
+\r
+       if (conn == NULL)\r
+               return;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " destroy_conn: conn %p id %d\n", conn, conn->cm_id);\r
+\r
+       dapl_os_lock(&conn->lock);\r
+       conn->destroy = 1;\r
+\r
+       if (ep != NULL) {\r
+               ep->cm_handle = NULL;\r
+               ep->qp_handle = NULL;\r
+               ep->qp_state = IB_QP_STATE_ERROR;\r
+       }\r
+\r
+       cm_id = conn->cm_id;\r
+       conn->cm_id = NULL;\r
+       dapl_os_unlock(&conn->lock);\r
+\r
+       /* \r
+        * rdma_destroy_id will force synchronization with async CM event \r
+        * thread since it blocks until the in-process event reference\r
+        * is cleared during our event processing call exit.\r
+        */\r
+       if (cm_id) {\r
+               if (cm_id->qp)\r
+                       rdma_destroy_qp(cm_id);\r
+\r
+               rdma_destroy_id(cm_id);\r
+       }\r
+       dapl_os_free(conn, sizeof(*conn));\r
+}\r
+\r
+static struct dapl_cm_id *dapli_req_recv(struct dapl_cm_id *conn,\r
+                                        struct rdma_cm_event *event)\r
+{\r
+       struct dapl_cm_id *new_conn;\r
+#ifdef DAPL_DBG\r
+       struct rdma_addr *ipaddr = &event->id->route.addr;\r
+#endif\r
+\r
+       if (conn->sp == NULL) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+                            " dapli_rep_recv: on invalid listen " "handle\n");\r
+               return NULL;\r
+       }\r
+\r
+       /* allocate new cm_id and merge listen parameters */\r
+       new_conn = dapl_os_alloc(sizeof(*new_conn));\r
+       if (new_conn) {\r
+               (void)dapl_os_memzero(new_conn, sizeof(*new_conn));\r
+               dapl_os_lock_init(&new_conn->lock);\r
+               new_conn->cm_id = event->id;    /* provided by uCMA */\r
+               event->id->context = new_conn;  /* update CM_ID context */\r
+               new_conn->sp = conn->sp;\r
+               new_conn->hca = conn->hca;\r
+\r
+               /* Get requesters connect data, setup for accept */\r
+               new_conn->params.responder_resources =\r
+                   DAPL_MIN(event->param.conn.responder_resources,\r
+                            conn->hca->ib_trans.rd_atom_in);\r
+               new_conn->params.initiator_depth =\r
+                   DAPL_MIN(event->param.conn.initiator_depth,\r
+                            conn->hca->ib_trans.rd_atom_out);\r
+\r
+               new_conn->params.flow_control = event->param.conn.flow_control;\r
+               new_conn->params.rnr_retry_count =\r
+                   event->param.conn.rnr_retry_count;\r
+               new_conn->params.retry_count = event->param.conn.retry_count;\r
+\r
+               /* save private data */\r
+               if (event->param.conn.private_data_len) {\r
+                       dapl_os_memcpy(new_conn->p_data,\r
+                                      event->param.conn.private_data,\r
+                                      event->param.conn.private_data_len);\r
+                       new_conn->params.private_data = new_conn->p_data;\r
+                       new_conn->params.private_data_len =\r
+                           event->param.conn.private_data_len;\r
+               }\r
+\r
+               dapl_dbg_log(DAPL_DBG_TYPE_CM, " passive_cb: "\r
+                            "REQ: SP %p PORT %d LID %d "\r
+                            "NEW CONN %p ID %p pdata %p,%d\n",\r
+                            new_conn->sp, ntohs(((struct sockaddr_in *)\r
+                                                 &ipaddr->src_addr)->sin_port),\r
+                            event->listen_id, new_conn, event->id,\r
+                            event->param.conn.private_data,\r
+                            event->param.conn.private_data_len);\r
+\r
+               dapl_dbg_log(DAPL_DBG_TYPE_CM, " passive_cb: "\r
+                            "REQ: IP SRC %x PORT %d DST %x PORT %d "\r
+                            "rr %d init %d\n", ntohl(((struct sockaddr_in *)\r
+                                                      &ipaddr->src_addr)->\r
+                                                     sin_addr.s_addr),\r
+                            ntohs(((struct sockaddr_in *)\r
+                                   &ipaddr->src_addr)->sin_port),\r
+                            ntohl(((struct sockaddr_in *)\r
+                                   &ipaddr->dst_addr)->sin_addr.s_addr),\r
+                            ntohs(((struct sockaddr_in *)\r
+                                   &ipaddr->dst_addr)->sin_port),\r
+                            new_conn->params.responder_resources,\r
+                            new_conn->params.initiator_depth);\r
+       }\r
+       return new_conn;\r
+}\r
+\r
+static void dapli_cm_active_cb(struct dapl_cm_id *conn,\r
+                              struct rdma_cm_event *event)\r
+{\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " active_cb: conn %p id %d event %d\n",\r
+                    conn, conn->cm_id, event->event);\r
+\r
+       dapl_os_lock(&conn->lock);\r
+       if (conn->destroy) {\r
+               dapl_os_unlock(&conn->lock);\r
+               return;\r
+       }\r
+       dapl_os_unlock(&conn->lock);\r
+\r
+       /* There is a chance that we can get events after\r
+        * the consumer calls disconnect in a pending state\r
+        * since the IB CM and uDAPL states are not shared.\r
+        * In some cases, IB CM could generate either a DCONN\r
+        * or CONN_ERR after the consumer returned from\r
+        * dapl_ep_disconnect with a DISCONNECTED event\r
+        * already queued. Check state here and bail to\r
+        * avoid any events after a disconnect.\r
+        */\r
+       if (DAPL_BAD_HANDLE(conn->ep, DAPL_MAGIC_EP))\r
+               return;\r
+\r
+       dapl_os_lock(&conn->ep->header.lock);\r
+       if (conn->ep->param.ep_state == DAT_EP_STATE_DISCONNECTED) {\r
+               dapl_os_unlock(&conn->ep->header.lock);\r
+               return;\r
+       }\r
+       if (event->event == RDMA_CM_EVENT_DISCONNECTED)\r
+               conn->ep->param.ep_state = DAT_EP_STATE_DISCONNECTED;\r
+\r
+       dapl_os_unlock(&conn->ep->header.lock);\r
+\r
+       switch (event->event) {\r
+       case RDMA_CM_EVENT_UNREACHABLE:\r
+       case RDMA_CM_EVENT_CONNECT_ERROR:\r
+               {\r
+                       dapl_log(DAPL_DBG_TYPE_WARN,\r
+                                "dapl_cma_active: CONN_ERR event=0x%x"\r
+                                " status=%d %s DST %s, %d\n",\r
+                                event->event, event->status,\r
+                                (event->status == -ETIMEDOUT) ? "TIMEOUT" : "",\r
+                                inet_ntoa(((struct sockaddr_in *)\r
+                                           &conn->cm_id->route.addr.dst_addr)->\r
+                                          sin_addr),\r
+                                ntohs(((struct sockaddr_in *)\r
+                                       &conn->cm_id->route.addr.dst_addr)->\r
+                                      sin_port));\r
+\r
+                       /* per DAT SPEC provider always returns UNREACHABLE */\r
+                       dapl_evd_connection_callback(conn,\r
+                                                    IB_CME_DESTINATION_UNREACHABLE,\r
+                                                    NULL, conn->ep);\r
+                       break;\r
+               }\r
+       case RDMA_CM_EVENT_REJECTED:\r
+               {\r
+                       ib_cm_events_t cm_event;\r
+                       unsigned char *pdata = NULL;\r
+\r
+                       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                                    " dapli_cm_active_handler: REJECTED reason=%d\n",\r
+                                    event->status);\r
+\r
+                       /* valid REJ from consumer will always contain private data */\r
+                       if (event->status == 28 &&\r
+                           event->param.conn.private_data_len) {\r
+                               cm_event =\r
+                                   IB_CME_DESTINATION_REJECT_PRIVATE_DATA;\r
+                               pdata =\r
+                                   (unsigned char *)event->param.conn.\r
+                                   private_data +\r
+                                   sizeof(struct dapl_pdata_hdr);\r
+                       } else {\r
+                               cm_event = IB_CME_DESTINATION_REJECT;\r
+                               dapl_log(DAPL_DBG_TYPE_WARN,\r
+                                        "dapl_cma_active: non-consumer REJ,"\r
+                                        " reason=%d, DST %s, %d\n",\r
+                                        event->status,\r
+                                        inet_ntoa(((struct sockaddr_in *)\r
+                                                   &conn->cm_id->route.addr.\r
+                                                   dst_addr)->sin_addr),\r
+                                        ntohs(((struct sockaddr_in *)\r
+                                               &conn->cm_id->route.addr.\r
+                                               dst_addr)->sin_port));\r
+                       }\r
+                       dapl_evd_connection_callback(conn, cm_event, pdata,\r
+                                                    conn->ep);\r
+                       break;\r
+               }\r
+       case RDMA_CM_EVENT_ESTABLISHED:\r
+               dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                            " active_cb: cm_id %d PORT %d CONNECTED to %s!\n",\r
+                            conn->cm_id, ntohs(((struct sockaddr_in *)\r
+                                                &conn->cm_id->route.addr.\r
+                                                dst_addr)->sin_port),\r
+                            inet_ntoa(((struct sockaddr_in *)\r
+                                       &conn->cm_id->route.addr.dst_addr)->\r
+                                      sin_addr));\r
+\r
+               /* setup local and remote ports for ep query */\r
+               conn->ep->param.remote_port_qual =\r
+                   PORT_TO_SID(rdma_get_dst_port(conn->cm_id));\r
+               conn->ep->param.local_port_qual =\r
+                   PORT_TO_SID(rdma_get_src_port(conn->cm_id));\r
+\r
+               dapl_evd_connection_callback(conn, IB_CME_CONNECTED,\r
+                                            event->param.conn.private_data,\r
+                                            conn->ep);\r
+               break;\r
+\r
+       case RDMA_CM_EVENT_DISCONNECTED:\r
+               dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                            " active_cb: DISC EVENT - EP %p\n",conn->ep);\r
+               rdma_disconnect(conn->cm_id);   /* required for DREP */\r
+               /* validate EP handle */\r
+               if (!DAPL_BAD_HANDLE(conn->ep, DAPL_MAGIC_EP))\r
+                       dapl_evd_connection_callback(conn,\r
+                                                    IB_CME_DISCONNECTED,\r
+                                                    NULL, conn->ep);\r
+               break;\r
+       default:\r
+               dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+                            " dapli_cm_active_cb_handler: Unexpected CM "\r
+                            "event %d on ID 0x%p\n", event->event,\r
+                            conn->cm_id);\r
+               break;\r
+       }\r
+\r
+       return;\r
+}\r
+\r
+static void dapli_cm_passive_cb(struct dapl_cm_id *conn,\r
+                               struct rdma_cm_event *event)\r
+{\r
+       struct dapl_cm_id *new_conn;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " passive_cb: conn %p id %d event %d\n",\r
+                    conn, event->id, event->event);\r
+\r
+       dapl_os_lock(&conn->lock);\r
+       if (conn->destroy) {\r
+               dapl_os_unlock(&conn->lock);\r
+               return;\r
+       }\r
+       dapl_os_unlock(&conn->lock);\r
+\r
+       switch (event->event) {\r
+       case RDMA_CM_EVENT_CONNECT_REQUEST:\r
+               /* create new conn object with new conn_id from event */\r
+               new_conn = dapli_req_recv(conn, event);\r
+\r
+               if (new_conn)\r
+                       dapls_cr_callback(new_conn,\r
+                                         IB_CME_CONNECTION_REQUEST_PENDING,\r
+                                         event->param.conn.private_data,\r
+                                         new_conn->sp);\r
+               break;\r
+       case RDMA_CM_EVENT_UNREACHABLE:\r
+       case RDMA_CM_EVENT_CONNECT_ERROR:\r
+               dapl_log(DAPL_DBG_TYPE_WARN,\r
+                        "dapl_cm_passive: CONN_ERR event=0x%x status=%d %s,"\r
+                        " DST %s,%d\n",\r
+                        event->event, event->status,\r
+                        (event->status == -ETIMEDOUT) ? "TIMEOUT" : "",\r
+                        inet_ntoa(((struct sockaddr_in *)\r
+                                   &conn->cm_id->route.addr.dst_addr)->\r
+                                  sin_addr), ntohs(((struct sockaddr_in *)\r
+                                                    &conn->cm_id->route.addr.\r
+                                                    dst_addr)->sin_port));\r
+\r
+               dapls_cr_callback(conn, IB_CME_DESTINATION_UNREACHABLE,\r
+                                 NULL, conn->sp);\r
+               break;\r
+\r
+       case RDMA_CM_EVENT_REJECTED:\r
+               {\r
+                       /* will alwasys be abnormal NON-consumer from active side */\r
+                       dapl_log(DAPL_DBG_TYPE_WARN,\r
+                                "dapl_cm_passive: non-consumer REJ, reason=%d,"\r
+                                " DST %s, %d\n",\r
+                                event->status,\r
+                                inet_ntoa(((struct sockaddr_in *)\r
+                                           &conn->cm_id->route.addr.dst_addr)->\r
+                                          sin_addr),\r
+                                ntohs(((struct sockaddr_in *)\r
+                                       &conn->cm_id->route.addr.dst_addr)->\r
+                                      sin_port));\r
+\r
+                       dapls_cr_callback(conn, IB_CME_DESTINATION_REJECT,\r
+                                         NULL, conn->sp);\r
+                       break;\r
+               }\r
+       case RDMA_CM_EVENT_ESTABLISHED:\r
+               dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                            " passive_cb: cm_id %p PORT %d CONNECTED from 0x%x!\n",\r
+                            conn->cm_id, ntohs(((struct sockaddr_in *)\r
+                                                &conn->cm_id->route.addr.\r
+                                                src_addr)->sin_port),\r
+                            ntohl(((struct sockaddr_in *)\r
+                                   &conn->cm_id->route.addr.dst_addr)->\r
+                                  sin_addr.s_addr));\r
+\r
+               dapls_cr_callback(conn, IB_CME_CONNECTED, NULL, conn->sp);\r
+\r
+               break;\r
+       case RDMA_CM_EVENT_DISCONNECTED:\r
+               rdma_disconnect(conn->cm_id);   /* required for DREP */\r
+               /* validate SP handle context */\r
+               if (!DAPL_BAD_HANDLE(conn->sp, DAPL_MAGIC_PSP) ||\r
+                   !DAPL_BAD_HANDLE(conn->sp, DAPL_MAGIC_RSP))\r
+                       dapls_cr_callback(conn,\r
+                                         IB_CME_DISCONNECTED, NULL, conn->sp);\r
+               break;\r
+       default:\r
+               dapl_dbg_log(DAPL_DBG_TYPE_ERR, " passive_cb: "\r
+                            "Unexpected CM event %d on ID 0x%p\n",\r
+                            event->event, conn->cm_id);\r
+               break;\r
+       }\r
+\r
+       return;\r
+}\r
+\r
+/************************ DAPL provider entry points **********************/\r
+\r
+/*\r
+ * dapls_ib_connect\r
+ *\r
+ * Initiate a connection with the passive listener on another node\r
+ *\r
+ * Input:\r
+ *     ep_handle,\r
+ *     remote_ia_address,\r
+ *     remote_conn_qual,\r
+ *     prd_size                size of private data and structure\r
+ *     prd_prt                 pointer to private data structure\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *     DAT_INVALID_PARAMETER\r
+ *\r
+ */\r
+DAT_RETURN dapls_ib_connect(IN DAT_EP_HANDLE ep_handle,\r
+                           IN DAT_IA_ADDRESS_PTR r_addr,\r
+                           IN DAT_CONN_QUAL r_qual,\r
+                           IN DAT_COUNT p_size, IN void *p_data)\r
+{\r
+       struct dapl_ep *ep_ptr = ep_handle;\r
+       struct dapl_cm_id *conn = ep_ptr->cm_handle;\r
+       int ret;\r
+\r
+       /* Sanity check */\r
+       if (NULL == ep_ptr)\r
+               return DAT_SUCCESS;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " connect: rSID 0x%llx rPort %d, pdata %p, ln %d\n",\r
+                    r_qual, ntohs(SID_TO_PORT(r_qual)), p_data, p_size);\r
+\r
+       /* rdma conn and cm_id pre-bound; reference via ep_ptr->cm_handle */\r
+\r
+       /* Setup QP/CM parameters and private data in cm_id */\r
+       (void)dapl_os_memzero(&conn->params, sizeof(conn->params));\r
+       conn->params.responder_resources =\r
+           ep_ptr->param.ep_attr.max_rdma_read_in;\r
+       conn->params.initiator_depth = ep_ptr->param.ep_attr.max_rdma_read_out;\r
+       conn->params.flow_control = 1;\r
+       conn->params.rnr_retry_count = IB_RNR_RETRY_COUNT;\r
+       conn->params.retry_count = IB_RC_RETRY_COUNT;\r
+       if (p_size) {\r
+               dapl_os_memcpy(conn->p_data, p_data, p_size);\r
+               conn->params.private_data = conn->p_data;\r
+               conn->params.private_data_len = p_size;\r
+       }\r
+\r
+       /* copy in remote address, need a copy for retry attempts */\r
+       dapl_os_memcpy(&conn->r_addr, r_addr, sizeof(*r_addr));\r
+\r
+       /* Resolve remote address, src already bound during QP create */\r
+       ((struct sockaddr_in *)&conn->r_addr)->sin_port = SID_TO_PORT(r_qual);\r
+       ((struct sockaddr_in *)&conn->r_addr)->sin_family = AF_INET;\r
+\r
+       ret = rdma_resolve_addr(conn->cm_id, NULL,\r
+                               (struct sockaddr *)&conn->r_addr,\r
+                               conn->arp_timeout);\r
+       if (ret) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " dapl_cma_connect: rdma_resolve_addr ERR 0x%x %s\n",\r
+                        ret, strerror(errno));\r
+               return dapl_convert_errno(errno, "ib_connect");\r
+       }\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " connect: resolve_addr: cm_id %p -> %s port %d\n",\r
+                    conn->cm_id,\r
+                    inet_ntoa(((struct sockaddr_in *)&conn->r_addr)->sin_addr),\r
+                    ((struct sockaddr_in *)&conn->r_addr)->sin_port);\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * dapls_ib_disconnect\r
+ *\r
+ * Disconnect an EP\r
+ *\r
+ * Input:\r
+ *     ep_handle,\r
+ *     disconnect_flags\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_disconnect(IN DAPL_EP * ep_ptr, IN DAT_CLOSE_FLAGS close_flags)\r
+{\r
+       dp_ib_cm_handle_t conn = ep_ptr->cm_handle;\r
+       int ret;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " disconnect(ep %p, conn %p, id %d flags %x)\n",\r
+                    ep_ptr, conn, (conn ? conn->cm_id : 0), close_flags);\r
+\r
+       if ((conn == IB_INVALID_HANDLE) || (conn->cm_id == NULL))\r
+               return DAT_SUCCESS;\r
+\r
+       /* no graceful half-pipe disconnect option */\r
+       ret = rdma_disconnect(conn->cm_id);\r
+       if (ret)\r
+               dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+                            " disconnect: ID %p ret 0x%x\n",\r
+                            ep_ptr->cm_handle, ret);\r
+\r
+       /* \r
+        * DAT event notification occurs from the callback\r
+        * Note: will fire even if DREQ goes unanswered on timeout \r
+        */\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * dapls_ib_disconnect_clean\r
+ *\r
+ * Clean up outstanding connection data. This routine is invoked\r
+ * after the final disconnect callback has occurred. Only on the\r
+ * ACTIVE side of a connection.\r
+ *\r
+ * Input:\r
+ *     ep_ptr          DAPL_EP\r
+ *     active          Indicates active side of connection\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     void\r
+ *\r
+ */\r
+void\r
+dapls_ib_disconnect_clean(IN DAPL_EP * ep_ptr,\r
+                         IN DAT_BOOLEAN active,\r
+                         IN const ib_cm_events_t ib_cm_event)\r
+{\r
+       /* nothing to do */\r
+       return;\r
+}\r
+\r
+/*\r
+ * dapl_ib_setup_conn_listener\r
+ *\r
+ * Have the CM set up a connection listener.\r
+ *\r
+ * Input:\r
+ *     ibm_hca_handle          HCA handle\r
+ *     qp_handle                       QP handle\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *     DAT_INTERNAL_ERROR\r
+ *     DAT_CONN_QUAL_UNAVAILBLE\r
+ *     DAT_CONN_QUAL_IN_USE\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_setup_conn_listener(IN DAPL_IA * ia_ptr,\r
+                            IN DAT_UINT64 ServiceID, IN DAPL_SP * sp_ptr)\r
+{\r
+       DAT_RETURN dat_status = DAT_SUCCESS;\r
+       ib_cm_srvc_handle_t conn;\r
+       DAT_SOCK_ADDR6 addr;    /* local binding address */\r
+\r
+       /* Allocate CM and initialize lock */\r
+       if ((conn = dapl_os_alloc(sizeof(*conn))) == NULL)\r
+               return DAT_INSUFFICIENT_RESOURCES;\r
+\r
+       dapl_os_memzero(conn, sizeof(*conn));\r
+       dapl_os_lock_init(&conn->lock);\r
+\r
+       /* create CM_ID, bind to local device, create QP */\r
+       if (rdma_create_id\r
+           (g_cm_events, &conn->cm_id, (void *)conn, RDMA_PS_TCP)) {\r
+               dapl_os_free(conn, sizeof(*conn));\r
+               return (dapl_convert_errno(errno, "setup_listener"));\r
+       }\r
+\r
+       /* open identifies the local device; per DAT specification */\r
+       /* Get family and address then set port to consumer's ServiceID */\r
+       dapl_os_memcpy(&addr, &ia_ptr->hca_ptr->hca_address, sizeof(addr));\r
+       ((struct sockaddr_in *)&addr)->sin_port = SID_TO_PORT(ServiceID);\r
+\r
+       if (rdma_bind_addr(conn->cm_id, (struct sockaddr *)&addr)) {\r
+               if ((errno == EBUSY) || (errno == EADDRINUSE))\r
+                       dat_status = DAT_CONN_QUAL_IN_USE;\r
+               else\r
+                       dat_status =\r
+                           dapl_convert_errno(errno, "setup_listener");\r
+               goto bail;\r
+       }\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " listen(ia_ptr %p SID 0x%llx Port %d sp %p conn %p id %d)\n",\r
+                    ia_ptr, ServiceID, ntohs(SID_TO_PORT(ServiceID)),\r
+                    sp_ptr, conn, conn->cm_id);\r
+\r
+       sp_ptr->cm_srvc_handle = conn;\r
+       conn->sp = sp_ptr;\r
+       conn->hca = ia_ptr->hca_ptr;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_EP,\r
+                    " listen(conn=%p cm_id=%d)\n",\r
+                    sp_ptr->cm_srvc_handle, conn->cm_id);\r
+\r
+       if (rdma_listen(conn->cm_id, 0)) {      /* max cma backlog */\r
+\r
+               if ((errno == EBUSY) || (errno == EADDRINUSE))\r
+                       dat_status = DAT_CONN_QUAL_IN_USE;\r
+               else\r
+                       dat_status =\r
+                           dapl_convert_errno(errno, "setup_listener");\r
+               goto bail;\r
+       }\r
+\r
+       /* success */\r
+       return DAT_SUCCESS;\r
+\r
+      bail:\r
+       rdma_destroy_id(conn->cm_id);\r
+       dapl_os_free(conn, sizeof(*conn));\r
+       return dat_status;\r
+}\r
+\r
+/*\r
+ * dapl_ib_remove_conn_listener\r
+ *\r
+ * Have the CM remove a connection listener.\r
+ *\r
+ * Input:\r
+ *     ia_handle               IA handle\r
+ *     ServiceID               IB Channel Service ID\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INVALID_STATE\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_remove_conn_listener(IN DAPL_IA * ia_ptr, IN DAPL_SP * sp_ptr)\r
+{\r
+       ib_cm_srvc_handle_t conn = sp_ptr->cm_srvc_handle;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " remove_listen(ia_ptr %p sp_ptr %p cm_ptr %p)\n",\r
+                    ia_ptr, sp_ptr, conn);\r
+\r
+       if (conn != IB_INVALID_HANDLE) {\r
+               sp_ptr->cm_srvc_handle = NULL;\r
+               dapls_ib_cm_free(conn, NULL);\r
+       }\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * dapls_ib_accept_connection\r
+ *\r
+ * Perform necessary steps to accept a connection\r
+ *\r
+ * Input:\r
+ *     cr_handle\r
+ *     ep_handle\r
+ *     private_data_size\r
+ *     private_data\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *     DAT_INTERNAL_ERROR\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_accept_connection(IN DAT_CR_HANDLE cr_handle,\r
+                          IN DAT_EP_HANDLE ep_handle,\r
+                          IN DAT_COUNT p_size, IN const DAT_PVOID p_data)\r
+{\r
+       DAPL_CR *cr_ptr = (DAPL_CR *) cr_handle;\r
+       DAPL_EP *ep_ptr = (DAPL_EP *) ep_handle;\r
+       DAPL_IA *ia_ptr = ep_ptr->header.owner_ia;\r
+       struct dapl_cm_id *cr_conn = cr_ptr->ib_cm_handle;\r
+       int ret;\r
+       DAT_RETURN dat_status;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " accept(cr %p conn %p, id %p, p_data %p, p_sz=%d)\n",\r
+                    cr_ptr, cr_conn, cr_conn->cm_id, p_data, p_size);\r
+\r
+       /* Obtain size of private data structure & contents */\r
+       if (p_size > IB_MAX_REP_PDATA_SIZE) {\r
+               dat_status = DAT_ERROR(DAT_LENGTH_ERROR, DAT_NO_SUBTYPE);\r
+               goto bail;\r
+       }\r
+\r
+       if (ep_ptr->qp_state == DAPL_QP_STATE_UNATTACHED) {\r
+               /* \r
+                * If we are lazy attaching the QP then we may need to\r
+                * hook it up here. Typically, we run this code only for\r
+                * DAT_PSP_PROVIDER_FLAG\r
+                */\r
+               dat_status = dapls_ib_qp_alloc(ia_ptr, ep_ptr, NULL);\r
+               if (dat_status != DAT_SUCCESS) {\r
+                       dapl_log(DAPL_DBG_TYPE_ERR,\r
+                                " dapl_cma_accept: qp_alloc ERR %d\n",\r
+                                dat_status);\r
+                       goto bail;\r
+               }\r
+       }\r
+\r
+       /* \r
+        * Validate device and port in EP cm_id against inbound \r
+        * CR cm_id. The pre-allocated EP cm_id is already bound to \r
+        * a local device (cm_id and QP) when created. Move the QP\r
+        * to the new cm_id only if device and port numbers match.\r
+        */\r
+       if (ep_ptr->cm_handle->cm_id->verbs == cr_conn->cm_id->verbs &&\r
+           ep_ptr->cm_handle->cm_id->port_num == cr_conn->cm_id->port_num) {\r
+               /* move QP to new cr_conn, remove QP ref in EP cm_id */\r
+               cr_conn->cm_id->qp = ep_ptr->cm_handle->cm_id->qp;\r
+               ep_ptr->cm_handle->cm_id->qp = NULL;\r
+               dapls_ib_cm_free(ep_ptr->cm_handle, NULL);\r
+       } else {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " dapl_cma_accept: ERR dev(%p!=%p) or"\r
+                        " port mismatch(%d!=%d)\n",\r
+                        ep_ptr->cm_handle->cm_id->verbs, cr_conn->cm_id->verbs,\r
+                        ntohs(ep_ptr->cm_handle->cm_id->port_num),\r
+                        ntohs(cr_conn->cm_id->port_num));\r
+               dat_status = DAT_INTERNAL_ERROR;\r
+               goto bail;\r
+       }\r
+\r
+       cr_ptr->param.local_ep_handle = ep_handle;\r
+       cr_conn->params.private_data = p_data;\r
+       cr_conn->params.private_data_len = p_size;\r
+\r
+       ret = rdma_accept(cr_conn->cm_id, &cr_conn->params);\r
+       if (ret) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR, " dapl_cma_accept: ERR %d %s\n",\r
+                        ret, strerror(errno));\r
+               dat_status = dapl_convert_errno(ret, "accept");\r
+               goto bail;\r
+       }\r
+\r
+       /* save accepted conn and EP reference, qp_handle unchanged */\r
+       ep_ptr->cm_handle = cr_conn;\r
+       cr_conn->ep = ep_ptr;\r
+\r
+       /* setup local and remote ports for ep query */\r
+       /* Note: port qual in network order */\r
+       ep_ptr->param.remote_port_qual =\r
+           PORT_TO_SID(rdma_get_dst_port(cr_conn->cm_id));\r
+       ep_ptr->param.local_port_qual =\r
+           PORT_TO_SID(rdma_get_src_port(cr_conn->cm_id));\r
+\r
+       return DAT_SUCCESS;\r
+      bail:\r
+       rdma_reject(cr_conn->cm_id, NULL, 0);\r
+       dapls_ib_cm_free(cr_conn, NULL);\r
+       return dat_status;\r
+}\r
+\r
+/*\r
+ * dapls_ib_reject_connection\r
+ *\r
+ * Reject a connection\r
+ *\r
+ * Input:\r
+ *     cr_handle\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INTERNAL_ERROR\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_reject_connection(IN dp_ib_cm_handle_t cm_handle,\r
+                          IN int reason,\r
+                          IN DAT_COUNT private_data_size,\r
+                          IN const DAT_PVOID private_data)\r
+{\r
+       int ret;\r
+       int offset = sizeof(struct dapl_pdata_hdr);\r
+       struct dapl_pdata_hdr pdata_hdr;\r
+\r
+       memset(&pdata_hdr, 0, sizeof pdata_hdr);\r
+       pdata_hdr.version = htonl((DAT_VERSION_MAJOR << 24) |\r
+                                 (DAT_VERSION_MINOR << 16) |\r
+                                 (VN_PROVIDER_MAJOR << 8) |\r
+                                 (VN_PROVIDER_MINOR));\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " reject: handle %p reason %x, ver=%x, data %p, sz=%d\n",\r
+                    cm_handle, reason, ntohl(pdata_hdr.version),\r
+                    private_data, private_data_size);\r
+\r
+       if (cm_handle == IB_INVALID_HANDLE) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+                            " reject: invalid handle: reason %d\n", reason);\r
+               return DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_CR);\r
+       }\r
+\r
+       if (private_data_size >\r
+           dapls_ib_private_data_size(NULL, DAPL_PDATA_CONN_REJ,\r
+                                      cm_handle->hca))\r
+               return DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3);\r
+\r
+       /* setup pdata_hdr and users data, in CR pdata buffer */\r
+       dapl_os_memcpy(cm_handle->p_data, &pdata_hdr, offset);\r
+       if (private_data_size)\r
+               dapl_os_memcpy(cm_handle->p_data + offset,\r
+                              private_data, private_data_size);\r
+\r
+       /*\r
+        * Always some private data with reject so active peer can\r
+        * determine real application reject from an abnormal \r
+        * application termination\r
+        */\r
+       ret = rdma_reject(cm_handle->cm_id,\r
+                         cm_handle->p_data, offset + private_data_size);\r
+\r
+       dapls_ib_cm_free(cm_handle, NULL);\r
+       return dapl_convert_errno(ret, "reject");\r
+}\r
+\r
+/*\r
+ * dapls_ib_cm_remote_addr\r
+ *\r
+ * Obtain the remote IP address given a connection\r
+ *\r
+ * Input:\r
+ *     cr_handle\r
+ *\r
+ * Output:\r
+ *     remote_ia_address: where to place the remote address\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INVALID_HANDLE\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_cm_remote_addr(IN DAT_HANDLE dat_handle, OUT DAT_SOCK_ADDR6 * raddr)\r
+{\r
+       DAPL_HEADER *header;\r
+       dp_ib_cm_handle_t ib_cm_handle;\r
+       struct rdma_addr *ipaddr;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_EP,\r
+                    " remote_addr(cm_handle=%p, r_addr=%p)\n",\r
+                    dat_handle, raddr);\r
+\r
+       header = (DAPL_HEADER *) dat_handle;\r
+\r
+       if (header->magic == DAPL_MAGIC_EP)\r
+               ib_cm_handle = ((DAPL_EP *) dat_handle)->cm_handle;\r
+       else if (header->magic == DAPL_MAGIC_CR)\r
+               ib_cm_handle = ((DAPL_CR *) dat_handle)->ib_cm_handle;\r
+       else\r
+               return DAT_INVALID_HANDLE;\r
+\r
+       /* get remote IP address from cm_id route */\r
+       ipaddr = &ib_cm_handle->cm_id->route.addr;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                    " remote_addr: conn %p id %p SRC %x DST %x PORT %d\n",\r
+                    ib_cm_handle, ib_cm_handle->cm_id,\r
+                    ntohl(((struct sockaddr_in *)\r
+                           &ipaddr->src_addr)->sin_addr.s_addr),\r
+                    ntohl(((struct sockaddr_in *)\r
+                           &ipaddr->dst_addr)->sin_addr.s_addr),\r
+                    ntohs(((struct sockaddr_in *)\r
+                           &ipaddr->dst_addr)->sin_port));\r
+\r
+       dapl_os_memcpy(raddr, &ipaddr->dst_addr, sizeof(DAT_SOCK_ADDR));\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * dapls_ib_private_data_size\r
+ *\r
+ * Return the size of private data given a connection op type\r
+ *\r
+ * Input:\r
+ *     prd_ptr         private data pointer\r
+ *     conn_op         connection operation type\r
+ *      hca_ptr         hca pointer, needed for transport type\r
+ *\r
+ * If prd_ptr is NULL, this is a query for the max size supported by\r
+ * the provider, otherwise it is the actual size of the private data\r
+ * contained in prd_ptr.\r
+ *\r
+ *\r
+ * Output:\r
+ *     None\r
+ *\r
+ * Returns:\r
+ *     length of private data\r
+ *\r
+ */\r
+int dapls_ib_private_data_size(IN DAPL_PRIVATE * prd_ptr,\r
+                              IN DAPL_PDATA_OP conn_op, IN DAPL_HCA * hca_ptr)\r
+{\r
+       int size;\r
+\r
+       if (hca_ptr->ib_hca_handle->device->transport_type\r
+           == IBV_TRANSPORT_IWARP)\r
+               return (IWARP_MAX_PDATA_SIZE - sizeof(struct dapl_pdata_hdr));\r
+\r
+       switch (conn_op) {\r
+\r
+       case DAPL_PDATA_CONN_REQ:\r
+               size = IB_MAX_REQ_PDATA_SIZE;\r
+               break;\r
+       case DAPL_PDATA_CONN_REP:\r
+               size = IB_MAX_REP_PDATA_SIZE;\r
+               break;\r
+       case DAPL_PDATA_CONN_REJ:\r
+               size = IB_MAX_REJ_PDATA_SIZE - sizeof(struct dapl_pdata_hdr);\r
+               break;\r
+       case DAPL_PDATA_CONN_DREQ:\r
+               size = IB_MAX_DREQ_PDATA_SIZE;\r
+               break;\r
+       case DAPL_PDATA_CONN_DREP:\r
+               size = IB_MAX_DREP_PDATA_SIZE;\r
+               break;\r
+       default:\r
+               size = 0;\r
+\r
+       }                       /* end case */\r
+\r
+       return size;\r
+}\r
+\r
+/*\r
+ * Map all CMA event codes to the DAT equivelent.\r
+ */\r
+#define DAPL_IB_EVENT_CNT      13\r
+\r
+static struct ib_cm_event_map {\r
+       const ib_cm_events_t ib_cm_event;\r
+       DAT_EVENT_NUMBER dat_event_num;\r
+} ib_cm_event_map[DAPL_IB_EVENT_CNT] = {\r
+       /* 00 */  {\r
+       IB_CME_CONNECTED, DAT_CONNECTION_EVENT_ESTABLISHED},\r
+           /* 01 */  {\r
+       IB_CME_DISCONNECTED, DAT_CONNECTION_EVENT_DISCONNECTED},\r
+           /* 02 */  {\r
+       IB_CME_DISCONNECTED_ON_LINK_DOWN,\r
+                   DAT_CONNECTION_EVENT_DISCONNECTED},\r
+           /* 03 */  {\r
+       IB_CME_CONNECTION_REQUEST_PENDING, DAT_CONNECTION_REQUEST_EVENT},\r
+           /* 04 */  {\r
+       IB_CME_CONNECTION_REQUEST_PENDING_PRIVATE_DATA,\r
+                   DAT_CONNECTION_REQUEST_EVENT},\r
+           /* 05 */  {\r
+       IB_CME_CONNECTION_REQUEST_ACKED, DAT_CONNECTION_REQUEST_EVENT},\r
+           /* 06 */  {\r
+       IB_CME_DESTINATION_REJECT,\r
+                   DAT_CONNECTION_EVENT_NON_PEER_REJECTED},\r
+           /* 07 */  {\r
+       IB_CME_DESTINATION_REJECT_PRIVATE_DATA,\r
+                   DAT_CONNECTION_EVENT_PEER_REJECTED},\r
+           /* 08 */  {\r
+       IB_CME_DESTINATION_UNREACHABLE, DAT_CONNECTION_EVENT_UNREACHABLE},\r
+           /* 09 */  {\r
+       IB_CME_TOO_MANY_CONNECTION_REQUESTS,\r
+                   DAT_CONNECTION_EVENT_NON_PEER_REJECTED},\r
+           /* 10 */  {\r
+       IB_CME_LOCAL_FAILURE, DAT_CONNECTION_EVENT_BROKEN},\r
+           /* 11 */  {\r
+       IB_CME_BROKEN, DAT_CONNECTION_EVENT_BROKEN},\r
+           /* 12 */  {\r
+IB_CME_TIMEOUT, DAT_CONNECTION_EVENT_TIMED_OUT},};\r
+\r
+/*\r
+ * dapls_ib_get_cm_event\r
+ *\r
+ * Return a DAT connection event given a provider CM event.\r
+ *\r
+ * Input:\r
+ *     dat_event_num   DAT event we need an equivelent CM event for\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     ib_cm_event of translated DAPL value\r
+ */\r
+DAT_EVENT_NUMBER\r
+dapls_ib_get_dat_event(IN const ib_cm_events_t ib_cm_event,\r
+                      IN DAT_BOOLEAN active)\r
+{\r
+       DAT_EVENT_NUMBER dat_event_num;\r
+       int i;\r
+\r
+       active = active;\r
+\r
+       dat_event_num = 0;\r
+       for (i = 0; i < DAPL_IB_EVENT_CNT; i++) {\r
+               if (ib_cm_event == ib_cm_event_map[i].ib_cm_event) {\r
+                       dat_event_num = ib_cm_event_map[i].dat_event_num;\r
+                       break;\r
+               }\r
+       }\r
+       dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,\r
+                    "dapls_ib_get_dat_event: event(%s) ib=0x%x dat=0x%x\n",\r
+                    active ? "active" : "passive", ib_cm_event, dat_event_num);\r
+\r
+       return dat_event_num;\r
+}\r
+\r
+/*\r
+ * dapls_ib_get_dat_event\r
+ *\r
+ * Return a DAT connection event given a provider CM event.\r
+ * \r
+ * Input:\r
+ *     ib_cm_event     event provided to the dapl callback routine\r
+ *     active          switch indicating active or passive connection\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_EVENT_NUMBER of translated provider value\r
+ */\r
+ib_cm_events_t dapls_ib_get_cm_event(IN DAT_EVENT_NUMBER dat_event_num)\r
+{\r
+       ib_cm_events_t ib_cm_event;\r
+       int i;\r
+\r
+       ib_cm_event = 0;\r
+       for (i = 0; i < DAPL_IB_EVENT_CNT; i++) {\r
+               if (dat_event_num == ib_cm_event_map[i].dat_event_num) {\r
+                       ib_cm_event = ib_cm_event_map[i].ib_cm_event;\r
+                       break;\r
+               }\r
+       }\r
+       return ib_cm_event;\r
+}\r
+\r
+void dapli_cma_event_cb(void)\r
+{\r
+       struct rdma_cm_event *event;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " cm_event()\n");\r
+\r
+       /* process one CM event, fairness */\r
+       if (!rdma_get_cm_event(g_cm_events, &event)) {\r
+               struct dapl_cm_id *conn;\r
+\r
+               /* set proper conn from cm_id context */\r
+               if (event->event == RDMA_CM_EVENT_CONNECT_REQUEST)\r
+                       conn = (struct dapl_cm_id *)event->listen_id->context;\r
+               else\r
+                       conn = (struct dapl_cm_id *)event->id->context;\r
+\r
+               dapl_dbg_log(DAPL_DBG_TYPE_CM,\r
+                            " cm_event: EVENT=%d ID=%p LID=%p CTX=%p\n",\r
+                            event->event, event->id, event->listen_id, conn);\r
+\r
+               switch (event->event) {\r
+               case RDMA_CM_EVENT_ADDR_RESOLVED:\r
+                       dapli_addr_resolve(conn);\r
+                       break;\r
+\r
+               case RDMA_CM_EVENT_ROUTE_RESOLVED:\r
+                       dapli_route_resolve(conn);\r
+                       break;\r
+\r
+               case RDMA_CM_EVENT_ADDR_ERROR:\r
+                       dapl_log(DAPL_DBG_TYPE_WARN,\r
+                                "dapl_cma_active: CM ADDR ERROR: ->"\r
+                                " DST %s retry (%d)..\n",\r
+                                inet_ntoa(((struct sockaddr_in *)\r
+                                           &conn->r_addr)->sin_addr),\r
+                                conn->arp_retries);\r
+\r
+                       /* retry address resolution */\r
+                       if ((--conn->arp_retries) &&\r
+                           (event->status == -ETIMEDOUT)) {\r
+                               int ret;\r
+                               ret = rdma_resolve_addr(conn->cm_id, NULL,\r
+                                                       (struct sockaddr *)\r
+                                                       &conn->r_addr,\r
+                                                       conn->arp_timeout);\r
+                               if (!ret)\r
+                                       break;\r
+                               else {\r
+                                       dapl_dbg_log(DAPL_DBG_TYPE_WARN,\r
+                                                    " ERROR: rdma_resolve_addr = "\r
+                                                    "%d %s\n",\r
+                                                    ret, strerror(errno));\r
+                               }\r
+                       }\r
+                       /* retries exhausted or resolve_addr failed */\r
+                       dapl_log(DAPL_DBG_TYPE_ERR,\r
+                                "dapl_cma_active: ARP_ERR, retries(%d)"\r
+                                " exhausted -> DST %s,%d\n",\r
+                                IB_ARP_RETRY_COUNT,\r
+                                inet_ntoa(((struct sockaddr_in *)\r
+                                           &conn->cm_id->route.addr.dst_addr)->\r
+                                          sin_addr),\r
+                                ntohs(((struct sockaddr_in *)\r
+                                       &conn->cm_id->route.addr.dst_addr)->\r
+                                      sin_port));\r
+\r
+                       dapl_evd_connection_callback(conn,\r
+                                                    IB_CME_DESTINATION_UNREACHABLE,\r
+                                                    NULL, conn->ep);\r
+                       break;\r
+\r
+               case RDMA_CM_EVENT_ROUTE_ERROR:\r
+                       dapl_log(DAPL_DBG_TYPE_WARN,\r
+                                "dapl_cma_active: CM ROUTE ERROR: ->"\r
+                                " DST %s retry (%d)..\n",\r
+                                inet_ntoa(((struct sockaddr_in *)\r
+                                           &conn->r_addr)->sin_addr),\r
+                                conn->route_retries);\r
+\r
+                       /* retry route resolution */\r
+                       if ((--conn->route_retries) &&\r
+                           (event->status == -ETIMEDOUT))\r
+                               dapli_addr_resolve(conn);\r
+                       else {\r
+                               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                                        "dapl_cma_active: PATH_RECORD_ERR,"\r
+                                        " retries(%d) exhausted, DST %s,%d\n",\r
+                                        IB_ROUTE_RETRY_COUNT,\r
+                                        inet_ntoa(((struct sockaddr_in *)\r
+                                                   &conn->cm_id->route.addr.\r
+                                                   dst_addr)->sin_addr),\r
+                                        ntohs(((struct sockaddr_in *)\r
+                                               &conn->cm_id->route.addr.\r
+                                               dst_addr)->sin_port));\r
+\r
+                               dapl_evd_connection_callback(conn,\r
+                                                            IB_CME_DESTINATION_UNREACHABLE,\r
+                                                            NULL, conn->ep);\r
+                       }\r
+                       break;\r
+\r
+               case RDMA_CM_EVENT_DEVICE_REMOVAL:\r
+                       dapl_evd_connection_callback(conn,\r
+                                                    IB_CME_LOCAL_FAILURE,\r
+                                                    NULL, conn->ep);\r
+                       break;\r
+               case RDMA_CM_EVENT_CONNECT_REQUEST:\r
+               case RDMA_CM_EVENT_CONNECT_ERROR:\r
+               case RDMA_CM_EVENT_UNREACHABLE:\r
+               case RDMA_CM_EVENT_REJECTED:\r
+               case RDMA_CM_EVENT_ESTABLISHED:\r
+               case RDMA_CM_EVENT_DISCONNECTED:\r
+                       /* passive or active */\r
+                       if (conn->sp)\r
+                               dapli_cm_passive_cb(conn, event);\r
+                       else\r
+                               dapli_cm_active_cb(conn, event);\r
+                       break;\r
+               case RDMA_CM_EVENT_CONNECT_RESPONSE:\r
+               default:\r
+                       dapl_dbg_log(DAPL_DBG_TYPE_WARN,\r
+                                    " cm_event: UNEXPECTED EVENT=%p ID=%p CTX=%p\n",\r
+                                    event->event, event->id,\r
+                                    event->id->context);\r
+                       break;\r
+               }\r
+               /* ack event, unblocks destroy_cm_id in consumer threads */\r
+               rdma_ack_cm_event(event);\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
diff --git a/ulp/dapl2/dapl/openib_cma/dapl_ib_dto.h b/ulp/dapl2/dapl/openib_cma/dapl_ib_dto.h
deleted file mode 100644 (file)
index d97c26b..0000000
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- * This Software is licensed under one of the following licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- *
- * 2) under the terms of the "The BSD License" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- *
- * Licensee has the right to choose one of the above licenses.
- *
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/***************************************************************************
- *
- *   Module:            uDAPL
- *
- *   Filename:          dapl_ib_dto.h
- *
- *   Author:            Arlin Davis
- *
- *   Created:           3/10/2005
- *
- *   Description: 
- *
- *   The OpenIB uCMA provider - DTO operations and CQE macros 
- *
- ****************************************************************************
- *                Source Control System Information
- *
- *    $Id: $
- *
- *     Copyright (c) 2005 Intel Corporation.  All rights reserved.
- *
- **************************************************************************/
-#ifndef _DAPL_IB_DTO_H_
-#define _DAPL_IB_DTO_H_
-
-#include "dapl_ib_util.h"
-
-#ifdef DAT_EXTENSIONS
-#include <dat2/dat_ib_extensions.h>
-#endif
-
-STATIC _INLINE_ int dapls_cqe_opcode(ib_work_completion_t *cqe_p);
-
-/*
- * dapls_ib_post_recv
- *
- * Provider specific Post RECV function
- */
-STATIC _INLINE_ DAT_RETURN 
-dapls_ib_post_recv (
-       IN  DAPL_EP             *ep_ptr,
-       IN  DAPL_COOKIE         *cookie,
-       IN  DAT_COUNT           segments,
-       IN  DAT_LMR_TRIPLET     *local_iov )
-{
-       struct ibv_recv_wr wr;
-       struct ibv_recv_wr *bad_wr;
-       ib_data_segment_t *ds = (ib_data_segment_t *)local_iov;
-       DAT_COUNT i, total_len;
-       int ret;
-       
-       dapl_dbg_log(DAPL_DBG_TYPE_EP,
-                    " post_rcv: ep %p cookie %p segs %d l_iov %p\n",
-                    ep_ptr, cookie, segments, local_iov);
-
-       /* setup work request */
-       total_len = 0;
-       wr.next = 0;
-       wr.num_sge = segments;
-       wr.wr_id = (uint64_t)(uintptr_t)cookie;
-       wr.sg_list = ds;
-
-       if (cookie != NULL) { 
-               for (i = 0; i < segments; i++) {
-                       dapl_dbg_log(DAPL_DBG_TYPE_EP, 
-                                    " post_rcv: l_key 0x%x va %p len %d\n",
-                                    ds->lkey, ds->addr, ds->length);
-                       total_len += ds->length;
-                       ds++;
-               }
-               cookie->val.dto.size = total_len;
-       }
-
-       ret = ibv_post_recv(ep_ptr->qp_handle->cm_id->qp, &wr, &bad_wr);
-       
-       if (ret)
-               return( dapl_convert_errno(errno,"ibv_recv") );
-
-       DAPL_CNTR(ep_ptr, DCNT_EP_POST_RECV);
-       DAPL_CNTR_DATA(ep_ptr, DCNT_EP_POST_RECV_DATA, total_len);
-
-       return DAT_SUCCESS;
-}
-
-/*
- * dapls_ib_post_send
- *
- * Provider specific Post SEND function
- */
-STATIC _INLINE_ DAT_RETURN 
-dapls_ib_post_send (
-       IN  DAPL_EP                     *ep_ptr,
-       IN  ib_send_op_type_t           op_type,
-       IN  DAPL_COOKIE                 *cookie,
-       IN  DAT_COUNT                   segments,
-       IN  DAT_LMR_TRIPLET             *local_iov,
-       IN  const DAT_RMR_TRIPLET       *remote_iov,
-       IN  DAT_COMPLETION_FLAGS        completion_flags)
-{
-       struct ibv_send_wr wr;
-       struct ibv_send_wr *bad_wr;
-       ib_data_segment_t *ds = (ib_data_segment_t *)local_iov;
-       ib_hca_transport_t *ibt_ptr = 
-               &ep_ptr->header.owner_ia->hca_ptr->ib_trans;
-       DAT_COUNT i, total_len;
-       int ret;
-       
-       dapl_dbg_log(DAPL_DBG_TYPE_EP,
-                    " post_snd: ep %p op %d ck %p sgs",
-                    "%d l_iov %p r_iov %p f %d\n",
-                    ep_ptr, op_type, cookie, segments, local_iov, 
-                    remote_iov, completion_flags);
-
-       /* setup the work request */
-       wr.next = 0;
-       wr.opcode = op_type;
-       wr.num_sge = segments;
-       wr.send_flags = 0;
-       wr.wr_id = (uint64_t)(uintptr_t)cookie;
-       wr.sg_list = ds;
-       total_len = 0;
-
-       if (cookie != NULL) {
-               for (i = 0; i < segments; i++ ) {
-                       dapl_dbg_log(DAPL_DBG_TYPE_EP, 
-                                    " post_snd: lkey 0x%x va %p len %d\n",
-                                    ds->lkey, ds->addr, ds->length );
-                       total_len += ds->length;
-                       ds++;
-               }
-               cookie->val.dto.size = total_len;
-       }
-
-       if (wr.num_sge && 
-           (op_type == OP_RDMA_WRITE || op_type == OP_RDMA_READ)) {
-               wr.wr.rdma.remote_addr = remote_iov->virtual_address;
-               wr.wr.rdma.rkey = remote_iov->rmr_context;
-               dapl_dbg_log(DAPL_DBG_TYPE_EP, 
-                            " post_snd_rdma: rkey 0x%x va %#016Lx\n",
-                            wr.wr.rdma.rkey, wr.wr.rdma.remote_addr);
-       }
-
-       /* inline data for send or write ops */
-       if ((total_len <= ibt_ptr->max_inline_send) && 
-          ((op_type == OP_SEND) || (op_type == OP_RDMA_WRITE))) 
-               wr.send_flags |= IBV_SEND_INLINE;
-       
-       /* set completion flags in work request */
-       wr.send_flags |= (DAT_COMPLETION_SUPPRESS_FLAG & 
-                               completion_flags) ? 0 : IBV_SEND_SIGNALED;
-       wr.send_flags |= (DAT_COMPLETION_BARRIER_FENCE_FLAG & 
-                               completion_flags) ? IBV_SEND_FENCE : 0;
-       wr.send_flags |= (DAT_COMPLETION_SOLICITED_WAIT_FLAG & 
-                               completion_flags) ? IBV_SEND_SOLICITED : 0;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_EP, 
-                    " post_snd: op 0x%x flags 0x%x sglist %p, %d\n", 
-                    wr.opcode, wr.send_flags, wr.sg_list, wr.num_sge);
-
-       ret = ibv_post_send(ep_ptr->qp_handle->cm_id->qp, &wr, &bad_wr);
-
-       if (ret)
-               return( dapl_convert_errno(errno,"ibv_send") );
-
-#ifdef DAPL_COUNTERS
-       switch (op_type) {
-       case OP_SEND:
-               DAPL_CNTR(ep_ptr, DCNT_EP_POST_SEND);
-               DAPL_CNTR_DATA(ep_ptr, DCNT_EP_POST_SEND_DATA,total_len);
-               break;
-       case OP_RDMA_WRITE:
-               DAPL_CNTR(ep_ptr, DCNT_EP_POST_WRITE);
-               DAPL_CNTR_DATA(ep_ptr, DCNT_EP_POST_WRITE_DATA,total_len);
-               break;  
-       case OP_RDMA_READ:
-               DAPL_CNTR(ep_ptr, DCNT_EP_POST_READ);
-               DAPL_CNTR_DATA(ep_ptr, DCNT_EP_POST_READ_DATA,total_len);
-               break;
-       default:
-               break;
-       }
-#endif /* DAPL_COUNTERS */
-
-       dapl_dbg_log(DAPL_DBG_TYPE_EP," post_snd: returned\n");
-       return DAT_SUCCESS;
-}
-
-/* map Work Completions to DAPL WR operations */
-STATIC _INLINE_ DAT_DTOS dapls_cqe_dtos_opcode(ib_work_completion_t *cqe_p)
-{
-       switch (cqe_p->opcode) {
-
-       case IBV_WC_SEND:
-               return (DAT_DTO_SEND);
-       case IBV_WC_RDMA_READ:
-               return (DAT_DTO_RDMA_READ);
-       case IBV_WC_BIND_MW:
-               return (DAT_DTO_BIND_MW);
-#ifdef DAT_EXTENSIONS
-       case IBV_WC_RDMA_WRITE:
-               if (cqe_p->wc_flags & IBV_WC_WITH_IMM)
-                       return (DAT_IB_DTO_RDMA_WRITE_IMMED);
-               else
-                       return (DAT_DTO_RDMA_WRITE);
-       case IBV_WC_COMP_SWAP:
-               return (DAT_IB_DTO_CMP_SWAP);
-       case IBV_WC_FETCH_ADD:
-               return (DAT_IB_DTO_FETCH_ADD);
-       case IBV_WC_RECV_RDMA_WITH_IMM:
-               return (DAT_IB_DTO_RECV_IMMED);
-#else
-       case IBV_WC_RDMA_WRITE:
-               return (DAT_DTO_RDMA_WRITE);
-#endif
-       case IBV_WC_RECV:
-               return (DAT_DTO_RECEIVE);
-       default:
-               return (0xff);
-       }
-}
-#define DAPL_GET_CQE_DTOS_OPTYPE(cqe_p) dapls_cqe_dtos_opcode(cqe_p)
-
-
-#ifdef DAT_EXTENSIONS
-/*
- * dapls_ib_post_ext_send
- *
- * Provider specific extended Post SEND function for atomics
- *     OP_COMP_AND_SWAP and OP_FETCH_AND_ADD
- */
-STATIC _INLINE_ DAT_RETURN 
-dapls_ib_post_ext_send (
-       IN  DAPL_EP                     *ep_ptr,
-       IN  ib_send_op_type_t           op_type,
-       IN  DAPL_COOKIE                 *cookie,
-       IN  DAT_COUNT                   segments,
-       IN  DAT_LMR_TRIPLET             *local_iov,
-       IN  const DAT_RMR_TRIPLET       *remote_iov,
-       IN  DAT_UINT32                  immed_data,
-       IN  DAT_UINT64                  compare_add,
-       IN  DAT_UINT64                  swap,
-       IN  DAT_COMPLETION_FLAGS        completion_flags)
-{
-       struct ibv_send_wr wr;
-       struct ibv_send_wr *bad_wr;
-       ib_data_segment_t *ds = (ib_data_segment_t *)local_iov;
-       DAT_COUNT i, total_len;
-       int ret;
-       
-       dapl_dbg_log(DAPL_DBG_TYPE_EP,
-                    " post_ext_snd: ep %p op %d ck %p sgs",
-                    "%d l_iov %p r_iov %p f %d\n",
-                    ep_ptr, op_type, cookie, segments, local_iov, 
-                    remote_iov, completion_flags);
-
-       /* setup the work request */
-       wr.next = 0;
-       wr.opcode = op_type;
-       wr.num_sge = segments;
-       wr.send_flags = 0;
-       wr.wr_id = (uint64_t)(uintptr_t)cookie;
-       wr.sg_list = ds;
-       total_len = 0;
-
-       if (cookie != NULL) {
-               for (i = 0; i < segments; i++ ) {
-                       dapl_dbg_log(DAPL_DBG_TYPE_EP, 
-                                    " post_ext_snd: lkey 0x%x va %p ln %d\n",
-                                    ds->lkey, ds->addr, ds->length);
-                       total_len += ds->length;
-                       ds++;
-               }
-               cookie->val.dto.size = total_len;
-       }
-
-       switch (op_type) {
-       case OP_RDMA_WRITE_IMM:
-               /* OP_RDMA_WRITE)IMMED has direct IB wr_type mapping */
-               dapl_dbg_log(DAPL_DBG_TYPE_EP, 
-                            " post_ext: rkey 0x%x va %#016Lx immed=0x%x\n",
-                            remote_iov?remote_iov->rmr_context:0, 
-                            remote_iov?remote_iov->virtual_address:0,
-                            immed_data);
-
-               wr.imm_data = immed_data;
-               if (wr.num_sge) {
-                       wr.wr.rdma.remote_addr = remote_iov->virtual_address;
-                       wr.wr.rdma.rkey = remote_iov->rmr_context;
-               }
-               break;
-       case OP_COMP_AND_SWAP:
-               /* OP_COMP_AND_SWAP has direct IB wr_type mapping */
-               dapl_dbg_log(DAPL_DBG_TYPE_EP, 
-                            " post_ext: OP_COMP_AND_SWAP=%lx,"
-                            "%lx rkey 0x%x va %#016Lx\n",
-                            compare_add, swap, remote_iov->rmr_context,
-                            remote_iov->virtual_address);
-               
-               wr.wr.atomic.compare_add = compare_add;
-               wr.wr.atomic.swap = swap;
-               wr.wr.atomic.remote_addr = remote_iov->virtual_address;
-               wr.wr.atomic.rkey = remote_iov->rmr_context;
-               break;
-       case OP_FETCH_AND_ADD:
-               /* OP_FETCH_AND_ADD has direct IB wr_type mapping */
-               dapl_dbg_log(DAPL_DBG_TYPE_EP, 
-                            " post_ext: OP_FETCH_AND_ADD=%lx,"
-                            "%lx rkey 0x%x va %#016Lx\n",
-                            compare_add, remote_iov->rmr_context,
-                            remote_iov->virtual_address);
-
-               wr.wr.atomic.compare_add = compare_add;
-               wr.wr.atomic.remote_addr = remote_iov->virtual_address;
-               wr.wr.atomic.rkey = remote_iov->rmr_context;
-               break;
-       default:
-               break;
-       }
-
-       /* set completion flags in work request */
-       wr.send_flags |= (DAT_COMPLETION_SUPPRESS_FLAG & 
-                               completion_flags) ? 0 : IBV_SEND_SIGNALED;
-       wr.send_flags |= (DAT_COMPLETION_BARRIER_FENCE_FLAG & 
-                               completion_flags) ? IBV_SEND_FENCE : 0;
-       wr.send_flags |= (DAT_COMPLETION_SOLICITED_WAIT_FLAG & 
-                               completion_flags) ? IBV_SEND_SOLICITED : 0;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_EP, 
-                    " post_snd: op 0x%x flags 0x%x sglist %p, %d\n", 
-                    wr.opcode, wr.send_flags, wr.sg_list, wr.num_sge);
-
-       ret = ibv_post_send(ep_ptr->qp_handle->cm_id->qp, &wr, &bad_wr);
-
-       if (ret)
-               return( dapl_convert_errno(errno,"ibv_send") );
-
-#ifdef DAPL_COUNTERS
-       switch (op_type) {
-       case OP_RDMA_WRITE_IMM:
-               DAPL_CNTR(ep_ptr, DCNT_EP_POST_WRITE_IMM);
-               DAPL_CNTR_DATA(ep_ptr, 
-                              DCNT_EP_POST_WRITE_IMM_DATA, total_len);
-               break;
-       case OP_COMP_AND_SWAP:
-               DAPL_CNTR(ep_ptr, DCNT_EP_POST_CMP_SWAP);
-               break;  
-       case OP_FETCH_AND_ADD:
-               DAPL_CNTR(ep_ptr, DCNT_EP_POST_FETCH_ADD);
-               break;
-       default:
-               break;
-       }
-#endif /* DAPL_COUNTERS */
-
-       dapl_dbg_log(DAPL_DBG_TYPE_EP," post_snd: returned\n");
-       return DAT_SUCCESS;
-}
-#endif
-
-STATIC _INLINE_ DAT_RETURN 
-dapls_ib_optional_prv_dat(
-       IN  DAPL_CR             *cr_ptr,
-       IN  const void          *event_data,
-       OUT   DAPL_CR           **cr_pp)
-{
-    return DAT_SUCCESS;
-}
-
-/* map Work Completions to DAPL WR operations */
-STATIC _INLINE_ int dapls_cqe_opcode(ib_work_completion_t *cqe_p)
-{
-#ifdef DAPL_COUNTERS
-       DAPL_COOKIE *cookie = (DAPL_COOKIE *)(uintptr_t)cqe_p->wr_id;
-#endif /* DAPL_COUNTERS */
-
-       switch (cqe_p->opcode) {
-       case IBV_WC_SEND:
-               return (OP_SEND);
-       case IBV_WC_RDMA_WRITE:
-               if (cqe_p->wc_flags & IBV_WC_WITH_IMM)
-                       return (OP_RDMA_WRITE_IMM);
-               else
-                       return (OP_RDMA_WRITE);
-       case IBV_WC_RDMA_READ:
-               return (OP_RDMA_READ);
-       case IBV_WC_COMP_SWAP:
-               return (OP_COMP_AND_SWAP);
-       case IBV_WC_FETCH_ADD:
-               return (OP_FETCH_AND_ADD);
-       case IBV_WC_BIND_MW:
-               return (OP_BIND_MW);
-       case IBV_WC_RECV:
-               if (cqe_p->wc_flags & IBV_WC_WITH_IMM) {
-                       DAPL_CNTR(cookie->ep, DCNT_EP_RECV_IMM);
-                       DAPL_CNTR_DATA(cookie->ep, DCNT_EP_RECV_IMM_DATA, 
-                                      cqe_p->byte_len);
-                       return (OP_RECEIVE_IMM);
-               } else {
-                       DAPL_CNTR(cookie->ep, DCNT_EP_RECV);
-                       DAPL_CNTR_DATA(cookie->ep, DCNT_EP_RECV_DATA, 
-                                      cqe_p->byte_len);
-                       return (OP_RECEIVE);
-               }
-       case IBV_WC_RECV_RDMA_WITH_IMM:
-               DAPL_CNTR(cookie->ep, DCNT_EP_RECV_RDMA_IMM);
-               DAPL_CNTR_DATA(cookie->ep, DCNT_EP_RECV_RDMA_IMM_DATA, 
-                              cqe_p->byte_len);
-               return (OP_RECEIVE_IMM);
-       default:
-               return (OP_INVALID);
-       }
-}
-
-#define DAPL_GET_CQE_OPTYPE(cqe_p) dapls_cqe_opcode(cqe_p)
-#define DAPL_GET_CQE_WRID(cqe_p) ((ib_work_completion_t*)cqe_p)->wr_id
-#define DAPL_GET_CQE_STATUS(cqe_p) ((ib_work_completion_t*)cqe_p)->status
-#define DAPL_GET_CQE_VENDOR_ERR(cqe_p) ((ib_work_completion_t*)cqe_p)->vendor_err
-#define DAPL_GET_CQE_BYTESNUM(cqe_p) ((ib_work_completion_t*)cqe_p)->byte_len
-#define DAPL_GET_CQE_IMMED_DATA(cqe_p) ((ib_work_completion_t*)cqe_p)->imm_data
-
-STATIC _INLINE_ char * dapls_dto_op_str(int op)
-{
-    static char *optable[] =
-    {
-        "OP_RDMA_WRITE",
-        "OP_RDMA_WRITE_IMM",
-        "OP_SEND",
-        "OP_SEND_IMM",
-        "OP_RDMA_READ",
-        "OP_COMP_AND_SWAP",
-        "OP_FETCH_AND_ADD",
-        "OP_RECEIVE",
-        "OP_RECEIVE_IMM",
-        "OP_BIND_MW"
-    };
-    return ((op < 0 || op > 9) ? "Invalid CQE OP?" : optable[op]);
-}
-
-static _INLINE_ char *
-dapls_cqe_op_str(IN ib_work_completion_t *cqe_ptr)
-{
-    return dapls_dto_op_str(DAPL_GET_CQE_OPTYPE(cqe_ptr));
-}
-
-#define DAPL_GET_CQE_OP_STR(cqe) dapls_cqe_op_str(cqe)
-
-#endif /*  _DAPL_IB_DTO_H_ */
diff --git a/ulp/dapl2/dapl/openib_cma/dapl_ib_extensions.c b/ulp/dapl2/dapl/openib_cma/dapl_ib_extensions.c
deleted file mode 100644 (file)
index 3bcde58..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright (c) 2007 Intel Corporation.  All rights reserved.
- *
- * This Software is licensed under one of the following licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- *
- * 2) under the terms of the "The BSD License" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- *
- * Licensee has the right to choose one of the above licenses.
- *
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/**********************************************************************
- * 
- * MODULE: dapl_ib_extensions.c
- *
- * PURPOSE:  Extensions routines for OpenIB uCMA provider
- *
- * $Id: $
- *
- **********************************************************************/
-
-#include "dapl.h"
-#include "dapl_adapter_util.h"
-#include "dapl_evd_util.h"
-#include "dapl_ib_util.h"
-#include "dapl_ep_util.h"
-#include "dapl_cookie.h"
-#include <stdarg.h>
-
-DAT_RETURN
-dapli_post_ext(IN DAT_EP_HANDLE ep_handle,
-              IN DAT_UINT64 cmp_add,
-              IN DAT_UINT64 swap,
-              IN DAT_UINT32 immed_data,
-              IN DAT_COUNT segments,
-              IN DAT_LMR_TRIPLET * local_iov,
-              IN DAT_DTO_COOKIE user_cookie,
-              IN const DAT_RMR_TRIPLET * remote_iov,
-              IN int op_type, IN DAT_COMPLETION_FLAGS flags);
-
-/*
- * dapl_extensions
- *
- * Process extension requests
- *
- * Input:
- *     ext_type,
- *     ...
- *
- * Output:
- *     Depends....
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_NOT_IMPLEMENTED
- *      .....
- *
- */
-DAT_RETURN
-dapl_extensions(IN DAT_HANDLE dat_handle,
-               IN DAT_EXTENDED_OP ext_op, IN va_list args)
-{
-       DAT_EP_HANDLE ep;
-       DAT_LMR_TRIPLET *lmr_p;
-       DAT_DTO_COOKIE cookie;
-       const DAT_RMR_TRIPLET *rmr_p;
-       DAT_UINT64 dat_uint64a, dat_uint64b;
-       DAT_UINT32 dat_uint32;
-       DAT_COUNT segments = 1;
-       DAT_COMPLETION_FLAGS comp_flags;
-       DAT_RETURN status = DAT_NOT_IMPLEMENTED;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_API,
-                    "dapl_extensions(hdl %p operation %d, ...)\n",
-                    dat_handle, ext_op);
-
-       switch ((int)ext_op) {
-
-       case DAT_IB_RDMA_WRITE_IMMED_OP:
-               dapl_dbg_log(DAPL_DBG_TYPE_RTN,
-                            " WRITE_IMMED_DATA extension call\n");
-
-               ep = dat_handle;        /* ep_handle */
-               segments = va_arg(args, DAT_COUNT);     /* num segments */
-               lmr_p = va_arg(args, DAT_LMR_TRIPLET *);
-               cookie = va_arg(args, DAT_DTO_COOKIE);
-               rmr_p = va_arg(args, const DAT_RMR_TRIPLET *);
-               dat_uint32 = va_arg(args, DAT_UINT32);  /* immed data */
-               comp_flags = va_arg(args, DAT_COMPLETION_FLAGS);
-
-               status = dapli_post_ext(ep, 0, 0, dat_uint32, segments, lmr_p,
-                                       cookie, rmr_p, OP_RDMA_WRITE_IMM,
-                                       comp_flags);
-               break;
-
-       case DAT_IB_CMP_AND_SWAP_OP:
-               dapl_dbg_log(DAPL_DBG_TYPE_RTN,
-                            " CMP_AND_SWAP extension call\n");
-
-               ep = dat_handle;        /* ep_handle */
-               dat_uint64a = va_arg(args, DAT_UINT64); /* cmp_value */
-               dat_uint64b = va_arg(args, DAT_UINT64); /* swap_value */
-               lmr_p = va_arg(args, DAT_LMR_TRIPLET *);
-               cookie = va_arg(args, DAT_DTO_COOKIE);
-               rmr_p = va_arg(args, const DAT_RMR_TRIPLET *);
-               comp_flags = va_arg(args, DAT_COMPLETION_FLAGS);
-
-               status = dapli_post_ext(ep, dat_uint64a, dat_uint64b,
-                                       0, segments, lmr_p, cookie, rmr_p,
-                                       OP_COMP_AND_SWAP, comp_flags);
-               break;
-
-       case DAT_IB_FETCH_AND_ADD_OP:
-               dapl_dbg_log(DAPL_DBG_TYPE_RTN,
-                            " FETCH_AND_ADD extension call\n");
-
-               ep = dat_handle;        /* ep_handle */
-               dat_uint64a = va_arg(args, DAT_UINT64); /* add value */
-               lmr_p = va_arg(args, DAT_LMR_TRIPLET *);
-               cookie = va_arg(args, DAT_DTO_COOKIE);
-               rmr_p = va_arg(args, const DAT_RMR_TRIPLET *);
-               comp_flags = va_arg(args, DAT_COMPLETION_FLAGS);
-
-               status = dapli_post_ext(ep, dat_uint64a, 0, 0, segments,
-                                       lmr_p, cookie, rmr_p,
-                                       OP_FETCH_AND_ADD, comp_flags);
-
-               break;
-
-#ifdef DAPL_COUNTERS
-       case DAT_QUERY_COUNTERS_OP:
-               {
-                       int cntr, reset;
-                       DAT_UINT64 *p_cntr_out;
-
-                       dapl_dbg_log(DAPL_DBG_TYPE_RTN,
-                                    " Query counter extension call\n");
-
-                       cntr = va_arg(args, int);
-                       p_cntr_out = va_arg(args, DAT_UINT64 *);
-                       reset = va_arg(args, int);
-
-                       status = dapl_query_counter(dat_handle, cntr,
-                                                   p_cntr_out, reset);
-                       break;
-               }
-       case DAT_PRINT_COUNTERS_OP:
-               {
-                       int cntr, reset;
-
-                       dapl_dbg_log(DAPL_DBG_TYPE_RTN,
-                                    " Print counter extension call\n");
-
-                       cntr = va_arg(args, int);
-                       reset = va_arg(args, int);
-
-                       dapl_print_counter(dat_handle, cntr, reset);
-                       status = DAT_SUCCESS;
-                       break;
-               }
-#endif                         /* DAPL_COUNTERS */
-
-       default:
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                            "unsupported extension(%d)\n", (int)ext_op);
-       }
-
-       return (status);
-}
-
-DAT_RETURN
-dapli_post_ext(IN DAT_EP_HANDLE ep_handle,
-              IN DAT_UINT64 cmp_add,
-              IN DAT_UINT64 swap,
-              IN DAT_UINT32 immed_data,
-              IN DAT_COUNT segments,
-              IN DAT_LMR_TRIPLET * local_iov,
-              IN DAT_DTO_COOKIE user_cookie,
-              IN const DAT_RMR_TRIPLET * remote_iov,
-              IN int op_type, IN DAT_COMPLETION_FLAGS flags)
-{
-       DAPL_EP *ep_ptr;
-       ib_qp_handle_t qp_ptr;
-       DAPL_COOKIE *cookie = NULL;
-       DAT_RETURN dat_status = DAT_SUCCESS;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_API,
-                    " post_ext_op: ep %p cmp_val %d "
-                    "swap_val %d cookie 0x%x, r_iov %p, flags 0x%x\n",
-                    ep_handle, (unsigned)cmp_add, (unsigned)swap,
-                    (unsigned)user_cookie.as_64, remote_iov, flags);
-
-       if (DAPL_BAD_HANDLE(ep_handle, DAPL_MAGIC_EP))
-               return (DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP));
-
-       ep_ptr = (DAPL_EP *) ep_handle;
-       qp_ptr = ep_ptr->qp_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,
-                                           DAPL_DTO_TYPE_EXTENSION,
-                                           user_cookie, &cookie);
-       if (dat_status != DAT_SUCCESS)
-               goto bail;
-
-       /*
-        * Take reference before posting to avoid race conditions with
-        * completions
-        */
-       dapl_os_atomic_inc(&ep_ptr->req_count);
-
-       /*
-        * Invoke provider specific routine to post DTO
-        */
-       dat_status = dapls_ib_post_ext_send(ep_ptr, op_type, cookie, segments,  /* data segments */
-                                           local_iov, remote_iov, immed_data,  /* immed data */
-                                           cmp_add,    /* compare or add */
-                                           swap,       /* swap */
-                                           flags);
-
-       if (dat_status != DAT_SUCCESS) {
-               dapl_os_atomic_dec(&ep_ptr->req_count);
-               dapls_cookie_dealloc(&ep_ptr->req_buffer, cookie);
-       }
-
-      bail:
-       return dat_status;
-
-}
-
-/* 
- * New provider routine to process extended DTO events 
- */
-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)
-{
-       uint32_t ibtype;
-       DAT_DTO_COMPLETION_EVENT_DATA *dto =
-           &event_ptr->event_data.dto_completion_event_data;
-       DAT_IB_EXTENSION_EVENT_DATA *ext_data = (DAT_IB_EXTENSION_EVENT_DATA *)
-           & event_ptr->event_extension_data[0];
-       DAT_DTO_COMPLETION_STATUS dto_status;
-
-       /* Get status from cqe */
-       dto_status = dapls_ib_get_dto_status(cqe_ptr);
-
-       dapl_dbg_log(DAPL_DBG_TYPE_EVD,
-                    " cqe_to_event_ext: dto_ptr %p ext_ptr %p status %d\n",
-                    dto, ext_data, dto_status);
-
-       event_ptr->event_number = DAT_IB_DTO_EVENT;
-       dto->ep_handle = cookie->ep;
-       dto->user_cookie = cookie->val.dto.cookie;
-       dto->operation = DAPL_GET_CQE_DTOS_OPTYPE(cqe_ptr);     /* new for 2.0 */
-       dto->status = ext_data->status = dto_status;
-
-       if (dto_status != DAT_DTO_SUCCESS)
-               return;
-
-       /* 
-        * Get operation type from CQ work completion entry and
-        * if extented operation then set extended event data
-        */
-       ibtype = DAPL_GET_CQE_OPTYPE(cqe_ptr);
-
-       switch (ibtype) {
-
-       case OP_RDMA_WRITE_IMM:
-               dapl_dbg_log(DAPL_DBG_TYPE_EVD,
-                            " cqe_to_event_ext: OP_RDMA_WRITE_IMMED\n");
-
-               /* type and outbound rdma write transfer size */
-               dto->transfered_length = cookie->val.dto.size;
-               ext_data->type = DAT_IB_RDMA_WRITE_IMMED;
-               break;
-       case OP_RECEIVE_IMM:
-               dapl_dbg_log(DAPL_DBG_TYPE_EVD,
-                            " cqe_to_event_ext: OP_RECEIVE_RDMA_IMMED\n");
-
-               /* immed recvd, type and inbound rdma write transfer size */
-               dto->transfered_length = DAPL_GET_CQE_BYTESNUM(cqe_ptr);
-               ext_data->type = DAT_IB_RDMA_WRITE_IMMED_DATA;
-               ext_data->val.immed.data = DAPL_GET_CQE_IMMED_DATA(cqe_ptr);
-               break;
-       case OP_COMP_AND_SWAP:
-               dapl_dbg_log(DAPL_DBG_TYPE_EVD,
-                            " cqe_to_event_ext: COMP_AND_SWAP_RESP\n");
-
-               /* original data is returned in LMR provided with post */
-               ext_data->type = DAT_IB_CMP_AND_SWAP;
-               dto->transfered_length = DAPL_GET_CQE_BYTESNUM(cqe_ptr);
-               break;
-       case OP_FETCH_AND_ADD:
-               dapl_dbg_log(DAPL_DBG_TYPE_EVD,
-                            " cqe_to_event_ext: FETCH_AND_ADD_RESP\n");
-
-               /* original data is returned in LMR provided with post */
-               ext_data->type = DAT_IB_FETCH_AND_ADD;
-               dto->transfered_length = DAPL_GET_CQE_BYTESNUM(cqe_ptr);
-               break;
-       default:
-               /* not extended operation */
-               ext_data->status = DAT_IB_OP_ERR;
-               dto->status = DAT_DTO_ERR_TRANSPORT;
-               break;
-       }
-}
diff --git a/ulp/dapl2/dapl/openib_cma/dapl_ib_qp.c b/ulp/dapl2/dapl/openib_cma/dapl_ib_qp.c
deleted file mode 100644 (file)
index c9a61c3..0000000
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (c) 2005-2007 Intel Corporation.  All rights reserved.
- *
- * This Software is licensed under one of the following licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- *
- * 2) under the terms of the "The BSD License" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- *
- * Licensee has the right to choose one of the above licenses.
- *
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/**********************************************************************
- *
- * MODULE: dapl_ib_qp.c
- *
- * PURPOSE: QP routines for access to OFED IB Verbs
- *
- * $Id: $
- *
- **********************************************************************/
-
-#include "dapl.h"
-#include "dapl_adapter_util.h"
-
-extern struct rdma_event_channel *g_cm_events;
-
-/*
- * dapl_ib_qp_alloc
- *
- * Alloc a QP
- *
- * Input:
- *     *ep_ptr         pointer to EP INFO
- *     ib_hca_handle   provider HCA handle
- *     ib_pd_handle    provider protection domain handle
- *     cq_recv         provider recv CQ handle
- *     cq_send         provider send CQ handle
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *     DAT_INTERNAL_ERROR
- *
- */
-DAT_RETURN dapls_ib_qp_alloc(IN DAPL_IA * ia_ptr,
-                            IN DAPL_EP * ep_ptr, IN DAPL_EP * ep_ctx_ptr)
-{
-       DAT_EP_ATTR *attr;
-       DAPL_EVD *rcv_evd, *req_evd;
-       ib_cq_handle_t rcv_cq, req_cq;
-       ib_pd_handle_t ib_pd_handle;
-       struct ibv_qp_init_attr qp_create;
-       dp_ib_cm_handle_t conn;
-       struct rdma_cm_id *cm_id;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_EP,
-                    " qp_alloc: ia_ptr %p ep_ptr %p ep_ctx_ptr %p\n",
-                    ia_ptr, ep_ptr, ep_ctx_ptr);
-
-       attr = &ep_ptr->param.ep_attr;
-       ib_pd_handle = ((DAPL_PZ *) ep_ptr->param.pz_handle)->pd_handle;
-       rcv_evd = (DAPL_EVD *) ep_ptr->param.recv_evd_handle;
-       req_evd = (DAPL_EVD *) ep_ptr->param.request_evd_handle;
-
-       /* 
-        * DAT allows usage model of EP's with no EVD's but IB does not. 
-        * Create a CQ with zero entries under the covers to support and 
-        * catch any invalid posting. 
-        */
-       if (rcv_evd != DAT_HANDLE_NULL)
-               rcv_cq = rcv_evd->ib_cq_handle;
-       else if (!ia_ptr->hca_ptr->ib_trans.ib_cq_empty)
-               rcv_cq = ia_ptr->hca_ptr->ib_trans.ib_cq_empty;
-       else {
-               struct ibv_comp_channel *channel =
-                   ia_ptr->hca_ptr->ib_trans.ib_cq;
-#ifdef CQ_WAIT_OBJECT
-               if (rcv_evd->cq_wait_obj_handle)
-                       channel = rcv_evd->cq_wait_obj_handle->events;
-#endif
-               /* Call IB verbs to create CQ */
-               rcv_cq = ibv_create_cq(ia_ptr->hca_ptr->ib_hca_handle,
-                                      0, NULL, channel, 0);
-
-               if (rcv_cq == IB_INVALID_HANDLE)
-                       return (dapl_convert_errno(ENOMEM, "create_cq"));
-
-               ia_ptr->hca_ptr->ib_trans.ib_cq_empty = rcv_cq;
-       }
-       if (req_evd != DAT_HANDLE_NULL)
-               req_cq = req_evd->ib_cq_handle;
-       else
-               req_cq = ia_ptr->hca_ptr->ib_trans.ib_cq_empty;
-
-       /* 
-        * IMPLEMENTATION NOTE:
-        * uDAPL allows consumers to post buffers on the EP after creation
-        * and before a connect request (outbound and inbound). This forces
-        * a binding to a device during the hca_open call and requires the
-        * consumer to predetermine which device to listen on or connect from.
-        * This restriction eliminates any option of listening or connecting 
-        * over multiple devices. uDAPL should add API's to resolve addresses 
-        * and bind to the device at the approriate time (before connect 
-        * and after CR arrives). Discovery should happen at connection time 
-        * based on addressing and not on static configuration during open.
-        */
-
-       /* Allocate CM and initialize lock */
-       if ((conn = dapl_os_alloc(sizeof(*conn))) == NULL)
-               return (dapl_convert_errno(ENOMEM, "create_cq"));
-
-       dapl_os_memzero(conn, sizeof(*conn));
-       dapl_os_lock_init(&conn->lock);
-
-       /* create CM_ID, bind to local device, create QP */
-       if (rdma_create_id(g_cm_events, &cm_id, (void *)conn, RDMA_PS_TCP)) {
-               dapl_os_free(conn, sizeof(*conn));
-               return (dapl_convert_errno(errno, "create_qp"));
-       }
-
-       /* open identifies the local device; per DAT specification */
-       if (rdma_bind_addr(cm_id,
-                          (struct sockaddr *)&ia_ptr->hca_ptr->hca_address))
-               goto bail;
-
-       /* Setup attributes and create qp */
-       dapl_os_memzero((void *)&qp_create, sizeof(qp_create));
-       qp_create.cap.max_send_wr = attr->max_request_dtos;
-       qp_create.cap.max_send_sge = attr->max_request_iov;
-       qp_create.cap.max_inline_data =
-           ia_ptr->hca_ptr->ib_trans.max_inline_send;
-       qp_create.send_cq = req_cq;
-
-       /* ibv assumes rcv_cq is never NULL, set to req_cq */
-       if (rcv_cq == NULL) {
-               qp_create.recv_cq = req_cq;
-               qp_create.cap.max_recv_wr = 0;
-               qp_create.cap.max_recv_sge = 0;
-       } else {
-               qp_create.recv_cq = rcv_cq;
-               qp_create.cap.max_recv_wr = attr->max_recv_dtos;
-               qp_create.cap.max_recv_sge = attr->max_recv_iov;
-       }
-       qp_create.qp_type = IBV_QPT_RC;
-       qp_create.qp_context = (void *)ep_ptr;
-
-       /* Let uCMA transition QP states */
-       if (rdma_create_qp(cm_id, ib_pd_handle, &qp_create))
-               goto bail;
-
-       conn->cm_id = cm_id;
-       conn->ep = ep_ptr;
-       conn->hca = ia_ptr->hca_ptr;
-
-       /* setup timers for address and route resolution */
-       conn->arp_timeout = dapl_os_get_env_val("DAPL_CM_ARP_TIMEOUT_MS",
-                                               IB_ARP_TIMEOUT);
-       conn->arp_retries = dapl_os_get_env_val("DAPL_CM_ARP_RETRY_COUNT",
-                                               IB_ARP_RETRY_COUNT);
-       conn->route_timeout = dapl_os_get_env_val("DAPL_CM_ROUTE_TIMEOUT_MS",
-                                                 IB_ROUTE_TIMEOUT);
-       conn->route_retries = dapl_os_get_env_val("DAPL_CM_ROUTE_RETRY_COUNT",
-                                                 IB_ROUTE_RETRY_COUNT);
-
-       /* setup up ep->param to reference the bound local address and port */
-       ep_ptr->param.local_ia_address_ptr = &cm_id->route.addr.src_addr;
-       ep_ptr->param.local_port_qual = rdma_get_src_port(cm_id);
-
-       ep_ptr->qp_handle = conn;
-       ep_ptr->qp_state = IB_QP_STATE_INIT;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_EP,
-                    " qp_alloc: qpn %p sq %d,%d rq %d,%d port=%d\n",
-                    ep_ptr->qp_handle->cm_id->qp->qp_num,
-                    qp_create.cap.max_send_wr, qp_create.cap.max_send_sge,
-                    qp_create.cap.max_recv_wr, qp_create.cap.max_recv_sge,
-                    ep_ptr->param.local_port_qual);
-
-       return DAT_SUCCESS;
-      bail:
-       rdma_destroy_id(cm_id);
-       dapl_os_free(conn, sizeof(*conn));
-       return (dapl_convert_errno(errno, "create_qp"));
-}
-
-/*
- * dapl_ib_qp_free
- *
- * Free a QP
- *
- * Input:
- *     ia_handle       IA handle
- *     *ep_ptr         pointer to EP INFO
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *  dapl_convert_errno
- *
- */
-DAT_RETURN dapls_ib_qp_free(IN DAPL_IA * ia_ptr, IN DAPL_EP * ep_ptr)
-{
-       dapl_dbg_log(DAPL_DBG_TYPE_EP, " qp_free:  ep_ptr %p qp %p\n",
-                    ep_ptr, ep_ptr->qp_handle);
-
-       if (ep_ptr->qp_handle != IB_INVALID_HANDLE) {
-               /* qp_handle is conn object with reference to cm_id and qp */
-               dapli_destroy_conn(ep_ptr->qp_handle);
-               ep_ptr->qp_handle = IB_INVALID_HANDLE;
-               ep_ptr->qp_state = IB_QP_STATE_ERROR;
-       }
-       return DAT_SUCCESS;
-}
-
-/*
- * dapl_ib_qp_modify
- *
- * Set the QP to the parameters specified in an EP_PARAM
- *
- * The EP_PARAM structure that is provided has been
- * sanitized such that only non-zero values are valid.
- *
- * Input:
- *     ib_hca_handle           HCA handle
- *     qp_handle               QP handle
- *     ep_attr                 Sanitized EP Params
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *     DAT_INVALID_PARAMETER
- *
- */
-DAT_RETURN dapls_ib_qp_modify(IN DAPL_IA * ia_ptr,
-                             IN DAPL_EP * ep_ptr, IN DAT_EP_ATTR * attr)
-{
-       struct ibv_qp_attr qp_attr;
-
-       if (ep_ptr->qp_handle == IB_INVALID_HANDLE)
-               return DAT_INVALID_PARAMETER;
-
-       /*
-        * Check if we have the right qp_state to modify attributes
-        */
-       if ((ep_ptr->qp_handle->cm_id->qp->state != IBV_QPS_RTR) &&
-           (ep_ptr->qp_handle->cm_id->qp->state != IBV_QPS_RTS))
-               return DAT_INVALID_STATE;
-
-       /* Adjust to current EP attributes */
-       dapl_os_memzero((void *)&qp_attr, sizeof(qp_attr));
-       qp_attr.cap.max_send_wr = attr->max_request_dtos;
-       qp_attr.cap.max_recv_wr = attr->max_recv_dtos;
-       qp_attr.cap.max_send_sge = attr->max_request_iov;
-       qp_attr.cap.max_recv_sge = attr->max_recv_iov;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_EP,
-                    "modify_qp: qp %p sq %d,%d, rq %d,%d\n",
-                    ep_ptr->qp_handle->cm_id->qp,
-                    qp_attr.cap.max_send_wr, qp_attr.cap.max_send_sge,
-                    qp_attr.cap.max_recv_wr, qp_attr.cap.max_recv_sge);
-
-       if (ibv_modify_qp(ep_ptr->qp_handle->cm_id->qp, &qp_attr, IBV_QP_CAP)) {
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                            "modify_qp: modify ep %p qp %p failed\n",
-                            ep_ptr, ep_ptr->qp_handle->cm_id->qp);
-               return (dapl_convert_errno(errno, "modify_qp_state"));
-       }
-
-       return DAT_SUCCESS;
-}
-
-/*
- * dapls_ib_reinit_ep
- *
- * Move the QP to INIT state again.
- *
- * Input:
- *     ep_ptr          DAPL_EP
- *
- * Output:
- *     none
- *
- * Returns:
- *     void
- *
- */
-void dapls_ib_reinit_ep(IN DAPL_EP * ep_ptr)
-{
-       /* uCMA does not allow reuse of CM_ID, destroy and create new one */
-       if (ep_ptr->qp_handle != IB_INVALID_HANDLE) {
-
-               /* destroy */
-               dapli_destroy_conn(ep_ptr->qp_handle);
-
-               /* create new CM_ID and QP */
-               ep_ptr->qp_handle = IB_INVALID_HANDLE;
-               dapls_ib_qp_alloc(ep_ptr->header.owner_ia, ep_ptr, ep_ptr);
-       }
-}
-
-/*
- * Local variables:
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 8
- * End:
- */
similarity index 58%
rename from ulp/dapl2/dapl/openib_cma/dapl_ib_util.c
rename to ulp/dapl2/dapl/openib_cma/device.c
index f48c1cb..3c9d135 100644 (file)
-/*
- * Copyright (c) 2005-2008 Intel Corporation.  All rights reserved.
- *
- * This Software is licensed under one of the following licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- *
- * 2) under the terms of the "The BSD License" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- *
- * Licensee has the right to choose one of the above licenses.
- *
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/**********************************************************************
- * 
- * MODULE: dapl_ib_util.c
- *
- * PURPOSE: OFED provider - init, open, close, utilities, work thread
- *
- * $Id:$
- *
- **********************************************************************/
-
-#ifdef RCSID
-static const char rcsid[] = "$Id:  $";
-#endif
-
-#include "openib_osd.h"
-#include "dapl.h"
-#include "dapl_adapter_util.h"
-#include "dapl_ib_util.h"
-#include "dapl_osd.h"
-
-#include <stdlib.h>
-
-int g_dapl_loopback_connection = 0;
-struct rdma_event_channel *g_cm_events = NULL;
-ib_thread_state_t g_ib_thread_state = 0;
-DAPL_OS_THREAD g_ib_thread;
-DAPL_OS_LOCK g_hca_lock;
-struct dapl_llist_entry *g_hca_list;
-
-#if defined(_WIN64) || defined(_WIN32)
-#include "..\..\..\..\..\etc\user\comp_channel.cpp"
-#include <rdma\winverbs.h>
-
-struct ibvw_windata windata;
-
-static int getipaddr_netdev(char *name, char *addr, int addr_len)
-{
-       IWVProvider *prov;
-       WV_DEVICE_ADDRESS devaddr;
-       struct addrinfo *res, *ai;
-       HRESULT hr;
-       int index;
-
-       if (strncmp(name, "rdma_dev", 8)) {
-               return EINVAL;
-       }
-
-       index = atoi(name + 8);
-
-       hr = WvGetObject(&IID_IWVProvider, (LPVOID *) &prov);
-       if (FAILED(hr)) {
-               return hr;
-       }
-
-       hr = getaddrinfo("..localmachine", NULL, NULL, &res);
-       if (hr) {
-               goto release;
-       }
-
-       for (ai = res; ai; ai = ai->ai_next) {
-               hr = prov->lpVtbl->TranslateAddress(prov, ai->ai_addr, &devaddr);
-               if (SUCCEEDED(hr) && (ai->ai_addrlen <= addr_len) && (index-- == 0)) {
-                       memcpy(addr, ai->ai_addr, ai->ai_addrlen);
-                       goto free;
-               }
-       }
-       hr = ENODEV;
-
-free:
-       freeaddrinfo(res);
-release:
-       prov->lpVtbl->Release(prov);
-       return hr;
-}
-
-static int dapls_os_init(void)
-{
-       return ibvw_get_windata(&windata, IBVW_WINDATA_VERSION);
-}
-
-static void dapls_os_release(void)
-{
-       if (windata.comp_mgr)
-               ibvw_release_windata(&windata, IBVW_WINDATA_VERSION);
-       windata.comp_mgr = NULL;
-}
-
-static int dapls_config_comp_channel(struct ibv_comp_channel *channel)
-{
-       channel->comp_channel.Milliseconds = 0;
-       return 0;
-}
-
-static int dapls_config_cm_channel(struct rdma_event_channel *channel)
-{
-       channel->channel.Milliseconds = 0;
-       return 0;
-}
-
-static int dapls_config_verbs(struct ibv_context *verbs)
-{
-       verbs->channel.Milliseconds = 0;
-       return 0;
-}
-
-static int dapls_thread_signal(void)
-{
-       CompManagerCancel(windata.comp_mgr);
-       return 0;
-}
-#else                          // _WIN64 || WIN32
-int g_ib_pipe[2];
-
-static int dapls_os_init(void)
-{
-       /* create pipe for waking up work thread */
-       return pipe(g_ib_pipe);
-}
-
-static void dapls_os_release(void)
-{
-       /* close pipe? */
-}
-
-/* Get IP address using network device name */
-static int getipaddr_netdev(char *name, char *addr, int addr_len)
-{
-       struct ifreq ifr;
-       int skfd, ret, len;
-
-       /* Fill in the structure */
-       snprintf(ifr.ifr_name, IFNAMSIZ, "%s", name);
-       ifr.ifr_hwaddr.sa_family = ARPHRD_INFINIBAND;
-
-       /* Create a socket fd */
-       skfd = socket(PF_INET, SOCK_STREAM, 0);
-       ret = ioctl(skfd, SIOCGIFADDR, &ifr);
-       if (ret)
-               goto bail;
-
-       switch (ifr.ifr_addr.sa_family) {
-#ifdef AF_INET6
-       case AF_INET6:
-               len = sizeof(struct sockaddr_in6);
-               break;
-#endif
-       case AF_INET:
-       default:
-               len = sizeof(struct sockaddr);
-               break;
-       }
-
-       if (len <= addr_len)
-               memcpy(addr, &ifr.ifr_addr, len);
-       else
-               ret = EINVAL;
-
-      bail:
-       close(skfd);
-       return ret;
-}
-
-static int dapls_config_fd(int fd)
-{
-       int opts;
-
-       opts = fcntl(fd, F_GETFL);
-       if (opts < 0 || fcntl(fd, F_SETFL, opts | O_NONBLOCK) < 0) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " dapls_config_fd: fcntl on fd %d ERR %d %s\n",
-                        fd, opts, strerror(errno));
-               return errno;
-       }
-
-       return 0;
-}
-
-static int dapls_config_comp_channel(struct ibv_comp_channel *channel)
-{
-       return dapls_config_fd(channel->fd);
-}
-
-static int dapls_config_cm_channel(struct rdma_event_channel *channel)
-{
-       return dapls_config_fd(channel->fd);
-}
-
-static int dapls_config_verbs(struct ibv_context *verbs)
-{
-       return dapls_config_fd(verbs->async_fd);
-}
-
-static int dapls_thread_signal(void)
-{
-       return write(g_ib_pipe[1], "w", sizeof "w");
-}
-#endif
-
-/* Get IP address using network name, address, or device name */
-static int getipaddr(char *name, char *addr, int len)
-{
-       struct addrinfo *res;
-
-       /* assume netdev for first attempt, then network and address type */
-       if (getipaddr_netdev(name, addr, len)) {
-               if (getaddrinfo(name, NULL, NULL, &res)) {
-                       dapl_log(DAPL_DBG_TYPE_ERR,
-                                " open_hca: getaddr_netdev ERROR:"
-                                " %s. Is %s configured?\n",
-                                strerror(errno), name);
-                       return 1;
-               } else {
-                       if (len >= res->ai_addrlen)
-                               memcpy(addr, res->ai_addr, res->ai_addrlen);
-                       else {
-                               freeaddrinfo(res);
-                               return 1;
-                       }
-                       freeaddrinfo(res);
-               }
-       }
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " getipaddr: family %d port %d addr %d.%d.%d.%d\n",
-                    ((struct sockaddr_in *)addr)->sin_family,
-                    ((struct sockaddr_in *)addr)->sin_port,
-                    ((struct sockaddr_in *)addr)->sin_addr.s_addr >> 0 & 0xff,
-                    ((struct sockaddr_in *)addr)->sin_addr.s_addr >> 8 & 0xff,
-                    ((struct sockaddr_in *)addr)->sin_addr.s_addr >> 16 & 0xff,
-                    ((struct sockaddr_in *)addr)->sin_addr.
-                    s_addr >> 24 & 0xff);
-
-       return 0;
-}
-
-/*
- * dapls_ib_init, dapls_ib_release
- *
- * Initialize Verb related items for device open
- *
- * Input:
- *     none
- *
- * Output:
- *     none
- *
- * Returns:
- *     0 success, -1 error
- *
- */
-int32_t dapls_ib_init(void)
-{
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " dapl_ib_init: \n");
-
-       /* initialize hca_list lock */
-       dapl_os_lock_init(&g_hca_lock);
-
-       /* initialize hca list for CQ events */
-       dapl_llist_init_head(&g_hca_list);
-
-       if (dapls_os_init())
-               return 1;
-
-       return 0;
-}
-
-int32_t dapls_ib_release(void)
-{
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " dapl_ib_release: \n");
-       dapli_ib_thread_destroy();
-       if (g_cm_events != NULL)
-               rdma_destroy_event_channel(g_cm_events);
-       dapls_os_release();
-       return 0;
-}
-
-/*
- * dapls_ib_open_hca
- *
- * Open HCA
- *
- * Input:
- *      *hca_name         pointer to provider device name
- *      *ib_hca_handle_p  pointer to provide HCA handle
- *
- * Output:
- *      none
- *
- * Return:
- *      DAT_SUCCESS
- *      dapl_convert_errno
- *
- */
-DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr)
-{
-       struct rdma_cm_id *cm_id = NULL;
-       union ibv_gid *gid;
-       int ret;
-       DAT_RETURN dat_status;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " open_hca: %s - %p\n", hca_name, hca_ptr);
-
-       /* Setup the global cm event channel */
-       dapl_os_lock(&g_hca_lock);
-       if (g_cm_events == NULL) {
-               g_cm_events = rdma_create_event_channel();
-               if (g_cm_events == NULL) {
-                       dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                                    " open_hca: ERR - RDMA channel %s\n",
-                                    strerror(errno));
-                       return DAT_INTERNAL_ERROR;
-               }
-       }
-       dapl_os_unlock(&g_hca_lock);
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " open_hca: RDMA channel created (%p)\n", g_cm_events);
-
-       dat_status = dapli_ib_thread_init();
-       if (dat_status != DAT_SUCCESS)
-               return dat_status;
-
-       /* HCA name will be hostname or IP address */
-       if (getipaddr((char *)hca_name,
-                     (char *)&hca_ptr->hca_address, sizeof(DAT_SOCK_ADDR6)))
-               return DAT_INVALID_ADDRESS;
-
-       /* cm_id will bind local device/GID based on IP address */
-       if (rdma_create_id(g_cm_events, &cm_id, (void *)hca_ptr, RDMA_PS_TCP)) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " open_hca: rdma_create_id ERR %s\n", strerror(errno));
-               return DAT_INTERNAL_ERROR;
-       }
-       ret = rdma_bind_addr(cm_id, (struct sockaddr *)&hca_ptr->hca_address);
-       if ((ret) || (cm_id->verbs == NULL)) {
-               rdma_destroy_id(cm_id);
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " open_hca: rdma_bind ERR %s."
-                        " Is %s configured?\n", strerror(errno), hca_name);
-               return DAT_INVALID_ADDRESS;
-       }
-
-       /* keep reference to IB device and cm_id */
-       hca_ptr->ib_trans.cm_id = cm_id;
-       hca_ptr->ib_hca_handle = cm_id->verbs;
-       dapls_config_verbs(cm_id->verbs);
-       hca_ptr->port_num = cm_id->port_num;
-       gid = &cm_id->route.addr.addr.ibaddr.sgid;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " open_hca: ctx=%p port=%d GID subnet %016llx id %016llx\n",
-                    cm_id->verbs, cm_id->port_num,
-                    (unsigned long long)ntohll(gid->global.subnet_prefix),
-                    (unsigned long long)ntohll(gid->global.interface_id));
-
-       /* set inline max with env or default, get local lid and gid 0 */
-       if (hca_ptr->ib_hca_handle->device->transport_type
-           == IBV_TRANSPORT_IWARP)
-               hca_ptr->ib_trans.max_inline_send =
-                   dapl_os_get_env_val("DAPL_MAX_INLINE",
-                                       INLINE_SEND_IWARP_DEFAULT);
-       else
-               hca_ptr->ib_trans.max_inline_send =
-                   dapl_os_get_env_val("DAPL_MAX_INLINE",
-                                       INLINE_SEND_IB_DEFAULT);
-
-       /* set CM timer defaults */
-       hca_ptr->ib_trans.max_cm_timeout =
-           dapl_os_get_env_val("DAPL_MAX_CM_RESPONSE_TIME",
-                               IB_CM_RESPONSE_TIMEOUT);
-       hca_ptr->ib_trans.max_cm_retries =
-           dapl_os_get_env_val("DAPL_MAX_CM_RETRIES", IB_CM_RETRIES);
-
-       /* EVD events without direct CQ channels, non-blocking */
-       hca_ptr->ib_trans.ib_cq =
-           ibv_create_comp_channel(hca_ptr->ib_hca_handle);
-       if (hca_ptr->ib_trans.ib_cq == NULL) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " open_hca: ibv_create_comp_channel ERR %s\n",
-                        strerror(errno));
-               goto bail;
-       }
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " open_hca: CQ channel created\n");
-
-       if (dapls_config_comp_channel(hca_ptr->ib_trans.ib_cq)) {
-               goto bail;
-       }
-
-       /* 
-        * Put new hca_transport on list for async and CQ event processing 
-        * Wakeup work thread to add to polling list
-        */
-       dapl_llist_init_entry((DAPL_LLIST_ENTRY *) & hca_ptr->ib_trans.entry);
-       dapl_os_lock(&g_hca_lock);
-       dapl_llist_add_tail(&g_hca_list,
-                           (DAPL_LLIST_ENTRY *) & hca_ptr->ib_trans.entry,
-                           &hca_ptr->ib_trans.entry);
-       if (dapls_thread_signal() == -1)
-               dapl_log(DAPL_DBG_TYPE_UTIL,
-                        " open_hca: thread wakeup error = %s\n",
-                        strerror(errno));
-       dapl_os_unlock(&g_hca_lock);
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " open_hca: %s, %s %d.%d.%d.%d INLINE_MAX=%d\n", hca_name,
-                    ((struct sockaddr_in *)
-                     &hca_ptr->hca_address)->sin_family == AF_INET ?
-                    "AF_INET" : "AF_INET6", ((struct sockaddr_in *)
-                                             &hca_ptr->hca_address)->sin_addr.
-                    s_addr >> 0 & 0xff, ((struct sockaddr_in *)
-                                         &hca_ptr->hca_address)->sin_addr.
-                    s_addr >> 8 & 0xff, ((struct sockaddr_in *)
-                                         &hca_ptr->hca_address)->sin_addr.
-                    s_addr >> 16 & 0xff, ((struct sockaddr_in *)
-                                          &hca_ptr->hca_address)->sin_addr.
-                    s_addr >> 24 & 0xff, hca_ptr->ib_trans.max_inline_send);
-
-       hca_ptr->ib_trans.d_hca = hca_ptr;
-       return DAT_SUCCESS;
-      bail:
-       rdma_destroy_id(hca_ptr->ib_trans.cm_id);
-       hca_ptr->ib_hca_handle = IB_INVALID_HANDLE;
-       return DAT_INTERNAL_ERROR;
-}
-
-/*
- * dapls_ib_close_hca
- *
- * Open HCA
- *
- * Input:
- *      DAPL_HCA   provide CA handle
- *
- * Output:
- *      none
- *
- * Return:
- *      DAT_SUCCESS
- *     dapl_convert_errno 
- *
- */
-DAT_RETURN dapls_ib_close_hca(IN DAPL_HCA * hca_ptr)
-{
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " close_hca: %p->%p\n",
-                    hca_ptr, hca_ptr->ib_hca_handle);
-
-       if (hca_ptr->ib_hca_handle != IB_INVALID_HANDLE) {
-               if (rdma_destroy_id(hca_ptr->ib_trans.cm_id))
-                       return (dapl_convert_errno(errno, "ib_close_device"));
-               hca_ptr->ib_hca_handle = IB_INVALID_HANDLE;
-       }
-
-       dapl_os_lock(&g_hca_lock);
-       if (g_ib_thread_state != IB_THREAD_RUN) {
-               dapl_os_unlock(&g_hca_lock);
-               goto bail;
-       }
-       dapl_os_unlock(&g_hca_lock);
-
-       /* 
-        * Remove hca from async and CQ event processing list
-        * Wakeup work thread to remove from polling list
-        */
-       hca_ptr->ib_trans.destroy = 1;
-       if (dapls_thread_signal() == -1)
-               dapl_log(DAPL_DBG_TYPE_UTIL,
-                        " destroy: thread wakeup error = %s\n",
-                        strerror(errno));
-
-       /* wait for thread to remove HCA references */
-       while (hca_ptr->ib_trans.destroy != 2) {
-               if (dapls_thread_signal() == -1)
-                       dapl_log(DAPL_DBG_TYPE_UTIL,
-                                " destroy: thread wakeup error = %s\n",
-                                strerror(errno));
-               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                            " ib_thread_destroy: wait on hca %p destroy\n");
-               dapl_os_sleep_usec(10000);
-       }
-      bail:
-       return (DAT_SUCCESS);
-}
-
-/*
- * dapls_ib_query_hca
- *
- * Query the hca attribute
- *
- * Input:
- *     hca_handl               hca handle      
- *     ia_attr                 attribute of the ia
- *     ep_attr                 attribute of the ep
- *     ip_addr                 ip address of DET NIC
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INVALID_HANDLE
- */
-
-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)
-{
-       struct ibv_device_attr dev_attr;
-       struct ibv_port_attr port_attr;
-
-       if (hca_ptr->ib_hca_handle == NULL) {
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR, " query_hca: BAD handle\n");
-               return (DAT_INVALID_HANDLE);
-       }
-
-       /* local IP address of device, set during ia_open */
-       if (ip_addr != NULL)
-               memcpy(ip_addr, &hca_ptr->hca_address, sizeof(DAT_SOCK_ADDR6));
-
-       if (ia_attr == NULL && ep_attr == NULL)
-               return DAT_SUCCESS;
-
-       /* query verbs for this device and port attributes */
-       if (ibv_query_device(hca_ptr->ib_hca_handle, &dev_attr) ||
-           ibv_query_port(hca_ptr->ib_hca_handle,
-                          hca_ptr->port_num, &port_attr))
-               return (dapl_convert_errno(errno, "ib_query_hca"));
-
-       /*
-        * There is no query for inline data so there is no way to 
-        * calculate the impact on sge nor the max inline send. Most 
-        * implementions consume 1 or none so just reduce by 1 until 
-        * we are provided with a query mechanism from verbs.
-        */
-       if (hca_ptr->ib_trans.max_inline_send)
-               dev_attr.max_sge--;
-
-       if (ia_attr != NULL) {
-               (void)dapl_os_memzero(ia_attr, sizeof(*ia_attr));
-               ia_attr->adapter_name[DAT_NAME_MAX_LENGTH - 1] = '\0';
-               ia_attr->vendor_name[DAT_NAME_MAX_LENGTH - 1] = '\0';
-               ia_attr->ia_address_ptr =
-                   (DAT_IA_ADDRESS_PTR) & hca_ptr->hca_address;
-
-               dapl_log(DAPL_DBG_TYPE_UTIL,
-                        "dapl_query_hca: %s %s %s\n", hca_ptr->name,
-                        ((struct sockaddr_in *)
-                         ia_attr->ia_address_ptr)->sin_family == AF_INET ?
-                        "AF_INET" : "AF_INET6",
-                        inet_ntoa(((struct sockaddr_in *)
-                                   ia_attr->ia_address_ptr)->sin_addr));
-
-               ia_attr->hardware_version_major = dev_attr.hw_ver;
-               ia_attr->max_eps = dev_attr.max_qp;
-               ia_attr->max_dto_per_ep = dev_attr.max_qp_wr;
-               ia_attr->max_rdma_read_in = dev_attr.max_res_rd_atom;
-               ia_attr->max_rdma_read_out = dev_attr.max_qp_init_rd_atom;
-               ia_attr->max_rdma_read_per_ep_in = dev_attr.max_qp_rd_atom;
-               ia_attr->max_rdma_read_per_ep_out =
-                   dev_attr.max_qp_init_rd_atom;
-               ia_attr->max_rdma_read_per_ep_in_guaranteed = DAT_TRUE;
-               ia_attr->max_rdma_read_per_ep_out_guaranteed = DAT_TRUE;
-               ia_attr->max_evds = dev_attr.max_cq;
-               ia_attr->max_evd_qlen = dev_attr.max_cqe;
-               ia_attr->max_iov_segments_per_dto = dev_attr.max_sge;
-               ia_attr->max_lmrs = dev_attr.max_mr;
-               /* 32bit attribute from 64bit, 4G-1 limit, DAT v2 needs fix */
-               ia_attr->max_lmr_block_size = 
-                   (dev_attr.max_mr_size >> 32) ? ~0 : dev_attr.max_mr_size;
-               ia_attr->max_rmrs = dev_attr.max_mw;
-               ia_attr->max_lmr_virtual_address = dev_attr.max_mr_size;
-               ia_attr->max_rmr_target_address = dev_attr.max_mr_size;
-               ia_attr->max_pzs = dev_attr.max_pd;
-               ia_attr->max_mtu_size = port_attr.max_msg_sz;
-               ia_attr->max_rdma_size = port_attr.max_msg_sz;
-               ia_attr->num_transport_attr = 0;
-               ia_attr->transport_attr = NULL;
-               ia_attr->num_vendor_attr = 0;
-               ia_attr->vendor_attr = NULL;
-               /* iWARP spec. - 1 sge for RDMA reads */
-               if (hca_ptr->ib_hca_handle->device->transport_type
-                   == IBV_TRANSPORT_IWARP)
-                       ia_attr->max_iov_segments_per_rdma_read = 1;
-               else
-                       ia_attr->max_iov_segments_per_rdma_read =
-                           dev_attr.max_sge;
-
-               ia_attr->max_iov_segments_per_rdma_write = dev_attr.max_sge;
-               /* save rd_atom for peer validation during connect requests */
-               hca_ptr->ib_trans.max_rdma_rd_in = dev_attr.max_qp_rd_atom;
-               hca_ptr->ib_trans.max_rdma_rd_out =
-                   dev_attr.max_qp_init_rd_atom;
-#ifdef DAT_EXTENSIONS
-               ia_attr->extension_supported = DAT_EXTENSION_IB;
-               ia_attr->extension_version = DAT_IB_EXTENSION_VERSION;
-#endif
-               dapl_log(DAPL_DBG_TYPE_UTIL,
-                        "dapl_query_hca: (ver=%x) ep's %d ep_q %d"
-                        " evd's %d evd_q %d mr %u\n",
-                        ia_attr->hardware_version_major,
-                        ia_attr->max_eps, ia_attr->max_dto_per_ep,
-                        ia_attr->max_evds, ia_attr->max_evd_qlen, 
-                        ia_attr->max_lmr_block_size);
-               dapl_log(DAPL_DBG_TYPE_UTIL,
-                        "dapl_query_hca: msg %llu rdma %llu iov's %d"
-                        " lmr %d rmr %d rd_in,out %d,%d inline=%d\n",
-                        ia_attr->max_mtu_size, ia_attr->max_rdma_size,
-                        ia_attr->max_iov_segments_per_dto, ia_attr->max_lmrs,
-                        ia_attr->max_rmrs, ia_attr->max_rdma_read_per_ep_in,
-                        ia_attr->max_rdma_read_per_ep_out,
-                        hca_ptr->ib_trans.max_inline_send);
-       }
-
-       if (ep_attr != NULL) {
-               (void)dapl_os_memzero(ep_attr, sizeof(*ep_attr));
-               ep_attr->max_mtu_size = port_attr.max_msg_sz;
-               ep_attr->max_rdma_size = port_attr.max_msg_sz;
-               ep_attr->max_recv_dtos = dev_attr.max_qp_wr;
-               ep_attr->max_request_dtos = dev_attr.max_qp_wr;
-               ep_attr->max_recv_iov = dev_attr.max_sge;
-               ep_attr->max_request_iov = dev_attr.max_sge;
-               ep_attr->max_rdma_read_in = dev_attr.max_qp_rd_atom;
-               ep_attr->max_rdma_read_out = dev_attr.max_qp_init_rd_atom;
-               /* iWARP spec. - 1 sge for RDMA reads */
-               if (hca_ptr->ib_hca_handle->device->transport_type
-                   == IBV_TRANSPORT_IWARP)
-                       ep_attr->max_rdma_read_iov = 1;
-               else
-                       ep_attr->max_rdma_read_iov = dev_attr.max_sge;
-
-               ep_attr->max_rdma_write_iov = dev_attr.max_sge;
-               dapl_log(DAPL_DBG_TYPE_UTIL,
-                        "dapl_query_hca: MAX msg %llu dto %d iov %d"
-                        " rdma i%d,o%d\n",
-                        ep_attr->max_mtu_size,
-                        ep_attr->max_recv_dtos, ep_attr->max_recv_iov,
-                        ep_attr->max_rdma_read_in, ep_attr->max_rdma_read_out);
-       }
-       return DAT_SUCCESS;
-}
-
-/*
- * dapls_ib_setup_async_callback
- *
- * Set up an asynchronous callbacks of various kinds
- *
- * Input:
- *     ia_handle               IA handle
- *     handler_type            type of handler to set up
- *     callback_handle         handle param for completion callbacks
- *     callback                callback routine pointer
- *     context                 argument for callback routine
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *     DAT_INVALID_PARAMETER
- *
- */
-DAT_RETURN dapls_ib_setup_async_callback(IN DAPL_IA * ia_ptr,
-                                        IN DAPL_ASYNC_HANDLER_TYPE type,
-                                        IN DAPL_EVD * evd_ptr,
-                                        IN ib_async_handler_t callback,
-                                        IN void *context)
-{
-       ib_hca_transport_t *hca_ptr;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " setup_async_cb: ia %p type %d hdl %p cb %p ctx %p\n",
-                    ia_ptr, type, evd_ptr, callback, context);
-
-       hca_ptr = &ia_ptr->hca_ptr->ib_trans;
-       switch (type) {
-       case DAPL_ASYNC_UNAFILIATED:
-               hca_ptr->async_unafiliated = (ib_async_handler_t) callback;
-               hca_ptr->async_un_ctx = context;
-               break;
-       case DAPL_ASYNC_CQ_ERROR:
-               hca_ptr->async_cq_error = (ib_async_cq_handler_t) callback;
-               break;
-       case DAPL_ASYNC_CQ_COMPLETION:
-               hca_ptr->async_cq = (ib_async_dto_handler_t) callback;
-               break;
-       case DAPL_ASYNC_QP_ERROR:
-               hca_ptr->async_qp_error = (ib_async_qp_handler_t) callback;
-               break;
-       default:
-               break;
-       }
-       return DAT_SUCCESS;
-}
-
-DAT_RETURN dapli_ib_thread_init(void)
-{
-       DAT_RETURN dat_status;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " ib_thread_init(%d)\n", dapl_os_getpid());
-
-       dapl_os_lock(&g_hca_lock);
-       if (g_ib_thread_state != IB_THREAD_INIT) {
-               dapl_os_unlock(&g_hca_lock);
-               return DAT_SUCCESS;
-       }
-
-       /* uCMA events non-blocking */
-       if (dapls_config_cm_channel(g_cm_events)) {
-               dapl_os_unlock(&g_hca_lock);
-               return (dapl_convert_errno(errno, "create_thread ERR: cm_fd"));
-       }
-
-       g_ib_thread_state = IB_THREAD_CREATE;
-       dapl_os_unlock(&g_hca_lock);
-
-       /* create thread to process inbound connect request */
-       dat_status = dapl_os_thread_create(dapli_thread, NULL, &g_ib_thread);
-       if (dat_status != DAT_SUCCESS)
-               return (dapl_convert_errno(errno,
-                                          "create_thread ERR:"
-                                          " check resource limits"));
-
-       /* wait for thread to start */
-       dapl_os_lock(&g_hca_lock);
-       while (g_ib_thread_state != IB_THREAD_RUN) {
-               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                            " ib_thread_init: waiting for ib_thread\n");
-               dapl_os_unlock(&g_hca_lock);
-               dapl_os_sleep_usec(2000);
-               dapl_os_lock(&g_hca_lock);
-       }
-       dapl_os_unlock(&g_hca_lock);
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " ib_thread_init(%d) exit\n", dapl_os_getpid());
-
-       return DAT_SUCCESS;
-}
-
-void dapli_ib_thread_destroy(void)
-{
-       int retries = 10;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " ib_thread_destroy(%d)\n", dapl_os_getpid());
-       /* 
-        * wait for async thread to terminate. 
-        * pthread_join would be the correct method
-        * but some applications have some issues
-        */
-
-       /* destroy ib_thread, wait for termination, if not already */
-       dapl_os_lock(&g_hca_lock);
-       if (g_ib_thread_state != IB_THREAD_RUN)
-               goto bail;
-
-       g_ib_thread_state = IB_THREAD_CANCEL;
-       if (dapls_thread_signal() == -1)
-               dapl_log(DAPL_DBG_TYPE_UTIL,
-                        " destroy: thread wakeup error = %s\n",
-                        strerror(errno));
-       while ((g_ib_thread_state != IB_THREAD_EXIT) && (retries--)) {
-               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                            " ib_thread_destroy: waiting for ib_thread\n");
-               if (dapls_thread_signal() == -1)
-                       dapl_log(DAPL_DBG_TYPE_UTIL,
-                                " destroy: thread wakeup error = %s\n",
-                                strerror(errno));
-               dapl_os_unlock(&g_hca_lock);
-               dapl_os_sleep_usec(2000);
-               dapl_os_lock(&g_hca_lock);
-       }
-
-      bail:
-       dapl_os_unlock(&g_hca_lock);
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " ib_thread_destroy(%d) exit\n", dapl_os_getpid());
-}
-
-void dapli_async_event_cb(struct _ib_hca_transport *hca)
-{
-       struct ibv_async_event event;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " async_event(%p)\n", hca);
-
-       if (hca->destroy)
-               return;
-
-       if (!ibv_get_async_event(hca->cm_id->verbs, &event)) {
-
-               switch (event.event_type) {
-               case IBV_EVENT_CQ_ERR:
-                       {
-                               struct dapl_ep *evd_ptr =
-                                   event.element.cq->cq_context;
-
-                               dapl_log(DAPL_DBG_TYPE_ERR,
-                                        "dapl async_event CQ (%p) ERR %d\n",
-                                        evd_ptr, event.event_type);
-
-                               /* report up if async callback still setup */
-                               if (hca->async_cq_error)
-                                       hca->async_cq_error(hca->cm_id->verbs,
-                                                           event.element.cq,
-                                                           &event,
-                                                           (void *)evd_ptr);
-                               break;
-                       }
-               case IBV_EVENT_COMM_EST:
-                       {
-                               /* Received msgs on connected QP before RTU */
-                               dapl_log(DAPL_DBG_TYPE_UTIL,
-                                        " async_event COMM_EST(%p) rdata beat RTU\n",
-                                        event.element.qp);
-
-                               break;
-                       }
-               case IBV_EVENT_QP_FATAL:
-               case IBV_EVENT_QP_REQ_ERR:
-               case IBV_EVENT_QP_ACCESS_ERR:
-               case IBV_EVENT_QP_LAST_WQE_REACHED:
-               case IBV_EVENT_SRQ_ERR:
-               case IBV_EVENT_SRQ_LIMIT_REACHED:
-               case IBV_EVENT_SQ_DRAINED:
-                       {
-                               struct dapl_ep *ep_ptr =
-                                   event.element.qp->qp_context;
-
-                               dapl_log(DAPL_DBG_TYPE_ERR,
-                                        "dapl async_event QP (%p) ERR %d\n",
-                                        ep_ptr, event.event_type);
-
-                               /* report up if async callback still setup */
-                               if (hca->async_qp_error)
-                                       hca->async_qp_error(hca->cm_id->verbs,
-                                                           ep_ptr->qp_handle,
-                                                           &event,
-                                                           (void *)ep_ptr);
-                               break;
-                       }
-               case IBV_EVENT_PATH_MIG:
-               case IBV_EVENT_PATH_MIG_ERR:
-               case IBV_EVENT_DEVICE_FATAL:
-               case IBV_EVENT_PORT_ACTIVE:
-               case IBV_EVENT_PORT_ERR:
-               case IBV_EVENT_LID_CHANGE:
-               case IBV_EVENT_PKEY_CHANGE:
-               case IBV_EVENT_SM_CHANGE:
-                       {
-                               dapl_log(DAPL_DBG_TYPE_WARN,
-                                        "dapl async_event: DEV ERR %d\n",
-                                        event.event_type);
-
-                               /* report up if async callback still setup */
-                               if (hca->async_unafiliated)
-                                       hca->async_unafiliated(hca->cm_id->
-                                                              verbs, &event,
-                                                              hca->
-                                                              async_un_ctx);
-                               break;
-                       }
-               case IBV_EVENT_CLIENT_REREGISTER:
-                       /* no need to report this event this time */
-                       dapl_log(DAPL_DBG_TYPE_UTIL,
-                                " async_event: IBV_EVENT_CLIENT_REREGISTER\n");
-                       break;
-
-               default:
-                       dapl_log(DAPL_DBG_TYPE_WARN,
-                                "dapl async_event: %d UNKNOWN\n",
-                                event.event_type);
-                       break;
-
-               }
-               ibv_ack_async_event(&event);
-       }
-}
-
-#if defined(_WIN64) || defined(_WIN32)
-/* work thread for uAT, uCM, CQ, and async events */
-void dapli_thread(void *arg)
-{
-       struct _ib_hca_transport *hca;
-       struct _ib_hca_transport *uhca[8];
-       COMP_CHANNEL *channel;
-       int ret, idx, cnt;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " ib_thread(%d,0x%x): ENTER: \n",
-                    dapl_os_getpid(), g_ib_thread);
-
-       dapl_os_lock(&g_hca_lock);
-       for (g_ib_thread_state = IB_THREAD_RUN;
-            g_ib_thread_state == IB_THREAD_RUN; dapl_os_lock(&g_hca_lock)) {
-
-               idx = 0;
-               hca = dapl_llist_is_empty(&g_hca_list) ? NULL :
-                   dapl_llist_peek_head(&g_hca_list);
-
-               while (hca) {
-                       uhca[idx++] = hca;
-                       hca = dapl_llist_next_entry(&g_hca_list,
-                                                   (DAPL_LLIST_ENTRY *) & hca->
-                                                   entry);
-               }
-               cnt = idx;
-
-               dapl_os_unlock(&g_hca_lock);
-               ret = CompManagerPoll(windata.comp_mgr, INFINITE, &channel);
-
-               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                            " ib_thread(%d) poll_event 0x%x\n",
-                            dapl_os_getpid(), ret);
-
-               dapli_cma_event_cb();
-
-               /* check and process CQ and ASYNC events, per device */
-               for (idx = 0; idx < cnt; idx++) {
-                       if (uhca[idx]->destroy == 1) {
-                               dapl_os_lock(&g_hca_lock);
-                               dapl_llist_remove_entry(&g_hca_list,
-                                                       (DAPL_LLIST_ENTRY *) &
-                                                       uhca[idx]->entry);
-                               dapl_os_unlock(&g_hca_lock);
-                               uhca[idx]->destroy = 2;
-                       } else {
-                               dapli_cq_event_cb(uhca[idx]);
-                               dapli_async_event_cb(uhca[idx]);
-                       }
-               }
-       }
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " ib_thread(%d) EXIT\n",
-                    dapl_os_getpid());
-       g_ib_thread_state = IB_THREAD_EXIT;
-       dapl_os_unlock(&g_hca_lock);
-}
-#else                          // _WIN64 || WIN32
-/* work thread for uAT, uCM, CQ, and async events */
-void dapli_thread(void *arg)
-{
-       struct pollfd ufds[__FD_SETSIZE];
-       struct _ib_hca_transport *uhca[__FD_SETSIZE] = { NULL };
-       struct _ib_hca_transport *hca;
-       int ret, idx, fds;
-       char rbuf[2];
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " ib_thread(%d,0x%x): ENTER: pipe %d ucma %d\n",
-                    dapl_os_getpid(), g_ib_thread, g_ib_pipe[0],
-                    g_cm_events->fd);
-
-       /* Poll across pipe, CM, AT never changes */
-       dapl_os_lock(&g_hca_lock);
-       g_ib_thread_state = IB_THREAD_RUN;
-
-       ufds[0].fd = g_ib_pipe[0];      /* pipe */
-       ufds[0].events = POLLIN;
-       ufds[1].fd = g_cm_events->fd;   /* uCMA */
-       ufds[1].events = POLLIN;
-
-       while (g_ib_thread_state == IB_THREAD_RUN) {
-
-               /* build ufds after pipe and uCMA events */
-               ufds[0].revents = 0;
-               ufds[1].revents = 0;
-               idx = 1;
-
-               /*  Walk HCA list and setup async and CQ events */
-               if (!dapl_llist_is_empty(&g_hca_list))
-                       hca = dapl_llist_peek_head(&g_hca_list);
-               else
-                       hca = NULL;
-
-               while (hca) {
-
-                       /* uASYNC events */
-                       ufds[++idx].fd = hca->cm_id->verbs->async_fd;
-                       ufds[idx].events = POLLIN;
-                       ufds[idx].revents = 0;
-                       uhca[idx] = hca;
-
-                       /* uCQ, non-direct events */
-                       ufds[++idx].fd = hca->ib_cq->fd;
-                       ufds[idx].events = POLLIN;
-                       ufds[idx].revents = 0;
-                       uhca[idx] = hca;
-
-                       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                                    " ib_thread(%d) poll_fd: hca[%d]=%p, async=%d"
-                                    " pipe=%d cm=%d cq=d\n",
-                                    dapl_os_getpid(), hca, ufds[idx - 1].fd,
-                                    ufds[0].fd, ufds[1].fd, ufds[idx].fd);
-
-                       hca = dapl_llist_next_entry(&g_hca_list,
-                                                   (DAPL_LLIST_ENTRY *) & hca->
-                                                   entry);
-               }
-
-               /* unlock, and setup poll */
-               fds = idx + 1;
-               dapl_os_unlock(&g_hca_lock);
-               ret = poll(ufds, fds, -1);
-               if (ret <= 0) {
-                       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                                    " ib_thread(%d): ERR %s poll\n",
-                                    dapl_os_getpid(), strerror(errno));
-                       dapl_os_lock(&g_hca_lock);
-                       continue;
-               }
-
-               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                            " ib_thread(%d) poll_event: "
-                            " async=0x%x pipe=0x%x cm=0x%x cq=0x%x\n",
-                            dapl_os_getpid(), ufds[idx - 1].revents,
-                            ufds[0].revents, ufds[1].revents,
-                            ufds[idx].revents);
-
-               /* uCMA events */
-               if (ufds[1].revents == POLLIN)
-                       dapli_cma_event_cb();
-
-               /* check and process CQ and ASYNC events, per device */
-               for (idx = 2; idx < fds; idx++) {
-                       if (ufds[idx].revents == POLLIN) {
-                               dapli_cq_event_cb(uhca[idx]);
-                               dapli_async_event_cb(uhca[idx]);
-                       }
-               }
-
-               /* check and process user events, PIPE */
-               if (ufds[0].revents == POLLIN) {
-                       if (read(g_ib_pipe[0], rbuf, 2) == -1)
-                               dapl_log(DAPL_DBG_TYPE_UTIL,
-                                        " cr_thread: pipe rd err= %s\n",
-                                        strerror(errno));
-
-                       /* cleanup any device on list marked for destroy */
-                       for (idx = 3; idx < fds; idx++) {
-                               if (uhca[idx] && uhca[idx]->destroy == 1) {
-                                       dapl_os_lock(&g_hca_lock);
-                                       dapl_llist_remove_entry(&g_hca_list,
-                                                               (DAPL_LLIST_ENTRY
-                                                                *)
-                                                               & uhca[idx]->
-                                                               entry);
-                                       dapl_os_unlock(&g_hca_lock);
-                                       uhca[idx]->destroy = 2;
-                               }
-                       }
-               }
-               dapl_os_lock(&g_hca_lock);
-       }
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " ib_thread(%d) EXIT\n",
-                    dapl_os_getpid());
-       g_ib_thread_state = IB_THREAD_EXIT;
-       dapl_os_unlock(&g_hca_lock);
-}
-#endif
-
-/*
- * dapls_set_provider_specific_attr
- *
- * Input:
- *     attr_ptr        Pointer provider specific attributes
- *
- * Output:
- *     none
- *
- * Returns:
- *     void
- */
-DAT_NAMED_ATTR ib_attrs[] = {
-#ifdef DAT_EXTENSIONS
-       {
-        "DAT_EXTENSION_INTERFACE", "TRUE"}
-       ,
-       {
-        DAT_IB_ATTR_FETCH_AND_ADD, "TRUE"}
-       ,
-       {
-        DAT_IB_ATTR_CMP_AND_SWAP, "TRUE"}
-       ,
-       {
-        DAT_IB_ATTR_IMMED_DATA, "TRUE"}
-       ,
-#ifdef DAPL_COUNTERS
-       {
-        DAT_ATTR_COUNTERS, "TRUE"}
-       ,
-#endif                         /* DAPL_COUNTERS */
-#endif
-};
-
-#define SPEC_ATTR_SIZE( x )    (sizeof( x ) / sizeof( DAT_NAMED_ATTR))
-
-void dapls_query_provider_specific_attr(IN DAPL_IA * ia_ptr,
-                                       IN DAT_PROVIDER_ATTR * attr_ptr)
-{
-       attr_ptr->num_provider_specific_attr = SPEC_ATTR_SIZE(ib_attrs);
-       attr_ptr->provider_specific_attr = ib_attrs;
-}
+/*\r
+ * Copyright (c) 2005-2008 Intel Corporation.  All rights reserved.\r
+ *\r
+ * This Software is licensed under one of the following licenses:\r
+ *\r
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/cpl.php.\r
+ *\r
+ * 2) under the terms of the "The BSD License" a copy of which is\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/bsd-license.php.\r
+ *\r
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a\r
+ *    copy of which is available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/gpl-license.php.\r
+ *\r
+ * Licensee has the right to choose one of the above licenses.\r
+ *\r
+ * Redistributions of source code must retain the above copyright\r
+ * notice and one of the license notices.\r
+ *\r
+ * Redistributions in binary form must reproduce both the above copyright\r
+ * notice, one of the license notices in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ */\r
+\r
+/**********************************************************************\r
+ * \r
+ * MODULE: dapl_ib_util.c\r
+ *\r
+ * PURPOSE: OFED provider - init, open, close, utilities, work thread\r
+ *\r
+ * $Id:$\r
+ *\r
+ **********************************************************************/\r
+\r
+#ifdef RCSID\r
+static const char rcsid[] = "$Id:  $";\r
+#endif\r
+\r
+#include "openib_osd.h"\r
+#include "dapl.h"\r
+#include "dapl_adapter_util.h"\r
+#include "dapl_ib_util.h"\r
+#include "dapl_osd.h"\r
+\r
+#include <stdlib.h>\r
+\r
+struct rdma_event_channel *g_cm_events = NULL;\r
+ib_thread_state_t g_ib_thread_state = 0;\r
+DAPL_OS_THREAD g_ib_thread;\r
+DAPL_OS_LOCK g_hca_lock;\r
+struct dapl_llist_entry *g_hca_list;\r
+\r
+#if defined(_WIN64) || defined(_WIN32)\r
+#include "..\..\..\..\..\etc\user\comp_channel.cpp"\r
+#include <rdma\winverbs.h>\r
+\r
+struct ibvw_windata windata;\r
+\r
+static int getipaddr_netdev(char *name, char *addr, int addr_len)\r
+{\r
+       IWVProvider *prov;\r
+       WV_DEVICE_ADDRESS devaddr;\r
+       struct addrinfo *res, *ai;\r
+       HRESULT hr;\r
+       int index;\r
+\r
+       if (strncmp(name, "rdma_dev", 8)) {\r
+               return EINVAL;\r
+       }\r
+\r
+       index = atoi(name + 8);\r
+\r
+       hr = WvGetObject(&IID_IWVProvider, (LPVOID *) &prov);\r
+       if (FAILED(hr)) {\r
+               return hr;\r
+       }\r
+\r
+       hr = getaddrinfo("..localmachine", NULL, NULL, &res);\r
+       if (hr) {\r
+               goto release;\r
+       }\r
+\r
+       for (ai = res; ai; ai = ai->ai_next) {\r
+               hr = prov->lpVtbl->TranslateAddress(prov, ai->ai_addr, &devaddr);\r
+               if (SUCCEEDED(hr) && (ai->ai_addrlen <= addr_len) && (index-- == 0)) {\r
+                       memcpy(addr, ai->ai_addr, ai->ai_addrlen);\r
+                       goto free;\r
+               }\r
+       }\r
+       hr = ENODEV;\r
+\r
+free:\r
+       freeaddrinfo(res);\r
+release:\r
+       prov->lpVtbl->Release(prov);\r
+       return hr;\r
+}\r
+\r
+static int dapls_os_init(void)\r
+{\r
+       return ibvw_get_windata(&windata, IBVW_WINDATA_VERSION);\r
+}\r
+\r
+static void dapls_os_release(void)\r
+{\r
+       if (windata.comp_mgr)\r
+               ibvw_release_windata(&windata, IBVW_WINDATA_VERSION);\r
+       windata.comp_mgr = NULL;\r
+}\r
+\r
+static int dapls_config_cm_channel(struct rdma_event_channel *channel)\r
+{\r
+       channel->channel.Milliseconds = 0;\r
+       return 0;\r
+}\r
+\r
+static int dapls_config_verbs(struct ibv_context *verbs)\r
+{\r
+       verbs->channel.Milliseconds = 0;\r
+       return 0;\r
+}\r
+\r
+static int dapls_thread_signal(void)\r
+{\r
+       CompManagerCancel(windata.comp_mgr);\r
+       return 0;\r
+}\r
+#else                          // _WIN64 || WIN32\r
+int g_ib_pipe[2];\r
+\r
+static int dapls_os_init(void)\r
+{\r
+       /* create pipe for waking up work thread */\r
+       return pipe(g_ib_pipe);\r
+}\r
+\r
+static void dapls_os_release(void)\r
+{\r
+       /* close pipe? */\r
+}\r
+\r
+/* Get IP address using network device name */\r
+static int getipaddr_netdev(char *name, char *addr, int addr_len)\r
+{\r
+       struct ifreq ifr;\r
+       int skfd, ret, len;\r
+\r
+       /* Fill in the structure */\r
+       snprintf(ifr.ifr_name, IFNAMSIZ, "%s", name);\r
+       ifr.ifr_hwaddr.sa_family = ARPHRD_INFINIBAND;\r
+\r
+       /* Create a socket fd */\r
+       skfd = socket(PF_INET, SOCK_STREAM, 0);\r
+       ret = ioctl(skfd, SIOCGIFADDR, &ifr);\r
+       if (ret)\r
+               goto bail;\r
+\r
+       switch (ifr.ifr_addr.sa_family) {\r
+#ifdef AF_INET6\r
+       case AF_INET6:\r
+               len = sizeof(struct sockaddr_in6);\r
+               break;\r
+#endif\r
+       case AF_INET:\r
+       default:\r
+               len = sizeof(struct sockaddr);\r
+               break;\r
+       }\r
+\r
+       if (len <= addr_len)\r
+               memcpy(addr, &ifr.ifr_addr, len);\r
+       else\r
+               ret = EINVAL;\r
+\r
+      bail:\r
+       close(skfd);\r
+       return ret;\r
+}\r
+\r
+static int dapls_config_fd(int fd)\r
+{\r
+       int opts;\r
+\r
+       opts = fcntl(fd, F_GETFL);\r
+       if (opts < 0 || fcntl(fd, F_SETFL, opts | O_NONBLOCK) < 0) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " dapls_config_fd: fcntl on fd %d ERR %d %s\n",\r
+                        fd, opts, strerror(errno));\r
+               return errno;\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+static int dapls_config_cm_channel(struct rdma_event_channel *channel)\r
+{\r
+       return dapls_config_fd(channel->fd);\r
+}\r
+\r
+static int dapls_config_verbs(struct ibv_context *verbs)\r
+{\r
+       return dapls_config_fd(verbs->async_fd);\r
+}\r
+\r
+static int dapls_thread_signal(void)\r
+{\r
+       return write(g_ib_pipe[1], "w", sizeof "w");\r
+}\r
+#endif\r
+\r
+/* Get IP address using network name, address, or device name */\r
+static int getipaddr(char *name, char *addr, int len)\r
+{\r
+       struct addrinfo *res;\r
+\r
+       /* assume netdev for first attempt, then network and address type */\r
+       if (getipaddr_netdev(name, addr, len)) {\r
+               if (getaddrinfo(name, NULL, NULL, &res)) {\r
+                       dapl_log(DAPL_DBG_TYPE_ERR,\r
+                                " open_hca: getaddr_netdev ERROR:"\r
+                                " %s. Is %s configured?\n",\r
+                                strerror(errno), name);\r
+                       return 1;\r
+               } else {\r
+                       if (len >= res->ai_addrlen)\r
+                               memcpy(addr, res->ai_addr, res->ai_addrlen);\r
+                       else {\r
+                               freeaddrinfo(res);\r
+                               return 1;\r
+                       }\r
+                       freeaddrinfo(res);\r
+               }\r
+       }\r
+\r
+       dapl_dbg_log(\r
+               DAPL_DBG_TYPE_UTIL,\r
+               " getipaddr: family %d port %d addr %d.%d.%d.%d\n",\r
+               ((struct sockaddr_in *)addr)->sin_family,\r
+               ((struct sockaddr_in *)addr)->sin_port,\r
+               ((struct sockaddr_in *)addr)->sin_addr.s_addr >> 0 & 0xff,\r
+               ((struct sockaddr_in *)addr)->sin_addr.s_addr >> 8 & 0xff,\r
+               ((struct sockaddr_in *)addr)->sin_addr.s_addr >> 16 & 0xff,\r
+               ((struct sockaddr_in *)addr)->sin_addr.\r
+                s_addr >> 24 & 0xff);\r
+\r
+       return 0;\r
+}\r
+\r
+/*\r
+ * dapls_ib_init, dapls_ib_release\r
+ *\r
+ * Initialize Verb related items for device open\r
+ *\r
+ * Input:\r
+ *     none\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     0 success, -1 error\r
+ *\r
+ */\r
+int32_t dapls_ib_init(void)\r
+{\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " dapl_ib_init: \n");\r
+\r
+       /* initialize hca_list lock */\r
+       dapl_os_lock_init(&g_hca_lock);\r
+\r
+       /* initialize hca list for CQ events */\r
+       dapl_llist_init_head(&g_hca_list);\r
+\r
+       if (dapls_os_init())\r
+               return 1;\r
+\r
+       return 0;\r
+}\r
+\r
+int32_t dapls_ib_release(void)\r
+{\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " dapl_ib_release: \n");\r
+       dapli_ib_thread_destroy();\r
+       if (g_cm_events != NULL)\r
+               rdma_destroy_event_channel(g_cm_events);\r
+       dapls_os_release();\r
+       return 0;\r
+}\r
+\r
+/*\r
+ * dapls_ib_open_hca\r
+ *\r
+ * Open HCA\r
+ *\r
+ * Input:\r
+ *      *hca_name         pointer to provider device name\r
+ *      *ib_hca_handle_p  pointer to provide HCA handle\r
+ *\r
+ * Output:\r
+ *      none\r
+ *\r
+ * Return:\r
+ *      DAT_SUCCESS\r
+ *      dapl_convert_errno\r
+ *\r
+ */\r
+DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr)\r
+{\r
+       struct rdma_cm_id *cm_id = NULL;\r
+       union ibv_gid *gid;\r
+       int ret;\r
+       DAT_RETURN dat_status;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " open_hca: %s - %p\n", hca_name, hca_ptr);\r
+\r
+       /* Setup the global cm event channel */\r
+       dapl_os_lock(&g_hca_lock);\r
+       if (g_cm_events == NULL) {\r
+               g_cm_events = rdma_create_event_channel();\r
+               if (g_cm_events == NULL) {\r
+                       dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+                                    " open_hca: ERR - RDMA channel %s\n",\r
+                                    strerror(errno));\r
+                       dapl_os_unlock(&g_hca_lock);\r
+                       return DAT_INTERNAL_ERROR;\r
+               }\r
+       }\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " open_hca: RDMA channel created (%p)\n", g_cm_events);\r
+\r
+       dat_status = dapli_ib_thread_init();\r
+       if (dat_status != DAT_SUCCESS)\r
+               return dat_status;\r
+\r
+       /* HCA name will be hostname or IP address */\r
+       if (getipaddr((char *)hca_name,\r
+                     (char *)&hca_ptr->hca_address, \r
+                     sizeof(DAT_SOCK_ADDR6)))\r
+               return DAT_INVALID_ADDRESS;\r
+\r
+       /* cm_id will bind local device/GID based on IP address */\r
+       if (rdma_create_id(g_cm_events, &cm_id, \r
+                          (void *)hca_ptr, RDMA_PS_TCP)) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " open_hca: rdma_create ERR %s\n", strerror(errno));\r
+               return DAT_INTERNAL_ERROR;\r
+       }\r
+       ret = rdma_bind_addr(cm_id, (struct sockaddr *)&hca_ptr->hca_address);\r
+       if ((ret) || (cm_id->verbs == NULL)) {\r
+               rdma_destroy_id(cm_id);\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " open_hca: rdma_bind ERR %s."\r
+                        " Is %s configured?\n", strerror(errno), hca_name);\r
+               return DAT_INVALID_ADDRESS;\r
+       }\r
+\r
+       /* keep reference to IB device and cm_id */\r
+       hca_ptr->ib_trans.cm_id = cm_id;\r
+       hca_ptr->ib_hca_handle = cm_id->verbs;\r
+       dapls_config_verbs(cm_id->verbs);\r
+       hca_ptr->port_num = cm_id->port_num;\r
+       hca_ptr->ib_trans.ib_dev = cm_id->verbs->device;\r
+       gid = &cm_id->route.addr.addr.ibaddr.sgid;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " open_hca: ctx=%p port=%d GID subnet %016llx"\r
+                    " id %016llx\n", cm_id->verbs, cm_id->port_num,\r
+                    (unsigned long long)ntohll(gid->global.subnet_prefix),\r
+                    (unsigned long long)ntohll(gid->global.interface_id));\r
+\r
+       /* set inline max with env or default, get local lid and gid 0 */\r
+       if (hca_ptr->ib_hca_handle->device->transport_type\r
+           == IBV_TRANSPORT_IWARP)\r
+               hca_ptr->ib_trans.max_inline_send =\r
+                   dapl_os_get_env_val("DAPL_MAX_INLINE",\r
+                                       INLINE_SEND_IWARP_DEFAULT);\r
+       else\r
+               hca_ptr->ib_trans.max_inline_send =\r
+                   dapl_os_get_env_val("DAPL_MAX_INLINE",\r
+                                       INLINE_SEND_IB_DEFAULT);\r
+\r
+       /* set CM timer defaults */\r
+       hca_ptr->ib_trans.max_cm_timeout =\r
+           dapl_os_get_env_val("DAPL_MAX_CM_RESPONSE_TIME",\r
+                               IB_CM_RESPONSE_TIMEOUT);\r
+       hca_ptr->ib_trans.max_cm_retries =\r
+           dapl_os_get_env_val("DAPL_MAX_CM_RETRIES", IB_CM_RETRIES);\r
+       \r
+       /* set default IB MTU */\r
+       hca_ptr->ib_trans.mtu = dapl_ib_mtu(2048);\r
+\r
+       /* \r
+        * Put new hca_transport on list for async and CQ event processing \r
+        * Wakeup work thread to add to polling list\r
+        */\r
+       dapl_llist_init_entry((DAPL_LLIST_ENTRY *) & hca_ptr->ib_trans.entry);\r
+       dapl_os_lock(&g_hca_lock);\r
+       dapl_llist_add_tail(&g_hca_list,\r
+                           (DAPL_LLIST_ENTRY *) & hca_ptr->ib_trans.entry,\r
+                           &hca_ptr->ib_trans.entry);\r
+       if (dapls_thread_signal() == -1)\r
+               dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                        " open_hca: thread wakeup error = %s\n",\r
+                        strerror(errno));\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " open_hca: %s, %s %d.%d.%d.%d INLINE_MAX=%d\n", hca_name,\r
+                    ((struct sockaddr_in *)\r
+                    &hca_ptr->hca_address)->sin_family == AF_INET ?\r
+                    "AF_INET" : "AF_INET6", \r
+                    ((struct sockaddr_in *)\r
+                    &hca_ptr->hca_address)->sin_addr.s_addr >> 0 & 0xff, \r
+                    ((struct sockaddr_in *)\r
+                    &hca_ptr->hca_address)->sin_addr.s_addr >> 8 & 0xff, \r
+                    ((struct sockaddr_in *)\r
+                    &hca_ptr->hca_address)->sin_addr.s_addr >> 16 & 0xff, \r
+                    ((struct sockaddr_in *)\r
+                    &hca_ptr->hca_address)->sin_addr.s_addr >> 24 & 0xff, \r
+                    hca_ptr->ib_trans.max_inline_send);\r
+\r
+       hca_ptr->ib_trans.d_hca = hca_ptr;\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * dapls_ib_close_hca\r
+ *\r
+ * Open HCA\r
+ *\r
+ * Input:\r
+ *      DAPL_HCA   provide CA handle\r
+ *\r
+ * Output:\r
+ *      none\r
+ *\r
+ * Return:\r
+ *      DAT_SUCCESS\r
+ *     dapl_convert_errno \r
+ *\r
+ */\r
+DAT_RETURN dapls_ib_close_hca(IN DAPL_HCA * hca_ptr)\r
+{\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " close_hca: %p->%p\n",\r
+                    hca_ptr, hca_ptr->ib_hca_handle);\r
+\r
+       if (hca_ptr->ib_hca_handle != IB_INVALID_HANDLE) {\r
+               if (rdma_destroy_id(hca_ptr->ib_trans.cm_id))\r
+                       return (dapl_convert_errno(errno, "ib_close_device"));\r
+               hca_ptr->ib_hca_handle = IB_INVALID_HANDLE;\r
+       }\r
+\r
+       dapl_os_lock(&g_hca_lock);\r
+       if (g_ib_thread_state != IB_THREAD_RUN) {\r
+               dapl_os_unlock(&g_hca_lock);\r
+               goto bail;\r
+       }\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
+       /* \r
+        * Remove hca from async event processing list\r
+        * Wakeup work thread to remove from polling list\r
+        */\r
+       hca_ptr->ib_trans.destroy = 1;\r
+       if (dapls_thread_signal() == -1)\r
+               dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                        " destroy: thread wakeup error = %s\n",\r
+                        strerror(errno));\r
+\r
+       /* wait for thread to remove HCA references */\r
+       while (hca_ptr->ib_trans.destroy != 2) {\r
+               if (dapls_thread_signal() == -1)\r
+                       dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                                " destroy: thread wakeup error = %s\n",\r
+                                strerror(errno));\r
+               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                            " ib_thread_destroy: wait on hca %p destroy\n");\r
+               dapl_os_sleep_usec(1000);\r
+       }\r
+bail:\r
+       return (DAT_SUCCESS);\r
+}\r
+\r
+\r
+DAT_RETURN dapli_ib_thread_init(void)\r
+{\r
+       DAT_RETURN dat_status;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " ib_thread_init(%d)\n", dapl_os_getpid());\r
+\r
+       dapl_os_lock(&g_hca_lock);\r
+       if (g_ib_thread_state != IB_THREAD_INIT) {\r
+               dapl_os_unlock(&g_hca_lock);\r
+               return DAT_SUCCESS;\r
+       }\r
+\r
+       /* uCMA events non-blocking */\r
+       if (dapls_config_cm_channel(g_cm_events)) {\r
+               dapl_os_unlock(&g_hca_lock);\r
+               return (dapl_convert_errno(errno, "create_thread ERR: cm_fd"));\r
+       }\r
+\r
+       g_ib_thread_state = IB_THREAD_CREATE;\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
+       /* create thread to process inbound connect request */\r
+       dat_status = dapl_os_thread_create(dapli_thread, NULL, &g_ib_thread);\r
+       if (dat_status != DAT_SUCCESS)\r
+               return (dapl_convert_errno(errno,\r
+                                          "create_thread ERR:"\r
+                                          " check resource limits"));\r
+\r
+       /* wait for thread to start */\r
+       dapl_os_lock(&g_hca_lock);\r
+       while (g_ib_thread_state != IB_THREAD_RUN) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                            " ib_thread_init: waiting for ib_thread\n");\r
+               dapl_os_unlock(&g_hca_lock);\r
+               dapl_os_sleep_usec(1000);\r
+               dapl_os_lock(&g_hca_lock);\r
+       }\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " ib_thread_init(%d) exit\n", dapl_os_getpid());\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+void dapli_ib_thread_destroy(void)\r
+{\r
+       int retries = 10;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " ib_thread_destroy(%d)\n", dapl_os_getpid());\r
+       /* \r
+        * wait for async thread to terminate. \r
+        * pthread_join would be the correct method\r
+        * but some applications have some issues\r
+        */\r
+\r
+       /* destroy ib_thread, wait for termination, if not already */\r
+       dapl_os_lock(&g_hca_lock);\r
+       if (g_ib_thread_state != IB_THREAD_RUN)\r
+               goto bail;\r
+\r
+       g_ib_thread_state = IB_THREAD_CANCEL;\r
+       if (dapls_thread_signal() == -1)\r
+               dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                        " destroy: thread wakeup error = %s\n",\r
+                        strerror(errno));\r
+       while ((g_ib_thread_state != IB_THREAD_EXIT) && (retries--)) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                            " ib_thread_destroy: waiting for ib_thread\n");\r
+               if (dapls_thread_signal() == -1)\r
+                       dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                                " destroy: thread wakeup error = %s\n",\r
+                                strerror(errno));\r
+               dapl_os_unlock(&g_hca_lock);\r
+               dapl_os_sleep_usec(2000);\r
+               dapl_os_lock(&g_hca_lock);\r
+       }\r
+bail:\r
+       dapl_os_unlock(&g_hca_lock);\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " ib_thread_destroy(%d) exit\n", dapl_os_getpid());\r
+}\r
+\r
+void dapli_async_event_cb(struct _ib_hca_transport *hca)\r
+{\r
+       struct ibv_async_event event;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " async_event(%p)\n", hca);\r
+\r
+       if (hca->destroy)\r
+               return;\r
+\r
+       if (!ibv_get_async_event(hca->cm_id->verbs, &event)) {\r
+\r
+               switch (event.event_type) {\r
+               case IBV_EVENT_CQ_ERR:\r
+               {\r
+                       struct dapl_ep *evd_ptr =\r
+                               event.element.cq->cq_context;\r
+\r
+                       dapl_log(DAPL_DBG_TYPE_ERR,\r
+                                "dapl async_event CQ (%p) ERR %d\n",\r
+                                evd_ptr, event.event_type);\r
+\r
+                       /* report up if async callback still setup */\r
+                       if (hca->async_cq_error)\r
+                               hca->async_cq_error(hca->cm_id->verbs,\r
+                                                       event.element.cq,\r
+                                                       &event,\r
+                                                       (void *)evd_ptr);\r
+                       break;\r
+               }\r
+               case IBV_EVENT_COMM_EST:\r
+               {\r
+                       /* Received msgs on connected QP before RTU */\r
+                       dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                                " async_event COMM_EST(%p) rdata beat RTU\n",\r
+                                event.element.qp);\r
+\r
+                       break;\r
+               }\r
+               case IBV_EVENT_QP_FATAL:\r
+               case IBV_EVENT_QP_REQ_ERR:\r
+               case IBV_EVENT_QP_ACCESS_ERR:\r
+               case IBV_EVENT_QP_LAST_WQE_REACHED:\r
+               case IBV_EVENT_SRQ_ERR:\r
+               case IBV_EVENT_SRQ_LIMIT_REACHED:\r
+               case IBV_EVENT_SQ_DRAINED:\r
+               {\r
+                       struct dapl_ep *ep_ptr =\r
+                               event.element.qp->qp_context;\r
+\r
+                       dapl_log(DAPL_DBG_TYPE_ERR,\r
+                                "dapl async_event QP (%p) ERR %d\n",\r
+                                ep_ptr, event.event_type);\r
+\r
+                       /* report up if async callback still setup */\r
+                       if (hca->async_qp_error)\r
+                               hca->async_qp_error(hca->cm_id->verbs,\r
+                                                   ep_ptr->qp_handle,\r
+                                                   &event,\r
+                                                   (void *)ep_ptr);\r
+                       break;\r
+               }\r
+               case IBV_EVENT_PATH_MIG:\r
+               case IBV_EVENT_PATH_MIG_ERR:\r
+               case IBV_EVENT_DEVICE_FATAL:\r
+               case IBV_EVENT_PORT_ACTIVE:\r
+               case IBV_EVENT_PORT_ERR:\r
+               case IBV_EVENT_LID_CHANGE:\r
+               case IBV_EVENT_PKEY_CHANGE:\r
+               case IBV_EVENT_SM_CHANGE:\r
+               {\r
+                       dapl_log(DAPL_DBG_TYPE_WARN,\r
+                                "dapl async_event: DEV ERR %d\n",\r
+                                event.event_type);\r
+\r
+                       /* report up if async callback still setup */\r
+                       if (hca->async_unafiliated)\r
+                               hca->async_unafiliated(hca->cm_id->\r
+                                                       verbs, &event,\r
+                                                       hca->\r
+                                                       async_un_ctx);\r
+                       break;\r
+               }\r
+               case IBV_EVENT_CLIENT_REREGISTER:\r
+                       /* no need to report this event this time */\r
+                       dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                                " async_event: IBV_CLIENT_REREGISTER\n");\r
+                       break;\r
+\r
+               default:\r
+                       dapl_log(DAPL_DBG_TYPE_WARN,\r
+                                "dapl async_event: %d UNKNOWN\n",\r
+                                event.event_type);\r
+                       break;\r
+\r
+               }\r
+               ibv_ack_async_event(&event);\r
+       }\r
+}\r
+\r
+#if defined(_WIN64) || defined(_WIN32)\r
+/* work thread for uAT, uCM, CQ, and async events */\r
+void dapli_thread(void *arg)\r
+{\r
+       struct _ib_hca_transport *hca;\r
+       struct _ib_hca_transport *uhca[8];\r
+       COMP_CHANNEL *channel;\r
+       int ret, idx, cnt;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " ib_thread(%d,0x%x): ENTER: \n",\r
+                    dapl_os_getpid(), g_ib_thread);\r
+\r
+       dapl_os_lock(&g_hca_lock);\r
+       for (g_ib_thread_state = IB_THREAD_RUN;\r
+            g_ib_thread_state == IB_THREAD_RUN; \r
+            dapl_os_lock(&g_hca_lock)) {\r
+\r
+               idx = 0;\r
+               hca = dapl_llist_is_empty(&g_hca_list) ? NULL :\r
+                     dapl_llist_peek_head(&g_hca_list);\r
+\r
+               while (hca) {\r
+                       uhca[idx++] = hca;\r
+                       hca = dapl_llist_next_entry(&g_hca_list,\r
+                                                   (DAPL_LLIST_ENTRY *)\r
+                                                   &hca->entry);\r
+               }\r
+               cnt = idx;\r
+\r
+               dapl_os_unlock(&g_hca_lock);\r
+               ret = CompManagerPoll(windata.comp_mgr, INFINITE, &channel);\r
+\r
+               dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                            " ib_thread(%d) poll_event 0x%x\n",\r
+                            dapl_os_getpid(), ret);\r
+\r
+               dapli_cma_event_cb();\r
+\r
+               /* check and process ASYNC events, per device */\r
+               for (idx = 0; idx < cnt; idx++) {\r
+                       if (uhca[idx]->destroy == 1) {\r
+                               dapl_os_lock(&g_hca_lock);\r
+                               dapl_llist_remove_entry(&g_hca_list,\r
+                                                       (DAPL_LLIST_ENTRY *)\r
+                                                       &uhca[idx]->entry);\r
+                               dapl_os_unlock(&g_hca_lock);\r
+                               uhca[idx]->destroy = 2;\r
+                       } else {\r
+                               dapli_async_event_cb(uhca[idx]);\r
+                       }\r
+               }\r
+       }\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " ib_thread(%d) EXIT\n",\r
+                    dapl_os_getpid());\r
+       g_ib_thread_state = IB_THREAD_EXIT;\r
+       dapl_os_unlock(&g_hca_lock);\r
+}\r
+#else                          // _WIN64 || WIN32\r
+/* work thread for uAT, uCM, CQ, and async events */\r
+void dapli_thread(void *arg)\r
+{\r
+       struct pollfd ufds[__FD_SETSIZE];\r
+       struct _ib_hca_transport *uhca[__FD_SETSIZE] = { NULL };\r
+       struct _ib_hca_transport *hca;\r
+       int ret, idx, fds;\r
+       char rbuf[2];\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_THREAD,\r
+                    " ib_thread(%d,0x%x): ENTER: pipe %d ucma %d\n",\r
+                    dapl_os_getpid(), g_ib_thread, g_ib_pipe[0],\r
+                    g_cm_events->fd);\r
+\r
+       /* Poll across pipe, CM, AT never changes */\r
+       dapl_os_lock(&g_hca_lock);\r
+       g_ib_thread_state = IB_THREAD_RUN;\r
+\r
+       ufds[0].fd = g_ib_pipe[0];      /* pipe */\r
+       ufds[0].events = POLLIN;\r
+       ufds[1].fd = g_cm_events->fd;   /* uCMA */\r
+       ufds[1].events = POLLIN;\r
+\r
+       while (g_ib_thread_state == IB_THREAD_RUN) {\r
+\r
+               /* build ufds after pipe and uCMA events */\r
+               ufds[0].revents = 0;\r
+               ufds[1].revents = 0;\r
+               idx = 1;\r
+\r
+               /*  Walk HCA list and setup async and CQ events */\r
+               if (!dapl_llist_is_empty(&g_hca_list))\r
+                       hca = dapl_llist_peek_head(&g_hca_list);\r
+               else\r
+                       hca = NULL;\r
+\r
+               while (hca) {\r
+\r
+                       /* uASYNC events */\r
+                       ufds[++idx].fd = hca->cm_id->verbs->async_fd;\r
+                       ufds[idx].events = POLLIN;\r
+                       ufds[idx].revents = 0;\r
+                       uhca[idx] = hca;\r
+\r
+                       dapl_dbg_log(DAPL_DBG_TYPE_THREAD,\r
+                                    " ib_thread(%d) poll_fd: hca[%d]=%p,"\r
+                                    " async=%d pipe=%d cm=%d \n",\r
+                                    dapl_os_getpid(), hca, ufds[idx - 1].fd,\r
+                                    ufds[0].fd, ufds[1].fd);\r
+\r
+                       hca = dapl_llist_next_entry(&g_hca_list,\r
+                                                   (DAPL_LLIST_ENTRY *)\r
+                                                   &hca->entry);\r
+               }\r
+\r
+               /* unlock, and setup poll */\r
+               fds = idx + 1;\r
+               dapl_os_unlock(&g_hca_lock);\r
+               ret = poll(ufds, fds, -1);\r
+               if (ret <= 0) {\r
+                       dapl_dbg_log(DAPL_DBG_TYPE_THREAD,\r
+                                    " ib_thread(%d): ERR %s poll\n",\r
+                                    dapl_os_getpid(), strerror(errno));\r
+                       dapl_os_lock(&g_hca_lock);\r
+                       continue;\r
+               }\r
+\r
+               dapl_dbg_log(DAPL_DBG_TYPE_THREAD,\r
+                            " ib_thread(%d) poll_event: "\r
+                            " async=0x%x pipe=0x%x cm=0x%x \n",\r
+                            dapl_os_getpid(), ufds[idx].revents,\r
+                            ufds[0].revents, ufds[1].revents);\r
+\r
+               /* uCMA events */\r
+               if (ufds[1].revents == POLLIN)\r
+                       dapli_cma_event_cb();\r
+\r
+               /* check and process ASYNC events, per device */\r
+               for (idx = 2; idx < fds; idx++) {\r
+                       if (ufds[idx].revents == POLLIN) {\r
+                               dapli_async_event_cb(uhca[idx]);\r
+                       }\r
+               }\r
+\r
+               /* check and process user events, PIPE */\r
+               if (ufds[0].revents == POLLIN) {\r
+                       if (read(g_ib_pipe[0], rbuf, 2) == -1)\r
+                               dapl_log(DAPL_DBG_TYPE_THREAD,\r
+                                        " cr_thread: pipe rd err= %s\n",\r
+                                        strerror(errno));\r
+\r
+                       /* cleanup any device on list marked for destroy */\r
+                       for (idx = 2; idx < fds; idx++) {\r
+                               if (uhca[idx] && uhca[idx]->destroy == 1) {\r
+                                       dapl_os_lock(&g_hca_lock);\r
+                                       dapl_llist_remove_entry(\r
+                                               &g_hca_list,\r
+                                               (DAPL_LLIST_ENTRY*)\r
+                                               &uhca[idx]->entry);\r
+                                       dapl_os_unlock(&g_hca_lock);\r
+                                       uhca[idx]->destroy = 2;\r
+                               }\r
+                       }\r
+               }\r
+               dapl_os_lock(&g_hca_lock);\r
+       }\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_THREAD, " ib_thread(%d) EXIT\n",\r
+                    dapl_os_getpid());\r
+       g_ib_thread_state = IB_THREAD_EXIT;\r
+       dapl_os_unlock(&g_hca_lock);\r
+}\r
+#endif\r
diff --git a/ulp/dapl2/dapl/openib_common.c b/ulp/dapl2/dapl/openib_common.c
new file mode 100644 (file)
index 0000000..336eff9
--- /dev/null
@@ -0,0 +1,6 @@
+\r
+#include "openib_common\mem.c"\r
+#include "openib_common\util.c"\r
+#include "openib_common\cq.c"\r
+#include "openib_common\qp.c"\r
+#include "openib_common\ib_extensions.c"\r
similarity index 65%
rename from ulp/dapl2/dapl/openib_cma/dapl_ib_cq.c
rename to ulp/dapl2/dapl/openib_common/cq.c
index 7f67982..aedfd71 100644 (file)
-/*
- * Copyright (c) 2005-2007 Intel Corporation.  All rights reserved.
- *
- * This Software is licensed under one of the following licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- *
- * 2) under the terms of the "The BSD License" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- *
- * Licensee has the right to choose one of the above licenses.
- *
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/**********************************************************************
- *
- * MODULE: dapl_ib_cq.c
- *
- * PURPOSE: completion queues for OFED IB Verbs
- *
- * $Id: $
- *
- **********************************************************************/
-
-#include "openib_osd.h"
-#include "dapl.h"
-#include "dapl_adapter_util.h"
-#include "dapl_lmr_util.h"
-#include "dapl_evd_util.h"
-#include "dapl_ring_buffer_util.h"
-
-/* One CQ event channel per HCA */
-void dapli_cq_event_cb(struct _ib_hca_transport *hca)
-{
-       /* check all comp events on this device */
-       struct dapl_evd *evd_ptr = NULL;
-       struct ibv_cq *ibv_cq = NULL;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " dapli_cq_event_cb(%p)\n", hca);
-
-       if (!ibv_get_cq_event(hca->ib_cq, &ibv_cq, (void *)&evd_ptr)) {
-
-               if (DAPL_BAD_HANDLE(evd_ptr, DAPL_MAGIC_EVD)) {
-                       ibv_ack_cq_events(ibv_cq, 1);
-                       return;
-               }
-
-               /* process DTO event via callback */
-               dapl_evd_dto_callback(hca->cm_id->verbs,
-                                     evd_ptr->ib_cq_handle, (void *)evd_ptr);
-
-               ibv_ack_cq_events(ibv_cq, 1);
-       }
-}
-
-/*
- * Map all verbs DTO completion codes to the DAT equivelent.
- *
- * Not returned by verbs:     DAT_DTO_ERR_PARTIAL_PACKET
- */
-static struct ib_status_map {
-       int ib_status;
-       DAT_DTO_COMPLETION_STATUS dat_status;
-} ib_status_map[] = {
-/* 00 */  {
-       IBV_WC_SUCCESS, DAT_DTO_SUCCESS},
-/* 01 */  {
-       IBV_WC_LOC_LEN_ERR, DAT_DTO_ERR_LOCAL_LENGTH},
-/* 02 */  {
-       IBV_WC_LOC_QP_OP_ERR, DAT_DTO_ERR_LOCAL_EP},
-/* 03 */  {
-       IBV_WC_LOC_EEC_OP_ERR, DAT_DTO_ERR_TRANSPORT},
-/* 04 */  {
-       IBV_WC_LOC_PROT_ERR, DAT_DTO_ERR_LOCAL_PROTECTION},
-/* 05 */  {
-       IBV_WC_WR_FLUSH_ERR, DAT_DTO_ERR_FLUSHED},
-/* 06 */  {
-       IBV_WC_MW_BIND_ERR, DAT_RMR_OPERATION_FAILED},
-/* 07 */  {
-       IBV_WC_BAD_RESP_ERR, DAT_DTO_ERR_BAD_RESPONSE},
-/* 08 */  {
-       IBV_WC_LOC_ACCESS_ERR, DAT_DTO_ERR_LOCAL_PROTECTION},
-/* 09 */  {
-       IBV_WC_REM_INV_REQ_ERR, DAT_DTO_ERR_REMOTE_RESPONDER},
-/* 10 */  {
-       IBV_WC_REM_ACCESS_ERR, DAT_DTO_ERR_REMOTE_ACCESS},
-/* 11 */  {
-       IBV_WC_REM_OP_ERR, DAT_DTO_ERR_REMOTE_RESPONDER},
-/* 12 */  {
-       IBV_WC_RETRY_EXC_ERR, DAT_DTO_ERR_TRANSPORT},
-/* 13 */  {
-       IBV_WC_RNR_RETRY_EXC_ERR, DAT_DTO_ERR_RECEIVER_NOT_READY},
-/* 14 */  {
-       IBV_WC_LOC_RDD_VIOL_ERR, DAT_DTO_ERR_LOCAL_PROTECTION},
-/* 15 */  {
-       IBV_WC_REM_INV_RD_REQ_ERR, DAT_DTO_ERR_REMOTE_RESPONDER},
-/* 16 */  {
-       IBV_WC_REM_ABORT_ERR, DAT_DTO_ERR_REMOTE_RESPONDER},
-/* 17 */  {
-       IBV_WC_INV_EECN_ERR, DAT_DTO_ERR_TRANSPORT},
-/* 18 */  {
-       IBV_WC_INV_EEC_STATE_ERR, DAT_DTO_ERR_TRANSPORT},
-/* 19 */  {
-       IBV_WC_FATAL_ERR, DAT_DTO_ERR_TRANSPORT},
-/* 20 */  {
-       IBV_WC_RESP_TIMEOUT_ERR, DAT_DTO_ERR_RECEIVER_NOT_READY},
-/* 21 */  {
-IBV_WC_GENERAL_ERR, DAT_DTO_ERR_TRANSPORT},};
-
-/*
- * dapls_ib_get_dto_status
- *
- * Return the DAT status of a DTO operation
- *
- * Input:
- *     cqe_ptr         pointer to completion queue entry
- *
- * Output:
- *     none
- *
- * Returns:
- *     Value from ib_status_map table above
- */
-
-DAT_DTO_COMPLETION_STATUS
-dapls_ib_get_dto_status(IN ib_work_completion_t * cqe_ptr)
-{
-       uint32_t ib_status;
-       int i;
-
-       ib_status = DAPL_GET_CQE_STATUS(cqe_ptr);
-
-       /*
-        * Due to the implementation of verbs completion code, we need to
-        * search the table for the correct value rather than assuming
-        * linear distribution.
-        */
-       for (i = 0; i <= IBV_WC_GENERAL_ERR; i++) {
-               if (ib_status == ib_status_map[i].ib_status) {
-                       if (ib_status != IBV_WC_SUCCESS) {
-                               dapl_dbg_log(DAPL_DBG_TYPE_DTO_COMP_ERR,
-                                            " DTO completion ERROR: %d: op %#x\n",
-                                            ib_status,
-                                            DAPL_GET_CQE_OPTYPE(cqe_ptr));
-                       }
-                       return ib_status_map[i].dat_status;
-               }
-       }
-
-       dapl_dbg_log(DAPL_DBG_TYPE_DTO_COMP_ERR,
-                    " DTO completion ERROR: %d: op %#x\n",
-                    ib_status, DAPL_GET_CQE_OPTYPE(cqe_ptr));
-
-       return DAT_DTO_FAILURE;
-}
-
-DAT_RETURN dapls_ib_get_async_event(IN ib_error_record_t * err_record,
-                                   OUT DAT_EVENT_NUMBER * async_event)
-{
-       DAT_RETURN dat_status = DAT_SUCCESS;
-       int err_code = err_record->event_type;
-
-       switch (err_code) {
-               /* OVERFLOW error */
-       case IBV_EVENT_CQ_ERR:
-               *async_event = DAT_ASYNC_ERROR_EVD_OVERFLOW;
-               break;
-               /* INTERNAL errors */
-       case IBV_EVENT_DEVICE_FATAL:
-               *async_event = DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR;
-               break;
-               /* CATASTROPHIC errors */
-       case IBV_EVENT_PORT_ERR:
-               *async_event = DAT_ASYNC_ERROR_IA_CATASTROPHIC;
-               break;
-               /* BROKEN QP error */
-       case IBV_EVENT_SQ_DRAINED:
-       case IBV_EVENT_QP_FATAL:
-       case IBV_EVENT_QP_REQ_ERR:
-       case IBV_EVENT_QP_ACCESS_ERR:
-               *async_event = DAT_ASYNC_ERROR_EP_BROKEN;
-               break;
-               /* connection completion */
-       case IBV_EVENT_COMM_EST:
-               *async_event = DAT_CONNECTION_EVENT_ESTABLISHED;
-               break;
-               /* TODO: process HW state changes */
-       case IBV_EVENT_PATH_MIG:
-       case IBV_EVENT_PATH_MIG_ERR:
-       case IBV_EVENT_PORT_ACTIVE:
-       case IBV_EVENT_LID_CHANGE:
-       case IBV_EVENT_PKEY_CHANGE:
-       case IBV_EVENT_SM_CHANGE:
-       default:
-               dat_status = DAT_ERROR(DAT_NOT_IMPLEMENTED, 0);
-       }
-       return dat_status;
-}
-
-/*
- * dapl_ib_cq_alloc
- *
- * Alloc a CQ
- *
- * Input:
- *     ia_handle               IA handle
- *     evd_ptr                 pointer to EVD struct
- *     cqlen                   minimum QLen
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INSUFFICIENT_RESOURCES
- *
- */
-DAT_RETURN
-dapls_ib_cq_alloc(IN DAPL_IA * ia_ptr,
-                 IN DAPL_EVD * evd_ptr, IN DAT_COUNT * cqlen)
-{
-       struct ibv_comp_channel *channel = ia_ptr->hca_ptr->ib_trans.ib_cq;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    "dapls_ib_cq_alloc: evd %p cqlen=%d \n", evd_ptr, *cqlen);
-
-#ifdef CQ_WAIT_OBJECT
-       if (evd_ptr->cq_wait_obj_handle)
-               channel = evd_ptr->cq_wait_obj_handle->events;
-#endif
-
-       /* Call IB verbs to create CQ */
-       evd_ptr->ib_cq_handle = ibv_create_cq(ia_ptr->hca_ptr->ib_hca_handle,
-                                             *cqlen, evd_ptr, channel, 0);
-
-       if (evd_ptr->ib_cq_handle == IB_INVALID_HANDLE)
-               return (dapl_convert_errno(errno, "create_cq"));
-
-       /* arm cq for events */
-       dapls_set_cq_notify(ia_ptr, evd_ptr);
-
-       /* update with returned cq entry size */
-       *cqlen = evd_ptr->ib_cq_handle->cqe;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    "dapls_ib_cq_alloc: new_cq %p cqlen=%d \n",
-                    evd_ptr->ib_cq_handle, *cqlen);
-
-       return DAT_SUCCESS;
-}
-
-/*
- * dapl_ib_cq_resize
- *
- * Alloc a CQ
- *
- * Input:
- *     ia_handle               IA handle
- *     evd_ptr                 pointer to EVD struct
- *     cqlen                   minimum QLen
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INVALID_PARAMETER
- *
- */
-DAT_RETURN
-dapls_ib_cq_resize(IN DAPL_IA * ia_ptr,
-                  IN DAPL_EVD * evd_ptr, IN DAT_COUNT * cqlen)
-{
-       ib_cq_handle_t new_cq;
-       struct ibv_comp_channel *channel = ia_ptr->hca_ptr->ib_trans.ib_cq;
-
-       /* IB verbs doe not support resize. Try to re-create CQ
-        * with new size. Can only be done if QP is not attached. 
-        * destroy EBUSY == QP still attached.
-        */
-
-#ifdef CQ_WAIT_OBJECT
-       if (evd_ptr->cq_wait_obj_handle)
-               channel = evd_ptr->cq_wait_obj_handle->events;
-#endif
-
-       /* Call IB verbs to create CQ */
-       new_cq = ibv_create_cq(ia_ptr->hca_ptr->ib_hca_handle, *cqlen,
-                              evd_ptr, channel, 0);
-
-       if (new_cq == IB_INVALID_HANDLE)
-               return DAT_INSUFFICIENT_RESOURCES;
-
-       /* destroy the original and replace if successful */
-       if (ibv_destroy_cq(evd_ptr->ib_cq_handle)) {
-               ibv_destroy_cq(new_cq);
-               return (dapl_convert_errno(errno, "resize_cq"));
-       }
-
-       /* update EVD with new cq handle and size */
-       evd_ptr->ib_cq_handle = new_cq;
-       *cqlen = new_cq->cqe;
-
-       /* arm cq for events */
-       dapls_set_cq_notify(ia_ptr, evd_ptr);
-
-       return DAT_SUCCESS;
-}
-
-/*
- * dapls_ib_cq_free
- *
- * destroy a CQ
- *
- * Input:
- *     ia_handle               IA handle
- *     evd_ptr                 pointer to EVD struct
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     DAT_INVALID_PARAMETER
- *
- */
-DAT_RETURN dapls_ib_cq_free(IN DAPL_IA * ia_ptr, IN DAPL_EVD * evd_ptr)
-{
-       if (evd_ptr->ib_cq_handle != IB_INVALID_HANDLE) {
-               /* copy all entries on CQ to EVD before destroying */
-               dapls_evd_copy_cq(evd_ptr);
-               if (ibv_destroy_cq(evd_ptr->ib_cq_handle))
-                       return (dapl_convert_errno(errno, "destroy_cq"));
-               evd_ptr->ib_cq_handle = IB_INVALID_HANDLE;
-       }
-       return DAT_SUCCESS;
-}
-
-/*
- * dapls_set_cq_notify
- *
- * Set the CQ notification for next
- *
- * Input:
- *     hca_handl               hca handle
- *     DAPL_EVD                evd handle
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     dapl_convert_errno 
- */
-DAT_RETURN dapls_set_cq_notify(IN DAPL_IA * ia_ptr, IN DAPL_EVD * evd_ptr)
-{
-       if (ibv_req_notify_cq(evd_ptr->ib_cq_handle, 0))
-               return (dapl_convert_errno(errno, "notify_cq"));
-       else
-               return DAT_SUCCESS;
-}
-
-/*
- * dapls_ib_completion_notify
- *
- * Set the CQ notification type
- *
- * Input:
- *     hca_handl               hca handle
- *     evd_ptr                 evd handle
- *     type                    notification type
- *
- * Output:
- *     none
- *
- * Returns:
- *     DAT_SUCCESS
- *     dapl_convert_errno
- */
-DAT_RETURN dapls_ib_completion_notify(IN ib_hca_handle_t hca_handle,
-                                     IN DAPL_EVD * evd_ptr,
-                                     IN ib_notification_type_t type)
-{
-       if (ibv_req_notify_cq(evd_ptr->ib_cq_handle, type))
-               return (dapl_convert_errno(errno, "notify_cq_type"));
-       else
-               return DAT_SUCCESS;
-}
-
-/*
- * dapls_ib_completion_poll
- *
- * CQ poll for completions
- *
- * Input:
- *     hca_handl               hca handle
- *     evd_ptr                 evd handle
- *     wc_ptr                  work completion
- *
- * Output:
- *     none
- *
- * Returns: 
- *     DAT_SUCCESS
- *     DAT_QUEUE_EMPTY
- *     
- */
-DAT_RETURN dapls_ib_completion_poll(IN DAPL_HCA * hca_ptr,
-                                   IN DAPL_EVD * evd_ptr,
-                                   IN ib_work_completion_t * wc_ptr)
-{
-       if (ibv_poll_cq(evd_ptr->ib_cq_handle, 1, wc_ptr) == 1)
-               return DAT_SUCCESS;
-
-       return DAT_QUEUE_EMPTY;
-}
-
-#ifdef CQ_WAIT_OBJECT
-
-/* NEW common wait objects for providers with direct CQ wait objects */
-DAT_RETURN
-dapls_ib_wait_object_create(IN DAPL_EVD * evd_ptr,
-                           IN ib_wait_obj_handle_t * p_cq_wait_obj_handle)
-{
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " cq_object_create: (%p,%p)\n",
-                    evd_ptr, p_cq_wait_obj_handle);
-
-       *p_cq_wait_obj_handle =
-           dapl_os_alloc(sizeof(struct _ib_wait_obj_handle));
-
-       if (*p_cq_wait_obj_handle == NULL)
-               return (dapl_convert_errno(ENOMEM, " wait_object_create"));
-
-       dapl_os_memzero(*p_cq_wait_obj_handle,
-                       sizeof(struct _ib_wait_obj_handle));
-
-       /* create pipe for waking up work thread */
-       if (pipe((*p_cq_wait_obj_handle)->pipe))
-               goto bail;
-
-       /* set cq_wait object to evd_ptr */
-       (*p_cq_wait_obj_handle)->events =
-           ibv_create_comp_channel(evd_ptr->header.owner_ia->hca_ptr->
-                                   ib_hca_handle);
-
-       if ((*p_cq_wait_obj_handle)->events == NULL)
-               goto bail;
-
-       return DAT_SUCCESS;
-      bail:
-       dapl_os_free(*p_cq_wait_obj_handle, sizeof(struct _ib_wait_obj_handle));
-       *p_cq_wait_obj_handle = NULL;
-       return (dapl_convert_errno(errno, " wait_object_create"));
-}
-
-DAT_RETURN
-dapls_ib_wait_object_destroy(IN ib_wait_obj_handle_t p_cq_wait_obj_handle)
-{
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " cq_object_destroy: wait_obj=%p\n", p_cq_wait_obj_handle);
-
-       ibv_destroy_comp_channel(p_cq_wait_obj_handle->events);
-
-       dapl_os_free(p_cq_wait_obj_handle, sizeof(struct _ib_wait_obj_handle));
-
-       return DAT_SUCCESS;
-}
-
-DAT_RETURN
-dapls_ib_wait_object_wakeup(IN ib_wait_obj_handle_t p_cq_wait_obj_handle)
-{
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " cq_object_wakeup: wait_obj=%p\n", p_cq_wait_obj_handle);
-
-       /* write to pipe for wake up */
-       if (write(p_cq_wait_obj_handle->pipe[1], "w", sizeof "w") == -1)
-               dapl_log(DAPL_DBG_TYPE_UTIL,
-                        " wait object wakeup write error = %s\n",
-                        strerror(errno));
-       return DAT_SUCCESS;
-}
-
-DAT_RETURN
-dapls_ib_wait_object_wait(IN ib_wait_obj_handle_t p_cq_wait_obj_handle,
-                         IN u_int32_t timeout)
-{
-       struct dapl_evd *evd_ptr;
-       struct ibv_cq *ibv_cq = NULL;
-       int status = 0;
-       int timeout_ms = -1;
-       struct pollfd ufds[2];
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " cq_object_wait: CQ channel %p time %d\n",
-                    p_cq_wait_obj_handle, timeout);
-
-       /* setup cq event channel and pipe fd for consumer wakeup */
-       ufds[0].fd = p_cq_wait_obj_handle->events->fd;
-       ufds[0].events = POLLIN;
-       ufds[0].revents = 0;
-       ufds[1].fd = p_cq_wait_obj_handle->pipe[0];
-       ufds[1].events = POLLIN;
-       ufds[1].revents = 0;
-
-       /* uDAPL timeout values in usecs */
-       if (timeout != DAT_TIMEOUT_INFINITE)
-               timeout_ms = timeout / 1000;
-
-       /* restart syscall */
-       while ((status = poll(ufds, 2, timeout_ms)) == -1)
-               if (errno == EINTR)
-                       continue;
-
-       /* returned event */
-       if (status > 0) {
-               if (ufds[0].revents == POLLIN) {
-                       if (!ibv_get_cq_event(p_cq_wait_obj_handle->events,
-                                             &ibv_cq, (void *)&evd_ptr)) {
-                               ibv_ack_cq_events(ibv_cq, 1);
-                       }
-               }
-               status = 0;
-
-               /* timeout */
-       } else if (status == 0)
-               status = ETIMEDOUT;
-       else
-               status = errno;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " cq_object_wait: RET evd %p ibv_cq %p %s\n",
-                    evd_ptr, ibv_cq, strerror(errno));
-
-       return (dapl_convert_errno(status, "cq_wait_object_wait"));
-
-}
-#endif
-
-/*
- * Local variables:
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 8
- * End:
- */
+/*\r
+ * Copyright (c) 2009 Intel Corporation.  All rights reserved.\r
+ *\r
+ * This Software is licensed under one of the following licenses:\r
+ *\r
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/cpl.php.\r
+ *\r
+ * 2) under the terms of the "The BSD License" a copy of which is\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/bsd-license.php.\r
+ *\r
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a\r
+ *    copy of which is available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/gpl-license.php.\r
+ *\r
+ * Licensee has the right to choose one of the above licenses.\r
+ *\r
+ * Redistributions of source code must retain the above copyright\r
+ * notice and one of the license notices.\r
+ *\r
+ * Redistributions in binary form must reproduce both the above copyright\r
+ * notice, one of the license notices in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ */\r
+#include "openib_osd.h"\r
+#include "dapl.h"\r
+#include "dapl_adapter_util.h"\r
+#include "dapl_lmr_util.h"\r
+#include "dapl_evd_util.h"\r
+#include "dapl_ring_buffer_util.h"\r
+\r
+/*\r
+ * Map all verbs DTO completion codes to the DAT equivelent.\r
+ *\r
+ * Not returned by verbs: DAT_DTO_ERR_PARTIAL_PACKET\r
+ */\r
+static struct ib_status_map {\r
+       int ib_status;\r
+       DAT_DTO_COMPLETION_STATUS dat_status;\r
+} ib_status_map[] = {\r
+/* 00 */  {IBV_WC_SUCCESS, DAT_DTO_SUCCESS},\r
+/* 01 */  {IBV_WC_LOC_LEN_ERR, DAT_DTO_ERR_LOCAL_LENGTH},\r
+/* 02 */  {IBV_WC_LOC_QP_OP_ERR, DAT_DTO_ERR_LOCAL_EP},\r
+/* 03 */  {IBV_WC_LOC_EEC_OP_ERR, DAT_DTO_ERR_TRANSPORT},\r
+/* 04 */  {IBV_WC_LOC_PROT_ERR, DAT_DTO_ERR_LOCAL_PROTECTION},\r
+/* 05 */  {IBV_WC_WR_FLUSH_ERR, DAT_DTO_ERR_FLUSHED},\r
+/* 06 */  {IBV_WC_MW_BIND_ERR, DAT_RMR_OPERATION_FAILED},\r
+/* 07 */  {IBV_WC_BAD_RESP_ERR, DAT_DTO_ERR_BAD_RESPONSE},\r
+/* 08 */  {IBV_WC_LOC_ACCESS_ERR, DAT_DTO_ERR_LOCAL_PROTECTION},\r
+/* 09 */  {IBV_WC_REM_INV_REQ_ERR, DAT_DTO_ERR_REMOTE_RESPONDER},\r
+/* 10 */  {IBV_WC_REM_ACCESS_ERR, DAT_DTO_ERR_REMOTE_ACCESS},\r
+/* 11 */  {IBV_WC_REM_OP_ERR, DAT_DTO_ERR_REMOTE_RESPONDER},\r
+/* 12 */  {IBV_WC_RETRY_EXC_ERR, DAT_DTO_ERR_TRANSPORT},\r
+/* 13 */  {IBV_WC_RNR_RETRY_EXC_ERR, DAT_DTO_ERR_RECEIVER_NOT_READY},\r
+/* 14 */  {IBV_WC_LOC_RDD_VIOL_ERR, DAT_DTO_ERR_LOCAL_PROTECTION},\r
+/* 15 */  {IBV_WC_REM_INV_RD_REQ_ERR, DAT_DTO_ERR_REMOTE_RESPONDER},\r
+/* 16 */  {IBV_WC_REM_ABORT_ERR, DAT_DTO_ERR_REMOTE_RESPONDER},\r
+/* 17 */  {IBV_WC_INV_EECN_ERR, DAT_DTO_ERR_TRANSPORT},\r
+/* 18 */  {IBV_WC_INV_EEC_STATE_ERR, DAT_DTO_ERR_TRANSPORT},\r
+/* 19 */  {IBV_WC_FATAL_ERR, DAT_DTO_ERR_TRANSPORT},\r
+/* 20 */  {IBV_WC_RESP_TIMEOUT_ERR, DAT_DTO_ERR_RECEIVER_NOT_READY},\r
+/* 21 */  {IBV_WC_GENERAL_ERR, DAT_DTO_ERR_TRANSPORT},\r
+};\r
+\r
+/*\r
+ * dapls_ib_get_dto_status\r
+ *\r
+ * Return the DAT status of a DTO operation\r
+ *\r
+ * Input:\r
+ *     cqe_ptr         pointer to completion queue entry\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     Value from ib_status_map table above\r
+ */\r
+\r
+DAT_DTO_COMPLETION_STATUS\r
+dapls_ib_get_dto_status(IN ib_work_completion_t * cqe_ptr)\r
+{\r
+       uint32_t ib_status;\r
+       int i;\r
+\r
+       ib_status = DAPL_GET_CQE_STATUS(cqe_ptr);\r
+\r
+       /*\r
+        * Due to the implementation of verbs completion code, we need to\r
+        * search the table for the correct value rather than assuming\r
+        * linear distribution.\r
+        */\r
+       for (i = 0; i <= IBV_WC_GENERAL_ERR; i++) {\r
+               if (ib_status == ib_status_map[i].ib_status) {\r
+                       if (ib_status != IBV_WC_SUCCESS) {\r
+                               dapl_log(DAPL_DBG_TYPE_DTO_COMP_ERR,\r
+                                        " DTO completion ERROR: %d:"\r
+                                        " op %#x\n",\r
+                                        ib_status,\r
+                                        DAPL_GET_CQE_OPTYPE(cqe_ptr));\r
+                       }\r
+                       return ib_status_map[i].dat_status;\r
+               }\r
+       }\r
+\r
+       return DAT_DTO_FAILURE;\r
+}\r
+\r
+DAT_RETURN dapls_ib_get_async_event(IN ib_error_record_t * err_record,\r
+                                   OUT DAT_EVENT_NUMBER * async_event)\r
+{\r
+       DAT_RETURN dat_status = DAT_SUCCESS;\r
+       int err_code = err_record->event_type;\r
+\r
+       switch (err_code) {\r
+               /* OVERFLOW error */\r
+       case IBV_EVENT_CQ_ERR:\r
+               *async_event = DAT_ASYNC_ERROR_EVD_OVERFLOW;\r
+               break;\r
+               /* INTERNAL errors */\r
+       case IBV_EVENT_DEVICE_FATAL:\r
+               *async_event = DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR;\r
+               break;\r
+               /* CATASTROPHIC errors */\r
+       case IBV_EVENT_PORT_ERR:\r
+               *async_event = DAT_ASYNC_ERROR_IA_CATASTROPHIC;\r
+               break;\r
+               /* BROKEN QP error */\r
+       case IBV_EVENT_SQ_DRAINED:\r
+       case IBV_EVENT_QP_FATAL:\r
+       case IBV_EVENT_QP_REQ_ERR:\r
+       case IBV_EVENT_QP_ACCESS_ERR:\r
+               *async_event = DAT_ASYNC_ERROR_EP_BROKEN;\r
+               break;\r
+\r
+               /* connection completion */\r
+       case IBV_EVENT_COMM_EST:\r
+               *async_event = DAT_CONNECTION_EVENT_ESTABLISHED;\r
+               break;\r
+\r
+               /* TODO: process HW state changes */\r
+       case IBV_EVENT_PATH_MIG:\r
+       case IBV_EVENT_PATH_MIG_ERR:\r
+       case IBV_EVENT_PORT_ACTIVE:\r
+       case IBV_EVENT_LID_CHANGE:\r
+       case IBV_EVENT_PKEY_CHANGE:\r
+       case IBV_EVENT_SM_CHANGE:\r
+       default:\r
+               dat_status = DAT_ERROR(DAT_NOT_IMPLEMENTED, 0);\r
+       }\r
+       return dat_status;\r
+}\r
+\r
+/*\r
+ * dapl_ib_cq_alloc\r
+ *\r
+ * Alloc a CQ\r
+ *\r
+ * Input:\r
+ *     ia_handle               IA handle\r
+ *     evd_ptr                 pointer to EVD struct\r
+ *     cqlen                   minimum QLen\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INSUFFICIENT_RESOURCES\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_cq_alloc(IN DAPL_IA * ia_ptr,\r
+                 IN DAPL_EVD * evd_ptr, IN DAT_COUNT * cqlen)\r
+{\r
+       struct ibv_comp_channel *channel = evd_ptr->cq_wait_obj_handle;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    "dapls_ib_cq_alloc: evd %p cqlen=%d \n", evd_ptr, *cqlen);\r
+\r
+       /* Call IB verbs to create CQ */\r
+       evd_ptr->ib_cq_handle = ibv_create_cq(ia_ptr->hca_ptr->ib_hca_handle,\r
+                                             *cqlen, evd_ptr, channel, 0);\r
+\r
+       if (evd_ptr->ib_cq_handle == IB_INVALID_HANDLE)\r
+               return DAT_INSUFFICIENT_RESOURCES;\r
+\r
+       /* arm cq for events */\r
+       dapls_set_cq_notify(ia_ptr, evd_ptr);\r
+\r
+       /* update with returned cq entry size */\r
+       *cqlen = evd_ptr->ib_cq_handle->cqe;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    "dapls_ib_cq_alloc: new_cq %p cqlen=%d \n",\r
+                    evd_ptr->ib_cq_handle, *cqlen);\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * dapl_ib_cq_resize\r
+ *\r
+ * Alloc a CQ\r
+ *\r
+ * Input:\r
+ *     ia_handle               IA handle\r
+ *     evd_ptr                 pointer to EVD struct\r
+ *     cqlen                   minimum QLen\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INVALID_PARAMETER\r
+ *\r
+ */\r
+DAT_RETURN\r
+dapls_ib_cq_resize(IN DAPL_IA * ia_ptr,\r
+                  IN DAPL_EVD * evd_ptr, IN DAT_COUNT * cqlen)\r
+{\r
+       ib_cq_handle_t new_cq;\r
+       struct ibv_comp_channel *channel = evd_ptr->cq_wait_obj_handle;\r
+\r
+       /* IB verbs DOES support resize. REDO THIS.\r
+        * Try to re-create CQ\r
+        * with new size. Can only be done if QP is not attached. \r
+        * destroy EBUSY == QP still attached.\r
+        */\r
+\r
+       /* Call IB verbs to create CQ */\r
+       new_cq = ibv_create_cq(ia_ptr->hca_ptr->ib_hca_handle, *cqlen,\r
+                              evd_ptr, channel, 0);\r
+\r
+       if (new_cq == IB_INVALID_HANDLE)\r
+               return DAT_INSUFFICIENT_RESOURCES;\r
+\r
+       /* destroy the original and replace if successful */\r
+       if (ibv_destroy_cq(evd_ptr->ib_cq_handle)) {\r
+               ibv_destroy_cq(new_cq);\r
+               return (dapl_convert_errno(errno, "resize_cq"));\r
+       }\r
+\r
+       /* update EVD with new cq handle and size */\r
+       evd_ptr->ib_cq_handle = new_cq;\r
+       *cqlen = new_cq->cqe;\r
+\r
+       /* arm cq for events */\r
+       dapls_set_cq_notify(ia_ptr, evd_ptr);\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * dapls_ib_cq_free\r
+ *\r
+ * destroy a CQ\r
+ *\r
+ * Input:\r
+ *     ia_handle               IA handle\r
+ *     evd_ptr                 pointer to EVD struct\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     DAT_INVALID_PARAMETER\r
+ *\r
+ */\r
+DAT_RETURN dapls_ib_cq_free(IN DAPL_IA * ia_ptr, IN DAPL_EVD * evd_ptr)\r
+{\r
+       DAT_EVENT event;\r
+       ib_work_completion_t wc;\r
+\r
+       if (evd_ptr->ib_cq_handle != IB_INVALID_HANDLE) {\r
+               /* pull off CQ and EVD entries and toss */\r
+               while (ibv_poll_cq(evd_ptr->ib_cq_handle, 1, &wc) == 1) ;\r
+               while (dapl_evd_dequeue(evd_ptr, &event) == DAT_SUCCESS) ;\r
+               if (ibv_destroy_cq(evd_ptr->ib_cq_handle))\r
+                       return (dapl_convert_errno(errno, "ibv_destroy_cq"));\r
+               evd_ptr->ib_cq_handle = IB_INVALID_HANDLE;\r
+       }\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * dapls_set_cq_notify\r
+ *\r
+ * Set the CQ notification for next\r
+ *\r
+ * Input:\r
+ *     hca_handl               hca handle\r
+ *     DAPL_EVD                evd handle\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     dapl_convert_errno \r
+ */\r
+DAT_RETURN dapls_set_cq_notify(IN DAPL_IA * ia_ptr, IN DAPL_EVD * evd_ptr)\r
+{\r
+       if (ibv_req_notify_cq(evd_ptr->ib_cq_handle, 0))\r
+               return (dapl_convert_errno(errno, "notify_cq"));\r
+       else\r
+               return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * dapls_ib_completion_notify\r
+ *\r
+ * Set the CQ notification type\r
+ *\r
+ * Input:\r
+ *     hca_handl               hca handle\r
+ *     evd_ptr                 evd handle\r
+ *     type                    notification type\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns:\r
+ *     DAT_SUCCESS\r
+ *     dapl_convert_errno\r
+ */\r
+DAT_RETURN dapls_ib_completion_notify(IN ib_hca_handle_t hca_handle,\r
+                                     IN DAPL_EVD * evd_ptr,\r
+                                     IN ib_notification_type_t type)\r
+{\r
+       if (ibv_req_notify_cq(evd_ptr->ib_cq_handle, type))\r
+               return (dapl_convert_errno(errno, "notify_cq_type"));\r
+       else\r
+               return DAT_SUCCESS;\r
+}\r
+\r
+/*\r
+ * dapls_ib_completion_poll\r
+ *\r
+ * CQ poll for completions\r
+ *\r
+ * Input:\r
+ *     hca_handl               hca handle\r
+ *     evd_ptr                 evd handle\r
+ *     wc_ptr                  work completion\r
+ *\r
+ * Output:\r
+ *     none\r
+ *\r
+ * Returns: \r
+ *     DAT_SUCCESS\r
+ *     DAT_QUEUE_EMPTY\r
+ *     \r
+ */\r
+DAT_RETURN dapls_ib_completion_poll(IN DAPL_HCA * hca_ptr,\r
+                                   IN DAPL_EVD * evd_ptr,\r
+                                   IN ib_work_completion_t * wc_ptr)\r
+{\r
+       int ret;\r
+\r
+       ret = ibv_poll_cq(evd_ptr->ib_cq_handle, 1, wc_ptr);\r
+       if (ret == 1)\r
+               return DAT_SUCCESS;\r
+\r
+       return DAT_QUEUE_EMPTY;\r
+}\r
+\r
+/* NEW common wait objects for providers with direct CQ wait objects */\r
+DAT_RETURN\r
+dapls_ib_wait_object_create(IN DAPL_EVD * evd_ptr,\r
+                           IN ib_wait_obj_handle_t * p_cq_wait_obj_handle)\r
+{\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " cq_object_create: (%p,%p)\n",\r
+                    evd_ptr, p_cq_wait_obj_handle);\r
+\r
+       /* set cq_wait object to evd_ptr */\r
+       *p_cq_wait_obj_handle =\r
+           ibv_create_comp_channel(evd_ptr->header.owner_ia->hca_ptr->\r
+                                   ib_hca_handle);\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+DAT_RETURN\r
+dapls_ib_wait_object_destroy(IN ib_wait_obj_handle_t p_cq_wait_obj_handle)\r
+{\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " cq_object_destroy: wait_obj=%p\n", p_cq_wait_obj_handle);\r
+\r
+       ibv_destroy_comp_channel(p_cq_wait_obj_handle);\r
+\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+DAT_RETURN\r
+dapls_ib_wait_object_wakeup(IN ib_wait_obj_handle_t p_cq_wait_obj_handle)\r
+{\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " cq_object_wakeup: wait_obj=%p\n", p_cq_wait_obj_handle);\r
+\r
+       /* no wake up mechanism */\r
+       return DAT_SUCCESS;\r
+}\r
+\r
+#if defined(_WIN32) || defined(_WIN64)\r
+DAT_RETURN\r
+dapls_ib_wait_object_wait(IN ib_wait_obj_handle_t p_cq_wait_obj_handle,\r
+                         IN uint32_t timeout)\r
+{\r
+       struct dapl_evd *evd_ptr;\r
+       struct ibv_cq *ibv_cq = NULL;\r
+       int status = 0;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " cq_object_wait: CQ channel %p time %d\n",\r
+                    p_cq_wait_obj_handle, timeout);\r
+\r
+       /* uDAPL timeout values in usecs */\r
+       p_cq_wait_obj_handle->comp_channel.Milliseconds = timeout / 1000;\r
+\r
+       /* returned event */\r
+       status = ibv_get_cq_event(p_cq_wait_obj_handle, &ibv_cq,\r
+                                 (void *)&evd_ptr);\r
+       if (status == 0) {\r
+               ibv_ack_cq_events(ibv_cq, 1);\r
+       }\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " cq_object_wait: RET evd %p ibv_cq %p %s\n",\r
+                    evd_ptr, ibv_cq, strerror(errno));\r
+\r
+       return (dapl_convert_errno(status, "cq_wait_object_wait"));\r
+}\r
+#else                  //_WIN32 || _WIN64\r
+DAT_RETURN\r
+dapls_ib_wait_object_wait(IN ib_wait_obj_handle_t p_cq_wait_obj_handle,\r
+                         IN uint32_t timeout)\r
+{\r
+       struct dapl_evd *evd_ptr;\r
+       struct ibv_cq *ibv_cq = NULL;\r
+       int status = 0;\r
+       int timeout_ms = -1;\r
+       struct pollfd cq_fd = {\r
+               .fd = p_cq_wait_obj_handle->fd,\r
+               .events = POLLIN,\r
+               .revents = 0\r
+       };\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " cq_object_wait: CQ channel %p time %d\n",\r
+                    p_cq_wait_obj_handle, timeout);\r
+\r
+       /* uDAPL timeout values in usecs */\r
+       if (timeout != DAT_TIMEOUT_INFINITE)\r
+               timeout_ms = timeout / 1000;\r
+\r
+       status = poll(&cq_fd, 1, timeout_ms);\r
+\r
+       /* returned event */\r
+       if (status > 0) {\r
+               if (!ibv_get_cq_event(p_cq_wait_obj_handle,\r
+                                     &ibv_cq, (void *)&evd_ptr)) {\r
+                       ibv_ack_cq_events(ibv_cq, 1);\r
+               }\r
+               status = 0;\r
+\r
+               /* timeout */\r
+       } else if (status == 0)\r
+               status = ETIMEDOUT;\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " cq_object_wait: RET evd %p ibv_cq %p %s\n",\r
+                    evd_ptr, ibv_cq, strerror(errno));\r
+\r
+       return (dapl_convert_errno(status, "cq_wait_object_wait"));\r
+\r
+}\r
+#endif                         //_WIN32 || _WIN64\r
+\r
+/*\r
+ * Local variables:\r
+ *  c-indent-level: 4\r
+ *  c-basic-offset: 4\r
+ *  tab-width: 8\r
+ * End:\r
+ */\r
diff --git a/ulp/dapl2/dapl/openib_common/dapl_ib_common.h b/ulp/dapl2/dapl/openib_common/dapl_ib_common.h
new file mode 100644 (file)
index 0000000..2ed5ea1
--- /dev/null
@@ -0,0 +1,299 @@
+/*\r
+ * Copyright (c) 2009 Intel Corporation.  All rights reserved.\r
+ *\r
+ * This Software is licensed under one of the following licenses:\r
+ *\r
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/cpl.php.\r
+ *\r
+ * 2) under the terms of the "The BSD License" a copy of which is\r
+ *    available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/bsd-license.php.\r
+ *\r
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a\r
+ *    copy of which is available from the Open Source Initiative, see\r
+ *    http://www.opensource.org/licenses/gpl-license.php.\r
+ *\r
+ * Licensee has the right to choose one of the above licenses.\r
+ *\r
+ * Redistributions of source code must retain the above copyright\r
+ * notice and one of the license notices.\r
+ *\r
+ * Redistributions in binary form must reproduce both the above copyright\r
+ * notice, one of the license notices in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ */\r
+\r
+/* \r
+ * Definitions common to all OpenIB providers, cma, scm, ucm \r
+ */\r
+\r
+#ifndef _DAPL_IB_COMMON_H_\r
+#define _DAPL_IB_COMMON_H_\r
+\r
+#include <infiniband/verbs.h>\r
+\r
+#ifdef DAT_EXTENSIONS\r
+#include <dat2/dat_ib_extensions.h>\r
+#endif\r
+\r
+#ifndef __cplusplus\r
+#define false 0\r
+#define true  1\r
+#endif /*__cplusplus */\r
+\r
+/* Typedefs to map common DAPL provider types to IB verbs */\r
+typedef        struct ibv_qp           *ib_qp_handle_t;\r
+typedef        struct ibv_cq           *ib_cq_handle_t;\r
+typedef        struct ibv_pd           *ib_pd_handle_t;\r
+typedef        struct ibv_mr           *ib_mr_handle_t;\r
+typedef        struct ibv_mw           *ib_mw_handle_t;\r
+typedef        struct ibv_wc           ib_work_completion_t;\r
+\r
+/* HCA context type maps to IB verbs  */\r
+typedef        struct ibv_context      *ib_hca_handle_t;\r
+typedef ib_hca_handle_t                dapl_ibal_ca_t;\r
+\r
+/* QP info to exchange, wire protocol version for these CM's */\r
+#define DCM_VER 4\r
+typedef struct _ib_qp_cm\r
+{ \r
+       uint16_t                ver;\r
+       uint16_t                rej;\r
+       uint16_t                lid;\r
+       uint16_t                port;\r
+       uint32_t                qpn;\r
+       uint32_t                p_size;\r
+       union ibv_gid           gid;\r
+       DAT_SOCK_ADDR6          ia_address;\r
+       uint16_t                qp_type; \r
+} ib_qp_cm_t;\r
+\r
+/* CM events */\r
+typedef enum {\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_CONNECTION_REQUEST_ACKED,\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_BROKEN,\r
+       IB_CME_TIMEOUT\r
+} ib_cm_events_t;\r
+\r
+/* Operation and state mappings */\r
+typedef int ib_send_op_type_t;\r
+typedef        struct  ibv_sge         ib_data_segment_t;\r
+typedef enum   ibv_qp_state    ib_qp_state_t;\r
+typedef        enum    ibv_event_type  ib_async_event_type;\r
+typedef struct ibv_async_event ib_error_record_t;      \r
+\r
+/* CQ notifications */\r
+typedef enum\r
+{\r
+       IB_NOTIFY_ON_NEXT_COMP,\r
+       IB_NOTIFY_ON_SOLIC_COMP\r
+\r
+} ib_notification_type_t;\r
+\r
+/* other mappings */\r
+typedef int                    ib_bool_t;\r
+typedef union ibv_gid          GID;\r
+typedef char                   *IB_HCA_NAME;\r
+typedef uint16_t               ib_hca_port_t;\r
+typedef uint32_t               ib_comp_handle_t;\r
+\r
+typedef struct ibv_comp_channel *ib_wait_obj_handle_t;\r
+\r
+/* Definitions */\r
+#define IB_INVALID_HANDLE      NULL\r
+\r
+/* inline send rdma threshold */\r
+#define        INLINE_SEND_IWARP_DEFAULT       64\r
+#define        INLINE_SEND_IB_DEFAULT          200\r
+\r
+/* qkey for UD QP's */\r
+#define DAT_UD_QKEY    0x78654321\r
+\r
+/* DTO OPs, ordered for DAPL ENUM definitions */\r
+#define OP_RDMA_WRITE           IBV_WR_RDMA_WRITE\r
+#define OP_RDMA_WRITE_IMM       IBV_WR_RDMA_WRITE_WITH_IMM\r
+#define OP_SEND                 IBV_WR_SEND\r
+#define OP_SEND_IMM             IBV_WR_SEND_WITH_IMM\r
+#define OP_RDMA_READ            IBV_WR_RDMA_READ\r
+#define OP_COMP_AND_SWAP        IBV_WR_ATOMIC_CMP_AND_SWP\r
+#define OP_FETCH_AND_ADD        IBV_WR_ATOMIC_FETCH_AND_ADD\r
+#define OP_RECEIVE              7   /* internal op */\r
+#define OP_RECEIVE_IMM         8   /* rdma write with immed, internel op */\r
+#define OP_RECEIVE_MSG_IMM     9   /* recv msg with immed, internel op */\r
+#define OP_BIND_MW              10   /* internal op */\r
+#define OP_SEND_UD              11  /* internal op */\r
+#define OP_RECV_UD              12  /* internal op */\r
+#define OP_INVALID             0xff\r
+\r
+/* Definitions to map QP state */\r
+#define IB_QP_STATE_RESET      IBV_QPS_RESET\r
+#define IB_QP_STATE_INIT       IBV_QPS_INIT\r
+#define IB_QP_STATE_RTR                IBV_QPS_RTR\r
+#define IB_QP_STATE_RTS                IBV_QPS_RTS\r
+#define IB_QP_STATE_SQD                IBV_QPS_SQD\r
+#define IB_QP_STATE_SQE                IBV_QPS_SQE\r
+#define IB_QP_STATE_ERROR      IBV_QPS_ERR\r
+\r
+/* Definitions for ibverbs/mthca return codes, should be defined in verbs.h */\r
+/* some are errno and some are -n values */\r
+\r
+/**\r
+ * ibv_get_device_name - Return kernel device name\r
+ * ibv_get_device_guid - Return device's node GUID\r
+ * ibv_open_device - Return ibv_context or NULL\r
+ * ibv_close_device - Return 0, (errno?)\r
+ * ibv_get_async_event - Return 0, -1 \r
+ * ibv_alloc_pd - Return ibv_pd, NULL\r
+ * ibv_dealloc_pd - Return 0, errno \r
+ * ibv_reg_mr - Return ibv_mr, NULL\r
+ * ibv_dereg_mr - Return 0, errno\r
+ * ibv_create_cq - Return ibv_cq, NULL\r
+ * ibv_destroy_cq - Return 0, errno\r
+ * ibv_get_cq_event - Return 0 & ibv_cq/context, int\r
+ * ibv_poll_cq - Return n & ibv_wc, 0 ok, -1 empty, -2 error \r
+ * ibv_req_notify_cq - Return 0 (void?)\r
+ * ibv_create_qp - Return ibv_qp, NULL\r
+ * ibv_modify_qp - Return 0, errno\r
+ * ibv_destroy_qp - Return 0, errno\r
+ * ibv_post_send - Return 0, -1 & bad_wr\r
+ * ibv_post_recv - Return 0, -1 & bad_wr \r
+ */\r
+\r
+/* async handler for DTO, CQ, QP, and unafiliated */\r
+typedef void (*ib_async_dto_handler_t)(\r
+    IN    ib_hca_handle_t    ib_hca_handle,\r
+    IN    ib_error_record_t  *err_code,\r
+    IN    void               *context);\r
+\r
+typedef void (*ib_async_cq_handler_t)(\r
+    IN    ib_hca_handle_t    ib_hca_handle,\r
+    IN    ib_cq_handle_t     ib_cq_handle,\r
+    IN    ib_error_record_t  *err_code,\r
+    IN    void               *context);\r
+\r
+typedef void (*ib_async_qp_handler_t)(\r
+    IN    ib_hca_handle_t    ib_hca_handle,\r
+    IN    ib_qp_handle_t     ib_qp_handle,\r
+    IN    ib_error_record_t  *err_code,\r
+    IN    void               *context);\r
+\r
+typedef void (*ib_async_handler_t)(\r
+    IN    ib_hca_handle_t    ib_hca_handle,\r
+    IN    ib_error_record_t  *err_code,\r
+    IN    void               *context);\r
+\r
+typedef enum\r
+{\r
+       IB_THREAD_INIT,\r
+       IB_THREAD_CREATE,\r
+       IB_THREAD_RUN,\r
+       IB_THREAD_CANCEL,\r
+       IB_THREAD_EXIT\r
+\r
+} ib_thread_state_t;\r
+\r
+\r
+/* provider specfic fields for shared memory support */\r
+typedef uint32_t ib_shm_transport_t;\r
+\r
+/* prototypes */\r
+int32_t        dapls_ib_init(void);\r
+int32_t        dapls_ib_release(void);\r
+enum ibv_mtu dapl_ib_mtu(int mtu);\r
+char *dapl_ib_mtu_str(enum ibv_mtu mtu);\r
+DAT_RETURN getlocalipaddr(DAT_SOCK_ADDR *addr, int addr_len);\r
+\r
+/* inline functions */\r
+STATIC _INLINE_ IB_HCA_NAME dapl_ib_convert_name (IN char *name)\r
+{\r
+       /* use ascii; name of local device */\r
+       return dapl_os_strdup(name);\r
+}\r
+\r
+STATIC _INLINE_ void dapl_ib_release_name (IN IB_HCA_NAME name)\r
+{\r
+       return;\r
+}\r
+\r
+/*\r
+ *  Convert errno to DAT_RETURN values\r
+ */\r
+STATIC _INLINE_ DAT_RETURN \r
+dapl_convert_errno( IN int err, IN const char *str )\r
+{\r
+    if (!err)  return DAT_SUCCESS;\r
+       \r
+#if DAPL_DBG\r
+    if ((err != EAGAIN) && (err != ETIMEDOUT))\r
+       dapl_dbg_log (DAPL_DBG_TYPE_ERR," %s %s\n", str, strerror(err));\r
+#endif \r
+\r
+    switch( err )\r
+    {\r
+       case EOVERFLOW  : return DAT_LENGTH_ERROR;\r
+       case EACCES     : return DAT_PRIVILEGES_VIOLATION;\r
+       case EPERM      : return DAT_PROTECTION_VIOLATION;                \r
+       case EINVAL     : return DAT_INVALID_HANDLE;\r
+       case EISCONN    : return DAT_INVALID_STATE | DAT_INVALID_STATE_EP_CONNECTED;\r
+       case ECONNREFUSED : return DAT_INVALID_STATE | DAT_INVALID_STATE_EP_NOTREADY;\r
+       case ETIMEDOUT  : return DAT_TIMEOUT_EXPIRED;\r
+       case ENETUNREACH: return DAT_INVALID_ADDRESS | DAT_INVALID_ADDRESS_UNREACHABLE;\r
+       case EADDRINUSE : return DAT_CONN_QUAL_IN_USE;\r
+       case EALREADY   : return DAT_INVALID_STATE | DAT_INVALID_STATE_EP_ACTCONNPENDING;\r
+       case ENOMEM     : return DAT_INSUFFICIENT_RESOURCES;\r
+        case EAGAIN    : return DAT_QUEUE_EMPTY;\r
+       case EINTR      : return DAT_INTERRUPTED_CALL;\r
+       case EAFNOSUPPORT : return DAT_INVALID_ADDRESS | DAT_INVALID_ADDRESS_MALFORMED;\r
+       case EFAULT     : \r
+       default         : return DAT_INTERNAL_ERROR;\r
+    }\r
+ }\r
+\r
+typedef enum dapl_cm_state \r
+{\r
+       DCM_INIT,\r
+       DCM_LISTEN,\r
+       DCM_CONN_PENDING,\r
+       DCM_RTU_PENDING,\r
+       DCM_ACCEPTING,\r
+       DCM_ACCEPTING_DATA,\r
+       DCM_ACCEPTED,\r
+       DCM_REJECTED,\r
+       DCM_CONNECTED,\r
+       DCM_RELEASED,\r
+       DCM_DISCONNECTED,\r
+       DCM_DESTROY\r
+} DAPL_CM_STATE;\r
+\r
+STATIC _INLINE_ char * dapl_cm_state_str(IN int st)\r
+{\r
+       static char *state[] = {\r
+               "CM_INIT",\r
+               "CM_LISTEN",\r
+               "CM_CONN_PENDING",\r
+               "CM_RTU_PENDING",\r
+               "CM_ACCEPTING",\r
+               "CM_ACCEPTING_DATA",\r
+               "CM_ACCEPTED",\r
+               "CM_REJECTED",\r
+               "CM_CONNECTED",\r
+               "CM_RELEASED",\r
+               "CM_DISCONNECTED",\r
+               "CM_DESTROY"\r
+        };\r
+        return ((st < 0 || st > 11) ? "Invalid CM state?" : state[st]);\r
+}\r
+\r
+#endif /*  _DAPL_IB_COMMON_H_ */\r
similarity index 95%
rename from ulp/dapl2/dapl/openib_scm/dapl_ib_dto.h
rename to ulp/dapl2/dapl/openib_common/dapl_ib_dto.h
index 9118b2e..1e74113 100644 (file)
-/*
- * This Software is licensed under one of the following licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- *
- * 2) under the terms of the "The BSD License" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- *
- * Licensee has the right to choose one of the above licenses.
- *
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-/***************************************************************************
- *
- *   Module:            uDAPL
- *
- *   Filename:          dapl_ib_dto.h
- *
- *   Author:            Arlin Davis
- *
- *   Created:           3/10/2005
- *
- *   Description: 
- *
- *   The OpenIB uCMA provider - DTO operations and CQE macros 
- *
- ****************************************************************************
- *                Source Control System Information
- *
- *    $Id: $
- *
- *     Copyright (c) 2005 Intel Corporation.  All rights reserved.
- *
- **************************************************************************/
-#ifndef _DAPL_IB_DTO_H_
-#define _DAPL_IB_DTO_H_
-
-#include "dapl_ib_util.h"
-
-#ifdef DAT_EXTENSIONS
-#include <dat2/dat_ib_extensions.h>
-#endif
-
-#define        DEFAULT_DS_ENTRIES      8
-
-STATIC _INLINE_ int dapls_cqe_opcode(ib_work_completion_t *cqe_p);
-
-#define CQE_WR_TYPE_UD(id) \
-       (((DAPL_COOKIE *)(uintptr_t)id)->ep->qp_handle->qp_type == IBV_QPT_UD)
-
-/*
- * dapls_ib_post_recv
- *
- * Provider specific Post RECV function
- */
-STATIC _INLINE_ DAT_RETURN 
-dapls_ib_post_recv (
-       IN  DAPL_EP             *ep_ptr,
-       IN  DAPL_COOKIE         *cookie,
-       IN  DAT_COUNT           segments,
-       IN  DAT_LMR_TRIPLET     *local_iov )
-{
-       struct ibv_recv_wr wr;
-       struct ibv_recv_wr *bad_wr;
-       ib_data_segment_t *ds = (ib_data_segment_t *)local_iov;
-       DAT_COUNT i, total_len;
-       int ret;
-       
-       dapl_dbg_log(DAPL_DBG_TYPE_EP,
-                    " post_rcv: ep %p cookie %p segs %d l_iov %p\n",
-                    ep_ptr, cookie, segments, local_iov);
-
-       /* setup work request */
-       total_len = 0;
-       wr.next = 0;
-       wr.num_sge = segments;
-       wr.wr_id = (uint64_t)(uintptr_t)cookie;
-       wr.sg_list = ds;
-
-       if (cookie != NULL) {
-               for (i = 0; i < segments; i++) {
-                       dapl_dbg_log(DAPL_DBG_TYPE_EP, 
-                                    " post_rcv: l_key 0x%x va %p len %d\n",
-                                    ds->lkey, ds->addr, ds->length );
-                       total_len += ds->length;
-                       ds++;
-               }
-               cookie->val.dto.size = total_len;
-       }
-
-       ret = ibv_post_recv(ep_ptr->qp_handle, &wr, &bad_wr);
-       
-       if (ret)
-               return(dapl_convert_errno(errno,"ibv_recv"));
-
-       DAPL_CNTR(ep_ptr, DCNT_EP_POST_RECV);
-       DAPL_CNTR_DATA(ep_ptr, DCNT_EP_POST_RECV_DATA, total_len);
-
-       return DAT_SUCCESS;
-}
-
-/*
- * dapls_ib_post_send
- *
- * Provider specific Post SEND function
- */
-STATIC _INLINE_ DAT_RETURN 
-dapls_ib_post_send (
-       IN  DAPL_EP                     *ep_ptr,
-       IN  ib_send_op_type_t           op_type,
-       IN  DAPL_COOKIE                 *cookie,
-       IN  DAT_COUNT                   segments,
-       IN  DAT_LMR_TRIPLET             *local_iov,
-       IN  const DAT_RMR_TRIPLET       *remote_iov,
-       IN  DAT_COMPLETION_FLAGS        completion_flags)
-{
-       struct ibv_send_wr wr;
-       struct ibv_send_wr *bad_wr;
-       ib_data_segment_t *ds = (ib_data_segment_t *)local_iov;
-       ib_hca_transport_t *ibt_ptr = 
-               &ep_ptr->header.owner_ia->hca_ptr->ib_trans;
-       DAT_COUNT i, total_len;
-       int ret;
-       
-       dapl_dbg_log(DAPL_DBG_TYPE_EP,
-                    " post_snd: ep %p op %d ck %p sgs",
-                    "%d l_iov %p r_iov %p f %d\n",
-                    ep_ptr, op_type, cookie, segments, local_iov, 
-                    remote_iov, completion_flags);
-
-#ifdef DAT_EXTENSIONS  
-       if (ep_ptr->qp_handle->qp_type != IBV_QPT_RC)
-               return(DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP));
-#endif
-       /* setup the work request */
-       wr.next = 0;
-       wr.opcode = op_type;
-       wr.num_sge = segments;
-       wr.send_flags = 0;
-       wr.wr_id = (uint64_t)(uintptr_t)cookie;
-       wr.sg_list = ds;
-       total_len = 0;
-
-       if (cookie != NULL) {
-               for (i = 0; i < segments; i++ ) {
-                       dapl_dbg_log(DAPL_DBG_TYPE_EP, 
-                                    " post_snd: lkey 0x%x va %p len %d\n",
-                                    ds->lkey, ds->addr, ds->length );
-                       total_len += ds->length;
-                       ds++;
-               }
-               cookie->val.dto.size = total_len;
-       }
-
-       if (wr.num_sge && 
-           (op_type == OP_RDMA_WRITE || op_type == OP_RDMA_READ)) {
-               wr.wr.rdma.remote_addr = remote_iov->virtual_address;
-               wr.wr.rdma.rkey = remote_iov->rmr_context;
-               dapl_dbg_log(DAPL_DBG_TYPE_EP, 
-                            " post_snd_rdma: rkey 0x%x va %#016Lx\n",
-                            wr.wr.rdma.rkey, wr.wr.rdma.remote_addr);
-       }
-
-
-       /* inline data for send or write ops */
-       if ((total_len <= ibt_ptr->max_inline_send) && 
-          ((op_type == OP_SEND) || (op_type == OP_RDMA_WRITE))) 
-               wr.send_flags |= IBV_SEND_INLINE;
-       
-       /* set completion flags in work request */
-       wr.send_flags |= (DAT_COMPLETION_SUPPRESS_FLAG & 
-                               completion_flags) ? 0 : IBV_SEND_SIGNALED;
-       wr.send_flags |= (DAT_COMPLETION_BARRIER_FENCE_FLAG & 
-                               completion_flags) ? IBV_SEND_FENCE : 0;
-       wr.send_flags |= (DAT_COMPLETION_SOLICITED_WAIT_FLAG & 
-                               completion_flags) ? IBV_SEND_SOLICITED : 0;
-
-       dapl_dbg_log(DAPL_DBG_TYPE_EP, 
-                    " post_snd: op 0x%x flags 0x%x sglist %p, %d\n", 
-                    wr.opcode, wr.send_flags, wr.sg_list, wr.num_sge);
-
-       ret = ibv_post_send(ep_ptr->qp_handle, &wr, &bad_wr);
-
-       if (ret)
-               return(dapl_convert_errno(errno,"ibv_send"));
-
-#ifdef DAPL_COUNTERS
-       switch (op_type) {
-       case OP_SEND:
-               DAPL_CNTR(ep_ptr, DCNT_EP_POST_SEND);
-               DAPL_CNTR_DATA(ep_ptr, DCNT_EP_POST_SEND_DATA,total_len);
-               break;
-       case OP_RDMA_WRITE:
-               DAPL_CNTR(ep_ptr, DCNT_EP_POST_WRITE);
-               DAPL_CNTR_DATA(ep_ptr, DCNT_EP_POST_WRITE_DATA,total_len);
-               break;  
-       case OP_RDMA_READ:
-               DAPL_CNTR(ep_ptr, DCNT_EP_POST_READ);
-               DAPL_CNTR_DATA(ep_ptr, DCNT_EP_POST_READ_DATA,total_len);
-               break;
-       default:
-               break;
-       }
-#endif /* DAPL_COUNTERS */
-
-       dapl_dbg_log(DAPL_DBG_TYPE_EP," post_snd: returned\n");
-       return DAT_SUCCESS;
-}
-
-/* map Work Completions to DAPL WR operations */
-STATIC _INLINE_ DAT_DTOS dapls_cqe_dtos_opcode(ib_work_completion_t *cqe_p)
-{
-       switch (cqe_p->opcode) {
-
-       case IBV_WC_SEND:
-#ifdef DAT_EXTENSIONS
-               if (CQE_WR_TYPE_UD(cqe_p->wr_id))
-                       return (DAT_IB_DTO_SEND_UD);
-               else
-#endif                 
-               return (DAT_DTO_SEND);
-       case IBV_WC_RDMA_READ:
-               return (DAT_DTO_RDMA_READ);
-       case IBV_WC_BIND_MW:
-               return (DAT_DTO_BIND_MW);
-#ifdef DAT_EXTENSIONS
-       case IBV_WC_RDMA_WRITE:
-               if (cqe_p->wc_flags & IBV_WC_WITH_IMM)
-                       return (DAT_IB_DTO_RDMA_WRITE_IMMED);
-               else
-                       return (DAT_DTO_RDMA_WRITE);</