00001
00002
00003
00004
00005
00006
00007
00013 #include "vipl_priv.h"
00014
00015
00037 VIP_ENTRY_POINT VIP_RETURN
00038 VipPostRecv (VIP_VI_HANDLE ViHandle,
00039 VIP_DESCRIPTOR * DescriptorPtr, VIP_MEM_HANDLE MemoryHandle)
00040 {
00041 VIP_VI *vip_vi_ptr;
00042 VIP_GM *vip_gm_ptr;
00043 VIP_NIC *vip_nic_ptr;
00044 VIP_UINT32 vip_vi_ptag_id;
00045 VIP_DEBUG_LABEL (("VipPostRecv"));
00046
00047
00048 vip_vi_ptr = (VIP_VI *) ViHandle;
00049 if (VIP_INVALID_VI_HANDLE (vip_vi_ptr))
00050 {
00051 VIP_DEBUG (("Invalid VI handle"));
00052 return VIP_INVALID_PARAMETER;
00053 }
00054 vip_nic_ptr = vip_vi_ptr->handle.vip_nic_ptr;
00055 vip_gm_ptr = vip_nic_ptr->vip_gm_ptr;
00056 VIP_MUTEX_LOCK (&(vip_gm_ptr->lock));
00057 VIP_MUTEX_LOCK (&(vip_nic_ptr->lock));
00058
00059 vip_vi_ptr->recv_queue.total_count++;
00060
00061
00062 if (DescriptorPtr == NULL)
00063 {
00064 VIP_DEBUG (("Descriptor is NULL"));
00065 goto async_post_desc_error;
00066 }
00067
00068
00069 if (VIP_INVALID_PTAG_HANDLE (vip_vi_ptr->vip_ptag_ptr))
00070 {
00071 VIP_DEBUG (("Invalid VI PTAG handle"));
00072 goto async_post_desc_error;
00073 }
00074 vip_vi_ptag_id = vip_vi_ptr->vip_ptag_ptr->id;
00075
00076
00077 if ((((VIP_UINTPTR) DescriptorPtr) & 0x3F) != 0)
00078 {
00079 VIP_DEBUG (("Descriptor is not aligned on a 64 Bytes boundary"));
00080 goto async_post_desc_error;
00081 }
00082
00083
00084 if (vip_check_memory_handle (vip_nic_ptr, MemoryHandle,
00085 (VIP_UINT64) ((VIP_UINTPTR) DescriptorPtr),
00086 sizeof (VIP_CONTROL_SEGMENT),
00087 vip_vi_ptag_id) != VIP_SUCCESS)
00088 {
00089 VIP_DEBUG (("Control segment Memory Handle check error"));
00090 goto async_post_desc_error;
00091 }
00092
00093 DescriptorPtr->CS.Next.AddressBits = 0;
00094 DescriptorPtr->CS.NextHandle = 0;
00095 DescriptorPtr->CS.Status = 0;
00096
00097
00098 if (vip_vi_ptr->recv_queue.last != NULL)
00099 {
00100
00101 VIP_ASSERT (vip_vi_ptr->recv_queue.first != NULL);
00102 VIP_ASSERT (vip_vi_ptr->recv_queue.total_count > 1);
00103 vip_vi_ptr->recv_queue.last->CS.Next.Address = DescriptorPtr;
00104 vip_vi_ptr->recv_queue.last->CS.NextHandle = MemoryHandle;
00105 vip_vi_ptr->recv_queue.last = DescriptorPtr;
00106 if (vip_vi_ptr->recv_queue.count_to_process == 0)
00107 {
00108 VIP_ASSERT (vip_vi_ptr->recv_queue.current_desc == NULL);
00109 vip_vi_ptr->recv_queue.current_desc = DescriptorPtr;
00110 vip_vi_ptr->recv_queue.current_mem = MemoryHandle;
00111 }
00112 }
00113 else
00114 {
00115 VIP_ASSERT (vip_vi_ptr->recv_queue.first == NULL);
00116 VIP_ASSERT (vip_vi_ptr->recv_queue.current_desc == NULL);
00117 VIP_ASSERT (vip_vi_ptr->recv_queue.count_to_process == 0);
00118 VIP_ASSERT (vip_vi_ptr->recv_queue.total_count == 1);
00119 vip_vi_ptr->recv_queue.first = DescriptorPtr;
00120 vip_vi_ptr->recv_queue.last = DescriptorPtr;
00121 vip_vi_ptr->recv_queue.current_desc = DescriptorPtr;
00122 vip_vi_ptr->recv_queue.current_mem = MemoryHandle;
00123 }
00124 vip_vi_ptr->recv_queue.count_to_process++;
00125
00126
00127 if (vip_vi_ptr->state == VIP_STATE_ERROR)
00128 {
00129 VIP_DEBUG (("VI is in error state"));
00130
00131
00132 DescriptorPtr->CS.Status |= VIP_STATUS_DESC_FLUSHED_ERROR;
00133 VIP_ASSERT (vip_vi_ptr->recv_queue.count_to_process == 1);
00134 vip_notify_desc_completion (DescriptorPtr, vip_vi_ptr, VIP_TRUE);
00135 vip_vi_ptr->recv_queue.current_desc = NULL;
00136 vip_vi_ptr->recv_queue.current_mem = 0;
00137 vip_vi_ptr->recv_queue.count_to_process = 0;
00138 }
00139
00140 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00141 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00142 return VIP_SUCCESS;
00143
00144 async_post_desc_error:
00145
00146 vip_generate_async_error (vip_nic_ptr, vip_vi_ptr, NULL, DescriptorPtr,
00147 VIP_RESOURCE_DESCRIPTOR, VIP_ERROR_POST_DESC, 0);
00148
00149 if (vip_vi_ptr->state != VIP_STATE_ERROR)
00150 {
00151
00152 vip_vi_transition_to_error_state (vip_vi_ptr, VIP_TRUE);
00153
00154
00155 vip_generate_async_error (vip_nic_ptr, vip_vi_ptr, NULL, NULL,
00156 VIP_RESOURCE_VI, VIP_ERROR_CONN_LOST, 0);
00157 }
00158
00159 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00160 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00161 VIP_DEBUG (("Post Descriptor error"));
00162 return VIP_SUCCESS;
00163 }