4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
32 #include <sys/systeminfo.h>
40 #include <sys/param.h>
41 #include <sys/types.h>
47 #include <libnvpair.h>
51 #include "piclenvmond.h"
54 /* external functions */
55 extern picl_errno_t
env_platmod_init();
56 extern void env_platmod_handle_event(const char *, const void *, size_t);
57 extern picl_errno_t
env_platmod_create_sensors();
58 extern picl_errno_t
env_platmod_setup_hotswap();
59 extern picl_errno_t
env_platmod_sp_monitor();
60 extern picl_errno_t
env_platmod_handle_bus_if_change(uint8_t);
61 extern picl_errno_t
env_platmod_handle_latch_open();
62 extern void env_platmod_handle_sensor_event(void *);
63 extern int process_platmod_sp_state_change_notif(void *);
64 extern int process_platmod_change_cpu_node_state(void *);
65 extern int process_platmod_change_cpci_state(void *);
66 extern int process_platmod_async_msg_notif(void *);
67 extern void process_platmod_sp_heartbeat(uint8_t);
68 extern picl_errno_t
env_platmod_create_hotswap_prop();
69 extern picl_errno_t
env_create_property(int ptype
, int pmode
,
70 size_t psize
, char *pname
, int (*readfn
)(ptree_rarg_t
*, void *),
71 int (*writefn
)(ptree_warg_t
*, const void *),
72 picl_nodehdl_t nodeh
, picl_prophdl_t
*propp
, void *vbuf
);
73 extern char *strtok_r(char *s1
, const char *s2
, char **lasts
);
75 /* external variables */
78 static char sys_name
[SYS_NMLN
];
79 static char chassisconf_name
[SYS_NMLN
];
80 static boolean_t parse_config_file
= B_FALSE
;
81 static int8_t alarm_check_interval
= -1;
82 static picl_nodehdl_t frutreeh
= 0;
83 static pthread_t polling_threadID
;
84 static boolean_t create_polling_thr
= B_TRUE
;
87 uint8_t cpu_geo_addr
= 0;
88 picl_nodehdl_t rooth
= 0, chassis_nodehdl
= 0, cpu_nodehdl
= 0;
89 picl_nodehdl_t platformh
= 0, sysmgmth
= 0, cpu_lnodehdl
= 0;
92 * envmond policy structure
94 typedef struct _policy
{
98 struct _policy
*nextp
;
102 * read_policy_configuration - extract info. from the envmond.conf
105 env_read_policy_configuration(char *conffile
, env_policy_t
**policypp
)
108 char buf
[RECORD_MAXSIZE
];
110 env_policy_t
*policyp
;
112 if ((fp
= fopen(conffile
, "r")) == NULL
) {
115 while (fgets(buf
, sizeof (buf
), fp
) != NULL
) {
116 if (buf
[0] && (buf
[0] == '#' || buf
[0] == '\n')) {
119 token
= (char *)strtok_r(buf
, RECORD_WHITESPACE
, &lasts
);
123 policyp
= (env_policy_t
*)malloc(sizeof (env_policy_t
));
124 if (policyp
== NULL
) {
127 policyp
->interval
= (uint8_t)strtoul(token
, NULL
, 0);
128 token
= (char *)strtok_r(lasts
, RECORD_WHITESPACE
, &lasts
);
132 policyp
->pname
= strdup(token
);
133 if (NULL
== policyp
->pname
) {
138 policyp
->argp
= strdup(lasts
);
139 if (policyp
->argp
== NULL
) {
143 policyp
->argp
= NULL
;
145 policyp
->nextp
= *policypp
;
155 *policypp
= (*policypp
)->nextp
;
156 free(policyp
->pname
);
164 * supports environmental policies
167 env_parse_config_file()
169 char conffile
[MAXPATHLEN
];
170 env_policy_t
*policyp
, *tmp
;
173 if (parse_config_file
== B_FALSE
) {
176 (void) snprintf(conffile
, sizeof (conffile
), ENV_CONFIG_FILE
,
178 bzero(&st
, sizeof (st
));
179 if (stat(conffile
, &st
) == -1) {
184 if (env_read_policy_configuration(conffile
, &policyp
) == -1) {
191 policyp
= policyp
->nextp
;
192 if (strcmp(tmp
->pname
, SERVICE_PROCESSOR
) == 0) {
193 alarm_check_interval
= tmp
->interval
;
194 if (env_debug
& DEBUG
)
195 syslog(LOG_INFO
, "Alarm Heartbeat frequency: "
196 "%d seconds", alarm_check_interval
);
205 * detects the presence of RTM for CPU board
214 req_pkt
.data
[0] = ENV_RTM_BUS_ID
;
215 req_pkt
.data
[1] = ENV_RTM_SLAVE_ADDR
;
216 req_pkt
.data
[2] = ENV_RTM_READ_SIZE
;
217 size
= ENV_RTM_PKT_LEN
;
219 /* initialize the request packet */
220 (void) smc_init_smc_msg(&req_pkt
, SMC_MASTER_RW_CMD
,
223 /* make a call to smc library to send cmd */
224 if (smc_send_msg(DEFAULT_FD
, &req_pkt
, &rsp_pkt
,
225 POLL_TIMEOUT
) != SMC_SUCCESS
) {
232 * this routine does the following:
233 * 1. initializes the CPU geo-addr
234 * 2. gets the system name
235 * 3. create the chassis type property
236 * 4. creates the conf_file property
245 char conf_name
[PICL_PROPNAMELEN_MAX
];
247 /* get the geo_addr */
248 /* initialize the request packet */
249 (void) smc_init_smc_msg(&req_pkt
, SMC_GET_GEOGRAPHICAL_ADDRESS
,
252 /* make a call to smc library to send cmd */
253 if (smc_send_msg(DEFAULT_FD
, &req_pkt
, &rsp_pkt
,
254 POLL_TIMEOUT
) != SMC_SUCCESS
) {
255 return (PICL_FAILURE
);
257 cpu_geo_addr
= rsp_pkt
.data
[0];
259 /* get the system name */
260 if (sysinfo(SI_PLATFORM
, sys_name
, sizeof (sys_name
)) == -1) {
261 return (PICL_FAILURE
);
263 (void) strncpy(chassisconf_name
, sys_name
,
264 sizeof (chassisconf_name
));
266 /* initialize the node handles */
267 if ((rc
= ptree_get_root(&rooth
)) != PICL_SUCCESS
) {
271 if ((rc
= ptree_get_node_by_path(FRUTREE_PATH
, &frutreeh
)) !=
276 if ((rc
= ptree_get_node_by_path(PICL_FRUTREE_CHASSIS
,
277 &chassis_nodehdl
)) != PICL_SUCCESS
) {
281 /* create the chassis type property */
282 if ((rc
= env_create_property(PICL_PTYPE_CHARSTRING
,
283 PICL_READ
, PICL_PROPNAMELEN_MAX
, PICL_PROP_CHASSIS_TYPE
,
284 NULLREAD
, NULLWRITE
, chassis_nodehdl
, (picl_prophdl_t
*)NULL
,
285 chassisconf_name
)) != PICL_SUCCESS
) {
290 * create dummy prop to inform frutree plugin abt conf file
291 * (rtm based or w/o rtm)
292 * frutree plugin removes this prop after reading the value
294 if (is_rtm_present() == B_TRUE
) {
295 (void) snprintf(conf_name
, sizeof (conf_name
),
296 "%s.RTM.conf", chassisconf_name
);
298 (void) snprintf(conf_name
, sizeof (conf_name
),
299 "%s.conf", chassisconf_name
);
302 if ((rc
= env_create_property(PICL_PTYPE_CHARSTRING
,
303 PICL_READ
, PICL_PROPNAMELEN_MAX
, PICL_PROP_CONF_FILE
, NULLREAD
,
304 NULLWRITE
, chassis_nodehdl
, (picl_prophdl_t
*)NULL
,
305 conf_name
)) != PICL_SUCCESS
) {
308 return (PICL_SUCCESS
);
317 picl_errno_t rc
= PICL_SUCCESS
;
319 if ((rc
= env_set_cpu_info()) != PICL_SUCCESS
) {
323 /* parse the configuration file */
324 env_parse_config_file();
327 * do any platform specific intialization if required
328 * IMPORTANT: must post dr_incoming resource event on
329 * chassis after doing all the reqd checks
331 rc
= env_platmod_init();
336 * sets smc global enables
339 env_set_smc_global_enables(boolean_t ipmi_enable
)
345 /* initialize the request packet */
346 (void) smc_init_smc_msg(&req_pkt
, SMC_GET_GLOBAL_ENABLES
,
349 /* make a call to smc library to send cmd */
350 if (smc_send_msg(DEFAULT_FD
, &req_pkt
, &rsp_pkt
,
351 POLL_TIMEOUT
) != SMC_SUCCESS
) {
355 req_pkt
.data
[0] = rsp_pkt
.data
[0];
356 req_pkt
.data
[1] = rsp_pkt
.data
[1];
358 req_pkt
.data
[1] |= ENV_IPMI_ENABLE_MASK
;
359 req_pkt
.data
[1] &= ENV_SENSOR_ENABLE_MASK
;
361 req_pkt
.data
[1] &= ENV_IPMI_DISABLE_MASK
;
362 req_pkt
.data
[1] |= ENV_SENSOR_DISABLE_MASK
;
364 size
= ENV_SET_GLOBAL_PKT_LEN
;
365 (void) smc_init_smc_msg(&req_pkt
, SMC_SET_GLOBAL_ENABLES
,
368 /* make a call to smc library to send cmd */
369 if (smc_send_msg(DEFAULT_FD
, &req_pkt
, &rsp_pkt
,
370 POLL_TIMEOUT
) != SMC_SUCCESS
) {
377 * wrapper smc drv open
383 if ((fd
= open(SMC_NODE
, O_RDWR
)) < 0) {
389 static picl_smc_event_t
390 env_handle_smc_local_event(void *res_datap
)
392 picl_errno_t rc
= PICL_SUCCESS
;
393 uint8_t event
= SMC_LOCAL_EVENT
;
394 uint8_t event_data
= BYTE_0(res_datap
);
396 if (env_debug
& EVENTS
)
397 syslog(LOG_INFO
, "Local Event Received, data %x\n", event_data
);
399 switch (event_data
) {
400 case SMC_LOCAL_EVENT_BRIDGE_IN_RESET
: /*FALLTHRU*/
401 case SMC_LOCAL_EVENT_BRIDGE_OUT_OF_RESET
:
402 if ((rc
= env_platmod_handle_bus_if_change(
403 event_data
)) != PICL_SUCCESS
) {
404 syslog(LOG_ERR
, gettext("SUNW_envmond:Error"
405 " in handling bus interface change "
406 "event, error = %d"), rc
);
409 case SMC_LOCAL_EVENT_LATCH_OPENED
:
410 syslog(LOG_INFO
, gettext("LATCH OPEN DETECTED"));
411 if ((rc
= env_platmod_handle_latch_open()) !=
413 syslog(LOG_ERR
, gettext("SUNW_envmond:Error"
414 " in handling latch open event, "
425 env_handle_async_msg_event(void *res_datap
)
427 int rc
= SMC_SUCCESS
;
428 uint8_t event
= BYTE_6(res_datap
);
430 if (env_debug
& EVENTS
)
431 syslog(LOG_INFO
, "Asynchronous Event %x Received, data %x\n",
432 event
, BYTE_7(res_datap
));
435 * This message comes to CPU when the service processor is going offline
438 case EVENT_MSG_AC_STATE_CHANGE
:
439 if ((rc
= process_platmod_sp_state_change_notif(res_datap
)) !=
441 syslog(LOG_ERR
, gettext("SUNW_envmond:Error in handling"
442 "service processor change of state event, "
447 * This message comes to CPU when service processor
448 * requests the CPU to go online or offline (shutdown).
450 case EVENT_MSG_CHANGE_CPU_NODE_STATE
:
451 if ((rc
= process_platmod_change_cpu_node_state(res_datap
)) !=
453 syslog(LOG_ERR
, gettext("SUNW_envmond:Error in handling"
454 "cpu change of state event, error = %d"), rc
);
458 * This message comes to CPU(Satellite) when the
459 * other node (Host) is going online or offline.
461 case EVENT_MSG_CHANGE_CPCI_STATE
:
462 if ((rc
= process_platmod_change_cpci_state(res_datap
)) !=
464 syslog(LOG_ERR
, gettext("SUNW_envmond:Error in handling"
465 "cpci change state event, error = %d"), rc
);
469 * This message comes from service processor to inform
470 * change in states for other nodes
472 case EVENT_MSG_ASYNC_EVENT_NOTIFICATION
:
473 if ((rc
= process_platmod_async_msg_notif(res_datap
)) !=
475 syslog(LOG_ERR
, gettext("SUNW_envmond:Error in handling"
476 "async event notification, error = %d"), rc
);
479 case MSG_GET_CPU_NODE_STATE
:
480 /* respond to the service processor heartbeat */
481 process_platmod_sp_heartbeat(BYTE_5(res_datap
));
490 static picl_smc_event_t
491 env_process_smc_event(int fd
, void **datapp
)
494 picl_smc_event_t event
;
495 void *res_datap
= NULL
;
497 if (read(fd
, (char *)&rsp_msg
, SC_MSG_MAX_SIZE
) < 0) {
501 if (SC_MSG_CC(&rsp_msg
) != 0) {
505 res_datap
= SC_MSG_DATA(&rsp_msg
);
506 if (env_debug
& EVENTS
)
507 syslog(LOG_INFO
, "Async Msg Cmd,data0,2 = %x,%x,%x\n",
508 SC_MSG_CMD(&rsp_msg
), BYTE_0(res_datap
),
511 if (SC_MSG_CMD(&rsp_msg
) == SMC_SMC_LOCAL_EVENT_NOTIF
) {
512 event
= env_handle_smc_local_event(res_datap
);
513 } else { /* it must be an IPMI event */
514 switch (BYTE_2(res_datap
)) {
517 if (env_debug
& DEBUG
)
518 syslog(LOG_INFO
, gettext("SUNW_envmond: "
519 " Sensor Event Received\n"));
521 switch (BYTE_3(res_datap
)) {
522 case TEMPERATURE_SENSOR_TYPE
:
523 event
= TEMPERATURE_SENSOR_EVENT
;
524 env_platmod_handle_sensor_event(res_datap
);
527 syslog(LOG_ERR
, gettext("SUNW_envmond:Unknown "
528 "sensor Event:%d\n"), BYTE_3(res_datap
));
533 env_handle_async_msg_event(res_datap
);
541 * polls SMC driver for SMC events
545 env_polling_thread(void *args
)
548 struct pollfd poll_fds
[1];
551 struct strioctl strio
;
554 smcfd
= env_open_smc();
556 syslog(LOG_ERR
, gettext("SUNW_envmond:Error in polling, "
557 "Open of SMC drv failed"));
558 create_polling_thr
= B_TRUE
;
562 set
.args
[0] = SMC_SENSOR_EVENT_ENABLE_SET
;
563 set
.attribute
= SC_ATTR_SHARED
;
564 strio
.ic_cmd
= SCIOC_MSG_SPEC
;
566 strio
.ic_len
= ENV_SENSOR_EV_ENABLE_PKT_LEN
;
567 strio
.ic_dp
= (char *)&set
;
568 if (ioctl(smcfd
, I_STR
, &strio
) < 0) {
569 syslog(LOG_ERR
, gettext("SUNW_envmond:Request for "
570 "Sensor events failed"));
572 create_polling_thr
= B_TRUE
;
576 /* request for async messages */
577 poll_fds
[0].fd
= smcfd
;
578 poll_fds
[0].events
= POLLIN
|POLLPRI
;
579 poll_fds
[0].revents
= 0;
581 set
.attribute
= SC_ATTR_SHARED
;
582 set
.args
[0] = SMC_IPMI_RESPONSE_NOTIF
;
583 set
.args
[1] = SMC_SMC_LOCAL_EVENT_NOTIF
;
584 strio
.ic_cmd
= SCIOC_MSG_SPEC
;
586 strio
.ic_len
= ENV_IPMI_SMC_ENABLE_PKT_LEN
;
587 strio
.ic_dp
= (char *)&set
;
588 if (ioctl(smcfd
, I_STR
, &strio
) == -1) {
589 syslog(LOG_ERR
, gettext("SUNW_envmond:Request for"
590 "Async messages failed"));
592 create_polling_thr
= B_TRUE
;
596 /* Now wait for SMC events to come */
598 poll_rc
= poll(poll_fds
, 1, -1); /* poll forever */
600 syslog(LOG_ERR
, gettext("SUNW_envmond:Event "
601 "processing halted"));
604 if (env_process_smc_event(smcfd
, &datap
) == NO_EVENT
) {
605 syslog(LOG_ERR
, gettext("SUNW_envmond:"
606 "wrong event data posted from SMC"));
610 create_polling_thr
= B_TRUE
;
615 * (to be)Called during chassis configuration. It does the following tasks.
616 * Set global enables on SMC
617 * Register for local(SMC) events and remote(IPMI) messages (State Change msgs)
618 * creates sensor nodes
620 * Initiallize the interaction with service processor
623 env_start_services(void)
626 if (env_debug
& DEBUG
) {
627 syslog(LOG_INFO
, "env_start_services begin");
630 /* set the SMC global enables */
631 if (env_set_smc_global_enables(B_TRUE
) == -1) {
632 syslog(LOG_ERR
, gettext("SUNW_envmond:Setting SMC "
634 return (PICL_FAILURE
);
637 /* start a worker thread to poll for SMC events */
638 if (create_polling_thr
) {
639 rc
= pthread_create(&polling_threadID
, NULL
,
640 &env_polling_thread
, NULL
);
642 syslog(LOG_ERR
, gettext("SUNW_envmond:Error in "
643 "creating polling thread"));
644 return (PICL_FAILURE
);
646 create_polling_thr
= B_FALSE
;
649 /* create the sensor nodes */
650 if ((rc
= env_platmod_create_sensors()) != PICL_SUCCESS
) {
651 syslog(LOG_ERR
, gettext("SUNW_envmond:Error in creating sensor"
652 " nodes, error = %d"), rc
);
655 /* intialize the hotswap framework */
656 if ((rc
= env_platmod_setup_hotswap()) != PICL_SUCCESS
) {
657 syslog(LOG_ERR
, gettext("SUNW_envmond:Error in hotswap "
658 "initialization, error = %d"), rc
);
661 if ((rc
= env_platmod_create_hotswap_prop()) != PICL_SUCCESS
) {
662 syslog(LOG_ERR
, gettext("SUNW_envmond:Error in creating "
663 "hotswap prop, error = %d"), rc
);
666 /* intialize interaction with service processor */
667 if ((rc
= env_platmod_sp_monitor()) != PICL_SUCCESS
) {
668 syslog(LOG_ERR
, gettext("SUNW_envmond:Failed to interact with"
669 " service processor, error = %d"), rc
);
671 return (PICL_SUCCESS
);
675 env_handle_chassis_configuring_event(char *state
)
677 picl_errno_t rc
= PICL_SUCCESS
;
678 picl_prophdl_t proph
;
679 picl_nodehdl_t rtm_lnodehdl
= 0;
680 char *cpu_name
= PICL_NODE_CPU
;
681 char *rtm_name
= PICL_NODE_RTM
;
682 uint64_t status_time
;
684 if (strcmp(state
, PICLEVENTARGVAL_CONFIGURING
) != 0) {
685 return (PICL_SUCCESS
);
688 /* initialize cpu loc node handle */
689 if (cpu_lnodehdl
== 0) {
690 if ((rc
= ptree_find_node(chassis_nodehdl
,
691 PICL_PROP_NAME
, PICL_PTYPE_CHARSTRING
,
692 cpu_name
, (strlen(cpu_name
) + 1),
693 &cpu_lnodehdl
)) != PICL_SUCCESS
) {
694 syslog(LOG_ERR
, gettext("SUNW_envmond: failed "
695 " to get CPU nodehdl, error = %d"), rc
);
700 /* create geo-addr prop under CPU location */
701 if (ptree_get_prop_by_name(cpu_lnodehdl
, PICL_PROP_GEO_ADDR
,
702 &proph
) == PICL_PROPNOTFOUND
) {
703 if ((rc
= env_create_property(PICL_PTYPE_UNSIGNED_INT
,
704 PICL_READ
, sizeof (cpu_geo_addr
),
705 PICL_PROP_GEO_ADDR
, NULLREAD
, NULLWRITE
,
706 cpu_lnodehdl
, &proph
,
707 (void *)&cpu_geo_addr
)) != PICL_SUCCESS
) {
711 if (ptree_get_prop_by_name(cpu_lnodehdl
,
712 PICL_PROP_STATUS_TIME
, &proph
) != PICL_SUCCESS
) {
713 status_time
= (uint64_t)time(NULL
);
714 (void) env_create_property(PICL_PTYPE_TIMESTAMP
,
715 PICL_READ
, sizeof (status_time
),
716 PICL_PROP_STATUS_TIME
, NULLREAD
, NULLWRITE
,
717 cpu_lnodehdl
, &proph
, &status_time
);
720 /* create geo address property for RTM node (if present) */
721 (void) ptree_find_node(chassis_nodehdl
,
722 PICL_PROP_NAME
, PICL_PTYPE_CHARSTRING
, rtm_name
,
723 (strlen(rtm_name
) + 1), &rtm_lnodehdl
);
725 if (rtm_lnodehdl
== 0) { /* RTM not present */
726 return (PICL_SUCCESS
);
729 if (ptree_get_prop_by_name(rtm_lnodehdl
, PICL_PROP_GEO_ADDR
,
730 &proph
) == PICL_PROPNOTFOUND
) {
731 if ((rc
= env_create_property(PICL_PTYPE_UNSIGNED_INT
,
732 PICL_READ
, sizeof (cpu_geo_addr
), PICL_PROP_GEO_ADDR
,
733 NULLREAD
, NULLWRITE
, rtm_lnodehdl
, &proph
,
734 &cpu_geo_addr
)) != PICL_SUCCESS
) {
735 syslog(LOG_ERR
, gettext("SUNW_envmond:Failed "
736 "to create CPU geo-addr, error = %d"), rc
);
740 if (ptree_get_prop_by_name(rtm_lnodehdl
,
741 PICL_PROP_STATUS_TIME
, &proph
) != PICL_SUCCESS
) {
742 status_time
= (uint64_t)time(NULL
);
743 (void) env_create_property(PICL_PTYPE_TIMESTAMP
,
744 PICL_READ
, sizeof (status_time
), PICL_PROP_STATUS_TIME
,
745 NULLREAD
, NULLWRITE
, rtm_lnodehdl
, &proph
,
749 /* start all the environment monitoring services */
750 if ((rc
= env_start_services()) != PICL_SUCCESS
) {
753 return (PICL_SUCCESS
);
757 * routine to handle all the picl state and condition change events
760 env_handle_event(const char *ename
, const void *earg
, size_t size
)
762 picl_nodehdl_t nodeh
= 0;
765 boolean_t state_event
;
766 char result
[PICL_PROPNAMELEN_MAX
];
771 if (strcmp(ename
, PICLEVENT_STATE_CHANGE
) == 0) {
772 state_event
= B_TRUE
;
773 } else if (strcmp(ename
, PICLEVENT_CONDITION_CHANGE
) == 0) {
774 state_event
= B_FALSE
;
779 /* unpack the nvlist and get the information */
780 if (nvlist_unpack((char *)earg
, size
, &nvlp
, NULL
)) {
783 if (nvlist_lookup_uint64(nvlp
, PICLEVENTARG_NODEHANDLE
, &nodeh
) == -1) {
787 if (nvlist_lookup_string(nvlp
, (state_event
) ?
789 PICLEVENTARG_CONDITION
, &value
) != 0) {
794 if (env_debug
& PICLEVENTS
) {
795 if (ptree_get_propval_by_name(nodeh
, PICL_PROP_NAME
,
796 result
, sizeof (result
)) != PICL_SUCCESS
) {
797 syslog(LOG_ERR
, " SUNW_envmond: error in getting"
798 " %s", PICL_PROP_NAME
);
802 syslog(LOG_INFO
, "SUNW_envmond: %s (%s) on %s",
803 ename
, value
, result
);
806 if (chassis_nodehdl
== 0 && state_event
) {
807 if (ptree_get_propval_by_name(nodeh
, PICL_PROP_NAME
,
808 result
, sizeof (result
)) != PICL_SUCCESS
) {
812 if (strcmp(result
, PICL_NODE_CHASSIS
) == 0) {
813 chassis_nodehdl
= nodeh
;
816 if (nodeh
== chassis_nodehdl
&& state_event
) {
817 (void) env_handle_chassis_configuring_event(value
);
819 /* do any platform specific handling that is reqd */
820 env_platmod_handle_event(ename
, earg
, size
);