cmd: remove sparc-only virtinfo
[unleashed.git] / usr / src / cmd / picl / plugins / sun4u / snowbird / envmond / piclplatmod.c
blob43c4c3d056d56921a70426b75342b378d094c1c9
1 /*
2 * CDDL HEADER START
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
7 * with the License.
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]
20 * CDDL HEADER END
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <stdio.h>
30 #include <limits.h>
31 #include <unistd.h>
32 #include <sys/systeminfo.h>
33 #include <pthread.h>
34 #include <syslog.h>
35 #include <picl.h>
36 #include <picltree.h>
37 #include <picldefs.h>
38 #include <string.h>
39 #include <libnvpair.h>
40 #include <libintl.h>
41 #include <librcm.h>
42 #include <stropts.h>
43 #include <smclib.h>
44 #include <sys/sysevent/dr.h>
45 #include "piclenvmond.h"
46 #include "picldr.h"
48 /* local defines */
49 #define RESET_CPU "/usr/sbin/shutdown -y -g 0 -i6"
50 #define SHUTDOWN_CPU "/usr/sbin/shutdown -y -g 0 -i0"
51 #define RCM_ABSTRACT_RESOURCE "SUNW_snowbird/board0/CPU1"
52 #define CPU_SENSOR_GEO_ADDR 0xe
53 #define IS_HEALTHY 0x01
54 #define PICL_NODE_SYSMGMT "sysmgmt"
55 #define SYSMGMT_PATH PLATFORM_PATH"/pci/pci/isa/sysmgmt"
56 #define BUF_SIZE 7
58 /* external functions */
59 extern picl_errno_t env_create_property(int, int, size_t, char *,
60 int (*readfn)(ptree_rarg_t *, void *),
61 int (*writefn)(ptree_warg_t *, const void *),
62 picl_nodehdl_t, picl_prophdl_t *, void *);
63 extern picl_errno_t post_dr_req_event(picl_nodehdl_t, char *, uint8_t);
64 extern picl_errno_t post_dr_ap_state_change_event(picl_nodehdl_t, char *,
65 uint8_t);
66 extern boolean_t env_admin_lock_enabled(picl_nodehdl_t);
67 extern picl_errno_t env_create_temp_sensor_node(picl_nodehdl_t, uint8_t);
68 extern void env_handle_sensor_event(void *);
69 extern int env_open_smc();
71 /* external variables */
72 extern int env_debug;
73 extern uint8_t cpu_geo_addr;
74 extern picl_nodehdl_t rooth, platformh, sysmgmth, sensorh;
75 extern picl_nodehdl_t chassis_nodehdl, cpu_nodehdl, cpu_lnodehdl;
77 /* locals */
78 static pthread_mutex_t env_dmc_mutex = PTHREAD_MUTEX_INITIALIZER;
79 static pthread_cond_t env_dmc_cond = PTHREAD_COND_INITIALIZER;
80 static boolean_t env_reset_cpu = B_FALSE;
81 static boolean_t env_shutdown_system = B_FALSE;
82 static env_state_event_t env_chassis_state = FRU_STATE_UNKNOWN;
83 static char *rcm_abstr_cp2300_name = RCM_ABSTRACT_RESOURCE;
84 static boolean_t env_got_dmc_msg = B_FALSE;
85 static long env_dmc_wait_time = 15;
86 static pthread_t dmc_thr_tid;
89 * issue halt or reboot based on the reset_cpu flag
91 /*ARGSUSED*/
92 static void
93 shutdown_cpu(boolean_t force)
95 if (env_shutdown_system) {
96 if (env_reset_cpu) {
97 (void) pclose(popen(RESET_CPU, "w"));
98 } else {
99 (void) pclose(popen(SHUTDOWN_CPU, "w"));
105 * inform RCM framework that the remove op is successful
107 static void
108 confirm_rcm(char *abstr_name, rcm_handle_t *rhandle)
110 rcm_notify_remove(rhandle, abstr_name, 0, NULL);
114 * inform RCM framework that the remove op is failed
116 static void
117 fail_rcm(char *abstr_name, rcm_handle_t *rhandle)
119 (void) rcm_notify_online(rhandle, abstr_name, 0, NULL);
123 * check RCM framework if it is ok to offline a device
125 static int
126 check_rcm(char *rcm_abstr_cp2300_name, uint_t flags)
128 rcm_info_t *rinfo;
129 rcm_handle_t *rhandle;
130 int rv;
132 if (rcm_alloc_handle(NULL, 0, NULL, &rhandle) != RCM_SUCCESS) {
133 return (RCM_FAILURE);
136 rv = rcm_request_offline(rhandle, rcm_abstr_cp2300_name,
137 flags, &rinfo);
139 if (rv == RCM_FAILURE) {
140 rcm_free_info(rinfo);
141 fail_rcm(rcm_abstr_cp2300_name, rhandle);
142 rcm_free_handle(rhandle);
143 return (RCM_FAILURE);
145 if (rv == RCM_CONFLICT) {
146 rcm_free_info(rinfo);
147 rcm_free_handle(rhandle);
148 return (RCM_CONFLICT);
151 confirm_rcm(rcm_abstr_cp2300_name, rhandle);
152 rcm_free_info(rinfo);
153 rcm_free_handle(rhandle);
154 return (RCM_SUCCESS);
158 * utility routine to send response to an IPMI message
160 static int
161 send_response2remote_device(uint8_t ipmb_addr, uint8_t cmd, uint8_t reqseq_lun,
162 uint8_t cc)
164 int rc = SMC_SUCCESS;
165 sc_reqmsg_t req_pkt;
166 sc_rspmsg_t rsp_pkt;
167 uint8_t data = cc; /* completion code */
169 /* make a call to ctsmc lib */
170 (void) smc_init_ipmi_msg(&req_pkt, cmd, DEFAULT_FD, 1, &data,
171 (reqseq_lun >> 2), ipmb_addr, SMC_NETFN_APP_RSP,
172 (reqseq_lun & 0x03));
173 rc = smc_send_msg(DEFAULT_FD, &req_pkt, &rsp_pkt,
174 POLL_TIMEOUT);
176 if (rc != SMC_SUCCESS)
177 syslog(LOG_ERR, gettext("SUNW_envmond:Error in sending response"
178 " to %x, error = %d"), ipmb_addr, rc);
179 return (rc);
183 * do all the checks like adminlock check, rcm check and initiate
184 * shutdown
186 /*ARGSUSED*/
187 static int
188 initiate_shutdown(boolean_t force)
190 int rv;
191 uint_t rcmflags = 0;
192 struct timespec rqtp, rmtp;
194 if (!env_shutdown_system) {
195 return (-1);
198 /* check the adminlock prop */
199 if ((!force) && (env_admin_lock_enabled(cpu_nodehdl))) {
200 syslog(LOG_ERR, gettext("SUNW_envmond: "
201 "CPU in use! Cannot shutdown"));
202 return (-1);
205 if (force) {
206 rcmflags = RCM_FORCE;
209 /* check with rcm framework */
210 rv = check_rcm(rcm_abstr_cp2300_name, rcmflags);
212 if ((rv == RCM_FAILURE) || (rv == RCM_CONFLICT)) {
213 syslog(LOG_ERR, gettext("SUNW_envmond: RCM error %d, Cannot"
214 " shutdown"), rv);
215 return (-1);
219 * force events on chassis node
221 if (force) {
222 if (post_dr_req_event(chassis_nodehdl, DR_REQ_OUTGOING_RES,
223 NO_WAIT) == PICL_SUCCESS) {
224 /* wait a little for clean up of frutree */
225 rqtp.tv_sec = 5;
226 rqtp.tv_nsec = 0;
227 (void) nanosleep(&rqtp, &rmtp);
230 * If force option is set, do it right here for now
231 * since there is no way to pass this info via events
232 * to frutree framework.
234 shutdown_cpu(force);
235 return (0);
238 if (post_dr_req_event(chassis_nodehdl, DR_REQ_OUTGOING_RES, NO_WAIT)
239 != PICL_SUCCESS) {
240 syslog(LOG_ERR, gettext("SUNW_envmond:cannot shutdown "
241 "the host CPU."));
242 return (-1);
244 return (0);
248 * get the HEALTHY# line state
249 * Return -1 for Error
250 * 0 for HEALTHY# down
251 * 1 for HEALTHY# up
253 static int
254 env_get_healthy_status()
256 sc_reqmsg_t req_pkt;
257 sc_rspmsg_t rsp_pkt;
258 uint8_t size = 0;
260 /* initialize the request packet */
261 (void) smc_init_smc_msg(&req_pkt, SMC_GET_EXECUTION_STATE,
262 DEFAULT_SEQN, size);
264 /* make a call to smc library to send cmd */
265 if (smc_send_msg(DEFAULT_FD, &req_pkt, &rsp_pkt,
266 POLL_TIMEOUT) != SMC_SUCCESS) {
267 return (-1);
269 return (rsp_pkt.data[0] & IS_HEALTHY);
273 * initialization
275 picl_errno_t
276 env_platmod_init()
278 picl_errno_t rc = PICL_SUCCESS;
280 if (rooth == 0) {
281 if (ptree_get_root(&rooth) != PICL_SUCCESS) {
282 return (rc);
286 if (chassis_nodehdl == 0) {
287 if ((rc = ptree_get_node_by_path(PICL_FRUTREE_CHASSIS,
288 &chassis_nodehdl)) != PICL_SUCCESS) {
289 return (rc);
292 if (post_dr_req_event(chassis_nodehdl, DR_REQ_INCOMING_RES,
293 NO_WAIT) != PICL_SUCCESS) {
294 syslog(LOG_ERR, gettext("SUNW_envmond: Error in "
295 "Posting configure event for Chassis node"));
296 rc = PICL_FAILURE;
298 return (rc);
302 * release all the resources
304 void
305 env_platmod_fini()
307 cpu_geo_addr = 0;
308 rooth = platformh = sysmgmth = 0;
309 chassis_nodehdl = cpu_nodehdl = cpu_lnodehdl = 0;
310 env_chassis_state = FRU_STATE_UNKNOWN;
311 (void) ptree_delete_node(sensorh);
312 (void) ptree_destroy_node(sensorh);
316 * handle chassis state change
318 static void
319 env_handle_chassis_state_event(char *state)
321 if (strcmp(state, PICLEVENTARGVAL_CONFIGURING) == 0) {
322 env_chassis_state = FRU_STATE_CONFIGURING;
323 return;
326 if (strcmp(state, PICLEVENTARGVAL_UNCONFIGURED) == 0) {
327 if (env_chassis_state == FRU_STATE_CONFIGURING ||
328 env_chassis_state == FRU_STATE_UNKNOWN) {
329 /* picl intialization is failed, dont issue shutdown */
330 env_chassis_state = FRU_STATE_UNCONFIGURED;
331 return;
333 env_chassis_state = FRU_STATE_UNCONFIGURED;
334 if (env_reset_cpu) {
335 (void) pclose(popen(RESET_CPU, "w"));
336 } else {
337 (void) pclose(popen(SHUTDOWN_CPU, "w"));
339 return;
342 if (strcmp(state, PICLEVENTARGVAL_CONFIGURED) == 0) {
343 env_chassis_state = FRU_STATE_CONFIGURED;
348 * event handler for watchdog state change event
350 static picl_errno_t
351 env_handle_watchdog_expiry(picl_nodehdl_t wd_nodehdl)
353 picl_errno_t rc = PICL_SUCCESS;
354 char class[PICL_CLASSNAMELEN_MAX];
355 char value[PICL_PROPNAMELEN_MAX];
356 char cond[BUF_SIZE];
358 if ((rc = ptree_get_propval_by_name(wd_nodehdl,
359 PICL_PROP_CLASSNAME, class,
360 PICL_CLASSNAMELEN_MAX)) != PICL_SUCCESS) {
361 return (rc);
364 /* if the event is not of watchdog-timer, return */
365 if (strcmp(class, PICL_CLASS_WATCHDOG_TIMER) != 0) {
366 return (PICL_INVALIDARG);
369 if ((rc = ptree_get_propval_by_name(wd_nodehdl,
370 PICL_PROP_WATCHDOG_ACTION, value, sizeof (value))) !=
371 PICL_SUCCESS) {
372 return (rc);
375 /* if action is none, dont do anything */
376 if (strcmp(value, PICL_PROPVAL_WD_ACTION_ALARM) != 0) {
377 return (PICL_SUCCESS);
380 (void) strncpy(cond, PICLEVENTARGVAL_FAILED, sizeof (cond));
381 /* update CPU condition to failed */
382 if ((rc = ptree_update_propval_by_name(cpu_nodehdl,
383 PICL_PROP_CONDITION, cond, sizeof (cond))) != PICL_SUCCESS) {
384 return (rc);
387 /* post dr ap state change event */
388 rc = post_dr_ap_state_change_event(cpu_nodehdl,
389 DR_RESERVED_ATTR, NO_COND_TIMEDWAIT);
390 return (rc);
394 * rotine that handles all the picl state and condition change events
396 void
397 env_platmod_handle_event(const char *ename, const void *earg, size_t size)
399 picl_errno_t rc;
400 picl_nodehdl_t nodeh = 0;
401 picl_prophdl_t proph;
402 nvlist_t *nvlp;
403 char *value;
404 boolean_t state_event;
405 env_state_event_t event;
406 char result[PICL_PROPNAMELEN_MAX];
407 uint64_t status_time, cond_time;
408 char cond[BUF_SIZE];
410 if (!ename) {
411 return;
413 if (strcmp(ename, PICLEVENT_STATE_CHANGE) == 0) {
414 state_event = B_TRUE;
415 } else if (strcmp(ename, PICLEVENT_CONDITION_CHANGE) == 0) {
416 state_event = B_FALSE;
417 } else {
418 syslog(LOG_ERR, gettext("SUNW_envmond: unknown event:%s\n"),
419 ename);
420 return;
423 /* unpack the nvlist and get the information */
424 if (nvlist_unpack((char *)earg, size, &nvlp, NULL)) {
425 return;
427 if (nvlist_lookup_uint64(nvlp, PICLEVENTARG_NODEHANDLE, &nodeh) == -1) {
428 nvlist_free(nvlp);
429 return;
431 if (nvlist_lookup_string(nvlp, (state_event) ?
432 PICLEVENTARG_STATE :
433 PICLEVENTARG_CONDITION, &value) != 0) {
434 nvlist_free(nvlp);
435 return;
438 if (env_debug & PICLEVENTS) {
439 if (ptree_get_propval_by_name(nodeh, PICL_PROP_NAME,
440 result, sizeof (result)) != PICL_SUCCESS) {
441 syslog(LOG_ERR, " SUNW_envmond: error in getting"
442 " node name");
443 nvlist_free(nvlp);
444 return;
446 syslog(LOG_INFO, "SUNW_envmond: %s (%s) on %s",
447 ename, value, result);
450 if (chassis_nodehdl == 0 && state_event) {
451 if (ptree_get_propval_by_name(nodeh, PICL_PROP_NAME,
452 result, sizeof (result)) != PICL_SUCCESS) {
453 nvlist_free(nvlp);
454 return;
456 if (strcmp(result, PICL_NODE_CHASSIS) == 0) {
457 chassis_nodehdl = nodeh;
461 if (nodeh == chassis_nodehdl && state_event) {
462 env_handle_chassis_state_event(value);
463 nvlist_free(nvlp);
464 return;
467 if (strcmp(PICLEVENTARGVAL_DISCONNECTED, value) == 0) {
468 event = LOC_STATE_DISCONNECTED;
469 } else if (strcmp(PICLEVENTARGVAL_CONNECTED, value) == 0) {
470 event = LOC_STATE_CONNECTED;
471 } else if (strcmp(PICLEVENTARGVAL_EMPTY, value) == 0) {
472 event = LOC_STATE_EMPTY;
473 } else if (strcmp(PICLEVENTARGVAL_CONFIGURED, value) == 0) {
474 event = FRU_STATE_CONFIGURED;
475 } else if (strcmp(PICLEVENTARGVAL_UNCONFIGURED, value) == 0) {
476 event = FRU_STATE_UNCONFIGURED;
477 } else if (strcmp(PICL_PROPVAL_WD_STATE_EXPIRED, value) == 0) {
478 /* watchdog expiry event */
479 if ((rc = env_handle_watchdog_expiry(nodeh)) != PICL_SUCCESS) {
480 syslog(LOG_ERR, gettext("SUNW_envmond:Error in handling"
481 "watchdog expiry event"));
483 nvlist_free(nvlp);
484 return;
485 } else {
486 nvlist_free(nvlp);
487 return;
490 switch (event) {
491 case LOC_STATE_EMPTY:
492 break;
494 case LOC_STATE_DISCONNECTED:
495 if (nodeh == cpu_lnodehdl) {
496 (void) initiate_shutdown(B_FALSE);
498 break;
499 case LOC_STATE_CONNECTED:
500 if (nodeh != cpu_lnodehdl) {
501 break;
503 if (ptree_get_propval_by_name(cpu_lnodehdl,
504 PICL_PROP_CHILD, &cpu_nodehdl,
505 sizeof (picl_nodehdl_t)) != PICL_SUCCESS) {
506 syslog(LOG_ERR, gettext("SUNW_envmond:Cannot "
507 "initialize CPU node handle %llx"), nodeh);
508 cpu_nodehdl = 0;
510 break;
511 case FRU_STATE_CONFIGURED:
512 if (nodeh != cpu_nodehdl) {
513 break;
515 if (ptree_get_prop_by_name(cpu_nodehdl,
516 PICL_PROP_STATUS_TIME, &proph) != PICL_SUCCESS) {
517 status_time = (uint64_t)time(NULL);
518 (void) env_create_property(PICL_PTYPE_TIMESTAMP,
519 PICL_READ, sizeof (status_time),
520 PICL_PROP_STATUS_TIME, NULLREAD,
521 NULLWRITE, cpu_nodehdl, &proph,
522 &status_time);
524 if (ptree_get_prop_by_name(cpu_nodehdl,
525 PICL_PROP_CONDITION_TIME, &proph) != PICL_SUCCESS) {
526 cond_time = (uint64_t)time(NULL);
527 (void) env_create_property(PICL_PTYPE_TIMESTAMP,
528 PICL_READ, sizeof (cond_time),
529 PICL_PROP_CONDITION_TIME, NULLREAD,
530 NULLWRITE, cpu_nodehdl, &proph,
531 &cond_time);
533 env_shutdown_system = B_FALSE;
534 /* if HEALTHY# is UP update the condition to "ok" */
535 switch (env_get_healthy_status()) {
536 case 0:
537 /* update CPU condition to failed */
538 (void) strncpy(cond, PICLEVENTARGVAL_FAILED, sizeof (cond));
539 break;
540 case 1:
541 /* update CPU condition to ok */
542 (void) strncpy(cond, PICLEVENTARGVAL_OK, sizeof (cond));
543 break;
544 case -1: /*FALLTHRU*/
545 default:
546 /* update the condition to unknown */
547 (void) strncpy(cond, PICLEVENTARGVAL_UNKNOWN, sizeof (cond));
548 syslog(LOG_ERR, gettext("SUNW_envmond:Error in "
549 "reading HEALTHY# status"));
552 if ((rc = ptree_update_propval_by_name(cpu_nodehdl,
553 PICL_PROP_CONDITION, cond, sizeof (cond))) !=
554 PICL_SUCCESS) {
555 syslog(LOG_ERR, gettext("SUNW_envmond:Error in "
556 "updating CPU condition, error = %d"), rc);
558 break;
559 case FRU_STATE_UNCONFIGURED:
560 if (env_reset_cpu && nodeh == cpu_nodehdl) {
561 (void) initiate_shutdown(B_FALSE);
563 break;
564 default:
565 break;
566 } /* end of switch */
567 nvlist_free(nvlp);
571 * This thread waits for dmc message to come, as it has to send
572 * response ACK back to DMC. Otherwise DMC may think that message
573 * is lost and issues poweroff on a node. So there is a chance for
574 * CPU to be powered off in the middle of shutdown process. If the
575 * DMC message didnt come, then process the local shutdown request.
577 /*ARGSUSED*/
578 static void *
579 env_wait_for_dmc_msg(void *args)
581 struct timeval ct;
582 struct timespec to;
584 (void) pthread_mutex_lock(&env_dmc_mutex);
585 if (env_got_dmc_msg == B_TRUE) {
586 (void) pthread_mutex_unlock(&env_dmc_mutex);
587 return (NULL);
591 * wait for specified time to check if dmc sends the
592 * shutdown request
594 (void) gettimeofday(&ct, NULL);
595 to.tv_sec = ct.tv_sec + env_dmc_wait_time;
596 to.tv_nsec = 0;
597 (void) pthread_cond_timedwait(&env_dmc_cond,
598 &env_dmc_mutex, &to);
599 if (env_got_dmc_msg == B_TRUE) {
600 (void) pthread_mutex_unlock(&env_dmc_mutex);
601 return (NULL);
603 (void) pthread_mutex_unlock(&env_dmc_mutex);
605 env_shutdown_system = B_TRUE;
606 env_reset_cpu = B_FALSE;
607 (void) initiate_shutdown(B_FALSE);
608 return (NULL);
612 * Handle the Latch open event(shutdown the node)
614 picl_errno_t
615 env_platmod_handle_latch_open()
618 * create a thread to process local event after waiting for DMC CPU
619 * node state offline message
621 if (pthread_create(&dmc_thr_tid, NULL, &env_wait_for_dmc_msg,
622 NULL) != 0) {
623 syslog(LOG_ERR, gettext("SUNW_envmond:Error in creating "
624 "dmc thread"));
625 return (PICL_FAILURE);
627 return (PICL_SUCCESS);
631 * For Sanibel, hotswap initialization is not reqd.
633 picl_errno_t
634 env_platmod_setup_hotswap()
636 return (PICL_SUCCESS);
640 * For sanibel this supoort is not required
642 picl_errno_t
643 env_platmod_sp_monitor()
645 return (PICL_SUCCESS);
649 * For sanibel this supoort is not required
651 picl_errno_t
652 env_platmod_create_hotswap_prop()
654 return (PICL_SUCCESS);
658 * For sanibel this supoort is not required
660 /*ARGSUSED*/
661 void
662 process_platmod_sp_heartbeat(uint8_t data)
667 * For sanibel this supoort is not required
669 /*ARGSUSED*/
671 process_platmod_async_msg_notif(void *resdatap)
673 return (0);
677 * For sanibel this supoort is not required
679 /*ARGSUSED*/
681 process_platmod_change_cpci_state(void *res_datap)
683 return (0);
687 * handle request from service processor for shutdown/online
690 process_platmod_change_cpu_node_state(void *res_datap)
692 int rc = SMC_SUCCESS;
693 uint8_t state = BYTE_7(res_datap);
694 boolean_t force_flag = B_FALSE;
696 switch (state & 1) {
697 case CPU_NODE_STATE_OFFLINE:
698 (void) pthread_mutex_lock(&env_dmc_mutex);
699 env_got_dmc_msg = B_TRUE;
700 (void) pthread_cond_signal(&env_dmc_cond);
701 (void) pthread_mutex_unlock(&env_dmc_mutex);
702 env_shutdown_system = B_TRUE;
703 if ((state >> 2) & 1)
704 env_reset_cpu = B_TRUE;
705 if (state >> 1 & 1) { /* force flag set? */
706 force_flag = B_TRUE;
707 } else {
708 force_flag = B_FALSE;
711 if (initiate_shutdown(force_flag) == 0) {
712 if ((rc = send_response2remote_device(SMC_BMC_ADDR,
713 EVENT_MSG_CHANGE_CPU_NODE_STATE,
714 BYTE_5(res_datap), 0x0)) != SMC_SUCCESS) {
715 return (rc);
717 } else {
718 if ((rc = send_response2remote_device(SMC_BMC_ADDR,
719 EVENT_MSG_CHANGE_CPU_NODE_STATE,
720 BYTE_5(res_datap), 0xFF)) != SMC_SUCCESS) {
721 return (rc);
723 env_shutdown_system = B_FALSE;
724 if ((state >> 2) & 1)
725 env_reset_cpu = B_FALSE;
727 break;
728 case CPU_NODE_STATE_ONLINE:
729 if ((rc = send_response2remote_device(SMC_BMC_ADDR,
730 EVENT_MSG_CHANGE_CPU_NODE_STATE,
731 BYTE_5(res_datap), 0x0)) != SMC_SUCCESS) {
732 return (rc);
734 break;
735 default:
736 break;
738 return (0);
742 * Handle change in state of service processor
745 process_platmod_sp_state_change_notif(void *res_datap)
747 int rc = SMC_SUCCESS;
748 uint8_t state = BYTE_7(res_datap);
749 uint8_t rq_addr = BYTE_4(res_datap);
751 if (rq_addr != SMC_BMC_ADDR) {
752 return (PICL_FAILURE);
755 switch (state) {
756 case CPU_NODE_STATE_ONLINE:
757 /* Send ACK to service processor */
758 if ((rc = send_response2remote_device(SMC_BMC_ADDR,
759 EVENT_MSG_AC_STATE_CHANGE,
760 BYTE_5(res_datap), 0x0)) != SMC_SUCCESS) {
761 return (rc);
763 break;
765 case CPU_NODE_STATE_OFFLINE:
766 /* Send ACK to service processor */
767 if ((rc = send_response2remote_device(SMC_BMC_ADDR,
768 EVENT_MSG_AC_STATE_CHANGE,
769 BYTE_5(res_datap), 0x0)) != SMC_SUCCESS) {
770 return (rc);
772 break;
774 default:
775 if ((rc = send_response2remote_device(SMC_BMC_ADDR,
776 EVENT_MSG_AC_STATE_CHANGE,
777 BYTE_5(res_datap), 0xFF)) != SMC_SUCCESS) {
778 return (rc);
780 break;
782 return (0);
786 * For sanibel this supoort is not required
788 /*ARGSUSED*/
789 picl_errno_t
790 env_platmod_handle_bus_if_change(uint8_t data)
792 return (PICL_SUCCESS);
796 * create the temperature sensor nodes
798 picl_errno_t
799 env_platmod_create_sensors()
801 picl_errno_t rc = PICL_SUCCESS;
803 if (rooth == 0) {
804 if ((rc = ptree_get_root(&rooth)) != PICL_SUCCESS) {
805 return (rc);
809 if (platformh == 0) {
810 if ((rc = ptree_get_node_by_path(PLATFORM_PATH,
811 &platformh)) != PICL_SUCCESS) {
812 return (rc);
816 if (sysmgmth == 0) {
817 if ((rc = ptree_get_node_by_path(SYSMGMT_PATH,
818 &sysmgmth)) != PICL_SUCCESS) {
819 return (rc);
823 rc = env_create_temp_sensor_node(sysmgmth, CPU_SENSOR_GEO_ADDR);
824 return (rc);
828 * handler for sensor event
830 void
831 env_platmod_handle_sensor_event(void *res_datap)
833 if (BYTE_4(res_datap) != CPU_SENSOR_GEO_ADDR) {
834 return;
836 env_handle_sensor_event(res_datap);