17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*06e46062Sjbeloro * Common Development and Distribution License (the "License").
6*06e46062Sjbeloro * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
21*06e46062Sjbeloro
227c478bd9Sstevel@tonic-gate /*
23*06e46062Sjbeloro * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate * This plugin creates PICL nodes and properties for objects handled through
317c478bd9Sstevel@tonic-gate * the enhanced LOMV system-processor interface.
327c478bd9Sstevel@tonic-gate *
337c478bd9Sstevel@tonic-gate * All the nodes which may be accessible through the system-processor are
347c478bd9Sstevel@tonic-gate * included below the service-processor node in the /platform tree.
357c478bd9Sstevel@tonic-gate * This plugin interrogates the system-processor to determine which of
367c478bd9Sstevel@tonic-gate * those nodes are actually available. Properties are added to such nodes and
377c478bd9Sstevel@tonic-gate * in the case of volatile properties like temperature, a call-back function
387c478bd9Sstevel@tonic-gate * is established for on-demand access to the current value.
397c478bd9Sstevel@tonic-gate * LEDs for which the system-processor provides write access are associated
407c478bd9Sstevel@tonic-gate * with read/write volatile properties.
417c478bd9Sstevel@tonic-gate *
427c478bd9Sstevel@tonic-gate * NOTE:
437c478bd9Sstevel@tonic-gate * Depends on PICL devtree plugin.
447c478bd9Sstevel@tonic-gate */
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gate #include <stdio.h>
477c478bd9Sstevel@tonic-gate #include <stdlib.h>
487c478bd9Sstevel@tonic-gate #include <unistd.h>
497c478bd9Sstevel@tonic-gate #include <fcntl.h>
507c478bd9Sstevel@tonic-gate #include <alloca.h>
517c478bd9Sstevel@tonic-gate #include <syslog.h>
527c478bd9Sstevel@tonic-gate #include <string.h>
537c478bd9Sstevel@tonic-gate #include <libintl.h>
547c478bd9Sstevel@tonic-gate #include <picl.h>
557c478bd9Sstevel@tonic-gate #include <picltree.h>
567c478bd9Sstevel@tonic-gate #include <libnvpair.h>
577c478bd9Sstevel@tonic-gate #include <errno.h>
587c478bd9Sstevel@tonic-gate #include <limits.h>
597c478bd9Sstevel@tonic-gate #include <ctype.h>
607c478bd9Sstevel@tonic-gate #include <sys/types.h>
617c478bd9Sstevel@tonic-gate #include <sys/stat.h>
627c478bd9Sstevel@tonic-gate #include <sys/obpdefs.h>
637c478bd9Sstevel@tonic-gate #include <sys/envmon.h>
647c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h>
657c478bd9Sstevel@tonic-gate #include <dirent.h>
667c478bd9Sstevel@tonic-gate #include <time.h>
677c478bd9Sstevel@tonic-gate #include <picldefs.h>
687c478bd9Sstevel@tonic-gate #include <picld_pluginutil.h>
697c478bd9Sstevel@tonic-gate #include <libdevinfo.h>
707c478bd9Sstevel@tonic-gate #include "piclenvmon.h"
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate static void piclenvmon_register(void);
737c478bd9Sstevel@tonic-gate static void piclenvmon_init(void);
747c478bd9Sstevel@tonic-gate static void piclenvmon_fini(void);
757c478bd9Sstevel@tonic-gate static node_el_t *create_node_el(picl_nodehdl_t nodeh);
767c478bd9Sstevel@tonic-gate static void delete_node_el(node_el_t *pel);
777c478bd9Sstevel@tonic-gate static node_list_t *create_node_list();
787c478bd9Sstevel@tonic-gate static void delete_node_list(node_list_t *pnl);
797c478bd9Sstevel@tonic-gate static void add_node_to_list(picl_nodehdl_t nodeh, node_list_t *listp);
807c478bd9Sstevel@tonic-gate static void get_node_list_by_class(picl_nodehdl_t nodeh,
817c478bd9Sstevel@tonic-gate const char *classname, node_list_t *listp);
827c478bd9Sstevel@tonic-gate static int get_envmon_limits(int envmon_fd, envmon_sysinfo_t *limits_p);
837c478bd9Sstevel@tonic-gate static void create_arrays();
847c478bd9Sstevel@tonic-gate static int get_envmon_node(picl_nodehdl_t *envmoninfh);
857c478bd9Sstevel@tonic-gate static char *create_envmon_pathname(picl_nodehdl_t envmoninfh);
867c478bd9Sstevel@tonic-gate static int get_child_by_name(picl_nodehdl_t nodeh, const char *name,
877c478bd9Sstevel@tonic-gate picl_nodehdl_t *childh);
887c478bd9Sstevel@tonic-gate static int add_regular_prop(picl_nodehdl_t nodeh, const char *name,
897c478bd9Sstevel@tonic-gate int type, int access, int size, const void *valbuf, picl_prophdl_t *prophp);
907c478bd9Sstevel@tonic-gate static int add_volatile_prop(picl_nodehdl_t nodeh, const char *name,
917c478bd9Sstevel@tonic-gate int type, int access, int size, ptree_vol_rdfunc_t rdfunc,
927c478bd9Sstevel@tonic-gate ptree_vol_wrfunc_t wrfunc, picl_prophdl_t *prophp);
937c478bd9Sstevel@tonic-gate static int get_sensor_data(int envmon_fd, envmon_handle_t *id, int cmd,
947c478bd9Sstevel@tonic-gate envmon_thresholds_t *lows, envmon_thresholds_t *highs, int16_t *value);
957c478bd9Sstevel@tonic-gate static int get_indicator_data(int envmon_fd, envmon_handle_t *id, int cmd,
967c478bd9Sstevel@tonic-gate int16_t *condition);
977c478bd9Sstevel@tonic-gate static int get_fan_data(int envmon_fd, envmon_handle_t *id, int cmd,
987c478bd9Sstevel@tonic-gate envmon_thresholds_t *lows, uint16_t *speed, char *units);
997c478bd9Sstevel@tonic-gate static int get_led_data(int envmon_fd, envmon_handle_t *id, int cmd,
1007c478bd9Sstevel@tonic-gate int8_t *state, int8_t *colour);
1017c478bd9Sstevel@tonic-gate static int get_keyswitch_data(int envmon_fd, envmon_handle_t *id, int cmd,
1027c478bd9Sstevel@tonic-gate envmon_keysw_pos_t *key_state);
1037c478bd9Sstevel@tonic-gate static void convert_node_name(char *ptr);
1047c478bd9Sstevel@tonic-gate static void convert_label_name(char *ptr);
1057c478bd9Sstevel@tonic-gate static int add_value_prop(picl_nodehdl_t node_hdl, const char *prop_name,
1067c478bd9Sstevel@tonic-gate int fru_type, int16_t value);
1077c478bd9Sstevel@tonic-gate static int find_picl_handle(picl_prophdl_t proph);
1087c478bd9Sstevel@tonic-gate static int lookup_led_status(int8_t state, const char **string);
1097c478bd9Sstevel@tonic-gate static int lookup_key_posn(envmon_keysw_pos_t pos, const char **string);
1107c478bd9Sstevel@tonic-gate static int get_config_file(char *filename);
1117c478bd9Sstevel@tonic-gate static int read_vol_data(ptree_rarg_t *r_arg, void *buf);
1127c478bd9Sstevel@tonic-gate static int write_led_data(ptree_warg_t *w_arg, const void *buf);
1137c478bd9Sstevel@tonic-gate static int add_env_nodes(int envmon_fd, uint8_t fru_type,
1147c478bd9Sstevel@tonic-gate picl_nodehdl_t envmonh);
1157c478bd9Sstevel@tonic-gate static void fixstate(uint8_t state, const char *string, int *max_len);
1167c478bd9Sstevel@tonic-gate static void fixkeyposn(envmon_keysw_pos_t keyposn, const char *string,
1177c478bd9Sstevel@tonic-gate int *max_len);
1187c478bd9Sstevel@tonic-gate static void setup_strings();
1197c478bd9Sstevel@tonic-gate static void free_vol_prop(picl_prophdl_t proph);
1207c478bd9Sstevel@tonic-gate static void envmon_evhandler(const char *ename, const void *earg,
1217c478bd9Sstevel@tonic-gate size_t size, void *cookie);
122*06e46062Sjbeloro static int get_serial_num(int envmon_fd, envmon_handle_t *id, int cmd,
123*06e46062Sjbeloro envmon_chassis_t *chassis);
1247c478bd9Sstevel@tonic-gate
1257c478bd9Sstevel@tonic-gate #pragma init(piclenvmon_register)
1267c478bd9Sstevel@tonic-gate
1277c478bd9Sstevel@tonic-gate static picld_plugin_reg_t my_reg_info = {
1287c478bd9Sstevel@tonic-gate PICLD_PLUGIN_VERSION_1,
1297c478bd9Sstevel@tonic-gate PICLD_PLUGIN_NON_CRITICAL,
1307c478bd9Sstevel@tonic-gate "SUNW_piclenvmon",
1317c478bd9Sstevel@tonic-gate piclenvmon_init,
1327c478bd9Sstevel@tonic-gate piclenvmon_fini
1337c478bd9Sstevel@tonic-gate };
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate static const char str_On[] = "on";
1367c478bd9Sstevel@tonic-gate static const char str_Off[] = "off";
137*06e46062Sjbeloro static const char str_Blinking[] = "blinking";
138*06e46062Sjbeloro static const char str_Flashing[] = "flashing";
1397c478bd9Sstevel@tonic-gate static const char str_SC[] = "SC";
1407c478bd9Sstevel@tonic-gate static char *envmon_device_name = NULL;
1417c478bd9Sstevel@tonic-gate static envmon_sysinfo_t env_limits;
1427c478bd9Sstevel@tonic-gate static handle_array_t handle_arr;
1437c478bd9Sstevel@tonic-gate static struct {
1447c478bd9Sstevel@tonic-gate int size;
1457c478bd9Sstevel@tonic-gate char *str_colour;
1467c478bd9Sstevel@tonic-gate } colour_lkup[1 + ENVMON_LED_CLR_RED];
1477c478bd9Sstevel@tonic-gate
1487c478bd9Sstevel@tonic-gate static struct {
1497c478bd9Sstevel@tonic-gate int8_t state;
1507c478bd9Sstevel@tonic-gate char *str_ledstate;
1517c478bd9Sstevel@tonic-gate } ledstate_lkup[] = {
1527c478bd9Sstevel@tonic-gate { ENVMON_LED_OFF },
1537c478bd9Sstevel@tonic-gate { ENVMON_LED_ON },
1547c478bd9Sstevel@tonic-gate { ENVMON_LED_BLINKING },
1557c478bd9Sstevel@tonic-gate { ENVMON_LED_FLASHING }
1567c478bd9Sstevel@tonic-gate };
1577c478bd9Sstevel@tonic-gate
1587c478bd9Sstevel@tonic-gate static struct {
1597c478bd9Sstevel@tonic-gate envmon_keysw_pos_t pos;
1607c478bd9Sstevel@tonic-gate char *str_keyposn;
1617c478bd9Sstevel@tonic-gate } keyposn_lkup[] = {
1627c478bd9Sstevel@tonic-gate { ENVMON_KEYSW_POS_UNKNOWN },
1637c478bd9Sstevel@tonic-gate { ENVMON_KEYSW_POS_NORMAL },
1647c478bd9Sstevel@tonic-gate { ENVMON_KEYSW_POS_DIAG },
1657c478bd9Sstevel@tonic-gate { ENVMON_KEYSW_POS_LOCKED },
1667c478bd9Sstevel@tonic-gate { ENVMON_KEYSW_POS_OFF }
1677c478bd9Sstevel@tonic-gate };
1687c478bd9Sstevel@tonic-gate
1697c478bd9Sstevel@tonic-gate /*
1707c478bd9Sstevel@tonic-gate * fru-type to ioctl cmd lookup
1717c478bd9Sstevel@tonic-gate */
1727c478bd9Sstevel@tonic-gate int fru_to_cmd[] = {
1737c478bd9Sstevel@tonic-gate ENVMONIOCVOLTSENSOR,
1747c478bd9Sstevel@tonic-gate ENVMONIOCVOLTIND,
1757c478bd9Sstevel@tonic-gate ENVMONIOCAMPSENSOR,
1767c478bd9Sstevel@tonic-gate ENVMONIOCAMPIND,
1777c478bd9Sstevel@tonic-gate ENVMONIOCTEMPSENSOR,
1787c478bd9Sstevel@tonic-gate ENVMONIOCTEMPIND,
1797c478bd9Sstevel@tonic-gate ENVMONIOCFAN,
1807c478bd9Sstevel@tonic-gate ENVMONIOCFANIND,
1817c478bd9Sstevel@tonic-gate ENVMONIOCGETLED,
182*06e46062Sjbeloro ENVMONIOCGETKEYSW,
183*06e46062Sjbeloro ENVMONIOCCHASSISSERIALNUM
1847c478bd9Sstevel@tonic-gate };
1857c478bd9Sstevel@tonic-gate
1867c478bd9Sstevel@tonic-gate /*
1877c478bd9Sstevel@tonic-gate * fru-type to PICL CLASS
1887c478bd9Sstevel@tonic-gate */
1897c478bd9Sstevel@tonic-gate const char *fru_to_class[] = {
1907c478bd9Sstevel@tonic-gate PICL_CLASS_VOLTAGE_SENSOR,
1917c478bd9Sstevel@tonic-gate PICL_CLASS_VOLTAGE_INDICATOR,
1927c478bd9Sstevel@tonic-gate PICL_CLASS_CURRENT_SENSOR,
1937c478bd9Sstevel@tonic-gate PICL_CLASS_CURRENT_INDICATOR,
1947c478bd9Sstevel@tonic-gate PICL_CLASS_TEMPERATURE_SENSOR,
1957c478bd9Sstevel@tonic-gate PICL_CLASS_TEMPERATURE_INDICATOR,
1967c478bd9Sstevel@tonic-gate PICL_CLASS_FAN,
1977c478bd9Sstevel@tonic-gate PICL_CLASS_FAN,
1987c478bd9Sstevel@tonic-gate PICL_CLASS_LED,
199*06e46062Sjbeloro PICL_CLASS_KEYSWITCH,
200*06e46062Sjbeloro PICL_CLASS_CHASSIS_SERIAL_NUM
2017c478bd9Sstevel@tonic-gate };
2027c478bd9Sstevel@tonic-gate
2037c478bd9Sstevel@tonic-gate /*
2047c478bd9Sstevel@tonic-gate * fru-type to PICL PROPERTY for volatile data
2057c478bd9Sstevel@tonic-gate */
2067c478bd9Sstevel@tonic-gate const char *fru_to_prop[] = {
2077c478bd9Sstevel@tonic-gate PICL_PROP_VOLTAGE,
2087c478bd9Sstevel@tonic-gate PICL_PROP_CONDITION,
2097c478bd9Sstevel@tonic-gate PICL_PROP_CURRENT,
2107c478bd9Sstevel@tonic-gate PICL_PROP_CONDITION,
2117c478bd9Sstevel@tonic-gate PICL_PROP_TEMPERATURE,
2127c478bd9Sstevel@tonic-gate PICL_PROP_CONDITION,
2137c478bd9Sstevel@tonic-gate PICL_PROP_FAN_SPEED,
2147c478bd9Sstevel@tonic-gate PICL_PROP_FAN_SPEED_UNIT,
2157c478bd9Sstevel@tonic-gate PICL_PROP_STATE,
216*06e46062Sjbeloro PICL_PROP_STATE,
217*06e46062Sjbeloro PICL_PROP_SERIAL_NUMBER
2187c478bd9Sstevel@tonic-gate };
2197c478bd9Sstevel@tonic-gate
2207c478bd9Sstevel@tonic-gate /*
2217c478bd9Sstevel@tonic-gate * fru-type to PICL PTYPE
2227c478bd9Sstevel@tonic-gate */
2237c478bd9Sstevel@tonic-gate int fru_to_ptype[] = {
2247c478bd9Sstevel@tonic-gate PICL_PTYPE_FLOAT,
2257c478bd9Sstevel@tonic-gate PICL_PTYPE_CHARSTRING,
2267c478bd9Sstevel@tonic-gate PICL_PTYPE_FLOAT,
2277c478bd9Sstevel@tonic-gate PICL_PTYPE_CHARSTRING,
2287c478bd9Sstevel@tonic-gate PICL_PTYPE_INT,
2297c478bd9Sstevel@tonic-gate PICL_PTYPE_CHARSTRING,
2307c478bd9Sstevel@tonic-gate PICL_PTYPE_UNSIGNED_INT,
2317c478bd9Sstevel@tonic-gate PICL_PTYPE_CHARSTRING,
2327c478bd9Sstevel@tonic-gate PICL_PTYPE_CHARSTRING,
233*06e46062Sjbeloro PICL_PTYPE_CHARSTRING,
2347c478bd9Sstevel@tonic-gate PICL_PTYPE_CHARSTRING
2357c478bd9Sstevel@tonic-gate };
2367c478bd9Sstevel@tonic-gate
2377c478bd9Sstevel@tonic-gate /*
2387c478bd9Sstevel@tonic-gate * condition strings
2397c478bd9Sstevel@tonic-gate */
2407c478bd9Sstevel@tonic-gate static char *cond_okay;
2417c478bd9Sstevel@tonic-gate static char *cond_failed;
2427c478bd9Sstevel@tonic-gate
2437c478bd9Sstevel@tonic-gate /*
2447c478bd9Sstevel@tonic-gate * fru-type to size of volatile property
2457c478bd9Sstevel@tonic-gate * the -1's are replaced by the max size of a condition string
2467c478bd9Sstevel@tonic-gate */
2477c478bd9Sstevel@tonic-gate int fru_to_size[] = {
248*06e46062Sjbeloro 4, -1, 4, -1, 2, -1, 2, -1, -1, -1, -1
2497c478bd9Sstevel@tonic-gate };
2507c478bd9Sstevel@tonic-gate
2517c478bd9Sstevel@tonic-gate static node_el_t *
create_node_el(picl_nodehdl_t nodeh)2527c478bd9Sstevel@tonic-gate create_node_el(picl_nodehdl_t nodeh)
2537c478bd9Sstevel@tonic-gate {
2547c478bd9Sstevel@tonic-gate node_el_t *ptr = malloc(sizeof (node_el_t));
2557c478bd9Sstevel@tonic-gate
2567c478bd9Sstevel@tonic-gate if (ptr != NULL) {
2577c478bd9Sstevel@tonic-gate ptr->nodeh = nodeh;
2587c478bd9Sstevel@tonic-gate ptr->next = NULL;
2597c478bd9Sstevel@tonic-gate }
2607c478bd9Sstevel@tonic-gate
2617c478bd9Sstevel@tonic-gate return (ptr);
2627c478bd9Sstevel@tonic-gate }
2637c478bd9Sstevel@tonic-gate
2647c478bd9Sstevel@tonic-gate static void
delete_node_el(node_el_t * pel)2657c478bd9Sstevel@tonic-gate delete_node_el(node_el_t *pel)
2667c478bd9Sstevel@tonic-gate {
2677c478bd9Sstevel@tonic-gate free(pel);
2687c478bd9Sstevel@tonic-gate }
2697c478bd9Sstevel@tonic-gate
2707c478bd9Sstevel@tonic-gate static node_list_t *
create_node_list()2717c478bd9Sstevel@tonic-gate create_node_list()
2727c478bd9Sstevel@tonic-gate {
2737c478bd9Sstevel@tonic-gate node_list_t *ptr = malloc(sizeof (node_list_t));
2747c478bd9Sstevel@tonic-gate
2757c478bd9Sstevel@tonic-gate if (ptr != NULL) {
2767c478bd9Sstevel@tonic-gate ptr->head = NULL;
2777c478bd9Sstevel@tonic-gate ptr->tail = NULL;
2787c478bd9Sstevel@tonic-gate }
2797c478bd9Sstevel@tonic-gate
2807c478bd9Sstevel@tonic-gate return (ptr);
2817c478bd9Sstevel@tonic-gate }
2827c478bd9Sstevel@tonic-gate
2837c478bd9Sstevel@tonic-gate static void
delete_node_list(node_list_t * pnl)2847c478bd9Sstevel@tonic-gate delete_node_list(node_list_t *pnl)
2857c478bd9Sstevel@tonic-gate {
2867c478bd9Sstevel@tonic-gate node_el_t *pel;
2877c478bd9Sstevel@tonic-gate
2887c478bd9Sstevel@tonic-gate if (pnl == NULL)
2897c478bd9Sstevel@tonic-gate return;
2907c478bd9Sstevel@tonic-gate
2917c478bd9Sstevel@tonic-gate while ((pel = pnl->head) != NULL) {
2927c478bd9Sstevel@tonic-gate pnl->head = pel->next;
2937c478bd9Sstevel@tonic-gate delete_node_el(pel);
2947c478bd9Sstevel@tonic-gate }
2957c478bd9Sstevel@tonic-gate
2967c478bd9Sstevel@tonic-gate /*
2977c478bd9Sstevel@tonic-gate * normally pnl->tail would be to NULL next,
2987c478bd9Sstevel@tonic-gate * but as it is about to be freed, this step can be skipped.
2997c478bd9Sstevel@tonic-gate */
3007c478bd9Sstevel@tonic-gate free(pnl);
3017c478bd9Sstevel@tonic-gate }
3027c478bd9Sstevel@tonic-gate
3037c478bd9Sstevel@tonic-gate /*
3047c478bd9Sstevel@tonic-gate * Get a linking element and add handle to end of chain
3057c478bd9Sstevel@tonic-gate */
3067c478bd9Sstevel@tonic-gate static void
add_node_to_list(picl_nodehdl_t nodeh,node_list_t * listp)3077c478bd9Sstevel@tonic-gate add_node_to_list(picl_nodehdl_t nodeh, node_list_t *listp)
3087c478bd9Sstevel@tonic-gate {
3097c478bd9Sstevel@tonic-gate node_el_t *pel = create_node_el(nodeh);
3107c478bd9Sstevel@tonic-gate
3117c478bd9Sstevel@tonic-gate if (pel != NULL) {
3127c478bd9Sstevel@tonic-gate if (listp->tail == NULL)
3137c478bd9Sstevel@tonic-gate listp->head = pel;
3147c478bd9Sstevel@tonic-gate else
3157c478bd9Sstevel@tonic-gate listp->tail->next = pel;
3167c478bd9Sstevel@tonic-gate
3177c478bd9Sstevel@tonic-gate listp->tail = pel;
3187c478bd9Sstevel@tonic-gate }
3197c478bd9Sstevel@tonic-gate }
3207c478bd9Sstevel@tonic-gate
3217c478bd9Sstevel@tonic-gate /*
3227c478bd9Sstevel@tonic-gate * Get a list of nodes of the specified classname under nodeh.
3237c478bd9Sstevel@tonic-gate * Once a node of the specified class is found, its children are not
3247c478bd9Sstevel@tonic-gate * searched.
3257c478bd9Sstevel@tonic-gate */
3267c478bd9Sstevel@tonic-gate static void
get_node_list_by_class(picl_nodehdl_t nodeh,const char * classname,node_list_t * listp)3277c478bd9Sstevel@tonic-gate get_node_list_by_class(picl_nodehdl_t nodeh, const char *classname,
3287c478bd9Sstevel@tonic-gate node_list_t *listp)
3297c478bd9Sstevel@tonic-gate {
3307c478bd9Sstevel@tonic-gate int err;
3317c478bd9Sstevel@tonic-gate char clname[PICL_CLASSNAMELEN_MAX+1];
3327c478bd9Sstevel@tonic-gate picl_nodehdl_t chdh;
3337c478bd9Sstevel@tonic-gate
3347c478bd9Sstevel@tonic-gate /*
3357c478bd9Sstevel@tonic-gate * go through the children
3367c478bd9Sstevel@tonic-gate */
3377c478bd9Sstevel@tonic-gate err = ptree_get_propval_by_name(nodeh, PICL_PROP_CHILD, &chdh,
3387c478bd9Sstevel@tonic-gate sizeof (picl_nodehdl_t));
3397c478bd9Sstevel@tonic-gate
3407c478bd9Sstevel@tonic-gate while (err == PICL_SUCCESS) {
3417c478bd9Sstevel@tonic-gate err = ptree_get_propval_by_name(chdh, PICL_PROP_CLASSNAME,
3427c478bd9Sstevel@tonic-gate clname, strlen(classname) + 1);
3437c478bd9Sstevel@tonic-gate
3447c478bd9Sstevel@tonic-gate if ((err == PICL_SUCCESS) && (strcmp(clname, classname) == 0))
3457c478bd9Sstevel@tonic-gate add_node_to_list(chdh, listp);
3467c478bd9Sstevel@tonic-gate else
3477c478bd9Sstevel@tonic-gate get_node_list_by_class(chdh, classname, listp);
3487c478bd9Sstevel@tonic-gate
3497c478bd9Sstevel@tonic-gate err = ptree_get_propval_by_name(chdh, PICL_PROP_PEER, &chdh,
3507c478bd9Sstevel@tonic-gate sizeof (picl_nodehdl_t));
3517c478bd9Sstevel@tonic-gate }
3527c478bd9Sstevel@tonic-gate }
3537c478bd9Sstevel@tonic-gate
3547c478bd9Sstevel@tonic-gate static int
get_envmon_limits(int envmon_fd,envmon_sysinfo_t * limits_p)3557c478bd9Sstevel@tonic-gate get_envmon_limits(int envmon_fd, envmon_sysinfo_t *limits_p)
3567c478bd9Sstevel@tonic-gate {
3577c478bd9Sstevel@tonic-gate return (ioctl(envmon_fd, ENVMONIOCSYSINFO, limits_p));
3587c478bd9Sstevel@tonic-gate }
3597c478bd9Sstevel@tonic-gate
3607c478bd9Sstevel@tonic-gate static int
re_create_arrays(int envmon_fd)3617c478bd9Sstevel@tonic-gate re_create_arrays(int envmon_fd)
3627c478bd9Sstevel@tonic-gate {
3637c478bd9Sstevel@tonic-gate envmon_sysinfo_t new_limits;
3647c478bd9Sstevel@tonic-gate int res;
3657c478bd9Sstevel@tonic-gate int maxnum;
3667c478bd9Sstevel@tonic-gate uchar_t *fru_types;
3677c478bd9Sstevel@tonic-gate envmon_handle_t *envhandles;
3687c478bd9Sstevel@tonic-gate picl_prophdl_t *piclprhdls;
3697c478bd9Sstevel@tonic-gate
3707c478bd9Sstevel@tonic-gate res = get_envmon_limits(envmon_fd, &new_limits);
3717c478bd9Sstevel@tonic-gate if (res != 0)
3727c478bd9Sstevel@tonic-gate return (res);
3737c478bd9Sstevel@tonic-gate
3747c478bd9Sstevel@tonic-gate maxnum = new_limits.maxVoltSens + new_limits.maxVoltInd +
3757c478bd9Sstevel@tonic-gate new_limits.maxAmpSens + new_limits.maxAmpInd +
3767c478bd9Sstevel@tonic-gate new_limits.maxTempSens + new_limits.maxTempInd +
3777c478bd9Sstevel@tonic-gate new_limits.maxFanSens + new_limits.maxFanInd +
3787c478bd9Sstevel@tonic-gate new_limits.maxLED + N_KEY_SWITCHES;
3797c478bd9Sstevel@tonic-gate
3807c478bd9Sstevel@tonic-gate if (maxnum != handle_arr.maxnum) {
3817c478bd9Sstevel@tonic-gate /*
3827c478bd9Sstevel@tonic-gate * space requirements have changed
3837c478bd9Sstevel@tonic-gate */
3847c478bd9Sstevel@tonic-gate fru_types = calloc(maxnum, sizeof (uchar_t));
3857c478bd9Sstevel@tonic-gate envhandles = calloc(maxnum, sizeof (envmon_handle_t));
3867c478bd9Sstevel@tonic-gate piclprhdls = calloc(maxnum, sizeof (picl_prophdl_t));
3877c478bd9Sstevel@tonic-gate if ((fru_types == NULL) || (envhandles == NULL) ||
3887c478bd9Sstevel@tonic-gate (piclprhdls == NULL)) {
3897c478bd9Sstevel@tonic-gate free(fru_types);
3907c478bd9Sstevel@tonic-gate free(envhandles);
3917c478bd9Sstevel@tonic-gate free(piclprhdls);
3927c478bd9Sstevel@tonic-gate return (-1);
3937c478bd9Sstevel@tonic-gate }
3947c478bd9Sstevel@tonic-gate free(handle_arr.fru_types);
3957c478bd9Sstevel@tonic-gate handle_arr.fru_types = fru_types;
3967c478bd9Sstevel@tonic-gate free(handle_arr.envhandles);
3977c478bd9Sstevel@tonic-gate handle_arr.envhandles = envhandles;
3987c478bd9Sstevel@tonic-gate free(handle_arr.piclprhdls);
3997c478bd9Sstevel@tonic-gate handle_arr.piclprhdls = piclprhdls;
4007c478bd9Sstevel@tonic-gate } else {
4017c478bd9Sstevel@tonic-gate (void) memset(handle_arr.fru_types, 0,
4027c478bd9Sstevel@tonic-gate maxnum * sizeof (uchar_t));
4037c478bd9Sstevel@tonic-gate (void) memset(handle_arr.envhandles, 0,
4047c478bd9Sstevel@tonic-gate maxnum * sizeof (envmon_handle_t));
4057c478bd9Sstevel@tonic-gate (void) memset(handle_arr.piclprhdls, 0,
4067c478bd9Sstevel@tonic-gate maxnum * sizeof (picl_prophdl_t));
4077c478bd9Sstevel@tonic-gate }
4087c478bd9Sstevel@tonic-gate
4097c478bd9Sstevel@tonic-gate handle_arr.num = 0;
4107c478bd9Sstevel@tonic-gate handle_arr.maxnum = maxnum;
4117c478bd9Sstevel@tonic-gate env_limits = new_limits;
4127c478bd9Sstevel@tonic-gate return (0);
4137c478bd9Sstevel@tonic-gate }
4147c478bd9Sstevel@tonic-gate
4157c478bd9Sstevel@tonic-gate static void
create_arrays()4167c478bd9Sstevel@tonic-gate create_arrays()
4177c478bd9Sstevel@tonic-gate {
4187c478bd9Sstevel@tonic-gate int maxnum = env_limits.maxVoltSens + env_limits.maxVoltInd +
4197c478bd9Sstevel@tonic-gate env_limits.maxAmpSens + env_limits.maxAmpInd +
4207c478bd9Sstevel@tonic-gate env_limits.maxTempSens + env_limits.maxTempInd +
4217c478bd9Sstevel@tonic-gate env_limits.maxFanSens + env_limits.maxFanInd +
4227c478bd9Sstevel@tonic-gate env_limits.maxLED + N_KEY_SWITCHES;
4237c478bd9Sstevel@tonic-gate handle_arr.maxnum = maxnum;
4247c478bd9Sstevel@tonic-gate handle_arr.num = 0;
4257c478bd9Sstevel@tonic-gate handle_arr.fru_types = calloc(maxnum, sizeof (uchar_t));
4267c478bd9Sstevel@tonic-gate handle_arr.envhandles = calloc(maxnum, sizeof (envmon_handle_t));
4277c478bd9Sstevel@tonic-gate handle_arr.piclprhdls = calloc(maxnum, sizeof (picl_prophdl_t));
4287c478bd9Sstevel@tonic-gate }
4297c478bd9Sstevel@tonic-gate
4307c478bd9Sstevel@tonic-gate static int
get_envmon_node(picl_nodehdl_t * envmoninfh)4317c478bd9Sstevel@tonic-gate get_envmon_node(picl_nodehdl_t *envmoninfh)
4327c478bd9Sstevel@tonic-gate {
4337c478bd9Sstevel@tonic-gate int err = PICL_SUCCESS;
4347c478bd9Sstevel@tonic-gate node_list_t *listp;
4357c478bd9Sstevel@tonic-gate
4367c478bd9Sstevel@tonic-gate listp = create_node_list();
4377c478bd9Sstevel@tonic-gate
4387c478bd9Sstevel@tonic-gate if ((err = ptree_get_node_by_path(PICL_NODE_ROOT PICL_NODE_PLATFORM,
4397c478bd9Sstevel@tonic-gate envmoninfh)) != PICL_SUCCESS) {
4407c478bd9Sstevel@tonic-gate syslog(LOG_ERR, EM_MISSING_NODE,
4417c478bd9Sstevel@tonic-gate PICL_NODE_ROOT PICL_NODE_PLATFORM);
4427c478bd9Sstevel@tonic-gate return (err); /* no /platform ! */
4437c478bd9Sstevel@tonic-gate }
4447c478bd9Sstevel@tonic-gate
4457c478bd9Sstevel@tonic-gate get_node_list_by_class(*envmoninfh, PICL_CLASS_SERVICE_PROCESSOR,
4467c478bd9Sstevel@tonic-gate listp);
4477c478bd9Sstevel@tonic-gate
4487c478bd9Sstevel@tonic-gate if (listp->head == NULL) {
4497c478bd9Sstevel@tonic-gate *envmoninfh = 0;
4507c478bd9Sstevel@tonic-gate syslog(LOG_ERR, EM_MISSING_NODE, PICL_CLASS_SERVICE_PROCESSOR);
4517c478bd9Sstevel@tonic-gate err = PICL_NODENOTFOUND;
4527c478bd9Sstevel@tonic-gate } else {
4537c478bd9Sstevel@tonic-gate *envmoninfh = listp->head->nodeh;
4547c478bd9Sstevel@tonic-gate }
4557c478bd9Sstevel@tonic-gate
4567c478bd9Sstevel@tonic-gate delete_node_list(listp);
4577c478bd9Sstevel@tonic-gate return (err);
4587c478bd9Sstevel@tonic-gate }
4597c478bd9Sstevel@tonic-gate
4607c478bd9Sstevel@tonic-gate static char *
create_envmon_pathname(picl_nodehdl_t envmoninfh)4617c478bd9Sstevel@tonic-gate create_envmon_pathname(picl_nodehdl_t envmoninfh)
4627c478bd9Sstevel@tonic-gate {
4637c478bd9Sstevel@tonic-gate char *ptr;
4647c478bd9Sstevel@tonic-gate char namebuf[PATH_MAX];
4657c478bd9Sstevel@tonic-gate size_t len;
4667c478bd9Sstevel@tonic-gate DIR *dirp;
4677c478bd9Sstevel@tonic-gate struct dirent *dp;
4687c478bd9Sstevel@tonic-gate struct stat statbuf;
4697c478bd9Sstevel@tonic-gate
4707c478bd9Sstevel@tonic-gate /* prefix devfs-path name with /devices */
4717c478bd9Sstevel@tonic-gate (void) strlcpy(namebuf, "/devices", PATH_MAX);
4727c478bd9Sstevel@tonic-gate
4737c478bd9Sstevel@tonic-gate /*
4747c478bd9Sstevel@tonic-gate * append devfs-path property
4757c478bd9Sstevel@tonic-gate */
4767c478bd9Sstevel@tonic-gate len = strlen(namebuf);
4777c478bd9Sstevel@tonic-gate if (ptree_get_propval_by_name(envmoninfh, PICL_PROP_DEVFS_PATH,
4787c478bd9Sstevel@tonic-gate namebuf + len, sizeof (namebuf) - len) != PICL_SUCCESS) {
4797c478bd9Sstevel@tonic-gate syslog(LOG_ERR, EM_SC_NODE_INCOMPLETE);
4807c478bd9Sstevel@tonic-gate return (NULL);
4817c478bd9Sstevel@tonic-gate }
4827c478bd9Sstevel@tonic-gate
4837c478bd9Sstevel@tonic-gate /* locate final component of name */
4847c478bd9Sstevel@tonic-gate ptr = strrchr(namebuf, '/');
4857c478bd9Sstevel@tonic-gate if (ptr == NULL)
4867c478bd9Sstevel@tonic-gate return (NULL);
4877c478bd9Sstevel@tonic-gate *ptr = '\0'; /* terminate at end of directory path */
4887c478bd9Sstevel@tonic-gate len = strlen(ptr + 1); /* length of terminal name */
4897c478bd9Sstevel@tonic-gate dirp = opendir(namebuf);
4907c478bd9Sstevel@tonic-gate if (dirp == NULL) {
4917c478bd9Sstevel@tonic-gate syslog(LOG_ERR, EM_SC_NODE_MISSING);
4927c478bd9Sstevel@tonic-gate return (NULL);
4937c478bd9Sstevel@tonic-gate }
4947c478bd9Sstevel@tonic-gate *ptr++ = '/'; /* restore '/' and advance to final name */
4957c478bd9Sstevel@tonic-gate
4967c478bd9Sstevel@tonic-gate while ((dp = readdir(dirp)) != NULL) {
4977c478bd9Sstevel@tonic-gate /*
4987c478bd9Sstevel@tonic-gate * look for a name which starts with the string at *ptr
4997c478bd9Sstevel@tonic-gate */
5007c478bd9Sstevel@tonic-gate if (strlen(dp->d_name) < len)
5017c478bd9Sstevel@tonic-gate continue; /* skip short names */
5027c478bd9Sstevel@tonic-gate if (strncmp(dp->d_name, ptr, len) == 0) {
5037c478bd9Sstevel@tonic-gate /*
5047c478bd9Sstevel@tonic-gate * Got a match, restore full pathname and stat the
5057c478bd9Sstevel@tonic-gate * entry. Reject if not a char device
5067c478bd9Sstevel@tonic-gate */
5077c478bd9Sstevel@tonic-gate (void) strlcpy(ptr, dp->d_name,
5087c478bd9Sstevel@tonic-gate sizeof (namebuf) - (ptr - namebuf));
5097c478bd9Sstevel@tonic-gate if (stat(namebuf, &statbuf) < 0)
5107c478bd9Sstevel@tonic-gate continue; /* reject if can't stat it */
5117c478bd9Sstevel@tonic-gate if (!S_ISCHR(statbuf.st_mode))
5127c478bd9Sstevel@tonic-gate continue; /* not a character device */
5137c478bd9Sstevel@tonic-gate /*
5147c478bd9Sstevel@tonic-gate * go with this entry
5157c478bd9Sstevel@tonic-gate */
5167c478bd9Sstevel@tonic-gate (void) closedir(dirp);
5177c478bd9Sstevel@tonic-gate return (strdup(namebuf));
5187c478bd9Sstevel@tonic-gate }
5197c478bd9Sstevel@tonic-gate }
5207c478bd9Sstevel@tonic-gate syslog(LOG_ERR, EM_SC_NODE_MISSING);
5217c478bd9Sstevel@tonic-gate (void) closedir(dirp);
5227c478bd9Sstevel@tonic-gate return (NULL);
5237c478bd9Sstevel@tonic-gate }
5247c478bd9Sstevel@tonic-gate
5257c478bd9Sstevel@tonic-gate /*
5267c478bd9Sstevel@tonic-gate * look for named node as child of supplied handle
5277c478bd9Sstevel@tonic-gate */
5287c478bd9Sstevel@tonic-gate static int
get_child_by_name(picl_nodehdl_t nodeh,const char * name,picl_nodehdl_t * childh)5297c478bd9Sstevel@tonic-gate get_child_by_name(picl_nodehdl_t nodeh, const char *name,
5307c478bd9Sstevel@tonic-gate picl_nodehdl_t *childh)
5317c478bd9Sstevel@tonic-gate {
5327c478bd9Sstevel@tonic-gate int err;
5337c478bd9Sstevel@tonic-gate char node_name[ENVMON_MAXNAMELEN];
5347c478bd9Sstevel@tonic-gate
5357c478bd9Sstevel@tonic-gate if (strlen(name) >= ENVMON_MAXNAMELEN)
5367c478bd9Sstevel@tonic-gate return (PICL_NODENOTFOUND);
5377c478bd9Sstevel@tonic-gate err = ptree_get_propval_by_name(nodeh, PICL_PROP_CHILD, childh,
5387c478bd9Sstevel@tonic-gate sizeof (*childh));
5397c478bd9Sstevel@tonic-gate while (err == PICL_SUCCESS) {
5407c478bd9Sstevel@tonic-gate err = ptree_get_propval_by_name(*childh, PICL_PROP_NAME,
5417c478bd9Sstevel@tonic-gate node_name, sizeof (node_name));
5427c478bd9Sstevel@tonic-gate if ((err == PICL_SUCCESS) &&
5437c478bd9Sstevel@tonic-gate (strncmp(name, node_name, ENVMON_MAXNAMELEN) == 0))
5447c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
5457c478bd9Sstevel@tonic-gate err = ptree_get_propval_by_name(*childh, PICL_PROP_PEER,
5467c478bd9Sstevel@tonic-gate childh, sizeof (*childh));
5477c478bd9Sstevel@tonic-gate }
5487c478bd9Sstevel@tonic-gate return (err);
5497c478bd9Sstevel@tonic-gate }
5507c478bd9Sstevel@tonic-gate
5517c478bd9Sstevel@tonic-gate /*
5527c478bd9Sstevel@tonic-gate * Create and add the specified regular property
5537c478bd9Sstevel@tonic-gate */
5547c478bd9Sstevel@tonic-gate static int
add_regular_prop(picl_nodehdl_t nodeh,const char * name,int type,int access,int size,const void * valbuf,picl_prophdl_t * prophp)5557c478bd9Sstevel@tonic-gate add_regular_prop(picl_nodehdl_t nodeh, const char *name, int type, int access,
5567c478bd9Sstevel@tonic-gate int size, const void *valbuf, picl_prophdl_t *prophp)
5577c478bd9Sstevel@tonic-gate {
5587c478bd9Sstevel@tonic-gate int err;
5597c478bd9Sstevel@tonic-gate ptree_propinfo_t propinfo;
5607c478bd9Sstevel@tonic-gate picl_prophdl_t proph;
5617c478bd9Sstevel@tonic-gate
5627c478bd9Sstevel@tonic-gate err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
5637c478bd9Sstevel@tonic-gate type, access, size, (char *)name, NULL, NULL);
5647c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
5657c478bd9Sstevel@tonic-gate return (err);
5667c478bd9Sstevel@tonic-gate
5677c478bd9Sstevel@tonic-gate err = ptree_create_and_add_prop(nodeh, &propinfo, (void *)valbuf,
5687c478bd9Sstevel@tonic-gate &proph);
5697c478bd9Sstevel@tonic-gate if (err == PICL_SUCCESS && prophp)
5707c478bd9Sstevel@tonic-gate *prophp = proph;
5717c478bd9Sstevel@tonic-gate return (err);
5727c478bd9Sstevel@tonic-gate }
5737c478bd9Sstevel@tonic-gate
5747c478bd9Sstevel@tonic-gate
5757c478bd9Sstevel@tonic-gate /*
5767c478bd9Sstevel@tonic-gate * Create and add the specified volatile property
5777c478bd9Sstevel@tonic-gate */
5787c478bd9Sstevel@tonic-gate static int
add_volatile_prop(picl_nodehdl_t nodeh,const char * name,int type,int access,int size,ptree_vol_rdfunc_t rdfunc,ptree_vol_wrfunc_t wrfunc,picl_prophdl_t * prophp)5797c478bd9Sstevel@tonic-gate add_volatile_prop(picl_nodehdl_t nodeh, const char *name, int type, int access,
5807c478bd9Sstevel@tonic-gate int size, ptree_vol_rdfunc_t rdfunc, ptree_vol_wrfunc_t wrfunc,
5817c478bd9Sstevel@tonic-gate picl_prophdl_t *prophp)
5827c478bd9Sstevel@tonic-gate {
5837c478bd9Sstevel@tonic-gate int err;
5847c478bd9Sstevel@tonic-gate ptree_propinfo_t propinfo;
5857c478bd9Sstevel@tonic-gate picl_prophdl_t proph;
5867c478bd9Sstevel@tonic-gate
5877c478bd9Sstevel@tonic-gate err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
5887c478bd9Sstevel@tonic-gate type, (access|PICL_VOLATILE), size, (char *)name, rdfunc, wrfunc);
5897c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
5907c478bd9Sstevel@tonic-gate return (err);
5917c478bd9Sstevel@tonic-gate
5927c478bd9Sstevel@tonic-gate err = ptree_create_and_add_prop(nodeh, &propinfo, NULL, &proph);
5937c478bd9Sstevel@tonic-gate if (err == PICL_SUCCESS && prophp)
5947c478bd9Sstevel@tonic-gate *prophp = proph;
5957c478bd9Sstevel@tonic-gate return (err);
5967c478bd9Sstevel@tonic-gate }
5977c478bd9Sstevel@tonic-gate
5987c478bd9Sstevel@tonic-gate /*
5997c478bd9Sstevel@tonic-gate * There are 5 different structures used for reading environmental data
6007c478bd9Sstevel@tonic-gate * from the service-processor. A different function is used for each one.
6017c478bd9Sstevel@tonic-gate * Some functions cover several ioctls, so the desired ioctl is part of
6027c478bd9Sstevel@tonic-gate * the interface. In each case the id parameter is read/write, the
6037c478bd9Sstevel@tonic-gate * returned value being the next id for this fru type.
6047c478bd9Sstevel@tonic-gate */
6057c478bd9Sstevel@tonic-gate
6067c478bd9Sstevel@tonic-gate /*
6077c478bd9Sstevel@tonic-gate * Function to read sensor data.
6087c478bd9Sstevel@tonic-gate */
6097c478bd9Sstevel@tonic-gate static int
get_sensor_data(int envmon_fd,envmon_handle_t * id,int cmd,envmon_thresholds_t * lows,envmon_thresholds_t * highs,int16_t * value)6107c478bd9Sstevel@tonic-gate get_sensor_data(int envmon_fd, envmon_handle_t *id, int cmd,
6117c478bd9Sstevel@tonic-gate envmon_thresholds_t *lows, envmon_thresholds_t *highs, int16_t *value)
6127c478bd9Sstevel@tonic-gate {
6137c478bd9Sstevel@tonic-gate int res;
6147c478bd9Sstevel@tonic-gate envmon_sensor_t data;
6157c478bd9Sstevel@tonic-gate
6167c478bd9Sstevel@tonic-gate (void) memset(&data, 0, sizeof (data));
6177c478bd9Sstevel@tonic-gate data.id = *id;
6187c478bd9Sstevel@tonic-gate res = ioctl(envmon_fd, cmd, &data);
6197c478bd9Sstevel@tonic-gate if (res < 0) {
6207c478bd9Sstevel@tonic-gate return (PICL_NOTREADABLE);
6217c478bd9Sstevel@tonic-gate }
6227c478bd9Sstevel@tonic-gate
6237c478bd9Sstevel@tonic-gate *id = data.next_id;
6247c478bd9Sstevel@tonic-gate
6257c478bd9Sstevel@tonic-gate if ((data.sensor_status & ENVMON_NOT_PRESENT) != 0)
6267c478bd9Sstevel@tonic-gate return (PICL_INVALIDHANDLE);
6277c478bd9Sstevel@tonic-gate
6287c478bd9Sstevel@tonic-gate /*
6297c478bd9Sstevel@tonic-gate * it is assumed that threshold data will be available,
6307c478bd9Sstevel@tonic-gate * even though the current sensor value may be inaccessible
6317c478bd9Sstevel@tonic-gate */
6327c478bd9Sstevel@tonic-gate if (lows != NULL)
6337c478bd9Sstevel@tonic-gate *lows = data.lowthresholds;
6347c478bd9Sstevel@tonic-gate if (highs != NULL)
6357c478bd9Sstevel@tonic-gate *highs = data.highthresholds;
6367c478bd9Sstevel@tonic-gate
6377c478bd9Sstevel@tonic-gate if ((data.sensor_status & ENVMON_INACCESSIBLE) != 0) {
6387c478bd9Sstevel@tonic-gate if (value != NULL)
6397c478bd9Sstevel@tonic-gate *value = ENVMON_VAL_UNAVAILABLE;
6407c478bd9Sstevel@tonic-gate return (PICL_PROPVALUNAVAILABLE);
6417c478bd9Sstevel@tonic-gate }
6427c478bd9Sstevel@tonic-gate if (value != NULL)
6437c478bd9Sstevel@tonic-gate *value = data.value;
6447c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
6457c478bd9Sstevel@tonic-gate }
6467c478bd9Sstevel@tonic-gate
6477c478bd9Sstevel@tonic-gate /*
6487c478bd9Sstevel@tonic-gate * Function to read indicator data.
6497c478bd9Sstevel@tonic-gate */
6507c478bd9Sstevel@tonic-gate static int
get_indicator_data(int envmon_fd,envmon_handle_t * id,int cmd,int16_t * condition)6517c478bd9Sstevel@tonic-gate get_indicator_data(int envmon_fd, envmon_handle_t *id, int cmd,
6527c478bd9Sstevel@tonic-gate int16_t *condition)
6537c478bd9Sstevel@tonic-gate {
6547c478bd9Sstevel@tonic-gate int res;
6557c478bd9Sstevel@tonic-gate envmon_indicator_t data;
6567c478bd9Sstevel@tonic-gate
6577c478bd9Sstevel@tonic-gate data.id = *id;
6587c478bd9Sstevel@tonic-gate res = ioctl(envmon_fd, cmd, &data);
6597c478bd9Sstevel@tonic-gate if (res < 0)
6607c478bd9Sstevel@tonic-gate return (PICL_NOTREADABLE);
6617c478bd9Sstevel@tonic-gate *id = data.next_id;
6627c478bd9Sstevel@tonic-gate if ((data.sensor_status & ENVMON_NOT_PRESENT) != 0)
6637c478bd9Sstevel@tonic-gate return (PICL_INVALIDHANDLE);
6647c478bd9Sstevel@tonic-gate if (condition != NULL)
6657c478bd9Sstevel@tonic-gate *condition = data.condition;
6667c478bd9Sstevel@tonic-gate if ((data.sensor_status & ENVMON_INACCESSIBLE) != 0) {
6677c478bd9Sstevel@tonic-gate return (PICL_PROPVALUNAVAILABLE);
6687c478bd9Sstevel@tonic-gate }
6697c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
6707c478bd9Sstevel@tonic-gate }
6717c478bd9Sstevel@tonic-gate
6727c478bd9Sstevel@tonic-gate /*
6737c478bd9Sstevel@tonic-gate * Function to read fan data.
6747c478bd9Sstevel@tonic-gate */
6757c478bd9Sstevel@tonic-gate static int
get_fan_data(int envmon_fd,envmon_handle_t * id,int cmd,envmon_thresholds_t * lows,uint16_t * speed,char * units)6767c478bd9Sstevel@tonic-gate get_fan_data(int envmon_fd, envmon_handle_t *id, int cmd,
6777c478bd9Sstevel@tonic-gate envmon_thresholds_t *lows, uint16_t *speed, char *units)
6787c478bd9Sstevel@tonic-gate {
6797c478bd9Sstevel@tonic-gate int res;
6807c478bd9Sstevel@tonic-gate envmon_fan_t data;
6817c478bd9Sstevel@tonic-gate
6827c478bd9Sstevel@tonic-gate data.id = *id;
6837c478bd9Sstevel@tonic-gate res = ioctl(envmon_fd, cmd, &data);
6847c478bd9Sstevel@tonic-gate if (res < 0)
6857c478bd9Sstevel@tonic-gate return (PICL_NOTREADABLE);
6867c478bd9Sstevel@tonic-gate *id = data.next_id;
6877c478bd9Sstevel@tonic-gate if ((data.sensor_status & ENVMON_NOT_PRESENT) != 0)
6887c478bd9Sstevel@tonic-gate return (PICL_INVALIDHANDLE);
6897c478bd9Sstevel@tonic-gate if (lows != NULL)
6907c478bd9Sstevel@tonic-gate *lows = data.lowthresholds;
6917c478bd9Sstevel@tonic-gate if (units != NULL)
6927c478bd9Sstevel@tonic-gate (void) strlcpy(units, data.units, sizeof (data.units));
6937c478bd9Sstevel@tonic-gate
6947c478bd9Sstevel@tonic-gate if ((data.sensor_status & ENVMON_INACCESSIBLE) != 0) {
6957c478bd9Sstevel@tonic-gate if (speed != NULL)
6967c478bd9Sstevel@tonic-gate *speed = ENVMON_VAL_UNAVAILABLE;
6977c478bd9Sstevel@tonic-gate return (PICL_PROPVALUNAVAILABLE);
6987c478bd9Sstevel@tonic-gate }
6997c478bd9Sstevel@tonic-gate if (speed != NULL)
7007c478bd9Sstevel@tonic-gate *speed = data.speed;
7017c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
7027c478bd9Sstevel@tonic-gate }
7037c478bd9Sstevel@tonic-gate
7047c478bd9Sstevel@tonic-gate /*
7057c478bd9Sstevel@tonic-gate * Function to read LED data.
7067c478bd9Sstevel@tonic-gate */
7077c478bd9Sstevel@tonic-gate static int
get_led_data(int envmon_fd,envmon_handle_t * id,int cmd,int8_t * state,int8_t * colour)7087c478bd9Sstevel@tonic-gate get_led_data(int envmon_fd, envmon_handle_t *id, int cmd,
7097c478bd9Sstevel@tonic-gate int8_t *state, int8_t *colour)
7107c478bd9Sstevel@tonic-gate {
7117c478bd9Sstevel@tonic-gate int res;
7127c478bd9Sstevel@tonic-gate envmon_led_info_t data;
7137c478bd9Sstevel@tonic-gate
7147c478bd9Sstevel@tonic-gate data.id = *id;
7157c478bd9Sstevel@tonic-gate res = ioctl(envmon_fd, cmd, &data);
7167c478bd9Sstevel@tonic-gate if (res < 0)
7177c478bd9Sstevel@tonic-gate return (PICL_NOTREADABLE);
7187c478bd9Sstevel@tonic-gate *id = data.next_id;
7197c478bd9Sstevel@tonic-gate if ((data.sensor_status & ENVMON_NOT_PRESENT) != 0)
7207c478bd9Sstevel@tonic-gate return (PICL_INVALIDHANDLE);
7217c478bd9Sstevel@tonic-gate if (colour != NULL)
7227c478bd9Sstevel@tonic-gate *colour = data.led_color;
7237c478bd9Sstevel@tonic-gate if ((data.sensor_status & ENVMON_INACCESSIBLE) != 0) {
7247c478bd9Sstevel@tonic-gate return (PICL_PROPVALUNAVAILABLE);
7257c478bd9Sstevel@tonic-gate }
7267c478bd9Sstevel@tonic-gate if (state != NULL)
7277c478bd9Sstevel@tonic-gate *state = data.led_state;
7287c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
7297c478bd9Sstevel@tonic-gate }
7307c478bd9Sstevel@tonic-gate
7317c478bd9Sstevel@tonic-gate /*
7327c478bd9Sstevel@tonic-gate * Function to read key-switch position
7337c478bd9Sstevel@tonic-gate * Returns PICL_INVALIDHANDLE if ioctl not supported (or fails)
7347c478bd9Sstevel@tonic-gate */
7357c478bd9Sstevel@tonic-gate static int
get_keyswitch_data(int envmon_fd,envmon_handle_t * id,int cmd,envmon_keysw_pos_t * key_state)7367c478bd9Sstevel@tonic-gate get_keyswitch_data(int envmon_fd, envmon_handle_t *id, int cmd,
7377c478bd9Sstevel@tonic-gate envmon_keysw_pos_t *key_state)
7387c478bd9Sstevel@tonic-gate {
7397c478bd9Sstevel@tonic-gate int res;
7407c478bd9Sstevel@tonic-gate
7417c478bd9Sstevel@tonic-gate if (id->name[0] == '\0') {
7427c478bd9Sstevel@tonic-gate (void) strlcpy(id->name, KEYSWITCH_NAME, sizeof (id->name));
7437c478bd9Sstevel@tonic-gate return (PICL_INVALIDHANDLE);
7447c478bd9Sstevel@tonic-gate } else if (strncmp(id->name, KEYSWITCH_NAME, sizeof (id->name)) != 0) {
7457c478bd9Sstevel@tonic-gate id->name[0] = '\0';
7467c478bd9Sstevel@tonic-gate return (PICL_INVALIDHANDLE);
7477c478bd9Sstevel@tonic-gate } else {
7487c478bd9Sstevel@tonic-gate res = ioctl(envmon_fd, cmd, key_state);
7497c478bd9Sstevel@tonic-gate id->name[0] = '\0';
7507c478bd9Sstevel@tonic-gate
7517c478bd9Sstevel@tonic-gate if (res < 0)
7527c478bd9Sstevel@tonic-gate return (PICL_INVALIDHANDLE);
7537c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
7547c478bd9Sstevel@tonic-gate }
7557c478bd9Sstevel@tonic-gate }
7567c478bd9Sstevel@tonic-gate
7577c478bd9Sstevel@tonic-gate /*
758*06e46062Sjbeloro * Function to read the chassis serial number
759*06e46062Sjbeloro * Returns PICL_INVALIDHANDLE if ioctl not supported (or fails)
760*06e46062Sjbeloro */
761*06e46062Sjbeloro static int
get_serial_num(int envmon_fd,envmon_handle_t * id,int cmd,envmon_chassis_t * chassis)762*06e46062Sjbeloro get_serial_num(int envmon_fd, envmon_handle_t *id, int cmd,
763*06e46062Sjbeloro envmon_chassis_t *chassis)
764*06e46062Sjbeloro {
765*06e46062Sjbeloro int res;
766*06e46062Sjbeloro
767*06e46062Sjbeloro if (id->name[0] == '\0') {
768*06e46062Sjbeloro (void) strlcpy(id->name, CHASSIS_SERIAL_NUMBER,
769*06e46062Sjbeloro sizeof (id->name));
770*06e46062Sjbeloro return (PICL_INVALIDHANDLE);
771*06e46062Sjbeloro } else if (strncmp(id->name, CHASSIS_SERIAL_NUMBER, sizeof (id->name))
772*06e46062Sjbeloro != 0) {
773*06e46062Sjbeloro id->name[0] = '\0';
774*06e46062Sjbeloro return (PICL_INVALIDHANDLE);
775*06e46062Sjbeloro } else {
776*06e46062Sjbeloro res = ioctl(envmon_fd, cmd, chassis);
777*06e46062Sjbeloro id->name[0] = '\0';
778*06e46062Sjbeloro
779*06e46062Sjbeloro if (res < 0)
780*06e46062Sjbeloro return (PICL_INVALIDHANDLE);
781*06e46062Sjbeloro return (PICL_SUCCESS);
782*06e46062Sjbeloro }
783*06e46062Sjbeloro }
784*06e46062Sjbeloro
785*06e46062Sjbeloro /*
7867c478bd9Sstevel@tonic-gate * change to lower case and convert any spaces into hyphens,
7877c478bd9Sstevel@tonic-gate * and any dots or colons symbols into underscores
7887c478bd9Sstevel@tonic-gate */
7897c478bd9Sstevel@tonic-gate static void
convert_node_name(char * ptr)7907c478bd9Sstevel@tonic-gate convert_node_name(char *ptr)
7917c478bd9Sstevel@tonic-gate {
7927c478bd9Sstevel@tonic-gate char ch;
7937c478bd9Sstevel@tonic-gate
7947c478bd9Sstevel@tonic-gate for (ch = *ptr; ch != '\0'; ch = *++ptr) {
7957c478bd9Sstevel@tonic-gate if (isupper(ch)) {
7967c478bd9Sstevel@tonic-gate *ptr = tolower(ch);
7977c478bd9Sstevel@tonic-gate } else if (isspace(ch)) {
7987c478bd9Sstevel@tonic-gate *ptr = '-';
7997c478bd9Sstevel@tonic-gate } else if ((ch == '.') || (ch == ':')) {
8007c478bd9Sstevel@tonic-gate *ptr = '_';
8017c478bd9Sstevel@tonic-gate }
8027c478bd9Sstevel@tonic-gate }
8037c478bd9Sstevel@tonic-gate }
8047c478bd9Sstevel@tonic-gate
8057c478bd9Sstevel@tonic-gate /*
8067c478bd9Sstevel@tonic-gate * strip to the last '.' separator and keep the rest
8077c478bd9Sstevel@tonic-gate * change ':' to '/' within the last component
8087c478bd9Sstevel@tonic-gate */
8097c478bd9Sstevel@tonic-gate static void
convert_label_name(char * name)8107c478bd9Sstevel@tonic-gate convert_label_name(char *name)
8117c478bd9Sstevel@tonic-gate {
8127c478bd9Sstevel@tonic-gate const char *cptr;
8137c478bd9Sstevel@tonic-gate char ch;
8147c478bd9Sstevel@tonic-gate
8157c478bd9Sstevel@tonic-gate cptr = strrchr(name, '.');
8167c478bd9Sstevel@tonic-gate
8177c478bd9Sstevel@tonic-gate if (cptr == NULL)
8187c478bd9Sstevel@tonic-gate cptr = name;
8197c478bd9Sstevel@tonic-gate else
8207c478bd9Sstevel@tonic-gate cptr++; /* skip the '.' */
8217c478bd9Sstevel@tonic-gate
8227c478bd9Sstevel@tonic-gate do {
8237c478bd9Sstevel@tonic-gate ch = *cptr++;
8247c478bd9Sstevel@tonic-gate
8257c478bd9Sstevel@tonic-gate if (ch == ':')
8267c478bd9Sstevel@tonic-gate ch = '/';
8277c478bd9Sstevel@tonic-gate
8287c478bd9Sstevel@tonic-gate *name++ = ch;
8297c478bd9Sstevel@tonic-gate } while (ch != '\0');
8307c478bd9Sstevel@tonic-gate }
8317c478bd9Sstevel@tonic-gate
8327c478bd9Sstevel@tonic-gate /*
8337c478bd9Sstevel@tonic-gate * add a value property
8347c478bd9Sstevel@tonic-gate */
8357c478bd9Sstevel@tonic-gate static int
add_value_prop(picl_nodehdl_t node_hdl,const char * prop_name,int fru_type,int16_t value)8367c478bd9Sstevel@tonic-gate add_value_prop(picl_nodehdl_t node_hdl, const char *prop_name, int fru_type,
8377c478bd9Sstevel@tonic-gate int16_t value)
8387c478bd9Sstevel@tonic-gate {
8397c478bd9Sstevel@tonic-gate int err;
8407c478bd9Sstevel@tonic-gate union {
8417c478bd9Sstevel@tonic-gate float u_f;
8427c478bd9Sstevel@tonic-gate int16_t u_i16;
8437c478bd9Sstevel@tonic-gate } val_buf;
8447c478bd9Sstevel@tonic-gate
8457c478bd9Sstevel@tonic-gate if (fru_to_ptype[fru_type] == PICL_PTYPE_FLOAT)
8467c478bd9Sstevel@tonic-gate val_buf.u_f = (float)((float)value / (float)1000.0);
8477c478bd9Sstevel@tonic-gate else
8487c478bd9Sstevel@tonic-gate val_buf.u_i16 = value;
8497c478bd9Sstevel@tonic-gate
8507c478bd9Sstevel@tonic-gate err = add_regular_prop(node_hdl, prop_name, fru_to_ptype[fru_type],
8517c478bd9Sstevel@tonic-gate PICL_READ, fru_to_size[fru_type], &val_buf, NULL);
8527c478bd9Sstevel@tonic-gate return (err);
8537c478bd9Sstevel@tonic-gate }
8547c478bd9Sstevel@tonic-gate
8557c478bd9Sstevel@tonic-gate static int
find_picl_handle(picl_prophdl_t proph)8567c478bd9Sstevel@tonic-gate find_picl_handle(picl_prophdl_t proph)
8577c478bd9Sstevel@tonic-gate {
8587c478bd9Sstevel@tonic-gate int index;
8597c478bd9Sstevel@tonic-gate
8607c478bd9Sstevel@tonic-gate for (index = 0; index < handle_arr.num; index++) {
8617c478bd9Sstevel@tonic-gate if (handle_arr.piclprhdls[index] == proph)
8627c478bd9Sstevel@tonic-gate return (index);
8637c478bd9Sstevel@tonic-gate }
8647c478bd9Sstevel@tonic-gate
8657c478bd9Sstevel@tonic-gate return (-1);
8667c478bd9Sstevel@tonic-gate }
8677c478bd9Sstevel@tonic-gate
8687c478bd9Sstevel@tonic-gate /*
8697c478bd9Sstevel@tonic-gate * look up function to convert led status into string
8707c478bd9Sstevel@tonic-gate */
8717c478bd9Sstevel@tonic-gate static int
lookup_led_status(int8_t state,const char ** string)8727c478bd9Sstevel@tonic-gate lookup_led_status(int8_t state, const char **string)
8737c478bd9Sstevel@tonic-gate {
8747c478bd9Sstevel@tonic-gate int i;
8757c478bd9Sstevel@tonic-gate int lim = sizeof (ledstate_lkup) / sizeof (ledstate_lkup[0]);
8767c478bd9Sstevel@tonic-gate
8777c478bd9Sstevel@tonic-gate for (i = 0; i < lim; i++) {
8787c478bd9Sstevel@tonic-gate if (ledstate_lkup[i].state == state) {
8797c478bd9Sstevel@tonic-gate *string = ledstate_lkup[i].str_ledstate;
8807c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
8817c478bd9Sstevel@tonic-gate }
8827c478bd9Sstevel@tonic-gate }
8837c478bd9Sstevel@tonic-gate
8847c478bd9Sstevel@tonic-gate *string = "";
8857c478bd9Sstevel@tonic-gate return (PICL_PROPVALUNAVAILABLE);
8867c478bd9Sstevel@tonic-gate }
8877c478bd9Sstevel@tonic-gate
8887c478bd9Sstevel@tonic-gate static int
lookup_key_posn(envmon_keysw_pos_t pos,const char ** string)8897c478bd9Sstevel@tonic-gate lookup_key_posn(envmon_keysw_pos_t pos, const char **string)
8907c478bd9Sstevel@tonic-gate {
8917c478bd9Sstevel@tonic-gate int i;
8927c478bd9Sstevel@tonic-gate int lim = sizeof (keyposn_lkup) / sizeof (keyposn_lkup[0]);
8937c478bd9Sstevel@tonic-gate
8947c478bd9Sstevel@tonic-gate for (i = 0; i < lim; i++) {
8957c478bd9Sstevel@tonic-gate if (keyposn_lkup[i].pos == pos) {
8967c478bd9Sstevel@tonic-gate *string = keyposn_lkup[i].str_keyposn;
8977c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
8987c478bd9Sstevel@tonic-gate }
8997c478bd9Sstevel@tonic-gate }
9007c478bd9Sstevel@tonic-gate
9017c478bd9Sstevel@tonic-gate *string = "";
9027c478bd9Sstevel@tonic-gate return (PICL_PROPVALUNAVAILABLE);
9037c478bd9Sstevel@tonic-gate }
9047c478bd9Sstevel@tonic-gate
9057c478bd9Sstevel@tonic-gate /*
9067c478bd9Sstevel@tonic-gate * function to read volatile data associated with a PICL property handle
9077c478bd9Sstevel@tonic-gate */
9087c478bd9Sstevel@tonic-gate static int
read_vol_data(ptree_rarg_t * r_arg,void * buf)9097c478bd9Sstevel@tonic-gate read_vol_data(ptree_rarg_t *r_arg, void *buf)
9107c478bd9Sstevel@tonic-gate {
9117c478bd9Sstevel@tonic-gate picl_prophdl_t proph;
9127c478bd9Sstevel@tonic-gate int index;
9137c478bd9Sstevel@tonic-gate uint8_t fru_type;
9147c478bd9Sstevel@tonic-gate envmon_handle_t id;
9157c478bd9Sstevel@tonic-gate int16_t sensor_data;
9167c478bd9Sstevel@tonic-gate int8_t led_state;
9177c478bd9Sstevel@tonic-gate envmon_keysw_pos_t key_posn;
918*06e46062Sjbeloro envmon_chassis_t chassis;
9197c478bd9Sstevel@tonic-gate float float_data;
9207c478bd9Sstevel@tonic-gate int cmd;
9217c478bd9Sstevel@tonic-gate int err;
9227c478bd9Sstevel@tonic-gate int envmon_fd;
9237c478bd9Sstevel@tonic-gate const char *cptr;
9247c478bd9Sstevel@tonic-gate
9257c478bd9Sstevel@tonic-gate proph = r_arg->proph;
9267c478bd9Sstevel@tonic-gate index = find_picl_handle(proph);
9277c478bd9Sstevel@tonic-gate if (index < 0)
9287c478bd9Sstevel@tonic-gate return (PICL_INVALIDHANDLE);
9297c478bd9Sstevel@tonic-gate fru_type = handle_arr.fru_types[index];
9307c478bd9Sstevel@tonic-gate id = handle_arr.envhandles[index];
9317c478bd9Sstevel@tonic-gate cmd = fru_to_cmd[fru_type];
9327c478bd9Sstevel@tonic-gate envmon_fd = open(envmon_device_name, O_RDONLY);
9337c478bd9Sstevel@tonic-gate if (envmon_fd < 0)
9347c478bd9Sstevel@tonic-gate return (PICL_NOTREADABLE);
9357c478bd9Sstevel@tonic-gate
9367c478bd9Sstevel@tonic-gate /*
9377c478bd9Sstevel@tonic-gate * read environmental data according to type
9387c478bd9Sstevel@tonic-gate */
9397c478bd9Sstevel@tonic-gate switch (fru_type) {
9407c478bd9Sstevel@tonic-gate case ENVMON_VOLT_SENS:
9417c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/
9427c478bd9Sstevel@tonic-gate case ENVMON_AMP_SENS:
9437c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/
9447c478bd9Sstevel@tonic-gate case ENVMON_TEMP_SENS:
9457c478bd9Sstevel@tonic-gate err = get_sensor_data(envmon_fd, &id, cmd, NULL, NULL,
9467c478bd9Sstevel@tonic-gate &sensor_data);
9477c478bd9Sstevel@tonic-gate break;
9487c478bd9Sstevel@tonic-gate case ENVMON_VOLT_IND:
9497c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/
9507c478bd9Sstevel@tonic-gate case ENVMON_AMP_IND:
9517c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/
9527c478bd9Sstevel@tonic-gate case ENVMON_TEMP_IND:
9537c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/
9547c478bd9Sstevel@tonic-gate case ENVMON_FAN_IND:
9557c478bd9Sstevel@tonic-gate err = get_indicator_data(envmon_fd, &id, cmd, &sensor_data);
9567c478bd9Sstevel@tonic-gate break;
9577c478bd9Sstevel@tonic-gate case ENVMON_FAN_SENS:
9587c478bd9Sstevel@tonic-gate err = get_fan_data(envmon_fd, &id, cmd, NULL,
9597c478bd9Sstevel@tonic-gate (uint16_t *)&sensor_data, NULL);
9607c478bd9Sstevel@tonic-gate break;
9617c478bd9Sstevel@tonic-gate case ENVMON_LED_IND:
9627c478bd9Sstevel@tonic-gate err = get_led_data(envmon_fd, &id, cmd, &led_state, NULL);
9637c478bd9Sstevel@tonic-gate break;
9647c478bd9Sstevel@tonic-gate case ENVMON_KEY_SWITCH:
9657c478bd9Sstevel@tonic-gate err = get_keyswitch_data(envmon_fd, &id, cmd, &key_posn);
9667c478bd9Sstevel@tonic-gate break;
967*06e46062Sjbeloro case ENVMON_CHASSIS:
968*06e46062Sjbeloro err = get_serial_num(envmon_fd, &id, cmd, &chassis);
969*06e46062Sjbeloro break;
9707c478bd9Sstevel@tonic-gate default:
9717c478bd9Sstevel@tonic-gate err = PICL_FAILURE;
9727c478bd9Sstevel@tonic-gate break;
9737c478bd9Sstevel@tonic-gate }
9747c478bd9Sstevel@tonic-gate
9757c478bd9Sstevel@tonic-gate (void) close(envmon_fd);
9767c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
9777c478bd9Sstevel@tonic-gate /*
9787c478bd9Sstevel@tonic-gate * PICL_INVALIDHANDLE is used internally, but it upsets
9797c478bd9Sstevel@tonic-gate * prtpicl; change it to PICL_PROPVALUNAVAILABLE
9807c478bd9Sstevel@tonic-gate */
9817c478bd9Sstevel@tonic-gate if (err == PICL_INVALIDHANDLE)
9827c478bd9Sstevel@tonic-gate err = PICL_PROPVALUNAVAILABLE;
9837c478bd9Sstevel@tonic-gate return (err);
9847c478bd9Sstevel@tonic-gate }
9857c478bd9Sstevel@tonic-gate
9867c478bd9Sstevel@tonic-gate /*
9877c478bd9Sstevel@tonic-gate * convert data and copy out
9887c478bd9Sstevel@tonic-gate */
9897c478bd9Sstevel@tonic-gate switch (fru_type) {
9907c478bd9Sstevel@tonic-gate case ENVMON_VOLT_SENS:
9917c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/
9927c478bd9Sstevel@tonic-gate case ENVMON_AMP_SENS:
9937c478bd9Sstevel@tonic-gate float_data = (float)((float)sensor_data / (float)1000.0);
9947c478bd9Sstevel@tonic-gate (void) memcpy(buf, &float_data, sizeof (float_data));
9957c478bd9Sstevel@tonic-gate break;
9967c478bd9Sstevel@tonic-gate
9977c478bd9Sstevel@tonic-gate case ENVMON_TEMP_SENS:
9987c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/
9997c478bd9Sstevel@tonic-gate case ENVMON_FAN_SENS:
10007c478bd9Sstevel@tonic-gate (void) memcpy(buf, &sensor_data, sizeof (sensor_data));
10017c478bd9Sstevel@tonic-gate break;
10027c478bd9Sstevel@tonic-gate
10037c478bd9Sstevel@tonic-gate case ENVMON_VOLT_IND:
10047c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/
10057c478bd9Sstevel@tonic-gate case ENVMON_AMP_IND:
10067c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/
10077c478bd9Sstevel@tonic-gate case ENVMON_TEMP_IND:
10087c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/
10097c478bd9Sstevel@tonic-gate case ENVMON_FAN_IND:
10107c478bd9Sstevel@tonic-gate (void) strlcpy(buf, sensor_data == 0 ? cond_okay : cond_failed,
10117c478bd9Sstevel@tonic-gate fru_to_size[fru_type]);
10127c478bd9Sstevel@tonic-gate break;
10137c478bd9Sstevel@tonic-gate
10147c478bd9Sstevel@tonic-gate case ENVMON_LED_IND:
10157c478bd9Sstevel@tonic-gate err = lookup_led_status(led_state, &cptr);
10167c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
10177c478bd9Sstevel@tonic-gate return (err);
10187c478bd9Sstevel@tonic-gate (void) strlcpy(buf, cptr, fru_to_size[fru_type]);
10197c478bd9Sstevel@tonic-gate break;
10207c478bd9Sstevel@tonic-gate
10217c478bd9Sstevel@tonic-gate case ENVMON_KEY_SWITCH:
10227c478bd9Sstevel@tonic-gate err = lookup_key_posn(key_posn, &cptr);
10237c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
10247c478bd9Sstevel@tonic-gate return (err);
10257c478bd9Sstevel@tonic-gate (void) strlcpy(buf, cptr, fru_to_size[fru_type]);
10267c478bd9Sstevel@tonic-gate break;
1027*06e46062Sjbeloro case ENVMON_CHASSIS:
1028*06e46062Sjbeloro (void) memcpy(buf, chassis.serial_number,
1029*06e46062Sjbeloro sizeof (chassis.serial_number));
1030*06e46062Sjbeloro break;
10317c478bd9Sstevel@tonic-gate
10327c478bd9Sstevel@tonic-gate default:
10337c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
10347c478bd9Sstevel@tonic-gate }
10357c478bd9Sstevel@tonic-gate
10367c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
10377c478bd9Sstevel@tonic-gate }
10387c478bd9Sstevel@tonic-gate
10397c478bd9Sstevel@tonic-gate static int
write_led_data(ptree_warg_t * w_arg,const void * buf)10407c478bd9Sstevel@tonic-gate write_led_data(ptree_warg_t *w_arg, const void *buf)
10417c478bd9Sstevel@tonic-gate {
10427c478bd9Sstevel@tonic-gate picl_prophdl_t proph;
10437c478bd9Sstevel@tonic-gate int index;
10447c478bd9Sstevel@tonic-gate uint8_t fru_type;
10457c478bd9Sstevel@tonic-gate int err;
10467c478bd9Sstevel@tonic-gate int envmon_fd;
10477c478bd9Sstevel@tonic-gate envmon_led_ctl_t led_ctl;
10487c478bd9Sstevel@tonic-gate
10497c478bd9Sstevel@tonic-gate proph = w_arg->proph;
10507c478bd9Sstevel@tonic-gate index = find_picl_handle(proph);
10517c478bd9Sstevel@tonic-gate if (index < 0)
10527c478bd9Sstevel@tonic-gate return (PICL_INVALIDHANDLE);
10537c478bd9Sstevel@tonic-gate fru_type = handle_arr.fru_types[index];
10547c478bd9Sstevel@tonic-gate if (fru_type != ENVMON_LED_IND)
10557c478bd9Sstevel@tonic-gate return (PICL_INVALIDARG);
10567c478bd9Sstevel@tonic-gate if (w_arg->cred.dc_euid != SUPER_USER)
10577c478bd9Sstevel@tonic-gate return (PICL_PERMDENIED);
10587c478bd9Sstevel@tonic-gate
10597c478bd9Sstevel@tonic-gate /* see if the requested state is recognized */
10607c478bd9Sstevel@tonic-gate if (strcasecmp(str_Off, buf) == 0)
10617c478bd9Sstevel@tonic-gate led_ctl.led_state = ENVMON_LED_OFF;
10627c478bd9Sstevel@tonic-gate else if (strcasecmp(str_On, buf) == 0)
10637c478bd9Sstevel@tonic-gate led_ctl.led_state = ENVMON_LED_ON;
1064*06e46062Sjbeloro else if (strcasecmp(str_Blinking, buf) == 0)
1065*06e46062Sjbeloro led_ctl.led_state = ENVMON_LED_BLINKING;
1066*06e46062Sjbeloro else if (strcasecmp(str_Flashing, buf) == 0)
1067*06e46062Sjbeloro led_ctl.led_state = ENVMON_LED_FLASHING;
10687c478bd9Sstevel@tonic-gate else
10697c478bd9Sstevel@tonic-gate return (PICL_INVALIDARG);
10707c478bd9Sstevel@tonic-gate
10717c478bd9Sstevel@tonic-gate envmon_fd = open(envmon_device_name, O_RDWR);
10727c478bd9Sstevel@tonic-gate if (envmon_fd < 0)
10737c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
10747c478bd9Sstevel@tonic-gate led_ctl.id = handle_arr.envhandles[index];
10757c478bd9Sstevel@tonic-gate err = ioctl(envmon_fd, ENVMONIOCSETLED, &led_ctl);
10767c478bd9Sstevel@tonic-gate (void) close(envmon_fd);
10777c478bd9Sstevel@tonic-gate if (err < 0)
10787c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
10797c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
10807c478bd9Sstevel@tonic-gate }
10817c478bd9Sstevel@tonic-gate
10827c478bd9Sstevel@tonic-gate /*
10837c478bd9Sstevel@tonic-gate * if colour information is not supplied by the service processor,
10847c478bd9Sstevel@tonic-gate * try to determine led colour from the handle name.
10857c478bd9Sstevel@tonic-gate */
10867c478bd9Sstevel@tonic-gate static void
fix_led_colour(int8_t * colour_p,const char * id)10877c478bd9Sstevel@tonic-gate fix_led_colour(int8_t *colour_p, const char *id)
10887c478bd9Sstevel@tonic-gate {
10897c478bd9Sstevel@tonic-gate const char *cptr = strrchr(id, '.');
10907c478bd9Sstevel@tonic-gate
10917c478bd9Sstevel@tonic-gate if ((*colour_p < ENVMON_LED_CLR_NONE) ||
10927c478bd9Sstevel@tonic-gate (*colour_p > ENVMON_LED_CLR_RED))
10937c478bd9Sstevel@tonic-gate syslog(LOG_ERR, EM_INVALID_COLOR, *colour_p, id);
10947c478bd9Sstevel@tonic-gate if (cptr == NULL) {
10957c478bd9Sstevel@tonic-gate *colour_p = ENVMON_LED_CLR_NONE;
10967c478bd9Sstevel@tonic-gate return;
10977c478bd9Sstevel@tonic-gate }
10987c478bd9Sstevel@tonic-gate
10997c478bd9Sstevel@tonic-gate cptr++; /* step over '.' */
11007c478bd9Sstevel@tonic-gate
11017c478bd9Sstevel@tonic-gate if (strcmp(cptr, LED_ACT) == 0)
11027c478bd9Sstevel@tonic-gate *colour_p = ENVMON_LED_CLR_GREEN;
11037c478bd9Sstevel@tonic-gate else if (strcmp(cptr, LED_SERVICE) == 0)
11047c478bd9Sstevel@tonic-gate *colour_p = ENVMON_LED_CLR_AMBER;
11057c478bd9Sstevel@tonic-gate else if (strcmp(cptr, LED_LOCATE) == 0)
11067c478bd9Sstevel@tonic-gate *colour_p = ENVMON_LED_CLR_WHITE;
11077c478bd9Sstevel@tonic-gate else if (strcmp(cptr, LED_OK2RM) == 0)
11087c478bd9Sstevel@tonic-gate *colour_p = ENVMON_LED_CLR_BLUE;
11097c478bd9Sstevel@tonic-gate else
11107c478bd9Sstevel@tonic-gate *colour_p = ENVMON_LED_CLR_NONE;
11117c478bd9Sstevel@tonic-gate }
11127c478bd9Sstevel@tonic-gate
11137c478bd9Sstevel@tonic-gate /*
11147c478bd9Sstevel@tonic-gate * Add nodes for environmental devices of type fru_type
11157c478bd9Sstevel@tonic-gate * below the supplied node.
11167c478bd9Sstevel@tonic-gate */
11177c478bd9Sstevel@tonic-gate static int
add_env_nodes(int envmon_fd,uint8_t fru_type,picl_nodehdl_t envmonh)11187c478bd9Sstevel@tonic-gate add_env_nodes(int envmon_fd, uint8_t fru_type, picl_nodehdl_t envmonh)
11197c478bd9Sstevel@tonic-gate {
11207c478bd9Sstevel@tonic-gate envmon_handle_t id;
11217c478bd9Sstevel@tonic-gate envmon_thresholds_t lows;
11227c478bd9Sstevel@tonic-gate envmon_thresholds_t highs;
11237c478bd9Sstevel@tonic-gate char units[ENVMON_MAXNAMELEN];
11247c478bd9Sstevel@tonic-gate char platform_tree_name[ENVMON_MAXNAMELEN];
11257c478bd9Sstevel@tonic-gate char label_name[ENVMON_MAXNAMELEN];
11267c478bd9Sstevel@tonic-gate int16_t sensor_data;
11277c478bd9Sstevel@tonic-gate int8_t led_state;
11287c478bd9Sstevel@tonic-gate int8_t colour;
11297c478bd9Sstevel@tonic-gate envmon_keysw_pos_t key_state;
1130*06e46062Sjbeloro envmon_chassis_t chassis_num;
11317c478bd9Sstevel@tonic-gate int cmd;
11327c478bd9Sstevel@tonic-gate int err;
11337c478bd9Sstevel@tonic-gate int index = handle_arr.num;
11347c478bd9Sstevel@tonic-gate picl_nodehdl_t node_hdl;
11357c478bd9Sstevel@tonic-gate
11367c478bd9Sstevel@tonic-gate /*
11377c478bd9Sstevel@tonic-gate * catch table is full at start
11387c478bd9Sstevel@tonic-gate */
11397c478bd9Sstevel@tonic-gate if (index >= handle_arr.maxnum)
11407c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
11417c478bd9Sstevel@tonic-gate
11427c478bd9Sstevel@tonic-gate cmd = fru_to_cmd[fru_type];
11437c478bd9Sstevel@tonic-gate id.name[0] = '\0';
11447c478bd9Sstevel@tonic-gate
11457c478bd9Sstevel@tonic-gate do {
11467c478bd9Sstevel@tonic-gate lows.warning = lows.shutdown = lows.poweroff =
11477c478bd9Sstevel@tonic-gate ENVMON_VAL_UNAVAILABLE;
11487c478bd9Sstevel@tonic-gate highs.warning = highs.shutdown = highs.poweroff =
11497c478bd9Sstevel@tonic-gate ENVMON_VAL_UNAVAILABLE;
11507c478bd9Sstevel@tonic-gate handle_arr.fru_types[index] = fru_type;
11517c478bd9Sstevel@tonic-gate /* must store id before reading data as it is then updated */
11527c478bd9Sstevel@tonic-gate handle_arr.envhandles[index] = id;
11537c478bd9Sstevel@tonic-gate /*
11547c478bd9Sstevel@tonic-gate * read environmental data according to type
11557c478bd9Sstevel@tonic-gate */
11567c478bd9Sstevel@tonic-gate switch (fru_type) {
11577c478bd9Sstevel@tonic-gate case ENVMON_VOLT_SENS:
11587c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/
11597c478bd9Sstevel@tonic-gate case ENVMON_AMP_SENS:
11607c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/
11617c478bd9Sstevel@tonic-gate case ENVMON_TEMP_SENS:
11627c478bd9Sstevel@tonic-gate err = get_sensor_data(envmon_fd, &id, cmd, &lows,
11637c478bd9Sstevel@tonic-gate &highs, &sensor_data);
11647c478bd9Sstevel@tonic-gate break;
11657c478bd9Sstevel@tonic-gate case ENVMON_VOLT_IND:
11667c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/
11677c478bd9Sstevel@tonic-gate case ENVMON_AMP_IND:
11687c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/
11697c478bd9Sstevel@tonic-gate case ENVMON_TEMP_IND:
11707c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/
11717c478bd9Sstevel@tonic-gate case ENVMON_FAN_IND:
11727c478bd9Sstevel@tonic-gate err = get_indicator_data(envmon_fd, &id, cmd,
11737c478bd9Sstevel@tonic-gate &sensor_data);
11747c478bd9Sstevel@tonic-gate break;
11757c478bd9Sstevel@tonic-gate case ENVMON_FAN_SENS:
11767c478bd9Sstevel@tonic-gate err = get_fan_data(envmon_fd, &id, cmd, &lows,
11777c478bd9Sstevel@tonic-gate (uint16_t *)&sensor_data, units);
11787c478bd9Sstevel@tonic-gate break;
11797c478bd9Sstevel@tonic-gate case ENVMON_LED_IND:
11807c478bd9Sstevel@tonic-gate err = get_led_data(envmon_fd, &id, cmd, &led_state,
11817c478bd9Sstevel@tonic-gate &colour);
11827c478bd9Sstevel@tonic-gate break;
11837c478bd9Sstevel@tonic-gate case ENVMON_KEY_SWITCH:
11847c478bd9Sstevel@tonic-gate err = get_keyswitch_data(envmon_fd, &id, cmd,
11857c478bd9Sstevel@tonic-gate &key_state);
11867c478bd9Sstevel@tonic-gate break;
1187*06e46062Sjbeloro case ENVMON_CHASSIS:
1188*06e46062Sjbeloro err = get_serial_num(envmon_fd, &id, cmd,
1189*06e46062Sjbeloro &chassis_num);
1190*06e46062Sjbeloro break;
11917c478bd9Sstevel@tonic-gate default:
11927c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
11937c478bd9Sstevel@tonic-gate }
11947c478bd9Sstevel@tonic-gate
11957c478bd9Sstevel@tonic-gate if (err == PICL_INVALIDHANDLE)
11967c478bd9Sstevel@tonic-gate continue;
11977c478bd9Sstevel@tonic-gate if ((err != PICL_SUCCESS) && (err != PICL_PROPVALUNAVAILABLE)) {
11987c478bd9Sstevel@tonic-gate syslog(LOG_ERR, EM_NODE_ACCESS, id, fru_type, err);
11997c478bd9Sstevel@tonic-gate continue;
12007c478bd9Sstevel@tonic-gate }
12017c478bd9Sstevel@tonic-gate
12027c478bd9Sstevel@tonic-gate /*
12037c478bd9Sstevel@tonic-gate * successfully read environmental data, add to PICL
12047c478bd9Sstevel@tonic-gate */
12057c478bd9Sstevel@tonic-gate (void) strlcpy(platform_tree_name,
12067c478bd9Sstevel@tonic-gate handle_arr.envhandles[index].name,
12077c478bd9Sstevel@tonic-gate sizeof (platform_tree_name));
12087c478bd9Sstevel@tonic-gate
12097c478bd9Sstevel@tonic-gate (void) strlcpy(label_name, platform_tree_name,
12107c478bd9Sstevel@tonic-gate ENVMON_MAXNAMELEN);
12117c478bd9Sstevel@tonic-gate convert_label_name(label_name);
12127c478bd9Sstevel@tonic-gate convert_node_name(platform_tree_name);
12137c478bd9Sstevel@tonic-gate /*
12147c478bd9Sstevel@tonic-gate * does this node already exist?
12157c478bd9Sstevel@tonic-gate */
12167c478bd9Sstevel@tonic-gate err = get_child_by_name(envmonh, platform_tree_name, &node_hdl);
12177c478bd9Sstevel@tonic-gate if (err == PICL_SUCCESS) {
12187c478bd9Sstevel@tonic-gate /*
12197c478bd9Sstevel@tonic-gate * skip over existing node
12207c478bd9Sstevel@tonic-gate */
12217c478bd9Sstevel@tonic-gate continue;
12227c478bd9Sstevel@tonic-gate }
12237c478bd9Sstevel@tonic-gate err = ptree_create_node(platform_tree_name,
12247c478bd9Sstevel@tonic-gate fru_to_class[fru_type], &node_hdl);
12257c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
12267c478bd9Sstevel@tonic-gate break;
12277c478bd9Sstevel@tonic-gate }
12287c478bd9Sstevel@tonic-gate err = add_volatile_prop(node_hdl, fru_to_prop[fru_type],
12297c478bd9Sstevel@tonic-gate fru_to_ptype[fru_type],
12307c478bd9Sstevel@tonic-gate PICL_READ | (fru_type == ENVMON_LED_IND ? PICL_WRITE : 0),
12317c478bd9Sstevel@tonic-gate fru_to_size[fru_type], read_vol_data,
12327c478bd9Sstevel@tonic-gate fru_type == ENVMON_LED_IND ? write_led_data : NULL,
12337c478bd9Sstevel@tonic-gate &handle_arr.piclprhdls[index]);
12347c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
12357c478bd9Sstevel@tonic-gate break;
12367c478bd9Sstevel@tonic-gate }
1237*06e46062Sjbeloro
12387c478bd9Sstevel@tonic-gate /*
12397c478bd9Sstevel@tonic-gate * if any thresholds are defined add a property
12407c478bd9Sstevel@tonic-gate */
12417c478bd9Sstevel@tonic-gate if (lows.warning != ENVMON_VAL_UNAVAILABLE) {
12427c478bd9Sstevel@tonic-gate err = add_value_prop(node_hdl, PICL_PROP_LOW_WARNING,
12437c478bd9Sstevel@tonic-gate fru_type, lows.warning);
12447c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
12457c478bd9Sstevel@tonic-gate break;
12467c478bd9Sstevel@tonic-gate }
12477c478bd9Sstevel@tonic-gate }
12487c478bd9Sstevel@tonic-gate if (lows.shutdown != ENVMON_VAL_UNAVAILABLE) {
12497c478bd9Sstevel@tonic-gate err = add_value_prop(node_hdl, PICL_PROP_LOW_SHUTDOWN,
12507c478bd9Sstevel@tonic-gate fru_type, lows.shutdown);
12517c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
12527c478bd9Sstevel@tonic-gate break;
12537c478bd9Sstevel@tonic-gate }
12547c478bd9Sstevel@tonic-gate }
12557c478bd9Sstevel@tonic-gate if (lows.poweroff != ENVMON_VAL_UNAVAILABLE) {
12567c478bd9Sstevel@tonic-gate err = add_value_prop(node_hdl, PICL_PROP_LOW_POWER_OFF,
12577c478bd9Sstevel@tonic-gate fru_type, lows.poweroff);
12587c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
12597c478bd9Sstevel@tonic-gate break;
12607c478bd9Sstevel@tonic-gate }
12617c478bd9Sstevel@tonic-gate }
12627c478bd9Sstevel@tonic-gate if (highs.warning != ENVMON_VAL_UNAVAILABLE) {
12637c478bd9Sstevel@tonic-gate err = add_value_prop(node_hdl, PICL_PROP_HIGH_WARNING,
12647c478bd9Sstevel@tonic-gate fru_type, highs.warning);
12657c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
12667c478bd9Sstevel@tonic-gate break;
12677c478bd9Sstevel@tonic-gate }
12687c478bd9Sstevel@tonic-gate }
12697c478bd9Sstevel@tonic-gate if (highs.shutdown != ENVMON_VAL_UNAVAILABLE) {
12707c478bd9Sstevel@tonic-gate err = add_value_prop(node_hdl, PICL_PROP_HIGH_SHUTDOWN,
12717c478bd9Sstevel@tonic-gate fru_type, highs.shutdown);
12727c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
12737c478bd9Sstevel@tonic-gate break;
12747c478bd9Sstevel@tonic-gate }
12757c478bd9Sstevel@tonic-gate }
12767c478bd9Sstevel@tonic-gate if (highs.poweroff != ENVMON_VAL_UNAVAILABLE) {
12777c478bd9Sstevel@tonic-gate err = add_value_prop(node_hdl, PICL_PROP_HIGH_POWER_OFF,
12787c478bd9Sstevel@tonic-gate fru_type, highs.poweroff);
12797c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
12807c478bd9Sstevel@tonic-gate break;
12817c478bd9Sstevel@tonic-gate }
12827c478bd9Sstevel@tonic-gate }
12837c478bd9Sstevel@tonic-gate
12847c478bd9Sstevel@tonic-gate /*
12857c478bd9Sstevel@tonic-gate * if device is a fan sensor, add a speedunit property
12867c478bd9Sstevel@tonic-gate */
12877c478bd9Sstevel@tonic-gate if (fru_type == ENVMON_FAN_SENS) {
12887c478bd9Sstevel@tonic-gate err = add_regular_prop(node_hdl,
12897c478bd9Sstevel@tonic-gate PICL_PROP_FAN_SPEED_UNIT, PICL_PTYPE_CHARSTRING,
12907c478bd9Sstevel@tonic-gate PICL_READ, 1 + strlen(units), units, NULL);
12917c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
12927c478bd9Sstevel@tonic-gate break;
12937c478bd9Sstevel@tonic-gate }
12947c478bd9Sstevel@tonic-gate }
12957c478bd9Sstevel@tonic-gate /*
12967c478bd9Sstevel@tonic-gate * If device is a LED indicator and returns a colour,
12977c478bd9Sstevel@tonic-gate * add a colour property.
12987c478bd9Sstevel@tonic-gate */
12997c478bd9Sstevel@tonic-gate if (fru_type == ENVMON_LED_IND) {
13007c478bd9Sstevel@tonic-gate if (colour < 0 || colour == ENVMON_LED_CLR_ANY ||
13017c478bd9Sstevel@tonic-gate colour > ENVMON_LED_CLR_RED)
13027c478bd9Sstevel@tonic-gate fix_led_colour(&colour,
13037c478bd9Sstevel@tonic-gate handle_arr.envhandles[index].name);
13047c478bd9Sstevel@tonic-gate if (colour != ENVMON_LED_CLR_NONE) {
13057c478bd9Sstevel@tonic-gate err = add_regular_prop(node_hdl,
13067c478bd9Sstevel@tonic-gate PICL_PROP_COLOR, PICL_PTYPE_CHARSTRING,
13077c478bd9Sstevel@tonic-gate PICL_READ, colour_lkup[colour].size,
13087c478bd9Sstevel@tonic-gate colour_lkup[colour].str_colour, NULL);
13097c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
13107c478bd9Sstevel@tonic-gate break;
13117c478bd9Sstevel@tonic-gate }
13127c478bd9Sstevel@tonic-gate }
13137c478bd9Sstevel@tonic-gate }
13147c478bd9Sstevel@tonic-gate /*
1315*06e46062Sjbeloro * add a label property unless it's a keyswitch or the
1316*06e46062Sjbeloro * chassis serial number. keyswitch and chassis serial
1317*06e46062Sjbeloro * number are labelled from a config file because the
13187c478bd9Sstevel@tonic-gate * ALOM interface doesn't supply a name for it)
13197c478bd9Sstevel@tonic-gate */
1320*06e46062Sjbeloro if ((fru_type != ENVMON_KEY_SWITCH) &&
1321*06e46062Sjbeloro (fru_type != ENVMON_CHASSIS)) {
13227c478bd9Sstevel@tonic-gate err = add_regular_prop(node_hdl, PICL_PROP_LABEL,
13237c478bd9Sstevel@tonic-gate PICL_PTYPE_CHARSTRING, PICL_READ,
13247c478bd9Sstevel@tonic-gate 1 + strlen(label_name), label_name, NULL);
13257c478bd9Sstevel@tonic-gate
13267c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
13277c478bd9Sstevel@tonic-gate break;
13287c478bd9Sstevel@tonic-gate }
13297c478bd9Sstevel@tonic-gate }
13307c478bd9Sstevel@tonic-gate /*
13317c478bd9Sstevel@tonic-gate * all properties added to this node, add the node below
13327c478bd9Sstevel@tonic-gate * the supplied anchor point
13337c478bd9Sstevel@tonic-gate */
13347c478bd9Sstevel@tonic-gate err = ptree_add_node(envmonh, node_hdl);
13357c478bd9Sstevel@tonic-gate
13367c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
13377c478bd9Sstevel@tonic-gate break;
13387c478bd9Sstevel@tonic-gate }
13397c478bd9Sstevel@tonic-gate
13407c478bd9Sstevel@tonic-gate /*
13417c478bd9Sstevel@tonic-gate * that node went in OK, advance index
13427c478bd9Sstevel@tonic-gate */
13437c478bd9Sstevel@tonic-gate index++;
13447c478bd9Sstevel@tonic-gate
13457c478bd9Sstevel@tonic-gate } while ((id.name[0] != '\0') && (index < handle_arr.maxnum));
13467c478bd9Sstevel@tonic-gate
13477c478bd9Sstevel@tonic-gate handle_arr.num = index;
13487c478bd9Sstevel@tonic-gate return (err);
13497c478bd9Sstevel@tonic-gate }
13507c478bd9Sstevel@tonic-gate
13517c478bd9Sstevel@tonic-gate static void
fixstate(uint8_t state,const char * string,int * max_len)13527c478bd9Sstevel@tonic-gate fixstate(uint8_t state, const char *string, int *max_len)
13537c478bd9Sstevel@tonic-gate {
13547c478bd9Sstevel@tonic-gate int i;
13557c478bd9Sstevel@tonic-gate int len;
13567c478bd9Sstevel@tonic-gate
13577c478bd9Sstevel@tonic-gate for (i = 0; i < (sizeof (ledstate_lkup) / sizeof (ledstate_lkup[0]));
13587c478bd9Sstevel@tonic-gate i++) {
13597c478bd9Sstevel@tonic-gate if (ledstate_lkup[i].state == state) {
13607c478bd9Sstevel@tonic-gate if (ledstate_lkup[i].str_ledstate != NULL)
13617c478bd9Sstevel@tonic-gate free(ledstate_lkup[i].str_ledstate);
13627c478bd9Sstevel@tonic-gate ledstate_lkup[i].str_ledstate = strdup(string);
13637c478bd9Sstevel@tonic-gate len = strlen(string);
13647c478bd9Sstevel@tonic-gate if (len >= *max_len)
13657c478bd9Sstevel@tonic-gate *max_len = len + 1;
13667c478bd9Sstevel@tonic-gate break;
13677c478bd9Sstevel@tonic-gate }
13687c478bd9Sstevel@tonic-gate }
13697c478bd9Sstevel@tonic-gate }
13707c478bd9Sstevel@tonic-gate
13717c478bd9Sstevel@tonic-gate static void
fixkeyposn(envmon_keysw_pos_t keyposn,const char * string,int * max_len)13727c478bd9Sstevel@tonic-gate fixkeyposn(envmon_keysw_pos_t keyposn, const char *string, int *max_len)
13737c478bd9Sstevel@tonic-gate {
13747c478bd9Sstevel@tonic-gate int i;
13757c478bd9Sstevel@tonic-gate int len;
13767c478bd9Sstevel@tonic-gate
13777c478bd9Sstevel@tonic-gate for (i = 0; i < (sizeof (keyposn_lkup) / sizeof (keyposn_lkup[0]));
13787c478bd9Sstevel@tonic-gate i++) {
13797c478bd9Sstevel@tonic-gate if (keyposn_lkup[i].pos == keyposn) {
13807c478bd9Sstevel@tonic-gate if (keyposn_lkup[i].str_keyposn != NULL)
13817c478bd9Sstevel@tonic-gate free(keyposn_lkup[i].str_keyposn);
13827c478bd9Sstevel@tonic-gate keyposn_lkup[i].str_keyposn = strdup(string);
13837c478bd9Sstevel@tonic-gate len = strlen(string);
13847c478bd9Sstevel@tonic-gate if (len >= *max_len)
13857c478bd9Sstevel@tonic-gate *max_len = len + 1;
13867c478bd9Sstevel@tonic-gate break;
13877c478bd9Sstevel@tonic-gate }
13887c478bd9Sstevel@tonic-gate }
13897c478bd9Sstevel@tonic-gate }
13907c478bd9Sstevel@tonic-gate
13917c478bd9Sstevel@tonic-gate static void
setup_strings()13927c478bd9Sstevel@tonic-gate setup_strings()
13937c478bd9Sstevel@tonic-gate {
13947c478bd9Sstevel@tonic-gate int string_size;
13957c478bd9Sstevel@tonic-gate int i;
13967c478bd9Sstevel@tonic-gate int lim = sizeof (colour_lkup) / sizeof (colour_lkup[0]);
13977c478bd9Sstevel@tonic-gate
13987c478bd9Sstevel@tonic-gate /*
13997c478bd9Sstevel@tonic-gate * initialise led colours lookup
14007c478bd9Sstevel@tonic-gate */
14017c478bd9Sstevel@tonic-gate for (i = 0; i < lim; i++) {
14027c478bd9Sstevel@tonic-gate if (colour_lkup[i].str_colour != NULL)
14037c478bd9Sstevel@tonic-gate free(colour_lkup[i].str_colour);
14047c478bd9Sstevel@tonic-gate }
14057c478bd9Sstevel@tonic-gate
14067c478bd9Sstevel@tonic-gate colour_lkup[ENVMON_LED_CLR_ANY].str_colour = strdup(gettext("any"));
14077c478bd9Sstevel@tonic-gate colour_lkup[ENVMON_LED_CLR_WHITE].str_colour =
14087c478bd9Sstevel@tonic-gate strdup(gettext("white"));
14097c478bd9Sstevel@tonic-gate colour_lkup[ENVMON_LED_CLR_BLUE].str_colour = strdup(gettext("blue"));
14107c478bd9Sstevel@tonic-gate colour_lkup[ENVMON_LED_CLR_GREEN].str_colour =
14117c478bd9Sstevel@tonic-gate strdup(gettext("green"));
14127c478bd9Sstevel@tonic-gate colour_lkup[ENVMON_LED_CLR_AMBER].str_colour =
14137c478bd9Sstevel@tonic-gate strdup(gettext("amber"));
14147c478bd9Sstevel@tonic-gate colour_lkup[ENVMON_LED_CLR_RED].str_colour =
14157c478bd9Sstevel@tonic-gate strdup(gettext("red"));
14167c478bd9Sstevel@tonic-gate
14177c478bd9Sstevel@tonic-gate for (i = 0; i < lim; i++) {
14187c478bd9Sstevel@tonic-gate if (colour_lkup[i].str_colour != NULL)
14197c478bd9Sstevel@tonic-gate colour_lkup[i].size =
14207c478bd9Sstevel@tonic-gate 1 + strlen(colour_lkup[i].str_colour);
14217c478bd9Sstevel@tonic-gate }
14227c478bd9Sstevel@tonic-gate
14237c478bd9Sstevel@tonic-gate /*
14247c478bd9Sstevel@tonic-gate * initialise condition strings and note longest
14257c478bd9Sstevel@tonic-gate */
14267c478bd9Sstevel@tonic-gate string_size = 0;
14277c478bd9Sstevel@tonic-gate cond_okay = strdup(gettext("okay"));
14287c478bd9Sstevel@tonic-gate if (strlen(cond_okay) >= string_size)
14297c478bd9Sstevel@tonic-gate string_size = 1 + strlen(cond_okay);
14307c478bd9Sstevel@tonic-gate cond_failed = strdup(gettext("failed"));
14317c478bd9Sstevel@tonic-gate if (strlen(cond_failed) >= string_size)
14327c478bd9Sstevel@tonic-gate string_size = 1 + strlen(cond_failed);
14337c478bd9Sstevel@tonic-gate
14347c478bd9Sstevel@tonic-gate for (i = 0; i < sizeof (fru_to_size) / sizeof (fru_to_size[0]); i++)
14357c478bd9Sstevel@tonic-gate if (fru_to_size[i] == -1)
14367c478bd9Sstevel@tonic-gate fru_to_size[i] = string_size;
14377c478bd9Sstevel@tonic-gate
14387c478bd9Sstevel@tonic-gate /*
14397c478bd9Sstevel@tonic-gate * initialise led state lookup strings
14407c478bd9Sstevel@tonic-gate */
14417c478bd9Sstevel@tonic-gate string_size = 0;
14427c478bd9Sstevel@tonic-gate fixstate(ENVMON_LED_OFF, gettext("off"), &string_size);
14437c478bd9Sstevel@tonic-gate fixstate(ENVMON_LED_ON, gettext("on"), &string_size);
14447c478bd9Sstevel@tonic-gate fixstate(ENVMON_LED_BLINKING, gettext("blinking"), &string_size);
14457c478bd9Sstevel@tonic-gate fixstate(ENVMON_LED_FLASHING, gettext("flashing"), &string_size);
14467c478bd9Sstevel@tonic-gate fru_to_size[ENVMON_LED_IND] = string_size;
14477c478bd9Sstevel@tonic-gate
14487c478bd9Sstevel@tonic-gate /*
14497c478bd9Sstevel@tonic-gate * initialise key position lookup strings
14507c478bd9Sstevel@tonic-gate */
14517c478bd9Sstevel@tonic-gate string_size = 0;
14527c478bd9Sstevel@tonic-gate fixkeyposn(ENVMON_KEYSW_POS_UNKNOWN, gettext("UNKNOWN"), &string_size);
14537c478bd9Sstevel@tonic-gate fixkeyposn(ENVMON_KEYSW_POS_NORMAL, gettext("NORMAL"), &string_size);
14547c478bd9Sstevel@tonic-gate fixkeyposn(ENVMON_KEYSW_POS_DIAG, gettext("DIAG"), &string_size);
14557c478bd9Sstevel@tonic-gate fixkeyposn(ENVMON_KEYSW_POS_LOCKED, gettext("LOCKED"), &string_size);
14567c478bd9Sstevel@tonic-gate fixkeyposn(ENVMON_KEYSW_POS_OFF, gettext("STBY"), &string_size);
14577c478bd9Sstevel@tonic-gate fru_to_size[ENVMON_KEY_SWITCH] = string_size;
1458*06e46062Sjbeloro
1459*06e46062Sjbeloro /*
1460*06e46062Sjbeloro * initialise chassis serial number string
1461*06e46062Sjbeloro */
1462*06e46062Sjbeloro fru_to_size[ENVMON_CHASSIS] = ENVMON_MAXNAMELEN;
14637c478bd9Sstevel@tonic-gate }
14647c478bd9Sstevel@tonic-gate
14657c478bd9Sstevel@tonic-gate /*
14667c478bd9Sstevel@tonic-gate * The size of outfilename must be PATH_MAX
14677c478bd9Sstevel@tonic-gate */
14687c478bd9Sstevel@tonic-gate static int
get_config_file(char * filename)14697c478bd9Sstevel@tonic-gate get_config_file(char *filename)
14707c478bd9Sstevel@tonic-gate {
14717c478bd9Sstevel@tonic-gate char nmbuf[SYS_NMLN];
14727c478bd9Sstevel@tonic-gate char pname[PATH_MAX];
14737c478bd9Sstevel@tonic-gate
14747c478bd9Sstevel@tonic-gate if (sysinfo(SI_PLATFORM, nmbuf, sizeof (nmbuf)) != -1) {
14757c478bd9Sstevel@tonic-gate (void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf);
14767c478bd9Sstevel@tonic-gate (void) strlcat(pname, ENVMON_CONFFILE_NAME, PATH_MAX);
14777c478bd9Sstevel@tonic-gate if (access(pname, R_OK) == 0) {
14787c478bd9Sstevel@tonic-gate (void) strlcpy(filename, pname, PATH_MAX);
14797c478bd9Sstevel@tonic-gate return (0);
14807c478bd9Sstevel@tonic-gate }
14817c478bd9Sstevel@tonic-gate }
14827c478bd9Sstevel@tonic-gate
14837c478bd9Sstevel@tonic-gate if (sysinfo(SI_MACHINE, nmbuf, sizeof (nmbuf)) != -1) {
14847c478bd9Sstevel@tonic-gate (void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf);
14857c478bd9Sstevel@tonic-gate (void) strlcat(pname, ENVMON_CONFFILE_NAME, PATH_MAX);
14867c478bd9Sstevel@tonic-gate if (access(pname, R_OK) == 0) {
14877c478bd9Sstevel@tonic-gate (void) strlcpy(filename, pname, PATH_MAX);
14887c478bd9Sstevel@tonic-gate return (0);
14897c478bd9Sstevel@tonic-gate }
14907c478bd9Sstevel@tonic-gate }
14917c478bd9Sstevel@tonic-gate
14927c478bd9Sstevel@tonic-gate (void) snprintf(pname, PATH_MAX, "%s/%s",
14937c478bd9Sstevel@tonic-gate PICLD_COMMON_PLUGIN_DIR, ENVMON_CONFFILE_NAME);
14947c478bd9Sstevel@tonic-gate
14957c478bd9Sstevel@tonic-gate if (access(pname, R_OK) == 0) {
14967c478bd9Sstevel@tonic-gate (void) strlcpy(filename, pname, PATH_MAX);
14977c478bd9Sstevel@tonic-gate return (0);
14987c478bd9Sstevel@tonic-gate }
14997c478bd9Sstevel@tonic-gate
15007c478bd9Sstevel@tonic-gate return (-1);
15017c478bd9Sstevel@tonic-gate }
15027c478bd9Sstevel@tonic-gate
15037c478bd9Sstevel@tonic-gate static void
free_vol_prop(picl_prophdl_t proph)15047c478bd9Sstevel@tonic-gate free_vol_prop(picl_prophdl_t proph)
15057c478bd9Sstevel@tonic-gate {
15067c478bd9Sstevel@tonic-gate int index;
15077c478bd9Sstevel@tonic-gate
15087c478bd9Sstevel@tonic-gate index = find_picl_handle(proph);
15097c478bd9Sstevel@tonic-gate if (index >= 0) {
15107c478bd9Sstevel@tonic-gate handle_arr.num--;
15117c478bd9Sstevel@tonic-gate if (index != handle_arr.num) {
15127c478bd9Sstevel@tonic-gate /* relocate last entry into hole just created */
15137c478bd9Sstevel@tonic-gate handle_arr.fru_types[index] =
15147c478bd9Sstevel@tonic-gate handle_arr.fru_types[handle_arr.num];
15157c478bd9Sstevel@tonic-gate handle_arr.envhandles[index] =
15167c478bd9Sstevel@tonic-gate handle_arr.envhandles[handle_arr.num];
15177c478bd9Sstevel@tonic-gate handle_arr.piclprhdls[index] =
15187c478bd9Sstevel@tonic-gate handle_arr.piclprhdls[handle_arr.num];
15197c478bd9Sstevel@tonic-gate }
15207c478bd9Sstevel@tonic-gate }
15217c478bd9Sstevel@tonic-gate }
15227c478bd9Sstevel@tonic-gate
15237c478bd9Sstevel@tonic-gate /*
15247c478bd9Sstevel@tonic-gate * handle PICL FRU ADDED and FRU REMOVED events
15257c478bd9Sstevel@tonic-gate */
15267c478bd9Sstevel@tonic-gate /*ARGSUSED*/
15277c478bd9Sstevel@tonic-gate static void
envmon_evhandler(const char * ename,const void * earg,size_t size,void * cookie)15287c478bd9Sstevel@tonic-gate envmon_evhandler(const char *ename, const void *earg, size_t size,
15297c478bd9Sstevel@tonic-gate void *cookie)
15307c478bd9Sstevel@tonic-gate {
15317c478bd9Sstevel@tonic-gate char path[MAXPATHLEN];
15327c478bd9Sstevel@tonic-gate picl_nodehdl_t locnodeh;
15337c478bd9Sstevel@tonic-gate int retval;
15347c478bd9Sstevel@tonic-gate picl_nodehdl_t childh;
15357c478bd9Sstevel@tonic-gate picl_nodehdl_t nodeh;
15367c478bd9Sstevel@tonic-gate picl_prophdl_t tableh;
15377c478bd9Sstevel@tonic-gate picl_prophdl_t tblh;
15387c478bd9Sstevel@tonic-gate picl_prophdl_t proph;
15397c478bd9Sstevel@tonic-gate ptree_propinfo_t pi;
15407c478bd9Sstevel@tonic-gate
15417c478bd9Sstevel@tonic-gate if (strcmp(ename, PICL_FRU_ADDED) == 0) {
15427c478bd9Sstevel@tonic-gate retval = nvlist_lookup_uint64((nvlist_t *)earg,
15437c478bd9Sstevel@tonic-gate PICLEVENTARG_PARENTHANDLE, &locnodeh);
15447c478bd9Sstevel@tonic-gate
15457c478bd9Sstevel@tonic-gate if (retval != 0) {
15467c478bd9Sstevel@tonic-gate syslog(LOG_ERR, EM_EV_MISSING_ARG,
15477c478bd9Sstevel@tonic-gate PICLEVENTARG_PARENTHANDLE);
15487c478bd9Sstevel@tonic-gate return;
15497c478bd9Sstevel@tonic-gate }
15507c478bd9Sstevel@tonic-gate retval = ptree_get_propval_by_name(locnodeh, PICL_PROP_NAME,
15517c478bd9Sstevel@tonic-gate path, sizeof (path));
15527c478bd9Sstevel@tonic-gate if (retval == PICL_SUCCESS) {
15537c478bd9Sstevel@tonic-gate /*
15547c478bd9Sstevel@tonic-gate * Open envmon device and interrogate
15557c478bd9Sstevel@tonic-gate */
15567c478bd9Sstevel@tonic-gate int envmon_fd;
15577c478bd9Sstevel@tonic-gate int fru_type;
15587c478bd9Sstevel@tonic-gate picl_nodehdl_t envmoninfh;
15597c478bd9Sstevel@tonic-gate
15607c478bd9Sstevel@tonic-gate if (get_envmon_node(&envmoninfh) != PICL_SUCCESS) {
15617c478bd9Sstevel@tonic-gate syslog(LOG_ERR, EM_SC_NODE_MISSING);
15627c478bd9Sstevel@tonic-gate return;
15637c478bd9Sstevel@tonic-gate }
15647c478bd9Sstevel@tonic-gate
15657c478bd9Sstevel@tonic-gate if ((envmon_fd = open(envmon_device_name, O_RDONLY)) <
15667c478bd9Sstevel@tonic-gate 0) {
15677c478bd9Sstevel@tonic-gate syslog(LOG_ERR, EM_SYS_ERR, envmon_device_name,
15687c478bd9Sstevel@tonic-gate strerror(errno));
15697c478bd9Sstevel@tonic-gate return;
15707c478bd9Sstevel@tonic-gate }
15717c478bd9Sstevel@tonic-gate
15727c478bd9Sstevel@tonic-gate if (strcmp(str_SC, path) == 0) {
15737c478bd9Sstevel@tonic-gate /*
15747c478bd9Sstevel@tonic-gate * SC state change - re-assess platform tree
15757c478bd9Sstevel@tonic-gate */
15767c478bd9Sstevel@tonic-gate if (re_create_arrays(envmon_fd) != 0) {
15777c478bd9Sstevel@tonic-gate /*
15787c478bd9Sstevel@tonic-gate * out of memory - make no changes
15797c478bd9Sstevel@tonic-gate */
15807c478bd9Sstevel@tonic-gate return;
15817c478bd9Sstevel@tonic-gate }
15827c478bd9Sstevel@tonic-gate /*
15837c478bd9Sstevel@tonic-gate * dropped memory of volatile prop handles
15847c478bd9Sstevel@tonic-gate * so drop the nodes also, then rebuild for
15857c478bd9Sstevel@tonic-gate * the newly loaded SC
15867c478bd9Sstevel@tonic-gate */
15877c478bd9Sstevel@tonic-gate retval = ptree_get_propval_by_name(envmoninfh,
15887c478bd9Sstevel@tonic-gate PICL_PROP_PARENT, &nodeh, sizeof (nodeh));
15897c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) {
15907c478bd9Sstevel@tonic-gate (void) close(envmon_fd);
15917c478bd9Sstevel@tonic-gate return;
15927c478bd9Sstevel@tonic-gate }
15937c478bd9Sstevel@tonic-gate retval = ptree_get_propval_by_name(envmoninfh,
15947c478bd9Sstevel@tonic-gate PICL_PROP_NAME, path, sizeof (path));
15957c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) {
15967c478bd9Sstevel@tonic-gate (void) close(envmon_fd);
15977c478bd9Sstevel@tonic-gate return;
15987c478bd9Sstevel@tonic-gate }
15997c478bd9Sstevel@tonic-gate
16007c478bd9Sstevel@tonic-gate retval = ptree_delete_node(envmoninfh);
16017c478bd9Sstevel@tonic-gate if (retval == PICL_SUCCESS)
16027c478bd9Sstevel@tonic-gate (void) ptree_destroy_node(envmoninfh);
16037c478bd9Sstevel@tonic-gate retval = ptree_create_node(path,
16047c478bd9Sstevel@tonic-gate PICL_CLASS_SERVICE_PROCESSOR, &envmoninfh);
16057c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) {
16067c478bd9Sstevel@tonic-gate (void) close(envmon_fd);
16077c478bd9Sstevel@tonic-gate return;
16087c478bd9Sstevel@tonic-gate }
16097c478bd9Sstevel@tonic-gate retval = ptree_add_node(nodeh, envmoninfh);
16107c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) {
16117c478bd9Sstevel@tonic-gate (void) close(envmon_fd);
16127c478bd9Sstevel@tonic-gate return;
16137c478bd9Sstevel@tonic-gate }
16147c478bd9Sstevel@tonic-gate }
16157c478bd9Sstevel@tonic-gate
16167c478bd9Sstevel@tonic-gate for (fru_type = 0; fru_type < ENVMONTYPES;
16177c478bd9Sstevel@tonic-gate fru_type++) {
16187c478bd9Sstevel@tonic-gate (void) add_env_nodes(envmon_fd, fru_type,
16197c478bd9Sstevel@tonic-gate envmoninfh);
16207c478bd9Sstevel@tonic-gate }
16217c478bd9Sstevel@tonic-gate
16227c478bd9Sstevel@tonic-gate (void) close(envmon_fd);
16237c478bd9Sstevel@tonic-gate }
16247c478bd9Sstevel@tonic-gate } else if (strcmp(ename, PICL_FRU_REMOVED) == 0) {
16257c478bd9Sstevel@tonic-gate retval = nvlist_lookup_uint64((nvlist_t *)earg,
16267c478bd9Sstevel@tonic-gate PICLEVENTARG_FRUHANDLE, &childh);
16277c478bd9Sstevel@tonic-gate
16287c478bd9Sstevel@tonic-gate if (retval != 0) {
16297c478bd9Sstevel@tonic-gate syslog(LOG_ERR, EM_EV_MISSING_ARG,
16307c478bd9Sstevel@tonic-gate PICLEVENTARG_FRUHANDLE);
16317c478bd9Sstevel@tonic-gate return;
16327c478bd9Sstevel@tonic-gate }
16337c478bd9Sstevel@tonic-gate retval = ptree_get_propval_by_name(childh, PICL_PROP_NAME,
16347c478bd9Sstevel@tonic-gate path, sizeof (path));
16357c478bd9Sstevel@tonic-gate if (retval == PICL_SUCCESS) {
16367c478bd9Sstevel@tonic-gate retval = ptree_get_prop_by_name(childh,
16377c478bd9Sstevel@tonic-gate PICL_PROP_DEVICES, &tableh);
16387c478bd9Sstevel@tonic-gate
16397c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) {
16407c478bd9Sstevel@tonic-gate /* no Devices table, nothing to do */
16417c478bd9Sstevel@tonic-gate return;
16427c478bd9Sstevel@tonic-gate }
16437c478bd9Sstevel@tonic-gate
16447c478bd9Sstevel@tonic-gate /*
16457c478bd9Sstevel@tonic-gate * follow all reference properties in the second
16467c478bd9Sstevel@tonic-gate * column of the table and delete the referenced node
16477c478bd9Sstevel@tonic-gate */
16487c478bd9Sstevel@tonic-gate retval = ptree_get_propval(tableh, &tblh,
16497c478bd9Sstevel@tonic-gate sizeof (tblh));
16507c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) {
16517c478bd9Sstevel@tonic-gate /*
16527c478bd9Sstevel@tonic-gate * can't get value of table property
16537c478bd9Sstevel@tonic-gate */
16547c478bd9Sstevel@tonic-gate return;
16557c478bd9Sstevel@tonic-gate }
16567c478bd9Sstevel@tonic-gate /* get first col, first row */
16577c478bd9Sstevel@tonic-gate retval = ptree_get_next_by_col(tblh, &tblh);
16587c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) {
16597c478bd9Sstevel@tonic-gate /*
16607c478bd9Sstevel@tonic-gate * no rows?
16617c478bd9Sstevel@tonic-gate */
16627c478bd9Sstevel@tonic-gate return;
16637c478bd9Sstevel@tonic-gate }
16647c478bd9Sstevel@tonic-gate /*
16657c478bd9Sstevel@tonic-gate * starting at next col, get every entry in the column
16667c478bd9Sstevel@tonic-gate */
16677c478bd9Sstevel@tonic-gate for (retval = ptree_get_next_by_row(tblh, &tblh);
16687c478bd9Sstevel@tonic-gate retval == PICL_SUCCESS;
16697c478bd9Sstevel@tonic-gate retval = ptree_get_next_by_col(tblh, &tblh)) {
16707c478bd9Sstevel@tonic-gate /*
16717c478bd9Sstevel@tonic-gate * should be a ref prop in our hands,
16727c478bd9Sstevel@tonic-gate * get the target node handle
16737c478bd9Sstevel@tonic-gate */
16747c478bd9Sstevel@tonic-gate retval = ptree_get_propval(tblh, &nodeh,
16757c478bd9Sstevel@tonic-gate sizeof (nodeh));
16767c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) {
16777c478bd9Sstevel@tonic-gate continue;
16787c478bd9Sstevel@tonic-gate }
16797c478bd9Sstevel@tonic-gate /*
16807c478bd9Sstevel@tonic-gate * got the referenced node, has it got a
16817c478bd9Sstevel@tonic-gate * volatile property to clean up?
16827c478bd9Sstevel@tonic-gate */
16837c478bd9Sstevel@tonic-gate retval = ptree_get_first_prop(nodeh, &proph);
16847c478bd9Sstevel@tonic-gate while (retval == PICL_SUCCESS) {
16857c478bd9Sstevel@tonic-gate retval = ptree_get_propinfo(proph, &pi);
16867c478bd9Sstevel@tonic-gate if ((retval == PICL_SUCCESS) &&
16877c478bd9Sstevel@tonic-gate (pi.piclinfo.accessmode &
16887c478bd9Sstevel@tonic-gate PICL_VOLATILE))
16897c478bd9Sstevel@tonic-gate free_vol_prop(proph);
16907c478bd9Sstevel@tonic-gate retval = ptree_get_next_prop(proph,
16917c478bd9Sstevel@tonic-gate &proph);
16927c478bd9Sstevel@tonic-gate }
16937c478bd9Sstevel@tonic-gate /*
16947c478bd9Sstevel@tonic-gate * all volatile properties gone, remove node
16957c478bd9Sstevel@tonic-gate */
16967c478bd9Sstevel@tonic-gate retval = ptree_delete_node(nodeh);
16977c478bd9Sstevel@tonic-gate if (retval == PICL_SUCCESS)
16987c478bd9Sstevel@tonic-gate (void) ptree_destroy_node(nodeh);
16997c478bd9Sstevel@tonic-gate }
17007c478bd9Sstevel@tonic-gate }
17017c478bd9Sstevel@tonic-gate }
17027c478bd9Sstevel@tonic-gate }
17037c478bd9Sstevel@tonic-gate
17047c478bd9Sstevel@tonic-gate /*
17057c478bd9Sstevel@tonic-gate * executed as part of .init when the plugin is dlopen()ed
17067c478bd9Sstevel@tonic-gate */
17077c478bd9Sstevel@tonic-gate static void
piclenvmon_register(void)17087c478bd9Sstevel@tonic-gate piclenvmon_register(void)
17097c478bd9Sstevel@tonic-gate {
17107c478bd9Sstevel@tonic-gate (void) picld_plugin_register(&my_reg_info);
17117c478bd9Sstevel@tonic-gate }
17127c478bd9Sstevel@tonic-gate
17137c478bd9Sstevel@tonic-gate /*
17147c478bd9Sstevel@tonic-gate * Init entry point of the plugin
17157c478bd9Sstevel@tonic-gate * Creates the PICL nodes and properties in the physical and logical aspects.
17167c478bd9Sstevel@tonic-gate */
17177c478bd9Sstevel@tonic-gate static void
piclenvmon_init(void)17187c478bd9Sstevel@tonic-gate piclenvmon_init(void)
17197c478bd9Sstevel@tonic-gate {
17207c478bd9Sstevel@tonic-gate picl_nodehdl_t rooth;
17217c478bd9Sstevel@tonic-gate picl_nodehdl_t plfh;
17227c478bd9Sstevel@tonic-gate picl_nodehdl_t envmoninfh;
17237c478bd9Sstevel@tonic-gate int res;
17247c478bd9Sstevel@tonic-gate int envmon_fd;
17257c478bd9Sstevel@tonic-gate int fru_type;
17267c478bd9Sstevel@tonic-gate char pathname[PATH_MAX];
17277c478bd9Sstevel@tonic-gate
17287c478bd9Sstevel@tonic-gate /*
17297c478bd9Sstevel@tonic-gate * locate and parse config file
17307c478bd9Sstevel@tonic-gate */
17317c478bd9Sstevel@tonic-gate if (get_config_file(pathname) < 0)
17327c478bd9Sstevel@tonic-gate return;
17337c478bd9Sstevel@tonic-gate
17347c478bd9Sstevel@tonic-gate if ((ptree_get_root(&rooth) != PICL_SUCCESS) ||
17357c478bd9Sstevel@tonic-gate (picld_pluginutil_parse_config_file(rooth, pathname) !=
17367c478bd9Sstevel@tonic-gate PICL_SUCCESS)) {
17377c478bd9Sstevel@tonic-gate syslog(LOG_ERR, EM_INIT_FAILED);
17387c478bd9Sstevel@tonic-gate }
17397c478bd9Sstevel@tonic-gate
17407c478bd9Sstevel@tonic-gate /*
17417c478bd9Sstevel@tonic-gate * Get platform node
17427c478bd9Sstevel@tonic-gate */
17437c478bd9Sstevel@tonic-gate if (ptree_get_node_by_path(PICL_NODE_ROOT PICL_NODE_PLATFORM, &plfh)
17447c478bd9Sstevel@tonic-gate != PICL_SUCCESS) {
17457c478bd9Sstevel@tonic-gate syslog(LOG_ERR, EM_MISSING_NODE, PICL_NODE_PLATFORM);
17467c478bd9Sstevel@tonic-gate syslog(LOG_ERR, EM_INIT_FAILED);
17477c478bd9Sstevel@tonic-gate return;
17487c478bd9Sstevel@tonic-gate }
17497c478bd9Sstevel@tonic-gate
17507c478bd9Sstevel@tonic-gate /*
17517c478bd9Sstevel@tonic-gate * Get service-processor node
17527c478bd9Sstevel@tonic-gate */
17537c478bd9Sstevel@tonic-gate if (get_envmon_node(&envmoninfh) != PICL_SUCCESS)
17547c478bd9Sstevel@tonic-gate return;
17557c478bd9Sstevel@tonic-gate
17567c478bd9Sstevel@tonic-gate /*
17577c478bd9Sstevel@tonic-gate * We may have been restarted, make sure we don't leak
17587c478bd9Sstevel@tonic-gate */
17597c478bd9Sstevel@tonic-gate if (envmon_device_name != NULL) {
17607c478bd9Sstevel@tonic-gate free(envmon_device_name);
17617c478bd9Sstevel@tonic-gate }
17627c478bd9Sstevel@tonic-gate
17637c478bd9Sstevel@tonic-gate if ((envmon_device_name = create_envmon_pathname(envmoninfh)) == NULL)
17647c478bd9Sstevel@tonic-gate return;
17657c478bd9Sstevel@tonic-gate
17667c478bd9Sstevel@tonic-gate /*
17677c478bd9Sstevel@tonic-gate * Open envmon device and interrogate for devices it monitors
17687c478bd9Sstevel@tonic-gate */
17697c478bd9Sstevel@tonic-gate if ((envmon_fd = open(envmon_device_name, O_RDONLY)) < 0) {
17707c478bd9Sstevel@tonic-gate syslog(LOG_ERR, EM_SYS_ERR, envmon_device_name,
17717c478bd9Sstevel@tonic-gate strerror(errno));
17727c478bd9Sstevel@tonic-gate return;
17737c478bd9Sstevel@tonic-gate }
17747c478bd9Sstevel@tonic-gate
17757c478bd9Sstevel@tonic-gate if (get_envmon_limits(envmon_fd, &env_limits) < 0)
17767c478bd9Sstevel@tonic-gate return;
17777c478bd9Sstevel@tonic-gate
17787c478bd9Sstevel@tonic-gate /*
17797c478bd9Sstevel@tonic-gate * A set of arrays are used whose bounds are determined by the
17807c478bd9Sstevel@tonic-gate * response to get_envmon_limits. Establish these arrays now.
17817c478bd9Sstevel@tonic-gate */
17827c478bd9Sstevel@tonic-gate create_arrays();
17837c478bd9Sstevel@tonic-gate setup_strings();
17847c478bd9Sstevel@tonic-gate
17857c478bd9Sstevel@tonic-gate for (fru_type = 0; fru_type < ENVMONTYPES; fru_type++) {
17867c478bd9Sstevel@tonic-gate (void) add_env_nodes(envmon_fd, fru_type, envmoninfh);
17877c478bd9Sstevel@tonic-gate }
17887c478bd9Sstevel@tonic-gate
17897c478bd9Sstevel@tonic-gate (void) close(envmon_fd);
17907c478bd9Sstevel@tonic-gate
17917c478bd9Sstevel@tonic-gate res = ptree_register_handler(PICL_FRU_ADDED, envmon_evhandler, NULL);
17927c478bd9Sstevel@tonic-gate if (res != PICL_SUCCESS) {
17937c478bd9Sstevel@tonic-gate syslog(LOG_ERR, EM_EVREG_FAILED, res);
17947c478bd9Sstevel@tonic-gate }
17957c478bd9Sstevel@tonic-gate res = ptree_register_handler(PICL_FRU_REMOVED, envmon_evhandler, NULL);
17967c478bd9Sstevel@tonic-gate if (res != PICL_SUCCESS) {
17977c478bd9Sstevel@tonic-gate syslog(LOG_ERR, EM_EVREG_FAILED, res);
17987c478bd9Sstevel@tonic-gate }
17997c478bd9Sstevel@tonic-gate }
18007c478bd9Sstevel@tonic-gate
18017c478bd9Sstevel@tonic-gate /*
18027c478bd9Sstevel@tonic-gate * fini entry point of the plugin
18037c478bd9Sstevel@tonic-gate */
18047c478bd9Sstevel@tonic-gate static void
piclenvmon_fini(void)18057c478bd9Sstevel@tonic-gate piclenvmon_fini(void)
18067c478bd9Sstevel@tonic-gate {
18077c478bd9Sstevel@tonic-gate if (envmon_device_name != NULL) {
18087c478bd9Sstevel@tonic-gate free(envmon_device_name);
18097c478bd9Sstevel@tonic-gate envmon_device_name = NULL;
18107c478bd9Sstevel@tonic-gate }
18117c478bd9Sstevel@tonic-gate (void) ptree_unregister_handler(PICL_FRU_ADDED,
18127c478bd9Sstevel@tonic-gate envmon_evhandler, NULL);
18137c478bd9Sstevel@tonic-gate (void) ptree_unregister_handler(PICL_FRU_REMOVED,
18147c478bd9Sstevel@tonic-gate envmon_evhandler, NULL);
18157c478bd9Sstevel@tonic-gate }
1816