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,