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 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 237c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate /* 307c478bd9Sstevel@tonic-gate * Daktari platform platform specific environment monitoring policies 317c478bd9Sstevel@tonic-gate */ 327c478bd9Sstevel@tonic-gate #include <poll.h> 337c478bd9Sstevel@tonic-gate #include <syslog.h> 347c478bd9Sstevel@tonic-gate #include <unistd.h> 357c478bd9Sstevel@tonic-gate #include <stdio.h> 367c478bd9Sstevel@tonic-gate #include <stdlib.h> 377c478bd9Sstevel@tonic-gate #include <errno.h> 387c478bd9Sstevel@tonic-gate #include <fcntl.h> 397c478bd9Sstevel@tonic-gate #include <strings.h> 407c478bd9Sstevel@tonic-gate #include <libintl.h> 417c478bd9Sstevel@tonic-gate #include <sys/types.h> 427c478bd9Sstevel@tonic-gate #include <sys/param.h> 437c478bd9Sstevel@tonic-gate #include <config_admin.h> 447c478bd9Sstevel@tonic-gate #include <libdevice.h> 457c478bd9Sstevel@tonic-gate #include <picl.h> 467c478bd9Sstevel@tonic-gate #include <picltree.h> 477c478bd9Sstevel@tonic-gate #include <psvc_objects.h> 487c478bd9Sstevel@tonic-gate #include <sys/i2c/clients/i2c_client.h> 497c478bd9Sstevel@tonic-gate #include <sys/daktari.h> 507c478bd9Sstevel@tonic-gate #include <sys/hpc3130_events.h> 517c478bd9Sstevel@tonic-gate #include <assert.h> 52*298b7f4cSjfrank #include <limits.h> 53*298b7f4cSjfrank #include <sys/systeminfo.h> 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/ 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate /* resides in libcfgadm */ 587c478bd9Sstevel@tonic-gate extern cfga_err_t config_change_state(cfga_cmd_t, int, char *const *, 597c478bd9Sstevel@tonic-gate const char *, struct cfga_confirm *, struct cfga_msg *, char **, 607c478bd9Sstevel@tonic-gate cfga_flags_t); 617c478bd9Sstevel@tonic-gate /* Local Routine */ 627c478bd9Sstevel@tonic-gate static int32_t update_gen_fault_led(psvc_opaque_t, char *); 637c478bd9Sstevel@tonic-gate static void shutdown_routine(void); 647c478bd9Sstevel@tonic-gate static int32_t update_thresholds(psvc_opaque_t hdlp, char *id, int offset); 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate #ifdef DEBUG 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate static int dak_policy_debug = 0; 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate #define D1SYS_ERR(ARGS) if (dak_policy_debug & 0x1) syslog ARGS; 727c478bd9Sstevel@tonic-gate #define D2SYS_ERR(ARGS) if (dak_policy_debug & 0x2) syslog ARGS; 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate #else 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate #define D1SYS_ERR(ARGS) 777c478bd9Sstevel@tonic-gate #define D2SYS_ERR(ARGS) 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate #endif 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate #define I2C_PATH "/devices/pci@9,700000/ebus@1/i2c@1,30" 82159cf8a6Swesolows #define I2C_NODE I2C_PATH ":devctl" 83159cf8a6Swesolows #define PCF8574 I2C_PATH "/ioexp@0,%x:pcf8574" 84159cf8a6Swesolows #define PCF8591 I2C_PATH "/adio@0,%x:port_0" 85159cf8a6Swesolows #define FRU I2C_PATH "/fru@0,%x:fru" 86159cf8a6Swesolows #define HPC3130_DEV I2C_PATH "/hotplug-controller@0,%2x:port_%1x" 877c478bd9Sstevel@tonic-gate #define GEN_FAULT_LED "FSP_GEN_FAULT_LED" 887c478bd9Sstevel@tonic-gate #define EMPTY_STRING "EMPTY" 897c478bd9Sstevel@tonic-gate #define DEVICE_FAILURE_MSG gettext("WARNING: Device %s failure detected") 907c478bd9Sstevel@tonic-gate #define DEVICE_INSERTED_MSG gettext("Device %s inserted") 917c478bd9Sstevel@tonic-gate #define DEVICE_REMOVED_MSG gettext("Device %s removed") 927c478bd9Sstevel@tonic-gate #define PS_UNPLUGGED_MSG gettext("Device %s unplugged") 937c478bd9Sstevel@tonic-gate #define PS_PLUGGED_MSG gettext("Device %s Plugged in") 947c478bd9Sstevel@tonic-gate #define DEVICE_OK_MSG gettext("Device %s OK") 957c478bd9Sstevel@tonic-gate #define SET_LED_FAILED_MSG \ 967c478bd9Sstevel@tonic-gate gettext("Failed to set LED state, id = %s, errno = %d\n") 977c478bd9Sstevel@tonic-gate #define GET_PRESENCE_FAILED_MSG \ 987c478bd9Sstevel@tonic-gate gettext("Failed to get presence attribute, id = %s, errno = %d\n") 997c478bd9Sstevel@tonic-gate #define GET_SENSOR_FAILED_MSG \ 1007c478bd9Sstevel@tonic-gate gettext("Failed to get sensor value, id = %s, errno = %d\n") 1017c478bd9Sstevel@tonic-gate #define ADD_PS_MSG \ 1027c478bd9Sstevel@tonic-gate gettext("WARNING: Only 1 Power Supply in system. ADD a 2nd Power Supply.\n") 1037c478bd9Sstevel@tonic-gate #define REMOVE_LOAD_MSG \ 1047c478bd9Sstevel@tonic-gate gettext("WARNING: Power Supply at 95%% current. Remove some load.\n") 1057c478bd9Sstevel@tonic-gate #define PS_OVER_CURRENT_MSG \ 1067c478bd9Sstevel@tonic-gate gettext("WARNING: Power Supply overcurrent detected\n") 1077c478bd9Sstevel@tonic-gate #define DEVICE_UNKNOWN_MSG gettext("Unknown device %s instance %d\n") 1087c478bd9Sstevel@tonic-gate #define DEVICE_HANDLE_FAIL_MSG \ 1097c478bd9Sstevel@tonic-gate gettext("Failed to get device handle for %s, errno = %d\n") 1107c478bd9Sstevel@tonic-gate #define DEVTREE_NODE_CREATE_FAILED \ 1117c478bd9Sstevel@tonic-gate gettext("psvc PICL plugin: Failed to create node for %s, errno = %d") 1127c478bd9Sstevel@tonic-gate #define DEVTREE_NODE_DELETE_FAILED \ 1137c478bd9Sstevel@tonic-gate gettext("psvc PICL plugin: Failed to delete node for %s, errno = %d") 1147c478bd9Sstevel@tonic-gate #define DISK_FAULT_MSG gettext("%s: Error Reported\n") 1157c478bd9Sstevel@tonic-gate #define DISK_OK_MSG gettext("%s: Error Cleared\n") 1167c478bd9Sstevel@tonic-gate #define SET_FANSPEED_FAILED_MSG \ 1177c478bd9Sstevel@tonic-gate gettext("Failed to set fan speed, id = %s, errno = %d\n") 1187c478bd9Sstevel@tonic-gate #define GET_ATTR_FRU_FAILED_MSG gettext("Failed psvc_get_attr for FRU info\n") 1197c478bd9Sstevel@tonic-gate #define NO_FRU_INFO_MSG \ 1207c478bd9Sstevel@tonic-gate gettext("No FRU Information for %s using default module card\n") 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate #define DAKTARI_MAX_PS 3 1237c478bd9Sstevel@tonic-gate #define DAK_MAX_PS_I_SENSORS 4 1247c478bd9Sstevel@tonic-gate #define DAK_MAX_DISKS 12 1257c478bd9Sstevel@tonic-gate #define DAK_MAX_CPU_MOD 4 1267c478bd9Sstevel@tonic-gate #define DAK_MAX_FAULT_SENSORS 3 1277c478bd9Sstevel@tonic-gate #define DAK_MAX_FANS 10 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate static int co_ps = 0; 1307c478bd9Sstevel@tonic-gate static char *shutdown_string = "shutdown -y -g 60 -i 5 \"OVERTEMP condition\""; 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate typedef struct i2c_hp { 1337c478bd9Sstevel@tonic-gate int32_t addr[2]; 1347c478bd9Sstevel@tonic-gate char name[256]; 1357c478bd9Sstevel@tonic-gate char compatible[256]; 1367c478bd9Sstevel@tonic-gate } i2c_hp_t; 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate typedef struct seg_desc { 1397c478bd9Sstevel@tonic-gate int32_t segdesc; 1407c478bd9Sstevel@tonic-gate int16_t segoffset; 1417c478bd9Sstevel@tonic-gate int16_t seglength; 1427c478bd9Sstevel@tonic-gate } seg_desc_t; 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate static int32_t threshold_names[] = { 1457c478bd9Sstevel@tonic-gate PSVC_HW_LO_SHUT_ATTR, 1467c478bd9Sstevel@tonic-gate PSVC_LO_SHUT_ATTR, 1477c478bd9Sstevel@tonic-gate PSVC_LO_WARN_ATTR, 1487c478bd9Sstevel@tonic-gate PSVC_NOT_USED, /* LOW MODE which is not used */ 1497c478bd9Sstevel@tonic-gate PSVC_OPTIMAL_TEMP_ATTR, 1507c478bd9Sstevel@tonic-gate PSVC_HI_WARN_ATTR, 1517c478bd9Sstevel@tonic-gate PSVC_HI_SHUT_ATTR, 1527c478bd9Sstevel@tonic-gate PSVC_HW_HI_SHUT_ATTR 1537c478bd9Sstevel@tonic-gate }; 1547c478bd9Sstevel@tonic-gate 155*298b7f4cSjfrank /* 156*298b7f4cSjfrank * The I2C bus is noisy, and the state may be incorrectly reported as 157*298b7f4cSjfrank * having changed. When the state changes, we attempt to confirm by 158*298b7f4cSjfrank * retrying. If any retries indicate that the state has not changed, we 159*298b7f4cSjfrank * assume the state change(s) were incorrect and the state has not changed. 160*298b7f4cSjfrank * The following variables are used to store the tuneable values read in 161*298b7f4cSjfrank * from the optional i2cparam.conf file for this shared object library. 162*298b7f4cSjfrank */ 163*298b7f4cSjfrank static int n_retry_pshp_status = PSVC_NUM_OF_RETRIES; 164*298b7f4cSjfrank static int retry_sleep_pshp_status = 1; 165*298b7f4cSjfrank static int n_read_overcurrent = PSVC_THRESHOLD_COUNTER; 166*298b7f4cSjfrank static int n_retry_devicefail = PSVC_NUM_OF_RETRIES; 167*298b7f4cSjfrank static int retry_sleep_devicefail = 1; 168*298b7f4cSjfrank static int n_read_fanfault = PSVC_THRESHOLD_COUNTER; 169*298b7f4cSjfrank static int n_retry_pshp = PSVC_NUM_OF_RETRIES; 170*298b7f4cSjfrank static int retry_sleep_pshp = 1; 171*298b7f4cSjfrank static int n_retry_diskfault = PSVC_NUM_OF_RETRIES; 172*298b7f4cSjfrank static int retry_sleep_diskfault = 1; 173*298b7f4cSjfrank static int n_retry_temp_shutdown = PSVC_NUM_OF_RETRIES; 174*298b7f4cSjfrank static int retry_sleep_temp_shutdown = 1; 175*298b7f4cSjfrank 176*298b7f4cSjfrank typedef struct { 177*298b7f4cSjfrank int *pvar; 178*298b7f4cSjfrank char *texttag; 179*298b7f4cSjfrank } i2c_noise_param_t; 180*298b7f4cSjfrank 181*298b7f4cSjfrank static i2c_noise_param_t i2cparams[] = { 182*298b7f4cSjfrank &n_retry_pshp_status, "n_retry_pshp_status", 183*298b7f4cSjfrank &retry_sleep_pshp_status, "retry_sleep_pshp_status", 184*298b7f4cSjfrank &n_read_overcurrent, "n_read_overcurrent", 185*298b7f4cSjfrank &n_retry_devicefail, "n_retry_devicefail", 186*298b7f4cSjfrank &retry_sleep_devicefail, "retry_sleep_devicefail", 187*298b7f4cSjfrank &n_read_fanfault, "n_read_fanfault", 188*298b7f4cSjfrank &n_retry_pshp, "n_retry_pshp", 189*298b7f4cSjfrank &retry_sleep_pshp, "retry_sleep_pshp", 190*298b7f4cSjfrank &n_retry_diskfault, "n_retry_diskfault", 191*298b7f4cSjfrank &retry_sleep_diskfault, "retry_sleep_diskfault", 192*298b7f4cSjfrank &n_retry_temp_shutdown, "n_retry_temp_shutdown", 193*298b7f4cSjfrank &retry_sleep_temp_shutdown, "retry_sleep_temp_shutdown", 194*298b7f4cSjfrank NULL, NULL 195*298b7f4cSjfrank }; 196*298b7f4cSjfrank 197*298b7f4cSjfrank #pragma init(i2cparams_load) 198*298b7f4cSjfrank 199*298b7f4cSjfrank static void 200*298b7f4cSjfrank i2cparams_debug(i2c_noise_param_t *pi2cparams, char *platform, 201*298b7f4cSjfrank int usingDefaults) 202*298b7f4cSjfrank { 203*298b7f4cSjfrank char s[128]; 204*298b7f4cSjfrank i2c_noise_param_t *p; 205*298b7f4cSjfrank 206*298b7f4cSjfrank if (!usingDefaults) { 207*298b7f4cSjfrank (void) snprintf(s, sizeof (s), 208*298b7f4cSjfrank "# Values from /usr/platform/%s/lib/i2cparam.conf\n", 209*298b7f4cSjfrank platform); 210*298b7f4cSjfrank syslog(LOG_WARNING, "%s", s); 211*298b7f4cSjfrank } else { 212*298b7f4cSjfrank /* no file - we're using the defaults */ 213*298b7f4cSjfrank (void) snprintf(s, sizeof (s), 214*298b7f4cSjfrank "# No /usr/platform/%s/lib/i2cparam.conf file, using defaults\n", 215*298b7f4cSjfrank platform); 216*298b7f4cSjfrank } 217*298b7f4cSjfrank (void) fputs(s, stdout); 218*298b7f4cSjfrank p = pi2cparams; 219*298b7f4cSjfrank while (p->pvar != NULL) { 220*298b7f4cSjfrank (void) snprintf(s, sizeof (s), "%s %d\n", p->texttag, 221*298b7f4cSjfrank *(p->pvar)); 222*298b7f4cSjfrank if (!usingDefaults) 223*298b7f4cSjfrank syslog(LOG_WARNING, "%s", s); 224*298b7f4cSjfrank (void) fputs(s, stdout); 225*298b7f4cSjfrank p++; 226*298b7f4cSjfrank } 227*298b7f4cSjfrank } 228*298b7f4cSjfrank 229*298b7f4cSjfrank static void 230*298b7f4cSjfrank i2cparams_load(void) 231*298b7f4cSjfrank { 232*298b7f4cSjfrank FILE *fp; 233*298b7f4cSjfrank char filename[PATH_MAX]; 234*298b7f4cSjfrank char platform[64]; 235*298b7f4cSjfrank char s[128]; 236*298b7f4cSjfrank char var[128]; 237*298b7f4cSjfrank int val; 238*298b7f4cSjfrank i2c_noise_param_t *p; 239*298b7f4cSjfrank 240*298b7f4cSjfrank if (sysinfo(SI_PLATFORM, platform, sizeof (platform)) == -1) { 241*298b7f4cSjfrank syslog(LOG_ERR, "sysinfo error %s\n", strerror(errno)); 242*298b7f4cSjfrank return; 243*298b7f4cSjfrank } 244*298b7f4cSjfrank (void) snprintf(filename, sizeof (filename), 245*298b7f4cSjfrank "/usr/platform/%s/lib/i2cparam.conf", platform); 246*298b7f4cSjfrank /* read thru the i2cparam.conf file and set variables */ 247*298b7f4cSjfrank if ((fp = fopen(filename, "r")) != NULL) { 248*298b7f4cSjfrank while (fgets(s, sizeof (s), fp) != NULL) { 249*298b7f4cSjfrank if (s[0] == '#') /* skip comment lines */ 250*298b7f4cSjfrank continue; 251*298b7f4cSjfrank /* try to find a string match and get the value */ 252*298b7f4cSjfrank if (sscanf(s, "%127s %d", var, &val) != 2) 253*298b7f4cSjfrank continue; 254*298b7f4cSjfrank if (val < 1) 255*298b7f4cSjfrank val = 1; /* clamp min value */ 256*298b7f4cSjfrank p = &(i2cparams[0]); 257*298b7f4cSjfrank while (p->pvar != NULL) { 258*298b7f4cSjfrank if (strncmp(p->texttag, var, sizeof (var)) == 259*298b7f4cSjfrank 0) { 260*298b7f4cSjfrank *(p->pvar) = val; 261*298b7f4cSjfrank break; 262*298b7f4cSjfrank } 263*298b7f4cSjfrank p++; 264*298b7f4cSjfrank } 265*298b7f4cSjfrank } 266*298b7f4cSjfrank (void) fclose(fp); 267*298b7f4cSjfrank } 268*298b7f4cSjfrank /* output the values of the parameters */ 269*298b7f4cSjfrank i2cparams_debug(&(i2cparams[0]), platform, ((fp == NULL)? 1 : 0)); 270*298b7f4cSjfrank } 271*298b7f4cSjfrank 2727c478bd9Sstevel@tonic-gate int32_t 2737c478bd9Sstevel@tonic-gate psvc_MB_update_thresholds_0(psvc_opaque_t hdlp, char *id, int offset) 2747c478bd9Sstevel@tonic-gate { 2757c478bd9Sstevel@tonic-gate int IO_offset = 0xd; 2767c478bd9Sstevel@tonic-gate int32_t err; 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate err = update_thresholds(hdlp, id, IO_offset); 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate return (err); 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate int32_t 2847c478bd9Sstevel@tonic-gate psvc_IO_update_thresholds_0(psvc_opaque_t hdlp, char *id, int offset) 2857c478bd9Sstevel@tonic-gate { 2867c478bd9Sstevel@tonic-gate int IO_offset = 0x8; 2877c478bd9Sstevel@tonic-gate int32_t err; 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate err = update_thresholds(hdlp, id, IO_offset); 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate return (err); 2927c478bd9Sstevel@tonic-gate } 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate int32_t 2957c478bd9Sstevel@tonic-gate psvc_DBP_update_thresholds_0(psvc_opaque_t hdlp, char *id, int offset) 2967c478bd9Sstevel@tonic-gate { 2977c478bd9Sstevel@tonic-gate int IO_offset = 0x7; 2987c478bd9Sstevel@tonic-gate int32_t err; 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate err = update_thresholds(hdlp, id, IO_offset); 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate return (err); 3037c478bd9Sstevel@tonic-gate } 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate /* 3067c478bd9Sstevel@tonic-gate * used to determine if a change of state occured. valid when states 3077c478bd9Sstevel@tonic-gate * are strings. 3087c478bd9Sstevel@tonic-gate */ 3097c478bd9Sstevel@tonic-gate static int8_t 3107c478bd9Sstevel@tonic-gate change_of_state_str(char *state1, char *check1, char *state2, char *check2) 3117c478bd9Sstevel@tonic-gate { 3127c478bd9Sstevel@tonic-gate int change = 0; 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate if ((strcmp(state1, check1) == 0) && (strcmp(state2, check2) != 0)) 3157c478bd9Sstevel@tonic-gate change = 1; 3167c478bd9Sstevel@tonic-gate if ((strcmp(state1, check1) != 0) && (strcmp(state2, check2) == 0)) 3177c478bd9Sstevel@tonic-gate change = 1; 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate return (change); 3207c478bd9Sstevel@tonic-gate } 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate /* 3237c478bd9Sstevel@tonic-gate * Update thresholds tries to read the temperature thresholds from the FRU 3247c478bd9Sstevel@tonic-gate * SEEproms and then updates the thresholds in the object by overriding the 3257c478bd9Sstevel@tonic-gate * hardcoded thresholds. For Daktari it is an Error if the FRU does not 3267c478bd9Sstevel@tonic-gate * contain the segment that had the temperature thresholds. 3277c478bd9Sstevel@tonic-gate */ 3287c478bd9Sstevel@tonic-gate static int32_t 3297c478bd9Sstevel@tonic-gate update_thresholds(psvc_opaque_t hdlp, char *id, int offset) 3307c478bd9Sstevel@tonic-gate { 3317c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 3327c478bd9Sstevel@tonic-gate fru_info_t fru_data; 3337c478bd9Sstevel@tonic-gate char *fru, seg_name[2]; 3347c478bd9Sstevel@tonic-gate int8_t seg_count, temp_array[8]; 3357c478bd9Sstevel@tonic-gate int32_t match_count, i, j, seg_desc_start = 0x1806, temp_address; 3367c478bd9Sstevel@tonic-gate int32_t seg_found, temp; 3377c478bd9Sstevel@tonic-gate boolean_t present; 3387c478bd9Sstevel@tonic-gate seg_desc_t segment; 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &present); 3417c478bd9Sstevel@tonic-gate if ((status != PSVC_SUCCESS) || (present != PSVC_PRESENT)) 3427c478bd9Sstevel@tonic-gate return (status); 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, &match_count, 3457c478bd9Sstevel@tonic-gate PSVC_FRU); 3467c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 3477c478bd9Sstevel@tonic-gate return (status); 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate for (i = 0; i < match_count; i++) { 3507c478bd9Sstevel@tonic-gate seg_found = 0; 3517c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 3527c478bd9Sstevel@tonic-gate &fru, PSVC_FRU, i); 3537c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 3547c478bd9Sstevel@tonic-gate return (status); 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate fru_data.buf_start = 0x1805; 3577c478bd9Sstevel@tonic-gate fru_data.buf = (char *)&seg_count; 3587c478bd9Sstevel@tonic-gate fru_data.read_size = 1; 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fru, PSVC_FRU_INFO_ATTR, 3617c478bd9Sstevel@tonic-gate &fru_data); 3627c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 3637c478bd9Sstevel@tonic-gate return (status); 3647c478bd9Sstevel@tonic-gate } 3657c478bd9Sstevel@tonic-gate for (j = 0; (j < seg_count) && (!seg_found); j++) { 3667c478bd9Sstevel@tonic-gate fru_data.buf_start = seg_desc_start; 3677c478bd9Sstevel@tonic-gate fru_data.buf = seg_name; 3687c478bd9Sstevel@tonic-gate fru_data.read_size = 2; 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fru, PSVC_FRU_INFO_ATTR, 3717c478bd9Sstevel@tonic-gate &fru_data); 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate seg_desc_start = seg_desc_start + 2; 3747c478bd9Sstevel@tonic-gate fru_data.buf_start = seg_desc_start; 3757c478bd9Sstevel@tonic-gate fru_data.buf = (char *)&segment; 3767c478bd9Sstevel@tonic-gate fru_data.read_size = sizeof (seg_desc_t); 3777c478bd9Sstevel@tonic-gate 3787c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fru, PSVC_FRU_INFO_ATTR, 3797c478bd9Sstevel@tonic-gate &fru_data); 3807c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 3817c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 3827c478bd9Sstevel@tonic-gate "Failed psvc_get_attr for FRU info\n"); 3837c478bd9Sstevel@tonic-gate return (status); 3847c478bd9Sstevel@tonic-gate } 3857c478bd9Sstevel@tonic-gate seg_desc_start = seg_desc_start + sizeof (seg_desc_t); 3867c478bd9Sstevel@tonic-gate if (memcmp(seg_name, "SC", 2) == 0) 3877c478bd9Sstevel@tonic-gate seg_found = 1; 3887c478bd9Sstevel@tonic-gate } 3897c478bd9Sstevel@tonic-gate if (seg_found) { 3907c478bd9Sstevel@tonic-gate temp_address = segment.segoffset + offset; 3917c478bd9Sstevel@tonic-gate fru_data.buf_start = temp_address; 3927c478bd9Sstevel@tonic-gate fru_data.buf = (char *)&temp_array; 3937c478bd9Sstevel@tonic-gate fru_data.read_size = sizeof (temp_array); 3947c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fru, PSVC_FRU_INFO_ATTR, 3957c478bd9Sstevel@tonic-gate &fru_data); 3967c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 3977c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 3987c478bd9Sstevel@tonic-gate "Failed psvc_get_attr for FRU info\n"); 3997c478bd9Sstevel@tonic-gate return (status); 4007c478bd9Sstevel@tonic-gate } else { 4017c478bd9Sstevel@tonic-gate for (j = 0; j < sizeof (temp_array); j++) { 4027c478bd9Sstevel@tonic-gate if (threshold_names[j] == 4037c478bd9Sstevel@tonic-gate PSVC_NOT_USED) 4047c478bd9Sstevel@tonic-gate continue; 4057c478bd9Sstevel@tonic-gate temp = temp_array[j]; 4067c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, 4077c478bd9Sstevel@tonic-gate threshold_names[j], &temp); 4087c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 4097c478bd9Sstevel@tonic-gate return (status); 4107c478bd9Sstevel@tonic-gate } 4117c478bd9Sstevel@tonic-gate } 4127c478bd9Sstevel@tonic-gate } 4137c478bd9Sstevel@tonic-gate } else { 4147c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "No FRU Information for %s" 4157c478bd9Sstevel@tonic-gate " using default temperatures\n", id); 4167c478bd9Sstevel@tonic-gate } 4177c478bd9Sstevel@tonic-gate } 4187c478bd9Sstevel@tonic-gate return (status); 4197c478bd9Sstevel@tonic-gate } 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate int32_t 4227c478bd9Sstevel@tonic-gate psvc_fan_init_speed_0(psvc_opaque_t hdlp, char *id) 4237c478bd9Sstevel@tonic-gate { 4247c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 4257c478bd9Sstevel@tonic-gate boolean_t present; 4267c478bd9Sstevel@tonic-gate char *control_id; 4277c478bd9Sstevel@tonic-gate int32_t init_speed = 0; 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &present); 4307c478bd9Sstevel@tonic-gate if ((status != PSVC_SUCCESS) || (present != PSVC_PRESENT)) 4317c478bd9Sstevel@tonic-gate return (status); 4327c478bd9Sstevel@tonic-gate 4337c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, &control_id, 4347c478bd9Sstevel@tonic-gate PSVC_FAN_DRIVE_CONTROL, 0); 4357c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 4367c478bd9Sstevel@tonic-gate return (status); 4377c478bd9Sstevel@tonic-gate 4387c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, control_id, PSVC_CONTROL_VALUE_ATTR, 4397c478bd9Sstevel@tonic-gate &init_speed); 4407c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 4417c478bd9Sstevel@tonic-gate syslog(LOG_ERR, SET_FANSPEED_FAILED_MSG, control_id, errno); 4427c478bd9Sstevel@tonic-gate return (status); 4437c478bd9Sstevel@tonic-gate } 4447c478bd9Sstevel@tonic-gate 4457c478bd9Sstevel@tonic-gate return (status); 4467c478bd9Sstevel@tonic-gate } 4477c478bd9Sstevel@tonic-gate 4487c478bd9Sstevel@tonic-gate int32_t 4497c478bd9Sstevel@tonic-gate psvc_update_setpoint_0(psvc_opaque_t hdlp, char *id) 4507c478bd9Sstevel@tonic-gate { 4517c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 4527c478bd9Sstevel@tonic-gate char *temp_sensor; 4537c478bd9Sstevel@tonic-gate int32_t match_count, i, temp; 4547c478bd9Sstevel@tonic-gate int16_t lowest_temp = 500; 4557c478bd9Sstevel@tonic-gate boolean_t present; 4567c478bd9Sstevel@tonic-gate 4577c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &present); 4587c478bd9Sstevel@tonic-gate if ((status != PSVC_SUCCESS) || (present != PSVC_PRESENT)) 4597c478bd9Sstevel@tonic-gate return (status); 4607c478bd9Sstevel@tonic-gate 4617c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, &match_count, 4627c478bd9Sstevel@tonic-gate PSVC_DEV_TEMP_SENSOR); 4637c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 4647c478bd9Sstevel@tonic-gate return (status); 4657c478bd9Sstevel@tonic-gate 4667c478bd9Sstevel@tonic-gate for (i = 0; i < match_count; i++) { 4677c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 4687c478bd9Sstevel@tonic-gate &temp_sensor, PSVC_DEV_TEMP_SENSOR, i); 4697c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 4707c478bd9Sstevel@tonic-gate return (status); 4717c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, temp_sensor, 4727c478bd9Sstevel@tonic-gate PSVC_OPTIMAL_TEMP_ATTR, &temp); 4737c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 4747c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "Failed to get Optimal temp for %s\n", 4757c478bd9Sstevel@tonic-gate temp_sensor); 4767c478bd9Sstevel@tonic-gate return (status); 4777c478bd9Sstevel@tonic-gate } 4787c478bd9Sstevel@tonic-gate if (temp < lowest_temp) 4797c478bd9Sstevel@tonic-gate lowest_temp = temp; 4807c478bd9Sstevel@tonic-gate } 4817c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_SETPOINT_ATTR, &lowest_temp); 4827c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 4837c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "Failed to change setpoint for %s\n", id); 4847c478bd9Sstevel@tonic-gate return (status); 4857c478bd9Sstevel@tonic-gate } 4867c478bd9Sstevel@tonic-gate return (status); 4877c478bd9Sstevel@tonic-gate } 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gate int32_t 4907c478bd9Sstevel@tonic-gate psvc_remove_missing_nodes_0(psvc_opaque_t hdlp, char *id) 4917c478bd9Sstevel@tonic-gate { 4927c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 4937c478bd9Sstevel@tonic-gate char state[32]; 4947c478bd9Sstevel@tonic-gate char *physical_dev; 4957c478bd9Sstevel@tonic-gate int32_t i, device_count; 4967c478bd9Sstevel@tonic-gate char parent_path[256]; 4977c478bd9Sstevel@tonic-gate picl_nodehdl_t child_node; 4987c478bd9Sstevel@tonic-gate boolean_t present; 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, 5017c478bd9Sstevel@tonic-gate &device_count, PSVC_PHYSICAL_DEVICE); 5027c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 5037c478bd9Sstevel@tonic-gate return (status); 5047c478bd9Sstevel@tonic-gate 5057c478bd9Sstevel@tonic-gate for (i = 0; i < device_count; i++) { 5067c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 5077c478bd9Sstevel@tonic-gate &physical_dev, PSVC_PHYSICAL_DEVICE, i); 5087c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 5097c478bd9Sstevel@tonic-gate return (status); 5107c478bd9Sstevel@tonic-gate if (strncmp(physical_dev, "LTC1427", 7) == 0) 5117c478bd9Sstevel@tonic-gate continue; 5127c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, physical_dev, 5137c478bd9Sstevel@tonic-gate PSVC_PROBE_RESULT_ATTR, state); 5147c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 5157c478bd9Sstevel@tonic-gate continue; 5167c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, physical_dev, PSVC_PRESENCE_ATTR, 5177c478bd9Sstevel@tonic-gate &present); 5187c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 5197c478bd9Sstevel@tonic-gate syslog(LOG_ERR, GET_PRESENCE_FAILED_MSG, physical_dev, 5207c478bd9Sstevel@tonic-gate errno); 5217c478bd9Sstevel@tonic-gate return (status); 5227c478bd9Sstevel@tonic-gate } 5237c478bd9Sstevel@tonic-gate 5247c478bd9Sstevel@tonic-gate if ((strcmp(state, PSVC_ERROR) == 0) && 5257c478bd9Sstevel@tonic-gate (present == PSVC_PRESENT)) { 5267c478bd9Sstevel@tonic-gate /* convert name to node, and parent path */ 5277c478bd9Sstevel@tonic-gate psvcplugin_lookup(physical_dev, parent_path, 5287c478bd9Sstevel@tonic-gate &child_node); 5297c478bd9Sstevel@tonic-gate /* Device removed */ 5307c478bd9Sstevel@tonic-gate ptree_delete_node(child_node); 5317c478bd9Sstevel@tonic-gate } 5327c478bd9Sstevel@tonic-gate } 5337c478bd9Sstevel@tonic-gate return (status); 5347c478bd9Sstevel@tonic-gate } 5357c478bd9Sstevel@tonic-gate 5367c478bd9Sstevel@tonic-gate int32_t 5377c478bd9Sstevel@tonic-gate psvc_check_ps_hotplug_status_0(psvc_opaque_t hdlp, char *id) 5387c478bd9Sstevel@tonic-gate { 5397c478bd9Sstevel@tonic-gate char fail_valid_switch_id[PICL_PROPNAMELEN_MAX]; 5407c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 5417c478bd9Sstevel@tonic-gate char valid_switch_state[32]; 5427c478bd9Sstevel@tonic-gate char state[32], fault[32]; 5437c478bd9Sstevel@tonic-gate int32_t led_count, j; 5447c478bd9Sstevel@tonic-gate char *led_id; 5457c478bd9Sstevel@tonic-gate char led_state[32]; 5467c478bd9Sstevel@tonic-gate boolean_t present; 5477c478bd9Sstevel@tonic-gate static int8_t hotplug_failed_count = 0; 548*298b7f4cSjfrank int retry; 5497c478bd9Sstevel@tonic-gate 5507c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &present); 5517c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 5527c478bd9Sstevel@tonic-gate syslog(LOG_ERR, GET_PRESENCE_FAILED_MSG, id, errno); 5537c478bd9Sstevel@tonic-gate return (status); 5547c478bd9Sstevel@tonic-gate } 5557c478bd9Sstevel@tonic-gate 5567c478bd9Sstevel@tonic-gate if (present == PSVC_ABSENT) { 5577c478bd9Sstevel@tonic-gate errno = ENODEV; 5587c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 5597c478bd9Sstevel@tonic-gate } 5607c478bd9Sstevel@tonic-gate 5617c478bd9Sstevel@tonic-gate snprintf(fail_valid_switch_id, sizeof (fail_valid_switch_id), "%s%s", 5627c478bd9Sstevel@tonic-gate id, "_SENSOR_VALID_SWITCH"); 5637c478bd9Sstevel@tonic-gate 5647c478bd9Sstevel@tonic-gate retry = 0; 5657c478bd9Sstevel@tonic-gate do { 5667c478bd9Sstevel@tonic-gate if (retry) 567*298b7f4cSjfrank (void) sleep(retry_sleep_pshp_status); 5687c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fail_valid_switch_id, 5697c478bd9Sstevel@tonic-gate PSVC_STATE_ATTR, valid_switch_state); 5707c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 5717c478bd9Sstevel@tonic-gate if (hotplug_failed_count == 0) { 5727c478bd9Sstevel@tonic-gate /* 5737c478bd9Sstevel@tonic-gate * First time the get_attr call failed 5747c478bd9Sstevel@tonic-gate * set count so that if we fail again 5757c478bd9Sstevel@tonic-gate * we will know 5767c478bd9Sstevel@tonic-gate */ 5777c478bd9Sstevel@tonic-gate hotplug_failed_count = 1; 5787c478bd9Sstevel@tonic-gate /* 5797c478bd9Sstevel@tonic-gate * We probably failed because the power 5807c478bd9Sstevel@tonic-gate * supply was just insterted or removed 5817c478bd9Sstevel@tonic-gate * before the get_attr call. We then 5827c478bd9Sstevel@tonic-gate * return from this policy successfully 5837c478bd9Sstevel@tonic-gate * knowing it will be run again shortly 5847c478bd9Sstevel@tonic-gate * with the right PS state. 5857c478bd9Sstevel@tonic-gate */ 5867c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 5877c478bd9Sstevel@tonic-gate } else { 5887c478bd9Sstevel@tonic-gate /* 5897c478bd9Sstevel@tonic-gate * We have failed before and so this 5907c478bd9Sstevel@tonic-gate * we will consider a hardware problem 5917c478bd9Sstevel@tonic-gate * and it should be reported 5927c478bd9Sstevel@tonic-gate */ 5937c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 5947c478bd9Sstevel@tonic-gate "Failed getting %s State: ", 5957c478bd9Sstevel@tonic-gate "ps_hotplug_status_0\n", 5967c478bd9Sstevel@tonic-gate fail_valid_switch_id); 5977c478bd9Sstevel@tonic-gate return (status); 5987c478bd9Sstevel@tonic-gate } 5997c478bd9Sstevel@tonic-gate } 6007c478bd9Sstevel@tonic-gate /* 6017c478bd9Sstevel@tonic-gate * Because we have successfully gotten a value from 6027c478bd9Sstevel@tonic-gate * the i2c device on the PS we will set the 6037c478bd9Sstevel@tonic-gate * failed_count to 0 6047c478bd9Sstevel@tonic-gate */ 6057c478bd9Sstevel@tonic-gate hotplug_failed_count = 0; 6067c478bd9Sstevel@tonic-gate 6077c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_STATE_ATTR, state); 6087c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 6097c478bd9Sstevel@tonic-gate return (status); 6107c478bd9Sstevel@tonic-gate retry++; 6117c478bd9Sstevel@tonic-gate /* 6127c478bd9Sstevel@tonic-gate * check to see if we need to retry. the conditions are: 6137c478bd9Sstevel@tonic-gate * 6147c478bd9Sstevel@tonic-gate * valid_switch_state state retry 6157c478bd9Sstevel@tonic-gate * -------------------------------------------------- 6167c478bd9Sstevel@tonic-gate * PSVC_OFF !PSVC_HOTPLUGGED yes 6177c478bd9Sstevel@tonic-gate * PSVC_ON PSVC_HOTPLUGGED yes 6187c478bd9Sstevel@tonic-gate * PSVC_OFF PSVC_HOTPLUGGED no 6197c478bd9Sstevel@tonic-gate * PSVC_ON !PSVC_HOTPLUGGED no 6207c478bd9Sstevel@tonic-gate */ 621*298b7f4cSjfrank } while ((retry < n_retry_pshp_status) && 6227c478bd9Sstevel@tonic-gate change_of_state_str(valid_switch_state, PSVC_OFF, 6237c478bd9Sstevel@tonic-gate state, PSVC_HOTPLUGGED)); 6247c478bd9Sstevel@tonic-gate 6257c478bd9Sstevel@tonic-gate if ((strcmp(valid_switch_state, PSVC_OFF) == 0) && 6267c478bd9Sstevel@tonic-gate (strcmp(state, PSVC_HOTPLUGGED) != 0)) { 6277c478bd9Sstevel@tonic-gate strcpy(state, PSVC_HOTPLUGGED); 6287c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_NO_FAULT); 6297c478bd9Sstevel@tonic-gate strcpy(led_state, PSVC_LED_OFF); 6307c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, 6317c478bd9Sstevel@tonic-gate state); 6327c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 6337c478bd9Sstevel@tonic-gate return (status); 6347c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, 6357c478bd9Sstevel@tonic-gate &led_count, PSVC_DEV_FAULT_LED); 6367c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 6377c478bd9Sstevel@tonic-gate return (status); 6387c478bd9Sstevel@tonic-gate 6397c478bd9Sstevel@tonic-gate for (j = 0; j < led_count; j++) { 6407c478bd9Sstevel@tonic-gate 6417c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 6427c478bd9Sstevel@tonic-gate &led_id, PSVC_DEV_FAULT_LED, j); 6437c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 6447c478bd9Sstevel@tonic-gate return (status); 6457c478bd9Sstevel@tonic-gate 6467c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, led_id, 6477c478bd9Sstevel@tonic-gate PSVC_LED_STATE_ATTR, led_state); 6487c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 6497c478bd9Sstevel@tonic-gate syslog(LOG_ERR, SET_LED_FAILED_MSG, led_id, 6507c478bd9Sstevel@tonic-gate errno); 6517c478bd9Sstevel@tonic-gate return (status); 6527c478bd9Sstevel@tonic-gate } 6537c478bd9Sstevel@tonic-gate 6547c478bd9Sstevel@tonic-gate } 6557c478bd9Sstevel@tonic-gate syslog(LOG_ERR, PS_UNPLUGGED_MSG, id); 6567c478bd9Sstevel@tonic-gate return (status); 6577c478bd9Sstevel@tonic-gate } 6587c478bd9Sstevel@tonic-gate 6597c478bd9Sstevel@tonic-gate if ((strcmp(valid_switch_state, PSVC_ON) == 0) && 6607c478bd9Sstevel@tonic-gate (strcmp(state, PSVC_HOTPLUGGED) == 0)) { 6617c478bd9Sstevel@tonic-gate strcpy(state, PSVC_OK); 6627c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_NO_FAULT); 6637c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, state); 6647c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 6657c478bd9Sstevel@tonic-gate return (status); 6667c478bd9Sstevel@tonic-gate syslog(LOG_ERR, PS_PLUGGED_MSG, id); 6677c478bd9Sstevel@tonic-gate } 6687c478bd9Sstevel@tonic-gate 6697c478bd9Sstevel@tonic-gate return (status); 6707c478bd9Sstevel@tonic-gate } 6717c478bd9Sstevel@tonic-gate 6727c478bd9Sstevel@tonic-gate int32_t 6737c478bd9Sstevel@tonic-gate psvc_ps_overcurrent_check_policy_0(psvc_opaque_t hdlp, char *system) 6747c478bd9Sstevel@tonic-gate { 6757c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 6767c478bd9Sstevel@tonic-gate boolean_t present; 6777c478bd9Sstevel@tonic-gate static char *sensor_id[DAKTARI_MAX_PS][DAK_MAX_PS_I_SENSORS]; 678360e6f5eSmathue static char *power_supply_id[DAKTARI_MAX_PS] = {NULL}; 6797c478bd9Sstevel@tonic-gate int32_t i, j; 6807c478bd9Sstevel@tonic-gate int32_t amps, oc_flag = 0, ps_present = 0; 6817c478bd9Sstevel@tonic-gate static int32_t hi_warn[DAKTARI_MAX_PS][DAK_MAX_PS_I_SENSORS]; 6827c478bd9Sstevel@tonic-gate char state[32]; 6837c478bd9Sstevel@tonic-gate static int8_t overcurrent_failed_check = 0; 684*298b7f4cSjfrank static int threshold_counter = 0; 6857c478bd9Sstevel@tonic-gate 6867c478bd9Sstevel@tonic-gate if (power_supply_id[0] == NULL) { 6877c478bd9Sstevel@tonic-gate for (i = 0; i < DAKTARI_MAX_PS; i++) { 6887c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, system, 6897c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &(power_supply_id[i]), 6907c478bd9Sstevel@tonic-gate PSVC_PS, i); 6917c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 6927c478bd9Sstevel@tonic-gate return (status); 6937c478bd9Sstevel@tonic-gate for (j = 0; j < DAK_MAX_PS_I_SENSORS; ++j) { 6947c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, 6957c478bd9Sstevel@tonic-gate power_supply_id[i], PSVC_ASSOC_ID_ATTR, 6967c478bd9Sstevel@tonic-gate &(sensor_id[i][j]), PSVC_PS_I_SENSOR, j); 6977c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 6987c478bd9Sstevel@tonic-gate return (status); 6997c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, sensor_id[i][j], 7007c478bd9Sstevel@tonic-gate PSVC_HI_WARN_ATTR, &(hi_warn[i][j])); 7017c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 7027c478bd9Sstevel@tonic-gate return (status); 7037c478bd9Sstevel@tonic-gate } 7047c478bd9Sstevel@tonic-gate } 7057c478bd9Sstevel@tonic-gate } 7067c478bd9Sstevel@tonic-gate 7077c478bd9Sstevel@tonic-gate for (i = 0; i < DAKTARI_MAX_PS; i++) { 7087c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, power_supply_id[i], 7097c478bd9Sstevel@tonic-gate PSVC_PRESENCE_ATTR, &present); 7107c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 7117c478bd9Sstevel@tonic-gate syslog(LOG_ERR, GET_PRESENCE_FAILED_MSG, 7127c478bd9Sstevel@tonic-gate power_supply_id[i], errno); 7137c478bd9Sstevel@tonic-gate return (status); 7147c478bd9Sstevel@tonic-gate } 7157c478bd9Sstevel@tonic-gate 7167c478bd9Sstevel@tonic-gate if (present == PSVC_ABSENT) { 7177c478bd9Sstevel@tonic-gate continue; 7187c478bd9Sstevel@tonic-gate } 7197c478bd9Sstevel@tonic-gate 7207c478bd9Sstevel@tonic-gate status = psvc_check_ps_hotplug_status_0(hdlp, 7217c478bd9Sstevel@tonic-gate power_supply_id[i]); 7227c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 7237c478bd9Sstevel@tonic-gate return (status); 7247c478bd9Sstevel@tonic-gate 7257c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, power_supply_id[i], 7267c478bd9Sstevel@tonic-gate PSVC_STATE_ATTR, state); 7277c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 7287c478bd9Sstevel@tonic-gate return (status); 7297c478bd9Sstevel@tonic-gate 7307c478bd9Sstevel@tonic-gate if (strcmp(state, PSVC_HOTPLUGGED) == 0) { 7317c478bd9Sstevel@tonic-gate continue; 7327c478bd9Sstevel@tonic-gate } else { 7337c478bd9Sstevel@tonic-gate ps_present++; 7347c478bd9Sstevel@tonic-gate } 7357c478bd9Sstevel@tonic-gate 7367c478bd9Sstevel@tonic-gate for (j = 0; j < DAK_MAX_PS_I_SENSORS; ++j) { 7377c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, sensor_id[i][j], 7387c478bd9Sstevel@tonic-gate PSVC_SENSOR_VALUE_ATTR, &s); 7397c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 7407c478bd9Sstevel@tonic-gate if (overcurrent_failed_check == 0) { 7417c478bd9Sstevel@tonic-gate /* 7427c478bd9Sstevel@tonic-gate * First time the get_attr call 7437c478bd9Sstevel@tonic-gate * failed set count so that if we 7447c478bd9Sstevel@tonic-gate * fail again we will know 7457c478bd9Sstevel@tonic-gate */ 7467c478bd9Sstevel@tonic-gate overcurrent_failed_check = 1; 7477c478bd9Sstevel@tonic-gate /* 7487c478bd9Sstevel@tonic-gate * We probably failed because the power 7497c478bd9Sstevel@tonic-gate * supply was just insterted or removed 7507c478bd9Sstevel@tonic-gate * before the get_attr call. We then 7517c478bd9Sstevel@tonic-gate * return from this policy successfully 7527c478bd9Sstevel@tonic-gate * knowing it will be run again shortly 7537c478bd9Sstevel@tonic-gate * with the right PS state. 7547c478bd9Sstevel@tonic-gate */ 7557c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 7567c478bd9Sstevel@tonic-gate } else { 7577c478bd9Sstevel@tonic-gate /* 7587c478bd9Sstevel@tonic-gate * We have failed before and so this we 7597c478bd9Sstevel@tonic-gate * will consider a hardware problem and 7607c478bd9Sstevel@tonic-gate * it should be reported. 7617c478bd9Sstevel@tonic-gate */ 7627c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 7637c478bd9Sstevel@tonic-gate "Failed getting %s sensor value", 7647c478bd9Sstevel@tonic-gate sensor_id[i][j]); 7657c478bd9Sstevel@tonic-gate return (status); 7667c478bd9Sstevel@tonic-gate } 7677c478bd9Sstevel@tonic-gate } 7687c478bd9Sstevel@tonic-gate /* 7697c478bd9Sstevel@tonic-gate * Because we have successfully gotten a value from the 7707c478bd9Sstevel@tonic-gate * i2c device on the PS we will set the failed_count 7717c478bd9Sstevel@tonic-gate * to 0. 7727c478bd9Sstevel@tonic-gate */ 7737c478bd9Sstevel@tonic-gate overcurrent_failed_check = 0; 7747c478bd9Sstevel@tonic-gate 7757c478bd9Sstevel@tonic-gate if (amps >= hi_warn[i][j]) { 7767c478bd9Sstevel@tonic-gate oc_flag = 1; 7777c478bd9Sstevel@tonic-gate } 7787c478bd9Sstevel@tonic-gate } 7797c478bd9Sstevel@tonic-gate } 7807c478bd9Sstevel@tonic-gate 7817c478bd9Sstevel@tonic-gate if (oc_flag) { 7827c478bd9Sstevel@tonic-gate /* 7837c478bd9Sstevel@tonic-gate * Because we observed an overcurrent 7847c478bd9Sstevel@tonic-gate * condition, we increment threshold_counter. 7857c478bd9Sstevel@tonic-gate * Once threshold_counter reaches the value 786*298b7f4cSjfrank * of n_read_overcurrent we log the event. 7877c478bd9Sstevel@tonic-gate */ 7887c478bd9Sstevel@tonic-gate threshold_counter++; 789*298b7f4cSjfrank if (threshold_counter == n_read_overcurrent) { 7907c478bd9Sstevel@tonic-gate threshold_counter = 0; 7917c478bd9Sstevel@tonic-gate if (ps_present == 1) { 7927c478bd9Sstevel@tonic-gate syslog(LOG_ERR, PS_OVER_CURRENT_MSG); 7937c478bd9Sstevel@tonic-gate syslog(LOG_ERR, ADD_PS_MSG); 7947c478bd9Sstevel@tonic-gate } else { 7957c478bd9Sstevel@tonic-gate syslog(LOG_ERR, PS_OVER_CURRENT_MSG); 7967c478bd9Sstevel@tonic-gate syslog(LOG_ERR, REMOVE_LOAD_MSG); 7977c478bd9Sstevel@tonic-gate } 7987c478bd9Sstevel@tonic-gate } 7997c478bd9Sstevel@tonic-gate } else { 8007c478bd9Sstevel@tonic-gate threshold_counter = 0; 8017c478bd9Sstevel@tonic-gate } 8027c478bd9Sstevel@tonic-gate 8037c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 8047c478bd9Sstevel@tonic-gate } 8057c478bd9Sstevel@tonic-gate 8067c478bd9Sstevel@tonic-gate int32_t 8077c478bd9Sstevel@tonic-gate psvc_ps_device_fail_notifier_policy_0(psvc_opaque_t hdlp, char *system) 8087c478bd9Sstevel@tonic-gate { 809360e6f5eSmathue static char *ps_id[DAKTARI_MAX_PS] = {NULL}; 8107c478bd9Sstevel@tonic-gate static char *sensor_id[DAKTARI_MAX_PS][DAK_MAX_FAULT_SENSORS]; 8117c478bd9Sstevel@tonic-gate char *led_id = "FSP_POWER_FAULT_LED"; 8127c478bd9Sstevel@tonic-gate int i, j; 8137c478bd9Sstevel@tonic-gate char state[32], fault[32], previous_state[32], past_state[32]; 8147c478bd9Sstevel@tonic-gate char led_state[32]; 8157c478bd9Sstevel@tonic-gate char bad_sensors[DAK_MAX_FAULT_SENSORS][256]; 8167c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 8177c478bd9Sstevel@tonic-gate boolean_t present; 8187c478bd9Sstevel@tonic-gate int fail_state; 8197c478bd9Sstevel@tonic-gate static int8_t device_fail_failed_check = 0; 820*298b7f4cSjfrank int retry, should_retry; 8217c478bd9Sstevel@tonic-gate 8227c478bd9Sstevel@tonic-gate if (ps_id[0] == NULL) { 8237c478bd9Sstevel@tonic-gate for (i = 0; i < DAKTARI_MAX_PS; i++) { 8247c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, system, 8257c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &(ps_id[i]), PSVC_PS, i); 8267c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 8277c478bd9Sstevel@tonic-gate return (status); 8287c478bd9Sstevel@tonic-gate for (j = 0; j < DAK_MAX_FAULT_SENSORS; j++) { 8297c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, ps_id[i], 8307c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &(sensor_id[i][j]), 8317c478bd9Sstevel@tonic-gate PSVC_DEV_FAULT_SENSOR, j); 8327c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 8337c478bd9Sstevel@tonic-gate return (status); 8347c478bd9Sstevel@tonic-gate } 8357c478bd9Sstevel@tonic-gate } 8367c478bd9Sstevel@tonic-gate } 8377c478bd9Sstevel@tonic-gate 8387c478bd9Sstevel@tonic-gate for (i = 0; i < DAKTARI_MAX_PS; i++) { 8397c478bd9Sstevel@tonic-gate fail_state = 0; 8407c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, ps_id[i], PSVC_PRESENCE_ATTR, 8417c478bd9Sstevel@tonic-gate &present); 8427c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 8437c478bd9Sstevel@tonic-gate return (status); 8447c478bd9Sstevel@tonic-gate 8457c478bd9Sstevel@tonic-gate if (present == PSVC_ABSENT) { 8467c478bd9Sstevel@tonic-gate errno = ENODEV; 8477c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 8487c478bd9Sstevel@tonic-gate } 8497c478bd9Sstevel@tonic-gate 8507c478bd9Sstevel@tonic-gate status = psvc_check_ps_hotplug_status_0(hdlp, ps_id[i]); 8517c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 8527c478bd9Sstevel@tonic-gate return (status); 8537c478bd9Sstevel@tonic-gate 8547c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, ps_id[i], PSVC_STATE_ATTR, 8557c478bd9Sstevel@tonic-gate past_state); 8567c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 8577c478bd9Sstevel@tonic-gate return (status); 8587c478bd9Sstevel@tonic-gate 8597c478bd9Sstevel@tonic-gate if (strcmp(past_state, PSVC_HOTPLUGGED) == 0) { 8607c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 8617c478bd9Sstevel@tonic-gate } 8627c478bd9Sstevel@tonic-gate 8637c478bd9Sstevel@tonic-gate retry = 0; 8647c478bd9Sstevel@tonic-gate do { 8657c478bd9Sstevel@tonic-gate if (retry) 866*298b7f4cSjfrank (void) sleep(retry_sleep_devicefail); 8677c478bd9Sstevel@tonic-gate fail_state = 0; 8687c478bd9Sstevel@tonic-gate should_retry = 0; 8697c478bd9Sstevel@tonic-gate for (j = 0; j < DAK_MAX_FAULT_SENSORS; ++j) { 8707c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, sensor_id[i][j], 8717c478bd9Sstevel@tonic-gate PSVC_SWITCH_STATE_ATTR, state); 8727c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 8737c478bd9Sstevel@tonic-gate if (device_fail_failed_check == 0) { 8747c478bd9Sstevel@tonic-gate /* 8757c478bd9Sstevel@tonic-gate * First time the get_attr call 8767c478bd9Sstevel@tonic-gate * failed set count so that 8777c478bd9Sstevel@tonic-gate * if we fail again we will know 8787c478bd9Sstevel@tonic-gate */ 8797c478bd9Sstevel@tonic-gate device_fail_failed_check = 1; 8807c478bd9Sstevel@tonic-gate /* 8817c478bd9Sstevel@tonic-gate * We probably failed because 8827c478bd9Sstevel@tonic-gate * the power supply was just 8837c478bd9Sstevel@tonic-gate * insterted or removed before 8847c478bd9Sstevel@tonic-gate * the get_attr call. We then 8857c478bd9Sstevel@tonic-gate * return from this policy 8867c478bd9Sstevel@tonic-gate * successfully knowing it will 8877c478bd9Sstevel@tonic-gate * be run again shortly 8887c478bd9Sstevel@tonic-gate * with the right PS state. 8897c478bd9Sstevel@tonic-gate */ 8907c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 8917c478bd9Sstevel@tonic-gate } else { 8927c478bd9Sstevel@tonic-gate /* 8937c478bd9Sstevel@tonic-gate * We have failed before and 8947c478bd9Sstevel@tonic-gate * so this we will consider a 8957c478bd9Sstevel@tonic-gate * hardware problem and 8967c478bd9Sstevel@tonic-gate * it should be reported. 8977c478bd9Sstevel@tonic-gate */ 8987c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "Failed in " 8997c478bd9Sstevel@tonic-gate "getting sensor state for " 9007c478bd9Sstevel@tonic-gate "%s\n", sensor_id[i][j]); 9017c478bd9Sstevel@tonic-gate 9027c478bd9Sstevel@tonic-gate return (status); 9037c478bd9Sstevel@tonic-gate } 9047c478bd9Sstevel@tonic-gate } 9057c478bd9Sstevel@tonic-gate 9067c478bd9Sstevel@tonic-gate /* 9077c478bd9Sstevel@tonic-gate * Because we have successfully gotten 9087c478bd9Sstevel@tonic-gate * a value from the i2c device on the 9097c478bd9Sstevel@tonic-gate * PS we will set the failed_count to 0. 9107c478bd9Sstevel@tonic-gate */ 9117c478bd9Sstevel@tonic-gate device_fail_failed_check = 0; 9127c478bd9Sstevel@tonic-gate 9137c478bd9Sstevel@tonic-gate /* 9147c478bd9Sstevel@tonic-gate * If we find that the sensor is on we 9157c478bd9Sstevel@tonic-gate * fill in the name of the sensor in 9167c478bd9Sstevel@tonic-gate * the bad_sensor array. If the sensor 9177c478bd9Sstevel@tonic-gate * is off we use EMPTY_STRING as a check 9187c478bd9Sstevel@tonic-gate * later on as to when NOT to print out 9197c478bd9Sstevel@tonic-gate * what is in bad_sensor[]. 9207c478bd9Sstevel@tonic-gate */ 9217c478bd9Sstevel@tonic-gate if (strcmp(state, PSVC_SWITCH_ON) == 0) { 9227c478bd9Sstevel@tonic-gate fail_state++; 9237c478bd9Sstevel@tonic-gate strlcpy(bad_sensors[j], sensor_id[i][j], 9247c478bd9Sstevel@tonic-gate sizeof (bad_sensors[j])); 9257c478bd9Sstevel@tonic-gate } else { 9267c478bd9Sstevel@tonic-gate strcpy(bad_sensors[j], EMPTY_STRING); 9277c478bd9Sstevel@tonic-gate } 9287c478bd9Sstevel@tonic-gate } 9297c478bd9Sstevel@tonic-gate retry++; 9307c478bd9Sstevel@tonic-gate /* 9317c478bd9Sstevel@tonic-gate * check to see if we need to retry. the conditions are: 9327c478bd9Sstevel@tonic-gate * 9337c478bd9Sstevel@tonic-gate * fail_state past_state retry 9347c478bd9Sstevel@tonic-gate * -------------------------------------------------- 9357c478bd9Sstevel@tonic-gate * + PSVC_OK yes 9367c478bd9Sstevel@tonic-gate * 0 PSVC_ERROR yes 9377c478bd9Sstevel@tonic-gate * + PSVC_ERROR no 9387c478bd9Sstevel@tonic-gate * 0 PSVC_OK no 9397c478bd9Sstevel@tonic-gate */ 9407c478bd9Sstevel@tonic-gate if ((fail_state > 0) && 9417c478bd9Sstevel@tonic-gate (strcmp(past_state, PSVC_OK) == 0)) { 9427c478bd9Sstevel@tonic-gate should_retry = 1; 9437c478bd9Sstevel@tonic-gate } else if ((fail_state == 0) && 9447c478bd9Sstevel@tonic-gate (strcmp(past_state, PSVC_ERROR) == 0)) { 9457c478bd9Sstevel@tonic-gate should_retry = 1; 9467c478bd9Sstevel@tonic-gate } 947*298b7f4cSjfrank } while ((retry < n_retry_devicefail) && should_retry); 9487c478bd9Sstevel@tonic-gate 9497c478bd9Sstevel@tonic-gate if (fail_state != 0) { 9507c478bd9Sstevel@tonic-gate strcpy(state, PSVC_ERROR); 9517c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_GEN_FAULT); 9527c478bd9Sstevel@tonic-gate } else { 9537c478bd9Sstevel@tonic-gate strcpy(state, PSVC_OK); 9547c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_NO_FAULT); 9557c478bd9Sstevel@tonic-gate } 9567c478bd9Sstevel@tonic-gate 9577c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, ps_id[i], PSVC_STATE_ATTR, state); 9587c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 9597c478bd9Sstevel@tonic-gate return (status); 9607c478bd9Sstevel@tonic-gate 9617c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, ps_id[i], PSVC_FAULTID_ATTR, 9627c478bd9Sstevel@tonic-gate fault); 9637c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 9647c478bd9Sstevel@tonic-gate return (status); 9657c478bd9Sstevel@tonic-gate 9667c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, ps_id[i], PSVC_PREV_STATE_ATTR, 9677c478bd9Sstevel@tonic-gate previous_state); 9687c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 9697c478bd9Sstevel@tonic-gate return (status); 9707c478bd9Sstevel@tonic-gate 9717c478bd9Sstevel@tonic-gate if (strcmp(state, previous_state) != 0) { 9727c478bd9Sstevel@tonic-gate char dev_label[32]; 9737c478bd9Sstevel@tonic-gate 9747c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, ps_id[i], PSVC_LABEL_ATTR, 9757c478bd9Sstevel@tonic-gate dev_label); 9767c478bd9Sstevel@tonic-gate 9777c478bd9Sstevel@tonic-gate if (strcmp(state, PSVC_ERROR) == 0) { 9787c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_FAILURE_MSG, dev_label); 9797c478bd9Sstevel@tonic-gate for (j = 0; j < DAK_MAX_FAULT_SENSORS; ++j) { 9807c478bd9Sstevel@tonic-gate if (strcmp(bad_sensors[j], 9817c478bd9Sstevel@tonic-gate EMPTY_STRING) != 0) 9827c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "%s\n", 9837c478bd9Sstevel@tonic-gate bad_sensors[j]); 9847c478bd9Sstevel@tonic-gate } 9857c478bd9Sstevel@tonic-gate strcpy(led_state, PSVC_LED_ON); 9867c478bd9Sstevel@tonic-gate } else { 9877c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_OK_MSG, dev_label); 9887c478bd9Sstevel@tonic-gate strcpy(led_state, PSVC_LED_OFF); 9897c478bd9Sstevel@tonic-gate } 9907c478bd9Sstevel@tonic-gate 9917c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, led_id, 9927c478bd9Sstevel@tonic-gate PSVC_LED_STATE_ATTR, led_state); 9937c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 9947c478bd9Sstevel@tonic-gate syslog(LOG_ERR, SET_LED_FAILED_MSG, led_id, 9957c478bd9Sstevel@tonic-gate errno); 9967c478bd9Sstevel@tonic-gate return (status); 9977c478bd9Sstevel@tonic-gate } 9987c478bd9Sstevel@tonic-gate } 9997c478bd9Sstevel@tonic-gate } 10007c478bd9Sstevel@tonic-gate 10017c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 10027c478bd9Sstevel@tonic-gate } 10037c478bd9Sstevel@tonic-gate 10047c478bd9Sstevel@tonic-gate int32_t 10057c478bd9Sstevel@tonic-gate psvc_ps_check_and_disable_dr_policy_0(psvc_opaque_t hdlp, char *id) 10067c478bd9Sstevel@tonic-gate { 10077c478bd9Sstevel@tonic-gate char state[32]; 1008360e6f5eSmathue static char *name[DAKTARI_MAX_PS] = {NULL}; 10097c478bd9Sstevel@tonic-gate int ps_cnt = 0; 10107c478bd9Sstevel@tonic-gate int i, j; 10117c478bd9Sstevel@tonic-gate int dr_conf; 10127c478bd9Sstevel@tonic-gate int fd, rv; 10137c478bd9Sstevel@tonic-gate boolean_t present; 10147c478bd9Sstevel@tonic-gate char dev_path[sizeof (HPC3130_DEV)+8]; 10157c478bd9Sstevel@tonic-gate unsigned char controller_names[HPC3130_CONTROLLERS] = 10167c478bd9Sstevel@tonic-gate { 0xe2, 0xe6, 0xe8, 0xec }; 10177c478bd9Sstevel@tonic-gate 10187c478bd9Sstevel@tonic-gate if (name[0] == NULL) { 10197c478bd9Sstevel@tonic-gate for (i = 0; i < DAKTARI_MAX_PS; i++) { 10207c478bd9Sstevel@tonic-gate rv = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 10217c478bd9Sstevel@tonic-gate &(name[i]), PSVC_PS, i); 10227c478bd9Sstevel@tonic-gate if (rv != PSVC_SUCCESS) 10237c478bd9Sstevel@tonic-gate return (rv); 10247c478bd9Sstevel@tonic-gate } 10257c478bd9Sstevel@tonic-gate } 10267c478bd9Sstevel@tonic-gate 10277c478bd9Sstevel@tonic-gate /* 10287c478bd9Sstevel@tonic-gate * Go through the power supplies to make sure they're present 10297c478bd9Sstevel@tonic-gate * and OK. 10307c478bd9Sstevel@tonic-gate */ 10317c478bd9Sstevel@tonic-gate ps_cnt = DAKTARI_MAX_PS; 10327c478bd9Sstevel@tonic-gate for (i = 0; i < DAKTARI_MAX_PS; i++) { 10337c478bd9Sstevel@tonic-gate rv = psvc_get_attr(hdlp, name[i], PSVC_PRESENCE_ATTR, 10347c478bd9Sstevel@tonic-gate &present); 10357c478bd9Sstevel@tonic-gate if (rv != PSVC_SUCCESS) 10367c478bd9Sstevel@tonic-gate return (rv); 10377c478bd9Sstevel@tonic-gate 10387c478bd9Sstevel@tonic-gate if (present != PSVC_PRESENT) { 10397c478bd9Sstevel@tonic-gate ps_cnt--; 10407c478bd9Sstevel@tonic-gate continue; 10417c478bd9Sstevel@tonic-gate } else { 10427c478bd9Sstevel@tonic-gate rv = psvc_get_attr(hdlp, name[i], PSVC_STATE_ATTR, 10437c478bd9Sstevel@tonic-gate state); 10447c478bd9Sstevel@tonic-gate if (rv != PSVC_SUCCESS) 10457c478bd9Sstevel@tonic-gate return (rv); 10467c478bd9Sstevel@tonic-gate 10477c478bd9Sstevel@tonic-gate if (strcmp(state, PSVC_OK)) 10487c478bd9Sstevel@tonic-gate ps_cnt--; 10497c478bd9Sstevel@tonic-gate } 10507c478bd9Sstevel@tonic-gate } 10517c478bd9Sstevel@tonic-gate 10527c478bd9Sstevel@tonic-gate /* 10537c478bd9Sstevel@tonic-gate * No change in DR configuration is needed if the new power supply 10547c478bd9Sstevel@tonic-gate * count equals the current count. 10557c478bd9Sstevel@tonic-gate */ 10567c478bd9Sstevel@tonic-gate if (ps_cnt == co_ps) 10577c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 10587c478bd9Sstevel@tonic-gate 10597c478bd9Sstevel@tonic-gate /* 10607c478bd9Sstevel@tonic-gate * Disable DR when hotplugged down to 1 power supply; enable DR when 10617c478bd9Sstevel@tonic-gate * hotplugged up from 1 supply. 10627c478bd9Sstevel@tonic-gate */ 10637c478bd9Sstevel@tonic-gate assert(ps_cnt); 10647c478bd9Sstevel@tonic-gate if ((co_ps == 0 || co_ps > 1) && ps_cnt != 1) { 10657c478bd9Sstevel@tonic-gate co_ps = ps_cnt; 10667c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 10677c478bd9Sstevel@tonic-gate } 10687c478bd9Sstevel@tonic-gate dr_conf = (ps_cnt == 1 ? HPC3130_DR_DISABLE : HPC3130_DR_ENABLE); 10697c478bd9Sstevel@tonic-gate co_ps = ps_cnt; 10707c478bd9Sstevel@tonic-gate 10717c478bd9Sstevel@tonic-gate for (i = 0; i < HPC3130_CONTROLLERS; i++) { 10727c478bd9Sstevel@tonic-gate for (j = 0; j < HPC3130_SLOTS; j++) { 10737c478bd9Sstevel@tonic-gate (void) snprintf(dev_path, sizeof (dev_path), 10747c478bd9Sstevel@tonic-gate HPC3130_DEV, controller_names[i], j); 10757c478bd9Sstevel@tonic-gate fd = open(dev_path, O_RDWR); 10767c478bd9Sstevel@tonic-gate if (fd == -1) 10777c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 10787c478bd9Sstevel@tonic-gate 10797c478bd9Sstevel@tonic-gate rv = ioctl(fd, HPC3130_CONF_DR, &dr_conf); 10807c478bd9Sstevel@tonic-gate close(fd); 10817c478bd9Sstevel@tonic-gate if (rv == -1) 10827c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 10837c478bd9Sstevel@tonic-gate } 10847c478bd9Sstevel@tonic-gate } 10857c478bd9Sstevel@tonic-gate 10867c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 10877c478bd9Sstevel@tonic-gate } 10887c478bd9Sstevel@tonic-gate 10897c478bd9Sstevel@tonic-gate int32_t 10907c478bd9Sstevel@tonic-gate psvc_fan_blast_shutoff_policy_0(psvc_opaque_t hdlp, char *id) 10917c478bd9Sstevel@tonic-gate { 10927c478bd9Sstevel@tonic-gate char switch_status[32]; 10937c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 10947c478bd9Sstevel@tonic-gate 10957c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_SWITCH_STATE_ATTR, switch_status); 10967c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 10977c478bd9Sstevel@tonic-gate return (status); 10987c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_SWITCH_STATE_ATTR, 10997c478bd9Sstevel@tonic-gate PSVC_SWITCH_OFF); 11007c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 11017c478bd9Sstevel@tonic-gate return (status); 11027c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_SWITCH_STATE_ATTR, 11037c478bd9Sstevel@tonic-gate PSVC_SWITCH_ON); 11047c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 11057c478bd9Sstevel@tonic-gate return (status); 11067c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_SWITCH_STATE_ATTR, 11077c478bd9Sstevel@tonic-gate PSVC_SWITCH_OFF); 11087c478bd9Sstevel@tonic-gate 11097c478bd9Sstevel@tonic-gate return (status); 11107c478bd9Sstevel@tonic-gate } 11117c478bd9Sstevel@tonic-gate 11127c478bd9Sstevel@tonic-gate int32_t 11137c478bd9Sstevel@tonic-gate psvc_fan_fault_check_policy_0(psvc_opaque_t hdlp, char *system) 11147c478bd9Sstevel@tonic-gate { 1115360e6f5eSmathue static char *fan_id[DAK_MAX_FANS] = {NULL}; 11167c478bd9Sstevel@tonic-gate boolean_t enabled; 11177c478bd9Sstevel@tonic-gate int32_t speed; 11187c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 11197c478bd9Sstevel@tonic-gate int r; 1120*298b7f4cSjfrank static int threshold_counter = 0; 11217c478bd9Sstevel@tonic-gate 11227c478bd9Sstevel@tonic-gate if (fan_id[0] == NULL) { 11237c478bd9Sstevel@tonic-gate for (r = 0; r < DAK_MAX_FANS; r++) { 11247c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, system, 11257c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &(fan_id[r]), PSVC_FAN, r); 11267c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 11277c478bd9Sstevel@tonic-gate return (status); 11287c478bd9Sstevel@tonic-gate } 11297c478bd9Sstevel@tonic-gate } 11307c478bd9Sstevel@tonic-gate 11317c478bd9Sstevel@tonic-gate for (r = 0; r < DAK_MAX_FANS; r++) { 11327c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fan_id[r], PSVC_ENABLE_ATTR, 11337c478bd9Sstevel@tonic-gate &enabled); 11347c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 11357c478bd9Sstevel@tonic-gate return (status); 11367c478bd9Sstevel@tonic-gate 11377c478bd9Sstevel@tonic-gate if (enabled == PSVC_ENABLED) { 11387c478bd9Sstevel@tonic-gate uint64_t features; 11397c478bd9Sstevel@tonic-gate char *switch_id; 11407c478bd9Sstevel@tonic-gate char switch_state[32], fan_state[32]; 11417c478bd9Sstevel@tonic-gate int fan_count, fans; 11427c478bd9Sstevel@tonic-gate char *other_fan_id; 11437c478bd9Sstevel@tonic-gate char fstate[32], ffault[32]; 11447c478bd9Sstevel@tonic-gate 11457c478bd9Sstevel@tonic-gate /* 11467c478bd9Sstevel@tonic-gate * If any other fan on the fan tray has an ERROR state, 11477c478bd9Sstevel@tonic-gate * mark this fan bad and return 11487c478bd9Sstevel@tonic-gate */ 11497c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, fan_id[r], PSVC_ASSOC_MATCHES_ATTR, 11507c478bd9Sstevel@tonic-gate &fan_count, PSVC_FAN_TRAY_FANS); 11517c478bd9Sstevel@tonic-gate for (fans = 0; fans < fan_count; ++fans) { 11527c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fan_id[r], 11537c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &other_fan_id, 11547c478bd9Sstevel@tonic-gate PSVC_FAN_TRAY_FANS, fans); 11557c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 11567c478bd9Sstevel@tonic-gate return (status); 11577c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, other_fan_id, 11587c478bd9Sstevel@tonic-gate PSVC_STATE_ATTR, fan_state); 11597c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 11607c478bd9Sstevel@tonic-gate return (status); 11617c478bd9Sstevel@tonic-gate 11627c478bd9Sstevel@tonic-gate if (strcmp(fan_state, PSVC_ERROR) == 0) { 11637c478bd9Sstevel@tonic-gate strlcpy(ffault, PSVC_GEN_FAULT, 11647c478bd9Sstevel@tonic-gate sizeof (ffault)); 11657c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, fan_id[r], 11667c478bd9Sstevel@tonic-gate PSVC_FAULTID_ATTR, ffault); 11677c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 11687c478bd9Sstevel@tonic-gate return (status); 11697c478bd9Sstevel@tonic-gate 11707c478bd9Sstevel@tonic-gate strlcpy(fstate, PSVC_ERROR, 11717c478bd9Sstevel@tonic-gate sizeof (fstate)); 11727c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, fan_id[r], 11737c478bd9Sstevel@tonic-gate PSVC_STATE_ATTR, fstate); 11747c478bd9Sstevel@tonic-gate 11757c478bd9Sstevel@tonic-gate return (status); 11767c478bd9Sstevel@tonic-gate } 11777c478bd9Sstevel@tonic-gate } 11787c478bd9Sstevel@tonic-gate 11797c478bd9Sstevel@tonic-gate /* 11807c478bd9Sstevel@tonic-gate * Select tachometer for IO or CPU primary/secondary 11817c478bd9Sstevel@tonic-gate * fans. 11827c478bd9Sstevel@tonic-gate */ 11837c478bd9Sstevel@tonic-gate pthread_mutex_lock(&fan_mutex); 11847c478bd9Sstevel@tonic-gate 11857c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fan_id[r], 11867c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &switch_id, 11877c478bd9Sstevel@tonic-gate PSVC_FAN_PRIM_SEC_SELECTOR, 0); 11887c478bd9Sstevel@tonic-gate 11897c478bd9Sstevel@tonic-gate if (status != PSVC_FAILURE) { 11907c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fan_id[r], 11917c478bd9Sstevel@tonic-gate PSVC_FEATURES_ATTR, &features); 11927c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 11937c478bd9Sstevel@tonic-gate pthread_mutex_unlock(&fan_mutex); 11947c478bd9Sstevel@tonic-gate return (status); 11957c478bd9Sstevel@tonic-gate } 11967c478bd9Sstevel@tonic-gate 11977c478bd9Sstevel@tonic-gate if (features & PSVC_DEV_PRIMARY) 11987c478bd9Sstevel@tonic-gate strlcpy(switch_state, PSVC_SWITCH_ON, 11997c478bd9Sstevel@tonic-gate sizeof (switch_state)); 12007c478bd9Sstevel@tonic-gate else 12017c478bd9Sstevel@tonic-gate strlcpy(switch_state, PSVC_SWITCH_OFF, 12027c478bd9Sstevel@tonic-gate sizeof (switch_state)); 12037c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, switch_id, 12047c478bd9Sstevel@tonic-gate PSVC_SWITCH_STATE_ATTR, switch_state); 12057c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 12067c478bd9Sstevel@tonic-gate pthread_mutex_unlock(&fan_mutex); 12077c478bd9Sstevel@tonic-gate return (status); 12087c478bd9Sstevel@tonic-gate } 12097c478bd9Sstevel@tonic-gate 12107c478bd9Sstevel@tonic-gate /* allow time for speed to be determined */ 12117c478bd9Sstevel@tonic-gate (void) poll(NULL, 0, 250); 12127c478bd9Sstevel@tonic-gate } 12137c478bd9Sstevel@tonic-gate 12147c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fan_id[r], 12157c478bd9Sstevel@tonic-gate PSVC_SENSOR_VALUE_ATTR, &speed); 12167c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 12177c478bd9Sstevel@tonic-gate pthread_mutex_unlock(&fan_mutex); 12187c478bd9Sstevel@tonic-gate return (status); 12197c478bd9Sstevel@tonic-gate } 12207c478bd9Sstevel@tonic-gate 12217c478bd9Sstevel@tonic-gate pthread_mutex_unlock(&fan_mutex); 12227c478bd9Sstevel@tonic-gate 12237c478bd9Sstevel@tonic-gate if (speed == 0) { 12247c478bd9Sstevel@tonic-gate threshold_counter++; 12257c478bd9Sstevel@tonic-gate if (threshold_counter == 1226*298b7f4cSjfrank n_read_fanfault) { 12277c478bd9Sstevel@tonic-gate int32_t i; 12287c478bd9Sstevel@tonic-gate int32_t led_count; 12297c478bd9Sstevel@tonic-gate char led_state[32]; 12307c478bd9Sstevel@tonic-gate char *led_id; 12317c478bd9Sstevel@tonic-gate char *slot_id; 12327c478bd9Sstevel@tonic-gate char label[32]; 12337c478bd9Sstevel@tonic-gate char state[32], fault[32]; 12347c478bd9Sstevel@tonic-gate 12357c478bd9Sstevel@tonic-gate threshold_counter = 0; 12367c478bd9Sstevel@tonic-gate strlcpy(fault, PSVC_GEN_FAULT, 12377c478bd9Sstevel@tonic-gate sizeof (fault)); 12387c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, fan_id[r], 12397c478bd9Sstevel@tonic-gate PSVC_FAULTID_ATTR, fault); 12407c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 12417c478bd9Sstevel@tonic-gate return (status); 12427c478bd9Sstevel@tonic-gate 12437c478bd9Sstevel@tonic-gate strlcpy(state, PSVC_ERROR, 12447c478bd9Sstevel@tonic-gate sizeof (state)); 12457c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, fan_id[r], 12467c478bd9Sstevel@tonic-gate PSVC_STATE_ATTR, state); 12477c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 12487c478bd9Sstevel@tonic-gate return (status); 12497c478bd9Sstevel@tonic-gate 12507c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fan_id[r], 12517c478bd9Sstevel@tonic-gate PSVC_LABEL_ATTR, label); 12527c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 12537c478bd9Sstevel@tonic-gate return (status); 12547c478bd9Sstevel@tonic-gate 12557c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_FAILURE_MSG, 12567c478bd9Sstevel@tonic-gate label); 12577c478bd9Sstevel@tonic-gate 12587c478bd9Sstevel@tonic-gate /* turn on fault LEDs */ 12597c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, fan_id[r], 12607c478bd9Sstevel@tonic-gate PSVC_ASSOC_MATCHES_ATTR, &led_count, 12617c478bd9Sstevel@tonic-gate PSVC_DEV_FAULT_LED); 12627c478bd9Sstevel@tonic-gate strlcpy(led_state, PSVC_LED_ON, 12637c478bd9Sstevel@tonic-gate sizeof (led_state)); 12647c478bd9Sstevel@tonic-gate for (i = 0; i < led_count; ++i) { 12657c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, 12667c478bd9Sstevel@tonic-gate fan_id[r], 12677c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &led_id, 12687c478bd9Sstevel@tonic-gate PSVC_DEV_FAULT_LED, i); 12697c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 12707c478bd9Sstevel@tonic-gate return (status); 12717c478bd9Sstevel@tonic-gate 12727c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, 12737c478bd9Sstevel@tonic-gate led_id, PSVC_LED_STATE_ATTR, 12747c478bd9Sstevel@tonic-gate led_state); 12757c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 12767c478bd9Sstevel@tonic-gate return (status); 12777c478bd9Sstevel@tonic-gate } 12787c478bd9Sstevel@tonic-gate 12797c478bd9Sstevel@tonic-gate /* turn on OK to remove LEDs */ 12807c478bd9Sstevel@tonic-gate 12817c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fan_id[r], 12827c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &slot_id, 12837c478bd9Sstevel@tonic-gate PSVC_PARENT, 0); 12847c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 12857c478bd9Sstevel@tonic-gate return (status); 12867c478bd9Sstevel@tonic-gate 12877c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, slot_id, 12887c478bd9Sstevel@tonic-gate PSVC_ASSOC_MATCHES_ATTR, &led_count, 12897c478bd9Sstevel@tonic-gate PSVC_SLOT_REMOVE_LED); 12907c478bd9Sstevel@tonic-gate strlcpy(led_state, PSVC_LED_ON, 12917c478bd9Sstevel@tonic-gate sizeof (led_state)); 12927c478bd9Sstevel@tonic-gate for (i = 0; i < led_count; ++i) { 12937c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, 12947c478bd9Sstevel@tonic-gate slot_id, 12957c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &led_id, 12967c478bd9Sstevel@tonic-gate PSVC_SLOT_REMOVE_LED, i); 12977c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 12987c478bd9Sstevel@tonic-gate return (status); 12997c478bd9Sstevel@tonic-gate 13007c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, 13017c478bd9Sstevel@tonic-gate led_id, PSVC_LED_STATE_ATTR, 13027c478bd9Sstevel@tonic-gate led_state); 13037c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 13047c478bd9Sstevel@tonic-gate return (status); 13057c478bd9Sstevel@tonic-gate } 13067c478bd9Sstevel@tonic-gate } 13077c478bd9Sstevel@tonic-gate } 13087c478bd9Sstevel@tonic-gate } 13097c478bd9Sstevel@tonic-gate } 13107c478bd9Sstevel@tonic-gate 13117c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 13127c478bd9Sstevel@tonic-gate } 13137c478bd9Sstevel@tonic-gate 13147c478bd9Sstevel@tonic-gate /* 13157c478bd9Sstevel@tonic-gate * This routine takes in the PSVC handle pointer, the PS name, and the 13167c478bd9Sstevel@tonic-gate * instance number (0, 1, or 2). It simply make a psvc_get call to get the 13177c478bd9Sstevel@tonic-gate * presence of each of the children under the PS. This call will set the 13187c478bd9Sstevel@tonic-gate * presence state of the child device if it was not there when the system 13197c478bd9Sstevel@tonic-gate * was booted. 13207c478bd9Sstevel@tonic-gate */ 13217c478bd9Sstevel@tonic-gate static int 13227c478bd9Sstevel@tonic-gate handle_ps_hotplug_children_presence(psvc_opaque_t hdlp, char *id) 13237c478bd9Sstevel@tonic-gate { 13247c478bd9Sstevel@tonic-gate char *sensor_id; 13257c478bd9Sstevel@tonic-gate char fail_valid_switch_id[PICL_PROPNAMELEN_MAX]; 13267c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 13277c478bd9Sstevel@tonic-gate boolean_t presence; 13287c478bd9Sstevel@tonic-gate int j; 13297c478bd9Sstevel@tonic-gate 13307c478bd9Sstevel@tonic-gate /* Get the Sensor Valid Switch presence */ 13317c478bd9Sstevel@tonic-gate snprintf(fail_valid_switch_id, sizeof (fail_valid_switch_id), "%s%s", 13327c478bd9Sstevel@tonic-gate id, "_SENSOR_VALID_SWITCH"); 13337c478bd9Sstevel@tonic-gate 13347c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fail_valid_switch_id, PSVC_PRESENCE_ATTR, 13357c478bd9Sstevel@tonic-gate &presence); 13367c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 13377c478bd9Sstevel@tonic-gate return (status); 13387c478bd9Sstevel@tonic-gate 13397c478bd9Sstevel@tonic-gate /* Go through each PS's fault sensors */ 13407c478bd9Sstevel@tonic-gate for (j = 0; j < DAK_MAX_FAULT_SENSORS; j++) { 13417c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 13427c478bd9Sstevel@tonic-gate &(sensor_id), PSVC_DEV_FAULT_SENSOR, j); 13437c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 13447c478bd9Sstevel@tonic-gate return (status); 13457c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, sensor_id, PSVC_PRESENCE_ATTR, 13467c478bd9Sstevel@tonic-gate &presence); 13477c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 13487c478bd9Sstevel@tonic-gate return (status); 13497c478bd9Sstevel@tonic-gate } 13507c478bd9Sstevel@tonic-gate 13517c478bd9Sstevel@tonic-gate /* Go through each PS's current sensors */ 13527c478bd9Sstevel@tonic-gate for (j = 0; j < DAK_MAX_PS_I_SENSORS; ++j) { 13537c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 13547c478bd9Sstevel@tonic-gate &(sensor_id), PSVC_PS_I_SENSOR, j); 13557c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 13567c478bd9Sstevel@tonic-gate return (status); 13577c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, sensor_id, PSVC_PRESENCE_ATTR, 13587c478bd9Sstevel@tonic-gate &presence); 13597c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 13607c478bd9Sstevel@tonic-gate return (status); 13617c478bd9Sstevel@tonic-gate 13627c478bd9Sstevel@tonic-gate } 13637c478bd9Sstevel@tonic-gate 13647c478bd9Sstevel@tonic-gate /* Go through each PS's onboard i2c hardware */ 13657c478bd9Sstevel@tonic-gate for (j = 0; j < 3; j++) { 13667c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 13677c478bd9Sstevel@tonic-gate &(sensor_id), PSVC_PHYSICAL_DEVICE, j); 13687c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 13697c478bd9Sstevel@tonic-gate return (status); 13707c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, sensor_id, PSVC_PRESENCE_ATTR, 13717c478bd9Sstevel@tonic-gate &presence); 13727c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 13737c478bd9Sstevel@tonic-gate return (status); 13747c478bd9Sstevel@tonic-gate } 13757c478bd9Sstevel@tonic-gate 13767c478bd9Sstevel@tonic-gate return (status); 13777c478bd9Sstevel@tonic-gate } 13787c478bd9Sstevel@tonic-gate 13797c478bd9Sstevel@tonic-gate static i2c_hp_t devices[3][3] = { 13807c478bd9Sstevel@tonic-gate {{{0, 0x90}, "adio", "i2c-pcf8591"}, {{0, 0x70}, "ioexp", "i2c-pcf8574"}, 13817c478bd9Sstevel@tonic-gate {{0, 0xa0}, "fru", "i2c-at24c64"}}, 13827c478bd9Sstevel@tonic-gate {{{0, 0x92}, "adio", "i2c-pcf8591"}, {{0, 0x72}, "ioexp", "i2c-pcf8574"}, 13837c478bd9Sstevel@tonic-gate {{0, 0xa2}, "fru", "i2c-at24c64"}}, 13847c478bd9Sstevel@tonic-gate {{{0, 0x94}, "adio", "i2c-pcf8591"}, {{0, 0x74}, "ioexp", "i2c-pcf8574"}, 13857c478bd9Sstevel@tonic-gate {{0, 0xa4}, "fru", "i2c-at24c64"}}, 13867c478bd9Sstevel@tonic-gate }; 13877c478bd9Sstevel@tonic-gate 13887c478bd9Sstevel@tonic-gate int32_t 13897c478bd9Sstevel@tonic-gate psvc_ps_hotplug_policy_0(psvc_opaque_t hdlp, char *id) 13907c478bd9Sstevel@tonic-gate { 13917c478bd9Sstevel@tonic-gate boolean_t presence, previous_presence; 13927c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 13937c478bd9Sstevel@tonic-gate char label[32], state[32], fault[32]; 13947c478bd9Sstevel@tonic-gate int32_t ps_instance, led_count; 13957c478bd9Sstevel@tonic-gate char *switch_id, *led_id; 13967c478bd9Sstevel@tonic-gate int i; 13977c478bd9Sstevel@tonic-gate picl_nodehdl_t parent_node; 13987c478bd9Sstevel@tonic-gate char parent_path[256], ps_path[256]; 13997c478bd9Sstevel@tonic-gate picl_nodehdl_t child_node; 14007c478bd9Sstevel@tonic-gate devctl_hdl_t bus_handle, dev_handle; 14017c478bd9Sstevel@tonic-gate devctl_ddef_t ddef_hdl; 14027c478bd9Sstevel@tonic-gate char pcf8574_devpath[256], pcf8591_devpath[256], fru_devpath[256]; 1403*298b7f4cSjfrank int retry; 14047c478bd9Sstevel@tonic-gate 14057c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PREV_PRESENCE_ATTR, 14067c478bd9Sstevel@tonic-gate &previous_presence); 14077c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 14087c478bd9Sstevel@tonic-gate return (status); 14097c478bd9Sstevel@tonic-gate 14107c478bd9Sstevel@tonic-gate retry = 0; 14117c478bd9Sstevel@tonic-gate do { 14127c478bd9Sstevel@tonic-gate if (retry) 1413*298b7f4cSjfrank (void) sleep(retry_sleep_pshp); 14147c478bd9Sstevel@tonic-gate 14157c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &presence); 14167c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 14177c478bd9Sstevel@tonic-gate return (status); 14187c478bd9Sstevel@tonic-gate retry++; 1419*298b7f4cSjfrank } while ((retry < n_retry_pshp) && 14207c478bd9Sstevel@tonic-gate (presence != previous_presence)); 14217c478bd9Sstevel@tonic-gate 14227c478bd9Sstevel@tonic-gate if (presence == previous_presence) { 14237c478bd9Sstevel@tonic-gate /* No change */ 14247c478bd9Sstevel@tonic-gate return (status); 14257c478bd9Sstevel@tonic-gate } 14267c478bd9Sstevel@tonic-gate 14277c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_LABEL_ATTR, label); 14287c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 14297c478bd9Sstevel@tonic-gate return (status); 14307c478bd9Sstevel@tonic-gate 14317c478bd9Sstevel@tonic-gate /* convert name to node, and parent path */ 14327c478bd9Sstevel@tonic-gate psvcplugin_lookup(id, parent_path, &child_node); 14337c478bd9Sstevel@tonic-gate 14347c478bd9Sstevel@tonic-gate if (presence == PSVC_PRESENT) { 14357c478bd9Sstevel@tonic-gate /* 14367c478bd9Sstevel@tonic-gate * Run this code if Power Supply was just added into the 14377c478bd9Sstevel@tonic-gate * System. This code toggles hotplug switch and adds the 14387c478bd9Sstevel@tonic-gate * PS and it's children to the picl tree. We then goto adding 14397c478bd9Sstevel@tonic-gate * device drivers at bottom of the routine. 14407c478bd9Sstevel@tonic-gate */ 14417c478bd9Sstevel@tonic-gate int32_t switch_count; 14427c478bd9Sstevel@tonic-gate char state[32], fault[32]; 14437c478bd9Sstevel@tonic-gate char switch_state[32]; 14447c478bd9Sstevel@tonic-gate 14457c478bd9Sstevel@tonic-gate /* may detect presence before all connections are made */ 14467c478bd9Sstevel@tonic-gate (void) poll(NULL, 0, 500); 14477c478bd9Sstevel@tonic-gate 14487c478bd9Sstevel@tonic-gate /* Device added */ 14497c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_INSERTED_MSG, label); 14507c478bd9Sstevel@tonic-gate 14517c478bd9Sstevel@tonic-gate strcpy(state, PSVC_OK); 14527c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, state); 14537c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 14547c478bd9Sstevel@tonic-gate return (status); 14557c478bd9Sstevel@tonic-gate 14567c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_NO_FAULT); 14577c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_FAULTID_ATTR, fault); 14587c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 14597c478bd9Sstevel@tonic-gate return (status); 14607c478bd9Sstevel@tonic-gate 14617c478bd9Sstevel@tonic-gate /* Enable i2c bus */ 14627c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, 14637c478bd9Sstevel@tonic-gate &switch_count, PSVC_HOTPLUG_ENABLE_SWITCH); 14647c478bd9Sstevel@tonic-gate for (i = 0; i < switch_count; ++i) { 14657c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 14667c478bd9Sstevel@tonic-gate &switch_id, PSVC_HOTPLUG_ENABLE_SWITCH, i); 14677c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 14687c478bd9Sstevel@tonic-gate return (status); 14697c478bd9Sstevel@tonic-gate 14707c478bd9Sstevel@tonic-gate strcpy(switch_state, PSVC_SWITCH_OFF); 14717c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, switch_id, 14727c478bd9Sstevel@tonic-gate PSVC_SWITCH_STATE_ATTR, switch_state); 14737c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 14747c478bd9Sstevel@tonic-gate return (status); 14757c478bd9Sstevel@tonic-gate 14767c478bd9Sstevel@tonic-gate strcpy(switch_state, PSVC_SWITCH_ON); 14777c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, switch_id, 14787c478bd9Sstevel@tonic-gate PSVC_SWITCH_STATE_ATTR, switch_state); 14797c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 14807c478bd9Sstevel@tonic-gate return (status); 14817c478bd9Sstevel@tonic-gate } 14827c478bd9Sstevel@tonic-gate ptree_get_node_by_path(parent_path, &parent_node); 14837c478bd9Sstevel@tonic-gate ptree_add_node(parent_node, child_node); 14847c478bd9Sstevel@tonic-gate snprintf(ps_path, sizeof (ps_path), "%s/%s", parent_path, id); 14857c478bd9Sstevel@tonic-gate psvcplugin_add_children(ps_path); 14867c478bd9Sstevel@tonic-gate } else { 14877c478bd9Sstevel@tonic-gate /* 14887c478bd9Sstevel@tonic-gate * Run this code if PS was just removed from the system. We 14897c478bd9Sstevel@tonic-gate * delete the device from the picl tree and then shut off 14907c478bd9Sstevel@tonic-gate * all fault lights associated with the PS. We also set the 14917c478bd9Sstevel@tonic-gate * device state to PSVC_REMOVED so that if we hit overcurrent 14927c478bd9Sstevel@tonic-gate * or fault checking code we can do a psvc call to see that 14937c478bd9Sstevel@tonic-gate * the device has not offically been added into the system. 14947c478bd9Sstevel@tonic-gate * We then will drop to code lower in the routine to remove 14957c478bd9Sstevel@tonic-gate * the device drivers for this PS. 14967c478bd9Sstevel@tonic-gate */ 14977c478bd9Sstevel@tonic-gate 14987c478bd9Sstevel@tonic-gate /* Device removed */ 14997c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_REMOVED_MSG, label); 15007c478bd9Sstevel@tonic-gate ptree_delete_node(child_node); 15017c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, &led_count, 15027c478bd9Sstevel@tonic-gate PSVC_DEV_FAULT_LED); 15037c478bd9Sstevel@tonic-gate 15047c478bd9Sstevel@tonic-gate for (i = 0; i < led_count; i++) { 15057c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 15067c478bd9Sstevel@tonic-gate &led_id, PSVC_DEV_FAULT_LED, i); 15077c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 15087c478bd9Sstevel@tonic-gate return (status); 15097c478bd9Sstevel@tonic-gate } 15107c478bd9Sstevel@tonic-gate 15117c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, led_id, 15127c478bd9Sstevel@tonic-gate PSVC_LED_STATE_ATTR, PSVC_OFF); 15137c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 15147c478bd9Sstevel@tonic-gate syslog(LOG_ERR, SET_LED_FAILED_MSG, led_id, 15157c478bd9Sstevel@tonic-gate errno); 15167c478bd9Sstevel@tonic-gate return (status); 15177c478bd9Sstevel@tonic-gate } 15187c478bd9Sstevel@tonic-gate 15197c478bd9Sstevel@tonic-gate } 15207c478bd9Sstevel@tonic-gate 15217c478bd9Sstevel@tonic-gate strcpy(state, PSVC_OK); 15227c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_NO_FAULT); 15237c478bd9Sstevel@tonic-gate 15247c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, state); 15257c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 15267c478bd9Sstevel@tonic-gate return (status); 15277c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_FAULTID_ATTR, fault); 15287c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 15297c478bd9Sstevel@tonic-gate return (status); 15307c478bd9Sstevel@tonic-gate } 15317c478bd9Sstevel@tonic-gate 15327c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_PREV_PRESENCE_ATTR, &presence); 15337c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 15347c478bd9Sstevel@tonic-gate return (status); 15357c478bd9Sstevel@tonic-gate 15367c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_INSTANCE_ATTR, &ps_instance); 15377c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 15387c478bd9Sstevel@tonic-gate return (status); 15397c478bd9Sstevel@tonic-gate 15407c478bd9Sstevel@tonic-gate if (presence != PSVC_PRESENT) { 15417c478bd9Sstevel@tonic-gate /* 15427c478bd9Sstevel@tonic-gate * This is the additional code needed to remove the PS from 15437c478bd9Sstevel@tonic-gate * the system. It removes the device drivers from the 15447c478bd9Sstevel@tonic-gate * device tree. 15457c478bd9Sstevel@tonic-gate */ 15467c478bd9Sstevel@tonic-gate snprintf(pcf8574_devpath, sizeof (pcf8574_devpath), PCF8574, 15477c478bd9Sstevel@tonic-gate devices[ps_instance][1].addr[1]); 15487c478bd9Sstevel@tonic-gate snprintf(pcf8591_devpath, sizeof (pcf8591_devpath), PCF8591, 15497c478bd9Sstevel@tonic-gate devices[ps_instance][0].addr[1]); 15507c478bd9Sstevel@tonic-gate snprintf(fru_devpath, sizeof (fru_devpath), FRU, 15517c478bd9Sstevel@tonic-gate devices[ps_instance][2].addr[1]); 15527c478bd9Sstevel@tonic-gate 15537c478bd9Sstevel@tonic-gate dev_handle = devctl_device_acquire(pcf8591_devpath, 0); 15547c478bd9Sstevel@tonic-gate if (dev_handle == NULL) { 15557c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_HANDLE_FAIL_MSG, 15567c478bd9Sstevel@tonic-gate pcf8591_devpath, errno); 15577c478bd9Sstevel@tonic-gate devctl_release(dev_handle); 15587c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 15597c478bd9Sstevel@tonic-gate } else if ((devctl_device_remove(dev_handle)) && 15607c478bd9Sstevel@tonic-gate (errno != ENXIO)) { 15617c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVTREE_NODE_DELETE_FAILED, 15627c478bd9Sstevel@tonic-gate pcf8591_devpath, errno); 15637c478bd9Sstevel@tonic-gate devctl_release(dev_handle); 15647c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 15657c478bd9Sstevel@tonic-gate } else { 15667c478bd9Sstevel@tonic-gate devctl_release(dev_handle); 15677c478bd9Sstevel@tonic-gate status = PSVC_SUCCESS; 15687c478bd9Sstevel@tonic-gate } 15697c478bd9Sstevel@tonic-gate 15707c478bd9Sstevel@tonic-gate dev_handle = devctl_device_acquire(pcf8574_devpath, 0); 15717c478bd9Sstevel@tonic-gate if (dev_handle == NULL) { 15727c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_HANDLE_FAIL_MSG, 15737c478bd9Sstevel@tonic-gate pcf8574_devpath, errno); 15747c478bd9Sstevel@tonic-gate devctl_release(dev_handle); 15757c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 15767c478bd9Sstevel@tonic-gate } else if ((devctl_device_remove(dev_handle)) && 15777c478bd9Sstevel@tonic-gate (errno != ENXIO)) { 15787c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVTREE_NODE_DELETE_FAILED, 15797c478bd9Sstevel@tonic-gate pcf8574_devpath, errno); 15807c478bd9Sstevel@tonic-gate devctl_release(dev_handle); 15817c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 15827c478bd9Sstevel@tonic-gate } else { 15837c478bd9Sstevel@tonic-gate devctl_release(dev_handle); 15847c478bd9Sstevel@tonic-gate status = PSVC_SUCCESS; 15857c478bd9Sstevel@tonic-gate } 15867c478bd9Sstevel@tonic-gate 15877c478bd9Sstevel@tonic-gate dev_handle = devctl_device_acquire(fru_devpath, 0); 15887c478bd9Sstevel@tonic-gate if (dev_handle == NULL) { 15897c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_HANDLE_FAIL_MSG, 15907c478bd9Sstevel@tonic-gate fru_devpath, errno); 15917c478bd9Sstevel@tonic-gate devctl_release(dev_handle); 15927c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 15937c478bd9Sstevel@tonic-gate } else if ((devctl_device_remove(dev_handle)) && 15947c478bd9Sstevel@tonic-gate (errno != ENXIO)) { 15957c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVTREE_NODE_DELETE_FAILED, 15967c478bd9Sstevel@tonic-gate fru_devpath, errno); 15977c478bd9Sstevel@tonic-gate devctl_release(dev_handle); 15987c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 15997c478bd9Sstevel@tonic-gate } else { 16007c478bd9Sstevel@tonic-gate devctl_release(dev_handle); 16017c478bd9Sstevel@tonic-gate status = PSVC_SUCCESS; 16027c478bd9Sstevel@tonic-gate } 16037c478bd9Sstevel@tonic-gate 16047c478bd9Sstevel@tonic-gate return (status); 16057c478bd9Sstevel@tonic-gate } 16067c478bd9Sstevel@tonic-gate 16077c478bd9Sstevel@tonic-gate /* 16087c478bd9Sstevel@tonic-gate * This code is to update the presences of power supply child 16097c478bd9Sstevel@tonic-gate * devices in the event that picld was started without a power 16107c478bd9Sstevel@tonic-gate * supply present. This call makes the devices available 16117c478bd9Sstevel@tonic-gate * after that initial insertion. 16127c478bd9Sstevel@tonic-gate */ 16137c478bd9Sstevel@tonic-gate status = handle_ps_hotplug_children_presence(hdlp, id); 16147c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 16157c478bd9Sstevel@tonic-gate return (status); 16167c478bd9Sstevel@tonic-gate } 16177c478bd9Sstevel@tonic-gate 16187c478bd9Sstevel@tonic-gate /* 16197c478bd9Sstevel@tonic-gate * We fall through to here if the device has been inserted. 16207c478bd9Sstevel@tonic-gate * Add the devinfo tree node entry for the seeprom and attach 16217c478bd9Sstevel@tonic-gate * the i2c seeprom driver 16227c478bd9Sstevel@tonic-gate */ 16237c478bd9Sstevel@tonic-gate 16247c478bd9Sstevel@tonic-gate bus_handle = devctl_bus_acquire(I2C_NODE, 0); 16257c478bd9Sstevel@tonic-gate if (bus_handle == NULL) { 16267c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_HANDLE_FAIL_MSG, I2C_NODE, errno); 16277c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 16287c478bd9Sstevel@tonic-gate } 16297c478bd9Sstevel@tonic-gate /* Create the deivce nodes for all 3 i2c parts on the PS */ 16307c478bd9Sstevel@tonic-gate for (i = 0; i < 3; i++) { 16317c478bd9Sstevel@tonic-gate ddef_hdl = devctl_ddef_alloc(devices[ps_instance][i].name, 0); 16327c478bd9Sstevel@tonic-gate if (ddef_hdl == NULL) { 16337c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_HANDLE_FAIL_MSG, 16347c478bd9Sstevel@tonic-gate devices[ps_instance][i].name, errno); 16357c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 16367c478bd9Sstevel@tonic-gate } 16377c478bd9Sstevel@tonic-gate status = devctl_ddef_string(ddef_hdl, "compatible", 16387c478bd9Sstevel@tonic-gate devices[ps_instance][i].compatible); 16397c478bd9Sstevel@tonic-gate if (status == -1) { 16407c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_HANDLE_FAIL_MSG, 16417c478bd9Sstevel@tonic-gate devices[ps_instance][i].name, errno); 16427c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 16437c478bd9Sstevel@tonic-gate } 16447c478bd9Sstevel@tonic-gate status = devctl_ddef_int_array(ddef_hdl, "reg", 2, 16457c478bd9Sstevel@tonic-gate devices[ps_instance][i].addr); 16467c478bd9Sstevel@tonic-gate if (status == -1) { 16477c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_HANDLE_FAIL_MSG, 16487c478bd9Sstevel@tonic-gate devices[ps_instance][i].name, errno); 16497c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 16507c478bd9Sstevel@tonic-gate } 16517c478bd9Sstevel@tonic-gate if (devctl_bus_dev_create(bus_handle, ddef_hdl, 0, 16527c478bd9Sstevel@tonic-gate &dev_handle)) { 16537c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVTREE_NODE_CREATE_FAILED, 16547c478bd9Sstevel@tonic-gate devices[ps_instance][i].name, errno); 16557c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 16567c478bd9Sstevel@tonic-gate } else 16577c478bd9Sstevel@tonic-gate devctl_release(dev_handle); 16587c478bd9Sstevel@tonic-gate devctl_ddef_free(ddef_hdl); 16597c478bd9Sstevel@tonic-gate } 16607c478bd9Sstevel@tonic-gate devctl_release(bus_handle); 16617c478bd9Sstevel@tonic-gate 16627c478bd9Sstevel@tonic-gate return (status); 16637c478bd9Sstevel@tonic-gate } 16647c478bd9Sstevel@tonic-gate 16657c478bd9Sstevel@tonic-gate static void 16667c478bd9Sstevel@tonic-gate shutdown_routine() 16677c478bd9Sstevel@tonic-gate { 16687c478bd9Sstevel@tonic-gate static boolean_t shutdown_flag = 0; 16697c478bd9Sstevel@tonic-gate 16707c478bd9Sstevel@tonic-gate if (!(shutdown_flag)) { 16717c478bd9Sstevel@tonic-gate system(shutdown_string); 16727c478bd9Sstevel@tonic-gate shutdown_flag = 1; 16737c478bd9Sstevel@tonic-gate } 16747c478bd9Sstevel@tonic-gate } 16757c478bd9Sstevel@tonic-gate 16767c478bd9Sstevel@tonic-gate /* 16777c478bd9Sstevel@tonic-gate * This policy checks temperature sensors to see if the fault attribute 16787c478bd9Sstevel@tonic-gate * is set to either High or Low Shutdown. If so then it shuts the system 16797c478bd9Sstevel@tonic-gate * down with a 1 minute warning period 16807c478bd9Sstevel@tonic-gate */ 16817c478bd9Sstevel@tonic-gate int32_t 16827c478bd9Sstevel@tonic-gate psvc_shutdown_policy(psvc_opaque_t hdlp, char *id) 16837c478bd9Sstevel@tonic-gate { 16847c478bd9Sstevel@tonic-gate int32_t status; 16857c478bd9Sstevel@tonic-gate char fault[32] = {0}; 16867c478bd9Sstevel@tonic-gate boolean_t pr; 1687*298b7f4cSjfrank int retry; 16887c478bd9Sstevel@tonic-gate 16897c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &pr); 16907c478bd9Sstevel@tonic-gate if ((status != PSVC_SUCCESS) || (pr != PSVC_PRESENT)) { 16917c478bd9Sstevel@tonic-gate return (status); 16927c478bd9Sstevel@tonic-gate } 16937c478bd9Sstevel@tonic-gate 1694*298b7f4cSjfrank retry = 0; 1695*298b7f4cSjfrank do { 1696*298b7f4cSjfrank if (retry) 1697*298b7f4cSjfrank (void) sleep(retry_sleep_temp_shutdown); 1698*298b7f4cSjfrank status = psvc_get_attr(hdlp, id, PSVC_FAULTID_ATTR, fault); 1699*298b7f4cSjfrank if (status != PSVC_SUCCESS) 1700*298b7f4cSjfrank return (status); 1701*298b7f4cSjfrank retry++; 1702*298b7f4cSjfrank } while (((strcmp(fault, PSVC_TEMP_LO_SHUT) == 0) || 1703*298b7f4cSjfrank (strcmp(fault, PSVC_TEMP_HI_SHUT) == 0)) && 1704*298b7f4cSjfrank (retry < n_retry_temp_shutdown)); 17057c478bd9Sstevel@tonic-gate if ((strcmp(fault, PSVC_TEMP_LO_SHUT) == 0) || 17067c478bd9Sstevel@tonic-gate (strcmp(fault, PSVC_TEMP_HI_SHUT) == 0)) { 17077c478bd9Sstevel@tonic-gate shutdown_routine(); 17087c478bd9Sstevel@tonic-gate } 17097c478bd9Sstevel@tonic-gate 17107c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 17117c478bd9Sstevel@tonic-gate } 17127c478bd9Sstevel@tonic-gate 17137c478bd9Sstevel@tonic-gate int32_t 17147c478bd9Sstevel@tonic-gate psvc_check_disk_fault_policy_0(psvc_opaque_t hdlp, char *id) 17157c478bd9Sstevel@tonic-gate { 17167c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 17177c478bd9Sstevel@tonic-gate int32_t i; 17187c478bd9Sstevel@tonic-gate char curr_state[32], prev_state[32], led_state[32]; 17197c478bd9Sstevel@tonic-gate char disk_fault[32], disk_state[32]; 1720360e6f5eSmathue static char *disk_id[DAK_MAX_DISKS] = {NULL}; 1721360e6f5eSmathue static char *led_id[DAK_MAX_DISKS] = {NULL}; 1722360e6f5eSmathue static char *parent_id[DAK_MAX_DISKS] = {NULL}; 17237c478bd9Sstevel@tonic-gate boolean_t present; 1724*298b7f4cSjfrank int retry; 17257c478bd9Sstevel@tonic-gate 17267c478bd9Sstevel@tonic-gate /* 17277c478bd9Sstevel@tonic-gate * Check which disk faulted, now get the disks. 17287c478bd9Sstevel@tonic-gate * We are now going to get disk, disk parent, 17297c478bd9Sstevel@tonic-gate * parent's leds, and check to see if parent's leds are on 17307c478bd9Sstevel@tonic-gate */ 17317c478bd9Sstevel@tonic-gate 17327c478bd9Sstevel@tonic-gate if (disk_id[0] == NULL) { 17337c478bd9Sstevel@tonic-gate for (i = 0; i < DAK_MAX_DISKS; i++) { 17347c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 17357c478bd9Sstevel@tonic-gate &(disk_id[i]), PSVC_DISK, i); 17367c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 17377c478bd9Sstevel@tonic-gate return (status); 17387c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, disk_id[i], 17397c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &(parent_id[i]), 17407c478bd9Sstevel@tonic-gate PSVC_PARENT, 0); 17417c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 17427c478bd9Sstevel@tonic-gate return (status); 17437c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, parent_id[i], 17447c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &(led_id[i]), 17457c478bd9Sstevel@tonic-gate PSVC_SLOT_FAULT_LED, 0); 17467c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 17477c478bd9Sstevel@tonic-gate return (status); 17487c478bd9Sstevel@tonic-gate 17497c478bd9Sstevel@tonic-gate } 17507c478bd9Sstevel@tonic-gate } 17517c478bd9Sstevel@tonic-gate 17527c478bd9Sstevel@tonic-gate for (i = 0; i < DAK_MAX_DISKS; i++) { 17537c478bd9Sstevel@tonic-gate curr_state[0] = 0; 17547c478bd9Sstevel@tonic-gate prev_state[0] = 0; 17557c478bd9Sstevel@tonic-gate 17567c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, disk_id[i], PSVC_PRESENCE_ATTR, 17577c478bd9Sstevel@tonic-gate &present); 17587c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 17597c478bd9Sstevel@tonic-gate return (status); 17607c478bd9Sstevel@tonic-gate 17617c478bd9Sstevel@tonic-gate if (present == PSVC_ABSENT) 17627c478bd9Sstevel@tonic-gate continue; 17637c478bd9Sstevel@tonic-gate 17647c478bd9Sstevel@tonic-gate /* 17657c478bd9Sstevel@tonic-gate * Check if whether or not the led is on. 17667c478bd9Sstevel@tonic-gate * If so, then this disk has a problem and 17677c478bd9Sstevel@tonic-gate * set its fault and error states to bad. 17687c478bd9Sstevel@tonic-gate * If not, then set fault and error states to good. 17697c478bd9Sstevel@tonic-gate * If the disk underwent a change in state, then 17707c478bd9Sstevel@tonic-gate * print out what state it's now in. 17717c478bd9Sstevel@tonic-gate */ 17727c478bd9Sstevel@tonic-gate 17737c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, disk_id[i], PSVC_STATE_ATTR, 17747c478bd9Sstevel@tonic-gate prev_state); 17757c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 17767c478bd9Sstevel@tonic-gate return (status); 17777c478bd9Sstevel@tonic-gate 17787c478bd9Sstevel@tonic-gate retry = 0; 17797c478bd9Sstevel@tonic-gate do { 17807c478bd9Sstevel@tonic-gate if (retry) 1781*298b7f4cSjfrank (void) sleep(retry_sleep_diskfault); 17827c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, led_id[i], PSVC_STATE_ATTR, 17837c478bd9Sstevel@tonic-gate led_state); 17847c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 17857c478bd9Sstevel@tonic-gate return (status); 17867c478bd9Sstevel@tonic-gate retry++; 17877c478bd9Sstevel@tonic-gate /* 17887c478bd9Sstevel@tonic-gate * check to see if we need to retry. the conditions are: 17897c478bd9Sstevel@tonic-gate * 17907c478bd9Sstevel@tonic-gate * prev_state led_state retry 17917c478bd9Sstevel@tonic-gate * -------------------------------------------------- 17927c478bd9Sstevel@tonic-gate * PSVC_ERROR PSVC_LED_ON yes 17937c478bd9Sstevel@tonic-gate * PSVC_OK PSVC_LED_OFF yes 17947c478bd9Sstevel@tonic-gate * PSVC_ERROR PSVC_LED_OFF no 17957c478bd9Sstevel@tonic-gate * PSVC_OK PSVC_LED_ON no 17967c478bd9Sstevel@tonic-gate */ 1797*298b7f4cSjfrank } while ((retry < n_retry_diskfault) && 17987c478bd9Sstevel@tonic-gate change_of_state_str(prev_state, PSVC_OK, 17997c478bd9Sstevel@tonic-gate led_state, PSVC_LED_ON)); 18007c478bd9Sstevel@tonic-gate 18017c478bd9Sstevel@tonic-gate /* 18027c478bd9Sstevel@tonic-gate * Set the disk's state and fault id according to 18037c478bd9Sstevel@tonic-gate * what we found the disk fault sensor (disk_slot_fault_led) 18047c478bd9Sstevel@tonic-gate * to be. 18057c478bd9Sstevel@tonic-gate */ 18067c478bd9Sstevel@tonic-gate if (strcmp(led_state, PSVC_LED_ON) == 0) { 18077c478bd9Sstevel@tonic-gate strcpy(disk_fault, PSVC_GEN_FAULT); 18087c478bd9Sstevel@tonic-gate strcpy(disk_state, PSVC_ERROR); 18097c478bd9Sstevel@tonic-gate } else { 18107c478bd9Sstevel@tonic-gate strcpy(disk_fault, PSVC_NO_FAULT); 18117c478bd9Sstevel@tonic-gate strcpy(disk_state, PSVC_OK); 18127c478bd9Sstevel@tonic-gate } 18137c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, disk_id[i], PSVC_STATE_ATTR, 18147c478bd9Sstevel@tonic-gate disk_state); 18157c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 18167c478bd9Sstevel@tonic-gate return (status); 18177c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, disk_id[i], PSVC_FAULTID_ATTR, 18187c478bd9Sstevel@tonic-gate disk_fault); 18197c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 18207c478bd9Sstevel@tonic-gate return (status); 18217c478bd9Sstevel@tonic-gate /* 18227c478bd9Sstevel@tonic-gate * Check disk states. If they differ, then print out 18237c478bd9Sstevel@tonic-gate * the current state of the disk 18247c478bd9Sstevel@tonic-gate */ 18257c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, disk_id[i], PSVC_PREV_STATE_ATTR, 18267c478bd9Sstevel@tonic-gate prev_state); 18277c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 18287c478bd9Sstevel@tonic-gate return (status); 18297c478bd9Sstevel@tonic-gate 18307c478bd9Sstevel@tonic-gate if (strcmp(disk_state, prev_state) != 0) { 18317c478bd9Sstevel@tonic-gate if (strcmp(disk_state, PSVC_ERROR) == 0) { 18327c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DISK_FAULT_MSG, disk_id[i]); 18337c478bd9Sstevel@tonic-gate } else { 18347c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DISK_OK_MSG, disk_id[i]); 18357c478bd9Sstevel@tonic-gate } 18367c478bd9Sstevel@tonic-gate } 18377c478bd9Sstevel@tonic-gate } 18387c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 18397c478bd9Sstevel@tonic-gate } 18407c478bd9Sstevel@tonic-gate 18417c478bd9Sstevel@tonic-gate int32_t 18427c478bd9Sstevel@tonic-gate psvc_update_FSP_fault_led_policy_0(psvc_opaque_t hdlp, char *id) 18437c478bd9Sstevel@tonic-gate { 18447c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 18457c478bd9Sstevel@tonic-gate int32_t i; 18467c478bd9Sstevel@tonic-gate int32_t dev_count, fault_state = 0; 18477c478bd9Sstevel@tonic-gate char *dev_id; 18487c478bd9Sstevel@tonic-gate char dev_state[32], led_state[32]; 18497c478bd9Sstevel@tonic-gate boolean_t present; 18507c478bd9Sstevel@tonic-gate 18517c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, &dev_count, 18527c478bd9Sstevel@tonic-gate PSVC_DEV_FAULT_SENSOR); 18537c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 18547c478bd9Sstevel@tonic-gate return (status); 18557c478bd9Sstevel@tonic-gate 18567c478bd9Sstevel@tonic-gate fault_state = 0; 18577c478bd9Sstevel@tonic-gate 18587c478bd9Sstevel@tonic-gate for (i = 0; i < dev_count; i++) { 18597c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 18607c478bd9Sstevel@tonic-gate &dev_id, PSVC_DEV_FAULT_SENSOR, i); 18617c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 18627c478bd9Sstevel@tonic-gate return (status); 18637c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, dev_id, PSVC_PRESENCE_ATTR, 18647c478bd9Sstevel@tonic-gate &present); 18657c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 18667c478bd9Sstevel@tonic-gate return (status); 18677c478bd9Sstevel@tonic-gate 18687c478bd9Sstevel@tonic-gate if (present == PSVC_ABSENT) 18697c478bd9Sstevel@tonic-gate continue; 18707c478bd9Sstevel@tonic-gate 18717c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, dev_id, PSVC_STATE_ATTR, 18727c478bd9Sstevel@tonic-gate dev_state); 18737c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 18747c478bd9Sstevel@tonic-gate return (status); 18757c478bd9Sstevel@tonic-gate 18767c478bd9Sstevel@tonic-gate if (strcmp(dev_state, PSVC_ERROR) == 0) { 18777c478bd9Sstevel@tonic-gate fault_state = 1; 18787c478bd9Sstevel@tonic-gate } 18797c478bd9Sstevel@tonic-gate } 18807c478bd9Sstevel@tonic-gate if (fault_state == 1) { 18817c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_STATE_ATTR, led_state); 18827c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 18837c478bd9Sstevel@tonic-gate return (status); 18847c478bd9Sstevel@tonic-gate if (strcmp(led_state, PSVC_OFF) == 0) { 18857c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, 18867c478bd9Sstevel@tonic-gate PSVC_ON); 18877c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 18887c478bd9Sstevel@tonic-gate return (status); 18897c478bd9Sstevel@tonic-gate } 18907c478bd9Sstevel@tonic-gate } else { 18917c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_STATE_ATTR, led_state); 18927c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 18937c478bd9Sstevel@tonic-gate return (status); 18947c478bd9Sstevel@tonic-gate if (strcmp(led_state, PSVC_ON) == 0) { 18957c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, 18967c478bd9Sstevel@tonic-gate PSVC_OFF); 18977c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 18987c478bd9Sstevel@tonic-gate return (status); 18997c478bd9Sstevel@tonic-gate } 19007c478bd9Sstevel@tonic-gate } 19017c478bd9Sstevel@tonic-gate status = update_gen_fault_led(hdlp, GEN_FAULT_LED); 19027c478bd9Sstevel@tonic-gate 19037c478bd9Sstevel@tonic-gate return (status); 19047c478bd9Sstevel@tonic-gate } 19057c478bd9Sstevel@tonic-gate 19067c478bd9Sstevel@tonic-gate int32_t 19077c478bd9Sstevel@tonic-gate update_gen_fault_led(psvc_opaque_t hdlp, char *id) 19087c478bd9Sstevel@tonic-gate { 19097c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 19107c478bd9Sstevel@tonic-gate int32_t i; 19117c478bd9Sstevel@tonic-gate int32_t led_count, fault_state; 19127c478bd9Sstevel@tonic-gate char *led_id; 19137c478bd9Sstevel@tonic-gate char led_state[32]; 19147c478bd9Sstevel@tonic-gate 19157c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, &led_count, 19167c478bd9Sstevel@tonic-gate PSVC_DEV_FAULT_SENSOR); 19177c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 19187c478bd9Sstevel@tonic-gate return (status); 19197c478bd9Sstevel@tonic-gate 19207c478bd9Sstevel@tonic-gate fault_state = 0; 19217c478bd9Sstevel@tonic-gate 19227c478bd9Sstevel@tonic-gate for (i = 0; i < led_count; i++) { 19237c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 19247c478bd9Sstevel@tonic-gate &led_id, PSVC_DEV_FAULT_SENSOR, i); 19257c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 19267c478bd9Sstevel@tonic-gate return (status); 19277c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, led_id, PSVC_STATE_ATTR, 19287c478bd9Sstevel@tonic-gate led_state); 19297c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 19307c478bd9Sstevel@tonic-gate return (status); 19317c478bd9Sstevel@tonic-gate 19327c478bd9Sstevel@tonic-gate if (strcmp(led_state, PSVC_ON) == 0) { 19337c478bd9Sstevel@tonic-gate fault_state = 1; 19347c478bd9Sstevel@tonic-gate } 19357c478bd9Sstevel@tonic-gate } 19367c478bd9Sstevel@tonic-gate 19377c478bd9Sstevel@tonic-gate if (fault_state == 1) { 19387c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_STATE_ATTR, led_state); 19397c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 19407c478bd9Sstevel@tonic-gate return (status); 19417c478bd9Sstevel@tonic-gate if (strcmp(led_state, PSVC_OFF) == 0) { 19427c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, 19437c478bd9Sstevel@tonic-gate PSVC_ON); 19447c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 19457c478bd9Sstevel@tonic-gate return (status); 19467c478bd9Sstevel@tonic-gate } 19477c478bd9Sstevel@tonic-gate } else { 19487c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_STATE_ATTR, led_state); 19497c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 19507c478bd9Sstevel@tonic-gate return (status); 19517c478bd9Sstevel@tonic-gate if (strcmp(led_state, PSVC_ON) == 0) { 19527c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, 19537c478bd9Sstevel@tonic-gate PSVC_OFF); 19547c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 19557c478bd9Sstevel@tonic-gate return (status); 19567c478bd9Sstevel@tonic-gate } 19577c478bd9Sstevel@tonic-gate } 19587c478bd9Sstevel@tonic-gate 19597c478bd9Sstevel@tonic-gate return (status); 19607c478bd9Sstevel@tonic-gate } 19617c478bd9Sstevel@tonic-gate 19627c478bd9Sstevel@tonic-gate 19637c478bd9Sstevel@tonic-gate /* 19647c478bd9Sstevel@tonic-gate * This function detects whether the module present in the dakatari's 19657c478bd9Sstevel@tonic-gate * CPU slot is a CPU module or a Zulu (XVR-4000). 19667c478bd9Sstevel@tonic-gate * Based on this detection it also sets the appropriate temperature sensors 19677c478bd9Sstevel@tonic-gate * to HOTPLUGGED, so that it works properly with check_temp() function 19687c478bd9Sstevel@tonic-gate */ 19697c478bd9Sstevel@tonic-gate #define MAX_MODULE_SIZE 20 19707c478bd9Sstevel@tonic-gate #define MAX_TEMP_SENSOR_SIZE 30 19717c478bd9Sstevel@tonic-gate 19727c478bd9Sstevel@tonic-gate int32_t 19737c478bd9Sstevel@tonic-gate psvc_update_cpu_module_card_node_0(psvc_opaque_t hdlp, char *id) 19747c478bd9Sstevel@tonic-gate { 19757c478bd9Sstevel@tonic-gate int32_t set_temp_sensor_properties(psvc_opaque_t, char *); 19767c478bd9Sstevel@tonic-gate int32_t remove_module_node(psvc_opaque_t, char *); 19777c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 19787c478bd9Sstevel@tonic-gate fru_info_t fru_data; 19797c478bd9Sstevel@tonic-gate char *fru, seg_name[2]; 19807c478bd9Sstevel@tonic-gate int8_t seg_count, module_card; 19817c478bd9Sstevel@tonic-gate int32_t match_count, i, j, seg_desc_start = 0x1806, module_address; 19827c478bd9Sstevel@tonic-gate int32_t seg_found; 19837c478bd9Sstevel@tonic-gate boolean_t present; 19847c478bd9Sstevel@tonic-gate seg_desc_t segment; 19857c478bd9Sstevel@tonic-gate char other_module_id[MAX_MODULE_SIZE]; 19867c478bd9Sstevel@tonic-gate char cpu_temp_sensor1[MAX_TEMP_SENSOR_SIZE]; 19877c478bd9Sstevel@tonic-gate char cpu_temp_sensor2[MAX_TEMP_SENSOR_SIZE]; 19887c478bd9Sstevel@tonic-gate char zulu_temp_sensor1[MAX_TEMP_SENSOR_SIZE]; 19897c478bd9Sstevel@tonic-gate char zulu_temp_sensor2[MAX_TEMP_SENSOR_SIZE]; 19907c478bd9Sstevel@tonic-gate int offset = 0x7; 19917c478bd9Sstevel@tonic-gate 19927c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &present); 19937c478bd9Sstevel@tonic-gate if ((status != PSVC_SUCCESS) || (present != PSVC_PRESENT)) { 19947c478bd9Sstevel@tonic-gate return (status); 19957c478bd9Sstevel@tonic-gate } 19967c478bd9Sstevel@tonic-gate 19977c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, &match_count, 19987c478bd9Sstevel@tonic-gate PSVC_FRU); 19997c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 20007c478bd9Sstevel@tonic-gate return (status); 20017c478bd9Sstevel@tonic-gate } 20027c478bd9Sstevel@tonic-gate 20037c478bd9Sstevel@tonic-gate for (i = 0; i < match_count; i++) { 20047c478bd9Sstevel@tonic-gate seg_found = 0; 20057c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, &fru, 20067c478bd9Sstevel@tonic-gate PSVC_FRU, i); 20077c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 20087c478bd9Sstevel@tonic-gate return (status); 20097c478bd9Sstevel@tonic-gate 20107c478bd9Sstevel@tonic-gate fru_data.buf_start = 0x1805; 20117c478bd9Sstevel@tonic-gate fru_data.buf = (char *)&seg_count; 20127c478bd9Sstevel@tonic-gate fru_data.read_size = 1; 20137c478bd9Sstevel@tonic-gate 20147c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fru, PSVC_FRU_INFO_ATTR, 20157c478bd9Sstevel@tonic-gate &fru_data); 20167c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 20177c478bd9Sstevel@tonic-gate return (status); 20187c478bd9Sstevel@tonic-gate } 20197c478bd9Sstevel@tonic-gate 20207c478bd9Sstevel@tonic-gate for (j = 0; (j < seg_count) && (!seg_found); j++) { 20217c478bd9Sstevel@tonic-gate fru_data.buf_start = seg_desc_start; 20227c478bd9Sstevel@tonic-gate fru_data.buf = seg_name; 20237c478bd9Sstevel@tonic-gate fru_data.read_size = 2; 20247c478bd9Sstevel@tonic-gate 20257c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fru, PSVC_FRU_INFO_ATTR, 20267c478bd9Sstevel@tonic-gate &fru_data); 20277c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 20287c478bd9Sstevel@tonic-gate syslog(LOG_ERR, GET_ATTR_FRU_FAILED_MSG); 20297c478bd9Sstevel@tonic-gate return (status); 20307c478bd9Sstevel@tonic-gate } 20317c478bd9Sstevel@tonic-gate 20327c478bd9Sstevel@tonic-gate seg_desc_start = seg_desc_start + 2; 20337c478bd9Sstevel@tonic-gate fru_data.buf_start = seg_desc_start; 20347c478bd9Sstevel@tonic-gate fru_data.buf = (char *)&segment; 20357c478bd9Sstevel@tonic-gate fru_data.read_size = sizeof (seg_desc_t); 20367c478bd9Sstevel@tonic-gate 20377c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fru, PSVC_FRU_INFO_ATTR, 20387c478bd9Sstevel@tonic-gate &fru_data); 20397c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 20407c478bd9Sstevel@tonic-gate syslog(LOG_ERR, GET_ATTR_FRU_FAILED_MSG); 20417c478bd9Sstevel@tonic-gate return (status); 20427c478bd9Sstevel@tonic-gate } 20437c478bd9Sstevel@tonic-gate seg_desc_start = seg_desc_start + sizeof (seg_desc_t); 20447c478bd9Sstevel@tonic-gate if (memcmp(seg_name, "SC", 2) == 0) 20457c478bd9Sstevel@tonic-gate seg_found = 1; 20467c478bd9Sstevel@tonic-gate } 20477c478bd9Sstevel@tonic-gate 20487c478bd9Sstevel@tonic-gate if (seg_found) { 20497c478bd9Sstevel@tonic-gate module_address = segment.segoffset + offset; 20507c478bd9Sstevel@tonic-gate fru_data.buf_start = module_address; 20517c478bd9Sstevel@tonic-gate fru_data.buf = (char *)&module_card; 20527c478bd9Sstevel@tonic-gate fru_data.read_size = 1; 20537c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fru, PSVC_FRU_INFO_ATTR, 20547c478bd9Sstevel@tonic-gate &fru_data); 20557c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 20567c478bd9Sstevel@tonic-gate syslog(LOG_ERR, GET_ATTR_FRU_FAILED_MSG); 20577c478bd9Sstevel@tonic-gate return (status); 20587c478bd9Sstevel@tonic-gate } 20597c478bd9Sstevel@tonic-gate } else { 20607c478bd9Sstevel@tonic-gate syslog(LOG_ERR, NO_FRU_INFO_MSG, id); 20617c478bd9Sstevel@tonic-gate } 20627c478bd9Sstevel@tonic-gate } 20637c478bd9Sstevel@tonic-gate 20647c478bd9Sstevel@tonic-gate if (strcmp(id, "ZULU_1_3_MOD_CARD") == 0) { 20657c478bd9Sstevel@tonic-gate strlcpy(other_module_id, "CPU_1_3_MOD_CARD", MAX_MODULE_SIZE); 20667c478bd9Sstevel@tonic-gate 20677c478bd9Sstevel@tonic-gate strlcpy(cpu_temp_sensor1, "CPU1_DIE_TEMPERATURE_SENSOR", 20687c478bd9Sstevel@tonic-gate MAX_TEMP_SENSOR_SIZE); 20697c478bd9Sstevel@tonic-gate strlcpy(cpu_temp_sensor2, "CPU3_DIE_TEMPERATURE_SENSOR", 20707c478bd9Sstevel@tonic-gate MAX_TEMP_SENSOR_SIZE); 20717c478bd9Sstevel@tonic-gate 20727c478bd9Sstevel@tonic-gate strlcpy(zulu_temp_sensor1, "ZULU1_DIE_TEMPERATURE_SENSOR", 20737c478bd9Sstevel@tonic-gate MAX_TEMP_SENSOR_SIZE); 20747c478bd9Sstevel@tonic-gate strlcpy(zulu_temp_sensor2, "ZULU3_DIE_TEMPERATURE_SENSOR", 20757c478bd9Sstevel@tonic-gate MAX_TEMP_SENSOR_SIZE); 20767c478bd9Sstevel@tonic-gate } 20777c478bd9Sstevel@tonic-gate 20787c478bd9Sstevel@tonic-gate if (strcmp(id, "ZULU_4_6_MOD_CARD") == 0) { 20797c478bd9Sstevel@tonic-gate strlcpy(other_module_id, "CPU_4_6_MOD_CARD", MAX_MODULE_SIZE); 20807c478bd9Sstevel@tonic-gate 20817c478bd9Sstevel@tonic-gate strlcpy(cpu_temp_sensor1, "CPU4_DIE_TEMPERATURE_SENSOR", 20827c478bd9Sstevel@tonic-gate MAX_TEMP_SENSOR_SIZE); 20837c478bd9Sstevel@tonic-gate strlcpy(cpu_temp_sensor2, "CPU6_DIE_TEMPERATURE_SENSOR", 20847c478bd9Sstevel@tonic-gate MAX_TEMP_SENSOR_SIZE); 20857c478bd9Sstevel@tonic-gate 20867c478bd9Sstevel@tonic-gate strlcpy(zulu_temp_sensor1, "ZULU4_DIE_TEMPERATURE_SENSOR", 20877c478bd9Sstevel@tonic-gate MAX_TEMP_SENSOR_SIZE); 20887c478bd9Sstevel@tonic-gate strlcpy(zulu_temp_sensor2, "ZULU6_DIE_TEMPERATURE_SENSOR", 20897c478bd9Sstevel@tonic-gate MAX_TEMP_SENSOR_SIZE); 20907c478bd9Sstevel@tonic-gate } 20917c478bd9Sstevel@tonic-gate 20927c478bd9Sstevel@tonic-gate 20937c478bd9Sstevel@tonic-gate /* 20947c478bd9Sstevel@tonic-gate * If the module in the CPU slot is a Zulu (XVR-4000), then 20957c478bd9Sstevel@tonic-gate * location 0x1EB0 in its FRUid prom has a value 0xFB. 20967c478bd9Sstevel@tonic-gate * If Zulu (XVR-4000) is detected, delete the CPU node, otherwise 20977c478bd9Sstevel@tonic-gate * delete the Zulu node. Also set the temperature sensor value to 20987c478bd9Sstevel@tonic-gate * HOTPLUGGED for absent temperature sensors. 20997c478bd9Sstevel@tonic-gate */ 21007c478bd9Sstevel@tonic-gate if ((module_card & 0xff) == 0xfb) { 21017c478bd9Sstevel@tonic-gate status = set_temp_sensor_properties(hdlp, cpu_temp_sensor1); 21027c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 21037c478bd9Sstevel@tonic-gate return (status); 21047c478bd9Sstevel@tonic-gate } 21057c478bd9Sstevel@tonic-gate 21067c478bd9Sstevel@tonic-gate status = set_temp_sensor_properties(hdlp, cpu_temp_sensor2); 21077c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 21087c478bd9Sstevel@tonic-gate return (status); 21097c478bd9Sstevel@tonic-gate } 21107c478bd9Sstevel@tonic-gate 21117c478bd9Sstevel@tonic-gate /* 21127c478bd9Sstevel@tonic-gate * Remove CPU node 21137c478bd9Sstevel@tonic-gate */ 21147c478bd9Sstevel@tonic-gate status = remove_module_node(hdlp, other_module_id); 21157c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 21167c478bd9Sstevel@tonic-gate return (status); 21177c478bd9Sstevel@tonic-gate } 21187c478bd9Sstevel@tonic-gate } else { 21197c478bd9Sstevel@tonic-gate status = set_temp_sensor_properties(hdlp, zulu_temp_sensor1); 21207c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 21217c478bd9Sstevel@tonic-gate return (status); 21227c478bd9Sstevel@tonic-gate } 21237c478bd9Sstevel@tonic-gate status = set_temp_sensor_properties(hdlp, zulu_temp_sensor2); 21247c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 21257c478bd9Sstevel@tonic-gate return (status); 21267c478bd9Sstevel@tonic-gate } 21277c478bd9Sstevel@tonic-gate 21287c478bd9Sstevel@tonic-gate /* 21297c478bd9Sstevel@tonic-gate * Remove Zulu (XVR-4000) node 21307c478bd9Sstevel@tonic-gate */ 21317c478bd9Sstevel@tonic-gate status = remove_module_node(hdlp, id); 21327c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 21337c478bd9Sstevel@tonic-gate return (status); 21347c478bd9Sstevel@tonic-gate } 21357c478bd9Sstevel@tonic-gate } 21367c478bd9Sstevel@tonic-gate 21377c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 21387c478bd9Sstevel@tonic-gate } 21397c478bd9Sstevel@tonic-gate 21407c478bd9Sstevel@tonic-gate 21417c478bd9Sstevel@tonic-gate /* 21427c478bd9Sstevel@tonic-gate * Remove the CPU slot's module node 21437c478bd9Sstevel@tonic-gate */ 21447c478bd9Sstevel@tonic-gate int32_t 21457c478bd9Sstevel@tonic-gate remove_module_node(psvc_opaque_t hdlp, char *id) 21467c478bd9Sstevel@tonic-gate { 21477c478bd9Sstevel@tonic-gate char parent_path[256]; 21487c478bd9Sstevel@tonic-gate picl_nodehdl_t child_node; 21497c478bd9Sstevel@tonic-gate 21507c478bd9Sstevel@tonic-gate /* convert name to node, and parent path */ 21517c478bd9Sstevel@tonic-gate psvcplugin_lookup(id, parent_path, &child_node); 21527c478bd9Sstevel@tonic-gate /* Device removed */ 21537c478bd9Sstevel@tonic-gate ptree_delete_node(child_node); 21547c478bd9Sstevel@tonic-gate 21557c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 21567c478bd9Sstevel@tonic-gate } 21577c478bd9Sstevel@tonic-gate 21587c478bd9Sstevel@tonic-gate 21597c478bd9Sstevel@tonic-gate /* 21607c478bd9Sstevel@tonic-gate * Set absent temperature sensor values to HOTPLUGGED 21617c478bd9Sstevel@tonic-gate */ 21627c478bd9Sstevel@tonic-gate int32_t 21637c478bd9Sstevel@tonic-gate set_temp_sensor_properties(psvc_opaque_t hdlp, char *id) 21647c478bd9Sstevel@tonic-gate { 21657c478bd9Sstevel@tonic-gate char state[32]; 21667c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 21677c478bd9Sstevel@tonic-gate 21687c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_STATE_ATTR, state); 21697c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 21707c478bd9Sstevel@tonic-gate return (status); 21717c478bd9Sstevel@tonic-gate } 21727c478bd9Sstevel@tonic-gate 21737c478bd9Sstevel@tonic-gate if (strcmp(state, PSVC_HOTPLUGGED) != 0) { 21747c478bd9Sstevel@tonic-gate strcpy(state, PSVC_HOTPLUGGED); 21757c478bd9Sstevel@tonic-gate 21767c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, state); 21777c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 21787c478bd9Sstevel@tonic-gate return (status); 21797c478bd9Sstevel@tonic-gate } 21807c478bd9Sstevel@tonic-gate } 21817c478bd9Sstevel@tonic-gate 21827c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 21837c478bd9Sstevel@tonic-gate } 2184