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