00001
00002
00003
00004
00005
00006
00007
00014 #include <stdlib.h>
00015 #include <string.h>
00016
00017 #include "vipl_priv.h"
00018
00031 void
00032 vip_process_send_desc (VIP_VI * vip_vi_ptr)
00033 {
00034 VIP_NIC *vip_nic_ptr;
00035 VIP_GM *vip_gm_ptr;
00036 VIP_UINT32 vip_vi_ptag_id;
00037 VIP_UINT32 total_length;
00038 VIP_UINT32 i;
00039 VIP_UINT32 address_segment;
00040 VIP_PACKET *pkt_ptr;
00041 VIP_PVOID data_ptr;
00042 #ifdef VI_GM_FAST_RDMA
00043 VIP_PVOID64 target_ptr;
00044 #endif
00045 VIP_DESCRIPTOR *vip_desc_ptr;
00046 VIP_SEND_REQ *vip_send_req_ptr;
00047 VIP_DATA_SEGMENT *vip_data_segment_ptr;
00048 VIP_DEBUG_LABEL (("vip_process_send_desc"));
00049
00050 vip_nic_ptr = vip_vi_ptr->handle.vip_nic_ptr;
00051 vip_gm_ptr = vip_nic_ptr->vip_gm_ptr;
00052 VIP_ASSERT_MUTEX_LOCKED (&(vip_gm_ptr->lock));
00053 VIP_ASSERT_MUTEX_LOCKED (&(vip_nic_ptr->lock));
00054
00055 vip_desc_ptr = vip_vi_ptr->send_queue.current_desc;
00056 vip_vi_ptag_id = vip_vi_ptr->vip_ptag_ptr->id;
00057
00058
00059 if ((((VIP_UINTPTR) vip_desc_ptr) & 0x3F) != 0)
00060 {
00061 VIP_DEBUG (("Descriptor is not aligned on a 64 Bytes boundary"));
00062 goto async_post_desc_error;
00063 }
00064
00065
00066 if (vip_check_memory_handle (vip_nic_ptr,
00067 vip_vi_ptr->send_queue.current_mem,
00068 (VIP_UINTPTR) vip_desc_ptr,
00069 sizeof (VIP_CONTROL_SEGMENT),
00070 vip_vi_ptag_id) != VIP_SUCCESS)
00071 {
00072 VIP_DEBUG (("Control segment Memory Handle check error"));
00073 goto async_post_desc_error;
00074 }
00075
00076
00077 if ((vip_desc_ptr->CS.Control & VIP_CONTROL_RESERVED) != 0)
00078 {
00079 VIP_DEBUG (("Control field reserved part is not set to 0"));
00080 vip_desc_ptr->CS.Status |= VIP_STATUS_FORMAT_ERROR;
00081 goto out_with_sync_error;
00082 }
00083
00084
00085 if (vip_desc_ptr->CS.Reserved != 0)
00086 {
00087 VIP_DEBUG (("Reserved field is not set to 0"));
00088 vip_desc_ptr->CS.Status |= VIP_STATUS_FORMAT_ERROR;
00089 goto out_with_sync_error;
00090 }
00091
00092
00093 if (vip_desc_ptr->CS.SegCount > VI_GM_MAX_SEGMENTS_PER_DESCRIPTOR)
00094 {
00095 VIP_DEBUG (("Number of Address/Data segments is exceeding capacity "
00096 "(max=%d)", VI_GM_MAX_SEGMENTS_PER_DESCRIPTOR));
00097 vip_desc_ptr->CS.Status |= VIP_STATUS_LENGTH_ERROR;
00098 goto out_with_sync_error;
00099 }
00100
00101
00102 VIP_ASSERT (vip_vi_ptr->mtu <= VI_GM_MAX_TRANSFER_SIZE);
00103 if (vip_desc_ptr->CS.Length > vip_vi_ptr->mtu)
00104 {
00105 VIP_DEBUG (("Data length is exceeding the MTU of the VI"));
00106 vip_desc_ptr->CS.Status |= VIP_STATUS_LENGTH_ERROR;
00107 goto out_with_sync_error;
00108 }
00109
00110
00111 if (vip_check_memory_handle (vip_nic_ptr,
00112 vip_vi_ptr->send_queue.current_mem,
00113 (VIP_UINTPTR) vip_desc_ptr,
00114 (sizeof (VIP_CONTROL_SEGMENT)
00115 + (vip_desc_ptr->CS.SegCount
00116 * sizeof (VIP_DESCRIPTOR_SEGMENT))),
00117 vip_vi_ptag_id) != VIP_SUCCESS)
00118 {
00119 VIP_DEBUG (("Data segments not covered by Memory Handle"));
00120 vip_desc_ptr->CS.Status |= VIP_STATUS_PROTECTION_ERROR;
00121 goto out_with_sync_error;
00122 }
00123
00124
00125 if (vip_vi_ptr->state != VIP_STATE_CONNECTED)
00126 {
00127 VIP_DEBUG (("VI is not connected"));
00128 vip_desc_ptr->CS.Status |= VIP_STATUS_DESC_FLUSHED_ERROR;
00129 goto out_with_sync_error;
00130 }
00131
00132
00133 switch (vip_desc_ptr->CS.Control & VIP_CONTROL_OP_MASK)
00134 {
00135 case VIP_CONTROL_OP_SENDRECV:
00136 address_segment = 0;
00137 break;
00138
00139 case VIP_CONTROL_OP_RDMAWRITE:
00140 address_segment = 1;
00141 break;
00142
00143 case VIP_CONTROL_OP_RDMAREAD:
00144 VIP_DEBUG (("RDMA Read operation not supported"));
00145 vip_desc_ptr->CS.Status |= VIP_STATUS_FORMAT_ERROR;
00146 goto out_with_sync_error;
00147
00148 default:
00149 VIP_DEBUG (("Control field Operation type is set to Reserved value"));
00150 vip_desc_ptr->CS.Status |= VIP_STATUS_FORMAT_ERROR;
00151 goto out_with_sync_error;
00152 }
00153
00154
00155 total_length = 0;
00156 for (i = address_segment; i < vip_desc_ptr->CS.SegCount; i++)
00157 {
00158 vip_data_segment_ptr = &(vip_desc_ptr->DS[i].Local);
00159
00160
00161 if (vip_data_segment_ptr->Length > VI_GM_MAX_TRANSFER_SIZE)
00162 {
00163 VIP_DEBUG (("Length of a data segment is exceeding the maximum "
00164 "transfert size (max=%d)", VI_GM_MAX_TRANSFER_SIZE));
00165 vip_desc_ptr->CS.Status |= VIP_STATUS_LENGTH_ERROR;
00166 goto out_with_sync_error;
00167 }
00168
00169
00170 if (vip_check_memory_handle (vip_nic_ptr,
00171 vip_data_segment_ptr->Handle,
00172 (VIP_UINTPTR)
00173 vip_data_segment_ptr->Data.Address,
00174 vip_data_segment_ptr->Length,
00175 vip_vi_ptag_id) != VIP_SUCCESS)
00176 {
00177 VIP_DEBUG (("Data segment Memory Handle check error"));
00178 vip_desc_ptr->CS.Status |= VIP_STATUS_PROTECTION_ERROR;
00179 goto out_with_sync_error;
00180 }
00181
00182 total_length += vip_data_segment_ptr->Length;
00183 }
00184
00185
00186 if (total_length != vip_desc_ptr->CS.Length)
00187 {
00188 VIP_DEBUG (("Data total length is different than Length field"));
00189 vip_desc_ptr->CS.Status |= VIP_STATUS_LENGTH_ERROR;
00190 goto out_with_sync_error;
00191 }
00192
00193
00194 if ((vip_desc_ptr->CS.Control
00195 & VIP_CONTROL_OP_MASK) == VIP_CONTROL_OP_SENDRECV)
00196 {
00197 vip_desc_ptr->CS.Status |= VIP_STATUS_OP_SEND;
00198
00199
00200 if ((total_length + sizeof (VIP_PACKET_EAGER_IMM_RR))
00201 <= VI_GM_EAGER_LENGTH)
00202 {
00203
00204 if ((vip_desc_ptr->CS.Control & VIP_CONTROL_IMMEDIATE) != 0)
00205 {
00206 VIP_DEBUG (("Eager with immediate (desc=%p)", vip_desc_ptr));
00207 switch (vip_vi_ptr->reliability)
00208 {
00209 case VIP_SERVICE_UNRELIABLE:
00210 vip_send_req_ptr =
00211 vip_allocate_packet (vip_gm_ptr, total_length
00212 + sizeof (VIP_PACKET_EAGER_IMM_UR));
00213 VIP_ASSERT (vip_send_req_ptr != NULL);
00214 pkt_ptr = (VIP_PACKET *) (vip_send_req_ptr->ptr);
00215 data_ptr = &(pkt_ptr->vip_pkt_eager_imm_ur.net_imm_data);
00216 if ((total_length + sizeof (VIP_PACKET_EAGER_IMM_UR))
00217 <= gm_mtu (vip_gm_ptr->gm_port))
00218 {
00219 vip_send_req_ptr->type |= VIP_SEND_REQ_UNRELIABLE;
00220 }
00221 VIP_FILL_GENERIC_HEAD (pkt_ptr, total_length, vip_vi_ptr,
00222 VIP_EAGER_IMM_PKT);
00223 break;
00224
00225 case VIP_SERVICE_RELIABLE_DELIVERY:
00226 vip_send_req_ptr =
00227 vip_allocate_packet (vip_gm_ptr, total_length
00228 + sizeof (VIP_PACKET_EAGER_IMM_RD));
00229 VIP_ASSERT (vip_send_req_ptr != NULL);
00230 pkt_ptr = (VIP_PACKET *) (vip_send_req_ptr->ptr);
00231 data_ptr = &(pkt_ptr->vip_pkt_eager_imm_rd.net_imm_data);
00232 VIP_FILL_GENERIC_HEAD (pkt_ptr, total_length, vip_vi_ptr,
00233 VIP_EAGER_IMM_PKT);
00234 pkt_ptr->vip_pkt_eager_imm_rd.net_local_nic_index =
00235 VIP_HTON_UINT16 (vip_nic_ptr->index);
00236 pkt_ptr->vip_pkt_eager_imm_rd.net_local_vi_index =
00237 VIP_HTON_UINT16 (vip_vi_ptr->index);
00238 break;
00239
00240 case VIP_SERVICE_RELIABLE_RECEPTION:
00241 vip_send_req_ptr =
00242 vip_allocate_packet (vip_gm_ptr, total_length
00243 + sizeof (VIP_PACKET_EAGER_IMM_RR));
00244 VIP_ASSERT (vip_send_req_ptr != NULL);
00245 pkt_ptr = (VIP_PACKET *) (vip_send_req_ptr->ptr);
00246 data_ptr = &(pkt_ptr->vip_pkt_eager_imm_rr.net_imm_data);
00247 VIP_FILL_GENERIC_HEAD (pkt_ptr, total_length, vip_vi_ptr,
00248 VIP_EAGER_IMM_PKT);
00249 pkt_ptr->vip_pkt_eager_imm_rr.net_local_nic_index =
00250 VIP_HTON_UINT16 (vip_nic_ptr->index);
00251 pkt_ptr->vip_pkt_eager_imm_rr.net_local_vi_index =
00252 VIP_HTON_UINT16 (vip_vi_ptr->index);
00253 break;
00254
00255 default:
00256 VIP_ABORT (("Invalid Reliability level in VI"));
00257 }
00258
00259 *(VIP_NET_UINT32*)data_ptr = VIP_HTON_UINT32(vip_desc_ptr->CS.ImmediateData);
00260 data_ptr = (VIP_PVOID) (((VIP_UINTPTR) data_ptr)
00261 + sizeof (VIP_UINT32)*2);
00262 }
00263 else
00264 {
00265 VIP_DEBUG (("Eager (desc=%p)", vip_desc_ptr));
00266
00267 switch (vip_vi_ptr->reliability)
00268 {
00269 case VIP_SERVICE_UNRELIABLE:
00270 vip_send_req_ptr =
00271 vip_allocate_packet (vip_gm_ptr, total_length
00272 + sizeof (VIP_PACKET_EAGER_UR));
00273 VIP_ASSERT (vip_send_req_ptr != NULL);
00274 pkt_ptr = (VIP_PACKET *) (vip_send_req_ptr->ptr);
00275 data_ptr = (VIP_PVOID) (((VIP_UINTPTR) pkt_ptr)
00276 + sizeof (VIP_PACKET_EAGER_UR));
00277 if ((total_length + sizeof (VIP_PACKET_EAGER_UR))
00278 <= gm_mtu (vip_gm_ptr->gm_port))
00279 {
00280 vip_send_req_ptr->type |= VIP_SEND_REQ_UNRELIABLE;
00281 }
00282
00283 VIP_FILL_GENERIC_HEAD (pkt_ptr, total_length, vip_vi_ptr,
00284 VIP_EAGER_PKT);
00285 break;
00286
00287 case VIP_SERVICE_RELIABLE_DELIVERY:
00288 vip_send_req_ptr =
00289 vip_allocate_packet (vip_gm_ptr, total_length
00290 + sizeof (VIP_PACKET_EAGER_RD));
00291 VIP_ASSERT (vip_send_req_ptr != NULL);
00292 pkt_ptr = (VIP_PACKET *) (vip_send_req_ptr->ptr);
00293 data_ptr = (VIP_PVOID) (((VIP_UINTPTR) pkt_ptr)
00294 + sizeof (VIP_PACKET_EAGER_RD));
00295 VIP_FILL_GENERIC_HEAD (pkt_ptr, total_length, vip_vi_ptr,
00296 VIP_EAGER_PKT);
00297 pkt_ptr->vip_pkt_eager_rd.net_local_nic_index =
00298 VIP_HTON_UINT16 (vip_nic_ptr->index);
00299 pkt_ptr->vip_pkt_eager_rd.net_local_vi_index =
00300 VIP_HTON_UINT16 (vip_vi_ptr->index);
00301 break;
00302
00303 case VIP_SERVICE_RELIABLE_RECEPTION:
00304 vip_send_req_ptr =
00305 vip_allocate_packet (vip_gm_ptr, total_length
00306 + sizeof (VIP_PACKET_EAGER_RR));
00307 VIP_ASSERT (vip_send_req_ptr != NULL);
00308 pkt_ptr = (VIP_PACKET *) (vip_send_req_ptr->ptr);
00309 data_ptr = (VIP_PVOID) (((VIP_UINTPTR) pkt_ptr)
00310 + sizeof (VIP_PACKET_EAGER_RR));
00311 VIP_FILL_GENERIC_HEAD (pkt_ptr, total_length, vip_vi_ptr,
00312 VIP_EAGER_PKT);
00313 pkt_ptr->vip_pkt_eager_rr.net_local_nic_index =
00314 VIP_HTON_UINT16 (vip_nic_ptr->index);
00315 pkt_ptr->vip_pkt_eager_rr.net_local_vi_index =
00316 VIP_HTON_UINT16 (vip_vi_ptr->index);
00317 break;
00318
00319 default:
00320 VIP_ABORT (("Invalid Reliability level in VI"));
00321 }
00322 }
00323
00324 for (i = address_segment; i < vip_desc_ptr->CS.SegCount; i++)
00325 {
00326 memcpy (data_ptr, vip_desc_ptr->DS[i].Local.Data.Address,
00327 vip_desc_ptr->DS[i].Local.Length);
00328 data_ptr = (VIP_PVOID) (((VIP_UINTPTR) data_ptr)
00329 + vip_desc_ptr->DS[i].Local.Length);
00330 }
00331
00332 if ((vip_send_req_ptr->type & VIP_SEND_REQ_UNRELIABLE) == 0)
00333 {
00334 VIP_ASSERT ((vip_send_req_ptr->type
00335 & VIP_SEND_REQ_RELIABLE) == 0);
00336 vip_send_req_ptr->type |= VIP_SEND_REQ_RELIABLE;
00337 }
00338
00339 vip_send_req_ptr->dest_port_id = vip_vi_ptr->gm_dest_port;
00340 vip_send_req_ptr->dest_gm_id = vip_vi_ptr->gm_dest_id;
00341 vip_send_req_ptr->vip_nic_ptr = vip_nic_ptr;
00342 vip_send_req_ptr->vip_vi_ptr = vip_vi_ptr;
00343 vip_send_req_ptr->vip_desc_ptr = vip_desc_ptr;
00344 vip_send_data (vip_send_req_ptr);
00345 }
00346 else
00347 {
00348
00349 VIP_DEBUG (("3Way request (desc=%p)", vip_desc_ptr));
00350 vip_send_req_ptr =
00351 vip_allocate_packet (vip_gm_ptr, sizeof (VIP_PACKET_3WAY_REQ));
00352 VIP_ASSERT (vip_send_req_ptr != NULL);
00353 pkt_ptr = (VIP_PACKET *) (vip_send_req_ptr->ptr);
00354 VIP_FILL_GENERIC_HEAD (pkt_ptr, total_length, vip_vi_ptr,
00355 VIP_3WAY_REQ_PKT);
00356 pkt_ptr->vip_pkt_3way_req.net_local_nic_index =
00357 VIP_HTON_UINT16 (vip_nic_ptr->index);
00358 pkt_ptr->vip_pkt_3way_req.net_local_vi_index =
00359 VIP_HTON_UINT16 (vip_vi_ptr->index);
00360
00361 vip_send_req_ptr->type |= VIP_SEND_REQ_RELIABLE;
00362 vip_send_req_ptr->dest_port_id = vip_vi_ptr->gm_dest_port;
00363 vip_send_req_ptr->dest_gm_id = vip_vi_ptr->gm_dest_id;
00364 vip_send_req_ptr->vip_nic_ptr = vip_nic_ptr;
00365 vip_send_req_ptr->vip_vi_ptr = vip_vi_ptr;
00366 vip_send_data (vip_send_req_ptr);
00367 }
00368 }
00369 else
00370 {
00371 vip_desc_ptr->CS.Status |= VIP_STATUS_OP_RDMA_WRITE;
00372
00373
00374 if (vip_desc_ptr->DS[0].Remote.Reserved != 0)
00375 {
00376 VIP_DEBUG (("Reserved part of the Address segment is not null"));
00377 vip_desc_ptr->CS.Status |= VIP_STATUS_FORMAT_ERROR;
00378 goto out_with_sync_error;
00379 }
00380
00381
00382 if ((vip_desc_ptr->CS.Control & VIP_CONTROL_IMMEDIATE) != 0)
00383 {
00384 VIP_DEBUG (("RDMA write with immediate (desc=%p)", vip_desc_ptr));
00385 i = sizeof (VIP_UINT32);
00386
00387
00388 vip_send_req_ptr =
00389 vip_allocate_packet (vip_gm_ptr, sizeof (VIP_PACKET_PUT_REQ_IMM));
00390 VIP_ASSERT (vip_send_req_ptr != NULL);
00391 pkt_ptr = (VIP_PACKET *) (vip_send_req_ptr->ptr);
00392 VIP_FILL_GENERIC_HEAD (pkt_ptr, total_length, vip_vi_ptr,
00393 VIP_PUT_REQ_IMM_PKT);
00394 ((VIP_PACKET_PUT_REQ_IMM *) pkt_ptr)->net_imm_data =
00395 VIP_HTON_UINT32(vip_desc_ptr->CS.ImmediateData);
00396
00397 pkt_ptr->vip_pkt_put_req.net_remote_buf =
00398 VIP_HTON_UINT64 (vip_desc_ptr->DS[0].Remote.Data.AddressBits);
00399 pkt_ptr->vip_pkt_put_req.net_remote_mem =
00400 VIP_HTON_UINT32 (vip_desc_ptr->DS[0].Remote.Handle);
00401 pkt_ptr->vip_pkt_put_req.net_local_nic_index =
00402 VIP_HTON_UINT16 (vip_nic_ptr->index);
00403 pkt_ptr->vip_pkt_put_req.net_local_vi_index =
00404 VIP_HTON_UINT16 (vip_vi_ptr->index);
00405
00406 *(VIP_NET_UINT32*) (((VIP_UINTPTR) pkt_ptr)
00407 + sizeof (VIP_PACKET_PUT_REQ)) =
00408 VIP_HTON_UINT32(vip_desc_ptr->CS.ImmediateData);
00409
00410 vip_send_req_ptr->type |= VIP_SEND_REQ_RELIABLE;
00411 vip_send_req_ptr->dest_port_id = vip_vi_ptr->gm_dest_port;
00412 vip_send_req_ptr->dest_gm_id = vip_vi_ptr->gm_dest_id;
00413 vip_send_req_ptr->vip_nic_ptr = vip_nic_ptr;
00414 vip_send_req_ptr->vip_vi_ptr = vip_vi_ptr;
00415 vip_send_data (vip_send_req_ptr);
00416 }
00417 else
00418 {
00419 VIP_DEBUG (("RDMA write (desc=%p)", vip_desc_ptr));
00420
00421 #ifndef VI_GM_FAST_RDMA
00422
00423 vip_send_req_ptr =
00424 vip_allocate_packet (vip_gm_ptr, sizeof (VIP_PACKET_PUT_REQ));
00425 VIP_ASSERT (vip_send_req_ptr != NULL);
00426 pkt_ptr = (VIP_PACKET *) (vip_send_req_ptr->ptr);
00427 VIP_FILL_GENERIC_HEAD (pkt_ptr, total_length, vip_vi_ptr,
00428 VIP_PUT_REQ_PKT);
00429
00430 pkt_ptr->vip_pkt_put_req.net_remote_buf =
00431 VIP_HTON_UINT64 (vip_desc_ptr->DS[0].Remote.Data.AddressBits);
00432 pkt_ptr->vip_pkt_put_req.net_remote_mem =
00433 VIP_HTON_UINT32 (vip_desc_ptr->DS[0].Remote.Handle);
00434 pkt_ptr->vip_pkt_put_req.net_local_nic_index =
00435 VIP_HTON_UINT16 (vip_nic_ptr->index);
00436 pkt_ptr->vip_pkt_put_req.net_local_vi_index =
00437 VIP_HTON_UINT16 (vip_vi_ptr->index);
00438
00439 vip_send_req_ptr->type |= VIP_SEND_REQ_RELIABLE;
00440 vip_send_req_ptr->dest_port_id = vip_vi_ptr->gm_dest_port;
00441 vip_send_req_ptr->dest_gm_id = vip_vi_ptr->gm_dest_id;
00442 vip_send_req_ptr->vip_nic_ptr = vip_nic_ptr;
00443 vip_send_req_ptr->vip_vi_ptr = vip_vi_ptr;
00444 vip_send_data (vip_send_req_ptr);
00445 #endif
00446 }
00447
00448 #ifdef VI_GM_FAST_RDMA
00449
00450
00451 total_length = 0;
00452 target_ptr = vip_desc_ptr->DS[0].Remote.Data;
00453 for (i = 1; i < vip_desc_ptr->CS.SegCount; i++) {
00454 if (vip_desc_ptr->DS[i].Local.Length > 0) {
00455 vip_send_req_ptr = vip_allocate_packet (vip_gm_ptr, 0);
00456 VIP_ASSERT (vip_send_req_ptr != NULL);
00457 vip_send_req_ptr->type |= VIP_SEND_REQ_RDMA_WRITE;
00458 vip_send_req_ptr->dest_port_id = vip_vi_ptr->gm_dest_port;
00459 vip_send_req_ptr->dest_gm_id = vip_vi_ptr->gm_dest_id;
00460 vip_send_req_ptr->length = vip_desc_ptr->DS[i].Local.Length;
00461 vip_send_req_ptr->target_ptr = target_ptr;
00462 vip_send_req_ptr->ptr = vip_desc_ptr->DS[i].Local.Data.Address;
00463 vip_send_req_ptr->vip_nic_ptr = vip_nic_ptr;
00464 vip_send_req_ptr->vip_vi_ptr = vip_vi_ptr;
00465 vip_send_data (vip_send_req_ptr);
00466
00467 total_length += vip_desc_ptr->DS[i].Local.Length;
00468 target_ptr.AddressBits += vip_desc_ptr->DS[i].Local.Length;
00469 }
00470 }
00471
00472 if (((vip_desc_ptr->CS.Control & VIP_CONTROL_IMMEDIATE) != 0)
00473 && (vip_vi_ptr->reliability == VIP_SERVICE_RELIABLE_RECEPTION)) {
00474
00475 vip_send_req_ptr = vip_allocate_packet (vip_gm_ptr,
00476 sizeof (VIP_PACKET_PUT_DONE));
00477 VIP_ASSERT (vip_send_req_ptr != NULL);
00478 pkt_ptr = (VIP_PACKET *) (vip_send_req_ptr->ptr);
00479 if ((vip_desc_ptr->CS.Control & VIP_CONTROL_IMMEDIATE) != 0)
00480 {
00481 VIP_FILL_GENERIC_HEAD (pkt_ptr, total_length, vip_vi_ptr,
00482 VIP_PUT_DONE_IMM_PKT);
00483 }
00484 else
00485 {
00486 VIP_FILL_GENERIC_HEAD (pkt_ptr, total_length, vip_vi_ptr,
00487 VIP_PUT_DONE_PKT);
00488 }
00489
00490 pkt_ptr->vip_pkt_put_done.net_local_nic_index =
00491 VIP_HTON_UINT16 (vip_nic_ptr->index);
00492 pkt_ptr->vip_pkt_put_done.net_local_vi_index =
00493 VIP_HTON_UINT16 (vip_vi_ptr->index);
00494
00495 vip_send_req_ptr->type |= VIP_SEND_REQ_RELIABLE;
00496 vip_send_req_ptr->dest_port_id = vip_vi_ptr->gm_dest_port;
00497 vip_send_req_ptr->dest_gm_id = vip_vi_ptr->gm_dest_id;
00498 vip_send_req_ptr->vip_nic_ptr = vip_nic_ptr;
00499 vip_send_req_ptr->vip_vi_ptr = vip_vi_ptr;
00500 vip_send_req_ptr->vip_desc_ptr = vip_desc_ptr;
00501 vip_send_data (vip_send_req_ptr);
00502 } else {
00503 vip_send_req_ptr = vip_allocate_packet (vip_gm_ptr, 0);
00504 VIP_ASSERT (vip_send_req_ptr != NULL);
00505 vip_send_req_ptr->type |= VIP_SEND_REQ_RDMA_WRITE;
00506 vip_send_req_ptr->dest_port_id = vip_vi_ptr->gm_dest_port;
00507 vip_send_req_ptr->dest_gm_id = vip_vi_ptr->gm_dest_id;
00508 vip_send_req_ptr->length = 1;
00509 vip_send_req_ptr->target_ptr = vip_desc_ptr->DS[0].Remote.Data;
00510 vip_send_req_ptr->ptr = vip_desc_ptr->DS[1].Local.Data.Address;
00511 vip_send_req_ptr->vip_nic_ptr = vip_nic_ptr;
00512 vip_send_req_ptr->vip_vi_ptr = vip_vi_ptr;
00513 vip_send_req_ptr->vip_desc_ptr = vip_desc_ptr;
00514 vip_send_data (vip_send_req_ptr);
00515 }
00516 #endif
00517
00518 }
00519 VIP_DEBUG (("Success"));
00520 return;
00521
00522 out_with_sync_error:
00523
00524 vip_notify_desc_completion (vip_desc_ptr, vip_vi_ptr, VIP_FALSE);
00525 VIP_DEBUG (("Synchronous error"));
00526 if ((vip_vi_ptr->reliability != VIP_SERVICE_UNRELIABLE)
00527 && (vip_vi_ptr->state != VIP_STATE_ERROR))
00528 {
00529
00530 vip_vi_transition_to_error_state (vip_vi_ptr, VIP_TRUE);
00531
00532
00533 vip_generate_async_error (vip_nic_ptr, vip_vi_ptr, NULL, NULL,
00534 VIP_RESOURCE_VI, VIP_ERROR_CONN_LOST, 0);
00535 }
00536 else
00537 {
00538
00539 VIP_ASSERT (vip_vi_ptr->send_queue.count_to_process > 0);
00540 vip_vi_ptr->send_queue.count_to_process--;
00541 vip_vi_ptr->send_queue.current_desc = vip_desc_ptr->CS.Next.Address;
00542 vip_vi_ptr->send_queue.current_mem = vip_desc_ptr->CS.NextHandle;
00543
00544
00545 if (vip_vi_ptr->send_queue.count_to_process > 0)
00546 {
00547 vip_process_send_desc (vip_vi_ptr);
00548 }
00549 }
00550 return;
00551
00552 async_post_desc_error:
00553
00554 vip_generate_async_error (vip_nic_ptr, vip_vi_ptr, NULL, vip_desc_ptr,
00555 VIP_RESOURCE_DESCRIPTOR, VIP_ERROR_POST_DESC, 0);
00556
00557 if (vip_vi_ptr->state != VIP_STATE_ERROR)
00558 {
00559
00560 vip_vi_transition_to_error_state (vip_vi_ptr, VIP_TRUE);
00561
00562
00563 vip_generate_async_error (vip_nic_ptr, vip_vi_ptr, NULL, NULL,
00564 VIP_RESOURCE_VI, VIP_ERROR_CONN_LOST, 0);
00565 }
00566
00567 VIP_DEBUG (("Asynchronous error"));
00568 return;
00569 }
00570
00587 VIP_SEND_REQ *
00588 vip_allocate_packet (VIP_GM * vip_gm_ptr, VIP_UINT32 length)
00589 {
00590 VIP_SEND_REQ *vip_send_req_ptr;
00591 VIP_DEBUG_LABEL (("vip_allocate_packet"));
00592
00593 VIP_ASSERT (vip_gm_ptr != NULL);
00594 VIP_ASSERT (length <= VI_GM_EAGER_LENGTH);
00595 VIP_ASSERT_MUTEX_LOCKED (&(vip_gm_ptr->lock));
00596
00597 vip_send_req_ptr =
00598 (VIP_SEND_REQ *) gm_lookaside_alloc (vip_gm_ptr->vip_send_req_lookaside);
00599 if (vip_send_req_ptr == NULL)
00600 {
00601 VIP_DEBUG (("Error allocating send request"));
00602 return NULL;
00603 }
00604
00605 if (length > 0)
00606 {
00607 if (vip_gm_ptr->send_buffers_free != NULL)
00608 {
00609 VIP_ASSERT (vip_gm_ptr->send_buf_free_cnt > 0);
00610 vip_send_req_ptr->ptr = vip_gm_ptr->send_buffers_free;
00611 vip_gm_ptr->send_buffers_free =
00612 *((VIP_PVOID *) (vip_gm_ptr->send_buffers_free));
00613 vip_send_req_ptr->type = VIP_SEND_REQ_DMA;
00614 vip_gm_ptr->send_buf_free_cnt--;
00615 }
00616 else
00617 {
00618 VIP_ASSERT (vip_gm_ptr->send_buf_free_cnt == 0);
00619 vip_send_req_ptr->ptr = malloc (length);
00620 if (vip_send_req_ptr->ptr == NULL)
00621 {
00622 VIP_DEBUG (("Not enough memory, malloc failed"));
00623 gm_lookaside_free (vip_send_req_ptr);
00624 return NULL;
00625 }
00626 vip_send_req_ptr->type = VIP_SEND_REQ_MALLOC;
00627 }
00628 }
00629 else
00630 {
00631 vip_send_req_ptr->ptr = NULL;
00632 vip_send_req_ptr->type = VIP_SEND_REQ_NONE;
00633 }
00634
00635 vip_send_req_ptr->dest_port_id = 0;
00636 vip_send_req_ptr->dest_gm_id = 0;
00637 vip_send_req_ptr->length = length;
00638 vip_send_req_ptr->target_ptr.AddressBits = 0;
00639 vip_send_req_ptr->vip_gm_ptr = vip_gm_ptr;
00640 vip_send_req_ptr->vip_nic_ptr = NULL;
00641 vip_send_req_ptr->vip_vi_ptr = NULL;
00642 vip_send_req_ptr->vip_desc_ptr = NULL;
00643 vip_send_req_ptr->next = NULL;
00644
00645 VIP_DEBUG (("Success"));
00646 return vip_send_req_ptr;
00647 }
00648
00661 void
00662 vip_send_data (VIP_SEND_REQ * vip_send_req_ptr)
00663 {
00664 VIP_GM *vip_gm_ptr;
00665 VIP_PVOID pkt;
00666 VIP_DEBUG_LABEL (("vip_send_data"));
00667
00668 VIP_ASSERT (vip_send_req_ptr != NULL);
00669 VIP_ASSERT (vip_send_req_ptr->type > 0);
00670 VIP_ASSERT (vip_send_req_ptr->dest_port_id > 0);
00671 VIP_ASSERT (vip_send_req_ptr->dest_gm_id > 0);
00672 VIP_ASSERT (vip_send_req_ptr->length > 0);
00673 VIP_ASSERT (vip_send_req_ptr->ptr != NULL);
00674 VIP_ASSERT (vip_send_req_ptr->vip_gm_ptr != NULL);
00675
00676 pkt = vip_send_req_ptr->ptr;
00677 vip_gm_ptr = vip_send_req_ptr->vip_gm_ptr;
00678 VIP_ASSERT_MUTEX_LOCKED (&(vip_gm_ptr->lock));
00679
00680 if ((vip_gm_ptr->send_fifo_head == NULL)
00681 && ((vip_send_req_ptr->type & VIP_SEND_REQ_MALLOC) == 0)
00682 && (vip_gm_ptr->send_tokens > 0))
00683 {
00684 VIP_ASSERT (vip_gm_ptr->send_fifo_head == NULL);
00685 VIP_ASSERT (vip_gm_ptr->send_fifo_tail == NULL);
00686 VIP_ASSERT (vip_gm_ptr->send_fifo_queued == 0);
00687
00688 switch ((vip_send_req_ptr->type) & VIP_SEND_REQ_OPMASK)
00689 {
00690 case VIP_SEND_REQ_RELIABLE:
00691 VIP_ASSERT ((vip_send_req_ptr->type & VIP_SEND_REQ_NONE) == 0);
00692 VIP_ASSERT (vip_send_req_ptr->target_ptr.Address == NULL);
00693
00694
00695
00696
00697
00698 gm_send_with_callback (vip_gm_ptr->gm_port, pkt,
00699 VI_GM_CTRL_GM_SIZE,
00700 vip_send_req_ptr->length,
00701 GM_LOW_PRIORITY,
00702 vip_send_req_ptr->dest_gm_id,
00703 vip_send_req_ptr->dest_port_id,
00704 vip_sent_callback, vip_send_req_ptr);
00705 VIP_DEBUG (("Reliable packet sent immediately"));
00706 break;
00707
00708 case VIP_SEND_REQ_UNRELIABLE:
00709 VIP_ASSERT (vip_send_req_ptr->length
00710 <= gm_mtu (vip_gm_ptr->gm_port));
00711 VIP_ASSERT (vip_send_req_ptr->vip_vi_ptr != NULL);
00712 VIP_ASSERT (vip_send_req_ptr->vip_vi_ptr->reliability
00713 == VIP_SERVICE_UNRELIABLE);
00714 VIP_ASSERT ((vip_send_req_ptr->type & VIP_SEND_REQ_NONE) == 0);
00715 VIP_ASSERT (vip_send_req_ptr->target_ptr.Address == NULL);
00716
00717
00718
00719
00720
00721
00722 gm_datagram_send (vip_gm_ptr->gm_port, pkt,
00723 VI_GM_CTRL_GM_SIZE,
00724 vip_send_req_ptr->length,
00725 GM_LOW_PRIORITY,
00726 vip_send_req_ptr->dest_gm_id,
00727 vip_send_req_ptr->dest_port_id,
00728 vip_sent_callback, vip_send_req_ptr);
00729 VIP_DEBUG (("Unreliable packet sent immediately"));
00730 break;
00731
00732 case VIP_SEND_REQ_RDMA_WRITE:
00733 VIP_ASSERT ((vip_send_req_ptr->type & VIP_SEND_REQ_NONE) != 0);
00734 VIP_ASSERT (vip_send_req_ptr->vip_vi_ptr != NULL);
00735 VIP_ASSERT (vip_send_req_ptr->target_ptr.Address != NULL);
00736
00737 gm_directed_send_with_callback
00738 (vip_gm_ptr->gm_port, pkt,
00739 (gm_remote_ptr_t) (vip_send_req_ptr->target_ptr.AddressBits),
00740 vip_send_req_ptr->length,
00741 GM_LOW_PRIORITY,
00742 vip_send_req_ptr->dest_gm_id,
00743 vip_send_req_ptr->dest_port_id,
00744 vip_sent_callback, vip_send_req_ptr);
00745 VIP_DEBUG (("RDMA PUT packet sent immediately"));
00746 break;
00747
00748 default:
00749 VIP_ABORT (("Invalid operation type in send request"));
00750 }
00751
00752 vip_gm_ptr->send_tokens--;
00753 if ((vip_send_req_ptr->vip_vi_ptr != NULL)
00754 && (vip_send_req_ptr->vip_desc_ptr != NULL))
00755 {
00756 vip_send_req_ptr->vip_vi_ptr->pending_callbacks++;
00757 }
00758 }
00759 else
00760 {
00761 if (vip_gm_ptr->send_fifo_head == NULL)
00762 {
00763 VIP_ASSERT (vip_gm_ptr->send_fifo_tail == NULL);
00764 VIP_ASSERT (vip_gm_ptr->send_fifo_queued == 0);
00765 vip_gm_ptr->send_fifo_head = vip_send_req_ptr;
00766 }
00767 else
00768 {
00769 VIP_ASSERT (vip_gm_ptr->send_fifo_tail->next == NULL);
00770 vip_gm_ptr->send_fifo_tail->next = vip_send_req_ptr;
00771 }
00772
00773 vip_gm_ptr->send_fifo_tail = vip_send_req_ptr;
00774 vip_send_req_ptr->next = NULL;
00775 vip_gm_ptr->send_fifo_queued++;
00776 VIP_DEBUG (("Packet queued in the send FIFO"));
00777 }
00778
00779 VIP_DEBUG (("Success"));
00780 }
00781
00794 static void
00795 vip_flush_fifo_send (VIP_GM * vip_gm_ptr)
00796 {
00797 VIP_SEND_REQ *vip_send_req_ptr;
00798 VIP_PVOID pkt;
00799 VIP_DEBUG_LABEL (("vip_flush_fifo_send"));
00800
00801 VIP_ASSERT_MUTEX_LOCKED (&(vip_gm_ptr->lock));
00802 VIP_ASSERT_MUTEX_LOCKED (&(vip_nic_ptr->lock));
00803
00804 while ((vip_gm_ptr->send_fifo_head != NULL)
00805 && (vip_gm_ptr->send_tokens > 0))
00806 {
00807 VIP_ASSERT (vip_gm_ptr->send_fifo_queued > 0);
00808 vip_send_req_ptr = vip_gm_ptr->send_fifo_head;
00809
00810 if ((vip_send_req_ptr->type & VIP_SEND_REQ_MALLOC) != 0)
00811 {
00812 if (vip_gm_ptr->send_buffers_free == NULL)
00813 {
00814 VIP_ASSERT (vip_gm_ptr->send_buf_free_cnt == 0);
00815 return;
00816 }
00817 else
00818 {
00819 VIP_ASSERT (vip_gm_ptr->send_buffers_free != NULL);
00820 VIP_ASSERT (vip_gm_ptr->send_buf_free_cnt > 0);
00821 VIP_ASSERT (vip_send_req_ptr->length > 0);
00822 VIP_ASSERT (vip_send_req_ptr->ptr != NULL);
00823 VIP_ASSERT (vip_send_req_ptr->vip_gm_ptr != NULL);
00824
00825 pkt = vip_gm_ptr->send_buffers_free;
00826 vip_gm_ptr->send_buffers_free =
00827 *((VIP_PVOID *) (vip_gm_ptr->send_buffers_free));
00828 memcpy (pkt, vip_send_req_ptr->ptr, vip_send_req_ptr->length);
00829 free (vip_send_req_ptr->ptr);
00830 vip_send_req_ptr->type |= ~VIP_SEND_REQ_MALLOC;
00831 vip_send_req_ptr->type |= VIP_SEND_REQ_DMA;
00832 vip_send_req_ptr->ptr = pkt;
00833 vip_gm_ptr->send_buf_free_cnt--;
00834 }
00835 }
00836
00837 pkt = vip_send_req_ptr->ptr;
00838 switch ((vip_send_req_ptr->type) & VIP_SEND_REQ_OPMASK)
00839 {
00840 case VIP_SEND_REQ_RELIABLE:
00841 VIP_ASSERT ((vip_send_req_ptr->type & VIP_SEND_REQ_NONE) == 0);
00842 VIP_ASSERT (vip_send_req_ptr->target_ptr.Address == NULL);
00843
00844
00845
00846
00847
00848 gm_send_with_callback (vip_gm_ptr->gm_port, pkt,
00849 VI_GM_CTRL_GM_SIZE,
00850 vip_send_req_ptr->length,
00851 GM_LOW_PRIORITY,
00852 vip_send_req_ptr->dest_gm_id,
00853 vip_send_req_ptr->dest_port_id,
00854 vip_sent_callback, vip_send_req_ptr);
00855 VIP_DEBUG (("Reliable packet sent from FIFO"));
00856 break;
00857
00858 case VIP_SEND_REQ_UNRELIABLE:
00859 VIP_ASSERT (vip_send_req_ptr->length
00860 <= gm_mtu (vip_gm_ptr->gm_port));
00861 VIP_ASSERT (vip_send_req_ptr->vip_vi_ptr != NULL);
00862 VIP_ASSERT (vip_send_req_ptr->vip_vi_ptr->reliability
00863 == VIP_SERVICE_UNRELIABLE);
00864 VIP_ASSERT ((vip_send_req_ptr->type & VIP_SEND_REQ_NONE) == 0);
00865 VIP_ASSERT (vip_send_req_ptr->target_ptr.Address == NULL);
00866
00867
00868
00869
00870
00871
00872 gm_datagram_send (vip_gm_ptr->gm_port, pkt,
00873 VI_GM_CTRL_GM_SIZE,
00874 vip_send_req_ptr->length,
00875 GM_LOW_PRIORITY,
00876 vip_send_req_ptr->dest_gm_id,
00877 vip_send_req_ptr->dest_port_id,
00878 vip_sent_callback, vip_send_req_ptr);
00879 VIP_DEBUG (("Unreliable packet sent from FIFO"));
00880 break;
00881
00882 case VIP_SEND_REQ_RDMA_WRITE:
00883 VIP_ASSERT ((vip_send_req_ptr->type & VIP_SEND_REQ_NONE) != 0);
00884 VIP_ASSERT (vip_send_req_ptr->vip_vi_ptr != NULL);
00885 VIP_ASSERT (vip_send_req_ptr->target_ptr.Address != NULL);
00886
00887 gm_directed_send_with_callback
00888 (vip_gm_ptr->gm_port, pkt,
00889 (gm_remote_ptr_t) (vip_send_req_ptr->target_ptr.AddressBits),
00890 vip_send_req_ptr->length,
00891 GM_LOW_PRIORITY,
00892 vip_send_req_ptr->dest_gm_id,
00893 vip_send_req_ptr->dest_port_id,
00894 vip_sent_callback, vip_send_req_ptr);
00895 VIP_DEBUG (("RDMA PUT packet sent from FIFO"));
00896 break;
00897
00898 default:
00899 VIP_ABORT (("Invalid operation type in send request"));
00900 }
00901
00902 vip_gm_ptr->send_tokens--;
00903 vip_gm_ptr->send_fifo_queued--;
00904 vip_gm_ptr->send_fifo_head = vip_send_req_ptr->next;
00905 if ((vip_send_req_ptr->vip_vi_ptr != NULL)
00906 && (vip_send_req_ptr->vip_desc_ptr != NULL))
00907 {
00908 vip_send_req_ptr->vip_vi_ptr->pending_callbacks++;
00909 }
00910
00911 if (vip_gm_ptr->send_fifo_head == NULL)
00912 {
00913 VIP_ASSERT (vip_gm_ptr->send_fifo_tail == vip_send_req_ptr);
00914 VIP_ASSERT (vip_gm_ptr->send_fifo_queued == 0);
00915 vip_gm_ptr->send_fifo_tail = NULL;
00916 }
00917 }
00918 }
00919
00932 static void
00933 vip_sent_report_callback_status (VIP_SEND_REQ * vip_send_req_ptr,
00934 gm_status_t status)
00935 {
00936 VIP_GM *vip_gm_ptr;
00937 VIP_DEBUG_LABEL (("Error"));
00938
00939 #if VI_GM_CATASTROPHIC_ERROR_VERBOSE
00940
00941 vip_gm_ptr = vip_send_req_ptr->vip_gm_ptr;
00942 VIP_DEBUG_PROTECTED (("GM send operation from %s (port %d)"
00943 " to %s (port %d%s) returned the error %u <%s>.\n",
00944 gm_node_id_to_host_name (vip_gm_ptr->gm_port,
00945 vip_gm_ptr->gm_id),
00946 vip_gm_ptr->gm_port_id,
00947 gm_node_id_to_host_name (vip_gm_ptr->gm_port,
00948 vip_send_req_ptr->dest_gm_id),
00949 vip_send_req_ptr->dest_port_id,
00950 ((vip_send_req_ptr->dest_port_id
00951 == VI_GM_PORT_CONN_MANAGER)
00952 ? ", Connection Manager" : ""), status,
00953 gm_strerror (status)));
00954
00955 #else
00956
00957 VIP_DEBUG (("Send completion error, message to GM id %d / port %d (%s)\n",
00958 vip_send_req_ptr->dest_gm_id, vip_send_req_ptr->dest_port_id,
00959 gm_strerror (status)));
00960
00961 #endif
00962 }
00963
00964
00980 static void
00981 vip_resume_callback (struct gm_port *port, void *context, gm_status_t status)
00982 {
00983 VIP_GM *vip_gm_ptr;
00984 VIP_VI *vip_vi_ptr;
00985 VIP_SEND_REQ *vip_send_req_ptr;
00986 VIP_DESCRIPTOR *vip_desc_ptr;
00987 VIP_DEBUG_LABEL (("vip_resume_callback"));
00988
00989 VIP_ASSERT (context != NULL);
00990 vip_send_req_ptr = (VIP_SEND_REQ *) context;
00991 vip_gm_ptr = vip_send_req_ptr->vip_gm_ptr;
00992 vip_vi_ptr = vip_send_req_ptr->vip_vi_ptr;
00993 VIP_ASSERT (vip_gm_ptr != NULL);
00994 VIP_ASSERT_MUTEX_LOCKED (&(vip_gm_ptr->lock));
00995
00996 VIP_DEBUG (("Resume sending to GM id %d / port %d\n",
00997 vip_send_req_ptr->dest_gm_id, vip_send_req_ptr->dest_port_id));
00998
00999 vip_desc_ptr = vip_send_req_ptr->vip_desc_ptr;
01000 if (vip_send_req_ptr->vip_nic_ptr != NULL)
01001 {
01002 if (VIP_INVALID_NIC_HANDLE (vip_send_req_ptr->vip_nic_ptr))
01003 {
01004 VIP_DEBUG (("Invalid NIC handle in send descriptor"));
01005 goto resume_recycle;
01006 }
01007
01008 VIP_MUTEX_LOCK (&(vip_send_req_ptr->vip_nic_ptr->lock));
01009 if (vip_desc_ptr != NULL)
01010 {
01011 vip_generate_async_error
01012 (vip_send_req_ptr->vip_nic_ptr, vip_vi_ptr, NULL,
01013 vip_desc_ptr, VIP_RESOURCE_NIC, VIP_ERROR_CATASTROPHIC,
01014 (vip_desc_ptr->CS.Status & VIP_STATUS_OP_MASK));
01015 }
01016 else
01017 {
01018 if (vip_vi_ptr->state != VIP_STATE_CONNECT_PENDING)
01019 {
01020 vip_generate_async_error
01021 (vip_send_req_ptr->vip_nic_ptr, vip_vi_ptr, NULL,
01022 vip_desc_ptr, VIP_RESOURCE_NIC, VIP_ERROR_CATASTROPHIC, 0);
01023 }
01024 }
01025
01026 if (vip_vi_ptr != NULL)
01027 {
01028
01029 if (vip_desc_ptr != NULL)
01030 {
01031 VIP_ASSERT (vip_vi_ptr->pending_callbacks > 0);
01032 vip_vi_ptr->pending_callbacks--;
01033
01034 vip_desc_ptr->CS.Status |= VIP_STATUS_TRANSPORT_ERROR;
01035 vip_notify_desc_completion (vip_desc_ptr, vip_vi_ptr,
01036 VIP_FALSE);
01037
01038 if (vip_vi_ptr->reliability != VIP_SERVICE_UNRELIABLE)
01039 {
01040
01041 if (vip_vi_ptr->send_queue.count_to_process > 0)
01042 {
01043 vip_vi_ptr->send_queue.count_to_process--;
01044 vip_vi_ptr->send_queue.current_desc =
01045 vip_desc_ptr->CS.Next.Address;
01046 vip_vi_ptr->send_queue.current_mem =
01047 vip_desc_ptr->CS.NextHandle;
01048 }
01049
01050
01051 if (vip_vi_ptr->send_queue.count_to_process > 0)
01052 {
01053 vip_process_send_desc (vip_vi_ptr);
01054 }
01055 }
01056 }
01057
01058 if ((vip_vi_ptr->state != VIP_STATE_ERROR)
01059 && (vip_vi_ptr->state != VIP_STATE_CONNECT_PENDING))
01060 {
01061
01062 vip_vi_transition_to_error_state (vip_vi_ptr, VIP_TRUE);
01063
01064
01065 vip_generate_async_error (vip_send_req_ptr->vip_nic_ptr,
01066 vip_vi_ptr, NULL, NULL,
01067 VIP_RESOURCE_VI,
01068 VIP_ERROR_CONN_LOST, 0);
01069 }
01070 }
01071
01072 VIP_MUTEX_UNLOCK (&(vip_send_req_ptr->vip_nic_ptr->lock));
01073 }
01074
01075 resume_recycle:
01076 switch (vip_send_req_ptr->type & VIP_SEND_REQ_TYPEMASK)
01077 {
01078 case VIP_SEND_REQ_DMA:
01079 *((VIP_PVOID *) (vip_send_req_ptr->ptr)) =
01080 vip_gm_ptr->send_buffers_free;
01081 vip_gm_ptr->send_buffers_free = vip_send_req_ptr->ptr;
01082 vip_gm_ptr->send_buf_free_cnt++;
01083 break;
01084
01085 case VIP_SEND_REQ_NONE:
01086 break;
01087
01088 case VIP_SEND_REQ_MALLOC:
01089 free (vip_send_req_ptr->ptr);
01090 break;
01091
01092 default:
01093 VIP_ABORT (("Bad send request type in resume callback"));
01094 }
01095
01096 VIP_ASSERT (vip_gm_ptr->send_tokens <= vip_gm_ptr->max_send_tokens);
01097 vip_gm_ptr->send_tokens++;
01098 gm_lookaside_free (vip_send_req_ptr);
01099
01100
01101 if (vip_gm_ptr->send_fifo_head != NULL)
01102 {
01103 vip_flush_fifo_send (vip_gm_ptr);
01104 }
01105
01106 VIP_DEBUG (("Success"));
01107 }
01108
01109
01124 void
01125 vip_sent_callback (struct gm_port *port, void *context, gm_status_t status)
01126 {
01127 VIP_GM *vip_gm_ptr;
01128 VIP_VI *vip_vi_ptr;
01129 VIP_SEND_REQ *vip_send_req_ptr;
01130 VIP_DESCRIPTOR *vip_desc_ptr;
01131 VIP_DEBUG_LABEL (("vip_sent_callback"));
01132
01133 VIP_ASSERT (context != NULL);
01134 vip_send_req_ptr = (VIP_SEND_REQ *) context;
01135 vip_gm_ptr = vip_send_req_ptr->vip_gm_ptr;
01136 vip_vi_ptr = vip_send_req_ptr->vip_vi_ptr;
01137 VIP_ASSERT (vip_gm_ptr != NULL);
01138 VIP_ASSERT_MUTEX_LOCKED (&(vip_gm_ptr->lock));
01139
01140 vip_desc_ptr = vip_send_req_ptr->vip_desc_ptr;
01141 if (status == GM_SUCCESS)
01142 {
01143 if (vip_desc_ptr != NULL)
01144 {
01145 if (VIP_INVALID_NIC_HANDLE (vip_send_req_ptr->vip_nic_ptr))
01146 {
01147 VIP_DEBUG (("Invalid NIC handle in send descriptor"));
01148 goto sent_recycle;
01149 }
01150
01151 VIP_MUTEX_LOCK (&(vip_send_req_ptr->vip_nic_ptr->lock));
01152 if (VIP_INVALID_VI_HANDLE (vip_vi_ptr))
01153 {
01154 VIP_ABORT (("Invalid VI handle in send descriptor"));
01155 }
01156
01157 VIP_ASSERT (vip_vi_ptr->pending_callbacks > 0);
01158 vip_vi_ptr->pending_callbacks--;
01159
01160
01161 if (vip_vi_ptr->reliability != VIP_SERVICE_RELIABLE_RECEPTION)
01162 {
01163 vip_notify_desc_completion (vip_desc_ptr, vip_vi_ptr,
01164 VIP_FALSE);
01165
01166
01167 VIP_ASSERT (vip_vi_ptr->send_queue.count_to_process > 0);
01168 vip_vi_ptr->send_queue.count_to_process--;
01169 vip_vi_ptr->send_queue.current_desc =
01170 vip_desc_ptr->CS.Next.Address;
01171 vip_vi_ptr->send_queue.current_mem =
01172 vip_desc_ptr->CS.NextHandle;
01173
01174
01175 if (vip_vi_ptr->send_queue.count_to_process > 0)
01176 {
01177 vip_process_send_desc (vip_vi_ptr);
01178 }
01179 }
01180 VIP_MUTEX_UNLOCK (&(vip_send_req_ptr->vip_nic_ptr->lock));
01181 }
01182 }
01183 else
01184 {
01185 vip_sent_report_callback_status (vip_send_req_ptr, status);
01186 gm_resume_sending (port, GM_LOW_PRIORITY,
01187 vip_send_req_ptr->dest_gm_id,
01188 vip_send_req_ptr->dest_port_id,
01189 vip_resume_callback, context);
01190 VIP_DEBUG (("Resuming sending"));
01191 return;
01192 }
01193
01194 sent_recycle:
01195 switch (vip_send_req_ptr->type & VIP_SEND_REQ_TYPEMASK)
01196 {
01197 case VIP_SEND_REQ_DMA:
01198 *((VIP_PVOID *) (vip_send_req_ptr->ptr)) =
01199 vip_gm_ptr->send_buffers_free;
01200 vip_gm_ptr->send_buffers_free = vip_send_req_ptr->ptr;
01201 vip_gm_ptr->send_buf_free_cnt++;
01202 break;
01203
01204 case VIP_SEND_REQ_NONE:
01205 break;
01206
01207 case VIP_SEND_REQ_MALLOC:
01208 free (vip_send_req_ptr->ptr);
01209 break;
01210
01211 default:
01212 VIP_ABORT (("Bad send request type in send callback"));
01213 }
01214
01215 VIP_ASSERT (vip_gm_ptr->send_tokens <= vip_gm_ptr->max_send_tokens);
01216 vip_gm_ptr->send_tokens++;
01217 gm_lookaside_free (vip_send_req_ptr);
01218
01219
01220 if (vip_gm_ptr->send_fifo_head != NULL)
01221 {
01222 vip_flush_fifo_send (vip_gm_ptr);
01223 }
01224