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 }