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

vipl_priv_recv.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 
00014 #ifndef WIN32
00015 #include <sys/time.h>
00016 #endif
00017 #include <stdlib.h>
00018 #include <string.h>
00019 
00020 #include "vipl_priv.h"
00021 
00039 void
00040 vip_return_report (VIP_GM * vip_gm_ptr,
00041                    VIP_NIC * vip_nic_ptr,
00042                    VIP_VI * vip_vi_ptr, 
00043                    VIP_UCHAR report, 
00044                    VIP_UCHAR recv_side)
00045 {
00046   VIP_SEND_REQ *vip_send_req_ptr;
00047   VIP_PACKET_REPORT *pkt_report_ptr;
00048   VIP_DEBUG_LABEL ("vip_return_report");
00049 
00050   if (vip_vi_ptr->gm_dest_port == 0)
00051     {
00052       VIP_DEBUG (("Report %d NOT sent back to unknown sender", report));
00053       return;
00054     }
00055   
00056   vip_send_req_ptr = vip_allocate_packet (vip_gm_ptr,
00057                                           sizeof (VIP_PACKET_REPORT));
00058   VIP_ASSERT (vip_send_req_ptr != NULL);
00059   pkt_report_ptr = (VIP_PACKET_REPORT *) (vip_send_req_ptr->ptr);
00060   pkt_report_ptr->type = VIP_HTON_UCHAR (VIP_REPORT_PKT);
00061   pkt_report_ptr->report = VIP_HTON_UCHAR (report);
00062   pkt_report_ptr->recv_side = VIP_HTON_UCHAR (recv_side);
00063   pkt_report_ptr->net_remote_nic_index = vip_vi_ptr->net_remote_nic_index;
00064   pkt_report_ptr->net_remote_vi_index = vip_vi_ptr->net_remote_vi_index;
00065 
00066   vip_send_req_ptr->type |= VIP_SEND_REQ_RELIABLE;
00067   vip_send_req_ptr->dest_port_id = (VIP_UCHAR) (vip_vi_ptr->gm_dest_port);
00068   vip_send_req_ptr->dest_gm_id = vip_vi_ptr->gm_dest_id;
00069   vip_send_req_ptr->vip_nic_ptr = vip_nic_ptr;
00070   vip_send_req_ptr->vip_vi_ptr = vip_vi_ptr;
00071   vip_send_data (vip_send_req_ptr);
00072 
00073   VIP_DEBUG (("Report %d sent back to sender", report));
00074 }
00075 
00094 static VIP_RETURN
00095 vip_check_nic_and_vi (VIP_GM * vip_gm_ptr,
00096                       gm_recv_event_t * event,
00097                       VIP_PACKET_EAGER_UR * ptr,
00098                       VIP_NIC ** result_vip_nic_ptr,
00099                       VIP_VI ** result_vip_vi_ptr, 
00100                       VIP_UCHAR recv_side)
00101 {
00102   VIP_NIC *vip_nic_ptr;
00103   VIP_VI *vip_vi_ptr;
00104   VIP_UINT16 vip_nic_index;
00105   VIP_UINT16 vip_vi_index;
00106   VIP_DEBUG_LABEL (("vip_check_nic_and_vi"));
00107 
00108   /* check NIC index */
00109   vip_nic_index = VIP_NTOH_UINT16 (ptr->net_remote_nic_index);
00110   VIP_ASSERT (vip_nic_index <= VI_GM_MAX_NIC_HANDLES);
00111   vip_nic_ptr = vip_gm_ptr->vip_nic_ptrs[vip_nic_index];
00112   if (VIP_INVALID_NIC_HANDLE (vip_nic_ptr))
00113     {
00114       VIP_DEBUG (("Invalid NIC index"));
00115       *result_vip_nic_ptr = NULL;
00116       *result_vip_vi_ptr = NULL;
00117       return VIP_INVALID_PARAMETER;
00118     }
00119   VIP_MUTEX_LOCK (&(vip_nic_ptr->lock));
00120 
00121   /* check vi handle ptr */
00122   vip_vi_index = VIP_NTOH_UINT16 (ptr->net_remote_vi_index);
00123   VIP_ASSERT (vip_vi_index <= VI_GM_MAX_VI);
00124   vip_vi_ptr = vip_nic_ptr->vip_vi_ptrs[vip_vi_index];
00125   if (VIP_INVALID_VI_HANDLE (vip_vi_ptr))
00126     {
00127       VIP_DEBUG (("Invalid VI index"));
00128       *result_vip_nic_ptr = vip_nic_ptr;
00129       *result_vip_vi_ptr = NULL;
00130       return VIP_INVALID_PARAMETER;
00131     }
00132 
00133   /* check that the sender is the other end of the VI */
00134   if ((vip_vi_ptr->gm_dest_port != gm_ntohc (event->recv.sender_port_id))
00135       || (vip_vi_ptr->gm_dest_id != gm_ntohs (event->recv.sender_node_id)))
00136     {
00137       VIP_DEBUG (("Sender is not the end of VI"));
00138       *result_vip_nic_ptr = vip_nic_ptr;
00139       *result_vip_vi_ptr = vip_vi_ptr;
00140       vip_return_report (vip_gm_ptr, vip_nic_ptr, vip_vi_ptr,
00141                          VIP_REPORT_INVALID_SENDER, recv_side);
00142       return VIP_INVALID_PARAMETER;
00143     }
00144 
00145   *result_vip_nic_ptr = vip_nic_ptr;
00146   *result_vip_vi_ptr = vip_vi_ptr;
00147   return VIP_SUCCESS;
00148 }
00149 
00167 static void
00168 vip_handle_matching_message (VIP_PACKET * inc_ptr,
00169                              gm_recv_event_t * event, 
00170                              VIP_GM * vip_gm_ptr)
00171 {
00172   VIP_VI *vip_vi_ptr;
00173   VIP_NIC *vip_nic_ptr;
00174   VIP_UINT32 vip_vi_ptag_id;
00175   VIP_UINT32 total_length;
00176   VIP_UINT32 length;
00177   VIP_UINT32 data_length;
00178   VIP_UINT32 i;
00179   VIP_PVOID data_ptr;
00180   VIP_PACKET *pkt_ptr;
00181   VIP_DESCRIPTOR *vip_desc_ptr;
00182   VIP_SEND_REQ *vip_send_req_ptr;
00183   VIP_DATA_SEGMENT *vip_data_segment_ptr;
00184   VIP_DEBUG_LABEL (("vip_handle_matching_message"));
00185 
00186   length = (((VIP_NTOH_UCHAR (inc_ptr->vip_pkt_eager_ur.length_24)) << 16)
00187             + ((VIP_NTOH_UCHAR (inc_ptr->vip_pkt_eager_ur.length_16)) << 8)
00188             + VIP_NTOH_UCHAR (inc_ptr->vip_pkt_eager_ur.length_8));
00189 
00190   /* check the NIC and VI */
00191   if (vip_check_nic_and_vi (vip_gm_ptr, event,
00192                             (VIP_PACKET_EAGER_UR *) inc_ptr, &vip_nic_ptr,
00193                             &vip_vi_ptr, VIP_TRUE) != VIP_SUCCESS)
00194     {
00195       if (vip_nic_ptr != NULL)
00196         {
00197           VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00198         }
00199       return;
00200     }
00201 
00202   /* check if the VI is in connected state */
00203   if (vip_vi_ptr->state != VIP_STATE_CONNECTED)
00204     {
00205       VIP_DEBUG (("VI is not in connected state, refuse incoming packet"));
00206       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00207       return;
00208     }
00209 
00210   /* check if the recv queue is empty */
00211   if (vip_vi_ptr->recv_queue.count_to_process <= 0)
00212     {
00213       /* recv queue empty */
00214       VIP_ASSERT (vip_vi_ptr->recv_queue.current_desc == NULL);
00215       switch (vip_vi_ptr->reliability)
00216         {
00217         case VIP_SERVICE_UNRELIABLE:
00218           if ((VIP_NTOH_UCHAR (inc_ptr->type) == VIP_3WAY_REQ_PKT)
00219               || (VIP_NTOH_UCHAR (inc_ptr->type) == VIP_PUT_REQ_IMM_PKT))
00220             {
00221               /* return a remote descriptor error report */
00222               vip_return_report (vip_gm_ptr, vip_nic_ptr, vip_vi_ptr,
00223                                  VIP_REPORT_RECV_QUEUE_EMPTY, VIP_TRUE);
00224             }
00225           break;
00226 
00227         case VIP_SERVICE_RELIABLE_DELIVERY:
00228           if ((VIP_NTOH_UCHAR (inc_ptr->type) == VIP_3WAY_REQ_PKT)
00229               || (VIP_NTOH_UCHAR (inc_ptr->type) == VIP_PUT_REQ_IMM_PKT))
00230             {
00231               /* return a remote descriptor error report */
00232               vip_return_report (vip_gm_ptr, vip_nic_ptr, vip_vi_ptr,
00233                                  VIP_REPORT_RECV_QUEUE_EMPTY, VIP_TRUE);
00234             }
00235 
00236           /* the VI transition to error state */
00237           vip_vi_transition_to_error_state (vip_vi_ptr, VIP_TRUE);
00238 
00239           /* generate the asynchronous error */
00240           vip_generate_async_error (vip_nic_ptr, vip_vi_ptr, NULL, NULL,
00241                                     VIP_RESOURCE_VI, VIP_ERROR_RECVQ_EMPTY,
00242                                     VIP_STATUS_OP_RECEIVE);
00243 
00244           /* a connection lost asynchronous error is generated */
00245           vip_generate_async_error (vip_nic_ptr, vip_vi_ptr, NULL, NULL,
00246                                     VIP_RESOURCE_VI, VIP_ERROR_CONN_LOST, 0);
00247           break;
00248 
00249         case VIP_SERVICE_RELIABLE_RECEPTION:
00250           /* generate the asynchronous error */
00251           vip_generate_async_error (vip_nic_ptr, vip_vi_ptr, NULL, NULL,
00252                                     VIP_RESOURCE_VI, VIP_ERROR_RECVQ_EMPTY,
00253                                     VIP_STATUS_OP_RECEIVE);
00254 
00255           /* generate the asynchronous error */
00256           vip_generate_async_error (vip_nic_ptr, vip_vi_ptr, NULL, NULL,
00257                                     VIP_RESOURCE_VI, VIP_ERROR_CONN_LOST, 0);
00258 
00259           /* the VI transition to error state */
00260           vip_vi_transition_to_error_state (vip_vi_ptr, VIP_FALSE);
00261 
00262           /* return a remote descriptor error report */
00263           vip_return_report (vip_gm_ptr, vip_nic_ptr, vip_vi_ptr,
00264                              VIP_REPORT_RECV_QUEUE_EMPTY, VIP_TRUE);
00265           break;
00266         }
00267 
00268       VIP_DEBUG (("No descriptors on the receive queue"));
00269       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00270       return;
00271     }
00272   else
00273     {
00274       total_length = 0;
00275       vip_desc_ptr = vip_vi_ptr->recv_queue.current_desc;
00276       vip_vi_ptag_id = vip_vi_ptr->vip_ptag_ptr->id;
00277       VIP_ASSERT (vip_vi_ptr->state == VIP_STATE_CONNECTED);
00278       VIP_ASSERT ((vip_desc_ptr->CS.Status & VIP_STATUS_DONE) == 0);
00279 
00280       /* check MemoryHandle */
00281       if (vip_check_memory_handle (vip_nic_ptr,
00282                                    vip_vi_ptr->recv_queue.current_mem,
00283                                    (VIP_UINTPTR) vip_desc_ptr,
00284                                    sizeof (VIP_CONTROL_SEGMENT),
00285                                    vip_vi_ptag_id) != VIP_SUCCESS)
00286         {
00287           VIP_DEBUG (("Control segment Memory Handle completion check error"));
00288           goto async_comp_desc_error;
00289         }
00290 
00291       /* check reserved part of the control field */
00292       if ((vip_desc_ptr->CS.Control & VIP_CONTROL_RESERVED) != 0)
00293         {
00294           VIP_DEBUG (("Control field reserved part is not set to 0"));
00295           vip_desc_ptr->CS.Status |= VIP_STATUS_FORMAT_ERROR;
00296           goto out_with_sync_error;
00297         }
00298 
00299       /* check that the Reserved field is set to 0 */
00300       if (vip_desc_ptr->CS.Reserved != 0)
00301         {
00302           VIP_DEBUG (("Reserved field is not set to 0"));
00303           vip_desc_ptr->CS.Status |= VIP_STATUS_FORMAT_ERROR;
00304           goto out_with_sync_error;
00305         }
00306 
00307       /* check number of segments */
00308       if (vip_desc_ptr->CS.SegCount > VI_GM_MAX_SEGMENTS_PER_DESCRIPTOR)
00309         {
00310           VIP_DEBUG (("Number of Address/Data segments is exceeding capacity "
00311                       "(max=%d)", VI_GM_MAX_SEGMENTS_PER_DESCRIPTOR));
00312           vip_desc_ptr->CS.Status |= VIP_STATUS_LENGTH_ERROR;
00313           goto out_with_sync_error;
00314         }
00315 
00316       /* check length of data */
00317       VIP_ASSERT (vip_vi_ptr->mtu <= VI_GM_MAX_TRANSFER_SIZE);
00318       if (vip_desc_ptr->CS.Length > vip_vi_ptr->mtu)
00319         {
00320           VIP_DEBUG (("Data length is exceeding the MTU of the VI"));
00321           vip_desc_ptr->CS.Status |= VIP_STATUS_LENGTH_ERROR;
00322           goto out_with_sync_error;
00323         }
00324 
00325       /* check MemoryHandle for data */
00326       if (vip_check_memory_handle (vip_nic_ptr,
00327                                    vip_vi_ptr->recv_queue.current_mem,
00328                                    (VIP_UINTPTR) vip_desc_ptr,
00329                                    (sizeof (VIP_CONTROL_SEGMENT)
00330                                     + (vip_desc_ptr->CS.SegCount
00331                                        * sizeof (VIP_DESCRIPTOR_SEGMENT))),
00332                                    vip_vi_ptag_id) != VIP_SUCCESS)
00333         {
00334           VIP_DEBUG (("Data segments not covered by Memory Handle"));
00335           vip_desc_ptr->CS.Status |= VIP_STATUS_PROTECTION_ERROR;
00336           goto out_with_sync_error;
00337         }
00338 
00339       /* check the operation type */
00340       switch (vip_desc_ptr->CS.Control & VIP_CONTROL_OP_MASK)
00341         {
00342         case VIP_CONTROL_OP_SENDRECV:
00343           break;
00344 
00345         case VIP_CONTROL_OP_RDMAWRITE:
00346           VIP_DEBUG (("RDMA Write operation is not valid on recv queue"));
00347           vip_desc_ptr->CS.Status |= VIP_STATUS_FORMAT_ERROR;
00348           goto out_with_sync_error;
00349 
00350         case VIP_CONTROL_OP_RDMAREAD:
00351           VIP_DEBUG (("RDMA Read operation is not valid on recv queue"));
00352           vip_desc_ptr->CS.Status |= VIP_STATUS_FORMAT_ERROR;
00353           goto out_with_sync_error;
00354 
00355         default:
00356           VIP_DEBUG (("Control field Operation type is set to Reserved value"));
00357           vip_desc_ptr->CS.Status |= VIP_STATUS_FORMAT_ERROR;
00358           goto out_with_sync_error;
00359         }
00360 
00361       /* check the Data segments */
00362       if (length > 0)
00363         {
00364           for (i = 0; i < vip_desc_ptr->CS.SegCount; i++)
00365             {
00366               vip_data_segment_ptr = &(vip_desc_ptr->DS[i].Local);
00367               if (vip_check_memory_handle (vip_nic_ptr,
00368                                            vip_data_segment_ptr->Handle,
00369                                            (VIP_UINTPTR)
00370                                            vip_data_segment_ptr->Data.Address,
00371                                            vip_data_segment_ptr->Length,
00372                                            vip_vi_ptag_id) != VIP_SUCCESS)
00373                 {
00374                   VIP_DEBUG (("Data segment Memory Handle check error"));
00375                   vip_desc_ptr->CS.Status |= VIP_STATUS_PROTECTION_ERROR;
00376                   goto out_with_sync_error;
00377                 }
00378 
00379               total_length += vip_data_segment_ptr->Length;
00380             }
00381         }
00382     }
00383 
00384   /* dispatch each packet type */
00385   switch (VIP_NTOH_UCHAR (inc_ptr->type))
00386     {
00387     case VIP_EAGER_PKT:
00388     case VIP_EAGER_IMM_PKT:
00389       VIP_DEBUG_PROTECTED
00390         (("Received VIP_EAGER_%sPKT from %s/%d\n",
00391           (VIP_NTOH_UCHAR (inc_ptr->type) == VIP_EAGER_PKT) ? "" : "IMM_",
00392           gm_node_id_to_host_name (vip_gm_ptr->gm_port,
00393                                    gm_ntohs (event->recv.sender_node_id)),
00394           gm_ntohc (event->recv.sender_port_id)));
00395 
00396       vip_desc_ptr->CS.Status |= VIP_STATUS_OP_RECEIVE;
00397 
00398       /* check if the recv descriptor is large enough */
00399       if (total_length < length)
00400         {
00401           VIP_DEBUG (("Data overrun"));
00402           vip_desc_ptr->CS.Length = 0;
00403           vip_desc_ptr->CS.Status |= VIP_STATUS_LENGTH_ERROR;
00404           if (VIP_NTOH_UCHAR (inc_ptr->type) == VIP_EAGER_IMM_PKT)
00405             {
00406               vip_desc_ptr->CS.Status |= VIP_STATUS_IMMEDIATE;
00407             }
00408           goto out_with_sync_error;
00409         }
00410 
00411       /* copy immediate data */
00412       data_ptr = NULL;
00413       if (VIP_NTOH_UCHAR (inc_ptr->type) == VIP_EAGER_IMM_PKT)
00414         {
00415           vip_desc_ptr->CS.Status |= VIP_STATUS_IMMEDIATE;
00416 
00417           switch (vip_vi_ptr->reliability)
00418             {
00419             case VIP_SERVICE_UNRELIABLE:
00420               vip_desc_ptr->CS.ImmediateData =
00421                 VIP_NTOH_UINT32(inc_ptr->vip_pkt_eager_imm_ur.net_imm_data);
00422               data_ptr = (VIP_PVOID) (((VIP_UINTPTR) inc_ptr)
00423                                       + sizeof (VIP_PACKET_EAGER_IMM_UR));
00424               break;
00425 
00426             case VIP_SERVICE_RELIABLE_DELIVERY:
00427               vip_desc_ptr->CS.ImmediateData =
00428                 VIP_NTOH_UINT32(inc_ptr->vip_pkt_eager_imm_rd.net_imm_data);
00429               data_ptr = (VIP_PVOID) (((VIP_UINTPTR) inc_ptr)
00430                                       + sizeof (VIP_PACKET_EAGER_IMM_RD));
00431               break;
00432 
00433             case VIP_SERVICE_RELIABLE_RECEPTION:
00434               vip_desc_ptr->CS.ImmediateData =
00435                 VIP_NTOH_UINT32(inc_ptr->vip_pkt_eager_imm_rr.net_imm_data);
00436               data_ptr = (VIP_PVOID) (((VIP_UINTPTR) inc_ptr)
00437                                       + sizeof (VIP_PACKET_EAGER_IMM_RR));
00438               break;
00439             }
00440         }
00441       else
00442         {
00443           switch (vip_vi_ptr->reliability)
00444             {
00445             case VIP_SERVICE_UNRELIABLE:
00446               data_ptr = (VIP_PVOID) (((VIP_UINTPTR) inc_ptr)
00447                                       + sizeof (VIP_PACKET_EAGER_UR));
00448               break;
00449 
00450             case VIP_SERVICE_RELIABLE_DELIVERY:
00451               data_ptr = (VIP_PVOID) (((VIP_UINTPTR) inc_ptr)
00452                                       + sizeof (VIP_PACKET_EAGER_RD));
00453               break;
00454 
00455             case VIP_SERVICE_RELIABLE_RECEPTION:
00456               data_ptr = (VIP_PVOID) (((VIP_UINTPTR) inc_ptr)
00457                                       + sizeof (VIP_PACKET_EAGER_RR));
00458               break;
00459             }
00460         }
00461 
00462       /* copy the incoming data into the Data segments */
00463       vip_desc_ptr->CS.Length = length;
00464       if (length > 0)
00465         {
00466           for (i = 0; i < vip_desc_ptr->CS.SegCount; i++)
00467             {
00468               vip_data_segment_ptr = &(vip_desc_ptr->DS[i].Local);
00469               if (length > vip_data_segment_ptr->Length)
00470                 {
00471                   data_length = vip_data_segment_ptr->Length;
00472                   memcpy (vip_data_segment_ptr->Data.Address, data_ptr,
00473                           vip_data_segment_ptr->Length);
00474                   data_ptr = (VIP_PVOID)
00475                     ((VIP_UINTPTR) data_ptr + vip_data_segment_ptr->Length);
00476                   length -= vip_data_segment_ptr->Length;
00477                 }
00478               else
00479                 {
00480                   memcpy (vip_data_segment_ptr->Data.Address, data_ptr,
00481                           length);
00482                   data_ptr = (VIP_PVOID) ((VIP_UINTPTR) data_ptr + length);
00483                   length = 0;
00484                   break;
00485                 }
00486             }
00487         }
00488 
00489       /* notify the completion */
00490       vip_notify_desc_completion (vip_desc_ptr, vip_vi_ptr, VIP_TRUE);
00491 
00492       /* send the report if reliable reception */
00493       if (vip_vi_ptr->reliability == VIP_SERVICE_RELIABLE_RECEPTION)
00494         {
00495           /* return a remote descriptor error report */
00496           vip_return_report (vip_gm_ptr, vip_nic_ptr, vip_vi_ptr,
00497                              VIP_REPORT_COMPLETION_RR, VIP_TRUE);
00498         }
00499 
00500       /* shift to the next recv descriptor */
00501       VIP_ASSERT (vip_vi_ptr->recv_queue.count_to_process > 0);
00502       vip_vi_ptr->recv_queue.count_to_process--;
00503       vip_vi_ptr->recv_queue.current_desc = vip_desc_ptr->CS.Next.Address;
00504       vip_vi_ptr->recv_queue.current_mem = vip_desc_ptr->CS.NextHandle;
00505       break;
00506 
00507     case VIP_3WAY_REQ_PKT:
00508       VIP_DEBUG_PROTECTED
00509         (("Received VIP_3WAY_REQ_PKT from %s/%d\n",
00510           gm_node_id_to_host_name (vip_gm_ptr->gm_port,
00511                                    gm_ntohs (event->recv.sender_node_id)),
00512           gm_ntohc (event->recv.sender_port_id)));
00513 
00514       vip_desc_ptr->CS.Status |= VIP_STATUS_OP_RECEIVE;
00515 
00516       /* check if the recv descriptor is large enough */
00517       if (total_length < length)
00518         {
00519           VIP_DEBUG (("Data overrun"));
00520           vip_desc_ptr->CS.Length = 0;
00521           vip_desc_ptr->CS.Status |= VIP_STATUS_LENGTH_ERROR;
00522           goto out_with_sync_error;
00523         }
00524 
00525       /* check (again) the memory handles */
00526       i = 0;
00527       data_length = 0;
00528       while (data_length < length)
00529         {
00530           data_length += vip_desc_ptr->DS[i].Local.Length;
00531           if (vip_desc_ptr->DS[i].Local.Length > 0)
00532             {
00533               i++;
00534             }
00535         }
00536       VIP_ASSERT (i <= vip_desc_ptr->CS.SegCount);
00537 
00538       /* send the 3way OK to send */
00539       i = ((i * sizeof (VIP_SEGMENT_HEADER)) + sizeof (VIP_PACKET_3WAY_OK));
00540       vip_send_req_ptr = vip_allocate_packet (vip_gm_ptr, i);
00541       VIP_ASSERT (vip_send_req_ptr != NULL);
00542       pkt_ptr = (VIP_PACKET *) (vip_send_req_ptr->ptr);
00543       VIP_FILL_GENERIC_HEAD (pkt_ptr, 0, vip_vi_ptr, VIP_3WAY_OK_PKT);
00544       pkt_ptr->vip_pkt_3way_ok.net_local_nic_index =
00545         VIP_HTON_UINT16 (vip_nic_ptr->index);
00546       pkt_ptr->vip_pkt_3way_ok.net_local_vi_index =
00547         VIP_HTON_UINT16 (vip_vi_ptr->index);
00548 
00549       i = 0;
00550       data_length = 0;
00551       while (data_length < length)
00552         {
00553           pkt_ptr->vip_pkt_3way_ok.segments[i].address =
00554             VIP_HTON_UINT64 (vip_desc_ptr->DS[i].Local.Data.AddressBits);
00555           pkt_ptr->vip_pkt_3way_ok.segments[i].length =
00556             VIP_HTON_UINT64 (vip_desc_ptr->DS[i].Local.Length);
00557 
00558           data_length += vip_desc_ptr->DS[i].Local.Length;
00559           if (vip_desc_ptr->DS[i].Local.Length > 0)
00560             {
00561               i++;
00562             }
00563         }
00564       pkt_ptr->vip_pkt_3way_ok.seg_count = VIP_HTON_UINT16 (i);
00565 
00566       vip_send_req_ptr->type |= VIP_SEND_REQ_RELIABLE;
00567       vip_send_req_ptr->dest_port_id = vip_vi_ptr->gm_dest_port;
00568       vip_send_req_ptr->dest_gm_id = vip_vi_ptr->gm_dest_id;
00569       vip_send_req_ptr->vip_nic_ptr = vip_nic_ptr;
00570       vip_send_req_ptr->vip_vi_ptr = vip_vi_ptr;
00571       vip_send_data (vip_send_req_ptr);
00572       break;
00573 
00574 
00575     case VIP_PUT_REQ_IMM_PKT:
00576       VIP_DEBUG_PROTECTED
00577         (("Received VIP_PUT_REQ_IMM_PKT from %s/%d\n",
00578           gm_node_id_to_host_name (vip_gm_ptr->gm_port,
00579                                    gm_ntohs (event->recv.sender_node_id)),
00580           gm_ntohc (event->recv.sender_port_id)));
00581 
00582       vip_desc_ptr->CS.Status |= VIP_STATUS_OP_REMOTE_RDMA_WRITE;
00583       vip_desc_ptr->CS.Status |= VIP_STATUS_IMMEDIATE;
00584 
00585       /* check if RDMA Write is enabled on the VI */
00586       if (vip_vi_ptr->rdma_write == VIP_FALSE)
00587         {
00588           VIP_DEBUG (("RDMA Write is not enabled on the VI"));
00589           vip_desc_ptr->CS.Status |= VIP_STATUS_PROTECTION_ERROR;
00590           goto sync_rdma_prot_error;
00591         }
00592 
00593       if (length > 0)
00594         {
00595           /* check the memory handle */
00596           if (vip_check_memory_handle
00597               (vip_nic_ptr,
00598                VIP_NTOH_UINT32 (inc_ptr->vip_pkt_put_req_imm.net_remote_mem),
00599                VIP_NTOH_UINT64 (inc_ptr->vip_pkt_put_req_imm.net_remote_buf),
00600                length, vip_vi_ptr->vip_ptag_ptr->id) != VIP_SUCCESS)
00601             {
00602               VIP_DEBUG (("Data segment Memory Handle check error"));
00603               vip_desc_ptr->CS.Status |= VIP_STATUS_PROTECTION_ERROR;
00604               goto sync_rdma_prot_error;
00605             }
00606 
00607           /* check RDMA write authorization */
00608           if (vip_nic_ptr->vip_mem_handle_ptrs
00609               [VIP_NTOH_UINT32
00610                (inc_ptr->vip_pkt_put_req_imm.net_remote_mem)]->rdma_write ==
00611               VIP_FALSE)
00612             {
00613               VIP_DEBUG (("RDMA write not allowed on the data segment"));
00614               vip_desc_ptr->CS.Status |= VIP_STATUS_PROTECTION_ERROR;
00615               goto sync_rdma_prot_error;
00616             }
00617         }
00618 
00619       /* copy immediate data */
00620       vip_desc_ptr->CS.ImmediateData =
00621         VIP_NTOH_UINT32(inc_ptr->vip_pkt_put_req_imm.net_imm_data);
00622       
00623 #ifndef VI_GM_FAST_RDMA
00624       /* send the PUT OK to send */
00625       vip_send_req_ptr = vip_allocate_packet (vip_gm_ptr,
00626                                               sizeof (VIP_PACKET_PUT_OK));
00627       VIP_ASSERT (vip_send_req_ptr != NULL);
00628       pkt_ptr = (VIP_PACKET *) (vip_send_req_ptr->ptr);
00629       VIP_FILL_GENERIC_HEAD (pkt_ptr, 0, vip_vi_ptr, VIP_PUT_OK_PKT);
00630       pkt_ptr->vip_pkt_put_ok.net_local_nic_index =
00631         VIP_HTON_UINT16 (vip_nic_ptr->index);
00632       pkt_ptr->vip_pkt_put_ok.net_local_vi_index =
00633         VIP_HTON_UINT16 (vip_vi_ptr->index);
00634 
00635       vip_send_req_ptr->type |= VIP_SEND_REQ_RELIABLE;
00636       vip_send_req_ptr->dest_port_id = vip_vi_ptr->gm_dest_port;
00637       vip_send_req_ptr->dest_gm_id = vip_vi_ptr->gm_dest_id;
00638       vip_send_req_ptr->vip_nic_ptr = vip_nic_ptr;
00639       vip_send_req_ptr->vip_vi_ptr = vip_vi_ptr;
00640       vip_send_data (vip_send_req_ptr);
00641 #endif
00642       break;
00643 
00644     default:
00645       VIP_ABORT (("Unknown packet type in incoming matching message (%d)",
00646                   VIP_NTOH_UCHAR (inc_ptr->type)));
00647     }
00648 
00649   VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00650   VIP_DEBUG (("Success"));
00651   return;
00652 
00653 out_with_sync_error:
00654   /* complete the current descriptor */
00655   vip_notify_desc_completion (vip_desc_ptr, vip_vi_ptr, VIP_TRUE);
00656   switch (vip_vi_ptr->reliability)
00657     {
00658     case VIP_SERVICE_UNRELIABLE:
00659       /* shift to the next recv descriptor */
00660       VIP_ASSERT (vip_vi_ptr->recv_queue.count_to_process > 0);
00661       vip_vi_ptr->recv_queue.count_to_process--;
00662       vip_vi_ptr->recv_queue.current_desc = vip_desc_ptr->CS.Next.Address;
00663       vip_vi_ptr->recv_queue.current_mem = vip_desc_ptr->CS.NextHandle;
00664 
00665       if ((VIP_NTOH_UCHAR (inc_ptr->type) == VIP_3WAY_REQ_PKT)
00666           || (VIP_NTOH_UCHAR (inc_ptr->type) == VIP_PUT_REQ_IMM_PKT))
00667         {
00668           /* return a remote descriptor error report */
00669           vip_return_report (vip_gm_ptr, vip_nic_ptr, vip_vi_ptr,
00670                              VIP_REPORT_REM_DESC_ERROR, VIP_TRUE);
00671         }
00672       break;
00673 
00674     case VIP_SERVICE_RELIABLE_DELIVERY:
00675       if ((VIP_NTOH_UCHAR (inc_ptr->type) == VIP_3WAY_REQ_PKT)
00676           || (VIP_NTOH_UCHAR (inc_ptr->type) == VIP_PUT_REQ_IMM_PKT))
00677         {
00678           /* return a remote descriptor error report */
00679           vip_return_report (vip_gm_ptr, vip_nic_ptr, vip_vi_ptr,
00680                              VIP_REPORT_REM_DESC_ERROR, VIP_TRUE);
00681 
00682           /* the VI transition to error state */
00683           vip_vi_transition_to_error_state (vip_vi_ptr, VIP_FALSE);
00684         }
00685       else
00686         {
00687           /* the VI transition to error state */
00688           vip_vi_transition_to_error_state (vip_vi_ptr, VIP_TRUE);
00689         }
00690 
00691       /* a connection lost asynchronous error is generated */
00692       vip_generate_async_error (vip_nic_ptr, vip_vi_ptr, NULL, NULL,
00693                                 VIP_RESOURCE_VI, VIP_ERROR_CONN_LOST, 0);
00694       break;
00695 
00696     case VIP_SERVICE_RELIABLE_RECEPTION:
00697       /* the VI transition to error state */
00698       vip_vi_transition_to_error_state (vip_vi_ptr, VIP_FALSE);
00699 
00700       /* a connection lost asynchronous error is generated */
00701       vip_generate_async_error (vip_nic_ptr, vip_vi_ptr, NULL, NULL,
00702                                 VIP_RESOURCE_VI, VIP_ERROR_CONN_LOST, 0);
00703 
00704       /* return a remote descriptor error report */
00705       vip_return_report (vip_gm_ptr, vip_nic_ptr, vip_vi_ptr,
00706                          VIP_REPORT_REM_DESC_ERROR, VIP_TRUE);
00707       break;
00708     }
00709   VIP_DEBUG (("Synchronous error"));
00710   VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00711   return;
00712 
00713 sync_rdma_prot_error:
00714   /* complete the current descriptor */
00715   vip_notify_desc_completion (vip_desc_ptr, vip_vi_ptr, VIP_TRUE);
00716 
00717   switch (vip_vi_ptr->reliability)
00718     {
00719     case VIP_SERVICE_UNRELIABLE:
00720       /* shift to the next recv descriptor */
00721       VIP_ASSERT (vip_vi_ptr->recv_queue.count_to_process > 0);
00722       vip_vi_ptr->recv_queue.count_to_process--;
00723       vip_vi_ptr->recv_queue.current_desc = vip_desc_ptr->CS.Next.Address;
00724       vip_vi_ptr->recv_queue.current_mem = vip_desc_ptr->CS.NextHandle;
00725 
00726       if ((VIP_NTOH_UCHAR (inc_ptr->type) == VIP_3WAY_REQ_PKT)
00727           || (VIP_NTOH_UCHAR (inc_ptr->type) == VIP_PUT_REQ_IMM_PKT))
00728         {
00729           /* return a remote descriptor error report */
00730           vip_return_report (vip_gm_ptr, vip_nic_ptr, vip_vi_ptr,
00731                              VIP_REPORT_RDMA_PROT_ERROR, VIP_TRUE);
00732         }
00733       break;
00734 
00735     case VIP_SERVICE_RELIABLE_DELIVERY:
00736       if ((VIP_NTOH_UCHAR (inc_ptr->type) == VIP_3WAY_REQ_PKT)
00737           || (VIP_NTOH_UCHAR (inc_ptr->type) == VIP_PUT_REQ_IMM_PKT))
00738         {
00739           /* return a remote descriptor error report */
00740           vip_return_report (vip_gm_ptr, vip_nic_ptr, vip_vi_ptr,
00741                              VIP_REPORT_RDMA_PROT_ERROR, VIP_TRUE);
00742         }
00743 
00744       /* the VI transition to error state */
00745       vip_vi_transition_to_error_state (vip_vi_ptr, VIP_TRUE);
00746 
00747       /* a connection lost asynchronous error is generated */
00748       vip_generate_async_error (vip_nic_ptr, vip_vi_ptr, NULL, NULL,
00749                                 VIP_RESOURCE_VI, VIP_ERROR_CONN_LOST, 0);
00750       break;
00751 
00752     case VIP_SERVICE_RELIABLE_RECEPTION:
00753       /* the VI transition to error state */
00754       vip_vi_transition_to_error_state (vip_vi_ptr, VIP_FALSE);
00755 
00756       /* a connection lost asynchronous error is generated */
00757       vip_generate_async_error (vip_nic_ptr, vip_vi_ptr, NULL, NULL,
00758                                 VIP_RESOURCE_VI, VIP_ERROR_CONN_LOST, 0);
00759 
00760       /* return a remote descriptor error report */
00761       vip_return_report (vip_gm_ptr, vip_nic_ptr, vip_vi_ptr,
00762                          VIP_REPORT_RDMA_PROT_ERROR, VIP_TRUE);
00763       break;
00764     }
00765 
00766   VIP_DEBUG (("RDMA Write protection error"));
00767   VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00768   return;
00769 
00770 async_comp_desc_error:
00771   /* generate the asynchronous error */
00772   vip_generate_async_error (vip_nic_ptr, vip_vi_ptr, NULL, vip_desc_ptr,
00773                             VIP_RESOURCE_DESCRIPTOR, VIP_ERROR_COMP_PROT, 0);
00774 
00775   if (vip_vi_ptr->reliability == VIP_SERVICE_RELIABLE_RECEPTION)
00776     {
00777       /* return a remote descriptor error report */
00778       vip_return_report (vip_gm_ptr, vip_nic_ptr, vip_vi_ptr,
00779                          VIP_REPORT_REM_DESC_ERROR, VIP_TRUE);
00780 
00781       /* the VI transition to error state */
00782       vip_vi_transition_to_error_state (vip_vi_ptr, VIP_FALSE);
00783 
00784       /* a connection lost asynchronous error is generated */
00785       vip_generate_async_error (vip_nic_ptr, vip_vi_ptr, NULL, NULL,
00786                                 VIP_RESOURCE_VI, VIP_ERROR_CONN_LOST, 0);
00787     }
00788   else
00789     {
00790       /* the VI transition to error state */
00791       vip_vi_transition_to_error_state (vip_vi_ptr, VIP_TRUE);
00792 
00793       /* a connection lost asynchronous error is generated */
00794       vip_generate_async_error (vip_nic_ptr, vip_vi_ptr, NULL, NULL,
00795                                 VIP_RESOURCE_VI, VIP_ERROR_CONN_LOST, 0);
00796     }
00797 
00798   VIP_DEBUG (("Asynchronous Post Descriptor error"));
00799   VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00800   return;
00801 }
00802 
00817 static void
00818 vip_handle_3way_ok (VIP_PACKET_3WAY_OK * ptr,
00819                     gm_recv_event_t * event, 
00820                     VIP_GM * vip_gm_ptr)
00821 {
00822   VIP_VI *vip_vi_ptr;
00823   VIP_NIC *vip_nic_ptr;
00824   VIP_UINT32 chunck_length;
00825   VIP_UINT32 total_length;
00826   VIP_PVOID source_ptr;
00827   VIP_PVOID64 target_ptr;
00828   VIP_UINT32 source_length;
00829   VIP_UINT32 target_length;
00830   VIP_UCHAR source_curseg;
00831   VIP_UCHAR target_curseg;
00832   VIP_UINT16 source_segnum;
00833   VIP_UINT16 target_segnum;
00834   VIP_PACKET *pkt_ptr;
00835   VIP_DESCRIPTOR *vip_desc_ptr;
00836   VIP_SEND_REQ *vip_send_req_ptr;
00837   VIP_DEBUG_LABEL (("vip_handle_3way_ok"));
00838 
00839   /* check the NIC and VI */
00840   if (vip_check_nic_and_vi (vip_gm_ptr, event, (VIP_PACKET_EAGER_UR *) ptr,
00841                             &vip_nic_ptr, &vip_vi_ptr,
00842                             VIP_FALSE) != VIP_SUCCESS)
00843     {
00844       if (vip_nic_ptr != NULL)
00845         {
00846           VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00847         }
00848       return;
00849     }
00850 
00851   /* check if the VI is in connected state */
00852   if (vip_vi_ptr->state != VIP_STATE_CONNECTED)
00853     {
00854       VIP_DEBUG (("VI is not in connected state, refuse incoming packet"));
00855       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00856       return;
00857     }
00858 
00859   vip_desc_ptr = vip_vi_ptr->send_queue.current_desc;
00860   VIP_ASSERT (vip_desc_ptr != NULL);
00861   VIP_ASSERT ((vip_desc_ptr->CS.Status & VIP_STATUS_DONE) == 0);
00862 
00863   source_ptr = vip_desc_ptr->DS[0].Local.Data.Address;
00864   source_length = vip_desc_ptr->DS[0].Local.Length;
00865   source_curseg = 0;
00866   source_segnum = vip_desc_ptr->CS.SegCount;
00867   target_ptr.AddressBits = VIP_NTOH_UINT64 (ptr->segments[0].address);
00868   target_length = VIP_NTOH_UINT64 (ptr->segments[0].length);
00869   target_curseg = 0;
00870   target_segnum = VIP_NTOH_UINT16 (ptr->seg_count);
00871   total_length = 0;
00872 
00873   while (1)
00874     {
00875       if (source_length < target_length)
00876         {
00877           chunck_length = source_length;
00878         }
00879       else
00880         {
00881           chunck_length = target_length;
00882         }
00883 
00884       vip_send_req_ptr = vip_allocate_packet (vip_gm_ptr, 0);
00885       VIP_ASSERT (vip_send_req_ptr != NULL);
00886       vip_send_req_ptr->type |= VIP_SEND_REQ_RDMA_WRITE;
00887       vip_send_req_ptr->dest_port_id = vip_vi_ptr->gm_dest_port;
00888       vip_send_req_ptr->dest_gm_id = vip_vi_ptr->gm_dest_id;
00889       vip_send_req_ptr->length = chunck_length;
00890       vip_send_req_ptr->target_ptr = target_ptr;
00891       vip_send_req_ptr->ptr = source_ptr;
00892       vip_send_req_ptr->vip_nic_ptr = vip_nic_ptr;
00893       vip_send_req_ptr->vip_vi_ptr = vip_vi_ptr;
00894       vip_send_data (vip_send_req_ptr);
00895 
00896       source_length -= chunck_length;
00897       target_length -= chunck_length;
00898       source_ptr = (VIP_PVOID) (((VIP_UINTPTR) source_ptr) + chunck_length);
00899       target_ptr.AddressBits += chunck_length;
00900       total_length += chunck_length;
00901 
00902       while (source_length == 0)
00903         {
00904           source_curseg++;
00905           if (source_curseg < source_segnum)
00906             {
00907               source_ptr = vip_desc_ptr->DS[source_curseg].Local.Data.Address;
00908               source_length = vip_desc_ptr->DS[source_curseg].Local.Length;
00909             }
00910           else
00911             {
00912               goto end_scatter;
00913             }
00914         }
00915 
00916       while (target_length == 0)
00917         {
00918           target_curseg++;
00919           if (target_curseg < target_segnum)
00920             {
00921               target_ptr.AddressBits =
00922                 VIP_NTOH_UINT64 (ptr->segments[target_curseg].address);
00923               target_length =
00924                 VIP_NTOH_UINT64 (ptr->segments[target_curseg].length);
00925             }
00926           else
00927             {
00928               VIP_ABORT (("Internal error (segment number overflow)"));
00929             }
00930         }
00931     }
00932 
00933 end_scatter:
00934   VIP_ASSERT (total_length == vip_desc_ptr->CS.Length);
00935 
00936   /* immediate data ? */
00937   if ((vip_desc_ptr->CS.Control & VIP_CONTROL_IMMEDIATE) != 0)
00938     {
00939       VIP_DEBUG (("3Way DONE with immediate"));
00940 
00941       vip_send_req_ptr =
00942         vip_allocate_packet (vip_gm_ptr, sizeof (VIP_PACKET_3WAY_DONE_IMM));
00943       VIP_ASSERT (vip_send_req_ptr != NULL);
00944       pkt_ptr = (VIP_PACKET *) (vip_send_req_ptr->ptr);
00945       VIP_FILL_GENERIC_HEAD (pkt_ptr, total_length, vip_vi_ptr,
00946                              VIP_3WAY_DONE_IMM_PKT);
00947       pkt_ptr->vip_pkt_3way_done_imm.net_imm_data =
00948         VIP_HTON_UINT32(vip_desc_ptr->CS.ImmediateData);
00949     }
00950   else
00951     {
00952       VIP_DEBUG (("3Way DONE"));
00953 
00954       vip_send_req_ptr =
00955         vip_allocate_packet (vip_gm_ptr, sizeof (VIP_PACKET_3WAY_DONE));
00956       VIP_ASSERT (vip_send_req_ptr != NULL);
00957       pkt_ptr = (VIP_PACKET *) (vip_send_req_ptr->ptr);
00958       VIP_FILL_GENERIC_HEAD (pkt_ptr, total_length, vip_vi_ptr,
00959                              VIP_3WAY_DONE_PKT);
00960     }
00961 
00962   pkt_ptr->vip_pkt_3way_done.net_local_nic_index =
00963     VIP_HTON_UINT16 (vip_nic_ptr->index);
00964   pkt_ptr->vip_pkt_3way_done.net_local_vi_index =
00965     VIP_HTON_UINT16 (vip_vi_ptr->index);
00966 
00967   vip_send_req_ptr->type |= VIP_SEND_REQ_RELIABLE;
00968   vip_send_req_ptr->dest_port_id = vip_vi_ptr->gm_dest_port;
00969   vip_send_req_ptr->dest_gm_id = vip_vi_ptr->gm_dest_id;
00970   vip_send_req_ptr->vip_nic_ptr = vip_nic_ptr;
00971   vip_send_req_ptr->vip_vi_ptr = vip_vi_ptr;
00972   vip_send_req_ptr->vip_desc_ptr = vip_desc_ptr;
00973   vip_send_data (vip_send_req_ptr);
00974 
00975   VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00976   VIP_DEBUG (("Success"));
00977 }
00978 
00993 static void
00994 vip_handle_3way_done (VIP_PACKET_3WAY_DONE * ptr,
00995                       gm_recv_event_t * event, 
00996                       VIP_GM * vip_gm_ptr)
00997 {
00998   VIP_VI *vip_vi_ptr;
00999   VIP_NIC *vip_nic_ptr;
01000   VIP_UINT32 length;
01001   VIP_DESCRIPTOR *vip_desc_ptr;
01002   VIP_DEBUG_LABEL (("vip_handle_3way_done"));
01003 
01004   length = (((VIP_NTOH_UCHAR (ptr->length_24)) << 16)
01005             + ((VIP_NTOH_UCHAR (ptr->length_16)) << 8)
01006             + VIP_NTOH_UCHAR (ptr->length_8));
01007 
01008   /* check the NIC and VI */
01009   if (vip_check_nic_and_vi (vip_gm_ptr, event, (VIP_PACKET_EAGER_UR *) ptr,
01010                             &vip_nic_ptr, &vip_vi_ptr,
01011                             VIP_TRUE) != VIP_SUCCESS)
01012     {
01013       if (vip_nic_ptr != NULL)
01014         {
01015           VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
01016         }
01017       return;
01018     }
01019 
01020   /* check if the VI is in connected state */
01021   if (vip_vi_ptr->state != VIP_STATE_CONNECTED)
01022     {
01023       VIP_DEBUG (("VI is not in connected state, refuse incoming packet"));
01024       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
01025       return;
01026     }
01027 
01028   vip_desc_ptr = vip_vi_ptr->recv_queue.current_desc;
01029   VIP_ASSERT (vip_desc_ptr != NULL);
01030   VIP_ASSERT ((vip_desc_ptr->CS.Status & VIP_STATUS_DONE) == 0);
01031 
01032   /* update length in descriptor */
01033   vip_desc_ptr->CS.Length = length;
01034 
01035   /* copy immediate data */
01036   if (VIP_NTOH_UCHAR (ptr->type) == VIP_3WAY_DONE_IMM_PKT)
01037     {
01038       vip_desc_ptr->CS.ImmediateData =
01039         VIP_NTOH_UINT32(((VIP_PACKET_3WAY_DONE_IMM *) ptr)->net_imm_data);
01040 
01041       vip_desc_ptr->CS.Status |= VIP_STATUS_IMMEDIATE;
01042     }
01043 
01044   vip_notify_desc_completion (vip_desc_ptr, vip_vi_ptr, VIP_TRUE);
01045 
01046   /* send the report if reliable reception */
01047   if (vip_vi_ptr->reliability == VIP_SERVICE_RELIABLE_RECEPTION)
01048     {
01049       vip_return_report (vip_gm_ptr, vip_nic_ptr, vip_vi_ptr,
01050                          VIP_REPORT_COMPLETION_RR, VIP_TRUE);
01051     }
01052 
01053   /* shift to the next recv descriptor */
01054   VIP_ASSERT (vip_vi_ptr->recv_queue.count_to_process > 0);
01055   vip_vi_ptr->recv_queue.count_to_process--;
01056   vip_vi_ptr->recv_queue.current_desc = vip_desc_ptr->CS.Next.Address;
01057   vip_vi_ptr->recv_queue.current_mem = vip_desc_ptr->CS.NextHandle;
01058 
01059   VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
01060   VIP_DEBUG (("Success"));
01061 }
01062 
01077 static void
01078 vip_handle_put_req (VIP_PACKET_PUT_REQ * ptr,
01079                     gm_recv_event_t * event, 
01080                     VIP_GM * vip_gm_ptr)
01081 {
01082   VIP_VI *vip_vi_ptr;
01083   VIP_NIC *vip_nic_ptr;
01084   VIP_UINT32 length;
01085   VIP_UINT32 vip_vi_ptag_id;
01086   VIP_PACKET *pkt_ptr;
01087   VIP_SEND_REQ *vip_send_req_ptr;
01088   VIP_DEBUG_LABEL (("vip_handle_put_req"));
01089 
01090   length = (((VIP_NTOH_UCHAR (ptr->length_24)) << 16)
01091             + ((VIP_NTOH_UCHAR (ptr->length_16)) << 8)
01092             + VIP_NTOH_UCHAR (ptr->length_8));
01093 
01094   /* check the NIC and VI */
01095   if (vip_check_nic_and_vi (vip_gm_ptr, event, (VIP_PACKET_EAGER_UR *) ptr,
01096                             &vip_nic_ptr, &vip_vi_ptr,
01097                             VIP_TRUE) != VIP_SUCCESS)
01098     {
01099       if (vip_nic_ptr != NULL)
01100         {
01101           VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
01102         }
01103       return;
01104     }
01105 
01106   /* check if the VI is in connected state */
01107   if (vip_vi_ptr->state != VIP_STATE_CONNECTED)
01108     {
01109       VIP_DEBUG (("VI is not in connected state, refuse incoming packet"));
01110       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
01111       return;
01112     }
01113 
01114   /* check if RDMA Write is enabled on the VI */
01115   if (vip_vi_ptr->rdma_write == VIP_FALSE)
01116     {
01117       VIP_DEBUG (("RDMA Write is not enabled on the VI"));
01118       goto out_with_rdma_protection_error;
01119     }
01120 
01121   if (length > 0)
01122     {
01123       /* check VI PTAG handle */
01124       if (VIP_INVALID_PTAG_HANDLE (vip_vi_ptr->vip_ptag_ptr))
01125         {
01126           VIP_DEBUG (("Invalid VI PTAG handle"));
01127           goto out_with_rdma_protection_error;
01128         }
01129       vip_vi_ptag_id = vip_vi_ptr->vip_ptag_ptr->id;
01130 
01131       /* check the memory handle */
01132       if (vip_check_memory_handle (vip_nic_ptr,
01133                                    VIP_NTOH_UINT32 (ptr->net_remote_mem),
01134                                    VIP_NTOH_UINT64 (ptr->net_remote_buf),
01135                                    length, vip_vi_ptr->vip_ptag_ptr->id)
01136           != VIP_SUCCESS)
01137         {
01138           VIP_DEBUG (("Data segment Memory Handle check error"));
01139           goto out_with_rdma_protection_error;
01140         }
01141 
01142       /* check RDMA write authorization */
01143       if (vip_nic_ptr->vip_mem_handle_ptrs
01144           [VIP_NTOH_UINT32 (ptr->net_remote_mem)]->rdma_write == VIP_FALSE)
01145         {
01146           VIP_DEBUG (("RDMA write not allowed on the data segment"));
01147           goto out_with_rdma_protection_error;
01148         }
01149     }
01150 
01151   /* send the PUT OK to send */
01152   vip_send_req_ptr = vip_allocate_packet (vip_gm_ptr,
01153                                           sizeof (VIP_PACKET_PUT_OK));
01154   VIP_ASSERT (vip_send_req_ptr != NULL);
01155   pkt_ptr = (VIP_PACKET *) (vip_send_req_ptr->ptr);
01156   VIP_FILL_GENERIC_HEAD (pkt_ptr, 0, vip_vi_ptr, VIP_PUT_OK_PKT);
01157 
01158   pkt_ptr->vip_pkt_put_ok.net_local_nic_index =
01159     VIP_HTON_UINT16 (vip_nic_ptr->index);
01160   pkt_ptr->vip_pkt_put_ok.net_local_vi_index =
01161     VIP_HTON_UINT16 (vip_vi_ptr->index);
01162 
01163   vip_send_req_ptr->type |= VIP_SEND_REQ_RELIABLE;
01164   vip_send_req_ptr->dest_port_id = vip_vi_ptr->gm_dest_port;
01165   vip_send_req_ptr->dest_gm_id = vip_vi_ptr->gm_dest_id;
01166   vip_send_req_ptr->vip_nic_ptr = vip_nic_ptr;
01167   vip_send_req_ptr->vip_vi_ptr = vip_vi_ptr;
01168   vip_send_data (vip_send_req_ptr);
01169 
01170   VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
01171   VIP_DEBUG (("Success"));
01172   return;
01173 
01174 out_with_rdma_protection_error:
01175   switch (vip_vi_ptr->reliability)
01176     {
01177     case VIP_SERVICE_UNRELIABLE:
01178       /* return a remote descriptor error report */
01179       vip_return_report (vip_gm_ptr, vip_nic_ptr, vip_vi_ptr,
01180                          VIP_REPORT_RDMA_PROT_ERROR, VIP_TRUE);
01181       break;
01182 
01183     case VIP_SERVICE_RELIABLE_DELIVERY:
01184       /* return a remote descriptor error report */
01185       vip_return_report (vip_gm_ptr, vip_nic_ptr, vip_vi_ptr,
01186                          VIP_REPORT_RDMA_PROT_ERROR, VIP_TRUE);
01187 
01188       /* generate the asynchronous error */
01189       vip_generate_async_error (vip_nic_ptr, vip_vi_ptr, NULL, NULL,
01190                                 VIP_RESOURCE_VI, VIP_ERROR_RDMAW_PROT, 0);
01191 
01192       /* the VI transition to error state */
01193       vip_vi_transition_to_error_state (vip_vi_ptr, VIP_TRUE);
01194 
01195       /* a connection lost asynchronous error is generated */
01196       vip_generate_async_error (vip_nic_ptr, vip_vi_ptr, NULL, NULL,
01197                                 VIP_RESOURCE_VI, VIP_ERROR_CONN_LOST, 0);
01198       break;
01199 
01200     case VIP_SERVICE_RELIABLE_RECEPTION:
01201       /* return a remote descriptor error report */
01202       vip_return_report (vip_gm_ptr, vip_nic_ptr, vip_vi_ptr,
01203                          VIP_REPORT_RDMA_PROT_ERROR, VIP_TRUE);
01204 
01205       /* generate the asynchronous error */
01206       vip_generate_async_error (vip_nic_ptr, vip_vi_ptr, NULL, NULL,
01207                                 VIP_RESOURCE_VI, VIP_ERROR_RDMAW_PROT, 0);
01208 
01209       /* the VI transition to error state */
01210       vip_vi_transition_to_error_state (vip_vi_ptr, VIP_FALSE);
01211 
01212       /* a connection lost asynchronous error is generated */
01213       vip_generate_async_error (vip_nic_ptr, vip_vi_ptr, NULL, NULL,
01214                                 VIP_RESOURCE_VI, VIP_ERROR_CONN_LOST, 0);
01215       break;
01216     }
01217 
01218   VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
01219   return;
01220 }
01221 
01236 static void
01237 vip_handle_put_ok (VIP_PACKET_PUT_OK * ptr,
01238                    gm_recv_event_t * event, 
01239                    VIP_GM * vip_gm_ptr)
01240 {
01241   VIP_VI *vip_vi_ptr;
01242   VIP_NIC