4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 * Daktari platform platform specific environment monitoring policies
40 #include <sys/types.h>
41 #include <sys/param.h>
42 #include <config_admin.h>
43 #include <libdevice.h>
46 #include <psvc_objects.h>
47 #include <sys/i2c/clients/i2c_client.h>
48 #include <sys/daktari.h>
49 #include <sys/hpc3130_events.h>
52 #include <sys/systeminfo.h>
56 /* resides in libcfgadm */
57 extern cfga_err_t
config_change_state(cfga_cmd_t
, int, char *const *,
58 const char *, struct cfga_confirm
*, struct cfga_msg
*, char **,
61 static int32_t update_gen_fault_led(psvc_opaque_t
, char *);
62 static void shutdown_routine(void);
63 static int32_t update_thresholds(psvc_opaque_t hdlp
, char *id
, int offset
);
68 static int dak_policy_debug
= 0;
70 #define D1SYS_ERR(ARGS) if (dak_policy_debug & 0x1) syslog ARGS;
71 #define D2SYS_ERR(ARGS) if (dak_policy_debug & 0x2) syslog ARGS;
75 #define D1SYS_ERR(ARGS)
76 #define D2SYS_ERR(ARGS)
80 #define I2C_PATH "/devices/pci@9,700000/ebus@1/i2c@1,30"
81 #define I2C_NODE I2C_PATH ":devctl"
82 #define PCF8574 I2C_PATH "/ioexp@0,%x:pcf8574"
83 #define PCF8591 I2C_PATH "/adio@0,%x:port_0"
84 #define FRU I2C_PATH "/fru@0,%x:fru"
85 #define HPC3130_DEV I2C_PATH "/hotplug-controller@0,%2x:port_%1x"
86 #define GEN_FAULT_LED "FSP_GEN_FAULT_LED"
87 #define EMPTY_STRING "EMPTY"
88 #define DEVICE_FAILURE_MSG gettext("WARNING: Device %s failure detected")
89 #define DEVICE_INSERTED_MSG gettext("Device %s inserted")
90 #define DEVICE_REMOVED_MSG gettext("Device %s removed")
91 #define PS_UNPLUGGED_MSG gettext("Device %s unplugged")
92 #define PS_PLUGGED_MSG gettext("Device %s Plugged in")
93 #define DEVICE_OK_MSG gettext("Device %s OK")
94 #define SET_LED_FAILED_MSG \
95 gettext("Failed to set LED state, id = %s, errno = %d\n")
96 #define GET_PRESENCE_FAILED_MSG \
97 gettext("Failed to get presence attribute, id = %s, errno = %d\n")
98 #define GET_SENSOR_FAILED_MSG \
99 gettext("Failed to get sensor value, id = %s, errno = %d\n")
101 gettext("WARNING: Only 1 Power Supply in system. ADD a 2nd Power Supply.\n")
102 #define REMOVE_LOAD_MSG \
103 gettext("WARNING: Power Supply at 95%% current. Remove some load.\n")
104 #define PS_OVER_CURRENT_MSG \
105 gettext("WARNING: Power Supply overcurrent detected\n")
106 #define PS_UNDER_CURRENT_MSG \
107 gettext("WARNING: PS%d Undercurrent on one or more DC lines\n")
108 #define DEVICE_UNKNOWN_MSG gettext("Unknown device %s instance %d\n")
109 #define DEVICE_HANDLE_FAIL_MSG \
110 gettext("Failed to get device handle for %s, errno = %d\n")
111 #define DEVTREE_NODE_CREATE_FAILED \
112 gettext("psvc PICL plugin: Failed to create node for %s, errno = %d")
113 #define DEVTREE_NODE_DELETE_FAILED \
114 gettext("psvc PICL plugin: Failed to delete node for %s, errno = %d")
115 #define DISK_FAULT_MSG gettext("%s: Error Reported\n")
116 #define DISK_OK_MSG gettext("%s: Error Cleared\n")
117 #define SET_FANSPEED_FAILED_MSG \
118 gettext("Failed to set fan speed, id = %s, errno = %d\n")
119 #define GET_ATTR_FRU_FAILED_MSG gettext("Failed psvc_get_attr for FRU info\n")
120 #define NO_FRU_INFO_MSG \
121 gettext("No FRU Information for %s using default module card\n")
123 #define DAKTARI_MAX_PS 3
124 #define DAK_MAX_PS_I_SENSORS 4
125 #define DAK_MAX_DISKS 12
126 #define DAK_MAX_CPU_MOD 4
127 #define DAK_MAX_FAULT_SENSORS 3
128 #define DAK_MAX_FANS 10
130 static int co_ps
= 0;
131 static char *shutdown_string
= "shutdown -y -g 60 -i 5 \"OVERTEMP condition\"";
133 typedef struct i2c_hp
{
136 char compatible
[256];
139 typedef struct seg_desc
{
145 static int32_t threshold_names
[] = {
146 PSVC_HW_LO_SHUT_ATTR
,
149 PSVC_NOT_USED
, /* LOW MODE which is not used */
150 PSVC_OPTIMAL_TEMP_ATTR
,
157 * The I2C bus is noisy, and the state may be incorrectly reported as
158 * having changed. When the state changes, we attempt to confirm by
159 * retrying. If any retries indicate that the state has not changed, we
160 * assume the state change(s) were incorrect and the state has not changed.
161 * The following variables are used to store the tuneable values read in
162 * from the optional i2cparam.conf file for this shared object library.
164 static int n_retry_pshp_status
= PSVC_NUM_OF_RETRIES
;
165 static int retry_sleep_pshp_status
= 1;
166 static int n_read_overcurrent
= PSVC_THRESHOLD_COUNTER
;
167 static int n_read_undercurrent
= PSVC_THRESHOLD_COUNTER
;
168 static int n_retry_devicefail
= PSVC_NUM_OF_RETRIES
;
169 static int retry_sleep_devicefail
= 1;
170 static int n_read_fanfault
= PSVC_THRESHOLD_COUNTER
;
171 static int n_retry_pshp
= PSVC_NUM_OF_RETRIES
;
172 static int retry_sleep_pshp
= 1;
173 static int n_retry_diskfault
= PSVC_NUM_OF_RETRIES
;
174 static int retry_sleep_diskfault
= 1;
175 static int n_retry_temp_shutdown
= PSVC_NUM_OF_RETRIES
;
176 static int retry_sleep_temp_shutdown
= 1;
183 static i2c_noise_param_t i2cparams
[] = {
184 &n_retry_pshp_status
, "n_retry_pshp_status",
185 &retry_sleep_pshp_status
, "retry_sleep_pshp_status",
186 &n_read_overcurrent
, "n_read_overcurrent",
187 &n_read_undercurrent
, "n_read_undercurrent",
188 &n_retry_devicefail
, "n_retry_devicefail",
189 &retry_sleep_devicefail
, "retry_sleep_devicefail",
190 &n_read_fanfault
, "n_read_fanfault",
191 &n_retry_pshp
, "n_retry_pshp",
192 &retry_sleep_pshp
, "retry_sleep_pshp",
193 &n_retry_diskfault
, "n_retry_diskfault",
194 &retry_sleep_diskfault
, "retry_sleep_diskfault",
195 &n_retry_temp_shutdown
, "n_retry_temp_shutdown",
196 &retry_sleep_temp_shutdown
, "retry_sleep_temp_shutdown",
200 #pragma init(i2cparams_load)
203 i2cparams_debug(i2c_noise_param_t
*pi2cparams
, char *platform
,
207 i2c_noise_param_t
*p
;
209 if (!usingDefaults
) {
210 (void) snprintf(s
, sizeof (s
),
211 "# Values from /usr/platform/%s/lib/i2cparam.conf\n",
213 syslog(LOG_WARNING
, "%s", s
);
215 /* no file - we're using the defaults */
216 (void) snprintf(s
, sizeof (s
),
217 "# No /usr/platform/%s/lib/i2cparam.conf file, using defaults\n",
220 (void) fputs(s
, stdout
);
222 while (p
->pvar
!= NULL
) {
223 (void) snprintf(s
, sizeof (s
), "%s %d\n", p
->texttag
,
226 syslog(LOG_WARNING
, "%s", s
);
227 (void) fputs(s
, stdout
);
236 char filename
[PATH_MAX
];
241 i2c_noise_param_t
*p
;
243 if (sysinfo(SI_PLATFORM
, platform
, sizeof (platform
)) == -1) {
244 syslog(LOG_ERR
, "sysinfo error %s\n", strerror(errno
));
247 (void) snprintf(filename
, sizeof (filename
),
248 "/usr/platform/%s/lib/i2cparam.conf", platform
);
249 /* read thru the i2cparam.conf file and set variables */
250 if ((fp
= fopen(filename
, "r")) != NULL
) {
251 while (fgets(s
, sizeof (s
), fp
) != NULL
) {
252 if (s
[0] == '#') /* skip comment lines */
254 /* try to find a string match and get the value */
255 if (sscanf(s
, "%127s %d", var
, &val
) != 2)
258 val
= 1; /* clamp min value */
260 while (p
->pvar
!= NULL
) {
261 if (strncmp(p
->texttag
, var
, sizeof (var
)) ==
271 /* output the values of the parameters */
272 i2cparams_debug(&(i2cparams
[0]), platform
, ((fp
== NULL
)? 1 : 0));
276 psvc_MB_update_thresholds_0(psvc_opaque_t hdlp
, char *id
, int offset
)
281 err
= update_thresholds(hdlp
, id
, IO_offset
);
287 psvc_IO_update_thresholds_0(psvc_opaque_t hdlp
, char *id
, int offset
)
292 err
= update_thresholds(hdlp
, id
, IO_offset
);
298 psvc_DBP_update_thresholds_0(psvc_opaque_t hdlp
, char *id
, int offset
)
303 err
= update_thresholds(hdlp
, id
, IO_offset
);
309 * used to determine if a change of state occured. valid when states
313 change_of_state_str(char *state1
, char *check1
, char *state2
, char *check2
)
317 if ((strcmp(state1
, check1
) == 0) && (strcmp(state2
, check2
) != 0))
319 if ((strcmp(state1
, check1
) != 0) && (strcmp(state2
, check2
) == 0))
326 * Update thresholds tries to read the temperature thresholds from the FRU
327 * SEEproms and then updates the thresholds in the object by overriding the
328 * hardcoded thresholds. For Daktari it is an Error if the FRU does not
329 * contain the segment that had the temperature thresholds.
332 update_thresholds(psvc_opaque_t hdlp
, char *id
, int offset
)
334 int32_t status
= PSVC_SUCCESS
;
336 char *fru
, seg_name
[2];
337 int8_t seg_count
, temp_array
[8];
338 int32_t match_count
, i
, j
, seg_desc_start
= 0x1806, temp_address
;
339 int32_t seg_found
, temp
;
343 status
= psvc_get_attr(hdlp
, id
, PSVC_PRESENCE_ATTR
, &present
);
344 if ((status
!= PSVC_SUCCESS
) || (present
!= PSVC_PRESENT
))
347 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_MATCHES_ATTR
, &match_count
,
349 if (status
== PSVC_FAILURE
)
352 for (i
= 0; i
< match_count
; i
++) {
354 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_ID_ATTR
,
356 if (status
!= PSVC_SUCCESS
)
359 fru_data
.buf_start
= 0x1805;
360 fru_data
.buf
= (char *)&seg_count
;
361 fru_data
.read_size
= 1;
363 status
= psvc_get_attr(hdlp
, fru
, PSVC_FRU_INFO_ATTR
,
365 if (status
!= PSVC_SUCCESS
) {
368 for (j
= 0; (j
< seg_count
) && (!seg_found
); j
++) {
369 fru_data
.buf_start
= seg_desc_start
;
370 fru_data
.buf
= seg_name
;
371 fru_data
.read_size
= 2;
373 status
= psvc_get_attr(hdlp
, fru
, PSVC_FRU_INFO_ATTR
,
376 seg_desc_start
= seg_desc_start
+ 2;
377 fru_data
.buf_start
= seg_desc_start
;
378 fru_data
.buf
= (char *)&segment
;
379 fru_data
.read_size
= sizeof (seg_desc_t
);
381 status
= psvc_get_attr(hdlp
, fru
, PSVC_FRU_INFO_ATTR
,
383 if (status
!= PSVC_SUCCESS
) {
385 "Failed psvc_get_attr for FRU info\n");
388 seg_desc_start
= seg_desc_start
+ sizeof (seg_desc_t
);
389 if (memcmp(seg_name
, "SC", 2) == 0)
393 temp_address
= segment
.segoffset
+ offset
;
394 fru_data
.buf_start
= temp_address
;
395 fru_data
.buf
= (char *)&temp_array
;
396 fru_data
.read_size
= sizeof (temp_array
);
397 status
= psvc_get_attr(hdlp
, fru
, PSVC_FRU_INFO_ATTR
,
399 if (status
!= PSVC_SUCCESS
) {
401 "Failed psvc_get_attr for FRU info\n");
404 for (j
= 0; j
< sizeof (temp_array
); j
++) {
405 if (threshold_names
[j
] ==
408 temp
= temp_array
[j
];
409 status
= psvc_set_attr(hdlp
, id
,
410 threshold_names
[j
], &temp
);
411 if (status
!= PSVC_SUCCESS
) {
417 syslog(LOG_ERR
, "No FRU Information for %s"
418 " using default temperatures\n", id
);
425 psvc_fan_init_speed_0(psvc_opaque_t hdlp
, char *id
)
427 int32_t status
= PSVC_SUCCESS
;
430 int32_t init_speed
= 0;
432 status
= psvc_get_attr(hdlp
, id
, PSVC_PRESENCE_ATTR
, &present
);
433 if ((status
!= PSVC_SUCCESS
) || (present
!= PSVC_PRESENT
))
436 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_ID_ATTR
, &control_id
,
437 PSVC_FAN_DRIVE_CONTROL
, 0);
438 if (status
!= PSVC_SUCCESS
)
441 status
= psvc_set_attr(hdlp
, control_id
, PSVC_CONTROL_VALUE_ATTR
,
443 if (status
== PSVC_FAILURE
) {
444 syslog(LOG_ERR
, SET_FANSPEED_FAILED_MSG
, control_id
, errno
);
452 psvc_update_setpoint_0(psvc_opaque_t hdlp
, char *id
)
454 int32_t status
= PSVC_SUCCESS
;
456 int32_t match_count
, i
, temp
;
457 int16_t lowest_temp
= 500;
460 status
= psvc_get_attr(hdlp
, id
, PSVC_PRESENCE_ATTR
, &present
);
461 if ((status
!= PSVC_SUCCESS
) || (present
!= PSVC_PRESENT
))
464 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_MATCHES_ATTR
, &match_count
,
465 PSVC_DEV_TEMP_SENSOR
);
466 if (status
== PSVC_FAILURE
)
469 for (i
= 0; i
< match_count
; i
++) {
470 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_ID_ATTR
,
471 &temp_sensor
, PSVC_DEV_TEMP_SENSOR
, i
);
472 if (status
!= PSVC_SUCCESS
)
474 status
= psvc_get_attr(hdlp
, temp_sensor
,
475 PSVC_OPTIMAL_TEMP_ATTR
, &temp
);
476 if (status
!= PSVC_SUCCESS
) {
477 syslog(LOG_ERR
, "Failed to get Optimal temp for %s\n",
481 if (temp
< lowest_temp
)
484 status
= psvc_set_attr(hdlp
, id
, PSVC_SETPOINT_ATTR
, &lowest_temp
);
485 if (status
== PSVC_FAILURE
) {
486 syslog(LOG_ERR
, "Failed to change setpoint for %s\n", id
);
493 psvc_remove_missing_nodes_0(psvc_opaque_t hdlp
, char *id
)
495 int32_t status
= PSVC_SUCCESS
;
498 int32_t i
, device_count
;
499 char parent_path
[256];
500 picl_nodehdl_t child_node
;
503 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_MATCHES_ATTR
,
504 &device_count
, PSVC_PHYSICAL_DEVICE
);
505 if (status
== PSVC_FAILURE
)
508 for (i
= 0; i
< device_count
; i
++) {
509 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_ID_ATTR
,
510 &physical_dev
, PSVC_PHYSICAL_DEVICE
, i
);
511 if (status
!= PSVC_SUCCESS
)
513 if (strncmp(physical_dev
, "LTC1427", 7) == 0)
515 status
= psvc_get_attr(hdlp
, physical_dev
,
516 PSVC_PROBE_RESULT_ATTR
, state
);
517 if (status
!= PSVC_SUCCESS
)
519 status
= psvc_get_attr(hdlp
, physical_dev
, PSVC_PRESENCE_ATTR
,
521 if (status
== PSVC_FAILURE
) {
522 syslog(LOG_ERR
, GET_PRESENCE_FAILED_MSG
, physical_dev
,
527 if ((strcmp(state
, PSVC_ERROR
) == 0) &&
528 (present
== PSVC_PRESENT
)) {
529 /* convert name to node, and parent path */
530 psvcplugin_lookup(physical_dev
, parent_path
,
533 ptree_delete_node(child_node
);
540 psvc_check_ps_hotplug_status_0(psvc_opaque_t hdlp
, char *id
)
542 char fail_valid_switch_id
[PICL_PROPNAMELEN_MAX
];
543 int32_t status
= PSVC_SUCCESS
;
544 char valid_switch_state
[32];
545 char state
[32], fault
[32];
546 int32_t led_count
, j
;
550 static int8_t hotplug_failed_count
= 0;
551 static int unplugged_ps
= 0;
555 status
= psvc_get_attr(hdlp
, id
, PSVC_PRESENCE_ATTR
, &present
);
556 if (status
== PSVC_FAILURE
) {
557 syslog(LOG_ERR
, GET_PRESENCE_FAILED_MSG
, id
, errno
);
561 if (present
== PSVC_ABSENT
) {
563 return (PSVC_FAILURE
);
566 snprintf(fail_valid_switch_id
, sizeof (fail_valid_switch_id
), "%s%s",
567 id
, "_SENSOR_VALID_SWITCH");
572 (void) sleep(retry_sleep_pshp_status
);
573 status
= psvc_get_attr(hdlp
, fail_valid_switch_id
,
574 PSVC_STATE_ATTR
, valid_switch_state
);
575 if (status
== PSVC_FAILURE
) {
576 if (hotplug_failed_count
== 0) {
578 * First time the get_attr call failed
579 * set count so that if we fail again
582 hotplug_failed_count
= 1;
584 * We probably failed because the power
585 * supply was just insterted or removed
586 * before the get_attr call. We then
587 * return from this policy successfully
588 * knowing it will be run again shortly
589 * with the right PS state.
591 return (PSVC_SUCCESS
);
594 * We have failed before and so this
595 * we will consider a hardware problem
596 * and it should be reported
599 "Failed getting %s State: ",
600 "ps_hotplug_status_0\n",
601 fail_valid_switch_id
);
606 * Because we have successfully gotten a value from
607 * the i2c device on the PS we will set the
610 hotplug_failed_count
= 0;
612 status
= psvc_get_attr(hdlp
, id
, PSVC_STATE_ATTR
, state
);
613 if (status
== PSVC_FAILURE
)
617 * check to see if we need to retry. the conditions are:
619 * valid_switch_state state retry
620 * --------------------------------------------------
621 * PSVC_OFF !PSVC_HOTPLUGGED yes
622 * PSVC_ON PSVC_HOTPLUGGED yes
623 * PSVC_OFF PSVC_HOTPLUGGED no
624 * PSVC_ON !PSVC_HOTPLUGGED no
626 } while ((retry
< n_retry_pshp_status
) &&
627 change_of_state_str(valid_switch_state
, PSVC_OFF
,
628 state
, PSVC_HOTPLUGGED
));
630 if ((strcmp(valid_switch_state
, PSVC_OFF
) == 0) &&
631 (strcmp(state
, PSVC_HOTPLUGGED
) != 0)) {
632 strcpy(state
, PSVC_HOTPLUGGED
);
633 strcpy(fault
, PSVC_NO_FAULT
);
634 strcpy(led_state
, PSVC_LED_OFF
);
635 status
= psvc_set_attr(hdlp
, id
, PSVC_STATE_ATTR
,
637 if (status
== PSVC_FAILURE
)
639 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_MATCHES_ATTR
,
640 &led_count
, PSVC_DEV_FAULT_LED
);
641 if (status
== PSVC_FAILURE
)
644 for (j
= 0; j
< led_count
; j
++) {
646 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_ID_ATTR
,
647 &led_id
, PSVC_DEV_FAULT_LED
, j
);
648 if (status
!= PSVC_SUCCESS
)
651 status
= psvc_set_attr(hdlp
, led_id
,
652 PSVC_LED_STATE_ATTR
, led_state
);
653 if (status
!= PSVC_SUCCESS
) {
654 syslog(LOG_ERR
, SET_LED_FAILED_MSG
, led_id
,
660 strcpy(led_state
, PSVC_LED_ON
);
661 status
= psvc_set_attr(hdlp
, "FSP_POWER_FAULT_LED",
662 PSVC_LED_STATE_ATTR
, led_state
);
663 if (status
!= PSVC_SUCCESS
) {
664 syslog(LOG_ERR
, SET_LED_FAILED_MSG
, led_id
, errno
);
667 unplugged_id
= id
+ 2;
668 unplugged_ps
= unplugged_ps
| (1 << (int)strtol(unplugged_id
,
670 status
= update_gen_fault_led(hdlp
, GEN_FAULT_LED
);
671 syslog(LOG_ERR
, PS_UNPLUGGED_MSG
, id
);
675 if ((strcmp(valid_switch_state
, PSVC_ON
) == 0) &&
676 (strcmp(state
, PSVC_HOTPLUGGED
) == 0)) {
677 strcpy(state
, PSVC_OK
);
678 strcpy(fault
, PSVC_NO_FAULT
);
679 status
= psvc_set_attr(hdlp
, id
, PSVC_STATE_ATTR
, state
);
680 if (status
== PSVC_FAILURE
)
682 unplugged_id
= id
+ 2;
683 unplugged_ps
= unplugged_ps
^ (1 << (int)strtol(unplugged_id
,
685 if (unplugged_ps
== 0) {
686 strcpy(led_state
, PSVC_LED_OFF
);
687 status
= psvc_set_attr(hdlp
, "FSP_POWER_FAULT_LED",
688 PSVC_LED_STATE_ATTR
, led_state
);
689 if (status
!= PSVC_SUCCESS
) {
690 syslog(LOG_ERR
, SET_LED_FAILED_MSG
, led_id
,
694 status
= update_gen_fault_led(hdlp
, GEN_FAULT_LED
);
696 syslog(LOG_ERR
, PS_PLUGGED_MSG
, id
);
703 psvc_ps_overcurrent_check_policy_0(psvc_opaque_t hdlp
, char *system
)
705 int32_t status
= PSVC_SUCCESS
;
707 static char *sensor_id
[DAKTARI_MAX_PS
][DAK_MAX_PS_I_SENSORS
];
708 static char *power_supply_id
[DAKTARI_MAX_PS
] = {NULL
};
710 int32_t amps
, oc_flag
= 0, ps_present
= 0;
711 static int32_t hi_warn
[DAKTARI_MAX_PS
][DAK_MAX_PS_I_SENSORS
];
713 static int8_t overcurrent_failed_check
= 0;
714 static int threshold_counter
= 0;
716 if (power_supply_id
[0] == NULL
) {
717 for (i
= 0; i
< DAKTARI_MAX_PS
; i
++) {
718 status
= psvc_get_attr(hdlp
, system
,
719 PSVC_ASSOC_ID_ATTR
, &(power_supply_id
[i
]),
721 if (status
!= PSVC_SUCCESS
)
723 for (j
= 0; j
< DAK_MAX_PS_I_SENSORS
; ++j
) {
724 status
= psvc_get_attr(hdlp
,
725 power_supply_id
[i
], PSVC_ASSOC_ID_ATTR
,
726 &(sensor_id
[i
][j
]), PSVC_PS_I_SENSOR
, j
);
727 if (status
!= PSVC_SUCCESS
)
729 status
= psvc_get_attr(hdlp
, sensor_id
[i
][j
],
730 PSVC_HI_WARN_ATTR
, &(hi_warn
[i
][j
]));
731 if (status
!= PSVC_SUCCESS
)
737 for (i
= 0; i
< DAKTARI_MAX_PS
; i
++) {
738 status
= psvc_get_attr(hdlp
, power_supply_id
[i
],
739 PSVC_PRESENCE_ATTR
, &present
);
740 if (status
== PSVC_FAILURE
) {
741 syslog(LOG_ERR
, GET_PRESENCE_FAILED_MSG
,
742 power_supply_id
[i
], errno
);
746 if (present
== PSVC_ABSENT
) {
750 status
= psvc_check_ps_hotplug_status_0(hdlp
,
752 if (status
== PSVC_FAILURE
)
755 status
= psvc_get_attr(hdlp
, power_supply_id
[i
],
756 PSVC_STATE_ATTR
, state
);
757 if (status
== PSVC_FAILURE
)
760 if (strcmp(state
, PSVC_HOTPLUGGED
) == 0) {
766 for (j
= 0; j
< DAK_MAX_PS_I_SENSORS
; ++j
) {
767 status
= psvc_get_attr(hdlp
, sensor_id
[i
][j
],
768 PSVC_SENSOR_VALUE_ATTR
, &s
);
769 if (status
!= PSVC_SUCCESS
) {
770 if (overcurrent_failed_check
== 0) {
772 * First time the get_attr call
773 * failed set count so that if we
774 * fail again we will know
776 overcurrent_failed_check
= 1;
778 * We probably failed because the power
779 * supply was just insterted or removed
780 * before the get_attr call. We then
781 * return from this policy successfully
782 * knowing it will be run again shortly
783 * with the right PS state.
785 return (PSVC_SUCCESS
);
788 * We have failed before and so this we
789 * will consider a hardware problem and
790 * it should be reported.
793 "Failed getting %s sensor value",
799 * Because we have successfully gotten a value from the
800 * i2c device on the PS we will set the failed_count
803 overcurrent_failed_check
= 0;
805 if (amps
>= hi_warn
[i
][j
]) {
813 * Because we observed an overcurrent
814 * condition, we increment threshold_counter.
815 * Once threshold_counter reaches the value
816 * of n_read_overcurrent we log the event.
819 if (threshold_counter
== n_read_overcurrent
) {
820 threshold_counter
= 0;
821 if (ps_present
== 1) {
822 syslog(LOG_ERR
, PS_OVER_CURRENT_MSG
);
823 syslog(LOG_ERR
, ADD_PS_MSG
);
825 syslog(LOG_ERR
, PS_OVER_CURRENT_MSG
);
826 syslog(LOG_ERR
, REMOVE_LOAD_MSG
);
830 threshold_counter
= 0;
833 return (PSVC_SUCCESS
);
837 psvc_ps_undercurrent_check(psvc_opaque_t hdlp
, char *id
, int32_t *uc_flag
)
839 int32_t status
= PSVC_SUCCESS
;
841 static char *sensor_id
[DAK_MAX_PS_I_SENSORS
];
844 static int32_t lo_warn
[DAK_MAX_PS_I_SENSORS
];
845 static int8_t undercurrent_failed_check
= 0;
847 status
= psvc_get_attr(hdlp
, id
, PSVC_PRESENCE_ATTR
, &present
);
848 if (status
== PSVC_FAILURE
) {
849 syslog(LOG_ERR
, GET_PRESENCE_FAILED_MSG
, id
, errno
);
853 if (present
== PSVC_ABSENT
) {
855 return (PSVC_FAILURE
);
858 for (j
= 0; j
< DAK_MAX_PS_I_SENSORS
; ++j
) {
859 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_ID_ATTR
,
860 &(sensor_id
[j
]), PSVC_PS_I_SENSOR
, j
);
861 if (status
!= PSVC_SUCCESS
)
863 status
= psvc_get_attr(hdlp
, sensor_id
[j
],
864 PSVC_LO_WARN_ATTR
, &(lo_warn
[j
]));
865 if (status
!= PSVC_SUCCESS
)
870 for (j
= 0; j
< DAK_MAX_PS_I_SENSORS
; ++j
) {
871 status
= psvc_get_attr(hdlp
, sensor_id
[j
],
872 PSVC_SENSOR_VALUE_ATTR
, &s
);
873 if (status
!= PSVC_SUCCESS
) {
874 if (undercurrent_failed_check
== 0) {
876 * First time the get_attr call
877 * failed set count so that if we
878 * fail again we will know.
880 undercurrent_failed_check
= 1;
882 * We probably failed because the power
883 * supply was just inserted or removed
884 * before the get_attr call. We then
885 * return from this policy successfully
886 * knowing it will be run again shortly
887 * with the right PS state.
889 return (PSVC_SUCCESS
);
892 * Repeated failures are logged.
895 "Failed getting %s sensor value",
901 * Because we have successfully gotten a value from the
902 * i2c device on the PS we will set the failed_count
905 undercurrent_failed_check
= 0;
907 if (amps
<= lo_warn
[j
]) {
909 return (PSVC_SUCCESS
);
913 return (PSVC_SUCCESS
);
917 psvc_ps_device_fail_notifier_policy_0(psvc_opaque_t hdlp
, char *system
)
919 static char *ps_id
[DAKTARI_MAX_PS
] = {NULL
};
920 static char *sensor_id
[DAKTARI_MAX_PS
][DAK_MAX_FAULT_SENSORS
];
921 char *led_id
= "FSP_POWER_FAULT_LED";
923 char state
[32], fault
[32], previous_state
[32], past_state
[32];
925 char bad_sensors
[DAK_MAX_FAULT_SENSORS
][256];
926 static int threshold_counter
[DAKTARI_MAX_PS
];
927 int32_t status
= PSVC_SUCCESS
;
930 static int8_t device_fail_failed_check
= 0;
931 int retry
, should_retry
;
933 if (ps_id
[0] == NULL
) {
934 for (i
= 0; i
< DAKTARI_MAX_PS
; i
++) {
935 status
= psvc_get_attr(hdlp
, system
,
936 PSVC_ASSOC_ID_ATTR
, &(ps_id
[i
]), PSVC_PS
, i
);
937 if (status
!= PSVC_SUCCESS
)
939 for (j
= 0; j
< DAK_MAX_FAULT_SENSORS
; j
++) {
940 status
= psvc_get_attr(hdlp
, ps_id
[i
],
941 PSVC_ASSOC_ID_ATTR
, &(sensor_id
[i
][j
]),
942 PSVC_DEV_FAULT_SENSOR
, j
);
943 if (status
!= PSVC_SUCCESS
)
949 for (i
= 0; i
< DAKTARI_MAX_PS
; i
++) {
951 status
= psvc_get_attr(hdlp
, ps_id
[i
], PSVC_PRESENCE_ATTR
,
953 if (status
== PSVC_FAILURE
)
956 if (present
== PSVC_ABSENT
) {
958 return (PSVC_FAILURE
);
961 status
= psvc_check_ps_hotplug_status_0(hdlp
, ps_id
[i
]);
962 if (status
== PSVC_FAILURE
)
965 status
= psvc_get_attr(hdlp
, ps_id
[i
], PSVC_STATE_ATTR
,
967 if (status
== PSVC_FAILURE
)
970 if (strcmp(past_state
, PSVC_HOTPLUGGED
) == 0) {
971 return (PICL_SUCCESS
);
977 (void) sleep(retry_sleep_devicefail
);
980 for (j
= 0; j
< DAK_MAX_FAULT_SENSORS
; ++j
) {
981 status
= psvc_get_attr(hdlp
, sensor_id
[i
][j
],
982 PSVC_SWITCH_STATE_ATTR
, state
);
983 if (status
!= PSVC_SUCCESS
) {
984 if (device_fail_failed_check
== 0) {
986 * First time the get_attr call
987 * failed set count so that
988 * if we fail again we will know
990 device_fail_failed_check
= 1;
992 * We probably failed because
993 * the power supply was just
994 * insterted or removed before
995 * the get_attr call. We then
996 * return from this policy
997 * successfully knowing it will
998 * be run again shortly
999 * with the right PS state.
1001 return (PSVC_SUCCESS
);
1004 * We have failed before and
1005 * so this we will consider a
1006 * hardware problem and
1007 * it should be reported.
1009 syslog(LOG_ERR
, "Failed in "
1010 "getting sensor state for "
1011 "%s\n", sensor_id
[i
][j
]);
1018 * Because we have successfully gotten
1019 * a value from the i2c device on the
1020 * PS we will set the failed_count to 0.
1022 device_fail_failed_check
= 0;
1025 * If we find that the sensor is on we
1026 * fill in the name of the sensor in
1027 * the bad_sensor array. If the sensor
1028 * is off we use EMPTY_STRING as a check
1029 * later on as to when NOT to print out
1030 * what is in bad_sensor[].
1032 if (strcmp(state
, PSVC_SWITCH_ON
) == 0) {
1034 strlcpy(bad_sensors
[j
], sensor_id
[i
][j
],
1035 sizeof (bad_sensors
[j
]));
1037 strcpy(bad_sensors
[j
], EMPTY_STRING
);
1042 * check to see if we need to retry. the conditions are:
1044 * fail_state past_state retry
1045 * --------------------------------------------------
1051 if ((fail_state
> 0) &&
1052 (strcmp(past_state
, PSVC_OK
) == 0)) {
1054 } else if ((fail_state
== 0) &&
1055 (strcmp(past_state
, PSVC_ERROR
) == 0)) {
1058 } while ((retry
< n_retry_devicefail
) && should_retry
);
1060 /* Under current check */
1061 status
= psvc_ps_undercurrent_check(hdlp
, ps_id
[i
], &uc_flag
);
1063 if (status
!= PSVC_FAILURE
) {
1066 * Because we observed an undercurrent
1067 * condition, we increment threshold counter.
1068 * Once threshold counter reaches the value
1069 * of n_read_undercurrent we log the event.
1071 threshold_counter
[i
]++;
1072 if (threshold_counter
[i
] >=
1073 n_read_undercurrent
) {
1075 syslog(LOG_ERR
, PS_UNDER_CURRENT_MSG
,
1079 threshold_counter
[i
] = 0;
1083 if (fail_state
!= 0) {
1084 strcpy(state
, PSVC_ERROR
);
1085 strcpy(fault
, PSVC_GEN_FAULT
);
1087 strcpy(state
, PSVC_OK
);
1088 strcpy(fault
, PSVC_NO_FAULT
);
1091 status
= psvc_set_attr(hdlp
, ps_id
[i
], PSVC_STATE_ATTR
, state
);
1092 if (status
!= PSVC_SUCCESS
)
1095 status
= psvc_set_attr(hdlp
, ps_id
[i
], PSVC_FAULTID_ATTR
,
1097 if (status
!= PSVC_SUCCESS
)
1100 status
= psvc_get_attr(hdlp
, ps_id
[i
], PSVC_PREV_STATE_ATTR
,
1102 if (status
!= PSVC_SUCCESS
)
1105 if (strcmp(state
, previous_state
) != 0) {
1108 psvc_get_attr(hdlp
, ps_id
[i
], PSVC_LABEL_ATTR
,
1111 if (strcmp(state
, PSVC_ERROR
) == 0) {
1112 syslog(LOG_ERR
, DEVICE_FAILURE_MSG
, dev_label
);
1113 for (j
= 0; j
< DAK_MAX_FAULT_SENSORS
; ++j
) {
1114 if (strcmp(bad_sensors
[j
],
1116 syslog(LOG_ERR
, "%s\n",
1119 strcpy(led_state
, PSVC_LED_ON
);
1121 syslog(LOG_ERR
, DEVICE_OK_MSG
, dev_label
);
1122 strcpy(led_state
, PSVC_LED_OFF
);
1125 status
= psvc_set_attr(hdlp
, led_id
,
1126 PSVC_LED_STATE_ATTR
, led_state
);
1127 if (status
!= PSVC_SUCCESS
) {
1128 syslog(LOG_ERR
, SET_LED_FAILED_MSG
, led_id
,
1135 return (PSVC_SUCCESS
);
1139 psvc_ps_check_and_disable_dr_policy_0(psvc_opaque_t hdlp
, char *id
)
1142 static char *name
[DAKTARI_MAX_PS
] = {NULL
};
1148 char dev_path
[sizeof (HPC3130_DEV
)+8];
1149 unsigned char controller_names
[HPC3130_CONTROLLERS
] =
1150 { 0xe2, 0xe6, 0xe8, 0xec };
1152 if (name
[0] == NULL
) {
1153 for (i
= 0; i
< DAKTARI_MAX_PS
; i
++) {
1154 rv
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_ID_ATTR
,
1155 &(name
[i
]), PSVC_PS
, i
);
1156 if (rv
!= PSVC_SUCCESS
)
1162 * Go through the power supplies to make sure they're present
1165 ps_cnt
= DAKTARI_MAX_PS
;
1166 for (i
= 0; i
< DAKTARI_MAX_PS
; i
++) {
1167 rv
= psvc_get_attr(hdlp
, name
[i
], PSVC_PRESENCE_ATTR
,
1169 if (rv
!= PSVC_SUCCESS
)
1172 if (present
!= PSVC_PRESENT
) {
1176 rv
= psvc_get_attr(hdlp
, name
[i
], PSVC_STATE_ATTR
,
1178 if (rv
!= PSVC_SUCCESS
)
1181 if (strcmp(state
, PSVC_OK
))
1187 * No change in DR configuration is needed if the new power supply
1188 * count equals the current count.
1190 if (ps_cnt
== co_ps
)
1191 return (PSVC_SUCCESS
);
1194 * Disable DR when hotplugged down to 1 power supply; enable DR when
1195 * hotplugged up from 1 supply.
1198 if ((co_ps
== 0 || co_ps
> 1) && ps_cnt
!= 1) {
1200 return (PSVC_SUCCESS
);
1202 dr_conf
= (ps_cnt
== 1 ? HPC3130_DR_DISABLE
: HPC3130_DR_ENABLE
);
1205 for (i
= 0; i
< HPC3130_CONTROLLERS
; i
++) {
1206 for (j
= 0; j
< HPC3130_SLOTS
; j
++) {
1207 (void) snprintf(dev_path
, sizeof (dev_path
),
1208 HPC3130_DEV
, controller_names
[i
], j
);
1209 fd
= open(dev_path
, O_RDWR
);
1211 return (PSVC_FAILURE
);
1213 rv
= ioctl(fd
, HPC3130_CONF_DR
, &dr_conf
);
1216 return (PSVC_FAILURE
);
1220 return (PSVC_SUCCESS
);
1224 psvc_fan_blast_shutoff_policy_0(psvc_opaque_t hdlp
, char *id
)
1226 char switch_status
[32];
1227 int32_t status
= PSVC_SUCCESS
;
1229 status
= psvc_get_attr(hdlp
, id
, PSVC_SWITCH_STATE_ATTR
, switch_status
);
1230 if (status
!= PSVC_SUCCESS
)
1232 status
= psvc_set_attr(hdlp
, id
, PSVC_SWITCH_STATE_ATTR
,
1234 if (status
!= PSVC_SUCCESS
)
1236 status
= psvc_set_attr(hdlp
, id
, PSVC_SWITCH_STATE_ATTR
,
1238 if (status
!= PSVC_SUCCESS
)
1240 status
= psvc_set_attr(hdlp
, id
, PSVC_SWITCH_STATE_ATTR
,
1247 psvc_fan_fault_check_policy_0(psvc_opaque_t hdlp
, char *system
)
1249 static char *fan_id
[DAK_MAX_FANS
] = {NULL
};
1252 int32_t status
= PSVC_SUCCESS
;
1254 static int threshold_counter
= 0;
1256 if (fan_id
[0] == NULL
) {
1257 for (r
= 0; r
< DAK_MAX_FANS
; r
++) {
1258 status
= psvc_get_attr(hdlp
, system
,
1259 PSVC_ASSOC_ID_ATTR
, &(fan_id
[r
]), PSVC_FAN
, r
);
1260 if (status
!= PSVC_SUCCESS
)
1265 for (r
= 0; r
< DAK_MAX_FANS
; r
++) {
1266 status
= psvc_get_attr(hdlp
, fan_id
[r
], PSVC_ENABLE_ATTR
,
1268 if (status
!= PSVC_SUCCESS
)
1271 if (enabled
== PSVC_ENABLED
) {
1274 char switch_state
[32], fan_state
[32];
1275 int fan_count
, fans
;
1277 char fstate
[32], ffault
[32];
1280 * If any other fan on the fan tray has an ERROR state,
1281 * mark this fan bad and return
1283 psvc_get_attr(hdlp
, fan_id
[r
], PSVC_ASSOC_MATCHES_ATTR
,
1284 &fan_count
, PSVC_FAN_TRAY_FANS
);
1285 for (fans
= 0; fans
< fan_count
; ++fans
) {
1286 status
= psvc_get_attr(hdlp
, fan_id
[r
],
1287 PSVC_ASSOC_ID_ATTR
, &other_fan_id
,
1288 PSVC_FAN_TRAY_FANS
, fans
);
1289 if (status
== PSVC_FAILURE
)
1291 status
= psvc_get_attr(hdlp
, other_fan_id
,
1292 PSVC_STATE_ATTR
, fan_state
);
1293 if (status
!= PSVC_SUCCESS
)
1296 if (strcmp(fan_state
, PSVC_ERROR
) == 0) {
1297 strlcpy(ffault
, PSVC_GEN_FAULT
,
1299 status
= psvc_set_attr(hdlp
, fan_id
[r
],
1300 PSVC_FAULTID_ATTR
, ffault
);
1301 if (status
!= PSVC_SUCCESS
)
1304 strlcpy(fstate
, PSVC_ERROR
,
1306 status
= psvc_set_attr(hdlp
, fan_id
[r
],
1307 PSVC_STATE_ATTR
, fstate
);
1314 * Select tachometer for IO or CPU primary/secondary
1317 pthread_mutex_lock(&fan_mutex
);
1319 status
= psvc_get_attr(hdlp
, fan_id
[r
],
1320 PSVC_ASSOC_ID_ATTR
, &switch_id
,
1321 PSVC_FAN_PRIM_SEC_SELECTOR
, 0);
1323 if (status
!= PSVC_FAILURE
) {
1324 status
= psvc_get_attr(hdlp
, fan_id
[r
],
1325 PSVC_FEATURES_ATTR
, &features
);
1326 if (status
== PSVC_FAILURE
) {
1327 pthread_mutex_unlock(&fan_mutex
);
1331 if (features
& PSVC_DEV_PRIMARY
)
1332 strlcpy(switch_state
, PSVC_SWITCH_ON
,
1333 sizeof (switch_state
));
1335 strlcpy(switch_state
, PSVC_SWITCH_OFF
,
1336 sizeof (switch_state
));
1337 status
= psvc_set_attr(hdlp
, switch_id
,
1338 PSVC_SWITCH_STATE_ATTR
, switch_state
);
1339 if (status
== PSVC_FAILURE
) {
1340 pthread_mutex_unlock(&fan_mutex
);
1344 /* allow time for speed to be determined */
1345 (void) poll(NULL
, 0, 250);
1348 status
= psvc_get_attr(hdlp
, fan_id
[r
],
1349 PSVC_SENSOR_VALUE_ATTR
, &speed
);
1350 if (status
!= PSVC_SUCCESS
) {
1351 pthread_mutex_unlock(&fan_mutex
);
1355 pthread_mutex_unlock(&fan_mutex
);
1358 threshold_counter
++;
1359 if (threshold_counter
==
1367 char state
[32], fault
[32];
1369 threshold_counter
= 0;
1370 strlcpy(fault
, PSVC_GEN_FAULT
,
1372 status
= psvc_set_attr(hdlp
, fan_id
[r
],
1373 PSVC_FAULTID_ATTR
, fault
);
1374 if (status
!= PSVC_SUCCESS
)
1377 strlcpy(state
, PSVC_ERROR
,
1379 status
= psvc_set_attr(hdlp
, fan_id
[r
],
1380 PSVC_STATE_ATTR
, state
);
1381 if (status
!= PSVC_SUCCESS
)
1384 status
= psvc_get_attr(hdlp
, fan_id
[r
],
1385 PSVC_LABEL_ATTR
, label
);
1386 if (status
!= PSVC_SUCCESS
)
1389 syslog(LOG_ERR
, DEVICE_FAILURE_MSG
,
1392 /* turn on fault LEDs */
1393 psvc_get_attr(hdlp
, fan_id
[r
],
1394 PSVC_ASSOC_MATCHES_ATTR
, &led_count
,
1395 PSVC_DEV_FAULT_LED
);
1396 strlcpy(led_state
, PSVC_LED_ON
,
1397 sizeof (led_state
));
1398 for (i
= 0; i
< led_count
; ++i
) {
1399 status
= psvc_get_attr(hdlp
,
1401 PSVC_ASSOC_ID_ATTR
, &led_id
,
1402 PSVC_DEV_FAULT_LED
, i
);
1403 if (status
== PSVC_FAILURE
)
1406 status
= psvc_set_attr(hdlp
,
1407 led_id
, PSVC_LED_STATE_ATTR
,
1409 if (status
== PSVC_FAILURE
)
1413 /* turn on OK to remove LEDs */
1415 status
= psvc_get_attr(hdlp
, fan_id
[r
],
1416 PSVC_ASSOC_ID_ATTR
, &slot_id
,
1418 if (status
!= PSVC_SUCCESS
)
1421 psvc_get_attr(hdlp
, slot_id
,
1422 PSVC_ASSOC_MATCHES_ATTR
, &led_count
,
1423 PSVC_SLOT_REMOVE_LED
);
1424 strlcpy(led_state
, PSVC_LED_ON
,
1425 sizeof (led_state
));
1426 for (i
= 0; i
< led_count
; ++i
) {
1427 status
= psvc_get_attr(hdlp
,
1429 PSVC_ASSOC_ID_ATTR
, &led_id
,
1430 PSVC_SLOT_REMOVE_LED
, i
);
1431 if (status
== PSVC_FAILURE
)
1434 status
= psvc_set_attr(hdlp
,
1435 led_id
, PSVC_LED_STATE_ATTR
,
1437 if (status
== PSVC_FAILURE
)
1445 return (PSVC_SUCCESS
);
1449 * This routine takes in the PSVC handle pointer, the PS name, and the
1450 * instance number (0, 1, or 2). It simply make a psvc_get call to get the
1451 * presence of each of the children under the PS. This call will set the
1452 * presence state of the child device if it was not there when the system
1456 handle_ps_hotplug_children_presence(psvc_opaque_t hdlp
, char *id
)
1459 char fail_valid_switch_id
[PICL_PROPNAMELEN_MAX
];
1460 int32_t status
= PSVC_SUCCESS
;
1464 /* Get the Sensor Valid Switch presence */
1465 snprintf(fail_valid_switch_id
, sizeof (fail_valid_switch_id
), "%s%s",
1466 id
, "_SENSOR_VALID_SWITCH");
1468 status
= psvc_get_attr(hdlp
, fail_valid_switch_id
, PSVC_PRESENCE_ATTR
,
1470 if (status
!= PSVC_SUCCESS
)
1473 /* Go through each PS's fault sensors */
1474 for (j
= 0; j
< DAK_MAX_FAULT_SENSORS
; j
++) {
1475 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_ID_ATTR
,
1476 &(sensor_id
), PSVC_DEV_FAULT_SENSOR
, j
);
1477 if (status
!= PSVC_SUCCESS
)
1479 status
= psvc_get_attr(hdlp
, sensor_id
, PSVC_PRESENCE_ATTR
,
1481 if (status
!= PSVC_SUCCESS
)
1485 /* Go through each PS's current sensors */
1486 for (j
= 0; j
< DAK_MAX_PS_I_SENSORS
; ++j
) {
1487 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_ID_ATTR
,
1488 &(sensor_id
), PSVC_PS_I_SENSOR
, j
);
1489 if (status
!= PSVC_SUCCESS
)
1491 status
= psvc_get_attr(hdlp
, sensor_id
, PSVC_PRESENCE_ATTR
,
1493 if (status
!= PSVC_SUCCESS
)
1498 /* Go through each PS's onboard i2c hardware */
1499 for (j
= 0; j
< 3; j
++) {
1500 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_ID_ATTR
,
1501 &(sensor_id
), PSVC_PHYSICAL_DEVICE
, j
);
1502 if (status
!= PSVC_SUCCESS
)
1504 status
= psvc_get_attr(hdlp
, sensor_id
, PSVC_PRESENCE_ATTR
,
1506 if (status
!= PSVC_SUCCESS
)
1513 static i2c_hp_t devices
[3][3] = {
1514 {{{0, 0x90}, "adio", "i2c-pcf8591"}, {{0, 0x70}, "ioexp", "i2c-pcf8574"},
1515 {{0, 0xa0}, "fru", "i2c-at24c64"}},
1516 {{{0, 0x92}, "adio", "i2c-pcf8591"}, {{0, 0x72}, "ioexp", "i2c-pcf8574"},
1517 {{0, 0xa2}, "fru", "i2c-at24c64"}},
1518 {{{0, 0x94}, "adio", "i2c-pcf8591"}, {{0, 0x74}, "ioexp", "i2c-pcf8574"},
1519 {{0, 0xa4}, "fru", "i2c-at24c64"}},
1523 psvc_ps_hotplug_policy_0(psvc_opaque_t hdlp
, char *id
)
1525 boolean_t presence
, previous_presence
;
1526 int32_t status
= PSVC_SUCCESS
;
1527 char label
[32], state
[32], fault
[32];
1528 int32_t ps_instance
, led_count
;
1529 char *switch_id
, *led_id
;
1531 picl_nodehdl_t parent_node
;
1532 char parent_path
[256], ps_path
[256];
1533 picl_nodehdl_t child_node
;
1534 devctl_hdl_t bus_handle
, dev_handle
;
1535 devctl_ddef_t ddef_hdl
;
1536 char pcf8574_devpath
[256], pcf8591_devpath
[256], fru_devpath
[256];
1539 status
= psvc_get_attr(hdlp
, id
, PSVC_PREV_PRESENCE_ATTR
,
1540 &previous_presence
);
1541 if (status
!= PSVC_SUCCESS
)
1547 (void) sleep(retry_sleep_pshp
);
1549 status
= psvc_get_attr(hdlp
, id
, PSVC_PRESENCE_ATTR
, &presence
);
1550 if (status
!= PSVC_SUCCESS
)
1553 } while ((retry
< n_retry_pshp
) &&
1554 (presence
!= previous_presence
));
1556 if (presence
== previous_presence
) {
1561 status
= psvc_get_attr(hdlp
, id
, PSVC_LABEL_ATTR
, label
);
1562 if (status
!= PSVC_SUCCESS
)
1565 /* convert name to node, and parent path */
1566 psvcplugin_lookup(id
, parent_path
, &child_node
);
1568 if (presence
== PSVC_PRESENT
) {
1570 * Run this code if Power Supply was just added into the
1571 * System. This code toggles hotplug switch and adds the
1572 * PS and it's children to the picl tree. We then goto adding
1573 * device drivers at bottom of the routine.
1575 int32_t switch_count
;
1576 char state
[32], fault
[32];
1577 char switch_state
[32];
1579 /* may detect presence before all connections are made */
1580 (void) poll(NULL
, 0, 500);
1583 syslog(LOG_ERR
, DEVICE_INSERTED_MSG
, label
);
1585 strcpy(state
, PSVC_OK
);
1586 status
= psvc_set_attr(hdlp
, id
, PSVC_STATE_ATTR
, state
);
1587 if (status
!= PSVC_SUCCESS
)
1590 strcpy(fault
, PSVC_NO_FAULT
);
1591 status
= psvc_set_attr(hdlp
, id
, PSVC_FAULTID_ATTR
, fault
);
1592 if (status
!= PSVC_SUCCESS
)
1595 /* Enable i2c bus */
1596 psvc_get_attr(hdlp
, id
, PSVC_ASSOC_MATCHES_ATTR
,
1597 &switch_count
, PSVC_HOTPLUG_ENABLE_SWITCH
);
1598 for (i
= 0; i
< switch_count
; ++i
) {
1599 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_ID_ATTR
,
1600 &switch_id
, PSVC_HOTPLUG_ENABLE_SWITCH
, i
);
1601 if (status
== PSVC_FAILURE
)
1604 strcpy(switch_state
, PSVC_SWITCH_OFF
);
1605 status
= psvc_set_attr(hdlp
, switch_id
,
1606 PSVC_SWITCH_STATE_ATTR
, switch_state
);
1607 if (status
== PSVC_FAILURE
)
1610 strcpy(switch_state
, PSVC_SWITCH_ON
);
1611 status
= psvc_set_attr(hdlp
, switch_id
,
1612 PSVC_SWITCH_STATE_ATTR
, switch_state
);
1613 if (status
== PSVC_FAILURE
)
1616 ptree_get_node_by_path(parent_path
, &parent_node
);
1617 ptree_add_node(parent_node
, child_node
);
1618 snprintf(ps_path
, sizeof (ps_path
), "%s/%s", parent_path
, id
);
1619 psvcplugin_add_children(ps_path
);
1622 * Run this code if PS was just removed from the system. We
1623 * delete the device from the picl tree and then shut off
1624 * all fault lights associated with the PS. We also set the
1625 * device state to PSVC_REMOVED so that if we hit overcurrent
1626 * or fault checking code we can do a psvc call to see that
1627 * the device has not offically been added into the system.
1628 * We then will drop to code lower in the routine to remove
1629 * the device drivers for this PS.
1632 /* Device removed */
1633 syslog(LOG_ERR
, DEVICE_REMOVED_MSG
, label
);
1634 ptree_delete_node(child_node
);
1635 psvc_get_attr(hdlp
, id
, PSVC_ASSOC_MATCHES_ATTR
, &led_count
,
1636 PSVC_DEV_FAULT_LED
);
1638 for (i
= 0; i
< led_count
; i
++) {
1639 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_ID_ATTR
,
1640 &led_id
, PSVC_DEV_FAULT_LED
, i
);
1641 if (status
!= PSVC_SUCCESS
) {
1645 status
= psvc_set_attr(hdlp
, led_id
,
1646 PSVC_LED_STATE_ATTR
, PSVC_OFF
);
1647 if (status
!= PSVC_SUCCESS
) {
1648 syslog(LOG_ERR
, SET_LED_FAILED_MSG
, led_id
,
1655 strcpy(state
, PSVC_OK
);
1656 strcpy(fault
, PSVC_NO_FAULT
);
1658 status
= psvc_set_attr(hdlp
, id
, PSVC_STATE_ATTR
, state
);
1659 if (status
!= PSVC_SUCCESS
)
1661 status
= psvc_set_attr(hdlp
, id
, PSVC_FAULTID_ATTR
, fault
);
1662 if (status
!= PSVC_SUCCESS
)
1666 status
= psvc_set_attr(hdlp
, id
, PSVC_PREV_PRESENCE_ATTR
, &presence
);
1667 if (status
!= PSVC_SUCCESS
)
1670 status
= psvc_get_attr(hdlp
, id
, PSVC_INSTANCE_ATTR
, &ps_instance
);
1671 if (status
!= PSVC_SUCCESS
)
1674 if (presence
!= PSVC_PRESENT
) {
1676 * This is the additional code needed to remove the PS from
1677 * the system. It removes the device drivers from the
1680 snprintf(pcf8574_devpath
, sizeof (pcf8574_devpath
), PCF8574
,
1681 devices
[ps_instance
][1].addr
[1]);
1682 snprintf(pcf8591_devpath
, sizeof (pcf8591_devpath
), PCF8591
,
1683 devices
[ps_instance
][0].addr
[1]);
1684 snprintf(fru_devpath
, sizeof (fru_devpath
), FRU
,
1685 devices
[ps_instance
][2].addr
[1]);
1687 dev_handle
= devctl_device_acquire(pcf8591_devpath
, 0);
1688 if (dev_handle
== NULL
) {
1689 syslog(LOG_ERR
, DEVICE_HANDLE_FAIL_MSG
,
1690 pcf8591_devpath
, errno
);
1691 devctl_release(dev_handle
);
1692 return (PSVC_FAILURE
);
1693 } else if ((devctl_device_remove(dev_handle
)) &&
1695 syslog(LOG_ERR
, DEVTREE_NODE_DELETE_FAILED
,
1696 pcf8591_devpath
, errno
);
1697 devctl_release(dev_handle
);
1698 return (PSVC_FAILURE
);
1700 devctl_release(dev_handle
);
1701 status
= PSVC_SUCCESS
;
1704 dev_handle
= devctl_device_acquire(pcf8574_devpath
, 0);
1705 if (dev_handle
== NULL
) {
1706 syslog(LOG_ERR
, DEVICE_HANDLE_FAIL_MSG
,
1707 pcf8574_devpath
, errno
);
1708 devctl_release(dev_handle
);
1709 return (PSVC_FAILURE
);
1710 } else if ((devctl_device_remove(dev_handle
)) &&
1712 syslog(LOG_ERR
, DEVTREE_NODE_DELETE_FAILED
,
1713 pcf8574_devpath
, errno
);
1714 devctl_release(dev_handle
);
1715 return (PSVC_FAILURE
);
1717 devctl_release(dev_handle
);
1718 status
= PSVC_SUCCESS
;
1721 dev_handle
= devctl_device_acquire(fru_devpath
, 0);
1722 if (dev_handle
== NULL
) {
1723 syslog(LOG_ERR
, DEVICE_HANDLE_FAIL_MSG
,
1724 fru_devpath
, errno
);
1725 devctl_release(dev_handle
);
1726 return (PSVC_FAILURE
);
1727 } else if ((devctl_device_remove(dev_handle
)) &&
1729 syslog(LOG_ERR
, DEVTREE_NODE_DELETE_FAILED
,
1730 fru_devpath
, errno
);
1731 devctl_release(dev_handle
);
1732 return (PSVC_FAILURE
);
1734 devctl_release(dev_handle
);
1735 status
= PSVC_SUCCESS
;
1742 * This code is to update the presences of power supply child
1743 * devices in the event that picld was started without a power
1744 * supply present. This call makes the devices available
1745 * after that initial insertion.
1747 status
= handle_ps_hotplug_children_presence(hdlp
, id
);
1748 if (status
== PSVC_FAILURE
) {
1753 * We fall through to here if the device has been inserted.
1754 * Add the devinfo tree node entry for the seeprom and attach
1755 * the i2c seeprom driver
1758 bus_handle
= devctl_bus_acquire(I2C_NODE
, 0);
1759 if (bus_handle
== NULL
) {
1760 syslog(LOG_ERR
, DEVICE_HANDLE_FAIL_MSG
, I2C_NODE
, errno
);
1761 return (PSVC_FAILURE
);
1763 /* Create the deivce nodes for all 3 i2c parts on the PS */
1764 for (i
= 0; i
< 3; i
++) {
1765 ddef_hdl
= devctl_ddef_alloc(devices
[ps_instance
][i
].name
, 0);
1766 if (ddef_hdl
== NULL
) {
1767 syslog(LOG_ERR
, DEVICE_HANDLE_FAIL_MSG
,
1768 devices
[ps_instance
][i
].name
, errno
);
1769 return (PSVC_FAILURE
);
1771 status
= devctl_ddef_string(ddef_hdl
, "compatible",
1772 devices
[ps_instance
][i
].compatible
);
1774 syslog(LOG_ERR
, DEVICE_HANDLE_FAIL_MSG
,
1775 devices
[ps_instance
][i
].name
, errno
);
1776 return (PSVC_FAILURE
);
1778 status
= devctl_ddef_int_array(ddef_hdl
, "reg", 2,
1779 devices
[ps_instance
][i
].addr
);
1781 syslog(LOG_ERR
, DEVICE_HANDLE_FAIL_MSG
,
1782 devices
[ps_instance
][i
].name
, errno
);
1783 return (PSVC_FAILURE
);
1785 if (devctl_bus_dev_create(bus_handle
, ddef_hdl
, 0,
1787 syslog(LOG_ERR
, DEVTREE_NODE_CREATE_FAILED
,
1788 devices
[ps_instance
][i
].name
, errno
);
1789 return (PSVC_FAILURE
);
1791 devctl_release(dev_handle
);
1792 devctl_ddef_free(ddef_hdl
);
1794 devctl_release(bus_handle
);
1802 static boolean_t shutdown_flag
= 0;
1804 if (!(shutdown_flag
)) {
1805 system(shutdown_string
);
1811 * This policy checks temperature sensors to see if the fault attribute
1812 * is set to either High or Low Shutdown. If so then it shuts the system
1813 * down with a 1 minute warning period
1816 psvc_shutdown_policy(psvc_opaque_t hdlp
, char *id
)
1819 char fault
[32] = {0};
1823 status
= psvc_get_attr(hdlp
, id
, PSVC_PRESENCE_ATTR
, &pr
);
1824 if ((status
!= PSVC_SUCCESS
) || (pr
!= PSVC_PRESENT
)) {
1831 (void) sleep(retry_sleep_temp_shutdown
);
1832 status
= psvc_get_attr(hdlp
, id
, PSVC_FAULTID_ATTR
, fault
);
1833 if (status
!= PSVC_SUCCESS
)
1836 } while (((strcmp(fault
, PSVC_TEMP_LO_SHUT
) == 0) ||
1837 (strcmp(fault
, PSVC_TEMP_HI_SHUT
) == 0)) &&
1838 (retry
< n_retry_temp_shutdown
));
1839 if ((strcmp(fault
, PSVC_TEMP_LO_SHUT
) == 0) ||
1840 (strcmp(fault
, PSVC_TEMP_HI_SHUT
) == 0)) {
1844 return (PSVC_SUCCESS
);
1848 psvc_check_disk_fault_policy_0(psvc_opaque_t hdlp
, char *id
)
1850 int32_t status
= PSVC_SUCCESS
;
1852 char curr_state
[32], prev_state
[32], led_state
[32];
1853 char disk_fault
[32], disk_state
[32];
1854 static char *disk_id
[DAK_MAX_DISKS
] = {NULL
};
1855 static char *led_id
[DAK_MAX_DISKS
] = {NULL
};
1856 static char *parent_id
[DAK_MAX_DISKS
] = {NULL
};
1861 * Check which disk faulted, now get the disks.
1862 * We are now going to get disk, disk parent,
1863 * parent's leds, and check to see if parent's leds are on
1866 if (disk_id
[0] == NULL
) {
1867 for (i
= 0; i
< DAK_MAX_DISKS
; i
++) {
1868 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_ID_ATTR
,
1869 &(disk_id
[i
]), PSVC_DISK
, i
);
1870 if (status
!= PSVC_SUCCESS
)
1872 status
= psvc_get_attr(hdlp
, disk_id
[i
],
1873 PSVC_ASSOC_ID_ATTR
, &(parent_id
[i
]),
1875 if (status
!= PSVC_SUCCESS
)
1877 status
= psvc_get_attr(hdlp
, parent_id
[i
],
1878 PSVC_ASSOC_ID_ATTR
, &(led_id
[i
]),
1879 PSVC_SLOT_FAULT_LED
, 0);
1880 if (status
!= PSVC_SUCCESS
)
1886 for (i
= 0; i
< DAK_MAX_DISKS
; i
++) {
1890 status
= psvc_get_attr(hdlp
, disk_id
[i
], PSVC_PRESENCE_ATTR
,
1892 if (status
!= PSVC_SUCCESS
)
1895 if (present
== PSVC_ABSENT
)
1899 * Check if whether or not the led is on.
1900 * If so, then this disk has a problem and
1901 * set its fault and error states to bad.
1902 * If not, then set fault and error states to good.
1903 * If the disk underwent a change in state, then
1904 * print out what state it's now in.
1907 status
= psvc_get_attr(hdlp
, disk_id
[i
], PSVC_STATE_ATTR
,
1909 if (status
!= PSVC_SUCCESS
)
1915 (void) sleep(retry_sleep_diskfault
);
1916 status
= psvc_get_attr(hdlp
, led_id
[i
], PSVC_STATE_ATTR
,
1918 if (status
!= PSVC_SUCCESS
)
1922 * check to see if we need to retry. the conditions are:
1924 * prev_state led_state retry
1925 * --------------------------------------------------
1926 * PSVC_ERROR PSVC_LED_ON yes
1927 * PSVC_OK PSVC_LED_OFF yes
1928 * PSVC_ERROR PSVC_LED_OFF no
1929 * PSVC_OK PSVC_LED_ON no
1931 } while ((retry
< n_retry_diskfault
) &&
1932 change_of_state_str(prev_state
, PSVC_OK
,
1933 led_state
, PSVC_LED_ON
));
1936 * Set the disk's state and fault id according to
1937 * what we found the disk fault sensor (disk_slot_fault_led)
1940 if (strcmp(led_state
, PSVC_LED_ON
) == 0) {
1941 strcpy(disk_fault
, PSVC_GEN_FAULT
);
1942 strcpy(disk_state
, PSVC_ERROR
);
1944 strcpy(disk_fault
, PSVC_NO_FAULT
);
1945 strcpy(disk_state
, PSVC_OK
);
1947 status
= psvc_set_attr(hdlp
, disk_id
[i
], PSVC_STATE_ATTR
,
1949 if (status
!= PSVC_SUCCESS
)
1951 status
= psvc_set_attr(hdlp
, disk_id
[i
], PSVC_FAULTID_ATTR
,
1953 if (status
!= PSVC_SUCCESS
)
1956 * Check disk states. If they differ, then print out
1957 * the current state of the disk
1959 status
= psvc_get_attr(hdlp
, disk_id
[i
], PSVC_PREV_STATE_ATTR
,
1961 if (status
!= PSVC_SUCCESS
)
1964 if (strcmp(disk_state
, prev_state
) != 0) {
1965 if (strcmp(disk_state
, PSVC_ERROR
) == 0) {
1966 syslog(LOG_ERR
, DISK_FAULT_MSG
, disk_id
[i
]);
1968 syslog(LOG_ERR
, DISK_OK_MSG
, disk_id
[i
]);
1972 return (PSVC_SUCCESS
);
1976 psvc_update_FSP_fault_led_policy_0(psvc_opaque_t hdlp
, char *id
)
1978 int32_t status
= PSVC_SUCCESS
;
1980 int32_t dev_count
, fault_state
= 0;
1982 char dev_state
[32], led_state
[32];
1985 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_MATCHES_ATTR
, &dev_count
,
1986 PSVC_DEV_FAULT_SENSOR
);
1987 if (status
!= PSVC_SUCCESS
)
1992 for (i
= 0; i
< dev_count
; i
++) {
1993 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_ID_ATTR
,
1994 &dev_id
, PSVC_DEV_FAULT_SENSOR
, i
);
1995 if (status
!= PSVC_SUCCESS
)
1997 status
= psvc_get_attr(hdlp
, dev_id
, PSVC_PRESENCE_ATTR
,
1999 if (status
!= PSVC_SUCCESS
)
2002 if (present
== PSVC_ABSENT
)
2005 status
= psvc_get_attr(hdlp
, dev_id
, PSVC_STATE_ATTR
,
2007 if (status
!= PSVC_SUCCESS
)
2010 if (strcmp(dev_state
, PSVC_ERROR
) == 0) {
2014 if (fault_state
== 1) {
2015 status
= psvc_get_attr(hdlp
, id
, PSVC_STATE_ATTR
, led_state
);
2016 if (status
!= PSVC_SUCCESS
)
2018 if (strcmp(led_state
, PSVC_OFF
) == 0) {
2019 status
= psvc_set_attr(hdlp
, id
, PSVC_STATE_ATTR
,
2021 if (status
!= PSVC_SUCCESS
)
2025 status
= psvc_get_attr(hdlp
, id
, PSVC_STATE_ATTR
, led_state
);
2026 if (status
!= PSVC_SUCCESS
)
2028 if (strcmp(led_state
, PSVC_ON
) == 0) {
2029 status
= psvc_set_attr(hdlp
, id
, PSVC_STATE_ATTR
,
2031 if (status
!= PSVC_SUCCESS
)
2035 status
= update_gen_fault_led(hdlp
, GEN_FAULT_LED
);
2041 update_gen_fault_led(psvc_opaque_t hdlp
, char *id
)
2043 int32_t status
= PSVC_SUCCESS
;
2045 int32_t led_count
, fault_state
;
2049 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_MATCHES_ATTR
, &led_count
,
2050 PSVC_DEV_FAULT_SENSOR
);
2051 if (status
!= PSVC_SUCCESS
)
2056 for (i
= 0; i
< led_count
; i
++) {
2057 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_ID_ATTR
,
2058 &led_id
, PSVC_DEV_FAULT_SENSOR
, i
);
2059 if (status
!= PSVC_SUCCESS
)
2061 status
= psvc_get_attr(hdlp
, led_id
, PSVC_STATE_ATTR
,
2063 if (status
!= PSVC_SUCCESS
)
2066 if (strcmp(led_state
, PSVC_ON
) == 0) {
2071 if (fault_state
== 1) {
2072 status
= psvc_get_attr(hdlp
, id
, PSVC_STATE_ATTR
, led_state
);
2073 if (status
!= PSVC_SUCCESS
)
2075 if (strcmp(led_state
, PSVC_OFF
) == 0) {
2076 status
= psvc_set_attr(hdlp
, id
, PSVC_STATE_ATTR
,
2078 if (status
!= PSVC_SUCCESS
)
2082 status
= psvc_get_attr(hdlp
, id
, PSVC_STATE_ATTR
, led_state
);
2083 if (status
!= PSVC_SUCCESS
)
2085 if (strcmp(led_state
, PSVC_ON
) == 0) {
2086 status
= psvc_set_attr(hdlp
, id
, PSVC_STATE_ATTR
,
2088 if (status
!= PSVC_SUCCESS
)
2098 * This function detects whether the module present in the dakatari's
2099 * CPU slot is a CPU module or a Zulu (XVR-4000).
2100 * Based on this detection it also sets the appropriate temperature sensors
2101 * to HOTPLUGGED, so that it works properly with check_temp() function
2103 #define MAX_MODULE_SIZE 20
2104 #define MAX_TEMP_SENSOR_SIZE 30
2107 psvc_update_cpu_module_card_node_0(psvc_opaque_t hdlp
, char *id
)
2109 int32_t set_temp_sensor_properties(psvc_opaque_t
, char *);
2110 int32_t remove_module_node(psvc_opaque_t
, char *);
2111 int32_t status
= PSVC_SUCCESS
;
2112 fru_info_t fru_data
;
2113 char *fru
, seg_name
[2];
2114 int8_t seg_count
, module_card
;
2115 int32_t match_count
, i
, j
, seg_desc_start
= 0x1806, module_address
;
2119 char other_module_id
[MAX_MODULE_SIZE
];
2120 char cpu_temp_sensor1
[MAX_TEMP_SENSOR_SIZE
];
2121 char cpu_temp_sensor2
[MAX_TEMP_SENSOR_SIZE
];
2122 char zulu_temp_sensor1
[MAX_TEMP_SENSOR_SIZE
];
2123 char zulu_temp_sensor2
[MAX_TEMP_SENSOR_SIZE
];
2126 status
= psvc_get_attr(hdlp
, id
, PSVC_PRESENCE_ATTR
, &present
);
2127 if ((status
!= PSVC_SUCCESS
) || (present
!= PSVC_PRESENT
)) {
2131 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_MATCHES_ATTR
, &match_count
,
2133 if (status
== PSVC_FAILURE
) {
2137 for (i
= 0; i
< match_count
; i
++) {
2139 status
= psvc_get_attr(hdlp
, id
, PSVC_ASSOC_ID_ATTR
, &fru
,
2141 if (status
!= PSVC_SUCCESS
)
2144 fru_data
.buf_start
= 0x1805;
2145 fru_data
.buf
= (char *)&seg_count
;
2146 fru_data
.read_size
= 1;
2148 status
= psvc_get_attr(hdlp
, fru
, PSVC_FRU_INFO_ATTR
,
2150 if (status
!= PSVC_SUCCESS
) {
2154 for (j
= 0; (j
< seg_count
) && (!seg_found
); j
++) {
2155 fru_data
.buf_start
= seg_desc_start
;
2156 fru_data
.buf
= seg_name
;
2157 fru_data
.read_size
= 2;
2159 status
= psvc_get_attr(hdlp
, fru
, PSVC_FRU_INFO_ATTR
,
2161 if (status
!= PSVC_SUCCESS
) {
2162 syslog(LOG_ERR
, GET_ATTR_FRU_FAILED_MSG
);
2166 seg_desc_start
= seg_desc_start
+ 2;
2167 fru_data
.buf_start
= seg_desc_start
;
2168 fru_data
.buf
= (char *)&segment
;
2169 fru_data
.read_size
= sizeof (seg_desc_t
);
2171 status
= psvc_get_attr(hdlp
, fru
, PSVC_FRU_INFO_ATTR
,
2173 if (status
!= PSVC_SUCCESS
) {
2174 syslog(LOG_ERR
, GET_ATTR_FRU_FAILED_MSG
);
2177 seg_desc_start
= seg_desc_start
+ sizeof (seg_desc_t
);
2178 if (memcmp(seg_name
, "SC", 2) == 0)
2183 module_address
= segment
.segoffset
+ offset
;
2184 fru_data
.buf_start
= module_address
;
2185 fru_data
.buf
= (char *)&module_card
;
2186 fru_data
.read_size
= 1;
2187 status
= psvc_get_attr(hdlp
, fru
, PSVC_FRU_INFO_ATTR
,
2189 if (status
!= PSVC_SUCCESS
) {
2190 syslog(LOG_ERR
, GET_ATTR_FRU_FAILED_MSG
);
2194 syslog(LOG_ERR
, NO_FRU_INFO_MSG
, id
);
2198 if (strcmp(id
, "ZULU_1_3_MOD_CARD") == 0) {
2199 strlcpy(other_module_id
, "CPU_1_3_MOD_CARD", MAX_MODULE_SIZE
);
2201 strlcpy(cpu_temp_sensor1
, "CPU1_DIE_TEMPERATURE_SENSOR",
2202 MAX_TEMP_SENSOR_SIZE
);
2203 strlcpy(cpu_temp_sensor2
, "CPU3_DIE_TEMPERATURE_SENSOR",
2204 MAX_TEMP_SENSOR_SIZE
);
2206 strlcpy(zulu_temp_sensor1
, "ZULU1_DIE_TEMPERATURE_SENSOR",
2207 MAX_TEMP_SENSOR_SIZE
);
2208 strlcpy(zulu_temp_sensor2
, "ZULU3_DIE_TEMPERATURE_SENSOR",
2209 MAX_TEMP_SENSOR_SIZE
);
2212 if (strcmp(id
, "ZULU_4_6_MOD_CARD") == 0) {
2213 strlcpy(other_module_id
, "CPU_4_6_MOD_CARD", MAX_MODULE_SIZE
);
2215 strlcpy(cpu_temp_sensor1
, "CPU4_DIE_TEMPERATURE_SENSOR",
2216 MAX_TEMP_SENSOR_SIZE
);
2217 strlcpy(cpu_temp_sensor2
, "CPU6_DIE_TEMPERATURE_SENSOR",
2218 MAX_TEMP_SENSOR_SIZE
);
2220 strlcpy(zulu_temp_sensor1
, "ZULU4_DIE_TEMPERATURE_SENSOR",
2221 MAX_TEMP_SENSOR_SIZE
);
2222 strlcpy(zulu_temp_sensor2
, "ZULU6_DIE_TEMPERATURE_SENSOR",
2223 MAX_TEMP_SENSOR_SIZE
);
2228 * If the module in the CPU slot is a Zulu (XVR-4000), then
2229 * location 0x1EB0 in its FRUid prom has a value 0xFB.
2230 * If Zulu (XVR-4000) is detected, delete the CPU node, otherwise
2231 * delete the Zulu node. Also set the temperature sensor value to
2232 * HOTPLUGGED for absent temperature sensors.
2234 if ((module_card
& 0xff) == 0xfb) {
2235 status
= set_temp_sensor_properties(hdlp
, cpu_temp_sensor1
);
2236 if (status
== PSVC_FAILURE
) {
2240 status
= set_temp_sensor_properties(hdlp
, cpu_temp_sensor2
);
2241 if (status
== PSVC_FAILURE
) {
2248 status
= remove_module_node(hdlp
, other_module_id
);
2249 if (status
== PSVC_FAILURE
) {
2253 status
= set_temp_sensor_properties(hdlp
, zulu_temp_sensor1
);
2254 if (status
== PSVC_FAILURE
) {
2257 status
= set_temp_sensor_properties(hdlp
, zulu_temp_sensor2
);
2258 if (status
== PSVC_FAILURE
) {
2263 * Remove Zulu (XVR-4000) node
2265 status
= remove_module_node(hdlp
, id
);
2266 if (status
== PSVC_FAILURE
) {
2271 return (PSVC_SUCCESS
);
2276 * Remove the CPU slot's module node
2279 remove_module_node(psvc_opaque_t hdlp
, char *id
)
2281 char parent_path
[256];
2282 picl_nodehdl_t child_node
;
2284 /* convert name to node, and parent path */
2285 psvcplugin_lookup(id
, parent_path
, &child_node
);
2286 /* Device removed */
2287 ptree_delete_node(child_node
);
2289 return (PSVC_SUCCESS
);
2294 * Set absent temperature sensor values to HOTPLUGGED
2297 set_temp_sensor_properties(psvc_opaque_t hdlp
, char *id
)
2300 int32_t status
= PSVC_SUCCESS
;
2302 status
= psvc_get_attr(hdlp
, id
, PSVC_STATE_ATTR
, state
);
2303 if (status
== PSVC_FAILURE
) {
2307 if (strcmp(state
, PSVC_HOTPLUGGED
) != 0) {
2308 strcpy(state
, PSVC_HOTPLUGGED
);
2310 status
= psvc_set_attr(hdlp
, id
, PSVC_STATE_ATTR
, state
);
2311 if (status
== PSVC_FAILURE
) {
2316 return (PSVC_SUCCESS
);