Print this page
4233 mptsas topo change buffer overflow


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.

  24  */
  25 /*
  26  * This file contains SM-HBA support for MPT SAS driver
  27  */
  28 
  29 #if defined(lint) || defined(DEBUG)
  30 #define MPTSAS_DEBUG
  31 #endif
  32 
  33 /*
  34  * standard header files
  35  */
  36 #include <sys/note.h>
  37 #include <sys/scsi/scsi.h>
  38 #include <sys/pci.h>
  39 #include <sys/scsi/generic/sas.h>
  40 #include <sys/scsi/impl/scsi_sas.h>
  41 
  42 #pragma pack(1)
  43 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
  44 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
  45 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
  46 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
  47 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
  48 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
  49 #pragma pack()
  50 
  51 /*
  52  * private header files.
  53  */
  54 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
  55 #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h>
  56 
  57 /*
  58  * SM - HBA statics
  59  */
  60 extern char *mptsas_driver_rev;
  61 





  62 static void
  63 mptsas_smhba_add_hba_prop(mptsas_t *mpt, data_type_t dt,
  64     char *prop_name, void *prop_val);
  65 
  66 void
  67 mptsas_smhba_show_phy_info(mptsas_t *mpt);
  68 
  69 static void
  70 mptsas_smhba_add_hba_prop(mptsas_t *mpt, data_type_t dt,
  71     char *prop_name, void *prop_val)
  72 {
  73         ASSERT(mpt != NULL);
  74 
  75         switch (dt) {
  76         case DATA_TYPE_INT32:
  77                 if (ddi_prop_update_int(DDI_DEV_T_NONE, mpt->m_dip,
  78                     prop_name, *(int *)prop_val)) {
  79                         mptsas_log(mpt, CE_WARN,
  80                             "%s: %s prop update failed", __func__, prop_name);
  81                 }


  99 {
 100         int i;
 101 
 102         ASSERT(mpt != NULL);
 103 
 104         for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
 105                 mptsas_log(mpt, CE_WARN,
 106                     "phy %d, Owner hdl:0x%x, attached hdl: 0x%x,"
 107                     "attached phy identifier %d,Program link rate 0x%x,"
 108                     "hw link rate 0x%x, negotiator link rate 0x%x, path %s",
 109                     i, mpt->m_phy_info[i].smhba_info.owner_devhdl,
 110                     mpt->m_phy_info[i].smhba_info.attached_devhdl,
 111                     mpt->m_phy_info[i].smhba_info.attached_phy_identify,
 112                     mpt->m_phy_info[i].smhba_info.programmed_link_rate,
 113                     mpt->m_phy_info[i].smhba_info.hw_link_rate,
 114                     mpt->m_phy_info[i].smhba_info.negotiated_link_rate,
 115                     mpt->m_phy_info[i].smhba_info.path);
 116         }
 117 }
 118 
 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)
 122 {
 123         int             i;
 124         int             j = 0;





















 125         int             rval;
 126         size_t          packed_size;
 127         char            *packed_data = NULL;
 128         char            phymask[MPTSAS_MAX_PHYS];
 129         nvlist_t        **phy_props;
 130         nvlist_t        *nvl;
 131         smhba_info_t    *pSmhba = NULL;
 132 
 133         if (phy_nums == 0) {

 134                 return;
 135         }
 136         if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
 137                 mptsas_log(mpt, CE_WARN, "%s: nvlist_alloc() failed", __func__);
 138         }
 139 
 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         rval = nvlist_add_nvlist_array(nvl, SAS_PHY_INFO_NVL, phy_props,
 187             phy_nums);
 188         if (rval) {
 189                 mptsas_log(mpt, CE_WARN,
 190                     " nv list array add failed, return value %d.",
 191                     rval);
 192                 goto exit;
 193         }
 194         (void) nvlist_size(nvl, &packed_size, NV_ENCODE_NATIVE);
 195         packed_data = kmem_zalloc(packed_size, KM_SLEEP);
 196         (void) nvlist_pack(nvl, &packed_data, &packed_size,
 197             NV_ENCODE_NATIVE, 0);
 198 
 199         (void) ddi_prop_update_byte_array(DDI_DEV_T_NONE, dip,
 200             SAS_PHY_INFO, (uchar_t *)packed_data, packed_size);
 201 
 202 exit:
 203         for (i = 0; i < phy_nums && phy_props[i] != NULL; i++) {
 204                 nvlist_free(phy_props[i]);
 205         }
 206         nvlist_free(nvl);
 207         kmem_free(phy_props, sizeof (nvlist_t *) * phy_nums);
 208 
 209         if (packed_data != NULL) {
 210                 kmem_free(packed_data, packed_size);
 211         }
 212 }
 213 









































 214 /*
 215  * Called with PHY lock held on phyp
 216  */
 217 void
 218 mptsas_smhba_log_sysevent(mptsas_t *mpt, char *subclass, char *etype,
 219     smhba_info_t *phyp)
 220 {
 221         nvlist_t        *attr_list;
 222         char            *pname;
 223         char            sas_addr[MPTSAS_WWN_STRLEN];
 224         uint8_t         phynum = 0;
 225         uint8_t         lrate = 0;
 226 
 227         if (mpt->m_dip == NULL)
 228                 return;
 229         if (phyp == NULL)
 230                 return;
 231 
 232         pname = kmem_zalloc(MAXPATHLEN, KM_NOSLEEP);
 233         if (pname == NULL)




   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  25  */
  26 /*
  27  * This file contains SM-HBA support for MPT SAS driver
  28  */
  29 
  30 #if defined(lint) || defined(DEBUG)
  31 #define MPTSAS_DEBUG
  32 #endif
  33 
  34 /*
  35  * standard header files
  36  */
  37 #include <sys/note.h>
  38 #include <sys/scsi/scsi.h>
  39 #include <sys/pci.h>
  40 #include <sys/scsi/generic/sas.h>
  41 #include <sys/scsi/impl/scsi_sas.h>
  42 
  43 #pragma pack(1)
  44 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
  45 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
  46 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
  47 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
  48 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
  49 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
  50 #pragma pack()
  51 
  52 /*
  53  * private header files.
  54  */
  55 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
  56 #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h>
  57 
  58 /*
  59  * SM - HBA statics
  60  */
  61 extern char *mptsas_driver_rev;
  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 
  68 static void
  69 mptsas_smhba_add_hba_prop(mptsas_t *mpt, data_type_t dt,
  70     char *prop_name, void *prop_val);
  71 
  72 void
  73 mptsas_smhba_show_phy_info(mptsas_t *mpt);
  74 
  75 static void
  76 mptsas_smhba_add_hba_prop(mptsas_t *mpt, data_type_t dt,
  77     char *prop_name, void *prop_val)
  78 {
  79         ASSERT(mpt != NULL);
  80 
  81         switch (dt) {
  82         case DATA_TYPE_INT32:
  83                 if (ddi_prop_update_int(DDI_DEV_T_NONE, mpt->m_dip,
  84                     prop_name, *(int *)prop_val)) {
  85                         mptsas_log(mpt, CE_WARN,
  86                             "%s: %s prop update failed", __func__, prop_name);
  87                 }


 105 {
 106         int i;
 107 
 108         ASSERT(mpt != NULL);
 109 
 110         for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
 111                 mptsas_log(mpt, CE_WARN,
 112                     "phy %d, Owner hdl:0x%x, attached hdl: 0x%x,"
 113                     "attached phy identifier %d,Program link rate 0x%x,"
 114                     "hw link rate 0x%x, negotiator link rate 0x%x, path %s",
 115                     i, mpt->m_phy_info[i].smhba_info.owner_devhdl,
 116                     mpt->m_phy_info[i].smhba_info.attached_devhdl,
 117                     mpt->m_phy_info[i].smhba_info.attached_phy_identify,
 118                     mpt->m_phy_info[i].smhba_info.programmed_link_rate,
 119                     mpt->m_phy_info[i].smhba_info.hw_link_rate,
 120                     mpt->m_phy_info[i].smhba_info.negotiated_link_rate,
 121                     mpt->m_phy_info[i].smhba_info.path);
 122         }
 123 }
 124 
 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)
 128 {
 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 {
 152         int             rval;
 153         size_t          packed_size;
 154         char            *packed_data = NULL;


 155         nvlist_t        *nvl;

 156 
 157         if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP) != 0) {
 158                 mptsas_log(mpt, CE_WARN, "%s: nvlist_alloc() failed", __func__);
 159                 return;
 160         }



 161 














































 162         rval = nvlist_add_nvlist_array(nvl, SAS_PHY_INFO_NVL, phy_props,
 163             phy_nums);
 164         if (rval) {
 165                 mptsas_log(mpt, CE_WARN,
 166                     " nv list array add failed, return value %d.", rval);

 167                 goto exit;
 168         }
 169         (void) nvlist_size(nvl, &packed_size, NV_ENCODE_NATIVE);
 170         packed_data = kmem_zalloc(packed_size, KM_SLEEP);
 171         (void) nvlist_pack(nvl, &packed_data, &packed_size,
 172             NV_ENCODE_NATIVE, 0);
 173 
 174         (void) ddi_prop_update_byte_array(DDI_DEV_T_NONE, dip,
 175             SAS_PHY_INFO, (uchar_t *)packed_data, packed_size);
 176 
 177 exit:



 178         nvlist_free(nvl);

 179 
 180         if (packed_data != NULL) {
 181                 kmem_free(packed_data, packed_size);
 182         }
 183 }
 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 
 226 /*
 227  * Called with PHY lock held on phyp
 228  */
 229 void
 230 mptsas_smhba_log_sysevent(mptsas_t *mpt, char *subclass, char *etype,
 231     smhba_info_t *phyp)
 232 {
 233         nvlist_t        *attr_list;
 234         char            *pname;
 235         char            sas_addr[MPTSAS_WWN_STRLEN];
 236         uint8_t         phynum = 0;
 237         uint8_t         lrate = 0;
 238 
 239         if (mpt->m_dip == NULL)
 240                 return;
 241         if (phyp == NULL)
 242                 return;
 243 
 244         pname = kmem_zalloc(MAXPATHLEN, KM_NOSLEEP);
 245         if (pname == NULL)