xref: /illumos-gate/usr/src/uts/common/io/ib/mgt/ibcm/ibcm_impl.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * ibcm_impl.c
31  *
32  * contains internal functions of IB CM module.
33  *
34  * TBD:
35  * 1. HCA CATASTROPHIC/RECOVERED not handled yet
36  */
37 
38 #include <sys/ib/mgt/ibcm/ibcm_impl.h>
39 #include <sys/disp.h>
40 
41 
42 /* function prototypes */
43 static ibcm_status_t	ibcm_init(void);
44 static ibcm_status_t	ibcm_fini(void);
45 
46 /* Routines to initialize and destory CM global locks and CVs */
47 static void		ibcm_init_locks(void);
48 static void		ibcm_fini_locks(void);
49 
50 /* Routines that initialize/teardown CM's global hca structures */
51 static void		ibcm_init_hcas();
52 static ibcm_status_t	ibcm_fini_hcas();
53 
54 static void		ibcm_init_classportinfo();
55 static void		ibcm_stop_timeout_thread();
56 
57 /* Routines that handle HCA attach/detach asyncs */
58 static void		ibcm_hca_attach(ib_guid_t);
59 static ibcm_status_t	ibcm_hca_detach(ibcm_hca_info_t *);
60 
61 /* Routines that initialize the HCA's port related fields */
62 static ibt_status_t	ibcm_hca_init_port(ibcm_hca_info_t *hcap,
63 			    uint8_t port_index);
64 static ibcm_status_t	ibcm_hca_fini_port(ibcm_hca_info_t *hcap,
65 			    uint8_t port_index);
66 
67 /*
68  * Routines that check if hca's avl trees and sidr lists are free of any
69  * active client resources ie., RC or UD state structures in certain states
70  */
71 static ibcm_status_t	ibcm_check_avl_clean(ibcm_hca_info_t *hcap);
72 static ibcm_status_t	ibcm_check_sidr_clean(ibcm_hca_info_t *hcap);
73 
74 /* Add a new hca structure to CM's global hca list */
75 static ibcm_hca_info_t	*ibcm_add_hca_entry(ib_guid_t hcaguid, uint_t nports);
76 
77 static void		ibcm_comm_est_handler(ibt_async_event_t *);
78 void			ibcm_async_handler(void *, ibt_hca_hdl_t,
79 			    ibt_async_code_t, ibt_async_event_t *);
80 
81 /* Global variables */
82 char			cmlog[] = "ibcm";	/* for debug log messages */
83 ibt_clnt_hdl_t		ibcm_ibt_handle;	/* IBT handle */
84 kmutex_t		ibcm_svc_info_lock;	/* list lock */
85 kcondvar_t		ibcm_svc_info_cv;	/* cv for deregister */
86 kmutex_t		ibcm_recv_mutex;
87 avl_tree_t		ibcm_svc_avl_tree;
88 taskq_t			*ibcm_taskq = NULL;
89 int			taskq_dispatch_fail_cnt;
90 
91 kmutex_t		ibcm_trace_mutex;	/* Trace mutex */
92 kmutex_t		ibcm_trace_print_mutex;	/* Trace print mutex */
93 int			ibcm_conn_max_trcnt = IBCM_MAX_CONN_TRCNT;
94 
95 int			ibcm_enable_trace = 4;	/* Trace level 4 by default */
96 
97 _NOTE(MUTEX_PROTECTS_DATA(ibcm_svc_info_lock, ibcm_svc_info_s::{svc_bind_list
98     svc_ref_cnt svc_to_delete}))
99 
100 _NOTE(MUTEX_PROTECTS_DATA(ibcm_svc_info_lock, ibcm_svc_bind_s::{sbind_link}))
101 
102 _NOTE(MUTEX_PROTECTS_DATA(ibcm_trace_mutex, ibcm_conn_trace_s))
103 
104 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibcm_conn_trace_s))
105 
106 _NOTE(MUTEX_PROTECTS_DATA(ibcm_trace_print_mutex, ibcm_debug_buf))
107 
108 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibcm_debug_buf))
109 
110 /*
111  * Initial state is INIT. All hca dr's return success immediately in this
112  * state, without adding or deleting any hca's to CM.
113  */
114 ibcm_finit_state_t	ibcm_finit_state = IBCM_FINIT_INIT;
115 
116 /* mutex and cv to manage hca's reference and resource count(s) */
117 kmutex_t		ibcm_global_hca_lock;
118 kcondvar_t		ibcm_global_hca_cv;
119 
120 /* mutex and cv to sa session open */
121 kmutex_t		ibcm_sa_open_lock;
122 kcondvar_t		ibcm_sa_open_cv;
123 
124 /* Deal with poor SA timeout behavior during stress */
125 kmutex_t		ibcm_sa_timeout_lock;
126 kcondvar_t		ibcm_sa_timeout_cv;
127 int			ibcm_sa_timeout_delay = 1;		/* in ticks */
128 int			ibcm_sa_timeout_simul;
129 int			ibcm_sa_timeout_simul_max;
130 int			ibcm_sa_timeout_simul_init = 8;		/* tunable */
131 
132 /* Control the number of RC connection requests get started simultaneously */
133 kcondvar_t		ibcm_rc_flow_control_cv;
134 int			ibcm_rc_flow_control_simul;
135 int			ibcm_rc_flow_control_simul_max;
136 int			ibcm_rc_flow_control_simul_init = 8;	/* tunable */
137 int			ibcm_rc_flow_control_simul_stalls;
138 
139 /* Control the number of disconnection requests get started simultaneously */
140 kcondvar_t		ibcm_close_flow_control_cv;
141 int			ibcm_close_flow_control_simul;
142 int			ibcm_close_flow_control_simul_max;
143 int			ibcm_close_flow_control_simul_init = 8;	/* tunable */
144 
145 _NOTE(MUTEX_PROTECTS_DATA(ibcm_sa_open_lock,
146     ibcm_port_info_s::{port_ibmf_saa_hdl port_saa_open_in_progress}))
147 
148 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibcm_port_info_s::{port_ibmf_saa_hdl}))
149 
150 /* serialize sm notice callbacks */
151 kmutex_t		ibcm_sm_notice_serialize_lock;
152 
153 _NOTE(LOCK_ORDER(ibcm_sm_notice_serialize_lock ibcm_global_hca_lock))
154 
155 _NOTE(MUTEX_PROTECTS_DATA(ibcm_global_hca_lock, ibcm_hca_info_s::{hca_state
156     hca_svc_cnt hca_acc_cnt hca_res_cnt hca_next}))
157 
158 _NOTE(MUTEX_PROTECTS_DATA(ibcm_global_hca_lock,
159     ibcm_port_info_s::{port_ibmf_hdl}))
160 
161 _NOTE(MUTEX_PROTECTS_DATA(ibcm_sm_notice_serialize_lock,
162     ibcm_port_info_s::{port_event_status}))
163 
164 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibcm_hca_info_s::{hca_state}))
165 _NOTE(DATA_READABLE_WITHOUT_LOCK(
166     ibcm_hca_info_s::{hca_port_info.port_ibmf_hdl}))
167 
168 /* mutex for CM's qp list management */
169 kmutex_t		ibcm_qp_list_lock;
170 
171 _NOTE(MUTEX_PROTECTS_DATA(ibcm_qp_list_lock, ibcm_port_info_s::{port_qplist}))
172 _NOTE(MUTEX_PROTECTS_DATA(ibcm_qp_list_lock, ibcm_qp_list_s))
173 _NOTE(MUTEX_PROTECTS_DATA(ibcm_qp_list_lock, ibcm_qp_list_s))
174 
175 kcondvar_t		ibcm_timeout_list_cv;
176 kcondvar_t		ibcm_timeout_thread_done_cv;
177 kt_did_t		ibcm_timeout_thread_did;
178 ibcm_state_data_t	*ibcm_timeout_list_hdr, *ibcm_timeout_list_tail;
179 ibcm_ud_state_data_t	*ibcm_ud_timeout_list_hdr, *ibcm_ud_timeout_list_tail;
180 kmutex_t		ibcm_timeout_list_lock;
181 uint8_t			ibcm_timeout_list_flags = 0;
182 pri_t			ibcm_timeout_thread_pri = MINCLSYSPRI;
183 
184 _NOTE(MUTEX_PROTECTS_DATA(ibcm_timeout_list_lock,
185     ibcm_state_data_s::timeout_next))
186 
187 _NOTE(MUTEX_PROTECTS_DATA(ibcm_timeout_list_lock,
188     ibcm_ud_state_data_s::ud_timeout_next))
189 
190 static ibt_clnt_modinfo_t ibcm_ibt_modinfo = {	/* Client's modinfop */
191 	IBTI_V1,
192 	IBT_CM,
193 	ibcm_async_handler,
194 	NULL,
195 	"IBCM"
196 };
197 
198 /* IBCM's list of HCAs registered with it */
199 static ibcm_hca_info_t	*ibcm_hca_listp = NULL;	/* CM's HCA list */
200 
201 /* Array of CM state call table functions */
202 ibcm_state_handler_t	ibcm_sm_funcs_tbl[] = {
203 	ibcm_process_req_msg,
204 	ibcm_process_mra_msg,
205 	ibcm_process_rej_msg,
206 	ibcm_process_rep_msg,
207 	ibcm_process_rtu_msg,
208 	ibcm_process_dreq_msg,
209 	ibcm_process_drep_msg,
210 	ibcm_process_sidr_req_msg,
211 	ibcm_process_sidr_rep_msg,
212 	ibcm_process_lap_msg,
213 	ibcm_process_apr_msg
214 };
215 
216 /* the following globals are CM tunables */
217 ibt_rnr_nak_time_t	ibcm_default_rnr_nak_time = IBT_RNR_NAK_655ms;
218 
219 uint32_t	ibcm_max_retries = IBCM_MAX_RETRIES;
220 clock_t		ibcm_local_processing_time = IBCM_LOCAL_RESPONSE_TIME;
221 clock_t		ibcm_remote_response_time = IBCM_REMOTE_RESPONSE_TIME;
222 ib_time_t	ibcm_max_sidr_rep_proctime = IBCM_MAX_SIDR_PROCESS_TIME;
223 ib_time_t	ibcm_max_sidr_pktlife_time = IBCM_MAX_SIDR_PKT_LIFE_TIME;
224 
225 ib_time_t	ibcm_max_sidr_rep_store_time = 18;
226 uint32_t	ibcm_wait_for_acc_cnt_timeout = 500000;	/* 500 ms */
227 uint32_t	ibcm_wait_for_res_cnt_timeout = 500000;	/* 500 ms */
228 
229 ib_time_t	ibcm_max_ib_pkt_lt = IBCM_MAX_IB_PKT_LT;
230 ib_time_t	ibcm_max_ib_mad_pkt_lt = IBCM_MAX_IB_MAD_PKT_LT;
231 
232 /*
233  * This delay accounts for time involved in various activities as follows :
234  *
235  * IBMF delays for posting the MADs in non-blocking mode
236  * IBMF delays for receiving the MADs and delivering to CM
237  * CM delays in processing the MADs before invoking client handlers,
238  * Any other delays associated with HCA driver in processing the MADs and
239  * 	other subsystems that CM may invoke (ex : SA, HCA driver)
240  */
241 uint32_t	ibcm_sw_delay	= 1000;	/* 1000us / 1ms */
242 uint32_t	ibcm_max_sa_retries = IBCM_MAX_SA_RETRIES + 1;
243 
244 /*	approx boot time */
245 uint32_t	ibcm_adj_btime = 4;	/* 4 seconds */
246 
247 /*
248  * The information in ibcm_clpinfo is kept in wireformat and is setup at
249  * init time, and used read-only after that
250  */
251 ibcm_classportinfo_msg_t	ibcm_clpinfo;
252 
253 char	*event_str[] = {
254 	"NEVER SEE THIS             ",
255 	"SESSION_ID                 ",
256 	"CHAN_HDL                   ",
257 	"LOCAL_COMID/HCA/PORT       ",
258 	"LOCAL_QPN                  ",
259 	"REMOTE_COMID/HCA           ",
260 	"REMOTE_QPN                 ",
261 	"BASE_TIME                  ",
262 	"INCOMING_REQ               ",
263 	"INCOMING_REP               ",
264 	"INCOMING_RTU               ",
265 	"INCOMING_COMEST            ",
266 	"INCOMING_MRA               ",
267 	"INCOMING_REJ               ",
268 	"INCOMING_LAP               ",
269 	"INCOMING_APR               ",
270 	"INCOMING_DREQ              ",
271 	"INCOMING_DREP              ",
272 	"OUTGOING_REQ               ",
273 	"OUTGOING_REP               ",
274 	"OUTGOING_RTU               ",
275 	"OUTGOING_LAP               ",
276 	"OUTGOING_APR               ",
277 	"OUTGOING_MRA               ",
278 	"OUTGOING_REJ               ",
279 	"OUTGOING_DREQ              ",
280 	"OUTGOING_DREP              ",
281 	"REQ_POST_COMPLETE          ",
282 	"REP_POST_COMPLETE          ",
283 	"RTU_POST_COMPLETE          ",
284 	"MRA_POST_COMPLETE          ",
285 	"REJ_POST_COMPLETE          ",
286 	"LAP_POST_COMPLETE          ",
287 	"APR_POST_COMPLETE          ",
288 	"DREQ_POST_COMPLETE         ",
289 	"DREP_POST_COMPLETE         ",
290 	"TIMEOUT_REP                ",
291 	"CALLED_REQ_RCVD_EVENT      ",
292 	"RET_REQ_RCVD_EVENT         ",
293 	"CALLED_REP_RCVD_EVENT      ",
294 	"RET_REP_RCVD_EVENT         ",
295 	"CALLED_CONN_EST_EVENT      ",
296 	"RET_CONN_EST_EVENT         ",
297 	"CALLED_CONN_FAIL_EVENT     ",
298 	"RET_CONN_FAIL_EVENT        ",
299 	"CALLED_CONN_CLOSE_EVENT    ",
300 	"RET_CONN_CLOSE_EVENT       ",
301 	"INIT_INIT                  ",
302 	"INIT_INIT_FAIL             ",
303 	"INIT_RTR                   ",
304 	"INIT_RTR_FAIL              ",
305 	"RTR_RTS                    ",
306 	"RTR_RTS_FAIL               ",
307 	"RTS_RTS                    ",
308 	"RTS_RTS_FAIL               ",
309 	"TO_ERROR                   ",
310 	"ERROR_FAIL                 ",
311 	"SET_ALT                    ",
312 	"SET_ALT_FAIL               ",
313 	"STALE_DETECT               ",
314 	"NEVER SEE THIS             "
315 };
316 
317 char	ibcm_debug_buf[IBCM_DEBUG_BUF_SIZE];
318 
319 _NOTE(SCHEME_PROTECTS_DATA("used in a localized function consistently",
320     ibcm_debug_buf))
321 _NOTE(READ_ONLY_DATA(ibcm_taskq))
322 
323 _NOTE(MUTEX_PROTECTS_DATA(ibcm_timeout_list_lock, ibcm_timeout_list_flags))
324 _NOTE(MUTEX_PROTECTS_DATA(ibcm_timeout_list_lock, ibcm_timeout_list_hdr))
325 _NOTE(MUTEX_PROTECTS_DATA(ibcm_timeout_list_lock, ibcm_ud_timeout_list_hdr))
326 
327 #ifdef DEBUG
328 int		ibcm_test_mode = 0;	/* set to 1, if running tests */
329 #endif
330 
331 
332 /* Module Driver Info */
333 static struct modlmisc ibcm_modlmisc = {
334 	&mod_miscops,
335 	"IB Communication Manager %I%"
336 };
337 
338 /* Module Linkage */
339 static struct modlinkage ibcm_modlinkage = {
340 	MODREV_1,
341 	&ibcm_modlmisc,
342 	NULL
343 };
344 
345 
346 int
347 _init(void)
348 {
349 	int		rval;
350 	ibcm_status_t	status;
351 
352 	status = ibcm_init();
353 	if (status != IBCM_SUCCESS) {
354 		IBTF_DPRINTF_L2(cmlog, "_init: ibcm failed %d", status);
355 		return (EINVAL);
356 	}
357 
358 	rval = mod_install(&ibcm_modlinkage);
359 	if (rval != 0) {
360 		IBTF_DPRINTF_L2(cmlog, "_init: ibcm mod_install failed %d",
361 		    rval);
362 		(void) ibcm_fini();
363 	}
364 
365 	IBTF_DPRINTF_L5(cmlog, "_init: ibcm successful");
366 	return (rval);
367 
368 }
369 
370 
371 int
372 _info(struct modinfo *modinfop)
373 {
374 	return (mod_info(&ibcm_modlinkage, modinfop));
375 }
376 
377 
378 int
379 _fini(void)
380 {
381 	int status;
382 
383 	if (ibcm_fini() != IBCM_SUCCESS)
384 		return (EBUSY);
385 
386 	if ((status = mod_remove(&ibcm_modlinkage)) != 0) {
387 		IBTF_DPRINTF_L2(cmlog, "_fini: ibcm mod_remove failed %d",
388 		    status);
389 		return (status);
390 	}
391 
392 	IBTF_DPRINTF_L5(cmlog, "_fini: ibcm successful");
393 
394 	return (status);
395 }
396 
397 /* Initializes all global mutex and CV in cm module */
398 static void
399 ibcm_init_locks()
400 {
401 
402 	/* Verify CM MAD sizes */
403 #ifdef DEBUG
404 
405 	if (ibcm_test_mode > 1) {
406 
407 		IBTF_DPRINTF_L1(cmlog, "REQ MAD SIZE %d",
408 		    sizeof (ibcm_req_msg_t));
409 		IBTF_DPRINTF_L1(cmlog, "REP MAD SIZE %d",
410 		    sizeof (ibcm_rep_msg_t));
411 		IBTF_DPRINTF_L1(cmlog, "RTU MAD SIZE %d",
412 		    sizeof (ibcm_rtu_msg_t));
413 		IBTF_DPRINTF_L1(cmlog, "MRA MAD SIZE %d",
414 		    sizeof (ibcm_mra_msg_t));
415 		IBTF_DPRINTF_L1(cmlog, "REJ MAD SIZE %d",
416 		    sizeof (ibcm_rej_msg_t));
417 		IBTF_DPRINTF_L1(cmlog, "LAP MAD SIZE %d",
418 		    sizeof (ibcm_lap_msg_t));
419 		IBTF_DPRINTF_L1(cmlog, "APR MAD SIZE %d",
420 		    sizeof (ibcm_apr_msg_t));
421 		IBTF_DPRINTF_L1(cmlog, "DREQ MAD SIZE %d",
422 		    sizeof (ibcm_dreq_msg_t));
423 		IBTF_DPRINTF_L1(cmlog, "DREP MAD SIZE %d",
424 		    sizeof (ibcm_drep_msg_t));
425 		IBTF_DPRINTF_L1(cmlog, "SIDR REQ MAD SIZE %d",
426 		    sizeof (ibcm_sidr_req_msg_t));
427 		IBTF_DPRINTF_L1(cmlog, "SIDR REP MAD SIZE %d",
428 		    sizeof (ibcm_sidr_rep_msg_t));
429 	}
430 
431 #endif
432 
433 	/* Create all global locks within cm module */
434 	mutex_init(&ibcm_svc_info_lock, NULL, MUTEX_DEFAULT, NULL);
435 	mutex_init(&ibcm_timeout_list_lock, NULL, MUTEX_DEFAULT, NULL);
436 	mutex_init(&ibcm_global_hca_lock, NULL, MUTEX_DEFAULT, NULL);
437 	mutex_init(&ibcm_sa_open_lock, NULL, MUTEX_DEFAULT, NULL);
438 	mutex_init(&ibcm_recv_mutex, NULL, MUTEX_DEFAULT, NULL);
439 	mutex_init(&ibcm_sm_notice_serialize_lock, NULL, MUTEX_DEFAULT, NULL);
440 	mutex_init(&ibcm_qp_list_lock, NULL, MUTEX_DEFAULT, NULL);
441 	mutex_init(&ibcm_trace_mutex, NULL, MUTEX_DEFAULT, NULL);
442 	mutex_init(&ibcm_trace_print_mutex, NULL, MUTEX_DEFAULT, NULL);
443 	cv_init(&ibcm_svc_info_cv, NULL, CV_DRIVER, NULL);
444 	cv_init(&ibcm_timeout_list_cv, NULL, CV_DRIVER, NULL);
445 	cv_init(&ibcm_timeout_thread_done_cv, NULL, CV_DRIVER, NULL);
446 	cv_init(&ibcm_global_hca_cv, NULL, CV_DRIVER, NULL);
447 	cv_init(&ibcm_sa_open_cv, NULL, CV_DRIVER, NULL);
448 	avl_create(&ibcm_svc_avl_tree, ibcm_svc_compare,
449 	    sizeof (ibcm_svc_info_t),
450 	    offsetof(struct ibcm_svc_info_s, svc_link));
451 
452 	IBTF_DPRINTF_L5(cmlog, "ibcm_init_locks: done");
453 }
454 
455 /* Destroys all global mutex and CV in cm module */
456 static void
457 ibcm_fini_locks()
458 {
459 	/* Destroy all global locks within cm module */
460 	mutex_destroy(&ibcm_svc_info_lock);
461 	mutex_destroy(&ibcm_timeout_list_lock);
462 	mutex_destroy(&ibcm_global_hca_lock);
463 	mutex_destroy(&ibcm_sa_open_lock);
464 	mutex_destroy(&ibcm_recv_mutex);
465 	mutex_destroy(&ibcm_sm_notice_serialize_lock);
466 	mutex_destroy(&ibcm_qp_list_lock);
467 	mutex_destroy(&ibcm_trace_mutex);
468 	mutex_destroy(&ibcm_trace_print_mutex);
469 	cv_destroy(&ibcm_svc_info_cv);
470 	cv_destroy(&ibcm_timeout_list_cv);
471 	cv_destroy(&ibcm_timeout_thread_done_cv);
472 	cv_destroy(&ibcm_global_hca_cv);
473 	cv_destroy(&ibcm_sa_open_cv);
474 	avl_destroy(&ibcm_svc_avl_tree);
475 
476 	IBTF_DPRINTF_L5(cmlog, "ibcm_fini_locks: done");
477 }
478 
479 
480 /* Initialize CM's classport info */
481 static void
482 ibcm_init_classportinfo()
483 {
484 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_clpinfo));
485 
486 	ibcm_clpinfo.BaseVersion = IBCM_MAD_BASE_VERSION;
487 	ibcm_clpinfo.ClassVersion = IBCM_MAD_CLASS_VERSION;
488 
489 	/* For now, CM supports same capabilities at all ports */
490 	ibcm_clpinfo.CapabilityMask =
491 	    h2b16(IBCM_CPINFO_CAP_RC | IBCM_CPINFO_CAP_SIDR);
492 
493 	/* Bits 0-7 are all 0 for Communication Mgmt Class */
494 
495 	/* For now, CM has the same respvalue at all ports */
496 	ibcm_clpinfo.RespTimeValue_plus =
497 	    h2b32(ibt_usec2ib(ibcm_local_processing_time) & 0x1f);
498 
499 	/* For now, redirect fields are set to 0 */
500 	/* Trap fields are not applicable to CM, hence set to 0 */
501 
502 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_clpinfo));
503 	IBTF_DPRINTF_L5(cmlog, "ibcm_init_classportinfo: done");
504 }
505 
506 /*
507  * ibcm_init():
508  * 	- call ibt_attach()
509  * 	- create AVL trees
510  *	- Attach HCA handlers that are already present before
511  *	CM got loaded.
512  *
513  * Arguments:	NONE
514  *
515  * Return values:
516  *	IBCM_SUCCESS - success
517  */
518 static ibcm_status_t
519 ibcm_init(void)
520 {
521 	ibt_status_t	status;
522 	kthread_t	*t;
523 
524 	IBTF_DPRINTF_L3(cmlog, "ibcm_init:");
525 
526 	ibcm_init_classportinfo();
527 
528 	if (ibcm_init_ids() != IBCM_SUCCESS) {
529 		IBTF_DPRINTF_L1(cmlog, "ibcm_init: "
530 		    "fatal error: vmem_create() failed");
531 		return (IBCM_FAILURE);
532 	}
533 	ibcm_init_locks();
534 
535 	if (ibcm_ar_init() != IBCM_SUCCESS) {
536 		IBTF_DPRINTF_L1(cmlog, "ibcm_init: "
537 		    "fatal error: ibcm_ar_init() failed");
538 		ibcm_fini_ids();
539 		ibcm_fini_locks();
540 		return (IBCM_FAILURE);
541 	}
542 
543 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_taskq))
544 	ibcm_taskq = system_taskq;
545 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_taskq))
546 
547 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_timeout_list_flags))
548 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_timeout_thread_did))
549 
550 	/* Start the timeout list processing thread */
551 	ibcm_timeout_list_flags = 0;
552 	t = thread_create(NULL, 0, ibcm_process_tlist, 0, 0, &p0, TS_RUN,
553 	    ibcm_timeout_thread_pri);
554 	ibcm_timeout_thread_did = t->t_did;
555 
556 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_timeout_list_flags))
557 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_timeout_thread_did))
558 
559 	/*
560 	 * NOTE : if ibt_attach is done after ibcm_init_hcas, then some
561 	 * HCA DR events may be lost. CM could call re-init hca list
562 	 * again, but it is more complicated. Some HCA's DR's lost may
563 	 * be HCA detach, which makes hca list re-syncing and locking more
564 	 * complex
565 	 */
566 	status = ibt_attach(&ibcm_ibt_modinfo, NULL, NULL, &ibcm_ibt_handle);
567 	if (status != IBT_SUCCESS) {
568 		IBTF_DPRINTF_L2(cmlog, "ibcm_init(): ibt_attach failed %d",
569 		    status);
570 		(void) ibcm_ar_fini();
571 		ibcm_fini_ids();
572 		ibcm_fini_locks();
573 		ibcm_stop_timeout_thread();
574 		return (IBCM_FAILURE);
575 	}
576 
577 	/* Block all HCA attach/detach asyncs */
578 	mutex_enter(&ibcm_global_hca_lock);
579 
580 	ibcm_init_hcas();
581 	ibcm_finit_state = IBCM_FINIT_IDLE;
582 
583 	/* Unblock any waiting HCA DR asyncs in CM */
584 	mutex_exit(&ibcm_global_hca_lock);
585 
586 	mutex_init(&ibcm_sa_timeout_lock, NULL, MUTEX_DEFAULT, NULL);
587 	cv_init(&ibcm_sa_timeout_cv, NULL, CV_DRIVER, NULL);
588 	cv_init(&ibcm_rc_flow_control_cv, NULL, CV_DRIVER, NULL);
589 	cv_init(&ibcm_close_flow_control_cv, NULL, CV_DRIVER, NULL);
590 	mutex_enter(&ibcm_sa_timeout_lock);
591 	ibcm_sa_timeout_simul_max = ibcm_sa_timeout_simul_init;
592 	ibcm_sa_timeout_simul = 0;
593 	ibcm_rc_flow_control_simul_max = ibcm_rc_flow_control_simul_init;
594 	ibcm_rc_flow_control_simul = 0;
595 	ibcm_close_flow_control_simul_max = ibcm_close_flow_control_simul_init;
596 	ibcm_close_flow_control_simul = 0;
597 	mutex_exit(&ibcm_sa_timeout_lock);
598 
599 	IBTF_DPRINTF_L4(cmlog, "ibcm_init: done");
600 	return (IBCM_SUCCESS);
601 }
602 
603 /* Allocates and initializes the "per hca" global data in CM */
604 static void
605 ibcm_init_hcas()
606 {
607 	uint_t	num_hcas = 0;
608 	ib_guid_t *guid_array;
609 	int i;
610 
611 	IBTF_DPRINTF_L5(cmlog, "ibcm_init_hcas:");
612 
613 	/* Get the number of HCAs */
614 	num_hcas = ibt_get_hca_list(&guid_array);
615 	IBTF_DPRINTF_L4(cmlog, "ibcm_init_hcas: ibt_get_hca_list() "
616 	    "returned %d hcas", num_hcas);
617 
618 	ASSERT(MUTEX_HELD(&ibcm_global_hca_lock));
619 
620 	for (i = 0; i < num_hcas; i++)
621 		ibcm_hca_attach(guid_array[i]);
622 
623 	if (num_hcas)
624 		ibt_free_hca_list(guid_array, num_hcas);
625 
626 	IBTF_DPRINTF_L5(cmlog, "ibcm_init_hcas: done");
627 }
628 
629 
630 /*
631  * ibcm_fini():
632  * 	- Deregister w/ ibt
633  * 	- Cleanup IBCM HCA listp
634  * 	- Destroy mutexes
635  *
636  * Arguments:	NONE
637  *
638  * Return values:
639  *	IBCM_SUCCESS - success
640  */
641 static ibcm_status_t
642 ibcm_fini(void)
643 {
644 	ibt_status_t	status;
645 
646 	IBTF_DPRINTF_L3(cmlog, "ibcm_fini:");
647 
648 	/*
649 	 * CM assumes that the all general clients got rid of all the
650 	 * established connections and service registrations, completed all
651 	 * pending SIDR operations before a call to ibcm_fini()
652 	 */
653 
654 	if (ibcm_ar_fini() != IBCM_SUCCESS) {
655 		IBTF_DPRINTF_L2(cmlog, "ibcm_fini: ibcm_ar_fini failed");
656 		return (IBCM_FAILURE);
657 	}
658 
659 	/* cleanup the svcinfo list */
660 	mutex_enter(&ibcm_svc_info_lock);
661 	if (avl_first(&ibcm_svc_avl_tree) != NULL) {
662 		IBTF_DPRINTF_L2(cmlog, "ibcm_fini: "
663 		    "ibcm_svc_avl_tree is not empty");
664 		mutex_exit(&ibcm_svc_info_lock);
665 		return (IBCM_FAILURE);
666 	}
667 	mutex_exit(&ibcm_svc_info_lock);
668 
669 	/* disables any new hca attach/detaches */
670 	mutex_enter(&ibcm_global_hca_lock);
671 
672 	ibcm_finit_state = IBCM_FINIT_BUSY;
673 
674 	if (ibcm_fini_hcas() != IBCM_SUCCESS) {
675 		IBTF_DPRINTF_L2(cmlog, "ibcm_fini: "
676 		    "some hca's still have client resources");
677 
678 		/* First, re-initialize the hcas */
679 		ibcm_init_hcas();
680 		/* and then enable the HCA asyncs */
681 		ibcm_finit_state = IBCM_FINIT_IDLE;
682 		mutex_exit(&ibcm_global_hca_lock);
683 		if (ibcm_ar_init() != IBCM_SUCCESS) {
684 			IBTF_DPRINTF_L1(cmlog, "ibcm_fini:ibcm_ar_init failed");
685 		}
686 		return (IBCM_FAILURE);
687 	}
688 
689 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_timeout_list_hdr))
690 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_ud_timeout_list_hdr))
691 
692 	ASSERT(ibcm_timeout_list_hdr == NULL);
693 	ASSERT(ibcm_ud_timeout_list_hdr == NULL);
694 
695 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_timeout_list_hdr))
696 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_ud_timeout_list_hdr))
697 
698 	/* Release any pending asyncs on ibcm_global_hca_lock */
699 	ibcm_finit_state = IBCM_FINIT_SUCCESS;
700 	mutex_exit(&ibcm_global_hca_lock);
701 
702 	ibcm_stop_timeout_thread();
703 
704 	/*
705 	 * Detach from IBTL. Waits until all pending asyncs are complete.
706 	 * Above cv_broadcast wakes up any waiting hca attach/detach asyncs
707 	 */
708 	status = ibt_detach(ibcm_ibt_handle);
709 
710 	/* if detach fails, CM didn't free up some resources, so assert */
711 	if (status != IBT_SUCCESS)
712 	    IBTF_DPRINTF_L1(cmlog, "ibcm_fini: ibt_detach failed %d", status);
713 
714 	mutex_destroy(&ibcm_sa_timeout_lock);
715 	cv_destroy(&ibcm_sa_timeout_cv);
716 	cv_destroy(&ibcm_rc_flow_control_cv);
717 	cv_destroy(&ibcm_close_flow_control_cv);
718 
719 	ibcm_fini_ids();
720 	ibcm_fini_locks();
721 	IBTF_DPRINTF_L3(cmlog, "ibcm_fini: done");
722 	return (IBCM_SUCCESS);
723 }
724 
725 /* This routine exit's the ibcm timeout thread  */
726 static void
727 ibcm_stop_timeout_thread()
728 {
729 	mutex_enter(&ibcm_timeout_list_lock);
730 
731 	/* Stop the timeout list processing thread */
732 	ibcm_timeout_list_flags =
733 	    ibcm_timeout_list_flags | IBCM_TIMEOUT_THREAD_EXIT;
734 
735 	/* Wake up, if the timeout thread is on a cv_wait */
736 	cv_signal(&ibcm_timeout_list_cv);
737 
738 	mutex_exit(&ibcm_timeout_list_lock);
739 	thread_join(ibcm_timeout_thread_did);
740 
741 	IBTF_DPRINTF_L5(cmlog, "ibcm_stop_timeout_thread: done");
742 }
743 
744 
745 /* Attempts to release all the hca's associated with CM */
746 static ibcm_status_t
747 ibcm_fini_hcas()
748 {
749 	ibcm_hca_info_t *hcap, *next;
750 
751 	IBTF_DPRINTF_L4(cmlog, "ibcm_fini_hcas:");
752 
753 	ASSERT(MUTEX_HELD(&ibcm_global_hca_lock));
754 
755 	hcap = ibcm_hca_listp;
756 	while (hcap != NULL) {
757 		next = hcap->hca_next;
758 		if (ibcm_hca_detach(hcap) != IBCM_SUCCESS) {
759 			ibcm_hca_listp = hcap;
760 			return (IBCM_FAILURE);
761 		}
762 		hcap = next;
763 	}
764 
765 	IBTF_DPRINTF_L4(cmlog, "ibcm_fini_hcas: SUCCEEDED");
766 	return (IBCM_SUCCESS);
767 }
768 
769 
770 /*
771  * ibcm_hca_attach():
772  *	Called as an asynchronous event to notify CM of an attach of HCA.
773  *	Here ibcm_hca_info_t is initialized and all fields are
774  *	filled in along with SA Access handles and IBMA handles.
775  *	Also called from ibcm_init to initialize ibcm_hca_info_t's for each
776  *	hca's
777  *
778  * Arguments: (WILL CHANGE BASED ON ASYNC EVENT CODE)
779  *	hca_guid	- HCA's guid
780  *
781  * Return values: NONE
782  */
783 static void
784 ibcm_hca_attach(ib_guid_t hcaguid)
785 {
786 	int			i;
787 	ibt_status_t		status;
788 	uint_t			nports = 0;
789 	ibcm_hca_info_t		*hcap;
790 	ibt_hca_attr_t		hca_attrs;
791 
792 	IBTF_DPRINTF_L3(cmlog, "ibcm_hca_attach: guid = 0x%llX", hcaguid);
793 
794 	ASSERT(MUTEX_HELD(&ibcm_global_hca_lock));
795 
796 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*hcap))
797 
798 	status = ibt_query_hca_byguid(hcaguid, &hca_attrs);
799 	if (status != IBT_SUCCESS) {
800 		IBTF_DPRINTF_L2(cmlog, "ibcm_hca_attach: "
801 		    "ibt_query_hca_byguid failed = %d", status);
802 		return;
803 	}
804 	nports = hca_attrs.hca_nports;
805 
806 	IBTF_DPRINTF_L4(cmlog, "ibcm_hca_attach: num ports = %x", nports);
807 
808 	if ((hcap = ibcm_add_hca_entry(hcaguid, nports)) == NULL)
809 		return;
810 
811 	hcap->hca_guid = hcaguid;	/* Set GUID */
812 	hcap->hca_num_ports = nports;	/* Set number of ports */
813 
814 	if (ibcm_init_hca_ids(hcap) != IBCM_SUCCESS) {
815 		ibcm_delete_hca_entry(hcap);
816 		return;
817 	}
818 
819 	/* Store the static hca attribute data */
820 	hcap->hca_caps = hca_attrs.hca_flags;
821 	hcap->hca_ack_delay = hca_attrs.hca_local_ack_delay;
822 	hcap->hca_max_rdma_in_qp = hca_attrs.hca_max_rdma_in_qp;
823 	hcap->hca_max_rdma_out_qp = hca_attrs.hca_max_rdma_out_qp;
824 
825 	/* loop thru nports and initialize IBMF handles */
826 	for (i = 0; i < hcap->hca_num_ports; i++) {
827 		status = ibt_get_port_state_byguid(hcaguid, i + 1, NULL, NULL);
828 		if (status != IBT_SUCCESS) {
829 			IBTF_DPRINTF_L2(cmlog, "ibcm_hca_attach: "
830 			    "port_num %d state DOWN", i + 1);
831 		}
832 
833 		hcap->hca_port_info[i].port_hcap = hcap;
834 		hcap->hca_port_info[i].port_num = i+1;
835 
836 		if (ibcm_hca_init_port(hcap, i) != IBT_SUCCESS)
837 			IBTF_DPRINTF_L2(cmlog, "ibcm_hca_attach: "
838 			    "ibcm_hca_init_port failed %d port_num %d",
839 			    status, i+1);
840 	}
841 
842 	/* create the "active" CM AVL tree */
843 	avl_create(&hcap->hca_active_tree, ibcm_active_node_compare,
844 	    sizeof (ibcm_state_data_t),
845 	    offsetof(struct ibcm_state_data_s, avl_active_link));
846 
847 	/* create the "passive" CM AVL tree */
848 	avl_create(&hcap->hca_passive_tree, ibcm_passive_node_compare,
849 	    sizeof (ibcm_state_data_t),
850 	    offsetof(struct ibcm_state_data_s, avl_passive_link));
851 
852 	/* create the "passive comid" CM AVL tree */
853 	avl_create(&hcap->hca_passive_comid_tree,
854 	    ibcm_passive_comid_node_compare,
855 	    sizeof (ibcm_state_data_t),
856 	    offsetof(struct ibcm_state_data_s, avl_passive_comid_link));
857 
858 	/*
859 	 * Mark the state of the HCA to "attach" only at the end
860 	 * Now CM starts accepting incoming MADs and client API calls
861 	 */
862 	hcap->hca_state = IBCM_HCA_ACTIVE;
863 
864 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*hcap))
865 
866 	IBTF_DPRINTF_L3(cmlog, "ibcm_hca_attach: ATTACH Done");
867 }
868 
869 /*
870  * ibcm_hca_detach():
871  *	Called as an asynchronous event to notify CM of a detach of HCA.
872  *	Here ibcm_hca_info_t is freed up and all fields that
873  *	were initialized earlier are cleaned up
874  *
875  * Arguments: (WILL CHANGE BASED ON ASYNC EVENT CODE)
876  *	hca_guid    - HCA's guid
877  *
878  * Return values:
879  *	IBCM_SUCCESS	- able to detach HCA
880  *	IBCM_FAILURE	- failed to detach HCA
881  */
882 static ibcm_status_t
883 ibcm_hca_detach(ibcm_hca_info_t *hcap)
884 {
885 	int		port_index, i;
886 	ibcm_status_t	status = IBCM_SUCCESS;
887 	clock_t		absolute_time;
888 
889 	IBTF_DPRINTF_L3(cmlog, "ibcm_hca_detach: hcap = 0x%p guid = 0x%llX",
890 	    hcap, hcap->hca_guid);
891 
892 	ASSERT(MUTEX_HELD(&ibcm_global_hca_lock));
893 
894 	/*
895 	 * Declare hca is going away to all CM clients. Wait until the
896 	 * access count becomes zero.
897 	 */
898 	hcap->hca_state = IBCM_HCA_NOT_ACTIVE;
899 
900 	/* wait on response CV to 500mS */
901 	absolute_time = ddi_get_lbolt() +
902 	    drv_usectohz(ibcm_wait_for_acc_cnt_timeout);
903 
904 	while (hcap->hca_acc_cnt > 0)
905 		if (cv_timedwait(&ibcm_global_hca_cv, &ibcm_global_hca_lock,
906 		    absolute_time) == -1)
907 			break;
908 
909 	if (hcap->hca_acc_cnt != 0) {
910 		/* We got a timeout */
911 #ifdef DEBUG
912 		if (ibcm_test_mode > 0)
913 			IBTF_DPRINTF_L1(cmlog, "ibcm_hca_detach: Unexpected "
914 			    "abort due to timeout on acc_cnt %u",
915 			    hcap->hca_acc_cnt);
916 		else
917 #endif
918 			IBTF_DPRINTF_L2(cmlog, "ibcm_hca_detach: Aborting due"
919 			    " to timeout on acc_cnt %u", hcap->hca_acc_cnt);
920 		hcap->hca_state = IBCM_HCA_ACTIVE;
921 		return (IBCM_FAILURE);
922 	}
923 
924 	/*
925 	 * First make sure, there are no active users of ibma handles,
926 	 * and then de-register handles.
927 	 */
928 
929 	/* make sure that there are no "Service"s registered w/ this HCA. */
930 	if (hcap->hca_svc_cnt != 0) {
931 		IBTF_DPRINTF_L2(cmlog, "ibcm_hca_detach: "
932 		    "Active services still there %d", hcap->hca_svc_cnt);
933 		hcap->hca_state = IBCM_HCA_ACTIVE;
934 		return (IBCM_FAILURE);
935 	}
936 
937 	if (ibcm_check_sidr_clean(hcap) != IBCM_SUCCESS) {
938 		IBTF_DPRINTF_L2(cmlog, "ibcm_hca_detach:"
939 		    "There are active SIDR operations");
940 		hcap->hca_state = IBCM_HCA_ACTIVE;
941 		return (IBCM_FAILURE);
942 	}
943 
944 	if (ibcm_check_avl_clean(hcap) != IBCM_SUCCESS) {
945 		IBTF_DPRINTF_L2(cmlog, "ibcm_hca_detach: "
946 		    "There are active RC connections");
947 		hcap->hca_state = IBCM_HCA_ACTIVE;
948 		return (IBCM_FAILURE);
949 	}
950 
951 	/*
952 	 * Now, wait until all rc and sidr stateps go away
953 	 * All these stateps must be short lived ones, waiting to be cleaned
954 	 * up after some timeout value, based on the current state.
955 	 */
956 	IBTF_DPRINTF_L5(cmlog, "hca_guid = 0x%llX res_cnt = %d",
957 	    hcap->hca_guid, hcap->hca_res_cnt);
958 
959 	/* wait on response CV to 500mS */
960 	absolute_time = ddi_get_lbolt() +
961 	    drv_usectohz(ibcm_wait_for_res_cnt_timeout);
962 
963 	while (hcap->hca_res_cnt > 0)
964 		if (cv_timedwait(&ibcm_global_hca_cv, &ibcm_global_hca_lock,
965 		    absolute_time) == -1)
966 			break;
967 
968 	if (hcap->hca_res_cnt != 0) {
969 		/* We got a timeout waiting for hca_res_cnt to become 0 */
970 #ifdef DEBUG
971 		if (ibcm_test_mode > 0)
972 			IBTF_DPRINTF_L1(cmlog, "ibcm_hca_detach: Unexpected "
973 			    "abort due to timeout on res_cnt %d",
974 			    hcap->hca_res_cnt);
975 		else
976 #endif
977 			IBTF_DPRINTF_L2(cmlog, "ibcm_hca_detach: Aborting due"
978 			    " to timeout on res_cnt %d", hcap->hca_res_cnt);
979 		hcap->hca_state = IBCM_HCA_ACTIVE;
980 		return (IBCM_FAILURE);
981 	}
982 
983 	/* Re-assert the while loop step above */
984 	ASSERT(hcap->hca_sidr_list == NULL);
985 	avl_destroy(&hcap->hca_active_tree);
986 	avl_destroy(&hcap->hca_passive_tree);
987 	avl_destroy(&hcap->hca_passive_comid_tree);
988 
989 	/*
990 	 * Unregister all ports from IBMA
991 	 * If there is a failure, re-initialize any free'd ibma handles. This
992 	 * is required to receive the incoming mads
993 	 */
994 	status = IBCM_SUCCESS;
995 	for (port_index = 0; port_index < hcap->hca_num_ports; port_index++) {
996 		if ((status = ibcm_hca_fini_port(hcap, port_index)) !=
997 		    IBCM_SUCCESS) {
998 			IBTF_DPRINTF_L2(cmlog, "ibcm_hca_detach: "
999 			    "Failed to free IBMA Handle for port_num %d",
1000 			    port_index + 1);
1001 			break;
1002 		}
1003 	}
1004 
1005 	/* If detach fails, re-initialize ibma handles for incoming mads */
1006 	if (status != IBCM_SUCCESS)  {
1007 		for (i = 0; i < port_index; i++) {
1008 			if (ibcm_hca_init_port(hcap, i) != IBT_SUCCESS)
1009 				IBTF_DPRINTF_L2(cmlog, "ibcm_hca_detach: "
1010 				    "Failed to re-allocate IBMA Handles for"
1011 				    " port_num %d", port_index + 1);
1012 		}
1013 		hcap->hca_state = IBCM_HCA_ACTIVE;
1014 		return (IBCM_FAILURE);
1015 	}
1016 
1017 	ibcm_fini_hca_ids(hcap);
1018 	ibcm_delete_hca_entry(hcap);
1019 
1020 	IBTF_DPRINTF_L3(cmlog, "ibcm_hca_detach: DETACH succeeded");
1021 	return (IBCM_SUCCESS);
1022 }
1023 
1024 /* Checks, if there are any active sidr state entries in the specified hca */
1025 static ibcm_status_t
1026 ibcm_check_sidr_clean(ibcm_hca_info_t *hcap)
1027 {
1028 	ibcm_ud_state_data_t	*usp;
1029 	uint32_t		transient_cnt = 0;
1030 
1031 	IBTF_DPRINTF_L5(cmlog, "ibcm_check_sidr_clean:");
1032 
1033 	rw_enter(&hcap->hca_sidr_list_lock, RW_WRITER);
1034 	usp = hcap->hca_sidr_list;	/* Point to the list */
1035 	while (usp != NULL) {
1036 		mutex_enter(&usp->ud_state_mutex);
1037 		if ((usp->ud_state != IBCM_STATE_SIDR_REP_SENT) &&
1038 		    (usp->ud_state != IBCM_STATE_TIMED_OUT) &&
1039 		    (usp->ud_state != IBCM_STATE_DELETE)) {
1040 
1041 			IBTF_DPRINTF_L3(cmlog, "ibcm_check_sidr_clean:"
1042 			    "usp = %p not in transient state = %d", usp,
1043 			    usp->ud_state);
1044 
1045 			mutex_exit(&usp->ud_state_mutex);
1046 			rw_exit(&hcap->hca_sidr_list_lock);
1047 			return (IBCM_FAILURE);
1048 		} else {
1049 			mutex_exit(&usp->ud_state_mutex);
1050 			++transient_cnt;
1051 		}
1052 
1053 		usp = usp->ud_nextp;
1054 	}
1055 	rw_exit(&hcap->hca_sidr_list_lock);
1056 
1057 	IBTF_DPRINTF_L4(cmlog, "ibcm_check_sidr_clean: transient_cnt %d",
1058 	    transient_cnt);
1059 
1060 	return (IBCM_SUCCESS);
1061 }
1062 
1063 /* Checks, if there are any active rc state entries, in the specified hca */
1064 static ibcm_status_t
1065 ibcm_check_avl_clean(ibcm_hca_info_t *hcap)
1066 
1067 {
1068 	ibcm_state_data_t	*sp;
1069 	avl_tree_t		*avl_tree;
1070 	uint32_t		transient_cnt = 0;
1071 
1072 	IBTF_DPRINTF_L5(cmlog, "ibcm_check_avl_clean:");
1073 	/*
1074 	 * Both the trees ie., active and passive must reference to all
1075 	 * statep's, so let's use one
1076 	 */
1077 	avl_tree = &hcap->hca_active_tree;
1078 
1079 	rw_enter(&hcap->hca_state_rwlock, RW_WRITER);
1080 
1081 	for (sp = avl_first(avl_tree); sp != NULL;
1082 	    sp = avl_walk(avl_tree, sp, AVL_AFTER)) {
1083 		mutex_enter(&sp->state_mutex);
1084 		if ((sp->state != IBCM_STATE_TIMEWAIT) &&
1085 		    (sp->state != IBCM_STATE_REJ_SENT) &&
1086 		    (sp->state != IBCM_STATE_DELETE)) {
1087 			IBTF_DPRINTF_L3(cmlog, "ibcm_check_avl_clean:"
1088 			    "sp = %p not in transient state = %d", sp,
1089 			    sp->state);
1090 			mutex_exit(&sp->state_mutex);
1091 			rw_exit(&hcap->hca_state_rwlock);
1092 			return (IBCM_FAILURE);
1093 		} else {
1094 			mutex_exit(&sp->state_mutex);
1095 			++transient_cnt;
1096 		}
1097 	}
1098 
1099 	rw_exit(&hcap->hca_state_rwlock);
1100 
1101 	IBTF_DPRINTF_L4(cmlog, "ibcm_check_avl_clean: transient_cnt %d",
1102 	    transient_cnt);
1103 
1104 	return (IBCM_SUCCESS);
1105 }
1106 
1107 /* Adds a new entry into CM's global hca list, if hca_guid is not there yet */
1108 static ibcm_hca_info_t *
1109 ibcm_add_hca_entry(ib_guid_t hcaguid, uint_t nports)
1110 {
1111 	ibcm_hca_info_t	*hcap;
1112 
1113 	IBTF_DPRINTF_L5(cmlog, "ibcm_add_hca_entry: guid = 0x%llX",
1114 	    hcaguid);
1115 
1116 	ASSERT(MUTEX_HELD(&ibcm_global_hca_lock));
1117 
1118 	/*
1119 	 * Check if this hca_guid already in the list
1120 	 * If yes, then ignore this and return NULL
1121 	 */
1122 
1123 	hcap = ibcm_hca_listp;
1124 
1125 	/* search for this HCA */
1126 	while (hcap != NULL) {
1127 		if (hcap->hca_guid == hcaguid) {
1128 			/* already exists */
1129 			IBTF_DPRINTF_L2(cmlog, "ibcm_add_hca_entry: "
1130 			"hcap %p guid 0x%llX, entry already exists !!",
1131 			hcap, hcap->hca_guid);
1132 			return (NULL);
1133 		}
1134 		hcap = hcap->hca_next;
1135 	}
1136 
1137 	/* Allocate storage for the new HCA entry found */
1138 	hcap = kmem_zalloc(sizeof (ibcm_hca_info_t) +
1139 	    (nports - 1) * sizeof (ibcm_port_info_t), KM_SLEEP);
1140 
1141 	/* initialize RW lock */
1142 	rw_init(&hcap->hca_state_rwlock, NULL, RW_DRIVER, NULL);
1143 	/* initialize SIDR list lock */
1144 	rw_init(&hcap->hca_sidr_list_lock, NULL, RW_DRIVER, NULL);
1145 	/* Insert "hcap" into the global HCA list maintained by CM */
1146 	hcap->hca_next = ibcm_hca_listp;
1147 	ibcm_hca_listp = hcap;
1148 
1149 	IBTF_DPRINTF_L5(cmlog, "ibcm_add_hca_entry: done hcap = 0x%p", hcap);
1150 
1151 	return (hcap);
1152 
1153 }
1154 
1155 /* deletes the given ibcm_hca_info_t from CM's global hca list */
1156 void
1157 ibcm_delete_hca_entry(ibcm_hca_info_t *hcap)
1158 {
1159 
1160 	ibcm_hca_info_t	*headp, *prevp = NULL;
1161 
1162 	/* ibcm_hca_global_lock is held */
1163 	IBTF_DPRINTF_L5(cmlog, "ibcm_delete_hca_entry: guid = 0x%llX "
1164 	    "hcap = 0x%p", hcap->hca_guid, hcap);
1165 
1166 	ASSERT(MUTEX_HELD(&ibcm_global_hca_lock));
1167 
1168 	headp = ibcm_hca_listp;
1169 	while (headp != NULL) {
1170 		if (headp == hcap) {
1171 			IBTF_DPRINTF_L3(cmlog, "ibcm_delete_hca_entry: "
1172 			    "deleting hcap %p hcaguid %llX", hcap,
1173 			    hcap->hca_guid);
1174 			if (prevp) {
1175 				prevp->hca_next = headp->hca_next;
1176 			} else {
1177 				prevp = headp->hca_next;
1178 				ibcm_hca_listp = prevp;
1179 			}
1180 			rw_destroy(&hcap->hca_state_rwlock);
1181 			rw_destroy(&hcap->hca_sidr_list_lock);
1182 			kmem_free(hcap, sizeof (ibcm_hca_info_t) +
1183 			    (hcap->hca_num_ports - 1) *
1184 			    sizeof (ibcm_port_info_t));
1185 			return;
1186 		}
1187 
1188 		prevp = headp;
1189 		headp = headp->hca_next;
1190 	}
1191 }
1192 
1193 /*
1194  * ibcm_find_hca_entry:
1195  *	Given a HCA's GUID find out ibcm_hca_info_t entry for that HCA
1196  *	This entry can be then used to access AVL tree/SIDR list etc.
1197  *	If entry exists and in HCA ATTACH state, then hca's ref cnt is
1198  *	incremented and entry returned. Else NULL returned.
1199  *
1200  *	All functions that use ibcm_find_hca_entry and get a non-NULL
1201  *	return values must call ibcm_dec_hca_acc_cnt to decrement the
1202  *	respective hca ref cnt. There shouldn't be any usage of
1203  *	ibcm_hca_info_t * returned from ibcm_find_hca_entry,
1204  *	after decrementing the hca_acc_cnt
1205  *
1206  * INPUTS:
1207  *	hca_guid	- HCA's guid
1208  *
1209  * RETURN VALUE:
1210  *	hcap		- if a match is found, else NULL
1211  */
1212 ibcm_hca_info_t *
1213 ibcm_find_hca_entry(ib_guid_t hca_guid)
1214 {
1215 	ibcm_hca_info_t *hcap;
1216 
1217 	IBTF_DPRINTF_L5(cmlog, "ibcm_find_hca_entry: guid = 0x%llX", hca_guid);
1218 
1219 	mutex_enter(&ibcm_global_hca_lock);
1220 
1221 	hcap = ibcm_hca_listp;
1222 	/* search for this HCA */
1223 	while (hcap != NULL) {
1224 		if (hcap->hca_guid == hca_guid)
1225 			break;
1226 		hcap = hcap->hca_next;
1227 	}
1228 
1229 	/* if no hcap for the hca_guid, return NULL */
1230 	if (hcap == NULL) {
1231 		mutex_exit(&ibcm_global_hca_lock);
1232 		return (NULL);
1233 	}
1234 
1235 	/* return hcap, only if it valid to use */
1236 	if (hcap->hca_state == IBCM_HCA_ACTIVE) {
1237 		++(hcap->hca_acc_cnt);
1238 
1239 		IBTF_DPRINTF_L5(cmlog, "ibcm_find_hca_entry: "
1240 		    "found hcap = 0x%p hca_acc_cnt %u", hcap,
1241 		    hcap->hca_acc_cnt);
1242 
1243 		mutex_exit(&ibcm_global_hca_lock);
1244 		return (hcap);
1245 	} else {
1246 		mutex_exit(&ibcm_global_hca_lock);
1247 
1248 		IBTF_DPRINTF_L2(cmlog, "ibcm_find_hca_entry: "
1249 		    "found hcap = 0x%p not in active state", hcap);
1250 		return (NULL);
1251 	}
1252 }
1253 
1254 /*
1255  * Searches for ibcm_hca_info_t entry based on hca_guid, but doesn't increment
1256  * the hca's reference count. This function is used, where the calling context
1257  * is attempting to delete hcap itself and hence acc_cnt cannot be incremented
1258  * OR assumes that valid hcap must be available in ibcm's global hca list.
1259  */
1260 ibcm_hca_info_t *
1261 ibcm_find_hcap_entry(ib_guid_t hca_guid)
1262 {
1263 	ibcm_hca_info_t *hcap;
1264 
1265 	IBTF_DPRINTF_L5(cmlog, "ibcm_find_hcap_entry: guid = 0x%llX", hca_guid);
1266 
1267 	ASSERT(MUTEX_HELD(&ibcm_global_hca_lock));
1268 
1269 	hcap = ibcm_hca_listp;
1270 	/* search for this HCA */
1271 	while (hcap != NULL) {
1272 		if (hcap->hca_guid == hca_guid)
1273 			break;
1274 		hcap = hcap->hca_next;
1275 	}
1276 
1277 	if (hcap == NULL)
1278 		IBTF_DPRINTF_L2(cmlog, "ibcm_find_hcap_entry: No hcap found for"
1279 		    " hca_guid 0x%llX", hca_guid);
1280 	else
1281 		IBTF_DPRINTF_L5(cmlog, "ibcm_find_hcap_entry: hcap found for"
1282 		    " hca_guid 0x%llX", hca_guid);
1283 
1284 	return (hcap);
1285 }
1286 
1287 /* increment the hca's temporary reference count */
1288 ibcm_status_t
1289 ibcm_inc_hca_acc_cnt(ibcm_hca_info_t *hcap)
1290 {
1291 	mutex_enter(&ibcm_global_hca_lock);
1292 	if (hcap->hca_state == IBCM_HCA_ACTIVE) {
1293 		++(hcap->hca_acc_cnt);
1294 		IBTF_DPRINTF_L5(cmlog, "ibcm_inc_hca_acc_cnt: "
1295 		    "hcap = 0x%p  acc_cnt = %d ", hcap, hcap->hca_acc_cnt);
1296 		mutex_exit(&ibcm_global_hca_lock);
1297 		return (IBCM_SUCCESS);
1298 	} else {
1299 		IBTF_DPRINTF_L2(cmlog, "ibcm_inc_hca_acc_cnt: "
1300 		    "hcap INACTIVE 0x%p  acc_cnt = %d ", hcap,
1301 		    hcap->hca_acc_cnt);
1302 		mutex_exit(&ibcm_global_hca_lock);
1303 		return (IBCM_FAILURE);
1304 	}
1305 }
1306 
1307 /* decrement the hca's ref count, and wake up any waiting threads */
1308 void
1309 ibcm_dec_hca_acc_cnt(ibcm_hca_info_t *hcap)
1310 {
1311 	mutex_enter(&ibcm_global_hca_lock);
1312 	ASSERT(hcap->hca_acc_cnt > 0);
1313 	--(hcap->hca_acc_cnt);
1314 	IBTF_DPRINTF_L5(cmlog, "ibcm_dec_hca_acc_cnt: hcap = 0x%p"
1315 	    "acc_cnt = %d", hcap, hcap->hca_acc_cnt);
1316 	if ((hcap->hca_state == IBCM_HCA_NOT_ACTIVE) &&
1317 	    (hcap->hca_acc_cnt == 0)) {
1318 		IBTF_DPRINTF_L3(cmlog, "ibcm_dec_hca_acc_cnt: "
1319 		    "cv_broadcast for hcap = 0x%p", hcap);
1320 		cv_broadcast(&ibcm_global_hca_cv);
1321 	}
1322 	mutex_exit(&ibcm_global_hca_lock);
1323 }
1324 
1325 /* increment the hca's resource count */
1326 void
1327 ibcm_inc_hca_res_cnt(ibcm_hca_info_t *hcap)
1328 
1329 {
1330 	mutex_enter(&ibcm_global_hca_lock);
1331 	++(hcap->hca_res_cnt);
1332 	IBTF_DPRINTF_L5(cmlog, "ibcm_inc_hca_res_cnt: hcap = 0x%p"
1333 	    "ref_cnt = %d", hcap, hcap->hca_res_cnt);
1334 	mutex_exit(&ibcm_global_hca_lock);
1335 }
1336 
1337 /* decrement the hca's resource count, and wake up any waiting threads */
1338 void
1339 ibcm_dec_hca_res_cnt(ibcm_hca_info_t *hcap)
1340 {
1341 	mutex_enter(&ibcm_global_hca_lock);
1342 	ASSERT(hcap->hca_res_cnt > 0);
1343 	--(hcap->hca_res_cnt);
1344 	IBTF_DPRINTF_L5(cmlog, "ibcm_dec_hca_res_cnt: hcap = 0x%p"
1345 	    "ref_cnt = %d", hcap, hcap->hca_res_cnt);
1346 	if ((hcap->hca_state == IBCM_HCA_NOT_ACTIVE) &&
1347 	    (hcap->hca_res_cnt == 0)) {
1348 		IBTF_DPRINTF_L3(cmlog, "ibcm_dec_hca_res_cnt: "
1349 		    "cv_broadcast for hcap = 0x%p", hcap);
1350 		cv_broadcast(&ibcm_global_hca_cv);
1351 	}
1352 	mutex_exit(&ibcm_global_hca_lock);
1353 }
1354 
1355 /* increment the hca's service count */
1356 void
1357 ibcm_inc_hca_svc_cnt(ibcm_hca_info_t *hcap)
1358 
1359 {
1360 	mutex_enter(&ibcm_global_hca_lock);
1361 	++(hcap->hca_svc_cnt);
1362 	IBTF_DPRINTF_L5(cmlog, "ibcm_inc_hca_svc_cnt: hcap = 0x%p"
1363 	    "svc_cnt = %d", hcap, hcap->hca_svc_cnt);
1364 	mutex_exit(&ibcm_global_hca_lock);
1365 }
1366 
1367 /* decrement the hca's service count */
1368 void
1369 ibcm_dec_hca_svc_cnt(ibcm_hca_info_t *hcap)
1370 {
1371 	mutex_enter(&ibcm_global_hca_lock);
1372 	ASSERT(hcap->hca_svc_cnt > 0);
1373 	--(hcap->hca_svc_cnt);
1374 	IBTF_DPRINTF_L5(cmlog, "ibcm_dec_hca_svc_cnt: hcap = 0x%p"
1375 	    "svc_cnt = %d", hcap, hcap->hca_svc_cnt);
1376 	mutex_exit(&ibcm_global_hca_lock);
1377 }
1378 
1379 void
1380 ibcm_rc_flow_control_enter()
1381 {
1382 	mutex_enter(&ibcm_sa_timeout_lock);
1383 	if (ibcm_rc_flow_control_simul_max != ibcm_rc_flow_control_simul_init) {
1384 		if (ibcm_rc_flow_control_simul_max <
1385 		    ibcm_rc_flow_control_simul_init) {
1386 			/* letting more flow should be gradual */
1387 			ibcm_rc_flow_control_simul_max++;
1388 			if (ibcm_rc_flow_control_simul <
1389 			    ibcm_rc_flow_control_simul_max - 1)
1390 				cv_signal(&ibcm_rc_flow_control_cv);
1391 		} else {
1392 			ibcm_rc_flow_control_simul_max =
1393 			    ibcm_rc_flow_control_simul_init;
1394 		}
1395 	}
1396 	while (ibcm_rc_flow_control_simul >= ibcm_rc_flow_control_simul_max) {
1397 		cv_wait(&ibcm_rc_flow_control_cv, &ibcm_sa_timeout_lock);
1398 	}
1399 	ibcm_rc_flow_control_simul++;
1400 	mutex_exit(&ibcm_sa_timeout_lock);
1401 }
1402 
1403 void
1404 ibcm_rc_flow_control_exit()
1405 {
1406 	mutex_enter(&ibcm_sa_timeout_lock);
1407 	if (ibcm_rc_flow_control_simul_max != ibcm_rc_flow_control_simul_init) {
1408 		if (ibcm_rc_flow_control_simul_max <
1409 		    ibcm_rc_flow_control_simul_init) {
1410 			/* letting more flow should be gradual */
1411 			ibcm_rc_flow_control_simul_max++;
1412 			if (ibcm_rc_flow_control_simul <
1413 			    ibcm_rc_flow_control_simul_max)
1414 				cv_signal(&ibcm_rc_flow_control_cv);
1415 		} else {
1416 			ibcm_rc_flow_control_simul_max =
1417 			    ibcm_rc_flow_control_simul_init;
1418 		}
1419 	}
1420 	if (--ibcm_rc_flow_control_simul < ibcm_rc_flow_control_simul_max)
1421 		cv_signal(&ibcm_rc_flow_control_cv);
1422 	mutex_exit(&ibcm_sa_timeout_lock);
1423 }
1424 
1425 void
1426 ibcm_close_flow_control_enter()
1427 {
1428 	mutex_enter(&ibcm_sa_timeout_lock);
1429 	if (ibcm_close_flow_control_simul_max !=
1430 	    ibcm_close_flow_control_simul_init) {
1431 		if (ibcm_close_flow_control_simul_max <
1432 		    ibcm_close_flow_control_simul_init) {
1433 			/* letting more flow should be gradual */
1434 			ibcm_close_flow_control_simul_max++;
1435 			if (ibcm_close_flow_control_simul <
1436 			    ibcm_close_flow_control_simul_max - 1)
1437 				cv_signal(&ibcm_close_flow_control_cv);
1438 		} else {
1439 			ibcm_close_flow_control_simul_max =
1440 			    ibcm_close_flow_control_simul_init;
1441 		}
1442 	}
1443 	while (ibcm_close_flow_control_simul >=
1444 	    ibcm_close_flow_control_simul_max) {
1445 		cv_wait(&ibcm_close_flow_control_cv, &ibcm_sa_timeout_lock);
1446 	}
1447 	ibcm_close_flow_control_simul++;
1448 	mutex_exit(&ibcm_sa_timeout_lock);
1449 }
1450 
1451 void
1452 ibcm_close_flow_control_exit()
1453 {
1454 	mutex_enter(&ibcm_sa_timeout_lock);
1455 	if (ibcm_close_flow_control_simul_max !=
1456 	    ibcm_close_flow_control_simul_init) {
1457 		if (ibcm_close_flow_control_simul_max <
1458 		    ibcm_close_flow_control_simul_init) {
1459 			/* letting more flow should be gradual */
1460 			ibcm_close_flow_control_simul_max++;
1461 			if (ibcm_close_flow_control_simul <
1462 			    ibcm_close_flow_control_simul_max)
1463 				cv_signal(&ibcm_close_flow_control_cv);
1464 		} else {
1465 			ibcm_close_flow_control_simul_max =
1466 			    ibcm_close_flow_control_simul_init;
1467 		}
1468 	}
1469 	if (--ibcm_close_flow_control_simul < ibcm_close_flow_control_simul_max)
1470 		cv_signal(&ibcm_close_flow_control_cv);
1471 	mutex_exit(&ibcm_sa_timeout_lock);
1472 }
1473 
1474 /*
1475  * This function is called when we hit any timeout, and have to retry.
1476  * The logic here is that the timeout may have been because the other
1477  * side of this connection is too busy to respond in time.  We provide
1478  * relief here by temporarily reducing the number of connections we
1479  * allow to be initiated.  As pending ones complete, we let new ones start.
1480  */
1481 void
1482 ibcm_rc_flow_control_stall()
1483 {
1484 	mutex_enter(&ibcm_sa_timeout_lock);
1485 	ibcm_rc_flow_control_simul_stalls++;
1486 	if (ibcm_rc_flow_control_simul_max)
1487 		ibcm_rc_flow_control_simul_max--;
1488 	mutex_exit(&ibcm_sa_timeout_lock);
1489 }
1490 
1491 void
1492 ibcm_sa_access_enter()
1493 {
1494 	mutex_enter(&ibcm_sa_timeout_lock);
1495 	while (ibcm_sa_timeout_simul == ibcm_sa_timeout_simul_max) {
1496 		cv_wait(&ibcm_sa_timeout_cv, &ibcm_sa_timeout_lock);
1497 	}
1498 	ibcm_sa_timeout_simul++;
1499 	mutex_exit(&ibcm_sa_timeout_lock);
1500 }
1501 
1502 void
1503 ibcm_sa_access_exit()
1504 {
1505 	mutex_enter(&ibcm_sa_timeout_lock);
1506 	cv_signal(&ibcm_sa_timeout_cv);
1507 	ibcm_sa_timeout_simul--;
1508 	mutex_exit(&ibcm_sa_timeout_lock);
1509 }
1510 
1511 static void
1512 ibcm_sm_notice_handler(ibmf_saa_handle_t saa_handle,
1513     ibmf_saa_subnet_event_t saa_event_code,
1514     ibmf_saa_event_details_t *saa_event_details,
1515     void *callback_arg)
1516 {
1517 	ibcm_port_info_t	*portp = (ibcm_port_info_t *)callback_arg;
1518 	ibt_subnet_event_code_t code;
1519 	ibt_subnet_event_t	event;
1520 	uint8_t			event_status;
1521 
1522 	IBTF_DPRINTF_L3(cmlog, "ibcm_sm_notice_handler: saa_hdl %p, code = %d",
1523 	    saa_handle, saa_event_code);
1524 
1525 	mutex_enter(&ibcm_sm_notice_serialize_lock);
1526 
1527 	switch (saa_event_code) {
1528 	case IBMF_SAA_EVENT_MCG_CREATED:
1529 		code = IBT_SM_EVENT_MCG_CREATED;
1530 		break;
1531 	case IBMF_SAA_EVENT_MCG_DELETED:
1532 		code = IBT_SM_EVENT_MCG_DELETED;
1533 		break;
1534 	case IBMF_SAA_EVENT_GID_AVAILABLE:
1535 		code = IBT_SM_EVENT_GID_AVAIL;
1536 		break;
1537 	case IBMF_SAA_EVENT_GID_UNAVAILABLE:
1538 		code = IBT_SM_EVENT_GID_UNAVAIL;
1539 		break;
1540 	case IBMF_SAA_EVENT_SUBSCRIBER_STATUS_CHG:
1541 		event_status =
1542 		    saa_event_details->ie_producer_event_status_mask &
1543 		    IBMF_SAA_EVENT_STATUS_MASK_PRODUCER_SM;
1544 		if (event_status == (portp->port_event_status &
1545 		    IBMF_SAA_EVENT_STATUS_MASK_PRODUCER_SM)) {
1546 			mutex_exit(&ibcm_sm_notice_serialize_lock);
1547 			return;	/* no change */
1548 		}
1549 		portp->port_event_status = event_status;
1550 		if (event_status == IBMF_SAA_EVENT_STATUS_MASK_PRODUCER_SM)
1551 			code = IBT_SM_EVENT_AVAILABLE;
1552 		else
1553 			code = IBT_SM_EVENT_UNAVAILABLE;
1554 		break;
1555 	default:
1556 		mutex_exit(&ibcm_sm_notice_serialize_lock);
1557 		return;
1558 	}
1559 
1560 	mutex_enter(&ibcm_global_hca_lock);
1561 
1562 	/* don't send the event if we're tearing down */
1563 	if (!IBCM_ACCESS_HCA_OK(portp->port_hcap)) {
1564 		mutex_exit(&ibcm_global_hca_lock);
1565 		mutex_exit(&ibcm_sm_notice_serialize_lock);
1566 		return;
1567 	}
1568 
1569 	++(portp->port_hcap->hca_acc_cnt);
1570 	mutex_exit(&ibcm_global_hca_lock);
1571 
1572 	event.sm_notice_gid = saa_event_details->ie_gid;
1573 	ibtl_cm_sm_notice_handler(portp->port_sgid0, code, &event);
1574 
1575 	mutex_exit(&ibcm_sm_notice_serialize_lock);
1576 
1577 	ibcm_dec_hca_acc_cnt(portp->port_hcap);
1578 }
1579 
1580 void
1581 ibt_register_subnet_notices(ibt_clnt_hdl_t ibt_hdl,
1582     ibt_sm_notice_handler_t sm_notice_handler, void *private)
1583 {
1584 	ibcm_port_info_t	*portp;
1585 	ibcm_hca_info_t		*hcap;
1586 	uint8_t			port;
1587 	int			num_failed_sgids;
1588 	ibtl_cm_sm_init_fail_t	*ifail;
1589 	ib_gid_t		*sgidp;
1590 
1591 	IBTF_DPRINTF_L3(cmlog, "ibt_register_subnet_notices: ibt_hdl = %p",
1592 	    ibt_hdl);
1593 
1594 	mutex_enter(&ibcm_sm_notice_serialize_lock);
1595 
1596 	ibtl_cm_set_sm_notice_handler(ibt_hdl, sm_notice_handler, private);
1597 	if (sm_notice_handler == NULL) {
1598 		mutex_exit(&ibcm_sm_notice_serialize_lock);
1599 		return;
1600 	}
1601 
1602 	/* for each port, if service is not available, make a call */
1603 	mutex_enter(&ibcm_global_hca_lock);
1604 	num_failed_sgids = 0;
1605 	hcap = ibcm_hca_listp;
1606 	while (hcap != NULL) {
1607 		portp = hcap->hca_port_info;
1608 		for (port = 0; port < hcap->hca_num_ports; port++) {
1609 			if (!(portp->port_event_status &
1610 			    IBMF_SAA_EVENT_STATUS_MASK_PRODUCER_SM))
1611 				num_failed_sgids++;
1612 			portp++;
1613 		}
1614 		hcap = hcap->hca_next;
1615 	}
1616 	if (num_failed_sgids != 0) {
1617 		ifail = kmem_alloc(sizeof (*ifail) +
1618 		    (num_failed_sgids - 1) * sizeof (ib_gid_t), KM_SLEEP);
1619 		ifail->smf_num_sgids = num_failed_sgids;
1620 		ifail->smf_ibt_hdl = ibt_hdl;
1621 		sgidp = &ifail->smf_sgid[0];
1622 		hcap = ibcm_hca_listp;
1623 		while (hcap != NULL) {
1624 			portp = hcap->hca_port_info;
1625 			for (port = 0; port < hcap->hca_num_ports; port++) {
1626 				if (!(portp->port_event_status &
1627 				    IBMF_SAA_EVENT_STATUS_MASK_PRODUCER_SM))
1628 					*sgidp++ = portp->port_sgid0;
1629 				portp++;
1630 			}
1631 			hcap = hcap->hca_next;
1632 		}
1633 	}
1634 	mutex_exit(&ibcm_global_hca_lock);
1635 
1636 	if (num_failed_sgids != 0) {
1637 		ibtl_cm_sm_notice_init_failure(ifail);
1638 		kmem_free(ifail, sizeof (*ifail) +
1639 		    (num_failed_sgids - 1) * sizeof (ib_gid_t));
1640 	}
1641 	mutex_exit(&ibcm_sm_notice_serialize_lock);
1642 }
1643 
1644 /* The following is run from a taskq because we've seen the stack overflow. */
1645 static void
1646 ibcm_init_saa(void *arg)
1647 {
1648 	ibcm_port_info_t		*portp = (ibcm_port_info_t *)arg;
1649 	int				status;
1650 	ib_guid_t			port_guid;
1651 	ibmf_saa_subnet_event_args_t	event_args;
1652 
1653 	port_guid = portp->port_sgid0.gid_guid;
1654 
1655 	IBTF_DPRINTF_L3(cmlog, "ibcm_init_saa: port guid %llX", port_guid);
1656 
1657 	event_args.is_event_callback_arg = portp;
1658 	event_args.is_event_callback = ibcm_sm_notice_handler;
1659 
1660 	if ((status = ibmf_sa_session_open(port_guid, 0, &event_args,
1661 	    IBMF_VERSION, 0, &portp->port_ibmf_saa_hdl)) != IBMF_SUCCESS) {
1662 		IBTF_DPRINTF_L2(cmlog, "ibcm_init_saa "
1663 		    "ibmf_sa_session_open failed for port guid %llX "
1664 		    "status = %d", port_guid, status);
1665 	} else {
1666 		IBTF_DPRINTF_L2(cmlog, "ibcm_init_saa "
1667 		    "registered sa_hdl 0x%p for port guid %llX",
1668 		    portp->port_ibmf_saa_hdl, port_guid);
1669 	}
1670 
1671 	mutex_enter(&ibcm_sa_open_lock);
1672 	portp->port_saa_open_in_progress = 0;
1673 	cv_broadcast(&ibcm_sa_open_cv);
1674 	mutex_exit(&ibcm_sa_open_lock);
1675 }
1676 
1677 void
1678 ibcm_init_saa_handle(ibcm_hca_info_t *hcap, uint8_t port)
1679 {
1680 	ibmf_saa_handle_t	saa_handle;
1681 	uint8_t			port_index = port - 1;
1682 	ibcm_port_info_t	*portp = &hcap->hca_port_info[port_index];
1683 	ibt_status_t		ibt_status;
1684 
1685 	if (port_index >= hcap->hca_num_ports)
1686 		return;
1687 
1688 	mutex_enter(&ibcm_sa_open_lock);
1689 	if (portp->port_saa_open_in_progress) {
1690 		mutex_exit(&ibcm_sa_open_lock);
1691 		return;
1692 	}
1693 
1694 	saa_handle = portp->port_ibmf_saa_hdl;
1695 	if (saa_handle != NULL) {
1696 		mutex_exit(&ibcm_sa_open_lock);
1697 		return;
1698 	}
1699 
1700 	portp->port_saa_open_in_progress = 1;
1701 	mutex_exit(&ibcm_sa_open_lock);
1702 
1703 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(portp->port_event_status))
1704 
1705 	/* The assumption is that we're getting event notifications */
1706 	portp->port_event_status = IBMF_SAA_EVENT_STATUS_MASK_PRODUCER_SM;
1707 
1708 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(portp->port_event_status))
1709 
1710 	ibt_status = ibt_get_port_state_byguid(portp->port_hcap->hca_guid,
1711 	    portp->port_num, &portp->port_sgid0, NULL);
1712 	if (ibt_status != IBT_SUCCESS) {
1713 		IBTF_DPRINTF_L2(cmlog, "ibcm_init_saa_handle "
1714 		    "ibt_get_port_state_byguid failed for guid %llX "
1715 		    "with status %d", portp->port_hcap->hca_guid, ibt_status);
1716 		mutex_enter(&ibcm_sa_open_lock);
1717 		portp->port_saa_open_in_progress = 0;
1718 		cv_broadcast(&ibcm_sa_open_cv);
1719 		mutex_exit(&ibcm_sa_open_lock);
1720 		return;
1721 	}
1722 	/* if the port is UP, try sa_session_open */
1723 	(void) taskq_dispatch(ibcm_taskq, ibcm_init_saa, portp, TQ_SLEEP);
1724 }
1725 
1726 
1727 ibmf_saa_handle_t
1728 ibcm_get_saa_handle(ibcm_hca_info_t *hcap, uint8_t port)
1729 {
1730 	ibmf_saa_handle_t	saa_handle;
1731 	uint8_t			port_index = port - 1;
1732 	ibcm_port_info_t	*portp = &hcap->hca_port_info[port_index];
1733 	ibt_status_t		ibt_status;
1734 
1735 	if (port_index >= hcap->hca_num_ports)
1736 		return (NULL);
1737 
1738 	mutex_enter(&ibcm_sa_open_lock);
1739 	while (portp->port_saa_open_in_progress) {
1740 		cv_wait(&ibcm_sa_open_cv, &ibcm_sa_open_lock);
1741 	}
1742 
1743 	saa_handle = portp->port_ibmf_saa_hdl;
1744 	if (saa_handle != NULL) {
1745 		mutex_exit(&ibcm_sa_open_lock);
1746 		return (saa_handle);
1747 	}
1748 
1749 	portp->port_saa_open_in_progress = 1;
1750 	mutex_exit(&ibcm_sa_open_lock);
1751 
1752 	ibt_status = ibt_get_port_state_byguid(portp->port_hcap->hca_guid,
1753 	    portp->port_num, &portp->port_sgid0, NULL);
1754 	if (ibt_status != IBT_SUCCESS) {
1755 		IBTF_DPRINTF_L2(cmlog, "ibcm_get_saa_handle "
1756 		    "ibt_get_port_state_byguid failed for guid %llX "
1757 		    "with status %d", portp->port_hcap->hca_guid, ibt_status);
1758 		mutex_enter(&ibcm_sa_open_lock);
1759 		portp->port_saa_open_in_progress = 0;
1760 		cv_broadcast(&ibcm_sa_open_cv);
1761 		mutex_exit(&ibcm_sa_open_lock);
1762 		return (NULL);
1763 	}
1764 	/* if the port is UP, try sa_session_open */
1765 	(void) taskq_dispatch(ibcm_taskq, ibcm_init_saa, portp, TQ_SLEEP);
1766 
1767 	mutex_enter(&ibcm_sa_open_lock);
1768 	while (portp->port_saa_open_in_progress) {
1769 		cv_wait(&ibcm_sa_open_cv, &ibcm_sa_open_lock);
1770 	}
1771 	saa_handle = portp->port_ibmf_saa_hdl;
1772 	mutex_exit(&ibcm_sa_open_lock);
1773 	return (saa_handle);
1774 }
1775 
1776 
1777 /*
1778  * ibcm_hca_init_port():
1779  * 	- Register port with IBMA
1780  *
1781  * Arguments:
1782  *	hcap		- HCA's guid
1783  *	port_index	- port number minus 1
1784  *
1785  * Return values:
1786  *	IBCM_SUCCESS - success
1787  */
1788 ibt_status_t
1789 ibcm_hca_init_port(ibcm_hca_info_t *hcap, uint8_t port_index)
1790 {
1791 	int			status;
1792 	ibmf_register_info_t	*ibmf_reg;
1793 
1794 	IBTF_DPRINTF_L4(cmlog, "ibcm_hca_init_port: hcap = 0x%p port_num %d",
1795 	    hcap, port_index + 1);
1796 
1797 	ASSERT(MUTEX_HELD(&ibcm_global_hca_lock));
1798 
1799 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(hcap->hca_port_info))
1800 
1801 	if (hcap->hca_port_info[port_index].port_ibmf_hdl == NULL) {
1802 		/* Register with IBMF */
1803 		ibmf_reg = &hcap->hca_port_info[port_index].port_ibmf_reg;
1804 		ibmf_reg->ir_ci_guid = hcap->hca_guid;
1805 		ibmf_reg->ir_port_num = port_index + 1;
1806 		ibmf_reg->ir_client_class = COMM_MGT_MANAGER_AGENT;
1807 
1808 		/*
1809 		 * register with management framework
1810 		 */
1811 		status = ibmf_register(ibmf_reg, IBMF_VERSION,
1812 		    IBMF_REG_FLAG_NO_OFFLOAD, NULL, NULL,
1813 		    &(hcap->hca_port_info[port_index].port_ibmf_hdl),
1814 		    &(hcap->hca_port_info[port_index].port_ibmf_caps));
1815 
1816 		if (status != IBMF_SUCCESS) {
1817 			IBTF_DPRINTF_L2(cmlog, "ibcm_hca_init_port: "
1818 			    "ibmf_register failed for port_num %x, "
1819 			    "status = %x", port_index + 1, status);
1820 			return (ibcm_ibmf_analyze_error(status));
1821 		}
1822 
1823 		hcap->hca_port_info[port_index].port_qp1.qp_cm =
1824 		    IBMF_QP_HANDLE_DEFAULT;
1825 		hcap->hca_port_info[port_index].port_qp1.qp_port =
1826 		    &(hcap->hca_port_info[port_index]);
1827 
1828 		/*
1829 		 * Register the read callback with IBMF.
1830 		 * Since we just did an ibmf_register, handle is
1831 		 * valid and ibcm_recv_cb() is valid so we can
1832 		 * safely assert for success of ibmf_setup_recv_cb()
1833 		 *
1834 		 * Depending on the "state" of the HCA,
1835 		 * CM may drop incoming packets
1836 		 */
1837 		status = ibmf_setup_async_cb(
1838 		    hcap->hca_port_info[port_index].port_ibmf_hdl,
1839 		    IBMF_QP_HANDLE_DEFAULT, ibcm_recv_cb,
1840 		    &(hcap->hca_port_info[port_index].port_qp1), 0);
1841 		ASSERT(status == IBMF_SUCCESS);
1842 
1843 		IBTF_DPRINTF_L5(cmlog, "ibcm_hca_init_port: "
1844 		    "IBMF hdl[%x] = 0x%p", port_index,
1845 		    hcap->hca_port_info[port_index].port_ibmf_hdl);
1846 
1847 		/* Attempt to get the saa_handle for this port */
1848 		ibcm_init_saa_handle(hcap, port_index + 1);
1849 	}
1850 
1851 	return (IBT_SUCCESS);
1852 }
1853 
1854 /*
1855  * useful, to re attempt to initialize port ibma handles from elsewhere in
1856  * cm code
1857  */
1858 ibt_status_t
1859 ibcm_hca_reinit_port(ibcm_hca_info_t *hcap, uint8_t port_index)
1860 {
1861 	ibt_status_t	status;
1862 
1863 	IBTF_DPRINTF_L5(cmlog, "ibcm_hca_reinit_port: hcap 0x%p port_num %d",
1864 	    hcap, port_index + 1);
1865 
1866 	mutex_enter(&ibcm_global_hca_lock);
1867 	status = ibcm_hca_init_port(hcap, port_index);
1868 	mutex_exit(&ibcm_global_hca_lock);
1869 	return (status);
1870 }
1871 
1872 
1873 /*
1874  * ibcm_hca_fini_port():
1875  * 	- Deregister port with IBMA
1876  *
1877  * Arguments:
1878  *	hcap		- HCA's guid
1879  *	port_index	- port number minus 1
1880  *
1881  * Return values:
1882  *	IBCM_SUCCESS - success
1883  */
1884 static ibcm_status_t
1885 ibcm_hca_fini_port(ibcm_hca_info_t *hcap, uint8_t port_index)
1886 {
1887 	int			ibmf_status;
1888 	ibcm_status_t		ibcm_status;
1889 
1890 	IBTF_DPRINTF_L4(cmlog, "ibcm_hca_fini_port: hcap = 0x%p port_num %d ",
1891 	    hcap, port_index + 1);
1892 
1893 	ASSERT(MUTEX_HELD(&ibcm_global_hca_lock));
1894 
1895 	if (hcap->hca_port_info[port_index].port_ibmf_saa_hdl != NULL) {
1896 		IBTF_DPRINTF_L5(cmlog, "ibcm_hca_fini_port: "
1897 		    "ibmf_sa_session_close IBMF SAA hdl %p",
1898 		    hcap->hca_port_info[port_index].port_ibmf_saa_hdl);
1899 
1900 		ibmf_status = ibmf_sa_session_close(
1901 		    &hcap->hca_port_info[port_index].port_ibmf_saa_hdl, 0);
1902 		if (ibmf_status != IBMF_SUCCESS) {
1903 			IBTF_DPRINTF_L2(cmlog, "ibcm_hca_fini_port "
1904 			    "ibmf_sa_session_close of port %d returned %x",
1905 			    port_index + 1, ibmf_status);
1906 			return (IBCM_FAILURE);
1907 		}
1908 	}
1909 
1910 	if (hcap->hca_port_info[port_index].port_ibmf_hdl != NULL) {
1911 		IBTF_DPRINTF_L5(cmlog, "ibcm_hca_fini_port: "
1912 		    "ibmf_unregister IBMF Hdl %p",
1913 		    hcap->hca_port_info[port_index].port_ibmf_hdl);
1914 
1915 		/* clean-up all the ibmf qp's allocated on this port */
1916 		ibcm_status = ibcm_free_allqps(hcap, port_index + 1);
1917 
1918 		if (ibcm_status != IBCM_SUCCESS) {
1919 
1920 			IBTF_DPRINTF_L2(cmlog, "ibcm_hca_fini_port "
1921 			    "ibcm_free_allqps failed for port_num %d",
1922 			    port_index + 1);
1923 			return (IBCM_FAILURE);
1924 		}
1925 
1926 		/* Tear down the receive callback */
1927 		ibmf_status = ibmf_tear_down_async_cb(
1928 		    hcap->hca_port_info[port_index].port_ibmf_hdl,
1929 		    IBMF_QP_HANDLE_DEFAULT, 0);
1930 
1931 		if (ibmf_status != IBMF_SUCCESS) {
1932 			IBTF_DPRINTF_L2(cmlog, "ibcm_hca_fini_port "
1933 			    "ibmf_tear_down_async_cb failed %d port_num %d",
1934 			    ibmf_status, port_index + 1);
1935 			return (IBCM_FAILURE);
1936 		}
1937 
1938 		/* Now, unregister with IBMF */
1939 		ibmf_status = ibmf_unregister(
1940 		    &hcap->hca_port_info[port_index].port_ibmf_hdl, 0);
1941 		IBTF_DPRINTF_L4(cmlog, "ibcm_hca_fini_port: "
1942 		    "ibmf_unregister of port_num %x returned %x",
1943 		    port_index + 1, ibmf_status);
1944 
1945 		if (ibmf_status == IBMF_SUCCESS)
1946 			hcap->hca_port_info[port_index].port_ibmf_hdl =
1947 								NULL;
1948 		else {
1949 			IBTF_DPRINTF_L2(cmlog, "ibcm_hca_fini_port "
1950 			    "ibmf_unregister failed %d port_num %d",
1951 			    ibmf_status, port_index + 1);
1952 			return (IBCM_FAILURE);
1953 		}
1954 	}
1955 	return (IBCM_SUCCESS);
1956 }
1957 
1958 /*
1959  * ibcm_comm_est_handler():
1960  *	Check if the given channel is in ESTABLISHED state or not
1961  *
1962  * Arguments:
1963  *	eventp	- A pointer to an ibt_async_event_t struct
1964  *
1965  * Return values: NONE
1966  */
1967 static void
1968 ibcm_comm_est_handler(ibt_async_event_t *eventp)
1969 {
1970 	ibcm_state_data_t	*statep;
1971 
1972 	IBTF_DPRINTF_L4(cmlog, "ibcm_comm_est_handler:");
1973 
1974 	/* Both QP and EEC handles can't be NULL */
1975 	if (eventp->ev_chan_hdl == NULL) {
1976 		IBTF_DPRINTF_L2(cmlog, "ibcm_comm_est_handler: "
1977 		    "both QP and EEC handles are NULL");
1978 		return;
1979 	}
1980 
1981 	/* get the "statep" from qp/eec handles */
1982 	IBCM_GET_CHAN_PRIVATE(eventp->ev_chan_hdl, statep);
1983 	if (statep == NULL) {
1984 		IBTF_DPRINTF_L2(cmlog, "ibcm_comm_est_handler: statep is NULL");
1985 		return;
1986 	}
1987 
1988 	mutex_enter(&statep->state_mutex);
1989 
1990 	IBCM_RELEASE_CHAN_PRIVATE(eventp->ev_chan_hdl);
1991 
1992 	IBTF_DPRINTF_L4(cmlog, "ibcm_comm_est_handler: statep = %p", statep);
1993 
1994 	IBCM_REF_CNT_INCR(statep);
1995 
1996 	if ((statep->state == IBCM_STATE_REP_SENT) ||
1997 	    (statep->state == IBCM_STATE_MRA_REP_RCVD)) {
1998 		timeout_id_t	timer_val = statep->timerid;
1999 
2000 		statep->state = IBCM_STATE_TRANSIENT_ESTABLISHED;
2001 
2002 		if (timer_val) {
2003 			statep->timerid = 0;
2004 			mutex_exit(&statep->state_mutex);
2005 			(void) untimeout(timer_val);
2006 		} else
2007 			mutex_exit(&statep->state_mutex);
2008 
2009 		/* CM doesn't have RTU message here */
2010 		ibcm_cep_state_rtu(statep, NULL);
2011 
2012 	} else {
2013 		if (statep->state == IBCM_STATE_ESTABLISHED) {
2014 			IBTF_DPRINTF_L4(cmlog, "ibcm_comm_est_handler: "
2015 			    "Channel already in ESTABLISHED state");
2016 		} else {
2017 			/* An unexpected behavior from remote */
2018 			IBTF_DPRINTF_L2(cmlog, "ibcm_comm_est_handler: "
2019 			    "Unexpected in state = %d", statep->state);
2020 		}
2021 		mutex_exit(&statep->state_mutex);
2022 
2023 		ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_COMEST);
2024 	}
2025 
2026 	mutex_enter(&statep->state_mutex);
2027 	IBCM_REF_CNT_DECR(statep);
2028 	mutex_exit(&statep->state_mutex);
2029 }
2030 
2031 
2032 /*
2033  * ibcm_async_handler():
2034  *	CM's Async Handler
2035  *	(Handles ATTACH, DETACH, COM_EST events)
2036  *
2037  * Arguments:
2038  *	eventp	- A pointer to an ibt_async_event_t struct
2039  *
2040  * Return values: None
2041  *
2042  * NOTE : CM assumes that all HCA DR events are delivered sequentially
2043  * i.e., until ibcm_async_handler  completes for a given HCA DR, framework
2044  * shall not invoke ibcm_async_handler with another DR event for the same
2045  * HCA
2046  */
2047 /* ARGSUSED */
2048 void
2049 ibcm_async_handler(void *clnt_hdl, ibt_hca_hdl_t hca_hdl,
2050     ibt_async_code_t code, ibt_async_event_t *eventp)
2051 {
2052 	ibcm_hca_info_t		*hcap;
2053 	ibcm_port_up_t		*pup;
2054 
2055 	IBTF_DPRINTF_L3(cmlog, "ibcm_async_handler: "
2056 	    "clnt_hdl = %p, code = 0x%x, eventp = 0x%p",
2057 	    clnt_hdl, code, eventp);
2058 
2059 	mutex_enter(&ibcm_global_hca_lock);
2060 
2061 	/* If fini is going to complete successfully, then return */
2062 	if (ibcm_finit_state != IBCM_FINIT_IDLE) {
2063 
2064 		/*
2065 		 * This finit state implies one of the following:
2066 		 * Init either didn't start or didn't complete OR
2067 		 * Fini is about to return SUCCESS and release the global lock.
2068 		 * In all these cases, it is safe to ignore the async.
2069 		 */
2070 
2071 		IBTF_DPRINTF_L2(cmlog, "ibcm_async_handler: ignoring event %x, "
2072 		    "as either init didn't complete or fini about to succeed",
2073 		    code);
2074 		mutex_exit(&ibcm_global_hca_lock);
2075 		return;
2076 	}
2077 
2078 	switch (code) {
2079 	case IBT_EVENT_PORT_UP:
2080 		mutex_exit(&ibcm_global_hca_lock);
2081 		pup = kmem_alloc(sizeof (ibcm_port_up_t), KM_SLEEP);
2082 		_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*pup))
2083 		pup->pup_hca_guid = eventp->ev_hca_guid;
2084 		pup->pup_port = eventp->ev_port;
2085 		_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*pup))
2086 		(void) taskq_dispatch(ibcm_taskq,
2087 		    ibcm_service_record_rewrite_task, pup, TQ_SLEEP);
2088 		return;
2089 
2090 	case IBT_HCA_ATTACH_EVENT:
2091 
2092 		/* eventp->ev_hcaguid is the HCA GUID of interest */
2093 		ibcm_hca_attach(eventp->ev_hca_guid);
2094 		break;
2095 
2096 	case IBT_HCA_DETACH_EVENT:
2097 
2098 		/* eventp->ev_hca_guid is the HCA GUID of interest */
2099 		if ((hcap = ibcm_find_hcap_entry(eventp->ev_hca_guid)) ==
2100 		    NULL) {
2101 			IBTF_DPRINTF_L2(cmlog, "ibcm_async_handler:"
2102 			    " hca %llX doesn't exist", eventp->ev_hca_guid);
2103 			break;
2104 		}
2105 
2106 		(void) ibcm_hca_detach(hcap);
2107 		break;
2108 
2109 	case IBT_EVENT_COM_EST_QP:
2110 		/* eventp->ev_qp_hdl is the ibt_qp_hdl_t of interest */
2111 	case IBT_EVENT_COM_EST_EEC:
2112 		/* eventp->ev_eec_hdl is the ibt_eec_hdl_t of interest */
2113 		ibcm_comm_est_handler(eventp);
2114 		break;
2115 	default:
2116 		break;
2117 	}
2118 
2119 	/* Unblock, any blocked fini/init operations */
2120 	mutex_exit(&ibcm_global_hca_lock);
2121 }
2122