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