1275c9da8Seschrock /*
2275c9da8Seschrock  * CDDL HEADER START
3275c9da8Seschrock  *
4275c9da8Seschrock  * The contents of this file are subject to the terms of the
5275c9da8Seschrock  * Common Development and Distribution License (the "License").
6275c9da8Seschrock  * You may not use this file except in compliance with the License.
7275c9da8Seschrock  *
8275c9da8Seschrock  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9275c9da8Seschrock  * or http://www.opensolaris.org/os/licensing.
10275c9da8Seschrock  * See the License for the specific language governing permissions
11275c9da8Seschrock  * and limitations under the License.
12275c9da8Seschrock  *
13275c9da8Seschrock  * When distributing Covered Code, include this CDDL HEADER in each
14275c9da8Seschrock  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15275c9da8Seschrock  * If applicable, add the following below this CDDL HEADER, with the
16275c9da8Seschrock  * fields enclosed by brackets "[]" replaced with your own identifying
17275c9da8Seschrock  * information: Portions Copyright [yyyy] [name of copyright owner]
18275c9da8Seschrock  *
19275c9da8Seschrock  * CDDL HEADER END
20275c9da8Seschrock  */
21275c9da8Seschrock 
22275c9da8Seschrock /*
23275c9da8Seschrock  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
2414ae03cbSAndy Fiddaman  * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
25275c9da8Seschrock  * Use is subject to license terms.
26275c9da8Seschrock  */
27*1c124bccSGarrett D'Amore /*
28*1c124bccSGarrett D'Amore  * Copyright 2019 RackTop Systems.
29*1c124bccSGarrett D'Amore  */
30275c9da8Seschrock 
31275c9da8Seschrock #include <sys/types.h>
32275c9da8Seschrock #include <stddef.h>
33275c9da8Seschrock #include <stdio.h>
34275c9da8Seschrock #include <string.h>
35275c9da8Seschrock #include <libnvpair.h>
36275c9da8Seschrock 
37275c9da8Seschrock #include <scsi/libses.h>
38275c9da8Seschrock #include "ses2_impl.h"
39275c9da8Seschrock 
40275c9da8Seschrock static int
elem_parse_device(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)41275c9da8Seschrock elem_parse_device(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
42275c9da8Seschrock {
43275c9da8Seschrock 	ses2_device_status_impl_t *dip = (ses2_device_status_impl_t *)esip;
44275c9da8Seschrock 	int nverr;
45275c9da8Seschrock 
46275c9da8Seschrock 	SES_NV_ADD(uint64, nverr, nvl, SES_DEV_PROP_SLOT_ADDR,
47275c9da8Seschrock 	    dip->sdsi_slot_addr);
48275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
49275c9da8Seschrock 	    dip->sdsi_report);
50275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
51275c9da8Seschrock 	    dip->sdsi_ident);
52275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_RMV, dip->sdsi_rmv);
53275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_READY_TO_INSERT,
54275c9da8Seschrock 	    dip->sdsi_ready_to_insert);
55275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_ENC_BYP_B,
56275c9da8Seschrock 	    dip->sdsi_enclosure_bypassed_b);
57275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_ENC_BYP_A,
58275c9da8Seschrock 	    dip->sdsi_enclosure_bypassed_a);
59275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DO_NOT_REMOVE,
60275c9da8Seschrock 	    dip->sdsi_do_not_remove);
61275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_APP_BYP_A,
62275c9da8Seschrock 	    dip->sdsi_app_client_bypassed_a);
63275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DEV_BYP_B,
64275c9da8Seschrock 	    dip->sdsi_device_bypassed_b);
65275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DEV_BYP_A,
66275c9da8Seschrock 	    dip->sdsi_device_bypassed_a);
67275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_BYP_B,
68275c9da8Seschrock 	    dip->sdsi_bypassed_b);
69275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_BYP_A,
70275c9da8Seschrock 	    dip->sdsi_bypassed_a);
71275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_OFF,
72275c9da8Seschrock 	    dip->sdsi_device_off);
73275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_FAULT_RQSTD,
74275c9da8Seschrock 	    dip->sdsi_fault_reqstd);
75275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_FAULT_SENSED,
76275c9da8Seschrock 	    dip->sdsi_fault_sensed);
77275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_APP_BYP_B,
78275c9da8Seschrock 	    dip->sdsi_app_client_bypassed_b);
79275c9da8Seschrock 
80275c9da8Seschrock 	return (0);
81275c9da8Seschrock }
82275c9da8Seschrock 
83275c9da8Seschrock static int
elem_parse_psu(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)84275c9da8Seschrock elem_parse_psu(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
85275c9da8Seschrock {
86275c9da8Seschrock 	ses2_psu_status_impl_t *pip = (ses2_psu_status_impl_t *)esip;
87275c9da8Seschrock 	int nverr;
88275c9da8Seschrock 
89275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
90275c9da8Seschrock 	    pip->spsi_ident);
91275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_DC_OVER_CURRENT,
92275c9da8Seschrock 	    pip->spsi_dc_over_current);
93275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_DC_UNDER_VOLTAGE,
94275c9da8Seschrock 	    pip->spsi_dc_under_voltage);
95275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_DC_OVER_VOLTAGE,
96275c9da8Seschrock 	    pip->spsi_dc_over_voltage);
97275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_DC_FAIL,
98275c9da8Seschrock 	    pip->spsi_dc_fail);
99275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_AC_FAIL,
100275c9da8Seschrock 	    pip->spsi_ac_fail);
101275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_TEMP_WARN,
102275c9da8Seschrock 	    pip->spsi_temp_warn);
103275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_OVERTEMP_FAIL,
104275c9da8Seschrock 	    pip->spsi_overtmp_fail);
105275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_OFF, pip->spsi_off);
106275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REQUESTED_ON,
107275c9da8Seschrock 	    pip->spsi_rqsted_on);
108275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, pip->spsi_fail);
109275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_HOT_SWAP,
110275c9da8Seschrock 	    pip->spsi_hot_swap);
111275c9da8Seschrock 
112275c9da8Seschrock 	return (0);
113275c9da8Seschrock }
114275c9da8Seschrock 
115275c9da8Seschrock static int
elem_parse_cooling(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)116275c9da8Seschrock elem_parse_cooling(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
117275c9da8Seschrock {
118275c9da8Seschrock 	ses2_cooling_status_impl_t *cip = (ses2_cooling_status_impl_t *)esip;
119275c9da8Seschrock 	int nverr;
120275c9da8Seschrock 
121275c9da8Seschrock 	SES_NV_ADD(uint64, nverr, nvl, SES_COOLING_PROP_FAN_SPEED,
122275c9da8Seschrock 	    SES2_ES_COOLING_ST_FAN_SPEED(cip));
123275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
124275c9da8Seschrock 	    cip->scsi_ident);
125275c9da8Seschrock 	SES_NV_ADD(uint64, nverr, nvl, SES_COOLING_PROP_SPEED_CODE,
126275c9da8Seschrock 	    cip->scsi_actual_speed_code);
127275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_OFF, cip->scsi_off);
128275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REQUESTED_ON,
129275c9da8Seschrock 	    cip->scsi_requested_on);
130275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, cip->scsi_fail);
131275c9da8Seschrock 
132275c9da8Seschrock 	return (0);
133275c9da8Seschrock }
134275c9da8Seschrock 
135275c9da8Seschrock static int
elem_parse_temp(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)136275c9da8Seschrock elem_parse_temp(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
137275c9da8Seschrock {
138275c9da8Seschrock 	ses2_temp_status_impl_t *tip = (ses2_temp_status_impl_t *)esip;
139275c9da8Seschrock 	int nverr;
140275c9da8Seschrock 
141275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, tip->stsi_ident);
142275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, tip->stsi_fail);
143275c9da8Seschrock 	SES_NV_ADD(int64, nverr, nvl, SES_TEMP_PROP_TEMP,
144275c9da8Seschrock 	    SES2_ES_TEMP_ST_TEMPERATURE(tip));
1459af3851aSeschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_WARN_UNDER,
146275c9da8Seschrock 	    tip->stsi_ut_warn);
1479af3851aSeschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_CRIT_UNDER,
148275c9da8Seschrock 	    tip->stsi_ut_fail);
1499af3851aSeschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_WARN_OVER,
150275c9da8Seschrock 	    tip->stsi_ot_warn);
1519af3851aSeschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_CRIT_OVER,
152275c9da8Seschrock 	    tip->stsi_ot_fail);
153275c9da8Seschrock 
154275c9da8Seschrock 	return (0);
155275c9da8Seschrock }
156275c9da8Seschrock 
157275c9da8Seschrock static int
elem_parse_lock(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)158275c9da8Seschrock elem_parse_lock(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
159275c9da8Seschrock {
160275c9da8Seschrock 	ses2_lock_status_impl_t *lip = (ses2_lock_status_impl_t *)esip;
161275c9da8Seschrock 	int nverr;
162275c9da8Seschrock 
163275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL,
164275c9da8Seschrock 	    lip->slsi_fail);
165275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
166275c9da8Seschrock 	    lip->slsi_ident);
167275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_LOCK_PROP_UNLOCKED,
168275c9da8Seschrock 	    lip->slsi_unlocked);
169275c9da8Seschrock 
170275c9da8Seschrock 	return (0);
171275c9da8Seschrock }
172275c9da8Seschrock 
173275c9da8Seschrock static int
elem_parse_alarm(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)174275c9da8Seschrock elem_parse_alarm(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
175275c9da8Seschrock {
176275c9da8Seschrock 	ses2_alarm_status_impl_t *aip = (ses2_alarm_status_impl_t *)esip;
177275c9da8Seschrock 	int nverr;
178275c9da8Seschrock 
179275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, aip->sasi_fail);
180275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
181275c9da8Seschrock 	    aip->sasi_ident);
182275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_UNRECOV,
183275c9da8Seschrock 	    aip->sasi_unrecov);
184275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_CRIT,
185275c9da8Seschrock 	    aip->sasi_crit);
186275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_NONCRIT,
187275c9da8Seschrock 	    aip->sasi_noncrit);
188275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_INFO,
189275c9da8Seschrock 	    aip->sasi_info);
190275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_REMIND,
191275c9da8Seschrock 	    aip->sasi_remind);
192275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_MUTED,
193275c9da8Seschrock 	    aip->sasi_muted);
194275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_RQST_MUTE,
195275c9da8Seschrock 	    aip->sasi_rqst_mute);
196275c9da8Seschrock 
197275c9da8Seschrock 	return (0);
198275c9da8Seschrock }
199275c9da8Seschrock 
200275c9da8Seschrock static int
elem_parse_esc(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)201275c9da8Seschrock elem_parse_esc(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
202275c9da8Seschrock {
203275c9da8Seschrock 	ses2_controller_status_impl_t *cip =
204275c9da8Seschrock 	    (ses2_controller_status_impl_t *)esip;
205275c9da8Seschrock 	int nverr;
206275c9da8Seschrock 
207275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, cip->scsi_fail);
208275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, cip->scsi_ident);
209275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
210275c9da8Seschrock 	    cip->scsi_report);
211275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_HOT_SWAP,
212275c9da8Seschrock 	    cip->scsi_hot_swap);
213275c9da8Seschrock 
214275c9da8Seschrock 	return (0);
215275c9da8Seschrock }
216275c9da8Seschrock 
217275c9da8Seschrock static int
elem_parse_scc(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)218275c9da8Seschrock elem_parse_scc(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
219275c9da8Seschrock {
220275c9da8Seschrock 	ses2_scc_status_impl_t *sip = (ses2_scc_status_impl_t *)esip;
221275c9da8Seschrock 	int nverr;
222275c9da8Seschrock 
223275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, sip->sss_fail);
224275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, sip->sss_ident);
225275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
226275c9da8Seschrock 	    sip->sss_report);
227275c9da8Seschrock 
228275c9da8Seschrock 	return (0);
229275c9da8Seschrock }
230275c9da8Seschrock 
231275c9da8Seschrock static int
elem_parse_cache(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)232275c9da8Seschrock elem_parse_cache(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
233275c9da8Seschrock {
234275c9da8Seschrock 	ses2_nvcache_status_impl_t *np = (ses2_nvcache_status_impl_t *)esip;
235275c9da8Seschrock 	int nverr;
236275c9da8Seschrock 
237275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, np->snsi_fail);
238275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
239275c9da8Seschrock 	    np->snsi_ident);
240275c9da8Seschrock 	SES_NV_ADD(uint64, nverr, nvl, SES_CACHE_PROP_SIZE,
241275c9da8Seschrock 	    SES2_NVCACHE_SIZE(np));
242275c9da8Seschrock 
243275c9da8Seschrock 	return (0);
244275c9da8Seschrock }
245275c9da8Seschrock 
246275c9da8Seschrock static int
elem_parse_ups(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)247275c9da8Seschrock elem_parse_ups(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
248275c9da8Seschrock {
249275c9da8Seschrock 	ses2_ups_status_impl_t *uip = (ses2_ups_status_impl_t *)esip;
250275c9da8Seschrock 	int nverr;
251275c9da8Seschrock 
252275c9da8Seschrock 	SES_NV_ADD(uint64, nverr, nvl, SES_UPS_PROP_TIMELEFT,
253275c9da8Seschrock 	    uip->susi_battery_status);
254275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_INTF_FAIL,
255275c9da8Seschrock 	    uip->susi_intf_fail);
256275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_WARN,
257275c9da8Seschrock 	    uip->susi_warn);
258275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_UPS_FAIL,
259275c9da8Seschrock 	    uip->susi_ups_fail);
260275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_DC_FAIL,
261275c9da8Seschrock 	    uip->susi_dc_fail);
262275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_AC_FAIL,
263275c9da8Seschrock 	    uip->susi_ac_fail);
264275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_AC_QUAL,
265275c9da8Seschrock 	    uip->susi_ac_qual);
266275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_AC_HI,
267275c9da8Seschrock 	    uip->susi_ac_hi);
268275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_AC_LO,
269275c9da8Seschrock 	    uip->susi_ac_lo);
270275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_BPF, uip->susi_bpf);
271275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_BATT_FAIL,
272275c9da8Seschrock 	    uip->susi_batt_fail);
273275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, uip->susi_fail);
274275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, uip->susi_ident);
275275c9da8Seschrock 
276275c9da8Seschrock 	return (0);
277275c9da8Seschrock }
278275c9da8Seschrock 
279275c9da8Seschrock static int
elem_parse_display(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)280275c9da8Seschrock elem_parse_display(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
281275c9da8Seschrock {
282275c9da8Seschrock 	ses2_display_status_impl_t *dip = (ses2_display_status_impl_t *)esip;
283275c9da8Seschrock 	int nverr;
284275c9da8Seschrock 
285275c9da8Seschrock 	SES_NV_ADD(uint64, nverr, nvl, SES_DPY_PROP_MODE,
286275c9da8Seschrock 	    dip->sdsi_display_mode_status);
287275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, dip->sdsi_fail);
288275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, dip->sdsi_ident);
289275c9da8Seschrock 	SES_NV_ADD(uint16, nverr, nvl, SES_DPY_PROP_CHAR,
290275c9da8Seschrock 	    dip->sdsi_display_character_status);
291275c9da8Seschrock 
292275c9da8Seschrock 	return (0);
293275c9da8Seschrock }
294275c9da8Seschrock 
295275c9da8Seschrock static int
elem_parse_keypad(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)296275c9da8Seschrock elem_parse_keypad(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
297275c9da8Seschrock {
298275c9da8Seschrock 	ses2_keypad_status_impl_t *kip = (ses2_keypad_status_impl_t *)esip;
299275c9da8Seschrock 	int nverr;
300275c9da8Seschrock 
301275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, kip->sksi_fail);
302275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, kip->sksi_ident);
303275c9da8Seschrock 
304275c9da8Seschrock 	return (0);
305275c9da8Seschrock }
306275c9da8Seschrock 
307275c9da8Seschrock static int
elem_parse_px(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)308275c9da8Seschrock elem_parse_px(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
309275c9da8Seschrock {
310275c9da8Seschrock 	ses2_port_status_impl_t *pip = (ses2_port_status_impl_t *)esip;
311275c9da8Seschrock 	int nverr;
312275c9da8Seschrock 
313275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, pip->spsi_fail);
314275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, pip->spsi_ident);
315275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
316275c9da8Seschrock 	    pip->spsi_report);
317275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PX_PROP_XMIT_FAIL,
318275c9da8Seschrock 	    pip->spsi_xmit_fail);
319275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PX_PROP_LOL, pip->spsi_lol);
320275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_DISABLED,
321275c9da8Seschrock 	    pip->spsi_disabled);
322275c9da8Seschrock 
323275c9da8Seschrock 	return (0);
324275c9da8Seschrock }
325275c9da8Seschrock 
326275c9da8Seschrock static int
elem_parse_lang(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)327275c9da8Seschrock elem_parse_lang(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
328275c9da8Seschrock {
329275c9da8Seschrock 	ses2_lang_status_impl_t *lip = (ses2_lang_status_impl_t *)esip;
330275c9da8Seschrock 	int nverr;
331275c9da8Seschrock 
332275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
333275c9da8Seschrock 	    lip->slsi_ident);
334275c9da8Seschrock 	SES_NV_ADD(uint64, nverr, nvl, SES_LANG_PROP_LANGCODE,
335275c9da8Seschrock 	    SCSI_READ16(&lip->slsi_language_code));
336275c9da8Seschrock 
337275c9da8Seschrock 	return (0);
338275c9da8Seschrock }
339275c9da8Seschrock 
340275c9da8Seschrock static int
elem_parse_comm(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)341275c9da8Seschrock elem_parse_comm(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
342275c9da8Seschrock {
343275c9da8Seschrock 	ses2_comm_status_impl_t *cip = (ses2_comm_status_impl_t *)esip;
344275c9da8Seschrock 	int nverr;
345275c9da8Seschrock 
346275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, cip->scsi_fail);
347275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
348275c9da8Seschrock 	    cip->scsi_ident);
349275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_DISABLED,
350275c9da8Seschrock 	    cip->scsi_disabled);
351275c9da8Seschrock 
352275c9da8Seschrock 	return (0);
353275c9da8Seschrock }
354275c9da8Seschrock 
355275c9da8Seschrock static int
elem_parse_voltage(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)356275c9da8Seschrock elem_parse_voltage(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
357275c9da8Seschrock {
358275c9da8Seschrock 	ses2_voltage_status_impl_t *vip = (ses2_voltage_status_impl_t *)esip;
359275c9da8Seschrock 	int nverr;
360275c9da8Seschrock 
3619af3851aSeschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_CRIT_UNDER,
362275c9da8Seschrock 	    vip->svsi_crit_under);
3639af3851aSeschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_CRIT_OVER,
364275c9da8Seschrock 	    vip->svsi_crit_over);
3659af3851aSeschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_WARN_UNDER,
366275c9da8Seschrock 	    vip->svsi_warn_under);
3679af3851aSeschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_WARN_OVER,
368275c9da8Seschrock 	    vip->svsi_warn_over);
369275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, vip->svsi_fail);
370275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, vip->svsi_ident);
371275c9da8Seschrock 	SES_NV_ADD(int64, nverr, nvl, SES_VS_PROP_VOLTAGE_MV,
372275c9da8Seschrock 	    SCSI_READ16(&vip->svsi_voltage));
373275c9da8Seschrock 
374275c9da8Seschrock 	return (0);
375275c9da8Seschrock }
376275c9da8Seschrock 
377275c9da8Seschrock static int
elem_parse_current(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)378275c9da8Seschrock elem_parse_current(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
379275c9da8Seschrock {
380275c9da8Seschrock 	ses2_current_status_impl_t *cip = (ses2_current_status_impl_t *)esip;
381275c9da8Seschrock 	int nverr;
382275c9da8Seschrock 
3839af3851aSeschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_CRIT_OVER,
384275c9da8Seschrock 	    cip->scsi_crit_over);
3859af3851aSeschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_WARN_OVER,
386275c9da8Seschrock 	    cip->scsi_warn_over);
387275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, cip->scsi_fail);
388275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, cip->scsi_ident);
389275c9da8Seschrock 	SES_NV_ADD(int64, nverr, nvl, SES_CS_PROP_CURRENT_MA,
390275c9da8Seschrock 	    SCSI_READ16(&cip->scsi_current));
391275c9da8Seschrock 
392275c9da8Seschrock 	return (0);
393275c9da8Seschrock }
394275c9da8Seschrock 
395275c9da8Seschrock static int
elem_parse_itp(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)396275c9da8Seschrock elem_parse_itp(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
397275c9da8Seschrock {
398275c9da8Seschrock 	ses2_itp_status_impl_t *iip = (ses2_itp_status_impl_t *)esip;
399275c9da8Seschrock 	int nverr;
400275c9da8Seschrock 
401275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, iip->sisi_fail);
402275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
403275c9da8Seschrock 	    iip->sisi_ident);
404275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
405275c9da8Seschrock 	    iip->sisi_report);
406275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_ITP_PROP_ENABLED,
407275c9da8Seschrock 	    iip->sisi_enabled);
408275c9da8Seschrock 
409275c9da8Seschrock 	return (0);
410275c9da8Seschrock }
411275c9da8Seschrock 
412275c9da8Seschrock static int
elem_parse_sse(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)413275c9da8Seschrock elem_parse_sse(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
414275c9da8Seschrock {
415275c9da8Seschrock 	ses2_ss_status_impl_t *sip = (ses2_ss_status_impl_t *)esip;
416275c9da8Seschrock 	int nverr;
417275c9da8Seschrock 
418275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, sip->sss_fail);
419275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, sip->sss_ident);
420275c9da8Seschrock 	SES_NV_ADD(uint64, nverr, nvl, SES_SS_PROP_SHORT_STATUS,
421275c9da8Seschrock 	    sip->sss_short_status);
422275c9da8Seschrock 
423275c9da8Seschrock 	return (0);
424275c9da8Seschrock }
425275c9da8Seschrock 
426275c9da8Seschrock static int
elem_parse_arraydev(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)427275c9da8Seschrock elem_parse_arraydev(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
428275c9da8Seschrock {
429275c9da8Seschrock 	ses2_array_device_status_impl_t *aip =
430275c9da8Seschrock 	    (ses2_array_device_status_impl_t *)esip;
431275c9da8Seschrock 	int nverr;
432275c9da8Seschrock 
433275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_RR_ABORT,
434275c9da8Seschrock 	    aip->sadsi_rr_abort);
435275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_REBUILD,
436275c9da8Seschrock 	    aip->sadsi_rebuild);
437275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_IN_FAILED_ARRAY,
438275c9da8Seschrock 	    aip->sadsi_in_failed_array);
439275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_IN_CRIT_ARRAY,
440275c9da8Seschrock 	    aip->sadsi_in_crit_array);
441275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_CONS_CHK,
442275c9da8Seschrock 	    aip->sadsi_cons_chk);
443275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_HOT_SPARE,
444275c9da8Seschrock 	    aip->sadsi_hot_spare);
445275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_RSVD_DEVICE,
446275c9da8Seschrock 	    aip->sadsi_rsvd_device);
447275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_OK, aip->sadsi_ok);
448275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
449275c9da8Seschrock 	    aip->sadsi_report);
450275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, aip->sadsi_ident);
451275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_RMV, aip->sadsi_rmv);
452275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_READY_TO_INSERT,
453275c9da8Seschrock 	    aip->sadsi_ready_to_insert);
454275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_ENC_BYP_B,
455275c9da8Seschrock 	    aip->sadsi_enclosure_bypassed_b);
456275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_ENC_BYP_A,
457275c9da8Seschrock 	    aip->sadsi_enclosure_bypassed_a);
458275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DO_NOT_REMOVE,
459275c9da8Seschrock 	    aip->sadsi_do_not_remove);
460275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_APP_BYP_A,
461275c9da8Seschrock 	    aip->sadsi_app_client_bypassed_a);
462275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DEV_BYP_B,
463275c9da8Seschrock 	    aip->sadsi_device_bypassed_b);
464275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DEV_BYP_A,
465275c9da8Seschrock 	    aip->sadsi_device_bypassed_a);
466275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_BYP_B,
467275c9da8Seschrock 	    aip->sadsi_bypassed_b);
468275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_BYP_A,
469275c9da8Seschrock 	    aip->sadsi_bypassed_a);
470275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_OFF,
471275c9da8Seschrock 	    aip->sadsi_device_off);
472275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_FAULT_RQSTD,
473275c9da8Seschrock 	    aip->sadsi_fault_reqstd);
474275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_FAULT_SENSED,
475275c9da8Seschrock 	    aip->sadsi_fault_sensed);
476275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_APP_BYP_B,
477275c9da8Seschrock 	    aip->sadsi_app_client_bypassed_b);
478275c9da8Seschrock 
479275c9da8Seschrock 	return (0);
480275c9da8Seschrock }
481275c9da8Seschrock 
482275c9da8Seschrock static int
elem_parse_expander(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)483275c9da8Seschrock elem_parse_expander(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
484275c9da8Seschrock {
485275c9da8Seschrock 	ses2_expander_status_impl_t *eip = (ses2_expander_status_impl_t *)esip;
486275c9da8Seschrock 	int nverr;
487275c9da8Seschrock 
488275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, eip->sesi_fail);
489275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, eip->sesi_ident);
490275c9da8Seschrock 
491275c9da8Seschrock 	return (0);
492275c9da8Seschrock }
493275c9da8Seschrock 
494275c9da8Seschrock static int
elem_parse_sasconn(const ses2_elem_status_impl_t * esip,nvlist_t * nvl)495275c9da8Seschrock elem_parse_sasconn(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
496275c9da8Seschrock {
497275c9da8Seschrock 	ses2_sasconn_status_impl_t *sip = (ses2_sasconn_status_impl_t *)esip;
498275c9da8Seschrock 	int nverr;
499275c9da8Seschrock 
500275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, sip->sss_fail);
501275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, sip->sss_ident);
502275c9da8Seschrock 	SES_NV_ADD(uint64, nverr, nvl, SES_SC_PROP_CONNECTOR_TYPE,
503275c9da8Seschrock 	    sip->sss_connector_type);
504275c9da8Seschrock 	SES_NV_ADD(uint64, nverr, nvl, SES_SC_PROP_PHYSICAL_LINK,
505275c9da8Seschrock 	    sip->sss_connector_physical_link);
506275c9da8Seschrock 
507275c9da8Seschrock 	return (0);
508275c9da8Seschrock }
509275c9da8Seschrock 
510275c9da8Seschrock static const struct status_parser {
511275c9da8Seschrock 	ses2_element_type_t type;
512275c9da8Seschrock 	int (*func)(const ses2_elem_status_impl_t *, nvlist_t *);
513275c9da8Seschrock } status_parsers[] = {
514275c9da8Seschrock 	{ SES_ET_DEVICE, elem_parse_device },
515275c9da8Seschrock 	{ SES_ET_POWER_SUPPLY, elem_parse_psu },
516275c9da8Seschrock 	{ SES_ET_COOLING, elem_parse_cooling },
517275c9da8Seschrock 	{ SES_ET_TEMPERATURE_SENSOR, elem_parse_temp },
518275c9da8Seschrock 	{ SES_ET_DOOR_LOCK, elem_parse_lock },
519275c9da8Seschrock 	{ SES_ET_AUDIBLE_ALARM, elem_parse_alarm },
520275c9da8Seschrock 	{ SES_ET_ESC_ELECTRONICS, elem_parse_esc },
521275c9da8Seschrock 	{ SES_ET_SCC_ELECTRONICS, elem_parse_scc },
522275c9da8Seschrock 	{ SES_ET_NONVOLATILE_CACHE, elem_parse_cache },
523275c9da8Seschrock 	{ SES_ET_UPS, elem_parse_ups },
524275c9da8Seschrock 	{ SES_ET_DISPLAY, elem_parse_display },
525275c9da8Seschrock 	{ SES_ET_KEY_PAD_ENTRY, elem_parse_keypad },
526275c9da8Seschrock 	{ SES_ET_SCSI_PORT_XCVR, elem_parse_px },
527275c9da8Seschrock 	{ SES_ET_LANGUAGE, elem_parse_lang },
528275c9da8Seschrock 	{ SES_ET_COMMUNICATION_PORT, elem_parse_comm },
529275c9da8Seschrock 	{ SES_ET_VOLTAGE_SENSOR, elem_parse_voltage },
530275c9da8Seschrock 	{ SES_ET_CURRENT_SENSOR, elem_parse_current },
531275c9da8Seschrock 	{ SES_ET_SCSI_TARGET_PORT, elem_parse_itp },
532275c9da8Seschrock 	{ SES_ET_SCSI_INITIATOR_PORT, elem_parse_itp },
533275c9da8Seschrock 	{ SES_ET_SIMPLE_SUBENCLOSURE, elem_parse_sse },
534275c9da8Seschrock 	{ SES_ET_ARRAY_DEVICE, elem_parse_arraydev },
535275c9da8Seschrock 	{ SES_ET_SAS_EXPANDER, elem_parse_expander },
536275c9da8Seschrock 	{ SES_ET_SAS_CONNECTOR, elem_parse_sasconn },
537275c9da8Seschrock 	{ (ses2_element_type_t)-1, NULL }
538275c9da8Seschrock };
539275c9da8Seschrock 
540275c9da8Seschrock static int
elem_parse_sd(ses_plugin_t * spp,ses_node_t * np)541275c9da8Seschrock elem_parse_sd(ses_plugin_t *spp, ses_node_t *np)
542275c9da8Seschrock {
543275c9da8Seschrock 	ses2_elem_status_impl_t *esip;
544275c9da8Seschrock 	const struct status_parser *sp;
545275c9da8Seschrock 	nvlist_t *nvl = ses_node_props(np);
546275c9da8Seschrock 	size_t len;
547275c9da8Seschrock 	int nverr;
548275c9da8Seschrock 	uint64_t type;
549275c9da8Seschrock 
550275c9da8Seschrock 	if ((esip = ses_plugin_page_lookup(spp,
551275c9da8Seschrock 	    ses_node_snapshot(np), SES2_DIAGPAGE_ENCLOSURE_CTL_STATUS,
552275c9da8Seschrock 	    np, &len)) == NULL)
553275c9da8Seschrock 		return (0);
554275c9da8Seschrock 
555275c9da8Seschrock 	VERIFY(nvlist_lookup_uint64(nvl, SES_PROP_ELEMENT_TYPE,
556275c9da8Seschrock 	    &type) == 0);
557275c9da8Seschrock 
558275c9da8Seschrock 	SES_NV_ADD(uint64, nverr, nvl, SES_PROP_STATUS_CODE,
559275c9da8Seschrock 	    esip->sesi_common.sesi_status_code);
560275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_SWAP,
561275c9da8Seschrock 	    esip->sesi_common.sesi_swap);
562275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_DISABLED,
563275c9da8Seschrock 	    esip->sesi_common.sesi_disabled);
564275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_PRDFAIL,
565275c9da8Seschrock 	    esip->sesi_common.sesi_prdfail);
566275c9da8Seschrock 
567275c9da8Seschrock 	for (sp = &status_parsers[0]; sp->type != (ses2_element_type_t)-1; sp++)
568275c9da8Seschrock 		if (sp->type == type && sp->func != NULL)
569275c9da8Seschrock 			return (sp->func(esip, nvl));
570275c9da8Seschrock 
571275c9da8Seschrock 	return (0);
572275c9da8Seschrock }
573275c9da8Seschrock 
574275c9da8Seschrock static int
elem_parse_descr(ses_plugin_t * sp,ses_node_t * np)575275c9da8Seschrock elem_parse_descr(ses_plugin_t *sp, ses_node_t *np)
576275c9da8Seschrock {
577275c9da8Seschrock 	char *desc;
578275c9da8Seschrock 	size_t len;
579275c9da8Seschrock 	nvlist_t *props = ses_node_props(np);
580275c9da8Seschrock 	int nverr;
581275c9da8Seschrock 
582275c9da8Seschrock 	if ((desc = ses_plugin_page_lookup(sp, ses_node_snapshot(np),
583275c9da8Seschrock 	    SES2_DIAGPAGE_ELEMENT_DESC, np, &len)) == NULL)
584275c9da8Seschrock 		return (0);
585275c9da8Seschrock 
586275c9da8Seschrock 	SES_NV_ADD(fixed_string, nverr, props, SES_PROP_DESCRIPTION,
587275c9da8Seschrock 	    desc, len);
588275c9da8Seschrock 
589275c9da8Seschrock 	return (0);
590275c9da8Seschrock }
591275c9da8Seschrock 
592275c9da8Seschrock static int
elem_parse_aes_fc(const ses2_aes_descr_fc_eip_impl_t * fp,nvlist_t * nvl,size_t len)593275c9da8Seschrock elem_parse_aes_fc(const ses2_aes_descr_fc_eip_impl_t *fp,
594275c9da8Seschrock     nvlist_t *nvl, size_t len)
595275c9da8Seschrock {
596275c9da8Seschrock 	int nverr, i;
597275c9da8Seschrock 	nvlist_t **nva;
598275c9da8Seschrock 	int nports;
599275c9da8Seschrock 
600275c9da8Seschrock 	if (len < offsetof(ses2_aes_descr_fc_eip_impl_t,
601275c9da8Seschrock 	    sadfi_ports))
602275c9da8Seschrock 		return (0);
603275c9da8Seschrock 
604275c9da8Seschrock 	SES_NV_ADD(uint64, nverr, nvl, SES_PROP_BAY_NUMBER,
605275c9da8Seschrock 	    fp->sadfi_bay_number);
606275c9da8Seschrock 	SES_NV_ADD(uint64, nverr, nvl, SES_FC_PROP_NODE_NAME,
607275c9da8Seschrock 	    SCSI_READ64(&fp->sadfi_node_name));
608275c9da8Seschrock 
609275c9da8Seschrock 	nports = MIN(fp->sadfi_n_ports,
610275c9da8Seschrock 	    (len - offsetof(ses2_aes_descr_fc_eip_impl_t,
611275c9da8Seschrock 	    sadfi_ports)) / sizeof (ses2_aes_port_descr_impl_t));
612275c9da8Seschrock 
613275c9da8Seschrock 	if (nports == 0)
614275c9da8Seschrock 		return (0);
615275c9da8Seschrock 
616275c9da8Seschrock 	nva = ses_zalloc(nports * sizeof (nvlist_t *));
617275c9da8Seschrock 	if (nva == NULL)
618275c9da8Seschrock 		return (-1);
619275c9da8Seschrock 
620275c9da8Seschrock 	for (i = 0; i < nports; i++) {
621275c9da8Seschrock 		if ((nverr = nvlist_alloc(&nva[i], NV_UNIQUE_NAME, 0)) != 0)
622275c9da8Seschrock 			goto fail;
623275c9da8Seschrock 		if ((nverr = nvlist_add_uint64(nva[i], SES_FC_PROP_LOOP_POS,
624275c9da8Seschrock 		    fp->sadfi_ports[i].sapdi_port_loop_position)) != 0)
625275c9da8Seschrock 			goto fail;
626275c9da8Seschrock 		if ((nverr = nvlist_add_uint64(nva[i], SES_FC_PROP_REQ_HARDADDR,
627275c9da8Seschrock 		    fp->sadfi_ports[i].sapdi_port_requested_hard_address)) != 0)
628275c9da8Seschrock 			goto fail;
629275c9da8Seschrock 		nverr = nvlist_add_uint64(nva[i], SES_FC_PROP_N_PORT_ID,
630275c9da8Seschrock 		    SCSI_READ24(fp->sadfi_ports[i].sapdi_n_port_identifier));
631275c9da8Seschrock 		if (nverr != 0)
632275c9da8Seschrock 			goto fail;
633275c9da8Seschrock 		if ((nverr = nvlist_add_uint64(nva[i], SES_FC_PROP_N_PORT_NAME,
634275c9da8Seschrock 		    SCSI_READ64(&fp->sadfi_ports[i].sapdi_n_port_name))) != 0)
635275c9da8Seschrock 			goto fail;
636275c9da8Seschrock 	}
637275c9da8Seschrock 
638275c9da8Seschrock 	if ((nverr = nvlist_add_nvlist_array(nvl, SES_FC_PROP_PORTS,
639275c9da8Seschrock 	    nva, nports)) != 0)
640275c9da8Seschrock 		goto fail;
641275c9da8Seschrock 
642275c9da8Seschrock 	for (i = 0; i < nports && nva[i] != NULL; i++)
643275c9da8Seschrock 		nvlist_free(nva[i]);
644275c9da8Seschrock 	ses_free(nva);
645275c9da8Seschrock 	return (0);
646275c9da8Seschrock 
647275c9da8Seschrock fail:
648275c9da8Seschrock 	for (i = 0; i < nports && nva[i] != NULL; i++)
649275c9da8Seschrock 		nvlist_free(nva[i]);
650275c9da8Seschrock 	ses_free(nva);
651275c9da8Seschrock 	return (ses_set_nverrno(nverr, NULL));
652275c9da8Seschrock }
653275c9da8Seschrock 
654275c9da8Seschrock static int
elem_parse_aes_device(const ses2_aes_descr_eip_impl_t * dep,nvlist_t * nvl,size_t len)655275c9da8Seschrock elem_parse_aes_device(const ses2_aes_descr_eip_impl_t *dep, nvlist_t *nvl,
656275c9da8Seschrock     size_t len)
657275c9da8Seschrock {
658275c9da8Seschrock 	ses2_aes_descr_fc_eip_impl_t *fp;
659275c9da8Seschrock 	ses2_aes_descr_sas0_eip_impl_t *s0ep;
660275c9da8Seschrock 	ses2_aes_descr_sas0_impl_t *s0p;
661275c9da8Seschrock 	ses2_aes_descr_impl_t *dip;
662275c9da8Seschrock 	nvlist_t **nva;
663275c9da8Seschrock 	int nverr, i;
664275c9da8Seschrock 	size_t nphy;
665275c9da8Seschrock 
666275c9da8Seschrock 	if (dep->sadei_eip) {
667275c9da8Seschrock 		s0ep = (ses2_aes_descr_sas0_eip_impl_t *)
668275c9da8Seschrock 		    dep->sadei_protocol_specific;
669275c9da8Seschrock 		s0p = (ses2_aes_descr_sas0_impl_t *)
670275c9da8Seschrock 		    dep->sadei_protocol_specific;
671275c9da8Seschrock 	} else {
672275c9da8Seschrock 		dip = (ses2_aes_descr_impl_t *)dep;
673275c9da8Seschrock 		s0ep = NULL;
674275c9da8Seschrock 		s0p = (ses2_aes_descr_sas0_impl_t *)
675275c9da8Seschrock 		    dip->sadei_protocol_specific;
676275c9da8Seschrock 	}
677275c9da8Seschrock 
678275c9da8Seschrock 	if (dep->sadei_invalid)
679275c9da8Seschrock 		return (0);
680275c9da8Seschrock 
681275c9da8Seschrock 	if (dep->sadei_protocol_identifier == SPC4_PROTO_FIBRE_CHANNEL) {
682275c9da8Seschrock 		fp = (ses2_aes_descr_fc_eip_impl_t *)
683275c9da8Seschrock 		    dep->sadei_protocol_specific;
684275c9da8Seschrock 
685275c9da8Seschrock 		if (!SES_WITHIN_PAGE_STRUCT(fp, dep, len))
686275c9da8Seschrock 			return (0);
687275c9da8Seschrock 
688275c9da8Seschrock 		return (elem_parse_aes_fc(fp, nvl, len -
689275c9da8Seschrock 		    offsetof(ses2_aes_descr_eip_impl_t,
690275c9da8Seschrock 		    sadei_protocol_specific)));
691275c9da8Seschrock 	} else if (dep->sadei_protocol_identifier != SPC4_PROTO_SAS) {
692275c9da8Seschrock 		return (0);
693275c9da8Seschrock 	}
694275c9da8Seschrock 
695275c9da8Seschrock 	if (s0p->sadsi_descriptor_type != SES2_AESD_SAS_DEVICE)
696275c9da8Seschrock 		return (0);
697275c9da8Seschrock 
698275c9da8Seschrock 	SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_SAS_NOT_ALL_PHYS,
699275c9da8Seschrock 	    s0p->sadsi_not_all_phys);
700275c9da8Seschrock 	if (s0ep != NULL) {
701275c9da8Seschrock 		SES_NV_ADD(uint64, nverr, nvl, SES_PROP_BAY_NUMBER,
702275c9da8Seschrock 		    s0ep->sadsi_bay_number);
703275c9da8Seschrock 		nphy = MIN(s0ep->sadsi_n_phy_descriptors,
704275c9da8Seschrock 		    (len - offsetof(ses2_aes_descr_sas0_eip_impl_t,
705275c9da8Seschrock 		    sadsi_phys)) / sizeof (ses2_aes_phy0_descr_impl_t));
706275c9da8Seschrock 	} else {
707275c9da8Seschrock 		nphy = MIN(s0p->sadsi_n_phy_descriptors,
708275c9da8Seschrock 		    (len - offsetof(ses2_aes_descr_sas0_impl_t,
709275c9da8Seschrock 		    sadsi_phys)) / sizeof (ses2_aes_phy0_descr_impl_t));
710275c9da8Seschrock 	}
711275c9da8Seschrock 
712275c9da8Seschrock 	if (nphy == 0)
713275c9da8Seschrock 		return (0);
714275c9da8Seschrock 
715275c9da8Seschrock 	nva = ses_zalloc(nphy * sizeof (nvlist_t *));
716275c9da8Seschrock 	if (nva == NULL)
717275c9da8Seschrock 		return (-1);
718275c9da8Seschrock 
719275c9da8Seschrock 	for (i = 0; i < nphy; i++) {
720275c9da8Seschrock 		ses2_aes_phy0_descr_impl_t *pp;
721275c9da8Seschrock 		pp = s0ep != NULL ? &s0ep->sadsi_phys[i] : &s0p->sadsi_phys[i];
722275c9da8Seschrock 		if ((nverr = nvlist_alloc(&nva[i], NV_UNIQUE_NAME, 0)) != 0)
723275c9da8Seschrock 			goto fail;
724275c9da8Seschrock 		if ((nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_DEVICE_TYPE,
725275c9da8Seschrock 		    pp->sapdi_device_type)) != 0)
726275c9da8Seschrock 			goto fail;
727275c9da8Seschrock 		if ((nverr = nvlist_add_boolean_value(nva[i],
728275c9da8Seschrock 		    SES_SAS_PROP_SMPI_PORT, pp->sapdi_smp_initiator_port)) != 0)
729275c9da8Seschrock 			goto fail;
730275c9da8Seschrock 		if ((nverr = nvlist_add_boolean_value(nva[i],
731275c9da8Seschrock 		    SES_SAS_PROP_STPI_PORT, pp->sapdi_stp_initiator_port)) != 0)
732275c9da8Seschrock 			goto fail;
733275c9da8Seschrock 		if ((nverr = nvlist_add_boolean_value(nva[i],
734275c9da8Seschrock 		    SES_SAS_PROP_SSPI_PORT, pp->sapdi_ssp_initiator_port)) != 0)
735275c9da8Seschrock 			goto fail;
736275c9da8Seschrock 		if ((nverr = nvlist_add_boolean_value(nva[i],
737275c9da8Seschrock 		    SES_SAS_PROP_SATA_DEVICE, pp->sapdi_sata_device)) != 0)
738275c9da8Seschrock 			goto fail;
739275c9da8Seschrock 		if ((nverr = nvlist_add_boolean_value(nva[i],
740275c9da8Seschrock 		    SES_SAS_PROP_SMPT_PORT, pp->sapdi_smp_target_port)) != 0)
741275c9da8Seschrock 			goto fail;
742275c9da8Seschrock 		if ((nverr = nvlist_add_boolean_value(nva[i],
743275c9da8Seschrock 		    SES_SAS_PROP_STPT_PORT, pp->sapdi_stp_target_port)) != 0)
744275c9da8Seschrock 			goto fail;
745275c9da8Seschrock 		if ((nverr = nvlist_add_boolean_value(nva[i],
746275c9da8Seschrock 		    SES_SAS_PROP_SSPT_PORT, pp->sapdi_ssp_target_port)) != 0)
747275c9da8Seschrock 			goto fail;
748275c9da8Seschrock 		nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_ATT_ADDR,
749275c9da8Seschrock 		    SCSI_READ64(&pp->sapdi_attached_sas_address));
750275c9da8Seschrock 		if (nverr != 0)
751275c9da8Seschrock 			goto fail;
752275c9da8Seschrock 		nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_ADDR,
753275c9da8Seschrock 		    SCSI_READ64(&pp->sapdi_sas_address));
754275c9da8Seschrock 		if (nverr != 0)
755275c9da8Seschrock 			goto fail;
756275c9da8Seschrock 		if ((nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_PHY_ID,
757275c9da8Seschrock 		    pp->sapdi_phy_identifier)) != 0)
758275c9da8Seschrock 			goto fail;
759275c9da8Seschrock 	}
760275c9da8Seschrock 
761275c9da8Seschrock 	if ((nverr = nvlist_add_nvlist_array(nvl, SES_SAS_PROP_PHYS,
762275c9da8Seschrock 	    nva, nphy)) != 0)
763275c9da8Seschrock 		goto fail;
764275c9da8Seschrock 
765275c9da8Seschrock 	for (i = 0; i < nphy && nva[i] != NULL; i++)
766275c9da8Seschrock 		nvlist_free(nva[i]);
767275c9da8Seschrock 	ses_free(nva);
768275c9da8Seschrock 	return (0);
769275c9da8Seschrock 
770275c9da8Seschrock fail:
771275c9da8Seschrock 	for (i = 0; i < nphy && nva[i] != NULL; i++)
772275c9da8Seschrock 		nvlist_free(nva[i]);
773275c9da8Seschrock 	ses_free(nva);
774275c9da8Seschrock 	return (ses_set_nverrno(nverr, NULL));
775275c9da8Seschrock }
776275c9da8Seschrock 
777275c9da8Seschrock static int
elem_parse_aes_expander(const ses2_aes_descr_eip_impl_t * dep,nvlist_t * nvl,size_t len)778275c9da8Seschrock elem_parse_aes_expander(const ses2_aes_descr_eip_impl_t *dep, nvlist_t *nvl,
779275c9da8Seschrock     size_t len)
780275c9da8Seschrock {
781275c9da8Seschrock 	ses2_aes_descr_exp_impl_t *sep;
782275c9da8Seschrock 	nvlist_t **nva;
783275c9da8Seschrock 	int nverr, i;
784275c9da8Seschrock 	size_t nphy;
785275c9da8Seschrock 
786275c9da8Seschrock 	if (dep->sadei_invalid)
787275c9da8Seschrock 		return (0);
788275c9da8Seschrock 
789275c9da8Seschrock 	/*
790275c9da8Seschrock 	 * This should never happen; no current SAS expander can have any
791275c9da8Seschrock 	 * other kind of ports.  But maybe someday - one could envision a
792275c9da8Seschrock 	 * SAS expander with iSCSI target ports, for example.
793275c9da8Seschrock 	 */
794275c9da8Seschrock 	if (dep->sadei_protocol_identifier != SPC4_PROTO_SAS)
795275c9da8Seschrock 		return (0);
796275c9da8Seschrock 
797275c9da8Seschrock 	sep = (ses2_aes_descr_exp_impl_t *)dep->sadei_protocol_specific;
798275c9da8Seschrock 	if (sep->sadei_descriptor_type != SES2_AESD_SAS_OTHER)
799275c9da8Seschrock 		return (0);
800275c9da8Seschrock 
801275c9da8Seschrock 	SES_NV_ADD(uint64, nverr, nvl, SES_EXP_PROP_SAS_ADDR,
802275c9da8Seschrock 	    SCSI_READ64(&sep->sadei_sas_address));
803275c9da8Seschrock 
804275c9da8Seschrock 	nphy = MIN(sep->sadei_n_exp_phy_descriptors,
805275c9da8Seschrock 	    (len - offsetof(ses2_aes_descr_exp_impl_t,
806275c9da8Seschrock 	    sadei_phys)) / sizeof (ses2_aes_exp_phy_descr_impl_t));
807275c9da8Seschrock 
808275c9da8Seschrock 	if (nphy == 0)
809275c9da8Seschrock 		return (0);
810275c9da8Seschrock 
811275c9da8Seschrock 	nva = ses_zalloc(nphy * sizeof (nvlist_t *));
812275c9da8Seschrock 	if (nva == NULL)
813275c9da8Seschrock 		return (-1);
814275c9da8Seschrock 
815275c9da8Seschrock 	for (i = 0; i < nphy; i++) {
816275c9da8Seschrock 		if ((nverr = nvlist_alloc(&nva[i], NV_UNIQUE_NAME, 0)) != 0)
817275c9da8Seschrock 			goto fail;
818275c9da8Seschrock 		if ((nverr = nvlist_add_uint64(nva[i], SES_PROP_CE_IDX,
819275c9da8Seschrock 		    sep->sadei_phys[i].saepdi_connector_element_index)) != 0)
820275c9da8Seschrock 			goto fail;
821275c9da8Seschrock 		if ((nverr = nvlist_add_uint64(nva[i], SES_PROP_OE_IDX,
822275c9da8Seschrock 		    sep->sadei_phys[i].saepdi_other_element_index)) != 0)
823275c9da8Seschrock 			goto fail;
824275c9da8Seschrock 	}
825275c9da8Seschrock 
826275c9da8Seschrock 	if ((nverr = nvlist_add_nvlist_array(nvl, SES_SAS_PROP_PHYS,
827275c9da8Seschrock 	    nva, nphy)) != 0)
828275c9da8Seschrock 		goto fail;
829275c9da8Seschrock 
830275c9da8Seschrock 	for (i = 0; i < nphy && nva[i] != NULL; i++)
831275c9da8Seschrock 		nvlist_free(nva[i]);
832275c9da8Seschrock 	ses_free(nva);
833275c9da8Seschrock 	return (0);
834275c9da8Seschrock 
835275c9da8Seschrock fail:
836275c9da8Seschrock 	for (i = 0; i < nphy && nva[i] != NULL; i++)
837275c9da8Seschrock 		nvlist_free(nva[i]);
838275c9da8Seschrock 	ses_free(nva);
839275c9da8Seschrock 	return (ses_set_nverrno(nverr, NULL));
840275c9da8Seschrock }
841275c9da8Seschrock 
842275c9da8Seschrock static int
elem_parse_aes_misc(const ses2_aes_descr_eip_impl_t * dep,nvlist_t * nvl,size_t len)843275c9da8Seschrock elem_parse_aes_misc(const ses2_aes_descr_eip_impl_t *dep, nvlist_t *nvl,
844275c9da8Seschrock     size_t len)
845275c9da8Seschrock {
846275c9da8Seschrock 	ses2_aes_descr_fc_eip_impl_t *fp;
847275c9da8Seschrock 	ses2_aes_descr_sas1_impl_t *s1p;
848275c9da8Seschrock 	nvlist_t **nva;
849275c9da8Seschrock 	int nverr, i;
850275c9da8Seschrock 	size_t nphy;
851275c9da8Seschrock 
852275c9da8Seschrock 	if (dep->sadei_invalid)
853275c9da8Seschrock 		return (0);
854275c9da8Seschrock 
855275c9da8Seschrock 	if (dep->sadei_protocol_identifier == SPC4_PROTO_FIBRE_CHANNEL) {
856275c9da8Seschrock 		fp = (ses2_aes_descr_fc_eip_impl_t *)
857275c9da8Seschrock 		    dep->sadei_protocol_specific;
858275c9da8Seschrock 
859275c9da8Seschrock 		if (!SES_WITHIN_PAGE_STRUCT(fp, dep, len))
860275c9da8Seschrock 			return (0);
861275c9da8Seschrock 
862275c9da8Seschrock 		return (elem_parse_aes_fc(fp, nvl, len -
863275c9da8Seschrock 		    offsetof(ses2_aes_descr_eip_impl_t,
864275c9da8Seschrock 		    sadei_protocol_specific)));
865275c9da8Seschrock 	} else if (dep->sadei_protocol_identifier != SPC4_PROTO_SAS) {
866275c9da8Seschrock 		return (0);
867275c9da8Seschrock 	}
868275c9da8Seschrock 
869275c9da8Seschrock 	s1p = (ses2_aes_descr_sas1_impl_t *)dep->sadei_protocol_specific;
870275c9da8Seschrock 	if (s1p->sadsi_descriptor_type == SES2_AESD_SAS_DEVICE)
871275c9da8Seschrock 		return (0);
872275c9da8Seschrock 
873275c9da8Seschrock 	nphy = MIN(s1p->sadsi_n_phy_descriptors,
874275c9da8Seschrock 	    (len - offsetof(ses2_aes_descr_sas1_impl_t,
875275c9da8Seschrock 	    sadsi_phys)) / sizeof (ses2_aes_phy1_descr_impl_t));
876275c9da8Seschrock 
87714ae03cbSAndy Fiddaman 	if (nphy == 0)
87814ae03cbSAndy Fiddaman 		return (0);
87914ae03cbSAndy Fiddaman 
880275c9da8Seschrock 	nva = ses_zalloc(nphy * sizeof (nvlist_t *));
881275c9da8Seschrock 	if (nva == NULL)
882275c9da8Seschrock 		return (-1);
883275c9da8Seschrock 
884275c9da8Seschrock 	for (i = 0; i < nphy; i++) {
885275c9da8Seschrock 		if ((nverr = nvlist_alloc(&nva[i], NV_UNIQUE_NAME, 0)) != 0)
886275c9da8Seschrock 			goto fail;
887275c9da8Seschrock 		if ((nverr = nvlist_add_uint64(nva[i], SES_PROP_CE_IDX,
888275c9da8Seschrock 		    s1p->sadsi_phys[i].sapdi_connector_element_index)) != 0)
889275c9da8Seschrock 			goto fail;
890275c9da8Seschrock 		if ((nverr = nvlist_add_uint64(nva[i], SES_PROP_OE_IDX,
891275c9da8Seschrock 		    s1p->sadsi_phys[i].sapdi_other_element_index)) != 0)
892275c9da8Seschrock 			goto fail;
893275c9da8Seschrock 		if ((nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_ADDR,
894275c9da8Seschrock 		    SCSI_READ64(&s1p->sadsi_phys[i].sapdi_sas_address))) != 0)
895275c9da8Seschrock 			goto fail;
896275c9da8Seschrock 	}
897275c9da8Seschrock 
898275c9da8Seschrock 	if ((nverr = nvlist_add_nvlist_array(nvl, SES_SAS_PROP_PHYS,
899275c9da8Seschrock 	    nva, nphy)) != 0)
900275c9da8Seschrock 		goto fail;
901275c9da8Seschrock 
902275c9da8Seschrock 	for (i = 0; i < nphy && nva[i] != NULL; i++)
903275c9da8Seschrock 		nvlist_free(nva[i]);
904275c9da8Seschrock 
905275c9da8Seschrock 	ses_free(nva);
906275c9da8Seschrock 	return (0);
907275c9da8Seschrock 
908275c9da8Seschrock fail:
909275c9da8Seschrock 	for (i = 0; i < nphy && nva[i] != NULL; i++)
910275c9da8Seschrock 		nvlist_free(nva[i]);
911275c9da8Seschrock 	ses_free(nva);
912275c9da8Seschrock 	return (nverr);
913275c9da8Seschrock }
914275c9da8Seschrock 
915275c9da8Seschrock static const struct aes_parser {
916275c9da8Seschrock 	ses2_element_type_t type;
917275c9da8Seschrock 	int (*func)(const ses2_aes_descr_eip_impl_t *, nvlist_t *, size_t);
918275c9da8Seschrock } aes_parsers[] = {
919275c9da8Seschrock 	{ SES_ET_DEVICE, elem_parse_aes_device },
920275c9da8Seschrock 	{ SES_ET_SCSI_TARGET_PORT, elem_parse_aes_misc },
921275c9da8Seschrock 	{ SES_ET_SCSI_INITIATOR_PORT, elem_parse_aes_misc },
922275c9da8Seschrock 	{ SES_ET_ESC_ELECTRONICS, elem_parse_aes_misc },
923275c9da8Seschrock 	{ SES_ET_ARRAY_DEVICE, elem_parse_aes_device },
924275c9da8Seschrock 	{ SES_ET_SAS_EXPANDER, elem_parse_aes_expander },
925275c9da8Seschrock 	{ (ses2_element_type_t)-1, NULL }
926275c9da8Seschrock };
927275c9da8Seschrock 
928275c9da8Seschrock static int
elem_parse_aes(ses_plugin_t * sp,ses_node_t * np)929275c9da8Seschrock elem_parse_aes(ses_plugin_t *sp, ses_node_t *np)
930275c9da8Seschrock {
931275c9da8Seschrock 	ses2_aes_descr_eip_impl_t *dep;
932275c9da8Seschrock 	nvlist_t *props = ses_node_props(np);
933275c9da8Seschrock 	const struct aes_parser *app;
934275c9da8Seschrock 	uint64_t type;
935275c9da8Seschrock 	size_t len;
936275c9da8Seschrock 
937275c9da8Seschrock 	if (ses_node_type(np) == SES_NODE_AGGREGATE)
938275c9da8Seschrock 		return (0);
939275c9da8Seschrock 
940275c9da8Seschrock 	VERIFY(nvlist_lookup_uint64(props, SES_PROP_ELEMENT_TYPE,
941275c9da8Seschrock 	    &type) == 0);
942275c9da8Seschrock 
943275c9da8Seschrock 	for (app = &aes_parsers[0]; app->func != NULL; app++)
944275c9da8Seschrock 		if (app->type == type)
945275c9da8Seschrock 			break;
946275c9da8Seschrock 	if (app->func == NULL)
947275c9da8Seschrock 		return (0);
948275c9da8Seschrock 
949275c9da8Seschrock 	if ((dep = ses_plugin_page_lookup(sp, ses_node_snapshot(np),
950275c9da8Seschrock 	    SES2_DIAGPAGE_ADDL_ELEM_STATUS, np, &len)) == NULL)
951275c9da8Seschrock 		return (0);
952275c9da8Seschrock 
953275c9da8Seschrock 	return (app->func(dep, props, len));
954275c9da8Seschrock }
955275c9da8Seschrock 
956275c9da8Seschrock static int
elem_parse_threshold(ses_plugin_t * sp,ses_node_t * np)957275c9da8Seschrock elem_parse_threshold(ses_plugin_t *sp, ses_node_t *np)
958275c9da8Seschrock {
959275c9da8Seschrock 	ses_snap_t *snap = ses_node_snapshot(np);
960275c9da8Seschrock 	ses2_threshold_impl_t *tp;
961275c9da8Seschrock 	nvlist_t *nvl = ses_node_props(np);
962275c9da8Seschrock 	int nverr;
963275c9da8Seschrock 	uint64_t type;
964275c9da8Seschrock 	size_t len;
965275c9da8Seschrock 
966275c9da8Seschrock 	VERIFY(nvlist_lookup_uint64(nvl, SES_PROP_ELEMENT_TYPE,
967275c9da8Seschrock 	    &type) == 0);
968275c9da8Seschrock 
969*1c124bccSGarrett D'Amore 	if ((tp = ses_plugin_page_lookup(sp, snap,
970*1c124bccSGarrett D'Amore 	    SES2_DIAGPAGE_THRESHOLD_IO, np, &len)) == NULL)
971*1c124bccSGarrett D'Amore 		return (0);
972*1c124bccSGarrett D'Amore 
973275c9da8Seschrock 	switch (type) {
974275c9da8Seschrock 	case SES_ET_TEMPERATURE_SENSOR:
975*1c124bccSGarrett D'Amore 		SES_NV_ADD(int64, nverr, nvl, SES_PROP_THRESH_CRIT_HI,
976*1c124bccSGarrett D'Amore 		    (int)tp->sti_high_crit + SES2_ES_TEMP_OFFSET);
977*1c124bccSGarrett D'Amore 		SES_NV_ADD(int64, nverr, nvl, SES_PROP_THRESH_WARN_HI,
978*1c124bccSGarrett D'Amore 		    (int)tp->sti_high_warn + SES2_ES_TEMP_OFFSET);
979*1c124bccSGarrett D'Amore 		SES_NV_ADD(int64, nverr, nvl, SES_PROP_THRESH_CRIT_LO,
980*1c124bccSGarrett D'Amore 		    (int)tp->sti_low_crit + SES2_ES_TEMP_OFFSET);
981*1c124bccSGarrett D'Amore 		SES_NV_ADD(int64, nverr, nvl, SES_PROP_THRESH_WARN_LO,
982*1c124bccSGarrett D'Amore 		    (int)tp->sti_low_warn + SES2_ES_TEMP_OFFSET);
983*1c124bccSGarrett D'Amore 		return (0);
984*1c124bccSGarrett D'Amore 
985275c9da8Seschrock 	case SES_ET_UPS:
986275c9da8Seschrock 	case SES_ET_CURRENT_SENSOR:
987*1c124bccSGarrett D'Amore 	case SES_ET_VOLTAGE_SENSOR:
988*1c124bccSGarrett D'Amore 		SES_NV_ADD(uint64, nverr, nvl, SES_PROP_THRESH_CRIT_HI,
989*1c124bccSGarrett D'Amore 		    tp->sti_high_crit);
990*1c124bccSGarrett D'Amore 		SES_NV_ADD(uint64, nverr, nvl, SES_PROP_THRESH_WARN_HI,
991*1c124bccSGarrett D'Amore 		    tp->sti_high_warn);
992*1c124bccSGarrett D'Amore 		SES_NV_ADD(uint64, nverr, nvl, SES_PROP_THRESH_CRIT_LO,
993*1c124bccSGarrett D'Amore 		    tp->sti_low_crit);
994*1c124bccSGarrett D'Amore 		SES_NV_ADD(uint64, nverr, nvl, SES_PROP_THRESH_WARN_LO,
995*1c124bccSGarrett D'Amore 		    tp->sti_low_warn);
996*1c124bccSGarrett D'Amore 		return (0);
997275c9da8Seschrock 	default:
998275c9da8Seschrock 		return (0);
999275c9da8Seschrock 	}
1000275c9da8Seschrock }
1001275c9da8Seschrock 
1002275c9da8Seschrock int
ses2_fill_element_node(ses_plugin_t * sp,ses_node_t * np)1003275c9da8Seschrock ses2_fill_element_node(ses_plugin_t *sp, ses_node_t *np)
1004275c9da8Seschrock {
1005275c9da8Seschrock 	int err;
1006275c9da8Seschrock 
1007275c9da8Seschrock 	if ((err = elem_parse_sd(sp, np)) != 0)
1008275c9da8Seschrock 		return (err);
1009275c9da8Seschrock 
1010275c9da8Seschrock 	if ((err = elem_parse_descr(sp, np)) != 0)
1011275c9da8Seschrock 		return (err);
1012275c9da8Seschrock 
1013275c9da8Seschrock 	if ((err = elem_parse_aes(sp, np)) != 0)
1014275c9da8Seschrock 		return (err);
1015275c9da8Seschrock 
1016275c9da8Seschrock 	if ((err = elem_parse_threshold(sp, np)) != 0)
1017275c9da8Seschrock 		return (err);
1018275c9da8Seschrock 
1019275c9da8Seschrock 	return (0);
1020275c9da8Seschrock }
1021