1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * This file contains routines to support the Platform Services Plugin 31*7c478bd9Sstevel@tonic-gate * These routines implement the platform independent environment monitoring 32*7c478bd9Sstevel@tonic-gate * and control policies that may be invoked by a daemon thread within 33*7c478bd9Sstevel@tonic-gate * the plugin 34*7c478bd9Sstevel@tonic-gate */ 35*7c478bd9Sstevel@tonic-gate 36*7c478bd9Sstevel@tonic-gate #include <syslog.h> 37*7c478bd9Sstevel@tonic-gate #include <unistd.h> 38*7c478bd9Sstevel@tonic-gate #include <stdio.h> 39*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 40*7c478bd9Sstevel@tonic-gate #include <libintl.h> 41*7c478bd9Sstevel@tonic-gate #include <errno.h> 42*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 43*7c478bd9Sstevel@tonic-gate #include <strings.h> 44*7c478bd9Sstevel@tonic-gate #include <libintl.h> 45*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 46*7c478bd9Sstevel@tonic-gate #include <picl.h> 47*7c478bd9Sstevel@tonic-gate #include <picltree.h> 48*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 49*7c478bd9Sstevel@tonic-gate #include <string.h> 50*7c478bd9Sstevel@tonic-gate #include <psvc_objects.h> 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate #define LOWTEMP_CRITICAL_MSG \ 53*7c478bd9Sstevel@tonic-gate gettext("CRITICAL : LOW TEMPERATURE DETECTED %d, %s") 54*7c478bd9Sstevel@tonic-gate #define LOWTEMP_WARNING_MSG \ 55*7c478bd9Sstevel@tonic-gate gettext("WARNING : LOW TEMPERATURE DETECTED %d, %s") 56*7c478bd9Sstevel@tonic-gate #define HIGHTEMP_CRITICAL_MSG \ 57*7c478bd9Sstevel@tonic-gate gettext("CRITICAL : HIGH TEMPERATURE DETECTED %d, %s") 58*7c478bd9Sstevel@tonic-gate #define HIGHTEMP_WARNING_MSG \ 59*7c478bd9Sstevel@tonic-gate gettext("WARNING : HIGH TEMPERATURE DETECTED %d, %s") 60*7c478bd9Sstevel@tonic-gate #define DEVICE_INSERTED_MSG gettext("Device %s inserted") 61*7c478bd9Sstevel@tonic-gate #define DEVICE_REMOVED_MSG gettext("Device %s removed") 62*7c478bd9Sstevel@tonic-gate #define DEVICE_FAILURE_MSG \ 63*7c478bd9Sstevel@tonic-gate gettext("CRITICAL: Device %s failure detected by sensor %s\n") 64*7c478bd9Sstevel@tonic-gate #define DEVICE_OK_MSG gettext("Device %s OK") 65*7c478bd9Sstevel@tonic-gate #define SECONDARY_FAN_FAIL_MSG gettext("Secondary fan failure, device %s") 66*7c478bd9Sstevel@tonic-gate #define KEYSWITCH_POS_READ_FAILED_MSG \ 67*7c478bd9Sstevel@tonic-gate gettext("Keyswitch position could not be determined") 68*7c478bd9Sstevel@tonic-gate #define KEYSWITCH_POS_CHANGED_MSG gettext("Keyswitch position changed to %s") 69*7c478bd9Sstevel@tonic-gate #define GET_PRESENCE_FAILED_MSG \ 70*7c478bd9Sstevel@tonic-gate gettext("Failed to get presence attribute, id = %s, errno = %d\n") 71*7c478bd9Sstevel@tonic-gate #define GET_SENSOR_FAILED_MSG \ 72*7c478bd9Sstevel@tonic-gate gettext("Failed to get sensor value, id = %s, errno = %d\n") 73*7c478bd9Sstevel@tonic-gate #define PS_OVER_CURRENT_MSG \ 74*7c478bd9Sstevel@tonic-gate gettext("WARNING: Power Supply overcurrent detected for %s\n") 75*7c478bd9Sstevel@tonic-gate #define SET_LED_FAILED_MSG \ 76*7c478bd9Sstevel@tonic-gate gettext("Failed to set LED state, id = %s, errno = %d\n") 77*7c478bd9Sstevel@tonic-gate #define SET_FANSPEED_FAILED_MSG \ 78*7c478bd9Sstevel@tonic-gate gettext("Failed to set fan speed, id = %s, errno = %d\n") 79*7c478bd9Sstevel@tonic-gate #define FAN_MISSING_MSG \ 80*7c478bd9Sstevel@tonic-gate gettext("WARNING: Fan missing, id = %s\n") 81*7c478bd9Sstevel@tonic-gate #define TEMP_SENSOR_FAULT \ 82*7c478bd9Sstevel@tonic-gate gettext("WARNING: Temperature Sensor %s returning faulty temp\n") 83*7c478bd9Sstevel@tonic-gate #define TEMP_OFFSET 17 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate static char *shutdown_string = "shutdown -y -g 60 -i 5 \"OVERTEMP condition\""; 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate static int cpus_online = 0; 88*7c478bd9Sstevel@tonic-gate 89*7c478bd9Sstevel@tonic-gate typedef struct seg_desc { 90*7c478bd9Sstevel@tonic-gate int32_t segdesc; 91*7c478bd9Sstevel@tonic-gate int16_t segoffset; 92*7c478bd9Sstevel@tonic-gate int16_t seglength; 93*7c478bd9Sstevel@tonic-gate } seg_desc_t; 94*7c478bd9Sstevel@tonic-gate 95*7c478bd9Sstevel@tonic-gate static int32_t threshold_names[] = { 96*7c478bd9Sstevel@tonic-gate PSVC_HW_LO_SHUT_ATTR, 97*7c478bd9Sstevel@tonic-gate PSVC_LO_SHUT_ATTR, 98*7c478bd9Sstevel@tonic-gate PSVC_LO_WARN_ATTR, 99*7c478bd9Sstevel@tonic-gate PSVC_NOT_USED, /* LOW MODE which is not used */ 100*7c478bd9Sstevel@tonic-gate PSVC_OPTIMAL_TEMP_ATTR, 101*7c478bd9Sstevel@tonic-gate PSVC_HI_WARN_ATTR, 102*7c478bd9Sstevel@tonic-gate PSVC_HI_SHUT_ATTR, 103*7c478bd9Sstevel@tonic-gate PSVC_HW_HI_SHUT_ATTR 104*7c478bd9Sstevel@tonic-gate }; 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate int32_t 107*7c478bd9Sstevel@tonic-gate psvc_update_thresholds_0(psvc_opaque_t hdlp, char *id) 108*7c478bd9Sstevel@tonic-gate { 109*7c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 110*7c478bd9Sstevel@tonic-gate fru_info_t fru_data; 111*7c478bd9Sstevel@tonic-gate char *fru, seg_name[2]; 112*7c478bd9Sstevel@tonic-gate int8_t seg_count, temp_array[8]; 113*7c478bd9Sstevel@tonic-gate int32_t match_count, i, j, seg_desc_start = 0x1806, temp_address; 114*7c478bd9Sstevel@tonic-gate int32_t seg_found, temp; 115*7c478bd9Sstevel@tonic-gate boolean_t present; 116*7c478bd9Sstevel@tonic-gate seg_desc_t segment; 117*7c478bd9Sstevel@tonic-gate 118*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &present); 119*7c478bd9Sstevel@tonic-gate if ((status != PSVC_SUCCESS) || (present != PSVC_PRESENT)) 120*7c478bd9Sstevel@tonic-gate return (status); 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, &match_count, 123*7c478bd9Sstevel@tonic-gate PSVC_FRU); 124*7c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 125*7c478bd9Sstevel@tonic-gate return (status); 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate for (i = 0; i < match_count; i++) { 128*7c478bd9Sstevel@tonic-gate seg_found = 0; 129*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 130*7c478bd9Sstevel@tonic-gate &fru, PSVC_FRU, i); 131*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 132*7c478bd9Sstevel@tonic-gate return (status); 133*7c478bd9Sstevel@tonic-gate 134*7c478bd9Sstevel@tonic-gate fru_data.buf_start = 0x1805; 135*7c478bd9Sstevel@tonic-gate fru_data.buf = (char *)&seg_count; 136*7c478bd9Sstevel@tonic-gate fru_data.read_size = 1; 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fru, PSVC_FRU_INFO_ATTR, 139*7c478bd9Sstevel@tonic-gate &fru_data); 140*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 141*7c478bd9Sstevel@tonic-gate return (status); 142*7c478bd9Sstevel@tonic-gate } 143*7c478bd9Sstevel@tonic-gate for (j = 0; (j < seg_count) && (!seg_found); j++) { 144*7c478bd9Sstevel@tonic-gate fru_data.buf_start = seg_desc_start; 145*7c478bd9Sstevel@tonic-gate fru_data.buf = seg_name; 146*7c478bd9Sstevel@tonic-gate fru_data.read_size = 2; 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fru, PSVC_FRU_INFO_ATTR, 149*7c478bd9Sstevel@tonic-gate &fru_data); 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate seg_desc_start = seg_desc_start + 2; 152*7c478bd9Sstevel@tonic-gate fru_data.buf_start = seg_desc_start; 153*7c478bd9Sstevel@tonic-gate fru_data.buf = (char *)&segment; 154*7c478bd9Sstevel@tonic-gate fru_data.read_size = sizeof (seg_desc_t); 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fru, PSVC_FRU_INFO_ATTR, 157*7c478bd9Sstevel@tonic-gate &fru_data); 158*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 159*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 160*7c478bd9Sstevel@tonic-gate "Failed psvc_get_attr for FRU info\n"); 161*7c478bd9Sstevel@tonic-gate return (status); 162*7c478bd9Sstevel@tonic-gate } 163*7c478bd9Sstevel@tonic-gate seg_desc_start = seg_desc_start + sizeof (seg_desc_t); 164*7c478bd9Sstevel@tonic-gate if (memcmp(seg_name, "SC", 2) == 0) 165*7c478bd9Sstevel@tonic-gate seg_found = 1; 166*7c478bd9Sstevel@tonic-gate } 167*7c478bd9Sstevel@tonic-gate if (seg_found) { 168*7c478bd9Sstevel@tonic-gate temp_address = segment.segoffset + TEMP_OFFSET; 169*7c478bd9Sstevel@tonic-gate fru_data.buf_start = temp_address; 170*7c478bd9Sstevel@tonic-gate fru_data.buf = (char *)&temp_array; 171*7c478bd9Sstevel@tonic-gate fru_data.read_size = sizeof (temp_array); 172*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, fru, PSVC_FRU_INFO_ATTR, 173*7c478bd9Sstevel@tonic-gate &fru_data); 174*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 175*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 176*7c478bd9Sstevel@tonic-gate "Failed psvc_get_attr for FRU info\n"); 177*7c478bd9Sstevel@tonic-gate return (status); 178*7c478bd9Sstevel@tonic-gate } else { 179*7c478bd9Sstevel@tonic-gate for (j = 0; j < sizeof (temp_array); j++) { 180*7c478bd9Sstevel@tonic-gate if (threshold_names[j] == PSVC_NOT_USED) 181*7c478bd9Sstevel@tonic-gate continue; 182*7c478bd9Sstevel@tonic-gate temp = temp_array[j]; 183*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, 184*7c478bd9Sstevel@tonic-gate threshold_names[j], &temp); 185*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 186*7c478bd9Sstevel@tonic-gate return (status); 187*7c478bd9Sstevel@tonic-gate } 188*7c478bd9Sstevel@tonic-gate } 189*7c478bd9Sstevel@tonic-gate } 190*7c478bd9Sstevel@tonic-gate } else { 191*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "No FRU Information for %s" 192*7c478bd9Sstevel@tonic-gate " using default temperatures\n", id); 193*7c478bd9Sstevel@tonic-gate } 194*7c478bd9Sstevel@tonic-gate } 195*7c478bd9Sstevel@tonic-gate return (status); 196*7c478bd9Sstevel@tonic-gate } 197*7c478bd9Sstevel@tonic-gate 198*7c478bd9Sstevel@tonic-gate #define MAX_TEMP_SENSORS 256 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate static int32_t 201*7c478bd9Sstevel@tonic-gate check_temp(psvc_opaque_t hdlp, char *id, int32_t silent) 202*7c478bd9Sstevel@tonic-gate { 203*7c478bd9Sstevel@tonic-gate int32_t lo_warn, hi_warn, lo_shut, hi_shut; 204*7c478bd9Sstevel@tonic-gate uint64_t features; 205*7c478bd9Sstevel@tonic-gate int32_t temp; 206*7c478bd9Sstevel@tonic-gate char previous_state[32]; 207*7c478bd9Sstevel@tonic-gate char led_state[32]; 208*7c478bd9Sstevel@tonic-gate char state[32]; 209*7c478bd9Sstevel@tonic-gate char fault[32]; 210*7c478bd9Sstevel@tonic-gate char label[32]; 211*7c478bd9Sstevel@tonic-gate boolean_t pr; 212*7c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 213*7c478bd9Sstevel@tonic-gate int8_t fail = 0; 214*7c478bd9Sstevel@tonic-gate static int8_t threshold_low_shut[MAX_TEMP_SENSORS] = {0}; 215*7c478bd9Sstevel@tonic-gate static int8_t threshold_high_shut[MAX_TEMP_SENSORS] = {0}; 216*7c478bd9Sstevel@tonic-gate static int8_t threshold_low_warn[MAX_TEMP_SENSORS] = {0}; 217*7c478bd9Sstevel@tonic-gate static int8_t threshold_high_warn[MAX_TEMP_SENSORS] = {0}; 218*7c478bd9Sstevel@tonic-gate int32_t instance; 219*7c478bd9Sstevel@tonic-gate 220*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_INSTANCE_ATTR, &instance); 221*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 222*7c478bd9Sstevel@tonic-gate return (status); 223*7c478bd9Sstevel@tonic-gate 224*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &pr); 225*7c478bd9Sstevel@tonic-gate if ((status != PSVC_SUCCESS) || (pr != PSVC_PRESENT)) { 226*7c478bd9Sstevel@tonic-gate return (status); 227*7c478bd9Sstevel@tonic-gate } 228*7c478bd9Sstevel@tonic-gate 229*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_STATE_ATTR, state); 230*7c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 231*7c478bd9Sstevel@tonic-gate return (status); 232*7c478bd9Sstevel@tonic-gate 233*7c478bd9Sstevel@tonic-gate if ((strcmp(state, PSVC_HOTPLUGGED) == 0)) { 234*7c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 235*7c478bd9Sstevel@tonic-gate } 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_FEATURES_ATTR, &features); 238*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 239*7c478bd9Sstevel@tonic-gate return (status); 240*7c478bd9Sstevel@tonic-gate 241*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_LO_WARN_ATTR, &lo_warn); 242*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 243*7c478bd9Sstevel@tonic-gate return (status); 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_LO_SHUT_ATTR, &lo_shut); 246*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 247*7c478bd9Sstevel@tonic-gate return (status); 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_HI_WARN_ATTR, &hi_warn); 250*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 251*7c478bd9Sstevel@tonic-gate return (status); 252*7c478bd9Sstevel@tonic-gate 253*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_HI_SHUT_ATTR, &hi_shut); 254*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 255*7c478bd9Sstevel@tonic-gate return (status); 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_SENSOR_VALUE_ATTR, &temp); 258*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 259*7c478bd9Sstevel@tonic-gate return (status); 260*7c478bd9Sstevel@tonic-gate } 261*7c478bd9Sstevel@tonic-gate 262*7c478bd9Sstevel@tonic-gate /* 263*7c478bd9Sstevel@tonic-gate * The following code is to check to see if the temp sensor is 264*7c478bd9Sstevel@tonic-gate * returning a faulty reading due to it either being bad or the 265*7c478bd9Sstevel@tonic-gate * CPU being powered off for some reason. Is so we will alert the user 266*7c478bd9Sstevel@tonic-gate * and just label the sensor bad but not the WHOLE CPU module. 267*7c478bd9Sstevel@tonic-gate */ 268*7c478bd9Sstevel@tonic-gate if ((temp == 127) && (strcmp(state, PSVC_ERROR) != 0)) { 269*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, PSVC_ERROR); 270*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 271*7c478bd9Sstevel@tonic-gate return (status); 272*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_FAULTID_ATTR, 273*7c478bd9Sstevel@tonic-gate PSVC_GEN_FAULT); 274*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 275*7c478bd9Sstevel@tonic-gate return (status); 276*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, TEMP_SENSOR_FAULT, id); 277*7c478bd9Sstevel@tonic-gate return (status); 278*7c478bd9Sstevel@tonic-gate } 279*7c478bd9Sstevel@tonic-gate 280*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_LABEL_ATTR, label); 281*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 282*7c478bd9Sstevel@tonic-gate return (status); 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate /* 285*7c478bd9Sstevel@tonic-gate * if any of the four temperature states (lo_shut, lo_warn, 286*7c478bd9Sstevel@tonic-gate * hi_shut, hi_warn) is detected we will not take an action 287*7c478bd9Sstevel@tonic-gate * until PSVC_THRESHOLD_COUNTER (i.e. 2) similar back-to-back readings 288*7c478bd9Sstevel@tonic-gate * take place. 289*7c478bd9Sstevel@tonic-gate */ 290*7c478bd9Sstevel@tonic-gate if ((features & PSVC_LOW_SHUT) && temp < lo_shut) { 291*7c478bd9Sstevel@tonic-gate /* 292*7c478bd9Sstevel@tonic-gate * once we are in one state, clear all the 293*7c478bd9Sstevel@tonic-gate * counters for the other three states since 294*7c478bd9Sstevel@tonic-gate * back-to-back readings of these other three 295*7c478bd9Sstevel@tonic-gate * states could not happen anymore. 296*7c478bd9Sstevel@tonic-gate */ 297*7c478bd9Sstevel@tonic-gate threshold_low_warn[instance] = 0; 298*7c478bd9Sstevel@tonic-gate threshold_high_shut[instance] = 0; 299*7c478bd9Sstevel@tonic-gate threshold_high_warn[instance] = 0; 300*7c478bd9Sstevel@tonic-gate threshold_low_shut[instance]++; 301*7c478bd9Sstevel@tonic-gate if (threshold_low_shut[instance] == PSVC_THRESHOLD_COUNTER) { 302*7c478bd9Sstevel@tonic-gate threshold_low_shut[instance] = 0; 303*7c478bd9Sstevel@tonic-gate fail = 1; 304*7c478bd9Sstevel@tonic-gate strcpy(state, PSVC_ERROR); 305*7c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_TEMP_LO_SHUT); 306*7c478bd9Sstevel@tonic-gate strcpy(led_state, PSVC_LED_ON); 307*7c478bd9Sstevel@tonic-gate if (silent == 0) 308*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, LOWTEMP_CRITICAL_MSG, 309*7c478bd9Sstevel@tonic-gate temp, label); 310*7c478bd9Sstevel@tonic-gate } else { /* Threshold for showing error not reached */ 311*7c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 312*7c478bd9Sstevel@tonic-gate } 313*7c478bd9Sstevel@tonic-gate } else if ((features & PSVC_LOW_WARN) && temp < lo_warn) { 314*7c478bd9Sstevel@tonic-gate threshold_low_shut[instance] = 0; 315*7c478bd9Sstevel@tonic-gate threshold_high_shut[instance] = 0; 316*7c478bd9Sstevel@tonic-gate threshold_high_warn[instance] = 0; 317*7c478bd9Sstevel@tonic-gate threshold_low_warn[instance]++; 318*7c478bd9Sstevel@tonic-gate if (threshold_low_warn[instance] == PSVC_THRESHOLD_COUNTER) { 319*7c478bd9Sstevel@tonic-gate threshold_low_warn[instance] = 0; 320*7c478bd9Sstevel@tonic-gate fail = 1; 321*7c478bd9Sstevel@tonic-gate strcpy(state, PSVC_ERROR); 322*7c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_TEMP_LO_WARN); 323*7c478bd9Sstevel@tonic-gate strcpy(led_state, PSVC_LED_ON); 324*7c478bd9Sstevel@tonic-gate if (silent == 0) 325*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, LOWTEMP_WARNING_MSG, 326*7c478bd9Sstevel@tonic-gate temp, label); 327*7c478bd9Sstevel@tonic-gate } else { /* Threshold for showing error not reached */ 328*7c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 329*7c478bd9Sstevel@tonic-gate } 330*7c478bd9Sstevel@tonic-gate } else if ((features & PSVC_HIGH_SHUT) && temp > hi_shut) { 331*7c478bd9Sstevel@tonic-gate threshold_low_warn[instance] = 0; 332*7c478bd9Sstevel@tonic-gate threshold_low_shut[instance] = 0; 333*7c478bd9Sstevel@tonic-gate threshold_high_warn[instance] = 0; 334*7c478bd9Sstevel@tonic-gate threshold_high_shut[instance]++; 335*7c478bd9Sstevel@tonic-gate if (threshold_high_shut[instance] == PSVC_THRESHOLD_COUNTER) { 336*7c478bd9Sstevel@tonic-gate threshold_high_shut[instance] = 0; 337*7c478bd9Sstevel@tonic-gate fail = 1; 338*7c478bd9Sstevel@tonic-gate strcpy(state, PSVC_ERROR); 339*7c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_TEMP_HI_SHUT); 340*7c478bd9Sstevel@tonic-gate strcpy(led_state, PSVC_LED_ON); 341*7c478bd9Sstevel@tonic-gate if (silent == 0) 342*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, HIGHTEMP_CRITICAL_MSG, 343*7c478bd9Sstevel@tonic-gate temp, label); 344*7c478bd9Sstevel@tonic-gate } else { /* Threshold for showing error not reached */ 345*7c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 346*7c478bd9Sstevel@tonic-gate } 347*7c478bd9Sstevel@tonic-gate } else if ((features & PSVC_HIGH_WARN) && temp > hi_warn) { 348*7c478bd9Sstevel@tonic-gate threshold_low_warn[instance] = 0; 349*7c478bd9Sstevel@tonic-gate threshold_low_shut[instance] = 0; 350*7c478bd9Sstevel@tonic-gate threshold_high_shut[instance] = 0; 351*7c478bd9Sstevel@tonic-gate threshold_high_warn[instance]++; 352*7c478bd9Sstevel@tonic-gate if (threshold_high_warn[instance] == PSVC_THRESHOLD_COUNTER) { 353*7c478bd9Sstevel@tonic-gate threshold_high_warn[instance] = 0; 354*7c478bd9Sstevel@tonic-gate fail = 1; 355*7c478bd9Sstevel@tonic-gate strcpy(state, PSVC_ERROR); 356*7c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_TEMP_HI_WARN); 357*7c478bd9Sstevel@tonic-gate strcpy(led_state, PSVC_LED_ON); 358*7c478bd9Sstevel@tonic-gate if (silent == 0) 359*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, HIGHTEMP_WARNING_MSG, 360*7c478bd9Sstevel@tonic-gate temp, label); 361*7c478bd9Sstevel@tonic-gate } else { /* Threshold for showing error not reached */ 362*7c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 363*7c478bd9Sstevel@tonic-gate } 364*7c478bd9Sstevel@tonic-gate } 365*7c478bd9Sstevel@tonic-gate 366*7c478bd9Sstevel@tonic-gate /* 367*7c478bd9Sstevel@tonic-gate * If we reached this point then that means that we are either 368*7c478bd9Sstevel@tonic-gate * okay, or we have showed error PSVC_THRESHOLD_COUNTER times. 369*7c478bd9Sstevel@tonic-gate */ 370*7c478bd9Sstevel@tonic-gate if (fail != 1) { 371*7c478bd9Sstevel@tonic-gate /* within limits */ 372*7c478bd9Sstevel@tonic-gate strcpy(state, PSVC_OK); 373*7c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_NO_FAULT); 374*7c478bd9Sstevel@tonic-gate strcpy(led_state, PSVC_LED_OFF); 375*7c478bd9Sstevel@tonic-gate } 376*7c478bd9Sstevel@tonic-gate 377*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, state); 378*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 379*7c478bd9Sstevel@tonic-gate return (status); 380*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_FAULTID_ATTR, fault); 381*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 382*7c478bd9Sstevel@tonic-gate return (status); 383*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PREV_STATE_ATTR, 384*7c478bd9Sstevel@tonic-gate previous_state); 385*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 386*7c478bd9Sstevel@tonic-gate return (status); 387*7c478bd9Sstevel@tonic-gate 388*7c478bd9Sstevel@tonic-gate if (strcmp(previous_state, state) != 0) { 389*7c478bd9Sstevel@tonic-gate char *led_id; 390*7c478bd9Sstevel@tonic-gate int32_t led_count; 391*7c478bd9Sstevel@tonic-gate int32_t i; 392*7c478bd9Sstevel@tonic-gate 393*7c478bd9Sstevel@tonic-gate /* change state of fault LEDs */ 394*7c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, &led_count, 395*7c478bd9Sstevel@tonic-gate PSVC_TS_OVERTEMP_LED); 396*7c478bd9Sstevel@tonic-gate for (i = 0; i < led_count; ++i) { 397*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, 398*7c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &led_id, 399*7c478bd9Sstevel@tonic-gate PSVC_TS_OVERTEMP_LED, i); 400*7c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 401*7c478bd9Sstevel@tonic-gate return (status); 402*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, led_id, 403*7c478bd9Sstevel@tonic-gate PSVC_LED_STATE_ATTR, led_state); 404*7c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 405*7c478bd9Sstevel@tonic-gate return (status); 406*7c478bd9Sstevel@tonic-gate } 407*7c478bd9Sstevel@tonic-gate } 408*7c478bd9Sstevel@tonic-gate 409*7c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 410*7c478bd9Sstevel@tonic-gate } 411*7c478bd9Sstevel@tonic-gate 412*7c478bd9Sstevel@tonic-gate int32_t 413*7c478bd9Sstevel@tonic-gate psvc_check_temperature_policy_0(psvc_opaque_t hdlp, char *id) 414*7c478bd9Sstevel@tonic-gate { 415*7c478bd9Sstevel@tonic-gate return (check_temp(hdlp, id, 0)); 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate int32_t 419*7c478bd9Sstevel@tonic-gate psvc_check_temperature_silent_policy_0(psvc_opaque_t hdlp, char *id) 420*7c478bd9Sstevel@tonic-gate { 421*7c478bd9Sstevel@tonic-gate return (check_temp(hdlp, id, 1)); 422*7c478bd9Sstevel@tonic-gate } 423*7c478bd9Sstevel@tonic-gate 424*7c478bd9Sstevel@tonic-gate int32_t 425*7c478bd9Sstevel@tonic-gate psvc_fan_enable_disable_policy_0(psvc_opaque_t hdlp, char *id) 426*7c478bd9Sstevel@tonic-gate { 427*7c478bd9Sstevel@tonic-gate char state[32], previous_state[32]; 428*7c478bd9Sstevel@tonic-gate char *backup_fan; 429*7c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 430*7c478bd9Sstevel@tonic-gate uint64_t features; 431*7c478bd9Sstevel@tonic-gate char label[32]; 432*7c478bd9Sstevel@tonic-gate boolean_t presence; 433*7c478bd9Sstevel@tonic-gate boolean_t enable; 434*7c478bd9Sstevel@tonic-gate 435*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_FEATURES_ATTR, &features); 436*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 437*7c478bd9Sstevel@tonic-gate return (status); 438*7c478bd9Sstevel@tonic-gate 439*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &presence); 440*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 441*7c478bd9Sstevel@tonic-gate return (status); 442*7c478bd9Sstevel@tonic-gate 443*7c478bd9Sstevel@tonic-gate if (presence == PSVC_ABSENT) { 444*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_LABEL_ATTR, label); 445*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 446*7c478bd9Sstevel@tonic-gate return (status); 447*7c478bd9Sstevel@tonic-gate 448*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ENABLE_ATTR, &enable); 449*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 450*7c478bd9Sstevel@tonic-gate return (status); 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate if (features & PSVC_DEV_PRIMARY) { 453*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 454*7c478bd9Sstevel@tonic-gate &backup_fan, PSVC_ALTERNATE, 0); 455*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 456*7c478bd9Sstevel@tonic-gate return (status); 457*7c478bd9Sstevel@tonic-gate 458*7c478bd9Sstevel@tonic-gate enable = PSVC_DISABLED; 459*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_ENABLE_ATTR, 460*7c478bd9Sstevel@tonic-gate &enable); 461*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 462*7c478bd9Sstevel@tonic-gate return (status); 463*7c478bd9Sstevel@tonic-gate 464*7c478bd9Sstevel@tonic-gate enable = PSVC_ENABLED; 465*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, backup_fan, 466*7c478bd9Sstevel@tonic-gate PSVC_ENABLE_ATTR, &enable); 467*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 468*7c478bd9Sstevel@tonic-gate return (status); 469*7c478bd9Sstevel@tonic-gate } else { 470*7c478bd9Sstevel@tonic-gate enable = PSVC_DISABLED; 471*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_ENABLE_ATTR, 472*7c478bd9Sstevel@tonic-gate &enable); 473*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 474*7c478bd9Sstevel@tonic-gate return (status); 475*7c478bd9Sstevel@tonic-gate } 476*7c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 477*7c478bd9Sstevel@tonic-gate } 478*7c478bd9Sstevel@tonic-gate 479*7c478bd9Sstevel@tonic-gate /* device was present */ 480*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_STATE_ATTR, state); 481*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 482*7c478bd9Sstevel@tonic-gate return (status); 483*7c478bd9Sstevel@tonic-gate 484*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PREV_STATE_ATTR, previous_state); 485*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 486*7c478bd9Sstevel@tonic-gate return (status); 487*7c478bd9Sstevel@tonic-gate 488*7c478bd9Sstevel@tonic-gate if (features & PSVC_DEV_PRIMARY) { 489*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 490*7c478bd9Sstevel@tonic-gate &backup_fan, PSVC_ALTERNATE, 0); 491*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 492*7c478bd9Sstevel@tonic-gate return (status); 493*7c478bd9Sstevel@tonic-gate 494*7c478bd9Sstevel@tonic-gate if (strcmp(state, PSVC_OK) == 0) { 495*7c478bd9Sstevel@tonic-gate enable = PSVC_ENABLED; 496*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_ENABLE_ATTR, 497*7c478bd9Sstevel@tonic-gate &enable); 498*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 499*7c478bd9Sstevel@tonic-gate return (status); 500*7c478bd9Sstevel@tonic-gate 501*7c478bd9Sstevel@tonic-gate enable = PSVC_DISABLED; 502*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, backup_fan, 503*7c478bd9Sstevel@tonic-gate PSVC_ENABLE_ATTR, &enable); 504*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 505*7c478bd9Sstevel@tonic-gate return (status); 506*7c478bd9Sstevel@tonic-gate } 507*7c478bd9Sstevel@tonic-gate if ((strcmp(state, PSVC_ERROR) == 0) && 508*7c478bd9Sstevel@tonic-gate (strcmp(previous_state, PSVC_ERROR) != 0)) { 509*7c478bd9Sstevel@tonic-gate enable = PSVC_DISABLED; 510*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_ENABLE_ATTR, 511*7c478bd9Sstevel@tonic-gate &enable); 512*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 513*7c478bd9Sstevel@tonic-gate return (status); 514*7c478bd9Sstevel@tonic-gate 515*7c478bd9Sstevel@tonic-gate enable = PSVC_ENABLED; 516*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, backup_fan, 517*7c478bd9Sstevel@tonic-gate PSVC_ENABLE_ATTR, &enable); 518*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 519*7c478bd9Sstevel@tonic-gate return (status); 520*7c478bd9Sstevel@tonic-gate } 521*7c478bd9Sstevel@tonic-gate } else { 522*7c478bd9Sstevel@tonic-gate if ((strcmp(state, PSVC_ERROR) == 0) && 523*7c478bd9Sstevel@tonic-gate (strcmp(previous_state, PSVC_ERROR) != 0)) { 524*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_LABEL_ATTR, 525*7c478bd9Sstevel@tonic-gate label); 526*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 527*7c478bd9Sstevel@tonic-gate return (status); 528*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, SECONDARY_FAN_FAIL_MSG, label); 529*7c478bd9Sstevel@tonic-gate } 530*7c478bd9Sstevel@tonic-gate } 531*7c478bd9Sstevel@tonic-gate return (status); 532*7c478bd9Sstevel@tonic-gate } 533*7c478bd9Sstevel@tonic-gate 534*7c478bd9Sstevel@tonic-gate /* 535*7c478bd9Sstevel@tonic-gate * psvc_switch_fan_onoff_policy_0 536*7c478bd9Sstevel@tonic-gate * Turn a fan on if it is enabled, turn it off if it is disabled. 537*7c478bd9Sstevel@tonic-gate */ 538*7c478bd9Sstevel@tonic-gate int32_t 539*7c478bd9Sstevel@tonic-gate psvc_switch_fan_onoff_policy_0(psvc_opaque_t hdlp, char *id) 540*7c478bd9Sstevel@tonic-gate { 541*7c478bd9Sstevel@tonic-gate boolean_t enable; 542*7c478bd9Sstevel@tonic-gate char *switchid; 543*7c478bd9Sstevel@tonic-gate char state[32]; 544*7c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 545*7c478bd9Sstevel@tonic-gate 546*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ENABLE_ATTR, &enable); 547*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 548*7c478bd9Sstevel@tonic-gate return (status); 549*7c478bd9Sstevel@tonic-gate 550*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, &switchid, 551*7c478bd9Sstevel@tonic-gate PSVC_FAN_ONOFF_SENSOR, 0); 552*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 553*7c478bd9Sstevel@tonic-gate return (status); 554*7c478bd9Sstevel@tonic-gate 555*7c478bd9Sstevel@tonic-gate if (enable == PSVC_DISABLED) { 556*7c478bd9Sstevel@tonic-gate strcpy(state, PSVC_SWITCH_OFF); 557*7c478bd9Sstevel@tonic-gate } else { 558*7c478bd9Sstevel@tonic-gate strcpy(state, PSVC_SWITCH_ON); 559*7c478bd9Sstevel@tonic-gate } 560*7c478bd9Sstevel@tonic-gate 561*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, switchid, PSVC_SWITCH_STATE_ATTR, state); 562*7c478bd9Sstevel@tonic-gate return (status); 563*7c478bd9Sstevel@tonic-gate } 564*7c478bd9Sstevel@tonic-gate 565*7c478bd9Sstevel@tonic-gate static int32_t 566*7c478bd9Sstevel@tonic-gate check_cpu_temp_fault(psvc_opaque_t hdlp, char *cpu, int32_t cpu_count) 567*7c478bd9Sstevel@tonic-gate { 568*7c478bd9Sstevel@tonic-gate char *sensorid; 569*7c478bd9Sstevel@tonic-gate int32_t sensor_count; 570*7c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 571*7c478bd9Sstevel@tonic-gate int32_t i; 572*7c478bd9Sstevel@tonic-gate uint64_t features; 573*7c478bd9Sstevel@tonic-gate char fault[32]; 574*7c478bd9Sstevel@tonic-gate 575*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, cpu, PSVC_FEATURES_ATTR, &features); 576*7c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 577*7c478bd9Sstevel@tonic-gate return (status); 578*7c478bd9Sstevel@tonic-gate 579*7c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, cpu, PSVC_ASSOC_MATCHES_ATTR, &sensor_count, 580*7c478bd9Sstevel@tonic-gate PSVC_DEV_TEMP_SENSOR); 581*7c478bd9Sstevel@tonic-gate for (i = 0; i < sensor_count; ++i) { 582*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, cpu, PSVC_ASSOC_ID_ATTR, 583*7c478bd9Sstevel@tonic-gate &sensorid, PSVC_DEV_TEMP_SENSOR, i); 584*7c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 585*7c478bd9Sstevel@tonic-gate return (status); 586*7c478bd9Sstevel@tonic-gate 587*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, sensorid, PSVC_FAULTID_ATTR, 588*7c478bd9Sstevel@tonic-gate fault); 589*7c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 590*7c478bd9Sstevel@tonic-gate return (status); 591*7c478bd9Sstevel@tonic-gate 592*7c478bd9Sstevel@tonic-gate if ((strcmp(fault, PSVC_TEMP_HI_SHUT) == 0) || 593*7c478bd9Sstevel@tonic-gate (strcmp(fault, PSVC_TEMP_LO_SHUT) == 0)) { 594*7c478bd9Sstevel@tonic-gate if (cpu_count == 1 || cpus_online == 1 || 595*7c478bd9Sstevel@tonic-gate !(features & PSVC_DEV_HOTPLUG)) { 596*7c478bd9Sstevel@tonic-gate system(shutdown_string); 597*7c478bd9Sstevel@tonic-gate } else { 598*7c478bd9Sstevel@tonic-gate /* FIX offline cpu */ 599*7c478bd9Sstevel@tonic-gate --cpus_online; 600*7c478bd9Sstevel@tonic-gate } 601*7c478bd9Sstevel@tonic-gate } 602*7c478bd9Sstevel@tonic-gate } 603*7c478bd9Sstevel@tonic-gate 604*7c478bd9Sstevel@tonic-gate return (status); 605*7c478bd9Sstevel@tonic-gate } 606*7c478bd9Sstevel@tonic-gate 607*7c478bd9Sstevel@tonic-gate int32_t 608*7c478bd9Sstevel@tonic-gate psvc_shutdown_policy_0(psvc_opaque_t hdlp, char *id) 609*7c478bd9Sstevel@tonic-gate { 610*7c478bd9Sstevel@tonic-gate int32_t cpu_count; 611*7c478bd9Sstevel@tonic-gate char *cpuid; 612*7c478bd9Sstevel@tonic-gate int32_t i; 613*7c478bd9Sstevel@tonic-gate boolean_t present; 614*7c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 615*7c478bd9Sstevel@tonic-gate 616*7c478bd9Sstevel@tonic-gate if (cpus_online == 0) { 617*7c478bd9Sstevel@tonic-gate /* obviously, zero isn't correct, count present cpu's */ 618*7c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, &cpu_count, 619*7c478bd9Sstevel@tonic-gate PSVC_CPU); 620*7c478bd9Sstevel@tonic-gate for (i = 0; i < cpu_count; ++i) { 621*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 622*7c478bd9Sstevel@tonic-gate &cpuid, PSVC_CPU, i); 623*7c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 624*7c478bd9Sstevel@tonic-gate return (status); 625*7c478bd9Sstevel@tonic-gate 626*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, cpuid, 627*7c478bd9Sstevel@tonic-gate PSVC_PRESENCE_ATTR, &present); 628*7c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE && present == PSVC_PRESENT) 629*7c478bd9Sstevel@tonic-gate return (status); 630*7c478bd9Sstevel@tonic-gate if (present == PSVC_PRESENT) 631*7c478bd9Sstevel@tonic-gate ++cpus_online; 632*7c478bd9Sstevel@tonic-gate } 633*7c478bd9Sstevel@tonic-gate } 634*7c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, &cpu_count, 635*7c478bd9Sstevel@tonic-gate PSVC_CPU); 636*7c478bd9Sstevel@tonic-gate for (i = 0; i < cpu_count; ++i) { 637*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, &cpuid, 638*7c478bd9Sstevel@tonic-gate PSVC_CPU, i); 639*7c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 640*7c478bd9Sstevel@tonic-gate return (status); 641*7c478bd9Sstevel@tonic-gate status = check_cpu_temp_fault(hdlp, cpuid, cpu_count); 642*7c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE && errno != ENODEV) 643*7c478bd9Sstevel@tonic-gate return (status); 644*7c478bd9Sstevel@tonic-gate } 645*7c478bd9Sstevel@tonic-gate 646*7c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 647*7c478bd9Sstevel@tonic-gate } 648*7c478bd9Sstevel@tonic-gate 649*7c478bd9Sstevel@tonic-gate /* 650*7c478bd9Sstevel@tonic-gate * psvc_keyswitch_position_policy_0 651*7c478bd9Sstevel@tonic-gate * Checks the state of the keyswitch sensors. 652*7c478bd9Sstevel@tonic-gate * If a keyswitch position sensor's state is on, the position 653*7c478bd9Sstevel@tonic-gate * of the key is written to syslog. If none of the sensors 654*7c478bd9Sstevel@tonic-gate * are on (keyswitch is not at one of the detents), a message is sent 655*7c478bd9Sstevel@tonic-gate * to syslog stating that the position is unknown. 656*7c478bd9Sstevel@tonic-gate */ 657*7c478bd9Sstevel@tonic-gate int32_t 658*7c478bd9Sstevel@tonic-gate psvc_keyswitch_position_policy_0(psvc_opaque_t hdlp, char *id) 659*7c478bd9Sstevel@tonic-gate { 660*7c478bd9Sstevel@tonic-gate char position[32]; 661*7c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 662*7c478bd9Sstevel@tonic-gate static int error_reported = 0; 663*7c478bd9Sstevel@tonic-gate static char local_previous_position[32]; 664*7c478bd9Sstevel@tonic-gate static int32_t first_time = 1; 665*7c478bd9Sstevel@tonic-gate int8_t retry; 666*7c478bd9Sstevel@tonic-gate 667*7c478bd9Sstevel@tonic-gate if (first_time) { 668*7c478bd9Sstevel@tonic-gate first_time = 0; 669*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_STATE_ATTR, 670*7c478bd9Sstevel@tonic-gate local_previous_position); 671*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 672*7c478bd9Sstevel@tonic-gate return (status); 673*7c478bd9Sstevel@tonic-gate } 674*7c478bd9Sstevel@tonic-gate 675*7c478bd9Sstevel@tonic-gate retry = 0; 676*7c478bd9Sstevel@tonic-gate do { 677*7c478bd9Sstevel@tonic-gate if (retry) 678*7c478bd9Sstevel@tonic-gate sleep(1); 679*7c478bd9Sstevel@tonic-gate 680*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_SWITCH_STATE_ATTR, 681*7c478bd9Sstevel@tonic-gate position); 682*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 683*7c478bd9Sstevel@tonic-gate return (status); 684*7c478bd9Sstevel@tonic-gate 685*7c478bd9Sstevel@tonic-gate if (strcmp(position, PSVC_ERROR) == 0) { 686*7c478bd9Sstevel@tonic-gate if ((errno == EINVAL) && (!(error_reported))) { 687*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 688*7c478bd9Sstevel@tonic-gate KEYSWITCH_POS_READ_FAILED_MSG); 689*7c478bd9Sstevel@tonic-gate error_reported = 1; 690*7c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 691*7c478bd9Sstevel@tonic-gate } 692*7c478bd9Sstevel@tonic-gate } 693*7c478bd9Sstevel@tonic-gate retry++; 694*7c478bd9Sstevel@tonic-gate } while ((retry < PSVC_NUM_OF_RETRIES) && 695*7c478bd9Sstevel@tonic-gate (strcmp(position, local_previous_position) != 0)); 696*7c478bd9Sstevel@tonic-gate 697*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, position); 698*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 699*7c478bd9Sstevel@tonic-gate return (status); 700*7c478bd9Sstevel@tonic-gate 701*7c478bd9Sstevel@tonic-gate if (strcmp(position, local_previous_position) != 0) { 702*7c478bd9Sstevel@tonic-gate error_reported = 0; 703*7c478bd9Sstevel@tonic-gate strcpy(local_previous_position, position); 704*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, KEYSWITCH_POS_CHANGED_MSG, position); 705*7c478bd9Sstevel@tonic-gate } 706*7c478bd9Sstevel@tonic-gate 707*7c478bd9Sstevel@tonic-gate return (status); 708*7c478bd9Sstevel@tonic-gate } 709*7c478bd9Sstevel@tonic-gate 710*7c478bd9Sstevel@tonic-gate int32_t 711*7c478bd9Sstevel@tonic-gate psvc_hotplug_notifier_policy_0(psvc_opaque_t hdlp, char *id) 712*7c478bd9Sstevel@tonic-gate { 713*7c478bd9Sstevel@tonic-gate boolean_t presence, previous_presence; 714*7c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 715*7c478bd9Sstevel@tonic-gate char label[32]; 716*7c478bd9Sstevel@tonic-gate int8_t retry; 717*7c478bd9Sstevel@tonic-gate 718*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PREV_PRESENCE_ATTR, 719*7c478bd9Sstevel@tonic-gate &previous_presence); 720*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 721*7c478bd9Sstevel@tonic-gate return (status); 722*7c478bd9Sstevel@tonic-gate retry = 0; 723*7c478bd9Sstevel@tonic-gate do { 724*7c478bd9Sstevel@tonic-gate if (retry) 725*7c478bd9Sstevel@tonic-gate sleep(1); 726*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &presence); 727*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 728*7c478bd9Sstevel@tonic-gate return (status); 729*7c478bd9Sstevel@tonic-gate retry++; 730*7c478bd9Sstevel@tonic-gate } while ((retry < PSVC_NUM_OF_RETRIES) && 731*7c478bd9Sstevel@tonic-gate (presence != previous_presence)); 732*7c478bd9Sstevel@tonic-gate 733*7c478bd9Sstevel@tonic-gate 734*7c478bd9Sstevel@tonic-gate if (presence != previous_presence) { 735*7c478bd9Sstevel@tonic-gate char parent_path[256]; 736*7c478bd9Sstevel@tonic-gate picl_nodehdl_t child_node; 737*7c478bd9Sstevel@tonic-gate 738*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_LABEL_ATTR, label); 739*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 740*7c478bd9Sstevel@tonic-gate return (status); 741*7c478bd9Sstevel@tonic-gate 742*7c478bd9Sstevel@tonic-gate /* return parent path and node for an object */ 743*7c478bd9Sstevel@tonic-gate psvcplugin_lookup(id, parent_path, &child_node); 744*7c478bd9Sstevel@tonic-gate 745*7c478bd9Sstevel@tonic-gate if (presence == PSVC_PRESENT) { 746*7c478bd9Sstevel@tonic-gate char state[32], fault[32]; 747*7c478bd9Sstevel@tonic-gate picl_nodehdl_t parent_node; 748*7c478bd9Sstevel@tonic-gate 749*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_INSERTED_MSG, label); 750*7c478bd9Sstevel@tonic-gate strcpy(state, PSVC_OK); 751*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, 752*7c478bd9Sstevel@tonic-gate state); 753*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 754*7c478bd9Sstevel@tonic-gate return (status); 755*7c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_NO_FAULT); 756*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_FAULTID_ATTR, 757*7c478bd9Sstevel@tonic-gate fault); 758*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 759*7c478bd9Sstevel@tonic-gate return (status); 760*7c478bd9Sstevel@tonic-gate } 761*7c478bd9Sstevel@tonic-gate 762*7c478bd9Sstevel@tonic-gate status = ptree_get_node_by_path(parent_path, 763*7c478bd9Sstevel@tonic-gate &parent_node); 764*7c478bd9Sstevel@tonic-gate if (status != 0) 765*7c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 766*7c478bd9Sstevel@tonic-gate status = ptree_add_node(parent_node, child_node); 767*7c478bd9Sstevel@tonic-gate if (status != 0) 768*7c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 769*7c478bd9Sstevel@tonic-gate } else { 770*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_REMOVED_MSG, label); 771*7c478bd9Sstevel@tonic-gate 772*7c478bd9Sstevel@tonic-gate ptree_delete_node(child_node); 773*7c478bd9Sstevel@tonic-gate 774*7c478bd9Sstevel@tonic-gate } 775*7c478bd9Sstevel@tonic-gate } 776*7c478bd9Sstevel@tonic-gate 777*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_PREV_PRESENCE_ATTR, &presence); 778*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 779*7c478bd9Sstevel@tonic-gate return (status); 780*7c478bd9Sstevel@tonic-gate 781*7c478bd9Sstevel@tonic-gate return (status); 782*7c478bd9Sstevel@tonic-gate } 783*7c478bd9Sstevel@tonic-gate 784*7c478bd9Sstevel@tonic-gate int32_t 785*7c478bd9Sstevel@tonic-gate psvc_fan_hotplug_policy_0(psvc_opaque_t hdlp, char *id) 786*7c478bd9Sstevel@tonic-gate { 787*7c478bd9Sstevel@tonic-gate boolean_t presence, previous_presence; 788*7c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 789*7c478bd9Sstevel@tonic-gate char label[32]; 790*7c478bd9Sstevel@tonic-gate int8_t retry; 791*7c478bd9Sstevel@tonic-gate 792*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PREV_PRESENCE_ATTR, 793*7c478bd9Sstevel@tonic-gate &previous_presence); 794*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 795*7c478bd9Sstevel@tonic-gate return (status); 796*7c478bd9Sstevel@tonic-gate 797*7c478bd9Sstevel@tonic-gate retry = 0; 798*7c478bd9Sstevel@tonic-gate do { 799*7c478bd9Sstevel@tonic-gate if (retry) 800*7c478bd9Sstevel@tonic-gate sleep(1); 801*7c478bd9Sstevel@tonic-gate 802*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &presence); 803*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 804*7c478bd9Sstevel@tonic-gate return (status); 805*7c478bd9Sstevel@tonic-gate retry++; 806*7c478bd9Sstevel@tonic-gate } while ((retry < PSVC_NUM_OF_RETRIES) && 807*7c478bd9Sstevel@tonic-gate (presence != previous_presence)); 808*7c478bd9Sstevel@tonic-gate 809*7c478bd9Sstevel@tonic-gate 810*7c478bd9Sstevel@tonic-gate if (presence != previous_presence) { 811*7c478bd9Sstevel@tonic-gate char parent_path[256]; 812*7c478bd9Sstevel@tonic-gate picl_nodehdl_t child_node; 813*7c478bd9Sstevel@tonic-gate 814*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_LABEL_ATTR, label); 815*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 816*7c478bd9Sstevel@tonic-gate return (status); 817*7c478bd9Sstevel@tonic-gate 818*7c478bd9Sstevel@tonic-gate /* return parent path and node for an object */ 819*7c478bd9Sstevel@tonic-gate psvcplugin_lookup(id, parent_path, &child_node); 820*7c478bd9Sstevel@tonic-gate 821*7c478bd9Sstevel@tonic-gate if (presence == PSVC_PRESENT) { 822*7c478bd9Sstevel@tonic-gate char state[32], fault[32]; 823*7c478bd9Sstevel@tonic-gate char *slot_id; 824*7c478bd9Sstevel@tonic-gate char *led_id; 825*7c478bd9Sstevel@tonic-gate int32_t i, led_count; 826*7c478bd9Sstevel@tonic-gate char led_state[32]; 827*7c478bd9Sstevel@tonic-gate picl_nodehdl_t parent_node; 828*7c478bd9Sstevel@tonic-gate 829*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_INSERTED_MSG, label); 830*7c478bd9Sstevel@tonic-gate 831*7c478bd9Sstevel@tonic-gate strcpy(state, PSVC_OK); 832*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, 833*7c478bd9Sstevel@tonic-gate state); 834*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 835*7c478bd9Sstevel@tonic-gate return (status); 836*7c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_NO_FAULT); 837*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_FAULTID_ATTR, 838*7c478bd9Sstevel@tonic-gate fault); 839*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 840*7c478bd9Sstevel@tonic-gate return (status); 841*7c478bd9Sstevel@tonic-gate 842*7c478bd9Sstevel@tonic-gate /* turn off fault LEDs */ 843*7c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, 844*7c478bd9Sstevel@tonic-gate &led_count, PSVC_DEV_FAULT_LED); 845*7c478bd9Sstevel@tonic-gate strcpy(led_state, PSVC_LED_OFF); 846*7c478bd9Sstevel@tonic-gate for (i = 0; i < led_count; ++i) { 847*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, 848*7c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &led_id, 849*7c478bd9Sstevel@tonic-gate PSVC_DEV_FAULT_LED, i); 850*7c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 851*7c478bd9Sstevel@tonic-gate return (status); 852*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, led_id, 853*7c478bd9Sstevel@tonic-gate PSVC_LED_STATE_ATTR, led_state); 854*7c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 855*7c478bd9Sstevel@tonic-gate return (status); 856*7c478bd9Sstevel@tonic-gate } 857*7c478bd9Sstevel@tonic-gate 858*7c478bd9Sstevel@tonic-gate /* turn off OK to remove LEDs */ 859*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 860*7c478bd9Sstevel@tonic-gate &slot_id, PSVC_PARENT, 0); 861*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 862*7c478bd9Sstevel@tonic-gate return (status); 863*7c478bd9Sstevel@tonic-gate 864*7c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, slot_id, PSVC_ASSOC_MATCHES_ATTR, 865*7c478bd9Sstevel@tonic-gate &led_count, PSVC_SLOT_REMOVE_LED); 866*7c478bd9Sstevel@tonic-gate strcpy(led_state, PSVC_LED_OFF); 867*7c478bd9Sstevel@tonic-gate for (i = 0; i < led_count; ++i) { 868*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, slot_id, 869*7c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &led_id, 870*7c478bd9Sstevel@tonic-gate PSVC_SLOT_REMOVE_LED, i); 871*7c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 872*7c478bd9Sstevel@tonic-gate return (status); 873*7c478bd9Sstevel@tonic-gate 874*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, led_id, 875*7c478bd9Sstevel@tonic-gate PSVC_LED_STATE_ATTR, led_state); 876*7c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 877*7c478bd9Sstevel@tonic-gate return (status); 878*7c478bd9Sstevel@tonic-gate } 879*7c478bd9Sstevel@tonic-gate 880*7c478bd9Sstevel@tonic-gate ptree_get_node_by_path(parent_path, &parent_node); 881*7c478bd9Sstevel@tonic-gate ptree_add_node(parent_node, child_node); 882*7c478bd9Sstevel@tonic-gate } else { 883*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_REMOVED_MSG, label); 884*7c478bd9Sstevel@tonic-gate ptree_delete_node(child_node); 885*7c478bd9Sstevel@tonic-gate } 886*7c478bd9Sstevel@tonic-gate } 887*7c478bd9Sstevel@tonic-gate 888*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_PREV_PRESENCE_ATTR, &presence); 889*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 890*7c478bd9Sstevel@tonic-gate return (status); 891*7c478bd9Sstevel@tonic-gate 892*7c478bd9Sstevel@tonic-gate return (status); 893*7c478bd9Sstevel@tonic-gate } 894*7c478bd9Sstevel@tonic-gate 895*7c478bd9Sstevel@tonic-gate int32_t 896*7c478bd9Sstevel@tonic-gate psvc_init_led_policy_0(psvc_opaque_t hdlp, char *id) 897*7c478bd9Sstevel@tonic-gate { 898*7c478bd9Sstevel@tonic-gate int32_t status; 899*7c478bd9Sstevel@tonic-gate 900*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_LED_STATE_ATTR, PSVC_LED_OFF); 901*7c478bd9Sstevel@tonic-gate return (status); 902*7c478bd9Sstevel@tonic-gate } 903*7c478bd9Sstevel@tonic-gate 904*7c478bd9Sstevel@tonic-gate int32_t 905*7c478bd9Sstevel@tonic-gate psvc_init_state_policy_0(psvc_opaque_t hdlp, char *id) 906*7c478bd9Sstevel@tonic-gate { 907*7c478bd9Sstevel@tonic-gate int32_t status; 908*7c478bd9Sstevel@tonic-gate 909*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, PSVC_OK); 910*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_FAULTID_ATTR, PSVC_NO_FAULT); 911*7c478bd9Sstevel@tonic-gate return (status); 912*7c478bd9Sstevel@tonic-gate } 913*7c478bd9Sstevel@tonic-gate 914*7c478bd9Sstevel@tonic-gate int32_t 915*7c478bd9Sstevel@tonic-gate psvc_ps_overcurrent_check_policy_0(psvc_opaque_t hdlp, char *power_supply_id) 916*7c478bd9Sstevel@tonic-gate { 917*7c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 918*7c478bd9Sstevel@tonic-gate boolean_t present; 919*7c478bd9Sstevel@tonic-gate char *sensor_id; 920*7c478bd9Sstevel@tonic-gate int32_t sensor_count; 921*7c478bd9Sstevel@tonic-gate int32_t i; 922*7c478bd9Sstevel@tonic-gate int32_t amps, hi_warn; 923*7c478bd9Sstevel@tonic-gate 924*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, power_supply_id, PSVC_PRESENCE_ATTR, 925*7c478bd9Sstevel@tonic-gate &present); 926*7c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) { 927*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, GET_PRESENCE_FAILED_MSG, power_supply_id, 928*7c478bd9Sstevel@tonic-gate errno); 929*7c478bd9Sstevel@tonic-gate return (status); 930*7c478bd9Sstevel@tonic-gate } 931*7c478bd9Sstevel@tonic-gate 932*7c478bd9Sstevel@tonic-gate if (present == PSVC_ABSENT) { 933*7c478bd9Sstevel@tonic-gate errno = ENODEV; 934*7c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 935*7c478bd9Sstevel@tonic-gate } 936*7c478bd9Sstevel@tonic-gate 937*7c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, power_supply_id, PSVC_ASSOC_MATCHES_ATTR, 938*7c478bd9Sstevel@tonic-gate &sensor_count, PSVC_PS_I_SENSOR); 939*7c478bd9Sstevel@tonic-gate for (i = 0; i < sensor_count; ++i) { 940*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, power_supply_id, 941*7c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &sensor_id, PSVC_PS_I_SENSOR, i); 942*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 943*7c478bd9Sstevel@tonic-gate return (status); 944*7c478bd9Sstevel@tonic-gate 945*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, sensor_id, PSVC_HI_WARN_ATTR, 946*7c478bd9Sstevel@tonic-gate &hi_warn); 947*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 948*7c478bd9Sstevel@tonic-gate return (status); 949*7c478bd9Sstevel@tonic-gate 950*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, sensor_id, 951*7c478bd9Sstevel@tonic-gate PSVC_SENSOR_VALUE_ATTR, &s); 952*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 953*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, GET_SENSOR_FAILED_MSG, sensor_id, 954*7c478bd9Sstevel@tonic-gate errno); 955*7c478bd9Sstevel@tonic-gate return (status); 956*7c478bd9Sstevel@tonic-gate } 957*7c478bd9Sstevel@tonic-gate 958*7c478bd9Sstevel@tonic-gate if (amps >= hi_warn) { 959*7c478bd9Sstevel@tonic-gate char label[32]; 960*7c478bd9Sstevel@tonic-gate 961*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, power_supply_id, 962*7c478bd9Sstevel@tonic-gate PSVC_LABEL_ATTR, &label); 963*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 964*7c478bd9Sstevel@tonic-gate return (status); 965*7c478bd9Sstevel@tonic-gate 966*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, PS_OVER_CURRENT_MSG, label); 967*7c478bd9Sstevel@tonic-gate } 968*7c478bd9Sstevel@tonic-gate } 969*7c478bd9Sstevel@tonic-gate 970*7c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 971*7c478bd9Sstevel@tonic-gate 972*7c478bd9Sstevel@tonic-gate } 973*7c478bd9Sstevel@tonic-gate 974*7c478bd9Sstevel@tonic-gate int32_t 975*7c478bd9Sstevel@tonic-gate psvc_device_fail_notifier_policy_0(psvc_opaque_t hdlp, char *id) 976*7c478bd9Sstevel@tonic-gate { 977*7c478bd9Sstevel@tonic-gate int32_t led_count, sensor_count; 978*7c478bd9Sstevel@tonic-gate char *led_id, *sensor_id; 979*7c478bd9Sstevel@tonic-gate int i; 980*7c478bd9Sstevel@tonic-gate char state[32], fault[32], previous_state[32]; 981*7c478bd9Sstevel@tonic-gate char led_state[32]; 982*7c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 983*7c478bd9Sstevel@tonic-gate boolean_t present; 984*7c478bd9Sstevel@tonic-gate 985*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &present); 986*7c478bd9Sstevel@tonic-gate if (status == PSVC_FAILURE) 987*7c478bd9Sstevel@tonic-gate return (status); 988*7c478bd9Sstevel@tonic-gate 989*7c478bd9Sstevel@tonic-gate if (present == PSVC_ABSENT) { 990*7c478bd9Sstevel@tonic-gate errno = ENODEV; 991*7c478bd9Sstevel@tonic-gate return (PSVC_FAILURE); 992*7c478bd9Sstevel@tonic-gate } 993*7c478bd9Sstevel@tonic-gate 994*7c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, &sensor_count, 995*7c478bd9Sstevel@tonic-gate PSVC_DEV_FAULT_SENSOR); 996*7c478bd9Sstevel@tonic-gate for (i = 0; i < sensor_count; ++i) { 997*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_ASSOC_ID_ATTR, 998*7c478bd9Sstevel@tonic-gate &sensor_id, PSVC_DEV_FAULT_SENSOR, i); 999*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 1000*7c478bd9Sstevel@tonic-gate return (status); 1001*7c478bd9Sstevel@tonic-gate 1002*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, sensor_id, 1003*7c478bd9Sstevel@tonic-gate PSVC_SWITCH_STATE_ATTR, state); 1004*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 1005*7c478bd9Sstevel@tonic-gate return (status); 1006*7c478bd9Sstevel@tonic-gate 1007*7c478bd9Sstevel@tonic-gate if (strcmp(state, PSVC_SWITCH_ON) == 0) { 1008*7c478bd9Sstevel@tonic-gate strcpy(state, PSVC_ERROR); 1009*7c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_GEN_FAULT); 1010*7c478bd9Sstevel@tonic-gate } else { 1011*7c478bd9Sstevel@tonic-gate strcpy(state, PSVC_OK); 1012*7c478bd9Sstevel@tonic-gate strcpy(fault, PSVC_NO_FAULT); 1013*7c478bd9Sstevel@tonic-gate } 1014*7c478bd9Sstevel@tonic-gate 1015*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_STATE_ATTR, state); 1016*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 1017*7c478bd9Sstevel@tonic-gate return (status); 1018*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, id, PSVC_FAULTID_ATTR, fault); 1019*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 1020*7c478bd9Sstevel@tonic-gate return (status); 1021*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PREV_STATE_ATTR, 1022*7c478bd9Sstevel@tonic-gate previous_state); 1023*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 1024*7c478bd9Sstevel@tonic-gate return (status); 1025*7c478bd9Sstevel@tonic-gate 1026*7c478bd9Sstevel@tonic-gate if (strcmp(state, previous_state) != 0) { 1027*7c478bd9Sstevel@tonic-gate char sensor_label[32]; 1028*7c478bd9Sstevel@tonic-gate char dev_label[32]; 1029*7c478bd9Sstevel@tonic-gate int32_t j; 1030*7c478bd9Sstevel@tonic-gate 1031*7c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, id, PSVC_LABEL_ATTR, dev_label); 1032*7c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, sensor_id, PSVC_LABEL_ATTR, 1033*7c478bd9Sstevel@tonic-gate sensor_label); 1034*7c478bd9Sstevel@tonic-gate 1035*7c478bd9Sstevel@tonic-gate if (strcmp(state, PSVC_ERROR) == 0) { 1036*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_FAILURE_MSG, dev_label, 1037*7c478bd9Sstevel@tonic-gate sensor_label); 1038*7c478bd9Sstevel@tonic-gate strcpy(led_state, PSVC_LED_ON); 1039*7c478bd9Sstevel@tonic-gate } else { 1040*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, DEVICE_OK_MSG, dev_label); 1041*7c478bd9Sstevel@tonic-gate strcpy(led_state, PSVC_LED_OFF); 1042*7c478bd9Sstevel@tonic-gate } 1043*7c478bd9Sstevel@tonic-gate 1044*7c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, id, PSVC_ASSOC_MATCHES_ATTR, 1045*7c478bd9Sstevel@tonic-gate &led_count, PSVC_DEV_FAULT_LED); 1046*7c478bd9Sstevel@tonic-gate for (j = 0; j < led_count; j++) { 1047*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, 1048*7c478bd9Sstevel@tonic-gate PSVC_ASSOC_ID_ATTR, &led_id, 1049*7c478bd9Sstevel@tonic-gate PSVC_DEV_FAULT_LED, j); 1050*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 1051*7c478bd9Sstevel@tonic-gate return (status); 1052*7c478bd9Sstevel@tonic-gate status = psvc_set_attr(hdlp, led_id, 1053*7c478bd9Sstevel@tonic-gate PSVC_LED_STATE_ATTR, led_state); 1054*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) { 1055*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, SET_LED_FAILED_MSG, 1056*7c478bd9Sstevel@tonic-gate led_id, errno); 1057*7c478bd9Sstevel@tonic-gate return (status); 1058*7c478bd9Sstevel@tonic-gate } 1059*7c478bd9Sstevel@tonic-gate } 1060*7c478bd9Sstevel@tonic-gate } 1061*7c478bd9Sstevel@tonic-gate } 1062*7c478bd9Sstevel@tonic-gate 1063*7c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 1064*7c478bd9Sstevel@tonic-gate } 1065*7c478bd9Sstevel@tonic-gate 1066*7c478bd9Sstevel@tonic-gate static float 1067*7c478bd9Sstevel@tonic-gate get_filtered_error(float *last_errors, int current_error) 1068*7c478bd9Sstevel@tonic-gate { 1069*7c478bd9Sstevel@tonic-gate float error; 1070*7c478bd9Sstevel@tonic-gate float adder; 1071*7c478bd9Sstevel@tonic-gate int i = 0; 1072*7c478bd9Sstevel@tonic-gate 1073*7c478bd9Sstevel@tonic-gate adder = last_errors[0]; 1074*7c478bd9Sstevel@tonic-gate for (i = 1; i < PSVC_MAXERRORS; i++) { 1075*7c478bd9Sstevel@tonic-gate adder = adder + last_errors[i]; 1076*7c478bd9Sstevel@tonic-gate } 1077*7c478bd9Sstevel@tonic-gate adder = adder + current_error; 1078*7c478bd9Sstevel@tonic-gate error = adder/(PSVC_MAXERRORS+1); 1079*7c478bd9Sstevel@tonic-gate 1080*7c478bd9Sstevel@tonic-gate return (error); 1081*7c478bd9Sstevel@tonic-gate } 1082*7c478bd9Sstevel@tonic-gate 1083*7c478bd9Sstevel@tonic-gate static int32_t 1084*7c478bd9Sstevel@tonic-gate change_cpu_fans(psvc_opaque_t hdlp, char *fan_id, int32_t fan_speed) 1085*7c478bd9Sstevel@tonic-gate { 1086*7c478bd9Sstevel@tonic-gate int err = PSVC_SUCCESS; 1087*7c478bd9Sstevel@tonic-gate int i; 1088*7c478bd9Sstevel@tonic-gate int32_t control_count; 1089*7c478bd9Sstevel@tonic-gate char *control_id; 1090*7c478bd9Sstevel@tonic-gate int32_t old_fan_speed; 1091*7c478bd9Sstevel@tonic-gate 1092*7c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, fan_id, PSVC_ASSOC_MATCHES_ATTR, &control_count, 1093*7c478bd9Sstevel@tonic-gate PSVC_FAN_DRIVE_CONTROL); 1094*7c478bd9Sstevel@tonic-gate if (control_count == 0) 1095*7c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 1096*7c478bd9Sstevel@tonic-gate 1097*7c478bd9Sstevel@tonic-gate err = psvc_get_attr(hdlp, fan_id, PSVC_ASSOC_ID_ATTR, &control_id, 1098*7c478bd9Sstevel@tonic-gate PSVC_FAN_DRIVE_CONTROL, 0); 1099*7c478bd9Sstevel@tonic-gate if (err != PSVC_SUCCESS) 1100*7c478bd9Sstevel@tonic-gate return (err); 1101*7c478bd9Sstevel@tonic-gate 1102*7c478bd9Sstevel@tonic-gate /* 1103*7c478bd9Sstevel@tonic-gate * this call will return PSVC_FAILURE on the first pass, 1104*7c478bd9Sstevel@tonic-gate * because no value has been set. 1105*7c478bd9Sstevel@tonic-gate */ 1106*7c478bd9Sstevel@tonic-gate err = psvc_get_attr(hdlp, control_id, PSVC_CONTROL_VALUE_ATTR, 1107*7c478bd9Sstevel@tonic-gate &old_fan_speed); 1108*7c478bd9Sstevel@tonic-gate if (err == PSVC_SUCCESS && old_fan_speed == fan_speed) 1109*7c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 1110*7c478bd9Sstevel@tonic-gate 1111*7c478bd9Sstevel@tonic-gate for (i = 0; i < control_count; i++) { 1112*7c478bd9Sstevel@tonic-gate err = psvc_get_attr(hdlp, fan_id, PSVC_ASSOC_ID_ATTR, 1113*7c478bd9Sstevel@tonic-gate &control_id, PSVC_FAN_DRIVE_CONTROL, i); 1114*7c478bd9Sstevel@tonic-gate if (err != PSVC_SUCCESS) 1115*7c478bd9Sstevel@tonic-gate return (err); 1116*7c478bd9Sstevel@tonic-gate 1117*7c478bd9Sstevel@tonic-gate err = psvc_set_attr(hdlp, control_id, PSVC_CONTROL_VALUE_ATTR, 1118*7c478bd9Sstevel@tonic-gate &fan_speed); 1119*7c478bd9Sstevel@tonic-gate if (err == PSVC_FAILURE) { 1120*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, SET_FANSPEED_FAILED_MSG, control_id, 1121*7c478bd9Sstevel@tonic-gate errno); 1122*7c478bd9Sstevel@tonic-gate return (err); 1123*7c478bd9Sstevel@tonic-gate } 1124*7c478bd9Sstevel@tonic-gate } 1125*7c478bd9Sstevel@tonic-gate return (err); 1126*7c478bd9Sstevel@tonic-gate } 1127*7c478bd9Sstevel@tonic-gate 1128*7c478bd9Sstevel@tonic-gate static int32_t 1129*7c478bd9Sstevel@tonic-gate device_temp_check(psvc_opaque_t hdlp, char *fan_id, int32_t *hot_device) 1130*7c478bd9Sstevel@tonic-gate { 1131*7c478bd9Sstevel@tonic-gate int i; 1132*7c478bd9Sstevel@tonic-gate int32_t err = PSVC_SUCCESS; 1133*7c478bd9Sstevel@tonic-gate char *sensor_id; 1134*7c478bd9Sstevel@tonic-gate int32_t sensor_count; 1135*7c478bd9Sstevel@tonic-gate int32_t temp; 1136*7c478bd9Sstevel@tonic-gate 1137*7c478bd9Sstevel@tonic-gate *hot_device = 0; 1138*7c478bd9Sstevel@tonic-gate 1139*7c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, fan_id, PSVC_ASSOC_MATCHES_ATTR, &sensor_count, 1140*7c478bd9Sstevel@tonic-gate PSVC_DEV_TEMP_SENSOR); 1141*7c478bd9Sstevel@tonic-gate for (i = 0; i < sensor_count; i++) { 1142*7c478bd9Sstevel@tonic-gate err = psvc_get_attr(hdlp, fan_id, PSVC_ASSOC_ID_ATTR, 1143*7c478bd9Sstevel@tonic-gate &sensor_id, PSVC_DEV_TEMP_SENSOR, i); 1144*7c478bd9Sstevel@tonic-gate if (err == PSVC_FAILURE) 1145*7c478bd9Sstevel@tonic-gate return (err); 1146*7c478bd9Sstevel@tonic-gate err = psvc_get_attr(hdlp, sensor_id, PSVC_SENSOR_VALUE_ATTR, 1147*7c478bd9Sstevel@tonic-gate &temp); 1148*7c478bd9Sstevel@tonic-gate if (err == PSVC_FAILURE) { 1149*7c478bd9Sstevel@tonic-gate if (errno == ENODEV) { 1150*7c478bd9Sstevel@tonic-gate temp = 0; 1151*7c478bd9Sstevel@tonic-gate } else { 1152*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, GET_SENSOR_FAILED_MSG, errno, 1153*7c478bd9Sstevel@tonic-gate sensor_id); 1154*7c478bd9Sstevel@tonic-gate return (err); 1155*7c478bd9Sstevel@tonic-gate } 1156*7c478bd9Sstevel@tonic-gate } 1157*7c478bd9Sstevel@tonic-gate 1158*7c478bd9Sstevel@tonic-gate if (*hot_device < temp) 1159*7c478bd9Sstevel@tonic-gate *hot_device = temp; 1160*7c478bd9Sstevel@tonic-gate } 1161*7c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 1162*7c478bd9Sstevel@tonic-gate } 1163*7c478bd9Sstevel@tonic-gate 1164*7c478bd9Sstevel@tonic-gate int32_t 1165*7c478bd9Sstevel@tonic-gate psvc_fan_control_policy_0(psvc_opaque_t hdlp, char *fan_id) 1166*7c478bd9Sstevel@tonic-gate { 1167*7c478bd9Sstevel@tonic-gate boolean_t is_enabled; 1168*7c478bd9Sstevel@tonic-gate int32_t err = PSVC_SUCCESS; 1169*7c478bd9Sstevel@tonic-gate int16_t setpoint, hysteresis, loopgain, loopbias; 1170*7c478bd9Sstevel@tonic-gate int current_error; /* Holds current error */ 1171*7c478bd9Sstevel@tonic-gate /* Signal before signaling */ 1172*7c478bd9Sstevel@tonic-gate float filtered_error; /* Holds the filtered error signal */ 1173*7c478bd9Sstevel@tonic-gate int ampout; /* output of loop amplifier */ 1174*7c478bd9Sstevel@tonic-gate int hot_device; 1175*7c478bd9Sstevel@tonic-gate 1176*7c478bd9Sstevel@tonic-gate int16_t error_number; 1177*7c478bd9Sstevel@tonic-gate float last_errors[PSVC_MAXERRORS]; /* Holds the filtered error */ 1178*7c478bd9Sstevel@tonic-gate /* from the last n iterations */ 1179*7c478bd9Sstevel@tonic-gate 1180*7c478bd9Sstevel@tonic-gate psvc_get_attr(hdlp, fan_id, PSVC_ENABLE_ATTR, &is_enabled); 1181*7c478bd9Sstevel@tonic-gate if (is_enabled == PSVC_DISABLED) 1182*7c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 1183*7c478bd9Sstevel@tonic-gate 1184*7c478bd9Sstevel@tonic-gate err = psvc_get_attr(hdlp, fan_id, PSVC_SETPOINT_ATTR, &setpoint); 1185*7c478bd9Sstevel@tonic-gate if (err != PSVC_SUCCESS) 1186*7c478bd9Sstevel@tonic-gate return (err); 1187*7c478bd9Sstevel@tonic-gate 1188*7c478bd9Sstevel@tonic-gate err = psvc_get_attr(hdlp, fan_id, PSVC_HYSTERESIS_ATTR, 1189*7c478bd9Sstevel@tonic-gate &hysteresis); 1190*7c478bd9Sstevel@tonic-gate if (err != PSVC_SUCCESS) 1191*7c478bd9Sstevel@tonic-gate return (err); 1192*7c478bd9Sstevel@tonic-gate 1193*7c478bd9Sstevel@tonic-gate err = psvc_get_attr(hdlp, fan_id, PSVC_LOOPGAIN_ATTR, &loopgain); 1194*7c478bd9Sstevel@tonic-gate if (err != PSVC_SUCCESS) 1195*7c478bd9Sstevel@tonic-gate return (err); 1196*7c478bd9Sstevel@tonic-gate 1197*7c478bd9Sstevel@tonic-gate err = psvc_get_attr(hdlp, fan_id, PSVC_LOOPBIAS_ATTR, &loopbias); 1198*7c478bd9Sstevel@tonic-gate if (err != PSVC_SUCCESS) 1199*7c478bd9Sstevel@tonic-gate return (err); 1200*7c478bd9Sstevel@tonic-gate 1201*7c478bd9Sstevel@tonic-gate err = psvc_get_attr(hdlp, fan_id, PSVC_TEMP_DIFFERENTIAL_ATTR, 1202*7c478bd9Sstevel@tonic-gate last_errors); 1203*7c478bd9Sstevel@tonic-gate if (err != PSVC_SUCCESS) 1204*7c478bd9Sstevel@tonic-gate return (err); 1205*7c478bd9Sstevel@tonic-gate 1206*7c478bd9Sstevel@tonic-gate err = psvc_get_attr(hdlp, fan_id, PSVC_TEMP_DIFFERENTIAL_INDEX_ATTR, 1207*7c478bd9Sstevel@tonic-gate &error_number); 1208*7c478bd9Sstevel@tonic-gate if (err != PSVC_SUCCESS) 1209*7c478bd9Sstevel@tonic-gate return (err); 1210*7c478bd9Sstevel@tonic-gate 1211*7c478bd9Sstevel@tonic-gate err = device_temp_check(hdlp, fan_id, &hot_device); 1212*7c478bd9Sstevel@tonic-gate if (err != PSVC_SUCCESS) { 1213*7c478bd9Sstevel@tonic-gate printf("psvc_fan_control failure in device_temp_check\n"); 1214*7c478bd9Sstevel@tonic-gate return (err); 1215*7c478bd9Sstevel@tonic-gate } 1216*7c478bd9Sstevel@tonic-gate current_error = setpoint - hot_device; 1217*7c478bd9Sstevel@tonic-gate filtered_error = get_filtered_error(last_errors, current_error); 1218*7c478bd9Sstevel@tonic-gate if (filtered_error <= 0 || filtered_error > hysteresis) { 1219*7c478bd9Sstevel@tonic-gate ampout = (int)((filtered_error * loopgain) + loopbias); 1220*7c478bd9Sstevel@tonic-gate if (ampout < 0) 1221*7c478bd9Sstevel@tonic-gate ampout = 0; 1222*7c478bd9Sstevel@tonic-gate if (ampout > 1023) 1223*7c478bd9Sstevel@tonic-gate ampout = 1023; 1224*7c478bd9Sstevel@tonic-gate err = change_cpu_fans(hdlp, fan_id, ampout); 1225*7c478bd9Sstevel@tonic-gate if (err != PSVC_SUCCESS) 1226*7c478bd9Sstevel@tonic-gate return (err); 1227*7c478bd9Sstevel@tonic-gate } 1228*7c478bd9Sstevel@tonic-gate last_errors[error_number++] = current_error; 1229*7c478bd9Sstevel@tonic-gate if (error_number == PSVC_MAXERRORS) 1230*7c478bd9Sstevel@tonic-gate error_number = 0; 1231*7c478bd9Sstevel@tonic-gate 1232*7c478bd9Sstevel@tonic-gate err = psvc_set_attr(hdlp, fan_id, PSVC_TEMP_DIFFERENTIAL_ATTR, 1233*7c478bd9Sstevel@tonic-gate last_errors); 1234*7c478bd9Sstevel@tonic-gate if (err != PSVC_SUCCESS) 1235*7c478bd9Sstevel@tonic-gate return (err); 1236*7c478bd9Sstevel@tonic-gate 1237*7c478bd9Sstevel@tonic-gate err = psvc_set_attr(hdlp, fan_id, PSVC_TEMP_DIFFERENTIAL_INDEX_ATTR, 1238*7c478bd9Sstevel@tonic-gate &error_number); 1239*7c478bd9Sstevel@tonic-gate if (err != PSVC_SUCCESS) 1240*7c478bd9Sstevel@tonic-gate return (err); 1241*7c478bd9Sstevel@tonic-gate 1242*7c478bd9Sstevel@tonic-gate return (PSVC_SUCCESS); 1243*7c478bd9Sstevel@tonic-gate } 1244*7c478bd9Sstevel@tonic-gate 1245*7c478bd9Sstevel@tonic-gate int32_t 1246*7c478bd9Sstevel@tonic-gate psvc_fan_present_policy_0(psvc_opaque_t hdlp, char *id) 1247*7c478bd9Sstevel@tonic-gate { 1248*7c478bd9Sstevel@tonic-gate int32_t status = PSVC_SUCCESS; 1249*7c478bd9Sstevel@tonic-gate boolean_t presence; 1250*7c478bd9Sstevel@tonic-gate int fd; 1251*7c478bd9Sstevel@tonic-gate FILE *fp; 1252*7c478bd9Sstevel@tonic-gate 1253*7c478bd9Sstevel@tonic-gate status = psvc_get_attr(hdlp, id, PSVC_PRESENCE_ATTR, &presence); 1254*7c478bd9Sstevel@tonic-gate if (status != PSVC_SUCCESS) 1255*7c478bd9Sstevel@tonic-gate return (status); 1256*7c478bd9Sstevel@tonic-gate 1257*7c478bd9Sstevel@tonic-gate if (presence == PSVC_ABSENT) { 1258*7c478bd9Sstevel@tonic-gate /* 1259*7c478bd9Sstevel@tonic-gate * We make this open, write, close, call because picld 1260*7c478bd9Sstevel@tonic-gate * starts in rcS.d while print services does not start 1261*7c478bd9Sstevel@tonic-gate * until later (either rc2.d or rc3.d) 1262*7c478bd9Sstevel@tonic-gate */ 1263*7c478bd9Sstevel@tonic-gate fd = open("/dev/console", O_WRONLY | O_NOCTTY); 1264*7c478bd9Sstevel@tonic-gate if (fd != -1) { 1265*7c478bd9Sstevel@tonic-gate fp = fdopen(fd, "w+"); 1266*7c478bd9Sstevel@tonic-gate if (fp != NULL) { 1267*7c478bd9Sstevel@tonic-gate fprintf(fp, FAN_MISSING_MSG, id); 1268*7c478bd9Sstevel@tonic-gate fclose(fp); 1269*7c478bd9Sstevel@tonic-gate } 1270*7c478bd9Sstevel@tonic-gate close(fd); 1271*7c478bd9Sstevel@tonic-gate } 1272*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, FAN_MISSING_MSG, id); 1273*7c478bd9Sstevel@tonic-gate } 1274*7c478bd9Sstevel@tonic-gate return (status); 1275*7c478bd9Sstevel@tonic-gate } 1276