Print this page
    
8368 remove warlock leftovers from usr/src/uts
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/io/ib/ibtl/ibtl_hca.c
          +++ new/usr/src/uts/common/io/ib/ibtl/ibtl_hca.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   */
  24   24  
  25   25  /*
  26   26   * ibtl_hca.c
  27   27   *
  28   28   * This file contains Transport API functions related to
  29   29   * Host Channel Adapter (HCA) Verbs.
  30   30   */
  31   31  
  32   32  #include <sys/ib/ibtl/impl/ibtl.h>
  33   33  
  34   34  static char ibtf_hca[] = "ibtl_hca";
  35   35  
  36   36  /* Prototype declarations. */
  37   37  static ibt_status_t ibtl_query_hca_ports(ibtl_hca_devinfo_t *hca_devp,
  38   38      uint8_t port, ibt_hca_portinfo_t **port_info_p, uint_t *ports_p,
  39   39      uint_t *size_p, int use_cache);
  40   40  
  41   41  /*
  42   42   * Function:
  43   43   *      ibt_open_hca
  44   44   * Input:
  45   45   *      ibt_hdl    - IBT Client Handle
  46   46   *      hca_guid   - HCA's node GUID.
  47   47   * Output:
  48   48   *      hca_hdl_p  - IBT HCA Handle.
  49   49   * Returns:
  50   50   *      IBT_SUCCESS
  51   51   *      IBT_HCA_IN_USE
  52   52   *      IBT_HCA_INVALID
  53   53   * Description:
  54   54   *      Open a HCA. HCA can only be opened/closed once. This routine allocates
  55   55   *      and returns a unique IBT Client HCA handle. Clients passes this
  56   56   *      handle on its subsequent references to this device. Once opened by a
  57   57   *      client, a specific HCA cannot be opened again until after it is closed.
  58   58   *      The IBT_HCA_IN_USE error is returned if client tries to open multiple
  59   59   *      times. In this case, previously allocated IBT HCA handle is returned to
  60   60   *      the client. Opening the HCA prepares the HCA for use by the client.
  61   61   */
  62   62  ibt_status_t
  63   63  ibt_open_hca(ibt_clnt_hdl_t ibt_hdl, ib_guid_t hca_guid,
  64   64      ibt_hca_hdl_t *hca_hdl_p)
  65   65  {
  66   66          ibtl_hca_t              *hca_infop;
  67   67          ibtl_hca_devinfo_t      *hca_devp;              /* HCA Dev Info */
  68   68  
  69   69          IBTF_DPRINTF_L3(ibtf_hca, "ibt_open_hca(%p, %llX)", ibt_hdl, hca_guid);
  70   70  
  71   71  
  72   72          /*
  73   73           * Get HCA Device Info Structure, referenced by HCA GUID.
  74   74           */
  75   75          mutex_enter(&ibtl_clnt_list_mutex);
  76   76          hca_devp = ibtl_get_hcadevinfo(hca_guid);
  77   77          if (hca_devp == NULL) {
  78   78                  /*
  79   79                   * If we are here, then the requested HCA device is not present.
  80   80                   * Return the status as Invalid HCA GUID.
  81   81                   */
  82   82                  mutex_exit(&ibtl_clnt_list_mutex);
  83   83  
  84   84                  IBTF_DPRINTF_L2(ibtf_hca, "ibt_open_hca: "
  85   85                      "HCA Device Not Found: Invalid HCA GUID");
  86   86  
  87   87                  *hca_hdl_p = NULL;
  88   88                  return (IBT_HCA_INVALID);
  89   89          }
  90   90  
  91   91          /*
  92   92           * Check whether open is allowed for this dip
  93   93           */
  94   94          if (ibt_hdl->clnt_dip) {
  95   95                  if (ddi_get_parent(ibt_hdl->clnt_dip) == hca_devp->hd_hca_dip) {
  96   96                          if (hca_guid != hca_devp->hd_hca_attr->hca_node_guid) {
  97   97                                  mutex_exit(&ibtl_clnt_list_mutex);
  98   98                                  return (IBT_FAILURE);
  99   99                          }
 100  100                  }
 101  101          }
 102  102  
 103  103          if (hca_devp->hd_state != IBTL_HCA_DEV_ATTACHED) {
 104  104                  /*
 105  105                   * If we are here, then the requested HCA device has detached,
 106  106                   * or is in the process of detaching.
 107  107                   */
 108  108                  mutex_exit(&ibtl_clnt_list_mutex);
 109  109  
 110  110                  IBTF_DPRINTF_L2(ibtf_hca, "ibt_open_hca: "
 111  111                      "HCA is busy trying to detach");
 112  112  
 113  113                  *hca_hdl_p = NULL;
 114  114                  return (IBT_HCA_BUSY_DETACHING);
 115  115          }
 116  116  
 117  117          /*
 118  118           * Yes, we found a HCA Device registered with IBTF, which matches with
 119  119           * the requested HCA_GUID.
 120  120           *
 121  121           * Check out whether this client has already opened this HCA device,
 122  122           * if yes return the status as IBT_HCA_IN_USE.
 123  123           */
 124  124          hca_infop = hca_devp->hd_clnt_list;
 125  125  
 126  126          while (hca_infop != NULL) {
 127  127                  if (ibt_hdl == hca_infop->ha_clnt_devp) {
 128  128                          IBTF_DPRINTF_L3(ibtf_hca,
 129  129                              "ibt_open_hca: Already Open");
 130  130  
 131  131                          if (hca_infop->ha_flags & IBTL_HA_CLOSING) {
 132  132                                  mutex_exit(&ibtl_clnt_list_mutex);
 133  133                                  *hca_hdl_p = NULL;
 134  134                                  return (IBT_HCA_BUSY_CLOSING);
 135  135                          }
 136  136                          mutex_exit(&ibtl_clnt_list_mutex);
 137  137  
 138  138                          /* Already Opened. Return back old HCA Handle. */
 139  139                          *hca_hdl_p = hca_infop;
 140  140  
 141  141                          return (IBT_HCA_IN_USE);
 142  142                  }
 143  143                  hca_infop = hca_infop->ha_clnt_link;
 144  144          }
 145  145  
 146  146          /* Create a new HCA Info entity. */
 147  147          hca_infop = kmem_zalloc(sizeof (ibtl_hca_t), KM_SLEEP);
 148  148  
 149  149          /* Update the HCA Info entity */
 150  150          hca_infop->ha_hca_devp  = hca_devp;     /* HCA Device Info */
 151  151          hca_infop->ha_clnt_devp = ibt_hdl;      /* Client Info */
 152  152  
 153  153          /* Update the HCA List, to keep track about the clients using it. */
 154  154          hca_infop->ha_clnt_link = hca_devp->hd_clnt_list;
 155  155          hca_devp->hd_clnt_list = hca_infop;
 156  156  
 157  157  
 158  158          /* Update the client's list to depict that it uses this HCA device. */
 159  159          hca_infop->ha_hca_link = ibt_hdl->clnt_hca_list;
 160  160          ibt_hdl->clnt_hca_list = hca_infop;
 161  161  
 162  162          mutex_exit(&ibtl_clnt_list_mutex);
 163  163  
 164  164          /*
 165  165           * Return back the address of ibtl_hca_t structure as an opaque
 166  166           * IBT HCA handle for the clients, to be used in future calls.
 167  167           */
 168  168          *hca_hdl_p = hca_infop;
 169  169  
 170  170          return (IBT_SUCCESS);
 171  171  }
 172  172  
 173  173  static char *ibtl_close_error_fmt = "IBT CLOSE HCA failed: %d '%s' "
 174  174          "resources not yet freed by client '%s'\n";
 175  175  
 176  176  #define IBTL_CLOSE_RESOURCE_CHECK(counter, resource_type) \
 177  177          if ((cntr = atomic_add_32_nv(&(counter), 0)) != 0) {            \
 178  178                  cmn_err(CE_CONT, ibtl_close_error_fmt,                  \
 179  179                      cntr, resource_type,                                \
 180  180                      hca_hdl->ha_clnt_devp->clnt_modinfop->mi_clnt_name); \
 181  181          }                                                               \
 182  182          error |= cntr
 183  183  
 184  184  /*
 185  185   * Function:
 186  186   *      ibt_close_hca
 187  187   * Input:
 188  188   *      hca_hdl  - The HCA handle as returned during its open.
 189  189   * Output:
 190  190   *      none
 191  191   * Returns:
 192  192   *      IBT_SUCCESS
 193  193   *      IBT_HCA_HDL_INVALID
 194  194   *      IBT_HCA_RESOURCES_NOT_FREED
 195  195   * Description:
 196  196   *      Close a HCA.
 197  197   */
 198  198  ibt_status_t
 199  199  ibt_close_hca(ibt_hca_hdl_t hca_hdl)
 200  200  {
 201  201          ibtl_hca_devinfo_t      *hca_devp, *tmp_devp;
 202  202          ibtl_hca_t              **hcapp;
 203  203          ibtl_clnt_t             *clntp = hca_hdl->ha_clnt_devp;
 204  204          uint32_t                cntr, error;
 205  205  
 206  206          IBTF_DPRINTF_L3(ibtf_hca, "ibt_close_hca(%p)", hca_hdl);
 207  207  
 208  208          /*
 209  209           * Verify the Input HCA Handle, if fake return error as
 210  210           * invalid HCA Handle.
 211  211           */
 212  212          mutex_enter(&ibtl_clnt_list_mutex);
 213  213          hca_devp = hca_hdl->ha_hca_devp;
 214  214          tmp_devp = ibtl_hca_list;
 215  215  
 216  216          for (; tmp_devp != NULL; tmp_devp = tmp_devp->hd_hca_dev_link)
 217  217                  if (tmp_devp == hca_devp)
 218  218                          break;
 219  219  
 220  220          if (tmp_devp == NULL) {
 221  221                  mutex_exit(&ibtl_clnt_list_mutex);
 222  222                  IBTF_DPRINTF_L2(ibtf_hca, "ibt_close_hca: "
 223  223                      "Unable to find this on global HCA list");
 224  224                  return (IBT_HCA_HDL_INVALID);
 225  225          }
 226  226  
 227  227          /* Make sure resources have been freed. */
 228  228          error = 0;
 229  229          IBTL_CLOSE_RESOURCE_CHECK(hca_hdl->ha_qp_cnt, "QP/Channel");
 230  230          IBTL_CLOSE_RESOURCE_CHECK(hca_hdl->ha_eec_cnt, "EEC");
 231  231          IBTL_CLOSE_RESOURCE_CHECK(hca_hdl->ha_cq_cnt, "CQ");
 232  232          IBTL_CLOSE_RESOURCE_CHECK(hca_hdl->ha_pd_cnt, "Protection Domain");
 233  233          IBTL_CLOSE_RESOURCE_CHECK(hca_hdl->ha_ah_cnt, "AH");
 234  234          IBTL_CLOSE_RESOURCE_CHECK(hca_hdl->ha_mr_cnt, "Memory Region");
 235  235          IBTL_CLOSE_RESOURCE_CHECK(hca_hdl->ha_mw_cnt, "Memory Window");
 236  236          IBTL_CLOSE_RESOURCE_CHECK(hca_hdl->ha_qpn_cnt, "QPN");
 237  237          IBTL_CLOSE_RESOURCE_CHECK(hca_hdl->ha_srq_cnt, "SRQ");
 238  238          IBTL_CLOSE_RESOURCE_CHECK(hca_hdl->ha_fmr_pool_cnt, "FMR Pool");
 239  239          if (error) {
 240  240                  mutex_exit(&ibtl_clnt_list_mutex);
 241  241                  return (IBT_HCA_RESOURCES_NOT_FREED);
 242  242          }
 243  243  
 244  244          /* we are now committed to closing the HCA */
 245  245          hca_hdl->ha_flags |= IBTL_HA_CLOSING;
 246  246          while (hca_hdl->ha_qpn_cnt > 0)
 247  247                  cv_wait(&ibtl_close_hca_cv, &ibtl_clnt_list_mutex);
 248  248  
 249  249          /*
 250  250           * Remove this HCA Device entry form Client's current list of HCA
 251  251           * Device Instances being used by it.
 252  252           */
 253  253          hcapp = &clntp->clnt_hca_list;
 254  254  
 255  255          for (; *hcapp != NULL; hcapp = &(*hcapp)->ha_hca_link)
 256  256                  if (*hcapp == hca_hdl)
 257  257                          break;
 258  258  
 259  259          if (*hcapp == NULL) {
 260  260                  IBTF_DPRINTF_L2(ibtf_hca, "ibt_close_hca: "
 261  261                      "Unable to find this HCA on client list");
 262  262                  mutex_exit(&ibtl_clnt_list_mutex);
 263  263                  return (IBT_HCA_HDL_INVALID);
 264  264          }
 265  265  
 266  266          /* hcapp now points to a link that points to us */
 267  267          *hcapp = hca_hdl->ha_hca_link;          /* remove us */
 268  268  
 269  269          /*
 270  270           * Remove this Client's entry from this HCA Device's Clients list.
 271  271           */
 272  272          hcapp = &hca_devp->hd_clnt_list;
 273  273  
 274  274          for (; *hcapp != NULL; hcapp = &(*hcapp)->ha_clnt_link)
 275  275                  if (*hcapp == hca_hdl)
 276  276                          break;
 277  277  
 278  278          if (*hcapp == NULL) {
 279  279                  mutex_exit(&ibtl_clnt_list_mutex);
 280  280                  IBTF_DPRINTF_L2(ibtf_hca, "ibt_close_hca: "
 281  281                      "Unable to find this HCA on the client's HCA list");
 282  282                  return (IBT_HCA_HDL_INVALID);
 283  283          }
 284  284  
 285  285          /* hcapp now points to a link that points to us */
 286  286          *hcapp = hca_hdl->ha_clnt_link;         /* remove us */
 287  287          mutex_exit(&ibtl_clnt_list_mutex);
 288  288  
 289  289          /* Free memory for this HCA Handle */
 290  290          ibtl_free_hca_async_check(hca_hdl);
 291  291  
 292  292          return (IBT_SUCCESS);
 293  293  }
 294  294  
 295  295  void
 296  296  ibtl_close_hca_check(ibt_hca_hdl_t hca_hdl)
 297  297  {
 298  298          IBTF_DPRINTF_L3(ibtf_hca, "ibtl_close_hca_check(%p)", hca_hdl);
 299  299  
 300  300          mutex_enter(&ibtl_clnt_list_mutex);
 301  301          if ((--hca_hdl->ha_qpn_cnt == 0) &&
 302  302              (hca_hdl->ha_flags & IBTL_HA_CLOSING)) {
 303  303                  cv_signal(&ibtl_close_hca_cv);
 304  304          }
 305  305          mutex_exit(&ibtl_clnt_list_mutex);
 306  306  }
 307  307  
 308  308  /*
 309  309   * Function:
 310  310   *      ibt_get_hca_list
 311  311   * Input:
 312  312   *      hca_list_p -  Address of pointer updated here.
 313  313   * Output:
 314  314   *      hca_list_p -  Points to an array of ib_guid_t's allocated here.
 315  315   * Returns:
 316  316   *      The actual number of valid ib_guid_t's returned.
 317  317   * Description:
 318  318   *      If hca_list_p is not NULL then the memory for the array of GUIDs is
 319  319   *      allocated here and should be freed by the caller using
 320  320   *      ibt_free_hca_list(). If hca_list_p is NULL then no memory is allocated
 321  321   *      by ibt_get_hca_list and only the number of HCAs in a system is returned.
 322  322   */
 323  323  uint_t
 324  324  ibt_get_hca_list(ib_guid_t **hca_list_p)
 325  325  {
 326  326          uint_t                  hca_count = 0;
 327  327          ibtl_hca_devinfo_t      *hca_devp;
 328  328          ib_guid_t               *hca_listp;
 329  329  
 330  330          IBTF_DPRINTF_L3(ibtf_hca, "ibt_get_hca_list(%p)", hca_list_p);
 331  331  
 332  332          mutex_enter(&ibtl_clnt_list_mutex);
 333  333  
 334  334          hca_devp = ibtl_hca_list;
 335  335          while (hca_devp != NULL) {
 336  336                  hca_count++;
 337  337                  hca_devp = hca_devp->hd_hca_dev_link;
 338  338          }
 339  339  
 340  340          if (hca_count == 0)
 341  341                  IBTF_DPRINTF_L2(ibtf_hca, "ibt_get_hca_list: "
 342  342                      "HCA device not found");
 343  343  
 344  344          if ((hca_count == 0) || (hca_list_p == NULL)) {
 345  345                  mutex_exit(&ibtl_clnt_list_mutex);
 346  346                  return (hca_count);
 347  347          }
 348  348  
 349  349          hca_listp = kmem_alloc(hca_count * sizeof (ib_guid_t), KM_SLEEP);
 350  350          *hca_list_p = hca_listp;
 351  351  
 352  352          hca_devp = ibtl_hca_list;
 353  353          while (hca_devp != NULL) {
 354  354                  /* Traverse Global HCA List & retrieve HCA Node GUIDs. */
 355  355                  *hca_listp++ = hca_devp->hd_hca_attr->hca_node_guid;
 356  356                  hca_devp = hca_devp->hd_hca_dev_link;
 357  357          }
 358  358          mutex_exit(&ibtl_clnt_list_mutex);
 359  359  
 360  360          IBTF_DPRINTF_L3(ibtf_hca, "ibt_get_hca_list: "
 361  361              "Returned <%d> entries @0x%p", hca_count, *hca_list_p);
 362  362  
 363  363          return (hca_count);
 364  364  }
 365  365  
 366  366  /*
 367  367   * Function:
 368  368   *      ibt_free_hca_list
 369  369   * Input:
 370  370   *      hca_list  - The address of an ib_guid_t pointer.
 371  371   *      entries   - The number of ib_guid_t entries to be freed.
 372  372   * Output:
 373  373   *      none.
 374  374   * Returns:
 375  375   *      none.
 376  376   * Description:
 377  377   *      The memory allocated in ibt_get_hca_list() is freed in this function.
 378  378   */
 379  379  void
 380  380  ibt_free_hca_list(ib_guid_t *hca_list, uint_t entries)
 381  381  {
 382  382          IBTF_DPRINTF_L3(ibtf_hca, "ibt_free_hca_list: "
 383  383              "Free <%d> entries from 0x%p", entries, hca_list);
 384  384  
 385  385          if ((hca_list != NULL) && (entries > 0))
 386  386                  kmem_free(hca_list, entries * sizeof (ib_guid_t));
 387  387  }
 388  388  
 389  389  /*
 390  390   * ibtl_portinfo_locked() is called when the portinfo cache is being
 391  391   * updated.  If this port's info update is in progress, we return 0
 392  392   * immediately and have the c
 393  393   * unless it's already in progress (distinguished by return value).
 394  394   * When done updating the portinfo, they call ibtl_portinfo_unlock().
 395  395   */
 396  396  
 397  397  static int
 398  398  ibtl_portinfo_locked(ibtl_hca_devinfo_t *hca_devp, uint8_t port)
 399  399  {
 400  400          ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
 401  401  
 402  402          for (;;) {
 403  403                  if (hca_devp->hd_portinfo_locked_port == 0) {
 404  404                          hca_devp->hd_portinfo_locked_port = port;
 405  405                          return (1); /* not busy, so OK to initiate update */
 406  406                  } else if (hca_devp->hd_portinfo_locked_port == port) {
 407  407                          IBTF_DPRINTF_L3(ibtf_hca, "ibtl_portinfo_locked: "
 408  408                              "HCA %p port %d is already locked",
 409  409                              hca_devp, port);
 410  410                          hca_devp->hd_portinfo_waiters = 1;
 411  411                          cv_wait(&hca_devp->hd_portinfo_cv,
 412  412                              &ibtl_clnt_list_mutex);
 413  413                          return (0); /* it's now done, so no need to initiate */
 414  414                  } else {
 415  415                          /* need to wait for other port before we try again */
 416  416                          hca_devp->hd_portinfo_waiters = 1;
 417  417                          cv_wait(&hca_devp->hd_portinfo_cv,
 418  418                              &ibtl_clnt_list_mutex);
 419  419                  }
 420  420          }
 421  421  }
 422  422  
 423  423  static void
 424  424  ibtl_portinfo_unlock(ibtl_hca_devinfo_t *hca_devp, uint8_t port)
 425  425  {
 426  426          ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
 427  427          ASSERT(hca_devp->hd_portinfo_locked_port == port);
 428  428          hca_devp->hd_portinfo_locked_port = 0;
 429  429          if (hca_devp->hd_portinfo_waiters) {
 430  430                  hca_devp->hd_portinfo_waiters = 0;
 431  431                  cv_broadcast(&hca_devp->hd_portinfo_cv);
 432  432                  IBTF_DPRINTF_L3(ibtf_hca, "ibtl_portinfo_unlock: "
 433  433                      "waking up waiters for port %d info on HCA %p",
 434  434                      port, hca_devp);
 435  435          }
 436  436  }
 437  437  
 438  438  /*
 439  439   * Function:
 440  440   *      ibt_get_port_state
 441  441   * Input:
 442  442   *      hca_devp    - The HCA Dev Info pointer.
 443  443   *      port        - Port number to query.
 444  444   * Output:
 445  445   *      sgid_p      - Returned sgid[0], NULL implies no return value.
 446  446   *      base_lid_p  - Returned base_lid, NULL implies no return value.
 447  447   * Returns:
 448  448   *      IBT_SUCCESS
 449  449   *      IBT_HCA_PORT_INVALID
 450  450   * Description:
 451  451   *      Returns HCA port attributes for one of the HCA ports.
 452  452   */
 453  453  static ibt_status_t
 454  454  ibtl_get_port_state(ibtl_hca_devinfo_t *hca_devp, uint8_t port,
 455  455      ib_gid_t *sgid_p, ib_lid_t *base_lid_p)
 456  456  {
 457  457          ibt_hca_portinfo_t *portinfop;
 458  458  
 459  459          ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
 460  460  
 461  461          if ((port < 1) || (port > hca_devp->hd_hca_attr->hca_nports)) {
 462  462                  IBTF_DPRINTF_L2(ibtf_hca, "ibtl_get_port_state: "
 463  463                      "invalid port %d, nports = %d", port,
 464  464                      hca_devp->hd_hca_attr->hca_nports);
 465  465                  return (IBT_HCA_PORT_INVALID);
 466  466          }
 467  467          portinfop = hca_devp->hd_portinfop + port - 1;
 468  468          if (portinfop->p_linkstate != IBT_PORT_ACTIVE)
 469  469                  ibtl_reinit_hca_portinfo(hca_devp, port);
 470  470  
 471  471          if (sgid_p)
 472  472                  *sgid_p = portinfop->p_sgid_tbl[0];
 473  473          if (base_lid_p)
 474  474                  *base_lid_p = portinfop->p_base_lid;
 475  475          if (portinfop->p_linkstate != IBT_PORT_ACTIVE) {
 476  476                  IBTF_DPRINTF_L2(ibtf_hca, "ibtl_get_port_state: "
 477  477                      "port %d, port_state %d, base_lid %d",
 478  478                      port, portinfop->p_linkstate, portinfop->p_base_lid);
 479  479                  return (IBT_HCA_PORT_NOT_ACTIVE);
 480  480          }
 481  481          IBTF_DPRINTF_L3(ibtf_hca, "ibtl_get_port_state: "
 482  482              "port %d, port_state %d, base_lid %d",
 483  483              port, portinfop->p_linkstate, portinfop->p_base_lid);
 484  484          return (IBT_SUCCESS);
 485  485  }
 486  486  
 487  487  /*
 488  488   * Function:
 489  489   *      ibt_get_port_state
 490  490   * Input:
 491  491   *      hca_hdl     - The HCA handle.
 492  492   *      port        - Port number to query.
 493  493   * Output:
 494  494   *      sgid_p      - Returned sgid[0], NULL implies no return value.
 495  495   *      base_lid_p  - Returned base_lid, NULL implies no return value.
 496  496   * Returns:
 497  497   *      IBT_SUCCESS
 498  498   *      IBT_HCA_PORT_INVALID
 499  499   * Description:
 500  500   *      Returns HCA port attributes for one of the HCA ports.
 501  501   */
 502  502  ibt_status_t
 503  503  ibt_get_port_state(ibt_hca_hdl_t hca_hdl, uint8_t port,
 504  504      ib_gid_t *sgid_p, ib_lid_t *base_lid_p)
 505  505  {
 506  506          ibt_status_t            retval;
 507  507  
 508  508          IBTF_DPRINTF_L3(ibtf_hca, "ibt_get_port_state(%p, %d, %p, %p)",
 509  509              hca_hdl, port, sgid_p, base_lid_p);
 510  510          mutex_enter(&ibtl_clnt_list_mutex);
 511  511          retval = ibtl_get_port_state(hca_hdl->ha_hca_devp, port, sgid_p,
 512  512              base_lid_p);
 513  513          mutex_exit(&ibtl_clnt_list_mutex);
 514  514          return (retval);
 515  515  }
 516  516  
 517  517  
 518  518  /*
 519  519   * Function:
 520  520   *      ibt_get_port_state_byguid
 521  521   * Input:
 522  522   *      hca_guid    - The HCA node GUID.
 523  523   *      port        - Port number to query.
 524  524   * Output:
 525  525   *      sgid_p      - Returned sgid[0], NULL implies no return value.
 526  526   *      base_lid_p  - Returned base_lid, NULL implies no return value.
 527  527   * Returns:
 528  528   *      IBT_SUCCESS
 529  529   *      IBT_HCA_PORT_INVALID
 530  530   *      IBT_HCA_INVALID
 531  531   * Description:
 532  532   *      Returns HCA port attributes for one of the HCA ports.
 533  533   */
 534  534  ibt_status_t
 535  535  ibt_get_port_state_byguid(ib_guid_t hca_guid, uint8_t port,
 536  536      ib_gid_t *sgid_p, ib_lid_t *base_lid_p)
 537  537  {
 538  538          ibtl_hca_devinfo_t      *hca_devp;              /* HCA Dev Info */
 539  539          ibt_status_t            retval;
 540  540  
 541  541          IBTF_DPRINTF_L3(ibtf_hca, "ibt_get_port_state_byguid(%llx, %d, %p, "
 542  542              "%p)", (longlong_t)hca_guid, port, sgid_p, base_lid_p);
 543  543          mutex_enter(&ibtl_clnt_list_mutex);
 544  544          hca_devp = ibtl_get_hcadevinfo(hca_guid);
 545  545          if (hca_devp == NULL)
 546  546                  retval = IBT_HCA_INVALID;
 547  547          else
 548  548                  retval = ibtl_get_port_state(hca_devp, port, sgid_p,
 549  549                      base_lid_p);
 550  550          mutex_exit(&ibtl_clnt_list_mutex);
 551  551          return (retval);
 552  552  }
 553  553  
 554  554  
 555  555  /*
 556  556   * Function:
 557  557   *      ibt_query_hca_byguid
 558  558   * Input:
 559  559   *      hca_guid  - The HCA node GUID.
 560  560   * Output:
 561  561   *      hca_attrs - A pointer to a ibt_hca_attr_t allocated by the caller,
 562  562   *                  into which the HCA Attributes are copied.
 563  563   * Returns:
 564  564   *      IBT_SUCCESS
 565  565   *      IBT_INVALID_PARAM
 566  566   *      IBT_HCA_INVALID
 567  567   * Description:
 568  568   *      Returns the static attributes of the specified HCA.
 569  569   */
 570  570  ibt_status_t
 571  571  ibt_query_hca_byguid(ib_guid_t hca_guid, ibt_hca_attr_t *hca_attrs)
 572  572  {
 573  573          ibtl_hca_devinfo_t      *hca_devp;      /* HCA Dev Info. */
 574  574  
 575  575          IBTF_DPRINTF_L3(ibtf_hca, "ibt_query_hca_byguid(%llX)", hca_guid);
 576  576  
 577  577          mutex_enter(&ibtl_clnt_list_mutex);
 578  578          /* Get HCA Dev Info Structure, referenced by HCA GUID. */
 579  579          hca_devp = ibtl_get_hcadevinfo(hca_guid);
 580  580          if (hca_devp == NULL) {
 581  581                  /*
 582  582                   * If we are here, then the requested HCA device is not present.
 583  583                   */
 584  584                  mutex_exit(&ibtl_clnt_list_mutex);
 585  585                  IBTF_DPRINTF_L2(ibtf_hca, "ibt_query_hca_byguid: "
 586  586                      "Device Not Found");
 587  587                  return (IBT_HCA_INVALID);
 588  588          }
 589  589  
 590  590          /* Return back the static HCA attributes */
 591  591          bcopy(hca_devp->hd_hca_attr, hca_attrs, sizeof (ibt_hca_attr_t));
 592  592  
 593  593          mutex_exit(&ibtl_clnt_list_mutex);
 594  594  
 595  595          return (IBT_SUCCESS);
 596  596  }
 597  597  
 598  598  
 599  599  /*
 600  600   * Function:
 601  601   *      ibt_query_hca
 602  602   * Input:
 603  603   *      hca_hdl   - The HCA handle.
 604  604   * Output:
 605  605   *      hca_attrs - A pointer to a ibt_hca_attr_t allocated by the caller,
 606  606   *                  into which the HCA Attributes are copied.
 607  607   * Returns:
 608  608   *      IBT_SUCCESS
 609  609   *
 610  610   * Description:
 611  611   *      Returns the static attributes of the specified HCA.
 612  612   */
 613  613  ibt_status_t
 614  614  ibt_query_hca(ibt_hca_hdl_t hca_hdl, ibt_hca_attr_t *hca_attrs)
 615  615  {
 616  616          IBTF_DPRINTF_L3(ibtf_hca, "ibt_query_hca(%p)", hca_hdl);
 617  617  
 618  618          /* Return back the static HCA attributes */
 619  619          bcopy(hca_hdl->ha_hca_devp->hd_hca_attr, hca_attrs,
 620  620              sizeof (ibt_hca_attr_t));
 621  621  
 622  622          return (IBT_SUCCESS);
 623  623  }
 624  624  
 625  625  #define ROUNDUP(x, y)   ((((x)+((y)-1))/(y))*(y))
 626  626  
 627  627  /*
 628  628   * Function:
 629  629   *      ibt_query_hca_ports
 630  630   * Input:
 631  631   *      hca_hdl     - The HCA handle.
 632  632   *      port        - Port number.  If "0", then query ALL Ports.
 633  633   * Output:
 634  634   *      port_info_p - The address of a pointer to a ibt_hca_portinfo_t struct.
 635  635   *      ports_p     - The number of hca ports on the specified HCA.
 636  636   *      size_p      - Size of the memory allocated by IBTL to get portinfo,
 637  637   *                   to be freed by calling ibt_free_portinfo().
 638  638   * Returns:
 639  639   *      IBT_SUCCESS
 640  640   *      IBT_HCA_HDL_INVALID
 641  641   *      IBT_HCA_INVALID
 642  642   * Description:
 643  643   *      Returns HCA port attributes for either "one", or "all" of the HCA ports.
 644  644   */
 645  645  ibt_status_t
 646  646  ibt_query_hca_ports(ibt_hca_hdl_t hca_hdl, uint8_t port,
 647  647      ibt_hca_portinfo_t **port_info_p, uint_t *ports_p, uint_t *size_p)
 648  648  {
 649  649          ibt_status_t    retval;
 650  650  
 651  651          IBTF_DPRINTF_L3(ibtf_hca, "ibt_query_hca_ports(%p, %d)",
 652  652              hca_hdl, port);
 653  653  
 654  654          mutex_enter(&ibtl_clnt_list_mutex);
 655  655  
 656  656          retval = ibtl_query_hca_ports(hca_hdl->ha_hca_devp, port, port_info_p,
 657  657              ports_p, size_p, 0);
 658  658  
 659  659          mutex_exit(&ibtl_clnt_list_mutex);
 660  660  
 661  661          return (retval);
 662  662  }
 663  663  
 664  664  /*
 665  665   * Function:
 666  666   *      ibt_query_hca_ports_byguid
 667  667   * Input:
 668  668   *      hca_guid    - The HCA node GUID.
 669  669   *      port        - Port number.  If "0", then query ALL Ports.
 670  670   * Output:
 671  671   *      port_info_p - The address of a pointer to a ibt_hca_portinfo_t struct.
 672  672   *      ports_p     - The number of hca ports on the specified HCA.
 673  673   *      size_p      - Size of the memory allocated by IBTL to get portinfo,
 674  674   *                   to be freed by calling ibt_free_portinfo().
 675  675   * Returns:
 676  676   *      IBT_SUCCESS
 677  677   *      IBT_HCA_HDL_INVALID
 678  678   *      IBT_HCA_INVALID
 679  679   * Description:
 680  680   *      Returns HCA port attributes for either "one", or "all" of the HCA ports.
 681  681   */
 682  682  ibt_status_t
 683  683  ibt_query_hca_ports_byguid(ib_guid_t hca_guid, uint8_t port,
 684  684      ibt_hca_portinfo_t **port_info_p, uint_t *ports_p, uint_t *size_p)
 685  685  {
 686  686          ibtl_hca_devinfo_t      *hca_devp;      /* HCA Dev Info */
 687  687          ibt_status_t            retval;
 688  688  
 689  689          mutex_enter(&ibtl_clnt_list_mutex);
 690  690          hca_devp = ibtl_get_hcadevinfo(hca_guid);
 691  691          if (hca_devp == NULL) {
 692  692                  /*
 693  693                   * If we are here, then the requested HCA device is not present.
 694  694                   * Return the status as Invalid HCA GUID.
 695  695                   */
 696  696                  *ports_p = *size_p = 0;
 697  697                  *port_info_p = NULL;
 698  698                  mutex_exit(&ibtl_clnt_list_mutex);
 699  699                  IBTF_DPRINTF_L2(ibtf_hca, "ibt_query_hca_ports_byguid: "
 700  700                      "HCA Device Not Found. ");
 701  701                  return (IBT_HCA_INVALID);
 702  702          }
 703  703  
 704  704          retval = ibtl_query_hca_ports(hca_devp, port, port_info_p, ports_p,
 705  705              size_p, 0);
 706  706  
 707  707          mutex_exit(&ibtl_clnt_list_mutex);
 708  708  
 709  709          return (retval);
 710  710  }
 711  711  
 712  712  /*
 713  713   * Define the above function for CM's use that uses the cached copy.
 714  714   */
 715  715  ibt_status_t
 716  716  ibtl_cm_query_hca_ports_byguid(ib_guid_t hca_guid, uint8_t port,
 717  717      ibt_hca_portinfo_t **port_info_p, uint_t *ports_p, uint_t *size_p)
 718  718  {
 719  719          ibtl_hca_devinfo_t      *hca_devp;      /* HCA Dev Info */
 720  720          ibt_status_t            retval;
 721  721  
 722  722          mutex_enter(&ibtl_clnt_list_mutex);
 723  723          hca_devp = ibtl_get_hcadevinfo(hca_guid);
 724  724          if (hca_devp == NULL) {
 725  725                  /*
 726  726                   * If we are here, then the requested HCA device is not present.
 727  727                   * Return the status as Invalid HCA GUID.
 728  728                   */
 729  729                  *ports_p = *size_p = 0;
 730  730                  *port_info_p = NULL;
 731  731                  mutex_exit(&ibtl_clnt_list_mutex);
 732  732                  IBTF_DPRINTF_L2(ibtf_hca, "ibt_query_hca_ports_byguid: "
 733  733                      "HCA Device Not Found. ");
 734  734                  return (IBT_HCA_INVALID);
 735  735          }
 736  736  
 737  737          retval = ibtl_query_hca_ports(hca_devp, port, port_info_p, ports_p,
 738  738              size_p, 1);
 739  739  
 740  740          mutex_exit(&ibtl_clnt_list_mutex);
 741  741  
 742  742          return (retval);
 743  743  }
 744  744  
 745  745  
 746  746  /*
 747  747   * ibtl_query_one_port - fill in portinfo for one port.
 748  748   */
 749  749  static ibt_status_t
 750  750  ibtl_query_one_port(ibtl_hca_devinfo_t *hca_devp, uint8_t port,
 751  751      ibt_hca_portinfo_t **port_info_p, uint_t *ports_p, uint_t *size_p,
 752  752      int use_cache)
 753  753  {
 754  754          ibt_hca_portinfo_t      *sp1;   /* src */
 755  755          ibt_hca_portinfo_t      *p1;    /* dst */
 756  756          caddr_t                 p2;
 757  757          uint_t                  len;
 758  758          uint_t                  sgid_tbl_len, pkey_tbl_len;
 759  759  
 760  760          ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
 761  761  
 762  762          IBTF_DPRINTF_L3(ibtf_hca, "ibtl_query_one_port(%p, %d)",
 763  763              hca_devp, port);
 764  764  
 765  765          if (port > hca_devp->hd_hca_attr->hca_nports) {
 766  766                  IBTF_DPRINTF_L2(ibtf_hca, "ibtl_query_one_port: "
 767  767                      "invalid port %d", port);
 768  768                  return (IBT_HCA_PORT_INVALID);
 769  769          }
 770  770  
 771  771          /* If the PORT_UP event is not supported, we need to query */
 772  772          sp1 = hca_devp->hd_portinfop + port - 1;
 773  773          if (use_cache == 0)
 774  774                  ibtl_reinit_hca_portinfo(hca_devp, port);
 775  775  
 776  776          *ports_p = 1;
 777  777  
 778  778          /*
 779  779           * Calculate how much memory we need for one port, and allocate it.
 780  780           */
 781  781          sgid_tbl_len = ROUNDUP(sp1->p_sgid_tbl_sz * sizeof (ib_gid_t),
 782  782              _LONG_LONG_ALIGNMENT);
 783  783          pkey_tbl_len = ROUNDUP(sp1->p_pkey_tbl_sz * sizeof (ib_pkey_t),
 784  784              _LONG_LONG_ALIGNMENT);
 785  785  
 786  786          len = sizeof (ibt_hca_portinfo_t) + sgid_tbl_len + pkey_tbl_len;
 787  787          *size_p = len;
 788  788  
 789  789          p1 = kmem_zalloc(len, KM_SLEEP);
 790  790          *port_info_p = p1;
 791  791          bcopy(sp1, p1, sizeof (ibt_hca_portinfo_t));
 792  792  
 793  793          /* initialize the p_pkey_tbl & p_sgid_tbl pointers. */
 794  794          p2 = (caddr_t)(p1 + 1); /* pkeys follow the struct ibt_hca_portinfo_s */
 795  795          bcopy(sp1->p_pkey_tbl, p2, pkey_tbl_len);
 796  796          p1->p_pkey_tbl = (ib_pkey_t *)p2;
 797  797  
 798  798          p2 += pkey_tbl_len;     /* sgids follow the pkeys */
 799  799          bcopy(sp1->p_sgid_tbl, p2, sgid_tbl_len);
 800  800          p1->p_sgid_tbl = (ib_gid_t *)p2;
 801  801  
 802  802          return (IBT_SUCCESS);
 803  803  }
 804  804  
 805  805  /*
 806  806   * ibtl_query_hca_ports - worker routine to get port_info for clients.
 807  807   */
 808  808  static ibt_status_t
 809  809  ibtl_query_hca_ports(ibtl_hca_devinfo_t *hca_devp, uint8_t port,
 810  810      ibt_hca_portinfo_t **port_info_p, uint_t *ports_p, uint_t *size_p,
 811  811      int use_cache)
 812  812  {
 813  813          ibt_hca_portinfo_t      *sp1;   /* src */
 814  814          ibt_hca_portinfo_t      *p1;    /* dst */
 815  815          uint_t                  i, nports;
 816  816          caddr_t                 p2;
 817  817          uint_t                  len;
 818  818          uint_t                  sgid_tbl_len, pkey_tbl_len;
 819  819  
 820  820          ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
 821  821  
 822  822          /*
 823  823           * If user has specified the port num, then query only that port,
 824  824           * else query all ports.
 825  825           */
 826  826          if (port)
 827  827                  return (ibtl_query_one_port(hca_devp, port, port_info_p,
 828  828                      ports_p, size_p, use_cache));
 829  829  
 830  830          IBTF_DPRINTF_L3(ibtf_hca, "ibtl_query_hca_ports(%p, ALL)", hca_devp);
 831  831  
 832  832          nports = hca_devp->hd_hca_attr->hca_nports;
 833  833          *ports_p = nports;
 834  834  
 835  835          /* If the PORT_UP event is not supported, we need to query */
 836  836          if (use_cache == 0)
 837  837                  for (i = 0; i < nports; i++)
 838  838                          ibtl_reinit_hca_portinfo(hca_devp, i + 1);
 839  839  
 840  840          sp1 = hca_devp->hd_portinfop;
 841  841  
 842  842          /*
 843  843           * Calculate how much memory we need for all ports, and allocate it.
 844  844           */
 845  845          sgid_tbl_len = ROUNDUP(sp1->p_sgid_tbl_sz * sizeof (ib_gid_t),
 846  846              _LONG_LONG_ALIGNMENT);
 847  847          pkey_tbl_len = ROUNDUP(sp1->p_pkey_tbl_sz * sizeof (ib_pkey_t),
 848  848              _LONG_LONG_ALIGNMENT);
 849  849  
 850  850          len = (sizeof (ibt_hca_portinfo_t) + sgid_tbl_len + pkey_tbl_len) *
 851  851              nports;
 852  852          *size_p = len;
 853  853  
 854  854          ASSERT(len == hca_devp->hd_portinfo_len);
 855  855  
 856  856          p1 = kmem_zalloc(len, KM_SLEEP);
 857  857          *port_info_p = p1;
 858  858          bcopy(sp1, p1, len);    /* start with an exact copy of our cache */
 859  859  
 860  860          p2 = (caddr_t)(p1 + nports);
 861  861  
 862  862          /* For each port, update the p_pkey_tbl & p_sgid_tbl ptrs. */
 863  863          for (i = 0; i < nports; i++) {
 864  864                  p1->p_pkey_tbl = (ib_pkey_t *)p2;
 865  865                  p2 += pkey_tbl_len;
 866  866                  p1->p_sgid_tbl = (ib_gid_t *)p2;
 867  867                  p2 += sgid_tbl_len;
 868  868                  p1++;
 869  869          }
 870  870          return (IBT_SUCCESS);
 871  871  }
 872  872  
 873  873  /*
 874  874   *      Search for a Full pkey.  Use the pkey at index 0 if not found.
 875  875   */
 876  876  static void
 877  877  ibtl_set_default_pkey_ix(ibt_hca_portinfo_t *p1)
 878  878  {
 879  879          uint16_t        pkey_ix;
 880  880  
 881  881          for (pkey_ix = 0; pkey_ix < p1->p_pkey_tbl_sz; pkey_ix++) {
 882  882                  if ((p1->p_pkey_tbl[pkey_ix] & 0x8000) &&
 883  883                      (p1->p_pkey_tbl[pkey_ix] != IB_PKEY_INVALID_FULL)) {
 884  884                          p1->p_def_pkey_ix = pkey_ix;
 885  885                          IBTF_DPRINTF_L3(ibtf_hca,
 886  886                              "ibtl_set_default_pkey_ix: portinfop %p, "
 887  887                              "FULL PKEY 0x%x found, pkey_ix is %d",
 888  888                              p1, p1->p_pkey_tbl[pkey_ix], pkey_ix);
 889  889                          return;
 890  890                  }
 891  891          }
 892  892          IBTF_DPRINTF_L2(ibtf_hca,
 893  893              "ibtl_set_default_pkey_ix: portinfop %p: failed "
 894  894              "to find a default PKEY in the table, using PKey 0x%x",
 895  895              p1, p1->p_pkey_tbl[0]);
 896  896          p1->p_def_pkey_ix = 0;
 897  897  }
 898  898  
 899  899  /*
 900  900   * ibtl_reinit_hca_portinfo - update the portinfo cache for use by IBTL.
 901  901   *
 902  902   * We have the HCA driver fill in a temporary portinfo, then we bcopy
 903  903   * it into our cache while holding the appropriate lock.
 904  904   */
 905  905  void
 906  906  ibtl_reinit_hca_portinfo(ibtl_hca_devinfo_t *hca_devp, uint8_t port)
 907  907  {
 908  908          ibt_status_t            status;
 909  909          ibt_hca_portinfo_t      *p1, *sp1;
 910  910          ibt_port_state_t        old_linkstate;
 911  911          uint_t                  len, sgid_tbl_len, pkey_tbl_len;
 912  912          ib_pkey_t               *saved_pkey_tbl;
 913  913          ib_gid_t                *saved_sgid_tbl;
 914  914          ib_sn_prefix_t          sn_pfx = 0;
 915  915          uint_t                  multiSM;
 916  916          int                     i;
 917  917  
 918  918          IBTF_DPRINTF_L3(ibtf_hca, "ibtl_reinit_hca_portinfo(%p, %d)",
 919  919              hca_devp, port);
 920  920  
 921  921          ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
 922  922          ASSERT(port != 0);
 923  923  
 924  924          if (ibtl_portinfo_locked(hca_devp, port)) {
 925  925                  /* we got the lock, so we need to do the portinfo update */
 926  926  
 927  927                  /* invalidate fast_gid_cache */
 928  928                  ibtl_fast_gid_cache_valid = B_FALSE;
 929  929  
 930  930                  p1 = hca_devp->hd_portinfop + port - 1;
 931  931                  sgid_tbl_len = ROUNDUP(p1->p_sgid_tbl_sz * sizeof (ib_gid_t),
 932  932                      _LONG_LONG_ALIGNMENT);
 933  933                  pkey_tbl_len = ROUNDUP(p1->p_pkey_tbl_sz * sizeof (ib_pkey_t),
 934  934                      _LONG_LONG_ALIGNMENT);
 935  935                  len = sizeof (ibt_hca_portinfo_t) + sgid_tbl_len + pkey_tbl_len;
 936  936  
 937  937                  /* update was NOT in progress, so we do it here */
 938  938                  mutex_exit(&ibtl_clnt_list_mutex);
 939  939  
 940  940                  IBTF_DPRINTF_L3(ibtf_hca, "ibtl_reinit_hca_portinfo(%p, %d): "
 941  941                      "calling ibc_query_hca_ports", hca_devp, port);
 942  942  
 943  943                  sp1 = kmem_zalloc(len, KM_SLEEP);
 944  944                  sp1->p_pkey_tbl = (ib_pkey_t *)(sp1 + 1);
 945  945                  sp1->p_sgid_tbl =
 946  946                      (ib_gid_t *)((caddr_t)sp1->p_pkey_tbl + pkey_tbl_len);
 947  947                  status = IBTL_HDIP2CIHCAOPS_P(hca_devp)->ibc_query_hca_ports(
 948  948                      IBTL_HDIP2CIHCA(hca_devp), port, sp1);
 949  949  
 950  950                  mutex_enter(&ibtl_clnt_list_mutex);
 951  951                  if (status != IBT_SUCCESS) {
 952  952                          IBTF_DPRINTF_L2(ibtf_hca,
 953  953                              "ibtl_reinit_hca_portinfo(%p, %d): "
 954  954                              "ibc_query_hca_ports() failed: status = %d",
 955  955                              hca_devp, port, status);
 956  956                  } else {
 957  957                          old_linkstate = p1->p_linkstate;
 958  958                          bcopy(sp1->p_pkey_tbl, p1->p_pkey_tbl, pkey_tbl_len);
 959  959                          bcopy(sp1->p_sgid_tbl, p1->p_sgid_tbl, sgid_tbl_len);
 960  960                          saved_pkey_tbl = p1->p_pkey_tbl;
 961  961                          saved_sgid_tbl = p1->p_sgid_tbl;
 962  962                          bcopy(sp1, p1, sizeof (ibt_hca_portinfo_t));
 963  963                          p1->p_pkey_tbl = saved_pkey_tbl;
 964  964                          p1->p_sgid_tbl = saved_sgid_tbl;
 965  965                          if (p1->p_linkstate == IBT_PORT_ACTIVE) {
 966  966                                  ibtl_set_default_pkey_ix(p1);
 967  967                                  if (p1->p_linkstate != old_linkstate)
 968  968                                          IBTF_DPRINTF_L2(ibtf_hca,
 969  969                                              "ibtl_reinit_hca_portinfo(%p, %d): "
 970  970                                              "PORT UP", hca_devp, port);
 971  971                          } else {
 972  972                                  if (p1->p_linkstate != IBT_PORT_ARM)
 973  973                                          p1->p_base_lid = 0;
 974  974                                  if (p1->p_linkstate != old_linkstate)
 975  975                                          IBTF_DPRINTF_L2(ibtf_hca,
 976  976                                              "ibtl_reinit_hca_portinfo(%p, %d): "
 977  977                                              "PORT DOWN", hca_devp, port);
 978  978                          }
 979  979                  }
 980  980                  kmem_free(sp1, len);
 981  981  
 982  982                  /* Set multism bit accordingly. */
 983  983                  multiSM = 0;
 984  984                  p1 = hca_devp->hd_portinfop;
 985  985                  for (i = 0; i < hca_devp->hd_hca_attr->hca_nports; i++) {
 986  986                          if (p1->p_linkstate == IBT_PORT_ACTIVE) {
 987  987                                  if (sn_pfx == 0) {
 988  988                                          sn_pfx = p1->p_sgid_tbl[0].gid_prefix;
 989  989                                  } else if (sn_pfx !=
 990  990                                      p1->p_sgid_tbl[0].gid_prefix) {
 991  991                                          multiSM = 1;
 992  992                                          IBTF_DPRINTF_L3(ibtf_hca,
 993  993                                              "ibtl_reinit_hca_portinfo: "
 994  994                                              "MULTI SM, Port1 SnPfx=0x%llX, "
 995  995                                              "Port2 SnPfx=0x%llX", sn_pfx,
 996  996                                              p1->p_sgid_tbl[0].gid_prefix);
 997  997                                  }
 998  998                          }
 999  999                          p1++;
1000 1000                  }
1001 1001                  hca_devp->hd_multism = multiSM;
1002 1002  
1003 1003                  ibtl_portinfo_unlock(hca_devp, port);
1004 1004          }
1005 1005  }
1006 1006  
1007 1007  /*
1008 1008   * ibtl_init_hca_portinfo - fill in the portinfo cache for use by IBTL.
1009 1009   */
1010 1010  ibt_status_t
1011 1011  ibtl_init_hca_portinfo(ibtl_hca_devinfo_t *hca_devp)
1012 1012  {
1013 1013          ibt_hca_portinfo_t      *p1;
1014 1014          ibt_status_t            retval;
1015 1015          uint_t                  i, nports;
1016 1016          caddr_t                 p2;
1017 1017          uint_t                  len;
1018 1018          uint_t                  sgid_tbl_len, pkey_tbl_len;
1019 1019          uint_t                  sgid_tbl_sz, pkey_tbl_sz;
1020 1020          ib_sn_prefix_t          sn_pfx = 0;
1021 1021          uint_t                  multiSM;
1022 1022  
1023 1023          IBTF_DPRINTF_L2(ibtf_hca, "ibtl_init_hca_portinfo(%p)", hca_devp);
1024 1024  
1025 1025          ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
1026 1026  
1027 1027          nports = hca_devp->hd_hca_attr->hca_nports;
1028 1028  
1029 1029          /*
1030 1030           * Calculate how much memory we need for all ports, and allocate it.
1031 1031           */
1032 1032          pkey_tbl_sz = IBTL_HDIP2PKEYTBLSZ(hca_devp);
1033 1033          sgid_tbl_sz = IBTL_HDIP2SGIDTBLSZ(hca_devp);
1034 1034          pkey_tbl_len = ROUNDUP(pkey_tbl_sz * sizeof (ib_pkey_t),
1035 1035              _LONG_LONG_ALIGNMENT);
1036 1036          sgid_tbl_len = ROUNDUP(sgid_tbl_sz * sizeof (ib_gid_t),
1037 1037              _LONG_LONG_ALIGNMENT);
1038 1038  
1039 1039          len = (sizeof (ibt_hca_portinfo_t) + sgid_tbl_len + pkey_tbl_len) *
1040 1040              nports;
1041 1041  
1042 1042          p1 = kmem_zalloc(len, KM_SLEEP);
1043 1043          p2 = (caddr_t)(p1 + nports);
1044 1044  
1045 1045          hca_devp->hd_portinfop = p1;
1046 1046          hca_devp->hd_portinfo_len = len;
1047 1047  
1048 1048          /* For each port initialize the p_pkey_tbl & p_sgid_tbl ptrs. */
1049 1049          for (i = 0; i < nports; i++) {
1050 1050                  p1->p_pkey_tbl_sz = pkey_tbl_sz;
1051 1051                  p1->p_sgid_tbl_sz = sgid_tbl_sz;
1052 1052                  p1->p_pkey_tbl = (ib_pkey_t *)p2;
1053 1053                  p2 += pkey_tbl_len;
1054 1054                  p1->p_sgid_tbl = (ib_gid_t *)p2;
1055 1055                  p2 += sgid_tbl_len;
1056 1056                  p1++;
1057 1057          }
1058 1058          p1 = hca_devp->hd_portinfop;
1059 1059          mutex_exit(&ibtl_clnt_list_mutex);
1060 1060  
1061 1061          /* re-direct the call to CI's call */
1062 1062          retval = IBTL_HDIP2CIHCAOPS_P(hca_devp)->ibc_query_hca_ports(
1063 1063              IBTL_HDIP2CIHCA(hca_devp), 0, p1);
1064 1064  
1065 1065          mutex_enter(&ibtl_clnt_list_mutex);
1066 1066          if (retval != IBT_SUCCESS) {
1067 1067                  IBTF_DPRINTF_L2(ibtf_hca, "ibtl_init_hca_portinfo(%p): "
1068 1068                      "ibc_query_hca_ports() failed: status = %d",
1069 1069                      hca_devp, retval);
1070 1070                  kmem_free(hca_devp->hd_portinfop, len);
1071 1071                  hca_devp->hd_portinfop = NULL;
1072 1072                  hca_devp->hd_portinfo_len = 0;
1073 1073                  return (retval);
1074 1074          }
1075 1075  
1076 1076          p1 = hca_devp->hd_portinfop;
1077 1077          multiSM = 0;
1078 1078          for (i = 0; i < nports; i++) {
1079 1079                  if (p1->p_linkstate == IBT_PORT_ACTIVE) {
1080 1080                          ibtl_set_default_pkey_ix(p1);
1081 1081                          if (sn_pfx == 0) {
1082 1082                                  sn_pfx = p1->p_sgid_tbl[0].gid_prefix;
1083 1083                          } else if (p1->p_sgid_tbl[0].gid_prefix != sn_pfx) {
1084 1084                                  multiSM = 1;
1085 1085                                  IBTF_DPRINTF_L3(ibtf_hca,
1086 1086                                      "ibtl_init_hca_portinfo: MULTI SM, "
1087 1087                                      "Port1 SnPfx=0x%llX, Port2 SnPfx=0x%llX",
1088 1088                                      sn_pfx, p1->p_sgid_tbl[0].gid_prefix);
1089 1089                          }
1090 1090                  } else {
1091 1091                          if (p1->p_linkstate != IBT_PORT_ARM)
1092 1092                                  p1->p_base_lid = 0;
1093 1093                  }
1094 1094                  p1++;
1095 1095          }
1096 1096          hca_devp->hd_multism = multiSM;
1097 1097  
1098 1098          return (IBT_SUCCESS);
1099 1099  }
1100 1100  
1101 1101  /*
1102 1102   * Function:
1103 1103   *      ibt_modify_system_image
1104 1104   * Input:
1105 1105   *      hca_hdl  - The HCA handle.
1106 1106   *      sys_guid - The New system image GUID.
1107 1107   * Description:
1108 1108   *      Modify specified HCA's system image GUID.
1109 1109   */
1110 1110  ibt_status_t
1111 1111  ibt_modify_system_image(ibt_hca_hdl_t hca_hdl, ib_guid_t sys_guid)
1112 1112  {
1113 1113          ibt_status_t            retval;
1114 1114  
1115 1115          IBTF_DPRINTF_L3(ibtf_hca, "ibt_modify_system_image(%p, %llX)",
1116 1116              hca_hdl, sys_guid);
1117 1117  
1118 1118          mutex_enter(&ibtl_clnt_list_mutex);
1119 1119          /* Get HCA Dev Info Structure, referenced by HCA GUID. */
1120 1120  
1121 1121          /* re-direct the call to CI's call */
1122 1122          retval = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_modify_system_image(
1123 1123              IBTL_HCA2CIHCA(hca_hdl), sys_guid);
1124 1124  
1125 1125          mutex_exit(&ibtl_clnt_list_mutex);
1126 1126          return (retval);
1127 1127  }
1128 1128  
1129 1129  /*
1130 1130   * Function:
1131 1131   *      ibt_modify_system_image_byguid
1132 1132   *
1133 1133   * Input:
1134 1134   *      hca_guid - The HCA Node GUID.
1135 1135   *      sys_guid - The New system image GUID.
1136 1136   * Description:
1137 1137   *      Modify specified HCA's system image GUID.
1138 1138   */
1139 1139  ibt_status_t
1140 1140  ibt_modify_system_image_byguid(ib_guid_t hca_guid, ib_guid_t sys_guid)
1141 1141  {
1142 1142          ibtl_hca_devinfo_t      *hca_devp;      /* HCA Dev Info. */
1143 1143          ibt_status_t            retval;
1144 1144  
1145 1145          IBTF_DPRINTF_L3(ibtf_hca, "ibt_modify_system_image_byguid(%llX, %llX)",
1146 1146              hca_guid, sys_guid);
1147 1147  
1148 1148          mutex_enter(&ibtl_clnt_list_mutex);
1149 1149          /* Get HCA Dev Info Structure, referenced by HCA GUID. */
1150 1150          hca_devp = ibtl_get_hcadevinfo(hca_guid);
1151 1151          if (hca_devp == NULL) {
1152 1152                  /*
1153 1153                   * If we are here, then the requested HCA device is not present.
1154 1154                   */
1155 1155                  mutex_exit(&ibtl_clnt_list_mutex);
1156 1156                  return (IBT_HCA_INVALID);
1157 1157          }
1158 1158  
1159 1159          /* re-direct the call to CI's call */
1160 1160          retval = IBTL_HDIP2CIHCAOPS_P(hca_devp)->ibc_modify_system_image(
1161 1161              IBTL_HDIP2CIHCA(hca_devp), sys_guid);
1162 1162  
1163 1163          mutex_exit(&ibtl_clnt_list_mutex);
1164 1164          return (retval);
1165 1165  }
1166 1166  
1167 1167  /*
1168 1168   * Function:
1169 1169   *      ibt_modify_port_byguid
1170 1170   * Input:
1171 1171   *      hca_guid - The HCA Guid.
1172 1172   *      cmds     - A pointer to an array of ibt_port_modify_t cmds. The
1173 1173   *                 pmod_port field specifies the port to modify (all ports if 0)
1174 1174   *                 and the pmod_flags field specifies which attribute to reset.
1175 1175   *      num_cmds - The number of commands in the cmds array.
1176 1176   * Output:
1177 1177   *      none.
1178 1178   * Returns:
1179 1179   *      IBT_SUCCESS
1180 1180   *      IBT_HCA_HDL_INVALID
1181 1181   *      IBT_HCA_CNTR_INVALID
1182 1182   *      IBT_HCA_CNTR_VAL_INVALID
1183 1183   * Description:
1184 1184   *      Reset the specified port, or all ports attribute(s).
1185 1185   */
1186 1186  ibt_status_t
1187 1187  ibt_modify_port_byguid(ib_guid_t hca_guid,  uint8_t port,
1188 1188      ibt_port_modify_flags_t flags, uint8_t init_type)
1189 1189  {
1190 1190          ibtl_hca_devinfo_t      *hca_devp;      /* HCA Dev Info. */
1191 1191          ibt_status_t            retval;
1192 1192  
1193 1193          IBTF_DPRINTF_L3(ibtf_hca, "ibt_modify_port_byguid(%llX, %d, %X, %X)",
1194 1194              hca_guid, port, flags, init_type);
1195 1195  
1196 1196          mutex_enter(&ibtl_clnt_list_mutex);
1197 1197          /* Get HCA Dev Info Structure, referenced by HCA GUID. */
1198 1198          hca_devp = ibtl_get_hcadevinfo(hca_guid);
1199 1199          if (hca_devp == NULL) {
1200 1200                  /*
1201 1201                   * If we are here, then the requested HCA device is not present.
1202 1202                   */
1203 1203                  mutex_exit(&ibtl_clnt_list_mutex);
1204 1204                  return (IBT_HCA_INVALID);
1205 1205          }
1206 1206  
1207 1207          /* re-direct the call to CI's call */
1208 1208          retval = IBTL_HDIP2CIHCAOPS_P(hca_devp)->ibc_modify_ports(
1209 1209              IBTL_HDIP2CIHCA(hca_devp), port, flags, init_type);
1210 1210  
1211 1211          mutex_exit(&ibtl_clnt_list_mutex);
1212 1212          return (retval);
1213 1213  }
1214 1214  
1215 1215  /*
1216 1216   * Function:
1217 1217   *      ibt_modify_port
1218 1218   * Input:
1219 1219   *      hca_hdl  - The HCA handle.
1220 1220   *      cmds     - A pointer to an array of ibt_port_modify_t cmds. The
1221 1221   *                 pmod_port field specifies the port to modify (all ports if 0)
1222 1222   *                 and the pmod_flags field specifies which attribute to reset.
1223 1223   *      num_cmds - The number of commands in the cmds array.
1224 1224   * Output:
1225 1225   *      none.
1226 1226   * Returns:
1227 1227   *      IBT_SUCCESS
1228 1228   *      IBT_HCA_HDL_INVALID
1229 1229   *      IBT_HCA_CNTR_INVALID
1230 1230   *      IBT_HCA_CNTR_VAL_INVALID
1231 1231   * Description:
1232 1232   *      Reset the specified port, or all ports attribute(s).
1233 1233   */
1234 1234  ibt_status_t
1235 1235  ibt_modify_port(ibt_hca_hdl_t hca_hdl, uint8_t port,
1236 1236      ibt_port_modify_flags_t flags, uint8_t init_type)
1237 1237  
1238 1238  {
1239 1239          ibt_status_t            retval;
1240 1240  
1241 1241          IBTF_DPRINTF_L3(ibtf_hca, "ibt_modify_port(%p, %d, %X, %X)",
1242 1242              hca_hdl, port, flags, init_type);
1243 1243  
1244 1244          mutex_enter(&ibtl_clnt_list_mutex);
1245 1245  
1246 1246          /* re-direct the call to CI's call */
1247 1247          retval = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_modify_ports(
1248 1248              IBTL_HCA2CIHCA(hca_hdl), port, flags, init_type);
1249 1249  
1250 1250          mutex_exit(&ibtl_clnt_list_mutex);
1251 1251          return (retval);
1252 1252  }
1253 1253  
1254 1254  /*
1255 1255   * Function:
1256 1256   *      ibt_free_portinfo
1257 1257   * Input:
1258 1258   *      port_info  - The address of an array to a ibt_hca_portinfo_t struct.
1259 1259   *      size       - Memory Size as returned from ibt_query_hca_ports().
1260 1260   * Output:
1261 1261   *      none
1262 1262   * Returns:
1263 1263   *      none
1264 1264   * Description:
1265 1265   *      Frees the memory allocated for a specified ibt_hca_portinfo_t struct.
1266 1266   */
1267 1267  void
1268 1268  ibt_free_portinfo(ibt_hca_portinfo_t *port_info, uint_t size)
1269 1269  {
1270 1270          IBTF_DPRINTF_L3(ibtf_hca, "ibt_free_portinfo(%p, %d)",
1271 1271              port_info, size);
1272 1272  
1273 1273          if ((port_info == NULL) || (size == 0)) {
1274 1274                  IBTF_DPRINTF_L2(ibtf_hca, "ibt_free_portinfo: NULL Pointer");
1275 1275          } else {
1276 1276                  kmem_free(port_info, size);
1277 1277          }
1278 1278  }
1279 1279  
1280 1280  
1281 1281  /*
1282 1282   * Function:
1283 1283   *      ibt_get_hcadevinfo
1284 1284   * Input:
1285 1285   *      hca_guid - The HCA's node GUID.
1286 1286   * Output:
1287 1287   *      none.
1288 1288   * Returns:
1289 1289   *      Pointer to HCA Device Info structure whose HCA GUID is requested or NULL
1290 1290   * Description:
1291 1291   *      Get a pointer to HCA Device Info Structure for the requested HCA GUID.
1292 1292   *      If no matching HCA GUID Device info is found, NULL is returned.
1293 1293   */
1294 1294  ibtl_hca_devinfo_t *
1295 1295  ibtl_get_hcadevinfo(ib_guid_t hca_guid)
1296 1296  {
1297 1297          ibtl_hca_devinfo_t      *hca_devp;      /* HCA Dev Info */
1298 1298  
1299 1299          IBTF_DPRINTF_L3(ibtf_hca, "ibtl_get_hcadevinfo(%llX)", hca_guid);
1300 1300  
1301 1301          ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
1302 1302  
1303 1303          hca_devp = ibtl_hca_list;
1304 1304  
1305 1305          /*
1306 1306           * Check whether a HCA device with requested Node GUID is available.
1307 1307           * This is done, by searching the global HCA devinfo list and
1308 1308           * comparing the Node GUID from the device attribute info.
1309 1309           */
1310 1310          while (hca_devp != NULL) {
1311 1311                  if (hca_devp->hd_hca_attr->hca_node_guid == hca_guid) {
1312 1312                          /* Match Found. */
1313 1313                          break;
1314 1314                  }
1315 1315                  hca_devp = hca_devp->hd_hca_dev_link;
1316 1316          }
1317 1317          return (hca_devp);
1318 1318  }
1319 1319  
1320 1320  
1321 1321  /*
1322 1322   * Function:
1323 1323   *      ibtl_pkey2index
1324 1324   * Input:
1325 1325   *      hca_devp     - The IBTL HCA Device Info.
1326 1326   *      port_num     - The HCA port number.
1327 1327   *      pkey         - The input PKey value, whose index we are interested in.
1328 1328   * Output:
1329 1329   *      pkey_ix      - The PKey index returned for the specified PKey.
1330 1330   * Returns:
1331 1331   *      IBT_SUCCESS/IBT_HCA_PORT_INVALID/IBT_INVALID_PARAM
1332 1332   * Description:
1333 1333   *      Returns the PKey Index for the specified PKey, the device as specified
1334 1334   *      by IBT HCA Handle.
1335 1335   */
1336 1336  static ibt_status_t
1337 1337  ibtl_pkey2index(ibtl_hca_devinfo_t *hca_devp, uint8_t port_num,
1338 1338      ib_pkey_t pkey, uint16_t *pkey_ix)
1339 1339  {
1340 1340          ibt_hca_portinfo_t      *port_infop;
1341 1341          uint_t                  ports;
1342 1342          uint_t                  i;
1343 1343  
1344 1344          IBTF_DPRINTF_L3(ibtf_hca, "ibtl_pkey2index(%p, %d, %d)",
1345 1345              hca_devp, port_num, pkey);
1346 1346  
1347 1347          ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
1348 1348  
1349 1349          if ((pkey == IB_PKEY_INVALID_FULL) ||
1350 1350              (pkey == IB_PKEY_INVALID_LIMITED))
1351 1351                  return (IBT_INVALID_PARAM);
1352 1352  
1353 1353          ports = hca_devp->hd_hca_attr->hca_nports;
1354 1354          if ((port_num == 0) || (port_num > ports)) {
1355 1355                  IBTF_DPRINTF_L2(ibtf_hca, "ibtl_pkey2index: "
1356 1356                      "Invalid port_num %d, range is (1 to %d)", port_num, ports);
1357 1357                  return (IBT_HCA_PORT_INVALID);
1358 1358          }
1359 1359  
1360 1360          port_infop = hca_devp->hd_portinfop + port_num - 1;
1361 1361          for (i = 0; i < port_infop->p_pkey_tbl_sz; i++) {
1362 1362                  if (pkey == port_infop->p_pkey_tbl[i]) {
1363 1363                          *pkey_ix = i;
1364 1364                          return (IBT_SUCCESS);
1365 1365                  }
1366 1366          }
1367 1367          return (IBT_INVALID_PARAM);
1368 1368  }
1369 1369  
1370 1370  /*
1371 1371   * Function:
1372 1372   *      ibtl_index2pkey
1373 1373   * Input:
1374 1374   *      hca_devp     - The IBTL HCA Device Info.
1375 1375   *      port_num     - The HCA port
1376 1376   *      pkey_ix      - The input PKey index, whose PKey we are interested in.
1377 1377   * Output:
1378 1378   *      pkey         - The returned PKey value.
1379 1379   * Returns:
1380 1380   *      IBT_SUCCESS/IBT_PKEY_IX_ILLEGAL/IBT_PKEY_IX_INVALID/IBT_HCA_PORT_INVALID
1381 1381   * Description:
1382 1382   *      Returns the PKey value for the specified PKey index, the device as
1383 1383   *      specified by IBT HCA Handle.
1384 1384   */
1385 1385  static ibt_status_t
1386 1386  ibtl_index2pkey(ibtl_hca_devinfo_t *hca_devp, uint8_t port_num,
1387 1387      uint16_t pkey_ix, ib_pkey_t *pkey)
1388 1388  {
1389 1389          ibt_hca_portinfo_t      *port_infop;
1390 1390          uint_t                  ports;
1391 1391  
1392 1392          IBTF_DPRINTF_L3(ibtf_hca, "ibtl_index2pkey(%p, %d, %d)",
1393 1393              hca_devp, port_num, pkey_ix);
1394 1394  
1395 1395          ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
1396 1396  
1397 1397          ports = hca_devp->hd_hca_attr->hca_nports;
1398 1398          if ((port_num == 0) || (port_num > ports)) {
1399 1399                  IBTF_DPRINTF_L2(ibtf_hca, "ibtl_index2pkey: "
1400 1400                      "Invalid port_num %d, range is (1 to %d)", port_num, ports);
1401 1401                  return (IBT_HCA_PORT_INVALID);
1402 1402          }
1403 1403  
1404 1404          port_infop = hca_devp->hd_portinfop + port_num - 1;
1405 1405          if (pkey_ix >= port_infop->p_pkey_tbl_sz) {
1406 1406                  IBTF_DPRINTF_L2(ibtf_hca, "ibtl_index2pkey: "
1407 1407                      "pkey index %d out of range (0, %d)",
1408 1408                      pkey_ix, port_infop->p_pkey_tbl_sz - 1);
1409 1409                  return (IBT_PKEY_IX_ILLEGAL);
1410 1410          }
1411 1411  
1412 1412          *pkey = port_infop->p_pkey_tbl[pkey_ix];
1413 1413          if ((*pkey == IB_PKEY_INVALID_FULL) ||
1414 1414              (*pkey == IB_PKEY_INVALID_LIMITED))
1415 1415                  return (IBT_PKEY_IX_INVALID);
1416 1416          return (IBT_SUCCESS);
1417 1417  }
1418 1418  
1419 1419  /*
1420 1420   * Function:
1421 1421   *      ibt_pkey2index
1422 1422   * Input:
1423 1423   *      hca_hdl      - The IBT HCA handle.
1424 1424   *      port_num     - The HCA port number.
1425 1425   *      pkey         - The input PKey value, whose index we are interested in.
1426 1426   * Output:
1427 1427   *      pkey_ix      - The PKey index returned for the specified PKey.
1428 1428   * Returns:
1429 1429   *      IBT_SUCCESS/IBT_HCA_PORT_INVALID/IBT_INVALID_PARAM
1430 1430   * Description:
1431 1431   *      Returns the PKey Index for the specified PKey, the device as specified
1432 1432   *      by IBT HCA Handle.
1433 1433   */
1434 1434  ibt_status_t
1435 1435  ibt_pkey2index(ibt_hca_hdl_t hca_hdl, uint8_t port_num, ib_pkey_t pkey,
1436 1436      uint16_t *pkey_ix)
1437 1437  {
1438 1438          ibt_status_t            retval;
1439 1439  
1440 1440          IBTF_DPRINTF_L3(ibtf_hca, "ibt_pkey2index(%p, %d, %d)",
1441 1441              hca_hdl, port_num, pkey);
1442 1442  
1443 1443          mutex_enter(&ibtl_clnt_list_mutex);
1444 1444          retval = ibtl_pkey2index(hca_hdl->ha_hca_devp, port_num, pkey, pkey_ix);
1445 1445          mutex_exit(&ibtl_clnt_list_mutex);
1446 1446  
1447 1447          return (retval);
1448 1448  }
1449 1449  
1450 1450  /*
1451 1451   * Function:
1452 1452   *      ibt_pkey2index_byguid
1453 1453   * Input:
1454 1454   *      hca_guid     - The HCA's node GUID.
1455 1455   *      port_num     - The HCA port number.
1456 1456   *      pkey         - The input PKey value, whose index we are interested in.
1457 1457   * Output:
1458 1458   *      pkey_ix      - The PKey Index returned for the specified PKey.
1459 1459   * Returns:
1460 1460   *      IBT_SUCCESS/IBT_HCA_PORT_INVALID/IBT_INVALID_PARAM/IBT_HCA_INVALID
1461 1461   * Description:
1462 1462   *      Returns the PKey Index for the specified PKey, the device as specified
1463 1463   *      by HCA GUID Info.
1464 1464   */
1465 1465  ibt_status_t
1466 1466  ibt_pkey2index_byguid(ib_guid_t hca_guid, uint8_t port_num, ib_pkey_t pkey,
1467 1467      uint16_t *pkey_ix)
1468 1468  {
1469 1469          ibt_status_t            retval;
1470 1470          ibtl_hca_devinfo_t      *hca_devp;      /* HCA Dev Info */
1471 1471  
1472 1472          IBTF_DPRINTF_L3(ibtf_hca, "ibt_pkey2index_byguid(%llX, %d, %d)",
1473 1473              hca_guid, port_num, pkey);
1474 1474  
1475 1475          mutex_enter(&ibtl_clnt_list_mutex);
1476 1476          hca_devp = ibtl_get_hcadevinfo(hca_guid);
1477 1477          if (hca_devp == NULL) {
1478 1478                  IBTF_DPRINTF_L2(ibtf_hca, "ibt_pkey2index_byguid: "
1479 1479                      "Invalid HCA GUID 0x%llx", hca_guid);
1480 1480                  mutex_exit(&ibtl_clnt_list_mutex);
1481 1481                  return (IBT_HCA_INVALID);
1482 1482          }
1483 1483          retval = ibtl_pkey2index(hca_devp, port_num, pkey, pkey_ix);
1484 1484          mutex_exit(&ibtl_clnt_list_mutex);
1485 1485  
1486 1486          return (retval);
1487 1487  }
1488 1488  
1489 1489  
1490 1490  /*
1491 1491   * Function:
1492 1492   *      ibt_index2pkey
1493 1493   * Input:
1494 1494   *      hca_hdl      - The IBT HCA handle.
1495 1495   *      port_num     - The HCA port
1496 1496   *      pkey_ix      - The input PKey index, whose PKey we are interested in.
1497 1497   * Output:
1498 1498   *      pkey         - The returned PKey value.
1499 1499   * Returns:
1500 1500   *      IBT_SUCCESS/IBT_PKEY_IX_ILLEGAL/IBT_PKEY_IX_INVALID/IBT_HCA_PORT_INVALID
1501 1501   * Description:
1502 1502   *      Returns the PKey value for the specified PKey index, the device as
1503 1503   *      specified by IBT HCA Handle.
1504 1504   */
1505 1505  ibt_status_t
1506 1506  ibt_index2pkey(ibt_hca_hdl_t hca_hdl, uint8_t port_num, uint16_t pkey_ix,
1507 1507      ib_pkey_t *pkey)
1508 1508  {
1509 1509          ibt_status_t            retval;
1510 1510  
1511 1511          IBTF_DPRINTF_L3(ibtf_hca, "ibt_index2pkey(%p, %d, %d)",
1512 1512              hca_hdl, port_num, pkey_ix);
1513 1513  
1514 1514          mutex_enter(&ibtl_clnt_list_mutex);
1515 1515          retval = ibtl_index2pkey(hca_hdl->ha_hca_devp, port_num, pkey_ix, pkey);
1516 1516          mutex_exit(&ibtl_clnt_list_mutex);
1517 1517  
1518 1518          return (retval);
1519 1519  }
1520 1520  
1521 1521  /*
1522 1522   * Function:
1523 1523   *      ibt_index2pkey_byguid
1524 1524   * Input:
1525 1525   *      hca_guid     - The HCA's node GUID.
1526 1526   *      port_num     - The HCA port
1527 1527   *      pkey_ix      - The input PKey index, whose PKey we are interested in.
1528 1528   * Output:
1529 1529   *      pkey         - The returned PKey value, for the specified index.
1530 1530   * Returns:
1531 1531   *      IBT_SUCCESS/IBT_PKEY_IX_ILLEGAL/IBT_PKEY_IX_INVALID/
1532 1532   *      IBT_HCA_PORT_INVALID/IBT_HCA_INVALID
1533 1533   * Description:
1534 1534   *      Returns the PKey Index for the specified PKey, the device as specified
1535 1535   *      by HCA GUID Info.
1536 1536   */
1537 1537  ibt_status_t
1538 1538  ibt_index2pkey_byguid(ib_guid_t hca_guid, uint8_t port_num, uint16_t pkey_ix,
1539 1539      ib_pkey_t *pkey)
1540 1540  {
1541 1541          ibt_status_t            retval;
1542 1542          ibtl_hca_devinfo_t      *hca_devp;      /* HCA Dev Info */
1543 1543  
1544 1544          IBTF_DPRINTF_L3(ibtf_hca, "ibt_index2pkey_byguid(%llX, %d, %d)",
1545 1545              hca_guid, port_num, pkey_ix);
1546 1546  
1547 1547          mutex_enter(&ibtl_clnt_list_mutex);
1548 1548          hca_devp = ibtl_get_hcadevinfo(hca_guid);
1549 1549          if (hca_devp == NULL) {
1550 1550                  IBTF_DPRINTF_L2(ibtf_hca, "ibt_index2pkey_byguid: "
1551 1551                      "Invalid HCA GUID 0x%llx", hca_guid);
  
    | 
      ↓ open down ↓ | 
    1551 lines elided | 
    
      ↑ open up ↑ | 
  
1552 1552                  mutex_exit(&ibtl_clnt_list_mutex);
1553 1553                  return (IBT_HCA_INVALID);
1554 1554          }
1555 1555          retval = ibtl_index2pkey(hca_devp, port_num, pkey_ix, pkey);
1556 1556          mutex_exit(&ibtl_clnt_list_mutex);
1557 1557  
1558 1558          return (retval);
1559 1559  }
1560 1560  
1561 1561  
1562      -_NOTE(SCHEME_PROTECTS_DATA("client managed", ibtl_hca_s::ha_clnt_private))
1563      -
1564 1562  /*
1565 1563   * Function:
1566 1564   *      ibt_set_hca_private
1567 1565   * Input:
1568 1566   *      hca_hdl         The ibt_hca_hdl_t of the opened HCA.
1569 1567   *      clnt_private    The client private data.
1570 1568   * Output:
1571 1569   *      none.
1572 1570   * Returns:
1573 1571   *      none
1574 1572   * Description:
1575 1573   *      Sets the client private data.
1576 1574   */
1577 1575  void
1578 1576  ibt_set_hca_private(ibt_hca_hdl_t hca_hdl, void *clnt_private)
1579 1577  {
1580 1578          hca_hdl->ha_clnt_private = clnt_private;
1581 1579  }
1582 1580  
1583 1581  
1584 1582  /*
1585 1583   * Function:
1586 1584   *      ibt_get_hca_private
1587 1585   * Input:
1588 1586   *      hca_hdl         The ibt_hca_hdl_t of the opened HCA.
1589 1587   * Output:
1590 1588   *      none
1591 1589   * Returns:
1592 1590   *      The client private data.
1593 1591   * Description:
1594 1592   *      Retrieves the private data from a specified HCA.
1595 1593   */
1596 1594  void *
1597 1595  ibt_get_hca_private(ibt_hca_hdl_t hca_hdl)
1598 1596  {
1599 1597          return (hca_hdl->ha_clnt_private);
1600 1598  }
1601 1599  
1602 1600  /*
1603 1601   * Function:
1604 1602   *      ibt_hca_handle_to_guid
1605 1603   * Input:
1606 1604   *      hca             HCA Handle.
1607 1605   * Output:
1608 1606   *      none.
1609 1607   * Returns:
1610 1608   *      hca_guid        Returned HCA GUID on which the specified Channel is
1611 1609   *                      allocated. Valid if it is non-NULL on return.
1612 1610   * Description:
1613 1611   *      A helper function to retrieve HCA GUID for the specified handle.
1614 1612   */
1615 1613  ib_guid_t
1616 1614  ibt_hca_handle_to_guid(ibt_hca_hdl_t hca)
1617 1615  {
1618 1616          IBTF_DPRINTF_L3(ibtf_hca, "ibt_hca_handle_to_guid(%p)", hca);
1619 1617          return (IBTL_HCA2HCAGUID(hca));
1620 1618  }
1621 1619  
1622 1620  /*
1623 1621   * Function:
1624 1622   *      ibt_hca_guid_to_handle
1625 1623   * Input:
1626 1624   *      ibt_hdl         The handle returned to the client by the IBTF from
1627 1625   *                      an ibt_attach() call.
1628 1626   *      hca_guid        HCA GUID
1629 1627   * Output:
1630 1628   *      hca_hdl         Returned ibt_hca_hdl_t.
1631 1629   * Returns:
1632 1630   *      IBT_SUCCESS
1633 1631   *      IBT_HCA_INVALID
1634 1632   * Description:
1635 1633   *      A helper function to retrieve a hca handle from a HCA GUID.
1636 1634   */
1637 1635  ibt_status_t
1638 1636  ibt_hca_guid_to_handle(ibt_clnt_hdl_t ibt_hdl, ib_guid_t hca_guid,
1639 1637      ibt_hca_hdl_t *hca_hdl)
1640 1638  {
1641 1639          ibtl_hca_t              *hca_infop;
1642 1640          ibtl_hca_devinfo_t      *hca_devp;              /* HCA Dev Info */
1643 1641          ibt_status_t            rval = IBT_HCA_INVALID;
1644 1642  
1645 1643          IBTF_DPRINTF_L3(ibtf_hca, "ibt_hca_guid_to_handle(%p, %llX)",
1646 1644              ibt_hdl, hca_guid);
1647 1645  
1648 1646          mutex_enter(&ibtl_clnt_list_mutex);
1649 1647  
1650 1648          /*
1651 1649           * Get HCA Device Info Structure, referenced by HCA GUID.
1652 1650           */
1653 1651          hca_devp = ibtl_get_hcadevinfo(hca_guid);
1654 1652          if (hca_devp == NULL) {
1655 1653                  /*
1656 1654                   * If we are here, then the requested HCA device is not present.
1657 1655                   * Return the status as Invalid HCA GUID.
1658 1656                   */
1659 1657                  mutex_exit(&ibtl_clnt_list_mutex);
1660 1658  
1661 1659                  IBTF_DPRINTF_L2(ibtf_hca, "ibt_hca_guid_to_handle: "
1662 1660                      "HCA Device Not Found: Invalid HCA GUID");
1663 1661  
1664 1662                  *hca_hdl = NULL;
1665 1663                  return (rval);
1666 1664          }
1667 1665  
1668 1666          /*
1669 1667           * Yes, we found a HCA Device registered with IBTF, which matches with
1670 1668           * the requested HCA_GUID.
1671 1669           */
1672 1670          hca_infop = hca_devp->hd_clnt_list;
1673 1671  
1674 1672          while (hca_infop != NULL) {
1675 1673                  if (ibt_hdl == hca_infop->ha_clnt_devp) {
1676 1674                          rval = IBT_SUCCESS;
1677 1675                          break;
1678 1676                  }
1679 1677                  hca_infop = hca_infop->ha_clnt_link;
1680 1678          }
1681 1679  
1682 1680          mutex_exit(&ibtl_clnt_list_mutex);
1683 1681          *hca_hdl = hca_infop;
1684 1682          return (rval);
1685 1683  }
  
    | 
      ↓ open down ↓ | 
    112 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX