psvcobj.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
* or http://www.opensolaris.org/os/licensing.
* 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"
/*
* This file consists of routines to manage objects in the
* "Platform Environment Services Framework". The classes
* and subclasses are defined by attributes and methods.
* The objects, and their initial, static, attribute values are
* specified in a configuration file, "psvcobj.conf".
* psvc_init() reads the configuration file and creates a repository
* of environmental objects in memory. A client application may manipulate
* these objects by invoking the psvc_get_attr(), and psvc_set_attr()
* routines with the object's string ID specified as an argument.
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include <stropts.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <syslog.h>
#include <stdarg.h>
#include <pthread.h>
#include <sys/systeminfo.h>
#define LIBRARY_BUILD 1
#include <psvc_objects.h>
#include <psvc_objects_class.h>
#include <sys/i2c/clients/i2c_client.h>
/* Mutex used for Daktari Fan speed reading */
pthread_mutex_t fan_mutex = PTHREAD_MUTEX_INITIALIZER;
/*LINTLIBRARY*/
#define ENV_DEBUG(str, id) printf("%s id %s\n", (str), (id))
#define BUFSZ 512
#define CLASS_MAX 12
#define SUBCLASS_MAX 10
static int32_t i_psvc_constructor_0_0(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_0_1(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_1_0(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_2_0(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_2_1(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_2_2(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_3_0(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_4_0(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_5_0(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_6_0(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_7_0(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_8_0(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_9_0(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_10_0(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_10_1(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_11_0(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_11_1(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_11_2(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_11_3(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_11_4(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_11_5(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_11_6(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_11_7(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_11_8(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_constructor_11_9(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_get_obj(EHdl_t *, char *, EObj_t **);
static int32_t i_psvc_destructor(EHdl_t *, char *, void *);
static int32_t i_psvc_get_devpath(EHdl_t *, uint64_t, char *);
static int32_t i_psvc_get_attr_generic(EHdl_t *, EObj_t *, int32_t, void *);
static int32_t i_psvc_get_attr_6_0(EHdl_t *, EObj_t *, int32_t, void *);
static int32_t i_psvc_get_reg_11_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id,
void *attrp);
static int32_t i_psvc_get_attr_10_1(EHdl_t *, EObj_t *, int32_t, void *);
static int32_t psvc_get_str_key(char *object);
int32_t ioctl_retry(int fp, int request, void * arg_pointer);
/*
* Method lookup tables
* Update when adding classes or subclasses.
*/
/* Lookup method by class, subclass, used when calling method */
static int32_t (*i_psvc_constructor[CLASS_MAX][SUBCLASS_MAX])(EHdl_t *,
char *, EObj_t **) = {
{i_psvc_constructor_0_0, i_psvc_constructor_0_1, 0, 0, 0, 0, 0, 0, 0, 0},
{i_psvc_constructor_1_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{i_psvc_constructor_2_0, i_psvc_constructor_2_1, i_psvc_constructor_2_2,
0, 0, 0, 0, 0, 0, 0},
{i_psvc_constructor_3_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{i_psvc_constructor_4_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{i_psvc_constructor_5_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{i_psvc_constructor_6_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{i_psvc_constructor_7_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{i_psvc_constructor_8_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{i_psvc_constructor_9_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{i_psvc_constructor_10_0, i_psvc_constructor_10_1, 0, 0, 0, 0, 0, 0, 0, 0},
{i_psvc_constructor_11_0, i_psvc_constructor_11_1, i_psvc_constructor_11_2,
i_psvc_constructor_11_3, i_psvc_constructor_11_4,
i_psvc_constructor_11_5, i_psvc_constructor_11_6,
i_psvc_constructor_11_7, i_psvc_constructor_11_8,
i_psvc_constructor_11_9},
};
static int32_t i_psvc_cell_size[8] = {1, 1, 2, 2, 4, 4, 8, 8};
static struct bits {
uint64_t bit;
char *label;
} feature_bits[] = {
{PSVC_DEV_PERM, "PERM="},
{PSVC_DEV_HOTPLUG, "HOTPLUG="},
{PSVC_DEV_OPTION, "OPTION="},
{PSVC_DEV_PRIMARY, "PRIMARY="},
{PSVC_DEV_SECONDARY, "SECONDARY="},
{PSVC_DEV_RDONLY, "RDONLY="},
{PSVC_DEV_RDWR, "RDWR="},
{PSVC_DEV_FRU, "FRU="},
{PSVC_LOW_WARN, "LO_WARN_MASK="},
{PSVC_LOW_SHUT, "LO_SHUT_MASK="},
{PSVC_HIGH_WARN, "HI_WARN_MASK="},
{PSVC_HIGH_SHUT, "HI_SHUT_MASK="},
{PSVC_CONVERSION_TABLE, "CONV_TABLE="},
{PSVC_OPT_TEMP, "OPT_TEMP_MASK="},
{PSVC_HW_LOW_SHUT, "HW_LO_MASK="},
{PSVC_HW_HIGH_SHUT, "HW_HI_MASK="},
{PSVC_FAN_DRIVE_PR, "FAN_DRIVE_PR="},
{PSVC_TEMP_DRIVEN, "TEMP_DRIVEN="},
{PSVC_SPEED_CTRL_PR, "SPEED_CTRL_PR="},
{PSVC_FAN_ON_OFF, "FAN_ON_OFF="},
{PSVC_CLOSED_LOOP_CTRL, "CLOSED_LOOP_CTRL="},
{PSVC_FAN_DRIVE_TABLE_PR, "FAN_DRIVE_TABLE_PR="},
{PSVC_DIE_TEMP, "DIE_TEMP="},
{PSVC_AMB_TEMP, "AMB_TEMP="},
{PSVC_DIGI_SENSOR, "DIGI_SENSOR="},
{PSVC_BI_STATE, "BI_STATE="},
{PSVC_TRI_STATE, "TRI_STATE="},
{PSVC_GREEN, "GREEN="},
{PSVC_AMBER, "AMBER="},
{PSVC_OUTPUT, "OUTPUT="},
{PSVC_INPUT, "INPUT="},
{PSVC_BIDIR, "BIDIR="},
{PSVC_BIT_POS, "BIT_POS="},
{PSVC_VAL_POS, "VAL_POS="},
{PSVC_NORMAL_POS_AV, "NORMAL_POS_AV="},
{PSVC_DIAG_POS_AV, "DIAG_POS_AV="},
{PSVC_LOCK_POS_AV, "LOCK_POS_AV="},
{PSVC_OFF_POS_AV, "OFF_POS_AV="},
{PSVC_GPIO_PORT, "GPIO_PORT="},
{PSVC_GPIO_REG, "GPIO_REG="}
};
#define ASSOC_STR_TAB_SIZE 33
static char *assoc_str_tab[] = {
"PSVC_PRESENCE_SENSOR", /* 0 */
"PSVC_FAN_ONOFF_SENSOR", /* 1 */
"PSVC_FAN_SPEED_TACHOMETER", /* 2 */
"PSVC_FAN_PRIM_SEC_SELECTOR", /* 3 */
"PSVC_DEV_TEMP_SENSOR", /* 4 */
"PSVC_FAN_DRIVE_CONTROL", /* 5 */
"PSVC_KS_NORMAL_POS_SENSOR", /* 6 */
"PSVC_KS_DIAG_POS_SENSOR", /* 7 */
"PSVC_KS_LOCK_POS_SENSOR", /* 8 */
"PSVC_KS_OFF_POS_SENSOR", /* 9 */
"PSVC_SLOT_FAULT_LED", /* 10 */
"PSVC_SLOT_REMOVE_LED", /* 11 */
"PSVC_TS_OVERTEMP_LED", /* 12 */
"PSVC_PS_I_SENSOR", /* 13 */
"PSVC_DEV_FAULT_SENSOR", /* 14 */
"PSVC_DEV_FAULT_LED", /* 15 */
"PSVC_TABLE", /* 16 */
"PSVC_PARENT", /* 17 */
"PSVC_CPU", /* 18 */
"PSVC_ALTERNATE", /* 19 */
"PSVC_HOTPLUG_ENABLE_SWITCH", /* 20 */
"PSVC_PS", /* 21 */
"PSVC_FAN", /* 22 */
"PSVC_TS", /* 23 */
"PSVC_DISK", /* 24 */
"PSVC_LED", /* 25 */
"PSVC_FSP_LED", /* 26 */
"PSVC_KEYSWITCH", /* 27 */
"PSVC_PCI_CARD", /* 28 */
"PSVC_PHYSICAL_DEVICE", /* 29 */
"PSVC_DEV_TYPE_SENSOR", /* 30 */
"PSVC_FAN_TRAY_FANS", /* 31 */
"PSVC_FRU" /* 32 */
};
#define FEATURE_BITS (sizeof (feature_bits) / sizeof (struct bits))
static struct bitfield {
int8_t shift;
char *label;
char *format;
} addr_fields[] =
{
{PSVC_VERSION_SHIFT, "VERSION=", "%d"},
{PSVC_ACTIVE_LOW_SHIFT, "ACTIVE_LOW=", "%d"},
{PSVC_BIT_NUM_SHIFT, "BIT_NUM=", "%d"},
{PSVC_INVERT_SHIFT, "INVERT=", "%d"},
{PSVC_PORT_SHIFT, "PORT=", "%d"},
{PSVC_BITSHIFT_SHIFT, "BITSHIFT=", "%d"},
{PSVC_BYTEMASK_SHIFT, "BYTEMASK=", "%x"},
{PSVC_REG_SHIFT, "REG=", "%d"},
{PSVC_TYPE_SHIFT, "TYPE=", "%d"},
{PSVC_BUSADDR_SHIFT, "BUSADDR=", "%x"},
{PSVC_BUSNUM_SHIFT, "BUSNUM=", "%d"},
{PSVC_CNTLR_SHIFT, "CNTLR=", "%d"},
};
#define ADDR_BITFIELDS (sizeof (addr_fields) / sizeof (struct bitfield))
/*
* record format is:
* pathname label1=val1,label2=val2,label3=val3
* Must be a space after the pathname and a comma between variables.
*/
static char *
find_label(char *str, char *label)
{
char *start;
start = strchr(str, ' ');
if (start == NULL)
return (start);
do {
++start;
if (strncmp(start, label, strlen(label)) == 0)
return (start);
start = strchr(start, ',');
} while (start != NULL);
return (NULL);
}
static int32_t
i_psvc_value(char *buf, int32_t attr_id, void *attrp)
{
char *val;
uint32_t temp32;
uint64_t temp64;
uint64_t result;
int32_t i;
int32_t found;
char label[64];
int val_size;
int label_size;
switch (attr_id) {
case PSVC_CLASS_ATTR:
case PSVC_SUBCLASS_ATTR:
case PSVC_INSTANCE_ATTR:
case PSVC_LO_WARN_ATTR:
case PSVC_LO_SHUT_ATTR:
case PSVC_HI_WARN_ATTR:
case PSVC_HI_SHUT_ATTR:
case PSVC_HW_HI_SHUT_ATTR:
case PSVC_HW_LO_SHUT_ATTR:
case PSVC_OPTIMAL_TEMP_ATTR:
snprintf(label, sizeof (label), "%s=", attr_str_tab[attr_id]);
val = find_label(buf, label);
if (val == NULL) {
errno = EINVAL;
return (PSVC_FAILURE);
}
found = sscanf(val + strlen(label),
"%d", (int32_t *)attrp);
if (found == 0)
*(int32_t *)attrp = 0;
break;
case PSVC_SETPOINT_ATTR:
case PSVC_HYSTERESIS_ATTR:
case PSVC_LOOPGAIN_ATTR:
case PSVC_LOOPBIAS_ATTR:
snprintf(label, sizeof (label), "%s=", attr_str_tab[attr_id]);
val = find_label(buf, label);
if (val == NULL) {
errno = EINVAL;
return (PSVC_FAILURE);
}
found = sscanf(val + strlen(label), "%hd", (int16_t *)attrp);
if (found == 0)
*(int16_t *)attrp = 0;
break;
case PSVC_LED_COLOR_ATTR:
case PSVC_LED_IS_LOCATOR_ATTR:
case PSVC_LED_LOCATOR_NAME_ATTR:
snprintf(label, sizeof (label), "%s=", attr_str_tab[attr_id]);
val = find_label(buf, label);
if (val == NULL) {
errno = EINVAL;
return (PSVC_FAILURE);
}
val_size = strlen(val);
label_size = strlen(label);
for (i = 0; i < val_size && val[i] != ','; i++);
if (i < strlen(val) - 1) {
strncpy((char *)attrp, val+label_size,
i - label_size);
} else
found = sscanf(val + label_size, "%s", (char *)attrp);
if (found == 0)
strcpy((char *)attrp, "");
break;
case PSVC_FEATURES_ATTR:
result = 0;
for (i = 0; i < FEATURE_BITS; ++i) {
val = find_label(buf, feature_bits[i].label);
if (val == NULL)
continue;
found = sscanf(val + strlen(feature_bits[i].label),
"%d", &temp32);
if (found != 0) {
if (temp32 == 1)
result |= feature_bits[i].bit;
}
}
*(uint64_t *)attrp = result;
break;
case PSVC_ADDR_SPEC_ATTR:
result = 0;
for (i = 0; i < ADDR_BITFIELDS; ++i) {
val = find_label(buf, addr_fields[i].label);
if (val == NULL)
continue;
found = sscanf(val + strlen(addr_fields[i].label),
addr_fields[i].format, &temp32);
if (found != 0) {
temp64 = temp32;
temp64 <<= addr_fields[i].shift;
result |= temp64;
}
}
*(uint64_t *)attrp = result;
break;
default:
errno = EINVAL;
return (PSVC_FAILURE);
}
return (PSVC_SUCCESS);
}
/* determine number of records in file section */
static int32_t
i_psvc_count_records(FILE *fp, char *end, uint32_t *countp)
{
long first_record;
char *ret;
char buf[BUFSZ];
uint32_t count = 0;
first_record = ftell(fp);
while ((ret = fgets(buf, BUFSZ, fp)) != NULL) {
if (strncmp(end, buf, strlen(end)) == 0)
break;
++count;
}
if (ret == NULL) {
errno = EINVAL;
return (PSVC_FAILURE);
}
fseek(fp, first_record, SEEK_SET);
*countp = count;
return (PSVC_SUCCESS);
}
/* determine number of records in file section */
static int32_t
i_psvc_count_tables_associations(FILE *fp, uint32_t *countp, char *end)
{
long first_record;
char *ret;
char buf[BUFSZ];
uint32_t count = 0;
first_record = ftell(fp);
while ((ret = fgets(buf, BUFSZ, fp)) != NULL) {
if (strncmp(end, buf, strlen(end)) == 0)
++count;
}
#ifdef lint
ret = ret;
#endif
fseek(fp, first_record, SEEK_SET);
*countp = count;
return (PSVC_SUCCESS);
}
/* determine number of records in a table */
static int32_t
i_psvc_count_table_records(FILE *fp, char *end, uint32_t *countp)
{
long first_record;
int ret;
char string[BUFSZ];
uint32_t count = 0;
first_record = ftell(fp);
while ((ret = fscanf(fp, "%s", string)) == 1) {
if (strncmp(end, string, strlen(end)) == 0)
break;
++count;
}
if (ret != 1) {
errno = EINVAL;
return (PSVC_FAILURE);
}
fseek(fp, first_record, SEEK_SET);
*countp = count;
return (PSVC_SUCCESS);
}
/*
* Find number of matches to an antecedent_id of a certain
* association type.
*/
static int32_t
i_psvc_get_assoc_matches(EHdl_t *hdlp, char *antecedent, int32_t assoc_id,
int32_t *matches)
{
int i;
int32_t key;
EAssocList_t *ap = hdlp->assoc_tbl + assoc_id;
*matches = 0;
if (ap->table == 0) {
errno = EINVAL;
return (PSVC_FAILURE);
}
key = psvc_get_str_key(antecedent);
for (i = 0; i < ap->count; ++i) {
if (ap->table[i].ant_key == key) {
if (strcmp(ap->table[i].antecedent_id, antecedent)
== 0)
++*matches;
}
}
return (PSVC_SUCCESS);
}
/*
* Find 1st m matches to an antecedent_id of a certain
* association type.
* Returns zero for success, -1 for failure.
*/
static int32_t
i_psvc_get_assoc_id(EHdl_t *hdlp, char *antecedent, int32_t assoc_id,
int32_t match, char **id_list)
{
int i;
int found = 0;
int32_t key;
EAssocList_t *ap = &hdlp->assoc_tbl[assoc_id];
if (ap->table == 0) {
errno = EINVAL;
return (-1);
}
key = psvc_get_str_key(antecedent);
for (i = 0; i < ap->count; ++i) {
if (ap->table[i].ant_key == key) {
if (strcmp(ap->table[i].antecedent_id, antecedent)
== 0) {
if (found == match) {
*id_list = ap->table[i].dependent_id;
return (0);
}
++found;
}
}
}
errno = EINVAL;
return (-1);
}
static int32_t
i_psvc_get_table_value(EHdl_t *hdlp, char *table_id, uint32_t index,
void *value)
{
int32_t i;
ETable_t *tblp;
ETable_Array *tbl_arr;
int32_t key, array;
key = psvc_get_str_key(table_id);
array = key % PSVC_MAX_TABLE_ARRAYS;
tbl_arr = &(hdlp->tbl_arry[array]);
for (i = 0; i < tbl_arr->obj_count; ++i) {
if (key == tbl_arr->obj_tbl[i].key) {
if (strcmp(tbl_arr->obj_tbl[i].name,
table_id) == 0)
break;
}
}
if (tbl_arr->obj_tbl[i].type != PSVC_TBL)
return (PSVC_FAILURE);
tblp = (ETable_t *)tbl_arr->obj_tbl[i].objp;
if (tblp->table == NULL)
return (PSVC_FAILURE);
if (index >= tblp->size)
return (PSVC_FAILURE);
switch (tblp->cell_type) {
case 0:
*(int8_t *)value = *((int8_t *)tblp->table + index);
break;
case 1:
*(uint8_t *)value = *((uint8_t *)tblp->table + index);
break;
case 2:
*(int16_t *)value = *((int16_t *)tblp->table + index);
break;
case 3:
*(uint16_t *)value = *((uint16_t *)tblp->table + index);
break;
case 4:
*(int32_t *)value = *((int32_t *)tblp->table + index);
break;
case 5:
*(uint32_t *)value = *((uint32_t *)tblp->table + index);
break;
case 6:
*(int64_t *)value = *((int64_t *)tblp->table + index);
break;
case 7:
*(uint64_t *)value = *((uint64_t *)tblp->table + index);
break;
default:
return (PSVC_FAILURE);
}
return (PSVC_SUCCESS);
}
int32_t
psvc_get_attr(EHdl_t *hdlp, char *name, int32_t attr_id, void *attr_valuep, ...)
{
EObj_t *objp;
int32_t status = PSVC_SUCCESS;
int32_t arg1, arg2;
va_list ap;
pthread_mutex_lock(&hdlp->mutex);
if (attr_valuep == NULL) {
errno = EFAULT;
pthread_mutex_unlock(&hdlp->mutex);
return (PSVC_FAILURE);
}
switch (attr_id) {
case PSVC_TABLE_VALUE_ATTR:
va_start(ap, attr_valuep);
status = i_psvc_get_table_value(hdlp, name,
va_arg(ap, uint32_t), attr_valuep);
va_end(ap);
break;
case PSVC_ASSOC_MATCHES_ATTR:
va_start(ap, attr_valuep);
status = i_psvc_get_assoc_matches(hdlp, name,
va_arg(ap, int32_t), attr_valuep);
va_end(ap);
break;
case PSVC_ASSOC_ID_ATTR:
va_start(ap, attr_valuep);
arg1 = va_arg(ap, int32_t);
arg2 = va_arg(ap, int32_t);
status = i_psvc_get_assoc_id(hdlp, name,
arg1, arg2, attr_valuep);
va_end(ap);
break;
default:
status = i_psvc_get_obj(hdlp, name, &objp);
if (status != PSVC_SUCCESS) {
pthread_mutex_unlock(&hdlp->mutex);
return (status);
}
status = (*objp->get_attr)(hdlp, objp, attr_id,
attr_valuep);
}
if (status != PSVC_SUCCESS) {
pthread_mutex_unlock(&hdlp->mutex);
return (status);
}
pthread_mutex_unlock(&hdlp->mutex);
return (status);
}
int32_t
psvc_set_attr(EHdl_t *hdlp, char *name, int32_t attr_id, void *attr_valuep)
{
EObj_t *objp;
int32_t status = PSVC_SUCCESS;
pthread_mutex_lock(&hdlp->mutex);
status = i_psvc_get_obj(hdlp, name, &objp);
if (status != PSVC_SUCCESS) {
pthread_mutex_unlock(&hdlp->mutex);
return (status);
}
if (attr_valuep == NULL) {
errno = EFAULT;
pthread_mutex_unlock(&hdlp->mutex);
return (PSVC_FAILURE);
}
status = (*objp->set_attr)(hdlp, objp, attr_id, attr_valuep);
if (status != PSVC_SUCCESS) {
pthread_mutex_unlock(&hdlp->mutex);
return (status);
}
pthread_mutex_unlock(&hdlp->mutex);
return (status);
}
static int32_t
i_psvc_get_presence(EHdl_t *hdlp, EObj_t *objp, boolean_t *pr)
{
EObj_t *pobjp, *mobjp;
int32_t matches;
char *mid;
char *parent_id;
int32_t status = PSVC_SUCCESS;
uint8_t value_8bit, value_8bit_inv;
boolean_t active_low, value;
if (strcmp(objp->label, PSVC_CHASSIS) == 0) {
*pr = PSVC_PRESENT;
objp->present = PSVC_PRESENT;
return (PSVC_SUCCESS);
}
status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PARENT, 0,
&parent_id);
if (status != PSVC_SUCCESS)
return (status);
if (strcmp(parent_id, PSVC_CHASSIS)) {
status = i_psvc_get_obj(hdlp, parent_id, &pobjp);
if (status != PSVC_SUCCESS)
return (status);
if (!pobjp->present) {
pobjp->get_attr(hdlp, pobjp, PSVC_PRESENCE_ATTR, pr);
*pr = pobjp->present;
objp->present = pobjp->present;
return (status);
}
}
(void) i_psvc_get_assoc_matches(hdlp, objp->label,
PSVC_PRESENCE_SENSOR, &matches);
if (matches != 0) {
status = i_psvc_get_assoc_id(hdlp, objp->label,
PSVC_PRESENCE_SENSOR, 0, &mid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, mid, &mobjp);
if (status != PSVC_SUCCESS)
return (status);
active_low = PSVC_IS_ACTIVE_LOW(mobjp->addr_spec);
if (mobjp->class == PSVC_BOOLEAN_GPIO_CLASS) {
status = mobjp->get_attr(hdlp, mobjp,
PSVC_GPIO_VALUE_ATTR, &value);
if (status != PSVC_SUCCESS)
return (status);
if (active_low)
if (value == 0)
*pr = PSVC_PRESENT;
else
*pr = PSVC_ABSENT;
else
if (value == 0)
*pr = PSVC_ABSENT;
else
*pr = PSVC_PRESENT;
} else if (mobjp->class == PSVC_8BIT_GPIO_CLASS) {
uint8_t bitshift, bytemask;
status = mobjp->get_attr(hdlp, mobjp,
PSVC_GPIO_VALUE_ATTR, &value_8bit);
if (status != PSVC_SUCCESS)
return (status);
if (PSVC_HP_INVERT(mobjp->addr_spec))
value_8bit_inv = ~value_8bit;
else
value_8bit_inv = value_8bit;
bitshift = PSVC_GET_ASPEC_BITSHIFT(mobjp->addr_spec);
bytemask = PSVC_GET_ASPEC_BYTEMASK(mobjp->addr_spec);
value_8bit_inv =
value_8bit_inv & (bytemask >> bitshift);
if (active_low)
if (value_8bit_inv == 0)
*pr = PSVC_PRESENT;
else
*pr = PSVC_ABSENT;
else
if (value_8bit_inv == 0)
*pr = PSVC_ABSENT;
else
*pr = PSVC_PRESENT;
} else {
errno = EINVAL;
return (PSVC_FAILURE);
}
} else {
*pr = PSVC_PRESENT;
}
objp->present = *pr;
return (status);
}
static int32_t
i_psvc_get_device_value_0_0(EHdl_t *hdlp, EObj_t *objp, int32_t *temp)
{
int32_t status = PSVC_SUCCESS, m;
char *tid;
int16_t temp16;
char *physid;
EObj_t *physobjp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_assoc_id(
hdlp, objp->label, PSVC_PHYSICAL_DEVICE, 0, &physid);
if (status != PSVC_SUCCESS) {
return (status);
}
status = i_psvc_get_obj(hdlp, physid, &physobjp);
if (status != PSVC_SUCCESS) {
return (status);
}
status = ((EPhysDev_t *)physobjp)->get_temperature(hdlp,
objp->addr_spec, temp);
if (status != PSVC_SUCCESS) {
return (status);
}
if (objp->features & PSVC_CONVERSION_TABLE) {
status = i_psvc_get_assoc_matches(hdlp, objp->label,
PSVC_TABLE, &m);
if ((status != PSVC_SUCCESS) || (m != 1)) {
return (status);
}
(void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
&tid);
status = i_psvc_get_table_value(hdlp, tid, *temp, &temp16);
*temp = temp16;
}
return (status);
}
static int32_t
i_psvc_get_device_value_0_1(EHdl_t *hdlp, EObj_t *objp, int32_t *temp)
{
int32_t status = PSVC_SUCCESS, m;
char *tid;
int16_t temp16;
char *physid;
EObj_t *physobjp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_assoc_id(
hdlp, objp->label, PSVC_PHYSICAL_DEVICE, 0, &physid);
if (status != PSVC_SUCCESS) {
return (status);
}
status = i_psvc_get_obj(hdlp, physid, &physobjp);
if (status != PSVC_SUCCESS) {
return (status);
}
status = ((EPhysDev_t *)physobjp)->get_temperature(hdlp,
objp->addr_spec, temp);
if (status != PSVC_SUCCESS) {
return (status);
}
if (objp->features & PSVC_CONVERSION_TABLE) {
status = i_psvc_get_assoc_matches(hdlp, objp->label,
PSVC_TABLE, &m);
if ((status != PSVC_SUCCESS) || (m != 1)) {
return (status);
}
(void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
&tid);
status = i_psvc_get_table_value(hdlp, tid, *temp, &temp16);
*temp = temp16;
}
return (status);
}
static int32_t
i_psvc_get_device_value_4_0(EHdl_t *hdlp, EObj_t *objp, int32_t *value)
{
int32_t status = PSVC_SUCCESS;
char *physid;
EObj_t *physobjp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
0, &physid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, physid, &physobjp);
if (status != PSVC_SUCCESS)
return (status);
status = ((EPhysDev_t *)physobjp)->get_input(hdlp, objp->addr_spec,
value);
if (status != PSVC_SUCCESS)
return (status);
if (objp->features & PSVC_CONVERSION_TABLE) {
int32_t m;
char *tid;
int16_t temp16;
status = i_psvc_get_assoc_matches(hdlp, objp->label,
PSVC_TABLE, &m);
if ((status != PSVC_SUCCESS) || (m != 1)) {
return (status);
}
(void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
&tid);
status = i_psvc_get_table_value(hdlp, tid, *value, &temp16);
*value = temp16;
}
return (status);
}
static int32_t
i_psvc_set_device_value_5_0(EHdl_t *hdlp, EObj_t *objp, int32_t *value)
{
int32_t status = PSVC_SUCCESS;
char *physid;
EObj_t *physobjp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
0, &physid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, physid, &physobjp);
if (status != PSVC_SUCCESS)
return (status);
status = ((EPhysDev_t *)physobjp)->set_output(hdlp, objp->addr_spec,
*value);
if (status != PSVC_SUCCESS)
return (status);
return (status);
}
static int32_t
i_psvc_get_device_value_5_0(EHdl_t *hdlp, EObj_t *objp, int32_t *value)
{
int32_t status = PSVC_SUCCESS;
char *physid;
EObj_t *physobjp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
0, &physid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, physid, &physobjp);
if (status != PSVC_SUCCESS)
return (status);
status = ((EPhysDev_t *)physobjp)->get_output(hdlp, objp->addr_spec,
value);
if (status != PSVC_SUCCESS)
return (status);
if (objp->features & PSVC_CONVERSION_TABLE) {
int32_t m;
char *tid;
int16_t temp16;
status = i_psvc_get_assoc_matches(hdlp, objp->label,
PSVC_TABLE, &m);
if ((status != PSVC_SUCCESS) || (m != 1)) {
return (status);
}
(void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
&tid);
status = i_psvc_get_table_value(hdlp, tid, *value, &temp16);
*value = temp16;
}
return (status);
}
static int32_t
i_psvc_get_device_value_6_0(EHdl_t *hdlp, EObj_t *objp, boolean_t *value)
{
int32_t status = PSVC_SUCCESS;
int32_t bit_value;
char *physid;
EObj_t *physobjp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
0, &physid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, physid, &physobjp);
if (status != PSVC_SUCCESS)
return (status);
status = ((EPhysDev_t *)physobjp)->get_bit(hdlp, objp->addr_spec,
&bit_value);
if (status != PSVC_SUCCESS)
return (status);
*value = bit_value;
return (status);
}
static int32_t
i_psvc_set_device_value_6_0(EHdl_t *hdlp, EObj_t *objp, boolean_t *value)
{
int32_t status = PSVC_SUCCESS;
int32_t bit_value;
char *physid;
EObj_t *physobjp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
bit_value = *value;
status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
0, &physid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, physid, &physobjp);
if (status != PSVC_SUCCESS)
return (status);
status = ((EPhysDev_t *)physobjp)->set_bit(hdlp, objp->addr_spec,
bit_value);
if (status != PSVC_SUCCESS)
return (status);
return (status);
}
static int32_t
i_psvc_get_device_value_1_0(EHdl_t *hdlp, EObj_t *objp, int32_t *fan_speed)
{
int32_t status = PSVC_SUCCESS;
EObj_t *ftobjp;
char *fan_tach;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_assoc_id(hdlp, objp->label,
PSVC_FAN_SPEED_TACHOMETER, 0, &fan_tach);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, fan_tach, &ftobjp);
if (status != PSVC_SUCCESS)
return (status);
status = ftobjp->get_attr(hdlp, ftobjp, PSVC_SENSOR_VALUE_ATTR,
fan_speed);
if (status != PSVC_SUCCESS)
return (status);
return (status);
}
static int32_t
i_psvc_get_device_value_7_0(EHdl_t *hdlp, EObj_t *objp, int32_t *fan_speed)
{
char *physid;
EObj_t *physobjp;
int32_t status = PSVC_SUCCESS;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
0, &physid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, physid, &physobjp);
if (status != PSVC_SUCCESS)
return (status);
status = ((EPhysDev_t *)physobjp)->get_fanspeed(hdlp, objp->addr_spec,
fan_speed);
if (status != PSVC_SUCCESS)
return (status);
if (objp->features & PSVC_CONVERSION_TABLE) {
int32_t m;
char *tid;
int16_t temp16;
status = i_psvc_get_assoc_matches(hdlp, objp->label,
PSVC_TABLE, &m);
if ((status != PSVC_SUCCESS) || (m != 1)) {
return (status);
}
(void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
&tid);
status = i_psvc_get_table_value(hdlp, tid, *fan_speed, &temp16);
*fan_speed = temp16;
}
return (status);
}
static int32_t
i_psvc_get_device_state_2_0(EHdl_t *hdlp, EObj_t *objp, char *led_state)
{
int32_t status = PSVC_SUCCESS;
int32_t bit_value;
boolean_t active_low;
char *physid;
EObj_t *physobjp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
0, &physid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, physid, &physobjp);
if (status != PSVC_SUCCESS)
return (status);
status = ((EPhysDev_t *)physobjp)->get_bit(hdlp, objp->addr_spec,
&bit_value);
if (status != PSVC_SUCCESS)
return (status);
active_low = PSVC_IS_ACTIVE_LOW(objp->addr_spec);
if (active_low)
if (bit_value == 0)
strcpy(led_state, PSVC_LED_ON);
else
strcpy(led_state, PSVC_LED_OFF);
else
if (bit_value == 0)
strcpy(led_state, PSVC_LED_OFF);
else
strcpy(led_state, PSVC_LED_ON);
return (status);
}
static int32_t
i_psvc_set_device_state_2_0(EHdl_t *hdlp, EObj_t *objp, char *led_state)
{
int32_t status = PSVC_SUCCESS;
boolean_t active_low;
int32_t bit_value;
char *physid;
EObj_t *physobjp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
if (strcmp(((ELed_t *)objp)->is_locator, PSVC_LOCATOR_TRUE) != 0) {
/*
* For Locator LEDs we ignore lit_count. RSC may have
* altered the LED state underneath us, So we should
* always just do what the user asked instead of trying
* to be smart.
*/
if (strcmp(led_state, PSVC_LED_ON) == 0)
((ELed_t *)objp)->lit_count++;
else if (strcmp(led_state, PSVC_LED_OFF) == 0) {
if (--((ELed_t *)objp)->lit_count > 0) {
return (PSVC_SUCCESS);
} else if (((ELed_t *)objp)->lit_count < 0)
((ELed_t *)objp)->lit_count = 0;
/* Fall through case is when lit_count is 0 */
}
}
strcpy(objp->previous_state, objp->state);
strcpy(objp->state, led_state);
bit_value = (strcmp(led_state, PSVC_LED_ON) == 0);
/*
* Flip the bit if necessary (for active_low devices,
* O ==> ON; 1 ==> OFF.
*/
active_low = PSVC_IS_ACTIVE_LOW(objp->addr_spec);
bit_value ^= active_low;
status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
0, &physid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, physid, &physobjp);
if (status != PSVC_SUCCESS)
return (status);
status = ((EPhysDev_t *)physobjp)->set_bit(hdlp, objp->addr_spec,
bit_value);
return (status);
}
static int32_t
i_psvc_get_device_state_2_1(EHdl_t *hdlp, EObj_t *objp, char *led_state)
{
int32_t status = PSVC_SUCCESS;
uint8_t value;
char *physid;
EObj_t *physobjp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
0, &physid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, physid, &physobjp);
if (status != PSVC_SUCCESS)
return (status);
status = ((EPhysDev_t *)physobjp)->get_reg(hdlp, objp->addr_spec,
&value);
if (status != PSVC_SUCCESS)
return (status);
switch (value) {
case 0:
strcpy(led_state, PSVC_LED_OFF);
break;
case 1:
strcpy(led_state, PSVC_LED_SLOW_BLINK);
break;
case 2:
strcpy(led_state, PSVC_LED_FAST_BLINK);
break;
case 3:
strcpy(led_state, PSVC_LED_ON);
break;
}
return (status);
}
static int32_t
i_psvc_set_device_state_2_1(EHdl_t *hdlp, EObj_t *objp, char *led_state)
{
int32_t status = PSVC_SUCCESS;
uint8_t value;
char *physid;
EObj_t *physobjp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
if (strcmp(led_state, PSVC_LED_ON) == 0)
((ELed_t *)objp)->lit_count++;
else if (strcmp(led_state, PSVC_LED_OFF) == 0) {
if (--((ELed_t *)objp)->lit_count > 0) {
return (PSVC_SUCCESS);
} else if (((ELed_t *)objp)->lit_count < 0)
((ELed_t *)objp)->lit_count = 0;
/* Fall through case is when lit_count is 0 */
}
strcpy(objp->previous_state, objp->state);
strcpy(objp->state, led_state);
if (strcmp(led_state, PSVC_LED_OFF) == 0)
value = 0;
else if (strcmp(led_state, PSVC_LED_SLOW_BLINK) == 0)
value = 1;
else if (strcmp(led_state, PSVC_LED_FAST_BLINK) == 0)
value = 2;
else if (strcmp(led_state, PSVC_LED_ON) == 0)
value = 3;
status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
0, &physid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, physid, &physobjp);
if (status != PSVC_SUCCESS)
return (status);
status = ((EPhysDev_t *)physobjp)->set_reg(hdlp, objp->addr_spec,
value);
return (status);
}
static int32_t
i_psvc_get_device_state_9_0(EHdl_t *hdlp, EObj_t *objp, char *pos)
{
int32_t status = PSVC_SUCCESS, matches;
char *sensorid;
EObj_t *sensorp;
char state[32];
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
if (objp->features & PSVC_NORMAL_POS_AV) {
(void) i_psvc_get_assoc_matches(hdlp, objp->label,
PSVC_KS_NORMAL_POS_SENSOR, &matches);
if (matches == 1) {
status = i_psvc_get_assoc_id(hdlp, objp->label,
PSVC_KS_NORMAL_POS_SENSOR, 0, &sensorid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, sensorid, &sensorp);
if (status != PSVC_SUCCESS)
return (status);
status = sensorp->get_attr(hdlp, sensorp,
PSVC_SWITCH_STATE_ATTR, state);
if (status != PSVC_SUCCESS)
return (status);
if (strcmp(state, PSVC_SWITCH_ON) == 0) {
strcpy(pos, PSVC_NORMAL_POS);
return (PSVC_SUCCESS);
}
}
}
if (objp->features & PSVC_DIAG_POS_AV) {
(void) i_psvc_get_assoc_matches(hdlp, objp->label,
PSVC_KS_DIAG_POS_SENSOR, &matches);
if (matches == 1) {
status = i_psvc_get_assoc_id(hdlp, objp->label,
PSVC_KS_DIAG_POS_SENSOR, 0, &sensorid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, sensorid, &sensorp);
if (status != PSVC_SUCCESS)
return (status);
status = sensorp->get_attr(hdlp, sensorp,
PSVC_SWITCH_STATE_ATTR, state);
if (status != PSVC_SUCCESS)
return (status);
if (strcmp(state, PSVC_SWITCH_ON) == 0) {
strcpy(pos, PSVC_DIAG_POS);
return (PSVC_SUCCESS);
}
}
}
if (objp->features & PSVC_LOCK_POS_AV) {
(void) i_psvc_get_assoc_matches(hdlp, objp->label,
PSVC_KS_LOCK_POS_SENSOR, &matches);
if (matches == 1) {
status = i_psvc_get_assoc_id(hdlp, objp->label,
PSVC_KS_LOCK_POS_SENSOR, 0, &sensorid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, sensorid, &sensorp);
if (status != PSVC_SUCCESS)
return (status);
status = sensorp->get_attr(hdlp, sensorp,
PSVC_SWITCH_STATE_ATTR, state);
if (status != PSVC_SUCCESS)
return (status);
if (strcmp(state, PSVC_SWITCH_ON) == 0) {
strcpy(pos, PSVC_LOCKED_POS);
return (PSVC_SUCCESS);
}
}
}
if (objp->features & PSVC_OFF_POS_AV) {
(void) i_psvc_get_assoc_matches(hdlp, objp->label,
PSVC_KS_OFF_POS_SENSOR, &matches);
if (matches == 1) {
status = i_psvc_get_assoc_id(hdlp, objp->label,
PSVC_KS_OFF_POS_SENSOR, 0, &sensorid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, sensorid, &sensorp);
if (status != PSVC_SUCCESS)
return (status);
status = sensorp->get_attr(hdlp, sensorp,
PSVC_SWITCH_STATE_ATTR, state);
if (status != PSVC_SUCCESS)
return (status);
if (strcmp(state, PSVC_SWITCH_ON) == 0) {
strcpy(pos, PSVC_OFF_POS);
return (PSVC_SUCCESS);
}
}
}
/* If we have fallen through till here, something's wrong */
errno = EINVAL;
return (PSVC_FAILURE);
}
static int32_t
i_psvc_get_device_value_10_0(EHdl_t *hdlp, EObj_t *objp, uint8_t *value)
{
int32_t status = PSVC_SUCCESS;
char *physid;
EObj_t *physobjp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
0, &physid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, physid, &physobjp);
if (status != PSVC_SUCCESS)
return (status);
status = ((EPhysDev_t *)physobjp)->get_reg(hdlp, objp->addr_spec,
value);
if (status != PSVC_SUCCESS)
return (status);
if (objp->features & PSVC_CONVERSION_TABLE) {
int32_t m;
char *tid;
uint8_t temp8;
status = i_psvc_get_assoc_matches(hdlp, objp->label,
PSVC_TABLE, &m);
if ((status != PSVC_SUCCESS) || (m != 1)) {
return (status);
}
(void) i_psvc_get_assoc_id(hdlp, objp->label,
PSVC_TABLE, 0, &tid);
status = i_psvc_get_table_value(hdlp, tid, *value, &temp8);
*value = temp8;
}
return (status);
}
static int32_t
i_psvc_get_device_value_10_1(EHdl_t *hdlp, EObj_t *objp, uint8_t *value)
{
int32_t status = PSVC_SUCCESS;
char *physid;
EObj_t *physobjp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
0, &physid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, physid, &physobjp);
if (status != PSVC_SUCCESS)
return (status);
status = ((EPhysDev_t *)physobjp)->get_port(hdlp, objp->addr_spec,
value);
if (status != PSVC_SUCCESS)
return (status);
return (status);
}
static int32_t
i_psvc_set_device_value_10_0(EHdl_t *hdlp, EObj_t *objp, uint8_t *value)
{
int32_t status = PSVC_SUCCESS;
char *physid;
EObj_t *physobjp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
0, &physid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, physid, &physobjp);
if (status != PSVC_SUCCESS)
return (status);
status = ((EPhysDev_t *)physobjp)->set_reg(hdlp, objp->addr_spec,
*value);
return (status);
}
static int32_t
i_psvc_set_device_value_10_1(EHdl_t *hdlp, EObj_t *objp, uint8_t *value)
{
int32_t status = PSVC_SUCCESS;
char *physid;
EObj_t *physobjp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
0, &physid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, physid, &physobjp);
if (status != PSVC_SUCCESS)
return (status);
status = ((EPhysDev_t *)physobjp)->set_port(hdlp, objp->addr_spec,
*value);
return (status);
}
static int32_t
i_psvc_get_device_state_8_0(EHdl_t *hdlp, EObj_t *objp, char *sw_state)
{
int32_t status = PSVC_SUCCESS;
boolean_t active_low;
int32_t bit_value;
char *physid;
EObj_t *physobjp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
0, &physid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, physid, &physobjp);
if (status != PSVC_SUCCESS)
return (status);
status = ((EPhysDev_t *)physobjp)->get_bit(hdlp, objp->addr_spec,
&bit_value);
if (status != PSVC_SUCCESS)
return (status);
active_low = PSVC_IS_ACTIVE_LOW(objp->addr_spec);
if (active_low)
if (bit_value == 0)
strcpy(sw_state, PSVC_SWITCH_ON);
else
strcpy(sw_state, PSVC_SWITCH_OFF);
else
if (bit_value == 0)
strcpy(sw_state, PSVC_SWITCH_OFF);
else
strcpy(sw_state, PSVC_SWITCH_ON);
return (status);
}
static int32_t
i_psvc_set_device_state_8_0(EHdl_t *hdlp, EObj_t *objp, char *sw_state)
{
int32_t status = PSVC_SUCCESS;
boolean_t active_low;
int32_t bit_value;
char *physid;
EObj_t *physobjp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
strcpy(objp->previous_state, objp->state);
strcpy(objp->state, sw_state);
active_low = PSVC_IS_ACTIVE_LOW(objp->addr_spec);
if (active_low)
if (strcmp(sw_state, PSVC_SWITCH_ON) == 0)
bit_value = 0;
else
bit_value = 1;
else
if (strcmp(sw_state, PSVC_SWITCH_ON) == 0)
bit_value = 1;
else
bit_value = 0;
status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
0, &physid);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, physid, &physobjp);
if (status != PSVC_SUCCESS)
return (status);
status = ((EPhysDev_t *)physobjp)->set_bit(hdlp, objp->addr_spec,
bit_value);
return (status);
}
/* LM75 */
static int32_t
i_psvc_get_temperature_11_2(EHdl_t *hdlp, uint64_t aspec, int32_t *temp)
{
int32_t status = PSVC_SUCCESS;
char path[1024];
int32_t fp;
int16_t temp16;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
status = ioctl_retry(fp, I2C_GET_TEMPERATURE, (void *)&temp16);
if (status == -1) {
close(fp);
errno = EIO;
return (PSVC_FAILURE);
}
*temp = temp16;
close(fp);
return (status);
}
/* MAX1617 */
static int32_t
i_psvc_get_temperature_11_4(EHdl_t *hdlp, uint64_t aspec, int32_t *temp)
{
int32_t status = PSVC_SUCCESS;
char path[1024];
int32_t fp;
int16_t temp16;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
status = ioctl_retry(fp, I2C_GET_TEMPERATURE, (void *)&temp16);
if (status == -1) {
close(fp);
errno = EIO;
return (PSVC_FAILURE);
}
*temp = temp16;
close(fp);
return (status);
}
/* PCF8591 */
static int32_t
i_psvc_get_temperature_11_6(EHdl_t *hdlp, uint64_t aspec, int32_t *temp)
{
int32_t status = PSVC_SUCCESS;
char path[1024];
int32_t fp;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
status = ioctl_retry(fp, I2C_GET_INPUT, (void *)temp);
if (status == -1) {
close(fp);
errno = EIO;
return (-1);
}
close(fp);
return (status);
}
/* SSC050 */
static int32_t
i_psvc_get_fanspeed_11_7(EHdl_t *hdlp, uint64_t aspec, int32_t *fan_speed)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
int32_t fp;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
ret = ioctl_retry(fp, I2C_GET_FAN_SPEED, (void *)fan_speed);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
close(fp);
return (status);
}
/* PCF8591 */
static int32_t
i_psvc_get_input_11_6(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
int32_t fp;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
ret = ioctl_retry(fp, I2C_GET_INPUT, (void *)value);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
close(fp);
return (status);
}
/* LTC1427 */
static int32_t
i_psvc_get_output_11_3(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
int32_t fp;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
ret = ioctl_retry(fp, I2C_GET_OUTPUT, (void *)value);
if (ret == -1) {
close(fp);
errno = EIO;
return (PSVC_FAILURE);
}
close(fp);
return (status);
}
/* PCF8591 */
static int32_t
i_psvc_get_output_11_6(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
int32_t fp;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
ret = ioctl_retry(fp, I2C_GET_OUTPUT, (void *)value);
if (ret == -1) {
close(fp);
errno = EIO;
return (PSVC_FAILURE);
}
close(fp);
return (status);
}
/* TDA8444 */
static int32_t
i_psvc_get_output_11_8(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
int32_t fp;
int8_t buf;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
ret = read(fp, &buf, 1);
if (ret == -1) {
close(fp);
errno = EIO;
return (PSVC_FAILURE);
}
*value = buf;
close(fp);
return (status);
}
/* LTC1427 */
static int32_t
i_psvc_set_output_11_3(EHdl_t *hdlp, uint64_t aspec, int32_t value)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
int32_t fp;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
ret = ioctl_retry(fp, I2C_SET_OUTPUT, (void *)&value);
if (ret == -1) {
close(fp);
errno = EIO;
return (PSVC_FAILURE);
}
close(fp);
return (status);
}
/* PCF8591 */
static int32_t
i_psvc_set_output_11_6(EHdl_t *hdlp, uint64_t aspec, int32_t value)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
int32_t fp;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
ret = ioctl_retry(fp, I2C_SET_OUTPUT, (void *)&value);
if (ret == -1) {
close(fp);
errno = EIO;
return (PSVC_FAILURE);
}
close(fp);
return (status);
}
/* TDA8444 */
static int32_t
i_psvc_set_output_11_8(EHdl_t *hdlp, uint64_t aspec, int32_t value)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
int32_t fp;
int8_t buf;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
buf = value;
ret = write(fp, &buf, 1);
if (ret == -1) {
close(fp);
errno = EIO;
return (PSVC_FAILURE);
}
close(fp);
return (status);
}
/* HPC3130 */
static int32_t
i_psvc_get_reg_11_1(EHdl_t *hdlp, uint64_t aspec, uint8_t *value)
{
int32_t ret, status = PSVC_SUCCESS;
uint8_t bitshift, bytemask;
char path[1024];
i2c_reg_t i2cregarg;
int32_t fp;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
i2cregarg.reg_num = PSVC_GET_ASPEC_REG(aspec);
ret = ioctl_retry(fp, I2C_GET_REG, (void *)&i2cregarg);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
bitshift = PSVC_GET_ASPEC_BITSHIFT(aspec);
bytemask = PSVC_GET_ASPEC_BYTEMASK(aspec);
if (value != NULL)
*value = (i2cregarg.reg_value & bytemask) >> bitshift;
close(fp);
return (status);
}
/* SSC050 */
static int32_t
i_psvc_get_reg_11_7(EHdl_t *hdlp, uint64_t aspec, uint8_t *value)
{
int32_t ret, status = PSVC_SUCCESS;
uint8_t bitshift, bytemask;
char path[1024];
i2c_reg_t i2cregarg;
int32_t fp;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
i2cregarg.reg_num = PSVC_GET_ASPEC_REG(aspec);
ret = ioctl_retry(fp, I2C_GET_REG, (void *)&i2cregarg);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
bitshift = PSVC_GET_ASPEC_BITSHIFT(aspec);
bytemask = PSVC_GET_ASPEC_BYTEMASK(aspec);
if (value != NULL)
*value = (i2cregarg.reg_value & bytemask) >> bitshift;
close(fp);
return (status);
}
/* HPC3130 */
static int32_t
i_psvc_set_reg_11_1(EHdl_t *hdlp, uint64_t aspec, int32_t value)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
i2c_reg_t i2cregarg;
int8_t tval;
uint8_t bitshift, bytemask;
int32_t fp;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
bitshift = PSVC_GET_ASPEC_BITSHIFT(aspec);
bytemask = PSVC_GET_ASPEC_BYTEMASK(aspec);
value = value << bitshift;
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
i2cregarg.reg_num = PSVC_GET_ASPEC_REG(aspec);
if (bytemask != 0xFF) {
ret = ioctl_retry(fp, I2C_GET_REG, (void *)&i2cregarg);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
tval = i2cregarg.reg_value;
tval = tval & ~bytemask;
} else
tval = 0;
value = tval | value;
i2cregarg.reg_value = value;
ret = ioctl_retry(fp, I2C_SET_REG, (void *)&i2cregarg);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
close(fp);
return (status);
}
/* SSC050 */
static int32_t
i_psvc_set_reg_11_7(EHdl_t *hdlp, uint64_t aspec, int32_t value)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
i2c_reg_t i2cregarg;
int8_t tval;
uint8_t bitshift, bytemask;
int32_t fp;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
bitshift = PSVC_GET_ASPEC_BITSHIFT(aspec);
bytemask = PSVC_GET_ASPEC_BYTEMASK(aspec);
value = value << bitshift;
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
i2cregarg.reg_num = PSVC_GET_ASPEC_REG(aspec);
if (bytemask != 0xFF) {
ret = ioctl_retry(fp, I2C_GET_REG, (void *)&i2cregarg);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
tval = i2cregarg.reg_value;
tval = tval & ~bytemask;
} else
tval = 0;
value = tval | value;
i2cregarg.reg_value = value;
ret = ioctl_retry(fp, I2C_SET_REG, (void *)&i2cregarg);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
close(fp);
return (status);
}
/* PCF8574 */
static int32_t
i_psvc_get_bit_11_5(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
i2c_bit_t bitarg;
int32_t fp;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
bitarg.bit_num = PSVC_GET_BIT_NUM(aspec);
bitarg.direction = DIR_NO_CHANGE;
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
ret = ioctl_retry(fp, I2C_GET_BIT, (void *)&bitarg);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
*value = bitarg.bit_value;
close(fp);
return (status);
}
/* PCF8574 */
static int32_t
i_psvc_get_port_11_5(EHdl_t *hdlp, uint64_t aspec, uint8_t *value)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
i2c_port_t port;
int32_t fp;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
port.direction = DIR_NO_CHANGE;
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
ret = ioctl_retry(fp, I2C_GET_PORT, (void *)&port);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
*value = port.value;
close(fp);
return (status);
}
/* SSC050 */
static int32_t
i_psvc_get_bit_11_7(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
i2c_bit_t bitarg;
int32_t fp;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
bitarg.bit_num = PSVC_GET_BIT_NUM(aspec);
bitarg.direction = DIR_NO_CHANGE;
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
ret = ioctl_retry(fp, I2C_GET_BIT, (void *)&bitarg);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
*value = bitarg.bit_value;
close(fp);
return (status);
}
/* PCF8574 */
static int32_t
i_psvc_set_bit_11_5(EHdl_t *hdlp, uint64_t aspec, int32_t value)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
i2c_bit_t bitarg;
int32_t fp;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
bitarg.bit_value = value;
bitarg.bit_num = PSVC_GET_BIT_NUM(aspec);
bitarg.direction = DIR_OUTPUT;
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
ret = ioctl_retry(fp, I2C_SET_BIT, (void *)&bitarg);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
close(fp);
return (status);
}
/* PCF8574 */
static int32_t
i_psvc_set_port_11_5(EHdl_t *hdlp, uint64_t aspec, int32_t value)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
i2c_port_t port;
int32_t fp;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
port.value = (uint8_t)value;
port.direction = DIR_NO_CHANGE;
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
ret = ioctl_retry(fp, I2C_SET_PORT, (void *)&port);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
close(fp);
return (status);
}
/* SSC050 */
static int32_t
i_psvc_set_bit_11_7(EHdl_t *hdlp, uint64_t aspec, int32_t value)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
i2c_bit_t bitarg;
int32_t fp;
status = i_psvc_get_devpath(hdlp, aspec, path);
if (status != PSVC_SUCCESS)
return (status);
bitarg.bit_value = value;
bitarg.bit_num = PSVC_GET_BIT_NUM(aspec);
bitarg.direction = DIR_OUTPUT;
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
ret = ioctl_retry(fp, I2C_SET_BIT, (void *)&bitarg);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
close(fp);
return (status);
}
/* AT24 */
static int32_t
i_psvc_probe_11_0(EHdl_t *hdlp, EObj_t *objp)
{
int32_t ret, status = PSVC_SUCCESS;
uint8_t value;
char path[1024];
int32_t fp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
if (status != PSVC_SUCCESS) {
return (status);
}
fp = open(path, O_RDWR);
if (fp == -1) {
return (PSVC_FAILURE);
}
ret = read(fp, &value, 1);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
close(fp);
return (status);
}
/* HPC3130 */
static int32_t
i_psvc_probe_11_1(EHdl_t *hdlp, EObj_t *objp)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
i2c_reg_t reg;
int32_t fp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
if (status != PSVC_SUCCESS)
return (status);
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
reg.reg_num = 0;
ret = ioctl_retry(fp, I2C_GET_REG, (void *)&reg);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
close(fp);
return (status);
}
/* LM75 */
static int32_t
i_psvc_probe_11_2(EHdl_t *hdlp, EObj_t *objp)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
int32_t fp;
int16_t temp16;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
if (status != PSVC_SUCCESS) {
return (status);
}
fp = open(path, O_RDWR);
if (fp == -1) {
return (PSVC_FAILURE);
}
ret = ioctl_retry(fp, I2C_GET_TEMPERATURE, (void *)&temp16);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
close(fp);
return (status);
}
/* LTC1427 */
static int32_t
i_psvc_probe_11_3(EHdl_t *hdlp, EObj_t *objp)
{
int32_t ret, status = PSVC_SUCCESS;
int32_t value;
char path[1024];
int32_t fp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
if (status != PSVC_SUCCESS) {
return (status);
}
fp = open(path, O_RDWR);
if (fp == -1) {
return (PSVC_FAILURE);
}
ret = ioctl_retry(fp, I2C_GET_OUTPUT, (void *)&value);
if (ret == -1) {
close(fp);
errno = EINVAL;
return (-1);
}
ret = ioctl_retry(fp, I2C_SET_OUTPUT, (void *)&value);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
close(fp);
return (status);
}
/* MAX1617 */
static int32_t
i_psvc_probe_11_4(EHdl_t *hdlp, EObj_t *objp)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
int32_t fp;
int16_t temp16;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
if (status != PSVC_SUCCESS) {
return (status);
}
fp = open(path, O_RDWR);
if (fp == -1) {
return (PSVC_FAILURE);
}
ret = ioctl_retry(fp, I2C_GET_TEMPERATURE, (void *)&temp16);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
close(fp);
return (status);
}
/* PCF8574 */
static int32_t
i_psvc_probe_11_5(EHdl_t *hdlp, EObj_t *objp)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
i2c_port_t port;
int32_t fp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
if (status != PSVC_SUCCESS) {
return (status);
}
port.direction = DIR_NO_CHANGE;
fp = open(path, O_RDWR);
if (fp == -1) {
return (PSVC_FAILURE);
}
ret = ioctl_retry(fp, I2C_GET_PORT, (void *)&port);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
close(fp);
return (status);
}
/* PCF8591 */
static int32_t
i_psvc_probe_11_6(EHdl_t *hdlp, EObj_t *objp)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
int32_t arg;
int32_t fp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
if (status != PSVC_SUCCESS)
return (status);
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
ret = ioctl_retry(fp, I2C_GET_INPUT, (void *)&arg);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
close(fp);
return (status);
}
/* SSC050 */
static int32_t
i_psvc_probe_11_7(EHdl_t *hdlp, EObj_t *objp)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
i2c_port_t port;
int32_t fp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
if (status != PSVC_SUCCESS)
return (status);
port.direction = DIR_NO_CHANGE;
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
ret = ioctl_retry(fp, I2C_GET_PORT, (void *)&port);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
close(fp);
return (status);
}
/* TDA8444 */
static int32_t
i_psvc_probe_11_8(EHdl_t *hdlp, EObj_t *objp)
{
int32_t ret, status = PSVC_SUCCESS;
uint8_t value;
char path[1024];
int32_t fp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
if (status != PSVC_SUCCESS)
return (status);
fp = open(path, O_RDWR);
if (fp == -1)
return (PSVC_FAILURE);
ret = read(fp, &value, 1);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
close(fp);
return (status);
}
/* SSC100 */
static int32_t
i_psvc_probe_11_9(EHdl_t *hdlp, EObj_t *objp)
{
int32_t ret, status = PSVC_SUCCESS;
char path[1024];
i2c_reg_t reg;
int32_t fp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
if (status != PSVC_SUCCESS) {
return (status);
}
fp = open(path, O_RDWR);
if (fp == -1) {
return (PSVC_FAILURE);
}
/*
* There are only a few register numbers that are valid numbers to
* read from. 0x10 is one of these registers. Any non-valid registers
* cause unknown behavior to the ssc100 device.
*/
reg.reg_num = 0x10;
ret = ioctl_retry(fp, I2C_GET_REG, (void *)&reg);
if (ret == -1) {
close(fp);
errno = EIO;
return (-1);
}
close(fp);
return (status);
}
/*
* Find start of a section within the config file,
* Returns number of records in the section.
* FILE *fd is set to first data record within section.
*/
static int32_t
i_psvc_find_file_section(FILE *fd, char *start)
{
char *ret;
char buf[BUFSZ];
char name[32];
int found;
fseek(fd, 0, SEEK_SET);
while ((ret = fgets(buf, BUFSZ, fd)) != NULL) {
if (strncmp(start, buf, strlen(start)) == 0)
break;
}
if (ret == NULL) {
errno = EINVAL;
return (-1);
}
found = sscanf(buf, "%s", name);
if (found != 1) {
errno = EINVAL;
return (-1);
} else {
return (0);
}
}
/* compare routine for qsort of str_tbl */
static int32_t
i_psvc_name_compare_qsort(EStringId_t *s1, EStringId_t *s2)
{
return (strcmp(s1->name, s2->name));
}
/* compare routine for bsearch of str_tbl */
static int32_t
i_psvc_name_compare_bsearch(char *s1, EStringId_t *s2)
{
return (strcmp(s1, s2->name));
}
/*
* Determine the initial state of a device.
*/
static int32_t
i_psvc_init_state(EHdl_t *hp, EObj_t *objp)
{
int32_t status = PSVC_SUCCESS;
if (objp->class == PSVC_ON_OFF_SWITCH_CLASS) {
char state[32];
status = objp->get_attr(hp, objp, PSVC_SWITCH_STATE_ATTR,
state);
if (status != PSVC_SUCCESS)
return (status);
if (strcmp(state, PSVC_SWITCH_ON) == 0)
strcpy(objp->state, PSVC_ON);
else
strcpy(objp->state, PSVC_OFF);
}
if (objp->class == PSVC_KEYSWITCH_CLASS) {
char state[32];
status = objp->get_attr(hp, objp, PSVC_SWITCH_STATE_ATTR,
state);
if (status != PSVC_SUCCESS)
return (status);
strcpy(objp->state, state);
}
return (status);
}
/*
* Return the object pointer for the object name passed in.
* Creates the object if this is the first access,
* Returns 0 if successful, -1 if not.
*/
static int32_t
i_psvc_get_obj(EHdl_t *hp, char *dev_name, EObj_t **objp)
{
int32_t i, ret;
int32_t found, key, array;
int32_t class, subclass;
boolean_t presence;
char name[NAMELEN];
char buf[BUFSZ];
char *start;
ETable_Array *tbl_arr;
key = psvc_get_str_key(dev_name);
array = key % PSVC_MAX_TABLE_ARRAYS;
tbl_arr = &(hp->tbl_arry[array]);
for (i = 0; i < tbl_arr->obj_count; ++i) {
if (key == tbl_arr->obj_tbl[i].key) {
if (strcmp(dev_name, tbl_arr->obj_tbl[i].name) == 0) {
if (tbl_arr->obj_tbl[i].type != PSVC_OBJ)
return (-1);
*objp = tbl_arr->obj_tbl[i].objp;
return (0);
}
}
}
if (i_psvc_find_file_section(hp->fp, "OBJECT_INFO") == -1) {
ENV_DEBUG("Couldn't find OBJECT_INFO section", dev_name);
return (-1);
}
fgets(buf, BUFSZ, hp->fp);
while (strcmp(buf, "OBJECT_INFO_END")) {
start = strrchr(buf, '/');
if (start == NULL) {
errno = EINVAL;
return (PSVC_FAILURE);
}
found = sscanf(start + 1, "%s", name);
if (found != 1) {
errno = EINVAL;
return (PSVC_FAILURE);
}
if (strcmp(name, dev_name) == 0) {
if (i_psvc_value(buf, PSVC_CLASS_ATTR, &class)
!= PSVC_SUCCESS)
return (PSVC_FAILURE);
if (i_psvc_value(buf, PSVC_SUBCLASS_ATTR, &subclass)
!= PSVC_SUCCESS)
return (PSVC_FAILURE);
ret = (*i_psvc_constructor[class][subclass])(hp,
dev_name, objp);
if (ret != PSVC_SUCCESS) {
return (-1);
}
ret = (*objp)->get_attr(hp, *objp, PSVC_PRESENCE_ATTR,
&presence);
(*objp)->previous_presence = presence;
if (ret != PSVC_SUCCESS || presence != PSVC_PRESENT)
return (ret);
return (i_psvc_init_state(hp, *objp));
}
fgets(buf, BUFSZ, hp->fp);
}
errno = EINVAL;
return (-1);
}
/*
* Gets the device path associated with an object id.
* Returns 0 if successful, -1 if not.
*/
static int32_t
i_psvc_get_devpath(EHdl_t *hp, uint64_t addr_spec, char *path)
{
int i;
EDevice_t *dp;
uint32_t controller, bus, addr, port;
controller = PSVC_GET_ASPEC_CNTLR(addr_spec);
bus = PSVC_GET_ASPEC_BUSNUM(addr_spec);
addr = PSVC_GET_ASPEC_BUSADDR(addr_spec);
port = PSVC_GET_ASPEC_PORT(addr_spec);
for (i = 0; i < hp->dev_count; ++i) {
dp = &hp->dev_tbl[i];
if (dp->controller == controller &&
dp->bus == bus &&
dp->addr == addr &&
dp->port == port) {
strcpy(path, dp->path);
return (PSVC_SUCCESS);
}
}
errno = EINVAL;
return (PSVC_FAILURE);
}
/* Load the association table */
static int32_t
i_psvc_load_associations(EHdl_t *hp, FILE *fp)
{
uint32_t count;
int found;
int i, j;
char name1[32], name2[32];
char buf[BUFSZ];
EStringId_t *namep;
EAssoc_t *ap;
int32_t id;
int32_t status;
/*
* ignore count in the file, correct count is highest
* association id + 1, now figured when loading ASSOC_STR
* section.
*/
if (i_psvc_find_file_section(fp, "ASSOCIATIONS") != PSVC_SUCCESS)
return (-1);
if ((hp->assoc_tbl = malloc(sizeof (EAssocList_t) * hp->assoc_count))
== NULL) {
return (-1);
}
memset(hp->assoc_tbl, 0, sizeof (EAssocList_t) * hp->assoc_count);
for (i = 0; i < hp->assoc_count; ++i) {
fgets(buf, BUFSZ, fp);
found = sscanf(buf, "%s %s", name1, name2);
if (strcmp("ASSOCIATIONS_END", name1) == 0)
break;
if (found != 2) {
errno = EINVAL;
return (-1);
}
namep = (EStringId_t *)bsearch(name2, hp->othr_tbl,
hp->othr_count, sizeof (EStringId_t),
(int (*)(const void *, const void *))
i_psvc_name_compare_bsearch);
if (namep == NULL) {
errno = EINVAL;
return (-1);
}
id = namep->id;
status = i_psvc_count_records(fp, "ASSOCIATION_END", &count);
if (status != PSVC_SUCCESS)
return (status);
hp->assoc_tbl[id].count = count;
hp->assoc_tbl[id].table =
(EAssoc_t *)malloc(sizeof (EAssoc_t) * count);
if (hp->assoc_tbl[id].table == NULL)
return (-1);
for (j = 0; j < count; ++j) {
ap = &hp->assoc_tbl[id].table[j];
fgets(buf, BUFSZ, fp);
found = sscanf(buf, "%s %s", ap->antecedent_id,
ap->dependent_id);
ap->ant_key = psvc_get_str_key(ap->antecedent_id);
if (found != 2) {
errno = EINVAL;
return (-1);
}
}
fgets(buf, BUFSZ, fp);
if (strncmp(buf, "ASSOCIATION_END", 15) != 0) {
errno = EINVAL;
return (-1);
}
}
return (0);
}
/* Load the table of tables */
static int32_t
i_psvc_load_tables(EHdl_t *hp, FILE *fp)
{
int i, j;
int found;
int ret;
int32_t cell_type;
int64_t *table;
char buf[BUFSZ];
int32_t status;
uint32_t table_count;
int32_t num, key, array;
char name[NAMELEN];
ETable_Array *tbl_arr;
if (i_psvc_find_file_section(fp, "TABLES") != PSVC_SUCCESS)
return (PSVC_SUCCESS); /* no tables */
status = i_psvc_count_tables_associations(fp, &table_count,
"TABLE_END");
if (status != PSVC_SUCCESS || table_count == 0)
return (status);
for (i = 0; i < table_count; ++i) {
int slot;
ETable_t *tblp;
fgets(buf, BUFSZ, fp);
if (strncmp(buf, "TABLE", 5) != 0) {
errno = EINVAL;
return (-1);
}
fgets(buf, BUFSZ, fp);
found = sscanf(buf, "%s %d", name, &cell_type);
key = psvc_get_str_key(name);
array = key % PSVC_MAX_TABLE_ARRAYS;
tbl_arr = &(hp->tbl_arry[array]);
if (tbl_arr->nextid == hp->total_obj_count) {
errno = EINVAL;
return (PSVC_FAILURE);
} else {
slot = tbl_arr->nextid++;
tbl_arr->obj_count++;
}
strcpy(tbl_arr->obj_tbl[slot].name, name);
tblp = (ETable_t *)malloc(sizeof (ETable_t));
if (tblp == NULL)
return (PSVC_FAILURE);
tbl_arr->obj_tbl[slot].key = key;
tbl_arr->obj_tbl[slot].objp = (EObj_t *)(void *)tblp;
tbl_arr->obj_tbl[slot].type = PSVC_TBL;
status = i_psvc_count_table_records(fp, "TABLE_END",
&tblp->size);
if (status != PSVC_SUCCESS)
return (status);
tblp->cell_type = (uint8_t)cell_type;
if (found != 2) {
errno = EINVAL;
return (-1);
}
/* allocate and load table */
tblp->table = (int64_t *)malloc(tblp->size *
i_psvc_cell_size[tblp->cell_type]);
if (tblp->table == NULL) {
return (-1);
}
table = tblp->table;
for (j = 0; j < tblp->size; ++j) {
switch (cell_type) {
case 0:
ret = fscanf(fp, "%d", &num);
*((int8_t *)table + j) = num;
break;
case 1:
ret = fscanf(fp, "%d", &num);
*((uint8_t *)table + j) = (uint8_t)num;
break;
case 2:
ret = fscanf(fp, "%hd",
((int16_t *)table + j));
break;
case 3:
ret = fscanf(fp, "%hd",
((uint16_t *)table + j));
break;
case 4:
ret = fscanf(fp, "%d",
((int32_t *)table + j));
break;
case 5:
ret = fscanf(fp, "%d",
((uint32_t *)table + j));
break;
case 6:
ret = fscanf(fp, "%lld",
((int64_t *)table + j));
break;
case 7:
ret = fscanf(fp, "%lld",
((uint64_t *)table + j));
break;
default:
errno = EINVAL;
return (-1);
}
if (ret != 1) {
errno = EINVAL;
return (-1);
}
}
fgets(buf, BUFSZ, fp); /* reads newline on data line */
fgets(buf, BUFSZ, fp);
if (strncmp(buf, "TABLE_END", 9) != 0) {
errno = EINVAL;
return (-1);
}
}
return (0);
}
static int32_t
i_psvc_destructor(EHdl_t *hdlp, char *name, void *objp)
{
int32_t i, key, array;
key = psvc_get_str_key(name);
array = key % PSVC_MAX_TABLE_ARRAYS;
for (i = 0; i < hdlp->tbl_arry[array].obj_count; ++i) {
if (key == hdlp->tbl_arry[array].obj_tbl[i].key) {
if (strcmp(hdlp->tbl_arry[array].obj_tbl[i].name,
name) == 0) {
hdlp->tbl_arry[array].obj_tbl[i].name[0] = '\0';
if (objp != NULL)
free(objp);
return (PSVC_SUCCESS);
}
}
}
return (PSVC_SUCCESS);
}
static int32_t
i_psvc_get_attr_generic(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id,
void * attrp)
{
int32_t status = PSVC_SUCCESS;
char *parent_id;
switch (attr_id) {
case PSVC_ADDR_SPEC_ATTR:
*(uint64_t *)attrp = objp->addr_spec;
break;
case PSVC_CLASS_ATTR:
*(int32_t *)attrp = objp->class;
break;
case PSVC_SUBCLASS_ATTR:
*(int32_t *)attrp = objp->subclass;
break;
case PSVC_PRESENCE_ATTR:
status = i_psvc_get_presence(hdlp, objp, (boolean_t *)attrp);
break;
case PSVC_PREV_PRESENCE_ATTR:
*(boolean_t *)attrp = objp->previous_presence;
break;
case PSVC_STATE_ATTR:
strcpy((char *)attrp, objp->state);
break;
case PSVC_PREV_STATE_ATTR:
strcpy((char *)attrp, objp->previous_state);
break;
case PSVC_ENABLE_ATTR:
*(boolean_t *)attrp = objp->enabled;
break;
case PSVC_FAULTID_ATTR:
strcpy((char *)attrp, objp->fault_id);
break;
case PSVC_FEATURES_ATTR:
*(uint64_t *)attrp = objp->features;
break;
case PSVC_LABEL_ATTR:
strcpy((char *)attrp, objp->label);
break;
case PSVC_FRUID_ATTR:
while ((objp->features & PSVC_DEV_FRU) == 0) {
status = i_psvc_get_assoc_id(hdlp, objp->label,
PSVC_PARENT, 0, &parent_id);
if (status != PSVC_SUCCESS)
return (status);
status = i_psvc_get_obj(hdlp, parent_id, &objp);
if (status != PSVC_SUCCESS)
return (status);
}
strcpy((char *)attrp, objp->label);
break;
case PSVC_INSTANCE_ATTR:
*(int32_t *)attrp = objp->instance;
break;
default:
errno = EINVAL;
return (PSVC_FAILURE);
}
return (status);
}
static int32_t
i_psvc_set_attr_generic(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id,
void * attrp)
{
int32_t status = PSVC_SUCCESS;
switch (attr_id) {
case PSVC_PREV_PRESENCE_ATTR:
objp->previous_presence = *(boolean_t *)attrp;
break;
case PSVC_STATE_ATTR:
strcpy(objp->previous_state, objp->state);
strcpy(objp->state, (char *)attrp);
break;
case PSVC_ENABLE_ATTR:
objp->enabled = *(boolean_t *)attrp;
break;
case PSVC_FAULTID_ATTR:
strcpy(objp->fault_id, (char *)attrp);
break;
default:
errno = EINVAL;
return (PSVC_FAILURE);
}
return (status);
}
static int32_t
i_psvc_get_attr_0_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
switch (attr_id) {
case PSVC_SENSOR_VALUE_ATTR:
return (i_psvc_get_device_value_0_0(hdlp, objp, attrp));
case PSVC_LO_WARN_ATTR:
*(int32_t *)attrp = ((ETempSensor_t *)objp)->lo_warn;
return (status);
case PSVC_LO_SHUT_ATTR:
*(int32_t *)attrp = ((ETempSensor_t *)objp)->lo_shut;
return (status);
case PSVC_HI_WARN_ATTR:
*(int32_t *)attrp = ((ETempSensor_t *)objp)->hi_warn;
return (status);
case PSVC_HI_SHUT_ATTR:
*(int32_t *)attrp = ((ETempSensor_t *)objp)->hi_shut;
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_get_attr_0_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
switch (attr_id) {
case PSVC_SENSOR_VALUE_ATTR:
return (i_psvc_get_device_value_0_1(hdlp, objp, attrp));
case PSVC_LO_WARN_ATTR:
*(int32_t *)attrp = ((ETempSensor_t *)objp)->lo_warn;
return (status);
case PSVC_LO_SHUT_ATTR:
*(int32_t *)attrp = ((ETempSensor_t *)objp)->lo_shut;
return (status);
case PSVC_HI_WARN_ATTR:
*(int32_t *)attrp = ((ETempSensor_t *)objp)->hi_warn;
return (status);
case PSVC_HI_SHUT_ATTR:
*(int32_t *)attrp = ((ETempSensor_t *)objp)->hi_shut;
return (status);
case PSVC_OPTIMAL_TEMP_ATTR:
*(int32_t *)attrp = ((ETempSensor_t *)objp)->opt_temp;
return (status);
case PSVC_HW_HI_SHUT_ATTR:
*(int32_t *)attrp = ((ETempSensor_t *)objp)->hw_hi_shut;
return (status);
case PSVC_HW_LO_SHUT_ATTR:
*(int32_t *)attrp = ((ETempSensor_t *)objp)->hw_lo_shut;
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_set_attr_0_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
switch (attr_id) {
case PSVC_LO_WARN_ATTR:
((ETempSensor_t *)objp)->lo_warn = *(int32_t *)attrp;
return (status);
case PSVC_LO_SHUT_ATTR:
((ETempSensor_t *)objp)->lo_shut = *(int32_t *)attrp;
return (status);
case PSVC_HI_WARN_ATTR:
((ETempSensor_t *)objp)->hi_warn = *(int32_t *)attrp;
return (status);
case PSVC_HI_SHUT_ATTR:
((ETempSensor_t *)objp)->hi_shut = *(int32_t *)attrp;
return (status);
case PSVC_OPTIMAL_TEMP_ATTR:
((ETempSensor_t *)objp)->opt_temp = *(int32_t *)attrp;
return (status);
case PSVC_HW_HI_SHUT_ATTR:
((ETempSensor_t *)objp)->hw_hi_shut = *(int32_t *)attrp;
return (status);
case PSVC_HW_LO_SHUT_ATTR:
((ETempSensor_t *)objp)->hw_lo_shut = *(int32_t *)attrp;
return (status);
}
status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_get_attr_1_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
switch (attr_id) {
case PSVC_SENSOR_VALUE_ATTR:
return (i_psvc_get_device_value_1_0(hdlp, objp, attrp));
case PSVC_SETPOINT_ATTR:
*(int16_t *)attrp = ((EFan_t *)objp)->setpoint;
return (status);
case PSVC_HYSTERESIS_ATTR:
*(int16_t *)attrp = ((EFan_t *)objp)->hysteresis;
return (status);
case PSVC_LOOPGAIN_ATTR:
*(int16_t *)attrp = ((EFan_t *)objp)->loopgain;
return (status);
case PSVC_LOOPBIAS_ATTR:
*(int16_t *)attrp = ((EFan_t *)objp)->loopbias;
return (status);
case PSVC_TEMP_DIFFERENTIAL_ATTR:
memcpy(attrp, ((EFan_t *)objp)->temp_differential,
sizeof (((EFan_t *)objp)->temp_differential));
return (status);
case PSVC_TEMP_DIFFERENTIAL_INDEX_ATTR:
*(int16_t *)attrp = ((EFan_t *)objp)->temp_differential_index;
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_set_attr_1_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
switch (attr_id) {
case PSVC_TEMP_DIFFERENTIAL_ATTR:
memcpy(((EFan_t *)objp)->temp_differential, attrp,
sizeof (((EFan_t *)objp)->temp_differential));
return (status);
case PSVC_TEMP_DIFFERENTIAL_INDEX_ATTR:
((EFan_t *)objp)->temp_differential_index = *(int16_t *)attrp;
return (status);
case PSVC_SETPOINT_ATTR:
((EFan_t *)objp)->setpoint = *(int16_t *)attrp;
return (status);
}
status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
return (PSVC_SUCCESS);
}
static int32_t
i_psvc_get_attr_2_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
switch (attr_id) {
case PSVC_LED_STATE_ATTR:
case PSVC_STATE_ATTR:
return (i_psvc_get_device_state_2_0(hdlp, objp, attrp));
case PSVC_LED_COLOR_ATTR:
strcpy((char *)attrp, ((ELed_t *)objp)->color);
return (status);
case PSVC_LIT_COUNT_ATTR:
*(int16_t *)attrp = ((ELed_t *)objp)->lit_count;
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_set_attr_2_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
switch (attr_id) {
case PSVC_LED_STATE_ATTR:
case PSVC_STATE_ATTR:
return (i_psvc_set_device_state_2_0(hdlp, objp, attrp));
}
status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_get_attr_2_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
switch (attr_id) {
case PSVC_LED_STATE_ATTR:
case PSVC_STATE_ATTR:
return (i_psvc_get_device_state_2_1(hdlp, objp, attrp));
case PSVC_LED_COLOR_ATTR:
strcpy((char *)attrp, ((ELed_t *)objp)->color);
return (status);
case PSVC_LIT_COUNT_ATTR:
*(int16_t *)attrp = ((ELed_t *)objp)->lit_count;
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_set_attr_2_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
switch (attr_id) {
case PSVC_LED_STATE_ATTR:
case PSVC_STATE_ATTR:
return (i_psvc_set_device_state_2_1(hdlp, objp, attrp));
}
status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_get_attr_2_2(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
switch (attr_id) {
case PSVC_LED_STATE_ATTR:
case PSVC_STATE_ATTR:
return (i_psvc_get_device_state_2_0(hdlp, objp, attrp));
case PSVC_LED_COLOR_ATTR:
strcpy((char *)attrp, ((ELed_t *)objp)->color);
return (status);
case PSVC_LIT_COUNT_ATTR:
*(int16_t *)attrp = ((ELed_t *)objp)->lit_count;
return (status);
case PSVC_LED_IS_LOCATOR_ATTR:
strcpy((char *)attrp, ((ELed_t *)objp)->is_locator);
return (status);
case PSVC_LED_LOCATOR_NAME_ATTR:
strcpy((char *)attrp, ((ELed_t *)objp)->locator_name);
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_get_attr_4_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
switch (attr_id) {
case PSVC_SENSOR_VALUE_ATTR:
return (i_psvc_get_device_value_4_0(hdlp, objp, attrp));
case PSVC_LO_WARN_ATTR:
*(int32_t *)attrp = ((EDigiSensor_t *)objp)->lo_warn;
return (status);
case PSVC_LO_SHUT_ATTR:
*(int32_t *)attrp = ((EDigiSensor_t *)objp)->lo_shut;
return (status);
case PSVC_HI_WARN_ATTR:
*(int32_t *)attrp = ((EDigiSensor_t *)objp)->hi_warn;
return (status);
case PSVC_HI_SHUT_ATTR:
*(int32_t *)attrp = ((EDigiSensor_t *)objp)->hi_shut;
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (PSVC_SUCCESS);
}
static int32_t
i_psvc_get_attr_5_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
if (attr_id == PSVC_CONTROL_VALUE_ATTR) {
return (i_psvc_get_device_value_5_0(hdlp, objp, attrp));
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_set_attr_5_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
if (attr_id == PSVC_CONTROL_VALUE_ATTR) {
return (i_psvc_set_device_value_5_0(hdlp, objp, attrp));
}
status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_get_attr_6_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
switch (attr_id) {
case PSVC_GPIO_VALUE_ATTR:
return (i_psvc_get_device_value_6_0(hdlp, objp, attrp));
case PSVC_GPIO_BITS:
*(int32_t *)attrp = 1;
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_set_attr_6_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
if (attr_id == PSVC_GPIO_VALUE_ATTR) {
return (i_psvc_set_device_value_6_0(hdlp, objp, attrp));
}
status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_get_attr_7_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
switch (attr_id) {
case PSVC_SENSOR_VALUE_ATTR:
return (i_psvc_get_device_value_7_0(hdlp, objp, attrp));
case PSVC_LO_WARN_ATTR:
*(int32_t *)attrp = ((EFanTach_t *)objp)->lo_warn;
return (status);
case PSVC_LO_SHUT_ATTR:
*(int32_t *)attrp = ((EFanTach_t *)objp)->lo_shut;
return (status);
case PSVC_HI_WARN_ATTR:
*(int32_t *)attrp = ((EFanTach_t *)objp)->hi_warn;
return (status);
case PSVC_HI_SHUT_ATTR:
*(int32_t *)attrp = ((EFanTach_t *)objp)->hi_shut;
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (PSVC_SUCCESS);
}
static int32_t
i_psvc_get_attr_8_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
switch (attr_id) {
case PSVC_SWITCH_STATE_ATTR:
case PSVC_STATE_ATTR:
return (i_psvc_get_device_state_8_0(hdlp, objp, attrp));
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_set_attr_8_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
switch (attr_id) {
case PSVC_SWITCH_STATE_ATTR:
case PSVC_STATE_ATTR:
return (i_psvc_set_device_state_8_0(hdlp, objp, attrp));
}
status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_get_attr_9_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
switch (attr_id) {
case PSVC_SWITCH_STATE_ATTR:
case PSVC_STATE_ATTR:
status = i_psvc_get_device_state_9_0(hdlp, objp, attrp);
if ((status == PSVC_FAILURE) && (errno == EINVAL)) {
strcpy((char *)attrp, PSVC_ERROR);
return (PSVC_SUCCESS);
} else {
return (status);
}
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_get_attr_10_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
switch (attr_id) {
case PSVC_GPIO_VALUE_ATTR:
return (i_psvc_get_device_value_10_0(hdlp, objp, attrp));
case PSVC_GPIO_BITS:
*(int32_t *)attrp = 8;
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_set_attr_10_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
if (attr_id == PSVC_GPIO_VALUE_ATTR) {
return (i_psvc_set_device_value_10_0(hdlp, objp, attrp));
}
status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_get_attr_10_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
switch (attr_id) {
case PSVC_GPIO_VALUE_ATTR:
return (i_psvc_get_device_value_10_1(hdlp, objp, attrp));
case PSVC_GPIO_BITS:
*(int32_t *)attrp = 8;
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_set_attr_10_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
if (attr_id == PSVC_GPIO_VALUE_ATTR) {
return (i_psvc_set_device_value_10_1(hdlp, objp, attrp));
}
status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
/* AT24 */
static int32_t
i_psvc_get_attr_11_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
int32_t probe_status;
switch (attr_id) {
case PSVC_PROBE_RESULT_ATTR:
probe_status = i_psvc_probe_11_0(hdlp, objp);
if (probe_status == PSVC_SUCCESS)
strcpy((char *)attrp, PSVC_OK);
else
strcpy((char *)attrp, PSVC_ERROR);
return (status);
case PSVC_FRU_INFO_ATTR:
status = i_psvc_get_reg_11_0(hdlp, objp, attr_id, attrp);
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_get_reg_11_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS, ret;
char path[1024], *data;
int32_t fp, temp_errno;
fru_info_t *fru_data;
fru_data = (fru_info_t *)attrp;
if (objp->present != PSVC_PRESENT) {
errno = ENODEV;
return (PSVC_FAILURE);
}
status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
if (status != PSVC_SUCCESS)
return (status);
fp = open(path, O_RDWR);
if (fp == -1) {
return (PSVC_FAILURE);
}
ret = lseek(fp, fru_data->buf_start, SEEK_SET);
if (ret != fru_data->buf_start) {
temp_errno = errno;
close(fp);
errno = temp_errno;
return (PSVC_FAILURE);
}
data = (char *)malloc(fru_data->read_size);
ret = read(fp, data, fru_data->read_size);
if (ret == -1) {
free(data);
close(fp);
errno = EIO;
return (-1);
}
memcpy(fru_data->buf, data, fru_data->read_size);
free(data);
close(fp);
return (status);
}
static int32_t
i_psvc_get_attr_11_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
int32_t probe_status;
if (attr_id == PSVC_PROBE_RESULT_ATTR) {
probe_status = i_psvc_probe_11_1(hdlp, objp);
if (probe_status == PSVC_SUCCESS)
strcpy((char *)attrp, PSVC_OK);
else
strcpy((char *)attrp, PSVC_ERROR);
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_get_attr_11_2(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
int32_t probe_status;
if (attr_id == PSVC_PROBE_RESULT_ATTR) {
probe_status = i_psvc_probe_11_2(hdlp, objp);
if (probe_status == PSVC_SUCCESS)
strcpy((char *)attrp, PSVC_OK);
else
strcpy((char *)attrp, PSVC_ERROR);
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_get_attr_11_3(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
int32_t probe_status;
if (attr_id == PSVC_PROBE_RESULT_ATTR) {
probe_status = i_psvc_probe_11_3(hdlp, objp);
if (probe_status == PSVC_SUCCESS)
strcpy((char *)attrp, PSVC_OK);
else
strcpy((char *)attrp, PSVC_ERROR);
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_get_attr_11_4(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
int32_t probe_status;
if (attr_id == PSVC_PROBE_RESULT_ATTR) {
probe_status = i_psvc_probe_11_4(hdlp, objp);
if (probe_status == PSVC_SUCCESS)
strcpy((char *)attrp, PSVC_OK);
else
strcpy((char *)attrp, PSVC_ERROR);
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_get_attr_11_5(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
int32_t probe_status;
if (attr_id == PSVC_PROBE_RESULT_ATTR) {
probe_status = i_psvc_probe_11_5(hdlp, objp);
if (probe_status == PSVC_SUCCESS)
strcpy((char *)attrp, PSVC_OK);
else
strcpy((char *)attrp, PSVC_ERROR);
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_get_attr_11_6(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
int32_t probe_status;
if (attr_id == PSVC_PROBE_RESULT_ATTR) {
probe_status = i_psvc_probe_11_6(hdlp, objp);
if (probe_status == PSVC_SUCCESS)
strcpy((char *)attrp, PSVC_OK);
else
strcpy((char *)attrp, PSVC_ERROR);
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_get_attr_11_7(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
int32_t probe_status;
if (attr_id == PSVC_PROBE_RESULT_ATTR) {
probe_status = i_psvc_probe_11_7(hdlp, objp);
if (probe_status == PSVC_SUCCESS)
strcpy((char *)attrp, PSVC_OK);
else
strcpy((char *)attrp, PSVC_ERROR);
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_get_attr_11_8(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
int32_t probe_status;
if (attr_id == PSVC_PROBE_RESULT_ATTR) {
probe_status = i_psvc_probe_11_8(hdlp, objp);
if (probe_status == PSVC_SUCCESS)
strcpy((char *)attrp, PSVC_OK);
else
strcpy((char *)attrp, PSVC_ERROR);
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_get_attr_11_9(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
{
int32_t status = PSVC_SUCCESS;
int32_t probe_status;
if (attr_id == PSVC_PROBE_RESULT_ATTR) {
probe_status = i_psvc_probe_11_9(hdlp, objp);
if (probe_status == PSVC_SUCCESS)
strcpy((char *)attrp, PSVC_OK);
else
strcpy((char *)attrp, PSVC_ERROR);
return (status);
}
status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
return (status);
}
static int32_t
i_psvc_load_generic(
EHdl_t *hdlp,
char *name,
EObj_t **objpp,
char *buf,
int32_t obj_size)
{
int32_t found, key, array;
EObj_t *objp;
char *start;
char cur_device[NAMELEN];
int slot;
ETable_Array *tbl_arr;
key = psvc_get_str_key(name);
array = key % PSVC_MAX_TABLE_ARRAYS;
tbl_arr = &(hdlp->tbl_arry[array]);
if (tbl_arr->nextid == hdlp->total_obj_count) {
errno = EINVAL;
return (PSVC_FAILURE);
} else {
slot = tbl_arr->nextid++;
tbl_arr->obj_count++;
}
if (i_psvc_find_file_section(hdlp->fp, "OBJECT_INFO") != PSVC_SUCCESS)
return (PSVC_FAILURE);
fgets(buf, BUFSZ, hdlp->fp);
while (strcmp(buf, "OBJECT_INFO_END")) {
start = strrchr(buf, '/');
if (start == NULL) {
errno = EINVAL;
return (PSVC_FAILURE);
}
found = sscanf(start + 1, "%s", cur_device);
if (found != 1) {
errno = EINVAL;
return (PSVC_FAILURE);
}
if (strcmp(name, cur_device) == 0) /* found it */
break;
fgets(buf, BUFSZ, hdlp->fp);
}
tbl_arr->obj_tbl[slot].objp = (EObj_t *)malloc(obj_size);
if (tbl_arr->obj_tbl[slot].objp == 0)
return (PSVC_FAILURE);
objp = (EObj_t *)tbl_arr->obj_tbl[slot].objp;
tbl_arr->obj_tbl[slot].type = PSVC_OBJ;
memset(objp, 0, obj_size);
strcpy(objp->label, name);
strcpy(tbl_arr->obj_tbl[slot].name, name);
tbl_arr->obj_tbl[slot].key = key;
if (i_psvc_value(buf, PSVC_CLASS_ATTR, &objp->class) != PSVC_SUCCESS) {
i_psvc_destructor(hdlp, name, objp);
return (PSVC_FAILURE);
}
if (i_psvc_value(buf, PSVC_SUBCLASS_ATTR, &objp->subclass) !=
PSVC_SUCCESS) {
i_psvc_destructor(hdlp, name, objp);
return (PSVC_FAILURE);
}
if (i_psvc_value(buf, PSVC_INSTANCE_ATTR, &objp->instance) !=
PSVC_SUCCESS) {
i_psvc_destructor(hdlp, name, objp);
return (PSVC_FAILURE);
}
if (i_psvc_value(buf, PSVC_FEATURES_ATTR, &objp->features) !=
PSVC_SUCCESS) {
i_psvc_destructor(hdlp, name, objp);
return (PSVC_FAILURE);
}
if (i_psvc_value(buf, PSVC_ADDR_SPEC_ATTR, &objp->addr_spec) !=
PSVC_SUCCESS) {
i_psvc_destructor(hdlp, name, objp);
return (PSVC_FAILURE);
}
if (objp->features & PSVC_DEV_SECONDARY)
objp->enabled = PSVC_DISABLED;
else
objp->enabled = PSVC_ENABLED;
if (PSVC_GET_VERSION(objp->addr_spec) > PSVC_VERSION) {
errno = EINVAL;
i_psvc_destructor(hdlp, name, objp);
return (PSVC_FAILURE);
}
*objpp = objp;
return (PSVC_SUCCESS);
}
static int32_t
i_psvc_not_supported()
{
errno = ENOTSUP;
return (PSVC_FAILURE);
}
/* Temperature sensor */
/* Class 0 Subclass 0 are temperature sensors that cannot be updated */
static int32_t
i_psvc_constructor_0_0(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
ETempSensor_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf,
sizeof (ETempSensor_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (ETempSensor_t *)*objpp;
if (i_psvc_value(buf, PSVC_LO_WARN_ATTR, &dp->lo_warn)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
if (i_psvc_value(buf, PSVC_LO_SHUT_ATTR, &dp->lo_shut)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
if (i_psvc_value(buf, PSVC_HI_WARN_ATTR, &dp->hi_warn)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
if (i_psvc_value(buf, PSVC_HI_SHUT_ATTR, &dp->hi_shut)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
dp->ld.constructor = i_psvc_constructor_0_0;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_0_0;
dp->ld.set_attr = i_psvc_set_attr_generic;
return (0);
}
/* Class 0 Subclass 1 are temperature sensors that can be updated */
static int32_t
i_psvc_constructor_0_1(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
ETempSensor_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf,
sizeof (ETempSensor_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (ETempSensor_t *)*objpp;
if (i_psvc_value(buf, PSVC_LO_WARN_ATTR, &dp->lo_warn)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
if (i_psvc_value(buf, PSVC_LO_SHUT_ATTR, &dp->lo_shut)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
if (i_psvc_value(buf, PSVC_HI_WARN_ATTR, &dp->hi_warn)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
if (i_psvc_value(buf, PSVC_HI_SHUT_ATTR, &dp->hi_shut)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
if ((*objpp)->features & PSVC_OPT_TEMP) {
if (i_psvc_value(buf, PSVC_OPTIMAL_TEMP_ATTR, &dp->opt_temp)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
}
if ((*objpp)->features & PSVC_HW_LOW_SHUT) {
if (i_psvc_value(buf, PSVC_HW_LO_SHUT_ATTR, &dp->hw_lo_shut)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
}
if ((*objpp)->features & PSVC_HW_HIGH_SHUT) {
if (i_psvc_value(buf, PSVC_HW_HI_SHUT_ATTR, &dp->hw_hi_shut)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
}
dp->ld.constructor = i_psvc_constructor_0_1;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_0_1;
dp->ld.set_attr = i_psvc_set_attr_0_1;
return (0);
}
/* Fan */
static int32_t
i_psvc_constructor_1_0(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
EFan_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf,
sizeof (EFan_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (EFan_t *)*objpp;
if (i_psvc_value(buf, PSVC_SETPOINT_ATTR, &dp->setpoint)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
if (i_psvc_value(buf, PSVC_HYSTERESIS_ATTR, &dp->hysteresis)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
if (i_psvc_value(buf, PSVC_LOOPGAIN_ATTR, &dp->loopgain)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
if (i_psvc_value(buf, PSVC_LOOPBIAS_ATTR, &dp->loopbias)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
dp->ld.constructor = i_psvc_constructor_1_0;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_1_0;
dp->ld.set_attr = i_psvc_set_attr_1_0;
return (PSVC_SUCCESS);
}
/* LED */
static int32_t
i_psvc_constructor_2_0(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
ELed_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf,
sizeof (ELed_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (ELed_t *)*objpp;
if (i_psvc_value(buf, PSVC_LED_COLOR_ATTR, dp->color)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
dp->ld.constructor = i_psvc_constructor_2_0;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_2_0;
dp->ld.set_attr = i_psvc_set_attr_2_0;
return (PSVC_SUCCESS);
}
static int32_t
i_psvc_constructor_2_1(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
ELed_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf,
sizeof (ELed_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (ELed_t *)*objpp;
if (i_psvc_value(buf, PSVC_LED_COLOR_ATTR, dp->color)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
dp->ld.constructor = i_psvc_constructor_2_1;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_2_1;
dp->ld.set_attr = i_psvc_set_attr_2_1;
return (PSVC_SUCCESS);
}
static int32_t
i_psvc_constructor_2_2(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
ELed_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf,
sizeof (ELed_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (ELed_t *)*objpp;
if (i_psvc_value(buf, PSVC_LED_COLOR_ATTR, dp->color)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
if (i_psvc_value(buf, PSVC_LED_IS_LOCATOR_ATTR, dp->is_locator)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
if (strcmp(dp->is_locator, PSVC_LOCATOR_TRUE) == 0) {
if (i_psvc_value(buf, PSVC_LED_LOCATOR_NAME_ATTR,
dp->locator_name) != PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
} else {
strcpy(dp->locator_name, "N/A");
}
dp->ld.constructor = i_psvc_constructor_2_2;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_2_2;
dp->ld.set_attr = i_psvc_set_attr_2_0;
return (PSVC_SUCCESS);
}
/* System Device */
static int32_t
i_psvc_constructor_3_0(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
ESystem_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (ESystem_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (ESystem_t *)*objpp;
dp->ld.constructor = i_psvc_constructor_3_0;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_generic;
dp->ld.set_attr = i_psvc_set_attr_generic;
return (PSVC_SUCCESS);
}
/* Digital Sensor */
static int32_t
i_psvc_constructor_4_0(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
EDigiSensor_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf,
sizeof (EDigiSensor_t));
if (status != PSVC_SUCCESS) {
return (status);
}
/* Load class specific info */
dp = (EDigiSensor_t *)*objpp;
if (i_psvc_value(buf, PSVC_LO_WARN_ATTR, &dp->lo_warn)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
if (i_psvc_value(buf, PSVC_LO_SHUT_ATTR, &dp->lo_shut)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
if (i_psvc_value(buf, PSVC_HI_WARN_ATTR, &dp->hi_warn)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
if (i_psvc_value(buf, PSVC_HI_SHUT_ATTR, &dp->hi_shut)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
dp->ld.constructor = i_psvc_constructor_4_0;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_4_0;
dp->ld.set_attr = i_psvc_set_attr_generic;
return (PSVC_SUCCESS);
}
/* Digital Control */
static int32_t
i_psvc_constructor_5_0(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
EDigiControl_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf,
sizeof (EDigiControl_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (EDigiControl_t *)*objpp;
dp->ld.constructor = i_psvc_constructor_5_0;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_5_0;
dp->ld.set_attr = i_psvc_set_attr_5_0;
return (PSVC_SUCCESS);
}
/* Boolean GPIO */
static int32_t
i_psvc_constructor_6_0(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
EBoolSensor_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf,
sizeof (EBoolSensor_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (EBoolSensor_t *)*objpp;
dp->ld.constructor = i_psvc_constructor_6_0;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_6_0;
dp->ld.set_attr = i_psvc_set_attr_6_0;
return (PSVC_SUCCESS);
}
/* Fan Tachometer */
static int32_t
i_psvc_constructor_7_0(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
EFanTach_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf,
sizeof (EFanTach_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (EFanTach_t *)*objpp;
if (i_psvc_value(buf, PSVC_LO_WARN_ATTR, &dp->lo_warn)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
if (i_psvc_value(buf, PSVC_LO_SHUT_ATTR, &dp->lo_shut)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
if (i_psvc_value(buf, PSVC_HI_WARN_ATTR, &dp->hi_warn)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
if (i_psvc_value(buf, PSVC_HI_SHUT_ATTR, &dp->hi_shut)
!= PSVC_SUCCESS) {
i_psvc_destructor(hdlp, id, dp);
return (PSVC_FAILURE);
}
dp->ld.constructor = i_psvc_constructor_7_0;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_7_0;
dp->ld.set_attr = i_psvc_set_attr_generic;
return (PSVC_SUCCESS);
}
/* On Off Switch */
static int32_t
i_psvc_constructor_8_0(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
ESwitch_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf,
sizeof (ESwitch_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (ESwitch_t *)*objpp;
dp->ld.constructor = i_psvc_constructor_8_0;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_8_0;
dp->ld.set_attr = i_psvc_set_attr_8_0;
return (PSVC_SUCCESS);
}
/* Key Switch */
static int32_t
i_psvc_constructor_9_0(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
EKeySwitch_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf,
sizeof (EKeySwitch_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (EKeySwitch_t *)*objpp;
dp->ld.constructor = i_psvc_constructor_9_0;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_9_0;
dp->ld.set_attr = i_psvc_set_attr_generic;
return (PSVC_SUCCESS);
}
/* 8 Bit GPIO , devices with registers, calls get_reg()/set_reg() */
static int32_t
i_psvc_constructor_10_0(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
EGPIO8_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EGPIO8_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (EGPIO8_t *)*objpp;
dp->ld.constructor = i_psvc_constructor_10_0;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_10_0;
dp->ld.set_attr = i_psvc_set_attr_10_0;
return (PSVC_SUCCESS);
}
/* 8 Bit GPIO , devices with ports, calls get_port()/set_port() */
static int32_t
i_psvc_constructor_10_1(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
EGPIO8_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EGPIO8_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (EGPIO8_t *)*objpp;
dp->ld.constructor = i_psvc_constructor_10_1;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_10_1;
dp->ld.set_attr = i_psvc_set_attr_10_1;
return (PSVC_SUCCESS);
}
/* AT24 */
static int32_t
i_psvc_constructor_11_0(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
EPhysDev_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf,
sizeof (EPhysDev_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (EPhysDev_t *)*objpp;
dp->ld.constructor = i_psvc_constructor_11_0;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_11_0;
dp->ld.set_attr = i_psvc_set_attr_generic;
dp->get_temperature = i_psvc_not_supported;
dp->get_fanspeed = i_psvc_not_supported;
dp->get_input = i_psvc_not_supported;
dp->get_bit = i_psvc_not_supported;
dp->set_bit = i_psvc_not_supported;
dp->get_port = i_psvc_not_supported;
dp->set_port = i_psvc_not_supported;
dp->get_output = i_psvc_not_supported;
dp->set_output = i_psvc_not_supported;
dp->get_reg = i_psvc_get_reg_11_0;
dp->set_reg = i_psvc_not_supported;
return (PSVC_SUCCESS);
}
/* HPC3130 */
static int32_t
i_psvc_constructor_11_1(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
EPhysDev_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (EPhysDev_t *)*objpp;
dp->ld.constructor = i_psvc_constructor_11_1;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_11_1;
dp->ld.set_attr = i_psvc_set_attr_generic;
dp->get_temperature = i_psvc_not_supported;
dp->get_fanspeed = i_psvc_not_supported;
dp->get_input = i_psvc_not_supported;
dp->get_bit = i_psvc_not_supported;
dp->set_bit = i_psvc_not_supported;
dp->get_port = i_psvc_not_supported;
dp->set_port = i_psvc_not_supported;
dp->get_output = i_psvc_not_supported;
dp->set_output = i_psvc_not_supported;
dp->get_reg = i_psvc_get_reg_11_1;
dp->set_reg = i_psvc_set_reg_11_1;
return (PSVC_SUCCESS);
}
/* LM75 */
static int32_t
i_psvc_constructor_11_2(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
EPhysDev_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (EPhysDev_t *)*objpp;
dp->ld.constructor = i_psvc_constructor_11_2;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_11_2;
dp->ld.set_attr = i_psvc_set_attr_generic;
dp->get_temperature = i_psvc_get_temperature_11_2;
dp->get_fanspeed = i_psvc_not_supported;
dp->get_input = i_psvc_not_supported;
dp->get_bit = i_psvc_not_supported;
dp->set_bit = i_psvc_not_supported;
dp->get_port = i_psvc_not_supported;
dp->set_port = i_psvc_not_supported;
dp->get_output = i_psvc_not_supported;
dp->set_output = i_psvc_not_supported;
dp->get_reg = i_psvc_not_supported;
dp->set_reg = i_psvc_not_supported;
return (PSVC_SUCCESS);
}
/* LTC1427 */
static int32_t
i_psvc_constructor_11_3(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
EPhysDev_t *dp;
char path[1024];
static int32_t fp = -1;
status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
if (status != PSVC_SUCCESS)
return (status);
/*
* The following code upto and including the open() call is so the
* device driver for the ltc1427 does not get unloaded by the OS at
* any time. This is important as the device driver is a write only
* physical device but DOES keep readable states in the device unitp
* structure (I2C_GET_OUTPUT) as a result this device should not
* be unload while PSVC is up and running
*/
status = i_psvc_get_devpath(hdlp, (*objpp)->addr_spec, path);
if (status != PSVC_SUCCESS) {
return (status);
}
if (fp != -1) close(fp);
fp = open(path, O_RDWR);
if (fp == -1) {
return (PSVC_FAILURE);
}
/* Load class specific info */
dp = (EPhysDev_t *)*objpp;
dp->ld.constructor = i_psvc_constructor_11_3;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_11_3;
dp->ld.set_attr = i_psvc_set_attr_generic;
dp->get_temperature = i_psvc_not_supported;
dp->get_fanspeed = i_psvc_not_supported;
dp->get_input = i_psvc_not_supported;
dp->get_bit = i_psvc_not_supported;
dp->set_bit = i_psvc_not_supported;
dp->get_port = i_psvc_not_supported;
dp->set_port = i_psvc_not_supported;
dp->get_output = i_psvc_get_output_11_3;
dp->set_output = i_psvc_set_output_11_3;
dp->get_reg = i_psvc_not_supported;
dp->set_reg = i_psvc_not_supported;
return (PSVC_SUCCESS);
}
/* MAX1617 */
static int32_t
i_psvc_constructor_11_4(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
EPhysDev_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (EPhysDev_t *)*objpp;
dp->ld.constructor = i_psvc_constructor_11_4;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_11_4;
dp->ld.set_attr = i_psvc_set_attr_generic;
dp->get_temperature = i_psvc_get_temperature_11_4;
dp->get_fanspeed = i_psvc_not_supported;
dp->get_input = i_psvc_not_supported;
dp->get_bit = i_psvc_not_supported;
dp->set_bit = i_psvc_not_supported;
dp->get_port = i_psvc_not_supported;
dp->set_port = i_psvc_not_supported;
dp->get_output = i_psvc_not_supported;
dp->set_output = i_psvc_not_supported;
dp->get_reg = i_psvc_not_supported;
dp->set_reg = i_psvc_not_supported;
return (PSVC_SUCCESS);
}
/* PCF8574 */
static int32_t
i_psvc_constructor_11_5(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
EPhysDev_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (EPhysDev_t *)*objpp;
dp->ld.constructor = i_psvc_constructor_11_5;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_11_5;
dp->ld.set_attr = i_psvc_set_attr_generic;
dp->get_temperature = i_psvc_not_supported;
dp->get_fanspeed = i_psvc_not_supported;
dp->get_input = i_psvc_not_supported;
dp->get_bit = i_psvc_get_bit_11_5;
dp->set_bit = i_psvc_set_bit_11_5;
dp->get_port = i_psvc_get_port_11_5;
dp->set_port = i_psvc_set_port_11_5;
dp->get_output = i_psvc_not_supported;
dp->set_output = i_psvc_not_supported;
dp->get_reg = i_psvc_not_supported;
dp->set_reg = i_psvc_not_supported;
return (PSVC_SUCCESS);
}
/* PCF8591 */
static int32_t
i_psvc_constructor_11_6(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
EPhysDev_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (EPhysDev_t *)*objpp;
dp->ld.constructor = i_psvc_constructor_11_6;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_11_6;
dp->ld.set_attr = i_psvc_set_attr_generic;
dp->get_temperature = i_psvc_get_temperature_11_6;
dp->get_fanspeed = i_psvc_not_supported;
dp->get_input = i_psvc_get_input_11_6;
dp->get_bit = i_psvc_not_supported;
dp->set_bit = i_psvc_not_supported;
dp->get_port = i_psvc_not_supported;
dp->set_port = i_psvc_not_supported;
dp->get_output = i_psvc_get_output_11_6;
dp->set_output = i_psvc_set_output_11_6;
dp->get_reg = i_psvc_not_supported;
dp->set_reg = i_psvc_not_supported;
return (PSVC_SUCCESS);
}
/* SSC050 */
static int32_t
i_psvc_constructor_11_7(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
EPhysDev_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (EPhysDev_t *)*objpp;
dp->ld.constructor = i_psvc_constructor_11_7;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_11_7;
dp->ld.set_attr = i_psvc_set_attr_generic;
dp->get_temperature = i_psvc_not_supported;
dp->get_fanspeed = i_psvc_get_fanspeed_11_7;
dp->get_input = i_psvc_not_supported;
dp->get_bit = i_psvc_get_bit_11_7;
dp->set_bit = i_psvc_set_bit_11_7;
dp->get_port = i_psvc_get_port_11_5; /* same as for class = 11, 5 */
dp->set_port = i_psvc_set_port_11_5;
dp->get_output = i_psvc_not_supported;
dp->set_output = i_psvc_not_supported;
dp->get_reg = i_psvc_get_reg_11_7;
dp->set_reg = i_psvc_set_reg_11_7;
return (PSVC_SUCCESS);
}
/* TDA8444 */
static int32_t
i_psvc_constructor_11_8(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
EPhysDev_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (EPhysDev_t *)*objpp;
dp->ld.constructor = i_psvc_constructor_11_8;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_11_8;
dp->ld.set_attr = i_psvc_set_attr_generic;
dp->get_temperature = i_psvc_not_supported;
dp->get_fanspeed = i_psvc_not_supported;
dp->get_input = i_psvc_not_supported;
dp->get_bit = i_psvc_not_supported;
dp->set_bit = i_psvc_not_supported;
dp->get_port = i_psvc_not_supported;
dp->set_port = i_psvc_not_supported;
dp->get_output = i_psvc_get_output_11_8;
dp->set_output = i_psvc_set_output_11_8;
dp->get_reg = i_psvc_not_supported;
dp->set_reg = i_psvc_not_supported;
return (PSVC_SUCCESS);
}
/* SSC100 */
static int32_t
i_psvc_constructor_11_9(
EHdl_t *hdlp,
char *id,
EObj_t **objpp)
{
int32_t status;
char buf[BUFSZ];
EPhysDev_t *dp;
status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
if (status != PSVC_SUCCESS)
return (status);
/* Load class specific info */
dp = (EPhysDev_t *)*objpp;
dp->ld.constructor = i_psvc_constructor_11_9;
dp->ld.destructor = i_psvc_destructor;
dp->ld.get_attr = i_psvc_get_attr_11_9;
dp->ld.set_attr = i_psvc_set_attr_generic;
dp->get_temperature = i_psvc_not_supported;
dp->get_fanspeed = i_psvc_not_supported;
dp->get_input = i_psvc_not_supported;
dp->get_bit = i_psvc_not_supported;
dp->set_bit = i_psvc_not_supported;
dp->get_port = i_psvc_get_port_11_5; /* Same as for class = 11, 5 */
dp->set_port = i_psvc_set_port_11_5;
dp->get_output = i_psvc_not_supported;
dp->set_output = i_psvc_not_supported;
dp->get_reg = i_psvc_not_supported;
dp->set_reg = i_psvc_not_supported;
return (PSVC_SUCCESS);
}
int32_t
psvc_init(EHdl_t **hdlpp)
{
EHdl_t *hdlp;
int i;
char buf[BUFSZ];
char platform[32];
char filename[256];
int found;
int32_t status;
pthread_mutexattr_t mutex_attr;
uint32_t table_count;
int forward_slash = 47;
int new_line = 10;
char *nl_char;
hdlp = (EHdl_t *)malloc(sizeof (EHdl_t));
if (hdlp == NULL)
return (-1);
memset(hdlp, 0, sizeof (EHdl_t));
/* Initialize the lock */
status = pthread_mutexattr_init(&mutex_attr);
if (status != 0) {
errno = status;
return (-1);
}
status = pthread_mutex_init(&hdlp->mutex, &mutex_attr);
if (status != 0) {
errno = status;
return (-1);
}
pthread_mutexattr_destroy(&mutex_attr);
if (sysinfo(SI_PLATFORM, platform, sizeof (platform)) == -1) {
return (-1);
}
snprintf(filename, sizeof (filename),
"/usr/platform/%s/lib/psvcobj.conf", platform);
if ((hdlp->fp = fopen(filename, "r")) == NULL) {
return (-1);
}
/* Build the association ID lookup table */
hdlp->othr_count = hdlp->assoc_count = ASSOC_STR_TAB_SIZE;
if ((hdlp->othr_tbl = (EStringId_t *)malloc(sizeof (EStringId_t) *
hdlp->othr_count)) == NULL) {
return (-1);
}
for (i = 0; i < hdlp->othr_count; ++i) {
hdlp->othr_tbl[i].id = i;
strcpy(hdlp->othr_tbl[i].name, assoc_str_tab[i]);
}
qsort(hdlp->othr_tbl, hdlp->othr_count, sizeof (EStringId_t),
(int (*)(const void *, const void *))i_psvc_name_compare_qsort);
/* determine total number of objects + tables */
if (i_psvc_find_file_section(hdlp->fp, "OBJECT_INFO") == -1) {
return (-1);
}
if (i_psvc_count_records(hdlp->fp, "OBJECT_INFO_END",
&hdlp->total_obj_count) == -1) {
return (-1);
}
if (i_psvc_find_file_section(hdlp->fp, "TABLES") == PSVC_SUCCESS) {
status = i_psvc_count_tables_associations(hdlp->fp,
&table_count, "TABLE_END");
if (status == PSVC_FAILURE) {
return (status);
}
hdlp->total_obj_count += table_count;
}
/* Allocate object name to object pointer translation table */
for (i = 0; i < PSVC_MAX_TABLE_ARRAYS; i++) {
if ((hdlp->tbl_arry[i].obj_tbl =
(ENamePtr_t *)malloc(
sizeof (ENamePtr_t) *hdlp->total_obj_count)) == NULL) {
return (-1);
}
memset(hdlp->tbl_arry[i].obj_tbl, 0,
sizeof (ENamePtr_t) * hdlp->total_obj_count);
hdlp->tbl_arry[i].obj_count = 0;
}
/* Build the association table */
if (i_psvc_load_associations(hdlp, hdlp->fp) == -1)
return (-1);
/* Build the table of device paths */
if (i_psvc_find_file_section(hdlp->fp, "DEVPATHS") == -1)
return (-1);
if (i_psvc_count_records(hdlp->fp, "DEVPATHS_END",
&hdlp->dev_count) == -1)
return (-1);
if ((hdlp->dev_tbl = (EDevice_t *)malloc(sizeof (EDevice_t) *
hdlp->dev_count)) == NULL) {
return (-1);
}
for (i = 0; i < hdlp->dev_count; ++i) {
fgets(buf, BUFSZ, hdlp->fp);
found = sscanf(buf, "%d %d %x %d",
&hdlp->dev_tbl[i].controller,
&hdlp->dev_tbl[i].bus, &hdlp->dev_tbl[i].addr,
&hdlp->dev_tbl[i].port);
if (found != 4) {
errno = EINVAL;
return (-1);
}
strcpy(hdlp->dev_tbl[i].path, strchr(buf, forward_slash));
/*
* Replace new line character with NUL character
*/
nl_char = strchr(hdlp->dev_tbl[i].path, new_line);
*nl_char = 0;
}
/* Build the table of tables */
if (i_psvc_load_tables(hdlp, hdlp->fp) == -1)
return (-1);
*hdlpp = hdlp;
return (0);
}
int32_t
psvc_fini(EHdl_t *hdlp)
{
int32_t i, j;
ETable_Array *array;
if (hdlp == 0)
return (PSVC_SUCCESS);
for (j = 0; j < PSVC_MAX_TABLE_ARRAYS; j++) {
if (hdlp->tbl_arry[j].obj_tbl != 0) {
array = &(hdlp->tbl_arry[j]);
for (i = 0; i < array->obj_count; ++i) {
if (array->obj_tbl[i].type == PSVC_OBJ) {
if (!array->obj_tbl[i].objp) {
/* Skip non-existent object */
continue;
}
array->obj_tbl[i].objp->destructor(hdlp,
array->obj_tbl[i].objp->label,
array->obj_tbl[i].objp);
}
if (array->obj_tbl[i].type == PSVC_TBL) {
ETable_t *tblp =
(ETable_t *)array->obj_tbl[i].objp;
if (tblp->table != 0)
free(tblp->table);
}
}
free(array->obj_tbl);
}
}
if (hdlp->othr_tbl != 0)
free(hdlp->othr_tbl);
if (hdlp->assoc_tbl != 0) {
for (i = 0; i < hdlp->assoc_count; ++i) {
if (hdlp->assoc_tbl[i].table != 0)
free(hdlp->assoc_tbl[i].table);
}
free(hdlp->assoc_tbl);
}
if (hdlp->dev_tbl != 0)
free(hdlp->dev_tbl);
if (hdlp->fp != 0)
fclose(hdlp->fp);
pthread_mutex_destroy(&hdlp->mutex);
free(hdlp);
return (PSVC_SUCCESS);
}
int32_t
ioctl_retry(int fp, int request, void * arg_pointer)
{
int32_t ret = PSVC_SUCCESS;
int32_t tries = 0;
/*
* Becuase the i2c bus is a multimaster bus we need to protect
* ourselves from bus masters that are not being good bus citizens.
* A retry number of 10 should be sufficient to handle any bad bus
* citizens. After that we will simply say that there is something
* wrong with the ioctl transaction and let it bubble back up.
*/
do {
ret = ioctl(fp, request, arg_pointer);
tries ++;
} while ((ret == -1) && (tries < 10));
return (ret);
}
static int32_t
psvc_get_str_key(char *object)
{
int32_t key = 0;
int i, length;
length = strlen(object);
for (i = 0; i < length; i++) {
if ((object[i] > 47) && (object[i] < 58)) {
key = key + ((object[i] - 50) + 2);
} else {
key = key + object[i];
}
}
return (key);
}