/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
*
* contains internal lookup functions of IB CM module
* along with some other miscellaneous stuff
*
* TBD:
* 1. Code needed to ensure that if any clients are using a service then
* don't de-register it.
*/
/* statics */
/*
* ibcm_lookup_msg:
*
* Retrieves an existing state structure or creates a new one if none found.
* This function is used during
* Active side CM for outgoing REQ message.
*
* NOTE: Only return IBCM_LOOKUP_FAIL if lookup failed to find a match.
*
* Arguments are:-
* event_type - type of message
* incoming REQ, REP, REJ, MRA, RTU
* remote_qpn - Remote QP number
* remote_hca_guid - Remote HCA GUID
* hcap - HCA entry ptr
* rstatep - return statep pointer
*
* Return Values:
* IBCM_LOOKUP_NEW - new statep allocated
* IBCM_LOOKUP_EXISTS - found an existing entry
* IBCM_LOOKUP_FAIL - No lookup entry found
* IBCM_MEMORY_FAILURE - Memory allocs failed
*/
{
event_type, comid);
/*
* Lookup in "hca_passive_tree" for IBCM_INCOMING_REQ and
* IBCM_INCOMING_REP_STALE;
*
* Lookup in "hca_passive_comid_tree" for IBCM_INCOMING_REQ_STALE
*
* All other lookups in "hca_active_tree".
*
* NOTE: "hca_active_tree" lookups are based on the local comid.
* "hca_passive_state_tree" lookups are based on remote QPN
* and remote hca GUID.
*
* Call avl_find to lookup in the respective tree and save result in
* "sp". If "sp" is null it implies that no match was found. If so,
* allocate a new ibcm_state_data_t and insert it into the AVL tree(s).
*/
if ((event_type == IBCM_INCOMING_REQ) ||
(event_type == IBCM_INCOMING_REP_STALE)) {
/* Lookup based on Remote QPN and Remote GUID in Passive Tree */
} else if ((event_type == IBCM_INCOMING_REQ_STALE) ||
(event_type == IBCM_INCOMING_REJ_RCOMID)) {
/* Lookup based on Remote COMID in Passive Tree */
} else { /* any other event including IBCM_OUTGOING_REQ */
/* Lookup based on Local comid in Active Tree */
}
/* matching entry found !! */
"statep = %p", sp);
if (event_type == IBCM_INCOMING_REQ)
return (IBCM_LOOKUP_EXISTS);
}
/*
* If we came here then it implies that CM didn't
* find a matching entry. We will create a new entry in avl tree,
* For all other event_types we return lookup failure
*/
if (!((event_type == IBCM_INCOMING_REQ) ||
(event_type == IBCM_INCOMING_REQ_STALE) ||
(event_type == IBCM_INCOMING_REP_STALE) ||
(event_type == IBCM_OUTGOING_REQ))) {
"event type %x remote_comid = 0x%x",
event_type, comid);
return (IBCM_LOOKUP_FAIL);
}
if ((event_type == IBCM_INCOMING_REQ) ||
(event_type == IBCM_OUTGOING_REQ)) {
/* fill in the new ibcm_state_data */
/* initialize statep */
if (ibcm_enable_trace != 0)
}
} else {
}
if ((event_type == IBCM_INCOMING_REQ) ||
(event_type == IBCM_INCOMING_REP_STALE)) {
/* First, insert a new "sp" into "hca_passive_tree" @ "where" */
/*
* We have to do an avl_find() to figure out
* "where" to insert the statep into the active tree.
*
* CM doesn't care for avl_find's retval.
*/
/* Next, insert the "sp" into "hca_active_tree" */
}
} else if (event_type == IBCM_INCOMING_REQ_STALE) {
} else { /* IBCM_OUTGOING_REQ */
/* Insert the new sp only into "hca_active_tree", @ "where" */
}
return (IBCM_LOOKUP_NEW); /* return new lookup */
}
/*
* ibcm_active_node_compare:
* - AVL active tree node compare
*
* Arguments:
* p1 : pointer to local comid
* p2 : pointer to passed ibcm_state_data_t
*
* Return values:
* 0 : match found
* -1 : no match but insert to left side of the tree
* +1 : no match but insert to right side of the tree
*/
int
{
return (+1);
return (-1);
} else {
return (0);
}
}
/*
* ibcm_passive_node_compare:
* - AVL passive tree node compare (passive side)
*
* Arguments:
* p1 : pointer to ibcm_passive_node_info (remote qpn and remote guid)
* p2 : pointer to passed ibcm_state_data_t
*
* Return values:
* 0 : match found
* -1 : no match but insert to left side of the tree
* +1 : no match but insert to right side of the tree
*/
int
{
/*
* PASSIVE SIDE: (REQ, REP, MRA, REJ)
* always search by active COMID
*/
return (+1);
return (-1);
} else {
return (-1);
return (+1);
} else {
return (0);
}
}
}
/*
* ibcm_passive_comid_node_compare:
* - AVL passive comid tree node compare (passive side)
*
* Arguments:
* p1 : pointer to ibcm_passive_comid_node_info
* (remote comid and remote guid)
* p2 : pointer to passed ibcm_state_data_t
*
* Return values:
* 0 : match found
* -1 : no match but insert to left side of the tree
* +1 : no match but insert to right side of the tree
*/
int
{
return (+1);
return (-1);
} else {
return (-1);
return (+1);
} else {
return (0);
}
}
}
void
{
statep);
" NULL");
return;
}
/*
* Once the avl tree lock is acquired, no other thread can increment
* ref cnt, until tree lock is exit'ed. Since the statep is removed
* from the avl's after acquiring lock below, no other thread can
* increment the ref cnt after acquiring the lock below
*/
/* Lookup based on Local comid in the active tree */
&a_where);
/* Lookup based on Remote QPN and Remote GUID in the passive tree */
/* Lookup based on Remote Comid and Remote GUID in the passive tree */
&info_comid, &pcomid_where);
/* remove it from the tree, destroy record and the nodep */
if (active_nodep == statep) {
}
if (passive_nodep == statep) {
}
if (passive_comid_nodep == statep) {
}
}
/*
* ibcm_dealloc_state_data:
* Deallocates all buffers and the memory of state structure
* This routine can be called on statep that has ref_cnt of 0, and that is
* already deleted from the avl tree's
*
* Arguments are:-
* statep - statep to be deleted
*
* Return Values: NONE
*/
void
{
int dump_trace;
return;
}
/* ref_cnt is 0 */
/* If timer is running - expire it */
if (timer_val != 0) {
} else
/* release the ref cnt on the associated ibmf qp */
&statep->stored_msg);
statep);
/* Ensure the thread doing ref cnt decr releases the mutex */
/*
* now call the mutex_destroy() and cv_destroy()
*/
/* free the comid */
/* Decrement the resource on hcap */
/* dump the trace data into ibtf_debug_buf */
/* free the statep */
}
/*
* ibcm_delete_state_data:
* Deletes the state from avl trees, and tries to deallocate state
*
* Arguments are:-
* statep - statep to be deleted
*
* Return Values: NONE
*/
void
{
/* Must acquire the state mutex to set delete_state_data */
return;
}
}
/*
* ibcm_find_sidr_entry:
* Routines for CM SIDR state structure list manipulation.
* Finds an entry based on lid, gid and grh exists fields
*
* INPUTS:
* lid: LID of incoming SIDR REQ
* gid: GID of incoming SIDR REQ
* grh_exists: TRUE if GRH exists in the incoming SIDR REQ
* req_id: Request ID
* hcap: CM State table to search for SIDR state structure
* statep: Returns a valid state structure, if one exists based
* on lid, gid and grh_exists fields
* flag: IBCM_FLAG_LOOKUP - just lookup
* IBCM_FLAG_LOOKUP_AND_ADD - if lookup fails, add it.
* Return Values:
* IBCM_LOOKUP_EXISTS - found an existing entry
* IBCM_LOOKUP_FAIL - failed to find an entry
* IBCM_LOOKUP_NEW - created a new entry
*/
{
"lid=%x, (%llX, %llX), grh: %x, id: %x",
if (flag == IBCM_FLAG_ADD) {
return (IBCM_LOOKUP_NEW);
}
/* traverse the list for a matching entry */
"lid=%x, (%llX, %llX), grh: %x, id: %x",
"found usp = %p", usp);
return (IBCM_LOOKUP_EXISTS);
}
}
/*
* If code came here --> it couldn't find a match.
* OR
* the "hcap->hca_sidr_list" was NULL
*/
if (flag == IBCM_FLAG_LOOKUP) {
"lid=%x, (%llX, %llX), grh: %x, id: %x",
} else {
}
return (status);
}
/*
* ibcm_add_sidr_entry:
* Adds a SIDR entry. Called *ONLY* from ibcm_find_sidr_entry()
*
* INPUTS:
* lid: LID of incoming SIDR REQ
* gid: GID of incoming SIDR REQ
* grh_exists: TRUE if GRH exists in the incoming SIDR REQ
* req_id: Request ID
* hcap: CM State table to search for SIDR state structure
* Return Values: NONE
*/
{
/* didn't find the entry - so create new */
/* Initialize some ud_statep fields */
/* Update the list */
return (ud_statep);
}
/*
* ibcm_delete_ud_state_data:
* Deletes a given state structure
*
* Arguments are:-
* statep - statep to be deleted
*
* Return Values: NONE
*/
void
{
"ud_statep or hcap is NULL");
return;
}
/* Next, remove this from the HCA SIDR list */
/* delete the matching entry */
if (prevp) {
} else {
}
break;
}
}
}
/*
* While ref_cnt > 0
* - implies someone else is accessing the statep (possibly in
* a timeout function handler etc.)
* - don't delete statep unless they are done otherwise potentially
* one could access released memory and panic.
*/
if (ud_statep->ud_ref_cnt > 0) {
"ud_statep 0x%p ud_ref_cnt = %x", ud_statep,
return;
}
}
/*
* ibcm_ud_dealloc_state_data:
* Deallocates a given ud state structure
*
* Arguments are:-
* ud statep - ud statep to be deleted
*
* Return Values: NONE
*/
void
{
/* If timer is running - expire it */
if (ud_statep->ud_timerid) {
ud_statep->ud_timerid = 0;
"Unexpected timer id 0x%p ud_statep 0x%p", timer_val,
} else
(void) ibcm_free_out_msg(
}
/* release the ref cnt on the associated ibmf qp */
/* Ensure the thread doing ref cnt decr releases the mutex */
/* now do the mutex_destroy() and cv_destroy() */
/* free the req id on SIDR REQ sender side */
/* Decrement the resource on hcap */
/* free the statep */
}
/*
* ibcm_init_ids:
* Create the vmem arenas for the various global ids
*
* Arguments are:-
* NONE
*
* Return Values: ibcm_status_t
*/
ibcm_init_ids(void)
{
0, VM_SLEEP | VMC_IDENTIFIER);
if (!ibcm_local_sid_arena)
return (IBCM_FAILURE);
if (!ibcm_ip_sid_arena)
return (IBCM_FAILURE);
/* create a random starting value for local service ids */
gethrestime(&tv);
return (IBCM_SUCCESS);
}
/*
* ibcm_init_hca_ids:
* Create the vmem arenas for the various hca level ids
*
* Arguments are:-
* hcap pointer to ibcm_hca_info_t
*
* Return Values: ibcm_status_t
*/
{
(void *)IBCM_INITIAL_COMID, IBCM_MAX_COMIDS,
if (!hcap->hca_comid_arena)
return (IBCM_FAILURE);
(void *)IBCM_INITIAL_REQID, IBCM_MAX_REQIDS,
if (!hcap->hca_reqid_arena) {
return (IBCM_FAILURE);
}
return (IBCM_SUCCESS);
}
/*
* ibcm_free_ids:
* Destroy the vmem arenas for the various ids
*
* Arguments are:-
* NONE
*
* Return Values: NONE
*/
void
ibcm_fini_ids(void)
{
/* All arenas shall be valid */
}
/*
* ibcm_free_hca_ids:
* Destroy the vmem arenas for the various ids
*
* Arguments are:-
* hcap pointer to ibcm_hca_info_t
*
* Return Values: NONE
*/
void
{
/* All arenas shall be valid */
}
/* Communication id management routines ie., allocate, free up comids */
/*
* ibcm_alloc_comid:
* Allocate a new communication id
*
* Arguments are:-
* hcap : pointer to ibcm_hca_info_t
* comid: pointer to the newly allocated communication id
*
* Return Values: ibt_status_t
*/
{
/* Use next fit, so least recently used com id is allocated */
VM_SLEEP | VM_NEXTFIT);
comid);
/*
* As comid is 32 bits, and maximum connections possible are 2^24
* per hca, comid allocation would never fail
*/
if (comid == 0) {
"no more comids available", hcap);
return (IBCM_FAILURE);
}
return (IBCM_SUCCESS);
}
/*
* ibcm_free_comid:
* Releases the given Communication Id
*
* Arguments are:
* hcap : pointer to ibcm_hca_info_t
* comid : Communication id to be free'd
*
* Return Values: NONE
*/
void
{
}
/* Allocate and Free local service ids */
/*
* ibcm_alloc_local_sids:
* Create and destroy the vmem arenas for the service ids
*
* Arguments are:-
* Number of contiguous SIDs needed
*
* Return Values: starting SID
*/
{
if (sid == 0) {
"no more local sids available");
} else {
}
return (sid);
}
/*
* ibcm_free_local_sids:
* Releases the given Local service id
*
* Arguments are:
* num_sids: Number of local service id's to be free'd
* service_id: Starting local service id that needs to be free'd
*
* Return Values: NONE
*/
void
{
}
/*
* ibcm_alloc_ip_sid:
* Allocate a local IP SID.
*/
{
VM_SLEEP | VM_NEXTFIT);
if (sid == 0) {
"SIDs available");
} else {
" allocated : 0x%016llX", sid);
}
return (sid);
}
/*
* ibcm_free_ip_sid:
* Releases the given IP Service ID
*/
void
{
}
/* Allocate and free request id routines for SIDR */
/*
* ibcm_alloc_reqid:
* Allocate a new SIDR REQ request id
*
* Arguments are:-
* hcap : pointer to ibcm_hca_info_t
* *reqid : pointer to the new request id returned
*
* Return Values: ibcm_status_t
*/
{
/* Use next fit, so least recently used com id is allocated */
VM_SLEEP | VM_NEXTFIT);
*reqid);
if (!(*reqid)) {
"no more req ids available");
return (IBCM_FAILURE);
}
return (IBCM_SUCCESS);
}
/*
* ibcm_free_reqid:
* Releases the given SIDR REQ request id
*
* Arguments are:
* hcap : pointer to ibcm_hca_info_t
* reqid : Request id to be free'd
*
* Return Values: NONE
*/
void
{
reqid);
}
/*
* ibcm_generate_tranid:
* Generate a new transaction id based on args
*
* Arguments are:-
* id 32 bit identifier
* cm_tran_priv CM private data to be filled in top 28 MSB bits of
* tran id
*
*
* Return Value: uint64_t
*/
{
/*
* copy comid to bits 31-0 of tran id,
* attr id to bits 35-32 of tran id,
* cm_priv to bits 63-36 of tran id
*/
if (cm_tran_priv == 0)
/*
* The below ensures that no duplicate transaction id is
* generated atleast for next 6 months. Calculations:
* (2^28)/(1000 * 60 * 24 * 30) = 6 approx
*/
}
#ifdef DEBUG
/*
* ibcm_decode_tranid:
* Decodes a given transaction id, assuming certain format.
*
* Arguments are:-
* tran_id Transaction id to be decoded
* cm_tran_priv CM private data retrieved from transaction id
*
* Return Value: None
*/
void
{
if (cm_tran_priv) {
"cm_tran_priv = %x", *cm_tran_priv);
}
}
#endif
/*
* Service ID entry create and lookup functions
*/
/*
* ibcm_svc_compare:
* - AVL svc tree node compare
*
* Arguments:
* p1 : pointer to local comid
* p2 : pointer to passed ibcm_state_data_t
*
* Return values:
* 0 : match found
* -1 : no match but insert to left side of the tree
* +1 : no match but insert to right side of the tree
*/
int
{
"sid: 0x%llx, numsids: %d, node_sid: 0x%llx node_num_sids: %d",
return (-1);
return (+1);
return (0); /* means there is some overlap of SIDs */
}
/*
* ibcm_create_svc_entry:
* Make sure no conflicting entry exists, then allocate it.
* Fill in the critical "look up" details that are provided
* in the arguments before dropping the lock.
*
* Return values:
* Pointer to ibcm_svc_info_t, if created, otherwise NULL.
*/
{
/* assume success, and avoid kmem while holding the writer lock */
#ifdef __lock_lint
#endif
return (NULL);
}
return (svcinfop);
}
/*
* ibcm_find_svc_entry:
* Finds a ibcm_svc_info_t entry into the CM's global table.
* The search done here assumes the list is sorted by SID.
*
* Arguments are:
* sid - Service ID to look up
*
* Return values:
* Pointer to ibcm_svc_info_t, if found, otherwise NULL.
*/
{
#ifdef __lock_lint
#endif
"found SID = 0x%llX", sid);
return (svcp); /* found it */
}
return (NULL);
}
/*
* ibcm_alloc_ibmf_msg:
* Allocate an ibmf message structure and the additional memory required for
* sending an outgoing CM mad. The ibmf message structure contains two
* ibmf_msg_bufs_t fields, one for the incoming MAD and one for the outgoing
* MAD. The CM must allocate the memory for the outgoing MAD. The msg_buf
* field has three buffers: the mad header, the class header, and the class
* data. To simplify the code and reduce the number of kmem_zalloc() calls,
* ibcm_alloc_ibmf_msg will allocate one buffer and set the pointers to the
* right offsets. No class header is needed so only the mad header and class
* data fields are used.
*/
{
int sa_retval;
if ((sa_retval =
IBMF_SUCCESS) {
"ibmf_alloc_msg failed with IBMF_ALLOC_SLEEP");
return (ibcm_ibmf_analyze_error(sa_retval));
}
/* initialize generic CM MAD header fields */
return (IBT_SUCCESS);
}
/*
* ibcm_free_ibmf_msg:
* Frees the buffer and ibmf message associated with an outgoing CM message.
* This function should only be used to free messages created by
* ibcm_alloc_out_msg. Will return IBCM_FAILURE if the ibmf_free_msg() call
* fails and IBCM_SUCCESS otherwise.
*/
{
int ibmf_status;
IBMF_SUCCESS) {
"ibmf_free_msg failed %d", ibmf_status);
return (IBCM_FAILURE);
} else
return (IBCM_SUCCESS);
}
{
int ibmf_status;
/*
* CM currently does not track port up and down status. If tracking of
* " port status" is added in the future, then CM could be optimized to
* re-use other ports on hcap, if the port associated with the above
* port_no is down. But, the issue of "reachability" needs to be
* handled, before selecting an alternative port different from above.
*/
++entry->qp_ref_cnt;
return (entry);
}
}
/*
* entry not found, attempt to alloc a qp
* This may be optimized in the future, to allocate ibmf qp's
* once the "CM mgmt pkeys" are precisely known.
*/
if (ibmf_status != IBMF_SUCCESS) {
"for Pkey = %x port_no = %x status = %d hcaguid = %llXp",
/*
* This may be optimized in the future, so as CM would attempt
* to re-use other QP's whose ref cnt is 0 in the respective
* port_qplist, by doing an ibmf_modify_qp with pkey above.
*/
return (NULL);
}
/* set-up the handler */
ibcm_recv_cb, entry, 0);
#ifdef DEBUG
#endif
return (entry);
}
void
{
}
/* called holding the ibcm_qp_list_lock mutex */
{
int ibmf_status;
/* check, there are no users of this ibmf qp */
if (cm_qp_entry->qp_ref_cnt != 0)
return (IBCM_FAILURE);
/* Tear down the receive callback */
if (ibmf_status != IBMF_SUCCESS) {
"ibmf_tear_down_async_cb failed %d port_num %d",
return (IBCM_FAILURE);
}
&cm_qp_entry->qp_cm, 0);
if (ibmf_status != IBMF_SUCCESS) {
" ibmf_status %d qp hdl %p port_no %x", ibmf_status,
return (IBCM_FAILURE);
}
return (IBCM_SUCCESS);
}
{
port_no);
}
else /* all ibmf qp's of port must have been free'd successfully */
return (ibcm_status);
}
/*
* ibt_bind_service() and ibt_get_paths() needs the following helper function
* to handle endianess in case of Service Data.
*/
void
{
int i;
for (i = 0; i < 16; i++)
for (i = 0; i < 8; i++)
for (i = 0; i < 4; i++)
for (i = 0; i < 2; i++)
}
void
{
int i;
for (i = 0; i < 16; i++)
for (i = 0; i < 8; i++)
for (i = 0; i < 4; i++)
for (i = 0; i < 2; i++)
}
/* Trace related functions */
void
{
/* Initialize trace related fields */
if ((ibcm_enable_trace & 1) == 0)
sizeof (tm_diff_type), KM_SLEEP);
}
void
{
/* free the trace data */
if (statep->conn_trace) {
sizeof (tm_diff_type));
}
}
/* mostly used to profile connection establishment times with dtrace */
void
{
}
void
{
return;
if (!conn_trace->conn_trace_events)
return;
/* No more trace memory available, hence return */
return;
} else
if ((ibcm_enable_trace & 1) == 0) {
time_diff >>= 10;
if (time_diff >= TM_DIFF_MAX) {
/* RESET, future times are relative to new base time. */
time_diff = 0;
}
}
}
void
{
statep);
ibcm_debug_buf[0] = '\0';
if (ibcm_debug_buf[0] != '\0')
#ifdef DEBUG
if (ibcm_test_mode > 1)
#endif
}
void
{
int tr_ind;
return;
if (!sp->conn_trace)
return;
if (!conn_trace->conn_trace_events)
return;
/* Print connection level global data */
/* Print statep, local comid, local qpn */
"%s%s0x%x/%llx/%d\n%s%s0x%x\n%s%s0x%x/%llx\n%s%s0x%x\n%s%s%llu\n",
if (rem_size <= 0) {
return;
}
"%s%sTM_DIFF %u\n", line_prefix,
if (rem_size <= 0) {
return;
}
}
}
#ifdef DEBUG
void
{
int ibmf_status;
if (ibmf_qp == IBMF_QP_HANDLE_DEFAULT) {
return;
}
&qp_port_num, 0);
}
/*
* ibcm_dump_raw_message:
* (can be called from the kernel debugger w/ the message pointer)
*
* Arguments:
* msgp - the messages that needs to be dumped
*
* Return values: NONE
*/
void
{
int i;
for (i = 0; i < IBCM_MAD_SIZE; i += 16) {
/* print in batches of 16 chars at a time */
"%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
c[i], c[i + 1], c[i + 2], c[i + 3], c[i + 4], c[i + 5],
c[i + 6], c[i + 7], c[i + 8], c[i + 9], c[i + 10],
c[i + 11], c[i + 12], c[i + 13], c[i + 14], c[i + 15]);
}
}
/*
* ibcm_dump_srv_rec:
* Dumps Service Records.
*
* Arguments:
* srv_rec - the pointer to sa_service_record_t struct.
*
* Return values: NONE
*/
void
{
uint8_t i;
for (i = 0; i < IB_SVC_DATA_LEN; i += 8) {
"\t 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X",
}
}
/*
* ibcm_dump_pathrec:
* Dumps Path Records.
*
* Arguments:
* path_rec - the pointer to sa_path_record_t struct.
*
* Return values: NONE
*/
void
{
}
/*
* ibcm_dump_node_rec:
* Dumps Node Records.
*
* Arguments:
* nrec - the pointer to sa_node_record_t struct.
*
* Return values: NONE
*/
void
{
(char *)&nrec->NodeDescription);
}
#endif
/*
* ibcm_ibtl_node_info:
* Get the node record of the destination specified by lid via the HCA
* and port specified.
*
* Arguments:
* hca_guid - GUID of the local HCA.
* port - port in the HCA to be used.
* lid - destination LID
* node_info_p - pointer to the Node Info to be returned.
*
* Return values:
* IBT_SUCCESS : Got the node record sucessfully
* IBT_FILURE : Failed to get the node record.
*/
{
void *res_p;
"HCA(%llX) info not found", hca_guid);
return (IBT_FAILURE);
}
/* Get SA Access Handle. */
if (saa_handle == NULL) {
return (IBT_FAILURE);
}
/* Retrieve Node Records from SA Access. */
if (ibt_status != IBT_SUCCESS) {
"failed (%d) to get Node records", ibt_status);
return (IBT_FAILURE);
}
*node_info_p))
*node_info_p))
}
return (IBT_SUCCESS);
}
/*
* ibcm_ibmf_analyze_error:
* Checks IBMF status and determines appropriate ibt status.
*
* Arguments:
* ibmf_status - IBMF Status
*
* Return values:
* ibt_status_t
*/
{
/*
* IBMF specific failure, return special error code
* to the client so that it can retrieve any associated ENA.
*/
return (ibmf_status);
} else if (ibmf_status == IBMF_TRANS_TIMEOUT) {
return (IBT_IBMF_TIMEOUT);
} else {
/*
* IBMF failed for some other reason, invalid arguments etc.
* Analyze, log ENA with IBTF and obtain a special ibt_status_t
* that indicates IBMF failure.
*/
if ((ibmf_status == IBMF_BAD_CLASS) ||
(ibmf_status == IBMF_BAD_HANDLE) ||
(ibmf_status == IBMF_BAD_QP_HANDLE) ||
(ibmf_status == IBMF_BAD_NODE) ||
(ibmf_status == IBMF_BAD_PORT) ||
(ibmf_status == IBMF_BAD_VERSION) ||
(ibmf_status == IBMF_BAD_FLAGS) ||
(ibmf_status == IBMF_BAD_SIZE) ||
(ibmf_status == IBMF_INVALID_GID) ||
(ibmf_status == IBMF_INVALID_ARG) ||
(ibmf_status == IBMF_INVALID_FIELD) ||
(ibmf_status == IBMF_UNSUPP_METHOD) ||
(ibmf_status == IBMF_UNSUPP_METHOD_ATTR)) {
/*
* These errors, we should not see...
* something really bad happened!.
*/
"Unexpected ERROR from IBMF - %d", ibmf_status);
}
return (ibt_get_module_failure(IBT_FAILURE_IBMF, 0));
}
}