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
↓ 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  /*
↓ 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)
↓ 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];
↓ open down ↓ 298 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX