1 /*
   2  * CDDL HEADER START
   3  *
   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 2008 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #pragma ident   "%Z%%M% %I%     %E% SMI"
  28 
  29 #include <sys/types.h>
  30 #include <stddef.h>
  31 #include <stdio.h>
  32 #include <string.h>
  33 #include <libnvpair.h>
  34 
  35 #include <scsi/libses.h>
  36 #include "ses2_impl.h"
  37 
  38 static int
  39 elem_parse_device(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
  40 {
  41         ses2_device_status_impl_t *dip = (ses2_device_status_impl_t *)esip;
  42         int nverr;
  43 
  44         SES_NV_ADD(uint64, nverr, nvl, SES_DEV_PROP_SLOT_ADDR,
  45             dip->sdsi_slot_addr);
  46         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
  47             dip->sdsi_report);
  48         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
  49             dip->sdsi_ident);
  50         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_RMV, dip->sdsi_rmv);
  51         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_READY_TO_INSERT,
  52             dip->sdsi_ready_to_insert);
  53         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_ENC_BYP_B,
  54             dip->sdsi_enclosure_bypassed_b);
  55         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_ENC_BYP_A,
  56             dip->sdsi_enclosure_bypassed_a);
  57         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DO_NOT_REMOVE,
  58             dip->sdsi_do_not_remove);
  59         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_APP_BYP_A,
  60             dip->sdsi_app_client_bypassed_a);
  61         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DEV_BYP_B,
  62             dip->sdsi_device_bypassed_b);
  63         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DEV_BYP_A,
  64             dip->sdsi_device_bypassed_a);
  65         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_BYP_B,
  66             dip->sdsi_bypassed_b);
  67         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_BYP_A,
  68             dip->sdsi_bypassed_a);
  69         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_OFF,
  70             dip->sdsi_device_off);
  71         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_FAULT_RQSTD,
  72             dip->sdsi_fault_reqstd);
  73         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_FAULT_SENSED,
  74             dip->sdsi_fault_sensed);
  75         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_APP_BYP_B,
  76             dip->sdsi_app_client_bypassed_b);
  77 
  78         return (0);
  79 }
  80 
  81 static int
  82 elem_parse_psu(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
  83 {
  84         ses2_psu_status_impl_t *pip = (ses2_psu_status_impl_t *)esip;
  85         int nverr;
  86 
  87         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
  88             pip->spsi_ident);
  89         SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_DC_OVER_CURRENT,
  90             pip->spsi_dc_over_current);
  91         SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_DC_UNDER_VOLTAGE,
  92             pip->spsi_dc_under_voltage);
  93         SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_DC_OVER_VOLTAGE,
  94             pip->spsi_dc_over_voltage);
  95         SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_DC_FAIL,
  96             pip->spsi_dc_fail);
  97         SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_AC_FAIL,
  98             pip->spsi_ac_fail);
  99         SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_TEMP_WARN,
 100             pip->spsi_temp_warn);
 101         SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_OVERTEMP_FAIL,
 102             pip->spsi_overtmp_fail);
 103         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_OFF, pip->spsi_off);
 104         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REQUESTED_ON,
 105             pip->spsi_rqsted_on);
 106         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, pip->spsi_fail);
 107         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_HOT_SWAP,
 108             pip->spsi_hot_swap);
 109 
 110         return (0);
 111 }
 112 
 113 static int
 114 elem_parse_cooling(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 115 {
 116         ses2_cooling_status_impl_t *cip = (ses2_cooling_status_impl_t *)esip;
 117         int nverr;
 118 
 119         SES_NV_ADD(uint64, nverr, nvl, SES_COOLING_PROP_FAN_SPEED,
 120             SES2_ES_COOLING_ST_FAN_SPEED(cip));
 121         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
 122             cip->scsi_ident);
 123         SES_NV_ADD(uint64, nverr, nvl, SES_COOLING_PROP_SPEED_CODE,
 124             cip->scsi_actual_speed_code);
 125         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_OFF, cip->scsi_off);
 126         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REQUESTED_ON,
 127             cip->scsi_requested_on);
 128         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, cip->scsi_fail);
 129 
 130         return (0);
 131 }
 132 
 133 static int
 134 elem_parse_temp(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 135 {
 136         ses2_temp_status_impl_t *tip = (ses2_temp_status_impl_t *)esip;
 137         int nverr;
 138 
 139         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, tip->stsi_ident);
 140         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, tip->stsi_fail);
 141         SES_NV_ADD(int64, nverr, nvl, SES_TEMP_PROP_TEMP,
 142             SES2_ES_TEMP_ST_TEMPERATURE(tip));
 143         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_WARN_UNDER,
 144             tip->stsi_ut_warn);
 145         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_CRIT_UNDER,
 146             tip->stsi_ut_fail);
 147         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_WARN_OVER,
 148             tip->stsi_ot_warn);
 149         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_CRIT_OVER,
 150             tip->stsi_ot_fail);
 151 
 152         return (0);
 153 }
 154 
 155 static int
 156 elem_parse_lock(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 157 {
 158         ses2_lock_status_impl_t *lip = (ses2_lock_status_impl_t *)esip;
 159         int nverr;
 160 
 161         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL,
 162             lip->slsi_fail);
 163         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
 164             lip->slsi_ident);
 165         SES_NV_ADD(boolean_value, nverr, nvl, SES_LOCK_PROP_UNLOCKED,
 166             lip->slsi_unlocked);
 167 
 168         return (0);
 169 }
 170 
 171 static int
 172 elem_parse_alarm(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 173 {
 174         ses2_alarm_status_impl_t *aip = (ses2_alarm_status_impl_t *)esip;
 175         int nverr;
 176 
 177         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, aip->sasi_fail);
 178         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
 179             aip->sasi_ident);
 180         SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_UNRECOV,
 181             aip->sasi_unrecov);
 182         SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_CRIT,
 183             aip->sasi_crit);
 184         SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_NONCRIT,
 185             aip->sasi_noncrit);
 186         SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_INFO,
 187             aip->sasi_info);
 188         SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_REMIND,
 189             aip->sasi_remind);
 190         SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_MUTED,
 191             aip->sasi_muted);
 192         SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_RQST_MUTE,
 193             aip->sasi_rqst_mute);
 194 
 195         return (0);
 196 }
 197 
 198 static int
 199 elem_parse_esc(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 200 {
 201         ses2_controller_status_impl_t *cip =
 202             (ses2_controller_status_impl_t *)esip;
 203         int nverr;
 204 
 205         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, cip->scsi_fail);
 206         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, cip->scsi_ident);
 207         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
 208             cip->scsi_report);
 209         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_HOT_SWAP,
 210             cip->scsi_hot_swap);
 211 
 212         return (0);
 213 }
 214 
 215 static int
 216 elem_parse_scc(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 217 {
 218         ses2_scc_status_impl_t *sip = (ses2_scc_status_impl_t *)esip;
 219         int nverr;
 220 
 221         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, sip->sss_fail);
 222         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, sip->sss_ident);
 223         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
 224             sip->sss_report);
 225 
 226         return (0);
 227 }
 228 
 229 static int
 230 elem_parse_cache(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 231 {
 232         ses2_nvcache_status_impl_t *np = (ses2_nvcache_status_impl_t *)esip;
 233         int nverr;
 234 
 235         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, np->snsi_fail);
 236         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
 237             np->snsi_ident);
 238         SES_NV_ADD(uint64, nverr, nvl, SES_CACHE_PROP_SIZE,
 239             SES2_NVCACHE_SIZE(np));
 240 
 241         return (0);
 242 }
 243 
 244 static int
 245 elem_parse_ups(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 246 {
 247         ses2_ups_status_impl_t *uip = (ses2_ups_status_impl_t *)esip;
 248         int nverr;
 249 
 250         SES_NV_ADD(uint64, nverr, nvl, SES_UPS_PROP_TIMELEFT,
 251             uip->susi_battery_status);
 252         SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_INTF_FAIL,
 253             uip->susi_intf_fail);
 254         SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_WARN,
 255             uip->susi_warn);
 256         SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_UPS_FAIL,
 257             uip->susi_ups_fail);
 258         SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_DC_FAIL,
 259             uip->susi_dc_fail);
 260         SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_AC_FAIL,
 261             uip->susi_ac_fail);
 262         SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_AC_QUAL,
 263             uip->susi_ac_qual);
 264         SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_AC_HI,
 265             uip->susi_ac_hi);
 266         SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_AC_LO,
 267             uip->susi_ac_lo);
 268         SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_BPF, uip->susi_bpf);
 269         SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_BATT_FAIL,
 270             uip->susi_batt_fail);
 271         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, uip->susi_fail);
 272         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, uip->susi_ident);
 273 
 274         return (0);
 275 }
 276 
 277 static int
 278 elem_parse_display(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 279 {
 280         ses2_display_status_impl_t *dip = (ses2_display_status_impl_t *)esip;
 281         int nverr;
 282 
 283         SES_NV_ADD(uint64, nverr, nvl, SES_DPY_PROP_MODE,
 284             dip->sdsi_display_mode_status);
 285         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, dip->sdsi_fail);
 286         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, dip->sdsi_ident);
 287         SES_NV_ADD(uint16, nverr, nvl, SES_DPY_PROP_CHAR,
 288             dip->sdsi_display_character_status);
 289 
 290         return (0);
 291 }
 292 
 293 static int
 294 elem_parse_keypad(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 295 {
 296         ses2_keypad_status_impl_t *kip = (ses2_keypad_status_impl_t *)esip;
 297         int nverr;
 298 
 299         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, kip->sksi_fail);
 300         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, kip->sksi_ident);
 301 
 302         return (0);
 303 }
 304 
 305 static int
 306 elem_parse_px(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 307 {
 308         ses2_port_status_impl_t *pip = (ses2_port_status_impl_t *)esip;
 309         int nverr;
 310 
 311         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, pip->spsi_fail);
 312         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, pip->spsi_ident);
 313         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
 314             pip->spsi_report);
 315         SES_NV_ADD(boolean_value, nverr, nvl, SES_PX_PROP_XMIT_FAIL,
 316             pip->spsi_xmit_fail);
 317         SES_NV_ADD(boolean_value, nverr, nvl, SES_PX_PROP_LOL, pip->spsi_lol);
 318         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_DISABLED,
 319             pip->spsi_disabled);
 320 
 321         return (0);
 322 }
 323 
 324 static int
 325 elem_parse_lang(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 326 {
 327         ses2_lang_status_impl_t *lip = (ses2_lang_status_impl_t *)esip;
 328         int nverr;
 329 
 330         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
 331             lip->slsi_ident);
 332         SES_NV_ADD(uint64, nverr, nvl, SES_LANG_PROP_LANGCODE,
 333             SCSI_READ16(&lip->slsi_language_code));
 334 
 335         return (0);
 336 }
 337 
 338 static int
 339 elem_parse_comm(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 340 {
 341         ses2_comm_status_impl_t *cip = (ses2_comm_status_impl_t *)esip;
 342         int nverr;
 343 
 344         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, cip->scsi_fail);
 345         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
 346             cip->scsi_ident);
 347         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_DISABLED,
 348             cip->scsi_disabled);
 349 
 350         return (0);
 351 }
 352 
 353 static int
 354 elem_parse_voltage(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 355 {
 356         ses2_voltage_status_impl_t *vip = (ses2_voltage_status_impl_t *)esip;
 357         int nverr;
 358 
 359         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_CRIT_UNDER,
 360             vip->svsi_crit_under);
 361         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_CRIT_OVER,
 362             vip->svsi_crit_over);
 363         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_WARN_UNDER,
 364             vip->svsi_warn_under);
 365         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_WARN_OVER,
 366             vip->svsi_warn_over);
 367         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, vip->svsi_fail);
 368         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, vip->svsi_ident);
 369         SES_NV_ADD(int64, nverr, nvl, SES_VS_PROP_VOLTAGE_MV,
 370             SCSI_READ16(&vip->svsi_voltage));
 371 
 372         return (0);
 373 }
 374 
 375 static int
 376 elem_parse_current(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 377 {
 378         ses2_current_status_impl_t *cip = (ses2_current_status_impl_t *)esip;
 379         int nverr;
 380 
 381         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_CRIT_OVER,
 382             cip->scsi_crit_over);
 383         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_WARN_OVER,
 384             cip->scsi_warn_over);
 385         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, cip->scsi_fail);
 386         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, cip->scsi_ident);
 387         SES_NV_ADD(int64, nverr, nvl, SES_CS_PROP_CURRENT_MA,
 388             SCSI_READ16(&cip->scsi_current));
 389 
 390         return (0);
 391 }
 392 
 393 static int
 394 elem_parse_itp(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 395 {
 396         ses2_itp_status_impl_t *iip = (ses2_itp_status_impl_t *)esip;
 397         int nverr;
 398 
 399         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, iip->sisi_fail);
 400         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
 401             iip->sisi_ident);
 402         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
 403             iip->sisi_report);
 404         SES_NV_ADD(boolean_value, nverr, nvl, SES_ITP_PROP_ENABLED,
 405             iip->sisi_enabled);
 406 
 407         return (0);
 408 }
 409 
 410 static int
 411 elem_parse_sse(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 412 {
 413         ses2_ss_status_impl_t *sip = (ses2_ss_status_impl_t *)esip;
 414         int nverr;
 415 
 416         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, sip->sss_fail);
 417         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, sip->sss_ident);
 418         SES_NV_ADD(uint64, nverr, nvl, SES_SS_PROP_SHORT_STATUS,
 419             sip->sss_short_status);
 420 
 421         return (0);
 422 }
 423 
 424 static int
 425 elem_parse_arraydev(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 426 {
 427         ses2_array_device_status_impl_t *aip =
 428             (ses2_array_device_status_impl_t *)esip;
 429         int nverr;
 430 
 431         SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_RR_ABORT,
 432             aip->sadsi_rr_abort);
 433         SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_REBUILD,
 434             aip->sadsi_rebuild);
 435         SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_IN_FAILED_ARRAY,
 436             aip->sadsi_in_failed_array);
 437         SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_IN_CRIT_ARRAY,
 438             aip->sadsi_in_crit_array);
 439         SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_CONS_CHK,
 440             aip->sadsi_cons_chk);
 441         SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_HOT_SPARE,
 442             aip->sadsi_hot_spare);
 443         SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_RSVD_DEVICE,
 444             aip->sadsi_rsvd_device);
 445         SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_OK, aip->sadsi_ok);
 446         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
 447             aip->sadsi_report);
 448         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, aip->sadsi_ident);
 449         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_RMV, aip->sadsi_rmv);
 450         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_READY_TO_INSERT,
 451             aip->sadsi_ready_to_insert);
 452         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_ENC_BYP_B,
 453             aip->sadsi_enclosure_bypassed_b);
 454         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_ENC_BYP_A,
 455             aip->sadsi_enclosure_bypassed_a);
 456         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DO_NOT_REMOVE,
 457             aip->sadsi_do_not_remove);
 458         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_APP_BYP_A,
 459             aip->sadsi_app_client_bypassed_a);
 460         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DEV_BYP_B,
 461             aip->sadsi_device_bypassed_b);
 462         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DEV_BYP_A,
 463             aip->sadsi_device_bypassed_a);
 464         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_BYP_B,
 465             aip->sadsi_bypassed_b);
 466         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_BYP_A,
 467             aip->sadsi_bypassed_a);
 468         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_OFF,
 469             aip->sadsi_device_off);
 470         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_FAULT_RQSTD,
 471             aip->sadsi_fault_reqstd);
 472         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_FAULT_SENSED,
 473             aip->sadsi_fault_sensed);
 474         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_APP_BYP_B,
 475             aip->sadsi_app_client_bypassed_b);
 476 
 477         return (0);
 478 }
 479 
 480 static int
 481 elem_parse_expander(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 482 {
 483         ses2_expander_status_impl_t *eip = (ses2_expander_status_impl_t *)esip;
 484         int nverr;
 485 
 486         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, eip->sesi_fail);
 487         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, eip->sesi_ident);
 488 
 489         return (0);
 490 }
 491 
 492 static int
 493 elem_parse_sasconn(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 494 {
 495         ses2_sasconn_status_impl_t *sip = (ses2_sasconn_status_impl_t *)esip;
 496         int nverr;
 497 
 498         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, sip->sss_fail);
 499         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, sip->sss_ident);
 500         SES_NV_ADD(uint64, nverr, nvl, SES_SC_PROP_CONNECTOR_TYPE,
 501             sip->sss_connector_type);
 502         SES_NV_ADD(uint64, nverr, nvl, SES_SC_PROP_PHYSICAL_LINK,
 503             sip->sss_connector_physical_link);
 504 
 505         return (0);
 506 }
 507 
 508 static const struct status_parser {
 509         ses2_element_type_t type;
 510         int (*func)(const ses2_elem_status_impl_t *, nvlist_t *);
 511 } status_parsers[] = {
 512         { SES_ET_DEVICE, elem_parse_device },
 513         { SES_ET_POWER_SUPPLY, elem_parse_psu },
 514         { SES_ET_COOLING, elem_parse_cooling },
 515         { SES_ET_TEMPERATURE_SENSOR, elem_parse_temp },
 516         { SES_ET_DOOR_LOCK, elem_parse_lock },
 517         { SES_ET_AUDIBLE_ALARM, elem_parse_alarm },
 518         { SES_ET_ESC_ELECTRONICS, elem_parse_esc },
 519         { SES_ET_SCC_ELECTRONICS, elem_parse_scc },
 520         { SES_ET_NONVOLATILE_CACHE, elem_parse_cache },
 521         { SES_ET_UPS, elem_parse_ups },
 522         { SES_ET_DISPLAY, elem_parse_display },
 523         { SES_ET_KEY_PAD_ENTRY, elem_parse_keypad },
 524         { SES_ET_SCSI_PORT_XCVR, elem_parse_px },
 525         { SES_ET_LANGUAGE, elem_parse_lang },
 526         { SES_ET_COMMUNICATION_PORT, elem_parse_comm },
 527         { SES_ET_VOLTAGE_SENSOR, elem_parse_voltage },
 528         { SES_ET_CURRENT_SENSOR, elem_parse_current },
 529         { SES_ET_SCSI_TARGET_PORT, elem_parse_itp },
 530         { SES_ET_SCSI_INITIATOR_PORT, elem_parse_itp },
 531         { SES_ET_SIMPLE_SUBENCLOSURE, elem_parse_sse },
 532         { SES_ET_ARRAY_DEVICE, elem_parse_arraydev },
 533         { SES_ET_SAS_EXPANDER, elem_parse_expander },
 534         { SES_ET_SAS_CONNECTOR, elem_parse_sasconn },
 535         { (ses2_element_type_t)-1, NULL }
 536 };
 537 
 538 static int
 539 elem_parse_sd(ses_plugin_t *spp, ses_node_t *np)
 540 {
 541         ses2_elem_status_impl_t *esip;
 542         const struct status_parser *sp;
 543         nvlist_t *nvl = ses_node_props(np);
 544         size_t len;
 545         int nverr;
 546         uint64_t type;
 547 
 548         if ((esip = ses_plugin_page_lookup(spp,
 549             ses_node_snapshot(np), SES2_DIAGPAGE_ENCLOSURE_CTL_STATUS,
 550             np, &len)) == NULL)
 551                 return (0);
 552 
 553         VERIFY(nvlist_lookup_uint64(nvl, SES_PROP_ELEMENT_TYPE,
 554             &type) == 0);
 555 
 556         SES_NV_ADD(uint64, nverr, nvl, SES_PROP_STATUS_CODE,
 557             esip->sesi_common.sesi_status_code);
 558         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_SWAP,
 559             esip->sesi_common.sesi_swap);
 560         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_DISABLED,
 561             esip->sesi_common.sesi_disabled);
 562         SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_PRDFAIL,
 563             esip->sesi_common.sesi_prdfail);
 564 
 565         for (sp = &status_parsers[0]; sp->type != (ses2_element_type_t)-1; sp++)
 566                 if (sp->type == type && sp->func != NULL)
 567                         return (sp->func(esip, nvl));
 568 
 569         return (0);
 570 }
 571 
 572 static int
 573 elem_parse_descr(ses_plugin_t *sp, ses_node_t *np)
 574 {
 575         char *desc;
 576         size_t len;
 577         nvlist_t *props = ses_node_props(np);
 578         int nverr;
 579 
 580         if ((desc = ses_plugin_page_lookup(sp, ses_node_snapshot(np),
 581             SES2_DIAGPAGE_ELEMENT_DESC, np, &len)) == NULL)
 582                 return (0);
 583 
 584         SES_NV_ADD(fixed_string, nverr, props, SES_PROP_DESCRIPTION,
 585             desc, len);
 586 
 587         return (0);
 588 }
 589 
 590 static int
 591 elem_parse_aes_fc(const ses2_aes_descr_fc_eip_impl_t *fp,
 592     nvlist_t *nvl, size_t len)
 593 {
 594         int nverr, i;
 595         nvlist_t **nva;
 596         int nports;
 597 
 598         if (len < offsetof(ses2_aes_descr_fc_eip_impl_t,
 599             sadfi_ports))
 600                 return (0);
 601 
 602         SES_NV_ADD(uint64, nverr, nvl, SES_PROP_BAY_NUMBER,
 603             fp->sadfi_bay_number);
 604         SES_NV_ADD(uint64, nverr, nvl, SES_FC_PROP_NODE_NAME,
 605             SCSI_READ64(&fp->sadfi_node_name));
 606 
 607         nports = MIN(fp->sadfi_n_ports,
 608             (len - offsetof(ses2_aes_descr_fc_eip_impl_t,
 609             sadfi_ports)) / sizeof (ses2_aes_port_descr_impl_t));
 610 
 611         if (nports == 0)
 612                 return (0);
 613 
 614         nva = ses_zalloc(nports * sizeof (nvlist_t *));
 615         if (nva == NULL)
 616                 return (-1);
 617 
 618         for (i = 0; i < nports; i++) {
 619                 if ((nverr = nvlist_alloc(&nva[i], NV_UNIQUE_NAME, 0)) != 0)
 620                         goto fail;
 621                 if ((nverr = nvlist_add_uint64(nva[i], SES_FC_PROP_LOOP_POS,
 622                     fp->sadfi_ports[i].sapdi_port_loop_position)) != 0)
 623                         goto fail;
 624                 if ((nverr = nvlist_add_uint64(nva[i], SES_FC_PROP_REQ_HARDADDR,
 625                     fp->sadfi_ports[i].sapdi_port_requested_hard_address)) != 0)
 626                         goto fail;
 627                 nverr = nvlist_add_uint64(nva[i], SES_FC_PROP_N_PORT_ID,
 628                     SCSI_READ24(fp->sadfi_ports[i].sapdi_n_port_identifier));
 629                 if (nverr != 0)
 630                         goto fail;
 631                 if ((nverr = nvlist_add_uint64(nva[i], SES_FC_PROP_N_PORT_NAME,
 632                     SCSI_READ64(&fp->sadfi_ports[i].sapdi_n_port_name))) != 0)
 633                         goto fail;
 634         }
 635 
 636         if ((nverr = nvlist_add_nvlist_array(nvl, SES_FC_PROP_PORTS,
 637             nva, nports)) != 0)
 638                 goto fail;
 639 
 640         for (i = 0; i < nports && nva[i] != NULL; i++)
 641                 nvlist_free(nva[i]);
 642         ses_free(nva);
 643         return (0);
 644 
 645 fail:
 646         for (i = 0; i < nports && nva[i] != NULL; i++)
 647                 nvlist_free(nva[i]);
 648         ses_free(nva);
 649         return (ses_set_nverrno(nverr, NULL));
 650 }
 651 
 652 /*
 653  * Parse the AES (0xa) SES diagnostic page.
 654  *
 655  * When making changes here, keep in mind that AES (re)parsing may be done by
 656  * libses plugin(s) so it may need to be updated as well.
 657  */
 658 static int
 659 elem_parse_aes_device(const ses2_aes_descr_eip_impl_t *dep, nvlist_t *nvl,
 660     size_t len)
 661 {
 662         ses2_aes_descr_fc_eip_impl_t *fp;
 663         ses2_aes_descr_sas0_eip_impl_t *s0ep;
 664         ses2_aes_descr_sas0_impl_t *s0p;
 665         ses2_aes_descr_impl_t *dip;
 666         nvlist_t **nva;
 667         int nverr, i;
 668         size_t nphy;
 669 
 670         if (dep->sadei_eip) {
 671                 s0ep = (ses2_aes_descr_sas0_eip_impl_t *)
 672                     dep->sadei_protocol_specific;
 673                 s0p = (ses2_aes_descr_sas0_impl_t *)
 674                     dep->sadei_protocol_specific;
 675         } else {
 676                 dip = (ses2_aes_descr_impl_t *)dep;
 677                 s0ep = NULL;
 678                 s0p = (ses2_aes_descr_sas0_impl_t *)
 679                     dip->sadei_protocol_specific;
 680         }
 681 
 682         if (dep->sadei_invalid)
 683                 return (0);
 684 
 685         if (dep->sadei_protocol_identifier == SPC4_PROTO_FIBRE_CHANNEL) {
 686                 fp = (ses2_aes_descr_fc_eip_impl_t *)
 687                     dep->sadei_protocol_specific;
 688 
 689                 if (!SES_WITHIN_PAGE_STRUCT(fp, dep, len))
 690                         return (0);
 691 
 692                 return (elem_parse_aes_fc(fp, nvl, len -
 693                     offsetof(ses2_aes_descr_eip_impl_t,
 694                     sadei_protocol_specific)));
 695         } else if (dep->sadei_protocol_identifier != SPC4_PROTO_SAS) {
 696                 return (0);
 697         }
 698 
 699         if (s0p->sadsi_descriptor_type != SES2_AESD_SAS_DEVICE)
 700                 return (0);
 701 
 702         SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_SAS_NOT_ALL_PHYS,
 703             s0p->sadsi_not_all_phys);
 704         if (s0ep != NULL) {
 705                 SES_NV_ADD(uint64, nverr, nvl, SES_PROP_BAY_NUMBER,
 706                     s0ep->sadsi_bay_number);
 707                 nphy = MIN(s0ep->sadsi_n_phy_descriptors,
 708                     (len - offsetof(ses2_aes_descr_sas0_eip_impl_t,
 709                     sadsi_phys)) / sizeof (ses2_aes_phy0_descr_impl_t));
 710         } else {
 711                 nphy = MIN(s0p->sadsi_n_phy_descriptors,
 712                     (len - offsetof(ses2_aes_descr_sas0_impl_t,
 713                     sadsi_phys)) / sizeof (ses2_aes_phy0_descr_impl_t));
 714         }
 715 
 716         if (nphy == 0)
 717                 return (0);
 718 
 719         nva = ses_zalloc(nphy * sizeof (nvlist_t *));
 720         if (nva == NULL)
 721                 return (-1);
 722 
 723         for (i = 0; i < nphy; i++) {
 724                 ses2_aes_phy0_descr_impl_t *pp;
 725                 pp = s0ep != NULL ? &s0ep->sadsi_phys[i] : &s0p->sadsi_phys[i];
 726                 if ((nverr = nvlist_alloc(&nva[i], NV_UNIQUE_NAME, 0)) != 0)
 727                         goto fail;
 728                 if ((nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_DEVICE_TYPE,
 729                     pp->sapdi_device_type)) != 0)
 730                         goto fail;
 731                 if ((nverr = nvlist_add_boolean_value(nva[i],
 732                     SES_SAS_PROP_SMPI_PORT, pp->sapdi_smp_initiator_port)) != 0)
 733                         goto fail;
 734                 if ((nverr = nvlist_add_boolean_value(nva[i],
 735                     SES_SAS_PROP_STPI_PORT, pp->sapdi_stp_initiator_port)) != 0)
 736                         goto fail;
 737                 if ((nverr = nvlist_add_boolean_value(nva[i],
 738                     SES_SAS_PROP_SSPI_PORT, pp->sapdi_ssp_initiator_port)) != 0)
 739                         goto fail;
 740                 if ((nverr = nvlist_add_boolean_value(nva[i],
 741                     SES_SAS_PROP_SATA_DEVICE, pp->sapdi_sata_device)) != 0)
 742                         goto fail;
 743                 if ((nverr = nvlist_add_boolean_value(nva[i],
 744                     SES_SAS_PROP_SMPT_PORT, pp->sapdi_smp_target_port)) != 0)
 745                         goto fail;
 746                 if ((nverr = nvlist_add_boolean_value(nva[i],
 747                     SES_SAS_PROP_STPT_PORT, pp->sapdi_stp_target_port)) != 0)
 748                         goto fail;
 749                 if ((nverr = nvlist_add_boolean_value(nva[i],
 750                     SES_SAS_PROP_SSPT_PORT, pp->sapdi_ssp_target_port)) != 0)
 751                         goto fail;
 752                 nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_ATT_ADDR,
 753                     SCSI_READ64(&pp->sapdi_attached_sas_address));
 754                 if (nverr != 0)
 755                         goto fail;
 756                 nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_ADDR,
 757                     SCSI_READ64(&pp->sapdi_sas_address));
 758                 if (nverr != 0)
 759                         goto fail;
 760                 if ((nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_PHY_ID,
 761                     pp->sapdi_phy_identifier)) != 0)
 762                         goto fail;
 763         }
 764 
 765         if ((nverr = nvlist_add_nvlist_array(nvl, SES_SAS_PROP_PHYS,
 766             nva, nphy)) != 0)
 767                 goto fail;
 768 
 769         for (i = 0; i < nphy && nva[i] != NULL; i++)
 770                 nvlist_free(nva[i]);
 771         ses_free(nva);
 772         return (0);
 773 
 774 fail:
 775         for (i = 0; i < nphy && nva[i] != NULL; i++)
 776                 nvlist_free(nva[i]);
 777         ses_free(nva);
 778         return (ses_set_nverrno(nverr, NULL));
 779 }
 780 
 781 static int
 782 elem_parse_aes_expander(const ses2_aes_descr_eip_impl_t *dep, nvlist_t *nvl,
 783     size_t len)
 784 {
 785         ses2_aes_descr_exp_impl_t *sep;
 786         nvlist_t **nva;
 787         int nverr, i;
 788         size_t nphy;
 789 
 790         if (dep->sadei_invalid)
 791                 return (0);
 792 
 793         /*
 794          * This should never happen; no current SAS expander can have any
 795          * other kind of ports.  But maybe someday - one could envision a
 796          * SAS expander with iSCSI target ports, for example.
 797          */
 798         if (dep->sadei_protocol_identifier != SPC4_PROTO_SAS)
 799                 return (0);
 800 
 801         sep = (ses2_aes_descr_exp_impl_t *)dep->sadei_protocol_specific;
 802         if (sep->sadei_descriptor_type != SES2_AESD_SAS_OTHER)
 803                 return (0);
 804 
 805         SES_NV_ADD(uint64, nverr, nvl, SES_EXP_PROP_SAS_ADDR,
 806             SCSI_READ64(&sep->sadei_sas_address));
 807 
 808         nphy = MIN(sep->sadei_n_exp_phy_descriptors,
 809             (len - offsetof(ses2_aes_descr_exp_impl_t,
 810             sadei_phys)) / sizeof (ses2_aes_exp_phy_descr_impl_t));
 811 
 812         if (nphy == 0)
 813                 return (0);
 814 
 815         nva = ses_zalloc(nphy * sizeof (nvlist_t *));
 816         if (nva == NULL)
 817                 return (-1);
 818 
 819         for (i = 0; i < nphy; i++) {
 820                 if ((nverr = nvlist_alloc(&nva[i], NV_UNIQUE_NAME, 0)) != 0)
 821                         goto fail;
 822                 if ((nverr = nvlist_add_uint64(nva[i], SES_PROP_CE_IDX,
 823                     sep->sadei_phys[i].saepdi_connector_element_index)) != 0)
 824                         goto fail;
 825                 if ((nverr = nvlist_add_uint64(nva[i], SES_PROP_OE_IDX,
 826                     sep->sadei_phys[i].saepdi_other_element_index)) != 0)
 827                         goto fail;
 828         }
 829 
 830         if ((nverr = nvlist_add_nvlist_array(nvl, SES_SAS_PROP_PHYS,
 831             nva, nphy)) != 0)
 832                 goto fail;
 833 
 834         for (i = 0; i < nphy && nva[i] != NULL; i++)
 835                 nvlist_free(nva[i]);
 836         ses_free(nva);
 837         return (0);
 838 
 839 fail:
 840         for (i = 0; i < nphy && nva[i] != NULL; i++)
 841                 nvlist_free(nva[i]);
 842         ses_free(nva);
 843         return (ses_set_nverrno(nverr, NULL));
 844 }
 845 
 846 static int
 847 elem_parse_aes_misc(const ses2_aes_descr_eip_impl_t *dep, nvlist_t *nvl,
 848     size_t len)
 849 {
 850         ses2_aes_descr_fc_eip_impl_t *fp;
 851         ses2_aes_descr_sas1_impl_t *s1p;
 852         nvlist_t **nva;
 853         int nverr, i;
 854         size_t nphy;
 855 
 856         if (dep->sadei_invalid)
 857                 return (0);
 858 
 859         if (dep->sadei_protocol_identifier == SPC4_PROTO_FIBRE_CHANNEL) {
 860                 fp = (ses2_aes_descr_fc_eip_impl_t *)
 861                     dep->sadei_protocol_specific;
 862 
 863                 if (!SES_WITHIN_PAGE_STRUCT(fp, dep, len))
 864                         return (0);
 865 
 866                 return (elem_parse_aes_fc(fp, nvl, len -
 867                     offsetof(ses2_aes_descr_eip_impl_t,
 868                     sadei_protocol_specific)));
 869         } else if (dep->sadei_protocol_identifier != SPC4_PROTO_SAS) {
 870                 return (0);
 871         }
 872 
 873         s1p = (ses2_aes_descr_sas1_impl_t *)dep->sadei_protocol_specific;
 874         if (s1p->sadsi_descriptor_type == SES2_AESD_SAS_DEVICE)
 875                 return (0);
 876 
 877         nphy = MIN(s1p->sadsi_n_phy_descriptors,
 878             (len - offsetof(ses2_aes_descr_sas1_impl_t,
 879             sadsi_phys)) / sizeof (ses2_aes_phy1_descr_impl_t));
 880 
 881         nva = ses_zalloc(nphy * sizeof (nvlist_t *));
 882         if (nva == NULL)
 883                 return (-1);
 884 
 885         for (i = 0; i < nphy; i++) {
 886                 if ((nverr = nvlist_alloc(&nva[i], NV_UNIQUE_NAME, 0)) != 0)
 887                         goto fail;
 888                 if ((nverr = nvlist_add_uint64(nva[i], SES_PROP_CE_IDX,
 889                     s1p->sadsi_phys[i].sapdi_connector_element_index)) != 0)
 890                         goto fail;
 891                 if ((nverr = nvlist_add_uint64(nva[i], SES_PROP_OE_IDX,
 892                     s1p->sadsi_phys[i].sapdi_other_element_index)) != 0)
 893                         goto fail;
 894                 if ((nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_ADDR,
 895                     SCSI_READ64(&s1p->sadsi_phys[i].sapdi_sas_address))) != 0)
 896                         goto fail;
 897         }
 898 
 899         if ((nverr = nvlist_add_nvlist_array(nvl, SES_SAS_PROP_PHYS,
 900             nva, nphy)) != 0)
 901                 goto fail;
 902 
 903         for (i = 0; i < nphy && nva[i] != NULL; i++)
 904                 nvlist_free(nva[i]);
 905 
 906         ses_free(nva);
 907         return (0);
 908 
 909 fail:
 910         for (i = 0; i < nphy && nva[i] != NULL; i++)
 911                 nvlist_free(nva[i]);
 912         ses_free(nva);
 913         return (nverr);
 914 }
 915 
 916 static const struct aes_parser {
 917         ses2_element_type_t type;
 918         int (*func)(const ses2_aes_descr_eip_impl_t *, nvlist_t *, size_t);
 919 } aes_parsers[] = {
 920         { SES_ET_DEVICE, elem_parse_aes_device },
 921         { SES_ET_SCSI_TARGET_PORT, elem_parse_aes_misc },
 922         { SES_ET_SCSI_INITIATOR_PORT, elem_parse_aes_misc },
 923         { SES_ET_ESC_ELECTRONICS, elem_parse_aes_misc },
 924         { SES_ET_ARRAY_DEVICE, elem_parse_aes_device },
 925         { SES_ET_SAS_EXPANDER, elem_parse_aes_expander },
 926         { (ses2_element_type_t)-1, NULL }
 927 };
 928 
 929 static int
 930 elem_parse_aes(ses_plugin_t *sp, ses_node_t *np)
 931 {
 932         ses2_aes_descr_eip_impl_t *dep;
 933         nvlist_t *props = ses_node_props(np);
 934         const struct aes_parser *app;
 935         uint64_t type;
 936         size_t len;
 937 
 938         if (ses_node_type(np) == SES_NODE_AGGREGATE)
 939                 return (0);
 940 
 941         VERIFY(nvlist_lookup_uint64(props, SES_PROP_ELEMENT_TYPE,
 942             &type) == 0);
 943 
 944         for (app = &aes_parsers[0]; app->func != NULL; app++)
 945                 if (app->type == type)
 946                         break;
 947         if (app->func == NULL)
 948                 return (0);
 949 
 950         if ((dep = ses_plugin_page_lookup(sp, ses_node_snapshot(np),
 951             SES2_DIAGPAGE_ADDL_ELEM_STATUS, np, &len)) == NULL)
 952                 return (0);
 953 
 954         return (app->func(dep, props, len));
 955 }
 956 
 957 static int
 958 elem_parse_threshold(ses_plugin_t *sp, ses_node_t *np)
 959 {
 960         ses_snap_t *snap = ses_node_snapshot(np);
 961         ses2_threshold_impl_t *tp;
 962         nvlist_t *nvl = ses_node_props(np);
 963         int nverr;
 964         uint64_t type;
 965         size_t len;
 966 
 967         VERIFY(nvlist_lookup_uint64(nvl, SES_PROP_ELEMENT_TYPE,
 968             &type) == 0);
 969 
 970         switch (type) {
 971         case SES_ET_TEMPERATURE_SENSOR:
 972         case SES_ET_UPS:
 973         case SES_ET_VOLTAGE_SENSOR:
 974         case SES_ET_CURRENT_SENSOR:
 975                 break;
 976         default:
 977                 return (0);
 978         }
 979 
 980         if ((tp = ses_plugin_page_lookup(sp, snap,
 981             SES2_DIAGPAGE_THRESHOLD_IO, np, &len)) == NULL)
 982                 return (0);
 983 
 984         SES_NV_ADD(uint64, nverr, nvl, SES_PROP_THRESH_CRIT_HI,
 985             tp->sti_high_crit);
 986         SES_NV_ADD(uint64, nverr, nvl, SES_PROP_THRESH_WARN_HI,
 987             tp->sti_high_warn);
 988         SES_NV_ADD(uint64, nverr, nvl, SES_PROP_THRESH_CRIT_LO,
 989             tp->sti_low_crit);
 990         SES_NV_ADD(uint64, nverr, nvl, SES_PROP_THRESH_WARN_LO,
 991             tp->sti_low_warn);
 992 
 993         return (0);
 994 }
 995 
 996 int
 997 ses2_fill_element_node(ses_plugin_t *sp, ses_node_t *np)
 998 {
 999         int err;
1000 
1001         if ((err = elem_parse_sd(sp, np)) != 0)
1002                 return (err);
1003 
1004         if ((err = elem_parse_descr(sp, np)) != 0)
1005                 return (err);
1006 
1007         if ((err = elem_parse_aes(sp, np)) != 0)
1008                 return (err);
1009 
1010         if ((err = elem_parse_threshold(sp, np)) != 0)
1011                 return (err);
1012 
1013         return (0);
1014 }