17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 55eb92cf2Sdhain * Common Development and Distribution License (the "License"). 65eb92cf2Sdhain * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*8a88157cSvb * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate /* 297c478bd9Sstevel@tonic-gate * Daktari platform platform specific environment monitoring policies 307c478bd9Sstevel@tonic-gate */ 317c478bd9Sstevel@tonic-gate #include <poll.h> 327c478bd9Sstevel@tonic-gate #include <syslog.h> 337c478bd9Sstevel@tonic-gate #include <unistd.h> 347c478bd9Sstevel@tonic-gate #include <stdio.h> 357c478bd9Sstevel@tonic-gate #include <stdlib.h> 367c478bd9Sstevel@tonic-gate #include <errno.h> 377c478bd9Sstevel@tonic-gate #include <fcntl.h> 387c478bd9Sstevel@tonic-gate #include <strings.h> 397c478bd9Sstevel@tonic-gate #include <libintl.h> 407c478bd9Sstevel@tonic-gate #include <sys/types.h> 417c478bd9Sstevel@tonic-gate #include <sys/param.h> 427c478bd9Sstevel@tonic-gate #include <config_admin.h> 437c478bd9Sstevel@tonic-gate #include <libdevice.h> 447c478bd9Sstevel@tonic-gate #include <picl.h> 457c478bd9Sstevel@tonic-gate #include <picltree.h> 467c478bd9Sstevel@tonic-gate #include <psvc_objects.h> 477c478bd9Sstevel@tonic-gate #include <sys/i2c/clients/i2c_client.h> 487c478bd9Sstevel@tonic-gate #include <sys/daktari.h> 497c478bd9Sstevel@tonic-gate #include <sys/hpc3130_events.h> 507c478bd9Sstevel@tonic-gate #include <assert.h> 51298b7f4cSjfrank #include <limits.h> 52298b7f4cSjfrank #include <sys/systeminfo.h> 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/ 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate /* resides in libcfgadm */ 577c478bd9Sstevel@tonic-gate extern cfga_err_t config_change_state(cfga_cmd_t, int, char *const *, 587c478bd9Sstevel@tonic-gate const char *, struct cfga_confirm *, struct cfga_msg *, char **, 597c478bd9Sstevel@tonic-gate cfga_flags_t); 607c478bd9Sstevel@tonic-gate /* Local Routine */ 617c478bd9Sstevel@tonic-gate static int32_t update_gen_fault_led(psvc_opaque_t, char *); 627c478bd9Sstevel@tonic-gate static void shutdown_routine(void); 637c478bd9Sstevel@tonic-gate static int32_t update_thresholds(psvc_opaque_t hdlp, char *id, int offset); 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate #ifdef DEBUG 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate static int dak_policy_debug = 0; 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate #define D1SYS_ERR(ARGS) if (dak_policy_debug & 0x1) syslog ARGS; 717c478bd9Sstevel@tonic-gate #define D2SYS_ERR(ARGS) if (dak_policy_debug & 0x2) syslog ARGS; 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate #else 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate #define D1SYS_ERR(ARGS) 767c478bd9Sstevel@tonic-gate #define D2SYS_ERR(ARGS) 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate #endif 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate #define I2C_PATH "/devices/pci@9,700000/ebus@1/i2c@1,30" 81159cf8a6Swesolows #define I2C_NODE I2C_PATH ":devctl" 82159cf8a6Swesolows #define PCF8574 I2C_PATH "/ioexp@0,%x:pcf8574" 83159cf8a6Swesolows #define PCF8591 I2C_PATH "/adio@0,%x:port_0" 84159cf8a6Swesolows #define FRU I2C_PATH "/fru@0,%x:fru" 85159cf8a6Swesolows #define HPC3130_DEV I2C_PATH "/hotplug-controller@0,%2x:port_%1x" 867c478bd9Sstevel@tonic-gate #define GEN_FAULT_LED "FSP_GEN_FAULT_LED" 877c478bd9Sstevel@tonic-gate #define EMPTY_STRING "EMPTY" 887c478bd9Sstevel@tonic-gate #define DEVICE_FAILURE_MSG gettext("WARNING: Device %s failure detected") 897c478bd9Sstevel@tonic-gate #define DEVICE_INSERTED_MSG gettext("Device %s inserted") 907c478bd9Sstevel@tonic-gate #define DEVICE_REMOVED_MSG gettext("Device %s removed") 917c478bd9Sstevel@tonic-gate #define PS_UNPLUGGED_MSG gettext("Device %s unplugged") 927c478bd9Sstevel@tonic-gate #define PS_PLUGGED_MSG gettext("Device %s Plugged in") 937c478bd9Sstevel@tonic-gate #define DEVICE_OK_MSG gettext("Device %s OK") 947c478bd9Sstevel@tonic-gate #define SET_LED_FAILED_MSG \ 957c478bd9Sstevel@tonic-gate gettext("Failed to set LED state, id = %s, errno = %d\n") 967c478bd9Sstevel@tonic-gate #define GET_PRESENCE_FAILED_MSG \ 977c478bd9Sstevel@tonic-gate gettext("Failed to get presence attribute, id = %s, errno = %d\n") 987c478bd9Sstevel@tonic-gate #define GET_SENSOR_FAILED_MSG \ 997c478bd9Sstevel@tonic-gate gettext("Failed to get sensor value, id = %s, errno = %d\n") 1007c478bd9Sstevel@tonic-gate #define ADD_PS_MSG \ 1017c478bd9Sstevel@tonic-gate gettext("WARNING: Only 1 Power Supply in system. ADD a 2nd Power Supply.\n") 1027c478bd9Sstevel@tonic-gate #define REMOVE_LOAD_MSG \ 1037c478bd9Sstevel@tonic-gate gettext("WARNING: Power Supply at 95%% current. Remove some load.\n") 1047c478bd9Sstevel@tonic-gate #define PS_OVER_CURRENT_MSG \ 1057c478bd9Sstevel@tonic-gate gettext("WARNING: Power Supply overcurrent detected\n") 106*8a88157cSvb #define PS_UNDER_CURRENT_MSG \ 107*8a88157cSvb gettext("WARNING: PS%d Undercurrent on one or more DC lines\n") 1087c478bd9Sstevel@tonic-gate #define DEVICE_UNKNOWN_MSG gettext("Unknown device %s instance %d\n") 1097c478bd9Sstevel@tonic-gate #define DEVICE_HANDLE_FAIL_MSG \ 1107c478bd9Sstevel@tonic-gate gettext("Failed to get device handle for %s, errno = %d\n") 1117c478bd9Sstevel@tonic-gate #define DEVTREE_NODE_CREATE_FAILED \ 1127c478bd9Sstevel@tonic-gate gettext("psvc PICL plugin: Failed to create node for %s, errno = %d") 1137c478bd9Sstevel@tonic-gate #define DEVTREE_NODE_DELETE_FAILED \ 1147c478bd9Sstevel@tonic-gate gettext("psvc PICL plugin: Failed to delete node for %s, errno = %d") 1157c478bd9Sstevel@tonic-gate #define DISK_FAULT_MSG gettext("%s: Error Reported\n") 1167c478bd9Sstevel@tonic-gate #define DISK_OK_MSG gettext("%s: Error Cleared\n") 1177c478bd9Sstevel@tonic-gate #define SET_FANSPEED_FAILED_MSG \ 1187c478bd9Sstevel@tonic-gate gettext("Failed to set fan speed, id = %s, errno = %d\n") 1197c478bd9Sstevel@tonic-gate #define GET_ATTR_FRU_FAILED_MSG gettext("Failed psvc_get_attr for FRU info\n") 1207c478bd9Sstevel@tonic-gate #define NO_FRU_INFO_MSG \ 1217c478bd9Sstevel@tonic-gate gettext("No FRU Information for %s using default module card\n") 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate #define DAKTARI_MAX_PS 3 1247c478bd9Sstevel@tonic-gate #define DAK_MAX_PS_I_SENSORS 4 1257c478bd9Sstevel@tonic-gate #define DAK_MAX_DISKS 12 1267c478bd9Sstevel@tonic-gate #define DAK_MAX_CPU_MOD 4 1277c478bd9Sstevel@tonic-gate #define DAK_MAX_FAULT_SENSORS 3 1287c478bd9Sstevel@tonic-gate #define DAK_MAX_FANS 10 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate static int co_ps = 0; 1317c478bd9Sstevel@tonic-gate static char *shutdown_string = "shutdown -y -g 60 -i 5 \"OVERTEMP condition\""; 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate typedef struct i2c_hp { 1347c478bd9Sstevel@tonic-gate int32_t addr[2]; 1357c478bd9Sstevel@tonic-gate char name[256]; 1367c478bd9Sstevel@tonic-gate char compatible[256]; 1377c478bd9Sstevel@tonic-gate } i2c_hp_t; 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate typedef struct seg_desc { 1407c478bd9Sstevel@tonic-gate int32_t segdesc; 1417c478bd9Sstevel@tonic-gate int16_t segoffset; 1427c478bd9Sstevel@tonic-gate int16_t seglength; 1437c478bd9Sstevel@tonic-gate } seg_desc_t; 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate static int32_t threshold_names[] = { 1467c478bd9Sstevel@tonic-gate PSVC_HW_LO_SHUT_ATTR, 1477c478bd9Sstevel@tonic-gate PSVC_LO_SHUT_ATTR, 1487c478bd9Sstevel@tonic-gate PSVC_LO_WARN_ATTR, 1497c478bd9Sstevel@tonic-gate PSVC_NOT_USED, /* LOW MODE which is not used */ 1507c478bd9Sstevel@tonic-gate PSVC_OPTIMAL_TEMP_ATTR, 1517c478bd9Sstevel@tonic-gate PSVC_HI_WARN_ATTR, 1527c478bd9Sstevel@tonic-gate PSVC_HI_SHUT_ATTR, 1537c478bd9Sstevel@tonic-gate PSVC_HW_HI_SHUT_ATTR 1547c478bd9Sstevel@tonic-gate }; 1557c478bd9Sstevel@tonic-gate 156298b7f4cSjfrank /* 157298b7f4cSjfrank * The I2C bus is noisy, and the state may be incorrectly reported as 158298b7f4cSjfrank * having changed. When the state changes, we attempt to confirm by 159298b7f4cSjfrank * retrying. If any retries indicate that the state has not changed, we 160298b7f4cSjfrank * assume the state change(s) were incorrect and the state has not changed. 161298b7f4cSjfrank * The following variables are used to store the tuneable values read in 162298b7f4cSjfrank * from the optional i2cparam.conf file for this shared object library. 163298b7f4cSjfrank */ 164298b7f4cSjfrank static int n_retry_pshp_status = PSVC_NUM_OF_RETRIES; 165298b7f4cSjfrank static int retry_sleep_pshp_status = 1; 166298b7f4cSjfrank static int n_read_overcurrent = PSVC_THRESHOLD_COUNTER; 167*8a88157cSvb static int n_read_undercurrent = PSVC_THRESHOLD_COUNTER; 168298b7f4cSjfrank static int n_retry_devicefail = PSVC_NUM_OF_RETRIES; 169298b7f4cSjfrank static int retry_sleep_devicefail = 1; 170298b7f4cSjfrank static int n_read_fanfault = PSVC_THRESHOLD_COUNTER; 171298b7f4cSjfrank static int n_retry_pshp = PSVC_NUM_OF_RETRIES; 172298b7f4cSjfrank static int retry_sleep_pshp = 1; 173298b7f4cSjfrank static int n_retry_diskfault = PSVC_NUM_OF_RETRIES; 174298b7f4cSjfrank static int retry_sleep_diskfault = 1; 175298b7f4cSjfrank static int n_retry_temp_shutdown = PSVC_NUM_OF_RETRIES; 176298b7f4cSjfrank static int retry_sleep_temp_shutdown = 1; 177298b7f4cSjfrank 178298b7f4cSjfrank typedef struct { 179298b7f4cSjfrank int *pvar; 180298b7f4cSjfrank char *texttag; 181298b7f4cSjfrank } i2c_noise_param_t; 182298b7f4cSjfrank 183298b7f4cSjfrank static i2c_noise_param_t i2cparams[] = { 184298b7f4cSjfrank &n_retry_pshp_status, "n_retry_pshp_status", 185298b7f4cSjfrank &retry_sleep_pshp_status, "retry_sleep_pshp_status", 186298b7f4cSjfrank &n_read_overcurrent, "n_read_overcurrent", 187*8a88157cSvb &n_read_undercurrent, "n_read_undercurrent", 188298b7f4cSjfrank &n_retry_devicefail, "n_retry_devicefail", 189298b7f4cSjfrank &retry_sleep_devicefail, "retry_sleep_devicefail", 190298b7f4cSjfrank &n_read_fanfault, "n_read_fanfault", 191298b7f4cSjfrank &n_retry_pshp, "n_retry_pshp", 192298b7f4cSjfrank &retry_sleep_pshp, "retry_sleep_pshp", 193298b7f4cSjfrank &n_retry_diskfault, "n_retry_diskfault", 194298b7f4cSjfrank &retry_sleep_diskfault, "retry_sleep_diskfault", 195298b7f4cSjfrank &n_retry_temp_shutdown, "n_retry_temp_shutdown", 196298b7f4cSjfrank &retry_sleep_temp_shutdown, "retry_sleep_temp_shutdown", 197298b7f4cSjfrank NULL, NULL 198298b7f4cSjfrank }; 199298b7f4cSjfrank 200298b7f4cSjfrank #pragma init(i2cparams_load) 201298b7f4cSjfrank 202298b7f4cSjfrank static void 203298b7f4cSjfrank i2cparams_debug(i2c_noise_param_t *pi2cparams, char *platform, 204298b7f4cSjfrank int usingDefaults) 205298b7f4cSjfrank { 206298b7f4cSjfrank char s[128]; 207298b7f4cSjfrank i2c_noise_param_t *p; 208298b7f4cSjfrank 209298b7f4cSjfrank if (!usingDefaults) { 210298b7f4cSjfrank (void) snprintf(s, sizeof (s), 211298b7f4cSjfrank "# Values from /usr/platform/%s/lib/i2cparam.conf\n", 212298b7f4cSjfrank platform); 213298b7f4cSjfrank syslog(LOG_WARNING, "%s", s); 214298b7f4cSjfrank } else { 215298b7f4cSjfrank /* no file - we're using the defaults */ 216298b7f4cSjfrank (void) snprintf(s, sizeof (s), 217298b7f4cSjfrank "# No /usr/platform/%s/lib/i2cparam.conf file, using defaults\n", 218298b7f4cSjfrank platform); 219298b7f4cSjfrank } 220298b7f4cSjfrank (void) fputs(s, stdout); 221298b7f4cSjfrank p = pi2cparams; 222298b7f4cSjfrank while (p->pvar != NULL) { 223298b7f4cSjfrank (void) snprintf(s, sizeof (s), "%s %d\n", p->texttag, 224298b7f4cSjfrank *(p->pvar)); 225298b7f4cSjfrank if (!usingDefaults) 226298b7f4cSjfrank syslog(LOG_WARNING, "%s", s); 227298b7f4cSjfrank (void) fputs(s, stdout); 228298b7f4cSjfrank p++; 229298b7f4cSjfrank } 230298b7f4cSjfrank } 231298b7f4cSjfrank 232298b7f4cSjfrank static void 233298b7f4cSjfrank i2cparams_load(void) 234298b7f4cSjfrank { 235298b7f4cSjfrank FILE *fp; 236298b7f4cSjfrank char filename[PATH_MAX]; 237298b7f4cSjfrank char platform[64]; 238298b7f4cSjfrank char s[128]; 239298b7f4cSjfrank char var[128]; 240298b7f4cSjfrank int val; 241298b7f4cSjfrank i2c_noise_param_t *p; 242298b7f4cSjfrank 243298b7f4cSjfrank if (sysinfo(SI_PLATFORM, platform, sizeof (platform)) == -1) { 244298b7f4cSjfrank syslog(LOG_ERR, "sysinfo error %s\n", strerror(errno)); 245298b7f4cSjfrank return; 246298b7f4cSjfrank } 247298b7f4cSjfrank (void) snprintf(filename, sizeof (filename), 248298b7f4cSjfrank "/usr/platform/%s/lib/i2cparam.conf", platform); 249298b7f4cSjfrank /* read thru the i2cparam.conf file and set variables */ 250298b7f4cSjfrank if ((fp = fopen(filename, "r")) != NULL) { 251298b7f4cSjfrank while (fgets(s, sizeof (s), fp) != NULL) { 252298b7f4cSjfrank if (s[0] == '#') /* skip comment lines */ 253298b7f4cSjfrank continue; 254298b7f4cSjfrank /* try to find a string match and get the value */ 255298b7f4cSjfrank if (sscanf(s, "%127s %d", var, &val) != 2) 256298b7f4cSjfrank continue; 257298b7f4cSjfrank if (val < 1) 258298b7f4cSjfrank val = 1; /* clamp min value */ 259298b7f4cSjfrank p = &(i2cparams[0]); 260298b7f4cSjfrank while (p->pvar != NULL) { 261298b7f4cSjfrank if (strncmp(p->texttag, var, sizeof (var)) == 262298b7f4cSjfrank 0) { 263298b7f4cSjfrank *(p->pvar) = val; 264298b7f4cSjfrank break; 265298b7f4cSjfrank } 266298b7f4cSjfrank p++; 267298b7f4cSjfrank } 268298b7f4cSjfrank } 269298b7f4cSjfrank (void) fclose(fp); 270298b7f4cSjfrank } 271298b7f4cSjfrank /* output the values of the parameters */ 272298b7f4cSjfrank i2cparams_debug(&(i2cparams[0]), platform, ((fp == NULL)? 1 : 0)); 273298b7f4cSjfrank } 274298b7f4cSjfrank 2757c478bd9Sstevel@tonic-gate int32_t 2767c478bd9Sstevel@tonic-gate psvc_MB_update_thresholds_0(psvc_opaque_t hdlp, char *id, int offset) 2777c478bd9Sstevel@tonic-gate { 2787c478bd9Sstevel@tonic-gate int IO_offset = 0xd; 2797c478bd9Sstevel@tonic-gate int32_t err; 2807c478bd9Sstevel@tonic-gate 2817c478bd9Sstevel@tonic-gate err = update_thresholds(hdlp, id, IO_offset); 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate return (err); 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate int32_t 2877c478bd9Sstevel@tonic-gate psvc_IO_update_thresholds_0(psvc_opaque_t hdlp, char *id, int offset) 2887c478bd9Sstevel@tonic-gate { 2897c478bd9Sstevel@tonic-gate int IO_offset = 0x8; 2907c478bd9Sstevel@tonic-gate int32_t err; 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate err = update_thresholds(hdlp, id, IO_offset); 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate return (err); 2957c478bd9Sstevel@tonic-gate } 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate int32_t 2987c478bd9Sstevel@tonic-gate psvc_DBP_update_thresholds_0(psvc_opaque_t hdlp, char *id, int offset) 2997c478bd9Sstevel@tonic-gate { 3007c478bd9Sstevel@tonic-gate int IO_offset = 0x7; 3017c478bd9Sstevel@tonic-gate int32_t err; 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate err = update_thresholds(hdlp, id, IO_offset); 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate return (err); 3067c478bd9Sstevel@tonic-gate } 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate /* 3097c478bd9Sstevel@tonic-gate * used to determine if a change of state occured. valid when states 3107c478bd9Sstevel@tonic-gate * are strings. 3117c478bd9Sstevel@tonic-gate */ 3127c478bd9Sstevel@tonic-gate static int8_t 3137c478bd9Sstevel@tonic-gate change_of_state_str(char *state1, char *check1, char *state2, char *check2) 3147c478bd9Sstevel@tonic-gate { 3157c478bd9Sstevel@tonic-gate int change = 0; 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate if ((strcmp(state1, check1) == 0) && (strcmp(state2, check2) != 0)) 3187c478bd9Sstevel@tonic-gate change = 1; 3197c478bd9Sstevel@tonic-gate if ((strcmp(state1, check1) != 0) && (strcmp(state2, check2) == 0)) 3207c478bd9Sstevel@tonic-gate change = 1; 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate return (change); 3237c478bd9Sstevel@tonic-gate } 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate /* 3267c478bd9Sstevel@tonic-gate * Update thresholds tries to read the temperature thresholds from the FRU 3277c478bd9Sstevel@tonic-gate * SEEproms and then updates the thresholds in the object by overriding the 3287c478bd9Sstevel@tonic-gate * hardcoded thresholds. For Daktari it is an Error if the FRU does not 3297c478bd9Sstevel@tonic-gate * contain the segment that had the temperature thresholds. 3307c478bd9Sstevel@tonic-gate */ 3317c478bd9Sstevel@tonic-gate static int32_t 3327c478bd9Sstevel@tonic-gate update_thresholds(psvc_opaque_t hdlp, char *id, int offset) 3337c478bd9Sstevel@tonic-gate { 3347c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 3357c478bd9Sstevel@tonic-gate fru_info_t fru_data; 3367c478bd9Sstevel@tonic-gate char *fru, seg_name[2]; 3377c478bd9Sstevel@tonic-gate int8_t seg_count, temp_array[8]; 3387c478bd9Sstevel@tonic-gate int32_t match_count, i, j, seg_desc_start = 0x1806, temp_address; 3397c478bd9Sstevel@tonic-gate int32_t seg_found, temp; 3407c478bd9Sstevel@tonic-gate boolean_t present; 3417c478bd9Sstevel@tonic-gate seg_desc_t segment; 3427c478bd9Sstevel@tonic-gate 3437c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &present); 3447c478bd9Sstevel@tonic-gate if ((status != PSVC_SUCCESS) || (present != PSVC_PRESENT)) 3457c478bd9Sstevel@tonic-gate return (status); 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, &match_count, 3487c478bd9Sstevel@tonic-gate PSVC_FRU); 3497c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 3507c478bd9Sstevel@tonic-gate return (status); 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate for (i = 0; i < match_count; i++) { 3537c478bd9Sstevel@tonic-gate seg_found = 0; 3547c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 3557c478bd9Sstevel@tonic-gate &fru, PSVC_FRU, i); 3567c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 3577c478bd9Sstevel@tonic-gate return (status); 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate fru_data.buf_start = 0x1805; 3607c478bd9Sstevel@tonic-gate fru_data.buf = (char *)&seg_count; 3617c478bd9Sstevel@tonic-gate fru_data.read_size = 1; 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fru, PSVC_FRU_INFO_ATTR, 3647c478bd9Sstevel@tonic-gate &fru_data); 3657c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 3667c478bd9Sstevel@tonic-gate return (status); 3677c478bd9Sstevel@tonic-gate } 3687c478bd9Sstevel@tonic-gate for (j = 0; (j < seg_count) && (!seg_found); j++) { 3697c478bd9Sstevel@tonic-gate fru_data.buf_start = seg_desc_start; 3707c478bd9Sstevel@tonic-gate fru_data.buf = seg_name; 3717c478bd9Sstevel@tonic-gate fru_data.read_size = 2; 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fru, PSVC_FRU_INFO_ATTR, 3747c478bd9Sstevel@tonic-gate &fru_data); 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate seg_desc_start = seg_desc_start + 2; 3777c478bd9Sstevel@tonic-gate fru_data.buf_start = seg_desc_start; 3787c478bd9Sstevel@tonic-gate fru_data.buf = (char *)&segment; 3797c478bd9Sstevel@tonic-gate fru_data.read_size = sizeof (seg_desc_t); 3807c478bd9Sstevel@tonic-gate 3817c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fru, PSVC_FRU_INFO_ATTR, 3827c478bd9Sstevel@tonic-gate &fru_data); 3837c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 3847c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 3857c478bd9Sstevel@tonic-gate "Failed psvc_get_attr for FRU info\n"); 3867c478bd9Sstevel@tonic-gate return (status); 3877c478bd9Sstevel@tonic-gate } 3887c478bd9Sstevel@tonic-gate seg_desc_start = seg_desc_start + sizeof (seg_desc_t); 3897c478bd9Sstevel@tonic-gate if (memcmp(seg_name, "SC", 2) == 0) 3907c478bd9Sstevel@tonic-gate seg_found = 1; 3917c478bd9Sstevel@tonic-gate } 3927c478bd9Sstevel@tonic-gate if (seg_found) { 3937c478bd9Sstevel@tonic-gate temp_address = segment.segoffset + offset; 3947c478bd9Sstevel@tonic-gate fru_data.buf_start = temp_address; 3957c478bd9Sstevel@tonic-gate fru_data.buf = (char *)&temp_array; 3967c478bd9Sstevel@tonic-gate fru_data.read_size = sizeof (temp_array); 3977c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fru, PSVC_FRU_INFO_ATTR, 3987c478bd9Sstevel@tonic-gate &fru_data); 3997c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 4007c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 4017c478bd9Sstevel@tonic-gate "Failed psvc_get_attr for FRU info\n"); 4027c478bd9Sstevel@tonic-gate return (status); 4037c478bd9Sstevel@tonic-gate } else { 4047c478bd9Sstevel@tonic-gate for (j = 0; j < sizeof (temp_array); j++) { 4057c478bd9Sstevel@tonic-gate if (threshold_names[j] == 4067c478bd9Sstevel@tonic-gate PSVC_NOT_USED) 4077c478bd9Sstevel@tonic-gate continue; 4087c478bd9Sstevel@tonic-gate temp = temp_array[j]; 4097c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, 4107c478bd9Sstevel@tonic-gate threshold_names[j], &temp); 4117c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 4127c478bd9Sstevel@tonic-gate return (status); 4137c478bd9Sstevel@tonic-gate } 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate } 4167c478bd9Sstevel@tonic-gate } else { 4177c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "No FRU Information for %s" 4187c478bd9Sstevel@tonic-gate " using default temperatures\n", id); 4197c478bd9Sstevel@tonic-gate } 4207c478bd9Sstevel@tonic-gate } 4217c478bd9Sstevel@tonic-gate return (status); 4227c478bd9Sstevel@tonic-gate } 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate int32_t 4257c478bd9Sstevel@tonic-gate psvc_fan_init_speed_0(psvc_opaque_t hdlp, char *id) 4267c478bd9Sstevel@tonic-gate { 4277c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 4287c478bd9Sstevel@tonic-gate boolean_t present; 4297c478bd9Sstevel@tonic-gate char *control_id; 4307c478bd9Sstevel@tonic-gate int32_t init_speed = 0; 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &present); 4337c478bd9Sstevel@tonic-gate if ((status != PSVC_SUCCESS) || (present != PSVC_PRESENT)) 4347c478bd9Sstevel@tonic-gate return (status); 4357c478bd9Sstevel@tonic-gate 4367c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, &control_id, 4375eb92cf2Sdhain PSVC_FAN_DRIVE_CONTROL, 0); 4387c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 4397c478bd9Sstevel@tonic-gate return (status); 4407c478bd9Sstevel@tonic-gate 4417c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, control_id, PSVC_CONTROL_VALUE_ATTR, 4427c478bd9Sstevel@tonic-gate &init_speed); 4437c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 4447c478bd9Sstevel@tonic-gate syslog(LOG_ERR, SET_FANSPEED_FAILED_MSG, control_id, errno); 4457c478bd9Sstevel@tonic-gate return (status); 4467c478bd9Sstevel@tonic-gate } 4477c478bd9Sstevel@tonic-gate 4487c478bd9Sstevel@tonic-gate return (status); 4497c478bd9Sstevel@tonic-gate } 4507c478bd9Sstevel@tonic-gate 4517c478bd9Sstevel@tonic-gate int32_t 4527c478bd9Sstevel@tonic-gate psvc_update_setpoint_0(psvc_opaque_t hdlp, char *id) 4537c478bd9Sstevel@tonic-gate { 4547c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 4557c478bd9Sstevel@tonic-gate char *temp_sensor; 4567c478bd9Sstevel@tonic-gate int32_t match_count, i, temp; 4577c478bd9Sstevel@tonic-gate int16_t lowest_temp = 500; 4587c478bd9Sstevel@tonic-gate boolean_t present; 4597c478bd9Sstevel@tonic-gate 4607c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &present); 4617c478bd9Sstevel@tonic-gate if ((status != PSVC_SUCCESS) || (present != PSVC_PRESENT)) 4627c478bd9Sstevel@tonic-gate return (status); 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, &match_count, 4657c478bd9Sstevel@tonic-gate PSVC_DEV_TEMP_SENSOR); 4667c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 4677c478bd9Sstevel@tonic-gate return (status); 4687c478bd9Sstevel@tonic-gate 4697c478bd9Sstevel@tonic-gate for (i = 0; i < match_count; i++) { 4707c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 4717c478bd9Sstevel@tonic-gate &temp_sensor, PSVC_DEV_TEMP_SENSOR, i); 4727c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 4737c478bd9Sstevel@tonic-gate return (status); 4747c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, temp_sensor, 4757c478bd9Sstevel@tonic-gate PSVC_OPTIMAL_TEMP_ATTR, &temp); 4767c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 4777c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "Failed to get Optimal temp for %s\n", 4787c478bd9Sstevel@tonic-gate temp_sensor); 4797c478bd9Sstevel@tonic-gate return (status); 4807c478bd9Sstevel@tonic-gate } 4817c478bd9Sstevel@tonic-gate if (temp < lowest_temp) 4827c478bd9Sstevel@tonic-gate lowest_temp = temp; 4837c478bd9Sstevel@tonic-gate } 4847c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_SETPOINT_ATTR, &lowest_temp); 4857c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 4867c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "Failed to change setpoint for %s\n", id); 4877c478bd9Sstevel@tonic-gate return (status); 4887c478bd9Sstevel@tonic-gate } 4897c478bd9Sstevel@tonic-gate return (status); 4907c478bd9Sstevel@tonic-gate } 4917c478bd9Sstevel@tonic-gate 4927c478bd9Sstevel@tonic-gate int32_t 4937c478bd9Sstevel@tonic-gate psvc_remove_missing_nodes_0(psvc_opaque_t hdlp, char *id) 4947c478bd9Sstevel@tonic-gate { 4957c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 4967c478bd9Sstevel@tonic-gate char state[32]; 4977c478bd9Sstevel@tonic-gate char *physical_dev; 4987c478bd9Sstevel@tonic-gate int32_t i, device_count; 4997c478bd9Sstevel@tonic-gate char parent_path[256]; 5007c478bd9Sstevel@tonic-gate picl_nodehdl_t child_node; 5017c478bd9Sstevel@tonic-gate boolean_t present; 5027c478bd9Sstevel@tonic-gate 5037c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, 5047c478bd9Sstevel@tonic-gate &device_count, PSVC_PHYSICAL_DEVICE); 5057c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 5067c478bd9Sstevel@tonic-gate return (status); 5077c478bd9Sstevel@tonic-gate 5087c478bd9Sstevel@tonic-gate for (i = 0; i < device_count; i++) { 5097c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 5107c478bd9Sstevel@tonic-gate &physical_dev, PSVC_PHYSICAL_DEVICE, i); 5117c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 5127c478bd9Sstevel@tonic-gate return (status); 5137c478bd9Sstevel@tonic-gate if (strncmp(physical_dev, "LTC1427", 7) == 0) 5147c478bd9Sstevel@tonic-gate continue; 5157c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, physical_dev, 5167c478bd9Sstevel@tonic-gate PSVC_PROBE_RESULT_ATTR, state); 5177c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 5187c478bd9Sstevel@tonic-gate continue; 5197c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, physical_dev, PSVC_PRESENCE_ATTR, 5207c478bd9Sstevel@tonic-gate &present); 5217c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 5227c478bd9Sstevel@tonic-gate syslog(LOG_ERR, GET_PRESENCE_FAILED_MSG, physical_dev, 5237c478bd9Sstevel@tonic-gate errno); 5247c478bd9Sstevel@tonic-gate return (status); 5257c478bd9Sstevel@tonic-gate } 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate if ((strcmp(state, PSVC_ERROR) == 0) && 5287c478bd9Sstevel@tonic-gate (present == PSVC_PRESENT)) { 5297c478bd9Sstevel@tonic-gate /* convert name to node, and parent path */ 5307c478bd9Sstevel@tonic-gate psvcplugin_lookup(physical_dev, parent_path, 5317c478bd9Sstevel@tonic-gate &child_node); 5327c478bd9Sstevel@tonic-gate /* Device removed */ 5337c478bd9Sstevel@tonic-gate ptree_delete_node(child_node); 5347c478bd9Sstevel@tonic-gate } 5357c478bd9Sstevel@tonic-gate } 5367c478bd9Sstevel@tonic-gate return (status); 5377c478bd9Sstevel@tonic-gate } 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate int32_t 5407c478bd9Sstevel@tonic-gate psvc_check_ps_hotplug_status_0(psvc_opaque_t hdlp, char *id) 5417c478bd9Sstevel@tonic-gate { 5427c478bd9Sstevel@tonic-gate char fail_valid_switch_id[PICL_PROPNAMELEN_MAX]; 5437c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 5447c478bd9Sstevel@tonic-gate char valid_switch_state[32]; 5457c478bd9Sstevel@tonic-gate char state[32], fault[32]; 5467c478bd9Sstevel@tonic-gate int32_t led_count, j; 5477c478bd9Sstevel@tonic-gate char *led_id; 5487c478bd9Sstevel@tonic-gate char led_state[32]; 5497c478bd9Sstevel@tonic-gate boolean_t present; 5507c478bd9Sstevel@tonic-gate static int8_t hotplug_failed_count = 0; 5515eb92cf2Sdhain static int unplugged_ps = 0; 552298b7f4cSjfrank int retry; 5535eb92cf2Sdhain char *unplugged_id; 5547c478bd9Sstevel@tonic-gate 5557c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &present); 5567c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 5577c478bd9Sstevel@tonic-gate syslog(LOG_ERR, GET_PRESENCE_FAILED_MSG, id, errno); 5587c478bd9Sstevel@tonic-gate return (status); 5597c478bd9Sstevel@tonic-gate } 5607c478bd9Sstevel@tonic-gate 5617c478bd9Sstevel@tonic-gate if (present == PSVC_ABSENT) { 5627c478bd9Sstevel@tonic-gate errno = ENODEV; 5637c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 5647c478bd9Sstevel@tonic-gate } 5657c478bd9Sstevel@tonic-gate 5667c478bd9Sstevel@tonic-gate snprintf(fail_valid_switch_id, sizeof (fail_valid_switch_id), "%s%s", 5677c478bd9Sstevel@tonic-gate id, "_SENSOR_VALID_SWITCH"); 5687c478bd9Sstevel@tonic-gate 5697c478bd9Sstevel@tonic-gate retry = 0; 5707c478bd9Sstevel@tonic-gate do { 5717c478bd9Sstevel@tonic-gate if (retry) 572298b7f4cSjfrank (void) sleep(retry_sleep_pshp_status); 5737c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fail_valid_switch_id, 5747c478bd9Sstevel@tonic-gate PSVC_STATE_ATTR, valid_switch_state); 5757c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 5767c478bd9Sstevel@tonic-gate if (hotplug_failed_count == 0) { 5777c478bd9Sstevel@tonic-gate /* 5787c478bd9Sstevel@tonic-gate * First time the get_attr call failed 5797c478bd9Sstevel@tonic-gate * set count so that if we fail again 5807c478bd9Sstevel@tonic-gate * we will know 5817c478bd9Sstevel@tonic-gate */ 5827c478bd9Sstevel@tonic-gate hotplug_failed_count = 1; 5837c478bd9Sstevel@tonic-gate /* 5847c478bd9Sstevel@tonic-gate * We probably failed because the power 5857c478bd9Sstevel@tonic-gate * supply was just insterted or removed 5867c478bd9Sstevel@tonic-gate * before the get_attr call. We then 5877c478bd9Sstevel@tonic-gate * return from this policy successfully 5887c478bd9Sstevel@tonic-gate * knowing it will be run again shortly 5897c478bd9Sstevel@tonic-gate * with the right PS state. 5907c478bd9Sstevel@tonic-gate */ 5917c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 5927c478bd9Sstevel@tonic-gate } else { 5937c478bd9Sstevel@tonic-gate /* 5947c478bd9Sstevel@tonic-gate * We have failed before and so this 5957c478bd9Sstevel@tonic-gate * we will consider a hardware problem 5967c478bd9Sstevel@tonic-gate * and it should be reported 5977c478bd9Sstevel@tonic-gate */ 5987c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 5997c478bd9Sstevel@tonic-gate "Failed getting %s State: ", 6007c478bd9Sstevel@tonic-gate "ps_hotplug_status_0\n", 6017c478bd9Sstevel@tonic-gate fail_valid_switch_id); 6027c478bd9Sstevel@tonic-gate return (status); 6037c478bd9Sstevel@tonic-gate } 6047c478bd9Sstevel@tonic-gate } 6057c478bd9Sstevel@tonic-gate /* 6067c478bd9Sstevel@tonic-gate * Because we have successfully gotten a value from 6077c478bd9Sstevel@tonic-gate * the i2c device on the PS we will set the 6087c478bd9Sstevel@tonic-gate * failed_count to 0 6097c478bd9Sstevel@tonic-gate */ 6107c478bd9Sstevel@tonic-gate hotplug_failed_count = 0; 6117c478bd9Sstevel@tonic-gate 6127c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_STATE_ATTR, state); 6137c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 6147c478bd9Sstevel@tonic-gate return (status); 6157c478bd9Sstevel@tonic-gate retry++; 6167c478bd9Sstevel@tonic-gate /* 6177c478bd9Sstevel@tonic-gate * check to see if we need to retry. the conditions are: 6187c478bd9Sstevel@tonic-gate * 6197c478bd9Sstevel@tonic-gate * valid_switch_state state retry 6207c478bd9Sstevel@tonic-gate * -------------------------------------------------- 6217c478bd9Sstevel@tonic-gate * PSVC_OFF !PSVC_HOTPLUGGED yes 6227c478bd9Sstevel@tonic-gate * PSVC_ON PSVC_HOTPLUGGED yes 6237c478bd9Sstevel@tonic-gate * PSVC_OFF PSVC_HOTPLUGGED no 6247c478bd9Sstevel@tonic-gate * PSVC_ON !PSVC_HOTPLUGGED no 6257c478bd9Sstevel@tonic-gate */ 626298b7f4cSjfrank } while ((retry < n_retry_pshp_status) && 6277c478bd9Sstevel@tonic-gate change_of_state_str(valid_switch_state, PSVC_OFF, 6287c478bd9Sstevel@tonic-gate state, PSVC_HOTPLUGGED)); 6297c478bd9Sstevel@tonic-gate 6307c478bd9Sstevel@tonic-gate if ((strcmp(valid_switch_state, PSVC_OFF) == 0) && 6315eb92cf2Sdhain (strcmp(state, PSVC_HOTPLUGGED) != 0)) { 6327c478bd9Sstevel@tonic-gate strcpy(state, PSVC_HOTPLUGGED); 6337c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_NO_FAULT); 6347c478bd9Sstevel@tonic-gate strcpy(led_state, PSVC_LED_OFF); 6357c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, 6365eb92cf2Sdhain state); 6377c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 6387c478bd9Sstevel@tonic-gate return (status); 6397c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, 6405eb92cf2Sdhain &led_count, PSVC_DEV_FAULT_LED); 6417c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 6427c478bd9Sstevel@tonic-gate return (status); 6437c478bd9Sstevel@tonic-gate 6447c478bd9Sstevel@tonic-gate for (j = 0; j < led_count; j++) { 6457c478bd9Sstevel@tonic-gate 6467c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 6475eb92cf2Sdhain &led_id, PSVC_DEV_FAULT_LED, j); 6487c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 6497c478bd9Sstevel@tonic-gate return (status); 6507c478bd9Sstevel@tonic-gate 6517c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, led_id, 6525eb92cf2Sdhain PSVC_LED_STATE_ATTR, led_state); 6537c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 6547c478bd9Sstevel@tonic-gate syslog(LOG_ERR, SET_LED_FAILED_MSG, led_id, 6557c478bd9Sstevel@tonic-gate errno); 6567c478bd9Sstevel@tonic-gate return (status); 6577c478bd9Sstevel@tonic-gate } 6587c478bd9Sstevel@tonic-gate 6597c478bd9Sstevel@tonic-gate } 6605eb92cf2Sdhain strcpy(led_state, PSVC_LED_ON); 6615eb92cf2Sdhain status = psvc_set_attr(hdlp, "FSP_POWER_FAULT_LED", 6625eb92cf2Sdhain PSVC_LED_STATE_ATTR, led_state); 6635eb92cf2Sdhain if (status != PSVC_SUCCESS) { 6645eb92cf2Sdhain syslog(LOG_ERR, SET_LED_FAILED_MSG, led_id, errno); 6655eb92cf2Sdhain return (status); 6665eb92cf2Sdhain } 6675eb92cf2Sdhain unplugged_id = id + 2; 6685eb92cf2Sdhain unplugged_ps = unplugged_ps | (1 << (int)strtol(unplugged_id, 6695eb92cf2Sdhain (char **)NULL, 10)); 6705eb92cf2Sdhain status = update_gen_fault_led(hdlp, GEN_FAULT_LED); 6717c478bd9Sstevel@tonic-gate syslog(LOG_ERR, PS_UNPLUGGED_MSG, id); 6727c478bd9Sstevel@tonic-gate return (status); 6737c478bd9Sstevel@tonic-gate } 6747c478bd9Sstevel@tonic-gate 6757c478bd9Sstevel@tonic-gate if ((strcmp(valid_switch_state, PSVC_ON) == 0) && 6765eb92cf2Sdhain (strcmp(state, PSVC_HOTPLUGGED) == 0)) { 6777c478bd9Sstevel@tonic-gate strcpy(state, PSVC_OK); 6787c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_NO_FAULT); 6797c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, state); 6807c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 6817c478bd9Sstevel@tonic-gate return (status); 6825eb92cf2Sdhain unplugged_id = id + 2; 6835eb92cf2Sdhain unplugged_ps = unplugged_ps ^ (1 << (int)strtol(unplugged_id, 6845eb92cf2Sdhain (char **)NULL, 10)); 6855eb92cf2Sdhain if (unplugged_ps == 0) { 6865eb92cf2Sdhain strcpy(led_state, PSVC_LED_OFF); 6875eb92cf2Sdhain status = psvc_set_attr(hdlp, "FSP_POWER_FAULT_LED", 6885eb92cf2Sdhain PSVC_LED_STATE_ATTR, led_state); 6895eb92cf2Sdhain if (status != PSVC_SUCCESS) { 6905eb92cf2Sdhain syslog(LOG_ERR, SET_LED_FAILED_MSG, led_id, 6915eb92cf2Sdhain errno); 6925eb92cf2Sdhain return (status); 6935eb92cf2Sdhain } 6945eb92cf2Sdhain status = update_gen_fault_led(hdlp, GEN_FAULT_LED); 6955eb92cf2Sdhain } 6967c478bd9Sstevel@tonic-gate syslog(LOG_ERR, PS_PLUGGED_MSG, id); 6977c478bd9Sstevel@tonic-gate } 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate return (status); 7007c478bd9Sstevel@tonic-gate } 7017c478bd9Sstevel@tonic-gate 7027c478bd9Sstevel@tonic-gate int32_t 7037c478bd9Sstevel@tonic-gate psvc_ps_overcurrent_check_policy_0(psvc_opaque_t hdlp, char *system) 7047c478bd9Sstevel@tonic-gate { 7057c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 7067c478bd9Sstevel@tonic-gate boolean_t present; 7077c478bd9Sstevel@tonic-gate static char *sensor_id[DAKTARI_MAX_PS][DAK_MAX_PS_I_SENSORS]; 708360e6f5eSmathue static char *power_supply_id[DAKTARI_MAX_PS] = {NULL}; 7097c478bd9Sstevel@tonic-gate int32_t i, j; 7107c478bd9Sstevel@tonic-gate int32_t amps, oc_flag = 0, ps_present = 0; 7117c478bd9Sstevel@tonic-gate static int32_t hi_warn[DAKTARI_MAX_PS][DAK_MAX_PS_I_SENSORS]; 7127c478bd9Sstevel@tonic-gate char state[32]; 7137c478bd9Sstevel@tonic-gate static int8_t overcurrent_failed_check = 0; 714298b7f4cSjfrank static int threshold_counter = 0; 7157c478bd9Sstevel@tonic-gate 7167c478bd9Sstevel@tonic-gate if (power_supply_id[0] == NULL) { 7177c478bd9Sstevel@tonic-gate for (i = 0; i < DAKTARI_MAX_PS; i++) { 7187c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, system, 7197c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &(power_supply_id[i]), 7207c478bd9Sstevel@tonic-gate PSVC_PS, i); 7217c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 7227c478bd9Sstevel@tonic-gate return (status); 7237c478bd9Sstevel@tonic-gate for (j = 0; j < DAK_MAX_PS_I_SENSORS; ++j) { 7247c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, 7257c478bd9Sstevel@tonic-gate power_supply_id[i], PSVC_ASSOC_ID_ATTR, 7267c478bd9Sstevel@tonic-gate &(sensor_id[i][j]), PSVC_PS_I_SENSOR, j); 7277c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 7287c478bd9Sstevel@tonic-gate return (status); 7297c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, sensor_id[i][j], 7307c478bd9Sstevel@tonic-gate PSVC_HI_WARN_ATTR, &(hi_warn[i][j])); 7317c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 7327c478bd9Sstevel@tonic-gate return (status); 7337c478bd9Sstevel@tonic-gate } 7347c478bd9Sstevel@tonic-gate } 7357c478bd9Sstevel@tonic-gate } 7367c478bd9Sstevel@tonic-gate 7377c478bd9Sstevel@tonic-gate for (i = 0; i < DAKTARI_MAX_PS; i++) { 7387c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, power_supply_id[i], 7395eb92cf2Sdhain PSVC_PRESENCE_ATTR, &present); 7407c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 7417c478bd9Sstevel@tonic-gate syslog(LOG_ERR, GET_PRESENCE_FAILED_MSG, 7425eb92cf2Sdhain power_supply_id[i], errno); 7437c478bd9Sstevel@tonic-gate return (status); 7447c478bd9Sstevel@tonic-gate } 7457c478bd9Sstevel@tonic-gate 7467c478bd9Sstevel@tonic-gate if (present == PSVC_ABSENT) { 7477c478bd9Sstevel@tonic-gate continue; 7487c478bd9Sstevel@tonic-gate } 7497c478bd9Sstevel@tonic-gate 7507c478bd9Sstevel@tonic-gate status = psvc_check_ps_hotplug_status_0(hdlp, 7517c478bd9Sstevel@tonic-gate power_supply_id[i]); 7527c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 7537c478bd9Sstevel@tonic-gate return (status); 7547c478bd9Sstevel@tonic-gate 7557c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, power_supply_id[i], 7567c478bd9Sstevel@tonic-gate PSVC_STATE_ATTR, state); 7577c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 7587c478bd9Sstevel@tonic-gate return (status); 7597c478bd9Sstevel@tonic-gate 7607c478bd9Sstevel@tonic-gate if (strcmp(state, PSVC_HOTPLUGGED) == 0) { 7617c478bd9Sstevel@tonic-gate continue; 7627c478bd9Sstevel@tonic-gate } else { 7637c478bd9Sstevel@tonic-gate ps_present++; 7647c478bd9Sstevel@tonic-gate } 7657c478bd9Sstevel@tonic-gate 7667c478bd9Sstevel@tonic-gate for (j = 0; j < DAK_MAX_PS_I_SENSORS; ++j) { 7677c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, sensor_id[i][j], 7685eb92cf2Sdhain PSVC_SENSOR_VALUE_ATTR, &s); 7697c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 7707c478bd9Sstevel@tonic-gate if (overcurrent_failed_check == 0) { 7717c478bd9Sstevel@tonic-gate /* 7727c478bd9Sstevel@tonic-gate * First time the get_attr call 7737c478bd9Sstevel@tonic-gate * failed set count so that if we 7747c478bd9Sstevel@tonic-gate * fail again we will know 7757c478bd9Sstevel@tonic-gate */ 7767c478bd9Sstevel@tonic-gate overcurrent_failed_check = 1; 7777c478bd9Sstevel@tonic-gate /* 7787c478bd9Sstevel@tonic-gate * We probably failed because the power 7797c478bd9Sstevel@tonic-gate * supply was just insterted or removed 7807c478bd9Sstevel@tonic-gate * before the get_attr call. We then 7817c478bd9Sstevel@tonic-gate * return from this policy successfully 7827c478bd9Sstevel@tonic-gate * knowing it will be run again shortly 7837c478bd9Sstevel@tonic-gate * with the right PS state. 7847c478bd9Sstevel@tonic-gate */ 7857c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 7867c478bd9Sstevel@tonic-gate } else { 7877c478bd9Sstevel@tonic-gate /* 7887c478bd9Sstevel@tonic-gate * We have failed before and so this we 7897c478bd9Sstevel@tonic-gate * will consider a hardware problem and 7907c478bd9Sstevel@tonic-gate * it should be reported. 7917c478bd9Sstevel@tonic-gate */ 7927c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 7937c478bd9Sstevel@tonic-gate "Failed getting %s sensor value", 7947c478bd9Sstevel@tonic-gate sensor_id[i][j]); 7957c478bd9Sstevel@tonic-gate return (status); 7967c478bd9Sstevel@tonic-gate } 7977c478bd9Sstevel@tonic-gate } 7987c478bd9Sstevel@tonic-gate /* 7997c478bd9Sstevel@tonic-gate * Because we have successfully gotten a value from the 8007c478bd9Sstevel@tonic-gate * i2c device on the PS we will set the failed_count 8017c478bd9Sstevel@tonic-gate * to 0. 8027c478bd9Sstevel@tonic-gate */ 8037c478bd9Sstevel@tonic-gate overcurrent_failed_check = 0; 8047c478bd9Sstevel@tonic-gate 8057c478bd9Sstevel@tonic-gate if (amps >= hi_warn[i][j]) { 8067c478bd9Sstevel@tonic-gate oc_flag = 1; 8077c478bd9Sstevel@tonic-gate } 8087c478bd9Sstevel@tonic-gate } 8097c478bd9Sstevel@tonic-gate } 8107c478bd9Sstevel@tonic-gate 8117c478bd9Sstevel@tonic-gate if (oc_flag) { 8127c478bd9Sstevel@tonic-gate /* 8137c478bd9Sstevel@tonic-gate * Because we observed an overcurrent 8147c478bd9Sstevel@tonic-gate * condition, we increment threshold_counter. 8157c478bd9Sstevel@tonic-gate * Once threshold_counter reaches the value 816298b7f4cSjfrank * of n_read_overcurrent we log the event. 8177c478bd9Sstevel@tonic-gate */ 8187c478bd9Sstevel@tonic-gate threshold_counter++; 819298b7f4cSjfrank if (threshold_counter == n_read_overcurrent) { 8207c478bd9Sstevel@tonic-gate threshold_counter = 0; 8217c478bd9Sstevel@tonic-gate if (ps_present == 1) { 8227c478bd9Sstevel@tonic-gate syslog(LOG_ERR, PS_OVER_CURRENT_MSG); 8237c478bd9Sstevel@tonic-gate syslog(LOG_ERR, ADD_PS_MSG); 8247c478bd9Sstevel@tonic-gate } else { 8257c478bd9Sstevel@tonic-gate syslog(LOG_ERR, PS_OVER_CURRENT_MSG); 8267c478bd9Sstevel@tonic-gate syslog(LOG_ERR, REMOVE_LOAD_MSG); 8277c478bd9Sstevel@tonic-gate } 8287c478bd9Sstevel@tonic-gate } 8297c478bd9Sstevel@tonic-gate } else { 8307c478bd9Sstevel@tonic-gate threshold_counter = 0; 8317c478bd9Sstevel@tonic-gate } 8327c478bd9Sstevel@tonic-gate 8337c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 8347c478bd9Sstevel@tonic-gate } 8357c478bd9Sstevel@tonic-gate 836*8a88157cSvb int32_t 837*8a88157cSvb psvc_ps_undercurrent_check(psvc_opaque_t hdlp, char *id, int32_t *uc_flag) 838*8a88157cSvb { 839*8a88157cSvb int32_t status = PSVC_SUCCESS; 840*8a88157cSvb boolean_t present; 841*8a88157cSvb static char *sensor_id[DAK_MAX_PS_I_SENSORS]; 842*8a88157cSvb int32_t j; 843*8a88157cSvb int32_t amps; 844*8a88157cSvb static int32_t lo_warn[DAK_MAX_PS_I_SENSORS]; 845*8a88157cSvb static int8_t undercurrent_failed_check = 0; 846*8a88157cSvb 847*8a88157cSvb status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &present); 848*8a88157cSvb if (status == PSVC_FAILURE) { 849*8a88157cSvb syslog(LOG_ERR, GET_PRESENCE_FAILED_MSG, id, errno); 850*8a88157cSvb return (status); 851*8a88157cSvb } 852*8a88157cSvb 853*8a88157cSvb if (present == PSVC_ABSENT) { 854*8a88157cSvb errno = ENODEV; 855*8a88157cSvb return (PSVC_FAILURE); 856*8a88157cSvb } 857*8a88157cSvb 858*8a88157cSvb for (j = 0; j < DAK_MAX_PS_I_SENSORS; ++j) { 859*8a88157cSvb status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 860*8a88157cSvb &(sensor_id[j]), PSVC_PS_I_SENSOR, j); 861*8a88157cSvb if (status != PSVC_SUCCESS) 862*8a88157cSvb return (status); 863*8a88157cSvb status = psvc_get_attr(hdlp, sensor_id[j], 864*8a88157cSvb PSVC_LO_WARN_ATTR, &(lo_warn[j])); 865*8a88157cSvb if (status != PSVC_SUCCESS) 866*8a88157cSvb return (status); 867*8a88157cSvb } 868*8a88157cSvb 869*8a88157cSvb *uc_flag = 0; 870*8a88157cSvb for (j = 0; j < DAK_MAX_PS_I_SENSORS; ++j) { 871*8a88157cSvb status = psvc_get_attr(hdlp, sensor_id[j], 872*8a88157cSvb PSVC_SENSOR_VALUE_ATTR, &s); 873*8a88157cSvb if (status != PSVC_SUCCESS) { 874*8a88157cSvb if (undercurrent_failed_check == 0) { 875*8a88157cSvb /* 876*8a88157cSvb * First time the get_attr call 877*8a88157cSvb * failed set count so that if we 878*8a88157cSvb * fail again we will know. 879*8a88157cSvb */ 880*8a88157cSvb undercurrent_failed_check = 1; 881*8a88157cSvb /* 882*8a88157cSvb * We probably failed because the power 883*8a88157cSvb * supply was just inserted or removed 884*8a88157cSvb * before the get_attr call. We then 885*8a88157cSvb * return from this policy successfully 886*8a88157cSvb * knowing it will be run again shortly 887*8a88157cSvb * with the right PS state. 888*8a88157cSvb */ 889*8a88157cSvb return (PSVC_SUCCESS); 890*8a88157cSvb } else { 891*8a88157cSvb /* 892*8a88157cSvb * Repeated failures are logged. 893*8a88157cSvb */ 894*8a88157cSvb syslog(LOG_ERR, 895*8a88157cSvb "Failed getting %s sensor value", 896*8a88157cSvb sensor_id[j]); 897*8a88157cSvb return (status); 898*8a88157cSvb } 899*8a88157cSvb } 900*8a88157cSvb /* 901*8a88157cSvb * Because we have successfully gotten a value from the 902*8a88157cSvb * i2c device on the PS we will set the failed_count 903*8a88157cSvb * to 0. 904*8a88157cSvb */ 905*8a88157cSvb undercurrent_failed_check = 0; 906*8a88157cSvb 907*8a88157cSvb if (amps <= lo_warn[j]) { 908*8a88157cSvb *uc_flag = 1; 909*8a88157cSvb return (PSVC_SUCCESS); 910*8a88157cSvb } 911*8a88157cSvb } 912*8a88157cSvb 913*8a88157cSvb return (PSVC_SUCCESS); 914*8a88157cSvb } 915*8a88157cSvb 9167c478bd9Sstevel@tonic-gate int32_t 9177c478bd9Sstevel@tonic-gate psvc_ps_device_fail_notifier_policy_0(psvc_opaque_t hdlp, char *system) 9187c478bd9Sstevel@tonic-gate { 919360e6f5eSmathue static char *ps_id[DAKTARI_MAX_PS] = {NULL}; 9207c478bd9Sstevel@tonic-gate static char *sensor_id[DAKTARI_MAX_PS][DAK_MAX_FAULT_SENSORS]; 9217c478bd9Sstevel@tonic-gate char *led_id = "FSP_POWER_FAULT_LED"; 922*8a88157cSvb int i, j, uc_flag; 9237c478bd9Sstevel@tonic-gate char state[32], fault[32], previous_state[32], past_state[32]; 9247c478bd9Sstevel@tonic-gate char led_state[32]; 9257c478bd9Sstevel@tonic-gate char bad_sensors[DAK_MAX_FAULT_SENSORS][256]; 926*8a88157cSvb static int threshold_counter[DAKTARI_MAX_PS]; 9277c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 9287c478bd9Sstevel@tonic-gate boolean_t present; 9297c478bd9Sstevel@tonic-gate int fail_state; 9307c478bd9Sstevel@tonic-gate static int8_t device_fail_failed_check = 0; 931298b7f4cSjfrank int retry, should_retry; 9327c478bd9Sstevel@tonic-gate 9337c478bd9Sstevel@tonic-gate if (ps_id[0] == NULL) { 9347c478bd9Sstevel@tonic-gate for (i = 0; i < DAKTARI_MAX_PS; i++) { 9357c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, system, 9367c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &(ps_id[i]), PSVC_PS, i); 9377c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 9387c478bd9Sstevel@tonic-gate return (status); 9397c478bd9Sstevel@tonic-gate for (j = 0; j < DAK_MAX_FAULT_SENSORS; j++) { 9407c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, ps_id[i], 9417c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &(sensor_id[i][j]), 9427c478bd9Sstevel@tonic-gate PSVC_DEV_FAULT_SENSOR, j); 9437c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 9447c478bd9Sstevel@tonic-gate return (status); 9457c478bd9Sstevel@tonic-gate } 9467c478bd9Sstevel@tonic-gate } 9477c478bd9Sstevel@tonic-gate } 9487c478bd9Sstevel@tonic-gate 9497c478bd9Sstevel@tonic-gate for (i = 0; i < DAKTARI_MAX_PS; i++) { 9507c478bd9Sstevel@tonic-gate fail_state = 0; 9517c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, ps_id[i], PSVC_PRESENCE_ATTR, 9527c478bd9Sstevel@tonic-gate &present); 9537c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 9547c478bd9Sstevel@tonic-gate return (status); 9557c478bd9Sstevel@tonic-gate 9567c478bd9Sstevel@tonic-gate if (present == PSVC_ABSENT) { 9577c478bd9Sstevel@tonic-gate errno = ENODEV; 9587c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 9597c478bd9Sstevel@tonic-gate } 9607c478bd9Sstevel@tonic-gate 9617c478bd9Sstevel@tonic-gate status = psvc_check_ps_hotplug_status_0(hdlp, ps_id[i]); 9627c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 9637c478bd9Sstevel@tonic-gate return (status); 9647c478bd9Sstevel@tonic-gate 9657c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, ps_id[i], PSVC_STATE_ATTR, 9667c478bd9Sstevel@tonic-gate past_state); 9677c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 9687c478bd9Sstevel@tonic-gate return (status); 9697c478bd9Sstevel@tonic-gate 9707c478bd9Sstevel@tonic-gate if (strcmp(past_state, PSVC_HOTPLUGGED) == 0) { 9717c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 9727c478bd9Sstevel@tonic-gate } 9737c478bd9Sstevel@tonic-gate 9747c478bd9Sstevel@tonic-gate retry = 0; 9757c478bd9Sstevel@tonic-gate do { 9767c478bd9Sstevel@tonic-gate if (retry) 977298b7f4cSjfrank (void) sleep(retry_sleep_devicefail); 9787c478bd9Sstevel@tonic-gate fail_state = 0; 9797c478bd9Sstevel@tonic-gate should_retry = 0; 9807c478bd9Sstevel@tonic-gate for (j = 0; j < DAK_MAX_FAULT_SENSORS; ++j) { 9817c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, sensor_id[i][j], 9827c478bd9Sstevel@tonic-gate PSVC_SWITCH_STATE_ATTR, state); 9837c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 9847c478bd9Sstevel@tonic-gate if (device_fail_failed_check == 0) { 9857c478bd9Sstevel@tonic-gate /* 9867c478bd9Sstevel@tonic-gate * First time the get_attr call 9877c478bd9Sstevel@tonic-gate * failed set count so that 9887c478bd9Sstevel@tonic-gate * if we fail again we will know 9897c478bd9Sstevel@tonic-gate */ 9907c478bd9Sstevel@tonic-gate device_fail_failed_check = 1; 9917c478bd9Sstevel@tonic-gate /* 9927c478bd9Sstevel@tonic-gate * We probably failed because 9937c478bd9Sstevel@tonic-gate * the power supply was just 9947c478bd9Sstevel@tonic-gate * insterted or removed before 9957c478bd9Sstevel@tonic-gate * the get_attr call. We then 9967c478bd9Sstevel@tonic-gate * return from this policy 9977c478bd9Sstevel@tonic-gate * successfully knowing it will 9987c478bd9Sstevel@tonic-gate * be run again shortly 9997c478bd9Sstevel@tonic-gate * with the right PS state. 10007c478bd9Sstevel@tonic-gate */ 10017c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 10027c478bd9Sstevel@tonic-gate } else { 10037c478bd9Sstevel@tonic-gate /* 10047c478bd9Sstevel@tonic-gate * We have failed before and 10057c478bd9Sstevel@tonic-gate * so this we will consider a 10067c478bd9Sstevel@tonic-gate * hardware problem and 10077c478bd9Sstevel@tonic-gate * it should be reported. 10087c478bd9Sstevel@tonic-gate */ 10097c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "Failed in " 10107c478bd9Sstevel@tonic-gate "getting sensor state for " 10117c478bd9Sstevel@tonic-gate "%s\n", sensor_id[i][j]); 10127c478bd9Sstevel@tonic-gate 10137c478bd9Sstevel@tonic-gate return (status); 10147c478bd9Sstevel@tonic-gate } 10157c478bd9Sstevel@tonic-gate } 10167c478bd9Sstevel@tonic-gate 10177c478bd9Sstevel@tonic-gate /* 10187c478bd9Sstevel@tonic-gate * Because we have successfully gotten 10197c478bd9Sstevel@tonic-gate * a value from the i2c device on the 10207c478bd9Sstevel@tonic-gate * PS we will set the failed_count to 0. 10217c478bd9Sstevel@tonic-gate */ 10227c478bd9Sstevel@tonic-gate device_fail_failed_check = 0; 10237c478bd9Sstevel@tonic-gate 10247c478bd9Sstevel@tonic-gate /* 10257c478bd9Sstevel@tonic-gate * If we find that the sensor is on we 10267c478bd9Sstevel@tonic-gate * fill in the name of the sensor in 10277c478bd9Sstevel@tonic-gate * the bad_sensor array. If the sensor 10287c478bd9Sstevel@tonic-gate * is off we use EMPTY_STRING as a check 10297c478bd9Sstevel@tonic-gate * later on as to when NOT to print out 10307c478bd9Sstevel@tonic-gate * what is in bad_sensor[]. 10317c478bd9Sstevel@tonic-gate */ 10327c478bd9Sstevel@tonic-gate if (strcmp(state, PSVC_SWITCH_ON) == 0) { 10337c478bd9Sstevel@tonic-gate fail_state++; 10347c478bd9Sstevel@tonic-gate strlcpy(bad_sensors[j], sensor_id[i][j], 10357c478bd9Sstevel@tonic-gate sizeof (bad_sensors[j])); 10367c478bd9Sstevel@tonic-gate } else { 10377c478bd9Sstevel@tonic-gate strcpy(bad_sensors[j], EMPTY_STRING); 10387c478bd9Sstevel@tonic-gate } 10397c478bd9Sstevel@tonic-gate } 10407c478bd9Sstevel@tonic-gate retry++; 10417c478bd9Sstevel@tonic-gate /* 10427c478bd9Sstevel@tonic-gate * check to see if we need to retry. the conditions are: 10437c478bd9Sstevel@tonic-gate * 10447c478bd9Sstevel@tonic-gate * fail_state past_state retry 10457c478bd9Sstevel@tonic-gate * -------------------------------------------------- 10467c478bd9Sstevel@tonic-gate * + PSVC_OK yes 10477c478bd9Sstevel@tonic-gate * 0 PSVC_ERROR yes 10487c478bd9Sstevel@tonic-gate * + PSVC_ERROR no 10497c478bd9Sstevel@tonic-gate * 0 PSVC_OK no 10507c478bd9Sstevel@tonic-gate */ 10517c478bd9Sstevel@tonic-gate if ((fail_state > 0) && 10527c478bd9Sstevel@tonic-gate (strcmp(past_state, PSVC_OK) == 0)) { 10537c478bd9Sstevel@tonic-gate should_retry = 1; 10547c478bd9Sstevel@tonic-gate } else if ((fail_state == 0) && 10557c478bd9Sstevel@tonic-gate (strcmp(past_state, PSVC_ERROR) == 0)) { 10567c478bd9Sstevel@tonic-gate should_retry = 1; 10577c478bd9Sstevel@tonic-gate } 1058298b7f4cSjfrank } while ((retry < n_retry_devicefail) && should_retry); 10597c478bd9Sstevel@tonic-gate 1060*8a88157cSvb /* Under current check */ 1061*8a88157cSvb status = psvc_ps_undercurrent_check(hdlp, ps_id[i], &uc_flag); 1062*8a88157cSvb 1063*8a88157cSvb if (status != PSVC_FAILURE) { 1064*8a88157cSvb if (uc_flag) { 1065*8a88157cSvb /* 1066*8a88157cSvb * Because we observed an undercurrent 1067*8a88157cSvb * condition, we increment threshold counter. 1068*8a88157cSvb * Once threshold counter reaches the value 1069*8a88157cSvb * of n_read_undercurrent we log the event. 1070*8a88157cSvb */ 1071*8a88157cSvb threshold_counter[i]++; 1072*8a88157cSvb if (threshold_counter[i] >= 1073*8a88157cSvb n_read_undercurrent) { 1074*8a88157cSvb fail_state++; 1075*8a88157cSvb syslog(LOG_ERR, PS_UNDER_CURRENT_MSG, 1076*8a88157cSvb i); 1077*8a88157cSvb } 1078*8a88157cSvb } else { 1079*8a88157cSvb threshold_counter[i] = 0; 1080*8a88157cSvb } 1081*8a88157cSvb } 1082*8a88157cSvb 10837c478bd9Sstevel@tonic-gate if (fail_state != 0) { 10847c478bd9Sstevel@tonic-gate strcpy(state, PSVC_ERROR); 10857c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_GEN_FAULT); 10867c478bd9Sstevel@tonic-gate } else { 10877c478bd9Sstevel@tonic-gate strcpy(state, PSVC_OK); 10887c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_NO_FAULT); 10897c478bd9Sstevel@tonic-gate } 10907c478bd9Sstevel@tonic-gate 10917c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, ps_id[i], PSVC_STATE_ATTR, state); 10927c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 10937c478bd9Sstevel@tonic-gate return (status); 10947c478bd9Sstevel@tonic-gate 10957c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, ps_id[i], PSVC_FAULTID_ATTR, 10967c478bd9Sstevel@tonic-gate fault); 10977c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 10987c478bd9Sstevel@tonic-gate return (status); 10997c478bd9Sstevel@tonic-gate 11007c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, ps_id[i], PSVC_PREV_STATE_ATTR, 11017c478bd9Sstevel@tonic-gate previous_state); 11027c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 11037c478bd9Sstevel@tonic-gate return (status); 11047c478bd9Sstevel@tonic-gate 11057c478bd9Sstevel@tonic-gate if (strcmp(state, previous_state) != 0) { 11067c478bd9Sstevel@tonic-gate char dev_label[32]; 11077c478bd9Sstevel@tonic-gate 11087c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, ps_id[i], PSVC_LABEL_ATTR, 11097c478bd9Sstevel@tonic-gate dev_label); 11107c478bd9Sstevel@tonic-gate 11117c478bd9Sstevel@tonic-gate if (strcmp(state, PSVC_ERROR) == 0) { 11127c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_FAILURE_MSG, dev_label); 11137c478bd9Sstevel@tonic-gate for (j = 0; j < DAK_MAX_FAULT_SENSORS; ++j) { 11147c478bd9Sstevel@tonic-gate if (strcmp(bad_sensors[j], 11155eb92cf2Sdhain EMPTY_STRING) != 0) 11167c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "%s\n", 11177c478bd9Sstevel@tonic-gate bad_sensors[j]); 11187c478bd9Sstevel@tonic-gate } 11197c478bd9Sstevel@tonic-gate strcpy(led_state, PSVC_LED_ON); 11207c478bd9Sstevel@tonic-gate } else { 11217c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_OK_MSG, dev_label); 11227c478bd9Sstevel@tonic-gate strcpy(led_state, PSVC_LED_OFF); 11237c478bd9Sstevel@tonic-gate } 11247c478bd9Sstevel@tonic-gate 11257c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, led_id, 11267c478bd9Sstevel@tonic-gate PSVC_LED_STATE_ATTR, led_state); 11277c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 11287c478bd9Sstevel@tonic-gate syslog(LOG_ERR, SET_LED_FAILED_MSG, led_id, 11297c478bd9Sstevel@tonic-gate errno); 11307c478bd9Sstevel@tonic-gate return (status); 11317c478bd9Sstevel@tonic-gate } 11327c478bd9Sstevel@tonic-gate } 11337c478bd9Sstevel@tonic-gate } 11347c478bd9Sstevel@tonic-gate 11357c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 11367c478bd9Sstevel@tonic-gate } 11377c478bd9Sstevel@tonic-gate 11387c478bd9Sstevel@tonic-gate int32_t 11397c478bd9Sstevel@tonic-gate psvc_ps_check_and_disable_dr_policy_0(psvc_opaque_t hdlp, char *id) 11407c478bd9Sstevel@tonic-gate { 11417c478bd9Sstevel@tonic-gate char state[32]; 1142360e6f5eSmathue static char *name[DAKTARI_MAX_PS] = {NULL}; 11437c478bd9Sstevel@tonic-gate int ps_cnt = 0; 11447c478bd9Sstevel@tonic-gate int i, j; 11457c478bd9Sstevel@tonic-gate int dr_conf; 11467c478bd9Sstevel@tonic-gate int fd, rv; 11477c478bd9Sstevel@tonic-gate boolean_t present; 11487c478bd9Sstevel@tonic-gate char dev_path[sizeof (HPC3130_DEV)+8]; 11497c478bd9Sstevel@tonic-gate unsigned char controller_names[HPC3130_CONTROLLERS] = 11507c478bd9Sstevel@tonic-gate { 0xe2, 0xe6, 0xe8, 0xec }; 11517c478bd9Sstevel@tonic-gate 11527c478bd9Sstevel@tonic-gate if (name[0] == NULL) { 11537c478bd9Sstevel@tonic-gate for (i = 0; i < DAKTARI_MAX_PS; i++) { 11547c478bd9Sstevel@tonic-gate rv = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 11557c478bd9Sstevel@tonic-gate &(name[i]), PSVC_PS, i); 11567c478bd9Sstevel@tonic-gate if (rv != PSVC_SUCCESS) 11577c478bd9Sstevel@tonic-gate return (rv); 11587c478bd9Sstevel@tonic-gate } 11597c478bd9Sstevel@tonic-gate } 11607c478bd9Sstevel@tonic-gate 11617c478bd9Sstevel@tonic-gate /* 11627c478bd9Sstevel@tonic-gate * Go through the power supplies to make sure they're present 11637c478bd9Sstevel@tonic-gate * and OK. 11647c478bd9Sstevel@tonic-gate */ 11657c478bd9Sstevel@tonic-gate ps_cnt = DAKTARI_MAX_PS; 11667c478bd9Sstevel@tonic-gate for (i = 0; i < DAKTARI_MAX_PS; i++) { 11677c478bd9Sstevel@tonic-gate rv = psvc_get_attr(hdlp, name[i], PSVC_PRESENCE_ATTR, 11687c478bd9Sstevel@tonic-gate &present); 11697c478bd9Sstevel@tonic-gate if (rv != PSVC_SUCCESS) 11707c478bd9Sstevel@tonic-gate return (rv); 11717c478bd9Sstevel@tonic-gate 11727c478bd9Sstevel@tonic-gate if (present != PSVC_PRESENT) { 11737c478bd9Sstevel@tonic-gate ps_cnt--; 11747c478bd9Sstevel@tonic-gate continue; 11757c478bd9Sstevel@tonic-gate } else { 11767c478bd9Sstevel@tonic-gate rv = psvc_get_attr(hdlp, name[i], PSVC_STATE_ATTR, 11775eb92cf2Sdhain state); 11787c478bd9Sstevel@tonic-gate if (rv != PSVC_SUCCESS) 11797c478bd9Sstevel@tonic-gate return (rv); 11807c478bd9Sstevel@tonic-gate 11817c478bd9Sstevel@tonic-gate if (strcmp(state, PSVC_OK)) 11827c478bd9Sstevel@tonic-gate ps_cnt--; 11837c478bd9Sstevel@tonic-gate } 11847c478bd9Sstevel@tonic-gate } 11857c478bd9Sstevel@tonic-gate 11867c478bd9Sstevel@tonic-gate /* 11877c478bd9Sstevel@tonic-gate * No change in DR configuration is needed if the new power supply 11887c478bd9Sstevel@tonic-gate * count equals the current count. 11897c478bd9Sstevel@tonic-gate */ 11907c478bd9Sstevel@tonic-gate if (ps_cnt == co_ps) 11917c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 11927c478bd9Sstevel@tonic-gate 11937c478bd9Sstevel@tonic-gate /* 11947c478bd9Sstevel@tonic-gate * Disable DR when hotplugged down to 1 power supply; enable DR when 11957c478bd9Sstevel@tonic-gate * hotplugged up from 1 supply. 11967c478bd9Sstevel@tonic-gate */ 11977c478bd9Sstevel@tonic-gate assert(ps_cnt); 11987c478bd9Sstevel@tonic-gate if ((co_ps == 0 || co_ps > 1) && ps_cnt != 1) { 11997c478bd9Sstevel@tonic-gate co_ps = ps_cnt; 12007c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 12017c478bd9Sstevel@tonic-gate } 12027c478bd9Sstevel@tonic-gate dr_conf = (ps_cnt == 1 ? HPC3130_DR_DISABLE : HPC3130_DR_ENABLE); 12037c478bd9Sstevel@tonic-gate co_ps = ps_cnt; 12047c478bd9Sstevel@tonic-gate 12057c478bd9Sstevel@tonic-gate for (i = 0; i < HPC3130_CONTROLLERS; i++) { 12067c478bd9Sstevel@tonic-gate for (j = 0; j < HPC3130_SLOTS; j++) { 12077c478bd9Sstevel@tonic-gate (void) snprintf(dev_path, sizeof (dev_path), 12087c478bd9Sstevel@tonic-gate HPC3130_DEV, controller_names[i], j); 12097c478bd9Sstevel@tonic-gate fd = open(dev_path, O_RDWR); 12107c478bd9Sstevel@tonic-gate if (fd == -1) 12117c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 12127c478bd9Sstevel@tonic-gate 12137c478bd9Sstevel@tonic-gate rv = ioctl(fd, HPC3130_CONF_DR, &dr_conf); 12147c478bd9Sstevel@tonic-gate close(fd); 12157c478bd9Sstevel@tonic-gate if (rv == -1) 12167c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 12177c478bd9Sstevel@tonic-gate } 12187c478bd9Sstevel@tonic-gate } 12197c478bd9Sstevel@tonic-gate 12207c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 12217c478bd9Sstevel@tonic-gate } 12227c478bd9Sstevel@tonic-gate 12237c478bd9Sstevel@tonic-gate int32_t 12247c478bd9Sstevel@tonic-gate psvc_fan_blast_shutoff_policy_0(psvc_opaque_t hdlp, char *id) 12257c478bd9Sstevel@tonic-gate { 12267c478bd9Sstevel@tonic-gate char switch_status[32]; 12277c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 12287c478bd9Sstevel@tonic-gate 12297c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_SWITCH_STATE_ATTR, switch_status); 12307c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 12317c478bd9Sstevel@tonic-gate return (status); 12327c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_SWITCH_STATE_ATTR, 12335eb92cf2Sdhain PSVC_SWITCH_OFF); 12347c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 12357c478bd9Sstevel@tonic-gate return (status); 12367c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_SWITCH_STATE_ATTR, 12375eb92cf2Sdhain PSVC_SWITCH_ON); 12387c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 12397c478bd9Sstevel@tonic-gate return (status); 12407c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_SWITCH_STATE_ATTR, 12415eb92cf2Sdhain PSVC_SWITCH_OFF); 12427c478bd9Sstevel@tonic-gate 12437c478bd9Sstevel@tonic-gate return (status); 12447c478bd9Sstevel@tonic-gate } 12457c478bd9Sstevel@tonic-gate 12467c478bd9Sstevel@tonic-gate int32_t 12477c478bd9Sstevel@tonic-gate psvc_fan_fault_check_policy_0(psvc_opaque_t hdlp, char *system) 12487c478bd9Sstevel@tonic-gate { 1249360e6f5eSmathue static char *fan_id[DAK_MAX_FANS] = {NULL}; 12507c478bd9Sstevel@tonic-gate boolean_t enabled; 12517c478bd9Sstevel@tonic-gate int32_t speed; 12527c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 12537c478bd9Sstevel@tonic-gate int r; 1254298b7f4cSjfrank static int threshold_counter = 0; 12557c478bd9Sstevel@tonic-gate 12567c478bd9Sstevel@tonic-gate if (fan_id[0] == NULL) { 12577c478bd9Sstevel@tonic-gate for (r = 0; r < DAK_MAX_FANS; r++) { 12587c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, system, 12597c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &(fan_id[r]), PSVC_FAN, r); 12607c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 12617c478bd9Sstevel@tonic-gate return (status); 12627c478bd9Sstevel@tonic-gate } 12637c478bd9Sstevel@tonic-gate } 12647c478bd9Sstevel@tonic-gate 12657c478bd9Sstevel@tonic-gate for (r = 0; r < DAK_MAX_FANS; r++) { 12667c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fan_id[r], PSVC_ENABLE_ATTR, 12677c478bd9Sstevel@tonic-gate &enabled); 12687c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 12697c478bd9Sstevel@tonic-gate return (status); 12707c478bd9Sstevel@tonic-gate 12717c478bd9Sstevel@tonic-gate if (enabled == PSVC_ENABLED) { 12727c478bd9Sstevel@tonic-gate uint64_t features; 12737c478bd9Sstevel@tonic-gate char *switch_id; 12747c478bd9Sstevel@tonic-gate char switch_state[32], fan_state[32]; 12757c478bd9Sstevel@tonic-gate int fan_count, fans; 12767c478bd9Sstevel@tonic-gate char *other_fan_id; 12777c478bd9Sstevel@tonic-gate char fstate[32], ffault[32]; 12787c478bd9Sstevel@tonic-gate 12797c478bd9Sstevel@tonic-gate /* 12807c478bd9Sstevel@tonic-gate * If any other fan on the fan tray has an ERROR state, 12817c478bd9Sstevel@tonic-gate * mark this fan bad and return 12827c478bd9Sstevel@tonic-gate */ 12837c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, fan_id[r], PSVC_ASSOC_MATCHES_ATTR, 12847c478bd9Sstevel@tonic-gate &fan_count, PSVC_FAN_TRAY_FANS); 12857c478bd9Sstevel@tonic-gate for (fans = 0; fans < fan_count; ++fans) { 12867c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fan_id[r], 12877c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &other_fan_id, 12887c478bd9Sstevel@tonic-gate PSVC_FAN_TRAY_FANS, fans); 12897c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 12907c478bd9Sstevel@tonic-gate return (status); 12917c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, other_fan_id, 12927c478bd9Sstevel@tonic-gate PSVC_STATE_ATTR, fan_state); 12937c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 12947c478bd9Sstevel@tonic-gate return (status); 12957c478bd9Sstevel@tonic-gate 12967c478bd9Sstevel@tonic-gate if (strcmp(fan_state, PSVC_ERROR) == 0) { 12977c478bd9Sstevel@tonic-gate strlcpy(ffault, PSVC_GEN_FAULT, 12987c478bd9Sstevel@tonic-gate sizeof (ffault)); 12997c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, fan_id[r], 13007c478bd9Sstevel@tonic-gate PSVC_FAULTID_ATTR, ffault); 13017c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 13027c478bd9Sstevel@tonic-gate return (status); 13037c478bd9Sstevel@tonic-gate 13047c478bd9Sstevel@tonic-gate strlcpy(fstate, PSVC_ERROR, 13057c478bd9Sstevel@tonic-gate sizeof (fstate)); 13067c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, fan_id[r], 13077c478bd9Sstevel@tonic-gate PSVC_STATE_ATTR, fstate); 13087c478bd9Sstevel@tonic-gate 13097c478bd9Sstevel@tonic-gate return (status); 13107c478bd9Sstevel@tonic-gate } 13117c478bd9Sstevel@tonic-gate } 13127c478bd9Sstevel@tonic-gate 13137c478bd9Sstevel@tonic-gate /* 13147c478bd9Sstevel@tonic-gate * Select tachometer for IO or CPU primary/secondary 13157c478bd9Sstevel@tonic-gate * fans. 13167c478bd9Sstevel@tonic-gate */ 13177c478bd9Sstevel@tonic-gate pthread_mutex_lock(&fan_mutex); 13187c478bd9Sstevel@tonic-gate 13197c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fan_id[r], 13207c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &switch_id, 13217c478bd9Sstevel@tonic-gate PSVC_FAN_PRIM_SEC_SELECTOR, 0); 13227c478bd9Sstevel@tonic-gate 13237c478bd9Sstevel@tonic-gate if (status != PSVC_FAILURE) { 13247c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fan_id[r], 13257c478bd9Sstevel@tonic-gate PSVC_FEATURES_ATTR, &features); 13267c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 13277c478bd9Sstevel@tonic-gate pthread_mutex_unlock(&fan_mutex); 13287c478bd9Sstevel@tonic-gate return (status); 13297c478bd9Sstevel@tonic-gate } 13307c478bd9Sstevel@tonic-gate 13317c478bd9Sstevel@tonic-gate if (features & PSVC_DEV_PRIMARY) 13327c478bd9Sstevel@tonic-gate strlcpy(switch_state, PSVC_SWITCH_ON, 13337c478bd9Sstevel@tonic-gate sizeof (switch_state)); 13347c478bd9Sstevel@tonic-gate else 13357c478bd9Sstevel@tonic-gate strlcpy(switch_state, PSVC_SWITCH_OFF, 13367c478bd9Sstevel@tonic-gate sizeof (switch_state)); 13377c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, switch_id, 13387c478bd9Sstevel@tonic-gate PSVC_SWITCH_STATE_ATTR, switch_state); 13397c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 13407c478bd9Sstevel@tonic-gate pthread_mutex_unlock(&fan_mutex); 13417c478bd9Sstevel@tonic-gate return (status); 13427c478bd9Sstevel@tonic-gate } 13437c478bd9Sstevel@tonic-gate 13447c478bd9Sstevel@tonic-gate /* allow time for speed to be determined */ 13457c478bd9Sstevel@tonic-gate (void) poll(NULL, 0, 250); 13467c478bd9Sstevel@tonic-gate } 13477c478bd9Sstevel@tonic-gate 13487c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fan_id[r], 13497c478bd9Sstevel@tonic-gate PSVC_SENSOR_VALUE_ATTR, &speed); 13507c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 13517c478bd9Sstevel@tonic-gate pthread_mutex_unlock(&fan_mutex); 13527c478bd9Sstevel@tonic-gate return (status); 13537c478bd9Sstevel@tonic-gate } 13547c478bd9Sstevel@tonic-gate 13557c478bd9Sstevel@tonic-gate pthread_mutex_unlock(&fan_mutex); 13567c478bd9Sstevel@tonic-gate 13577c478bd9Sstevel@tonic-gate if (speed == 0) { 13587c478bd9Sstevel@tonic-gate threshold_counter++; 13597c478bd9Sstevel@tonic-gate if (threshold_counter == 1360298b7f4cSjfrank n_read_fanfault) { 13617c478bd9Sstevel@tonic-gate int32_t i; 13627c478bd9Sstevel@tonic-gate int32_t led_count; 13637c478bd9Sstevel@tonic-gate char led_state[32]; 13647c478bd9Sstevel@tonic-gate char *led_id; 13657c478bd9Sstevel@tonic-gate char *slot_id; 13667c478bd9Sstevel@tonic-gate char label[32]; 13677c478bd9Sstevel@tonic-gate char state[32], fault[32]; 13687c478bd9Sstevel@tonic-gate 13697c478bd9Sstevel@tonic-gate threshold_counter = 0; 13707c478bd9Sstevel@tonic-gate strlcpy(fault, PSVC_GEN_FAULT, 13717c478bd9Sstevel@tonic-gate sizeof (fault)); 13727c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, fan_id[r], 13737c478bd9Sstevel@tonic-gate PSVC_FAULTID_ATTR, fault); 13747c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 13757c478bd9Sstevel@tonic-gate return (status); 13767c478bd9Sstevel@tonic-gate 13777c478bd9Sstevel@tonic-gate strlcpy(state, PSVC_ERROR, 13787c478bd9Sstevel@tonic-gate sizeof (state)); 13797c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, fan_id[r], 13807c478bd9Sstevel@tonic-gate PSVC_STATE_ATTR, state); 13817c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 13827c478bd9Sstevel@tonic-gate return (status); 13837c478bd9Sstevel@tonic-gate 13847c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fan_id[r], 13857c478bd9Sstevel@tonic-gate PSVC_LABEL_ATTR, label); 13867c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 13877c478bd9Sstevel@tonic-gate return (status); 13887c478bd9Sstevel@tonic-gate 13897c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_FAILURE_MSG, 13907c478bd9Sstevel@tonic-gate label); 13917c478bd9Sstevel@tonic-gate 13927c478bd9Sstevel@tonic-gate /* turn on fault LEDs */ 13937c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, fan_id[r], 13947c478bd9Sstevel@tonic-gate PSVC_ASSOC_MATCHES_ATTR, &led_count, 13957c478bd9Sstevel@tonic-gate PSVC_DEV_FAULT_LED); 13967c478bd9Sstevel@tonic-gate strlcpy(led_state, PSVC_LED_ON, 13977c478bd9Sstevel@tonic-gate sizeof (led_state)); 13987c478bd9Sstevel@tonic-gate for (i = 0; i < led_count; ++i) { 13997c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, 14007c478bd9Sstevel@tonic-gate fan_id[r], 14017c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &led_id, 14027c478bd9Sstevel@tonic-gate PSVC_DEV_FAULT_LED, i); 14037c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 14047c478bd9Sstevel@tonic-gate return (status); 14057c478bd9Sstevel@tonic-gate 14067c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, 14077c478bd9Sstevel@tonic-gate led_id, PSVC_LED_STATE_ATTR, 14087c478bd9Sstevel@tonic-gate led_state); 14097c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 14107c478bd9Sstevel@tonic-gate return (status); 14117c478bd9Sstevel@tonic-gate } 14127c478bd9Sstevel@tonic-gate 14137c478bd9Sstevel@tonic-gate /* turn on OK to remove LEDs */ 14147c478bd9Sstevel@tonic-gate 14157c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fan_id[r], 14167c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &slot_id, 14177c478bd9Sstevel@tonic-gate PSVC_PARENT, 0); 14187c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 14197c478bd9Sstevel@tonic-gate return (status); 14207c478bd9Sstevel@tonic-gate 14217c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, slot_id, 14227c478bd9Sstevel@tonic-gate PSVC_ASSOC_MATCHES_ATTR, &led_count, 14237c478bd9Sstevel@tonic-gate PSVC_SLOT_REMOVE_LED); 14247c478bd9Sstevel@tonic-gate strlcpy(led_state, PSVC_LED_ON, 14257c478bd9Sstevel@tonic-gate sizeof (led_state)); 14267c478bd9Sstevel@tonic-gate for (i = 0; i < led_count; ++i) { 14277c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, 14287c478bd9Sstevel@tonic-gate slot_id, 14297c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &led_id, 14307c478bd9Sstevel@tonic-gate PSVC_SLOT_REMOVE_LED, i); 14317c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 14327c478bd9Sstevel@tonic-gate return (status); 14337c478bd9Sstevel@tonic-gate 14347c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, 14357c478bd9Sstevel@tonic-gate led_id, PSVC_LED_STATE_ATTR, 14367c478bd9Sstevel@tonic-gate led_state); 14377c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 14387c478bd9Sstevel@tonic-gate return (status); 14397c478bd9Sstevel@tonic-gate } 14407c478bd9Sstevel@tonic-gate } 14417c478bd9Sstevel@tonic-gate } 14427c478bd9Sstevel@tonic-gate } 14437c478bd9Sstevel@tonic-gate } 14447c478bd9Sstevel@tonic-gate 14457c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 14467c478bd9Sstevel@tonic-gate } 14477c478bd9Sstevel@tonic-gate 14487c478bd9Sstevel@tonic-gate /* 14497c478bd9Sstevel@tonic-gate * This routine takes in the PSVC handle pointer, the PS name, and the 14507c478bd9Sstevel@tonic-gate * instance number (0, 1, or 2). It simply make a psvc_get call to get the 14517c478bd9Sstevel@tonic-gate * presence of each of the children under the PS. This call will set the 14527c478bd9Sstevel@tonic-gate * presence state of the child device if it was not there when the system 14537c478bd9Sstevel@tonic-gate * was booted. 14547c478bd9Sstevel@tonic-gate */ 14557c478bd9Sstevel@tonic-gate static int 14567c478bd9Sstevel@tonic-gate handle_ps_hotplug_children_presence(psvc_opaque_t hdlp, char *id) 14577c478bd9Sstevel@tonic-gate { 14587c478bd9Sstevel@tonic-gate char *sensor_id; 14597c478bd9Sstevel@tonic-gate char fail_valid_switch_id[PICL_PROPNAMELEN_MAX]; 14607c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 14617c478bd9Sstevel@tonic-gate boolean_t presence; 14627c478bd9Sstevel@tonic-gate int j; 14637c478bd9Sstevel@tonic-gate 14647c478bd9Sstevel@tonic-gate /* Get the Sensor Valid Switch presence */ 14657c478bd9Sstevel@tonic-gate snprintf(fail_valid_switch_id, sizeof (fail_valid_switch_id), "%s%s", 14667c478bd9Sstevel@tonic-gate id, "_SENSOR_VALID_SWITCH"); 14677c478bd9Sstevel@tonic-gate 14687c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fail_valid_switch_id, PSVC_PRESENCE_ATTR, 14697c478bd9Sstevel@tonic-gate &presence); 14707c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 14717c478bd9Sstevel@tonic-gate return (status); 14727c478bd9Sstevel@tonic-gate 14737c478bd9Sstevel@tonic-gate /* Go through each PS's fault sensors */ 14747c478bd9Sstevel@tonic-gate for (j = 0; j < DAK_MAX_FAULT_SENSORS; j++) { 14757c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 14767c478bd9Sstevel@tonic-gate &(sensor_id), PSVC_DEV_FAULT_SENSOR, j); 14777c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 14787c478bd9Sstevel@tonic-gate return (status); 14797c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, sensor_id, PSVC_PRESENCE_ATTR, 14807c478bd9Sstevel@tonic-gate &presence); 14817c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 14827c478bd9Sstevel@tonic-gate return (status); 14837c478bd9Sstevel@tonic-gate } 14847c478bd9Sstevel@tonic-gate 14857c478bd9Sstevel@tonic-gate /* Go through each PS's current sensors */ 14867c478bd9Sstevel@tonic-gate for (j = 0; j < DAK_MAX_PS_I_SENSORS; ++j) { 14877c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 14887c478bd9Sstevel@tonic-gate &(sensor_id), PSVC_PS_I_SENSOR, j); 14897c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 14907c478bd9Sstevel@tonic-gate return (status); 14917c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, sensor_id, PSVC_PRESENCE_ATTR, 14927c478bd9Sstevel@tonic-gate &presence); 14937c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 14947c478bd9Sstevel@tonic-gate return (status); 14957c478bd9Sstevel@tonic-gate 14967c478bd9Sstevel@tonic-gate } 14977c478bd9Sstevel@tonic-gate 14987c478bd9Sstevel@tonic-gate /* Go through each PS's onboard i2c hardware */ 14997c478bd9Sstevel@tonic-gate for (j = 0; j < 3; j++) { 15007c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 15017c478bd9Sstevel@tonic-gate &(sensor_id), PSVC_PHYSICAL_DEVICE, j); 15027c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 15037c478bd9Sstevel@tonic-gate return (status); 15047c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, sensor_id, PSVC_PRESENCE_ATTR, 15057c478bd9Sstevel@tonic-gate &presence); 15067c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 15077c478bd9Sstevel@tonic-gate return (status); 15087c478bd9Sstevel@tonic-gate } 15097c478bd9Sstevel@tonic-gate 15107c478bd9Sstevel@tonic-gate return (status); 15117c478bd9Sstevel@tonic-gate } 15127c478bd9Sstevel@tonic-gate 15137c478bd9Sstevel@tonic-gate static i2c_hp_t devices[3][3] = { 15147c478bd9Sstevel@tonic-gate {{{0, 0x90}, "adio", "i2c-pcf8591"}, {{0, 0x70}, "ioexp", "i2c-pcf8574"}, 15157c478bd9Sstevel@tonic-gate {{0, 0xa0}, "fru", "i2c-at24c64"}}, 15167c478bd9Sstevel@tonic-gate {{{0, 0x92}, "adio", "i2c-pcf8591"}, {{0, 0x72}, "ioexp", "i2c-pcf8574"}, 15177c478bd9Sstevel@tonic-gate {{0, 0xa2}, "fru", "i2c-at24c64"}}, 15187c478bd9Sstevel@tonic-gate {{{0, 0x94}, "adio", "i2c-pcf8591"}, {{0, 0x74}, "ioexp", "i2c-pcf8574"}, 15197c478bd9Sstevel@tonic-gate {{0, 0xa4}, "fru", "i2c-at24c64"}}, 15207c478bd9Sstevel@tonic-gate }; 15217c478bd9Sstevel@tonic-gate 15227c478bd9Sstevel@tonic-gate int32_t 15237c478bd9Sstevel@tonic-gate psvc_ps_hotplug_policy_0(psvc_opaque_t hdlp, char *id) 15247c478bd9Sstevel@tonic-gate { 15257c478bd9Sstevel@tonic-gate boolean_t presence, previous_presence; 15267c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 15277c478bd9Sstevel@tonic-gate char label[32], state[32], fault[32]; 15287c478bd9Sstevel@tonic-gate int32_t ps_instance, led_count; 15297c478bd9Sstevel@tonic-gate char *switch_id, *led_id; 15307c478bd9Sstevel@tonic-gate int i; 15317c478bd9Sstevel@tonic-gate picl_nodehdl_t parent_node; 15327c478bd9Sstevel@tonic-gate char parent_path[256], ps_path[256]; 15337c478bd9Sstevel@tonic-gate picl_nodehdl_t child_node; 15347c478bd9Sstevel@tonic-gate devctl_hdl_t bus_handle, dev_handle; 15357c478bd9Sstevel@tonic-gate devctl_ddef_t ddef_hdl; 15367c478bd9Sstevel@tonic-gate char pcf8574_devpath[256], pcf8591_devpath[256], fru_devpath[256]; 1537298b7f4cSjfrank int retry; 15387c478bd9Sstevel@tonic-gate 15397c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PREV_PRESENCE_ATTR, 15405eb92cf2Sdhain &previous_presence); 15417c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 15427c478bd9Sstevel@tonic-gate return (status); 15437c478bd9Sstevel@tonic-gate 15447c478bd9Sstevel@tonic-gate retry = 0; 15457c478bd9Sstevel@tonic-gate do { 15467c478bd9Sstevel@tonic-gate if (retry) 1547298b7f4cSjfrank (void) sleep(retry_sleep_pshp); 15487c478bd9Sstevel@tonic-gate 15497c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &presence); 15507c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 15517c478bd9Sstevel@tonic-gate return (status); 15527c478bd9Sstevel@tonic-gate retry++; 1553298b7f4cSjfrank } while ((retry < n_retry_pshp) && 15547c478bd9Sstevel@tonic-gate (presence != previous_presence)); 15557c478bd9Sstevel@tonic-gate 15567c478bd9Sstevel@tonic-gate if (presence == previous_presence) { 15577c478bd9Sstevel@tonic-gate /* No change */ 15587c478bd9Sstevel@tonic-gate return (status); 15597c478bd9Sstevel@tonic-gate } 15607c478bd9Sstevel@tonic-gate 15617c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_LABEL_ATTR, label); 15627c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 15637c478bd9Sstevel@tonic-gate return (status); 15647c478bd9Sstevel@tonic-gate 15657c478bd9Sstevel@tonic-gate /* convert name to node, and parent path */ 15667c478bd9Sstevel@tonic-gate psvcplugin_lookup(id, parent_path, &child_node); 15677c478bd9Sstevel@tonic-gate 15687c478bd9Sstevel@tonic-gate if (presence == PSVC_PRESENT) { 15697c478bd9Sstevel@tonic-gate /* 15707c478bd9Sstevel@tonic-gate * Run this code if Power Supply was just added into the 15717c478bd9Sstevel@tonic-gate * System. This code toggles hotplug switch and adds the 15727c478bd9Sstevel@tonic-gate * PS and it's children to the picl tree. We then goto adding 15737c478bd9Sstevel@tonic-gate * device drivers at bottom of the routine. 15747c478bd9Sstevel@tonic-gate */ 15757c478bd9Sstevel@tonic-gate int32_t switch_count; 15767c478bd9Sstevel@tonic-gate char state[32], fault[32]; 15777c478bd9Sstevel@tonic-gate char switch_state[32]; 15787c478bd9Sstevel@tonic-gate 15797c478bd9Sstevel@tonic-gate /* may detect presence before all connections are made */ 15807c478bd9Sstevel@tonic-gate (void) poll(NULL, 0, 500); 15817c478bd9Sstevel@tonic-gate 15827c478bd9Sstevel@tonic-gate /* Device added */ 15837c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_INSERTED_MSG, label); 15847c478bd9Sstevel@tonic-gate 15857c478bd9Sstevel@tonic-gate strcpy(state, PSVC_OK); 15867c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, state); 15877c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 15887c478bd9Sstevel@tonic-gate return (status); 15897c478bd9Sstevel@tonic-gate 15907c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_NO_FAULT); 15917c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_FAULTID_ATTR, fault); 15927c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 15937c478bd9Sstevel@tonic-gate return (status); 15947c478bd9Sstevel@tonic-gate 15957c478bd9Sstevel@tonic-gate /* Enable i2c bus */ 15967c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, 15975eb92cf2Sdhain &switch_count, PSVC_HOTPLUG_ENABLE_SWITCH); 15987c478bd9Sstevel@tonic-gate for (i = 0; i < switch_count; ++i) { 15997c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 16005eb92cf2Sdhain &switch_id, PSVC_HOTPLUG_ENABLE_SWITCH, i); 16017c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 16027c478bd9Sstevel@tonic-gate return (status); 16037c478bd9Sstevel@tonic-gate 16047c478bd9Sstevel@tonic-gate strcpy(switch_state, PSVC_SWITCH_OFF); 16057c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, switch_id, 16065eb92cf2Sdhain PSVC_SWITCH_STATE_ATTR, switch_state); 16077c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 16087c478bd9Sstevel@tonic-gate return (status); 16097c478bd9Sstevel@tonic-gate 16107c478bd9Sstevel@tonic-gate strcpy(switch_state, PSVC_SWITCH_ON); 16117c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, switch_id, 16125eb92cf2Sdhain PSVC_SWITCH_STATE_ATTR, switch_state); 16137c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 16147c478bd9Sstevel@tonic-gate return (status); 16157c478bd9Sstevel@tonic-gate } 16167c478bd9Sstevel@tonic-gate ptree_get_node_by_path(parent_path, &parent_node); 16177c478bd9Sstevel@tonic-gate ptree_add_node(parent_node, child_node); 16187c478bd9Sstevel@tonic-gate snprintf(ps_path, sizeof (ps_path), "%s/%s", parent_path, id); 16197c478bd9Sstevel@tonic-gate psvcplugin_add_children(ps_path); 16207c478bd9Sstevel@tonic-gate } else { 16217c478bd9Sstevel@tonic-gate /* 16227c478bd9Sstevel@tonic-gate * Run this code if PS was just removed from the system. We 16237c478bd9Sstevel@tonic-gate * delete the device from the picl tree and then shut off 16247c478bd9Sstevel@tonic-gate * all fault lights associated with the PS. We also set the 16257c478bd9Sstevel@tonic-gate * device state to PSVC_REMOVED so that if we hit overcurrent 16267c478bd9Sstevel@tonic-gate * or fault checking code we can do a psvc call to see that 16277c478bd9Sstevel@tonic-gate * the device has not offically been added into the system. 16287c478bd9Sstevel@tonic-gate * We then will drop to code lower in the routine to remove 16297c478bd9Sstevel@tonic-gate * the device drivers for this PS. 16307c478bd9Sstevel@tonic-gate */ 16317c478bd9Sstevel@tonic-gate 16327c478bd9Sstevel@tonic-gate /* Device removed */ 16337c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_REMOVED_MSG, label); 16347c478bd9Sstevel@tonic-gate ptree_delete_node(child_node); 16357c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, &led_count, 16365eb92cf2Sdhain PSVC_DEV_FAULT_LED); 16377c478bd9Sstevel@tonic-gate 16387c478bd9Sstevel@tonic-gate for (i = 0; i < led_count; i++) { 16397c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 16405eb92cf2Sdhain &led_id, PSVC_DEV_FAULT_LED, i); 16417c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 16427c478bd9Sstevel@tonic-gate return (status); 16437c478bd9Sstevel@tonic-gate } 16447c478bd9Sstevel@tonic-gate 16457c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, led_id, 16467c478bd9Sstevel@tonic-gate PSVC_LED_STATE_ATTR, PSVC_OFF); 16477c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 16487c478bd9Sstevel@tonic-gate syslog(LOG_ERR, SET_LED_FAILED_MSG, led_id, 16495eb92cf2Sdhain errno); 16507c478bd9Sstevel@tonic-gate return (status); 16517c478bd9Sstevel@tonic-gate } 16527c478bd9Sstevel@tonic-gate 16537c478bd9Sstevel@tonic-gate } 16547c478bd9Sstevel@tonic-gate 16557c478bd9Sstevel@tonic-gate strcpy(state, PSVC_OK); 16567c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_NO_FAULT); 16577c478bd9Sstevel@tonic-gate 16587c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, state); 16597c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 16607c478bd9Sstevel@tonic-gate return (status); 16617c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_FAULTID_ATTR, fault); 16627c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 16637c478bd9Sstevel@tonic-gate return (status); 16647c478bd9Sstevel@tonic-gate } 16657c478bd9Sstevel@tonic-gate 16667c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_PREV_PRESENCE_ATTR, &presence); 16677c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 16687c478bd9Sstevel@tonic-gate return (status); 16697c478bd9Sstevel@tonic-gate 16707c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_INSTANCE_ATTR, &ps_instance); 16717c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 16727c478bd9Sstevel@tonic-gate return (status); 16737c478bd9Sstevel@tonic-gate 16747c478bd9Sstevel@tonic-gate if (presence != PSVC_PRESENT) { 16757c478bd9Sstevel@tonic-gate /* 16767c478bd9Sstevel@tonic-gate * This is the additional code needed to remove the PS from 16777c478bd9Sstevel@tonic-gate * the system. It removes the device drivers from the 16787c478bd9Sstevel@tonic-gate * device tree. 16797c478bd9Sstevel@tonic-gate */ 16807c478bd9Sstevel@tonic-gate snprintf(pcf8574_devpath, sizeof (pcf8574_devpath), PCF8574, 16815eb92cf2Sdhain devices[ps_instance][1].addr[1]); 16827c478bd9Sstevel@tonic-gate snprintf(pcf8591_devpath, sizeof (pcf8591_devpath), PCF8591, 16835eb92cf2Sdhain devices[ps_instance][0].addr[1]); 16847c478bd9Sstevel@tonic-gate snprintf(fru_devpath, sizeof (fru_devpath), FRU, 16855eb92cf2Sdhain devices[ps_instance][2].addr[1]); 16867c478bd9Sstevel@tonic-gate 16877c478bd9Sstevel@tonic-gate dev_handle = devctl_device_acquire(pcf8591_devpath, 0); 16887c478bd9Sstevel@tonic-gate if (dev_handle == NULL) { 16897c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_HANDLE_FAIL_MSG, 16905eb92cf2Sdhain pcf8591_devpath, errno); 16917c478bd9Sstevel@tonic-gate devctl_release(dev_handle); 16927c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 16937c478bd9Sstevel@tonic-gate } else if ((devctl_device_remove(dev_handle)) && 16945eb92cf2Sdhain (errno != ENXIO)) { 16957c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVTREE_NODE_DELETE_FAILED, 16965eb92cf2Sdhain pcf8591_devpath, errno); 16977c478bd9Sstevel@tonic-gate devctl_release(dev_handle); 16987c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 16997c478bd9Sstevel@tonic-gate } else { 17007c478bd9Sstevel@tonic-gate devctl_release(dev_handle); 17017c478bd9Sstevel@tonic-gate status = PSVC_SUCCESS; 17027c478bd9Sstevel@tonic-gate } 17037c478bd9Sstevel@tonic-gate 17047c478bd9Sstevel@tonic-gate dev_handle = devctl_device_acquire(pcf8574_devpath, 0); 17057c478bd9Sstevel@tonic-gate if (dev_handle == NULL) { 17067c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_HANDLE_FAIL_MSG, 17075eb92cf2Sdhain pcf8574_devpath, errno); 17087c478bd9Sstevel@tonic-gate devctl_release(dev_handle); 17097c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 17107c478bd9Sstevel@tonic-gate } else if ((devctl_device_remove(dev_handle)) && 17115eb92cf2Sdhain (errno != ENXIO)) { 17127c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVTREE_NODE_DELETE_FAILED, 17135eb92cf2Sdhain pcf8574_devpath, errno); 17147c478bd9Sstevel@tonic-gate devctl_release(dev_handle); 17157c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 17167c478bd9Sstevel@tonic-gate } else { 17177c478bd9Sstevel@tonic-gate devctl_release(dev_handle); 17187c478bd9Sstevel@tonic-gate status = PSVC_SUCCESS; 17197c478bd9Sstevel@tonic-gate } 17207c478bd9Sstevel@tonic-gate 17217c478bd9Sstevel@tonic-gate dev_handle = devctl_device_acquire(fru_devpath, 0); 17227c478bd9Sstevel@tonic-gate if (dev_handle == NULL) { 17237c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_HANDLE_FAIL_MSG, 17245eb92cf2Sdhain fru_devpath, errno); 17257c478bd9Sstevel@tonic-gate devctl_release(dev_handle); 17267c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 17277c478bd9Sstevel@tonic-gate } else if ((devctl_device_remove(dev_handle)) && 17285eb92cf2Sdhain (errno != ENXIO)) { 17297c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVTREE_NODE_DELETE_FAILED, 17305eb92cf2Sdhain fru_devpath, errno); 17317c478bd9Sstevel@tonic-gate devctl_release(dev_handle); 17327c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 17337c478bd9Sstevel@tonic-gate } else { 17347c478bd9Sstevel@tonic-gate devctl_release(dev_handle); 17357c478bd9Sstevel@tonic-gate status = PSVC_SUCCESS; 17367c478bd9Sstevel@tonic-gate } 17377c478bd9Sstevel@tonic-gate 17387c478bd9Sstevel@tonic-gate return (status); 17397c478bd9Sstevel@tonic-gate } 17407c478bd9Sstevel@tonic-gate 17417c478bd9Sstevel@tonic-gate /* 17427c478bd9Sstevel@tonic-gate * This code is to update the presences of power supply child 17437c478bd9Sstevel@tonic-gate * devices in the event that picld was started without a power 17447c478bd9Sstevel@tonic-gate * supply present. This call makes the devices available 17457c478bd9Sstevel@tonic-gate * after that initial insertion. 17467c478bd9Sstevel@tonic-gate */ 17477c478bd9Sstevel@tonic-gate status = handle_ps_hotplug_children_presence(hdlp, id); 17487c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 17497c478bd9Sstevel@tonic-gate return (status); 17507c478bd9Sstevel@tonic-gate } 17517c478bd9Sstevel@tonic-gate 17527c478bd9Sstevel@tonic-gate /* 17537c478bd9Sstevel@tonic-gate * We fall through to here if the device has been inserted. 17547c478bd9Sstevel@tonic-gate * Add the devinfo tree node entry for the seeprom and attach 17557c478bd9Sstevel@tonic-gate * the i2c seeprom driver 17567c478bd9Sstevel@tonic-gate */ 17577c478bd9Sstevel@tonic-gate 17587c478bd9Sstevel@tonic-gate bus_handle = devctl_bus_acquire(I2C_NODE, 0); 17597c478bd9Sstevel@tonic-gate if (bus_handle == NULL) { 17607c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_HANDLE_FAIL_MSG, I2C_NODE, errno); 17617c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 17627c478bd9Sstevel@tonic-gate } 17637c478bd9Sstevel@tonic-gate /* Create the deivce nodes for all 3 i2c parts on the PS */ 17647c478bd9Sstevel@tonic-gate for (i = 0; i < 3; i++) { 17657c478bd9Sstevel@tonic-gate ddef_hdl = devctl_ddef_alloc(devices[ps_instance][i].name, 0); 17667c478bd9Sstevel@tonic-gate if (ddef_hdl == NULL) { 17677c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_HANDLE_FAIL_MSG, 17685eb92cf2Sdhain devices[ps_instance][i].name, errno); 17697c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 17707c478bd9Sstevel@tonic-gate } 17717c478bd9Sstevel@tonic-gate status = devctl_ddef_string(ddef_hdl, "compatible", 17725eb92cf2Sdhain devices[ps_instance][i].compatible); 17737c478bd9Sstevel@tonic-gate if (status == -1) { 17747c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_HANDLE_FAIL_MSG, 17755eb92cf2Sdhain devices[ps_instance][i].name, errno); 17767c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 17777c478bd9Sstevel@tonic-gate } 17787c478bd9Sstevel@tonic-gate status = devctl_ddef_int_array(ddef_hdl, "reg", 2, 17795eb92cf2Sdhain devices[ps_instance][i].addr); 17807c478bd9Sstevel@tonic-gate if (status == -1) { 17817c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_HANDLE_FAIL_MSG, 17825eb92cf2Sdhain devices[ps_instance][i].name, errno); 17837c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 17847c478bd9Sstevel@tonic-gate } 17857c478bd9Sstevel@tonic-gate if (devctl_bus_dev_create(bus_handle, ddef_hdl, 0, 17865eb92cf2Sdhain &dev_handle)) { 17877c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVTREE_NODE_CREATE_FAILED, 17885eb92cf2Sdhain devices[ps_instance][i].name, errno); 17897c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 17907c478bd9Sstevel@tonic-gate } else 17917c478bd9Sstevel@tonic-gate devctl_release(dev_handle); 17927c478bd9Sstevel@tonic-gate devctl_ddef_free(ddef_hdl); 17937c478bd9Sstevel@tonic-gate } 17947c478bd9Sstevel@tonic-gate devctl_release(bus_handle); 17957c478bd9Sstevel@tonic-gate 17967c478bd9Sstevel@tonic-gate return (status); 17977c478bd9Sstevel@tonic-gate } 17987c478bd9Sstevel@tonic-gate 17997c478bd9Sstevel@tonic-gate static void 18007c478bd9Sstevel@tonic-gate shutdown_routine() 18017c478bd9Sstevel@tonic-gate { 18027c478bd9Sstevel@tonic-gate static boolean_t shutdown_flag = 0; 18037c478bd9Sstevel@tonic-gate 18047c478bd9Sstevel@tonic-gate if (!(shutdown_flag)) { 18057c478bd9Sstevel@tonic-gate system(shutdown_string); 18067c478bd9Sstevel@tonic-gate shutdown_flag = 1; 18077c478bd9Sstevel@tonic-gate } 18087c478bd9Sstevel@tonic-gate } 18097c478bd9Sstevel@tonic-gate 18107c478bd9Sstevel@tonic-gate /* 18117c478bd9Sstevel@tonic-gate * This policy checks temperature sensors to see if the fault attribute 18127c478bd9Sstevel@tonic-gate * is set to either High or Low Shutdown. If so then it shuts the system 18137c478bd9Sstevel@tonic-gate * down with a 1 minute warning period 18147c478bd9Sstevel@tonic-gate */ 18157c478bd9Sstevel@tonic-gate int32_t 18167c478bd9Sstevel@tonic-gate psvc_shutdown_policy(psvc_opaque_t hdlp, char *id) 18177c478bd9Sstevel@tonic-gate { 18187c478bd9Sstevel@tonic-gate int32_t status; 18197c478bd9Sstevel@tonic-gate char fault[32] = {0}; 18207c478bd9Sstevel@tonic-gate boolean_t pr; 1821298b7f4cSjfrank int retry; 18227c478bd9Sstevel@tonic-gate 18237c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &pr); 18247c478bd9Sstevel@tonic-gate if ((status != PSVC_SUCCESS) || (pr != PSVC_PRESENT)) { 18257c478bd9Sstevel@tonic-gate return (status); 18267c478bd9Sstevel@tonic-gate } 18277c478bd9Sstevel@tonic-gate 1828298b7f4cSjfrank retry = 0; 1829298b7f4cSjfrank do { 1830298b7f4cSjfrank if (retry) 1831298b7f4cSjfrank (void) sleep(retry_sleep_temp_shutdown); 1832298b7f4cSjfrank status = psvc_get_attr(hdlp, id, PSVC_FAULTID_ATTR, fault); 1833298b7f4cSjfrank if (status != PSVC_SUCCESS) 1834298b7f4cSjfrank return (status); 1835298b7f4cSjfrank retry++; 1836298b7f4cSjfrank } while (((strcmp(fault, PSVC_TEMP_LO_SHUT) == 0) || 1837298b7f4cSjfrank (strcmp(fault, PSVC_TEMP_HI_SHUT) == 0)) && 18385eb92cf2Sdhain (retry < n_retry_temp_shutdown)); 18397c478bd9Sstevel@tonic-gate if ((strcmp(fault, PSVC_TEMP_LO_SHUT) == 0) || 18407c478bd9Sstevel@tonic-gate (strcmp(fault, PSVC_TEMP_HI_SHUT) == 0)) { 18417c478bd9Sstevel@tonic-gate shutdown_routine(); 18427c478bd9Sstevel@tonic-gate } 18437c478bd9Sstevel@tonic-gate 18447c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 18457c478bd9Sstevel@tonic-gate } 18467c478bd9Sstevel@tonic-gate 18477c478bd9Sstevel@tonic-gate int32_t 18487c478bd9Sstevel@tonic-gate psvc_check_disk_fault_policy_0(psvc_opaque_t hdlp, char *id) 18497c478bd9Sstevel@tonic-gate { 18507c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 18517c478bd9Sstevel@tonic-gate int32_t i; 18527c478bd9Sstevel@tonic-gate char curr_state[32], prev_state[32], led_state[32]; 18537c478bd9Sstevel@tonic-gate char disk_fault[32], disk_state[32]; 1854360e6f5eSmathue static char *disk_id[DAK_MAX_DISKS] = {NULL}; 1855360e6f5eSmathue static char *led_id[DAK_MAX_DISKS] = {NULL}; 1856360e6f5eSmathue static char *parent_id[DAK_MAX_DISKS] = {NULL}; 18577c478bd9Sstevel@tonic-gate boolean_t present; 1858298b7f4cSjfrank int retry; 18597c478bd9Sstevel@tonic-gate 18607c478bd9Sstevel@tonic-gate /* 18617c478bd9Sstevel@tonic-gate * Check which disk faulted, now get the disks. 18627c478bd9Sstevel@tonic-gate * We are now going to get disk, disk parent, 18637c478bd9Sstevel@tonic-gate * parent's leds, and check to see if parent's leds are on 18647c478bd9Sstevel@tonic-gate */ 18657c478bd9Sstevel@tonic-gate 18667c478bd9Sstevel@tonic-gate if (disk_id[0] == NULL) { 18677c478bd9Sstevel@tonic-gate for (i = 0; i < DAK_MAX_DISKS; i++) { 18687c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 18697c478bd9Sstevel@tonic-gate &(disk_id[i]), PSVC_DISK, i); 18707c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 18717c478bd9Sstevel@tonic-gate return (status); 18727c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, disk_id[i], 18737c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &(parent_id[i]), 18747c478bd9Sstevel@tonic-gate PSVC_PARENT, 0); 18757c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 18767c478bd9Sstevel@tonic-gate return (status); 18777c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, parent_id[i], 18787c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &(led_id[i]), 18797c478bd9Sstevel@tonic-gate PSVC_SLOT_FAULT_LED, 0); 18807c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 18817c478bd9Sstevel@tonic-gate return (status); 18827c478bd9Sstevel@tonic-gate 18837c478bd9Sstevel@tonic-gate } 18847c478bd9Sstevel@tonic-gate } 18857c478bd9Sstevel@tonic-gate 18867c478bd9Sstevel@tonic-gate for (i = 0; i < DAK_MAX_DISKS; i++) { 18877c478bd9Sstevel@tonic-gate curr_state[0] = 0; 18887c478bd9Sstevel@tonic-gate prev_state[0] = 0; 18897c478bd9Sstevel@tonic-gate 18907c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, disk_id[i], PSVC_PRESENCE_ATTR, 18915eb92cf2Sdhain &present); 18927c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 18937c478bd9Sstevel@tonic-gate return (status); 18947c478bd9Sstevel@tonic-gate 18957c478bd9Sstevel@tonic-gate if (present == PSVC_ABSENT) 18967c478bd9Sstevel@tonic-gate continue; 18977c478bd9Sstevel@tonic-gate 18987c478bd9Sstevel@tonic-gate /* 18997c478bd9Sstevel@tonic-gate * Check if whether or not the led is on. 19007c478bd9Sstevel@tonic-gate * If so, then this disk has a problem and 19017c478bd9Sstevel@tonic-gate * set its fault and error states to bad. 19027c478bd9Sstevel@tonic-gate * If not, then set fault and error states to good. 19037c478bd9Sstevel@tonic-gate * If the disk underwent a change in state, then 19047c478bd9Sstevel@tonic-gate * print out what state it's now in. 19057c478bd9Sstevel@tonic-gate */ 19067c478bd9Sstevel@tonic-gate 19077c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, disk_id[i], PSVC_STATE_ATTR, 19087c478bd9Sstevel@tonic-gate prev_state); 19097c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 19107c478bd9Sstevel@tonic-gate return (status); 19117c478bd9Sstevel@tonic-gate 19127c478bd9Sstevel@tonic-gate retry = 0; 19137c478bd9Sstevel@tonic-gate do { 19147c478bd9Sstevel@tonic-gate if (retry) 1915298b7f4cSjfrank (void) sleep(retry_sleep_diskfault); 19167c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, led_id[i], PSVC_STATE_ATTR, 19177c478bd9Sstevel@tonic-gate led_state); 19187c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 19197c478bd9Sstevel@tonic-gate return (status); 19207c478bd9Sstevel@tonic-gate retry++; 19217c478bd9Sstevel@tonic-gate /* 19227c478bd9Sstevel@tonic-gate * check to see if we need to retry. the conditions are: 19237c478bd9Sstevel@tonic-gate * 19247c478bd9Sstevel@tonic-gate * prev_state led_state retry 19257c478bd9Sstevel@tonic-gate * -------------------------------------------------- 19267c478bd9Sstevel@tonic-gate * PSVC_ERROR PSVC_LED_ON yes 19277c478bd9Sstevel@tonic-gate * PSVC_OK PSVC_LED_OFF yes 19287c478bd9Sstevel@tonic-gate * PSVC_ERROR PSVC_LED_OFF no 19297c478bd9Sstevel@tonic-gate * PSVC_OK PSVC_LED_ON no 19307c478bd9Sstevel@tonic-gate */ 1931298b7f4cSjfrank } while ((retry < n_retry_diskfault) && 19327c478bd9Sstevel@tonic-gate change_of_state_str(prev_state, PSVC_OK, 19337c478bd9Sstevel@tonic-gate led_state, PSVC_LED_ON)); 19347c478bd9Sstevel@tonic-gate 19357c478bd9Sstevel@tonic-gate /* 19367c478bd9Sstevel@tonic-gate * Set the disk's state and fault id according to 19377c478bd9Sstevel@tonic-gate * what we found the disk fault sensor (disk_slot_fault_led) 19387c478bd9Sstevel@tonic-gate * to be. 19397c478bd9Sstevel@tonic-gate */ 19407c478bd9Sstevel@tonic-gate if (strcmp(led_state, PSVC_LED_ON) == 0) { 19417c478bd9Sstevel@tonic-gate strcpy(disk_fault, PSVC_GEN_FAULT); 19427c478bd9Sstevel@tonic-gate strcpy(disk_state, PSVC_ERROR); 19437c478bd9Sstevel@tonic-gate } else { 19447c478bd9Sstevel@tonic-gate strcpy(disk_fault, PSVC_NO_FAULT); 19457c478bd9Sstevel@tonic-gate strcpy(disk_state, PSVC_OK); 19467c478bd9Sstevel@tonic-gate } 19477c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, disk_id[i], PSVC_STATE_ATTR, 19485eb92cf2Sdhain disk_state); 19497c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 19507c478bd9Sstevel@tonic-gate return (status); 19517c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, disk_id[i], PSVC_FAULTID_ATTR, 19525eb92cf2Sdhain disk_fault); 19537c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 19547c478bd9Sstevel@tonic-gate return (status); 19557c478bd9Sstevel@tonic-gate /* 19567c478bd9Sstevel@tonic-gate * Check disk states. If they differ, then print out 19577c478bd9Sstevel@tonic-gate * the current state of the disk 19587c478bd9Sstevel@tonic-gate */ 19597c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, disk_id[i], PSVC_PREV_STATE_ATTR, 19605eb92cf2Sdhain prev_state); 19617c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 19627c478bd9Sstevel@tonic-gate return (status); 19637c478bd9Sstevel@tonic-gate 19647c478bd9Sstevel@tonic-gate if (strcmp(disk_state, prev_state) != 0) { 19657c478bd9Sstevel@tonic-gate if (strcmp(disk_state, PSVC_ERROR) == 0) { 19667c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DISK_FAULT_MSG, disk_id[i]); 19677c478bd9Sstevel@tonic-gate } else { 19687c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DISK_OK_MSG, disk_id[i]); 19697c478bd9Sstevel@tonic-gate } 19707c478bd9Sstevel@tonic-gate } 19717c478bd9Sstevel@tonic-gate } 19727c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 19737c478bd9Sstevel@tonic-gate } 19747c478bd9Sstevel@tonic-gate 19757c478bd9Sstevel@tonic-gate int32_t 19767c478bd9Sstevel@tonic-gate psvc_update_FSP_fault_led_policy_0(psvc_opaque_t hdlp, char *id) 19777c478bd9Sstevel@tonic-gate { 19787c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 19797c478bd9Sstevel@tonic-gate int32_t i; 19807c478bd9Sstevel@tonic-gate int32_t dev_count, fault_state = 0; 19817c478bd9Sstevel@tonic-gate char *dev_id; 19827c478bd9Sstevel@tonic-gate char dev_state[32], led_state[32]; 19837c478bd9Sstevel@tonic-gate boolean_t present; 19847c478bd9Sstevel@tonic-gate 19857c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, &dev_count, 19865eb92cf2Sdhain PSVC_DEV_FAULT_SENSOR); 19877c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 19887c478bd9Sstevel@tonic-gate return (status); 19897c478bd9Sstevel@tonic-gate 19907c478bd9Sstevel@tonic-gate fault_state = 0; 19917c478bd9Sstevel@tonic-gate 19927c478bd9Sstevel@tonic-gate for (i = 0; i < dev_count; i++) { 19937c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 19945eb92cf2Sdhain &dev_id, PSVC_DEV_FAULT_SENSOR, i); 19957c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 19967c478bd9Sstevel@tonic-gate return (status); 19977c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, dev_id, PSVC_PRESENCE_ATTR, 19985eb92cf2Sdhain &present); 19997c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 20007c478bd9Sstevel@tonic-gate return (status); 20017c478bd9Sstevel@tonic-gate 20027c478bd9Sstevel@tonic-gate if (present == PSVC_ABSENT) 20037c478bd9Sstevel@tonic-gate continue; 20047c478bd9Sstevel@tonic-gate 20057c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, dev_id, PSVC_STATE_ATTR, 20065eb92cf2Sdhain dev_state); 20077c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 20087c478bd9Sstevel@tonic-gate return (status); 20097c478bd9Sstevel@tonic-gate 20107c478bd9Sstevel@tonic-gate if (strcmp(dev_state, PSVC_ERROR) == 0) { 20117c478bd9Sstevel@tonic-gate fault_state = 1; 20127c478bd9Sstevel@tonic-gate } 20137c478bd9Sstevel@tonic-gate } 20147c478bd9Sstevel@tonic-gate if (fault_state == 1) { 20157c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_STATE_ATTR, led_state); 20167c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 20177c478bd9Sstevel@tonic-gate return (status); 20187c478bd9Sstevel@tonic-gate if (strcmp(led_state, PSVC_OFF) == 0) { 20197c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, 20207c478bd9Sstevel@tonic-gate PSVC_ON); 20217c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 20227c478bd9Sstevel@tonic-gate return (status); 20237c478bd9Sstevel@tonic-gate } 20247c478bd9Sstevel@tonic-gate } else { 20257c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_STATE_ATTR, led_state); 20267c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 20277c478bd9Sstevel@tonic-gate return (status); 20287c478bd9Sstevel@tonic-gate if (strcmp(led_state, PSVC_ON) == 0) { 20297c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, 20307c478bd9Sstevel@tonic-gate PSVC_OFF); 20317c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 20327c478bd9Sstevel@tonic-gate return (status); 20337c478bd9Sstevel@tonic-gate } 20347c478bd9Sstevel@tonic-gate } 20357c478bd9Sstevel@tonic-gate status = update_gen_fault_led(hdlp, GEN_FAULT_LED); 20367c478bd9Sstevel@tonic-gate 20377c478bd9Sstevel@tonic-gate return (status); 20387c478bd9Sstevel@tonic-gate } 20397c478bd9Sstevel@tonic-gate 20407c478bd9Sstevel@tonic-gate int32_t 20417c478bd9Sstevel@tonic-gate update_gen_fault_led(psvc_opaque_t hdlp, char *id) 20427c478bd9Sstevel@tonic-gate { 20437c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 20447c478bd9Sstevel@tonic-gate int32_t i; 20457c478bd9Sstevel@tonic-gate int32_t led_count, fault_state; 20467c478bd9Sstevel@tonic-gate char *led_id; 20477c478bd9Sstevel@tonic-gate char led_state[32]; 20487c478bd9Sstevel@tonic-gate 20497c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, &led_count, 20505eb92cf2Sdhain PSVC_DEV_FAULT_SENSOR); 20517c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 20527c478bd9Sstevel@tonic-gate return (status); 20537c478bd9Sstevel@tonic-gate 20547c478bd9Sstevel@tonic-gate fault_state = 0; 20557c478bd9Sstevel@tonic-gate 20567c478bd9Sstevel@tonic-gate for (i = 0; i < led_count; i++) { 20577c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 20585eb92cf2Sdhain &led_id, PSVC_DEV_FAULT_SENSOR, i); 20597c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 20607c478bd9Sstevel@tonic-gate return (status); 20617c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, led_id, PSVC_STATE_ATTR, 20625eb92cf2Sdhain led_state); 20637c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 20647c478bd9Sstevel@tonic-gate return (status); 20657c478bd9Sstevel@tonic-gate 20667c478bd9Sstevel@tonic-gate if (strcmp(led_state, PSVC_ON) == 0) { 20677c478bd9Sstevel@tonic-gate fault_state = 1; 20687c478bd9Sstevel@tonic-gate } 20697c478bd9Sstevel@tonic-gate } 20707c478bd9Sstevel@tonic-gate 20717c478bd9Sstevel@tonic-gate if (fault_state == 1) { 20727c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_STATE_ATTR, led_state); 20737c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 20747c478bd9Sstevel@tonic-gate return (status); 20757c478bd9Sstevel@tonic-gate if (strcmp(led_state, PSVC_OFF) == 0) { 20767c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, 20777c478bd9Sstevel@tonic-gate PSVC_ON); 20787c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 20797c478bd9Sstevel@tonic-gate return (status); 20807c478bd9Sstevel@tonic-gate } 20817c478bd9Sstevel@tonic-gate } else { 20827c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_STATE_ATTR, led_state); 20837c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 20847c478bd9Sstevel@tonic-gate return (status); 20857c478bd9Sstevel@tonic-gate if (strcmp(led_state, PSVC_ON) == 0) { 20867c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, 20877c478bd9Sstevel@tonic-gate PSVC_OFF); 20887c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 20897c478bd9Sstevel@tonic-gate return (status); 20907c478bd9Sstevel@tonic-gate } 20917c478bd9Sstevel@tonic-gate } 20927c478bd9Sstevel@tonic-gate 20937c478bd9Sstevel@tonic-gate return (status); 20947c478bd9Sstevel@tonic-gate } 20957c478bd9Sstevel@tonic-gate 20967c478bd9Sstevel@tonic-gate 20977c478bd9Sstevel@tonic-gate /* 20987c478bd9Sstevel@tonic-gate * This function detects whether the module present in the dakatari's 20997c478bd9Sstevel@tonic-gate * CPU slot is a CPU module or a Zulu (XVR-4000). 21007c478bd9Sstevel@tonic-gate * Based on this detection it also sets the appropriate temperature sensors 21017c478bd9Sstevel@tonic-gate * to HOTPLUGGED, so that it works properly with check_temp() function 21027c478bd9Sstevel@tonic-gate */ 21037c478bd9Sstevel@tonic-gate #define MAX_MODULE_SIZE 20 21047c478bd9Sstevel@tonic-gate #define MAX_TEMP_SENSOR_SIZE 30 21057c478bd9Sstevel@tonic-gate 21067c478bd9Sstevel@tonic-gate int32_t 21077c478bd9Sstevel@tonic-gate psvc_update_cpu_module_card_node_0(psvc_opaque_t hdlp, char *id) 21087c478bd9Sstevel@tonic-gate { 21097c478bd9Sstevel@tonic-gate int32_t set_temp_sensor_properties(psvc_opaque_t, char *); 21107c478bd9Sstevel@tonic-gate int32_t remove_module_node(psvc_opaque_t, char *); 21117c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 21127c478bd9Sstevel@tonic-gate fru_info_t fru_data; 21137c478bd9Sstevel@tonic-gate char *fru, seg_name[2]; 21147c478bd9Sstevel@tonic-gate int8_t seg_count, module_card; 21157c478bd9Sstevel@tonic-gate int32_t match_count, i, j, seg_desc_start = 0x1806, module_address; 21167c478bd9Sstevel@tonic-gate int32_t seg_found; 21177c478bd9Sstevel@tonic-gate boolean_t present; 21187c478bd9Sstevel@tonic-gate seg_desc_t segment; 21197c478bd9Sstevel@tonic-gate char other_module_id[MAX_MODULE_SIZE]; 21207c478bd9Sstevel@tonic-gate char cpu_temp_sensor1[MAX_TEMP_SENSOR_SIZE]; 21217c478bd9Sstevel@tonic-gate char cpu_temp_sensor2[MAX_TEMP_SENSOR_SIZE]; 21227c478bd9Sstevel@tonic-gate char zulu_temp_sensor1[MAX_TEMP_SENSOR_SIZE]; 21237c478bd9Sstevel@tonic-gate char zulu_temp_sensor2[MAX_TEMP_SENSOR_SIZE]; 21247c478bd9Sstevel@tonic-gate int offset = 0x7; 21257c478bd9Sstevel@tonic-gate 21267c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &present); 21277c478bd9Sstevel@tonic-gate if ((status != PSVC_SUCCESS) || (present != PSVC_PRESENT)) { 21287c478bd9Sstevel@tonic-gate return (status); 21297c478bd9Sstevel@tonic-gate } 21307c478bd9Sstevel@tonic-gate 21317c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, &match_count, 21327c478bd9Sstevel@tonic-gate PSVC_FRU); 21337c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 21347c478bd9Sstevel@tonic-gate return (status); 21357c478bd9Sstevel@tonic-gate } 21367c478bd9Sstevel@tonic-gate 21377c478bd9Sstevel@tonic-gate for (i = 0; i < match_count; i++) { 21387c478bd9Sstevel@tonic-gate seg_found = 0; 21397c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, &fru, 21407c478bd9Sstevel@tonic-gate PSVC_FRU, i); 21417c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 21427c478bd9Sstevel@tonic-gate return (status); 21437c478bd9Sstevel@tonic-gate 21447c478bd9Sstevel@tonic-gate fru_data.buf_start = 0x1805; 21457c478bd9Sstevel@tonic-gate fru_data.buf = (char *)&seg_count; 21467c478bd9Sstevel@tonic-gate fru_data.read_size = 1; 21477c478bd9Sstevel@tonic-gate 21487c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fru, PSVC_FRU_INFO_ATTR, 21497c478bd9Sstevel@tonic-gate &fru_data); 21507c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 21517c478bd9Sstevel@tonic-gate return (status); 21527c478bd9Sstevel@tonic-gate } 21537c478bd9Sstevel@tonic-gate 21547c478bd9Sstevel@tonic-gate for (j = 0; (j < seg_count) && (!seg_found); j++) { 21557c478bd9Sstevel@tonic-gate fru_data.buf_start = seg_desc_start; 21567c478bd9Sstevel@tonic-gate fru_data.buf = seg_name; 21577c478bd9Sstevel@tonic-gate fru_data.read_size = 2; 21587c478bd9Sstevel@tonic-gate 21597c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fru, PSVC_FRU_INFO_ATTR, 21607c478bd9Sstevel@tonic-gate &fru_data); 21617c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 21627c478bd9Sstevel@tonic-gate syslog(LOG_ERR, GET_ATTR_FRU_FAILED_MSG); 21637c478bd9Sstevel@tonic-gate return (status); 21647c478bd9Sstevel@tonic-gate } 21657c478bd9Sstevel@tonic-gate 21667c478bd9Sstevel@tonic-gate seg_desc_start = seg_desc_start + 2; 21677c478bd9Sstevel@tonic-gate fru_data.buf_start = seg_desc_start; 21687c478bd9Sstevel@tonic-gate fru_data.buf = (char *)&segment; 21697c478bd9Sstevel@tonic-gate fru_data.read_size = sizeof (seg_desc_t); 21707c478bd9Sstevel@tonic-gate 21717c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fru, PSVC_FRU_INFO_ATTR, 21727c478bd9Sstevel@tonic-gate &fru_data); 21737c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 21747c478bd9Sstevel@tonic-gate syslog(LOG_ERR, GET_ATTR_FRU_FAILED_MSG); 21757c478bd9Sstevel@tonic-gate return (status); 21767c478bd9Sstevel@tonic-gate } 21777c478bd9Sstevel@tonic-gate seg_desc_start = seg_desc_start + sizeof (seg_desc_t); 21787c478bd9Sstevel@tonic-gate if (memcmp(seg_name, "SC", 2) == 0) 21797c478bd9Sstevel@tonic-gate seg_found = 1; 21807c478bd9Sstevel@tonic-gate } 21817c478bd9Sstevel@tonic-gate 21827c478bd9Sstevel@tonic-gate if (seg_found) { 21837c478bd9Sstevel@tonic-gate module_address = segment.segoffset + offset; 21847c478bd9Sstevel@tonic-gate fru_data.buf_start = module_address; 21857c478bd9Sstevel@tonic-gate fru_data.buf = (char *)&module_card; 21867c478bd9Sstevel@tonic-gate fru_data.read_size = 1; 21877c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fru, PSVC_FRU_INFO_ATTR, 21887c478bd9Sstevel@tonic-gate &fru_data); 21897c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 21907c478bd9Sstevel@tonic-gate syslog(LOG_ERR, GET_ATTR_FRU_FAILED_MSG); 21917c478bd9Sstevel@tonic-gate return (status); 21927c478bd9Sstevel@tonic-gate } 21937c478bd9Sstevel@tonic-gate } else { 21947c478bd9Sstevel@tonic-gate syslog(LOG_ERR, NO_FRU_INFO_MSG, id); 21957c478bd9Sstevel@tonic-gate } 21967c478bd9Sstevel@tonic-gate } 21977c478bd9Sstevel@tonic-gate 21987c478bd9Sstevel@tonic-gate if (strcmp(id, "ZULU_1_3_MOD_CARD") == 0) { 21997c478bd9Sstevel@tonic-gate strlcpy(other_module_id, "CPU_1_3_MOD_CARD", MAX_MODULE_SIZE); 22007c478bd9Sstevel@tonic-gate 22017c478bd9Sstevel@tonic-gate strlcpy(cpu_temp_sensor1, "CPU1_DIE_TEMPERATURE_SENSOR", 22027c478bd9Sstevel@tonic-gate MAX_TEMP_SENSOR_SIZE); 22037c478bd9Sstevel@tonic-gate strlcpy(cpu_temp_sensor2, "CPU3_DIE_TEMPERATURE_SENSOR", 22047c478bd9Sstevel@tonic-gate MAX_TEMP_SENSOR_SIZE); 22057c478bd9Sstevel@tonic-gate 22067c478bd9Sstevel@tonic-gate strlcpy(zulu_temp_sensor1, "ZULU1_DIE_TEMPERATURE_SENSOR", 22077c478bd9Sstevel@tonic-gate MAX_TEMP_SENSOR_SIZE); 22087c478bd9Sstevel@tonic-gate strlcpy(zulu_temp_sensor2, "ZULU3_DIE_TEMPERATURE_SENSOR", 22097c478bd9Sstevel@tonic-gate MAX_TEMP_SENSOR_SIZE); 22107c478bd9Sstevel@tonic-gate } 22117c478bd9Sstevel@tonic-gate 22127c478bd9Sstevel@tonic-gate if (strcmp(id, "ZULU_4_6_MOD_CARD") == 0) { 22137c478bd9Sstevel@tonic-gate strlcpy(other_module_id, "CPU_4_6_MOD_CARD", MAX_MODULE_SIZE); 22147c478bd9Sstevel@tonic-gate 22157c478bd9Sstevel@tonic-gate strlcpy(cpu_temp_sensor1, "CPU4_DIE_TEMPERATURE_SENSOR", 22167c478bd9Sstevel@tonic-gate MAX_TEMP_SENSOR_SIZE); 22177c478bd9Sstevel@tonic-gate strlcpy(cpu_temp_sensor2, "CPU6_DIE_TEMPERATURE_SENSOR", 22187c478bd9Sstevel@tonic-gate MAX_TEMP_SENSOR_SIZE); 22197c478bd9Sstevel@tonic-gate 22207c478bd9Sstevel@tonic-gate strlcpy(zulu_temp_sensor1, "ZULU4_DIE_TEMPERATURE_SENSOR", 22217c478bd9Sstevel@tonic-gate MAX_TEMP_SENSOR_SIZE); 22227c478bd9Sstevel@tonic-gate strlcpy(zulu_temp_sensor2, "ZULU6_DIE_TEMPERATURE_SENSOR", 22237c478bd9Sstevel@tonic-gate MAX_TEMP_SENSOR_SIZE); 22247c478bd9Sstevel@tonic-gate } 22257c478bd9Sstevel@tonic-gate 22267c478bd9Sstevel@tonic-gate 22277c478bd9Sstevel@tonic-gate /* 22287c478bd9Sstevel@tonic-gate * If the module in the CPU slot is a Zulu (XVR-4000), then 22297c478bd9Sstevel@tonic-gate * location 0x1EB0 in its FRUid prom has a value 0xFB. 22307c478bd9Sstevel@tonic-gate * If Zulu (XVR-4000) is detected, delete the CPU node, otherwise 22317c478bd9Sstevel@tonic-gate * delete the Zulu node. Also set the temperature sensor value to 22327c478bd9Sstevel@tonic-gate * HOTPLUGGED for absent temperature sensors. 22337c478bd9Sstevel@tonic-gate */ 22347c478bd9Sstevel@tonic-gate if ((module_card & 0xff) == 0xfb) { 22357c478bd9Sstevel@tonic-gate status = set_temp_sensor_properties(hdlp, cpu_temp_sensor1); 22367c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 22377c478bd9Sstevel@tonic-gate return (status); 22387c478bd9Sstevel@tonic-gate } 22397c478bd9Sstevel@tonic-gate 22407c478bd9Sstevel@tonic-gate status = set_temp_sensor_properties(hdlp, cpu_temp_sensor2); 22417c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 22427c478bd9Sstevel@tonic-gate return (status); 22437c478bd9Sstevel@tonic-gate } 22447c478bd9Sstevel@tonic-gate 22457c478bd9Sstevel@tonic-gate /* 22467c478bd9Sstevel@tonic-gate * Remove CPU node 22477c478bd9Sstevel@tonic-gate */ 22487c478bd9Sstevel@tonic-gate status = remove_module_node(hdlp, other_module_id); 22497c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 22507c478bd9Sstevel@tonic-gate return (status); 22517c478bd9Sstevel@tonic-gate } 22527c478bd9Sstevel@tonic-gate } else { 22537c478bd9Sstevel@tonic-gate status = set_temp_sensor_properties(hdlp, zulu_temp_sensor1); 22547c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 22557c478bd9Sstevel@tonic-gate return (status); 22567c478bd9Sstevel@tonic-gate } 22577c478bd9Sstevel@tonic-gate status = set_temp_sensor_properties(hdlp, zulu_temp_sensor2); 22587c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 22597c478bd9Sstevel@tonic-gate return (status); 22607c478bd9Sstevel@tonic-gate } 22617c478bd9Sstevel@tonic-gate 22627c478bd9Sstevel@tonic-gate /* 22637c478bd9Sstevel@tonic-gate * Remove Zulu (XVR-4000) node 22647c478bd9Sstevel@tonic-gate */ 22657c478bd9Sstevel@tonic-gate status = remove_module_node(hdlp, id); 22667c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 22677c478bd9Sstevel@tonic-gate return (status); 22687c478bd9Sstevel@tonic-gate } 22697c478bd9Sstevel@tonic-gate } 22707c478bd9Sstevel@tonic-gate 22717c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 22727c478bd9Sstevel@tonic-gate } 22737c478bd9Sstevel@tonic-gate 22747c478bd9Sstevel@tonic-gate 22757c478bd9Sstevel@tonic-gate /* 22767c478bd9Sstevel@tonic-gate * Remove the CPU slot's module node 22777c478bd9Sstevel@tonic-gate */ 22787c478bd9Sstevel@tonic-gate int32_t 22797c478bd9Sstevel@tonic-gate remove_module_node(psvc_opaque_t hdlp, char *id) 22807c478bd9Sstevel@tonic-gate { 22817c478bd9Sstevel@tonic-gate char parent_path[256]; 22827c478bd9Sstevel@tonic-gate picl_nodehdl_t child_node; 22837c478bd9Sstevel@tonic-gate 22847c478bd9Sstevel@tonic-gate /* convert name to node, and parent path */ 22857c478bd9Sstevel@tonic-gate psvcplugin_lookup(id, parent_path, &child_node); 22867c478bd9Sstevel@tonic-gate /* Device removed */ 22877c478bd9Sstevel@tonic-gate ptree_delete_node(child_node); 22887c478bd9Sstevel@tonic-gate 22897c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 22907c478bd9Sstevel@tonic-gate } 22917c478bd9Sstevel@tonic-gate 22927c478bd9Sstevel@tonic-gate 22937c478bd9Sstevel@tonic-gate /* 22947c478bd9Sstevel@tonic-gate * Set absent temperature sensor values to HOTPLUGGED 22957c478bd9Sstevel@tonic-gate */ 22967c478bd9Sstevel@tonic-gate int32_t 22977c478bd9Sstevel@tonic-gate set_temp_sensor_properties(psvc_opaque_t hdlp, char *id) 22987c478bd9Sstevel@tonic-gate { 22997c478bd9Sstevel@tonic-gate char state[32]; 23007c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 23017c478bd9Sstevel@tonic-gate 23027c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_STATE_ATTR, state); 23037c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 23047c478bd9Sstevel@tonic-gate return (status); 23057c478bd9Sstevel@tonic-gate } 23067c478bd9Sstevel@tonic-gate 23077c478bd9Sstevel@tonic-gate if (strcmp(state, PSVC_HOTPLUGGED) != 0) { 23087c478bd9Sstevel@tonic-gate strcpy(state, PSVC_HOTPLUGGED); 23097c478bd9Sstevel@tonic-gate 23107c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, state); 23117c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 23127c478bd9Sstevel@tonic-gate return (status); 23137c478bd9Sstevel@tonic-gate } 23147c478bd9Sstevel@tonic-gate } 23157c478bd9Sstevel@tonic-gate 23167c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 23177c478bd9Sstevel@tonic-gate } 2318