00001
00002
00003
00004
00005
00006
00007
00013 #include <stdlib.h>
00014 #include <string.h>
00015
00016 #include "vipl_priv.h"
00017
00018
00086 VIP_ENTRY_POINT VIP_RETURN
00087 VipConnectRequest (VIP_VI_HANDLE ViHandle,
00088 VIP_NET_ADDRESS * LocalAddr,
00089 VIP_NET_ADDRESS * RemoteAddr,
00090 VIP_ULONG Timeout, VIP_VI_ATTRIBUTES * RemoteViAttribs)
00091 {
00092 VIP_VI *vip_vi_ptr;
00093 VIP_GM *vip_gm_ptr;
00094 VIP_NIC *vip_nic_ptr;
00095 VIP_CONN *vip_conn_ptr;
00096 VIP_UINT32 remote_gm_id;
00097 VIP_UINT32 conn_mgr_node_id;
00098 VIP_SEND_REQ *vip_send_req_ptr;
00099 VIP_PACKET_CONN_LIST *pkt_list_ptr;
00100 VIP_PACKET_CONN_ACK *pkt_ack_ptr;
00101 VIP_RETURN vip_status = VIP_SUCCESS;
00102 gm_status_t gm_status;
00103 VIP_DEBUG_LABEL (("VipConnectRequest"));
00104
00105
00106 if (LocalAddr == NULL)
00107 {
00108 VIP_DEBUG (("LocalAddr is NULL"));
00109 return VIP_INVALID_PARAMETER;
00110 }
00111
00112 if (RemoteAddr == NULL)
00113 {
00114 VIP_DEBUG (("RemoteAddr is NULL"));
00115 return VIP_INVALID_PARAMETER;
00116 }
00117
00118 if (RemoteViAttribs == NULL)
00119 {
00120 VIP_DEBUG (("RemoteViAttribs is NULL"));
00121 return VIP_INVALID_PARAMETER;
00122 }
00123
00124 if (Timeout == 0)
00125 {
00126 VIP_DEBUG (("Timeout 0"));
00127 return VIP_INVALID_PARAMETER;
00128 }
00129
00130
00131 if (LocalAddr->HostAddressLen != VI_GM_MAC_ADDRESS_LEN)
00132 {
00133 VIP_DEBUG (("Local Host Address Length is invalid (should be %d)",
00134 VI_GM_MAC_ADDRESS_LEN));
00135 return VIP_INVALID_PARAMETER;
00136 }
00137
00138
00139 if (LocalAddr->DiscriminatorLen > VI_GM_MAX_DISCRIMINATOR_LEN)
00140 {
00141 VIP_DEBUG (("Local Discriminator Length is too large (max=%d)",
00142 VI_GM_MAX_DISCRIMINATOR_LEN));
00143 return VIP_INVALID_PARAMETER;
00144 }
00145
00146
00147 if (RemoteAddr->HostAddressLen != VI_GM_MAC_ADDRESS_LEN)
00148 {
00149 VIP_DEBUG (("Remote Host Address Length is invalid (should be %d)",
00150 VI_GM_MAC_ADDRESS_LEN));
00151 return VIP_INVALID_PARAMETER;
00152 }
00153
00154
00155 if (RemoteAddr->DiscriminatorLen > VI_GM_MAX_DISCRIMINATOR_LEN)
00156 {
00157 VIP_DEBUG (("Remote Discriminator Length is too large (max=%d)",
00158 VI_GM_MAX_DISCRIMINATOR_LEN));
00159 return VIP_INVALID_PARAMETER;
00160 }
00161
00162
00163 vip_vi_ptr = (VIP_VI *) ViHandle;
00164 if (VIP_INVALID_VI_HANDLE (vip_vi_ptr))
00165 {
00166 VIP_DEBUG (("Invalid VI handle"));
00167 return VIP_INVALID_PARAMETER;
00168 }
00169 vip_nic_ptr = vip_vi_ptr->handle.vip_nic_ptr;
00170 vip_gm_ptr = vip_nic_ptr->vip_gm_ptr;
00171 VIP_MUTEX_LOCK (&(vip_gm_ptr->lock));
00172 VIP_PROGRESSION (vip_gm_ptr);
00173 VIP_MUTEX_LOCK (&(vip_nic_ptr->lock));
00174
00175
00176 if (vip_vi_ptr->state != VIP_STATE_IDLE)
00177 {
00178 VIP_DEBUG (("VI is not in IDLE state"));
00179 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00180 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00181 return VIP_INVALID_STATE;
00182 }
00183
00184
00185 if (memcmp (vip_gm_ptr->mac_address,
00186 LocalAddr->HostAddress, LocalAddr->HostAddressLen) != 0)
00187 {
00188 VIP_DEBUG (("Host Address does not match NIC id"));
00189 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00190 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00191 return VIP_INVALID_PARAMETER;
00192 }
00193
00194
00195 VIP_ENTER_IOCTL (vip_gm_ptr);
00196 gm_status = gm_unique_id_to_node_id (vip_gm_ptr->gm_port,
00197 RemoteAddr->HostAddress,
00198 &remote_gm_id);
00199 VIP_EXIT_IOCTL (vip_gm_ptr);
00200
00201 if (gm_status != GM_SUCCESS)
00202 {
00203 VIP_DEBUG_GM (("Unable to get the GM id of the remote Myrinet board"));
00204 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00205 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00206 return VIP_INVALID_PARAMETER;
00207 }
00208
00209 if (remote_gm_id == GM_NO_SUCH_NODE_ID)
00210 {
00211 VIP_DEBUG (("Remote Host Address is unknown from the Myrinet map"));
00212 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00213 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00214 return VIP_INVALID_PARAMETER;
00215 }
00216
00217 VIP_MUTEX_LOCK (&vip_gm_host_name_lock);
00218 if (strchr (gm_node_id_to_host_name (vip_gm_ptr->gm_port,
00219 remote_gm_id), ':') != NULL)
00220 {
00221 VIP_UCHAR gm_name[GM_MAX_HOST_NAME_LEN];
00222
00223 strcpy (gm_name, gm_node_id_to_host_name (vip_gm_ptr->gm_port,
00224 remote_gm_id));
00225 *strchr (gm_name, ':') = '\0';
00226 conn_mgr_node_id = gm_host_name_to_node_id (vip_gm_ptr->gm_port,
00227 gm_name);
00228 if (conn_mgr_node_id == GM_NO_SUCH_NODE_ID)
00229 {
00230 VIP_MUTEX_UNLOCK (&vip_gm_host_name_lock);
00231 VIP_DEBUG (("Unable to get the GM id of the remote Myrinet board 0"));
00232 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00233 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00234 return VIP_INVALID_PARAMETER;
00235 }
00236 }
00237 else
00238 {
00239 conn_mgr_node_id = remote_gm_id;
00240 }
00241 VIP_MUTEX_UNLOCK (&vip_gm_host_name_lock);
00242
00243
00244 vip_conn_ptr = (VIP_CONN *)
00245 vip_allocate_handle (&(vip_nic_ptr->vip_conn_set));
00246 if (vip_conn_ptr == NULL)
00247 {
00248 VIP_DEBUG (("VIP_CONN alloc failed"));
00249 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00250 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00251 return VIP_ERROR_RESOURCE;
00252 }
00253
00254
00255 vip_send_req_ptr =
00256 vip_allocate_packet (vip_gm_ptr, sizeof (VIP_PACKET_CONN_LIST));
00257 if (vip_send_req_ptr == NULL)
00258 {
00259 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00260 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00261 return VIP_ERROR_RESOURCE;
00262 }
00263
00264 vip_conn_ptr->waiting_list = VIP_FALSE;
00265 vip_conn_ptr->remote_vi_attribs.ReliabilityLevel = vip_vi_ptr->reliability;
00266 vip_conn_ptr->remote_vi_attribs.MaxTransferSize = vip_vi_ptr->mtu;
00267 vip_conn_ptr->remote_vi_attribs.QoS = vip_vi_ptr->qos;
00268 vip_conn_ptr->remote_vi_attribs.EnableRdmaRead = VIP_FALSE;
00269 vip_conn_ptr->locale_disc_len = LocalAddr->DiscriminatorLen;
00270 memcpy (vip_conn_ptr->locale_net_addr, LocalAddr->HostAddress,
00271 VI_GM_MAC_ADDRESS_LEN + LocalAddr->DiscriminatorLen);
00272 vip_conn_ptr->remote_disc_len = RemoteAddr->DiscriminatorLen;
00273 memcpy (vip_conn_ptr->remote_net_addr, RemoteAddr->HostAddress,
00274 VI_GM_MAC_ADDRESS_LEN + RemoteAddr->DiscriminatorLen);
00275 vip_conn_ptr->remote_gm_id = remote_gm_id;
00276 vip_conn_ptr->remote_port_id = 1;
00277 vip_conn_ptr->type = VIP_CONN_TYPE_CLIENT;
00278 vip_conn_ptr->status = VIP_NOT_DONE;
00279 vip_conn_ptr->vip_vi_ptr = vip_vi_ptr;
00280 VIP_EVENT_INIT (&(vip_conn_ptr->event));
00281 vip_vi_ptr->state = VIP_STATE_CONNECT_PENDING;
00282 vip_vi_ptr->conn_ptr = vip_conn_ptr;
00283
00284
00285 pkt_list_ptr = (VIP_PACKET_CONN_LIST *) (vip_send_req_ptr->ptr);
00286 pkt_list_ptr->type = VIP_HTON_UCHAR (VIP_CONN_LIST_REQ_PKT);
00287 memcpy(pkt_list_ptr->gm_unique_id, RemoteAddr->HostAddress, 6);
00288 pkt_list_ptr->clt_seq_num = VIP_HTON_UINT16 (vip_conn_ptr->handle.seq_num);
00289 pkt_list_ptr->clt_conn_ptr =
00290 VIP_HTON_UINT64 (vip_addr2addrbits (vip_conn_ptr));
00291
00292 vip_send_req_ptr->type |= VIP_SEND_REQ_RELIABLE;
00293 vip_send_req_ptr->dest_port_id = VI_GM_PORT_CONN_MANAGER;
00294 vip_send_req_ptr->dest_gm_id = conn_mgr_node_id;
00295 vip_send_req_ptr->vip_nic_ptr = vip_nic_ptr;
00296 vip_send_req_ptr->vip_vi_ptr = vip_vi_ptr;
00297 vip_send_data (vip_send_req_ptr);
00298
00299
00300 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00301 vip_status = vip_wait_for_notification (Timeout,
00302 (VIP_HANDLE *) vip_conn_ptr,
00303 &(vip_conn_ptr->event),
00304 &vip_is_conn_notified,
00305 vip_conn_ptr);
00306 VIP_MUTEX_LOCK (&(vip_nic_ptr->lock));
00307
00308
00309 switch (vip_status)
00310 {
00311 case VIP_SUCCESS:
00312 break;
00313
00314 case VIP_INVALID_PARAMETER:
00315 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00316 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00317 return VIP_INVALID_PARAMETER;
00318
00319 case VIP_TIMEOUT:
00320 VIP_ASSERT (vip_conn_ptr->status == VIP_NOT_DONE);
00321 if (vip_vi_ptr->state == VIP_STATE_CONNECT_PENDING)
00322 {
00323 vip_vi_ptr->state = VIP_STATE_IDLE;
00324 }
00325 vip_free_handle (&(vip_nic_ptr->vip_conn_set),
00326 (VIP_HANDLE *) vip_conn_ptr);
00327 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00328 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00329 return VIP_TIMEOUT;
00330
00331 default:
00332 VIP_ABORT (("Blocking wait return code is invalid"));
00333 }
00334
00335
00336 vip_status = vip_conn_ptr->status;
00337 switch (vip_status)
00338 {
00339 case VIP_SUCCESS:
00340
00341 *RemoteViAttribs = vip_conn_ptr->remote_vi_attribs;
00342
00343
00344 vip_send_req_ptr =
00345 vip_allocate_packet (vip_gm_ptr, sizeof (VIP_PACKET_CONN_ACK));
00346 if (vip_send_req_ptr == NULL)
00347 {
00348 vip_vi_ptr->state = VIP_STATE_IDLE;
00349 vip_free_handle (&(vip_nic_ptr->vip_conn_set),
00350 (VIP_HANDLE *) vip_conn_ptr);
00351 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00352 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00353 return VIP_ERROR_RESOURCE;
00354 }
00355
00356 pkt_ack_ptr = (VIP_PACKET_CONN_ACK *) (vip_send_req_ptr->ptr);
00357 pkt_ack_ptr->type = VIP_HTON_UCHAR (VIP_CONN_ACK_PKT);
00358 pkt_ack_ptr->status = VIP_HTON_UCHAR (VIP_SUCCESS);
00359 pkt_ack_ptr->srv_seq_num = vip_conn_ptr->net_remote_seq_num;
00360 pkt_ack_ptr->srv_conn_ptr = vip_conn_ptr->net_remote_conn_ptr;
00361 pkt_ack_ptr->net_local_nic_index = VIP_HTON_UINT16 (vip_nic_ptr->index);
00362 pkt_ack_ptr->net_local_vi_index = VIP_HTON_UINT16 (vip_vi_ptr->index);
00363
00364 vip_send_req_ptr->type |= VIP_SEND_REQ_RELIABLE;
00365 vip_send_req_ptr->dest_port_id = vip_conn_ptr->remote_port_id;
00366 vip_send_req_ptr->dest_gm_id = vip_conn_ptr->remote_gm_id;
00367 vip_send_req_ptr->vip_nic_ptr = vip_nic_ptr;
00368 vip_send_req_ptr->vip_vi_ptr = vip_vi_ptr;
00369 vip_send_data (vip_send_req_ptr);
00370
00371 vip_free_handle (&(vip_nic_ptr->vip_conn_set),
00372 (VIP_HANDLE *) vip_conn_ptr);
00373 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00374 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00375 VIP_DEBUG (("Success: Connection established"));
00376 return VIP_SUCCESS;
00377
00378 case VIP_REJECT:
00379
00380 VIP_DEBUG (("Rejected"));
00381 if (vip_vi_ptr->state == VIP_STATE_CONNECT_PENDING)
00382 {
00383 vip_vi_ptr->state = VIP_STATE_IDLE;
00384 }
00385 vip_free_handle (&(vip_nic_ptr->vip_conn_set),
00386 (VIP_HANDLE *) vip_conn_ptr);
00387 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00388 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00389 return VIP_REJECT;
00390
00391 case VIP_NO_MATCH:
00392
00393 VIP_DEBUG (("No match"));
00394 if (vip_vi_ptr->state == VIP_STATE_CONNECT_PENDING)
00395 {
00396 vip_vi_ptr->state = VIP_STATE_IDLE;
00397 }
00398 vip_free_handle (&(vip_nic_ptr->vip_conn_set),
00399 (VIP_HANDLE *) vip_conn_ptr);
00400 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00401 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00402 return VIP_NO_MATCH;
00403
00404 default:
00405 VIP_ABORT (("Connect request return wrong status"));
00406 }
00407
00408 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00409 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00410 return vip_status;
00411 }