Print this page
4233 mptsas topo change buffer overflow

*** 19,28 **** --- 19,29 ---- * CDDL HEADER END */ /* * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2013 Nexenta Systems, Inc. All rights reserved. */ /* * This file contains SM-HBA support for MPT SAS driver */
*** 57,66 **** --- 58,72 ---- /* * SM - HBA statics */ extern char *mptsas_driver_rev; + static void mptsas_smhba_create_phy_props(nvlist_t **, smhba_info_t *, uint8_t, + uint16_t *); + static void mptsas_smhba_update_phy_props(mptsas_t *, dev_info_t *, nvlist_t **, + uint8_t); + static void mptsas_smhba_add_hba_prop(mptsas_t *mpt, data_type_t dt, char *prop_name, void *prop_val); void
*** 114,196 **** mpt->m_phy_info[i].smhba_info.negotiated_link_rate, mpt->m_phy_info[i].smhba_info.path); } } ! void ! mptsas_smhba_set_phy_props(mptsas_t *mpt, char *iport, dev_info_t *dip, ! uint8_t phy_nums, uint16_t *attached_devhdl) { ! int i; ! int j = 0; int rval; size_t packed_size; char *packed_data = NULL; - char phymask[MPTSAS_MAX_PHYS]; - nvlist_t **phy_props; nvlist_t *nvl; - smhba_info_t *pSmhba = NULL; ! if (phy_nums == 0) { return; } - if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) { - mptsas_log(mpt, CE_WARN, "%s: nvlist_alloc() failed", __func__); - } - phy_props = kmem_zalloc(sizeof (nvlist_t *) * phy_nums, - KM_SLEEP); - - for (i = 0; i < mpt->m_num_phys; i++) { - - bzero(phymask, sizeof (phymask)); - (void) sprintf(phymask, "%x", mpt->m_phy_info[i].phy_mask); - if (strcmp(phymask, iport) == 0) { - pSmhba = &mpt->m_phy_info[i].smhba_info; - (void) nvlist_alloc(&phy_props[j], NV_UNIQUE_NAME, 0); - (void) nvlist_add_uint8(phy_props[j], SAS_PHY_ID, i); - (void) nvlist_add_uint8(phy_props[j], - "phyState", - (pSmhba->negotiated_link_rate - & 0x0f)); - (void) nvlist_add_int8(phy_props[j], - SAS_NEG_LINK_RATE, - (pSmhba->negotiated_link_rate - & 0x0f)); - (void) nvlist_add_int8(phy_props[j], - SAS_PROG_MIN_LINK_RATE, - (pSmhba->programmed_link_rate - & 0x0f)); - (void) nvlist_add_int8(phy_props[j], - SAS_HW_MIN_LINK_RATE, - (pSmhba->hw_link_rate - & 0x0f)); - (void) nvlist_add_int8(phy_props[j], - SAS_PROG_MAX_LINK_RATE, - ((pSmhba->programmed_link_rate - & 0xf0) >> 4)); - (void) nvlist_add_int8(phy_props[j], - SAS_HW_MAX_LINK_RATE, - ((pSmhba->hw_link_rate - & 0xf0) >> 4)); - - j++; - - if (pSmhba->attached_devhdl && - (attached_devhdl != NULL)) { - *attached_devhdl = - pSmhba->attached_devhdl; - } - } - } - rval = nvlist_add_nvlist_array(nvl, SAS_PHY_INFO_NVL, phy_props, phy_nums); if (rval) { mptsas_log(mpt, CE_WARN, ! " nv list array add failed, return value %d.", ! rval); goto exit; } (void) nvlist_size(nvl, &packed_size, NV_ENCODE_NATIVE); packed_data = kmem_zalloc(packed_size, KM_SLEEP); (void) nvlist_pack(nvl, &packed_data, &packed_size, --- 120,171 ---- mpt->m_phy_info[i].smhba_info.negotiated_link_rate, mpt->m_phy_info[i].smhba_info.path); } } ! static void ! mptsas_smhba_create_phy_props(nvlist_t **phy_props, smhba_info_t *pSmhba, ! uint8_t phy_id, uint16_t *attached_devhdl) { ! (void) nvlist_alloc(phy_props, NV_UNIQUE_NAME, KM_SLEEP); ! (void) nvlist_add_uint8(*phy_props, SAS_PHY_ID, phy_id); ! (void) nvlist_add_uint8(*phy_props, "phyState", ! (pSmhba->negotiated_link_rate & 0x0f)); ! (void) nvlist_add_int8(*phy_props, SAS_NEG_LINK_RATE, ! (pSmhba->negotiated_link_rate & 0x0f)); ! (void) nvlist_add_int8(*phy_props, SAS_PROG_MIN_LINK_RATE, ! (pSmhba->programmed_link_rate & 0x0f)); ! (void) nvlist_add_int8(*phy_props, SAS_HW_MIN_LINK_RATE, ! (pSmhba->hw_link_rate & 0x0f)); ! (void) nvlist_add_int8(*phy_props, SAS_PROG_MAX_LINK_RATE, ! ((pSmhba->programmed_link_rate & 0xf0) >> 4)); ! (void) nvlist_add_int8(*phy_props, SAS_HW_MAX_LINK_RATE, ! ((pSmhba->hw_link_rate & 0xf0) >> 4)); ! ! if (pSmhba->attached_devhdl && (attached_devhdl != NULL)) ! *attached_devhdl = pSmhba->attached_devhdl; ! } ! ! static void ! mptsas_smhba_update_phy_props(mptsas_t *mpt, dev_info_t *dip, ! nvlist_t **phy_props, uint8_t phy_nums) ! { int rval; size_t packed_size; char *packed_data = NULL; nvlist_t *nvl; ! if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP) != 0) { ! mptsas_log(mpt, CE_WARN, "%s: nvlist_alloc() failed", __func__); return; } rval = nvlist_add_nvlist_array(nvl, SAS_PHY_INFO_NVL, phy_props, phy_nums); if (rval) { mptsas_log(mpt, CE_WARN, ! " nv list array add failed, return value %d.", rval); goto exit; } (void) nvlist_size(nvl, &packed_size, NV_ENCODE_NATIVE); packed_data = kmem_zalloc(packed_size, KM_SLEEP); (void) nvlist_pack(nvl, &packed_data, &packed_size,
*** 198,218 **** (void) ddi_prop_update_byte_array(DDI_DEV_T_NONE, dip, SAS_PHY_INFO, (uchar_t *)packed_data, packed_size); exit: - for (i = 0; i < phy_nums && phy_props[i] != NULL; i++) { - nvlist_free(phy_props[i]); - } nvlist_free(nvl); - kmem_free(phy_props, sizeof (nvlist_t *) * phy_nums); if (packed_data != NULL) { kmem_free(packed_data, packed_size); } } /* * Called with PHY lock held on phyp */ void mptsas_smhba_log_sysevent(mptsas_t *mpt, char *subclass, char *etype, --- 173,230 ---- (void) ddi_prop_update_byte_array(DDI_DEV_T_NONE, dip, SAS_PHY_INFO, (uchar_t *)packed_data, packed_size); exit: nvlist_free(nvl); if (packed_data != NULL) { kmem_free(packed_data, packed_size); } } + void + mptsas_smhba_set_one_phy_props(mptsas_t *mpt, dev_info_t *dip, uint8_t phy_id, + uint16_t *attached_devhdl) + { + nvlist_t *phy_props; + + ASSERT(phy_id < mpt->m_num_phys); + + mptsas_smhba_create_phy_props(&phy_props, + &mpt->m_phy_info[phy_id].smhba_info, phy_id, attached_devhdl); + + mptsas_smhba_update_phy_props(mpt, dip, &phy_props, 1); + + nvlist_free(phy_props); + } + + void + mptsas_smhba_set_all_phy_props(mptsas_t *mpt, dev_info_t *dip, uint8_t phy_nums, + mptsas_phymask_t phy_mask, uint16_t *attached_devhdl) + { + int i, j; + nvlist_t **phy_props; + + if (phy_nums == 0) + return; + + phy_props = kmem_zalloc(sizeof (nvlist_t *) * phy_nums, KM_SLEEP); + + for (i = 0, j = 0; i < mpt->m_num_phys && j < phy_nums; i++) + if (phy_mask == mpt->m_phy_info[i].phy_mask) + mptsas_smhba_create_phy_props(&phy_props[j++], + &mpt->m_phy_info[i].smhba_info, i, attached_devhdl); + + mptsas_smhba_update_phy_props(mpt, dip, phy_props, j); + + for (i = 0; i < j && phy_props[i] != NULL; i++) + nvlist_free(phy_props[i]); + + kmem_free(phy_props, sizeof (nvlist_t *) * phy_nums); + } + /* * Called with PHY lock held on phyp */ void mptsas_smhba_log_sysevent(mptsas_t *mpt, char *subclass, char *etype,