
00001 /******************************************************** 00002 * Myricom VI-GM networking software and documentation * 00003 * Copyright (c) 2001 by Myricom, Inc. * 00004 * All rights reserved. * 00005 * See the file `COPYING' for copyright notice. * 00006 ********************************************************/ 00007 00013 #include "vipl_priv.h" 00014 00015 00039 VIP_ENTRY_POINT VIP_RETURN 00040 VipDestroyVi (VIP_VI_HANDLE ViHandle) 00041 { 00042 VIP_VI *vip_vi_ptr; 00043 VIP_NIC *vip_nic_ptr; 00044 VIP_DEBUG_LABEL (("VipDestroyVi")); 00045 00046 /* check vi handle */ 00047 vip_vi_ptr = (VIP_VI *) ViHandle; 00048 if (VIP_INVALID_VI_HANDLE (vip_vi_ptr)) 00049 { 00050 VIP_DEBUG (("Invalid NIC handle")); 00051 return VIP_INVALID_PARAMETER; 00052 } 00053 vip_nic_ptr = vip_vi_ptr->handle.vip_nic_ptr; 00054 VIP_MUTEX_LOCK (&(vip_nic_ptr->lock)); 00055 00056 /* check vi ref count */ 00057 if (vip_vi_ptr->handle.ref_count > 0) 00058 { 00059 VIP_DEBUG (("Pending network operation on the VI")); 00060 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock)); 00061 return VIP_ERROR_RESOURCE; 00062 } 00063 00064 /* check vi state */ 00065 if (vip_vi_ptr->state != VIP_STATE_IDLE) 00066 { 00067 VIP_DEBUG (("VI is not in idle state")); 00068 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock)); 00069 return VIP_INVALID_STATE; 00070 } 00071 00072 /* check for pending send descriptors */ 00073 if (vip_vi_ptr->send_queue.total_count > 0) 00074 { 00075 VIP_DEBUG (("VI has pending send descriptors")); 00076 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock)); 00077 return VIP_INVALID_STATE; 00078 } 00079 00080 /* check for pending receive descriptors */ 00081 if (vip_vi_ptr->recv_queue.total_count > 0) 00082 { 00083 VIP_DEBUG (("VI has pending receive descriptors")); 00084 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock)); 00085 return VIP_INVALID_STATE; 00086 } 00087 00088 /* cancel the send notify thread if needed */ 00089 if (vip_vi_ptr->send_queue.notify_initialized == VIP_TRUE) 00090 { 00091 vip_vi_ptr->send_queue.notify_cancelled = VIP_TRUE; 00092 VIP_SEMAPHORE_POST (&(vip_vi_ptr->send_queue.notify_tokens)); 00093 VIP_MUTEX_LOCK (&(vip_nic_ptr->vip_gm_ptr->lock)); 00094 VIP_EVENT_SIGNAL (&(vip_vi_ptr->send_queue.event)); 00095 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->vip_gm_ptr->lock)); 00096 VIP_THREAD_JOIN (vip_vi_ptr->send_queue.notify_thread); 00097 } 00098 00099 /* cancel the recv notify thread if needed */ 00100 if (vip_vi_ptr->recv_queue.notify_initialized == VIP_TRUE) 00101 { 00102 vip_vi_ptr->recv_queue.notify_cancelled = VIP_TRUE; 00103 VIP_SEMAPHORE_POST (&(vip_vi_ptr->recv_queue.notify_tokens)); 00104 VIP_MUTEX_LOCK (&(vip_nic_ptr->vip_gm_ptr->lock)); 00105 VIP_EVENT_SIGNAL (&(vip_vi_ptr->recv_queue.event)); 00106 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->vip_gm_ptr->lock)); 00107 VIP_THREAD_JOIN (vip_vi_ptr->recv_queue.notify_thread); 00108 } 00109 00110 /* decrease send CQ reference counter if needed */ 00111 if (vip_vi_ptr->send_queue.vip_cq_ptr != NULL) 00112 { 00113 VIP_ASSERT (vip_vi_ptr->send_queue.vip_cq_ptr->handle.ref_count > 0); 00114 vip_vi_ptr->send_queue.vip_cq_ptr->handle.ref_count--; 00115 } 00116 00117 /* decrease recv CQ reference counter if needed */ 00118 if (vip_vi_ptr->recv_queue.vip_cq_ptr != NULL) 00119 { 00120 VIP_ASSERT (vip_vi_ptr->recv_queue.vip_cq_ptr->handle.ref_count > 0); 00121 vip_vi_ptr->recv_queue.vip_cq_ptr->handle.ref_count--; 00122 } 00123 00124 /* decrease ptag reference counter */ 00125 VIP_ASSERT (vip_vi_ptr->vip_ptag_ptr->handle.ref_count > 0); 00126 vip_vi_ptr->vip_ptag_ptr->handle.ref_count--; 00127 00128 /* free the index in the VI ptrs tab and the vi handle itself */ 00129 vip_nic_ptr->vip_vi_ptrs[vip_vi_ptr->index] = 00130 ((VIP_VI *) ((VIP_UINTPTR) (vip_nic_ptr->vip_vi_index_free))); 00131 vip_nic_ptr->vip_vi_index_free = vip_vi_ptr->index; 00132 vip_vi_ptr->index = 0; 00133 vip_free_handle (&(vip_nic_ptr->vip_vi_set), (VIP_HANDLE *) vip_vi_ptr); 00134 00135 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock)); 00136 VIP_DEBUG (("Success")); 00137 return VIP_SUCCESS; 00138 }
1.4.4.