Main Page | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

vippostrecv.c

Go to the documentation of this file.
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 
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   /* check VI handle */
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   /* check descriptor */
00062   if (DescriptorPtr == NULL)
00063     {
00064       VIP_DEBUG (("Descriptor is NULL"));
00065       goto async_post_desc_error;
00066     }
00067 
00068   /* check VI PTAG handle */
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   /* check that the descriptor is aligned on a 64 Bytes boundary */
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   /* check MemoryHandle */
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   /* queue the recv descriptor */
00098   if (vip_vi_ptr->recv_queue.last != NULL)
00099     {
00100       /* there is already some descriptors in the queue */
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   /* check VI state immediately */
00127   if (vip_vi_ptr->state == VIP_STATE_ERROR)
00128     {
00129       VIP_DEBUG (("VI is in error state"));
00130 
00131       /* complete the current descriptor */
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   /* generate the asynchronous error */
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       /* the VI transition to error state */
00152       vip_vi_transition_to_error_state (vip_vi_ptr, VIP_TRUE);
00153 
00154       /* a connection lost asynchronous error is generated */
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 }
VI-GM-1.3 by Myricom © 1997-2006. Documentation generated on 20 May 2006 by doxygen 1.4.4.