psvcpolicy.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1999-2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Littleneck platform specific environment monitoring policies
*/
#include <syslog.h>
#include <unistd.h>
#include <stdio.h>
#include <libintl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/time_impl.h>
#include <libdevinfo.h>
#include <libdevice.h>
#include <picl.h>
#include <picltree.h>
#include <psvc_objects.h>
/*LINTLIBRARY*/
#define LOWTEMP_CRITICAL_MSG \
gettext("CRITICAL : LOW TEMPERATURE DETECTED %d, %s")
#define LOWTEMP_WARNING_MSG \
gettext("WARNING : LOW TEMPERATURE DETECTED %d, %s")
#define HIGHTEMP_CRITICAL_MSG \
gettext("CRITICAL : HIGH TEMPERATURE DETECTED %d, %s")
#define HIGHTEMP_WARNING_MSG \
gettext("WARNING : HIGH TEMPERATURE DETECTED %d, %s")
#define PS_TYPE_MSG \
gettext("WARNING: Incorrect type power supply inserted, device %s")
#define DEVICE_FAILURE_MSG \
gettext("WARNING: Device %s failure detected by sensor %s\n")
#define DEVTREE_NODE_CREATE_FAILED \
gettext("psvc PICL plugin: Failed to create node for %s, errno = %d")
#define DEVTREE_NODE_DELETE_FAILED \
gettext("psvc PICL plugin: Failed to delete node for %s, errno = %d")
#define NO_FRU_INFO \
gettext("No FRU Information for %s using default temperatures\n")
static char *shutdown_string = "shutdown -y -g 60 -i 5 \"OVERTEMP condition\"";
typedef struct seg_desc {
} seg_desc_t;
char *seg_to_find);
static int temp_attr[] = {
};
#define TEMP_OFFSET 12
#define PART_NO_OFFSET 152
#define NUM_OF_SEG_ADDR 0x1805
#define SEG_DESC_START 0x1806
#define PSVC_NO_DEVICE -2
char seg_to_find[2])
{
char seg_name[2];
/*
* Read the number of segments in the Read Only section
*/
&fru_data);
/*
* We test for ENOENT and ENXIO because Littleneck does not
* have actual presence sensors and so the only way to see
* if a part is there or not is to actually make a call to
* that part.
*/
if (status != PSVC_SUCCESS) {
return (PSVC_NO_DEVICE);
else
return (PSVC_FAILURE);
}
/*
* Read in each segment to find the segment we are looking for
*/
&fru_data);
&fru_data);
if (status != PSVC_SUCCESS) {
"Failed psvc_get_attr for FRU info\n");
return (PSVC_FAILURE);
}
seg_found = 1;
}
}
return (seg_found);
}
{
int fd;
PSVC_FRU);
if (status == PSVC_FAILURE)
return (status);
for (i = 0; i < fru_count; i++) {
seg_found = 0;
if (status != PSVC_SUCCESS)
return (status);
if (seg_found == PSVC_FAILURE)
return (PSVC_FAILURE);
else if (seg_found == PSVC_NO_DEVICE)
return (PSVC_SUCCESS);
if (seg_found) {
/*
* For Littleneck we need to read the offset of the
* die-sensor data record
*/
&fru_data);
if (status != PSVC_SUCCESS) {
"Failed psvc_get_attr for FRU info\n");
return (status);
}
/*
* Now go and get the new temperature settings
*/
&fru_data);
if (status != PSVC_SUCCESS) {
"Failed psvc_get_attr for FRU info\n");
return (status);
} else {
/*
* Now set the updated Thresholds
*/
for (j = 0; j < MAX_TEMP_ATTR; j++) {
}
}
} else {
/*
* For Littleneck only we need to check for the part
* number of the CPU as there are parts that do not
* have the ES segment programmed.
*/
if (seg_found == PSVC_FAILURE)
return (PSVC_FAILURE);
if (seg_found) {
/*
* We now goto the SD segment to get the part
* number.
*/
if (status != PSVC_SUCCESS) {
"for FRU info\n");
return (status);
}
/*
* We are go through the parts list to see
* if the part number from the FRU is in
* this list. If it is we simply return
* as the FRU is not programmed.
*/
for (j = 0; j < num_of_parts; j++) {
7) == 0) {
return (status);
}
}
}
/*
* If the Part is not in the Part list and we
* get to here this means that the FRU is
* considered broken (no ES segment found)
* and we need to report this.
*/
/*
* We make this open, write, close, call
* because picld starts in rcS.d while print
* services does not start until later
* (either rc2.d or rc3.d).
*/
if (fd != -1) {
}
}
}
}
return (status);
}
{
char previous_state[32];
char state[32];
char fault[32];
char label[32];
return (status);
}
if (status != PSVC_SUCCESS) {
return (PSVC_SUCCESS);
else
return (PSVC_FAILURE);
}
if (status != PSVC_SUCCESS)
return (status);
if (status != PSVC_SUCCESS)
return (status);
if (status != PSVC_SUCCESS)
return (status);
if (status != PSVC_SUCCESS)
return (status);
if (status != PSVC_SUCCESS)
return (status);
if (status != PSVC_SUCCESS)
return (status);
} else {
/* within limits */
}
if (status != PSVC_SUCCESS)
return (status);
if (status != PSVC_SUCCESS)
return (status);
if (status != PSVC_SUCCESS)
return (status);
char *led_id;
led_id = "SYSTEM_FAULT_LED_WR";
if (status != PSVC_SUCCESS)
return (status);
else
if (status != PSVC_SUCCESS)
return (status);
}
return (PSVC_SUCCESS);
}
{
char label[32];
int i;
char led_state[32];
char parent_path[256];
int ps_instance;
char devpath[256];
if (status != PSVC_SUCCESS)
return (status);
if (status != PSVC_SUCCESS)
return (status);
if (presence == previous_presence) {
/* No change */
return (status);
}
if (status != PSVC_SUCCESS)
return (status);
/* Convert name to node and parent path */
if (presence == PSVC_PRESENT) {
/* may detect presence before all connections are made */
sleep(1);
/* Device added */
/* Verify P/S is correct type */
&sensor_id, PSVC_DEV_TYPE_SENSOR, 0);
if (status != PSVC_SUCCESS)
return (status);
if (status != PSVC_SUCCESS)
return (status);
} else { /* wrong type */
}
if (status != PSVC_SUCCESS)
return (status);
if (status != PSVC_SUCCESS)
return (status);
/* Set state of fault LEDs */
if (status != PSVC_SUCCESS) {
gettext("Failed for PSVC_DEV_FAULT_LED\n"));
return (status);
}
for (i = 0; i < led_count; ++i) {
PSVC_DEV_FAULT_LED, i);
if (status != PSVC_SUCCESS)
return (status);
if (status != PSVC_SUCCESS)
return (status);
}
} else {
/* Device removed */
}
if (status != PSVC_SUCCESS)
return (status);
if (status != PSVC_SUCCESS)
return (status);
if (presence != PSVC_PRESENT) {
if (ps_instance == 0)
else
if (devctl_device_remove(dev_handle)) {
errno);
} else {
}
return (status);
}
/*
* We fall through to here if the device has been inserted.
* Add the devinfo tree node entry for the seeprom and attach
* the i2c seeprom driver
*/
if (ps_instance == 0) {
} else {
}
} else
return (status);
}
{
int i;
if (status == PSVC_FAILURE)
return (status);
if (present == PSVC_ABSENT) {
return (PSVC_FAILURE);
}
for (i = 0; i < sensor_count; ++i) {
&sensor_id, PSVC_DEV_FAULT_SENSOR, i);
if (status != PSVC_SUCCESS)
return (status);
if (status != PSVC_SUCCESS)
return (status);
} else {
}
if (status != PSVC_SUCCESS)
return (status);
if (status != PSVC_SUCCESS)
return (status);
if (status != PSVC_SUCCESS)
return (status);
char sensor_label[32];
char dev_label[32];
else
led_id = "SYSTEM_FAULT_LED_WR";
if (status != PSVC_SUCCESS)
return (status);
else
if (status != PSVC_SUCCESS)
return (status);
}
}
return (PSVC_SUCCESS);
}
{
if (status != PSVC_SUCCESS)
return (status);
if (status != PSVC_SUCCESS)
return (status);
return (status);
}
static int32_t
{
char *sensorid;
int32_t i;
char fault[32];
for (i = 0; i < sensor_count; ++i) {
&sensorid, PSVC_DEV_TEMP_SENSOR, i);
if (status == PSVC_FAILURE)
return (status);
fault);
if (status == PSVC_FAILURE)
return (status);
}
}
return (status);
}
{
char *cpuid;
int32_t i;
PSVC_CPU);
for (i = 0; i < cpu_count; ++i) {
PSVC_CPU, i);
if (status == PSVC_FAILURE)
return (status);
return (status);
if (present == PSVC_PRESENT) {
return (status);
}
}
return (PSVC_SUCCESS);
}