Home | History | Annotate | Download | only in ibtl
      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 (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      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.
     12  *
     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]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 /*
     27  * ibtl_impl.c
     28  *
     29  * This file contains the IBTF module's initialization and
     30  * IBTF Clients/Modules registration routines.
     31  */
     32 
     33 #include <sys/modctl.h>
     34 #include <sys/sunndi.h>
     35 #include <sys/ib/ibtl/impl/ibtl.h>
     36 #include <sys/ib/ibtl/impl/ibtl_ibnex.h>
     37 
     38 /*
     39  * Globals.
     40  */
     41 static char ibtf[] = "ibtl_impl";
     42 
     43 extern ibtl_ibnex_callback_t	ibtl_ibnex_callback_routine;
     44 
     45 /*
     46  * ibtl_clnt_list:
     47  *
     48  *	Head of the list of IBT Client Instances. The IBT Client List
     49  *	is modified by IBTF on an IBT client's ibt_attach/ibt_detach call.
     50  *
     51  * ibtl_hca_list:
     52  *
     53  *	Head of the list of HCA devices. The HCA List is modified by IBTF on
     54  *	a CI's ibc_attach/ibc_detach call.
     55  *	The datap of the list elements points to an ibtl_hca_devinfo_s
     56  *	structure.
     57  *
     58  *				(ibc_attach)
     59  *  ibtl_hca_list	-> ibtl_hca_devinfo_t--> ...	-->ibtl_hca_devinfo_t
     60  *	[per-hca_dev]		|	^			{nth HCA Dev}
     61  *				|	|
     62  *				|  ibtl_hca_t (ibt_open_hca)
     63  *				|	^  |
     64  *				|	|  |
     65  *				v	|  V
     66  *  ibtl_clnt_list	->	ibtl_clnt_t--> ...--> {n'th Module}
     67  *	[per-client_instance]	(ibt_attach)
     68  *
     69  */
     70 
     71 /* Global List of IBT Client Instances, and associated mutex. */
     72 struct ibtl_clnt_s *ibtl_clnt_list = NULL;
     73 kmutex_t ibtl_clnt_list_mutex;
     74 
     75 /* Lock for the race between the client and CM to free QPs. */
     76 kmutex_t ibtl_free_qp_mutex;
     77 
     78 /* Lock for the race between the client closing the HCA and QPN being freed. */
     79 kcondvar_t ibtl_close_hca_cv;
     80 
     81 /* Global List of HCA Devices, and associated mutex. */
     82 struct ibtl_hca_devinfo_s *ibtl_hca_list = NULL;
     83 
     84 /* Well-known async handlers and associated client private. */
     85 ibt_async_handler_t ibtl_cm_async_handler;
     86 ibt_async_handler_t ibtl_dm_async_handler;
     87 ibt_async_handler_t ibtl_ibma_async_handler;
     88 void	*ibtl_cm_clnt_private;
     89 void	*ibtl_dm_clnt_private;
     90 void	*ibtl_ibma_clnt_private;
     91 
     92 extern int ib_hw_status;
     93 _NOTE(SCHEME_PROTECTS_DATA("Scheme protects data", ib_hw_status))
     94 
     95 /*
     96  * Misc Module Declarations.
     97  */
     98 extern struct mod_ops mod_miscops;
     99 static struct modlmisc modlmisc = {
    100 	&mod_miscops,			/* Type of module - misc. */
    101 	"IB Transport Layer"		/* Name of the Module. */
    102 };
    103 
    104 static struct modlinkage modlinkage = {
    105 	MODREV_1, (void *)&modlmisc, NULL
    106 };
    107 
    108 static void ibtl_kstat_init(ibtl_hca_devinfo_t *);
    109 static void ibtl_kstat_fini(ibtl_hca_devinfo_t *);
    110 static void ibtl_kstat_stats_create(ibtl_hca_devinfo_t *, uint_t);
    111 static void ibtl_kstat_pkeys_create(ibtl_hca_devinfo_t *, uint_t);
    112 
    113 /*
    114  * IBTF Loadable Module Routines.
    115  */
    116 
    117 int
    118 _init(void)
    119 {
    120 	int rval;
    121 
    122 	if ((rval = mod_install(&modlinkage)) != 0)
    123 		return (rval);
    124 
    125 	/*
    126 	 * initialize IBTL ib2usec table
    127 	 */
    128 	ibtl_ib2usec_init();
    129 
    130 	/*
    131 	 * Initialize Logging
    132 	 */
    133 	ibtl_logging_initialization();
    134 
    135 	/*
    136 	 * Initialize the Alloc QP States.
    137 	 */
    138 	ibtl_init_cep_states();
    139 
    140 	/*
    141 	 * Initialize all Global Link Lists.
    142 	 */
    143 	mutex_init(&ibtl_clnt_list_mutex, NULL, MUTEX_DEFAULT, NULL);
    144 	mutex_init(&ibtl_free_qp_mutex, NULL, MUTEX_DEFAULT, NULL);
    145 	cv_init(&ibtl_close_hca_cv, NULL, CV_DEFAULT, NULL);
    146 
    147 	mutex_init(&ibtl_qp_mutex, NULL, MUTEX_DEFAULT, NULL);
    148 	cv_init(&ibtl_qp_cv, NULL, CV_DEFAULT, NULL);
    149 
    150 	ibtl_thread_init();
    151 
    152 	return (rval);
    153 }
    154 
    155 
    156 /*
    157  * The IBTF Module is never unloaded. Actually there is no need of this
    158  * routine, but provided just in case.
    159  */
    160 int
    161 _fini(void)
    162 {
    163 	int rval;
    164 
    165 	if ((rval = mod_remove(&modlinkage)) != 0) {
    166 		return (rval);
    167 	}
    168 
    169 	ibtl_thread_fini();
    170 
    171 	mutex_destroy(&ibtl_clnt_list_mutex);
    172 	mutex_destroy(&ibtl_free_qp_mutex);
    173 	cv_destroy(&ibtl_close_hca_cv);
    174 	mutex_destroy(&ibtl_qp_mutex);
    175 	cv_destroy(&ibtl_qp_cv);
    176 
    177 	/*
    178 	 * Stop Logging
    179 	 */
    180 	ibtl_logging_destroy();
    181 
    182 	return (rval);
    183 }
    184 
    185 
    186 int
    187 _info(struct modinfo *modinfop)
    188 {
    189 	/* Return the Module Information. */
    190 	return (mod_info(&modlinkage, modinfop));
    191 }
    192 
    193 
    194 /*
    195  * IBTF Client Registration Routines.
    196  */
    197 
    198 /*
    199  * Function:
    200  *	ibt_attach
    201  * Input:
    202  *	modinfop	- Client Module info structure.
    203  *	arg		- usually client's dip
    204  *	clnt_private	- client's private data pointer.
    205  * Output:
    206  *	ibt_hdl_p	- pointer to client's specific IBT handle,
    207  *			 which is opaque to clients.
    208  * Returns:
    209  *	IBT_SUCCESS
    210  *	IBT_INVALID_PARAM
    211  * Called by:
    212  *	IBTF Client module during its attach() to register its instance
    213  *	to IBTF.
    214  * Description:
    215  *	Registers the IBTF client module instance and returns an opaque
    216  *	handler to the client to be used for future calls to IBTF.
    217  *	Adds this client module instance to ibtl_clnt_list list.
    218  *	Records well-known async handlers.
    219  */
    220 ibt_status_t
    221 ibt_attach(ibt_clnt_modinfo_t *mod_infop, dev_info_t *arg, void *clnt_private,
    222     ibt_clnt_hdl_t *ibt_hdl_p)
    223 {
    224 	dev_info_t	*pdip;
    225 	ibtl_clnt_t	*clntp;
    226 
    227 	IBTF_DPRINTF_L3(ibtf, "ibt_attach(%p, %p, %p)",
    228 	    mod_infop, arg, clnt_private);
    229 
    230 	if (mod_infop->mi_clnt_name == NULL) {
    231 		IBTF_DPRINTF_L1(ibtf, "ibt_attach: "
    232 		    "IB client needs to specify its name");
    233 		return (IBT_INVALID_PARAM);
    234 	}
    235 
    236 	/*
    237 	 * Validate the Transport API version.
    238 	 */
    239 	if (mod_infop->mi_ibt_version != IBTI_V_CURR) {
    240 		IBTF_DPRINTF_L1(ibtf, "ibt_attach: IB client '%s' has an "
    241 		    "invalid IB TI Version '%d'", mod_infop->mi_clnt_name,
    242 		    mod_infop->mi_ibt_version);
    243 		return (IBT_NOT_SUPPORTED);
    244 	}
    245 
    246 	if (mod_infop->mi_async_handler == NULL) {
    247 		IBTF_DPRINTF_L2(ibtf, "ibt_attach: Client '%s' has not\n"
    248 		    "        provided an Asynchronous Event Handler.\n"
    249 		    "        This will be required soon.",
    250 		    mod_infop->mi_clnt_name);
    251 	}
    252 
    253 	/*
    254 	 * Check out Client's Class information. If it is not of mgmt class,
    255 	 * we expect 'arg' to be Not NULL and point to client driver's
    256 	 * device info struct.
    257 	 */
    258 	if ((!IBT_MISCMOD_CLIENTS(mod_infop->mi_clnt_class)) &&
    259 	    (arg == NULL)) {
    260 		IBTF_DPRINTF_L1(ibtf, "ibt_attach: "
    261 		    "arg not set with driver's dip.");
    262 		return (IBT_INVALID_PARAM);
    263 	}
    264 
    265 	if (!IBT_MISCMOD_CLIENTS(mod_infop->mi_clnt_class)) {
    266 		pdip = ddi_get_parent(arg);
    267 		if (pdip == NULL ||
    268 		    ibtl_ibnex_valid_hca_parent(pdip) != IBT_SUCCESS) {
    269 			IBTF_DPRINTF_L2(ibtf, "ibt_attach: "
    270 			    "client %s is not a child of IB nexus driver.",
    271 			    ddi_driver_name(arg));
    272 			return (IBT_INVALID_PARAM);
    273 		}
    274 	}
    275 
    276 	mutex_enter(&ibtl_clnt_list_mutex);
    277 	if (mod_infop->mi_clnt_class == IBT_CM) {
    278 		if (ibtl_cm_async_handler != NULL) {
    279 			IBTF_DPRINTF_L1(ibtf, "ibt_attach: "
    280 			    "CM is already attached.");
    281 			mutex_exit(&ibtl_clnt_list_mutex);
    282 			return (IBT_INVALID_PARAM);
    283 		}
    284 		ibtl_cm_async_handler = mod_infop->mi_async_handler;
    285 		ibtl_cm_clnt_private = clnt_private;
    286 	} else if (mod_infop->mi_clnt_class == IBT_DM) {
    287 		if (ibtl_dm_async_handler != NULL) {
    288 			IBTF_DPRINTF_L1(ibtf, "ibt_attach: "
    289 			    "DM is already attached.");
    290 			mutex_exit(&ibtl_clnt_list_mutex);
    291 			return (IBT_INVALID_PARAM);
    292 		}
    293 		ibtl_dm_async_handler = mod_infop->mi_async_handler;
    294 		ibtl_dm_clnt_private = clnt_private;
    295 	} else if (mod_infop->mi_clnt_class == IBT_IBMA) {
    296 		if (ibtl_ibma_async_handler != NULL) {
    297 			IBTF_DPRINTF_L1(ibtf, "ibt_attach: "
    298 			    "IBMF is already attached.");
    299 			mutex_exit(&ibtl_clnt_list_mutex);
    300 			return (IBT_INVALID_PARAM);
    301 		}
    302 		ibtl_ibma_async_handler = mod_infop->mi_async_handler;
    303 		ibtl_ibma_clnt_private = clnt_private;
    304 	}
    305 
    306 	/* Allocate the memory for per-client-device info structure */
    307 	clntp = kmem_zalloc(sizeof (ibtl_clnt_t), KM_SLEEP);
    308 
    309 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(clntp->clnt_modinfop,
    310 	    clntp->clnt_dip, clntp->clnt_name, clntp->clnt_async_cnt,
    311 	    clntp->clnt_private))
    312 	/* Update the Client info structure */
    313 	clntp->clnt_modinfop = mod_infop;	/* IBT Client's Mod Info */
    314 	clntp->clnt_private = clnt_private;	/* IBT Client's private */
    315 	clntp->clnt_dip = arg;			/* IBT Client's dip */
    316 	clntp->clnt_async_cnt = 0;
    317 	/* using a count of 7 below guarantees it is NULL terminated */
    318 	(void) strncpy(clntp->clnt_name, mod_infop->mi_clnt_name, 7);
    319 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(clntp->clnt_modinfop,
    320 	    clntp->clnt_dip, clntp->clnt_name, clntp->clnt_async_cnt,
    321 	    clntp->clnt_private))
    322 
    323 	/*
    324 	 * Update Client Device Instance List.
    325 	 */
    326 	clntp->clnt_list_link = ibtl_clnt_list;
    327 	ibtl_clnt_list = clntp;
    328 	mutex_exit(&ibtl_clnt_list_mutex);
    329 
    330 	/*
    331 	 * The ibt_hdl_p is a opaque handle which is the address of
    332 	 * ibt_clnt_t structure passed back to the clients.
    333 	 * The client will pass on this handle in its future calls to IBTF.
    334 	 */
    335 	*ibt_hdl_p = clntp;
    336 
    337 	return (IBT_SUCCESS);
    338 }
    339 
    340 
    341 /*
    342  * Function:
    343  *	ibt_detach
    344  * Input:
    345  *	ibt_hdl - IBT Handle as returned during ibt_attach call.
    346  * Output:
    347  *	none
    348  * Returns:
    349  *	IBT_SUCCESS
    350  *	IBT_INVALID_PARAM.
    351  * Called by:
    352  *	IBTF Client module during its detach() to de-register its instance
    353  *	from IBTF.
    354  * Description:
    355  *	Deregisters the IBTF client module instance from the IBTF.
    356  *	All resources and any reference to this ibt_hdl will be removed.
    357  */
    358 ibt_status_t
    359 ibt_detach(ibt_clnt_hdl_t ibt_hdl)
    360 {
    361 	ibtl_clnt_t **clntpp;
    362 
    363 	IBTF_DPRINTF_L3(ibtf, "ibt_detach(%p)", ibt_hdl);
    364 
    365 	mutex_enter(&ibtl_clnt_list_mutex);
    366 	clntpp = &ibtl_clnt_list;
    367 	for (; *clntpp != NULL; clntpp = &(*clntpp)->clnt_list_link)
    368 		if (*clntpp == ibt_hdl)
    369 			break;
    370 	if (*clntpp == NULL) {
    371 		IBTF_DPRINTF_L1(ibtf, "ibt_detach: Client @ %p Not Found",
    372 		    ibt_hdl);
    373 		mutex_exit(&ibtl_clnt_list_mutex);
    374 		return (IBT_INVALID_PARAM);
    375 	}
    376 
    377 	/*
    378 	 * Check out whether the client has freed all its resources.
    379 	 * If not done, then fail the detach.
    380 	 *
    381 	 * viz. A client has to close all the HCA they have opened,
    382 	 * i.e. the HCA List maintained for clients has to be empty.
    383 	 * If this list is not empty, then the client has not performed
    384 	 * complete clean-up, so fail the detach.
    385 	 */
    386 	if (ibt_hdl->clnt_hca_list != NULL) {
    387 		mutex_exit(&ibtl_clnt_list_mutex);
    388 
    389 		IBTF_DPRINTF_L2(ibtf, "ibt_detach: "
    390 		    "ERROR: Client '%s' has not closed all of its HCAs",
    391 		    ibt_hdl->clnt_modinfop->mi_clnt_name);
    392 		return (IBT_HCA_RESOURCES_NOT_FREED);
    393 	}
    394 
    395 	if (ibt_hdl->clnt_srv_cnt != 0) {
    396 		mutex_exit(&ibtl_clnt_list_mutex);
    397 		IBTF_DPRINTF_L2(ibtf, "ibt_detach: client '%s' still has "
    398 		    "services or subnet_notices registered",
    399 		    ibt_hdl->clnt_modinfop->mi_clnt_name);
    400 		return (IBT_HCA_RESOURCES_NOT_FREED);
    401 	}
    402 
    403 	/*
    404 	 * Delete the entry of this module from the ibtl_clnt_list List.
    405 	 */
    406 	*clntpp = ibt_hdl->clnt_list_link;	/* remove us */
    407 
    408 	/* make sure asyncs complete before freeing */
    409 	ibtl_free_clnt_async_check(ibt_hdl);
    410 
    411 	if (ibt_hdl->clnt_modinfop->mi_clnt_class == IBT_CM) {
    412 		ibtl_cm_async_handler = NULL;
    413 		ibtl_cm_clnt_private = NULL;
    414 	} else if (ibt_hdl->clnt_modinfop->mi_clnt_class == IBT_DM) {
    415 		ibtl_dm_async_handler = NULL;
    416 		ibtl_dm_clnt_private = NULL;
    417 	} else if (ibt_hdl->clnt_modinfop->mi_clnt_class == IBT_IBMA) {
    418 		ibtl_ibma_async_handler = NULL;
    419 		ibtl_ibma_clnt_private = NULL;
    420 	}
    421 	mutex_exit(&ibtl_clnt_list_mutex);
    422 
    423 	/* Free up the memory of per-client info struct. */
    424 	kmem_free(ibt_hdl, sizeof (ibtl_clnt_t));
    425 
    426 	return (IBT_SUCCESS);
    427 }
    428 
    429 static void
    430 ibtl_set_ibhw_status()
    431 {
    432 	ib_hw_status++;
    433 }
    434 
    435 static void
    436 ibtl_clear_ibhw_status()
    437 {
    438 	ib_hw_status--;
    439 }
    440 
    441 /*
    442  * Function:
    443  *	ibc_init
    444  * Input:
    445  *	modlp		- Pointer to IBC client module linkage structure
    446  * Output:
    447  *	None
    448  * Returns:
    449  *	0 always for now
    450  * Called by:
    451  *	CI client calls IBTF during its _init() to register HCA with
    452  *	Solaris I/O framework.
    453  * Description:
    454  *	Initializes the CI clients module linkage structure with
    455  *	default bus_ops structure
    456  */
    457 int
    458 ibc_init(struct modlinkage *modlp)
    459 {
    460 	ibtl_ibnex_cb_args_t	cb_args;
    461 
    462 	mutex_enter(&ibtl_clnt_list_mutex);
    463 	cb_args.cb_flag = IBTL_IBNEX_IBC_INIT;
    464 	cb_args.cb_modlp = modlp;
    465 	if (ibtl_ibnex_callback_routine) {
    466 		(void) ((*ibtl_ibnex_callback_routine)(&cb_args));
    467 	}
    468 	mutex_exit(&ibtl_clnt_list_mutex);
    469 	return (0);
    470 }
    471 
    472 
    473 /*
    474  * Function:
    475  *	ibc_fini
    476  * Input:
    477  *	modlp		- Pointer to IBC client module linkage structure
    478  * Output:
    479  *	None
    480  * Returns:
    481  *	None
    482  * Called by:
    483  *	CI client calls IBTF during its _fini() to remove HCA with
    484  *	Solaris I/O framework.
    485  * Description:
    486  *	Undo what is done during ibc_init
    487  */
    488 void
    489 ibc_fini(struct modlinkage *modlp)
    490 {
    491 	ibtl_ibnex_cb_args_t	cb_args;
    492 
    493 	mutex_enter(&ibtl_clnt_list_mutex);
    494 	cb_args.cb_flag = IBTL_IBNEX_IBC_FINI;
    495 	cb_args.cb_modlp = modlp;
    496 	if (ibtl_ibnex_callback_routine) {
    497 		(void) ((*ibtl_ibnex_callback_routine)(&cb_args));
    498 	}
    499 	mutex_exit(&ibtl_clnt_list_mutex);
    500 }
    501 
    502 /*
    503  * Function:
    504  *	ibc_attach
    505  * Input:
    506  *	info_p		- IBC HCA Info.
    507  * Output:
    508  *	ibc_hdl_p	- IBC Client's HCA Handle.
    509  * Returns:
    510  *	IBC_SUCCESS
    511  *	IBC_FAILURE
    512  * Called by:
    513  *	CI calls IBTF during its attach() to register HCA Device with IBTF.
    514  * Description:
    515  *	Registers the presence of HCA device by providing the HCA device info
    516  *  	structure and provides an opaque HCA handler for future calls to this
    517  *  	HCA device.
    518  */
    519 ibc_status_t
    520 ibc_attach(ibc_clnt_hdl_t *ibc_hdl_p, ibc_hca_info_t *info_p)
    521 {
    522 	ibtl_hca_devinfo_t	*hca_devp;
    523 	uint_t			nports;
    524 	ibt_status_t		status;
    525 
    526 	IBTF_DPRINTF_L2(ibtf, "ibc_attach(%p, %p)", ibc_hdl_p, info_p);
    527 
    528 	/* Validate the Transport API version */
    529 	if (info_p->hca_ci_vers != IBCI_V3) {
    530 		IBTF_DPRINTF_L1(ibtf, "ibc_attach: Invalid IB CI Version '%d'",
    531 		    info_p->hca_ci_vers);
    532 		return (IBC_FAILURE);
    533 	}
    534 
    535 	if (info_p->hca_attr == NULL) {
    536 		IBTF_DPRINTF_L1(ibtf, "ibc_attach: "
    537 		    "HCA Attributes must be specified.");
    538 		return (IBC_FAILURE);
    539 	}
    540 
    541 	nports = info_p->hca_attr->hca_nports;
    542 	if (nports == 0) {
    543 		IBTF_DPRINTF_L1(ibtf, "ibc_attach: "
    544 		    "Number of ports must be valid");
    545 		return (IBC_FAILURE);
    546 	}
    547 
    548 	if (info_p->hca_attr->hca_max_port_pkey_tbl_sz == 0) {
    549 		IBTF_DPRINTF_L1(ibtf, "ibc_attach: "
    550 		    "Number of Partitions must be at least 1");
    551 		return (IBC_FAILURE);
    552 	}
    553 
    554 	if ((info_p->hca_attr->hca_flags & IBT_HCA_CURRENT_QP_STATE) == 0) {
    555 		IBTF_DPRINTF_L1(ibtf, "ibc_attach: "
    556 		    "HCA driver must support QP current state checking");
    557 		return (IBC_FAILURE);
    558 	}
    559 
    560 	if ((info_p->hca_attr->hca_flags & IBT_HCA_PORT_UP) == 0) {
    561 		IBTF_DPRINTF_L1(ibtf, "ibc_attach: "
    562 		    "HCA driver must support PORT_UP async events");
    563 		return (IBC_FAILURE);
    564 	}
    565 
    566 	/*
    567 	 * Install IB nexus driver (if not installed already)
    568 	 */
    569 	ibtl_set_ibhw_status();
    570 	if (ndi_devi_config_vhci("ib", 0) == NULL) {
    571 		IBTF_DPRINTF_L2(ibtf, "ibc_attach: IB nexus attach failed");
    572 		ibtl_clear_ibhw_status();
    573 		return (IBC_FAILURE);
    574 	}
    575 
    576 	ibtl_thread_init2();
    577 
    578 	/* Allocate the memory for per-client info structure */
    579 	hca_devp = kmem_zalloc(sizeof (ibtl_hca_devinfo_t) +
    580 	    (nports - 1) * sizeof (ibtl_async_port_event_t), KM_SLEEP);
    581 
    582 	mutex_enter(&ibtl_clnt_list_mutex);
    583 
    584 	/* Update HCA dev info structure */
    585 	hca_devp->hd_ibc_hca_hdl = info_p->hca_handle;
    586 	hca_devp->hd_ibc_ops	= info_p->hca_ops;
    587 	hca_devp->hd_hca_attr	= info_p->hca_attr;
    588 	hca_devp->hd_hca_dip	= info_p->hca_dip;
    589 
    590 	status = ibtl_init_hca_portinfo(hca_devp);
    591 	if (status != IBT_SUCCESS) {
    592 		mutex_exit(&ibtl_clnt_list_mutex);
    593 		IBTF_DPRINTF_L1(ibtf, "ibc_attach: call to ibc_query_hca_ports "
    594 		    "failed: status = %d", status);
    595 		kmem_free(hca_devp, sizeof (ibtl_hca_devinfo_t) +
    596 		    (nports - 1) * sizeof (ibtl_async_port_event_t));
    597 		return (IBC_FAILURE);
    598 	}
    599 
    600 	/* Register the with MPxIO as PHCI */
    601 	if (ibtl_ibnex_phci_register(info_p->hca_dip) != IBT_SUCCESS) {
    602 		mutex_exit(&ibtl_clnt_list_mutex);
    603 		IBTF_DPRINTF_L1(ibtf, "ibc_attach: MPxIO register failed");
    604 		kmem_free(hca_devp, sizeof (ibtl_hca_devinfo_t) +
    605 		    (nports - 1) * sizeof (ibtl_async_port_event_t));
    606 		return (IBC_FAILURE);
    607 	}
    608 
    609 	/* Initialize the Client List for this HCA. */
    610 	hca_devp->hd_state	= IBTL_HCA_DEV_ATTACHED;
    611 
    612 	/* lock out asyncs until after we announce the new HCA */
    613 	hca_devp->hd_async_busy = 1;
    614 
    615 	cv_init(&hca_devp->hd_async_task_cv, NULL, CV_DEFAULT, NULL);
    616 	cv_init(&hca_devp->hd_async_busy_cv, NULL, CV_DEFAULT, NULL);
    617 
    618 	/* init portinfo locking variables */
    619 	hca_devp->hd_portinfo_locked_port = 0;
    620 	cv_init(&hca_devp->hd_portinfo_cv, NULL, CV_DEFAULT, NULL);
    621 
    622 	ibtl_kstat_init(hca_devp);
    623 
    624 	mutex_exit(&ibtl_clnt_list_mutex);
    625 
    626 	/*
    627 	 * The ibc_hdl_p points to an opaque handle which is the address
    628 	 * of ibt_hca_devinfo_t structure passed back to the CI.
    629 	 * The CI will pass on this handle in its future upcalls to IBTF.
    630 	 */
    631 	*ibc_hdl_p = hca_devp;
    632 
    633 	return (IBC_SUCCESS);
    634 }
    635 
    636 
    637 /*
    638  * Function:
    639  *	ibc_post_attach
    640  * Input:
    641  *	ibc_hdl		- IBC Client's HCA Handle.
    642  * Returns:
    643  *	none
    644  * Called by:
    645  *	CI calls IBTF during its attach() after a successful ibc_attach().
    646  * Description:
    647  *	Announces to all known clients the existence of this HCA (by GUID).
    648  */
    649 void
    650 ibc_post_attach(ibc_clnt_hdl_t ibc_hdl)
    651 {
    652 	IBTF_DPRINTF_L2(ibtf, "ibc_post_attach(%p)", ibc_hdl);
    653 
    654 	/*
    655 	 * Update the HCA Device List.
    656 	 */
    657 	mutex_enter(&ibtl_clnt_list_mutex);
    658 	ibc_hdl->hd_hca_dev_link = ibtl_hca_list;
    659 	ibtl_hca_list = ibc_hdl;
    660 	mutex_exit(&ibtl_clnt_list_mutex);
    661 
    662 	/* notify all IBT Client Device Instances of the new HCA Device */
    663 	ibtl_announce_new_hca(ibc_hdl);
    664 }
    665 
    666 
    667 /*
    668  * Function:
    669  *	ibc_pre_detach
    670  * Input:
    671  *	ibc_clnt_hdl	- IBC HCA Handle as returned during ibc_attach call.
    672  *  	cmd		- DDI_DETACH/DDI_SUSPEND command.
    673  * Output:
    674  *	none
    675  * Returns:
    676  *	IBC_SUCCESS
    677  *	IBC_FAILURE.
    678  * Called by:
    679  *	CI to try to get all IBTF clients to close the HCA device.
    680  * Description:
    681  *	Attempts to deregister the HCA device entry from the IBTF.
    682  *	If all resources are freed by the IBTF clients and this HCA
    683  *	is closed, then IBC_SUCCESS is returned.
    684  */
    685 ibc_status_t
    686 ibc_pre_detach(ibc_clnt_hdl_t hca_devp, ddi_detach_cmd_t cmd)
    687 {
    688 	ibtl_hca_devinfo_t **hcapp, *hcap;
    689 
    690 	IBTF_DPRINTF_L2(ibtf, "ibc_pre_detach(%p, 0x%x)", hca_devp, cmd);
    691 
    692 	/*
    693 	 * Return failure, if command is not DDI_DETACH
    694 	 */
    695 	switch (cmd) {
    696 	case DDI_DETACH:
    697 		break;
    698 	default:
    699 		return (IBC_FAILURE); /* TBD: DDI_FAILURE */
    700 	}
    701 
    702 	/* Make sure this HCA is on the HCA Device List.  */
    703 	mutex_enter(&ibtl_clnt_list_mutex);
    704 	hcap = ibtl_hca_list;
    705 	while (hcap != NULL) {
    706 		if (hcap == hca_devp)
    707 			break;
    708 		hcap = hcap->hd_hca_dev_link;
    709 	}
    710 	if (hcap == NULL) {
    711 		mutex_exit(&ibtl_clnt_list_mutex);
    712 		return (IBC_FAILURE);
    713 	}
    714 
    715 	/*
    716 	 * Initially set the state to "Detaching".
    717 	 */
    718 	hca_devp->hd_state = IBTL_HCA_DEV_DETACHING;
    719 
    720 	/*
    721 	 * Try to detach all IBTI clients, and continue only if all
    722 	 * of the detaches succeed.
    723 	 */
    724 	if (ibtl_detach_all_clients(hca_devp)) {
    725 		hca_devp->hd_state = IBTL_HCA_DEV_ATTACHED; /* fix hd_state */
    726 		mutex_exit(&ibtl_clnt_list_mutex);
    727 
    728 		return (IBC_FAILURE);
    729 	}
    730 
    731 	/*
    732 	 * Check to see if all clients closed this HCA, or not.
    733 	 * We only succeed if all clients cooperated.
    734 	 */
    735 	if (hca_devp->hd_clnt_list != NULL) {
    736 		hca_devp->hd_state = IBTL_HCA_DEV_ATTACHED;
    737 		mutex_exit(&ibtl_clnt_list_mutex);
    738 		IBTF_DPRINTF_L2(ibtf, "ibc_pre_detach: HCA still has attached "
    739 		    "clients");
    740 		return (IBC_FAILURE);
    741 	}
    742 
    743 	/*
    744 	 * mark this device as detached
    745 	 */
    746 	hca_devp->hd_state = IBTL_HCA_DEV_DETACHED;
    747 
    748 	/* Delete the entry for this hca_devp from hca_head_list */
    749 	hcapp = &ibtl_hca_list;
    750 	while (*hcapp != NULL) {
    751 		if (*hcapp == hca_devp)
    752 			break;
    753 		hcapp = &(*hcapp)->hd_hca_dev_link;
    754 	}
    755 
    756 	if (ibtl_ibnex_phci_unregister(hca_devp->hd_hca_dip) != IBT_SUCCESS) {
    757 		hca_devp->hd_state = IBTL_HCA_DEV_ATTACHED; /* fix hd_state */
    758 		mutex_exit(&ibtl_clnt_list_mutex);
    759 		IBTF_DPRINTF_L1(ibtf, "ibc_pre_detach: PHCI unregister failed");
    760 		return (IBC_FAILURE);
    761 	}
    762 
    763 	if (*hcapp == NULL) {
    764 		hca_devp->hd_state = IBTL_HCA_DEV_ATTACHED; /* fix hd_state */
    765 		mutex_exit(&ibtl_clnt_list_mutex);
    766 		IBTF_DPRINTF_L1(ibtf, "ibc_pre_detach: HCA not attached");
    767 		return (IBC_FAILURE);
    768 	}
    769 	*hcapp = hca_devp->hd_hca_dev_link;
    770 	ibtl_fast_gid_cache_valid = B_FALSE;	/* invalidate fast_gid_cache */
    771 	mutex_exit(&ibtl_clnt_list_mutex);
    772 
    773 	return (IBC_SUCCESS);
    774 }
    775 
    776 /*
    777  * Function:
    778  *	ibc_detach
    779  * Input:
    780  *	ibc_clnt_hdl	- IBC HCA Handle as returned during ibc_attach call.
    781  * Output:
    782  *	none
    783  * Returns:
    784  *	None
    785  * Called by:
    786  *	CI to detach the HCA device from IBTF.
    787  * Description:
    788  *	Do the second step of detaching the HCA, which is required
    789  *	after a successful ibc_pre_detach.
    790  */
    791 void
    792 ibc_detach(ibc_clnt_hdl_t hca_devp)
    793 {
    794 	IBTF_DPRINTF_L2(ibtf, "ibc_detach(%p)", hca_devp);
    795 
    796 	mutex_enter(&ibtl_clnt_list_mutex);
    797 	if (hca_devp->hd_state != IBTL_HCA_DEV_DETACHED) {
    798 		mutex_exit(&ibtl_clnt_list_mutex);
    799 		IBTF_DPRINTF_L0(ibtf, "ibc_detach: HCA has not successfully "
    800 		    "pre-detached");
    801 		return;
    802 	}
    803 
    804 	cv_destroy(&hca_devp->hd_async_task_cv);
    805 	cv_destroy(&hca_devp->hd_async_busy_cv);
    806 	cv_destroy(&hca_devp->hd_portinfo_cv);
    807 
    808 	kmem_free(hca_devp->hd_portinfop, hca_devp->hd_portinfo_len);
    809 	mutex_exit(&ibtl_clnt_list_mutex);
    810 
    811 	ibtl_kstat_fini(hca_devp);
    812 
    813 	/* Free up the memory of per-client info struct */
    814 	kmem_free(hca_devp, sizeof (ibtl_hca_devinfo_t) +
    815 	    (hca_devp->hd_hca_attr->hca_nports - 1) *
    816 	    sizeof (ibtl_async_port_event_t));
    817 	ibtl_clear_ibhw_status();
    818 }
    819 
    820 /*
    821  * Function:
    822  *	ibt_ci_data_in()
    823  *
    824  * Input:
    825  *	hca_hdl			HCA Handle.
    826  *	flags			IBT_COMPLETE_ALLOC - Finish a deferred alloc.
    827  *      object                  Identifies the type object pointed to by
    828  *                              ibt_object_handle.
    829  *
    830  *      ibt_object_handle       The handle of the object to be associated with
    831  *				the data in/out
    832  *
    833  *	data_p			Pointer data passed in to the CI. The buffer
    834  *				should be allocated by the caller.
    835  *
    836  *	data_sz			The size of the buffer pointed to by
    837  *				data_p.
    838  * Output:
    839  *
    840  * Returns:
    841  *	IBT_SUCCESS
    842  *	IBT_NOT_SUPPORTED	Feature not supported.
    843  *	IBT_INVALID_PARAM	Invalid object type specified.
    844  *	IBT_HCA_HDL_INVALID
    845  *	IBT_AH_HDL_INVALID/IBT_UD_DEST_HDL_INVALID
    846  *	IBT_CHAN_HDL_INVALID/IBT_QP_HDL_INVALID
    847  *	IBT_CQ_HDL_INVALID
    848  *	IBT_EEC_HDL_INVALID
    849  *	IBT_RDD_HDL_INVALID
    850  *	IBT_MW_HDL_INVALID
    851  *	IBT_PD_HDL_INVALID
    852  *	IBT_SRQ_HDL_INVALID
    853  *
    854  * Description:
    855  *	Exchange CI private data for the specified CI object.
    856  */
    857 ibt_status_t
    858 ibt_ci_data_in(ibt_hca_hdl_t hca, ibt_ci_data_flags_t flags,
    859     ibt_object_type_t object, void *ibt_object_handle, void *data_p,
    860     size_t data_sz)
    861 {
    862 	ibt_status_t		retval;
    863 	void			*ci_obj_hdl;
    864 
    865 	IBTF_DPRINTF_L3(ibtf, "ibt_ci_data_in(%p, %x, %d, %p, %p, %d)",
    866 	    hca, flags, object, ibt_object_handle, data_p, data_sz);
    867 
    868 	switch (object) {
    869 	case IBT_HDL_HCA:
    870 		ci_obj_hdl = (void *)
    871 		    (IBTL_HCA2CIHCA(((ibt_hca_hdl_t)ibt_object_handle)));
    872 		break;
    873 
    874 	case IBT_HDL_CHANNEL:
    875 		ci_obj_hdl = (void *)
    876 		    (IBTL_CHAN2CIQP(((ibt_channel_hdl_t)ibt_object_handle)));
    877 		break;
    878 
    879 	case IBT_HDL_CQ:
    880 		ci_obj_hdl = (void *)
    881 		    (((ibt_cq_hdl_t)(ibt_object_handle))->cq_ibc_cq_hdl);
    882 		break;
    883 
    884 	case IBT_HDL_EEC:
    885 		ci_obj_hdl = (void *)
    886 		    (((ibt_eec_hdl_t)(ibt_object_handle))->eec_ibc_eec_hdl);
    887 		break;
    888 
    889 	case IBT_HDL_UD_DEST:
    890 		ci_obj_hdl = (void *)
    891 		    (((ibt_ud_dest_hdl_t)(ibt_object_handle))->ud_ah);
    892 		break;
    893 
    894 	case IBT_HDL_SRQ:
    895 		ci_obj_hdl = (void *)
    896 		    (((ibt_srq_hdl_t)(ibt_object_handle))->srq_ibc_srq_hdl);
    897 		break;
    898 
    899 	default:
    900 		ci_obj_hdl = ibt_object_handle;
    901 		break;
    902 	}
    903 
    904 	retval = (IBTL_HCA2CIHCAOPS_P(hca)->ibc_ci_data_in)(IBTL_HCA2CIHCA(hca),
    905 	    flags, object, ci_obj_hdl, data_p, data_sz);
    906 
    907 	if (retval != IBT_SUCCESS) {
    908 		IBTF_DPRINTF_L2(ibtf, "ibt_ci_data_in: Failed : %d", retval);
    909 	}
    910 	return (retval);
    911 }
    912 
    913 /*
    914  * Function:
    915  *	ibt_ci_data_out()
    916  *
    917  * Input:
    918  *	hca_hdl			HCA Handle.
    919  *	flags			IBT_COMPLETE_ALLOC - Finish a deferred alloc.
    920  *      object                  Identifies the type object pointed to by
    921  *                              ibt_object_handle.
    922  *
    923  *      ibt_object_handle       The handle of the object to be associated with
    924  *				the data in/out
    925  *
    926  *	data_p			Pointer to a buffer in which to return the CI
    927  *				private data. The buffer should be allocated
    928  *				by the caller.
    929  *
    930  *	data_sz			The size of the buffer pointed to by
    931  *				data_p.
    932  * Output:
    933  *
    934  * Returns:
    935  *	IBT_SUCCESS
    936  *	IBT_NOT_SUPPORTED	Feature not supported.
    937  *	IBT_INSUFF_RESOURCE	The buffer pointed to by data_p was too
    938  *				small to hold the data.
    939  *	IBT_INVALID_PARAM	Invalid object type specified.
    940  *	IBT_HCA_HDL_INVALID
    941  *	IBT_AH_HDL_INVALID/IBT_UD_DEST_HDL_INVALID
    942  *	IBT_CHAN_HDL_INVALID/IBT_QP_HDL_INVALID
    943  *	IBT_CQ_HDL_INVALID
    944  *	IBT_EEC_HDL_INVALID
    945  *	IBT_RDD_HDL_INVALID
    946  *	IBT_MW_HDL_INVALID
    947  *	IBT_PD_HDL_INVALID
    948  *	IBT_SRQ_HDL_INVALID
    949  *
    950  * Description:
    951  *	Exchange CI private data for the specified CI object.
    952  */
    953 ibt_status_t
    954 ibt_ci_data_out(ibt_hca_hdl_t hca, ibt_ci_data_flags_t flags,
    955     ibt_object_type_t object, void *ibt_object_handle, void *data_p,
    956     size_t data_sz)
    957 {
    958 	ibt_status_t		retval;
    959 	void			*ci_obj_hdl;
    960 
    961 	IBTF_DPRINTF_L3(ibtf, "ibt_ci_data_out(%p, %x, %d, %p, %p, %d)",
    962 	    hca, flags, object, ibt_object_handle, data_p, data_sz);
    963 
    964 	switch (object) {
    965 	case  IBT_HDL_HCA:
    966 		ci_obj_hdl = (void *)
    967 		    (IBTL_HCA2CIHCA(((ibt_hca_hdl_t)ibt_object_handle)));
    968 		break;
    969 
    970 	case IBT_HDL_CHANNEL:
    971 		ci_obj_hdl = (void *)
    972 		    (IBTL_CHAN2CIQP(((ibt_channel_hdl_t)ibt_object_handle)));
    973 		break;
    974 
    975 	case IBT_HDL_CQ:
    976 		ci_obj_hdl = (void *)
    977 		    (((ibt_cq_hdl_t)(ibt_object_handle))->cq_ibc_cq_hdl);
    978 		break;
    979 
    980 	case IBT_HDL_EEC:
    981 		ci_obj_hdl = (void *)
    982 		    (((ibt_eec_hdl_t)(ibt_object_handle))->eec_ibc_eec_hdl);
    983 		break;
    984 
    985 	case IBT_HDL_UD_DEST:
    986 		ci_obj_hdl = (void *)
    987 		    (((ibt_ud_dest_hdl_t)(ibt_object_handle))->ud_ah);
    988 		break;
    989 
    990 	case IBT_HDL_SRQ:
    991 		ci_obj_hdl = (void *)
    992 		    (((ibt_srq_hdl_t)(ibt_object_handle))->srq_ibc_srq_hdl);
    993 		break;
    994 
    995 	default:
    996 		ci_obj_hdl = ibt_object_handle;
    997 		break;
    998 	}
    999 
   1000 	retval = (IBTL_HCA2CIHCAOPS_P(hca)->ibc_ci_data_out)
   1001 	    (IBTL_HCA2CIHCA(hca), flags, object, ci_obj_hdl, data_p, data_sz);
   1002 
   1003 	if (retval != IBT_SUCCESS) {
   1004 		IBTF_DPRINTF_L2(ibtf, "ibt_ci_data_out: Failed : %d", retval);
   1005 	}
   1006 	return (retval);
   1007 }
   1008 
   1009 
   1010 /*
   1011  * FMA Support functions.
   1012  */
   1013 
   1014 #define	IBTL_ENA_MASK		0xC0000000
   1015 #define	IBTL_ENA_POSSIBLE	0x80000000
   1016 #define	IBTL_TYPE_SHIFT		27
   1017 
   1018 /*
   1019  * Function:
   1020  *	ibt_get_module_failure()
   1021  *
   1022  * Input:
   1023  *	type			Identifies the failing IB module.
   1024  *	ena			'0' or the data for Fault Management
   1025  *				Architecture (ENA).
   1026  *
   1027  * Returns:
   1028  *	status			Special IB failure status.
   1029  *
   1030  * Description:
   1031  *	XXX Just stubbed out to return failures with no data for Fault
   1032  *	Management Architecture (ENAs) at the moment XXX
   1033  */
   1034 ibt_status_t
   1035 ibt_get_module_failure(ibt_failure_type_t type, uint64_t ena)
   1036 {
   1037 	ibt_status_t	ret;
   1038 
   1039 	IBTF_DPRINTF_L3(ibtf, "ibt_get_module_failure(%d, 0x%llX)", type, ena);
   1040 
   1041 	switch (type) {
   1042 	case IBT_FAILURE_CI:
   1043 	case IBT_FAILURE_IBMF:
   1044 	case IBT_FAILURE_IBCM:
   1045 	case IBT_FAILURE_IBDM:
   1046 	case IBT_FAILURE_IBTL:
   1047 	case IBT_FAILURE_IBSM:
   1048 		ret = IBTL_ENA_POSSIBLE | (type << IBTL_TYPE_SHIFT);
   1049 		break;
   1050 	default:
   1051 		ret = IBT_FAILURE;
   1052 	}
   1053 	IBTF_DPRINTF_L3(ibtf, "ibt_get_module_failure: ret = 0x%lX", ret);
   1054 	return (ret);
   1055 }
   1056 
   1057 
   1058 /*
   1059  * Function:
   1060  *	ibc_get_ci_failure()
   1061  *
   1062  * Input:
   1063  *	ena			'0' or the data for Fault Management
   1064  *				Architecture (ENA).
   1065  *
   1066  * Returns:
   1067  *	status			Special CI failure status.
   1068  *
   1069  * Description:
   1070  *	Just use the function above to do the job.
   1071  */
   1072 ibt_status_t
   1073 ibc_get_ci_failure(uint64_t ena)
   1074 {
   1075 	return (ibt_get_module_failure(IBT_FAILURE_CI, ena));
   1076 }
   1077 
   1078 
   1079 /*
   1080  * ibt_check_failure()
   1081  *	Function to test for special case failures.
   1082  *
   1083  *	status		An ibt_status_t returned from an IBTF function call.
   1084  *
   1085  *	reserved_p	NULL, or a pointer to where we store the data for
   1086  *			Fault Management Architecture (ENA).
   1087  *
   1088  * Description:
   1089  *	XXX Still need to determine the data for Fault Management Architecture
   1090  *	(ENA), using 0 for now XXX
   1091  */
   1092 ibt_failure_type_t
   1093 ibt_check_failure(ibt_status_t status, uint64_t *reserved_p)
   1094 {
   1095 	ibt_failure_type_t type;
   1096 
   1097 	IBTF_DPRINTF_L3(ibtf, "ibt_check_failure(%X)", status);
   1098 
   1099 	if ((status & IBTL_ENA_MASK) == IBTL_ENA_POSSIBLE) {
   1100 		type = status & ~IBTL_ENA_POSSIBLE >> IBTL_TYPE_SHIFT;
   1101 
   1102 		/* XXX Need more work here... */
   1103 		if (reserved_p != NULL)
   1104 			*reserved_p = 0;
   1105 	} else {
   1106 		type = IBT_FAILURE_STANDARD;
   1107 		if (reserved_p != NULL)
   1108 			*reserved_p = 0;	/* No FMA Data Available. */
   1109 	}
   1110 	IBTF_DPRINTF_L3(ibtf, "ibt_check_failure: type = 0x%X", type);
   1111 	return (type);
   1112 }
   1113 
   1114 /*
   1115  * Initialize and create kstats.
   1116  *
   1117  * We create the following kstats on all ports of the HCA:
   1118  *	<hca_driver_name><instance_number>/port<port_num>/stats
   1119  *	<hca_driver_name><instance_number>/port<port_num>/pkeys
   1120  */
   1121 static void
   1122 ibtl_kstat_init(ibtl_hca_devinfo_t *hca_devp)
   1123 {
   1124 	uint_t			nports = hca_devp->hd_hca_attr->hca_nports;
   1125 	ibtl_hca_port_kstat_t	*pks;
   1126 	int			i;
   1127 
   1128 	IBTF_DPRINTF_L3(ibtf, "ibtl_kstat_init(hca_devp = 0x%p)", hca_devp);
   1129 
   1130 	hca_devp->hd_hca_port_ks_info_len =
   1131 	    sizeof (ibtl_hca_port_kstat_t) * nports;
   1132 	pks = kmem_zalloc(hca_devp->hd_hca_port_ks_info_len, KM_SLEEP);
   1133 	hca_devp->hd_hca_port_ks_info = pks;
   1134 
   1135 	for (i = 0; i < nports; i++, pks++) {
   1136 		pks->pks_hca_devp = hca_devp;
   1137 		pks->pks_port_num = i + 1;
   1138 		ibtl_kstat_stats_create(hca_devp, i + 1);
   1139 		ibtl_kstat_pkeys_create(hca_devp, i + 1);
   1140 	}
   1141 }
   1142 
   1143 /*
   1144  * Delete kstats on all ports of the HCA.
   1145  */
   1146 static void
   1147 ibtl_kstat_fini(ibtl_hca_devinfo_t *hca_devp)
   1148 {
   1149 	ibtl_hca_port_kstat_t	*pks;
   1150 	int			i;
   1151 
   1152 	IBTF_DPRINTF_L3(ibtf, "ibtl_kstat_fini(hca_devp = 0x%p)", hca_devp);
   1153 
   1154 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*hca_devp))
   1155 
   1156 	pks = hca_devp->hd_hca_port_ks_info;
   1157 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*pks))
   1158 
   1159 	if (pks == NULL)
   1160 		return;
   1161 
   1162 	for (i = 0; i < hca_devp->hd_hca_attr->hca_nports; i++, pks++) {
   1163 		if (pks->pks_stats_ksp)
   1164 			kstat_delete(pks->pks_stats_ksp);
   1165 
   1166 		if (pks->pks_pkeys_ksp) {
   1167 			ASSERT(!MUTEX_HELD(&ibtl_clnt_list_mutex));
   1168 			kstat_delete(pks->pks_pkeys_ksp);
   1169 		}
   1170 	}
   1171 
   1172 	kmem_free(hca_devp->hd_hca_port_ks_info,
   1173 	    hca_devp->hd_hca_port_ks_info_len);
   1174 }
   1175 
   1176 /*
   1177  * Update "stats" kstat.
   1178  * Called by kstat framework.
   1179  */
   1180 static int
   1181 ibtl_kstat_stats_update(kstat_t *ksp, int rw)
   1182 {
   1183 	ibtl_hca_port_kstat_t	*pks;
   1184 	ibtl_hca_devinfo_t	*hca_devp;
   1185 	ibt_hca_portinfo_t	*p;
   1186 	struct kstat_named	*data;
   1187 
   1188 	IBTF_DPRINTF_L4(ibtf, "ibtl_kstat_stats_update(ksp = 0x%p, rw = %d)",
   1189 	    ksp, rw);
   1190 
   1191 	if (rw == KSTAT_WRITE)
   1192 		return (EACCES);
   1193 
   1194 	mutex_enter(&ibtl_clnt_list_mutex);
   1195 
   1196 	/*
   1197 	 * Update the link_state kstat using the value from portinfo cache.
   1198 	 */
   1199 	pks = ksp->ks_private;
   1200 	hca_devp = pks->pks_hca_devp;
   1201 	data = (struct kstat_named *)(ksp->ks_data);
   1202 	p = hca_devp->hd_portinfop + pks->pks_port_num - 1;
   1203 	data[0].value.ui32 = (uint32_t)p->p_linkstate;
   1204 
   1205 	mutex_exit(&ibtl_clnt_list_mutex);
   1206 
   1207 	return (0);
   1208 }
   1209 
   1210 /*
   1211  * Create "stats" kstat for the specified HCA port in the form:
   1212  *	<hca_driver_name><instance_number>/port<port_num>/stats
   1213  *	At preset it contains only one named data of "link_state"
   1214  */
   1215 static void
   1216 ibtl_kstat_stats_create(ibtl_hca_devinfo_t *hca_devp, uint_t port_num)
   1217 {
   1218 	struct kstat		*ksp;
   1219 	struct kstat_named	*named_data;
   1220 	char			*drv_name;
   1221 	int			drv_instance;
   1222 	ibtl_hca_port_kstat_t	*pks;
   1223 	char			kname[40];
   1224 
   1225 	IBTF_DPRINTF_L3(ibtf, "ibtl_kstat_stats_create(hca_devp = 0x%p, "
   1226 	    "port_num = 0x%u)", hca_devp, port_num);
   1227 
   1228 	drv_name = (char *)ddi_driver_name(hca_devp->hd_hca_dip);
   1229 	drv_instance = ddi_get_instance(hca_devp->hd_hca_dip);
   1230 	(void) snprintf(kname, sizeof (kname), "%s%d/port%d/stats",
   1231 	    drv_name, drv_instance, port_num);
   1232 
   1233 	ksp = kstat_create("ibtf", 0, kname, "ib", KSTAT_TYPE_NAMED, 1, 0);
   1234 	if (ksp == NULL) {
   1235 		IBTF_DPRINTF_L2(ibtf,
   1236 		    "ibtl_kstat_stats_create: kstat_create() failed");
   1237 		return;
   1238 	}
   1239 
   1240 	named_data = (struct kstat_named *)(ksp->ks_data);
   1241 	kstat_named_init(&named_data[0], "link_state", KSTAT_DATA_UINT32);
   1242 
   1243 	pks = hca_devp->hd_hca_port_ks_info + port_num - 1;
   1244 	pks->pks_stats_ksp = ksp;
   1245 
   1246 	ksp->ks_private = pks;
   1247 	ksp->ks_update = ibtl_kstat_stats_update;
   1248 
   1249 	/* Install the kstat */
   1250 	kstat_install(ksp);
   1251 }
   1252 
   1253 /*
   1254  * Update "pkeys" kstat.
   1255  *
   1256  * Called by kstat framework. Since ks_lock was set to ibtl_clnt_list_mutex
   1257  * at the time of the kstat creation, kstat framework will hold this lock
   1258  * while calling this function.
   1259  */
   1260 static int
   1261 ibtl_kstat_pkeys_update(kstat_t *ksp, int rw)
   1262 {
   1263 	ibtl_hca_port_kstat_t	*pks;
   1264 	ibtl_hca_devinfo_t	*hca_devp;
   1265 	ibt_hca_portinfo_t	*p;
   1266 
   1267 	IBTF_DPRINTF_L4(ibtf, "ibtl_kstat_pkeys_update(ksp = 0x%p, rw = %d)",
   1268 	    ksp, rw);
   1269 
   1270 #ifndef	__lock_lint
   1271 	ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
   1272 #endif
   1273 
   1274 	if (rw == KSTAT_WRITE)
   1275 		return (EACCES);
   1276 
   1277 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ksp))
   1278 
   1279 	pks = ksp->ks_private;
   1280 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*pks))
   1281 
   1282 	hca_devp = pks->pks_hca_devp;
   1283 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*hca_devp))
   1284 
   1285 	/*
   1286 	 * Point kstat data to the pkey table in the portinfo cache.
   1287 	 */
   1288 
   1289 	p = hca_devp->hd_portinfop + pks->pks_port_num - 1;
   1290 
   1291 	ksp->ks_data = p->p_pkey_tbl;
   1292 	ksp->ks_ndata = p->p_pkey_tbl_sz;
   1293 	ksp->ks_data_size = p->p_pkey_tbl_sz * sizeof (ib_pkey_t);
   1294 
   1295 	return (0);
   1296 }
   1297 
   1298 /*
   1299  * Create "pkeys" kstat for the specified HCA port in the form:
   1300  *	<hca_driver_name><instance_number>/port<port_num>/pkeys
   1301  *
   1302  * Currently kstat framework allows only some fixed data types as named
   1303  * data components under a named kstat. Due to this limitation it is not
   1304  * possible to add "pkeys" as a named data under the "stats" kstat.
   1305  */
   1306 static void
   1307 ibtl_kstat_pkeys_create(ibtl_hca_devinfo_t *hca_devp, uint_t port_num)
   1308 {
   1309 	struct kstat		*ksp;
   1310 	char			*drv_name;
   1311 	int			drv_instance;
   1312 	char			kname[40];
   1313 	ibtl_hca_port_kstat_t	*pks;
   1314 
   1315 	IBTF_DPRINTF_L3(ibtf, "ibtl_kstat_stats_create(hca_devp = 0x%p, "
   1316 	    "port_num = 0x%u)", hca_devp, port_num);
   1317 
   1318 	drv_name = (char *)ddi_driver_name(hca_devp->hd_hca_dip);
   1319 	drv_instance = ddi_get_instance(hca_devp->hd_hca_dip);
   1320 	(void) snprintf(kname, sizeof (kname), "%s%d/port%d/pkeys",
   1321 	    drv_name, drv_instance, port_num);
   1322 
   1323 	ksp = kstat_create("ibtf", 0, kname, "ib", KSTAT_TYPE_RAW, 0,
   1324 	    KSTAT_FLAG_VAR_SIZE | KSTAT_FLAG_VIRTUAL);
   1325 	if (ksp == NULL) {
   1326 		IBTF_DPRINTF_L2(ibtf,
   1327 		    "ibtl_kstat_pkeys_create: kstat_create() failed");
   1328 		return;
   1329 	}
   1330 
   1331 	pks = hca_devp->hd_hca_port_ks_info + port_num - 1;
   1332 	pks->pks_pkeys_ksp = ksp;
   1333 
   1334 	ksp->ks_private = pks;
   1335 	ksp->ks_update = ibtl_kstat_pkeys_update;
   1336 	ksp->ks_lock = &ibtl_clnt_list_mutex;
   1337 
   1338 	/*
   1339 	 * We just go with the default_kstat_snapshot().
   1340 	 * So there is no need to set ks_snapshot field.
   1341 	 */
   1342 
   1343 	/* Install the kstat */
   1344 	kstat_install(ksp);
   1345 }
   1346