ibtl_cm.c revision b29057431058f049213acfca99fa74ca4badffa0
/*
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* These routines tie the Communication Manager into IBTL.
*/
/*
* Globals.
*/
static char ibtf_cm[] = "ibtl_cm";
/*
* Function:
* ibtl_cm_set_chan_private
* Input:
* chan Channel Handle.
* cm_private CM private data.
* Output:
* none.
* Returns:
* none.
* Description:
* A helper function to store CM's Private data in the specified channel.
*/
void
{
chan, cm_private);
if (cm_private == NULL)
}
/*
* Function:
* ibtl_cm_get_chan_private
* Input:
* chan Channel Handle.
* Output:
* cm_private_p The CM private data.
* Returns:
* CM private data.
* Description:
* A helper function to get CM's Private data for the specified channel.
*/
void *
{
void *cm_private;
#ifndef __lock_lint
/* IBCM will call the release function if cm_private is non-NULL */
if (cm_private == NULL)
#endif
return (cm_private);
}
void
{
#ifndef __lock_lint
#endif
}
void
{
}
/*
* Function:
* ibtl_cm_get_chan_type
* Input:
* chan Channel Handle.
* Output:
* none.
* Returns:
* Channel transport type.
* Description:
* A helper function to get channel transport type.
*/
{
}
/*
* Function:
* ibtl_cm_change_service_cnt
* Input:
* ibt_hdl Client's IBT Handle.
* delta_num_sids The change in the number of service ids
* (positive for ibt_register_service() and
* negative fo ibt_service_deregister()).
*/
void
{
"ERROR: service registration counter underflow\n"
"current count = %d, requested delta = %d",
}
}
/*
* Function:
* ibtl_cm_get_hca_port
* Input:
* gid Source GID.
* hca_guid Optional source HCA GUID on which SGID is available.
* Ignored if zero.
* Output:
* hca_port Pointer to ibtl_cm_hca_port_t struct.
* Returns:
* IBT_SUCCESS.
* Description:
* A helper function to get HCA node GUID, Base LID, SGID Index,
* port number, LMC and MTU for the specified SGID.
* Also filling default SGID, to be used in ibmf_sa_session_open.
*/
{
uint_t i;
static uint8_t fast_sgid_ix;
static ibt_hca_portinfo_t *fast_portinfop;
static ib_guid_t fast_node_guid;
static ib_guid_t fast_port_guid;
"NULL SGID specified.");
return (IBT_INVALID_PARAM);
}
if ((ibtl_fast_gid_cache_valid == B_TRUE) &&
"Mis-match hca_guid v/s sgid combination.");
return (IBT_INVALID_PARAM);
}
return (IBT_SUCCESS);
}
/* If HCA GUID is specified, then lookup in that device only. */
if (hca_guid) {
} else {
}
continue;
continue;
/*
* Found the matching GID.
*/
return (IBT_SUCCESS);
}
}
/* Asked to look in the specified HCA device only?. */
if (hca_guid)
break;
/* Get next in the list */
}
/* If we are here, then we failed to get a match, so return error. */
return (IBT_INVALID_PARAM);
}
static ibt_status_t
{
uint_t i, j;
*count = 0;
/* If HCA GUID is specified, then lookup in that device only. */
if (attr->pa_hca_guid) {
} else {
}
if ((flags & IBT_PATH_APM) &&
"HCA (%llX) - APM NOT SUPPORTED ", hca_guid);
if (attr->pa_hca_guid)
break;
goto search_next;
}
if ((attr->pa_hca_port_num) &&
"Asked only on Port# %d, so skip this "
continue;
}
continue;
}
continue;
continue;
}
for (j = 0; j < pinfop->p_sgid_tbl_sz; j++) {
gid.gid_prefix) ||
continue;
} else {
attr->pa_hca_guid =
goto got_apm_hca_info;
}
}
}
continue;
}
for (j = 0; j < pinfop->p_sgid_tbl_sz; j++) {
if (!(flags & IBT_PATH_APM) &&
gid.gid_prefix) ||
continue;
}
pcount++;
if (plistp) {
plistp->p_base_lid =
plistp->p_port_num =
if (hdevp->hd_multism)
"ibtl_cm_get_cnt: HCA"
"(%llX,%d) SGID(%llX:%llX)",
plistp++;
}
}
}
}
/* Asked to look in the specified HCA device only?. */
if (attr->pa_hca_guid)
break;
if (flags & IBT_PATH_APM) {
if (pcount == 2) {
break;
} else if (pcount == 1) {
if (hdevp->hd_hca_dev_link) {
tmp_pcount = pcount;
pcount = 0;
} else if (tmp_hca_guid) {
} else {
}
} else if ((pcount == 0) && (tmp_hca_guid)) {
pcount = tmp_pcount;
}
}
}
if (pcount) {
} else {
"Appropriate Source Points NOT found");
if (retval == IBT_SUCCESS)
}
return (retval);
}
{
uint_t i, j;
*port_list_p = NULL;
/* Get "number of active src points" so that we can allocate memory. */
count);
if (retval != IBT_SUCCESS)
return (retval);
/* Allocate Memory to hold Src Point information. */
/*
* Verify that the count we got previously is still valid, as we had
* dropped mutex to allocate memory. If not, restart the process.
*/
if (retval != IBT_SUCCESS) {
return (retval);
goto get_plist_start;
}
*port_list_p = p_listp;
/*
* Src count hasn't changed, still holding the lock fill-in the
* required source point information.
*/
if (retval != IBT_SUCCESS) {
*port_list_p = NULL;
return (retval);
}
p_listp = *port_list_p;
for (i = 0; i < count - 1; i++) {
for (j = 0; j < count - 1 - i; j++) {
break;
}
}
break;
}
for (i = 0; i < count; i++)
/*
* Sort (bubble sort) the list based on MTU quality (higher on top).
* Sorting is only performed, if IBT_PATH_AVAIL is set.
*/
(!(flags & IBT_PATH_APM))) {
for (i = 0; i < count - 1; i++) {
for (j = 0; j < count - 1 - i; j++) {
}
}
}
}
/* Avoid having same HCA next to each other in the list. */
for (i = 0; i < count - 1; i++) {
for (j = 0; j < (count - 1 - i); j++) {
if ((p_listp[j].p_hca_guid ==
(j+2 < count)) {
}
}
}
}
/*
* If SGID is specified, then make sure that SGID info is first
* in the array.
*/
for (i = 1; i < count; i++) {
}
}
}
#ifndef lint
#endif
return (retval);
}
void
{
int count;
}
}
/*
* Function:
* ibtl_cm_get_1st_full_pkey_ix
* Input:
* hca_guid HCA GUID.
* port Port Number.
* Output:
* None.
* Returns:
* P_Key Index of the first full member available from the P_Key table
* of the specified HCA<->Port.
* Description:
* A helper function to get P_Key Index of the first full member P_Key
* available on the specified HCA and Port combination.
*/
{
(port != 0)) {
} else {
}
return (pkey_ix);
}
{
int i, j, k;
int count = 0;
int gid_specified;
"NO HCA (%llX) availble", hca_guid);
return (IBT_NO_HCAS_AVAILABLE);
}
gid_specified = 1;
else
gid_specified = 0;
continue;
for (j = 0; j < pinfop->p_sgid_tbl_sz; j++) {
if (gid_specified &&
/*
* Don't return the input specified
* GID
*/
continue;
}
count++;
}
}
}
if (count == 0) {
"Companion GIDs not available");
return (IBT_GIDS_NOT_FOUND);
}
*num_gids_p = count;
k = 0;
continue;
for (j = 0; j < pinfop->p_sgid_tbl_sz; j++) {
if (gid_specified &&
continue;
"ibtl_cm_get_local_comp_gids: GID[%d]="
k++;
if (k == count)
break;
}
}
if (k == count)
break;
}
return (IBT_SUCCESS);
}
int
{
"availble", hca_guid);
return (-1);
}
multi_sm);
return (multi_sm);
}