
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 00045 VIP_ENTRY_POINT VIP_RETURN 00046 VipRecvDone (VIP_VI_HANDLE ViHandle, VIP_DESCRIPTOR ** DescriptorPtr) 00047 { 00048 VIP_VI *vip_vi_ptr; 00049 VIP_GM *vip_gm_ptr; 00050 VIP_NIC *vip_nic_ptr; 00051 VIP_DEBUG_LABEL (("VipRecvDone")); 00052 00053 /* check VI handle */ 00054 vip_vi_ptr = (VIP_VI *) ViHandle; 00055 if (VIP_INVALID_VI_HANDLE (vip_vi_ptr)) 00056 { 00057 VIP_DEBUG (("Invalid VI handle")); 00058 return VIP_INVALID_PARAMETER; 00059 } 00060 vip_nic_ptr = vip_vi_ptr->handle.vip_nic_ptr; 00061 vip_gm_ptr = vip_vi_ptr->handle.vip_nic_ptr->vip_gm_ptr; 00062 VIP_MUTEX_LOCK (&(vip_gm_ptr->lock)); 00063 VIP_PROGRESSION (vip_gm_ptr); 00064 VIP_MUTEX_LOCK (&(vip_nic_ptr->lock)); 00065 00066 /* check if recv queue empty */ 00067 if (vip_vi_ptr->recv_queue.total_count == 0) 00068 { 00069 VIP_DEBUG (("VI recv queue is empty")); 00070 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock)); 00071 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock)); 00072 *DescriptorPtr = NULL; 00073 return VIP_DESCRIPTOR_ERROR; 00074 } 00075 00076 /* check if recv descriptor is NULL */ 00077 if (vip_vi_ptr->recv_queue.first == NULL) 00078 { 00079 VIP_ASSERT (vip_vi_ptr->recv_queue.total_count > 0); 00080 vip_vi_ptr->recv_queue.total_count--; 00081 VIP_DEBUG (("Recv Descriptor was NULL")); 00082 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock)); 00083 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock)); 00084 *DescriptorPtr = NULL; 00085 return VIP_DESCRIPTOR_ERROR; 00086 } 00087 00088 /* check if descriptor is complete */ 00089 if ((vip_vi_ptr->recv_queue.first->CS.Status & VIP_STATUS_DONE) == 0) 00090 { 00091 VIP_DEBUG (("Descriptor is not complete")); 00092 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock)); 00093 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock)); 00094 *DescriptorPtr = NULL; 00095 return VIP_NOT_DONE; 00096 } 00097 00098 /* dequeue the descriptor */ 00099 *DescriptorPtr = vip_vi_ptr->recv_queue.first; 00100 VIP_ASSERT (vip_vi_ptr->recv_queue.total_count > 0); 00101 vip_vi_ptr->recv_queue.total_count--; 00102 vip_vi_ptr->recv_queue.first = (*DescriptorPtr)->CS.Next.Address; 00103 if (vip_vi_ptr->recv_queue.first == NULL) 00104 { 00105 VIP_ASSERT (vip_vi_ptr->recv_queue.last == *DescriptorPtr); 00106 vip_vi_ptr->recv_queue.last = NULL; 00107 } 00108 00109 /* check if error code in status */ 00110 if (((*DescriptorPtr)->CS.Status & VIP_STATUS_ERROR_MASK) != 0) 00111 { 00112 VIP_DEBUG (("Descriptor completed with error status")); 00113 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock)); 00114 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock)); 00115 return VIP_DESCRIPTOR_ERROR; 00116 } 00117 00118 VIP_DEBUG (("Success")); 00119 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock)); 00120 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock)); 00121 return VIP_SUCCESS; 00122 }
1.4.4.