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 static int 653 elem_parse_aes_device(const ses2_aes_descr_eip_impl_t *dep, nvlist_t *nvl, 654 size_t len) 655 { 656 ses2_aes_descr_fc_eip_impl_t *fp; 657 ses2_aes_descr_sas0_eip_impl_t *s0ep; 658 ses2_aes_descr_sas0_impl_t *s0p; 659 ses2_aes_descr_impl_t *dip; 660 nvlist_t **nva; 661 int nverr, i; 662 size_t nphy; 663 664 if (dep->sadei_eip) { 665 s0ep = (ses2_aes_descr_sas0_eip_impl_t *) 666 dep->sadei_protocol_specific; 667 s0p = (ses2_aes_descr_sas0_impl_t *) 668 dep->sadei_protocol_specific; 669 } else { 670 dip = (ses2_aes_descr_impl_t *)dep; 671 s0ep = NULL; 672 s0p = (ses2_aes_descr_sas0_impl_t *) 673 dip->sadei_protocol_specific; 674 } 675 676 if (dep->sadei_invalid) 677 return (0); 678 679 if (dep->sadei_protocol_identifier == SPC4_PROTO_FIBRE_CHANNEL) { 680 fp = (ses2_aes_descr_fc_eip_impl_t *) 681 dep->sadei_protocol_specific; 682 683 if (!SES_WITHIN_PAGE_STRUCT(fp, dep, len)) 684 return (0); 685 686 return (elem_parse_aes_fc(fp, nvl, len - 687 offsetof(ses2_aes_descr_eip_impl_t, 688 sadei_protocol_specific))); 689 } else if (dep->sadei_protocol_identifier != SPC4_PROTO_SAS) { 690 return (0); 691 } 692 693 if (s0p->sadsi_descriptor_type != SES2_AESD_SAS_DEVICE) 694 return (0); 695 696 SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_SAS_NOT_ALL_PHYS, 697 s0p->sadsi_not_all_phys); 698 if (s0ep != NULL) { 699 SES_NV_ADD(uint64, nverr, nvl, SES_PROP_BAY_NUMBER, 700 s0ep->sadsi_bay_number); 701 nphy = MIN(s0ep->sadsi_n_phy_descriptors, 702 (len - offsetof(ses2_aes_descr_sas0_eip_impl_t, 703 sadsi_phys)) / sizeof (ses2_aes_phy0_descr_impl_t)); 704 } else { 705 nphy = MIN(s0p->sadsi_n_phy_descriptors, 706 (len - offsetof(ses2_aes_descr_sas0_impl_t, 707 sadsi_phys)) / sizeof (ses2_aes_phy0_descr_impl_t)); 708 } 709 710 if (nphy == 0) 711 return (0); 712 713 nva = ses_zalloc(nphy * sizeof (nvlist_t *)); 714 if (nva == NULL) 715 return (-1); 716 717 for (i = 0; i < nphy; i++) { 718 ses2_aes_phy0_descr_impl_t *pp; 719 pp = s0ep != NULL ? &s0ep->sadsi_phys[i] : &s0p->sadsi_phys[i]; 720 if ((nverr = nvlist_alloc(&nva[i], NV_UNIQUE_NAME, 0)) != 0) 721 goto fail; 722 if ((nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_DEVICE_TYPE, 723 pp->sapdi_device_type)) != 0) 724 goto fail; 725 if ((nverr = nvlist_add_boolean_value(nva[i], 726 SES_SAS_PROP_SMPI_PORT, pp->sapdi_smp_initiator_port)) != 0) 727 goto fail; 728 if ((nverr = nvlist_add_boolean_value(nva[i], 729 SES_SAS_PROP_STPI_PORT, pp->sapdi_stp_initiator_port)) != 0) 730 goto fail; 731 if ((nverr = nvlist_add_boolean_value(nva[i], 732 SES_SAS_PROP_SSPI_PORT, pp->sapdi_ssp_initiator_port)) != 0) 733 goto fail; 734 if ((nverr = nvlist_add_boolean_value(nva[i], 735 SES_SAS_PROP_SATA_DEVICE, pp->sapdi_sata_device)) != 0) 736 goto fail; 737 if ((nverr = nvlist_add_boolean_value(nva[i], 738 SES_SAS_PROP_SMPT_PORT, pp->sapdi_smp_target_port)) != 0) 739 goto fail; 740 if ((nverr = nvlist_add_boolean_value(nva[i], 741 SES_SAS_PROP_STPT_PORT, pp->sapdi_stp_target_port)) != 0) 742 goto fail; 743 if ((nverr = nvlist_add_boolean_value(nva[i], 744 SES_SAS_PROP_SSPT_PORT, pp->sapdi_ssp_target_port)) != 0) 745 goto fail; 746 nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_ATT_ADDR, 747 SCSI_READ64(&pp->sapdi_attached_sas_address)); 748 if (nverr != 0) 749 goto fail; 750 nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_ADDR, 751 SCSI_READ64(&pp->sapdi_sas_address)); 752 if (nverr != 0) 753 goto fail; 754 if ((nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_PHY_ID, 755 pp->sapdi_phy_identifier)) != 0) 756 goto fail; 757 } 758 759 if ((nverr = nvlist_add_nvlist_array(nvl, SES_SAS_PROP_PHYS, 760 nva, nphy)) != 0) 761 goto fail; 762 763 for (i = 0; i < nphy && nva[i] != NULL; i++) 764 nvlist_free(nva[i]); 765 ses_free(nva); 766 return (0); 767 768 fail: 769 for (i = 0; i < nphy && nva[i] != NULL; i++) 770 nvlist_free(nva[i]); 771 ses_free(nva); 772 return (ses_set_nverrno(nverr, NULL)); 773 } 774 775 static int 776 elem_parse_aes_expander(const ses2_aes_descr_eip_impl_t *dep, nvlist_t *nvl, 777 size_t len) 778 { 779 ses2_aes_descr_exp_impl_t *sep; 780 nvlist_t **nva; 781 int nverr, i; 782 size_t nphy; 783 784 if (dep->sadei_invalid) 785 return (0); 786 787 /* 788 * This should never happen; no current SAS expander can have any 789 * other kind of ports. But maybe someday - one could envision a 790 * SAS expander with iSCSI target ports, for example. 791 */ 792 if (dep->sadei_protocol_identifier != SPC4_PROTO_SAS) 793 return (0); 794 795 sep = (ses2_aes_descr_exp_impl_t *)dep->sadei_protocol_specific; 796 if (sep->sadei_descriptor_type != SES2_AESD_SAS_OTHER) 797 return (0); 798 799 SES_NV_ADD(uint64, nverr, nvl, SES_EXP_PROP_SAS_ADDR, 800 SCSI_READ64(&sep->sadei_sas_address)); 801 802 nphy = MIN(sep->sadei_n_exp_phy_descriptors, 803 (len - offsetof(ses2_aes_descr_exp_impl_t, 804 sadei_phys)) / sizeof (ses2_aes_exp_phy_descr_impl_t)); 805 806 if (nphy == 0) 807 return (0); 808 809 nva = ses_zalloc(nphy * sizeof (nvlist_t *)); 810 if (nva == NULL) 811 return (-1); 812 813 for (i = 0; i < nphy; i++) { 814 if ((nverr = nvlist_alloc(&nva[i], NV_UNIQUE_NAME, 0)) != 0) 815 goto fail; 816 if ((nverr = nvlist_add_uint64(nva[i], SES_PROP_CE_IDX, 817 sep->sadei_phys[i].saepdi_connector_element_index)) != 0) 818 goto fail; 819 if ((nverr = nvlist_add_uint64(nva[i], SES_PROP_OE_IDX, 820 sep->sadei_phys[i].saepdi_other_element_index)) != 0) 821 goto fail; 822 } 823 824 if ((nverr = nvlist_add_nvlist_array(nvl, SES_SAS_PROP_PHYS, 825 nva, nphy)) != 0) 826 goto fail; 827 828 for (i = 0; i < nphy && nva[i] != NULL; i++) 829 nvlist_free(nva[i]); 830 ses_free(nva); 831 return (0); 832 833 fail: 834 for (i = 0; i < nphy && nva[i] != NULL; i++) 835 nvlist_free(nva[i]); 836 ses_free(nva); 837 return (ses_set_nverrno(nverr, NULL)); 838 } 839 840 static int 841 elem_parse_aes_misc(const ses2_aes_descr_eip_impl_t *dep, nvlist_t *nvl, 842 size_t len) 843 { 844 ses2_aes_descr_fc_eip_impl_t *fp; 845 ses2_aes_descr_sas1_impl_t *s1p; 846 nvlist_t **nva; 847 int nverr, i; 848 size_t nphy; 849 850 if (dep->sadei_invalid) 851 return (0); 852 853 if (dep->sadei_protocol_identifier == SPC4_PROTO_FIBRE_CHANNEL) { 854 fp = (ses2_aes_descr_fc_eip_impl_t *) 855 dep->sadei_protocol_specific; 856 857 if (!SES_WITHIN_PAGE_STRUCT(fp, dep, len)) 858 return (0); 859 860 return (elem_parse_aes_fc(fp, nvl, len - 861 offsetof(ses2_aes_descr_eip_impl_t, 862 sadei_protocol_specific))); 863 } else if (dep->sadei_protocol_identifier != SPC4_PROTO_SAS) { 864 return (0); 865 } 866 867 s1p = (ses2_aes_descr_sas1_impl_t *)dep->sadei_protocol_specific; 868 if (s1p->sadsi_descriptor_type == SES2_AESD_SAS_DEVICE) 869 return (0); 870 871 nphy = MIN(s1p->sadsi_n_phy_descriptors, 872 (len - offsetof(ses2_aes_descr_sas1_impl_t, 873 sadsi_phys)) / sizeof (ses2_aes_phy1_descr_impl_t)); 874 875 nva = ses_zalloc(nphy * sizeof (nvlist_t *)); 876 if (nva == NULL) 877 return (-1); 878 879 for (i = 0; i < nphy; i++) { 880 if ((nverr = nvlist_alloc(&nva[i], NV_UNIQUE_NAME, 0)) != 0) 881 goto fail; 882 if ((nverr = nvlist_add_uint64(nva[i], SES_PROP_CE_IDX, 883 s1p->sadsi_phys[i].sapdi_connector_element_index)) != 0) 884 goto fail; 885 if ((nverr = nvlist_add_uint64(nva[i], SES_PROP_OE_IDX, 886 s1p->sadsi_phys[i].sapdi_other_element_index)) != 0) 887 goto fail; 888 if ((nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_ADDR, 889 SCSI_READ64(&s1p->sadsi_phys[i].sapdi_sas_address))) != 0) 890 goto fail; 891 } 892 893 if ((nverr = nvlist_add_nvlist_array(nvl, SES_SAS_PROP_PHYS, 894 nva, nphy)) != 0) 895 goto fail; 896 897 for (i = 0; i < nphy && nva[i] != NULL; i++) 898 nvlist_free(nva[i]); 899 900 ses_free(nva); 901 return (0); 902 903 fail: 904 for (i = 0; i < nphy && nva[i] != NULL; i++) 905 nvlist_free(nva[i]); 906 ses_free(nva); 907 return (nverr); 908 } 909 910 static const struct aes_parser { 911 ses2_element_type_t type; 912 int (*func)(const ses2_aes_descr_eip_impl_t *, nvlist_t *, size_t); 913 } aes_parsers[] = { 914 { SES_ET_DEVICE, elem_parse_aes_device }, 915 { SES_ET_SCSI_TARGET_PORT, elem_parse_aes_misc }, 916 { SES_ET_SCSI_INITIATOR_PORT, elem_parse_aes_misc }, 917 { SES_ET_ESC_ELECTRONICS, elem_parse_aes_misc }, 918 { SES_ET_ARRAY_DEVICE, elem_parse_aes_device }, 919 { SES_ET_SAS_EXPANDER, elem_parse_aes_expander }, 920 { (ses2_element_type_t)-1, NULL } 921 }; 922 923 static int 924 elem_parse_aes(ses_plugin_t *sp, ses_node_t *np) 925 { 926 ses2_aes_descr_eip_impl_t *dep; 927 nvlist_t *props = ses_node_props(np); 928 const struct aes_parser *app; 929 uint64_t type; 930 size_t len; 931 932 if (ses_node_type(np) == SES_NODE_AGGREGATE) 933 return (0); 934 935 VERIFY(nvlist_lookup_uint64(props, SES_PROP_ELEMENT_TYPE, 936 &type) == 0); 937 938 for (app = &aes_parsers[0]; app->func != NULL; app++) 939 if (app->type == type) 940 break; 941 if (app->func == NULL) 942 return (0); 943 944 if ((dep = ses_plugin_page_lookup(sp, ses_node_snapshot(np), 945 SES2_DIAGPAGE_ADDL_ELEM_STATUS, np, &len)) == NULL) 946 return (0); 947 948 return (app->func(dep, props, len)); 949 } 950 951 static int 952 elem_parse_threshold(ses_plugin_t *sp, ses_node_t *np) 953 { 954 ses_snap_t *snap = ses_node_snapshot(np); 955 ses2_threshold_impl_t *tp; 956 nvlist_t *nvl = ses_node_props(np); 957 int nverr; 958 uint64_t type; 959 size_t len; 960 961 VERIFY(nvlist_lookup_uint64(nvl, SES_PROP_ELEMENT_TYPE, 962 &type) == 0); 963 964 switch (type) { 965 case SES_ET_TEMPERATURE_SENSOR: 966 case SES_ET_UPS: 967 case SES_ET_VOLTAGE_SENSOR: 968 case SES_ET_CURRENT_SENSOR: 969 break; 970 default: 971 return (0); 972 } 973 974 if ((tp = ses_plugin_page_lookup(sp, snap, 975 SES2_DIAGPAGE_THRESHOLD_IO, np, &len)) == NULL) 976 return (0); 977 978 SES_NV_ADD(uint64, nverr, nvl, SES_PROP_THRESH_CRIT_HI, 979 tp->sti_high_crit); 980 SES_NV_ADD(uint64, nverr, nvl, SES_PROP_THRESH_WARN_HI, 981 tp->sti_high_warn); 982 SES_NV_ADD(uint64, nverr, nvl, SES_PROP_THRESH_CRIT_LO, 983 tp->sti_low_crit); 984 SES_NV_ADD(uint64, nverr, nvl, SES_PROP_THRESH_WARN_LO, 985 tp->sti_low_warn); 986 987 return (0); 988 } 989 990 int 991 ses2_fill_element_node(ses_plugin_t *sp, ses_node_t *np) 992 { 993 int err; 994 995 if ((err = elem_parse_sd(sp, np)) != 0) 996 return (err); 997 998 if ((err = elem_parse_descr(sp, np)) != 0) 999 return (err); 1000 1001 if ((err = elem_parse_aes(sp, np)) != 0) 1002 return (err); 1003 1004 if ((err = elem_parse_threshold(sp, np)) != 0) 1005 return (err); 1006 1007 return (0); 1008 } 1009