Print this page
    
4233 mptsas topo change buffer overflow
    
      
        | Split | Close | 
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_smhba.c
          +++ new/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_smhba.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
  
    | ↓ open down ↓ | 13 lines elided | ↑ open up ↑ | 
  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  /*
  23   23   * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
       24 + * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  24   25   */
  25   26  /*
  26   27   * This file contains SM-HBA support for MPT SAS driver
  27   28   */
  28   29  
  29   30  #if defined(lint) || defined(DEBUG)
  30   31  #define MPTSAS_DEBUG
  31   32  #endif
  32   33  
  33   34  /*
  34   35   * standard header files
  35   36   */
  36   37  #include <sys/note.h>
  37   38  #include <sys/scsi/scsi.h>
  38   39  #include <sys/pci.h>
  39   40  #include <sys/scsi/generic/sas.h>
  40   41  #include <sys/scsi/impl/scsi_sas.h>
  41   42  
  42   43  #pragma pack(1)
  43   44  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
  44   45  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
  45   46  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
  46   47  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
  47   48  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
  48   49  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
  49   50  #pragma pack()
  50   51  
  51   52  /*
  
    | ↓ open down ↓ | 18 lines elided | ↑ open up ↑ | 
  52   53   * private header files.
  53   54   */
  54   55  #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
  55   56  #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h>
  56   57  
  57   58  /*
  58   59   * SM - HBA statics
  59   60   */
  60   61  extern char *mptsas_driver_rev;
  61   62  
       63 +static void mptsas_smhba_create_phy_props(nvlist_t **, smhba_info_t *, uint8_t,
       64 +    uint16_t *);
       65 +static void mptsas_smhba_update_phy_props(mptsas_t *, dev_info_t *, nvlist_t **,
       66 +    uint8_t);
       67 +
  62   68  static void
  63   69  mptsas_smhba_add_hba_prop(mptsas_t *mpt, data_type_t dt,
  64   70      char *prop_name, void *prop_val);
  65   71  
  66   72  void
  67   73  mptsas_smhba_show_phy_info(mptsas_t *mpt);
  68   74  
  69   75  static void
  70   76  mptsas_smhba_add_hba_prop(mptsas_t *mpt, data_type_t dt,
  71   77      char *prop_name, void *prop_val)
  72   78  {
  73   79          ASSERT(mpt != NULL);
  74   80  
  75   81          switch (dt) {
  76   82          case DATA_TYPE_INT32:
  77   83                  if (ddi_prop_update_int(DDI_DEV_T_NONE, mpt->m_dip,
  78   84                      prop_name, *(int *)prop_val)) {
  79   85                          mptsas_log(mpt, CE_WARN,
  80   86                              "%s: %s prop update failed", __func__, prop_name);
  81   87                  }
  82   88                  break;
  83   89          case DATA_TYPE_STRING:
  84   90                  if (ddi_prop_update_string(DDI_DEV_T_NONE, mpt->m_dip,
  85   91                      prop_name, (char *)prop_val)) {
  86   92                          mptsas_log(mpt, CE_WARN,
  87   93                              "%s: %s prop update failed", __func__, prop_name);
  88   94                  }
  89   95                  break;
  90   96          default:
  91   97                  mptsas_log(mpt, CE_WARN, "%s: "
  92   98                      "Unhandled datatype(%d) for (%s). Skipping prop update.",
  93   99                      __func__, dt, prop_name);
  94  100          }
  95  101  }
  96  102  
  97  103  void
  98  104  mptsas_smhba_show_phy_info(mptsas_t *mpt)
  99  105  {
 100  106          int i;
 101  107  
 102  108          ASSERT(mpt != NULL);
 103  109  
 104  110          for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
 105  111                  mptsas_log(mpt, CE_WARN,
 106  112                      "phy %d, Owner hdl:0x%x, attached hdl: 0x%x,"
 107  113                      "attached phy identifier %d,Program link rate 0x%x,"
 108  114                      "hw link rate 0x%x, negotiator link rate 0x%x, path %s",
  
    | ↓ open down ↓ | 37 lines elided | ↑ open up ↑ | 
 109  115                      i, mpt->m_phy_info[i].smhba_info.owner_devhdl,
 110  116                      mpt->m_phy_info[i].smhba_info.attached_devhdl,
 111  117                      mpt->m_phy_info[i].smhba_info.attached_phy_identify,
 112  118                      mpt->m_phy_info[i].smhba_info.programmed_link_rate,
 113  119                      mpt->m_phy_info[i].smhba_info.hw_link_rate,
 114  120                      mpt->m_phy_info[i].smhba_info.negotiated_link_rate,
 115  121                      mpt->m_phy_info[i].smhba_info.path);
 116  122          }
 117  123  }
 118  124  
 119      -void
 120      -mptsas_smhba_set_phy_props(mptsas_t *mpt, char *iport, dev_info_t *dip,
 121      -    uint8_t phy_nums, uint16_t *attached_devhdl)
      125 +static void
      126 +mptsas_smhba_create_phy_props(nvlist_t **phy_props, smhba_info_t *pSmhba,
      127 +    uint8_t phy_id, uint16_t *attached_devhdl)
 122  128  {
 123      -        int             i;
 124      -        int             j = 0;
      129 +        (void) nvlist_alloc(phy_props, NV_UNIQUE_NAME, KM_SLEEP);
      130 +        (void) nvlist_add_uint8(*phy_props, SAS_PHY_ID, phy_id);
      131 +        (void) nvlist_add_uint8(*phy_props, "phyState",
      132 +            (pSmhba->negotiated_link_rate & 0x0f));
      133 +        (void) nvlist_add_int8(*phy_props, SAS_NEG_LINK_RATE,
      134 +            (pSmhba->negotiated_link_rate & 0x0f));
      135 +        (void) nvlist_add_int8(*phy_props, SAS_PROG_MIN_LINK_RATE,
      136 +            (pSmhba->programmed_link_rate & 0x0f));
      137 +        (void) nvlist_add_int8(*phy_props, SAS_HW_MIN_LINK_RATE,
      138 +            (pSmhba->hw_link_rate & 0x0f));
      139 +        (void) nvlist_add_int8(*phy_props, SAS_PROG_MAX_LINK_RATE,
      140 +            ((pSmhba->programmed_link_rate & 0xf0) >> 4));
      141 +        (void) nvlist_add_int8(*phy_props, SAS_HW_MAX_LINK_RATE,
      142 +            ((pSmhba->hw_link_rate & 0xf0) >> 4));
      143 +
      144 +        if (pSmhba->attached_devhdl && (attached_devhdl != NULL))
      145 +                *attached_devhdl = pSmhba->attached_devhdl;
      146 +}
      147 +
      148 +static void
      149 +mptsas_smhba_update_phy_props(mptsas_t *mpt, dev_info_t *dip,
      150 +    nvlist_t **phy_props, uint8_t phy_nums)
      151 +{
 125  152          int             rval;
 126  153          size_t          packed_size;
 127  154          char            *packed_data = NULL;
 128      -        char            phymask[MPTSAS_MAX_PHYS];
 129      -        nvlist_t        **phy_props;
 130  155          nvlist_t        *nvl;
 131      -        smhba_info_t    *pSmhba = NULL;
 132  156  
 133      -        if (phy_nums == 0) {
      157 +        if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP) != 0) {
      158 +                mptsas_log(mpt, CE_WARN, "%s: nvlist_alloc() failed", __func__);
 134  159                  return;
 135  160          }
 136      -        if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
 137      -                mptsas_log(mpt, CE_WARN, "%s: nvlist_alloc() failed", __func__);
 138      -        }
 139  161  
 140      -        phy_props = kmem_zalloc(sizeof (nvlist_t *) * phy_nums,
 141      -            KM_SLEEP);
 142      -
 143      -        for (i = 0; i < mpt->m_num_phys; i++) {
 144      -
 145      -                bzero(phymask, sizeof (phymask));
 146      -                (void) sprintf(phymask, "%x", mpt->m_phy_info[i].phy_mask);
 147      -                if (strcmp(phymask, iport) == 0) {
 148      -                        pSmhba = &mpt->m_phy_info[i].smhba_info;
 149      -                        (void) nvlist_alloc(&phy_props[j], NV_UNIQUE_NAME, 0);
 150      -                        (void) nvlist_add_uint8(phy_props[j], SAS_PHY_ID, i);
 151      -                        (void) nvlist_add_uint8(phy_props[j],
 152      -                            "phyState",
 153      -                            (pSmhba->negotiated_link_rate
 154      -                            & 0x0f));
 155      -                        (void) nvlist_add_int8(phy_props[j],
 156      -                            SAS_NEG_LINK_RATE,
 157      -                            (pSmhba->negotiated_link_rate
 158      -                            & 0x0f));
 159      -                        (void) nvlist_add_int8(phy_props[j],
 160      -                            SAS_PROG_MIN_LINK_RATE,
 161      -                            (pSmhba->programmed_link_rate
 162      -                            & 0x0f));
 163      -                        (void) nvlist_add_int8(phy_props[j],
 164      -                            SAS_HW_MIN_LINK_RATE,
 165      -                            (pSmhba->hw_link_rate
 166      -                            & 0x0f));
 167      -                        (void) nvlist_add_int8(phy_props[j],
 168      -                            SAS_PROG_MAX_LINK_RATE,
 169      -                            ((pSmhba->programmed_link_rate
 170      -                            & 0xf0) >> 4));
 171      -                        (void) nvlist_add_int8(phy_props[j],
 172      -                            SAS_HW_MAX_LINK_RATE,
 173      -                            ((pSmhba->hw_link_rate
 174      -                            & 0xf0) >> 4));
 175      -
 176      -                        j++;
 177      -
 178      -                        if (pSmhba->attached_devhdl &&
 179      -                            (attached_devhdl != NULL)) {
 180      -                                *attached_devhdl =
 181      -                                    pSmhba->attached_devhdl;
 182      -                        }
 183      -                }
 184      -        }
 185      -
 186  162          rval = nvlist_add_nvlist_array(nvl, SAS_PHY_INFO_NVL, phy_props,
 187  163              phy_nums);
 188  164          if (rval) {
 189  165                  mptsas_log(mpt, CE_WARN,
 190      -                    " nv list array add failed, return value %d.",
 191      -                    rval);
      166 +                    " nv list array add failed, return value %d.", rval);
 192  167                  goto exit;
 193  168          }
 194  169          (void) nvlist_size(nvl, &packed_size, NV_ENCODE_NATIVE);
 195  170          packed_data = kmem_zalloc(packed_size, KM_SLEEP);
 196  171          (void) nvlist_pack(nvl, &packed_data, &packed_size,
 197  172              NV_ENCODE_NATIVE, 0);
 198  173  
 199  174          (void) ddi_prop_update_byte_array(DDI_DEV_T_NONE, dip,
 200  175              SAS_PHY_INFO, (uchar_t *)packed_data, packed_size);
 201  176  
 202  177  exit:
 203      -        for (i = 0; i < phy_nums && phy_props[i] != NULL; i++) {
 204      -                nvlist_free(phy_props[i]);
 205      -        }
 206  178          nvlist_free(nvl);
 207      -        kmem_free(phy_props, sizeof (nvlist_t *) * phy_nums);
 208  179  
 209  180          if (packed_data != NULL) {
 210  181                  kmem_free(packed_data, packed_size);
 211  182          }
 212  183  }
 213  184  
      185 +void
      186 +mptsas_smhba_set_one_phy_props(mptsas_t *mpt, dev_info_t *dip, uint8_t phy_id,
      187 +    uint16_t *attached_devhdl)
      188 +{
      189 +        nvlist_t        *phy_props;
      190 +
      191 +        ASSERT(phy_id < mpt->m_num_phys);
      192 +
      193 +        mptsas_smhba_create_phy_props(&phy_props,
      194 +            &mpt->m_phy_info[phy_id].smhba_info, phy_id, attached_devhdl);
      195 +
      196 +        mptsas_smhba_update_phy_props(mpt, dip, &phy_props, 1);
      197 +
      198 +        nvlist_free(phy_props);
      199 +}
      200 +
      201 +void
      202 +mptsas_smhba_set_all_phy_props(mptsas_t *mpt, dev_info_t *dip, uint8_t phy_nums,
      203 +    mptsas_phymask_t phy_mask, uint16_t *attached_devhdl)
      204 +{
      205 +        int             i, j;
      206 +        nvlist_t        **phy_props;
      207 +
      208 +        if (phy_nums == 0)
      209 +                return;
      210 +
      211 +        phy_props = kmem_zalloc(sizeof (nvlist_t *) * phy_nums, KM_SLEEP);
      212 +
      213 +        for (i = 0, j = 0; i < mpt->m_num_phys && j < phy_nums; i++)
      214 +                if (phy_mask == mpt->m_phy_info[i].phy_mask)
      215 +                        mptsas_smhba_create_phy_props(&phy_props[j++],
      216 +                            &mpt->m_phy_info[i].smhba_info, i, attached_devhdl);
      217 +
      218 +        mptsas_smhba_update_phy_props(mpt, dip, phy_props, j);
      219 +
      220 +        for (i = 0; i < j && phy_props[i] != NULL; i++)
      221 +                nvlist_free(phy_props[i]);
      222 +
      223 +        kmem_free(phy_props, sizeof (nvlist_t *) * phy_nums);
      224 +}
      225 +
 214  226  /*
 215  227   * Called with PHY lock held on phyp
 216  228   */
 217  229  void
 218  230  mptsas_smhba_log_sysevent(mptsas_t *mpt, char *subclass, char *etype,
 219  231      smhba_info_t *phyp)
 220  232  {
 221  233          nvlist_t        *attr_list;
 222  234          char            *pname;
 223  235          char            sas_addr[MPTSAS_WWN_STRLEN];
 224  236          uint8_t         phynum = 0;
 225  237          uint8_t         lrate = 0;
 226  238  
 227  239          if (mpt->m_dip == NULL)
 228  240                  return;
 229  241          if (phyp == NULL)
 230  242                  return;
 231  243  
 232  244          pname = kmem_zalloc(MAXPATHLEN, KM_NOSLEEP);
 233  245          if (pname == NULL)
 234  246                  return;
 235  247  
 236  248          if ((strcmp(subclass, ESC_SAS_PHY_EVENT) == 0) ||
 237  249              (strcmp(subclass, ESC_SAS_HBA_PORT_BROADCAST) == 0)) {
 238  250                  ASSERT(phyp != NULL);
 239  251                  (void) strncpy(pname, phyp->path, strlen(phyp->path));
 240  252                  phynum = phyp->phy_id;
 241  253                  bzero(sas_addr, sizeof (sas_addr));
 242  254                  (void) sprintf(sas_addr, "w%016"PRIx64, phyp->sas_addr);
 243  255                  if (strcmp(etype, SAS_PHY_ONLINE) == 0) {
 244  256                          lrate = phyp->negotiated_link_rate;
 245  257                  }
 246  258          }
 247  259          if (strcmp(subclass, ESC_SAS_HBA_PORT_BROADCAST) == 0) {
 248  260                  (void) ddi_pathname(mpt->m_dip, pname);
 249  261          }
 250  262  
 251  263          if (nvlist_alloc(&attr_list, NV_UNIQUE_NAME_TYPE, 0) != 0) {
 252  264                  mptsas_log(mpt, CE_WARN,
 253  265                      "%s: Failed to post sysevent", __func__);
 254  266                  kmem_free(pname, MAXPATHLEN);
 255  267                  return;
 256  268          }
 257  269  
 258  270          if (nvlist_add_int32(attr_list, SAS_DRV_INST,
 259  271              ddi_get_instance(mpt->m_dip)) != 0)
 260  272                  goto fail;
 261  273  
 262  274          if (nvlist_add_string(attr_list, SAS_PORT_ADDR, sas_addr) != 0)
 263  275                  goto fail;
 264  276  
 265  277          if (nvlist_add_string(attr_list, SAS_DEVFS_PATH, pname) != 0)
 266  278                  goto fail;
 267  279  
 268  280          if (nvlist_add_uint8(attr_list, SAS_PHY_ID, phynum) != 0)
 269  281                  goto fail;
 270  282  
 271  283          if (strcmp(etype, SAS_PHY_ONLINE) == 0) {
 272  284                  if (nvlist_add_uint8(attr_list, SAS_LINK_RATE, lrate) != 0)
 273  285                          goto fail;
 274  286          }
 275  287  
 276  288          if (nvlist_add_string(attr_list, SAS_EVENT_TYPE, etype) != 0)
 277  289                  goto fail;
 278  290  
 279  291          (void) ddi_log_sysevent(mpt->m_dip, DDI_VENDOR_SUNW, EC_HBA, subclass,
 280  292              attr_list, NULL, DDI_NOSLEEP);
 281  293  
 282  294  fail:
 283  295          kmem_free(pname, MAXPATHLEN);
 284  296          nvlist_free(attr_list);
 285  297  }
 286  298  
 287  299  void
 288  300  mptsas_create_phy_stats(mptsas_t *mpt, char *iport, dev_info_t *dip)
 289  301  {
 290  302          sas_phy_stats_t         *ps;
 291  303          smhba_info_t            *phyp;
 292  304          int                     ndata;
 293  305          char                    ks_name[KSTAT_STRLEN];
 294  306          char                    phymask[MPTSAS_MAX_PHYS];
 295  307          int                     i;
 296  308  
 297  309          ASSERT(iport != NULL);
 298  310          ASSERT(mpt != NULL);
 299  311  
 300  312          for (i = 0; i < mpt->m_num_phys; i++) {
 301  313  
 302  314                  bzero(phymask, sizeof (phymask));
 303  315                  (void) sprintf(phymask, "%x", mpt->m_phy_info[i].phy_mask);
 304  316                  if (strcmp(phymask, iport) == 0) {
 305  317  
 306  318                          phyp = &mpt->m_phy_info[i].smhba_info;
 307  319                          mutex_enter(&phyp->phy_mutex);
 308  320  
 309  321                          if (phyp->phy_stats != NULL) {
 310  322                                  mutex_exit(&phyp->phy_mutex);
 311  323                                  /* We've already created this kstat instance */
 312  324                                  continue;
 313  325                          }
 314  326  
 315  327                          ndata = (sizeof (sas_phy_stats_t)/
 316  328                              sizeof (kstat_named_t));
 317  329                          (void) snprintf(ks_name, sizeof (ks_name),
 318  330                              "%s.%llx.%d.%d", ddi_driver_name(dip),
 319  331                              (longlong_t)mpt->un.m_base_wwid,
 320  332                              ddi_get_instance(dip), i);
 321  333  
 322  334                          phyp->phy_stats = kstat_create("mptsas",
 323  335                              ddi_get_instance(dip), ks_name, KSTAT_SAS_PHY_CLASS,
 324  336                              KSTAT_TYPE_NAMED, ndata, 0);
 325  337  
 326  338                          if (phyp->phy_stats == NULL) {
 327  339                                  mutex_exit(&phyp->phy_mutex);
 328  340                                  mptsas_log(mpt, CE_WARN,
 329  341                                      "%s: Failed to create %s kstats", __func__,
 330  342                                      ks_name);
 331  343                                  continue;
 332  344                          }
 333  345  
 334  346                          ps = (sas_phy_stats_t *)phyp->phy_stats->ks_data;
 335  347  
 336  348                          kstat_named_init(&ps->seconds_since_last_reset,
 337  349                              "SecondsSinceLastReset", KSTAT_DATA_ULONGLONG);
 338  350                          kstat_named_init(&ps->tx_frames,
 339  351                              "TxFrames", KSTAT_DATA_ULONGLONG);
 340  352                          kstat_named_init(&ps->rx_frames,
 341  353                              "RxFrames", KSTAT_DATA_ULONGLONG);
 342  354                          kstat_named_init(&ps->tx_words,
 343  355                              "TxWords", KSTAT_DATA_ULONGLONG);
 344  356                          kstat_named_init(&ps->rx_words,
 345  357                              "RxWords", KSTAT_DATA_ULONGLONG);
 346  358                          kstat_named_init(&ps->invalid_dword_count,
 347  359                              "InvalidDwordCount", KSTAT_DATA_ULONGLONG);
 348  360                          kstat_named_init(&ps->running_disparity_error_count,
 349  361                              "RunningDisparityErrorCount", KSTAT_DATA_ULONGLONG);
 350  362                          kstat_named_init(&ps->loss_of_dword_sync_count,
 351  363                              "LossofDwordSyncCount", KSTAT_DATA_ULONGLONG);
 352  364                          kstat_named_init(&ps->phy_reset_problem_count,
 353  365                              "PhyResetProblemCount", KSTAT_DATA_ULONGLONG);
 354  366  
 355  367                          phyp->phy_stats->ks_private = phyp;
 356  368                          phyp->phy_stats->ks_update = mptsas_update_phy_stats;
 357  369                          kstat_install(phyp->phy_stats);
 358  370                          mutex_exit(&phyp->phy_mutex);
 359  371                  }
 360  372          }
 361  373  }
 362  374  
 363  375  int
 364  376  mptsas_update_phy_stats(kstat_t *ks, int rw)
 365  377  {
 366  378          int                     ret = DDI_FAILURE;
 367  379          smhba_info_t            *pptr = NULL;
 368  380          sas_phy_stats_t         *ps = ks->ks_data;
 369  381          uint32_t                page_address;
 370  382          mptsas_t                *mpt;
 371  383  
 372  384          _NOTE(ARGUNUSED(rw));
 373  385  
 374  386          pptr = (smhba_info_t *)ks->ks_private;
 375  387          ASSERT((pptr != NULL));
 376  388          mpt = (mptsas_t *)pptr->mpt;
 377  389          ASSERT((mpt != NULL));
 378  390          page_address = (MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | pptr->phy_id);
 379  391  
 380  392          /*
 381  393           * We just want to lock against other invocations of kstat;
 382  394           * we don't need to pmcs_lock_phy() for this.
 383  395           */
 384  396          mutex_enter(&mpt->m_mutex);
 385  397  
 386  398          ret = mptsas_get_sas_phy_page1(pptr->mpt, page_address, pptr);
 387  399  
 388  400          if (ret == DDI_FAILURE)
 389  401                  goto fail;
 390  402  
 391  403          ps->invalid_dword_count.value.ull =
 392  404              (unsigned long long)pptr->invalid_dword_count;
 393  405  
 394  406          ps->running_disparity_error_count.value.ull =
 395  407              (unsigned long long)pptr->running_disparity_error_count;
 396  408  
 397  409          ps->loss_of_dword_sync_count.value.ull =
 398  410              (unsigned long long)pptr->loss_of_dword_sync_count;
 399  411  
 400  412          ps->phy_reset_problem_count.value.ull =
 401  413              (unsigned long long)pptr->phy_reset_problem_count;
 402  414  
 403  415          ret = DDI_SUCCESS;
 404  416  fail:
 405  417          mutex_exit(&mpt->m_mutex);
 406  418  
 407  419          return (ret);
 408  420  }
 409  421  
 410  422  void
 411  423  mptsas_destroy_phy_stats(mptsas_t *mpt)
 412  424  {
 413  425          smhba_info_t    *phyp;
 414  426          int                     i = 0;
 415  427  
 416  428          ASSERT(mpt != NULL);
 417  429  
 418  430          for (i = 0; i < mpt->m_num_phys; i++) {
 419  431                  phyp = &mpt->m_phy_info[i].smhba_info;
 420  432                  if (phyp == NULL) {
 421  433                          continue;
 422  434                  }
 423  435  
 424  436                  mutex_enter(&phyp->phy_mutex);
 425  437                  if (phyp->phy_stats != NULL) {
 426  438                          kstat_delete(phyp->phy_stats);
 427  439                          phyp->phy_stats = NULL;
 428  440                  }
 429  441                  mutex_exit(&phyp->phy_mutex);
 430  442          }
 431  443  }
 432  444  
 433  445  int
 434  446  mptsas_smhba_phy_init(mptsas_t *mpt)
 435  447  {
 436  448          int             i = 0;
 437  449          int             rval = DDI_SUCCESS;
 438  450          uint32_t        page_address;
 439  451  
 440  452          ASSERT(mutex_owned(&mpt->m_mutex));
 441  453  
 442  454          for (i = 0; i < mpt->m_num_phys; i++) {
 443  455                  page_address =
 444  456                      (MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER |
 445  457                      (MPI2_SAS_PHY_PGAD_PHY_NUMBER_MASK & i));
 446  458                  rval = mptsas_get_sas_phy_page0(mpt,
 447  459                      page_address, &mpt->m_phy_info[i].smhba_info);
 448  460                  if (rval != DDI_SUCCESS) {
 449  461                          mptsas_log(mpt, CE_WARN,
 450  462                              "Failed to get sas phy page 0"
 451  463                              " for each phy");
 452  464                          return (DDI_FAILURE);
 453  465                  }
 454  466                  mpt->m_phy_info[i].smhba_info.phy_id = (uint8_t)i;
 455  467                  mpt->m_phy_info[i].smhba_info.sas_addr =
 456  468                      mpt->un.m_base_wwid + i;
 457  469                  mpt->m_phy_info[i].smhba_info.mpt = mpt;
 458  470          }
 459  471          return (DDI_SUCCESS);
 460  472  }
 461  473  
 462  474  int
 463  475  mptsas_smhba_setup(mptsas_t *mpt)
 464  476  {
 465  477          int             sm_hba = 1;
 466  478          char            chiprev, hw_rev[24];
 467  479          char            serial_number[72];
 468  480          int             protocol = 0;
 469  481  
 470  482          mutex_enter(&mpt->m_mutex);
 471  483          if (mptsas_smhba_phy_init(mpt)) {
 472  484                  mutex_exit(&mpt->m_mutex);
 473  485                  return (DDI_FAILURE);
 474  486          }
 475  487          mutex_exit(&mpt->m_mutex);
 476  488  
 477  489          /* SM-HBA support */
 478  490          mptsas_smhba_add_hba_prop(mpt, DATA_TYPE_INT32, MPTSAS_SMHBA_SUPPORTED,
 479  491              &sm_hba);
 480  492  
 481  493          /* SM-HBA driver version */
 482  494          mptsas_smhba_add_hba_prop(mpt, DATA_TYPE_STRING, MPTSAS_DRV_VERSION,
 483  495              mptsas_driver_rev);
 484  496  
 485  497          /* SM-HBA hardware version */
 486  498          chiprev = 'A' + mpt->m_revid;
 487  499          (void) snprintf(hw_rev, 2, "%s", &chiprev);
 488  500          mptsas_smhba_add_hba_prop(mpt, DATA_TYPE_STRING, MPTSAS_HWARE_VERSION,
 489  501              hw_rev);
 490  502  
 491  503          /* SM-HBA phy number per HBA */
 492  504          mptsas_smhba_add_hba_prop(mpt, DATA_TYPE_INT32, MPTSAS_NUM_PHYS_HBA,
 493  505              &(mpt->m_num_phys));
 494  506  
 495  507          /* SM-HBA protocal support */
 496  508          protocol = SAS_SSP_SUPPORT | SAS_SATA_SUPPORT | SAS_SMP_SUPPORT;
 497  509          mptsas_smhba_add_hba_prop(mpt, DATA_TYPE_INT32,
 498  510              MPTSAS_SUPPORTED_PROTOCOL, &protocol);
 499  511  
 500  512          mptsas_smhba_add_hba_prop(mpt, DATA_TYPE_STRING, MPTSAS_MANUFACTURER,
 501  513              mpt->m_MANU_page0.ChipName);
 502  514  
 503  515          mptsas_smhba_add_hba_prop(mpt, DATA_TYPE_STRING, MPTSAS_MODEL_NAME,
 504  516              mpt->m_MANU_page0.BoardName);
 505  517  
 506  518          /*
 507  519           * VPD data is not available, we make a serial number for this.
 508  520           */
 509  521  
 510  522          (void) sprintf(serial_number, "%s%s%s%s%s",
 511  523              mpt->m_MANU_page0.ChipName,
 512  524              mpt->m_MANU_page0.ChipRevision,
 513  525              mpt->m_MANU_page0.BoardName,
 514  526              mpt->m_MANU_page0.BoardAssembly,
 515  527              mpt->m_MANU_page0.BoardTracerNumber);
 516  528  
 517  529          mptsas_smhba_add_hba_prop(mpt, DATA_TYPE_STRING, MPTSAS_SERIAL_NUMBER,
 518  530              &serial_number[0]);
 519  531  
 520  532          return (DDI_SUCCESS);
 521  533  }
  
    | ↓ open down ↓ | 298 lines elided | ↑ open up ↑ | 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX