2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A#include <sys/types.h>
2N/A#include <stddef.h>
2N/A#include <stdio.h>
2N/A#include <string.h>
2N/A#include <libnvpair.h>
2N/A
2N/A#include <scsi/libses.h>
2N/A#include "ses2_impl.h"
2N/A
2N/Astatic int
2N/Aelem_parse_device(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_device_status_impl_t *dip = (ses2_device_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(uint64, nverr, nvl, SES_DEV_PROP_SLOT_ADDR,
2N/A dip->sdsi_slot_addr);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
2N/A dip->sdsi_report);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
2N/A dip->sdsi_ident);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_RMV, dip->sdsi_rmv);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_READY_TO_INSERT,
2N/A dip->sdsi_ready_to_insert);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_ENC_BYP_B,
2N/A dip->sdsi_enclosure_bypassed_b);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_ENC_BYP_A,
2N/A dip->sdsi_enclosure_bypassed_a);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DO_NOT_REMOVE,
2N/A dip->sdsi_do_not_remove);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_APP_BYP_A,
2N/A dip->sdsi_app_client_bypassed_a);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DEV_BYP_B,
2N/A dip->sdsi_device_bypassed_b);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DEV_BYP_A,
2N/A dip->sdsi_device_bypassed_a);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_BYP_B,
2N/A dip->sdsi_bypassed_b);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_BYP_A,
2N/A dip->sdsi_bypassed_a);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_OFF,
2N/A dip->sdsi_device_off);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_FAULT_RQSTD,
2N/A dip->sdsi_fault_reqstd);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_FAULT_SENSED,
2N/A dip->sdsi_fault_sensed);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_APP_BYP_B,
2N/A dip->sdsi_app_client_bypassed_b);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_psu(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_psu_status_impl_t *pip = (ses2_psu_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
2N/A pip->spsi_ident);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_DC_OVER_CURRENT,
2N/A pip->spsi_dc_over_current);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_DC_UNDER_VOLTAGE,
2N/A pip->spsi_dc_under_voltage);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_DC_OVER_VOLTAGE,
2N/A pip->spsi_dc_over_voltage);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_DC_FAIL,
2N/A pip->spsi_dc_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_AC_FAIL,
2N/A pip->spsi_ac_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_TEMP_WARN,
2N/A pip->spsi_temp_warn);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_OVERTEMP_FAIL,
2N/A pip->spsi_overtmp_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_OFF, pip->spsi_off);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REQUESTED_ON,
2N/A pip->spsi_rqsted_on);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, pip->spsi_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_HOT_SWAP,
2N/A pip->spsi_hot_swap);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_cooling(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_cooling_status_impl_t *cip = (ses2_cooling_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(uint64, nverr, nvl, SES_COOLING_PROP_FAN_SPEED,
2N/A SES2_ES_COOLING_ST_FAN_SPEED(cip));
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
2N/A cip->scsi_ident);
2N/A SES_NV_ADD(uint64, nverr, nvl, SES_COOLING_PROP_SPEED_CODE,
2N/A cip->scsi_actual_speed_code);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_OFF, cip->scsi_off);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REQUESTED_ON,
2N/A cip->scsi_requested_on);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, cip->scsi_fail);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_temp(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_temp_status_impl_t *tip = (ses2_temp_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, tip->stsi_ident);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, tip->stsi_fail);
2N/A SES_NV_ADD(int64, nverr, nvl, SES_TEMP_PROP_TEMP,
2N/A SES2_ES_TEMP_ST_TEMPERATURE(tip));
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_WARN_UNDER,
2N/A tip->stsi_ut_warn);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_CRIT_UNDER,
2N/A tip->stsi_ut_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_WARN_OVER,
2N/A tip->stsi_ot_warn);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_CRIT_OVER,
2N/A tip->stsi_ot_fail);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_lock(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_lock_status_impl_t *lip = (ses2_lock_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL,
2N/A lip->slsi_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
2N/A lip->slsi_ident);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_LOCK_PROP_UNLOCKED,
2N/A lip->slsi_unlocked);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_alarm(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_alarm_status_impl_t *aip = (ses2_alarm_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, aip->sasi_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
2N/A aip->sasi_ident);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_UNRECOV,
2N/A aip->sasi_unrecov);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_CRIT,
2N/A aip->sasi_crit);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_NONCRIT,
2N/A aip->sasi_noncrit);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_INFO,
2N/A aip->sasi_info);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_REMIND,
2N/A aip->sasi_remind);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_MUTED,
2N/A aip->sasi_muted);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_RQST_MUTE,
2N/A aip->sasi_rqst_mute);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_esc(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_controller_status_impl_t *cip =
2N/A (ses2_controller_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, cip->scsi_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, cip->scsi_ident);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
2N/A cip->scsi_report);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_HOT_SWAP,
2N/A cip->scsi_hot_swap);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_scc(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_scc_status_impl_t *sip = (ses2_scc_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, sip->sss_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, sip->sss_ident);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
2N/A sip->sss_report);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_cache(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_nvcache_status_impl_t *np = (ses2_nvcache_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, np->snsi_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
2N/A np->snsi_ident);
2N/A SES_NV_ADD(uint64, nverr, nvl, SES_CACHE_PROP_SIZE,
2N/A SES2_NVCACHE_SIZE(np));
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_ups(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_ups_status_impl_t *uip = (ses2_ups_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(uint64, nverr, nvl, SES_UPS_PROP_TIMELEFT,
2N/A uip->susi_battery_status);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_INTF_FAIL,
2N/A uip->susi_intf_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_WARN,
2N/A uip->susi_warn);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_UPS_FAIL,
2N/A uip->susi_ups_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_DC_FAIL,
2N/A uip->susi_dc_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_AC_FAIL,
2N/A uip->susi_ac_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_AC_QUAL,
2N/A uip->susi_ac_qual);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_AC_HI,
2N/A uip->susi_ac_hi);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_AC_LO,
2N/A uip->susi_ac_lo);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_BPF, uip->susi_bpf);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_BATT_FAIL,
2N/A uip->susi_batt_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, uip->susi_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, uip->susi_ident);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_display(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_display_status_impl_t *dip = (ses2_display_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(uint64, nverr, nvl, SES_DPY_PROP_MODE,
2N/A dip->sdsi_display_mode_status);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, dip->sdsi_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, dip->sdsi_ident);
2N/A SES_NV_ADD(uint16, nverr, nvl, SES_DPY_PROP_CHAR,
2N/A dip->sdsi_display_character_status);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_keypad(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_keypad_status_impl_t *kip = (ses2_keypad_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, kip->sksi_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, kip->sksi_ident);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_px(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_port_status_impl_t *pip = (ses2_port_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, pip->spsi_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, pip->spsi_ident);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
2N/A pip->spsi_report);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PX_PROP_XMIT_FAIL,
2N/A pip->spsi_xmit_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PX_PROP_LOL, pip->spsi_lol);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_DISABLED,
2N/A pip->spsi_disabled);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_lang(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_lang_status_impl_t *lip = (ses2_lang_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
2N/A lip->slsi_ident);
2N/A SES_NV_ADD(uint64, nverr, nvl, SES_LANG_PROP_LANGCODE,
2N/A SCSI_READ16(&lip->slsi_language_code));
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_comm(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_comm_status_impl_t *cip = (ses2_comm_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, cip->scsi_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
2N/A cip->scsi_ident);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_DISABLED,
2N/A cip->scsi_disabled);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_voltage(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_voltage_status_impl_t *vip = (ses2_voltage_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_CRIT_UNDER,
2N/A vip->svsi_crit_under);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_CRIT_OVER,
2N/A vip->svsi_crit_over);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_WARN_UNDER,
2N/A vip->svsi_warn_under);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_WARN_OVER,
2N/A vip->svsi_warn_over);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, vip->svsi_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, vip->svsi_ident);
2N/A SES_NV_ADD(int64, nverr, nvl, SES_VS_PROP_VOLTAGE_MV,
2N/A SCSI_READ16(&vip->svsi_voltage));
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_current(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_current_status_impl_t *cip = (ses2_current_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_CRIT_OVER,
2N/A cip->scsi_crit_over);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_WARN_OVER,
2N/A cip->scsi_warn_over);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, cip->scsi_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, cip->scsi_ident);
2N/A SES_NV_ADD(int64, nverr, nvl, SES_CS_PROP_CURRENT_MA,
2N/A SCSI_READ16(&cip->scsi_current));
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_itp(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_itp_status_impl_t *iip = (ses2_itp_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, iip->sisi_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
2N/A iip->sisi_ident);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
2N/A iip->sisi_report);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_ITP_PROP_ENABLED,
2N/A iip->sisi_enabled);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_sse(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_ss_status_impl_t *sip = (ses2_ss_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, sip->sss_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, sip->sss_ident);
2N/A SES_NV_ADD(uint64, nverr, nvl, SES_SS_PROP_SHORT_STATUS,
2N/A sip->sss_short_status);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_arraydev(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_array_device_status_impl_t *aip =
2N/A (ses2_array_device_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_RR_ABORT,
2N/A aip->sadsi_rr_abort);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_REBUILD,
2N/A aip->sadsi_rebuild);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_IN_FAILED_ARRAY,
2N/A aip->sadsi_in_failed_array);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_IN_CRIT_ARRAY,
2N/A aip->sadsi_in_crit_array);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_CONS_CHK,
2N/A aip->sadsi_cons_chk);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_HOT_SPARE,
2N/A aip->sadsi_hot_spare);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_RSVD_DEVICE,
2N/A aip->sadsi_rsvd_device);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_OK, aip->sadsi_ok);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
2N/A aip->sadsi_report);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, aip->sadsi_ident);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_RMV, aip->sadsi_rmv);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_READY_TO_INSERT,
2N/A aip->sadsi_ready_to_insert);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_ENC_BYP_B,
2N/A aip->sadsi_enclosure_bypassed_b);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_ENC_BYP_A,
2N/A aip->sadsi_enclosure_bypassed_a);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DO_NOT_REMOVE,
2N/A aip->sadsi_do_not_remove);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_APP_BYP_A,
2N/A aip->sadsi_app_client_bypassed_a);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DEV_BYP_B,
2N/A aip->sadsi_device_bypassed_b);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DEV_BYP_A,
2N/A aip->sadsi_device_bypassed_a);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_BYP_B,
2N/A aip->sadsi_bypassed_b);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_BYP_A,
2N/A aip->sadsi_bypassed_a);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_OFF,
2N/A aip->sadsi_device_off);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_FAULT_RQSTD,
2N/A aip->sadsi_fault_reqstd);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_FAULT_SENSED,
2N/A aip->sadsi_fault_sensed);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_APP_BYP_B,
2N/A aip->sadsi_app_client_bypassed_b);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_expander(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_expander_status_impl_t *eip = (ses2_expander_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, eip->sesi_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, eip->sesi_ident);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_sasconn(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
2N/A{
2N/A ses2_sasconn_status_impl_t *sip = (ses2_sasconn_status_impl_t *)esip;
2N/A int nverr;
2N/A
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, sip->sss_fail);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, sip->sss_ident);
2N/A SES_NV_ADD(uint64, nverr, nvl, SES_SC_PROP_CONNECTOR_TYPE,
2N/A sip->sss_connector_type);
2N/A SES_NV_ADD(uint64, nverr, nvl, SES_SC_PROP_PHYSICAL_LINK,
2N/A sip->sss_connector_physical_link);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic const struct status_parser {
2N/A ses2_element_type_t type;
2N/A int (*func)(const ses2_elem_status_impl_t *, nvlist_t *);
2N/A} status_parsers[] = {
2N/A { SES_ET_DEVICE, elem_parse_device },
2N/A { SES_ET_POWER_SUPPLY, elem_parse_psu },
2N/A { SES_ET_COOLING, elem_parse_cooling },
2N/A { SES_ET_TEMPERATURE_SENSOR, elem_parse_temp },
2N/A { SES_ET_DOOR_LOCK, elem_parse_lock },
2N/A { SES_ET_AUDIBLE_ALARM, elem_parse_alarm },
2N/A { SES_ET_ESC_ELECTRONICS, elem_parse_esc },
2N/A { SES_ET_SCC_ELECTRONICS, elem_parse_scc },
2N/A { SES_ET_NONVOLATILE_CACHE, elem_parse_cache },
2N/A { SES_ET_UPS, elem_parse_ups },
2N/A { SES_ET_DISPLAY, elem_parse_display },
2N/A { SES_ET_KEY_PAD_ENTRY, elem_parse_keypad },
2N/A { SES_ET_SCSI_PORT_XCVR, elem_parse_px },
2N/A { SES_ET_LANGUAGE, elem_parse_lang },
2N/A { SES_ET_COMMUNICATION_PORT, elem_parse_comm },
2N/A { SES_ET_VOLTAGE_SENSOR, elem_parse_voltage },
2N/A { SES_ET_CURRENT_SENSOR, elem_parse_current },
2N/A { SES_ET_SCSI_TARGET_PORT, elem_parse_itp },
2N/A { SES_ET_SCSI_INITIATOR_PORT, elem_parse_itp },
2N/A { SES_ET_SIMPLE_SUBENCLOSURE, elem_parse_sse },
2N/A { SES_ET_ARRAY_DEVICE, elem_parse_arraydev },
2N/A { SES_ET_SAS_EXPANDER, elem_parse_expander },
2N/A { SES_ET_SAS_CONNECTOR, elem_parse_sasconn },
2N/A { (ses2_element_type_t)-1, NULL }
2N/A};
2N/A
2N/Astatic int
2N/Aelem_parse_sd(ses_plugin_t *spp, ses_node_t *np)
2N/A{
2N/A ses2_elem_status_impl_t *esip;
2N/A const struct status_parser *sp;
2N/A nvlist_t *nvl = ses_node_props(np);
2N/A size_t len;
2N/A int nverr;
2N/A uint64_t type;
2N/A
2N/A if ((esip = ses_plugin_page_lookup(spp,
2N/A ses_node_snapshot(np), SES2_DIAGPAGE_ENCLOSURE_CTL_STATUS,
2N/A np, &len)) == NULL)
2N/A return (0);
2N/A
2N/A VERIFY(nvlist_lookup_uint64(nvl, SES_PROP_ELEMENT_TYPE,
2N/A &type) == 0);
2N/A
2N/A SES_NV_ADD(uint64, nverr, nvl, SES_PROP_STATUS_CODE,
2N/A esip->sesi_common.sesi_status_code);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_SWAP,
2N/A esip->sesi_common.sesi_swap);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_DISABLED,
2N/A esip->sesi_common.sesi_disabled);
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_PRDFAIL,
2N/A esip->sesi_common.sesi_prdfail);
2N/A
2N/A for (sp = &status_parsers[0]; sp->type != (ses2_element_type_t)-1; sp++)
2N/A if (sp->type == type && sp->func != NULL)
2N/A return (sp->func(esip, nvl));
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_descr(ses_plugin_t *sp, ses_node_t *np)
2N/A{
2N/A char *desc;
2N/A size_t len;
2N/A nvlist_t *props = ses_node_props(np);
2N/A int nverr;
2N/A
2N/A if ((desc = ses_plugin_page_lookup(sp, ses_node_snapshot(np),
2N/A SES2_DIAGPAGE_ELEMENT_DESC, np, &len)) == NULL)
2N/A return (0);
2N/A
2N/A SES_NV_ADD(fixed_string, nverr, props, SES_PROP_DESCRIPTION,
2N/A desc, len);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_aes_fc(const ses2_aes_descr_fc_eip_impl_t *fp,
2N/A nvlist_t *nvl, size_t len)
2N/A{
2N/A int nverr, i;
2N/A nvlist_t **nva;
2N/A int nports;
2N/A
2N/A if (len < offsetof(ses2_aes_descr_fc_eip_impl_t,
2N/A sadfi_ports))
2N/A return (0);
2N/A
2N/A SES_NV_ADD(uint64, nverr, nvl, SES_PROP_BAY_NUMBER,
2N/A fp->sadfi_bay_number);
2N/A SES_NV_ADD(uint64, nverr, nvl, SES_FC_PROP_NODE_NAME,
2N/A SCSI_READ64(&fp->sadfi_node_name));
2N/A
2N/A nports = MIN(fp->sadfi_n_ports,
2N/A (len - offsetof(ses2_aes_descr_fc_eip_impl_t,
2N/A sadfi_ports)) / sizeof (ses2_aes_port_descr_impl_t));
2N/A
2N/A if (nports == 0)
2N/A return (0);
2N/A
2N/A nva = ses_zalloc(nports * sizeof (nvlist_t *));
2N/A if (nva == NULL)
2N/A return (-1);
2N/A
2N/A for (i = 0; i < nports; i++) {
2N/A if ((nverr = nvlist_alloc(&nva[i], NV_UNIQUE_NAME, 0)) != 0)
2N/A goto fail;
2N/A if ((nverr = nvlist_add_uint64(nva[i], SES_FC_PROP_LOOP_POS,
2N/A fp->sadfi_ports[i].sapdi_port_loop_position)) != 0)
2N/A goto fail;
2N/A if ((nverr = nvlist_add_uint64(nva[i], SES_FC_PROP_REQ_HARDADDR,
2N/A fp->sadfi_ports[i].sapdi_port_requested_hard_address)) != 0)
2N/A goto fail;
2N/A nverr = nvlist_add_uint64(nva[i], SES_FC_PROP_N_PORT_ID,
2N/A SCSI_READ24(fp->sadfi_ports[i].sapdi_n_port_identifier));
2N/A if (nverr != 0)
2N/A goto fail;
2N/A if ((nverr = nvlist_add_uint64(nva[i], SES_FC_PROP_N_PORT_NAME,
2N/A SCSI_READ64(&fp->sadfi_ports[i].sapdi_n_port_name))) != 0)
2N/A goto fail;
2N/A }
2N/A
2N/A if ((nverr = nvlist_add_nvlist_array(nvl, SES_FC_PROP_PORTS,
2N/A nva, nports)) != 0)
2N/A goto fail;
2N/A
2N/A for (i = 0; i < nports && nva[i] != NULL; i++)
2N/A nvlist_free(nva[i]);
2N/A ses_free(nva);
2N/A return (0);
2N/A
2N/Afail:
2N/A for (i = 0; i < nports && nva[i] != NULL; i++)
2N/A nvlist_free(nva[i]);
2N/A ses_free(nva);
2N/A return (ses_set_nverrno(nverr, NULL));
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_aes_device(const ses2_aes_descr_eip_impl_t *dep, nvlist_t *nvl,
2N/A size_t len)
2N/A{
2N/A ses2_aes_descr_fc_eip_impl_t *fp;
2N/A ses2_aes_descr_sas0_eip_impl_t *s0ep;
2N/A ses2_aes_descr_sas0_impl_t *s0p;
2N/A ses2_aes_descr_impl_t *dip;
2N/A nvlist_t **nva;
2N/A int nverr, i;
2N/A size_t nphy;
2N/A
2N/A if (dep->sadei_eip) {
2N/A s0ep = (ses2_aes_descr_sas0_eip_impl_t *)
2N/A dep->sadei_protocol_specific;
2N/A s0p = (ses2_aes_descr_sas0_impl_t *)
2N/A dep->sadei_protocol_specific;
2N/A } else {
2N/A dip = (ses2_aes_descr_impl_t *)dep;
2N/A s0ep = NULL;
2N/A s0p = (ses2_aes_descr_sas0_impl_t *)
2N/A dip->sadei_protocol_specific;
2N/A }
2N/A
2N/A if (dep->sadei_invalid)
2N/A return (0);
2N/A
2N/A if (dep->sadei_protocol_identifier == SPC4_PROTO_FIBRE_CHANNEL) {
2N/A fp = (ses2_aes_descr_fc_eip_impl_t *)
2N/A dep->sadei_protocol_specific;
2N/A
2N/A if (!SES_WITHIN_PAGE_STRUCT(fp, dep, len))
2N/A return (0);
2N/A
2N/A return (elem_parse_aes_fc(fp, nvl, len -
2N/A offsetof(ses2_aes_descr_eip_impl_t,
2N/A sadei_protocol_specific)));
2N/A } else if (dep->sadei_protocol_identifier != SPC4_PROTO_SAS) {
2N/A return (0);
2N/A }
2N/A
2N/A if (s0p->sadsi_descriptor_type != SES2_AESD_SAS_DEVICE)
2N/A return (0);
2N/A
2N/A SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_SAS_NOT_ALL_PHYS,
2N/A s0p->sadsi_not_all_phys);
2N/A if (s0ep != NULL) {
2N/A SES_NV_ADD(uint64, nverr, nvl, SES_PROP_BAY_NUMBER,
2N/A s0ep->sadsi_bay_number);
2N/A nphy = MIN(s0ep->sadsi_n_phy_descriptors,
2N/A (len - offsetof(ses2_aes_descr_sas0_eip_impl_t,
2N/A sadsi_phys)) / sizeof (ses2_aes_phy0_descr_impl_t));
2N/A } else {
2N/A nphy = MIN(s0p->sadsi_n_phy_descriptors,
2N/A (len - offsetof(ses2_aes_descr_sas0_impl_t,
2N/A sadsi_phys)) / sizeof (ses2_aes_phy0_descr_impl_t));
2N/A }
2N/A
2N/A if (nphy == 0)
2N/A return (0);
2N/A
2N/A nva = ses_zalloc(nphy * sizeof (nvlist_t *));
2N/A if (nva == NULL)
2N/A return (-1);
2N/A
2N/A for (i = 0; i < nphy; i++) {
2N/A ses2_aes_phy0_descr_impl_t *pp;
2N/A pp = s0ep != NULL ? &s0ep->sadsi_phys[i] : &s0p->sadsi_phys[i];
2N/A if ((nverr = nvlist_alloc(&nva[i], NV_UNIQUE_NAME, 0)) != 0)
2N/A goto fail;
2N/A if ((nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_DEVICE_TYPE,
2N/A pp->sapdi_device_type)) != 0)
2N/A goto fail;
2N/A if ((nverr = nvlist_add_boolean_value(nva[i],
2N/A SES_SAS_PROP_SMPI_PORT, pp->sapdi_smp_initiator_port)) != 0)
2N/A goto fail;
2N/A if ((nverr = nvlist_add_boolean_value(nva[i],
2N/A SES_SAS_PROP_STPI_PORT, pp->sapdi_stp_initiator_port)) != 0)
2N/A goto fail;
2N/A if ((nverr = nvlist_add_boolean_value(nva[i],
2N/A SES_SAS_PROP_SSPI_PORT, pp->sapdi_ssp_initiator_port)) != 0)
2N/A goto fail;
2N/A if ((nverr = nvlist_add_boolean_value(nva[i],
2N/A SES_SAS_PROP_SATA_DEVICE, pp->sapdi_sata_device)) != 0)
2N/A goto fail;
2N/A if ((nverr = nvlist_add_boolean_value(nva[i],
2N/A SES_SAS_PROP_SMPT_PORT, pp->sapdi_smp_target_port)) != 0)
2N/A goto fail;
2N/A if ((nverr = nvlist_add_boolean_value(nva[i],
2N/A SES_SAS_PROP_STPT_PORT, pp->sapdi_stp_target_port)) != 0)
2N/A goto fail;
2N/A if ((nverr = nvlist_add_boolean_value(nva[i],
2N/A SES_SAS_PROP_SSPT_PORT, pp->sapdi_ssp_target_port)) != 0)
2N/A goto fail;
2N/A nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_ATT_ADDR,
2N/A SCSI_READ64(&pp->sapdi_attached_sas_address));
2N/A if (nverr != 0)
2N/A goto fail;
2N/A nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_ADDR,
2N/A SCSI_READ64(&pp->sapdi_sas_address));
2N/A if (nverr != 0)
2N/A goto fail;
2N/A if ((nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_PHY_ID,
2N/A pp->sapdi_phy_identifier)) != 0)
2N/A goto fail;
2N/A }
2N/A
2N/A if ((nverr = nvlist_add_nvlist_array(nvl, SES_SAS_PROP_PHYS,
2N/A nva, nphy)) != 0)
2N/A goto fail;
2N/A
2N/A for (i = 0; i < nphy && nva[i] != NULL; i++)
2N/A nvlist_free(nva[i]);
2N/A ses_free(nva);
2N/A return (0);
2N/A
2N/Afail:
2N/A for (i = 0; i < nphy && nva[i] != NULL; i++)
2N/A nvlist_free(nva[i]);
2N/A ses_free(nva);
2N/A return (ses_set_nverrno(nverr, NULL));
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_aes_expander(const ses2_aes_descr_eip_impl_t *dep, nvlist_t *nvl,
2N/A size_t len)
2N/A{
2N/A ses2_aes_descr_exp_impl_t *sep;
2N/A nvlist_t **nva;
2N/A int nverr, i;
2N/A size_t nphy;
2N/A
2N/A if (dep->sadei_invalid)
2N/A return (0);
2N/A
2N/A /*
2N/A * This should never happen; no current SAS expander can have any
2N/A * other kind of ports. But maybe someday - one could envision a
2N/A * SAS expander with iSCSI target ports, for example.
2N/A */
2N/A if (dep->sadei_protocol_identifier != SPC4_PROTO_SAS)
2N/A return (0);
2N/A
2N/A sep = (ses2_aes_descr_exp_impl_t *)dep->sadei_protocol_specific;
2N/A if (sep->sadei_descriptor_type != SES2_AESD_SAS_OTHER)
2N/A return (0);
2N/A
2N/A SES_NV_ADD(uint64, nverr, nvl, SES_EXP_PROP_SAS_ADDR,
2N/A SCSI_READ64(&sep->sadei_sas_address));
2N/A
2N/A nphy = MIN(sep->sadei_n_exp_phy_descriptors,
2N/A (len - offsetof(ses2_aes_descr_exp_impl_t,
2N/A sadei_phys)) / sizeof (ses2_aes_exp_phy_descr_impl_t));
2N/A
2N/A if (nphy == 0)
2N/A return (0);
2N/A
2N/A nva = ses_zalloc(nphy * sizeof (nvlist_t *));
2N/A if (nva == NULL)
2N/A return (-1);
2N/A
2N/A for (i = 0; i < nphy; i++) {
2N/A if ((nverr = nvlist_alloc(&nva[i], NV_UNIQUE_NAME, 0)) != 0)
2N/A goto fail;
2N/A if ((nverr = nvlist_add_uint64(nva[i], SES_PROP_CE_IDX,
2N/A sep->sadei_phys[i].saepdi_connector_element_index)) != 0)
2N/A goto fail;
2N/A if ((nverr = nvlist_add_uint64(nva[i], SES_PROP_OE_IDX,
2N/A sep->sadei_phys[i].saepdi_other_element_index)) != 0)
2N/A goto fail;
2N/A }
2N/A
2N/A if ((nverr = nvlist_add_nvlist_array(nvl, SES_SAS_PROP_PHYS,
2N/A nva, nphy)) != 0)
2N/A goto fail;
2N/A
2N/A for (i = 0; i < nphy && nva[i] != NULL; i++)
2N/A nvlist_free(nva[i]);
2N/A ses_free(nva);
2N/A return (0);
2N/A
2N/Afail:
2N/A for (i = 0; i < nphy && nva[i] != NULL; i++)
2N/A nvlist_free(nva[i]);
2N/A ses_free(nva);
2N/A return (ses_set_nverrno(nverr, NULL));
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_aes_misc(const ses2_aes_descr_eip_impl_t *dep, nvlist_t *nvl,
2N/A size_t len)
2N/A{
2N/A ses2_aes_descr_fc_eip_impl_t *fp;
2N/A ses2_aes_descr_sas1_impl_t *s1p;
2N/A nvlist_t **nva;
2N/A int nverr, i;
2N/A size_t nphy;
2N/A
2N/A if (dep->sadei_invalid)
2N/A return (0);
2N/A
2N/A if (dep->sadei_protocol_identifier == SPC4_PROTO_FIBRE_CHANNEL) {
2N/A fp = (ses2_aes_descr_fc_eip_impl_t *)
2N/A dep->sadei_protocol_specific;
2N/A
2N/A if (!SES_WITHIN_PAGE_STRUCT(fp, dep, len))
2N/A return (0);
2N/A
2N/A return (elem_parse_aes_fc(fp, nvl, len -
2N/A offsetof(ses2_aes_descr_eip_impl_t,
2N/A sadei_protocol_specific)));
2N/A } else if (dep->sadei_protocol_identifier != SPC4_PROTO_SAS) {
2N/A return (0);
2N/A }
2N/A
2N/A s1p = (ses2_aes_descr_sas1_impl_t *)dep->sadei_protocol_specific;
2N/A if (s1p->sadsi_descriptor_type == SES2_AESD_SAS_DEVICE)
2N/A return (0);
2N/A
2N/A nphy = MIN(s1p->sadsi_n_phy_descriptors,
2N/A (len - offsetof(ses2_aes_descr_sas1_impl_t,
2N/A sadsi_phys)) / sizeof (ses2_aes_phy1_descr_impl_t));
2N/A
2N/A nva = ses_zalloc(nphy * sizeof (nvlist_t *));
2N/A if (nva == NULL)
2N/A return (-1);
2N/A
2N/A for (i = 0; i < nphy; i++) {
2N/A if ((nverr = nvlist_alloc(&nva[i], NV_UNIQUE_NAME, 0)) != 0)
2N/A goto fail;
2N/A if ((nverr = nvlist_add_uint64(nva[i], SES_PROP_CE_IDX,
2N/A s1p->sadsi_phys[i].sapdi_connector_element_index)) != 0)
2N/A goto fail;
2N/A if ((nverr = nvlist_add_uint64(nva[i], SES_PROP_OE_IDX,
2N/A s1p->sadsi_phys[i].sapdi_other_element_index)) != 0)
2N/A goto fail;
2N/A if ((nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_ADDR,
2N/A SCSI_READ64(&s1p->sadsi_phys[i].sapdi_sas_address))) != 0)
2N/A goto fail;
2N/A }
2N/A
2N/A if ((nverr = nvlist_add_nvlist_array(nvl, SES_SAS_PROP_PHYS,
2N/A nva, nphy)) != 0)
2N/A goto fail;
2N/A
2N/A for (i = 0; i < nphy && nva[i] != NULL; i++)
2N/A nvlist_free(nva[i]);
2N/A
2N/A ses_free(nva);
2N/A return (0);
2N/A
2N/Afail:
2N/A for (i = 0; i < nphy && nva[i] != NULL; i++)
2N/A nvlist_free(nva[i]);
2N/A ses_free(nva);
2N/A return (nverr);
2N/A}
2N/A
2N/Astatic const struct aes_parser {
2N/A ses2_element_type_t type;
2N/A int (*func)(const ses2_aes_descr_eip_impl_t *, nvlist_t *, size_t);
2N/A} aes_parsers[] = {
2N/A { SES_ET_DEVICE, elem_parse_aes_device },
2N/A { SES_ET_SCSI_TARGET_PORT, elem_parse_aes_misc },
2N/A { SES_ET_SCSI_INITIATOR_PORT, elem_parse_aes_misc },
2N/A { SES_ET_ESC_ELECTRONICS, elem_parse_aes_misc },
2N/A { SES_ET_ARRAY_DEVICE, elem_parse_aes_device },
2N/A { SES_ET_SAS_EXPANDER, elem_parse_aes_expander },
2N/A { (ses2_element_type_t)-1, NULL }
2N/A};
2N/A
2N/Astatic int
2N/Aelem_parse_aes(ses_plugin_t *sp, ses_node_t *np)
2N/A{
2N/A ses2_aes_descr_eip_impl_t *dep;
2N/A nvlist_t *props = ses_node_props(np);
2N/A const struct aes_parser *app;
2N/A uint64_t type;
2N/A size_t len;
2N/A
2N/A if (ses_node_type(np) == SES_NODE_AGGREGATE)
2N/A return (0);
2N/A
2N/A VERIFY(nvlist_lookup_uint64(props, SES_PROP_ELEMENT_TYPE,
2N/A &type) == 0);
2N/A
2N/A for (app = &aes_parsers[0]; app->func != NULL; app++)
2N/A if (app->type == type)
2N/A break;
2N/A if (app->func == NULL)
2N/A return (0);
2N/A
2N/A if ((dep = ses_plugin_page_lookup(sp, ses_node_snapshot(np),
2N/A SES2_DIAGPAGE_ADDL_ELEM_STATUS, np, &len)) == NULL)
2N/A return (0);
2N/A
2N/A return (app->func(dep, props, len));
2N/A}
2N/A
2N/Astatic int
2N/Aelem_parse_threshold(ses_plugin_t *sp, ses_node_t *np)
2N/A{
2N/A ses_snap_t *snap = ses_node_snapshot(np);
2N/A ses2_threshold_impl_t *tp;
2N/A nvlist_t *nvl = ses_node_props(np);
2N/A int nverr;
2N/A uint64_t type;
2N/A size_t len;
2N/A
2N/A VERIFY(nvlist_lookup_uint64(nvl, SES_PROP_ELEMENT_TYPE,
2N/A &type) == 0);
2N/A
2N/A switch (type) {
2N/A case SES_ET_TEMPERATURE_SENSOR:
2N/A case SES_ET_UPS:
2N/A case SES_ET_VOLTAGE_SENSOR:
2N/A case SES_ET_CURRENT_SENSOR:
2N/A break;
2N/A default:
2N/A return (0);
2N/A }
2N/A
2N/A if ((tp = ses_plugin_page_lookup(sp, snap,
2N/A SES2_DIAGPAGE_THRESHOLD_IO, np, &len)) == NULL)
2N/A return (0);
2N/A
2N/A SES_NV_ADD(uint64, nverr, nvl, SES_PROP_THRESH_CRIT_HI,
2N/A tp->sti_high_crit);
2N/A SES_NV_ADD(uint64, nverr, nvl, SES_PROP_THRESH_WARN_HI,
2N/A tp->sti_high_warn);
2N/A SES_NV_ADD(uint64, nverr, nvl, SES_PROP_THRESH_CRIT_LO,
2N/A tp->sti_low_crit);
2N/A SES_NV_ADD(uint64, nverr, nvl, SES_PROP_THRESH_WARN_LO,
2N/A tp->sti_low_warn);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Aint
2N/Ases2_fill_element_node(ses_plugin_t *sp, ses_node_t *np)
2N/A{
2N/A int err;
2N/A
2N/A if ((err = elem_parse_sd(sp, np)) != 0)
2N/A return (err);
2N/A
2N/A if ((err = elem_parse_descr(sp, np)) != 0)
2N/A return (err);
2N/A
2N/A if ((err = elem_parse_aes(sp, np)) != 0)
2N/A return (err);
2N/A
2N/A if ((err = elem_parse_threshold(sp, np)) != 0)
2N/A return (err);
2N/A
2N/A return (0);
2N/A}