]> git.openfabrics.org - ~shefty/rdma-win.git/commitdiff
[DAPL2] ucm, scm, cma: destroy verbs completion channels created via ia_open or ep_cr...
authorStan Smith <stan.smith@intel.com>
Fri, 19 Feb 2010 17:09:58 +0000 (17:09 +0000)
committerStan Smith <stan.smith@intel.com>
Fri, 19 Feb 2010 17:09:58 +0000 (17:09 +0000)
Completion channels are created with ia_open for CNO events and  with ep_create in cases where DAT allows EP(qp) to be created with no EVD(cq) and IB doesn't. These completion channels need to be destroyed at close along with a CQ for the "EP without EVD" case.

Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
git-svn-id: svn://openib.tc.cornell.edu/gen1@2705 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

branches/WOF2-2/ulp/dapl2/dapl/openib_cma/device.c
branches/WOF2-2/ulp/dapl2/dapl/openib_scm/device.c
branches/WOF2-2/ulp/dapl2/dapl/openib_ucm/device.c

index 32090fbef3c7bf97b695130a848a1de680394f71..5dba4f74757c3935a025e6780ed089ec52c2666c 100644 (file)
@@ -502,6 +502,17 @@ DAT_RETURN dapls_ib_close_hca(IN DAPL_HCA * hca_ptr)
                dapl_os_sleep_usec(1000);\r
        }\r
 bail:\r
+\r
+       if (hca_ptr->ib_trans.ib_cq)\r
+               ibv_destroy_comp_channel(hca_ptr->ib_trans.ib_cq);\r
+\r
+       if (hca_ptr->ib_trans.ib_cq_empty) {\r
+               struct ibv_comp_channel *channel;\r
+               channel = hca_ptr->ib_trans.ib_cq_empty->channel;\r
+               ibv_destroy_cq(hca_ptr->ib_trans.ib_cq_empty);\r
+               ibv_destroy_comp_channel(channel);\r
+       }\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
index bb3893a72c3de5ade7fb323216f2f4a75e1f1872..04e992a8ef86dbb1bd317dfeb9da5c41a16d6b4e 100644 (file)
@@ -504,6 +504,16 @@ DAT_RETURN dapls_ib_close_hca(IN DAPL_HCA * hca_ptr)
        }\r
 \r
 out:\r
+       if (hca_ptr->ib_trans.ib_cq)\r
+               ibv_destroy_comp_channel(hca_ptr->ib_trans.ib_cq);\r
+\r
+       if (hca_ptr->ib_trans.ib_cq_empty) {\r
+               struct ibv_comp_channel *channel;\r
+               channel = hca_ptr->ib_trans.ib_cq_empty->channel;\r
+               ibv_destroy_cq(hca_ptr->ib_trans.ib_cq_empty);\r
+               ibv_destroy_comp_channel(channel);\r
+       }\r
+\r
        if (hca_ptr->ib_hca_handle != IB_INVALID_HANDLE) {\r
                if (ibv_close_device(hca_ptr->ib_hca_handle))\r
                        return (dapl_convert_errno(errno, "ib_close_device"));\r
index e890eefff056d73325c51858f05e0d4e82543b9f..8eeaea37099aaf95fb33f82f173907a58994c600 100644 (file)
-/*
- * Copyright (c) 2009 Intel Corporation.  All rights reserved.
- *
- * This Software is licensed under one of the following licenses:
- *
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/cpl.php.
- *
- * 2) under the terms of the "The BSD License" a copy of which is
- *    available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- *
- * Licensee has the right to choose one of the above licenses.
- *
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- *
- * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
- * and/or other materials provided with the distribution.
- */
-
-#include "openib_osd.h"
-#include "dapl.h"
-#include "dapl_adapter_util.h"
-#include "dapl_ib_util.h"
-#include "dapl_osd.h"
-
-#include <stdlib.h>
-
-static void ucm_service_destroy(IN DAPL_HCA *hca);
-static int  ucm_service_create(IN DAPL_HCA *hca);
-
-#if defined (_WIN32)
-#include "..\..\..\..\..\etc\user\comp_channel.cpp"
-#include <rdma\winverbs.h>
-
-static int32_t create_os_signal(IN DAPL_HCA * hca_ptr)
-{
+/*\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
+#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
+static void ucm_service_destroy(IN DAPL_HCA *hca);\r
+static int  ucm_service_create(IN DAPL_HCA *hca);\r
+\r
+#if defined (_WIN32)\r
+#include "..\..\..\..\..\etc\user\comp_channel.cpp"\r
+#include <rdma\winverbs.h>\r
+\r
+static int32_t create_os_signal(IN DAPL_HCA * hca_ptr)\r
+{\r
        return CompSetInit(&hca_ptr->ib_trans.signal.set);\r
-}
-
-static void destroy_os_signal(IN DAPL_HCA * hca_ptr)
-{
+}\r
+\r
+static void destroy_os_signal(IN DAPL_HCA * hca_ptr)\r
+{\r
        CompSetCleanup(&hca_ptr->ib_trans.signal.set);\r
-}
-
-static int dapls_config_verbs(struct ibv_context *verbs)
-{
-       verbs->channel.Milliseconds = 0;
-       return 0;
-}
-
-static int dapls_config_comp_channel(struct ibv_comp_channel *channel)
-{
-       channel->comp_channel.Milliseconds = 0;
-       return 0;
-}
-
-#else // _WIN32
-
-static int32_t create_os_signal(IN DAPL_HCA * hca_ptr)
-{
-       DAPL_SOCKET listen_socket;
-       struct sockaddr_in addr;
-       socklen_t addrlen = sizeof(addr);
-       int ret;
-
-       listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-       if (listen_socket == DAPL_INVALID_SOCKET)
-               return 1;
-
-       memset(&addr, 0, sizeof addr);
-       addr.sin_family = AF_INET;
-       addr.sin_addr.s_addr = htonl(0x7f000001);
-       ret = bind(listen_socket, (struct sockaddr *)&addr, sizeof addr);
-       if (ret)
-               goto err1;
-
-       ret = getsockname(listen_socket, (struct sockaddr *)&addr, &addrlen);
-       if (ret)
-               goto err1;
-
-       ret = listen(listen_socket, 0);
-       if (ret)
-               goto err1;
-
-       hca_ptr->ib_trans.signal.scm[1] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-       if (hca_ptr->ib_trans.signal.scm[1] == DAPL_INVALID_SOCKET)
-               goto err1;
-
-       ret = connect(hca_ptr->ib_trans.signal.scm[1], 
-                     (struct sockaddr *)&addr, sizeof(addr));
-       if (ret)
-               goto err2;
-
-       hca_ptr->ib_trans.signal.scm[0] = accept(listen_socket, NULL, NULL);
-       if (hca_ptr->ib_trans.signal.scm[0] == DAPL_INVALID_SOCKET)
-               goto err2;
-
-       closesocket(listen_socket);
-       return 0;
-
-      err2:
-       closesocket(hca_ptr->ib_trans.signal.scm[1]);
-      err1:
-       closesocket(listen_socket);
-       return 1;
-}
-
-static void destroy_os_signal(IN DAPL_HCA * hca_ptr)
-{
-       closesocket(hca_ptr->ib_trans.signal.scm[0]);
-       closesocket(hca_ptr->ib_trans.signal.scm[1]);
-}
-
-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_verbs(struct ibv_context *verbs)
-{
-       return dapls_config_fd(verbs->async_fd);
-}
-
-static int dapls_config_comp_channel(struct ibv_comp_channel *channel)
-{
-       return dapls_config_fd(channel->fd);
-}
-
-#endif
-
-/*
- * 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)
-{
-       return 0;
-}
-
-int32_t dapls_ib_release(void)
-{
-       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 ibv_device **dev_list;
-       struct ibv_port_attr port_attr;
-       int i;
-       DAT_RETURN dat_status;
-
-       /* Get list of all IB devices, find match, open */
-       dev_list = ibv_get_device_list(NULL);
-       if (!dev_list) {
-               dapl_dbg_log(DAPL_DBG_TYPE_ERR,
-                            " open_hca: ibv_get_device_list() failed\n",
-                            hca_name);
-               return DAT_INTERNAL_ERROR;
-       }
-
-       for (i = 0; dev_list[i]; ++i) {
-               hca_ptr->ib_trans.ib_dev = dev_list[i];
-               if (!strcmp(ibv_get_device_name(hca_ptr->ib_trans.ib_dev),
-                           hca_name))
-                       goto found;
-       }
-
-       dapl_log(DAPL_DBG_TYPE_ERR,
-                " open_hca: device %s not found\n", hca_name);
-       goto err;
-
-found:
-
-       hca_ptr->ib_hca_handle = ibv_open_device(hca_ptr->ib_trans.ib_dev);
-       if (!hca_ptr->ib_hca_handle) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " open_hca: dev open failed for %s, err=%s\n",
-                        ibv_get_device_name(hca_ptr->ib_trans.ib_dev),
-                        strerror(errno));
-               goto err;
-       }
-       hca_ptr->ib_trans.ib_ctx = hca_ptr->ib_hca_handle;
-       dapls_config_verbs(hca_ptr->ib_hca_handle);
-       
-       /* get lid for this hca-port, network order */
-       if (ibv_query_port(hca_ptr->ib_hca_handle,
-                          (uint8_t)hca_ptr->port_num, &port_attr)) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " open_hca: get lid ERR for %s, err=%s\n",
-                        ibv_get_device_name(hca_ptr->ib_trans.ib_dev),
-                        strerror(errno));
-               goto err;
-       } else {
-               hca_ptr->ib_trans.addr.ib.lid = htons(port_attr.lid);
-       }
-
-       /* get gid for this hca-port, network order */
-       if (ibv_query_gid(hca_ptr->ib_hca_handle,
-                         (uint8_t) hca_ptr->port_num, 0,
-                         (union ibv_gid *)&hca_ptr->ib_trans.addr.ib.gid)) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " open_hca: query GID ERR for %s, err=%s\n",
-                        ibv_get_device_name(hca_ptr->ib_trans.ib_dev),
-                        strerror(errno));
-               goto err;
-       }
-
-       /* set RC tunables via enviroment or default */
-       hca_ptr->ib_trans.max_inline_send =
-           dapl_os_get_env_val("DAPL_MAX_INLINE", INLINE_SEND_IB_DEFAULT);
-       hca_ptr->ib_trans.ack_retry =
-           dapl_os_get_env_val("DAPL_ACK_RETRY", DCM_ACK_RETRY);
-       hca_ptr->ib_trans.ack_timer =
-           dapl_os_get_env_val("DAPL_ACK_TIMER", DCM_ACK_TIMER);
-       hca_ptr->ib_trans.rnr_retry =
-           dapl_os_get_env_val("DAPL_RNR_RETRY", DCM_RNR_RETRY);
-       hca_ptr->ib_trans.rnr_timer =
-           dapl_os_get_env_val("DAPL_RNR_TIMER", DCM_RNR_TIMER);
-       hca_ptr->ib_trans.global =
-           dapl_os_get_env_val("DAPL_GLOBAL_ROUTING", DCM_GLOBAL);
-       hca_ptr->ib_trans.hop_limit =
-           dapl_os_get_env_val("DAPL_HOP_LIMIT", DCM_HOP_LIMIT);
-       hca_ptr->ib_trans.tclass =
-           dapl_os_get_env_val("DAPL_TCLASS", DCM_TCLASS);
-       hca_ptr->ib_trans.mtu =
-           dapl_ib_mtu(dapl_os_get_env_val("DAPL_IB_MTU", DCM_IB_MTU));
-
-       /* initialize CM list, LISTEN, SND queue, PSP array, locks */
-       if ((dapl_os_lock_init(&hca_ptr->ib_trans.lock)) != DAT_SUCCESS)
-               goto err;
-       
-       if ((dapl_os_lock_init(&hca_ptr->ib_trans.llock)) != DAT_SUCCESS)
-               goto err;
-       
-       if ((dapl_os_lock_init(&hca_ptr->ib_trans.slock)) != DAT_SUCCESS)
-               goto err;
-
-       if ((dapl_os_lock_init(&hca_ptr->ib_trans.plock)) != DAT_SUCCESS)
-               goto err;
-
-       /* EVD events without direct CQ channels, CNO support */
-       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;
-       }
-       dapls_config_comp_channel(hca_ptr->ib_trans.ib_cq);
-
-       /* initialize CM and listen lists on this HCA uCM QP */
-       dapl_llist_init_head(&hca_ptr->ib_trans.list);
-       dapl_llist_init_head(&hca_ptr->ib_trans.llist);
-
-       /* create uCM qp services */
-       if (ucm_service_create(hca_ptr))
-               goto bail;
-
-       if (create_os_signal(hca_ptr)) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " open_hca: failed to init cr pipe - %s\n",
-                        strerror(errno));
-               goto bail;
-       }
-
-       /* create thread to process inbound connect request */
-       hca_ptr->ib_trans.cm_state = IB_THREAD_INIT;
-       dat_status = dapl_os_thread_create(cm_thread,
-                                          (void *)hca_ptr,
-                                          &hca_ptr->ib_trans.thread);
-       if (dat_status != DAT_SUCCESS) {
-               dapl_log(DAPL_DBG_TYPE_ERR,
-                        " open_hca: failed to create thread\n");
-               goto bail;
-       }
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " open_hca: devname %s, ctx %p port %d, hostname_IP %s\n",
-                    ibv_get_device_name(hca_ptr->ib_trans.ib_dev),
-                    hca_ptr->ib_hca_handle,
-                    hca_ptr->port_num, 
-                    inet_ntoa(((struct sockaddr_in *)
-                              &hca_ptr->hca_address)->sin_addr));
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                    " open_hca: QPN 0x%x LID 0x%x GID Subnet 0x" F64x ""
-                    " ID 0x" F64x "\n", 
-                    ntohl(hca_ptr->ib_trans.addr.ib.qpn),
-                    ntohs(hca_ptr->ib_trans.addr.ib.lid), 
-                    (unsigned long long)
-                    ntohll(*(uint64_t*)&hca_ptr->ib_trans.addr.ib.gid[0]),
-                    (unsigned long long)
-                    ntohll(*(uint64_t*)&hca_ptr->ib_trans.addr.ib.gid[8]));
-
-       /* save LID, GID, QPN, PORT address information, for ia_queries */
-       /* Set AF_INET6 to insure callee address storage of 28 bytes */
-       hca_ptr->ib_trans.hca = hca_ptr;
-       hca_ptr->ib_trans.addr.ib.family = AF_INET6; 
-       hca_ptr->ib_trans.addr.ib.qp_type = IBV_QPT_UD;
-       memcpy(&hca_ptr->hca_address, 
-              &hca_ptr->ib_trans.addr, 
-              sizeof(union dcm_addr));
-
-       ibv_free_device_list(dev_list);
-
-       /* wait for cm_thread */
-       while (hca_ptr->ib_trans.cm_state != IB_THREAD_RUN) 
-               dapl_os_sleep_usec(1000);
-
-       return dat_status;
-
-bail:
-       ucm_service_destroy(hca_ptr);
-       ibv_close_device(hca_ptr->ib_hca_handle);
-       hca_ptr->ib_hca_handle = IB_INVALID_HANDLE;
-      
-err:
-       ibv_free_device_list(dev_list);
-       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\n", hca_ptr);
-
-       if (hca_ptr->ib_trans.cm_state == IB_THREAD_RUN) {
-               hca_ptr->ib_trans.cm_state = IB_THREAD_CANCEL;
-               dapls_thread_signal(&hca_ptr->ib_trans.signal);
-               while (hca_ptr->ib_trans.cm_state != IB_THREAD_EXIT) {
-                       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
-                               " close_hca: waiting for cr_thread\n");
-                       dapls_thread_signal(&hca_ptr->ib_trans.signal);
-                       dapl_os_sleep_usec(1000);
-               }
-       }
-
-       dapl_os_lock_destroy(&hca_ptr->ib_trans.lock);
-       dapl_os_lock_destroy(&hca_ptr->ib_trans.llock);
-       destroy_os_signal(hca_ptr);
-       ucm_service_destroy(hca_ptr);
-
-       if (hca_ptr->ib_hca_handle != IB_INVALID_HANDLE) {
-               if (ibv_close_device(hca_ptr->ib_hca_handle))
-                       return (dapl_convert_errno(errno, "ib_close_device"));
-               hca_ptr->ib_hca_handle = IB_INVALID_HANDLE;
-       }
-
-       return (DAT_SUCCESS);
-}
-
-/* Create uCM endpoint services, allocate remote_ah's array */
-static void ucm_service_destroy(IN DAPL_HCA *hca)
-{
-       ib_hca_transport_t *tp = &hca->ib_trans;
-       int msg_size = sizeof(ib_cm_msg_t);
-
-       if (tp->mr_sbuf)
-               ibv_dereg_mr(tp->mr_sbuf);
-
-       if (tp->mr_rbuf)
-               ibv_dereg_mr(tp->mr_rbuf);
-
-       if (tp->qp)
-               ibv_destroy_qp(tp->qp);
-
-       if (tp->scq)
-               ibv_destroy_cq(tp->scq);
-
-       if (tp->rcq)
-               ibv_destroy_cq(tp->rcq);
-
-       if (tp->rch)
-               ibv_destroy_comp_channel(tp->rch);
-
-       if (tp->ah) {
-               int i;
-
-               for (i = 0;i < 0xffff; i++) {
-                       if (tp->ah[i])
-                               ibv_destroy_ah(tp->ah[i]);
-               }
-               dapl_os_free(tp->ah, (sizeof(*tp->ah) * 0xffff));
-       }
-
-       if (tp->pd)
-               ibv_dealloc_pd(tp->pd);
-
-       if (tp->sid)
-               dapl_os_free(tp->sid, (sizeof(*tp->sid) * 0xffff));
-
-       if (tp->rbuf)
-               dapl_os_free(tp->rbuf, (msg_size * tp->qpe));
-
-       if (tp->sbuf)
-               dapl_os_free(tp->sbuf, (msg_size * tp->qpe));
-}
-
-static int ucm_service_create(IN DAPL_HCA *hca)
-{
-        struct ibv_qp_init_attr qp_create;
-       ib_hca_transport_t *tp = &hca->ib_trans;
-       struct ibv_recv_wr recv_wr, *recv_err;
-        struct ibv_sge sge;
-       int i, mlen = sizeof(ib_cm_msg_t);
-       int hlen = sizeof(struct ibv_grh); /* hdr included with UD recv */
-
-       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " ucm_create: \n");
-
-       /* setup CM timers and queue sizes */
-       tp->retries = dapl_os_get_env_val("DAPL_UCM_RETRY", DCM_RETRY_CNT);
-       tp->rep_time = dapl_os_get_env_val("DAPL_UCM_REP_TIME", DCM_REP_TIME);
-       tp->rtu_time = dapl_os_get_env_val("DAPL_UCM_RTU_TIME", DCM_RTU_TIME);
-       tp->cm_timer = DAPL_MIN(tp->rep_time,tp->rtu_time);
-       tp->qpe = dapl_os_get_env_val("DAPL_UCM_QP_SIZE", DCM_QP_SIZE);
-       tp->cqe = dapl_os_get_env_val("DAPL_UCM_CQ_SIZE", DCM_CQ_SIZE);
-       tp->pd = ibv_alloc_pd(hca->ib_hca_handle);
-        if (!tp->pd) 
-                goto bail;
-        
-        dapl_log(DAPL_DBG_TYPE_UTIL,
-                        " create_service: pd %p ctx %p handle 0x%x\n",
-                         tp->pd, tp->pd->context, tp->pd->handle);
-
-       tp->rch = ibv_create_comp_channel(hca->ib_hca_handle);
-       if (!tp->rch) 
-               goto bail;
-
-       tp->scq = ibv_create_cq(hca->ib_hca_handle, tp->cqe, hca, NULL, 0);
-       if (!tp->scq) 
-               goto bail;
-        
-       tp->rcq = ibv_create_cq(hca->ib_hca_handle, tp->cqe, hca, tp->rch, 0);
-       if (!tp->rcq) 
-               goto bail;
-
-       if(ibv_req_notify_cq(tp->rcq, 0))
-               goto bail; 
-       dapl_os_memzero((void *)&qp_create, sizeof(qp_create));
-       qp_create.qp_type = IBV_QPT_UD;
-       qp_create.send_cq = tp->scq;
-       qp_create.recv_cq = tp->rcq;
-       qp_create.cap.max_send_wr = qp_create.cap.max_recv_wr = tp->qpe;
-       qp_create.cap.max_send_sge = qp_create.cap.max_recv_sge = 1;
-       qp_create.cap.max_inline_data = tp->max_inline_send;
-       qp_create.qp_context = (void *)hca;
-
-       tp->qp = ibv_create_qp(tp->pd, &qp_create);
-       if (!tp->qp) 
-                goto bail;
-
-       tp->ah = (ib_ah_handle_t*) dapl_os_alloc(sizeof(ib_ah_handle_t) * 0xffff);
-       tp->sid = (uint8_t*) dapl_os_alloc(sizeof(uint8_t) * 0xffff);
-       tp->rbuf = (void*) dapl_os_alloc((mlen + hlen) * tp->qpe);
-       tp->sbuf = (void*) dapl_os_alloc(mlen * tp->qpe);
-
-       if (!tp->ah || !tp->rbuf || !tp->sbuf || !tp->sid)
-               goto bail;
-
-       (void)dapl_os_memzero(tp->ah, (sizeof(ib_ah_handle_t) * 0xffff));
-       (void)dapl_os_memzero(tp->sid, (sizeof(uint8_t) * 0xffff));
-       tp->sid[0] = 1; /* resv slot 0, 0 == no ports available */
-       (void)dapl_os_memzero(tp->rbuf, ((mlen + hlen) * tp->qpe));
-       (void)dapl_os_memzero(tp->sbuf, (mlen * tp->qpe));
-
-       tp->mr_sbuf = ibv_reg_mr(tp->pd, tp->sbuf, 
-                                (mlen * tp->qpe),
-                                IBV_ACCESS_LOCAL_WRITE);
-       if (!tp->mr_sbuf)
-               goto bail;
-
-       tp->mr_rbuf = ibv_reg_mr(tp->pd, tp->rbuf, 
-                                ((mlen + hlen) * tp->qpe),
-                                IBV_ACCESS_LOCAL_WRITE);
-       if (!tp->mr_rbuf)
-               goto bail;
-       
-       /* modify UD QP: init, rtr, rts */
-       if ((dapls_modify_qp_ud(hca, tp->qp)) != DAT_SUCCESS)
-               goto bail;
-
-       /* post receive buffers, setup head, tail pointers */
-       recv_wr.next = NULL;
-       recv_wr.sg_list = &sge;
-       recv_wr.num_sge = 1;
-       sge.length = mlen + hlen;
-       sge.lkey = tp->mr_rbuf->lkey;
-
-       for (i = 0; i < tp->qpe; i++) {
-               recv_wr.wr_id = 
-                       (uintptr_t)((char *)&tp->rbuf[i] + 
-                                   sizeof(struct ibv_grh));
-               sge.addr = (uintptr_t) &tp->rbuf[i];
-               if (ibv_post_recv(tp->qp, &recv_wr, &recv_err))
-                       goto bail;
-       }
-
-       /* save qp_num as part of ia_address, network order */
-       tp->addr.ib.qpn = htonl(tp->qp->qp_num);
-        return 0;
-bail:
-       dapl_log(DAPL_DBG_TYPE_ERR,
-                " ucm_create_services: ERR %s\n", strerror(errno));
-       ucm_service_destroy(hca);
-       return -1;
-}
-
-void ucm_async_event(struct dapl_hca *hca)
-{
-       struct ibv_async_event event;
-       struct _ib_hca_transport *tp = &hca->ib_trans;
-
-       dapl_log(DAPL_DBG_TYPE_WARN, " async_event(%p)\n", hca);
-
-       if (!ibv_get_async_event(hca->ib_hca_handle, &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 (tp->async_cq_error)
-                               tp->async_cq_error(hca->ib_hca_handle,
-                                                  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 (tp->async_qp_error)
-                               tp->async_qp_error(hca->ib_hca_handle,
-                                                  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 (tp->async_unafiliated)
-                               tp->async_unafiliated(hca->ib_hca_handle,
-                                                     &event,
-                                                     tp->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_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);
-       }
-}
-
+}\r
+\r
+static int dapls_config_verbs(struct ibv_context *verbs)\r
+{\r
+       verbs->channel.Milliseconds = 0;\r
+       return 0;\r
+}\r
+\r
+static int dapls_config_comp_channel(struct ibv_comp_channel *channel)\r
+{\r
+       channel->comp_channel.Milliseconds = 0;\r
+       return 0;\r
+}\r
+\r
+#else // _WIN32\r
+\r
+static int32_t create_os_signal(IN DAPL_HCA * hca_ptr)\r
+{\r
+       DAPL_SOCKET listen_socket;\r
+       struct sockaddr_in addr;\r
+       socklen_t addrlen = sizeof(addr);\r
+       int ret;\r
+\r
+       listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);\r
+       if (listen_socket == DAPL_INVALID_SOCKET)\r
+               return 1;\r
+\r
+       memset(&addr, 0, sizeof addr);\r
+       addr.sin_family = AF_INET;\r
+       addr.sin_addr.s_addr = htonl(0x7f000001);\r
+       ret = bind(listen_socket, (struct sockaddr *)&addr, sizeof addr);\r
+       if (ret)\r
+               goto err1;\r
+\r
+       ret = getsockname(listen_socket, (struct sockaddr *)&addr, &addrlen);\r
+       if (ret)\r
+               goto err1;\r
+\r
+       ret = listen(listen_socket, 0);\r
+       if (ret)\r
+               goto err1;\r
+\r
+       hca_ptr->ib_trans.signal.scm[1] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);\r
+       if (hca_ptr->ib_trans.signal.scm[1] == DAPL_INVALID_SOCKET)\r
+               goto err1;\r
+\r
+       ret = connect(hca_ptr->ib_trans.signal.scm[1], \r
+                     (struct sockaddr *)&addr, sizeof(addr));\r
+       if (ret)\r
+               goto err2;\r
+\r
+       hca_ptr->ib_trans.signal.scm[0] = accept(listen_socket, NULL, NULL);\r
+       if (hca_ptr->ib_trans.signal.scm[0] == DAPL_INVALID_SOCKET)\r
+               goto err2;\r
+\r
+       closesocket(listen_socket);\r
+       return 0;\r
+\r
+      err2:\r
+       closesocket(hca_ptr->ib_trans.signal.scm[1]);\r
+      err1:\r
+       closesocket(listen_socket);\r
+       return 1;\r
+}\r
+\r
+static void destroy_os_signal(IN DAPL_HCA * hca_ptr)\r
+{\r
+       closesocket(hca_ptr->ib_trans.signal.scm[0]);\r
+       closesocket(hca_ptr->ib_trans.signal.scm[1]);\r
+}\r
+\r
+static int dapls_config_fd(int fd)\r
+{\r
+       int opts;\r
+\r
+       opts = fcntl(fd, F_GETFL);\r
+       if (opts < 0 || fcntl(fd, F_SETFL, opts | O_NONBLOCK) < 0) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " dapls_config_fd: fcntl on fd %d ERR %d %s\n",\r
+                        fd, opts, strerror(errno));\r
+               return errno;\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+static int dapls_config_verbs(struct ibv_context *verbs)\r
+{\r
+       return dapls_config_fd(verbs->async_fd);\r
+}\r
+\r
+static int dapls_config_comp_channel(struct ibv_comp_channel *channel)\r
+{\r
+       return dapls_config_fd(channel->fd);\r
+}\r
+\r
+#endif\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
+       return 0;\r
+}\r
+\r
+int32_t dapls_ib_release(void)\r
+{\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 ibv_device **dev_list;\r
+       struct ibv_port_attr port_attr;\r
+       int i;\r
+       DAT_RETURN dat_status;\r
+\r
+       /* Get list of all IB devices, find match, open */\r
+       dev_list = ibv_get_device_list(NULL);\r
+       if (!dev_list) {\r
+               dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
+                            " open_hca: ibv_get_device_list() failed\n",\r
+                            hca_name);\r
+               return DAT_INTERNAL_ERROR;\r
+       }\r
+\r
+       for (i = 0; dev_list[i]; ++i) {\r
+               hca_ptr->ib_trans.ib_dev = dev_list[i];\r
+               if (!strcmp(ibv_get_device_name(hca_ptr->ib_trans.ib_dev),\r
+                           hca_name))\r
+                       goto found;\r
+       }\r
+\r
+       dapl_log(DAPL_DBG_TYPE_ERR,\r
+                " open_hca: device %s not found\n", hca_name);\r
+       goto err;\r
+\r
+found:\r
+\r
+       hca_ptr->ib_hca_handle = ibv_open_device(hca_ptr->ib_trans.ib_dev);\r
+       if (!hca_ptr->ib_hca_handle) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " open_hca: dev open failed for %s, err=%s\n",\r
+                        ibv_get_device_name(hca_ptr->ib_trans.ib_dev),\r
+                        strerror(errno));\r
+               goto err;\r
+       }\r
+       hca_ptr->ib_trans.ib_ctx = hca_ptr->ib_hca_handle;\r
+       dapls_config_verbs(hca_ptr->ib_hca_handle);\r
+       \r
+       /* get lid for this hca-port, network order */\r
+       if (ibv_query_port(hca_ptr->ib_hca_handle,\r
+                          (uint8_t)hca_ptr->port_num, &port_attr)) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " open_hca: get lid ERR for %s, err=%s\n",\r
+                        ibv_get_device_name(hca_ptr->ib_trans.ib_dev),\r
+                        strerror(errno));\r
+               goto err;\r
+       } else {\r
+               hca_ptr->ib_trans.addr.ib.lid = htons(port_attr.lid);\r
+       }\r
+\r
+       /* get gid for this hca-port, network order */\r
+       if (ibv_query_gid(hca_ptr->ib_hca_handle,\r
+                         (uint8_t) hca_ptr->port_num, 0,\r
+                         (union ibv_gid *)&hca_ptr->ib_trans.addr.ib.gid)) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " open_hca: query GID ERR for %s, err=%s\n",\r
+                        ibv_get_device_name(hca_ptr->ib_trans.ib_dev),\r
+                        strerror(errno));\r
+               goto err;\r
+       }\r
+\r
+       /* set RC tunables via enviroment or default */\r
+       hca_ptr->ib_trans.max_inline_send =\r
+           dapl_os_get_env_val("DAPL_MAX_INLINE", INLINE_SEND_IB_DEFAULT);\r
+       hca_ptr->ib_trans.ack_retry =\r
+           dapl_os_get_env_val("DAPL_ACK_RETRY", DCM_ACK_RETRY);\r
+       hca_ptr->ib_trans.ack_timer =\r
+           dapl_os_get_env_val("DAPL_ACK_TIMER", DCM_ACK_TIMER);\r
+       hca_ptr->ib_trans.rnr_retry =\r
+           dapl_os_get_env_val("DAPL_RNR_RETRY", DCM_RNR_RETRY);\r
+       hca_ptr->ib_trans.rnr_timer =\r
+           dapl_os_get_env_val("DAPL_RNR_TIMER", DCM_RNR_TIMER);\r
+       hca_ptr->ib_trans.global =\r
+           dapl_os_get_env_val("DAPL_GLOBAL_ROUTING", DCM_GLOBAL);\r
+       hca_ptr->ib_trans.hop_limit =\r
+           dapl_os_get_env_val("DAPL_HOP_LIMIT", DCM_HOP_LIMIT);\r
+       hca_ptr->ib_trans.tclass =\r
+           dapl_os_get_env_val("DAPL_TCLASS", DCM_TCLASS);\r
+       hca_ptr->ib_trans.mtu =\r
+           dapl_ib_mtu(dapl_os_get_env_val("DAPL_IB_MTU", DCM_IB_MTU));\r
+\r
+       /* initialize CM list, LISTEN, SND queue, PSP array, locks */\r
+       if ((dapl_os_lock_init(&hca_ptr->ib_trans.lock)) != DAT_SUCCESS)\r
+               goto err;\r
+       \r
+       if ((dapl_os_lock_init(&hca_ptr->ib_trans.llock)) != DAT_SUCCESS)\r
+               goto err;\r
+       \r
+       if ((dapl_os_lock_init(&hca_ptr->ib_trans.slock)) != DAT_SUCCESS)\r
+               goto err;\r
+\r
+       if ((dapl_os_lock_init(&hca_ptr->ib_trans.plock)) != DAT_SUCCESS)\r
+               goto err;\r
+\r
+       /* EVD events without direct CQ channels, CNO support */\r
+       hca_ptr->ib_trans.ib_cq =\r
+           ibv_create_comp_channel(hca_ptr->ib_hca_handle);\r
+       if (hca_ptr->ib_trans.ib_cq == NULL) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " open_hca: ibv_create_comp_channel ERR %s\n",\r
+                        strerror(errno));\r
+               goto bail;\r
+       }\r
+       dapls_config_comp_channel(hca_ptr->ib_trans.ib_cq);\r
+\r
+       /* initialize CM and listen lists on this HCA uCM QP */\r
+       dapl_llist_init_head(&hca_ptr->ib_trans.list);\r
+       dapl_llist_init_head(&hca_ptr->ib_trans.llist);\r
+\r
+       /* create uCM qp services */\r
+       if (ucm_service_create(hca_ptr))\r
+               goto bail;\r
+\r
+       if (create_os_signal(hca_ptr)) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " open_hca: failed to init cr pipe - %s\n",\r
+                        strerror(errno));\r
+               goto bail;\r
+       }\r
+\r
+       /* create thread to process inbound connect request */\r
+       hca_ptr->ib_trans.cm_state = IB_THREAD_INIT;\r
+       dat_status = dapl_os_thread_create(cm_thread,\r
+                                          (void *)hca_ptr,\r
+                                          &hca_ptr->ib_trans.thread);\r
+       if (dat_status != DAT_SUCCESS) {\r
+               dapl_log(DAPL_DBG_TYPE_ERR,\r
+                        " open_hca: failed to create thread\n");\r
+               goto bail;\r
+       }\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " open_hca: devname %s, ctx %p port %d, hostname_IP %s\n",\r
+                    ibv_get_device_name(hca_ptr->ib_trans.ib_dev),\r
+                    hca_ptr->ib_hca_handle,\r
+                    hca_ptr->port_num, \r
+                    inet_ntoa(((struct sockaddr_in *)\r
+                              &hca_ptr->hca_address)->sin_addr));\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                    " open_hca: QPN 0x%x LID 0x%x GID Subnet 0x" F64x ""\r
+                    " ID 0x" F64x "\n", \r
+                    ntohl(hca_ptr->ib_trans.addr.ib.qpn),\r
+                    ntohs(hca_ptr->ib_trans.addr.ib.lid), \r
+                    (unsigned long long)\r
+                    ntohll(*(uint64_t*)&hca_ptr->ib_trans.addr.ib.gid[0]),\r
+                    (unsigned long long)\r
+                    ntohll(*(uint64_t*)&hca_ptr->ib_trans.addr.ib.gid[8]));\r
+\r
+       /* save LID, GID, QPN, PORT address information, for ia_queries */\r
+       /* Set AF_INET6 to insure callee address storage of 28 bytes */\r
+       hca_ptr->ib_trans.hca = hca_ptr;\r
+       hca_ptr->ib_trans.addr.ib.family = AF_INET6; \r
+       hca_ptr->ib_trans.addr.ib.qp_type = IBV_QPT_UD;\r
+       memcpy(&hca_ptr->hca_address, \r
+              &hca_ptr->ib_trans.addr, \r
+              sizeof(union dcm_addr));\r
+\r
+       ibv_free_device_list(dev_list);\r
+\r
+       /* wait for cm_thread */\r
+       while (hca_ptr->ib_trans.cm_state != IB_THREAD_RUN) \r
+               dapl_os_sleep_usec(1000);\r
+\r
+       return dat_status;\r
+\r
+bail:\r
+       ucm_service_destroy(hca_ptr);\r
+       ibv_close_device(hca_ptr->ib_hca_handle);\r
+       hca_ptr->ib_hca_handle = IB_INVALID_HANDLE;\r
+      \r
+err:\r
+       ibv_free_device_list(dev_list);\r
+       return DAT_INTERNAL_ERROR;\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\n", hca_ptr);\r
+\r
+       if (hca_ptr->ib_trans.cm_state == IB_THREAD_RUN) {\r
+               hca_ptr->ib_trans.cm_state = IB_THREAD_CANCEL;\r
+               dapls_thread_signal(&hca_ptr->ib_trans.signal);\r
+               while (hca_ptr->ib_trans.cm_state != IB_THREAD_EXIT) {\r
+                       dapl_dbg_log(DAPL_DBG_TYPE_UTIL,\r
+                               " close_hca: waiting for cr_thread\n");\r
+                       dapls_thread_signal(&hca_ptr->ib_trans.signal);\r
+                       dapl_os_sleep_usec(1000);\r
+               }\r
+       }\r
+\r
+       dapl_os_lock_destroy(&hca_ptr->ib_trans.lock);\r
+       dapl_os_lock_destroy(&hca_ptr->ib_trans.llock);\r
+       destroy_os_signal(hca_ptr);\r
+       ucm_service_destroy(hca_ptr);\r
+\r
+       if (hca_ptr->ib_trans.ib_cq)\r
+               ibv_destroy_comp_channel(hca_ptr->ib_trans.ib_cq);\r
+\r
+       if (hca_ptr->ib_trans.ib_cq_empty) {\r
+               struct ibv_comp_channel *channel;\r
+               channel = hca_ptr->ib_trans.ib_cq_empty->channel;\r
+               ibv_destroy_cq(hca_ptr->ib_trans.ib_cq_empty);\r
+               ibv_destroy_comp_channel(channel);\r
+       }\r
+\r
+       if (hca_ptr->ib_hca_handle != IB_INVALID_HANDLE) {\r
+               if (ibv_close_device(hca_ptr->ib_hca_handle))\r
+                       return (dapl_convert_errno(errno, "ib_close_device"));\r
+               hca_ptr->ib_hca_handle = IB_INVALID_HANDLE;\r
+       }\r
+\r
+       return (DAT_SUCCESS);\r
+}\r
+\r
+/* Create uCM endpoint services, allocate remote_ah's array */\r
+static void ucm_service_destroy(IN DAPL_HCA *hca)\r
+{\r
+       ib_hca_transport_t *tp = &hca->ib_trans;\r
+       int msg_size = sizeof(ib_cm_msg_t);\r
+\r
+       if (tp->mr_sbuf)\r
+               ibv_dereg_mr(tp->mr_sbuf);\r
+\r
+       if (tp->mr_rbuf)\r
+               ibv_dereg_mr(tp->mr_rbuf);\r
+\r
+       if (tp->qp)\r
+               ibv_destroy_qp(tp->qp);\r
+\r
+       if (tp->scq)\r
+               ibv_destroy_cq(tp->scq);\r
+\r
+       if (tp->rcq)\r
+               ibv_destroy_cq(tp->rcq);\r
+\r
+       if (tp->rch)\r
+               ibv_destroy_comp_channel(tp->rch);\r
+\r
+       if (tp->ah) {\r
+               int i;\r
+\r
+               for (i = 0;i < 0xffff; i++) {\r
+                       if (tp->ah[i])\r
+                               ibv_destroy_ah(tp->ah[i]);\r
+               }\r
+               dapl_os_free(tp->ah, (sizeof(*tp->ah) * 0xffff));\r
+       }\r
+\r
+       if (tp->pd)\r
+               ibv_dealloc_pd(tp->pd);\r
+\r
+       if (tp->sid)\r
+               dapl_os_free(tp->sid, (sizeof(*tp->sid) * 0xffff));\r
+\r
+       if (tp->rbuf)\r
+               dapl_os_free(tp->rbuf, (msg_size * tp->qpe));\r
+\r
+       if (tp->sbuf)\r
+               dapl_os_free(tp->sbuf, (msg_size * tp->qpe));\r
+}\r
+\r
+static int ucm_service_create(IN DAPL_HCA *hca)\r
+{\r
+        struct ibv_qp_init_attr qp_create;\r
+       ib_hca_transport_t *tp = &hca->ib_trans;\r
+       struct ibv_recv_wr recv_wr, *recv_err;\r
+        struct ibv_sge sge;\r
+       int i, mlen = sizeof(ib_cm_msg_t);\r
+       int hlen = sizeof(struct ibv_grh); /* hdr included with UD recv */\r
+\r
+       dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " ucm_create: \n");\r
+\r
+       /* setup CM timers and queue sizes */\r
+       tp->retries = dapl_os_get_env_val("DAPL_UCM_RETRY", DCM_RETRY_CNT);\r
+       tp->rep_time = dapl_os_get_env_val("DAPL_UCM_REP_TIME", DCM_REP_TIME);\r
+       tp->rtu_time = dapl_os_get_env_val("DAPL_UCM_RTU_TIME", DCM_RTU_TIME);\r
+       tp->cm_timer = DAPL_MIN(tp->rep_time,tp->rtu_time);\r
+       tp->qpe = dapl_os_get_env_val("DAPL_UCM_QP_SIZE", DCM_QP_SIZE);\r
+       tp->cqe = dapl_os_get_env_val("DAPL_UCM_CQ_SIZE", DCM_CQ_SIZE);\r
+       tp->pd = ibv_alloc_pd(hca->ib_hca_handle);\r
+        if (!tp->pd) \r
+                goto bail;\r
+        \r
+        dapl_log(DAPL_DBG_TYPE_UTIL,\r
+                        " create_service: pd %p ctx %p handle 0x%x\n",\r
+                         tp->pd, tp->pd->context, tp->pd->handle);\r
+\r
+       tp->rch = ibv_create_comp_channel(hca->ib_hca_handle);\r
+       if (!tp->rch) \r
+               goto bail;\r
+\r
+       tp->scq = ibv_create_cq(hca->ib_hca_handle, tp->cqe, hca, NULL, 0);\r
+       if (!tp->scq) \r
+               goto bail;\r
+        \r
+       tp->rcq = ibv_create_cq(hca->ib_hca_handle, tp->cqe, hca, tp->rch, 0);\r
+       if (!tp->rcq) \r
+               goto bail;\r
+\r
+       if(ibv_req_notify_cq(tp->rcq, 0))\r
+               goto bail; \r
\r
+       dapl_os_memzero((void *)&qp_create, sizeof(qp_create));\r
+       qp_create.qp_type = IBV_QPT_UD;\r
+       qp_create.send_cq = tp->scq;\r
+       qp_create.recv_cq = tp->rcq;\r
+       qp_create.cap.max_send_wr = qp_create.cap.max_recv_wr = tp->qpe;\r
+       qp_create.cap.max_send_sge = qp_create.cap.max_recv_sge = 1;\r
+       qp_create.cap.max_inline_data = tp->max_inline_send;\r
+       qp_create.qp_context = (void *)hca;\r
+\r
+       tp->qp = ibv_create_qp(tp->pd, &qp_create);\r
+       if (!tp->qp) \r
+                goto bail;\r
+\r
+       tp->ah = (ib_ah_handle_t*) dapl_os_alloc(sizeof(ib_ah_handle_t) * 0xffff);\r
+       tp->sid = (uint8_t*) dapl_os_alloc(sizeof(uint8_t) * 0xffff);\r
+       tp->rbuf = (void*) dapl_os_alloc((mlen + hlen) * tp->qpe);\r
+       tp->sbuf = (void*) dapl_os_alloc(mlen * tp->qpe);\r
+\r
+       if (!tp->ah || !tp->rbuf || !tp->sbuf || !tp->sid)\r
+               goto bail;\r
+\r
+       (void)dapl_os_memzero(tp->ah, (sizeof(ib_ah_handle_t) * 0xffff));\r
+       (void)dapl_os_memzero(tp->sid, (sizeof(uint8_t) * 0xffff));\r
+       tp->sid[0] = 1; /* resv slot 0, 0 == no ports available */\r
+       (void)dapl_os_memzero(tp->rbuf, ((mlen + hlen) * tp->qpe));\r
+       (void)dapl_os_memzero(tp->sbuf, (mlen * tp->qpe));\r
+\r
+       tp->mr_sbuf = ibv_reg_mr(tp->pd, tp->sbuf, \r
+                                (mlen * tp->qpe),\r
+                                IBV_ACCESS_LOCAL_WRITE);\r
+       if (!tp->mr_sbuf)\r
+               goto bail;\r
+\r
+       tp->mr_rbuf = ibv_reg_mr(tp->pd, tp->rbuf, \r
+                                ((mlen + hlen) * tp->qpe),\r
+                                IBV_ACCESS_LOCAL_WRITE);\r
+       if (!tp->mr_rbuf)\r
+               goto bail;\r
+       \r
+       /* modify UD QP: init, rtr, rts */\r
+       if ((dapls_modify_qp_ud(hca, tp->qp)) != DAT_SUCCESS)\r
+               goto bail;\r
+\r
+       /* post receive buffers, setup head, tail pointers */\r
+       recv_wr.next = NULL;\r
+       recv_wr.sg_list = &sge;\r
+       recv_wr.num_sge = 1;\r
+       sge.length = mlen + hlen;\r
+       sge.lkey = tp->mr_rbuf->lkey;\r
+\r
+       for (i = 0; i < tp->qpe; i++) {\r
+               recv_wr.wr_id = \r
+                       (uintptr_t)((char *)&tp->rbuf[i] + \r
+                                   sizeof(struct ibv_grh));\r
+               sge.addr = (uintptr_t) &tp->rbuf[i];\r
+               if (ibv_post_recv(tp->qp, &recv_wr, &recv_err))\r
+                       goto bail;\r
+       }\r
+\r
+       /* save qp_num as part of ia_address, network order */\r
+       tp->addr.ib.qpn = htonl(tp->qp->qp_num);\r
+        return 0;\r
+bail:\r
+       dapl_log(DAPL_DBG_TYPE_ERR,\r
+                " ucm_create_services: ERR %s\n", strerror(errno));\r
+       ucm_service_destroy(hca);\r
+       return -1;\r
+}\r
+\r
+void ucm_async_event(struct dapl_hca *hca)\r
+{\r
+       struct ibv_async_event event;\r
+       struct _ib_hca_transport *tp = &hca->ib_trans;\r
+\r
+       dapl_log(DAPL_DBG_TYPE_WARN, " async_event(%p)\n", hca);\r
+\r
+       if (!ibv_get_async_event(hca->ib_hca_handle, &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 (tp->async_cq_error)\r
+                               tp->async_cq_error(hca->ib_hca_handle,\r
+                                                  event.element.cq,\r
+                                                  &event, (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 (tp->async_qp_error)\r
+                               tp->async_qp_error(hca->ib_hca_handle,\r
+                                                  ep_ptr->qp_handle,\r
+                                                  &event, (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 (tp->async_unafiliated)\r
+                               tp->async_unafiliated(hca->ib_hca_handle,\r
+                                                     &event,\r
+                                                     tp->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