19e39c5baSBill Taylor /*
29e39c5baSBill Taylor * CDDL HEADER START
39e39c5baSBill Taylor *
49e39c5baSBill Taylor * The contents of this file are subject to the terms of the
59e39c5baSBill Taylor * Common Development and Distribution License (the "License").
69e39c5baSBill Taylor * You may not use this file except in compliance with the License.
79e39c5baSBill Taylor *
89e39c5baSBill Taylor * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99e39c5baSBill Taylor * or http://www.opensolaris.org/os/licensing.
109e39c5baSBill Taylor * See the License for the specific language governing permissions
119e39c5baSBill Taylor * and limitations under the License.
129e39c5baSBill Taylor *
139e39c5baSBill Taylor * When distributing Covered Code, include this CDDL HEADER in each
149e39c5baSBill Taylor * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159e39c5baSBill Taylor * If applicable, add the following below this CDDL HEADER, with the
169e39c5baSBill Taylor * fields enclosed by brackets "[]" replaced with your own identifying
179e39c5baSBill Taylor * information: Portions Copyright [yyyy] [name of copyright owner]
189e39c5baSBill Taylor *
199e39c5baSBill Taylor * CDDL HEADER END
209e39c5baSBill Taylor */
219e39c5baSBill Taylor
229e39c5baSBill Taylor /*
239e39c5baSBill Taylor * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
249e39c5baSBill Taylor */
259e39c5baSBill Taylor
269e39c5baSBill Taylor /*
279e39c5baSBill Taylor * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
289e39c5baSBill Taylor * Use is subject to license terms.
299e39c5baSBill Taylor */
309e39c5baSBill Taylor
319e39c5baSBill Taylor /*
329e39c5baSBill Taylor *
339e39c5baSBill Taylor * MODULE: dapl_osd.c
349e39c5baSBill Taylor *
359e39c5baSBill Taylor * PURPOSE: Operating System Dependent layer
369e39c5baSBill Taylor * Description:
379e39c5baSBill Taylor * Provide OS dependent functions with a canonical DAPL
389e39c5baSBill Taylor * interface. Designed to be portable and hide OS specific quirks
399e39c5baSBill Taylor * of common functions.
409e39c5baSBill Taylor *
419e39c5baSBill Taylor *
429e39c5baSBill Taylor * $Id: dapl_osd.c,v 1.26 2003/07/31 14:04:18 jlentini Exp $
439e39c5baSBill Taylor */
449e39c5baSBill Taylor
459e39c5baSBill Taylor #include "dapl_osd.h"
469e39c5baSBill Taylor #include "dapl.h"
479e39c5baSBill Taylor #include "dapl_hca_util.h"
489e39c5baSBill Taylor #include "dapl_ia_util.h"
499e39c5baSBill Taylor #include "dapl_rmr_util.h"
509e39c5baSBill Taylor #include "dapl_lmr_util.h"
519e39c5baSBill Taylor #include "dapl_pz_util.h"
529e39c5baSBill Taylor #include "dapl_ep_util.h"
539e39c5baSBill Taylor #include "dapl_cr_util.h"
549e39c5baSBill Taylor #include "dapl_evd_util.h"
559e39c5baSBill Taylor #include "dapl_sp_util.h"
569e39c5baSBill Taylor #include "dapl_adapter_util.h"
579e39c5baSBill Taylor #include "dapl_provider.h"
589e39c5baSBill Taylor #include "dapl_hash.h"
599e39c5baSBill Taylor #include "dapl_debug.h"
609e39c5baSBill Taylor
619e39c5baSBill Taylor #include <sys/time.h>
629e39c5baSBill Taylor #include <stdlib.h> /* needed for getenv() */
639e39c5baSBill Taylor #include <pthread.h> /* needed for pthread_atfork() */
649e39c5baSBill Taylor #include <signal.h> /* needed for thread setup */
659e39c5baSBill Taylor
669e39c5baSBill Taylor static void dapls_osd_fork_cleanup(void);
679e39c5baSBill Taylor
689e39c5baSBill Taylor /*
699e39c5baSBill Taylor * dapl_osd_init
709e39c5baSBill Taylor *
719e39c5baSBill Taylor * Do Linux initialization:
729e39c5baSBill Taylor * - Set up fork handler to clean up DAPL resources in the child
739e39c5baSBill Taylor * process after a fork().
749e39c5baSBill Taylor *
759e39c5baSBill Taylor * Input:
769e39c5baSBill Taylor * none
779e39c5baSBill Taylor *
789e39c5baSBill Taylor * Returns:
799e39c5baSBill Taylor * DAT_SUCCESS
809e39c5baSBill Taylor */
819e39c5baSBill Taylor void
dapl_os_init()829e39c5baSBill Taylor dapl_os_init()
839e39c5baSBill Taylor {
849e39c5baSBill Taylor int status;
859e39c5baSBill Taylor
869e39c5baSBill Taylor /*
879e39c5baSBill Taylor * Set up fork control
889e39c5baSBill Taylor */
899e39c5baSBill Taylor status = pthread_atfork(NULL, NULL, dapls_osd_fork_cleanup);
909e39c5baSBill Taylor if (status != 0) {
919e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_WARN,
929e39c5baSBill Taylor "WARNING: pthread_atfork %d\n", status);
939e39c5baSBill Taylor }
949e39c5baSBill Taylor }
959e39c5baSBill Taylor
969e39c5baSBill Taylor
979e39c5baSBill Taylor /*
989e39c5baSBill Taylor * dapl_os_get_time
999e39c5baSBill Taylor *
1009e39c5baSBill Taylor * Return 64 bit value of current time in microseconds.
1019e39c5baSBill Taylor *
1029e39c5baSBill Taylor * Input:
1039e39c5baSBill Taylor * loc User location to place current time
1049e39c5baSBill Taylor *
1059e39c5baSBill Taylor * Returns:
1069e39c5baSBill Taylor * DAT_SUCCESS
1079e39c5baSBill Taylor */
1089e39c5baSBill Taylor
1099e39c5baSBill Taylor DAT_RETURN
dapl_os_get_time(OUT DAPL_OS_TIMEVAL * loc)1109e39c5baSBill Taylor dapl_os_get_time(
1119e39c5baSBill Taylor OUT DAPL_OS_TIMEVAL * loc)
1129e39c5baSBill Taylor {
1139e39c5baSBill Taylor struct timeval tv;
1149e39c5baSBill Taylor struct timezone tz;
1159e39c5baSBill Taylor
1169e39c5baSBill Taylor
1179e39c5baSBill Taylor (void) gettimeofday(&tv, &tz);
1189e39c5baSBill Taylor *loc = ((DAT_UINT64)(tv.tv_sec) * 1000000L) + (DAT_UINT64) tv.tv_usec;
1199e39c5baSBill Taylor
1209e39c5baSBill Taylor return (DAT_SUCCESS);
1219e39c5baSBill Taylor }
1229e39c5baSBill Taylor
1239e39c5baSBill Taylor
1249e39c5baSBill Taylor /*
1259e39c5baSBill Taylor * dapl_os_get__env_bool
1269e39c5baSBill Taylor *
1279e39c5baSBill Taylor * Return boolean value of passed in environment variable: 1 if present,
1289e39c5baSBill Taylor * 0 if not
1299e39c5baSBill Taylor *
1309e39c5baSBill Taylor * Input:
1319e39c5baSBill Taylor *
1329e39c5baSBill Taylor *
1339e39c5baSBill Taylor * Returns:
1349e39c5baSBill Taylor * TRUE or FALSE
1359e39c5baSBill Taylor */
1369e39c5baSBill Taylor int
dapl_os_get_env_bool(char * env_str)1379e39c5baSBill Taylor dapl_os_get_env_bool(
1389e39c5baSBill Taylor char *env_str)
1399e39c5baSBill Taylor {
1409e39c5baSBill Taylor char *env_var;
1419e39c5baSBill Taylor
1429e39c5baSBill Taylor env_var = getenv(env_str);
1439e39c5baSBill Taylor if (env_var != NULL) {
1449e39c5baSBill Taylor return (1);
1459e39c5baSBill Taylor }
1469e39c5baSBill Taylor
1479e39c5baSBill Taylor return (0);
1489e39c5baSBill Taylor }
1499e39c5baSBill Taylor
1509e39c5baSBill Taylor
1519e39c5baSBill Taylor /*
1529e39c5baSBill Taylor * dapl_os_get_env_val
1539e39c5baSBill Taylor *
1549e39c5baSBill Taylor * Update val to value of passed in environment variable if present
1559e39c5baSBill Taylor *
1569e39c5baSBill Taylor * Input:
1579e39c5baSBill Taylor * env_str
1589e39c5baSBill Taylor * def_val default value if environment variable does not exist
1599e39c5baSBill Taylor *
1609e39c5baSBill Taylor * Returns:
1619e39c5baSBill Taylor * TRUE or FALSE
1629e39c5baSBill Taylor */
1639e39c5baSBill Taylor int
dapl_os_get_env_val(char * env_str,int def_val)1649e39c5baSBill Taylor dapl_os_get_env_val(
1659e39c5baSBill Taylor char *env_str,
1669e39c5baSBill Taylor int def_val)
1679e39c5baSBill Taylor {
1689e39c5baSBill Taylor char *env_var;
1699e39c5baSBill Taylor
1709e39c5baSBill Taylor env_var = getenv(env_str);
1719e39c5baSBill Taylor if (env_var != NULL) {
1729e39c5baSBill Taylor def_val = strtol(env_var, NULL, 0);
1739e39c5baSBill Taylor }
1749e39c5baSBill Taylor
1759e39c5baSBill Taylor return (def_val);
1769e39c5baSBill Taylor }
1779e39c5baSBill Taylor
1789e39c5baSBill Taylor
1799e39c5baSBill Taylor /*
1809e39c5baSBill Taylor * Wait object routines
1819e39c5baSBill Taylor */
1829e39c5baSBill Taylor
1839e39c5baSBill Taylor /*
1849e39c5baSBill Taylor * dapl_os_wait_object_init
1859e39c5baSBill Taylor *
1869e39c5baSBill Taylor * Initialize a wait object
1879e39c5baSBill Taylor *
1889e39c5baSBill Taylor * Input:
1899e39c5baSBill Taylor * wait_obj
1909e39c5baSBill Taylor *
1919e39c5baSBill Taylor * Returns:
1929e39c5baSBill Taylor * DAT_SUCCESS
1939e39c5baSBill Taylor * DAT_INTERNAL_ERROR
1949e39c5baSBill Taylor */
1959e39c5baSBill Taylor DAT_RETURN
dapl_os_wait_object_init(IN DAPL_OS_WAIT_OBJECT * wait_obj)1969e39c5baSBill Taylor dapl_os_wait_object_init(
1979e39c5baSBill Taylor IN DAPL_OS_WAIT_OBJECT *wait_obj)
1989e39c5baSBill Taylor {
1999e39c5baSBill Taylor wait_obj->signaled = DAT_FALSE;
2009e39c5baSBill Taylor if (0 != pthread_cond_init(&wait_obj->cv, NULL)) {
2019e39c5baSBill Taylor return (DAT_ERROR(DAT_INTERNAL_ERROR, 0));
2029e39c5baSBill Taylor }
2039e39c5baSBill Taylor
2049e39c5baSBill Taylor /* Always returns 0. */
2059e39c5baSBill Taylor (void) pthread_mutex_init(&wait_obj->lock, NULL);
2069e39c5baSBill Taylor
2079e39c5baSBill Taylor return (DAT_SUCCESS);
2089e39c5baSBill Taylor }
2099e39c5baSBill Taylor
2109e39c5baSBill Taylor
2119e39c5baSBill Taylor /*
2129e39c5baSBill Taylor * Wait on the supplied wait object, up to the specified time_out.
2139e39c5baSBill Taylor * A timeout of DAT_TIMEOUT_INFINITE will wait indefinitely.
2149e39c5baSBill Taylor * Timeout should be specified in micro seconds.
2159e39c5baSBill Taylor *
2169e39c5baSBill Taylor * Functional returns:
2179e39c5baSBill Taylor * DAT_SUCCESS -- another thread invoked dapl_os_wait object_wakeup
2189e39c5baSBill Taylor * DAT_INVALID_STATE -- someone else is already waiting in this wait
2199e39c5baSBill Taylor * object.
2209e39c5baSBill Taylor * only one waiter is allowed at a time.
2219e39c5baSBill Taylor * DAT_ABORT -- another thread invoked dapl_os_wait_object_destroy
2229e39c5baSBill Taylor * DAT_TIMEOUT -- the specified time limit was reached.
2239e39c5baSBill Taylor */
2249e39c5baSBill Taylor
2259e39c5baSBill Taylor DAT_RETURN
dapl_os_wait_object_wait(IN DAPL_OS_WAIT_OBJECT * wait_obj,IN DAT_TIMEOUT timeout_val)2269e39c5baSBill Taylor dapl_os_wait_object_wait(
2279e39c5baSBill Taylor IN DAPL_OS_WAIT_OBJECT *wait_obj,
2289e39c5baSBill Taylor IN DAT_TIMEOUT timeout_val)
2299e39c5baSBill Taylor {
2309e39c5baSBill Taylor DAT_RETURN dat_status;
2319e39c5baSBill Taylor int pthread_status;
2329e39c5baSBill Taylor struct timespec future;
2339e39c5baSBill Taylor
2349e39c5baSBill Taylor dat_status = DAT_SUCCESS;
2359e39c5baSBill Taylor pthread_status = 0;
2369e39c5baSBill Taylor
2379e39c5baSBill Taylor if (timeout_val != DAT_TIMEOUT_INFINITE) {
2389e39c5baSBill Taylor struct timeval now;
2399e39c5baSBill Taylor struct timezone tz;
2409e39c5baSBill Taylor unsigned int microsecs;
2419e39c5baSBill Taylor
2429e39c5baSBill Taylor (void) gettimeofday(&now, &tz);
2439e39c5baSBill Taylor microsecs = now.tv_usec + (timeout_val % 1000000);
2449e39c5baSBill Taylor if (microsecs > 1000000) {
2459e39c5baSBill Taylor now.tv_sec = now.tv_sec + timeout_val / 1000000 + 1;
2469e39c5baSBill Taylor now.tv_usec = microsecs - 1000000;
2479e39c5baSBill Taylor } else {
2489e39c5baSBill Taylor now.tv_sec = now.tv_sec + timeout_val / 1000000;
2499e39c5baSBill Taylor now.tv_usec = microsecs;
2509e39c5baSBill Taylor }
2519e39c5baSBill Taylor
2529e39c5baSBill Taylor /* Convert timeval to timespec */
2539e39c5baSBill Taylor future.tv_sec = now.tv_sec;
2549e39c5baSBill Taylor future.tv_nsec = now.tv_usec * 1000;
2559e39c5baSBill Taylor
2569e39c5baSBill Taylor (void) pthread_mutex_lock(&wait_obj->lock);
2579e39c5baSBill Taylor while (wait_obj->signaled == DAT_FALSE && pthread_status == 0) {
2589e39c5baSBill Taylor pthread_status = pthread_cond_timedwait(
2599e39c5baSBill Taylor &wait_obj->cv, &wait_obj->lock, &future);
2609e39c5baSBill Taylor
2619e39c5baSBill Taylor /*
2629e39c5baSBill Taylor * No need to reset &future if we go around the loop;
2639e39c5baSBill Taylor * It's an absolute time.
2649e39c5baSBill Taylor */
2659e39c5baSBill Taylor }
2669e39c5baSBill Taylor /* Reset the signaled status if we were woken up. */
2679e39c5baSBill Taylor if (pthread_status == 0) {
2689e39c5baSBill Taylor wait_obj->signaled = DAT_FALSE;
2699e39c5baSBill Taylor }
2709e39c5baSBill Taylor (void) pthread_mutex_unlock(&wait_obj->lock);
2719e39c5baSBill Taylor } else {
2729e39c5baSBill Taylor (void) pthread_mutex_lock(&wait_obj->lock);
2739e39c5baSBill Taylor while (wait_obj->signaled == DAT_FALSE && pthread_status == 0) {
2749e39c5baSBill Taylor pthread_status = pthread_cond_wait(
2759e39c5baSBill Taylor &wait_obj->cv, &wait_obj->lock);
2769e39c5baSBill Taylor }
2779e39c5baSBill Taylor /* Reset the signaled status if we were woken up. */
2789e39c5baSBill Taylor if (pthread_status == 0) {
2799e39c5baSBill Taylor wait_obj->signaled = DAT_FALSE;
2809e39c5baSBill Taylor }
2819e39c5baSBill Taylor (void) pthread_mutex_unlock(&wait_obj->lock);
2829e39c5baSBill Taylor }
2839e39c5baSBill Taylor
2849e39c5baSBill Taylor if (ETIMEDOUT == pthread_status) {
2859e39c5baSBill Taylor dat_status = DAT_ERROR(DAT_TIMEOUT_EXPIRED, 0);
2869e39c5baSBill Taylor } else if (0 != pthread_status) {
2879e39c5baSBill Taylor dat_status = DAT_ERROR(DAT_INTERNAL_ERROR, 0);
2889e39c5baSBill Taylor }
2899e39c5baSBill Taylor
2909e39c5baSBill Taylor return (dat_status);
2919e39c5baSBill Taylor }
2929e39c5baSBill Taylor
2939e39c5baSBill Taylor
2949e39c5baSBill Taylor /*
2959e39c5baSBill Taylor * dapl_os_wait_object_wakeup
2969e39c5baSBill Taylor *
2979e39c5baSBill Taylor * Wakeup a thread waiting on a wait object
2989e39c5baSBill Taylor *
2999e39c5baSBill Taylor * Input:
3009e39c5baSBill Taylor * wait_obj
3019e39c5baSBill Taylor *
3029e39c5baSBill Taylor * Returns:
3039e39c5baSBill Taylor * DAT_SUCCESS
3049e39c5baSBill Taylor * DAT_INTERNAL_ERROR
3059e39c5baSBill Taylor */
3069e39c5baSBill Taylor DAT_RETURN
dapl_os_wait_object_wakeup(IN DAPL_OS_WAIT_OBJECT * wait_obj)3079e39c5baSBill Taylor dapl_os_wait_object_wakeup(
3089e39c5baSBill Taylor IN DAPL_OS_WAIT_OBJECT *wait_obj)
3099e39c5baSBill Taylor {
3109e39c5baSBill Taylor (void) pthread_mutex_lock(&wait_obj->lock);
3119e39c5baSBill Taylor wait_obj->signaled = DAT_TRUE;
3129e39c5baSBill Taylor (void) pthread_mutex_unlock(&wait_obj->lock);
3139e39c5baSBill Taylor if (0 != pthread_cond_signal(&wait_obj->cv)) {
3149e39c5baSBill Taylor return (DAT_ERROR(DAT_INTERNAL_ERROR, 0));
3159e39c5baSBill Taylor }
3169e39c5baSBill Taylor
3179e39c5baSBill Taylor return (DAT_SUCCESS);
3189e39c5baSBill Taylor }
3199e39c5baSBill Taylor
3209e39c5baSBill Taylor
3219e39c5baSBill Taylor /*
3229e39c5baSBill Taylor * dapl_os_wait_object_destroy
3239e39c5baSBill Taylor *
3249e39c5baSBill Taylor * Destroy a wait object
3259e39c5baSBill Taylor *
3269e39c5baSBill Taylor * Input:
3279e39c5baSBill Taylor * wait_obj
3289e39c5baSBill Taylor *
3299e39c5baSBill Taylor * Returns:
3309e39c5baSBill Taylor * DAT_SUCCESS
3319e39c5baSBill Taylor * DAT_INTERNAL_ERROR
3329e39c5baSBill Taylor */
3339e39c5baSBill Taylor DAT_RETURN
dapl_os_wait_object_destroy(IN DAPL_OS_WAIT_OBJECT * wait_obj)3349e39c5baSBill Taylor dapl_os_wait_object_destroy(
3359e39c5baSBill Taylor IN DAPL_OS_WAIT_OBJECT *wait_obj)
3369e39c5baSBill Taylor {
3379e39c5baSBill Taylor if (0 != pthread_cond_destroy(&wait_obj->cv)) {
3389e39c5baSBill Taylor return (DAT_ERROR(DAT_INTERNAL_ERROR, 0));
3399e39c5baSBill Taylor }
3409e39c5baSBill Taylor if (0 != pthread_mutex_destroy(&wait_obj->lock)) {
3419e39c5baSBill Taylor return (DAT_ERROR(DAT_INTERNAL_ERROR, 0));
3429e39c5baSBill Taylor }
3439e39c5baSBill Taylor
3449e39c5baSBill Taylor return (DAT_SUCCESS);
3459e39c5baSBill Taylor }
3469e39c5baSBill Taylor
3479e39c5baSBill Taylor
3489e39c5baSBill Taylor /*
3499e39c5baSBill Taylor * dapls_osd_fork_cleanup
3509e39c5baSBill Taylor *
3519e39c5baSBill Taylor * Update val to value of passed in environment variable if present
3529e39c5baSBill Taylor *
3539e39c5baSBill Taylor * Input:
3549e39c5baSBill Taylor * env_str
3559e39c5baSBill Taylor * val Updated if environment variable exists
3569e39c5baSBill Taylor *
3579e39c5baSBill Taylor * Returns:
3589e39c5baSBill Taylor * TRUE or FALSE
3599e39c5baSBill Taylor */
3609e39c5baSBill Taylor void
dapls_osd_fork_cleanup(void)3619e39c5baSBill Taylor dapls_osd_fork_cleanup(void)
3629e39c5baSBill Taylor {
3639e39c5baSBill Taylor DAPL_PROVIDER_LIST_NODE *cur_node;
3649e39c5baSBill Taylor DAPL_HCA *hca_ptr;
3659e39c5baSBill Taylor DAPL_IA *ia_ptr;
3669e39c5baSBill Taylor DAPL_LMR *lmr_ptr;
3679e39c5baSBill Taylor DAPL_RMR *rmr_ptr;
3689e39c5baSBill Taylor DAPL_PZ *pz_ptr;
3699e39c5baSBill Taylor DAPL_CR *cr_ptr;
3709e39c5baSBill Taylor DAPL_EP *ep_ptr;
3719e39c5baSBill Taylor DAPL_EVD *evd_ptr;
3729e39c5baSBill Taylor DAT_EP_PARAM *param;
3739e39c5baSBill Taylor DAPL_SP *sp_ptr;
3749e39c5baSBill Taylor
3759e39c5baSBill Taylor while (NULL != g_dapl_provider_list.head) {
3769e39c5baSBill Taylor cur_node = g_dapl_provider_list.head;
3779e39c5baSBill Taylor g_dapl_provider_list.head = cur_node->next;
3789e39c5baSBill Taylor
3799e39c5baSBill Taylor hca_ptr = (DAPL_HCA *) cur_node->data.extension;
3809e39c5baSBill Taylor
3819e39c5baSBill Taylor /*
3829e39c5baSBill Taylor * Walk the list of IA ptrs & clean up. This is purposely
3839e39c5baSBill Taylor * a destructive list walk, we really don't want to preserve
3849e39c5baSBill Taylor * any of it.
3859e39c5baSBill Taylor */
3869e39c5baSBill Taylor while (!dapl_llist_is_empty(&hca_ptr->ia_list_head)) {
3879e39c5baSBill Taylor ia_ptr = (DAPL_IA *)
3889e39c5baSBill Taylor dapl_llist_peek_head(&hca_ptr->ia_list_head);
3899e39c5baSBill Taylor
3909e39c5baSBill Taylor /*
3919e39c5baSBill Taylor * The rest of the cleanup code is similar to
3929e39c5baSBill Taylor * dapl_ia_close, the big difference is that we don't
3939e39c5baSBill Taylor * release IB resources, only memory; the underlying IB
3949e39c5baSBill Taylor * subsystem doesn't deal with fork at all, so leave
3959e39c5baSBill Taylor * IB handles alone.
3969e39c5baSBill Taylor */
3979e39c5baSBill Taylor while (!dapl_llist_is_empty(&ia_ptr->rmr_list_head)) {
3989e39c5baSBill Taylor rmr_ptr = (DAPL_RMR *)
3999e39c5baSBill Taylor dapl_llist_peek_head(&ia_ptr->
4009e39c5baSBill Taylor rmr_list_head);
4019e39c5baSBill Taylor if (rmr_ptr->param.lmr_triplet.
4029e39c5baSBill Taylor virtual_address != 0) {
403*fb4cdc19SToomas Soome dapl_os_atomic_dec(&rmr_ptr->
4049e39c5baSBill Taylor lmr->lmr_ref_count);
4059e39c5baSBill Taylor rmr_ptr->param.lmr_triplet.
4069e39c5baSBill Taylor virtual_address = 0;
4079e39c5baSBill Taylor }
4089e39c5baSBill Taylor dapl_os_atomic_dec(&rmr_ptr->pz->pz_ref_count);
4099e39c5baSBill Taylor dapl_ia_unlink_rmr(rmr_ptr->header.owner_ia,
4109e39c5baSBill Taylor rmr_ptr);
4119e39c5baSBill Taylor dapl_rmr_dealloc(rmr_ptr);
4129e39c5baSBill Taylor }
4139e39c5baSBill Taylor
4149e39c5baSBill Taylor while (!dapl_llist_is_empty(&ia_ptr->rsp_list_head)) {
4159e39c5baSBill Taylor sp_ptr = (DAPL_SP *) dapl_llist_peek_head(
4169e39c5baSBill Taylor &ia_ptr->rsp_list_head);
4179e39c5baSBill Taylor dapl_os_atomic_dec(&((DAPL_EVD *)sp_ptr->
4189e39c5baSBill Taylor evd_handle)->evd_ref_count);
4199e39c5baSBill Taylor dapls_ia_unlink_sp(ia_ptr, sp_ptr);
4209e39c5baSBill Taylor dapls_sp_free_sp(sp_ptr);
4219e39c5baSBill Taylor }
4229e39c5baSBill Taylor
4239e39c5baSBill Taylor while (!dapl_llist_is_empty(&ia_ptr->ep_list_head)) {
4249e39c5baSBill Taylor ep_ptr = (DAPL_EP *) dapl_llist_peek_head(
4259e39c5baSBill Taylor &ia_ptr->ep_list_head);
4269e39c5baSBill Taylor param = &ep_ptr->param;
4279e39c5baSBill Taylor if (param->pz_handle != NULL) {
4289e39c5baSBill Taylor dapl_os_atomic_dec(&((DAPL_PZ *)param->
4299e39c5baSBill Taylor pz_handle)->pz_ref_count);
4309e39c5baSBill Taylor }
4319e39c5baSBill Taylor if (param->recv_evd_handle != NULL) {
4329e39c5baSBill Taylor dapl_os_atomic_dec(&((DAPL_EVD *)param->
4339e39c5baSBill Taylor recv_evd_handle)->evd_ref_count);
4349e39c5baSBill Taylor }
4359e39c5baSBill Taylor if (param->request_evd_handle) {
4369e39c5baSBill Taylor dapl_os_atomic_dec(&((DAPL_EVD *)param->
4379e39c5baSBill Taylor request_evd_handle)->evd_ref_count);
4389e39c5baSBill Taylor }
4399e39c5baSBill Taylor if (param->connect_evd_handle != NULL) {
4409e39c5baSBill Taylor dapl_os_atomic_dec(&((DAPL_EVD *)param->
4419e39c5baSBill Taylor connect_evd_handle)->evd_ref_count);
4429e39c5baSBill Taylor }
4439e39c5baSBill Taylor
4449e39c5baSBill Taylor /* ...and free the resource */
4459e39c5baSBill Taylor dapl_ia_unlink_ep(ia_ptr, ep_ptr);
4469e39c5baSBill Taylor dapl_ep_dealloc(ep_ptr);
4479e39c5baSBill Taylor }
4489e39c5baSBill Taylor
4499e39c5baSBill Taylor while (!dapl_llist_is_empty(&ia_ptr->lmr_list_head)) {
4509e39c5baSBill Taylor lmr_ptr = (DAPL_LMR *) dapl_llist_peek_head(
4519e39c5baSBill Taylor &ia_ptr->lmr_list_head);
4529e39c5baSBill Taylor
4539e39c5baSBill Taylor (void) dapls_hash_remove(lmr_ptr->header.
4549e39c5baSBill Taylor owner_ia->hca_ptr->lmr_hash_table,
4559e39c5baSBill Taylor lmr_ptr->param.lmr_context, NULL);
4569e39c5baSBill Taylor
4579e39c5baSBill Taylor pz_ptr = (DAPL_PZ *) lmr_ptr->param.pz_handle;
4589e39c5baSBill Taylor dapl_os_atomic_dec(&pz_ptr->pz_ref_count);
4599e39c5baSBill Taylor dapl_ia_unlink_lmr(lmr_ptr->header.owner_ia,
4609e39c5baSBill Taylor lmr_ptr);
4619e39c5baSBill Taylor dapl_lmr_dealloc(lmr_ptr);
4629e39c5baSBill Taylor }
4639e39c5baSBill Taylor
4649e39c5baSBill Taylor while (!dapl_llist_is_empty(&ia_ptr->psp_list_head)) {
4659e39c5baSBill Taylor sp_ptr = (DAPL_SP *) dapl_llist_peek_head(
4669e39c5baSBill Taylor &ia_ptr->psp_list_head);
4679e39c5baSBill Taylor while (!dapl_llist_is_empty(&sp_ptr->
4689e39c5baSBill Taylor cr_list_head)) {
4699e39c5baSBill Taylor cr_ptr = (DAPL_CR *)
4709e39c5baSBill Taylor dapl_llist_peek_head(
4719e39c5baSBill Taylor &sp_ptr->cr_list_head);
4729e39c5baSBill Taylor dapl_sp_remove_cr(sp_ptr, cr_ptr);
4739e39c5baSBill Taylor dapls_cr_free(cr_ptr);
4749e39c5baSBill Taylor }
4759e39c5baSBill Taylor
4769e39c5baSBill Taylor dapls_ia_unlink_sp(ia_ptr, sp_ptr);
4779e39c5baSBill Taylor dapl_os_atomic_dec(&((DAPL_EVD *)sp_ptr->
4789e39c5baSBill Taylor evd_handle)->evd_ref_count);
4799e39c5baSBill Taylor dapls_sp_free_sp(sp_ptr);
4809e39c5baSBill Taylor }
4819e39c5baSBill Taylor
4829e39c5baSBill Taylor while (!dapl_llist_is_empty(&ia_ptr->pz_list_head)) {
4839e39c5baSBill Taylor pz_ptr = (DAPL_PZ *)
4849e39c5baSBill Taylor dapl_llist_peek_head(&ia_ptr->pz_list_head);
4859e39c5baSBill Taylor dapl_ia_unlink_pz(pz_ptr->header.owner_ia,
4869e39c5baSBill Taylor pz_ptr);
4879e39c5baSBill Taylor dapl_pz_dealloc(pz_ptr);
4889e39c5baSBill Taylor }
4899e39c5baSBill Taylor
4909e39c5baSBill Taylor while (!dapl_llist_is_empty(&ia_ptr->evd_list_head)) {
4919e39c5baSBill Taylor evd_ptr = (DAPL_EVD *) dapl_llist_peek_head(
4929e39c5baSBill Taylor &ia_ptr->evd_list_head);
4939e39c5baSBill Taylor dapl_ia_unlink_evd(evd_ptr->header.owner_ia,
4949e39c5baSBill Taylor evd_ptr);
4959e39c5baSBill Taylor /*
4969e39c5baSBill Taylor * reset the cq_handle to avoid having it
4979e39c5baSBill Taylor * removed
4989e39c5baSBill Taylor */
4999e39c5baSBill Taylor evd_ptr->ib_cq_handle = IB_INVALID_HANDLE;
5009e39c5baSBill Taylor (void) dapls_evd_dealloc(evd_ptr);
5019e39c5baSBill Taylor }
5029e39c5baSBill Taylor
5039e39c5baSBill Taylor dapl_hca_unlink_ia(ia_ptr->hca_ptr, ia_ptr);
5049e39c5baSBill Taylor /*
5059e39c5baSBill Taylor * asycn error evd was taken care of above, reset the
5069e39c5baSBill Taylor * pointer
5079e39c5baSBill Taylor */
5089e39c5baSBill Taylor ia_ptr->async_error_evd = NULL;
5099e39c5baSBill Taylor dapls_ia_free(ia_ptr);
5109e39c5baSBill Taylor } /* end while( ia_ptr != NULL ) */
5119e39c5baSBill Taylor
5129e39c5baSBill Taylor
5139e39c5baSBill Taylor dapl_os_free(cur_node, sizeof (DAPL_PROVIDER_LIST_NODE));
5149e39c5baSBill Taylor } /* end while (NULL != g_dapl_provider_list.head) */
5159e39c5baSBill Taylor }
5169e39c5baSBill Taylor
5179e39c5baSBill Taylor
5189e39c5baSBill Taylor /*
5199e39c5baSBill Taylor * Local variables:
5209e39c5baSBill Taylor * c-indent-level: 4
5219e39c5baSBill Taylor * c-basic-offset: 4
5229e39c5baSBill Taylor * tab-width: 8
5239e39c5baSBill Taylor * End:
5249e39c5baSBill Taylor */
525