4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/ib/ibtl/impl/ibtl.h>
27 #include <sys/ib/ibtl/impl/ibtl_cm.h>
31 * These routines tie the Communication Manager into IBTL.
37 static char ibtf_cm
[] = "ibtl_cm";
38 boolean_t ibtl_fast_gid_cache_valid
= B_FALSE
;
42 * ibtl_cm_set_chan_private
44 * chan Channel Handle.
45 * cm_private CM private data.
51 * A helper function to store CM's Private data in the specified channel.
54 ibtl_cm_set_chan_private(ibt_channel_hdl_t chan
, void *cm_private
)
56 IBTF_DPRINTF_L3(ibtf_cm
, "ibtl_cm_set_chan_private(%p, %p)",
59 mutex_enter(&chan
->ch_cm_mutex
);
60 chan
->ch_cm_private
= cm_private
;
61 if (cm_private
== NULL
)
62 cv_signal(&chan
->ch_cm_cv
);
63 mutex_exit(&chan
->ch_cm_mutex
);
69 * ibtl_cm_get_chan_private
71 * chan Channel Handle.
73 * cm_private_p The CM private data.
77 * A helper function to get CM's Private data for the specified channel.
80 ibtl_cm_get_chan_private(ibt_channel_hdl_t chan
)
84 IBTF_DPRINTF_L3(ibtf_cm
, "ibtl_cm_get_chan_private(%p)", chan
);
85 mutex_enter(&chan
->ch_cm_mutex
);
86 cm_private
= chan
->ch_cm_private
;
88 /* IBCM will call the release function if cm_private is non-NULL */
89 if (cm_private
== NULL
)
91 mutex_exit(&chan
->ch_cm_mutex
);
96 ibtl_cm_release_chan_private(ibt_channel_hdl_t chan
)
99 mutex_exit(&chan
->ch_cm_mutex
);
104 ibtl_cm_wait_chan_private(ibt_channel_hdl_t chan
)
106 mutex_enter(&chan
->ch_cm_mutex
);
107 if (chan
->ch_cm_private
!= NULL
)
108 cv_wait(&chan
->ch_cm_cv
, &chan
->ch_cm_mutex
);
109 mutex_exit(&chan
->ch_cm_mutex
);
110 delay(drv_usectohz(50000));
116 * ibtl_cm_get_chan_type
118 * chan Channel Handle.
122 * Channel transport type.
124 * A helper function to get channel transport type.
127 ibtl_cm_get_chan_type(ibt_channel_hdl_t chan
)
129 IBTF_DPRINTF_L3(ibtf_cm
, "ibtl_cm_get_chan_type(%p)", chan
);
131 return (chan
->ch_qp
.qp_type
);
136 * ibtl_cm_change_service_cnt
138 * ibt_hdl Client's IBT Handle.
139 * delta_num_sids The change in the number of service ids
140 * (positive for ibt_register_service() and
141 * negative fo ibt_service_deregister()).
144 ibtl_cm_change_service_cnt(ibt_clnt_hdl_t ibt_hdl
, int delta_num_sids
)
146 IBTF_DPRINTF_L3(ibtf_cm
, "ibtl_cm_change_service_cnt(%p. %d)",
147 ibt_hdl
, delta_num_sids
);
149 mutex_enter(&ibtl_clnt_list_mutex
);
150 if ((delta_num_sids
< 0) && (-delta_num_sids
> ibt_hdl
->clnt_srv_cnt
)) {
151 IBTF_DPRINTF_L2(ibtf_cm
, "ibtl_cm_change_service_cnt: "
152 "ERROR: service registration counter underflow\n"
153 "current count = %d, requested delta = %d",
154 ibt_hdl
->clnt_srv_cnt
, delta_num_sids
);
156 ibt_hdl
->clnt_srv_cnt
+= delta_num_sids
;
157 mutex_exit(&ibtl_clnt_list_mutex
);
163 * ibtl_cm_get_hca_port
166 * hca_guid Optional source HCA GUID on which SGID is available.
169 * hca_port Pointer to ibtl_cm_hca_port_t struct.
173 * A helper function to get HCA node GUID, Base LID, SGID Index,
174 * port number, LMC and MTU for the specified SGID.
175 * Also filling default SGID, to be used in ibmf_sa_session_open.
178 ibtl_cm_get_hca_port(ib_gid_t gid
, ib_guid_t hca_guid
,
179 ibtl_cm_hca_port_t
*hca_port
)
181 ibtl_hca_devinfo_t
*hca_devp
; /* HCA Dev Info */
182 ibt_hca_portinfo_t
*portinfop
;
186 static ib_gid_t fast_gid
; /* fast_gid_cache data */
187 static uint8_t fast_sgid_ix
;
188 static ibt_hca_portinfo_t
*fast_portinfop
;
189 static ib_guid_t fast_node_guid
;
190 static ib_guid_t fast_port_guid
;
192 IBTF_DPRINTF_L3(ibtf_cm
, "ibtl_cm_get_hca_port(%llX:%llX, %llX)",
193 gid
.gid_prefix
, gid
.gid_guid
, hca_guid
);
195 if ((gid
.gid_prefix
== 0) || (gid
.gid_guid
== 0)) {
196 IBTF_DPRINTF_L2(ibtf_cm
, "ibtl_cm_get_hca_port: "
197 "NULL SGID specified.");
198 return (IBT_INVALID_PARAM
);
201 mutex_enter(&ibtl_clnt_list_mutex
);
203 if ((ibtl_fast_gid_cache_valid
== B_TRUE
) &&
204 (gid
.gid_guid
== fast_gid
.gid_guid
) &&
205 (gid
.gid_prefix
== fast_gid
.gid_prefix
)) {
207 if ((hca_guid
!= 0) && (hca_guid
!= fast_node_guid
)) {
208 IBTF_DPRINTF_L3(ibtf_cm
, "ibtl_cm_get_hca_port: "
209 "Mis-match hca_guid v/s sgid combination.");
210 mutex_exit(&ibtl_clnt_list_mutex
);
211 return (IBT_INVALID_PARAM
);
214 portinfop
= fast_portinfop
;
215 hca_port
->hp_base_lid
= portinfop
->p_base_lid
;
216 hca_port
->hp_port
= portinfop
->p_port_num
;
217 hca_port
->hp_sgid_ix
= fast_sgid_ix
;
218 hca_port
->hp_lmc
= portinfop
->p_lmc
;
219 hca_port
->hp_mtu
= portinfop
->p_mtu
;
220 hca_port
->hp_hca_guid
= fast_node_guid
;
221 hca_port
->hp_port_guid
= fast_port_guid
;
223 mutex_exit(&ibtl_clnt_list_mutex
);
225 return (IBT_SUCCESS
);
228 /* If HCA GUID is specified, then lookup in that device only. */
230 hca_devp
= ibtl_get_hcadevinfo(hca_guid
);
232 hca_devp
= ibtl_hca_list
;
235 while (hca_devp
!= NULL
) {
237 ports
= hca_devp
->hd_hca_attr
->hca_nports
;
238 portinfop
= hca_devp
->hd_portinfop
;
240 for (port
= 0; port
< ports
; port
++, portinfop
++) {
241 if (portinfop
->p_linkstate
!= IBT_PORT_ACTIVE
)
243 sgid
= &portinfop
->p_sgid_tbl
[0];
244 for (i
= 0; i
< portinfop
->p_sgid_tbl_sz
; i
++, sgid
++) {
245 if ((gid
.gid_guid
!= sgid
->gid_guid
) ||
246 (gid
.gid_prefix
!= sgid
->gid_prefix
))
250 * Found the matching GID.
252 ibtl_fast_gid_cache_valid
= B_TRUE
;
254 fast_portinfop
= portinfop
;
255 fast_node_guid
= hca_port
->hp_hca_guid
=
256 hca_devp
->hd_hca_attr
->hca_node_guid
;
257 fast_sgid_ix
= hca_port
->hp_sgid_ix
= i
;
259 portinfop
->p_sgid_tbl
[0].gid_guid
;
260 hca_port
->hp_port_guid
= fast_port_guid
;
261 hca_port
->hp_base_lid
= portinfop
->p_base_lid
;
262 hca_port
->hp_port
= portinfop
->p_port_num
;
263 hca_port
->hp_lmc
= portinfop
->p_lmc
;
264 hca_port
->hp_mtu
= portinfop
->p_mtu
;
266 mutex_exit(&ibtl_clnt_list_mutex
);
268 return (IBT_SUCCESS
);
272 /* Asked to look in the specified HCA device only?. */
276 /* Get next in the list */
277 hca_devp
= hca_devp
->hd_hca_dev_link
;
280 mutex_exit(&ibtl_clnt_list_mutex
);
282 /* If we are here, then we failed to get a match, so return error. */
283 return (IBT_INVALID_PARAM
);
288 ibtl_cm_get_cnt(ibt_path_attr_t
*attr
, ibt_path_flags_t flags
,
289 ibtl_cm_port_list_t
*plistp
, uint_t
*count
)
291 ibtl_hca_devinfo_t
*hdevp
;
292 ibt_hca_portinfo_t
*pinfop
;
293 ib_guid_t hca_guid
, tmp_hca_guid
= 0;
295 uint_t pcount
= 0, tmp_pcount
= 0;
297 ibt_status_t retval
= IBT_SUCCESS
;
302 /* If HCA GUID is specified, then lookup in that device only. */
303 if (attr
->pa_hca_guid
) {
304 hdevp
= ibtl_get_hcadevinfo(attr
->pa_hca_guid
);
306 hdevp
= ibtl_hca_list
;
309 while (hdevp
!= NULL
) {
310 hca_guid
= hdevp
->hd_hca_attr
->hca_node_guid
;
312 if ((flags
& IBT_PATH_APM
) &&
313 (!(hdevp
->hd_hca_attr
->hca_flags
&
314 IBT_HCA_AUTO_PATH_MIG
))) {
316 IBTF_DPRINTF_L2(ibtf_cm
, "ibtl_cm_get_cnt: "
317 "HCA (%llX) - APM NOT SUPPORTED ", hca_guid
);
319 retval
= IBT_APM_NOT_SUPPORTED
;
321 if (attr
->pa_hca_guid
)
326 for (i
= 0; i
< hdevp
->hd_hca_attr
->hca_nports
; i
++) {
328 if ((attr
->pa_hca_port_num
) &&
329 (attr
->pa_hca_port_num
!= (i
+ 1))) {
330 IBTF_DPRINTF_L3(ibtf_cm
, "ibtl_cm_get_cnt: "
331 "Asked only on Port# %d, so skip this "
332 "port(%d)", attr
->pa_hca_port_num
, (i
+ 1));
335 pinfop
= hdevp
->hd_portinfop
+ i
;
337 if (pinfop
->p_linkstate
!= IBT_PORT_ACTIVE
) {
338 retval
= IBT_HCA_PORT_NOT_ACTIVE
;
341 if (attr
->pa_mtu
.r_mtu
) {
342 if ((attr
->pa_mtu
.r_selector
== IBT_GT
) &&
343 (attr
->pa_mtu
.r_mtu
>= pinfop
->p_mtu
))
345 else if ((attr
->pa_mtu
.r_selector
== IBT_EQU
) &&
346 (attr
->pa_mtu
.r_mtu
> pinfop
->p_mtu
))
350 if ((flags
& IBT_PATH_APM
) && (!attr
->pa_hca_guid
) &&
351 attr
->pa_sgid
.gid_prefix
&&
352 attr
->pa_sgid
.gid_guid
) {
353 for (j
= 0; j
< pinfop
->p_sgid_tbl_sz
; j
++) {
354 gid
= pinfop
->p_sgid_tbl
[j
];
355 if (gid
.gid_prefix
&& gid
.gid_guid
) {
356 if ((attr
->pa_sgid
.gid_prefix
!=
358 (attr
->pa_sgid
.gid_guid
!=
364 goto got_apm_hca_info
;
371 for (j
= 0; j
< pinfop
->p_sgid_tbl_sz
; j
++) {
372 gid
= pinfop
->p_sgid_tbl
[j
];
373 if (gid
.gid_prefix
&& gid
.gid_guid
) {
374 if (!(flags
& IBT_PATH_APM
) &&
375 attr
->pa_sgid
.gid_prefix
&&
376 attr
->pa_sgid
.gid_guid
) {
377 if ((attr
->pa_sgid
.gid_prefix
!=
379 (attr
->pa_sgid
.gid_guid
!=
385 plistp
->p_hca_guid
= hca_guid
;
386 plistp
->p_mtu
= pinfop
->p_mtu
;
391 plistp
->p_sgid_ix
= j
;
392 plistp
->p_sgid
= gid
;
393 plistp
->p_count
= cnt
;
394 if (hdevp
->hd_multism
)
398 IBTF_DPRINTF_L3(ibtf_cm
,
399 "ibtl_cm_get_cnt: HCA"
400 "(%llX,%d) SGID(%llX:%llX)",
403 plistp
->p_sgid
.gid_prefix
,
404 plistp
->p_sgid
.gid_guid
);
411 /* Asked to look in the specified HCA device only?. */
412 if (attr
->pa_hca_guid
)
415 if (flags
& IBT_PATH_APM
) {
417 attr
->pa_hca_guid
= hca_guid
;
419 } else if (pcount
== 1) {
420 if (hdevp
->hd_hca_dev_link
) {
421 tmp_hca_guid
= hca_guid
;
424 } else if (tmp_hca_guid
) {
425 attr
->pa_hca_guid
= tmp_hca_guid
;
427 attr
->pa_hca_guid
= hca_guid
;
429 } else if ((pcount
== 0) && (tmp_hca_guid
)) {
430 attr
->pa_hca_guid
= tmp_hca_guid
;
435 hdevp
= hdevp
->hd_hca_dev_link
;
441 retval
= IBT_SUCCESS
;
443 IBTF_DPRINTF_L2(ibtf_cm
, "ibtl_cm_get_cnt: "
444 "Appropriate Source Points NOT found");
445 if (retval
== IBT_SUCCESS
)
446 retval
= IBT_NO_HCAS_AVAILABLE
;
454 ibtl_cm_get_active_plist(ibt_path_attr_t
*attr
, ibt_path_flags_t flags
,
455 ibtl_cm_port_list_t
**port_list_p
)
457 ibtl_cm_port_list_t
*p_listp
, tmp
;
459 uint_t count
, rcount
;
460 boolean_t multi_hca
= B_FALSE
;
461 ibt_status_t retval
= IBT_SUCCESS
;
463 IBTF_DPRINTF_L3(ibtf_cm
, "ibtl_cm_get_active_plist(%p, %X)",
469 /* Get "number of active src points" so that we can allocate memory. */
470 mutex_enter(&ibtl_clnt_list_mutex
);
471 retval
= ibtl_cm_get_cnt(attr
, flags
, NULL
, &count
);
472 mutex_exit(&ibtl_clnt_list_mutex
);
474 IBTF_DPRINTF_L3(ibtf_cm
, "ibtl_cm_get_active_plist: Found %d SrcPoint",
476 if (retval
!= IBT_SUCCESS
)
479 /* Allocate Memory to hold Src Point information. */
480 p_listp
= kmem_zalloc(count
* sizeof (ibtl_cm_port_list_t
), KM_SLEEP
);
483 * Verify that the count we got previously is still valid, as we had
484 * dropped mutex to allocate memory. If not, restart the process.
486 mutex_enter(&ibtl_clnt_list_mutex
);
487 retval
= ibtl_cm_get_cnt(attr
, flags
, NULL
, &rcount
);
488 if (retval
!= IBT_SUCCESS
) {
489 mutex_exit(&ibtl_clnt_list_mutex
);
490 kmem_free(p_listp
, count
* sizeof (ibtl_cm_port_list_t
));
492 } else if (rcount
!= count
) {
493 mutex_exit(&ibtl_clnt_list_mutex
);
494 kmem_free(p_listp
, count
* sizeof (ibtl_cm_port_list_t
));
495 goto get_plist_start
;
498 *port_list_p
= p_listp
;
500 * Src count hasn't changed, still holding the lock fill-in the
501 * required source point information.
503 retval
= ibtl_cm_get_cnt(attr
, flags
, p_listp
, &rcount
);
504 mutex_exit(&ibtl_clnt_list_mutex
);
505 if (retval
!= IBT_SUCCESS
) {
506 kmem_free(p_listp
, count
* sizeof (ibtl_cm_port_list_t
));
511 p_listp
= *port_list_p
;
513 _NOTE(NO_COMPETING_THREADS_NOW
)
515 for (i
= 0; i
< count
- 1; i
++) {
516 for (j
= 0; j
< count
- 1 - i
; j
++) {
517 if (p_listp
[j
].p_hca_guid
!= p_listp
[j
+1].p_hca_guid
) {
522 if (multi_hca
== B_TRUE
)
526 if (multi_hca
== B_TRUE
)
527 for (i
= 0; i
< count
; i
++)
528 p_listp
[i
].p_multi
|= IBTL_CM_MULTI_HCA
;
531 * Sort (bubble sort) the list based on MTU quality (higher on top).
532 * Sorting is only performed, if IBT_PATH_AVAIL is set.
534 if (((attr
->pa_mtu
.r_selector
== IBT_GT
) || (flags
& IBT_PATH_AVAIL
)) &&
535 (!(flags
& IBT_PATH_APM
))) {
536 for (i
= 0; i
< count
- 1; i
++) {
537 for (j
= 0; j
< count
- 1 - i
; j
++) {
538 if (p_listp
[j
].p_mtu
< p_listp
[j
+1].p_mtu
) {
540 p_listp
[j
] = p_listp
[j
+1];
547 if ((p_listp
->p_multi
& IBTL_CM_MULTI_HCA
) &&
548 (flags
& IBT_PATH_AVAIL
) && (!(flags
& IBT_PATH_APM
))) {
549 /* Avoid having same HCA next to each other in the list. */
550 for (i
= 0; i
< count
- 1; i
++) {
551 for (j
= 0; j
< (count
- 1 - i
); j
++) {
552 if ((p_listp
[j
].p_hca_guid
==
553 p_listp
[j
+1].p_hca_guid
) &&
556 p_listp
[j
+1] = p_listp
[j
+2];
564 * If SGID is specified, then make sure that SGID info is first
567 if (attr
->pa_sgid
.gid_guid
&& (p_listp
->p_count
> 1) &&
568 (p_listp
[0].p_sgid
.gid_guid
!= attr
->pa_sgid
.gid_guid
)) {
569 for (i
= 1; i
< count
; i
++) {
570 if (p_listp
[i
].p_sgid
.gid_guid
==
571 attr
->pa_sgid
.gid_guid
) {
573 p_listp
[i
] = p_listp
[0];
579 _NOTE(COMPETING_THREADS_NOW
)
581 IBTF_DPRINTF_L3(ibtf_cm
, "ibtl_cm_get_active_plist: "
582 "Returned <%d> entries @0x%p", count
, *port_list_p
);
589 ibtl_cm_free_active_plist(ibtl_cm_port_list_t
*plist
)
593 IBTF_DPRINTF_L3(ibtf_cm
, "ibtl_cm_free_active_plist(%p)", plist
);
596 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*plist
))
597 count
= plist
->p_count
;
598 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*plist
))
600 kmem_free(plist
, count
* sizeof (ibtl_cm_port_list_t
));
606 * ibtl_cm_get_1st_full_pkey_ix
613 * P_Key Index of the first full member available from the P_Key table
614 * of the specified HCA<->Port.
616 * A helper function to get P_Key Index of the first full member P_Key
617 * available on the specified HCA and Port combination.
620 ibtl_cm_get_1st_full_pkey_ix(ib_guid_t hca_guid
, uint8_t port
)
622 ibtl_hca_devinfo_t
*hca_devp
; /* HCA Dev Info */
623 uint16_t pkey_ix
= 0;
625 IBTF_DPRINTF_L3(ibtf_cm
, "ibtl_cm_get_1st_full_pkey_ix(%llX, %d)",
628 mutex_enter(&ibtl_clnt_list_mutex
);
629 hca_devp
= ibtl_get_hcadevinfo(hca_guid
);
631 if ((hca_devp
!= NULL
) && (port
<= hca_devp
->hd_hca_attr
->hca_nports
) &&
633 pkey_ix
= hca_devp
->hd_portinfop
[port
- 1].p_def_pkey_ix
;
635 IBTF_DPRINTF_L2(ibtf_cm
, "ibtl_cm_get_1st_full_pkey_ix: "
636 "Invalid HCA (%llX), Port (%d) specified.", hca_guid
, port
);
638 mutex_exit(&ibtl_clnt_list_mutex
);
645 ibtl_cm_get_local_comp_gids(ib_guid_t hca_guid
, ib_gid_t gid
, ib_gid_t
**gids_p
,
648 ibtl_hca_devinfo_t
*hdevp
; /* HCA Dev Info */
649 ibt_hca_portinfo_t
*pinfop
;
651 ib_gid_t
*gidp
= NULL
;
656 IBTF_DPRINTF_L3(ibtf_cm
, "ibtl_cm_get_local_comp_gids(%llX, %llX:%llX)",
657 hca_guid
, gid
.gid_prefix
, gid
.gid_guid
);
659 mutex_enter(&ibtl_clnt_list_mutex
);
660 hdevp
= ibtl_get_hcadevinfo(hca_guid
);
663 IBTF_DPRINTF_L3(ibtf_cm
, "ibtl_cm_get_local_comp_gids: ",
664 "NO HCA (%llX) availble", hca_guid
);
665 mutex_exit(&ibtl_clnt_list_mutex
);
666 return (IBT_NO_HCAS_AVAILABLE
);
669 if (gid
.gid_prefix
&& gid
.gid_guid
)
674 for (i
= 0; i
< hdevp
->hd_hca_attr
->hca_nports
; i
++) {
675 pinfop
= hdevp
->hd_portinfop
+ i
;
677 if (pinfop
->p_linkstate
!= IBT_PORT_ACTIVE
)
680 for (j
= 0; j
< pinfop
->p_sgid_tbl_sz
; j
++) {
681 sgid
= pinfop
->p_sgid_tbl
[j
];
682 if (sgid
.gid_prefix
&& sgid
.gid_guid
) {
684 ((gid
.gid_prefix
== sgid
.gid_prefix
) &&
685 (gid
.gid_guid
== sgid
.gid_guid
))) {
687 * Don't return the input specified
698 IBTF_DPRINTF_L2(ibtf_cm
, "ibtl_cm_get_local_comp_gids: "
699 "Companion GIDs not available");
700 mutex_exit(&ibtl_clnt_list_mutex
);
701 return (IBT_GIDS_NOT_FOUND
);
704 gidp
= kmem_zalloc(count
* sizeof (ib_gid_t
), KM_SLEEP
);
709 for (i
= 0; i
< hdevp
->hd_hca_attr
->hca_nports
; i
++) {
710 pinfop
= hdevp
->hd_portinfop
+ i
;
712 if (pinfop
->p_linkstate
!= IBT_PORT_ACTIVE
)
715 for (j
= 0; j
< pinfop
->p_sgid_tbl_sz
; j
++) {
716 sgid
= pinfop
->p_sgid_tbl
[j
];
717 if (sgid
.gid_prefix
&& sgid
.gid_guid
) {
719 ((gid
.gid_prefix
== sgid
.gid_prefix
) &&
720 (gid
.gid_guid
== sgid
.gid_guid
)))
723 gidp
[k
].gid_prefix
= sgid
.gid_prefix
;
724 gidp
[k
].gid_guid
= sgid
.gid_guid
;
726 IBTF_DPRINTF_L3(ibtf_cm
,
727 "ibtl_cm_get_local_comp_gids: GID[%d]="
728 "%llX:%llX", k
, gidp
[k
].gid_prefix
,
738 mutex_exit(&ibtl_clnt_list_mutex
);
740 return (IBT_SUCCESS
);
745 ibtl_cm_is_multi_sm(ib_guid_t hca_guid
)
747 ibtl_hca_devinfo_t
*hdevp
; /* HCA Dev Info */
750 mutex_enter(&ibtl_clnt_list_mutex
);
751 hdevp
= ibtl_get_hcadevinfo(hca_guid
);
753 IBTF_DPRINTF_L2(ibtf_cm
, "ibtl_cm_is_multi_sm: NO HCA (%llX) "
754 "availble", hca_guid
);
755 mutex_exit(&ibtl_clnt_list_mutex
);
758 multi_sm
= hdevp
->hd_multism
;
759 mutex_exit(&ibtl_clnt_list_mutex
);
761 IBTF_DPRINTF_L3(ibtf_cm
, "ibtl_cm_is_multi_sm(%llX): %d", hca_guid
,
768 ibtl_cm_get_clnt_name(ibt_clnt_hdl_t ibt_hdl
)
771 return (ibt_hdl
->clnt_name
);