xref: /onnv-gate/usr/src/cmd/picl/plugins/sun4u/psvc/psvcobj/psvcobj.c (revision 1049:434f22a692cd)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
23*1049Sjfrank  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
290Sstevel@tonic-gate /*
300Sstevel@tonic-gate  * This file consists of routines to manage objects in the
310Sstevel@tonic-gate  * "Platform Environment Services Framework". The classes
320Sstevel@tonic-gate  * and subclasses are defined by attributes and methods.
330Sstevel@tonic-gate  * The objects, and their initial, static, attribute values are
340Sstevel@tonic-gate  * specified in a configuration file, "psvcobj.conf".
350Sstevel@tonic-gate  * psvc_init() reads the configuration file and creates a repository
360Sstevel@tonic-gate  * of environmental objects in memory. A client application may manipulate
370Sstevel@tonic-gate  * these objects by invoking the psvc_get_attr(), and psvc_set_attr()
380Sstevel@tonic-gate  * routines with the object's string ID specified as an argument.
390Sstevel@tonic-gate  */
400Sstevel@tonic-gate #include <stdio.h>
410Sstevel@tonic-gate #include <math.h>
420Sstevel@tonic-gate #include <stdlib.h>
430Sstevel@tonic-gate #include <unistd.h>
440Sstevel@tonic-gate #include <stropts.h>
450Sstevel@tonic-gate #include <string.h>
460Sstevel@tonic-gate #include <errno.h>
470Sstevel@tonic-gate #include <fcntl.h>
480Sstevel@tonic-gate #include <pthread.h>
490Sstevel@tonic-gate #include <syslog.h>
500Sstevel@tonic-gate #include <stdarg.h>
510Sstevel@tonic-gate #include <pthread.h>
520Sstevel@tonic-gate #include <sys/systeminfo.h>
530Sstevel@tonic-gate 
540Sstevel@tonic-gate #define	LIBRARY_BUILD 1
550Sstevel@tonic-gate #include <psvc_objects.h>
560Sstevel@tonic-gate #include <psvc_objects_class.h>
570Sstevel@tonic-gate #include <sys/i2c/clients/i2c_client.h>
580Sstevel@tonic-gate 
590Sstevel@tonic-gate /* Mutex used for Daktari Fan speed reading */
600Sstevel@tonic-gate pthread_mutex_t fan_mutex = PTHREAD_MUTEX_INITIALIZER;
610Sstevel@tonic-gate 
620Sstevel@tonic-gate /*LINTLIBRARY*/
630Sstevel@tonic-gate 
640Sstevel@tonic-gate #define	ENV_DEBUG(str, id) printf("%s id %s\n", (str), (id))
650Sstevel@tonic-gate 
660Sstevel@tonic-gate #define	BUFSZ  512
670Sstevel@tonic-gate 
680Sstevel@tonic-gate #define	CLASS_MAX	12
690Sstevel@tonic-gate #define	SUBCLASS_MAX	10
700Sstevel@tonic-gate 
710Sstevel@tonic-gate static int32_t i_psvc_constructor_0_0(EHdl_t *, char *, EObj_t **);
720Sstevel@tonic-gate static int32_t i_psvc_constructor_0_1(EHdl_t *, char *, EObj_t **);
730Sstevel@tonic-gate static int32_t i_psvc_constructor_1_0(EHdl_t *, char *, EObj_t **);
740Sstevel@tonic-gate static int32_t i_psvc_constructor_2_0(EHdl_t *, char *, EObj_t **);
750Sstevel@tonic-gate static int32_t i_psvc_constructor_2_1(EHdl_t *, char *, EObj_t **);
760Sstevel@tonic-gate static int32_t i_psvc_constructor_2_2(EHdl_t *, char *, EObj_t **);
770Sstevel@tonic-gate static int32_t i_psvc_constructor_3_0(EHdl_t *, char *, EObj_t **);
780Sstevel@tonic-gate static int32_t i_psvc_constructor_4_0(EHdl_t *, char *, EObj_t **);
790Sstevel@tonic-gate static int32_t i_psvc_constructor_5_0(EHdl_t *, char *, EObj_t **);
800Sstevel@tonic-gate static int32_t i_psvc_constructor_6_0(EHdl_t *, char *, EObj_t **);
810Sstevel@tonic-gate static int32_t i_psvc_constructor_7_0(EHdl_t *, char *, EObj_t **);
820Sstevel@tonic-gate static int32_t i_psvc_constructor_8_0(EHdl_t *, char *, EObj_t **);
830Sstevel@tonic-gate static int32_t i_psvc_constructor_9_0(EHdl_t *, char *, EObj_t **);
840Sstevel@tonic-gate static int32_t i_psvc_constructor_10_0(EHdl_t *, char *, EObj_t **);
850Sstevel@tonic-gate static int32_t i_psvc_constructor_10_1(EHdl_t *, char *, EObj_t **);
860Sstevel@tonic-gate static int32_t i_psvc_constructor_11_0(EHdl_t *, char *, EObj_t **);
870Sstevel@tonic-gate static int32_t i_psvc_constructor_11_1(EHdl_t *, char *, EObj_t **);
880Sstevel@tonic-gate static int32_t i_psvc_constructor_11_2(EHdl_t *, char *, EObj_t **);
890Sstevel@tonic-gate static int32_t i_psvc_constructor_11_3(EHdl_t *, char *, EObj_t **);
900Sstevel@tonic-gate static int32_t i_psvc_constructor_11_4(EHdl_t *, char *, EObj_t **);
910Sstevel@tonic-gate static int32_t i_psvc_constructor_11_5(EHdl_t *, char *, EObj_t **);
920Sstevel@tonic-gate static int32_t i_psvc_constructor_11_6(EHdl_t *, char *, EObj_t **);
930Sstevel@tonic-gate static int32_t i_psvc_constructor_11_7(EHdl_t *, char *, EObj_t **);
940Sstevel@tonic-gate static int32_t i_psvc_constructor_11_8(EHdl_t *, char *, EObj_t **);
950Sstevel@tonic-gate static int32_t i_psvc_constructor_11_9(EHdl_t *, char *, EObj_t **);
960Sstevel@tonic-gate 
970Sstevel@tonic-gate static int32_t i_psvc_get_obj(EHdl_t *, char *, EObj_t **);
980Sstevel@tonic-gate static int32_t i_psvc_destructor(EHdl_t *, char *, void *);
990Sstevel@tonic-gate static int32_t i_psvc_get_devpath(EHdl_t *, uint64_t, char *);
1000Sstevel@tonic-gate static int32_t i_psvc_get_attr_generic(EHdl_t *, EObj_t *, int32_t, void *);
1010Sstevel@tonic-gate static int32_t i_psvc_get_attr_6_0(EHdl_t *, EObj_t *, int32_t, void *);
1020Sstevel@tonic-gate static int32_t i_psvc_get_reg_11_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id,
1030Sstevel@tonic-gate     void *attrp);
1040Sstevel@tonic-gate static int32_t i_psvc_get_attr_10_1(EHdl_t *, EObj_t *, int32_t, void *);
1050Sstevel@tonic-gate static int32_t psvc_get_str_key(char *object);
1060Sstevel@tonic-gate 
1070Sstevel@tonic-gate int32_t ioctl_retry(int fp, int request, void * arg_pointer);
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate /*
1100Sstevel@tonic-gate  * Method lookup tables
1110Sstevel@tonic-gate  * Update when adding classes or subclasses.
1120Sstevel@tonic-gate  */
1130Sstevel@tonic-gate 
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate /* Lookup method by class, subclass, used when calling method */
1160Sstevel@tonic-gate static int32_t (*i_psvc_constructor[CLASS_MAX][SUBCLASS_MAX])(EHdl_t *,
1170Sstevel@tonic-gate 	char *, EObj_t **) = {
1180Sstevel@tonic-gate {i_psvc_constructor_0_0, i_psvc_constructor_0_1, 0, 0, 0, 0, 0, 0, 0, 0},
1190Sstevel@tonic-gate 	{i_psvc_constructor_1_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1200Sstevel@tonic-gate {i_psvc_constructor_2_0, i_psvc_constructor_2_1, i_psvc_constructor_2_2,
1210Sstevel@tonic-gate 		0, 0, 0, 0, 0, 0, 0},
1220Sstevel@tonic-gate 	{i_psvc_constructor_3_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1230Sstevel@tonic-gate 	{i_psvc_constructor_4_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1240Sstevel@tonic-gate 	{i_psvc_constructor_5_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1250Sstevel@tonic-gate 	{i_psvc_constructor_6_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1260Sstevel@tonic-gate 	{i_psvc_constructor_7_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1270Sstevel@tonic-gate 	{i_psvc_constructor_8_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1280Sstevel@tonic-gate 	{i_psvc_constructor_9_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1290Sstevel@tonic-gate {i_psvc_constructor_10_0, i_psvc_constructor_10_1, 0, 0, 0, 0, 0, 0, 0, 0},
1300Sstevel@tonic-gate {i_psvc_constructor_11_0, i_psvc_constructor_11_1, i_psvc_constructor_11_2,
1310Sstevel@tonic-gate 	i_psvc_constructor_11_3, i_psvc_constructor_11_4,
1320Sstevel@tonic-gate 	i_psvc_constructor_11_5, i_psvc_constructor_11_6,
1330Sstevel@tonic-gate 	i_psvc_constructor_11_7, i_psvc_constructor_11_8,
1340Sstevel@tonic-gate 	i_psvc_constructor_11_9},
1350Sstevel@tonic-gate };
1360Sstevel@tonic-gate 
1370Sstevel@tonic-gate static int32_t i_psvc_cell_size[8] = {1, 1, 2, 2, 4, 4, 8, 8};
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate static struct bits {
1400Sstevel@tonic-gate 	uint64_t	bit;
1410Sstevel@tonic-gate 	char		*label;
1420Sstevel@tonic-gate } feature_bits[] = {
1430Sstevel@tonic-gate {PSVC_DEV_PERM, "PERM="},
1440Sstevel@tonic-gate {PSVC_DEV_HOTPLUG, "HOTPLUG="},
1450Sstevel@tonic-gate {PSVC_DEV_OPTION, "OPTION="},
1460Sstevel@tonic-gate {PSVC_DEV_PRIMARY, "PRIMARY="},
1470Sstevel@tonic-gate {PSVC_DEV_SECONDARY, "SECONDARY="},
1480Sstevel@tonic-gate {PSVC_DEV_RDONLY, "RDONLY="},
1490Sstevel@tonic-gate {PSVC_DEV_RDWR, "RDWR="},
1500Sstevel@tonic-gate {PSVC_DEV_FRU, "FRU="},
1510Sstevel@tonic-gate {PSVC_LOW_WARN, "LO_WARN_MASK="},
1520Sstevel@tonic-gate {PSVC_LOW_SHUT, "LO_SHUT_MASK="},
1530Sstevel@tonic-gate {PSVC_HIGH_WARN, "HI_WARN_MASK="},
1540Sstevel@tonic-gate {PSVC_HIGH_SHUT, "HI_SHUT_MASK="},
1550Sstevel@tonic-gate {PSVC_CONVERSION_TABLE, "CONV_TABLE="},
1560Sstevel@tonic-gate {PSVC_OPT_TEMP, "OPT_TEMP_MASK="},
1570Sstevel@tonic-gate {PSVC_HW_LOW_SHUT, "HW_LO_MASK="},
1580Sstevel@tonic-gate {PSVC_HW_HIGH_SHUT, "HW_HI_MASK="},
1590Sstevel@tonic-gate {PSVC_FAN_DRIVE_PR, "FAN_DRIVE_PR="},
1600Sstevel@tonic-gate {PSVC_TEMP_DRIVEN, "TEMP_DRIVEN="},
1610Sstevel@tonic-gate {PSVC_SPEED_CTRL_PR, "SPEED_CTRL_PR="},
1620Sstevel@tonic-gate {PSVC_FAN_ON_OFF, "FAN_ON_OFF="},
1630Sstevel@tonic-gate {PSVC_CLOSED_LOOP_CTRL, "CLOSED_LOOP_CTRL="},
1640Sstevel@tonic-gate {PSVC_FAN_DRIVE_TABLE_PR, "FAN_DRIVE_TABLE_PR="},
1650Sstevel@tonic-gate {PSVC_DIE_TEMP, "DIE_TEMP="},
1660Sstevel@tonic-gate {PSVC_AMB_TEMP, "AMB_TEMP="},
1670Sstevel@tonic-gate {PSVC_DIGI_SENSOR, "DIGI_SENSOR="},
1680Sstevel@tonic-gate {PSVC_BI_STATE, "BI_STATE="},
1690Sstevel@tonic-gate {PSVC_TRI_STATE, "TRI_STATE="},
1700Sstevel@tonic-gate {PSVC_GREEN, "GREEN="},
1710Sstevel@tonic-gate {PSVC_AMBER, "AMBER="},
1720Sstevel@tonic-gate {PSVC_OUTPUT, "OUTPUT="},
1730Sstevel@tonic-gate {PSVC_INPUT, "INPUT="},
1740Sstevel@tonic-gate {PSVC_BIDIR, "BIDIR="},
1750Sstevel@tonic-gate {PSVC_BIT_POS, "BIT_POS="},
1760Sstevel@tonic-gate {PSVC_VAL_POS, "VAL_POS="},
1770Sstevel@tonic-gate {PSVC_NORMAL_POS_AV, "NORMAL_POS_AV="},
1780Sstevel@tonic-gate {PSVC_DIAG_POS_AV, "DIAG_POS_AV="},
1790Sstevel@tonic-gate {PSVC_LOCK_POS_AV, "LOCK_POS_AV="},
1800Sstevel@tonic-gate {PSVC_OFF_POS_AV, "OFF_POS_AV="},
1810Sstevel@tonic-gate {PSVC_GPIO_PORT, "GPIO_PORT="},
1820Sstevel@tonic-gate {PSVC_GPIO_REG, "GPIO_REG="}
1830Sstevel@tonic-gate };
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate #define	ASSOC_STR_TAB_SIZE 33
1860Sstevel@tonic-gate static char *assoc_str_tab[] = {
1870Sstevel@tonic-gate 	"PSVC_PRESENCE_SENSOR",			/* 0 */
1880Sstevel@tonic-gate 	"PSVC_FAN_ONOFF_SENSOR",		/* 1 */
1890Sstevel@tonic-gate 	"PSVC_FAN_SPEED_TACHOMETER",		/* 2 */
1900Sstevel@tonic-gate 	"PSVC_FAN_PRIM_SEC_SELECTOR",		/* 3 */
1910Sstevel@tonic-gate 	"PSVC_DEV_TEMP_SENSOR",			/* 4 */
1920Sstevel@tonic-gate 	"PSVC_FAN_DRIVE_CONTROL",		/* 5 */
1930Sstevel@tonic-gate 	"PSVC_KS_NORMAL_POS_SENSOR",		/* 6 */
1940Sstevel@tonic-gate 	"PSVC_KS_DIAG_POS_SENSOR",		/* 7 */
1950Sstevel@tonic-gate 	"PSVC_KS_LOCK_POS_SENSOR",		/* 8 */
1960Sstevel@tonic-gate 	"PSVC_KS_OFF_POS_SENSOR",		/* 9 */
1970Sstevel@tonic-gate 	"PSVC_SLOT_FAULT_LED",			/* 10 */
1980Sstevel@tonic-gate 	"PSVC_SLOT_REMOVE_LED",			/* 11 */
1990Sstevel@tonic-gate 	"PSVC_TS_OVERTEMP_LED",			/* 12 */
2000Sstevel@tonic-gate 	"PSVC_PS_I_SENSOR",			/* 13 */
2010Sstevel@tonic-gate 	"PSVC_DEV_FAULT_SENSOR",		/* 14 */
2020Sstevel@tonic-gate 	"PSVC_DEV_FAULT_LED",			/* 15 */
2030Sstevel@tonic-gate 	"PSVC_TABLE",				/* 16 */
2040Sstevel@tonic-gate 	"PSVC_PARENT",				/* 17 */
2050Sstevel@tonic-gate 	"PSVC_CPU",				/* 18 */
2060Sstevel@tonic-gate 	"PSVC_ALTERNATE",			/* 19 */
2070Sstevel@tonic-gate 	"PSVC_HOTPLUG_ENABLE_SWITCH",		/* 20 */
2080Sstevel@tonic-gate 	"PSVC_PS",				/* 21 */
2090Sstevel@tonic-gate 	"PSVC_FAN",				/* 22 */
2100Sstevel@tonic-gate 	"PSVC_TS",				/* 23 */
2110Sstevel@tonic-gate 	"PSVC_DISK",				/* 24 */
2120Sstevel@tonic-gate 	"PSVC_LED",				/* 25 */
2130Sstevel@tonic-gate 	"PSVC_FSP_LED",				/* 26 */
2140Sstevel@tonic-gate 	"PSVC_KEYSWITCH",			/* 27 */
2150Sstevel@tonic-gate 	"PSVC_PCI_CARD",			/* 28 */
2160Sstevel@tonic-gate 	"PSVC_PHYSICAL_DEVICE",			/* 29 */
2170Sstevel@tonic-gate 	"PSVC_DEV_TYPE_SENSOR",			/* 30 */
2180Sstevel@tonic-gate 	"PSVC_FAN_TRAY_FANS",			/* 31 */
2190Sstevel@tonic-gate 	"PSVC_FRU"				/* 32 */
2200Sstevel@tonic-gate };
2210Sstevel@tonic-gate 
2220Sstevel@tonic-gate #define	FEATURE_BITS (sizeof (feature_bits) / sizeof (struct bits))
2230Sstevel@tonic-gate 
2240Sstevel@tonic-gate static struct bitfield {
2250Sstevel@tonic-gate 	int8_t shift;
2260Sstevel@tonic-gate 	char   *label;
2270Sstevel@tonic-gate 	char   *format;
2280Sstevel@tonic-gate } addr_fields[] =
2290Sstevel@tonic-gate {
2300Sstevel@tonic-gate {PSVC_VERSION_SHIFT, "VERSION=", "%d"},
2310Sstevel@tonic-gate {PSVC_ACTIVE_LOW_SHIFT, "ACTIVE_LOW=", "%d"},
2320Sstevel@tonic-gate {PSVC_BIT_NUM_SHIFT, "BIT_NUM=", "%d"},
2330Sstevel@tonic-gate {PSVC_INVERT_SHIFT, "INVERT=", "%d"},
2340Sstevel@tonic-gate {PSVC_PORT_SHIFT, "PORT=", "%d"},
2350Sstevel@tonic-gate {PSVC_BITSHIFT_SHIFT, "BITSHIFT=", "%d"},
2360Sstevel@tonic-gate {PSVC_BYTEMASK_SHIFT, "BYTEMASK=", "%x"},
2370Sstevel@tonic-gate {PSVC_REG_SHIFT, "REG=", "%d"},
2380Sstevel@tonic-gate {PSVC_TYPE_SHIFT, "TYPE=", "%d"},
2390Sstevel@tonic-gate {PSVC_BUSADDR_SHIFT, "BUSADDR=", "%x"},
2400Sstevel@tonic-gate {PSVC_BUSNUM_SHIFT, "BUSNUM=", "%d"},
2410Sstevel@tonic-gate {PSVC_CNTLR_SHIFT, "CNTLR=", "%d"},
2420Sstevel@tonic-gate };
2430Sstevel@tonic-gate #define	ADDR_BITFIELDS (sizeof (addr_fields) / sizeof (struct bitfield))
2440Sstevel@tonic-gate 
2450Sstevel@tonic-gate /*
2460Sstevel@tonic-gate  * record format is:
2470Sstevel@tonic-gate  * pathname label1=val1,label2=val2,label3=val3
2480Sstevel@tonic-gate  * Must be a space after the pathname and a comma between variables.
2490Sstevel@tonic-gate  */
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate static char *
find_label(char * str,char * label)2520Sstevel@tonic-gate find_label(char *str, char *label)
2530Sstevel@tonic-gate {
2540Sstevel@tonic-gate 	char *start;
2550Sstevel@tonic-gate 
2560Sstevel@tonic-gate 	start = strchr(str, ' ');
2570Sstevel@tonic-gate 	if (start == NULL)
2580Sstevel@tonic-gate 		return (start);
2590Sstevel@tonic-gate 
2600Sstevel@tonic-gate 	do {
2610Sstevel@tonic-gate 		++start;
2620Sstevel@tonic-gate 		if (strncmp(start, label, strlen(label)) == 0)
2630Sstevel@tonic-gate 			return (start);
2640Sstevel@tonic-gate 
2650Sstevel@tonic-gate 		start = strchr(start, ',');
2660Sstevel@tonic-gate 	} while (start != NULL);
2670Sstevel@tonic-gate 
2680Sstevel@tonic-gate 	return (NULL);
2690Sstevel@tonic-gate }
2700Sstevel@tonic-gate 
2710Sstevel@tonic-gate static int32_t
i_psvc_value(char * buf,int32_t attr_id,void * attrp)2720Sstevel@tonic-gate i_psvc_value(char *buf, int32_t attr_id, void *attrp)
2730Sstevel@tonic-gate {
2740Sstevel@tonic-gate 	char *val;
2750Sstevel@tonic-gate 	uint32_t temp32;
2760Sstevel@tonic-gate 	uint64_t temp64;
2770Sstevel@tonic-gate 	uint64_t result;
2780Sstevel@tonic-gate 	int32_t i;
2790Sstevel@tonic-gate 	int32_t found;
2800Sstevel@tonic-gate 	char label[64];
2810Sstevel@tonic-gate 	int val_size;
2820Sstevel@tonic-gate 	int label_size;
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate 
2850Sstevel@tonic-gate 	switch (attr_id) {
2860Sstevel@tonic-gate 	case PSVC_CLASS_ATTR:
2870Sstevel@tonic-gate 	case PSVC_SUBCLASS_ATTR:
2880Sstevel@tonic-gate 	case PSVC_INSTANCE_ATTR:
2890Sstevel@tonic-gate 	case PSVC_LO_WARN_ATTR:
2900Sstevel@tonic-gate 	case PSVC_LO_SHUT_ATTR:
2910Sstevel@tonic-gate 	case PSVC_HI_WARN_ATTR:
2920Sstevel@tonic-gate 	case PSVC_HI_SHUT_ATTR:
2930Sstevel@tonic-gate 	case PSVC_HW_HI_SHUT_ATTR:
2940Sstevel@tonic-gate 	case PSVC_HW_LO_SHUT_ATTR:
2950Sstevel@tonic-gate 	case PSVC_OPTIMAL_TEMP_ATTR:
2960Sstevel@tonic-gate 		snprintf(label, sizeof (label), "%s=", attr_str_tab[attr_id]);
2970Sstevel@tonic-gate 		val = find_label(buf, label);
2980Sstevel@tonic-gate 		if (val == NULL) {
2990Sstevel@tonic-gate 			errno = EINVAL;
3000Sstevel@tonic-gate 			return (PSVC_FAILURE);
3010Sstevel@tonic-gate 		}
3020Sstevel@tonic-gate 		found = sscanf(val + strlen(label),
3030Sstevel@tonic-gate 			"%d", (int32_t *)attrp);
3040Sstevel@tonic-gate 		if (found == 0)
3050Sstevel@tonic-gate 			*(int32_t *)attrp = 0;
3060Sstevel@tonic-gate 		break;
3070Sstevel@tonic-gate 	case PSVC_SETPOINT_ATTR:
3080Sstevel@tonic-gate 	case PSVC_HYSTERESIS_ATTR:
3090Sstevel@tonic-gate 	case PSVC_LOOPGAIN_ATTR:
3100Sstevel@tonic-gate 	case PSVC_LOOPBIAS_ATTR:
3110Sstevel@tonic-gate 		snprintf(label, sizeof (label), "%s=", attr_str_tab[attr_id]);
3120Sstevel@tonic-gate 		val = find_label(buf, label);
3130Sstevel@tonic-gate 		if (val == NULL) {
3140Sstevel@tonic-gate 			errno = EINVAL;
3150Sstevel@tonic-gate 			return (PSVC_FAILURE);
3160Sstevel@tonic-gate 		}
3170Sstevel@tonic-gate 
3180Sstevel@tonic-gate 		found = sscanf(val + strlen(label), "%hd", (int16_t *)attrp);
3190Sstevel@tonic-gate 		if (found == 0)
3200Sstevel@tonic-gate 			*(int16_t *)attrp = 0;
3210Sstevel@tonic-gate 		break;
3220Sstevel@tonic-gate 	case PSVC_LED_COLOR_ATTR:
3230Sstevel@tonic-gate 	case PSVC_LED_IS_LOCATOR_ATTR:
3240Sstevel@tonic-gate 	case PSVC_LED_LOCATOR_NAME_ATTR:
3250Sstevel@tonic-gate 		snprintf(label, sizeof (label), "%s=", attr_str_tab[attr_id]);
3260Sstevel@tonic-gate 		val = find_label(buf, label);
3270Sstevel@tonic-gate 		if (val == NULL) {
3280Sstevel@tonic-gate 			errno = EINVAL;
3290Sstevel@tonic-gate 			return (PSVC_FAILURE);
3300Sstevel@tonic-gate 		}
3310Sstevel@tonic-gate 		val_size = strlen(val);
3320Sstevel@tonic-gate 		label_size = strlen(label);
3330Sstevel@tonic-gate 
3340Sstevel@tonic-gate 		for (i = 0; i < val_size && val[i] != ','; i++);
3350Sstevel@tonic-gate 		if (i < strlen(val) - 1) {
3360Sstevel@tonic-gate 			strncpy((char *)attrp, val+label_size,
3370Sstevel@tonic-gate 				i - label_size);
3380Sstevel@tonic-gate 		} else
3390Sstevel@tonic-gate 		found = sscanf(val + label_size, "%s", (char *)attrp);
3400Sstevel@tonic-gate 		if (found == 0)
3410Sstevel@tonic-gate 			strcpy((char *)attrp, "");
3420Sstevel@tonic-gate 		break;
3430Sstevel@tonic-gate 	case PSVC_FEATURES_ATTR:
3440Sstevel@tonic-gate 		result = 0;
3450Sstevel@tonic-gate 		for (i = 0; i < FEATURE_BITS; ++i) {
3460Sstevel@tonic-gate 			val = find_label(buf, feature_bits[i].label);
3470Sstevel@tonic-gate 			if (val == NULL)
3480Sstevel@tonic-gate 				continue;
3490Sstevel@tonic-gate 			found = sscanf(val + strlen(feature_bits[i].label),
3500Sstevel@tonic-gate 				"%d", &temp32);
3510Sstevel@tonic-gate 			if (found != 0) {
3520Sstevel@tonic-gate 				if (temp32 == 1)
3530Sstevel@tonic-gate 					result |= feature_bits[i].bit;
3540Sstevel@tonic-gate 			}
3550Sstevel@tonic-gate 		}
3560Sstevel@tonic-gate 		*(uint64_t *)attrp = result;
3570Sstevel@tonic-gate 		break;
3580Sstevel@tonic-gate 	case PSVC_ADDR_SPEC_ATTR:
3590Sstevel@tonic-gate 		result = 0;
3600Sstevel@tonic-gate 		for (i = 0; i < ADDR_BITFIELDS; ++i) {
3610Sstevel@tonic-gate 			val = find_label(buf, addr_fields[i].label);
3620Sstevel@tonic-gate 			if (val == NULL)
3630Sstevel@tonic-gate 				continue;
3640Sstevel@tonic-gate 			found = sscanf(val + strlen(addr_fields[i].label),
3650Sstevel@tonic-gate 				addr_fields[i].format, &temp32);
3660Sstevel@tonic-gate 			if (found != 0) {
3670Sstevel@tonic-gate 				temp64 = temp32;
3680Sstevel@tonic-gate 				temp64 <<= addr_fields[i].shift;
3690Sstevel@tonic-gate 				result |= temp64;
3700Sstevel@tonic-gate 			}
3710Sstevel@tonic-gate 		}
3720Sstevel@tonic-gate 		*(uint64_t *)attrp = result;
3730Sstevel@tonic-gate 		break;
3740Sstevel@tonic-gate 	default:
3750Sstevel@tonic-gate 		errno = EINVAL;
3760Sstevel@tonic-gate 		return (PSVC_FAILURE);
3770Sstevel@tonic-gate 	}
3780Sstevel@tonic-gate 	return (PSVC_SUCCESS);
3790Sstevel@tonic-gate }
3800Sstevel@tonic-gate 
3810Sstevel@tonic-gate /* determine number of records in file section */
3820Sstevel@tonic-gate static int32_t
i_psvc_count_records(FILE * fp,char * end,uint32_t * countp)3830Sstevel@tonic-gate i_psvc_count_records(FILE *fp, char *end, uint32_t *countp)
3840Sstevel@tonic-gate {
3850Sstevel@tonic-gate 	long first_record;
3860Sstevel@tonic-gate 	char *ret;
3870Sstevel@tonic-gate 	char buf[BUFSZ];
3880Sstevel@tonic-gate 	uint32_t count = 0;
3890Sstevel@tonic-gate 
3900Sstevel@tonic-gate 	first_record = ftell(fp);
3910Sstevel@tonic-gate 
3920Sstevel@tonic-gate 	while ((ret = fgets(buf, BUFSZ, fp)) != NULL) {
3930Sstevel@tonic-gate 		if (strncmp(end, buf, strlen(end)) == 0)
3940Sstevel@tonic-gate 			break;
3950Sstevel@tonic-gate 		++count;
3960Sstevel@tonic-gate 	}
3970Sstevel@tonic-gate 
3980Sstevel@tonic-gate 	if (ret == NULL) {
3990Sstevel@tonic-gate 		errno = EINVAL;
4000Sstevel@tonic-gate 		return (PSVC_FAILURE);
4010Sstevel@tonic-gate 	}
4020Sstevel@tonic-gate 
4030Sstevel@tonic-gate 	fseek(fp, first_record, SEEK_SET);
4040Sstevel@tonic-gate 	*countp = count;
4050Sstevel@tonic-gate 	return (PSVC_SUCCESS);
4060Sstevel@tonic-gate }
4070Sstevel@tonic-gate 
4080Sstevel@tonic-gate /* determine number of records in file section */
4090Sstevel@tonic-gate static int32_t
i_psvc_count_tables_associations(FILE * fp,uint32_t * countp,char * end)4100Sstevel@tonic-gate i_psvc_count_tables_associations(FILE *fp, uint32_t *countp, char *end)
4110Sstevel@tonic-gate {
4120Sstevel@tonic-gate 	long first_record;
4130Sstevel@tonic-gate 	char *ret;
4140Sstevel@tonic-gate 	char buf[BUFSZ];
4150Sstevel@tonic-gate 	uint32_t count = 0;
4160Sstevel@tonic-gate 
4170Sstevel@tonic-gate 	first_record = ftell(fp);
4180Sstevel@tonic-gate 
4190Sstevel@tonic-gate 	while ((ret = fgets(buf, BUFSZ, fp)) != NULL) {
4200Sstevel@tonic-gate 		if (strncmp(end, buf, strlen(end)) == 0)
4210Sstevel@tonic-gate 			++count;
4220Sstevel@tonic-gate 	}
4230Sstevel@tonic-gate #ifdef	lint
4240Sstevel@tonic-gate 	ret = ret;
4250Sstevel@tonic-gate #endif
4260Sstevel@tonic-gate 
4270Sstevel@tonic-gate 	fseek(fp, first_record, SEEK_SET);
4280Sstevel@tonic-gate 	*countp = count;
4290Sstevel@tonic-gate 	return (PSVC_SUCCESS);
4300Sstevel@tonic-gate }
4310Sstevel@tonic-gate 
4320Sstevel@tonic-gate /* determine number of records in a table */
4330Sstevel@tonic-gate static int32_t
i_psvc_count_table_records(FILE * fp,char * end,uint32_t * countp)4340Sstevel@tonic-gate i_psvc_count_table_records(FILE *fp, char *end, uint32_t *countp)
4350Sstevel@tonic-gate {
4360Sstevel@tonic-gate 	long first_record;
4370Sstevel@tonic-gate 	int ret;
4380Sstevel@tonic-gate 	char string[BUFSZ];
4390Sstevel@tonic-gate 	uint32_t count = 0;
4400Sstevel@tonic-gate 
4410Sstevel@tonic-gate 	first_record = ftell(fp);
4420Sstevel@tonic-gate 
4430Sstevel@tonic-gate 	while ((ret = fscanf(fp, "%s", string)) == 1) {
4440Sstevel@tonic-gate 		if (strncmp(end, string, strlen(end)) == 0)
4450Sstevel@tonic-gate 			break;
4460Sstevel@tonic-gate 		++count;
4470Sstevel@tonic-gate 	}
4480Sstevel@tonic-gate 
4490Sstevel@tonic-gate 	if (ret != 1) {
4500Sstevel@tonic-gate 		errno = EINVAL;
4510Sstevel@tonic-gate 		return (PSVC_FAILURE);
4520Sstevel@tonic-gate 	}
4530Sstevel@tonic-gate 
4540Sstevel@tonic-gate 	fseek(fp, first_record, SEEK_SET);
4550Sstevel@tonic-gate 	*countp = count;
4560Sstevel@tonic-gate 	return (PSVC_SUCCESS);
4570Sstevel@tonic-gate }
4580Sstevel@tonic-gate 
4590Sstevel@tonic-gate /*
4600Sstevel@tonic-gate  * Find number of matches to an antecedent_id of a certain
4610Sstevel@tonic-gate  * association type.
4620Sstevel@tonic-gate  */
4630Sstevel@tonic-gate static int32_t
i_psvc_get_assoc_matches(EHdl_t * hdlp,char * antecedent,int32_t assoc_id,int32_t * matches)4640Sstevel@tonic-gate i_psvc_get_assoc_matches(EHdl_t *hdlp, char *antecedent, int32_t assoc_id,
4650Sstevel@tonic-gate 	int32_t *matches)
4660Sstevel@tonic-gate {
4670Sstevel@tonic-gate 	int i;
4680Sstevel@tonic-gate 	int32_t key;
4690Sstevel@tonic-gate 	EAssocList_t *ap = hdlp->assoc_tbl + assoc_id;
4700Sstevel@tonic-gate 
4710Sstevel@tonic-gate 	*matches = 0;
4720Sstevel@tonic-gate 
4730Sstevel@tonic-gate 	if (ap->table == 0) {
4740Sstevel@tonic-gate 		errno = EINVAL;
4750Sstevel@tonic-gate 		return (PSVC_FAILURE);
4760Sstevel@tonic-gate 	}
4770Sstevel@tonic-gate 
4780Sstevel@tonic-gate 	key = psvc_get_str_key(antecedent);
4790Sstevel@tonic-gate 
4800Sstevel@tonic-gate 	for (i = 0; i < ap->count; ++i) {
4810Sstevel@tonic-gate 		if (ap->table[i].ant_key == key) {
4820Sstevel@tonic-gate 			if (strcmp(ap->table[i].antecedent_id, antecedent)
4830Sstevel@tonic-gate 			    == 0)
4840Sstevel@tonic-gate 				++*matches;
4850Sstevel@tonic-gate 		}
4860Sstevel@tonic-gate 	}
4870Sstevel@tonic-gate 	return (PSVC_SUCCESS);
4880Sstevel@tonic-gate }
4890Sstevel@tonic-gate 
4900Sstevel@tonic-gate /*
4910Sstevel@tonic-gate  * Find 1st m matches to an antecedent_id of a certain
4920Sstevel@tonic-gate  * association type.
4930Sstevel@tonic-gate  * Returns zero for success, -1 for failure.
4940Sstevel@tonic-gate  */
4950Sstevel@tonic-gate static int32_t
i_psvc_get_assoc_id(EHdl_t * hdlp,char * antecedent,int32_t assoc_id,int32_t match,char ** id_list)4960Sstevel@tonic-gate i_psvc_get_assoc_id(EHdl_t *hdlp, char *antecedent, int32_t assoc_id,
4970Sstevel@tonic-gate 	int32_t match, char **id_list)
4980Sstevel@tonic-gate {
4990Sstevel@tonic-gate 	int i;
5000Sstevel@tonic-gate 	int found = 0;
5010Sstevel@tonic-gate 	int32_t key;
5020Sstevel@tonic-gate 	EAssocList_t *ap = &hdlp->assoc_tbl[assoc_id];
5030Sstevel@tonic-gate 
5040Sstevel@tonic-gate 	if (ap->table == 0) {
5050Sstevel@tonic-gate 		errno = EINVAL;
5060Sstevel@tonic-gate 		return (-1);
5070Sstevel@tonic-gate 	}
5080Sstevel@tonic-gate 
5090Sstevel@tonic-gate 	key = psvc_get_str_key(antecedent);
5100Sstevel@tonic-gate 
5110Sstevel@tonic-gate 	for (i = 0; i < ap->count; ++i) {
5120Sstevel@tonic-gate 		if (ap->table[i].ant_key == key) {
5130Sstevel@tonic-gate 			if (strcmp(ap->table[i].antecedent_id, antecedent)
5140Sstevel@tonic-gate 			    == 0) {
5150Sstevel@tonic-gate 				if (found == match) {
5160Sstevel@tonic-gate 					*id_list = ap->table[i].dependent_id;
5170Sstevel@tonic-gate 					return (0);
5180Sstevel@tonic-gate 				}
5190Sstevel@tonic-gate 				++found;
5200Sstevel@tonic-gate 			}
5210Sstevel@tonic-gate 		}
5220Sstevel@tonic-gate 	}
5230Sstevel@tonic-gate 
5240Sstevel@tonic-gate 	errno = EINVAL;
5250Sstevel@tonic-gate 	return (-1);
5260Sstevel@tonic-gate }
5270Sstevel@tonic-gate 
5280Sstevel@tonic-gate static int32_t
i_psvc_get_table_value(EHdl_t * hdlp,char * table_id,uint32_t index,void * value)5290Sstevel@tonic-gate i_psvc_get_table_value(EHdl_t *hdlp, char *table_id, uint32_t index,
5300Sstevel@tonic-gate 	void *value)
5310Sstevel@tonic-gate {
5320Sstevel@tonic-gate 	int32_t i;
5330Sstevel@tonic-gate 	ETable_t *tblp;
5340Sstevel@tonic-gate 	ETable_Array *tbl_arr;
5350Sstevel@tonic-gate 	int32_t key, array;
5360Sstevel@tonic-gate 
5370Sstevel@tonic-gate 	key = psvc_get_str_key(table_id);
5380Sstevel@tonic-gate 	array = key % PSVC_MAX_TABLE_ARRAYS;
5390Sstevel@tonic-gate 	tbl_arr = &(hdlp->tbl_arry[array]);
5400Sstevel@tonic-gate 
5410Sstevel@tonic-gate 	for (i = 0; i < tbl_arr->obj_count; ++i) {
5420Sstevel@tonic-gate 		if (key == tbl_arr->obj_tbl[i].key) {
5430Sstevel@tonic-gate 			if (strcmp(tbl_arr->obj_tbl[i].name,
5440Sstevel@tonic-gate 				table_id) == 0)
5450Sstevel@tonic-gate 				break;
5460Sstevel@tonic-gate 		}
5470Sstevel@tonic-gate 	}
5480Sstevel@tonic-gate 
5490Sstevel@tonic-gate 	if (tbl_arr->obj_tbl[i].type != PSVC_TBL)
5500Sstevel@tonic-gate 		return (PSVC_FAILURE);
5510Sstevel@tonic-gate 
5520Sstevel@tonic-gate 	tblp = (ETable_t *)tbl_arr->obj_tbl[i].objp;
5530Sstevel@tonic-gate 
5540Sstevel@tonic-gate 	if (tblp->table == NULL)
5550Sstevel@tonic-gate 		return (PSVC_FAILURE);
5560Sstevel@tonic-gate 
5570Sstevel@tonic-gate 	if (index >= tblp->size)
5580Sstevel@tonic-gate 		return (PSVC_FAILURE);
5590Sstevel@tonic-gate 
5600Sstevel@tonic-gate 	switch (tblp->cell_type) {
5610Sstevel@tonic-gate 		case 0:
5620Sstevel@tonic-gate 			*(int8_t *)value = *((int8_t *)tblp->table + index);
5630Sstevel@tonic-gate 			break;
5640Sstevel@tonic-gate 		case 1:
5650Sstevel@tonic-gate 			*(uint8_t *)value = *((uint8_t *)tblp->table + index);
5660Sstevel@tonic-gate 			break;
5670Sstevel@tonic-gate 		case 2:
5680Sstevel@tonic-gate 			*(int16_t *)value = *((int16_t *)tblp->table + index);
5690Sstevel@tonic-gate 			break;
5700Sstevel@tonic-gate 		case 3:
5710Sstevel@tonic-gate 			*(uint16_t *)value = *((uint16_t *)tblp->table + index);
5720Sstevel@tonic-gate 			break;
5730Sstevel@tonic-gate 		case 4:
5740Sstevel@tonic-gate 			*(int32_t *)value = *((int32_t *)tblp->table + index);
5750Sstevel@tonic-gate 			break;
5760Sstevel@tonic-gate 		case 5:
5770Sstevel@tonic-gate 			*(uint32_t *)value = *((uint32_t *)tblp->table + index);
5780Sstevel@tonic-gate 			break;
5790Sstevel@tonic-gate 		case 6:
5800Sstevel@tonic-gate 			*(int64_t *)value = *((int64_t *)tblp->table + index);
5810Sstevel@tonic-gate 			break;
5820Sstevel@tonic-gate 		case 7:
5830Sstevel@tonic-gate 			*(uint64_t *)value = *((uint64_t *)tblp->table + index);
5840Sstevel@tonic-gate 			break;
5850Sstevel@tonic-gate 		default:
5860Sstevel@tonic-gate 			return (PSVC_FAILURE);
5870Sstevel@tonic-gate 	}
5880Sstevel@tonic-gate 
5890Sstevel@tonic-gate 	return (PSVC_SUCCESS);
5900Sstevel@tonic-gate }
5910Sstevel@tonic-gate 
5920Sstevel@tonic-gate int32_t
psvc_get_attr(EHdl_t * hdlp,char * name,int32_t attr_id,void * attr_valuep,...)5930Sstevel@tonic-gate psvc_get_attr(EHdl_t *hdlp, char *name, int32_t attr_id, void *attr_valuep, ...)
5940Sstevel@tonic-gate {
5950Sstevel@tonic-gate 	EObj_t *objp;
5960Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
5970Sstevel@tonic-gate 	int32_t arg1, arg2;
5980Sstevel@tonic-gate 	va_list ap;
5990Sstevel@tonic-gate 
6000Sstevel@tonic-gate 	pthread_mutex_lock(&hdlp->mutex);
6010Sstevel@tonic-gate 
6020Sstevel@tonic-gate 	if (attr_valuep == NULL) {
6030Sstevel@tonic-gate 		errno = EFAULT;
6040Sstevel@tonic-gate 		pthread_mutex_unlock(&hdlp->mutex);
6050Sstevel@tonic-gate 		return (PSVC_FAILURE);
6060Sstevel@tonic-gate 	}
6070Sstevel@tonic-gate 
6080Sstevel@tonic-gate 	switch (attr_id) {
6090Sstevel@tonic-gate 	case PSVC_TABLE_VALUE_ATTR:
6100Sstevel@tonic-gate 		va_start(ap, attr_valuep);
6110Sstevel@tonic-gate 		status = i_psvc_get_table_value(hdlp, name,
6120Sstevel@tonic-gate 			va_arg(ap, uint32_t), attr_valuep);
6130Sstevel@tonic-gate 		va_end(ap);
6140Sstevel@tonic-gate 		break;
6150Sstevel@tonic-gate 	case PSVC_ASSOC_MATCHES_ATTR:
6160Sstevel@tonic-gate 		va_start(ap, attr_valuep);
6170Sstevel@tonic-gate 		status = i_psvc_get_assoc_matches(hdlp, name,
6180Sstevel@tonic-gate 			va_arg(ap, int32_t), attr_valuep);
6190Sstevel@tonic-gate 		va_end(ap);
6200Sstevel@tonic-gate 		break;
6210Sstevel@tonic-gate 	case PSVC_ASSOC_ID_ATTR:
6220Sstevel@tonic-gate 		va_start(ap, attr_valuep);
6230Sstevel@tonic-gate 		arg1 = va_arg(ap, int32_t);
6240Sstevel@tonic-gate 		arg2 = va_arg(ap, int32_t);
6250Sstevel@tonic-gate 		status = i_psvc_get_assoc_id(hdlp, name,
6260Sstevel@tonic-gate 		    arg1, arg2, attr_valuep);
6270Sstevel@tonic-gate 		va_end(ap);
6280Sstevel@tonic-gate 		break;
6290Sstevel@tonic-gate 	default:
6300Sstevel@tonic-gate 		status = i_psvc_get_obj(hdlp, name, &objp);
6310Sstevel@tonic-gate 		if (status != PSVC_SUCCESS) {
6320Sstevel@tonic-gate 			pthread_mutex_unlock(&hdlp->mutex);
6330Sstevel@tonic-gate 			return (status);
6340Sstevel@tonic-gate 		}
6350Sstevel@tonic-gate 		status = (*objp->get_attr)(hdlp, objp, attr_id,
6360Sstevel@tonic-gate 			attr_valuep);
6370Sstevel@tonic-gate 	}
6380Sstevel@tonic-gate 
6390Sstevel@tonic-gate 	if (status != PSVC_SUCCESS) {
6400Sstevel@tonic-gate 		pthread_mutex_unlock(&hdlp->mutex);
6410Sstevel@tonic-gate 		return (status);
6420Sstevel@tonic-gate 	}
6430Sstevel@tonic-gate 
6440Sstevel@tonic-gate 	pthread_mutex_unlock(&hdlp->mutex);
6450Sstevel@tonic-gate 	return (status);
6460Sstevel@tonic-gate }
6470Sstevel@tonic-gate 
6480Sstevel@tonic-gate int32_t
psvc_set_attr(EHdl_t * hdlp,char * name,int32_t attr_id,void * attr_valuep)6490Sstevel@tonic-gate psvc_set_attr(EHdl_t *hdlp, char *name, int32_t attr_id, void *attr_valuep)
6500Sstevel@tonic-gate {
6510Sstevel@tonic-gate 	EObj_t *objp;
6520Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
6530Sstevel@tonic-gate 
6540Sstevel@tonic-gate 	pthread_mutex_lock(&hdlp->mutex);
6550Sstevel@tonic-gate 	status = i_psvc_get_obj(hdlp, name, &objp);
6560Sstevel@tonic-gate 	if (status != PSVC_SUCCESS) {
6570Sstevel@tonic-gate 		pthread_mutex_unlock(&hdlp->mutex);
6580Sstevel@tonic-gate 		return (status);
6590Sstevel@tonic-gate 	}
6600Sstevel@tonic-gate 
6610Sstevel@tonic-gate 	if (attr_valuep == NULL) {
6620Sstevel@tonic-gate 		errno = EFAULT;
6630Sstevel@tonic-gate 		pthread_mutex_unlock(&hdlp->mutex);
6640Sstevel@tonic-gate 		return (PSVC_FAILURE);
6650Sstevel@tonic-gate 	}
6660Sstevel@tonic-gate 
6670Sstevel@tonic-gate 	status = (*objp->set_attr)(hdlp, objp, attr_id, attr_valuep);
6680Sstevel@tonic-gate 	if (status != PSVC_SUCCESS) {
6690Sstevel@tonic-gate 		pthread_mutex_unlock(&hdlp->mutex);
6700Sstevel@tonic-gate 		return (status);
6710Sstevel@tonic-gate 	}
6720Sstevel@tonic-gate 
6730Sstevel@tonic-gate 	pthread_mutex_unlock(&hdlp->mutex);
6740Sstevel@tonic-gate 	return (status);
6750Sstevel@tonic-gate }
6760Sstevel@tonic-gate 
6770Sstevel@tonic-gate 
6780Sstevel@tonic-gate static int32_t
i_psvc_get_presence(EHdl_t * hdlp,EObj_t * objp,boolean_t * pr)6790Sstevel@tonic-gate i_psvc_get_presence(EHdl_t *hdlp, EObj_t *objp, boolean_t *pr)
6800Sstevel@tonic-gate {
6810Sstevel@tonic-gate 	EObj_t *pobjp, *mobjp;
6820Sstevel@tonic-gate 	int32_t matches;
6830Sstevel@tonic-gate 	char *mid;
6840Sstevel@tonic-gate 	char *parent_id;
6850Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
6860Sstevel@tonic-gate 	uint8_t value_8bit, value_8bit_inv;
6870Sstevel@tonic-gate 	boolean_t active_low, value;
6880Sstevel@tonic-gate 
6890Sstevel@tonic-gate 	if (strcmp(objp->label, PSVC_CHASSIS) == 0) {
6900Sstevel@tonic-gate 		*pr = PSVC_PRESENT;
6910Sstevel@tonic-gate 		objp->present = PSVC_PRESENT;
6920Sstevel@tonic-gate 		return (PSVC_SUCCESS);
6930Sstevel@tonic-gate 	}
6940Sstevel@tonic-gate 
6950Sstevel@tonic-gate 	status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PARENT, 0,
6960Sstevel@tonic-gate 		&parent_id);
6970Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
6980Sstevel@tonic-gate 		return (status);
6990Sstevel@tonic-gate 
7000Sstevel@tonic-gate 	if (strcmp(parent_id, PSVC_CHASSIS)) {
7010Sstevel@tonic-gate 		status = i_psvc_get_obj(hdlp, parent_id, &pobjp);
7020Sstevel@tonic-gate 		if (status != PSVC_SUCCESS)
7030Sstevel@tonic-gate 			return (status);
7040Sstevel@tonic-gate 		if (!pobjp->present) {
7050Sstevel@tonic-gate 			pobjp->get_attr(hdlp, pobjp, PSVC_PRESENCE_ATTR, pr);
7060Sstevel@tonic-gate 			*pr = pobjp->present;
7070Sstevel@tonic-gate 			objp->present = pobjp->present;
7080Sstevel@tonic-gate 			return (status);
7090Sstevel@tonic-gate 		}
7100Sstevel@tonic-gate 	}
7110Sstevel@tonic-gate 
7120Sstevel@tonic-gate 	(void) i_psvc_get_assoc_matches(hdlp, objp->label,
7130Sstevel@tonic-gate 		PSVC_PRESENCE_SENSOR, &matches);
7140Sstevel@tonic-gate 
7150Sstevel@tonic-gate 	if (matches != 0) {
7160Sstevel@tonic-gate 		status = i_psvc_get_assoc_id(hdlp, objp->label,
7170Sstevel@tonic-gate 		    PSVC_PRESENCE_SENSOR, 0, &mid);
7180Sstevel@tonic-gate 		if (status != PSVC_SUCCESS)
7190Sstevel@tonic-gate 			return (status);
7200Sstevel@tonic-gate 		status = i_psvc_get_obj(hdlp, mid, &mobjp);
7210Sstevel@tonic-gate 		if (status != PSVC_SUCCESS)
7220Sstevel@tonic-gate 			return (status);
7230Sstevel@tonic-gate 
7240Sstevel@tonic-gate 		active_low = PSVC_IS_ACTIVE_LOW(mobjp->addr_spec);
7250Sstevel@tonic-gate 
7260Sstevel@tonic-gate 		if (mobjp->class == PSVC_BOOLEAN_GPIO_CLASS) {
7270Sstevel@tonic-gate 			status = mobjp->get_attr(hdlp, mobjp,
7280Sstevel@tonic-gate 				PSVC_GPIO_VALUE_ATTR, &value);
7290Sstevel@tonic-gate 			if (status != PSVC_SUCCESS)
7300Sstevel@tonic-gate 				return (status);
7310Sstevel@tonic-gate 			if (active_low)
7320Sstevel@tonic-gate 				if (value == 0)
7330Sstevel@tonic-gate 					*pr = PSVC_PRESENT;
7340Sstevel@tonic-gate 				else
7350Sstevel@tonic-gate 					*pr = PSVC_ABSENT;
7360Sstevel@tonic-gate 			else
7370Sstevel@tonic-gate 				if (value == 0)
7380Sstevel@tonic-gate 					*pr = PSVC_ABSENT;
7390Sstevel@tonic-gate 				else
7400Sstevel@tonic-gate 					*pr = PSVC_PRESENT;
7410Sstevel@tonic-gate 		} else if (mobjp->class == PSVC_8BIT_GPIO_CLASS) {
7420Sstevel@tonic-gate 			uint8_t bitshift, bytemask;
7430Sstevel@tonic-gate 
7440Sstevel@tonic-gate 			status = mobjp->get_attr(hdlp, mobjp,
7450Sstevel@tonic-gate 				PSVC_GPIO_VALUE_ATTR, &value_8bit);
7460Sstevel@tonic-gate 			if (status != PSVC_SUCCESS)
7470Sstevel@tonic-gate 				return (status);
7480Sstevel@tonic-gate 			if (PSVC_HP_INVERT(mobjp->addr_spec))
7490Sstevel@tonic-gate 				value_8bit_inv = ~value_8bit;
7500Sstevel@tonic-gate 			else
7510Sstevel@tonic-gate 				value_8bit_inv = value_8bit;
7520Sstevel@tonic-gate 			bitshift = PSVC_GET_ASPEC_BITSHIFT(mobjp->addr_spec);
7530Sstevel@tonic-gate 			bytemask = PSVC_GET_ASPEC_BYTEMASK(mobjp->addr_spec);
7540Sstevel@tonic-gate 			value_8bit_inv =
7550Sstevel@tonic-gate 				value_8bit_inv & (bytemask >> bitshift);
7560Sstevel@tonic-gate 			if (active_low)
7570Sstevel@tonic-gate 				if (value_8bit_inv == 0)
7580Sstevel@tonic-gate 					*pr = PSVC_PRESENT;
7590Sstevel@tonic-gate 				else
7600Sstevel@tonic-gate 					*pr = PSVC_ABSENT;
7610Sstevel@tonic-gate 			else
7620Sstevel@tonic-gate 				if (value_8bit_inv == 0)
7630Sstevel@tonic-gate 					*pr = PSVC_ABSENT;
7640Sstevel@tonic-gate 				else
7650Sstevel@tonic-gate 					*pr = PSVC_PRESENT;
7660Sstevel@tonic-gate 		} else {
7670Sstevel@tonic-gate 			errno = EINVAL;
7680Sstevel@tonic-gate 			return (PSVC_FAILURE);
7690Sstevel@tonic-gate 		}
7700Sstevel@tonic-gate 	} else {
7710Sstevel@tonic-gate 		*pr = PSVC_PRESENT;
7720Sstevel@tonic-gate 	}
7730Sstevel@tonic-gate 
7740Sstevel@tonic-gate 	objp->present = *pr;
7750Sstevel@tonic-gate 
7760Sstevel@tonic-gate 	return (status);
7770Sstevel@tonic-gate }
7780Sstevel@tonic-gate 
7790Sstevel@tonic-gate static int32_t
i_psvc_get_device_value_0_0(EHdl_t * hdlp,EObj_t * objp,int32_t * temp)7800Sstevel@tonic-gate i_psvc_get_device_value_0_0(EHdl_t *hdlp, EObj_t *objp, int32_t *temp)
7810Sstevel@tonic-gate {
7820Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS, m;
7830Sstevel@tonic-gate 	char *tid;
7840Sstevel@tonic-gate 	int16_t temp16;
7850Sstevel@tonic-gate 	char *physid;
7860Sstevel@tonic-gate 	EObj_t *physobjp;
7870Sstevel@tonic-gate 
7880Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
7890Sstevel@tonic-gate 		errno = ENODEV;
7900Sstevel@tonic-gate 		return (PSVC_FAILURE);
7910Sstevel@tonic-gate 	}
7920Sstevel@tonic-gate 
7930Sstevel@tonic-gate 	status = i_psvc_get_assoc_id(
7940Sstevel@tonic-gate 		hdlp, objp->label, PSVC_PHYSICAL_DEVICE, 0, &physid);
7950Sstevel@tonic-gate 	if (status != PSVC_SUCCESS) {
7960Sstevel@tonic-gate 		return (status);
7970Sstevel@tonic-gate 	}
7980Sstevel@tonic-gate 	status = i_psvc_get_obj(hdlp, physid, &physobjp);
7990Sstevel@tonic-gate 	if (status != PSVC_SUCCESS) {
8000Sstevel@tonic-gate 		return (status);
8010Sstevel@tonic-gate 	}
8020Sstevel@tonic-gate 
8030Sstevel@tonic-gate 	status = ((EPhysDev_t *)physobjp)->get_temperature(hdlp,
8040Sstevel@tonic-gate 		objp->addr_spec, temp);
8050Sstevel@tonic-gate 	if (status != PSVC_SUCCESS) {
8060Sstevel@tonic-gate 		return (status);
8070Sstevel@tonic-gate 	}
8080Sstevel@tonic-gate 
8090Sstevel@tonic-gate 	if (objp->features & PSVC_CONVERSION_TABLE) {
8100Sstevel@tonic-gate 		status = i_psvc_get_assoc_matches(hdlp, objp->label,
8110Sstevel@tonic-gate 		    PSVC_TABLE, &m);
8120Sstevel@tonic-gate 		if ((status != PSVC_SUCCESS) || (m != 1)) {
8130Sstevel@tonic-gate 			return (status);
8140Sstevel@tonic-gate 		}
8150Sstevel@tonic-gate 
8160Sstevel@tonic-gate 		(void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
8170Sstevel@tonic-gate 			&tid);
8180Sstevel@tonic-gate 
8190Sstevel@tonic-gate 		status = i_psvc_get_table_value(hdlp, tid, *temp, &temp16);
8200Sstevel@tonic-gate 		*temp = temp16;
8210Sstevel@tonic-gate 	}
8220Sstevel@tonic-gate 	return (status);
8230Sstevel@tonic-gate }
8240Sstevel@tonic-gate 
8250Sstevel@tonic-gate static int32_t
i_psvc_get_device_value_0_1(EHdl_t * hdlp,EObj_t * objp,int32_t * temp)8260Sstevel@tonic-gate i_psvc_get_device_value_0_1(EHdl_t *hdlp, EObj_t *objp, int32_t *temp)
8270Sstevel@tonic-gate {
8280Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS, m;
8290Sstevel@tonic-gate 	char *tid;
8300Sstevel@tonic-gate 	int16_t temp16;
8310Sstevel@tonic-gate 	char *physid;
8320Sstevel@tonic-gate 	EObj_t *physobjp;
8330Sstevel@tonic-gate 
8340Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
8350Sstevel@tonic-gate 		errno = ENODEV;
8360Sstevel@tonic-gate 		return (PSVC_FAILURE);
8370Sstevel@tonic-gate 	}
8380Sstevel@tonic-gate 
8390Sstevel@tonic-gate 	status = i_psvc_get_assoc_id(
8400Sstevel@tonic-gate 		hdlp, objp->label, PSVC_PHYSICAL_DEVICE, 0, &physid);
8410Sstevel@tonic-gate 	if (status != PSVC_SUCCESS) {
8420Sstevel@tonic-gate 		return (status);
8430Sstevel@tonic-gate 	}
8440Sstevel@tonic-gate 	status = i_psvc_get_obj(hdlp, physid, &physobjp);
8450Sstevel@tonic-gate 	if (status != PSVC_SUCCESS) {
8460Sstevel@tonic-gate 		return (status);
8470Sstevel@tonic-gate 	}
8480Sstevel@tonic-gate 
8490Sstevel@tonic-gate 	status = ((EPhysDev_t *)physobjp)->get_temperature(hdlp,
8500Sstevel@tonic-gate 		objp->addr_spec, temp);
8510Sstevel@tonic-gate 	if (status != PSVC_SUCCESS) {
8520Sstevel@tonic-gate 		return (status);
8530Sstevel@tonic-gate 	}
8540Sstevel@tonic-gate 
8550Sstevel@tonic-gate 	if (objp->features & PSVC_CONVERSION_TABLE) {
8560Sstevel@tonic-gate 		status = i_psvc_get_assoc_matches(hdlp, objp->label,
8570Sstevel@tonic-gate 		    PSVC_TABLE, &m);
8580Sstevel@tonic-gate 		if ((status != PSVC_SUCCESS) || (m != 1)) {
8590Sstevel@tonic-gate 			return (status);
8600Sstevel@tonic-gate 		}
8610Sstevel@tonic-gate 
8620Sstevel@tonic-gate 		(void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
8630Sstevel@tonic-gate 			&tid);
8640Sstevel@tonic-gate 
8650Sstevel@tonic-gate 		status = i_psvc_get_table_value(hdlp, tid, *temp, &temp16);
8660Sstevel@tonic-gate 		*temp = temp16;
8670Sstevel@tonic-gate 	}
8680Sstevel@tonic-gate 	return (status);
8690Sstevel@tonic-gate }
8700Sstevel@tonic-gate 
8710Sstevel@tonic-gate static int32_t
i_psvc_get_device_value_4_0(EHdl_t * hdlp,EObj_t * objp,int32_t * value)8720Sstevel@tonic-gate i_psvc_get_device_value_4_0(EHdl_t *hdlp, EObj_t *objp, int32_t *value)
8730Sstevel@tonic-gate {
8740Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
8750Sstevel@tonic-gate 	char *physid;
8760Sstevel@tonic-gate 	EObj_t *physobjp;
8770Sstevel@tonic-gate 
8780Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
8790Sstevel@tonic-gate 		errno = ENODEV;
8800Sstevel@tonic-gate 		return (PSVC_FAILURE);
8810Sstevel@tonic-gate 	}
8820Sstevel@tonic-gate 
8830Sstevel@tonic-gate 	status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
8840Sstevel@tonic-gate 		0, &physid);
8850Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
8860Sstevel@tonic-gate 		return (status);
8870Sstevel@tonic-gate 	status = i_psvc_get_obj(hdlp, physid, &physobjp);
8880Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
8890Sstevel@tonic-gate 		return (status);
8900Sstevel@tonic-gate 
8910Sstevel@tonic-gate 	status = ((EPhysDev_t *)physobjp)->get_input(hdlp, objp->addr_spec,
8920Sstevel@tonic-gate 		value);
8930Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
8940Sstevel@tonic-gate 		return (status);
8950Sstevel@tonic-gate 
8960Sstevel@tonic-gate 	if (objp->features & PSVC_CONVERSION_TABLE) {
8970Sstevel@tonic-gate 		int32_t m;
8980Sstevel@tonic-gate 		char *tid;
8990Sstevel@tonic-gate 		int16_t temp16;
9000Sstevel@tonic-gate 
9010Sstevel@tonic-gate 		status = i_psvc_get_assoc_matches(hdlp, objp->label,
9020Sstevel@tonic-gate 		    PSVC_TABLE, &m);
9030Sstevel@tonic-gate 		if ((status != PSVC_SUCCESS) || (m != 1)) {
9040Sstevel@tonic-gate 			return (status);
9050Sstevel@tonic-gate 		}
9060Sstevel@tonic-gate 
9070Sstevel@tonic-gate 		(void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
9080Sstevel@tonic-gate 			&tid);
9090Sstevel@tonic-gate 
9100Sstevel@tonic-gate 		status = i_psvc_get_table_value(hdlp, tid, *value, &temp16);
9110Sstevel@tonic-gate 		*value = temp16;
9120Sstevel@tonic-gate 	}
9130Sstevel@tonic-gate 
9140Sstevel@tonic-gate 	return (status);
9150Sstevel@tonic-gate }
9160Sstevel@tonic-gate 
9170Sstevel@tonic-gate static int32_t
i_psvc_set_device_value_5_0(EHdl_t * hdlp,EObj_t * objp,int32_t * value)9180Sstevel@tonic-gate i_psvc_set_device_value_5_0(EHdl_t *hdlp, EObj_t *objp, int32_t *value)
9190Sstevel@tonic-gate {
9200Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
9210Sstevel@tonic-gate 	char *physid;
9220Sstevel@tonic-gate 	EObj_t *physobjp;
9230Sstevel@tonic-gate 
9240Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
9250Sstevel@tonic-gate 		errno = ENODEV;
9260Sstevel@tonic-gate 		return (PSVC_FAILURE);
9270Sstevel@tonic-gate 	}
9280Sstevel@tonic-gate 
9290Sstevel@tonic-gate 	status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
9300Sstevel@tonic-gate 		0, &physid);
9310Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
9320Sstevel@tonic-gate 		return (status);
9330Sstevel@tonic-gate 	status = i_psvc_get_obj(hdlp, physid, &physobjp);
9340Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
9350Sstevel@tonic-gate 		return (status);
9360Sstevel@tonic-gate 	status = ((EPhysDev_t *)physobjp)->set_output(hdlp, objp->addr_spec,
9370Sstevel@tonic-gate 		*value);
9380Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
9390Sstevel@tonic-gate 		return (status);
9400Sstevel@tonic-gate 
9410Sstevel@tonic-gate 	return (status);
9420Sstevel@tonic-gate }
9430Sstevel@tonic-gate 
9440Sstevel@tonic-gate static int32_t
i_psvc_get_device_value_5_0(EHdl_t * hdlp,EObj_t * objp,int32_t * value)9450Sstevel@tonic-gate i_psvc_get_device_value_5_0(EHdl_t *hdlp, EObj_t *objp, int32_t *value)
9460Sstevel@tonic-gate {
9470Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
9480Sstevel@tonic-gate 	char *physid;
9490Sstevel@tonic-gate 	EObj_t *physobjp;
9500Sstevel@tonic-gate 
9510Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
9520Sstevel@tonic-gate 		errno = ENODEV;
9530Sstevel@tonic-gate 		return (PSVC_FAILURE);
9540Sstevel@tonic-gate 	}
9550Sstevel@tonic-gate 
9560Sstevel@tonic-gate 	status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
9570Sstevel@tonic-gate 		0, &physid);
9580Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
9590Sstevel@tonic-gate 		return (status);
9600Sstevel@tonic-gate 	status = i_psvc_get_obj(hdlp, physid, &physobjp);
9610Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
9620Sstevel@tonic-gate 		return (status);
9630Sstevel@tonic-gate 
9640Sstevel@tonic-gate 	status = ((EPhysDev_t *)physobjp)->get_output(hdlp, objp->addr_spec,
9650Sstevel@tonic-gate 		value);
9660Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
9670Sstevel@tonic-gate 		return (status);
9680Sstevel@tonic-gate 
9690Sstevel@tonic-gate 	if (objp->features & PSVC_CONVERSION_TABLE) {
9700Sstevel@tonic-gate 		int32_t m;
9710Sstevel@tonic-gate 		char *tid;
9720Sstevel@tonic-gate 		int16_t temp16;
9730Sstevel@tonic-gate 
9740Sstevel@tonic-gate 		status = i_psvc_get_assoc_matches(hdlp, objp->label,
9750Sstevel@tonic-gate 		    PSVC_TABLE, &m);
9760Sstevel@tonic-gate 		if ((status != PSVC_SUCCESS) || (m != 1)) {
9770Sstevel@tonic-gate 			return (status);
9780Sstevel@tonic-gate 		}
9790Sstevel@tonic-gate 
9800Sstevel@tonic-gate 		(void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
9810Sstevel@tonic-gate 			&tid);
9820Sstevel@tonic-gate 
9830Sstevel@tonic-gate 		status = i_psvc_get_table_value(hdlp, tid, *value, &temp16);
9840Sstevel@tonic-gate 		*value = temp16;
9850Sstevel@tonic-gate 	}
9860Sstevel@tonic-gate 	return (status);
9870Sstevel@tonic-gate }
9880Sstevel@tonic-gate 
9890Sstevel@tonic-gate static int32_t
i_psvc_get_device_value_6_0(EHdl_t * hdlp,EObj_t * objp,boolean_t * value)9900Sstevel@tonic-gate i_psvc_get_device_value_6_0(EHdl_t *hdlp, EObj_t *objp, boolean_t *value)
9910Sstevel@tonic-gate {
9920Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
9930Sstevel@tonic-gate 	int32_t bit_value;
9940Sstevel@tonic-gate 	char *physid;
9950Sstevel@tonic-gate 	EObj_t *physobjp;
9960Sstevel@tonic-gate 
9970Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
9980Sstevel@tonic-gate 		errno = ENODEV;
9990Sstevel@tonic-gate 		return (PSVC_FAILURE);
10000Sstevel@tonic-gate 	}
10010Sstevel@tonic-gate 
10020Sstevel@tonic-gate 	status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
10030Sstevel@tonic-gate 		0, &physid);
10040Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
10050Sstevel@tonic-gate 		return (status);
10060Sstevel@tonic-gate 	status = i_psvc_get_obj(hdlp, physid, &physobjp);
10070Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
10080Sstevel@tonic-gate 		return (status);
10090Sstevel@tonic-gate 
10100Sstevel@tonic-gate 	status = ((EPhysDev_t *)physobjp)->get_bit(hdlp, objp->addr_spec,
10110Sstevel@tonic-gate 		&bit_value);
10120Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
10130Sstevel@tonic-gate 		return (status);
10140Sstevel@tonic-gate 
10150Sstevel@tonic-gate 	*value = bit_value;
10160Sstevel@tonic-gate 
10170Sstevel@tonic-gate 	return (status);
10180Sstevel@tonic-gate }
10190Sstevel@tonic-gate 
10200Sstevel@tonic-gate static int32_t
i_psvc_set_device_value_6_0(EHdl_t * hdlp,EObj_t * objp,boolean_t * value)10210Sstevel@tonic-gate i_psvc_set_device_value_6_0(EHdl_t *hdlp, EObj_t *objp, boolean_t *value)
10220Sstevel@tonic-gate {
10230Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
10240Sstevel@tonic-gate 	int32_t bit_value;
10250Sstevel@tonic-gate 	char *physid;
10260Sstevel@tonic-gate 	EObj_t *physobjp;
10270Sstevel@tonic-gate 
10280Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
10290Sstevel@tonic-gate 		errno = ENODEV;
10300Sstevel@tonic-gate 		return (PSVC_FAILURE);
10310Sstevel@tonic-gate 	}
10320Sstevel@tonic-gate 
10330Sstevel@tonic-gate 	bit_value = *value;
10340Sstevel@tonic-gate 	status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
10350Sstevel@tonic-gate 		0, &physid);
10360Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
10370Sstevel@tonic-gate 		return (status);
10380Sstevel@tonic-gate 	status = i_psvc_get_obj(hdlp, physid, &physobjp);
10390Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
10400Sstevel@tonic-gate 		return (status);
10410Sstevel@tonic-gate 
10420Sstevel@tonic-gate 	status = ((EPhysDev_t *)physobjp)->set_bit(hdlp, objp->addr_spec,
10430Sstevel@tonic-gate 		bit_value);
10440Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
10450Sstevel@tonic-gate 		return (status);
10460Sstevel@tonic-gate 
10470Sstevel@tonic-gate 	return (status);
10480Sstevel@tonic-gate }
10490Sstevel@tonic-gate 
10500Sstevel@tonic-gate static int32_t
i_psvc_get_device_value_1_0(EHdl_t * hdlp,EObj_t * objp,int32_t * fan_speed)10510Sstevel@tonic-gate i_psvc_get_device_value_1_0(EHdl_t *hdlp, EObj_t *objp, int32_t *fan_speed)
10520Sstevel@tonic-gate {
10530Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
10540Sstevel@tonic-gate 	EObj_t *ftobjp;
10550Sstevel@tonic-gate 	char *fan_tach;
10560Sstevel@tonic-gate 
10570Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
10580Sstevel@tonic-gate 		errno = ENODEV;
10590Sstevel@tonic-gate 		return (PSVC_FAILURE);
10600Sstevel@tonic-gate 	}
10610Sstevel@tonic-gate 
10620Sstevel@tonic-gate 	status = i_psvc_get_assoc_id(hdlp, objp->label,
10630Sstevel@tonic-gate 		PSVC_FAN_SPEED_TACHOMETER, 0, &fan_tach);
10640Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
10650Sstevel@tonic-gate 		return (status);
10660Sstevel@tonic-gate 
10670Sstevel@tonic-gate 	status = i_psvc_get_obj(hdlp, fan_tach, &ftobjp);
10680Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
10690Sstevel@tonic-gate 		return (status);
10700Sstevel@tonic-gate 
10710Sstevel@tonic-gate 	status = ftobjp->get_attr(hdlp, ftobjp, PSVC_SENSOR_VALUE_ATTR,
10720Sstevel@tonic-gate 		fan_speed);
10730Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
10740Sstevel@tonic-gate 		return (status);
10750Sstevel@tonic-gate 
10760Sstevel@tonic-gate 	return (status);
10770Sstevel@tonic-gate }
10780Sstevel@tonic-gate 
10790Sstevel@tonic-gate static int32_t
i_psvc_get_device_value_7_0(EHdl_t * hdlp,EObj_t * objp,int32_t * fan_speed)10800Sstevel@tonic-gate i_psvc_get_device_value_7_0(EHdl_t *hdlp, EObj_t *objp, int32_t *fan_speed)
10810Sstevel@tonic-gate {
10820Sstevel@tonic-gate 	char *physid;
10830Sstevel@tonic-gate 	EObj_t *physobjp;
10840Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
10850Sstevel@tonic-gate 
10860Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
10870Sstevel@tonic-gate 		errno = ENODEV;
10880Sstevel@tonic-gate 		return (PSVC_FAILURE);
10890Sstevel@tonic-gate 	}
10900Sstevel@tonic-gate 
10910Sstevel@tonic-gate 	status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
10920Sstevel@tonic-gate 		0, &physid);
10930Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
10940Sstevel@tonic-gate 		return (status);
10950Sstevel@tonic-gate 	status = i_psvc_get_obj(hdlp, physid, &physobjp);
10960Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
10970Sstevel@tonic-gate 		return (status);
10980Sstevel@tonic-gate 
10990Sstevel@tonic-gate 	status = ((EPhysDev_t *)physobjp)->get_fanspeed(hdlp, objp->addr_spec,
11000Sstevel@tonic-gate 		fan_speed);
11010Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
11020Sstevel@tonic-gate 		return (status);
11030Sstevel@tonic-gate 
11040Sstevel@tonic-gate 	if (objp->features & PSVC_CONVERSION_TABLE) {
11050Sstevel@tonic-gate 		int32_t m;
11060Sstevel@tonic-gate 		char *tid;
11070Sstevel@tonic-gate 		int16_t temp16;
11080Sstevel@tonic-gate 
11090Sstevel@tonic-gate 		status = i_psvc_get_assoc_matches(hdlp, objp->label,
11100Sstevel@tonic-gate 		    PSVC_TABLE, &m);
11110Sstevel@tonic-gate 		if ((status != PSVC_SUCCESS) || (m != 1)) {
11120Sstevel@tonic-gate 			return (status);
11130Sstevel@tonic-gate 		}
11140Sstevel@tonic-gate 
11150Sstevel@tonic-gate 		(void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
11160Sstevel@tonic-gate 			&tid);
11170Sstevel@tonic-gate 
11180Sstevel@tonic-gate 		status = i_psvc_get_table_value(hdlp, tid, *fan_speed, &temp16);
11190Sstevel@tonic-gate 		*fan_speed = temp16;
11200Sstevel@tonic-gate 	}
11210Sstevel@tonic-gate 	return (status);
11220Sstevel@tonic-gate }
11230Sstevel@tonic-gate 
11240Sstevel@tonic-gate static int32_t
i_psvc_get_device_state_2_0(EHdl_t * hdlp,EObj_t * objp,char * led_state)11250Sstevel@tonic-gate i_psvc_get_device_state_2_0(EHdl_t *hdlp, EObj_t *objp, char *led_state)
11260Sstevel@tonic-gate {
11270Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
11280Sstevel@tonic-gate 	int32_t bit_value;
11290Sstevel@tonic-gate 	boolean_t active_low;
11300Sstevel@tonic-gate 	char *physid;
11310Sstevel@tonic-gate 	EObj_t *physobjp;
11320Sstevel@tonic-gate 
11330Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
11340Sstevel@tonic-gate 		errno = ENODEV;
11350Sstevel@tonic-gate 		return (PSVC_FAILURE);
11360Sstevel@tonic-gate 	}
11370Sstevel@tonic-gate 
11380Sstevel@tonic-gate 	status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
11390Sstevel@tonic-gate 		0, &physid);
11400Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
11410Sstevel@tonic-gate 		return (status);
11420Sstevel@tonic-gate 	status = i_psvc_get_obj(hdlp, physid, &physobjp);
11430Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
11440Sstevel@tonic-gate 		return (status);
11450Sstevel@tonic-gate 
11460Sstevel@tonic-gate 	status = ((EPhysDev_t *)physobjp)->get_bit(hdlp, objp->addr_spec,
11470Sstevel@tonic-gate 		&bit_value);
11480Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
11490Sstevel@tonic-gate 		return (status);
11500Sstevel@tonic-gate 
11510Sstevel@tonic-gate 	active_low = PSVC_IS_ACTIVE_LOW(objp->addr_spec);
11520Sstevel@tonic-gate 	if (active_low)
11530Sstevel@tonic-gate 		if (bit_value == 0)
11540Sstevel@tonic-gate 			strcpy(led_state, PSVC_LED_ON);
11550Sstevel@tonic-gate 		else
11560Sstevel@tonic-gate 			strcpy(led_state, PSVC_LED_OFF);
11570Sstevel@tonic-gate 	else
11580Sstevel@tonic-gate 		if (bit_value == 0)
11590Sstevel@tonic-gate 			strcpy(led_state, PSVC_LED_OFF);
11600Sstevel@tonic-gate 		else
11610Sstevel@tonic-gate 			strcpy(led_state, PSVC_LED_ON);
11620Sstevel@tonic-gate 
11630Sstevel@tonic-gate 	return (status);
11640Sstevel@tonic-gate }
11650Sstevel@tonic-gate 
11660Sstevel@tonic-gate static int32_t
i_psvc_set_device_state_2_0(EHdl_t * hdlp,EObj_t * objp,char * led_state)11670Sstevel@tonic-gate i_psvc_set_device_state_2_0(EHdl_t *hdlp, EObj_t *objp, char *led_state)
11680Sstevel@tonic-gate {
11690Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
11700Sstevel@tonic-gate 	boolean_t active_low;
11710Sstevel@tonic-gate 	int32_t bit_value;
11720Sstevel@tonic-gate 	char *physid;
11730Sstevel@tonic-gate 	EObj_t *physobjp;
11740Sstevel@tonic-gate 
11750Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
11760Sstevel@tonic-gate 		errno = ENODEV;
11770Sstevel@tonic-gate 		return (PSVC_FAILURE);
11780Sstevel@tonic-gate 	}
11790Sstevel@tonic-gate 
11800Sstevel@tonic-gate 	if (strcmp(((ELed_t *)objp)->is_locator, PSVC_LOCATOR_TRUE) != 0) {
11810Sstevel@tonic-gate 		/*
11820Sstevel@tonic-gate 		 * For Locator LEDs we ignore lit_count.  RSC may have
11830Sstevel@tonic-gate 		 * altered the LED state underneath us, So we should
11840Sstevel@tonic-gate 		 * always just do what the user asked instead of trying
11850Sstevel@tonic-gate 		 * to be smart.
11860Sstevel@tonic-gate 		 */
11870Sstevel@tonic-gate 
11880Sstevel@tonic-gate 		if (strcmp(led_state, PSVC_LED_ON) == 0)
11890Sstevel@tonic-gate 			((ELed_t *)objp)->lit_count++;
11900Sstevel@tonic-gate 		else if (strcmp(led_state, PSVC_LED_OFF) == 0) {
11910Sstevel@tonic-gate 			if (--((ELed_t *)objp)->lit_count > 0) {
11920Sstevel@tonic-gate 				return (PSVC_SUCCESS);
11930Sstevel@tonic-gate 			} else if (((ELed_t *)objp)->lit_count < 0)
11940Sstevel@tonic-gate 				((ELed_t *)objp)->lit_count = 0;
11950Sstevel@tonic-gate 			/* Fall through case is when lit_count is 0 */
11960Sstevel@tonic-gate 		}
11970Sstevel@tonic-gate 	}
11980Sstevel@tonic-gate 
11990Sstevel@tonic-gate 	strcpy(objp->previous_state, objp->state);
12000Sstevel@tonic-gate 	strcpy(objp->state, led_state);
12010Sstevel@tonic-gate 
12020Sstevel@tonic-gate 	bit_value = (strcmp(led_state, PSVC_LED_ON) == 0);
12030Sstevel@tonic-gate 
12040Sstevel@tonic-gate 	/*
12050Sstevel@tonic-gate 	 * Flip the bit if necessary (for active_low devices,
12060Sstevel@tonic-gate 	 * O ==> ON; 1 ==> OFF.
12070Sstevel@tonic-gate 	 */
12080Sstevel@tonic-gate 	active_low = PSVC_IS_ACTIVE_LOW(objp->addr_spec);
12090Sstevel@tonic-gate 	bit_value ^= active_low;
12100Sstevel@tonic-gate 
12110Sstevel@tonic-gate 	status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
12120Sstevel@tonic-gate 		0, &physid);
12130Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
12140Sstevel@tonic-gate 		return (status);
12150Sstevel@tonic-gate 	status = i_psvc_get_obj(hdlp, physid, &physobjp);
12160Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
12170Sstevel@tonic-gate 		return (status);
12180Sstevel@tonic-gate 
12190Sstevel@tonic-gate 	status = ((EPhysDev_t *)physobjp)->set_bit(hdlp, objp->addr_spec,
12200Sstevel@tonic-gate 		bit_value);
12210Sstevel@tonic-gate 	return (status);
12220Sstevel@tonic-gate }
12230Sstevel@tonic-gate 
12240Sstevel@tonic-gate static int32_t
i_psvc_get_device_state_2_1(EHdl_t * hdlp,EObj_t * objp,char * led_state)12250Sstevel@tonic-gate i_psvc_get_device_state_2_1(EHdl_t *hdlp, EObj_t *objp, char *led_state)
12260Sstevel@tonic-gate {
12270Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
12280Sstevel@tonic-gate 	uint8_t value;
12290Sstevel@tonic-gate 	char *physid;
12300Sstevel@tonic-gate 	EObj_t *physobjp;
12310Sstevel@tonic-gate 
12320Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
12330Sstevel@tonic-gate 		errno = ENODEV;
12340Sstevel@tonic-gate 		return (PSVC_FAILURE);
12350Sstevel@tonic-gate 	}
12360Sstevel@tonic-gate 
12370Sstevel@tonic-gate 	status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
12380Sstevel@tonic-gate 		0, &physid);
12390Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
12400Sstevel@tonic-gate 		return (status);
12410Sstevel@tonic-gate 	status = i_psvc_get_obj(hdlp, physid, &physobjp);
12420Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
12430Sstevel@tonic-gate 		return (status);
12440Sstevel@tonic-gate 
12450Sstevel@tonic-gate 	status = ((EPhysDev_t *)physobjp)->get_reg(hdlp, objp->addr_spec,
12460Sstevel@tonic-gate 		&value);
12470Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
12480Sstevel@tonic-gate 		return (status);
12490Sstevel@tonic-gate 
12500Sstevel@tonic-gate 	switch (value) {
12510Sstevel@tonic-gate 	case 0:
12520Sstevel@tonic-gate 		strcpy(led_state, PSVC_LED_OFF);
12530Sstevel@tonic-gate 		break;
12540Sstevel@tonic-gate 	case 1:
12550Sstevel@tonic-gate 		strcpy(led_state, PSVC_LED_SLOW_BLINK);
12560Sstevel@tonic-gate 		break;
12570Sstevel@tonic-gate 	case 2:
12580Sstevel@tonic-gate 		strcpy(led_state, PSVC_LED_FAST_BLINK);
12590Sstevel@tonic-gate 		break;
12600Sstevel@tonic-gate 	case 3:
12610Sstevel@tonic-gate 		strcpy(led_state, PSVC_LED_ON);
12620Sstevel@tonic-gate 		break;
12630Sstevel@tonic-gate 	}
12640Sstevel@tonic-gate 
12650Sstevel@tonic-gate 	return (status);
12660Sstevel@tonic-gate }
12670Sstevel@tonic-gate 
12680Sstevel@tonic-gate static int32_t
i_psvc_set_device_state_2_1(EHdl_t * hdlp,EObj_t * objp,char * led_state)12690Sstevel@tonic-gate i_psvc_set_device_state_2_1(EHdl_t *hdlp, EObj_t *objp, char *led_state)
12700Sstevel@tonic-gate {
12710Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
12720Sstevel@tonic-gate 	uint8_t value;
12730Sstevel@tonic-gate 	char *physid;
12740Sstevel@tonic-gate 	EObj_t *physobjp;
12750Sstevel@tonic-gate 
12760Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
12770Sstevel@tonic-gate 		errno = ENODEV;
12780Sstevel@tonic-gate 		return (PSVC_FAILURE);
12790Sstevel@tonic-gate 	}
12800Sstevel@tonic-gate 
12810Sstevel@tonic-gate 	if (strcmp(led_state, PSVC_LED_ON) == 0)
12820Sstevel@tonic-gate 		((ELed_t *)objp)->lit_count++;
12830Sstevel@tonic-gate 	else if (strcmp(led_state, PSVC_LED_OFF) == 0) {
12840Sstevel@tonic-gate 		if (--((ELed_t *)objp)->lit_count > 0) {
12850Sstevel@tonic-gate 			return (PSVC_SUCCESS);
12860Sstevel@tonic-gate 		} else if (((ELed_t *)objp)->lit_count < 0)
12870Sstevel@tonic-gate 			((ELed_t *)objp)->lit_count = 0;
12880Sstevel@tonic-gate 
12890Sstevel@tonic-gate 		/* Fall through case is when lit_count is 0 */
12900Sstevel@tonic-gate 	}
12910Sstevel@tonic-gate 
12920Sstevel@tonic-gate 	strcpy(objp->previous_state, objp->state);
12930Sstevel@tonic-gate 	strcpy(objp->state, led_state);
12940Sstevel@tonic-gate 
12950Sstevel@tonic-gate 	if (strcmp(led_state, PSVC_LED_OFF) == 0)
12960Sstevel@tonic-gate 		value = 0;
12970Sstevel@tonic-gate 	else if (strcmp(led_state, PSVC_LED_SLOW_BLINK) == 0)
12980Sstevel@tonic-gate 		value = 1;
12990Sstevel@tonic-gate 	else if (strcmp(led_state, PSVC_LED_FAST_BLINK) == 0)
13000Sstevel@tonic-gate 		value = 2;
13010Sstevel@tonic-gate 	else if (strcmp(led_state, PSVC_LED_ON) == 0)
13020Sstevel@tonic-gate 		value = 3;
13030Sstevel@tonic-gate 
13040Sstevel@tonic-gate 	status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
13050Sstevel@tonic-gate 		0, &physid);
13060Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
13070Sstevel@tonic-gate 		return (status);
13080Sstevel@tonic-gate 	status = i_psvc_get_obj(hdlp, physid, &physobjp);
13090Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
13100Sstevel@tonic-gate 		return (status);
13110Sstevel@tonic-gate 
13120Sstevel@tonic-gate 	status = ((EPhysDev_t *)physobjp)->set_reg(hdlp, objp->addr_spec,
13130Sstevel@tonic-gate 		value);
13140Sstevel@tonic-gate 
13150Sstevel@tonic-gate 	return (status);
13160Sstevel@tonic-gate }
13170Sstevel@tonic-gate 
13180Sstevel@tonic-gate static int32_t
i_psvc_get_device_state_9_0(EHdl_t * hdlp,EObj_t * objp,char * pos)13190Sstevel@tonic-gate i_psvc_get_device_state_9_0(EHdl_t *hdlp, EObj_t *objp, char *pos)
13200Sstevel@tonic-gate {
13210Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS, matches;
13220Sstevel@tonic-gate 	char *sensorid;
13230Sstevel@tonic-gate 	EObj_t *sensorp;
13240Sstevel@tonic-gate 	char state[32];
13250Sstevel@tonic-gate 
13260Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
13270Sstevel@tonic-gate 		errno = ENODEV;
13280Sstevel@tonic-gate 		return (PSVC_FAILURE);
13290Sstevel@tonic-gate 	}
13300Sstevel@tonic-gate 
13310Sstevel@tonic-gate 	if (objp->features & PSVC_NORMAL_POS_AV) {
13320Sstevel@tonic-gate 		(void) i_psvc_get_assoc_matches(hdlp, objp->label,
13330Sstevel@tonic-gate 		    PSVC_KS_NORMAL_POS_SENSOR, &matches);
13340Sstevel@tonic-gate 		if (matches == 1) {
13350Sstevel@tonic-gate 			status = i_psvc_get_assoc_id(hdlp, objp->label,
13360Sstevel@tonic-gate 				PSVC_KS_NORMAL_POS_SENSOR, 0, &sensorid);
13370Sstevel@tonic-gate 			if (status != PSVC_SUCCESS)
13380Sstevel@tonic-gate 				return (status);
13390Sstevel@tonic-gate 
13400Sstevel@tonic-gate 			status = i_psvc_get_obj(hdlp, sensorid, &sensorp);
13410Sstevel@tonic-gate 			if (status != PSVC_SUCCESS)
13420Sstevel@tonic-gate 				return (status);
13430Sstevel@tonic-gate 
13440Sstevel@tonic-gate 			status = sensorp->get_attr(hdlp, sensorp,
13450Sstevel@tonic-gate 				PSVC_SWITCH_STATE_ATTR, state);
13460Sstevel@tonic-gate 			if (status != PSVC_SUCCESS)
13470Sstevel@tonic-gate 				return (status);
13480Sstevel@tonic-gate 
13490Sstevel@tonic-gate 			if (strcmp(state, PSVC_SWITCH_ON) == 0) {
13500Sstevel@tonic-gate 				strcpy(pos, PSVC_NORMAL_POS);
13510Sstevel@tonic-gate 				return (PSVC_SUCCESS);
13520Sstevel@tonic-gate 			}
13530Sstevel@tonic-gate 		}
13540Sstevel@tonic-gate 	}
13550Sstevel@tonic-gate 
13560Sstevel@tonic-gate 	if (objp->features & PSVC_DIAG_POS_AV) {
13570Sstevel@tonic-gate 		(void) i_psvc_get_assoc_matches(hdlp, objp->label,
13580Sstevel@tonic-gate 		    PSVC_KS_DIAG_POS_SENSOR, &matches);
13590Sstevel@tonic-gate 		if (matches == 1) {
13600Sstevel@tonic-gate 			status = i_psvc_get_assoc_id(hdlp, objp->label,
13610Sstevel@tonic-gate 			    PSVC_KS_DIAG_POS_SENSOR, 0, &sensorid);
13620Sstevel@tonic-gate 			if (status != PSVC_SUCCESS)
13630Sstevel@tonic-gate 				return (status);
13640Sstevel@tonic-gate 
13650Sstevel@tonic-gate 			status = i_psvc_get_obj(hdlp, sensorid, &sensorp);
13660Sstevel@tonic-gate 			if (status != PSVC_SUCCESS)
13670Sstevel@tonic-gate 				return (status);
13680Sstevel@tonic-gate 
13690Sstevel@tonic-gate 			status = sensorp->get_attr(hdlp, sensorp,
13700Sstevel@tonic-gate 				PSVC_SWITCH_STATE_ATTR, state);
13710Sstevel@tonic-gate 			if (status != PSVC_SUCCESS)
13720Sstevel@tonic-gate 				return (status);
13730Sstevel@tonic-gate 
13740Sstevel@tonic-gate 			if (strcmp(state, PSVC_SWITCH_ON) == 0) {
13750Sstevel@tonic-gate 				strcpy(pos, PSVC_DIAG_POS);
13760Sstevel@tonic-gate 				return (PSVC_SUCCESS);
13770Sstevel@tonic-gate 			}
13780Sstevel@tonic-gate 		}
13790Sstevel@tonic-gate 	}
13800Sstevel@tonic-gate 
13810Sstevel@tonic-gate 	if (objp->features & PSVC_LOCK_POS_AV) {
13820Sstevel@tonic-gate 		(void) i_psvc_get_assoc_matches(hdlp, objp->label,
13830Sstevel@tonic-gate 		    PSVC_KS_LOCK_POS_SENSOR, &matches);
13840Sstevel@tonic-gate 		if (matches == 1) {
13850Sstevel@tonic-gate 			status = i_psvc_get_assoc_id(hdlp, objp->label,
13860Sstevel@tonic-gate 			    PSVC_KS_LOCK_POS_SENSOR, 0, &sensorid);
13870Sstevel@tonic-gate 			if (status != PSVC_SUCCESS)
13880Sstevel@tonic-gate 				return (status);
13890Sstevel@tonic-gate 
13900Sstevel@tonic-gate 			status = i_psvc_get_obj(hdlp, sensorid, &sensorp);
13910Sstevel@tonic-gate 			if (status != PSVC_SUCCESS)
13920Sstevel@tonic-gate 				return (status);
13930Sstevel@tonic-gate 
13940Sstevel@tonic-gate 			status = sensorp->get_attr(hdlp, sensorp,
13950Sstevel@tonic-gate 				PSVC_SWITCH_STATE_ATTR, state);
13960Sstevel@tonic-gate 			if (status != PSVC_SUCCESS)
13970Sstevel@tonic-gate 				return (status);
13980Sstevel@tonic-gate 
13990Sstevel@tonic-gate 			if (strcmp(state, PSVC_SWITCH_ON) == 0) {
14000Sstevel@tonic-gate 				strcpy(pos, PSVC_LOCKED_POS);
14010Sstevel@tonic-gate 				return (PSVC_SUCCESS);
14020Sstevel@tonic-gate 			}
14030Sstevel@tonic-gate 		}
14040Sstevel@tonic-gate 	}
14050Sstevel@tonic-gate 
14060Sstevel@tonic-gate 	if (objp->features & PSVC_OFF_POS_AV) {
14070Sstevel@tonic-gate 		(void) i_psvc_get_assoc_matches(hdlp, objp->label,
14080Sstevel@tonic-gate 		    PSVC_KS_OFF_POS_SENSOR, &matches);
14090Sstevel@tonic-gate 		if (matches == 1) {
14100Sstevel@tonic-gate 			status = i_psvc_get_assoc_id(hdlp, objp->label,
14110Sstevel@tonic-gate 			    PSVC_KS_OFF_POS_SENSOR, 0, &sensorid);
14120Sstevel@tonic-gate 			if (status != PSVC_SUCCESS)
14130Sstevel@tonic-gate 				return (status);
14140Sstevel@tonic-gate 
14150Sstevel@tonic-gate 			status = i_psvc_get_obj(hdlp, sensorid, &sensorp);
14160Sstevel@tonic-gate 			if (status != PSVC_SUCCESS)
14170Sstevel@tonic-gate 				return (status);
14180Sstevel@tonic-gate 
14190Sstevel@tonic-gate 			status = sensorp->get_attr(hdlp, sensorp,
14200Sstevel@tonic-gate 				PSVC_SWITCH_STATE_ATTR, state);
14210Sstevel@tonic-gate 			if (status != PSVC_SUCCESS)
14220Sstevel@tonic-gate 				return (status);
14230Sstevel@tonic-gate 
14240Sstevel@tonic-gate 			if (strcmp(state, PSVC_SWITCH_ON) == 0) {
14250Sstevel@tonic-gate 				strcpy(pos, PSVC_OFF_POS);
14260Sstevel@tonic-gate 				return (PSVC_SUCCESS);
14270Sstevel@tonic-gate 			}
14280Sstevel@tonic-gate 		}
14290Sstevel@tonic-gate 	}
14300Sstevel@tonic-gate 	/* If we have fallen through till here, something's wrong */
14310Sstevel@tonic-gate 	errno = EINVAL;
14320Sstevel@tonic-gate 	return (PSVC_FAILURE);
14330Sstevel@tonic-gate }
14340Sstevel@tonic-gate 
14350Sstevel@tonic-gate 
14360Sstevel@tonic-gate static int32_t
i_psvc_get_device_value_10_0(EHdl_t * hdlp,EObj_t * objp,uint8_t * value)14370Sstevel@tonic-gate i_psvc_get_device_value_10_0(EHdl_t *hdlp, EObj_t *objp, uint8_t *value)
14380Sstevel@tonic-gate {
14390Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
14400Sstevel@tonic-gate 	char *physid;
14410Sstevel@tonic-gate 	EObj_t *physobjp;
14420Sstevel@tonic-gate 
14430Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
14440Sstevel@tonic-gate 		errno = ENODEV;
14450Sstevel@tonic-gate 		return (PSVC_FAILURE);
14460Sstevel@tonic-gate 	}
14470Sstevel@tonic-gate 
14480Sstevel@tonic-gate 	status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
14490Sstevel@tonic-gate 		0, &physid);
14500Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
14510Sstevel@tonic-gate 		return (status);
14520Sstevel@tonic-gate 	status = i_psvc_get_obj(hdlp, physid, &physobjp);
14530Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
14540Sstevel@tonic-gate 		return (status);
14550Sstevel@tonic-gate 
14560Sstevel@tonic-gate 	status = ((EPhysDev_t *)physobjp)->get_reg(hdlp, objp->addr_spec,
14570Sstevel@tonic-gate 		value);
14580Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
14590Sstevel@tonic-gate 		return (status);
14600Sstevel@tonic-gate 
14610Sstevel@tonic-gate 	if (objp->features & PSVC_CONVERSION_TABLE) {
14620Sstevel@tonic-gate 		int32_t m;
14630Sstevel@tonic-gate 		char *tid;
14640Sstevel@tonic-gate 		uint8_t temp8;
14650Sstevel@tonic-gate 
14660Sstevel@tonic-gate 		status = i_psvc_get_assoc_matches(hdlp, objp->label,
14670Sstevel@tonic-gate 		    PSVC_TABLE, &m);
14680Sstevel@tonic-gate 		if ((status != PSVC_SUCCESS) || (m != 1)) {
14690Sstevel@tonic-gate 			return (status);
14700Sstevel@tonic-gate 		}
14710Sstevel@tonic-gate 
14720Sstevel@tonic-gate 		(void) i_psvc_get_assoc_id(hdlp, objp->label,
14730Sstevel@tonic-gate 			PSVC_TABLE, 0, &tid);
14740Sstevel@tonic-gate 
14750Sstevel@tonic-gate 		status = i_psvc_get_table_value(hdlp, tid, *value, &temp8);
14760Sstevel@tonic-gate 		*value = temp8;
14770Sstevel@tonic-gate 	}
14780Sstevel@tonic-gate 	return (status);
14790Sstevel@tonic-gate }
14800Sstevel@tonic-gate 
14810Sstevel@tonic-gate static int32_t
i_psvc_get_device_value_10_1(EHdl_t * hdlp,EObj_t * objp,uint8_t * value)14820Sstevel@tonic-gate i_psvc_get_device_value_10_1(EHdl_t *hdlp, EObj_t *objp, uint8_t *value)
14830Sstevel@tonic-gate {
14840Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
14850Sstevel@tonic-gate 	char *physid;
14860Sstevel@tonic-gate 	EObj_t *physobjp;
14870Sstevel@tonic-gate 
14880Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
14890Sstevel@tonic-gate 		errno = ENODEV;
14900Sstevel@tonic-gate 		return (PSVC_FAILURE);
14910Sstevel@tonic-gate 	}
14920Sstevel@tonic-gate 
14930Sstevel@tonic-gate 	status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
14940Sstevel@tonic-gate 		0, &physid);
14950Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
14960Sstevel@tonic-gate 		return (status);
14970Sstevel@tonic-gate 	status = i_psvc_get_obj(hdlp, physid, &physobjp);
14980Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
14990Sstevel@tonic-gate 		return (status);
15000Sstevel@tonic-gate 
15010Sstevel@tonic-gate 	status = ((EPhysDev_t *)physobjp)->get_port(hdlp, objp->addr_spec,
15020Sstevel@tonic-gate 		value);
15030Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
15040Sstevel@tonic-gate 		return (status);
15050Sstevel@tonic-gate 
15060Sstevel@tonic-gate 	return (status);
15070Sstevel@tonic-gate }
15080Sstevel@tonic-gate 
15090Sstevel@tonic-gate static int32_t
i_psvc_set_device_value_10_0(EHdl_t * hdlp,EObj_t * objp,uint8_t * value)15100Sstevel@tonic-gate i_psvc_set_device_value_10_0(EHdl_t *hdlp, EObj_t *objp, uint8_t *value)
15110Sstevel@tonic-gate {
15120Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
15130Sstevel@tonic-gate 	char *physid;
15140Sstevel@tonic-gate 	EObj_t *physobjp;
15150Sstevel@tonic-gate 
15160Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
15170Sstevel@tonic-gate 		errno = ENODEV;
15180Sstevel@tonic-gate 		return (PSVC_FAILURE);
15190Sstevel@tonic-gate 	}
15200Sstevel@tonic-gate 
15210Sstevel@tonic-gate 	status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
15220Sstevel@tonic-gate 		0, &physid);
15230Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
15240Sstevel@tonic-gate 		return (status);
15250Sstevel@tonic-gate 	status = i_psvc_get_obj(hdlp, physid, &physobjp);
15260Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
15270Sstevel@tonic-gate 		return (status);
15280Sstevel@tonic-gate 
15290Sstevel@tonic-gate 	status = ((EPhysDev_t *)physobjp)->set_reg(hdlp, objp->addr_spec,
15300Sstevel@tonic-gate 		*value);
15310Sstevel@tonic-gate 	return (status);
15320Sstevel@tonic-gate }
15330Sstevel@tonic-gate 
15340Sstevel@tonic-gate static int32_t
i_psvc_set_device_value_10_1(EHdl_t * hdlp,EObj_t * objp,uint8_t * value)15350Sstevel@tonic-gate i_psvc_set_device_value_10_1(EHdl_t *hdlp, EObj_t *objp, uint8_t *value)
15360Sstevel@tonic-gate {
15370Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
15380Sstevel@tonic-gate 	char *physid;
15390Sstevel@tonic-gate 	EObj_t *physobjp;
15400Sstevel@tonic-gate 
15410Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
15420Sstevel@tonic-gate 		errno = ENODEV;
15430Sstevel@tonic-gate 		return (PSVC_FAILURE);
15440Sstevel@tonic-gate 	}
15450Sstevel@tonic-gate 
15460Sstevel@tonic-gate 	status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
15470Sstevel@tonic-gate 		0, &physid);
15480Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
15490Sstevel@tonic-gate 		return (status);
15500Sstevel@tonic-gate 	status = i_psvc_get_obj(hdlp, physid, &physobjp);
15510Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
15520Sstevel@tonic-gate 		return (status);
15530Sstevel@tonic-gate 
15540Sstevel@tonic-gate 	status = ((EPhysDev_t *)physobjp)->set_port(hdlp, objp->addr_spec,
15550Sstevel@tonic-gate 		*value);
15560Sstevel@tonic-gate 	return (status);
15570Sstevel@tonic-gate }
15580Sstevel@tonic-gate 
15590Sstevel@tonic-gate static int32_t
i_psvc_get_device_state_8_0(EHdl_t * hdlp,EObj_t * objp,char * sw_state)15600Sstevel@tonic-gate i_psvc_get_device_state_8_0(EHdl_t *hdlp, EObj_t *objp, char *sw_state)
15610Sstevel@tonic-gate {
15620Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
15630Sstevel@tonic-gate 	boolean_t active_low;
15640Sstevel@tonic-gate 	int32_t bit_value;
15650Sstevel@tonic-gate 	char *physid;
15660Sstevel@tonic-gate 	EObj_t *physobjp;
15670Sstevel@tonic-gate 
15680Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
15690Sstevel@tonic-gate 		errno = ENODEV;
15700Sstevel@tonic-gate 		return (PSVC_FAILURE);
15710Sstevel@tonic-gate 	}
15720Sstevel@tonic-gate 
15730Sstevel@tonic-gate 	status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
15740Sstevel@tonic-gate 		0, &physid);
15750Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
15760Sstevel@tonic-gate 		return (status);
15770Sstevel@tonic-gate 	status = i_psvc_get_obj(hdlp, physid, &physobjp);
15780Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
15790Sstevel@tonic-gate 		return (status);
15800Sstevel@tonic-gate 
15810Sstevel@tonic-gate 	status = ((EPhysDev_t *)physobjp)->get_bit(hdlp, objp->addr_spec,
15820Sstevel@tonic-gate 		&bit_value);
15830Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
15840Sstevel@tonic-gate 		return (status);
15850Sstevel@tonic-gate 
15860Sstevel@tonic-gate 	active_low = PSVC_IS_ACTIVE_LOW(objp->addr_spec);
15870Sstevel@tonic-gate 	if (active_low)
15880Sstevel@tonic-gate 		if (bit_value == 0)
15890Sstevel@tonic-gate 			strcpy(sw_state, PSVC_SWITCH_ON);
15900Sstevel@tonic-gate 		else
15910Sstevel@tonic-gate 			strcpy(sw_state, PSVC_SWITCH_OFF);
15920Sstevel@tonic-gate 	else
15930Sstevel@tonic-gate 		if (bit_value == 0)
15940Sstevel@tonic-gate 			strcpy(sw_state, PSVC_SWITCH_OFF);
15950Sstevel@tonic-gate 		else
15960Sstevel@tonic-gate 			strcpy(sw_state, PSVC_SWITCH_ON);
15970Sstevel@tonic-gate 
15980Sstevel@tonic-gate 	return (status);
15990Sstevel@tonic-gate }
16000Sstevel@tonic-gate 
16010Sstevel@tonic-gate static int32_t
i_psvc_set_device_state_8_0(EHdl_t * hdlp,EObj_t * objp,char * sw_state)16020Sstevel@tonic-gate i_psvc_set_device_state_8_0(EHdl_t *hdlp, EObj_t *objp, char *sw_state)
16030Sstevel@tonic-gate {
16040Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
16050Sstevel@tonic-gate 	boolean_t active_low;
16060Sstevel@tonic-gate 	int32_t bit_value;
16070Sstevel@tonic-gate 	char *physid;
16080Sstevel@tonic-gate 	EObj_t *physobjp;
16090Sstevel@tonic-gate 
16100Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
16110Sstevel@tonic-gate 		errno = ENODEV;
16120Sstevel@tonic-gate 		return (PSVC_FAILURE);
16130Sstevel@tonic-gate 	}
16140Sstevel@tonic-gate 
16150Sstevel@tonic-gate 	strcpy(objp->previous_state, objp->state);
16160Sstevel@tonic-gate 	strcpy(objp->state, sw_state);
16170Sstevel@tonic-gate 
16180Sstevel@tonic-gate 	active_low = PSVC_IS_ACTIVE_LOW(objp->addr_spec);
16190Sstevel@tonic-gate 
16200Sstevel@tonic-gate 	if (active_low)
16210Sstevel@tonic-gate 		if (strcmp(sw_state, PSVC_SWITCH_ON) == 0)
16220Sstevel@tonic-gate 			bit_value = 0;
16230Sstevel@tonic-gate 		else
16240Sstevel@tonic-gate 			bit_value = 1;
16250Sstevel@tonic-gate 	else
16260Sstevel@tonic-gate 		if (strcmp(sw_state, PSVC_SWITCH_ON) == 0)
16270Sstevel@tonic-gate 			bit_value = 1;
16280Sstevel@tonic-gate 		else
16290Sstevel@tonic-gate 			bit_value = 0;
16300Sstevel@tonic-gate 
16310Sstevel@tonic-gate 	status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
16320Sstevel@tonic-gate 		0, &physid);
16330Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
16340Sstevel@tonic-gate 		return (status);
16350Sstevel@tonic-gate 	status = i_psvc_get_obj(hdlp, physid, &physobjp);
16360Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
16370Sstevel@tonic-gate 		return (status);
16380Sstevel@tonic-gate 
16390Sstevel@tonic-gate 	status = ((EPhysDev_t *)physobjp)->set_bit(hdlp, objp->addr_spec,
16400Sstevel@tonic-gate 		bit_value);
16410Sstevel@tonic-gate 	return (status);
16420Sstevel@tonic-gate }
16430Sstevel@tonic-gate 
16440Sstevel@tonic-gate /* LM75 */
16450Sstevel@tonic-gate static int32_t
i_psvc_get_temperature_11_2(EHdl_t * hdlp,uint64_t aspec,int32_t * temp)16460Sstevel@tonic-gate i_psvc_get_temperature_11_2(EHdl_t *hdlp, uint64_t aspec, int32_t *temp)
16470Sstevel@tonic-gate {
16480Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
16490Sstevel@tonic-gate 	char path[1024];
16500Sstevel@tonic-gate 	int32_t fp;
16510Sstevel@tonic-gate 	int16_t temp16;
16520Sstevel@tonic-gate 
16530Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
16540Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
16550Sstevel@tonic-gate 		return (status);
16560Sstevel@tonic-gate 
16570Sstevel@tonic-gate 	fp = open(path, O_RDWR);
16580Sstevel@tonic-gate 	if (fp == -1)
16590Sstevel@tonic-gate 		return (PSVC_FAILURE);
16600Sstevel@tonic-gate 
16610Sstevel@tonic-gate 	status = ioctl_retry(fp, I2C_GET_TEMPERATURE, (void *)&temp16);
16620Sstevel@tonic-gate 	if (status == -1) {
16630Sstevel@tonic-gate 		close(fp);
16640Sstevel@tonic-gate 		errno = EIO;
16650Sstevel@tonic-gate 		return (PSVC_FAILURE);
16660Sstevel@tonic-gate 	}
16670Sstevel@tonic-gate 	*temp = temp16;
16680Sstevel@tonic-gate 
16690Sstevel@tonic-gate 	close(fp);
16700Sstevel@tonic-gate 
16710Sstevel@tonic-gate 	return (status);
16720Sstevel@tonic-gate }
16730Sstevel@tonic-gate 
16740Sstevel@tonic-gate /* MAX1617 */
16750Sstevel@tonic-gate static int32_t
i_psvc_get_temperature_11_4(EHdl_t * hdlp,uint64_t aspec,int32_t * temp)16760Sstevel@tonic-gate i_psvc_get_temperature_11_4(EHdl_t *hdlp, uint64_t aspec, int32_t *temp)
16770Sstevel@tonic-gate {
16780Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
16790Sstevel@tonic-gate 	char path[1024];
16800Sstevel@tonic-gate 	int32_t fp;
16810Sstevel@tonic-gate 	int16_t temp16;
16820Sstevel@tonic-gate 
16830Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
16840Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
16850Sstevel@tonic-gate 		return (status);
16860Sstevel@tonic-gate 
16870Sstevel@tonic-gate 	fp = open(path, O_RDWR);
16880Sstevel@tonic-gate 	if (fp == -1)
16890Sstevel@tonic-gate 		return (PSVC_FAILURE);
16900Sstevel@tonic-gate 
16910Sstevel@tonic-gate 	status = ioctl_retry(fp, I2C_GET_TEMPERATURE, (void *)&temp16);
16920Sstevel@tonic-gate 	if (status == -1) {
16930Sstevel@tonic-gate 		close(fp);
16940Sstevel@tonic-gate 		errno = EIO;
16950Sstevel@tonic-gate 		return (PSVC_FAILURE);
16960Sstevel@tonic-gate 	}
16970Sstevel@tonic-gate 	*temp = temp16;
16980Sstevel@tonic-gate 
16990Sstevel@tonic-gate 	close(fp);
17000Sstevel@tonic-gate 
17010Sstevel@tonic-gate 	return (status);
17020Sstevel@tonic-gate }
17030Sstevel@tonic-gate 
17040Sstevel@tonic-gate /* PCF8591 */
17050Sstevel@tonic-gate static int32_t
i_psvc_get_temperature_11_6(EHdl_t * hdlp,uint64_t aspec,int32_t * temp)17060Sstevel@tonic-gate i_psvc_get_temperature_11_6(EHdl_t *hdlp, uint64_t aspec, int32_t *temp)
17070Sstevel@tonic-gate {
17080Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
17090Sstevel@tonic-gate 	char path[1024];
17100Sstevel@tonic-gate 	int32_t fp;
17110Sstevel@tonic-gate 
17120Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
17130Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
17140Sstevel@tonic-gate 		return (status);
17150Sstevel@tonic-gate 
17160Sstevel@tonic-gate 	fp = open(path, O_RDWR);
17170Sstevel@tonic-gate 	if (fp == -1)
17180Sstevel@tonic-gate 		return (PSVC_FAILURE);
17190Sstevel@tonic-gate 
17200Sstevel@tonic-gate 	status = ioctl_retry(fp, I2C_GET_INPUT, (void *)temp);
17210Sstevel@tonic-gate 	if (status == -1) {
17220Sstevel@tonic-gate 		close(fp);
17230Sstevel@tonic-gate 		errno = EIO;
17240Sstevel@tonic-gate 		return (-1);
17250Sstevel@tonic-gate 	}
17260Sstevel@tonic-gate 
17270Sstevel@tonic-gate 	close(fp);
17280Sstevel@tonic-gate 
17290Sstevel@tonic-gate 	return (status);
17300Sstevel@tonic-gate }
17310Sstevel@tonic-gate 
17320Sstevel@tonic-gate /* SSC050 */
17330Sstevel@tonic-gate static int32_t
i_psvc_get_fanspeed_11_7(EHdl_t * hdlp,uint64_t aspec,int32_t * fan_speed)17340Sstevel@tonic-gate i_psvc_get_fanspeed_11_7(EHdl_t *hdlp, uint64_t aspec, int32_t *fan_speed)
17350Sstevel@tonic-gate {
17360Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
17370Sstevel@tonic-gate 	char path[1024];
17380Sstevel@tonic-gate 	int32_t fp;
17390Sstevel@tonic-gate 
17400Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
17410Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
17420Sstevel@tonic-gate 		return (status);
17430Sstevel@tonic-gate 
17440Sstevel@tonic-gate 	fp = open(path, O_RDWR);
17450Sstevel@tonic-gate 	if (fp == -1)
17460Sstevel@tonic-gate 		return (PSVC_FAILURE);
17470Sstevel@tonic-gate 
17480Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_GET_FAN_SPEED, (void *)fan_speed);
17490Sstevel@tonic-gate 	if (ret == -1) {
17500Sstevel@tonic-gate 		close(fp);
17510Sstevel@tonic-gate 		errno = EIO;
17520Sstevel@tonic-gate 		return (-1);
17530Sstevel@tonic-gate 	}
17540Sstevel@tonic-gate 
17550Sstevel@tonic-gate 	close(fp);
17560Sstevel@tonic-gate 
17570Sstevel@tonic-gate 	return (status);
17580Sstevel@tonic-gate }
17590Sstevel@tonic-gate 
17600Sstevel@tonic-gate /* PCF8591 */
17610Sstevel@tonic-gate static int32_t
i_psvc_get_input_11_6(EHdl_t * hdlp,uint64_t aspec,int32_t * value)17620Sstevel@tonic-gate i_psvc_get_input_11_6(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
17630Sstevel@tonic-gate {
17640Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
17650Sstevel@tonic-gate 	char path[1024];
17660Sstevel@tonic-gate 	int32_t fp;
17670Sstevel@tonic-gate 
17680Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
17690Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
17700Sstevel@tonic-gate 		return (status);
17710Sstevel@tonic-gate 
17720Sstevel@tonic-gate 	fp = open(path, O_RDWR);
17730Sstevel@tonic-gate 	if (fp == -1)
17740Sstevel@tonic-gate 		return (PSVC_FAILURE);
17750Sstevel@tonic-gate 
17760Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_GET_INPUT, (void *)value);
17770Sstevel@tonic-gate 	if (ret == -1) {
17780Sstevel@tonic-gate 		close(fp);
17790Sstevel@tonic-gate 		errno = EIO;
17800Sstevel@tonic-gate 		return (-1);
17810Sstevel@tonic-gate 	}
17820Sstevel@tonic-gate 
17830Sstevel@tonic-gate 	close(fp);
17840Sstevel@tonic-gate 
17850Sstevel@tonic-gate 	return (status);
17860Sstevel@tonic-gate }
17870Sstevel@tonic-gate 
17880Sstevel@tonic-gate /* LTC1427 */
17890Sstevel@tonic-gate static int32_t
i_psvc_get_output_11_3(EHdl_t * hdlp,uint64_t aspec,int32_t * value)17900Sstevel@tonic-gate i_psvc_get_output_11_3(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
17910Sstevel@tonic-gate {
17920Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
17930Sstevel@tonic-gate 	char path[1024];
17940Sstevel@tonic-gate 	int32_t fp;
17950Sstevel@tonic-gate 
17960Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
17970Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
17980Sstevel@tonic-gate 		return (status);
17990Sstevel@tonic-gate 
18000Sstevel@tonic-gate 	fp = open(path, O_RDWR);
18010Sstevel@tonic-gate 	if (fp == -1)
18020Sstevel@tonic-gate 		return (PSVC_FAILURE);
18030Sstevel@tonic-gate 
18040Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_GET_OUTPUT, (void *)value);
18050Sstevel@tonic-gate 	if (ret == -1) {
18060Sstevel@tonic-gate 		close(fp);
18070Sstevel@tonic-gate 		errno = EIO;
18080Sstevel@tonic-gate 		return (PSVC_FAILURE);
18090Sstevel@tonic-gate 	}
18100Sstevel@tonic-gate 
18110Sstevel@tonic-gate 	close(fp);
18120Sstevel@tonic-gate 
18130Sstevel@tonic-gate 	return (status);
18140Sstevel@tonic-gate }
18150Sstevel@tonic-gate 
18160Sstevel@tonic-gate /* PCF8591 */
18170Sstevel@tonic-gate static int32_t
i_psvc_get_output_11_6(EHdl_t * hdlp,uint64_t aspec,int32_t * value)18180Sstevel@tonic-gate i_psvc_get_output_11_6(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
18190Sstevel@tonic-gate {
18200Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
18210Sstevel@tonic-gate 	char path[1024];
18220Sstevel@tonic-gate 	int32_t fp;
18230Sstevel@tonic-gate 
18240Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
18250Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
18260Sstevel@tonic-gate 		return (status);
18270Sstevel@tonic-gate 
18280Sstevel@tonic-gate 	fp = open(path, O_RDWR);
18290Sstevel@tonic-gate 	if (fp == -1)
18300Sstevel@tonic-gate 		return (PSVC_FAILURE);
18310Sstevel@tonic-gate 
18320Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_GET_OUTPUT, (void *)value);
18330Sstevel@tonic-gate 	if (ret == -1) {
18340Sstevel@tonic-gate 		close(fp);
18350Sstevel@tonic-gate 		errno = EIO;
18360Sstevel@tonic-gate 		return (PSVC_FAILURE);
18370Sstevel@tonic-gate 	}
18380Sstevel@tonic-gate 
18390Sstevel@tonic-gate 	close(fp);
18400Sstevel@tonic-gate 
18410Sstevel@tonic-gate 	return (status);
18420Sstevel@tonic-gate }
18430Sstevel@tonic-gate 
18440Sstevel@tonic-gate /* TDA8444 */
18450Sstevel@tonic-gate static int32_t
i_psvc_get_output_11_8(EHdl_t * hdlp,uint64_t aspec,int32_t * value)18460Sstevel@tonic-gate i_psvc_get_output_11_8(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
18470Sstevel@tonic-gate {
18480Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
18490Sstevel@tonic-gate 	char path[1024];
18500Sstevel@tonic-gate 	int32_t fp;
18510Sstevel@tonic-gate 	int8_t buf;
18520Sstevel@tonic-gate 
18530Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
18540Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
18550Sstevel@tonic-gate 		return (status);
18560Sstevel@tonic-gate 
18570Sstevel@tonic-gate 	fp = open(path, O_RDWR);
18580Sstevel@tonic-gate 	if (fp == -1)
18590Sstevel@tonic-gate 		return (PSVC_FAILURE);
18600Sstevel@tonic-gate 
18610Sstevel@tonic-gate 	ret = read(fp, &buf, 1);
18620Sstevel@tonic-gate 	if (ret == -1) {
18630Sstevel@tonic-gate 		close(fp);
18640Sstevel@tonic-gate 		errno = EIO;
18650Sstevel@tonic-gate 		return (PSVC_FAILURE);
18660Sstevel@tonic-gate 	}
18670Sstevel@tonic-gate 	*value = buf;
18680Sstevel@tonic-gate 
18690Sstevel@tonic-gate 	close(fp);
18700Sstevel@tonic-gate 
18710Sstevel@tonic-gate 	return (status);
18720Sstevel@tonic-gate }
18730Sstevel@tonic-gate 
18740Sstevel@tonic-gate /* LTC1427 */
18750Sstevel@tonic-gate static int32_t
i_psvc_set_output_11_3(EHdl_t * hdlp,uint64_t aspec,int32_t value)18760Sstevel@tonic-gate i_psvc_set_output_11_3(EHdl_t *hdlp, uint64_t aspec, int32_t value)
18770Sstevel@tonic-gate {
18780Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
18790Sstevel@tonic-gate 	char path[1024];
18800Sstevel@tonic-gate 	int32_t fp;
18810Sstevel@tonic-gate 
18820Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
18830Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
18840Sstevel@tonic-gate 		return (status);
18850Sstevel@tonic-gate 
18860Sstevel@tonic-gate 	fp = open(path, O_RDWR);
18870Sstevel@tonic-gate 	if (fp == -1)
18880Sstevel@tonic-gate 		return (PSVC_FAILURE);
18890Sstevel@tonic-gate 
18900Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_SET_OUTPUT, (void *)&value);
18910Sstevel@tonic-gate 	if (ret == -1) {
18920Sstevel@tonic-gate 		close(fp);
18930Sstevel@tonic-gate 		errno = EIO;
18940Sstevel@tonic-gate 		return (PSVC_FAILURE);
18950Sstevel@tonic-gate 	}
18960Sstevel@tonic-gate 
18970Sstevel@tonic-gate 	close(fp);
18980Sstevel@tonic-gate 
18990Sstevel@tonic-gate 	return (status);
19000Sstevel@tonic-gate }
19010Sstevel@tonic-gate 
19020Sstevel@tonic-gate /* PCF8591 */
19030Sstevel@tonic-gate static int32_t
i_psvc_set_output_11_6(EHdl_t * hdlp,uint64_t aspec,int32_t value)19040Sstevel@tonic-gate i_psvc_set_output_11_6(EHdl_t *hdlp, uint64_t aspec, int32_t value)
19050Sstevel@tonic-gate {
19060Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
19070Sstevel@tonic-gate 	char path[1024];
19080Sstevel@tonic-gate 	int32_t fp;
19090Sstevel@tonic-gate 
19100Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
19110Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
19120Sstevel@tonic-gate 		return (status);
19130Sstevel@tonic-gate 
19140Sstevel@tonic-gate 	fp = open(path, O_RDWR);
19150Sstevel@tonic-gate 	if (fp == -1)
19160Sstevel@tonic-gate 		return (PSVC_FAILURE);
19170Sstevel@tonic-gate 
19180Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_SET_OUTPUT, (void *)&value);
19190Sstevel@tonic-gate 	if (ret == -1) {
19200Sstevel@tonic-gate 		close(fp);
19210Sstevel@tonic-gate 		errno = EIO;
19220Sstevel@tonic-gate 		return (PSVC_FAILURE);
19230Sstevel@tonic-gate 	}
19240Sstevel@tonic-gate 
19250Sstevel@tonic-gate 	close(fp);
19260Sstevel@tonic-gate 
19270Sstevel@tonic-gate 	return (status);
19280Sstevel@tonic-gate }
19290Sstevel@tonic-gate 
19300Sstevel@tonic-gate /* TDA8444 */
19310Sstevel@tonic-gate static int32_t
i_psvc_set_output_11_8(EHdl_t * hdlp,uint64_t aspec,int32_t value)19320Sstevel@tonic-gate i_psvc_set_output_11_8(EHdl_t *hdlp, uint64_t aspec, int32_t value)
19330Sstevel@tonic-gate {
19340Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
19350Sstevel@tonic-gate 	char path[1024];
19360Sstevel@tonic-gate 	int32_t fp;
19370Sstevel@tonic-gate 	int8_t buf;
19380Sstevel@tonic-gate 
19390Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
19400Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
19410Sstevel@tonic-gate 		return (status);
19420Sstevel@tonic-gate 
19430Sstevel@tonic-gate 	fp = open(path, O_RDWR);
19440Sstevel@tonic-gate 	if (fp == -1)
19450Sstevel@tonic-gate 		return (PSVC_FAILURE);
19460Sstevel@tonic-gate 
19470Sstevel@tonic-gate 	buf = value;
19480Sstevel@tonic-gate 	ret = write(fp, &buf, 1);
19490Sstevel@tonic-gate 	if (ret == -1) {
19500Sstevel@tonic-gate 		close(fp);
19510Sstevel@tonic-gate 		errno = EIO;
19520Sstevel@tonic-gate 		return (PSVC_FAILURE);
19530Sstevel@tonic-gate 	}
19540Sstevel@tonic-gate 
19550Sstevel@tonic-gate 	close(fp);
19560Sstevel@tonic-gate 
19570Sstevel@tonic-gate 	return (status);
19580Sstevel@tonic-gate }
19590Sstevel@tonic-gate 
19600Sstevel@tonic-gate /* HPC3130 */
19610Sstevel@tonic-gate static int32_t
i_psvc_get_reg_11_1(EHdl_t * hdlp,uint64_t aspec,uint8_t * value)19620Sstevel@tonic-gate i_psvc_get_reg_11_1(EHdl_t *hdlp, uint64_t aspec, uint8_t *value)
19630Sstevel@tonic-gate {
19640Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
19650Sstevel@tonic-gate 	uint8_t bitshift, bytemask;
19660Sstevel@tonic-gate 	char path[1024];
19670Sstevel@tonic-gate 	i2c_reg_t i2cregarg;
19680Sstevel@tonic-gate 	int32_t fp;
19690Sstevel@tonic-gate 
19700Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
19710Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
19720Sstevel@tonic-gate 		return (status);
19730Sstevel@tonic-gate 	fp = open(path, O_RDWR);
19740Sstevel@tonic-gate 	if (fp == -1)
19750Sstevel@tonic-gate 		return (PSVC_FAILURE);
19760Sstevel@tonic-gate 
19770Sstevel@tonic-gate 	i2cregarg.reg_num = PSVC_GET_ASPEC_REG(aspec);
19780Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_GET_REG, (void *)&i2cregarg);
19790Sstevel@tonic-gate 	if (ret == -1) {
19800Sstevel@tonic-gate 		close(fp);
19810Sstevel@tonic-gate 		errno = EIO;
19820Sstevel@tonic-gate 		return (-1);
19830Sstevel@tonic-gate 	}
19840Sstevel@tonic-gate 
19850Sstevel@tonic-gate 	bitshift = PSVC_GET_ASPEC_BITSHIFT(aspec);
19860Sstevel@tonic-gate 	bytemask = PSVC_GET_ASPEC_BYTEMASK(aspec);
19870Sstevel@tonic-gate 	if (value != NULL)
19880Sstevel@tonic-gate 		*value = (i2cregarg.reg_value & bytemask) >> bitshift;
19890Sstevel@tonic-gate 	close(fp);
19900Sstevel@tonic-gate 
19910Sstevel@tonic-gate 	return (status);
19920Sstevel@tonic-gate }
19930Sstevel@tonic-gate 
19940Sstevel@tonic-gate /* SSC050 */
19950Sstevel@tonic-gate static int32_t
i_psvc_get_reg_11_7(EHdl_t * hdlp,uint64_t aspec,uint8_t * value)19960Sstevel@tonic-gate i_psvc_get_reg_11_7(EHdl_t *hdlp, uint64_t aspec, uint8_t *value)
19970Sstevel@tonic-gate {
19980Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
19990Sstevel@tonic-gate 	uint8_t bitshift, bytemask;
20000Sstevel@tonic-gate 	char path[1024];
20010Sstevel@tonic-gate 	i2c_reg_t i2cregarg;
20020Sstevel@tonic-gate 	int32_t fp;
20030Sstevel@tonic-gate 
20040Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
20050Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
20060Sstevel@tonic-gate 		return (status);
20070Sstevel@tonic-gate 
20080Sstevel@tonic-gate 	fp = open(path, O_RDWR);
20090Sstevel@tonic-gate 	if (fp == -1)
20100Sstevel@tonic-gate 		return (PSVC_FAILURE);
20110Sstevel@tonic-gate 
20120Sstevel@tonic-gate 	i2cregarg.reg_num = PSVC_GET_ASPEC_REG(aspec);
20130Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_GET_REG, (void *)&i2cregarg);
20140Sstevel@tonic-gate 	if (ret == -1) {
20150Sstevel@tonic-gate 		close(fp);
20160Sstevel@tonic-gate 		errno = EIO;
20170Sstevel@tonic-gate 		return (-1);
20180Sstevel@tonic-gate 	}
20190Sstevel@tonic-gate 
20200Sstevel@tonic-gate 	bitshift = PSVC_GET_ASPEC_BITSHIFT(aspec);
20210Sstevel@tonic-gate 	bytemask = PSVC_GET_ASPEC_BYTEMASK(aspec);
20220Sstevel@tonic-gate 	if (value != NULL)
20230Sstevel@tonic-gate 		*value = (i2cregarg.reg_value & bytemask) >> bitshift;
20240Sstevel@tonic-gate 
20250Sstevel@tonic-gate 	close(fp);
20260Sstevel@tonic-gate 
20270Sstevel@tonic-gate 	return (status);
20280Sstevel@tonic-gate }
20290Sstevel@tonic-gate 
20300Sstevel@tonic-gate /* HPC3130 */
20310Sstevel@tonic-gate static int32_t
i_psvc_set_reg_11_1(EHdl_t * hdlp,uint64_t aspec,int32_t value)20320Sstevel@tonic-gate i_psvc_set_reg_11_1(EHdl_t *hdlp, uint64_t aspec, int32_t value)
20330Sstevel@tonic-gate {
20340Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
20350Sstevel@tonic-gate 	char path[1024];
20360Sstevel@tonic-gate 	i2c_reg_t i2cregarg;
20370Sstevel@tonic-gate 	int8_t tval;
20380Sstevel@tonic-gate 	uint8_t bitshift, bytemask;
20390Sstevel@tonic-gate 	int32_t fp;
20400Sstevel@tonic-gate 
20410Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
20420Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
20430Sstevel@tonic-gate 		return (status);
20440Sstevel@tonic-gate 
20450Sstevel@tonic-gate 	bitshift = PSVC_GET_ASPEC_BITSHIFT(aspec);
20460Sstevel@tonic-gate 	bytemask = PSVC_GET_ASPEC_BYTEMASK(aspec);
20470Sstevel@tonic-gate 	value = value << bitshift;
20480Sstevel@tonic-gate 
20490Sstevel@tonic-gate 	fp = open(path, O_RDWR);
20500Sstevel@tonic-gate 	if (fp == -1)
20510Sstevel@tonic-gate 		return (PSVC_FAILURE);
20520Sstevel@tonic-gate 
20530Sstevel@tonic-gate 	i2cregarg.reg_num = PSVC_GET_ASPEC_REG(aspec);
20540Sstevel@tonic-gate 	if (bytemask != 0xFF) {
20550Sstevel@tonic-gate 		ret = ioctl_retry(fp, I2C_GET_REG, (void *)&i2cregarg);
20560Sstevel@tonic-gate 		if (ret == -1) {
20570Sstevel@tonic-gate 			close(fp);
20580Sstevel@tonic-gate 			errno = EIO;
20590Sstevel@tonic-gate 			return (-1);
20600Sstevel@tonic-gate 		}
20610Sstevel@tonic-gate 		tval = i2cregarg.reg_value;
20620Sstevel@tonic-gate 		tval = tval & ~bytemask;
20630Sstevel@tonic-gate 	} else
20640Sstevel@tonic-gate 		tval = 0;
20650Sstevel@tonic-gate 
20660Sstevel@tonic-gate 	value = tval | value;
20670Sstevel@tonic-gate 	i2cregarg.reg_value = value;
20680Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_SET_REG, (void *)&i2cregarg);
20690Sstevel@tonic-gate 	if (ret == -1) {
20700Sstevel@tonic-gate 		close(fp);
20710Sstevel@tonic-gate 		errno = EIO;
20720Sstevel@tonic-gate 		return (-1);
20730Sstevel@tonic-gate 	}
20740Sstevel@tonic-gate 
20750Sstevel@tonic-gate 	close(fp);
20760Sstevel@tonic-gate 
20770Sstevel@tonic-gate 	return (status);
20780Sstevel@tonic-gate }
20790Sstevel@tonic-gate 
20800Sstevel@tonic-gate /* SSC050 */
20810Sstevel@tonic-gate static int32_t
i_psvc_set_reg_11_7(EHdl_t * hdlp,uint64_t aspec,int32_t value)20820Sstevel@tonic-gate i_psvc_set_reg_11_7(EHdl_t *hdlp, uint64_t aspec, int32_t value)
20830Sstevel@tonic-gate {
20840Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
20850Sstevel@tonic-gate 	char path[1024];
20860Sstevel@tonic-gate 	i2c_reg_t i2cregarg;
20870Sstevel@tonic-gate 	int8_t tval;
20880Sstevel@tonic-gate 	uint8_t bitshift, bytemask;
20890Sstevel@tonic-gate 	int32_t fp;
20900Sstevel@tonic-gate 
20910Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
20920Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
20930Sstevel@tonic-gate 		return (status);
20940Sstevel@tonic-gate 
20950Sstevel@tonic-gate 	bitshift = PSVC_GET_ASPEC_BITSHIFT(aspec);
20960Sstevel@tonic-gate 	bytemask = PSVC_GET_ASPEC_BYTEMASK(aspec);
20970Sstevel@tonic-gate 	value = value << bitshift;
20980Sstevel@tonic-gate 
20990Sstevel@tonic-gate 	fp = open(path, O_RDWR);
21000Sstevel@tonic-gate 	if (fp == -1)
21010Sstevel@tonic-gate 		return (PSVC_FAILURE);
21020Sstevel@tonic-gate 
21030Sstevel@tonic-gate 	i2cregarg.reg_num = PSVC_GET_ASPEC_REG(aspec);
21040Sstevel@tonic-gate 	if (bytemask != 0xFF) {
21050Sstevel@tonic-gate 		ret = ioctl_retry(fp, I2C_GET_REG, (void *)&i2cregarg);
21060Sstevel@tonic-gate 		if (ret == -1) {
21070Sstevel@tonic-gate 			close(fp);
21080Sstevel@tonic-gate 			errno = EIO;
21090Sstevel@tonic-gate 			return (-1);
21100Sstevel@tonic-gate 		}
21110Sstevel@tonic-gate 		tval = i2cregarg.reg_value;
21120Sstevel@tonic-gate 		tval = tval & ~bytemask;
21130Sstevel@tonic-gate 	} else
21140Sstevel@tonic-gate 		tval = 0;
21150Sstevel@tonic-gate 
21160Sstevel@tonic-gate 	value = tval | value;
21170Sstevel@tonic-gate 	i2cregarg.reg_value = value;
21180Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_SET_REG, (void *)&i2cregarg);
21190Sstevel@tonic-gate 	if (ret == -1) {
21200Sstevel@tonic-gate 		close(fp);
21210Sstevel@tonic-gate 		errno = EIO;
21220Sstevel@tonic-gate 		return (-1);
21230Sstevel@tonic-gate 	}
21240Sstevel@tonic-gate 
21250Sstevel@tonic-gate 	close(fp);
21260Sstevel@tonic-gate 
21270Sstevel@tonic-gate 	return (status);
21280Sstevel@tonic-gate }
21290Sstevel@tonic-gate 
21300Sstevel@tonic-gate /* PCF8574 */
21310Sstevel@tonic-gate static int32_t
i_psvc_get_bit_11_5(EHdl_t * hdlp,uint64_t aspec,int32_t * value)21320Sstevel@tonic-gate i_psvc_get_bit_11_5(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
21330Sstevel@tonic-gate {
21340Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
21350Sstevel@tonic-gate 	char path[1024];
21360Sstevel@tonic-gate 	i2c_bit_t bitarg;
21370Sstevel@tonic-gate 	int32_t fp;
21380Sstevel@tonic-gate 
21390Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
21400Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
21410Sstevel@tonic-gate 		return (status);
21420Sstevel@tonic-gate 
21430Sstevel@tonic-gate 	bitarg.bit_num = PSVC_GET_BIT_NUM(aspec);
21440Sstevel@tonic-gate 	bitarg.direction = DIR_NO_CHANGE;
21450Sstevel@tonic-gate 
21460Sstevel@tonic-gate 	fp = open(path, O_RDWR);
21470Sstevel@tonic-gate 	if (fp == -1)
21480Sstevel@tonic-gate 		return (PSVC_FAILURE);
21490Sstevel@tonic-gate 
21500Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_GET_BIT, (void *)&bitarg);
21510Sstevel@tonic-gate 	if (ret == -1) {
21520Sstevel@tonic-gate 		close(fp);
21530Sstevel@tonic-gate 		errno = EIO;
21540Sstevel@tonic-gate 		return (-1);
21550Sstevel@tonic-gate 	}
21560Sstevel@tonic-gate 
21570Sstevel@tonic-gate 	*value = bitarg.bit_value;
21580Sstevel@tonic-gate 
21590Sstevel@tonic-gate 	close(fp);
21600Sstevel@tonic-gate 
21610Sstevel@tonic-gate 	return (status);
21620Sstevel@tonic-gate }
21630Sstevel@tonic-gate 
21640Sstevel@tonic-gate /* PCF8574 */
21650Sstevel@tonic-gate static int32_t
i_psvc_get_port_11_5(EHdl_t * hdlp,uint64_t aspec,uint8_t * value)21660Sstevel@tonic-gate i_psvc_get_port_11_5(EHdl_t *hdlp, uint64_t aspec, uint8_t *value)
21670Sstevel@tonic-gate {
21680Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
21690Sstevel@tonic-gate 	char path[1024];
21700Sstevel@tonic-gate 	i2c_port_t port;
21710Sstevel@tonic-gate 	int32_t fp;
21720Sstevel@tonic-gate 
21730Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
21740Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
21750Sstevel@tonic-gate 		return (status);
21760Sstevel@tonic-gate 
21770Sstevel@tonic-gate 	port.direction = DIR_NO_CHANGE;
21780Sstevel@tonic-gate 
21790Sstevel@tonic-gate 	fp = open(path, O_RDWR);
21800Sstevel@tonic-gate 	if (fp == -1)
21810Sstevel@tonic-gate 		return (PSVC_FAILURE);
21820Sstevel@tonic-gate 
21830Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_GET_PORT, (void *)&port);
21840Sstevel@tonic-gate 	if (ret == -1) {
21850Sstevel@tonic-gate 		close(fp);
21860Sstevel@tonic-gate 		errno = EIO;
21870Sstevel@tonic-gate 		return (-1);
21880Sstevel@tonic-gate 	}
21890Sstevel@tonic-gate 
21900Sstevel@tonic-gate 	*value = port.value;
21910Sstevel@tonic-gate 
21920Sstevel@tonic-gate 	close(fp);
21930Sstevel@tonic-gate 
21940Sstevel@tonic-gate 	return (status);
21950Sstevel@tonic-gate }
21960Sstevel@tonic-gate 
21970Sstevel@tonic-gate /* SSC050 */
21980Sstevel@tonic-gate static int32_t
i_psvc_get_bit_11_7(EHdl_t * hdlp,uint64_t aspec,int32_t * value)21990Sstevel@tonic-gate i_psvc_get_bit_11_7(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
22000Sstevel@tonic-gate {
22010Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
22020Sstevel@tonic-gate 	char path[1024];
22030Sstevel@tonic-gate 	i2c_bit_t bitarg;
22040Sstevel@tonic-gate 	int32_t fp;
22050Sstevel@tonic-gate 
22060Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
22070Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
22080Sstevel@tonic-gate 		return (status);
22090Sstevel@tonic-gate 
22100Sstevel@tonic-gate 	bitarg.bit_num = PSVC_GET_BIT_NUM(aspec);
22110Sstevel@tonic-gate 	bitarg.direction = DIR_NO_CHANGE;
22120Sstevel@tonic-gate 
22130Sstevel@tonic-gate 	fp = open(path, O_RDWR);
22140Sstevel@tonic-gate 	if (fp == -1)
22150Sstevel@tonic-gate 		return (PSVC_FAILURE);
22160Sstevel@tonic-gate 
22170Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_GET_BIT, (void *)&bitarg);
22180Sstevel@tonic-gate 	if (ret == -1) {
22190Sstevel@tonic-gate 		close(fp);
22200Sstevel@tonic-gate 		errno = EIO;
22210Sstevel@tonic-gate 		return (-1);
22220Sstevel@tonic-gate 	}
22230Sstevel@tonic-gate 
22240Sstevel@tonic-gate 	*value = bitarg.bit_value;
22250Sstevel@tonic-gate 
22260Sstevel@tonic-gate 	close(fp);
22270Sstevel@tonic-gate 
22280Sstevel@tonic-gate 	return (status);
22290Sstevel@tonic-gate }
22300Sstevel@tonic-gate 
22310Sstevel@tonic-gate /* PCF8574 */
22320Sstevel@tonic-gate static int32_t
i_psvc_set_bit_11_5(EHdl_t * hdlp,uint64_t aspec,int32_t value)22330Sstevel@tonic-gate i_psvc_set_bit_11_5(EHdl_t *hdlp, uint64_t aspec, int32_t value)
22340Sstevel@tonic-gate {
22350Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
22360Sstevel@tonic-gate 	char path[1024];
22370Sstevel@tonic-gate 	i2c_bit_t bitarg;
22380Sstevel@tonic-gate 	int32_t fp;
22390Sstevel@tonic-gate 
22400Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
22410Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
22420Sstevel@tonic-gate 		return (status);
22430Sstevel@tonic-gate 
22440Sstevel@tonic-gate 	bitarg.bit_value = value;
22450Sstevel@tonic-gate 	bitarg.bit_num = PSVC_GET_BIT_NUM(aspec);
22460Sstevel@tonic-gate 	bitarg.direction = DIR_OUTPUT;
22470Sstevel@tonic-gate 	fp = open(path, O_RDWR);
22480Sstevel@tonic-gate 	if (fp == -1)
22490Sstevel@tonic-gate 		return (PSVC_FAILURE);
22500Sstevel@tonic-gate 
22510Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_SET_BIT, (void *)&bitarg);
22520Sstevel@tonic-gate 	if (ret == -1) {
22530Sstevel@tonic-gate 		close(fp);
22540Sstevel@tonic-gate 		errno = EIO;
22550Sstevel@tonic-gate 		return (-1);
22560Sstevel@tonic-gate 	}
22570Sstevel@tonic-gate 
22580Sstevel@tonic-gate 	close(fp);
22590Sstevel@tonic-gate 
22600Sstevel@tonic-gate 	return (status);
22610Sstevel@tonic-gate }
22620Sstevel@tonic-gate 
22630Sstevel@tonic-gate /* PCF8574 */
22640Sstevel@tonic-gate static int32_t
i_psvc_set_port_11_5(EHdl_t * hdlp,uint64_t aspec,int32_t value)22650Sstevel@tonic-gate i_psvc_set_port_11_5(EHdl_t *hdlp, uint64_t aspec, int32_t value)
22660Sstevel@tonic-gate {
22670Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
22680Sstevel@tonic-gate 	char path[1024];
22690Sstevel@tonic-gate 	i2c_port_t port;
22700Sstevel@tonic-gate 	int32_t fp;
22710Sstevel@tonic-gate 
22720Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
22730Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
22740Sstevel@tonic-gate 		return (status);
22750Sstevel@tonic-gate 
22760Sstevel@tonic-gate 	port.value = (uint8_t)value;
22770Sstevel@tonic-gate 	port.direction = DIR_NO_CHANGE;
22780Sstevel@tonic-gate 	fp = open(path, O_RDWR);
22790Sstevel@tonic-gate 	if (fp == -1)
22800Sstevel@tonic-gate 		return (PSVC_FAILURE);
22810Sstevel@tonic-gate 
22820Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_SET_PORT, (void *)&port);
22830Sstevel@tonic-gate 	if (ret == -1) {
22840Sstevel@tonic-gate 		close(fp);
22850Sstevel@tonic-gate 		errno = EIO;
22860Sstevel@tonic-gate 		return (-1);
22870Sstevel@tonic-gate 	}
22880Sstevel@tonic-gate 
22890Sstevel@tonic-gate 	close(fp);
22900Sstevel@tonic-gate 
22910Sstevel@tonic-gate 	return (status);
22920Sstevel@tonic-gate }
22930Sstevel@tonic-gate 
22940Sstevel@tonic-gate /* SSC050 */
22950Sstevel@tonic-gate static int32_t
i_psvc_set_bit_11_7(EHdl_t * hdlp,uint64_t aspec,int32_t value)22960Sstevel@tonic-gate i_psvc_set_bit_11_7(EHdl_t *hdlp, uint64_t aspec, int32_t value)
22970Sstevel@tonic-gate {
22980Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
22990Sstevel@tonic-gate 	char path[1024];
23000Sstevel@tonic-gate 	i2c_bit_t bitarg;
23010Sstevel@tonic-gate 	int32_t fp;
23020Sstevel@tonic-gate 
23030Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, aspec, path);
23040Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
23050Sstevel@tonic-gate 		return (status);
23060Sstevel@tonic-gate 
23070Sstevel@tonic-gate 	bitarg.bit_value = value;
23080Sstevel@tonic-gate 	bitarg.bit_num = PSVC_GET_BIT_NUM(aspec);
23090Sstevel@tonic-gate 	bitarg.direction = DIR_OUTPUT;
23100Sstevel@tonic-gate 
23110Sstevel@tonic-gate 	fp = open(path, O_RDWR);
23120Sstevel@tonic-gate 	if (fp == -1)
23130Sstevel@tonic-gate 		return (PSVC_FAILURE);
23140Sstevel@tonic-gate 
23150Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_SET_BIT, (void *)&bitarg);
23160Sstevel@tonic-gate 	if (ret == -1) {
23170Sstevel@tonic-gate 		close(fp);
23180Sstevel@tonic-gate 		errno = EIO;
23190Sstevel@tonic-gate 		return (-1);
23200Sstevel@tonic-gate 	}
23210Sstevel@tonic-gate 
23220Sstevel@tonic-gate 	close(fp);
23230Sstevel@tonic-gate 
23240Sstevel@tonic-gate 	return (status);
23250Sstevel@tonic-gate }
23260Sstevel@tonic-gate 
23270Sstevel@tonic-gate /* AT24 */
23280Sstevel@tonic-gate static int32_t
i_psvc_probe_11_0(EHdl_t * hdlp,EObj_t * objp)23290Sstevel@tonic-gate i_psvc_probe_11_0(EHdl_t *hdlp, EObj_t *objp)
23300Sstevel@tonic-gate {
23310Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
23320Sstevel@tonic-gate 	uint8_t value;
23330Sstevel@tonic-gate 	char path[1024];
23340Sstevel@tonic-gate 	int32_t fp;
23350Sstevel@tonic-gate 
23360Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
23370Sstevel@tonic-gate 		errno = ENODEV;
23380Sstevel@tonic-gate 		return (PSVC_FAILURE);
23390Sstevel@tonic-gate 	}
23400Sstevel@tonic-gate 
23410Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
23420Sstevel@tonic-gate 	if (status != PSVC_SUCCESS) {
23430Sstevel@tonic-gate 		return (status);
23440Sstevel@tonic-gate 	}
23450Sstevel@tonic-gate 
23460Sstevel@tonic-gate 	fp = open(path, O_RDWR);
23470Sstevel@tonic-gate 	if (fp == -1) {
23480Sstevel@tonic-gate 		return (PSVC_FAILURE);
23490Sstevel@tonic-gate 	}
23500Sstevel@tonic-gate 
23510Sstevel@tonic-gate 	ret = read(fp, &value, 1);
23520Sstevel@tonic-gate 	if (ret == -1) {
23530Sstevel@tonic-gate 		close(fp);
23540Sstevel@tonic-gate 		errno = EIO;
23550Sstevel@tonic-gate 		return (-1);
23560Sstevel@tonic-gate 	}
23570Sstevel@tonic-gate 
23580Sstevel@tonic-gate 	close(fp);
23590Sstevel@tonic-gate 
23600Sstevel@tonic-gate 	return (status);
23610Sstevel@tonic-gate }
23620Sstevel@tonic-gate 
23630Sstevel@tonic-gate /* HPC3130 */
23640Sstevel@tonic-gate static int32_t
i_psvc_probe_11_1(EHdl_t * hdlp,EObj_t * objp)23650Sstevel@tonic-gate i_psvc_probe_11_1(EHdl_t *hdlp, EObj_t *objp)
23660Sstevel@tonic-gate {
23670Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
23680Sstevel@tonic-gate 	char path[1024];
23690Sstevel@tonic-gate 	i2c_reg_t reg;
23700Sstevel@tonic-gate 	int32_t fp;
23710Sstevel@tonic-gate 
23720Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
23730Sstevel@tonic-gate 		errno = ENODEV;
23740Sstevel@tonic-gate 		return (PSVC_FAILURE);
23750Sstevel@tonic-gate 	}
23760Sstevel@tonic-gate 
23770Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
23780Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
23790Sstevel@tonic-gate 		return (status);
23800Sstevel@tonic-gate 
23810Sstevel@tonic-gate 	fp = open(path, O_RDWR);
23820Sstevel@tonic-gate 	if (fp == -1)
23830Sstevel@tonic-gate 		return (PSVC_FAILURE);
23840Sstevel@tonic-gate 
23850Sstevel@tonic-gate 	reg.reg_num = 0;
23860Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_GET_REG, (void *)&reg);
23870Sstevel@tonic-gate 	if (ret == -1) {
23880Sstevel@tonic-gate 		close(fp);
23890Sstevel@tonic-gate 		errno = EIO;
23900Sstevel@tonic-gate 		return (-1);
23910Sstevel@tonic-gate 	}
23920Sstevel@tonic-gate 
23930Sstevel@tonic-gate 	close(fp);
23940Sstevel@tonic-gate 
23950Sstevel@tonic-gate 	return (status);
23960Sstevel@tonic-gate }
23970Sstevel@tonic-gate 
23980Sstevel@tonic-gate /* LM75 */
23990Sstevel@tonic-gate static int32_t
i_psvc_probe_11_2(EHdl_t * hdlp,EObj_t * objp)24000Sstevel@tonic-gate i_psvc_probe_11_2(EHdl_t *hdlp, EObj_t *objp)
24010Sstevel@tonic-gate {
24020Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
24030Sstevel@tonic-gate 	char path[1024];
24040Sstevel@tonic-gate 	int32_t fp;
24050Sstevel@tonic-gate 	int16_t temp16;
24060Sstevel@tonic-gate 
24070Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
24080Sstevel@tonic-gate 		errno = ENODEV;
24090Sstevel@tonic-gate 		return (PSVC_FAILURE);
24100Sstevel@tonic-gate 	}
24110Sstevel@tonic-gate 
24120Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
24130Sstevel@tonic-gate 	if (status != PSVC_SUCCESS) {
24140Sstevel@tonic-gate 		return (status);
24150Sstevel@tonic-gate 	}
24160Sstevel@tonic-gate 
24170Sstevel@tonic-gate 	fp = open(path, O_RDWR);
24180Sstevel@tonic-gate 	if (fp == -1) {
24190Sstevel@tonic-gate 		return (PSVC_FAILURE);
24200Sstevel@tonic-gate 	}
24210Sstevel@tonic-gate 
24220Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_GET_TEMPERATURE, (void *)&temp16);
24230Sstevel@tonic-gate 	if (ret == -1) {
24240Sstevel@tonic-gate 		close(fp);
24250Sstevel@tonic-gate 		errno = EIO;
24260Sstevel@tonic-gate 		return (-1);
24270Sstevel@tonic-gate 	}
24280Sstevel@tonic-gate 
24290Sstevel@tonic-gate 	close(fp);
24300Sstevel@tonic-gate 
24310Sstevel@tonic-gate 	return (status);
24320Sstevel@tonic-gate }
24330Sstevel@tonic-gate 
24340Sstevel@tonic-gate /* LTC1427 */
24350Sstevel@tonic-gate static int32_t
i_psvc_probe_11_3(EHdl_t * hdlp,EObj_t * objp)24360Sstevel@tonic-gate i_psvc_probe_11_3(EHdl_t *hdlp, EObj_t *objp)
24370Sstevel@tonic-gate {
24380Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
24390Sstevel@tonic-gate 	int32_t value;
24400Sstevel@tonic-gate 	char path[1024];
24410Sstevel@tonic-gate 	int32_t fp;
24420Sstevel@tonic-gate 
24430Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
24440Sstevel@tonic-gate 		errno = ENODEV;
24450Sstevel@tonic-gate 		return (PSVC_FAILURE);
24460Sstevel@tonic-gate 	}
24470Sstevel@tonic-gate 
24480Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
24490Sstevel@tonic-gate 	if (status != PSVC_SUCCESS) {
24500Sstevel@tonic-gate 		return (status);
24510Sstevel@tonic-gate 	}
24520Sstevel@tonic-gate 
24530Sstevel@tonic-gate 	fp = open(path, O_RDWR);
24540Sstevel@tonic-gate 	if (fp == -1) {
24550Sstevel@tonic-gate 		return (PSVC_FAILURE);
24560Sstevel@tonic-gate 	}
24570Sstevel@tonic-gate 
24580Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_GET_OUTPUT, (void *)&value);
24590Sstevel@tonic-gate 	if (ret == -1) {
24600Sstevel@tonic-gate 		close(fp);
24610Sstevel@tonic-gate 		errno = EINVAL;
24620Sstevel@tonic-gate 		return (-1);
24630Sstevel@tonic-gate 	}
24640Sstevel@tonic-gate 
24650Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_SET_OUTPUT, (void *)&value);
24660Sstevel@tonic-gate 	if (ret == -1) {
24670Sstevel@tonic-gate 		close(fp);
24680Sstevel@tonic-gate 		errno = EIO;
24690Sstevel@tonic-gate 		return (-1);
24700Sstevel@tonic-gate 	}
24710Sstevel@tonic-gate 
24720Sstevel@tonic-gate 	close(fp);
24730Sstevel@tonic-gate 	return (status);
24740Sstevel@tonic-gate }
24750Sstevel@tonic-gate 
24760Sstevel@tonic-gate /* MAX1617 */
24770Sstevel@tonic-gate static int32_t
i_psvc_probe_11_4(EHdl_t * hdlp,EObj_t * objp)24780Sstevel@tonic-gate i_psvc_probe_11_4(EHdl_t *hdlp, EObj_t *objp)
24790Sstevel@tonic-gate {
24800Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
24810Sstevel@tonic-gate 	char path[1024];
24820Sstevel@tonic-gate 	int32_t fp;
24830Sstevel@tonic-gate 	int16_t temp16;
24840Sstevel@tonic-gate 
24850Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
24860Sstevel@tonic-gate 		errno = ENODEV;
24870Sstevel@tonic-gate 		return (PSVC_FAILURE);
24880Sstevel@tonic-gate 	}
24890Sstevel@tonic-gate 
24900Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
24910Sstevel@tonic-gate 	if (status != PSVC_SUCCESS) {
24920Sstevel@tonic-gate 		return (status);
24930Sstevel@tonic-gate 	}
24940Sstevel@tonic-gate 
24950Sstevel@tonic-gate 	fp = open(path, O_RDWR);
24960Sstevel@tonic-gate 	if (fp == -1) {
24970Sstevel@tonic-gate 		return (PSVC_FAILURE);
24980Sstevel@tonic-gate 	}
24990Sstevel@tonic-gate 
25000Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_GET_TEMPERATURE, (void *)&temp16);
25010Sstevel@tonic-gate 	if (ret == -1) {
25020Sstevel@tonic-gate 		close(fp);
25030Sstevel@tonic-gate 		errno = EIO;
25040Sstevel@tonic-gate 		return (-1);
25050Sstevel@tonic-gate 	}
25060Sstevel@tonic-gate 
25070Sstevel@tonic-gate 	close(fp);
25080Sstevel@tonic-gate 
25090Sstevel@tonic-gate 	return (status);
25100Sstevel@tonic-gate }
25110Sstevel@tonic-gate 
25120Sstevel@tonic-gate /* PCF8574 */
25130Sstevel@tonic-gate static int32_t
i_psvc_probe_11_5(EHdl_t * hdlp,EObj_t * objp)25140Sstevel@tonic-gate i_psvc_probe_11_5(EHdl_t *hdlp, EObj_t *objp)
25150Sstevel@tonic-gate {
25160Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
25170Sstevel@tonic-gate 	char path[1024];
25180Sstevel@tonic-gate 	i2c_port_t port;
25190Sstevel@tonic-gate 	int32_t fp;
25200Sstevel@tonic-gate 
25210Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
25220Sstevel@tonic-gate 		errno = ENODEV;
25230Sstevel@tonic-gate 		return (PSVC_FAILURE);
25240Sstevel@tonic-gate 	}
25250Sstevel@tonic-gate 
25260Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
25270Sstevel@tonic-gate 	if (status != PSVC_SUCCESS) {
25280Sstevel@tonic-gate 		return (status);
25290Sstevel@tonic-gate 	}
25300Sstevel@tonic-gate 
25310Sstevel@tonic-gate 	port.direction = DIR_NO_CHANGE;
25320Sstevel@tonic-gate 
25330Sstevel@tonic-gate 	fp = open(path, O_RDWR);
25340Sstevel@tonic-gate 	if (fp == -1) {
25350Sstevel@tonic-gate 		return (PSVC_FAILURE);
25360Sstevel@tonic-gate 	}
25370Sstevel@tonic-gate 
25380Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_GET_PORT, (void *)&port);
25390Sstevel@tonic-gate 	if (ret == -1) {
25400Sstevel@tonic-gate 		close(fp);
25410Sstevel@tonic-gate 		errno = EIO;
25420Sstevel@tonic-gate 		return (-1);
25430Sstevel@tonic-gate 	}
25440Sstevel@tonic-gate 
25450Sstevel@tonic-gate 	close(fp);
25460Sstevel@tonic-gate 
25470Sstevel@tonic-gate 	return (status);
25480Sstevel@tonic-gate }
25490Sstevel@tonic-gate 
25500Sstevel@tonic-gate /* PCF8591 */
25510Sstevel@tonic-gate static int32_t
i_psvc_probe_11_6(EHdl_t * hdlp,EObj_t * objp)25520Sstevel@tonic-gate i_psvc_probe_11_6(EHdl_t *hdlp, EObj_t *objp)
25530Sstevel@tonic-gate {
25540Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
25550Sstevel@tonic-gate 	char path[1024];
25560Sstevel@tonic-gate 	int32_t arg;
25570Sstevel@tonic-gate 	int32_t fp;
25580Sstevel@tonic-gate 
25590Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
25600Sstevel@tonic-gate 		errno = ENODEV;
25610Sstevel@tonic-gate 		return (PSVC_FAILURE);
25620Sstevel@tonic-gate 	}
25630Sstevel@tonic-gate 
25640Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
25650Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
25660Sstevel@tonic-gate 		return (status);
25670Sstevel@tonic-gate 
25680Sstevel@tonic-gate 	fp = open(path, O_RDWR);
25690Sstevel@tonic-gate 	if (fp == -1)
25700Sstevel@tonic-gate 		return (PSVC_FAILURE);
25710Sstevel@tonic-gate 
25720Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_GET_INPUT, (void *)&arg);
25730Sstevel@tonic-gate 	if (ret == -1) {
25740Sstevel@tonic-gate 		close(fp);
25750Sstevel@tonic-gate 		errno = EIO;
25760Sstevel@tonic-gate 		return (-1);
25770Sstevel@tonic-gate 	}
25780Sstevel@tonic-gate 
25790Sstevel@tonic-gate 	close(fp);
25800Sstevel@tonic-gate 
25810Sstevel@tonic-gate 	return (status);
25820Sstevel@tonic-gate }
25830Sstevel@tonic-gate 
25840Sstevel@tonic-gate /* SSC050 */
25850Sstevel@tonic-gate static int32_t
i_psvc_probe_11_7(EHdl_t * hdlp,EObj_t * objp)25860Sstevel@tonic-gate i_psvc_probe_11_7(EHdl_t *hdlp, EObj_t *objp)
25870Sstevel@tonic-gate {
25880Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
25890Sstevel@tonic-gate 	char path[1024];
25900Sstevel@tonic-gate 	i2c_port_t port;
25910Sstevel@tonic-gate 	int32_t fp;
25920Sstevel@tonic-gate 
25930Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
25940Sstevel@tonic-gate 		errno = ENODEV;
25950Sstevel@tonic-gate 		return (PSVC_FAILURE);
25960Sstevel@tonic-gate 	}
25970Sstevel@tonic-gate 
25980Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
25990Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
26000Sstevel@tonic-gate 		return (status);
26010Sstevel@tonic-gate 
26020Sstevel@tonic-gate 	port.direction = DIR_NO_CHANGE;
26030Sstevel@tonic-gate 
26040Sstevel@tonic-gate 	fp = open(path, O_RDWR);
26050Sstevel@tonic-gate 	if (fp == -1)
26060Sstevel@tonic-gate 		return (PSVC_FAILURE);
26070Sstevel@tonic-gate 
26080Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_GET_PORT, (void *)&port);
26090Sstevel@tonic-gate 	if (ret == -1) {
26100Sstevel@tonic-gate 		close(fp);
26110Sstevel@tonic-gate 		errno = EIO;
26120Sstevel@tonic-gate 		return (-1);
26130Sstevel@tonic-gate 	}
26140Sstevel@tonic-gate 
26150Sstevel@tonic-gate 	close(fp);
26160Sstevel@tonic-gate 
26170Sstevel@tonic-gate 	return (status);
26180Sstevel@tonic-gate }
26190Sstevel@tonic-gate 
26200Sstevel@tonic-gate /* TDA8444 */
26210Sstevel@tonic-gate static int32_t
i_psvc_probe_11_8(EHdl_t * hdlp,EObj_t * objp)26220Sstevel@tonic-gate i_psvc_probe_11_8(EHdl_t *hdlp, EObj_t *objp)
26230Sstevel@tonic-gate {
26240Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
26250Sstevel@tonic-gate 	uint8_t value;
26260Sstevel@tonic-gate 	char path[1024];
26270Sstevel@tonic-gate 	int32_t fp;
26280Sstevel@tonic-gate 
26290Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
26300Sstevel@tonic-gate 		errno = ENODEV;
26310Sstevel@tonic-gate 		return (PSVC_FAILURE);
26320Sstevel@tonic-gate 	}
26330Sstevel@tonic-gate 
26340Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
26350Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
26360Sstevel@tonic-gate 		return (status);
26370Sstevel@tonic-gate 
26380Sstevel@tonic-gate 	fp = open(path, O_RDWR);
26390Sstevel@tonic-gate 	if (fp == -1)
26400Sstevel@tonic-gate 		return (PSVC_FAILURE);
26410Sstevel@tonic-gate 
26420Sstevel@tonic-gate 	ret = read(fp, &value, 1);
26430Sstevel@tonic-gate 	if (ret == -1) {
26440Sstevel@tonic-gate 		close(fp);
26450Sstevel@tonic-gate 		errno = EIO;
26460Sstevel@tonic-gate 		return (-1);
26470Sstevel@tonic-gate 	}
26480Sstevel@tonic-gate 
26490Sstevel@tonic-gate 	close(fp);
26500Sstevel@tonic-gate 
26510Sstevel@tonic-gate 	return (status);
26520Sstevel@tonic-gate }
26530Sstevel@tonic-gate 
26540Sstevel@tonic-gate 
26550Sstevel@tonic-gate /* SSC100 */
26560Sstevel@tonic-gate static int32_t
i_psvc_probe_11_9(EHdl_t * hdlp,EObj_t * objp)26570Sstevel@tonic-gate i_psvc_probe_11_9(EHdl_t *hdlp, EObj_t *objp)
26580Sstevel@tonic-gate {
26590Sstevel@tonic-gate 	int32_t ret, status = PSVC_SUCCESS;
26600Sstevel@tonic-gate 	char path[1024];
26610Sstevel@tonic-gate 	i2c_reg_t reg;
26620Sstevel@tonic-gate 	int32_t fp;
26630Sstevel@tonic-gate 
26640Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
26650Sstevel@tonic-gate 		errno = ENODEV;
26660Sstevel@tonic-gate 		return (PSVC_FAILURE);
26670Sstevel@tonic-gate 	}
26680Sstevel@tonic-gate 
26690Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
26700Sstevel@tonic-gate 	if (status != PSVC_SUCCESS) {
26710Sstevel@tonic-gate 		return (status);
26720Sstevel@tonic-gate 	}
26730Sstevel@tonic-gate 
26740Sstevel@tonic-gate 	fp = open(path, O_RDWR);
26750Sstevel@tonic-gate 	if (fp == -1) {
26760Sstevel@tonic-gate 		return (PSVC_FAILURE);
26770Sstevel@tonic-gate 	}
26780Sstevel@tonic-gate 
26790Sstevel@tonic-gate 	/*
26800Sstevel@tonic-gate 	 * There are only a few register numbers that are valid numbers to
26810Sstevel@tonic-gate 	 * read from. 0x10 is one of these registers. Any non-valid registers
26820Sstevel@tonic-gate 	 * cause unknown behavior to the ssc100 device.
26830Sstevel@tonic-gate 	 */
26840Sstevel@tonic-gate 	reg.reg_num = 0x10;
26850Sstevel@tonic-gate 	ret = ioctl_retry(fp, I2C_GET_REG, (void *)&reg);
26860Sstevel@tonic-gate 	if (ret == -1) {
26870Sstevel@tonic-gate 		close(fp);
26880Sstevel@tonic-gate 		errno = EIO;
26890Sstevel@tonic-gate 		return (-1);
26900Sstevel@tonic-gate 	}
26910Sstevel@tonic-gate 
26920Sstevel@tonic-gate 	close(fp);
26930Sstevel@tonic-gate 
26940Sstevel@tonic-gate 	return (status);
26950Sstevel@tonic-gate }
26960Sstevel@tonic-gate 
26970Sstevel@tonic-gate 
26980Sstevel@tonic-gate /*
26990Sstevel@tonic-gate  * Find start of a section within the config file,
27000Sstevel@tonic-gate  * Returns number of records in the section.
27010Sstevel@tonic-gate  * FILE *fd is set to first data record within section.
27020Sstevel@tonic-gate  */
27030Sstevel@tonic-gate static int32_t
i_psvc_find_file_section(FILE * fd,char * start)27040Sstevel@tonic-gate i_psvc_find_file_section(FILE *fd, char *start)
27050Sstevel@tonic-gate {
27060Sstevel@tonic-gate 	char *ret;
27070Sstevel@tonic-gate 	char buf[BUFSZ];
27080Sstevel@tonic-gate 	char name[32];
27090Sstevel@tonic-gate 	int found;
27100Sstevel@tonic-gate 
27110Sstevel@tonic-gate 	fseek(fd, 0, SEEK_SET);
27120Sstevel@tonic-gate 	while ((ret = fgets(buf, BUFSZ, fd)) != NULL) {
27130Sstevel@tonic-gate 		if (strncmp(start, buf, strlen(start)) == 0)
27140Sstevel@tonic-gate 			break;
27150Sstevel@tonic-gate 	}
27160Sstevel@tonic-gate 
27170Sstevel@tonic-gate 	if (ret == NULL) {
27180Sstevel@tonic-gate 		errno = EINVAL;
27190Sstevel@tonic-gate 		return (-1);
27200Sstevel@tonic-gate 	}
27210Sstevel@tonic-gate 
27220Sstevel@tonic-gate 	found = sscanf(buf, "%s", name);
27230Sstevel@tonic-gate 	if (found != 1) {
27240Sstevel@tonic-gate 		errno = EINVAL;
27250Sstevel@tonic-gate 		return (-1);
27260Sstevel@tonic-gate 	} else {
27270Sstevel@tonic-gate 		return (0);
27280Sstevel@tonic-gate 	}
27290Sstevel@tonic-gate 
27300Sstevel@tonic-gate }
27310Sstevel@tonic-gate 
27320Sstevel@tonic-gate /* compare routine for qsort of str_tbl */
27330Sstevel@tonic-gate static int32_t
i_psvc_name_compare_qsort(EStringId_t * s1,EStringId_t * s2)27340Sstevel@tonic-gate i_psvc_name_compare_qsort(EStringId_t *s1, EStringId_t *s2)
27350Sstevel@tonic-gate {
27360Sstevel@tonic-gate 	return (strcmp(s1->name, s2->name));
27370Sstevel@tonic-gate }
27380Sstevel@tonic-gate 
27390Sstevel@tonic-gate /* compare routine for bsearch of str_tbl */
27400Sstevel@tonic-gate static int32_t
i_psvc_name_compare_bsearch(char * s1,EStringId_t * s2)27410Sstevel@tonic-gate i_psvc_name_compare_bsearch(char *s1, EStringId_t *s2)
27420Sstevel@tonic-gate {
27430Sstevel@tonic-gate 	return (strcmp(s1, s2->name));
27440Sstevel@tonic-gate }
27450Sstevel@tonic-gate 
27460Sstevel@tonic-gate /*
27470Sstevel@tonic-gate  * Determine the initial state of a device.
27480Sstevel@tonic-gate  */
27490Sstevel@tonic-gate static int32_t
i_psvc_init_state(EHdl_t * hp,EObj_t * objp)27500Sstevel@tonic-gate i_psvc_init_state(EHdl_t *hp, EObj_t *objp)
27510Sstevel@tonic-gate {
27520Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
27530Sstevel@tonic-gate 
27540Sstevel@tonic-gate 	if (objp->class == PSVC_ON_OFF_SWITCH_CLASS) {
27550Sstevel@tonic-gate 		char state[32];
27560Sstevel@tonic-gate 
27570Sstevel@tonic-gate 		status = objp->get_attr(hp, objp, PSVC_SWITCH_STATE_ATTR,
27580Sstevel@tonic-gate 			state);
27590Sstevel@tonic-gate 		if (status != PSVC_SUCCESS)
27600Sstevel@tonic-gate 			return (status);
27610Sstevel@tonic-gate 
27620Sstevel@tonic-gate 		if (strcmp(state, PSVC_SWITCH_ON) == 0)
27630Sstevel@tonic-gate 			strcpy(objp->state, PSVC_ON);
27640Sstevel@tonic-gate 		else
27650Sstevel@tonic-gate 			strcpy(objp->state, PSVC_OFF);
27660Sstevel@tonic-gate 	}
27670Sstevel@tonic-gate 
27680Sstevel@tonic-gate 	if (objp->class == PSVC_KEYSWITCH_CLASS) {
27690Sstevel@tonic-gate 		char state[32];
27700Sstevel@tonic-gate 
27710Sstevel@tonic-gate 		status = objp->get_attr(hp, objp, PSVC_SWITCH_STATE_ATTR,
27720Sstevel@tonic-gate 			state);
27730Sstevel@tonic-gate 		if (status != PSVC_SUCCESS)
27740Sstevel@tonic-gate 			return (status);
27750Sstevel@tonic-gate 		strcpy(objp->state, state);
27760Sstevel@tonic-gate 	}
27770Sstevel@tonic-gate 
27780Sstevel@tonic-gate 	return (status);
27790Sstevel@tonic-gate }
27800Sstevel@tonic-gate 
27810Sstevel@tonic-gate /*
27820Sstevel@tonic-gate  * Return the object pointer for the object name passed in.
27830Sstevel@tonic-gate  * Creates the object if this is the first access,
27840Sstevel@tonic-gate  * Returns 0 if successful, -1 if not.
27850Sstevel@tonic-gate  */
27860Sstevel@tonic-gate static int32_t
i_psvc_get_obj(EHdl_t * hp,char * dev_name,EObj_t ** objp)27870Sstevel@tonic-gate i_psvc_get_obj(EHdl_t *hp, char *dev_name, EObj_t **objp)
27880Sstevel@tonic-gate {
27890Sstevel@tonic-gate 	int32_t i, ret;
27900Sstevel@tonic-gate 	int32_t found, key, array;
27910Sstevel@tonic-gate 	int32_t class, subclass;
27920Sstevel@tonic-gate 	boolean_t presence;
27930Sstevel@tonic-gate 	char name[NAMELEN];
27940Sstevel@tonic-gate 	char buf[BUFSZ];
27950Sstevel@tonic-gate 	char *start;
27960Sstevel@tonic-gate 	ETable_Array *tbl_arr;
27970Sstevel@tonic-gate 
27980Sstevel@tonic-gate 	key = psvc_get_str_key(dev_name);
27990Sstevel@tonic-gate 	array = key % PSVC_MAX_TABLE_ARRAYS;
28000Sstevel@tonic-gate 	tbl_arr = &(hp->tbl_arry[array]);
28010Sstevel@tonic-gate 
28020Sstevel@tonic-gate 	for (i = 0; i < tbl_arr->obj_count; ++i) {
28030Sstevel@tonic-gate 		if (key ==  tbl_arr->obj_tbl[i].key) {
28040Sstevel@tonic-gate 			if (strcmp(dev_name, tbl_arr->obj_tbl[i].name) == 0) {
28050Sstevel@tonic-gate 				if (tbl_arr->obj_tbl[i].type != PSVC_OBJ)
28060Sstevel@tonic-gate 					return (-1);
28070Sstevel@tonic-gate 				*objp = tbl_arr->obj_tbl[i].objp;
28080Sstevel@tonic-gate 				return (0);
28090Sstevel@tonic-gate 			}
28100Sstevel@tonic-gate 		}
28110Sstevel@tonic-gate 	}
28120Sstevel@tonic-gate 
28130Sstevel@tonic-gate 	if (i_psvc_find_file_section(hp->fp, "OBJECT_INFO") == -1) {
28140Sstevel@tonic-gate 		ENV_DEBUG("Couldn't find OBJECT_INFO section", dev_name);
28150Sstevel@tonic-gate 		return (-1);
28160Sstevel@tonic-gate 	}
28170Sstevel@tonic-gate 
28180Sstevel@tonic-gate 	fgets(buf, BUFSZ, hp->fp);
28190Sstevel@tonic-gate 	while (strcmp(buf, "OBJECT_INFO_END")) {
28200Sstevel@tonic-gate 		start = strrchr(buf, '/');
28210Sstevel@tonic-gate 		if (start == NULL) {
28220Sstevel@tonic-gate 			errno = EINVAL;
28230Sstevel@tonic-gate 			return (PSVC_FAILURE);
28240Sstevel@tonic-gate 		}
28250Sstevel@tonic-gate 		found = sscanf(start + 1, "%s",  name);
28260Sstevel@tonic-gate 		if (found != 1) {
28270Sstevel@tonic-gate 			errno = EINVAL;
28280Sstevel@tonic-gate 			return (PSVC_FAILURE);
28290Sstevel@tonic-gate 		}
28300Sstevel@tonic-gate 
28310Sstevel@tonic-gate 		if (strcmp(name, dev_name) == 0) {
28320Sstevel@tonic-gate 
28330Sstevel@tonic-gate 			if (i_psvc_value(buf, PSVC_CLASS_ATTR, &class)
28340Sstevel@tonic-gate 			    != PSVC_SUCCESS)
28350Sstevel@tonic-gate 				return (PSVC_FAILURE);
28360Sstevel@tonic-gate 			if (i_psvc_value(buf, PSVC_SUBCLASS_ATTR, &subclass)
28370Sstevel@tonic-gate 			    != PSVC_SUCCESS)
28380Sstevel@tonic-gate 				return (PSVC_FAILURE);
28390Sstevel@tonic-gate 			ret = (*i_psvc_constructor[class][subclass])(hp,
28400Sstevel@tonic-gate 				dev_name, objp);
28410Sstevel@tonic-gate 			if (ret != PSVC_SUCCESS) {
28420Sstevel@tonic-gate 				return (-1);
28430Sstevel@tonic-gate 			}
28440Sstevel@tonic-gate 			ret = (*objp)->get_attr(hp, *objp, PSVC_PRESENCE_ATTR,
28450Sstevel@tonic-gate 				&presence);
28460Sstevel@tonic-gate 			(*objp)->previous_presence = presence;
28470Sstevel@tonic-gate 			if (ret != PSVC_SUCCESS || presence != PSVC_PRESENT)
28480Sstevel@tonic-gate 				return (ret);
28490Sstevel@tonic-gate 
28500Sstevel@tonic-gate 			return (i_psvc_init_state(hp, *objp));
28510Sstevel@tonic-gate 		}
28520Sstevel@tonic-gate 		fgets(buf, BUFSZ, hp->fp);
28530Sstevel@tonic-gate 	}
28540Sstevel@tonic-gate 
28550Sstevel@tonic-gate 	errno = EINVAL;
28560Sstevel@tonic-gate 	return (-1);
28570Sstevel@tonic-gate }
28580Sstevel@tonic-gate 
28590Sstevel@tonic-gate /*
28600Sstevel@tonic-gate  * Gets the device path associated with an object id.
28610Sstevel@tonic-gate  * Returns 0 if successful, -1 if not.
28620Sstevel@tonic-gate  */
28630Sstevel@tonic-gate static int32_t
i_psvc_get_devpath(EHdl_t * hp,uint64_t addr_spec,char * path)28640Sstevel@tonic-gate i_psvc_get_devpath(EHdl_t *hp, uint64_t addr_spec, char *path)
28650Sstevel@tonic-gate {
28660Sstevel@tonic-gate 	int i;
28670Sstevel@tonic-gate 	EDevice_t *dp;
28680Sstevel@tonic-gate 	uint32_t controller, bus, addr, port;
28690Sstevel@tonic-gate 
28700Sstevel@tonic-gate 	controller = PSVC_GET_ASPEC_CNTLR(addr_spec);
28710Sstevel@tonic-gate 	bus = PSVC_GET_ASPEC_BUSNUM(addr_spec);
28720Sstevel@tonic-gate 	addr = PSVC_GET_ASPEC_BUSADDR(addr_spec);
28730Sstevel@tonic-gate 	port = PSVC_GET_ASPEC_PORT(addr_spec);
28740Sstevel@tonic-gate 
28750Sstevel@tonic-gate 	for (i = 0; i < hp->dev_count; ++i) {
28760Sstevel@tonic-gate 		dp = &hp->dev_tbl[i];
28770Sstevel@tonic-gate 		if (dp->controller == controller &&
28780Sstevel@tonic-gate 		    dp->bus == bus &&
28790Sstevel@tonic-gate 		    dp->addr == addr &&
28800Sstevel@tonic-gate 		    dp->port == port) {
28810Sstevel@tonic-gate 			strcpy(path, dp->path);
28820Sstevel@tonic-gate 			return (PSVC_SUCCESS);
28830Sstevel@tonic-gate 		}
28840Sstevel@tonic-gate 	}
28850Sstevel@tonic-gate 
28860Sstevel@tonic-gate 	errno = EINVAL;
28870Sstevel@tonic-gate 	return (PSVC_FAILURE);
28880Sstevel@tonic-gate }
28890Sstevel@tonic-gate 
28900Sstevel@tonic-gate 
28910Sstevel@tonic-gate /* Load the association table */
28920Sstevel@tonic-gate static int32_t
i_psvc_load_associations(EHdl_t * hp,FILE * fp)28930Sstevel@tonic-gate i_psvc_load_associations(EHdl_t *hp, FILE *fp)
28940Sstevel@tonic-gate {
28950Sstevel@tonic-gate 	uint32_t count;
28960Sstevel@tonic-gate 	int found;
28970Sstevel@tonic-gate 	int i, j;
28980Sstevel@tonic-gate 	char name1[32], name2[32];
28990Sstevel@tonic-gate 	char buf[BUFSZ];
29000Sstevel@tonic-gate 	EStringId_t *namep;
29010Sstevel@tonic-gate 	EAssoc_t *ap;
29020Sstevel@tonic-gate 	int32_t id;
29030Sstevel@tonic-gate 	int32_t status;
29040Sstevel@tonic-gate 
29050Sstevel@tonic-gate 	/*
29060Sstevel@tonic-gate 	 * ignore count in the file, correct count is highest
29070Sstevel@tonic-gate 	 * association id + 1, now figured when loading ASSOC_STR
29080Sstevel@tonic-gate 	 * section.
29090Sstevel@tonic-gate 	 */
29100Sstevel@tonic-gate 	if (i_psvc_find_file_section(fp, "ASSOCIATIONS") != PSVC_SUCCESS)
29110Sstevel@tonic-gate 		return (-1);
29120Sstevel@tonic-gate 	if ((hp->assoc_tbl = malloc(sizeof (EAssocList_t) * hp->assoc_count))
29130Sstevel@tonic-gate 			== NULL) {
29140Sstevel@tonic-gate 		return (-1);
29150Sstevel@tonic-gate 	}
29160Sstevel@tonic-gate 	memset(hp->assoc_tbl, 0, sizeof (EAssocList_t) * hp->assoc_count);
29170Sstevel@tonic-gate 
29180Sstevel@tonic-gate 	for (i = 0; i < hp->assoc_count; ++i) {
29190Sstevel@tonic-gate 		fgets(buf, BUFSZ, fp);
29200Sstevel@tonic-gate 		found = sscanf(buf, "%s %s", name1, name2);
29210Sstevel@tonic-gate 		if (strcmp("ASSOCIATIONS_END", name1) == 0)
29220Sstevel@tonic-gate 			break;
29230Sstevel@tonic-gate 		if (found != 2) {
29240Sstevel@tonic-gate 			errno = EINVAL;
29250Sstevel@tonic-gate 			return (-1);
29260Sstevel@tonic-gate 		}
29270Sstevel@tonic-gate 		namep = (EStringId_t *)bsearch(name2, hp->othr_tbl,
29280Sstevel@tonic-gate 			hp->othr_count, sizeof (EStringId_t),
29290Sstevel@tonic-gate 			(int (*)(const void *, const void *))
29300Sstevel@tonic-gate 			i_psvc_name_compare_bsearch);
29310Sstevel@tonic-gate 		if (namep == NULL) {
29320Sstevel@tonic-gate 			errno = EINVAL;
29330Sstevel@tonic-gate 			return (-1);
29340Sstevel@tonic-gate 		}
29350Sstevel@tonic-gate 		id = namep->id;
29360Sstevel@tonic-gate 
29370Sstevel@tonic-gate 		status = i_psvc_count_records(fp, "ASSOCIATION_END", &count);
29380Sstevel@tonic-gate 		if (status != PSVC_SUCCESS)
29390Sstevel@tonic-gate 			return (status);
29400Sstevel@tonic-gate 		hp->assoc_tbl[id].count = count;
29410Sstevel@tonic-gate 		hp->assoc_tbl[id].table =
29420Sstevel@tonic-gate 			(EAssoc_t *)malloc(sizeof (EAssoc_t) * count);
29430Sstevel@tonic-gate 		if (hp->assoc_tbl[id].table == NULL)
29440Sstevel@tonic-gate 			return (-1);
29450Sstevel@tonic-gate 
29460Sstevel@tonic-gate 		for (j = 0; j < count; ++j) {
29470Sstevel@tonic-gate 			ap = &hp->assoc_tbl[id].table[j];
29480Sstevel@tonic-gate 			fgets(buf, BUFSZ, fp);
29490Sstevel@tonic-gate 			found = sscanf(buf, "%s %s", ap->antecedent_id,
29500Sstevel@tonic-gate 				ap->dependent_id);
29510Sstevel@tonic-gate 			ap->ant_key = psvc_get_str_key(ap->antecedent_id);
29520Sstevel@tonic-gate 			if (found != 2) {
29530Sstevel@tonic-gate 				errno = EINVAL;
29540Sstevel@tonic-gate 				return (-1);
29550Sstevel@tonic-gate 			}
29560Sstevel@tonic-gate 		}
29570Sstevel@tonic-gate 
29580Sstevel@tonic-gate 
29590Sstevel@tonic-gate 		fgets(buf, BUFSZ, fp);
29600Sstevel@tonic-gate 		if (strncmp(buf, "ASSOCIATION_END", 15) != 0) {
29610Sstevel@tonic-gate 			errno = EINVAL;
29620Sstevel@tonic-gate 			return (-1);
29630Sstevel@tonic-gate 		}
29640Sstevel@tonic-gate 	}
29650Sstevel@tonic-gate 
29660Sstevel@tonic-gate 	return (0);
29670Sstevel@tonic-gate }
29680Sstevel@tonic-gate 
29690Sstevel@tonic-gate /* Load the table of tables */
29700Sstevel@tonic-gate static int32_t
i_psvc_load_tables(EHdl_t * hp,FILE * fp)29710Sstevel@tonic-gate i_psvc_load_tables(EHdl_t *hp, FILE *fp)
29720Sstevel@tonic-gate {
29730Sstevel@tonic-gate 	int i, j;
29740Sstevel@tonic-gate 	int found;
29750Sstevel@tonic-gate 	int ret;
29760Sstevel@tonic-gate 	int32_t cell_type;
29770Sstevel@tonic-gate 	int64_t *table;
29780Sstevel@tonic-gate 	char buf[BUFSZ];
29790Sstevel@tonic-gate 	int32_t status;
29800Sstevel@tonic-gate 	uint32_t table_count;
29810Sstevel@tonic-gate 	int32_t num, key, array;
29820Sstevel@tonic-gate 	char name[NAMELEN];
29830Sstevel@tonic-gate 	ETable_Array *tbl_arr;
29840Sstevel@tonic-gate 
29850Sstevel@tonic-gate 	if (i_psvc_find_file_section(fp, "TABLES") != PSVC_SUCCESS)
29860Sstevel@tonic-gate 		return (PSVC_SUCCESS);	/* no tables */
29870Sstevel@tonic-gate 	status = i_psvc_count_tables_associations(fp, &table_count,
29880Sstevel@tonic-gate 			"TABLE_END");
29890Sstevel@tonic-gate 	if (status != PSVC_SUCCESS || table_count == 0)
29900Sstevel@tonic-gate 		return (status);
29910Sstevel@tonic-gate 
29920Sstevel@tonic-gate 	for (i = 0; i < table_count; ++i) {
29930Sstevel@tonic-gate 		int slot;
29940Sstevel@tonic-gate 		ETable_t *tblp;
29950Sstevel@tonic-gate 
29960Sstevel@tonic-gate 		fgets(buf, BUFSZ, fp);
29970Sstevel@tonic-gate 		if (strncmp(buf, "TABLE", 5) != 0) {
29980Sstevel@tonic-gate 			errno = EINVAL;
29990Sstevel@tonic-gate 			return (-1);
30000Sstevel@tonic-gate 		}
30010Sstevel@tonic-gate 
30020Sstevel@tonic-gate 		fgets(buf, BUFSZ, fp);
30030Sstevel@tonic-gate 		found = sscanf(buf, "%s %d", name, &cell_type);
30040Sstevel@tonic-gate 		key = psvc_get_str_key(name);
30050Sstevel@tonic-gate 		array = key % PSVC_MAX_TABLE_ARRAYS;
30060Sstevel@tonic-gate 		tbl_arr = &(hp->tbl_arry[array]);
30070Sstevel@tonic-gate 
30080Sstevel@tonic-gate 		if (tbl_arr->nextid == hp->total_obj_count) {
30090Sstevel@tonic-gate 			errno = EINVAL;
30100Sstevel@tonic-gate 			return (PSVC_FAILURE);
30110Sstevel@tonic-gate 		} else {
30120Sstevel@tonic-gate 			slot = tbl_arr->nextid++;
30130Sstevel@tonic-gate 			tbl_arr->obj_count++;
30140Sstevel@tonic-gate 		}
30150Sstevel@tonic-gate 
30160Sstevel@tonic-gate 		strcpy(tbl_arr->obj_tbl[slot].name, name);
30170Sstevel@tonic-gate 
30180Sstevel@tonic-gate 		tblp = (ETable_t *)malloc(sizeof (ETable_t));
30190Sstevel@tonic-gate 		if (tblp == NULL)
30200Sstevel@tonic-gate 			return (PSVC_FAILURE);
30210Sstevel@tonic-gate 		tbl_arr->obj_tbl[slot].key = key;
30220Sstevel@tonic-gate 		tbl_arr->obj_tbl[slot].objp = (EObj_t *)(void *)tblp;
30230Sstevel@tonic-gate 		tbl_arr->obj_tbl[slot].type = PSVC_TBL;
30240Sstevel@tonic-gate 
30250Sstevel@tonic-gate 		status = i_psvc_count_table_records(fp, "TABLE_END",
30260Sstevel@tonic-gate 			&tblp->size);
30270Sstevel@tonic-gate 		if (status != PSVC_SUCCESS)
30280Sstevel@tonic-gate 			return (status);
30290Sstevel@tonic-gate 		tblp->cell_type = (uint8_t)cell_type;
30300Sstevel@tonic-gate 		if (found != 2) {
30310Sstevel@tonic-gate 			errno = EINVAL;
30320Sstevel@tonic-gate 			return (-1);
30330Sstevel@tonic-gate 		}
30340Sstevel@tonic-gate 
30350Sstevel@tonic-gate 		/* allocate and load table */
30360Sstevel@tonic-gate 		tblp->table = (int64_t *)malloc(tblp->size *
30370Sstevel@tonic-gate 			i_psvc_cell_size[tblp->cell_type]);
30380Sstevel@tonic-gate 		if (tblp->table == NULL) {
30390Sstevel@tonic-gate 			return (-1);
30400Sstevel@tonic-gate 		}
30410Sstevel@tonic-gate 
30420Sstevel@tonic-gate 		table = tblp->table;
30430Sstevel@tonic-gate 		for (j = 0; j < tblp->size; ++j) {
30440Sstevel@tonic-gate 			switch (cell_type) {
30450Sstevel@tonic-gate 				case 0:
30460Sstevel@tonic-gate 					ret = fscanf(fp, "%d", &num);
30470Sstevel@tonic-gate 					*((int8_t *)table + j) = num;
30480Sstevel@tonic-gate 					break;
30490Sstevel@tonic-gate 				case 1:
30500Sstevel@tonic-gate 					ret = fscanf(fp, "%d", &num);
30510Sstevel@tonic-gate 					*((uint8_t *)table + j) = (uint8_t)num;
30520Sstevel@tonic-gate 					break;
30530Sstevel@tonic-gate 				case 2:
30540Sstevel@tonic-gate 					ret = fscanf(fp, "%hd",
30550Sstevel@tonic-gate 						((int16_t *)table + j));
30560Sstevel@tonic-gate 					break;
30570Sstevel@tonic-gate 				case 3:
30580Sstevel@tonic-gate 					ret = fscanf(fp, "%hd",
30590Sstevel@tonic-gate 						((uint16_t *)table + j));
30600Sstevel@tonic-gate 					break;
30610Sstevel@tonic-gate 				case 4:
30620Sstevel@tonic-gate 					ret = fscanf(fp, "%d",
30630Sstevel@tonic-gate 						((int32_t *)table + j));
30640Sstevel@tonic-gate 					break;
30650Sstevel@tonic-gate 				case 5:
30660Sstevel@tonic-gate 					ret = fscanf(fp, "%d",
30670Sstevel@tonic-gate 						((uint32_t *)table + j));
30680Sstevel@tonic-gate 					break;
30690Sstevel@tonic-gate 				case 6:
30700Sstevel@tonic-gate 					ret = fscanf(fp, "%lld",
30710Sstevel@tonic-gate 						((int64_t *)table + j));
30720Sstevel@tonic-gate 					break;
30730Sstevel@tonic-gate 				case 7:
30740Sstevel@tonic-gate 					ret = fscanf(fp, "%lld",
30750Sstevel@tonic-gate 						((uint64_t *)table + j));
30760Sstevel@tonic-gate 					break;
30770Sstevel@tonic-gate 				default:
30780Sstevel@tonic-gate 					errno = EINVAL;
30790Sstevel@tonic-gate 					return (-1);
30800Sstevel@tonic-gate 			}
30810Sstevel@tonic-gate 			if (ret != 1) {
30820Sstevel@tonic-gate 				errno = EINVAL;
30830Sstevel@tonic-gate 				return (-1);
30840Sstevel@tonic-gate 			}
30850Sstevel@tonic-gate 		}
30860Sstevel@tonic-gate 		fgets(buf, BUFSZ, fp);  /* reads newline on data line */
30870Sstevel@tonic-gate 		fgets(buf, BUFSZ, fp);
30880Sstevel@tonic-gate 		if (strncmp(buf, "TABLE_END", 9) != 0) {
30890Sstevel@tonic-gate 			errno = EINVAL;
30900Sstevel@tonic-gate 			return (-1);
30910Sstevel@tonic-gate 		}
30920Sstevel@tonic-gate 
30930Sstevel@tonic-gate 	}
30940Sstevel@tonic-gate 
30950Sstevel@tonic-gate 	return (0);
30960Sstevel@tonic-gate }
30970Sstevel@tonic-gate 
30980Sstevel@tonic-gate static int32_t
i_psvc_destructor(EHdl_t * hdlp,char * name,void * objp)30990Sstevel@tonic-gate i_psvc_destructor(EHdl_t *hdlp, char *name, void *objp)
31000Sstevel@tonic-gate {
31010Sstevel@tonic-gate 	int32_t i, key, array;
31020Sstevel@tonic-gate 
31030Sstevel@tonic-gate 	key = psvc_get_str_key(name);
31040Sstevel@tonic-gate 	array = key % PSVC_MAX_TABLE_ARRAYS;
31050Sstevel@tonic-gate 
31060Sstevel@tonic-gate 	for (i = 0; i < hdlp->tbl_arry[array].obj_count; ++i) {
31070Sstevel@tonic-gate 		if (key == hdlp->tbl_arry[array].obj_tbl[i].key) {
31080Sstevel@tonic-gate 			if (strcmp(hdlp->tbl_arry[array].obj_tbl[i].name,
31090Sstevel@tonic-gate 				name) == 0) {
31100Sstevel@tonic-gate 				hdlp->tbl_arry[array].obj_tbl[i].name[0] = '\0';
31110Sstevel@tonic-gate 				if (objp != NULL)
31120Sstevel@tonic-gate 					free(objp);
31130Sstevel@tonic-gate 				return (PSVC_SUCCESS);
31140Sstevel@tonic-gate 			}
31150Sstevel@tonic-gate 		}
31160Sstevel@tonic-gate 	}
31170Sstevel@tonic-gate 
31180Sstevel@tonic-gate 	return (PSVC_SUCCESS);
31190Sstevel@tonic-gate }
31200Sstevel@tonic-gate 
31210Sstevel@tonic-gate static int32_t
i_psvc_get_attr_generic(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)31220Sstevel@tonic-gate i_psvc_get_attr_generic(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id,
31230Sstevel@tonic-gate     void * attrp)
31240Sstevel@tonic-gate {
31250Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
31260Sstevel@tonic-gate 	char *parent_id;
31270Sstevel@tonic-gate 
31280Sstevel@tonic-gate 	switch (attr_id) {
31290Sstevel@tonic-gate 	case PSVC_ADDR_SPEC_ATTR:
31300Sstevel@tonic-gate 		*(uint64_t *)attrp = objp->addr_spec;
31310Sstevel@tonic-gate 		break;
31320Sstevel@tonic-gate 	case PSVC_CLASS_ATTR:
31330Sstevel@tonic-gate 		*(int32_t *)attrp = objp->class;
31340Sstevel@tonic-gate 		break;
31350Sstevel@tonic-gate 	case PSVC_SUBCLASS_ATTR:
31360Sstevel@tonic-gate 		*(int32_t *)attrp = objp->subclass;
31370Sstevel@tonic-gate 		break;
31380Sstevel@tonic-gate 	case PSVC_PRESENCE_ATTR:
31390Sstevel@tonic-gate 		status = i_psvc_get_presence(hdlp, objp, (boolean_t *)attrp);
31400Sstevel@tonic-gate 		break;
31410Sstevel@tonic-gate 	case PSVC_PREV_PRESENCE_ATTR:
31420Sstevel@tonic-gate 		*(boolean_t *)attrp = objp->previous_presence;
31430Sstevel@tonic-gate 		break;
31440Sstevel@tonic-gate 	case PSVC_STATE_ATTR:
31450Sstevel@tonic-gate 		strcpy((char *)attrp, objp->state);
31460Sstevel@tonic-gate 		break;
31470Sstevel@tonic-gate 	case PSVC_PREV_STATE_ATTR:
31480Sstevel@tonic-gate 		strcpy((char *)attrp, objp->previous_state);
31490Sstevel@tonic-gate 		break;
31500Sstevel@tonic-gate 	case PSVC_ENABLE_ATTR:
31510Sstevel@tonic-gate 		*(boolean_t *)attrp = objp->enabled;
31520Sstevel@tonic-gate 		break;
31530Sstevel@tonic-gate 	case PSVC_FAULTID_ATTR:
31540Sstevel@tonic-gate 		strcpy((char *)attrp, objp->fault_id);
31550Sstevel@tonic-gate 		break;
31560Sstevel@tonic-gate 	case PSVC_FEATURES_ATTR:
31570Sstevel@tonic-gate 		*(uint64_t *)attrp = objp->features;
31580Sstevel@tonic-gate 		break;
31590Sstevel@tonic-gate 	case PSVC_LABEL_ATTR:
31600Sstevel@tonic-gate 		strcpy((char *)attrp, objp->label);
31610Sstevel@tonic-gate 		break;
31620Sstevel@tonic-gate 	case PSVC_FRUID_ATTR:
31630Sstevel@tonic-gate 		while ((objp->features & PSVC_DEV_FRU) == 0) {
31640Sstevel@tonic-gate 			status = i_psvc_get_assoc_id(hdlp, objp->label,
31650Sstevel@tonic-gate 				PSVC_PARENT, 0, &parent_id);
31660Sstevel@tonic-gate 			if (status != PSVC_SUCCESS)
31670Sstevel@tonic-gate 				return (status);
31680Sstevel@tonic-gate 
31690Sstevel@tonic-gate 			status = i_psvc_get_obj(hdlp, parent_id, &objp);
31700Sstevel@tonic-gate 			if (status != PSVC_SUCCESS)
31710Sstevel@tonic-gate 				return (status);
31720Sstevel@tonic-gate 		}
31730Sstevel@tonic-gate 
31740Sstevel@tonic-gate 		strcpy((char *)attrp, objp->label);
31750Sstevel@tonic-gate 		break;
31760Sstevel@tonic-gate 	case PSVC_INSTANCE_ATTR:
31770Sstevel@tonic-gate 		*(int32_t *)attrp = objp->instance;
31780Sstevel@tonic-gate 		break;
31790Sstevel@tonic-gate 	default:
31800Sstevel@tonic-gate 		errno = EINVAL;
31810Sstevel@tonic-gate 		return (PSVC_FAILURE);
31820Sstevel@tonic-gate 	}
31830Sstevel@tonic-gate 
31840Sstevel@tonic-gate 	return (status);
31850Sstevel@tonic-gate }
31860Sstevel@tonic-gate 
31870Sstevel@tonic-gate static int32_t
i_psvc_set_attr_generic(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)31880Sstevel@tonic-gate i_psvc_set_attr_generic(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id,
31890Sstevel@tonic-gate     void * attrp)
31900Sstevel@tonic-gate {
31910Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
31920Sstevel@tonic-gate 
31930Sstevel@tonic-gate 	switch (attr_id) {
31940Sstevel@tonic-gate 	case PSVC_PREV_PRESENCE_ATTR:
31950Sstevel@tonic-gate 		objp->previous_presence = *(boolean_t *)attrp;
31960Sstevel@tonic-gate 		break;
31970Sstevel@tonic-gate 	case PSVC_STATE_ATTR:
31980Sstevel@tonic-gate 		strcpy(objp->previous_state, objp->state);
31990Sstevel@tonic-gate 		strcpy(objp->state, (char *)attrp);
32000Sstevel@tonic-gate 		break;
32010Sstevel@tonic-gate 	case PSVC_ENABLE_ATTR:
32020Sstevel@tonic-gate 		objp->enabled = *(boolean_t *)attrp;
32030Sstevel@tonic-gate 		break;
32040Sstevel@tonic-gate 	case PSVC_FAULTID_ATTR:
32050Sstevel@tonic-gate 		strcpy(objp->fault_id, (char *)attrp);
32060Sstevel@tonic-gate 		break;
32070Sstevel@tonic-gate 	default:
32080Sstevel@tonic-gate 		errno = EINVAL;
32090Sstevel@tonic-gate 		return (PSVC_FAILURE);
32100Sstevel@tonic-gate 	}
32110Sstevel@tonic-gate 	return (status);
32120Sstevel@tonic-gate }
32130Sstevel@tonic-gate 
32140Sstevel@tonic-gate static int32_t
i_psvc_get_attr_0_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)32150Sstevel@tonic-gate i_psvc_get_attr_0_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
32160Sstevel@tonic-gate {
32170Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
32180Sstevel@tonic-gate 
32190Sstevel@tonic-gate 	switch (attr_id) {
32200Sstevel@tonic-gate 	case PSVC_SENSOR_VALUE_ATTR:
32210Sstevel@tonic-gate 		return (i_psvc_get_device_value_0_0(hdlp, objp, attrp));
32220Sstevel@tonic-gate 	case PSVC_LO_WARN_ATTR:
32230Sstevel@tonic-gate 		*(int32_t *)attrp = ((ETempSensor_t *)objp)->lo_warn;
32240Sstevel@tonic-gate 		return (status);
32250Sstevel@tonic-gate 	case PSVC_LO_SHUT_ATTR:
32260Sstevel@tonic-gate 		*(int32_t *)attrp = ((ETempSensor_t *)objp)->lo_shut;
32270Sstevel@tonic-gate 		return (status);
32280Sstevel@tonic-gate 	case PSVC_HI_WARN_ATTR:
32290Sstevel@tonic-gate 		*(int32_t *)attrp = ((ETempSensor_t *)objp)->hi_warn;
32300Sstevel@tonic-gate 		return (status);
32310Sstevel@tonic-gate 	case PSVC_HI_SHUT_ATTR:
32320Sstevel@tonic-gate 		*(int32_t *)attrp = ((ETempSensor_t *)objp)->hi_shut;
32330Sstevel@tonic-gate 		return (status);
32340Sstevel@tonic-gate 	}
32350Sstevel@tonic-gate 
32360Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
32370Sstevel@tonic-gate 
32380Sstevel@tonic-gate 	return (status);
32390Sstevel@tonic-gate }
32400Sstevel@tonic-gate 
32410Sstevel@tonic-gate static int32_t
i_psvc_get_attr_0_1(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)32420Sstevel@tonic-gate i_psvc_get_attr_0_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
32430Sstevel@tonic-gate {
32440Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
32450Sstevel@tonic-gate 
32460Sstevel@tonic-gate 	switch (attr_id) {
32470Sstevel@tonic-gate 	case PSVC_SENSOR_VALUE_ATTR:
32480Sstevel@tonic-gate 		return (i_psvc_get_device_value_0_1(hdlp, objp, attrp));
32490Sstevel@tonic-gate 	case PSVC_LO_WARN_ATTR:
32500Sstevel@tonic-gate 		*(int32_t *)attrp = ((ETempSensor_t *)objp)->lo_warn;
32510Sstevel@tonic-gate 		return (status);
32520Sstevel@tonic-gate 	case PSVC_LO_SHUT_ATTR:
32530Sstevel@tonic-gate 		*(int32_t *)attrp = ((ETempSensor_t *)objp)->lo_shut;
32540Sstevel@tonic-gate 		return (status);
32550Sstevel@tonic-gate 	case PSVC_HI_WARN_ATTR:
32560Sstevel@tonic-gate 		*(int32_t *)attrp = ((ETempSensor_t *)objp)->hi_warn;
32570Sstevel@tonic-gate 		return (status);
32580Sstevel@tonic-gate 	case PSVC_HI_SHUT_ATTR:
32590Sstevel@tonic-gate 		*(int32_t *)attrp = ((ETempSensor_t *)objp)->hi_shut;
32600Sstevel@tonic-gate 		return (status);
32610Sstevel@tonic-gate 	case PSVC_OPTIMAL_TEMP_ATTR:
32620Sstevel@tonic-gate 		*(int32_t *)attrp = ((ETempSensor_t *)objp)->opt_temp;
32630Sstevel@tonic-gate 		return (status);
32640Sstevel@tonic-gate 	case PSVC_HW_HI_SHUT_ATTR:
32650Sstevel@tonic-gate 		*(int32_t *)attrp = ((ETempSensor_t *)objp)->hw_hi_shut;
32660Sstevel@tonic-gate 		return (status);
32670Sstevel@tonic-gate 	case PSVC_HW_LO_SHUT_ATTR:
32680Sstevel@tonic-gate 		*(int32_t *)attrp = ((ETempSensor_t *)objp)->hw_lo_shut;
32690Sstevel@tonic-gate 		return (status);
32700Sstevel@tonic-gate 	}
32710Sstevel@tonic-gate 
32720Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
32730Sstevel@tonic-gate 
32740Sstevel@tonic-gate 	return (status);
32750Sstevel@tonic-gate }
32760Sstevel@tonic-gate 
32770Sstevel@tonic-gate static int32_t
i_psvc_set_attr_0_1(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)32780Sstevel@tonic-gate i_psvc_set_attr_0_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
32790Sstevel@tonic-gate {
32800Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
32810Sstevel@tonic-gate 
32820Sstevel@tonic-gate 	switch (attr_id) {
32830Sstevel@tonic-gate 	case PSVC_LO_WARN_ATTR:
32840Sstevel@tonic-gate 		((ETempSensor_t *)objp)->lo_warn = *(int32_t *)attrp;
32850Sstevel@tonic-gate 		return (status);
32860Sstevel@tonic-gate 	case PSVC_LO_SHUT_ATTR:
32870Sstevel@tonic-gate 		((ETempSensor_t *)objp)->lo_shut = *(int32_t *)attrp;
32880Sstevel@tonic-gate 		return (status);
32890Sstevel@tonic-gate 	case PSVC_HI_WARN_ATTR:
32900Sstevel@tonic-gate 		((ETempSensor_t *)objp)->hi_warn = *(int32_t *)attrp;
32910Sstevel@tonic-gate 		return (status);
32920Sstevel@tonic-gate 	case PSVC_HI_SHUT_ATTR:
32930Sstevel@tonic-gate 		((ETempSensor_t *)objp)->hi_shut = *(int32_t *)attrp;
32940Sstevel@tonic-gate 		return (status);
32950Sstevel@tonic-gate 	case PSVC_OPTIMAL_TEMP_ATTR:
32960Sstevel@tonic-gate 		((ETempSensor_t *)objp)->opt_temp = *(int32_t *)attrp;
32970Sstevel@tonic-gate 		return (status);
32980Sstevel@tonic-gate 	case PSVC_HW_HI_SHUT_ATTR:
32990Sstevel@tonic-gate 		((ETempSensor_t *)objp)->hw_hi_shut = *(int32_t *)attrp;
33000Sstevel@tonic-gate 		return (status);
33010Sstevel@tonic-gate 	case PSVC_HW_LO_SHUT_ATTR:
33020Sstevel@tonic-gate 		((ETempSensor_t *)objp)->hw_lo_shut = *(int32_t *)attrp;
33030Sstevel@tonic-gate 		return (status);
33040Sstevel@tonic-gate 	}
33050Sstevel@tonic-gate 
33060Sstevel@tonic-gate 	status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
33070Sstevel@tonic-gate 
33080Sstevel@tonic-gate 	return (status);
33090Sstevel@tonic-gate }
33100Sstevel@tonic-gate 
33110Sstevel@tonic-gate static int32_t
i_psvc_get_attr_1_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)33120Sstevel@tonic-gate i_psvc_get_attr_1_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
33130Sstevel@tonic-gate {
33140Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
33150Sstevel@tonic-gate 
33160Sstevel@tonic-gate 	switch (attr_id) {
33170Sstevel@tonic-gate 	case PSVC_SENSOR_VALUE_ATTR:
33180Sstevel@tonic-gate 		return (i_psvc_get_device_value_1_0(hdlp, objp, attrp));
33190Sstevel@tonic-gate 	case PSVC_SETPOINT_ATTR:
33200Sstevel@tonic-gate 		*(int16_t *)attrp = ((EFan_t *)objp)->setpoint;
33210Sstevel@tonic-gate 		return (status);
33220Sstevel@tonic-gate 	case PSVC_HYSTERESIS_ATTR:
33230Sstevel@tonic-gate 		*(int16_t *)attrp = ((EFan_t *)objp)->hysteresis;
33240Sstevel@tonic-gate 		return (status);
33250Sstevel@tonic-gate 	case PSVC_LOOPGAIN_ATTR:
33260Sstevel@tonic-gate 		*(int16_t *)attrp = ((EFan_t *)objp)->loopgain;
33270Sstevel@tonic-gate 		return (status);
33280Sstevel@tonic-gate 	case PSVC_LOOPBIAS_ATTR:
33290Sstevel@tonic-gate 		*(int16_t *)attrp = ((EFan_t *)objp)->loopbias;
33300Sstevel@tonic-gate 		return (status);
33310Sstevel@tonic-gate 	case PSVC_TEMP_DIFFERENTIAL_ATTR:
33320Sstevel@tonic-gate 		memcpy(attrp, ((EFan_t *)objp)->temp_differential,
33330Sstevel@tonic-gate 			sizeof (((EFan_t *)objp)->temp_differential));
33340Sstevel@tonic-gate 		return (status);
33350Sstevel@tonic-gate 	case PSVC_TEMP_DIFFERENTIAL_INDEX_ATTR:
33360Sstevel@tonic-gate 		*(int16_t *)attrp = ((EFan_t *)objp)->temp_differential_index;
33370Sstevel@tonic-gate 		return (status);
33380Sstevel@tonic-gate 	}
33390Sstevel@tonic-gate 
33400Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
33410Sstevel@tonic-gate 
33420Sstevel@tonic-gate 	return (status);
33430Sstevel@tonic-gate }
33440Sstevel@tonic-gate 
33450Sstevel@tonic-gate static int32_t
i_psvc_set_attr_1_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)33460Sstevel@tonic-gate i_psvc_set_attr_1_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
33470Sstevel@tonic-gate {
33480Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
33490Sstevel@tonic-gate 
33500Sstevel@tonic-gate 	switch (attr_id) {
33510Sstevel@tonic-gate 	case PSVC_TEMP_DIFFERENTIAL_ATTR:
33520Sstevel@tonic-gate 		memcpy(((EFan_t *)objp)->temp_differential, attrp,
33530Sstevel@tonic-gate 			sizeof (((EFan_t *)objp)->temp_differential));
33540Sstevel@tonic-gate 		return (status);
33550Sstevel@tonic-gate 	case PSVC_TEMP_DIFFERENTIAL_INDEX_ATTR:
33560Sstevel@tonic-gate 		((EFan_t *)objp)->temp_differential_index = *(int16_t *)attrp;
33570Sstevel@tonic-gate 		return (status);
33580Sstevel@tonic-gate 	case PSVC_SETPOINT_ATTR:
33590Sstevel@tonic-gate 		((EFan_t *)objp)->setpoint = *(int16_t *)attrp;
33600Sstevel@tonic-gate 		return (status);
33610Sstevel@tonic-gate 	}
33620Sstevel@tonic-gate 
33630Sstevel@tonic-gate 	status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
33640Sstevel@tonic-gate 
33650Sstevel@tonic-gate 	return (PSVC_SUCCESS);
33660Sstevel@tonic-gate }
33670Sstevel@tonic-gate 
33680Sstevel@tonic-gate static int32_t
i_psvc_get_attr_2_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)33690Sstevel@tonic-gate i_psvc_get_attr_2_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
33700Sstevel@tonic-gate {
33710Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
33720Sstevel@tonic-gate 
33730Sstevel@tonic-gate 	switch (attr_id) {
33740Sstevel@tonic-gate 	case PSVC_LED_STATE_ATTR:
33750Sstevel@tonic-gate 	case PSVC_STATE_ATTR:
33760Sstevel@tonic-gate 		return (i_psvc_get_device_state_2_0(hdlp, objp, attrp));
33770Sstevel@tonic-gate 	case PSVC_LED_COLOR_ATTR:
33780Sstevel@tonic-gate 		strcpy((char *)attrp, ((ELed_t *)objp)->color);
33790Sstevel@tonic-gate 		return (status);
33800Sstevel@tonic-gate 	case PSVC_LIT_COUNT_ATTR:
33810Sstevel@tonic-gate 		*(int16_t *)attrp = ((ELed_t *)objp)->lit_count;
33820Sstevel@tonic-gate 		return (status);
33830Sstevel@tonic-gate 	}
33840Sstevel@tonic-gate 
33850Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
33860Sstevel@tonic-gate 
33870Sstevel@tonic-gate 	return (status);
33880Sstevel@tonic-gate }
33890Sstevel@tonic-gate 
33900Sstevel@tonic-gate static int32_t
i_psvc_set_attr_2_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)33910Sstevel@tonic-gate i_psvc_set_attr_2_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
33920Sstevel@tonic-gate {
33930Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
33940Sstevel@tonic-gate 
33950Sstevel@tonic-gate 	switch (attr_id) {
33960Sstevel@tonic-gate 	case PSVC_LED_STATE_ATTR:
33970Sstevel@tonic-gate 	case PSVC_STATE_ATTR:
33980Sstevel@tonic-gate 		return (i_psvc_set_device_state_2_0(hdlp, objp, attrp));
33990Sstevel@tonic-gate 	}
34000Sstevel@tonic-gate 
34010Sstevel@tonic-gate 	status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
34020Sstevel@tonic-gate 
34030Sstevel@tonic-gate 	return (status);
34040Sstevel@tonic-gate }
34050Sstevel@tonic-gate 
34060Sstevel@tonic-gate static int32_t
i_psvc_get_attr_2_1(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)34070Sstevel@tonic-gate i_psvc_get_attr_2_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
34080Sstevel@tonic-gate {
34090Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
34100Sstevel@tonic-gate 
34110Sstevel@tonic-gate 	switch (attr_id) {
34120Sstevel@tonic-gate 	case PSVC_LED_STATE_ATTR:
34130Sstevel@tonic-gate 	case PSVC_STATE_ATTR:
34140Sstevel@tonic-gate 		return (i_psvc_get_device_state_2_1(hdlp, objp, attrp));
34150Sstevel@tonic-gate 	case PSVC_LED_COLOR_ATTR:
34160Sstevel@tonic-gate 		strcpy((char *)attrp, ((ELed_t *)objp)->color);
34170Sstevel@tonic-gate 		return (status);
34180Sstevel@tonic-gate 	case PSVC_LIT_COUNT_ATTR:
34190Sstevel@tonic-gate 		*(int16_t *)attrp = ((ELed_t *)objp)->lit_count;
34200Sstevel@tonic-gate 		return (status);
34210Sstevel@tonic-gate 	}
34220Sstevel@tonic-gate 
34230Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
34240Sstevel@tonic-gate 
34250Sstevel@tonic-gate 	return (status);
34260Sstevel@tonic-gate }
34270Sstevel@tonic-gate 
34280Sstevel@tonic-gate static int32_t
i_psvc_set_attr_2_1(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)34290Sstevel@tonic-gate i_psvc_set_attr_2_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
34300Sstevel@tonic-gate {
34310Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
34320Sstevel@tonic-gate 
34330Sstevel@tonic-gate 	switch (attr_id) {
34340Sstevel@tonic-gate 	case PSVC_LED_STATE_ATTR:
34350Sstevel@tonic-gate 	case PSVC_STATE_ATTR:
34360Sstevel@tonic-gate 		return (i_psvc_set_device_state_2_1(hdlp, objp, attrp));
34370Sstevel@tonic-gate 	}
34380Sstevel@tonic-gate 
34390Sstevel@tonic-gate 	status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
34400Sstevel@tonic-gate 
34410Sstevel@tonic-gate 	return (status);
34420Sstevel@tonic-gate }
34430Sstevel@tonic-gate 
34440Sstevel@tonic-gate static int32_t
i_psvc_get_attr_2_2(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)34450Sstevel@tonic-gate i_psvc_get_attr_2_2(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
34460Sstevel@tonic-gate {
34470Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
34480Sstevel@tonic-gate 
34490Sstevel@tonic-gate 	switch (attr_id) {
34500Sstevel@tonic-gate 	case PSVC_LED_STATE_ATTR:
34510Sstevel@tonic-gate 	case PSVC_STATE_ATTR:
34520Sstevel@tonic-gate 		return (i_psvc_get_device_state_2_0(hdlp, objp, attrp));
34530Sstevel@tonic-gate 	case PSVC_LED_COLOR_ATTR:
34540Sstevel@tonic-gate 		strcpy((char *)attrp, ((ELed_t *)objp)->color);
34550Sstevel@tonic-gate 		return (status);
34560Sstevel@tonic-gate 	case PSVC_LIT_COUNT_ATTR:
34570Sstevel@tonic-gate 		*(int16_t *)attrp = ((ELed_t *)objp)->lit_count;
34580Sstevel@tonic-gate 		return (status);
34590Sstevel@tonic-gate 	case PSVC_LED_IS_LOCATOR_ATTR:
34600Sstevel@tonic-gate 		strcpy((char *)attrp, ((ELed_t *)objp)->is_locator);
34610Sstevel@tonic-gate 		return (status);
34620Sstevel@tonic-gate 	case PSVC_LED_LOCATOR_NAME_ATTR:
34630Sstevel@tonic-gate 		strcpy((char *)attrp, ((ELed_t *)objp)->locator_name);
34640Sstevel@tonic-gate 		return (status);
34650Sstevel@tonic-gate 	}
34660Sstevel@tonic-gate 
34670Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
34680Sstevel@tonic-gate 
34690Sstevel@tonic-gate 	return (status);
34700Sstevel@tonic-gate }
34710Sstevel@tonic-gate 
34720Sstevel@tonic-gate static int32_t
i_psvc_get_attr_4_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)34730Sstevel@tonic-gate i_psvc_get_attr_4_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
34740Sstevel@tonic-gate {
34750Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
34760Sstevel@tonic-gate 
34770Sstevel@tonic-gate 	switch (attr_id) {
34780Sstevel@tonic-gate 	case PSVC_SENSOR_VALUE_ATTR:
34790Sstevel@tonic-gate 		return (i_psvc_get_device_value_4_0(hdlp, objp, attrp));
34800Sstevel@tonic-gate 	case PSVC_LO_WARN_ATTR:
34810Sstevel@tonic-gate 		*(int32_t *)attrp = ((EDigiSensor_t *)objp)->lo_warn;
34820Sstevel@tonic-gate 		return (status);
34830Sstevel@tonic-gate 	case PSVC_LO_SHUT_ATTR:
34840Sstevel@tonic-gate 		*(int32_t *)attrp = ((EDigiSensor_t *)objp)->lo_shut;
34850Sstevel@tonic-gate 		return (status);
34860Sstevel@tonic-gate 	case PSVC_HI_WARN_ATTR:
34870Sstevel@tonic-gate 		*(int32_t *)attrp = ((EDigiSensor_t *)objp)->hi_warn;
34880Sstevel@tonic-gate 		return (status);
34890Sstevel@tonic-gate 	case PSVC_HI_SHUT_ATTR:
34900Sstevel@tonic-gate 		*(int32_t *)attrp = ((EDigiSensor_t *)objp)->hi_shut;
34910Sstevel@tonic-gate 		return (status);
34920Sstevel@tonic-gate 	}
34930Sstevel@tonic-gate 
34940Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
34950Sstevel@tonic-gate 
34960Sstevel@tonic-gate 	return (PSVC_SUCCESS);
34970Sstevel@tonic-gate }
34980Sstevel@tonic-gate 
34990Sstevel@tonic-gate static int32_t
i_psvc_get_attr_5_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)35000Sstevel@tonic-gate i_psvc_get_attr_5_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
35010Sstevel@tonic-gate {
35020Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
35030Sstevel@tonic-gate 
35040Sstevel@tonic-gate 	if (attr_id == PSVC_CONTROL_VALUE_ATTR) {
35050Sstevel@tonic-gate 		return (i_psvc_get_device_value_5_0(hdlp, objp, attrp));
35060Sstevel@tonic-gate 	}
35070Sstevel@tonic-gate 
35080Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
35090Sstevel@tonic-gate 
35100Sstevel@tonic-gate 	return (status);
35110Sstevel@tonic-gate }
35120Sstevel@tonic-gate 
35130Sstevel@tonic-gate static int32_t
i_psvc_set_attr_5_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)35140Sstevel@tonic-gate i_psvc_set_attr_5_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
35150Sstevel@tonic-gate {
35160Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
35170Sstevel@tonic-gate 
35180Sstevel@tonic-gate 	if (attr_id == PSVC_CONTROL_VALUE_ATTR) {
35190Sstevel@tonic-gate 		return (i_psvc_set_device_value_5_0(hdlp, objp, attrp));
35200Sstevel@tonic-gate 	}
35210Sstevel@tonic-gate 
35220Sstevel@tonic-gate 	status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
35230Sstevel@tonic-gate 
35240Sstevel@tonic-gate 	return (status);
35250Sstevel@tonic-gate }
35260Sstevel@tonic-gate 
35270Sstevel@tonic-gate static int32_t
i_psvc_get_attr_6_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)35280Sstevel@tonic-gate i_psvc_get_attr_6_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
35290Sstevel@tonic-gate {
35300Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
35310Sstevel@tonic-gate 
35320Sstevel@tonic-gate 	switch (attr_id) {
35330Sstevel@tonic-gate 	case PSVC_GPIO_VALUE_ATTR:
35340Sstevel@tonic-gate 		return (i_psvc_get_device_value_6_0(hdlp, objp, attrp));
35350Sstevel@tonic-gate 	case PSVC_GPIO_BITS:
35360Sstevel@tonic-gate 		*(int32_t *)attrp = 1;
35370Sstevel@tonic-gate 		return (status);
35380Sstevel@tonic-gate 	}
35390Sstevel@tonic-gate 
35400Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
35410Sstevel@tonic-gate 
35420Sstevel@tonic-gate 	return (status);
35430Sstevel@tonic-gate }
35440Sstevel@tonic-gate 
35450Sstevel@tonic-gate static int32_t
i_psvc_set_attr_6_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)35460Sstevel@tonic-gate i_psvc_set_attr_6_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
35470Sstevel@tonic-gate {
35480Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
35490Sstevel@tonic-gate 
35500Sstevel@tonic-gate 	if (attr_id == PSVC_GPIO_VALUE_ATTR) {
35510Sstevel@tonic-gate 		return (i_psvc_set_device_value_6_0(hdlp, objp, attrp));
35520Sstevel@tonic-gate 	}
35530Sstevel@tonic-gate 
35540Sstevel@tonic-gate 	status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
35550Sstevel@tonic-gate 
35560Sstevel@tonic-gate 	return (status);
35570Sstevel@tonic-gate }
35580Sstevel@tonic-gate 
35590Sstevel@tonic-gate static int32_t
i_psvc_get_attr_7_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)35600Sstevel@tonic-gate i_psvc_get_attr_7_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
35610Sstevel@tonic-gate {
35620Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
35630Sstevel@tonic-gate 
35640Sstevel@tonic-gate 	switch (attr_id) {
35650Sstevel@tonic-gate 	case PSVC_SENSOR_VALUE_ATTR:
35660Sstevel@tonic-gate 		return (i_psvc_get_device_value_7_0(hdlp, objp, attrp));
35670Sstevel@tonic-gate 	case PSVC_LO_WARN_ATTR:
35680Sstevel@tonic-gate 		*(int32_t *)attrp = ((EFanTach_t *)objp)->lo_warn;
35690Sstevel@tonic-gate 		return (status);
35700Sstevel@tonic-gate 	case PSVC_LO_SHUT_ATTR:
35710Sstevel@tonic-gate 		*(int32_t *)attrp = ((EFanTach_t *)objp)->lo_shut;
35720Sstevel@tonic-gate 		return (status);
35730Sstevel@tonic-gate 	case PSVC_HI_WARN_ATTR:
35740Sstevel@tonic-gate 		*(int32_t *)attrp = ((EFanTach_t *)objp)->hi_warn;
35750Sstevel@tonic-gate 		return (status);
35760Sstevel@tonic-gate 	case PSVC_HI_SHUT_ATTR:
35770Sstevel@tonic-gate 		*(int32_t *)attrp = ((EFanTach_t *)objp)->hi_shut;
35780Sstevel@tonic-gate 		return (status);
35790Sstevel@tonic-gate 	}
35800Sstevel@tonic-gate 
35810Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
35820Sstevel@tonic-gate 
35830Sstevel@tonic-gate 	return (PSVC_SUCCESS);
35840Sstevel@tonic-gate }
35850Sstevel@tonic-gate 
35860Sstevel@tonic-gate static int32_t
i_psvc_get_attr_8_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)35870Sstevel@tonic-gate i_psvc_get_attr_8_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
35880Sstevel@tonic-gate {
35890Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
35900Sstevel@tonic-gate 
35910Sstevel@tonic-gate 	switch (attr_id) {
35920Sstevel@tonic-gate 	case PSVC_SWITCH_STATE_ATTR:
35930Sstevel@tonic-gate 	case PSVC_STATE_ATTR:
35940Sstevel@tonic-gate 		return (i_psvc_get_device_state_8_0(hdlp, objp, attrp));
35950Sstevel@tonic-gate 	}
35960Sstevel@tonic-gate 
35970Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
35980Sstevel@tonic-gate 
35990Sstevel@tonic-gate 	return (status);
36000Sstevel@tonic-gate }
36010Sstevel@tonic-gate 
36020Sstevel@tonic-gate static int32_t
i_psvc_set_attr_8_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)36030Sstevel@tonic-gate i_psvc_set_attr_8_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
36040Sstevel@tonic-gate {
36050Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
36060Sstevel@tonic-gate 
36070Sstevel@tonic-gate 	switch (attr_id) {
36080Sstevel@tonic-gate 	case PSVC_SWITCH_STATE_ATTR:
36090Sstevel@tonic-gate 	case PSVC_STATE_ATTR:
36100Sstevel@tonic-gate 		return (i_psvc_set_device_state_8_0(hdlp, objp, attrp));
36110Sstevel@tonic-gate 	}
36120Sstevel@tonic-gate 
36130Sstevel@tonic-gate 	status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
36140Sstevel@tonic-gate 
36150Sstevel@tonic-gate 	return (status);
36160Sstevel@tonic-gate }
36170Sstevel@tonic-gate 
36180Sstevel@tonic-gate static int32_t
i_psvc_get_attr_9_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)36190Sstevel@tonic-gate i_psvc_get_attr_9_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
36200Sstevel@tonic-gate {
36210Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
36220Sstevel@tonic-gate 
36230Sstevel@tonic-gate 	switch (attr_id) {
36240Sstevel@tonic-gate 	case PSVC_SWITCH_STATE_ATTR:
36250Sstevel@tonic-gate 	case PSVC_STATE_ATTR:
36260Sstevel@tonic-gate 		status = i_psvc_get_device_state_9_0(hdlp, objp, attrp);
36270Sstevel@tonic-gate 		if ((status == PSVC_FAILURE) && (errno == EINVAL)) {
36280Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_ERROR);
36290Sstevel@tonic-gate 			return (PSVC_SUCCESS);
36300Sstevel@tonic-gate 		} else {
36310Sstevel@tonic-gate 			return (status);
36320Sstevel@tonic-gate 		}
36330Sstevel@tonic-gate 	}
36340Sstevel@tonic-gate 
36350Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
36360Sstevel@tonic-gate 
36370Sstevel@tonic-gate 	return (status);
36380Sstevel@tonic-gate }
36390Sstevel@tonic-gate 
36400Sstevel@tonic-gate static int32_t
i_psvc_get_attr_10_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)36410Sstevel@tonic-gate i_psvc_get_attr_10_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
36420Sstevel@tonic-gate {
36430Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
36440Sstevel@tonic-gate 
36450Sstevel@tonic-gate 	switch (attr_id) {
36460Sstevel@tonic-gate 	case PSVC_GPIO_VALUE_ATTR:
36470Sstevel@tonic-gate 		return (i_psvc_get_device_value_10_0(hdlp, objp, attrp));
36480Sstevel@tonic-gate 	case PSVC_GPIO_BITS:
36490Sstevel@tonic-gate 		*(int32_t *)attrp = 8;
36500Sstevel@tonic-gate 		return (status);
36510Sstevel@tonic-gate 	}
36520Sstevel@tonic-gate 
36530Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
36540Sstevel@tonic-gate 
36550Sstevel@tonic-gate 	return (status);
36560Sstevel@tonic-gate }
36570Sstevel@tonic-gate 
36580Sstevel@tonic-gate static int32_t
i_psvc_set_attr_10_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)36590Sstevel@tonic-gate i_psvc_set_attr_10_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
36600Sstevel@tonic-gate {
36610Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
36620Sstevel@tonic-gate 
36630Sstevel@tonic-gate 	if (attr_id == PSVC_GPIO_VALUE_ATTR) {
36640Sstevel@tonic-gate 		return (i_psvc_set_device_value_10_0(hdlp, objp, attrp));
36650Sstevel@tonic-gate 	}
36660Sstevel@tonic-gate 
36670Sstevel@tonic-gate 	status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
36680Sstevel@tonic-gate 
36690Sstevel@tonic-gate 	return (status);
36700Sstevel@tonic-gate }
36710Sstevel@tonic-gate 
36720Sstevel@tonic-gate static int32_t
i_psvc_get_attr_10_1(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)36730Sstevel@tonic-gate i_psvc_get_attr_10_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
36740Sstevel@tonic-gate {
36750Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
36760Sstevel@tonic-gate 
36770Sstevel@tonic-gate 	switch (attr_id) {
36780Sstevel@tonic-gate 	case PSVC_GPIO_VALUE_ATTR:
36790Sstevel@tonic-gate 		return (i_psvc_get_device_value_10_1(hdlp, objp, attrp));
36800Sstevel@tonic-gate 	case PSVC_GPIO_BITS:
36810Sstevel@tonic-gate 		*(int32_t *)attrp = 8;
36820Sstevel@tonic-gate 		return (status);
36830Sstevel@tonic-gate 	}
36840Sstevel@tonic-gate 
36850Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
36860Sstevel@tonic-gate 
36870Sstevel@tonic-gate 	return (status);
36880Sstevel@tonic-gate }
36890Sstevel@tonic-gate 
36900Sstevel@tonic-gate static int32_t
i_psvc_set_attr_10_1(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)36910Sstevel@tonic-gate i_psvc_set_attr_10_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
36920Sstevel@tonic-gate {
36930Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
36940Sstevel@tonic-gate 
36950Sstevel@tonic-gate 	if (attr_id == PSVC_GPIO_VALUE_ATTR) {
36960Sstevel@tonic-gate 		return (i_psvc_set_device_value_10_1(hdlp, objp, attrp));
36970Sstevel@tonic-gate 	}
36980Sstevel@tonic-gate 
36990Sstevel@tonic-gate 	status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
37000Sstevel@tonic-gate 
37010Sstevel@tonic-gate 	return (status);
37020Sstevel@tonic-gate }
37030Sstevel@tonic-gate 
37040Sstevel@tonic-gate /* AT24 */
37050Sstevel@tonic-gate static int32_t
i_psvc_get_attr_11_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)37060Sstevel@tonic-gate i_psvc_get_attr_11_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
37070Sstevel@tonic-gate {
37080Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
37090Sstevel@tonic-gate 	int32_t probe_status;
37100Sstevel@tonic-gate 
37110Sstevel@tonic-gate 	switch (attr_id) {
37120Sstevel@tonic-gate 	case PSVC_PROBE_RESULT_ATTR:
37130Sstevel@tonic-gate 		probe_status = i_psvc_probe_11_0(hdlp, objp);
37140Sstevel@tonic-gate 		if (probe_status == PSVC_SUCCESS)
37150Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_OK);
37160Sstevel@tonic-gate 		else
37170Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_ERROR);
37180Sstevel@tonic-gate 		return (status);
37190Sstevel@tonic-gate 	case PSVC_FRU_INFO_ATTR:
37200Sstevel@tonic-gate 		status = i_psvc_get_reg_11_0(hdlp, objp, attr_id, attrp);
37210Sstevel@tonic-gate 		return (status);
37220Sstevel@tonic-gate 	}
37230Sstevel@tonic-gate 
37240Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
37250Sstevel@tonic-gate 
37260Sstevel@tonic-gate 	return (status);
37270Sstevel@tonic-gate }
37280Sstevel@tonic-gate 
37290Sstevel@tonic-gate static int32_t
i_psvc_get_reg_11_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)37300Sstevel@tonic-gate i_psvc_get_reg_11_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
37310Sstevel@tonic-gate {
37320Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS, ret;
37330Sstevel@tonic-gate 	char path[1024], *data;
37340Sstevel@tonic-gate 	int32_t fp, temp_errno;
37350Sstevel@tonic-gate 	fru_info_t *fru_data;
37360Sstevel@tonic-gate 
37370Sstevel@tonic-gate 	fru_data = (fru_info_t *)attrp;
37380Sstevel@tonic-gate 
37390Sstevel@tonic-gate 	if (objp->present != PSVC_PRESENT) {
37400Sstevel@tonic-gate 		errno = ENODEV;
37410Sstevel@tonic-gate 		return (PSVC_FAILURE);
37420Sstevel@tonic-gate 	}
37430Sstevel@tonic-gate 
37440Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
37450Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
37460Sstevel@tonic-gate 		return (status);
37470Sstevel@tonic-gate 
37480Sstevel@tonic-gate 	fp = open(path, O_RDWR);
37490Sstevel@tonic-gate 	if (fp == -1) {
37500Sstevel@tonic-gate 		return (PSVC_FAILURE);
37510Sstevel@tonic-gate 	}
37520Sstevel@tonic-gate 
37530Sstevel@tonic-gate 	ret = lseek(fp, fru_data->buf_start, SEEK_SET);
37540Sstevel@tonic-gate 	if (ret != fru_data->buf_start) {
37550Sstevel@tonic-gate 		temp_errno = errno;
37560Sstevel@tonic-gate 		close(fp);
37570Sstevel@tonic-gate 		errno = temp_errno;
37580Sstevel@tonic-gate 		return (PSVC_FAILURE);
37590Sstevel@tonic-gate 	}
37600Sstevel@tonic-gate 
37610Sstevel@tonic-gate 	data = (char *)malloc(fru_data->read_size);
37620Sstevel@tonic-gate 	ret = read(fp, data, fru_data->read_size);
37630Sstevel@tonic-gate 	if (ret == -1) {
37640Sstevel@tonic-gate 		free(data);
37650Sstevel@tonic-gate 		close(fp);
37660Sstevel@tonic-gate 		errno = EIO;
37670Sstevel@tonic-gate 		return (-1);
37680Sstevel@tonic-gate 	}
37690Sstevel@tonic-gate 
37700Sstevel@tonic-gate 	memcpy(fru_data->buf, data, fru_data->read_size);
37710Sstevel@tonic-gate 	free(data);
37720Sstevel@tonic-gate 	close(fp);
37730Sstevel@tonic-gate 
37740Sstevel@tonic-gate 	return (status);
37750Sstevel@tonic-gate }
37760Sstevel@tonic-gate 
37770Sstevel@tonic-gate static int32_t
i_psvc_get_attr_11_1(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)37780Sstevel@tonic-gate i_psvc_get_attr_11_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
37790Sstevel@tonic-gate {
37800Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
37810Sstevel@tonic-gate 	int32_t probe_status;
37820Sstevel@tonic-gate 
37830Sstevel@tonic-gate 	if (attr_id == PSVC_PROBE_RESULT_ATTR) {
37840Sstevel@tonic-gate 		probe_status = i_psvc_probe_11_1(hdlp, objp);
37850Sstevel@tonic-gate 		if (probe_status == PSVC_SUCCESS)
37860Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_OK);
37870Sstevel@tonic-gate 		else
37880Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_ERROR);
37890Sstevel@tonic-gate 		return (status);
37900Sstevel@tonic-gate 	}
37910Sstevel@tonic-gate 
37920Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
37930Sstevel@tonic-gate 
37940Sstevel@tonic-gate 	return (status);
37950Sstevel@tonic-gate }
37960Sstevel@tonic-gate 
37970Sstevel@tonic-gate static int32_t
i_psvc_get_attr_11_2(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)37980Sstevel@tonic-gate i_psvc_get_attr_11_2(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
37990Sstevel@tonic-gate {
38000Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
38010Sstevel@tonic-gate 	int32_t probe_status;
38020Sstevel@tonic-gate 
38030Sstevel@tonic-gate 	if (attr_id == PSVC_PROBE_RESULT_ATTR) {
38040Sstevel@tonic-gate 		probe_status = i_psvc_probe_11_2(hdlp, objp);
38050Sstevel@tonic-gate 		if (probe_status == PSVC_SUCCESS)
38060Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_OK);
38070Sstevel@tonic-gate 		else
38080Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_ERROR);
38090Sstevel@tonic-gate 		return (status);
38100Sstevel@tonic-gate 	}
38110Sstevel@tonic-gate 
38120Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
38130Sstevel@tonic-gate 
38140Sstevel@tonic-gate 	return (status);
38150Sstevel@tonic-gate }
38160Sstevel@tonic-gate 
38170Sstevel@tonic-gate static int32_t
i_psvc_get_attr_11_3(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)38180Sstevel@tonic-gate i_psvc_get_attr_11_3(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
38190Sstevel@tonic-gate {
38200Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
38210Sstevel@tonic-gate 	int32_t probe_status;
38220Sstevel@tonic-gate 
38230Sstevel@tonic-gate 	if (attr_id == PSVC_PROBE_RESULT_ATTR) {
38240Sstevel@tonic-gate 		probe_status = i_psvc_probe_11_3(hdlp, objp);
38250Sstevel@tonic-gate 		if (probe_status == PSVC_SUCCESS)
38260Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_OK);
38270Sstevel@tonic-gate 		else
38280Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_ERROR);
38290Sstevel@tonic-gate 		return (status);
38300Sstevel@tonic-gate 	}
38310Sstevel@tonic-gate 
38320Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
38330Sstevel@tonic-gate 
38340Sstevel@tonic-gate 	return (status);
38350Sstevel@tonic-gate }
38360Sstevel@tonic-gate 
38370Sstevel@tonic-gate static int32_t
i_psvc_get_attr_11_4(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)38380Sstevel@tonic-gate i_psvc_get_attr_11_4(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
38390Sstevel@tonic-gate {
38400Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
38410Sstevel@tonic-gate 	int32_t probe_status;
38420Sstevel@tonic-gate 
38430Sstevel@tonic-gate 	if (attr_id == PSVC_PROBE_RESULT_ATTR) {
38440Sstevel@tonic-gate 		probe_status = i_psvc_probe_11_4(hdlp, objp);
38450Sstevel@tonic-gate 		if (probe_status == PSVC_SUCCESS)
38460Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_OK);
38470Sstevel@tonic-gate 		else
38480Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_ERROR);
38490Sstevel@tonic-gate 		return (status);
38500Sstevel@tonic-gate 	}
38510Sstevel@tonic-gate 
38520Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
38530Sstevel@tonic-gate 
38540Sstevel@tonic-gate 	return (status);
38550Sstevel@tonic-gate }
38560Sstevel@tonic-gate 
38570Sstevel@tonic-gate static int32_t
i_psvc_get_attr_11_5(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)38580Sstevel@tonic-gate i_psvc_get_attr_11_5(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
38590Sstevel@tonic-gate {
38600Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
38610Sstevel@tonic-gate 	int32_t probe_status;
38620Sstevel@tonic-gate 
38630Sstevel@tonic-gate 	if (attr_id == PSVC_PROBE_RESULT_ATTR) {
38640Sstevel@tonic-gate 		probe_status = i_psvc_probe_11_5(hdlp, objp);
38650Sstevel@tonic-gate 		if (probe_status == PSVC_SUCCESS)
38660Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_OK);
38670Sstevel@tonic-gate 		else
38680Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_ERROR);
38690Sstevel@tonic-gate 		return (status);
38700Sstevel@tonic-gate 	}
38710Sstevel@tonic-gate 
38720Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
38730Sstevel@tonic-gate 
38740Sstevel@tonic-gate 	return (status);
38750Sstevel@tonic-gate }
38760Sstevel@tonic-gate 
38770Sstevel@tonic-gate static int32_t
i_psvc_get_attr_11_6(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)38780Sstevel@tonic-gate i_psvc_get_attr_11_6(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
38790Sstevel@tonic-gate {
38800Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
38810Sstevel@tonic-gate 	int32_t probe_status;
38820Sstevel@tonic-gate 
38830Sstevel@tonic-gate 	if (attr_id == PSVC_PROBE_RESULT_ATTR) {
38840Sstevel@tonic-gate 		probe_status = i_psvc_probe_11_6(hdlp, objp);
38850Sstevel@tonic-gate 		if (probe_status == PSVC_SUCCESS)
38860Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_OK);
38870Sstevel@tonic-gate 		else
38880Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_ERROR);
38890Sstevel@tonic-gate 		return (status);
38900Sstevel@tonic-gate 	}
38910Sstevel@tonic-gate 
38920Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
38930Sstevel@tonic-gate 
38940Sstevel@tonic-gate 	return (status);
38950Sstevel@tonic-gate }
38960Sstevel@tonic-gate 
38970Sstevel@tonic-gate static int32_t
i_psvc_get_attr_11_7(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)38980Sstevel@tonic-gate i_psvc_get_attr_11_7(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
38990Sstevel@tonic-gate {
39000Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
39010Sstevel@tonic-gate 	int32_t probe_status;
39020Sstevel@tonic-gate 
39030Sstevel@tonic-gate 	if (attr_id == PSVC_PROBE_RESULT_ATTR) {
39040Sstevel@tonic-gate 		probe_status = i_psvc_probe_11_7(hdlp, objp);
39050Sstevel@tonic-gate 		if (probe_status == PSVC_SUCCESS)
39060Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_OK);
39070Sstevel@tonic-gate 		else
39080Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_ERROR);
39090Sstevel@tonic-gate 		return (status);
39100Sstevel@tonic-gate 	}
39110Sstevel@tonic-gate 
39120Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
39130Sstevel@tonic-gate 
39140Sstevel@tonic-gate 	return (status);
39150Sstevel@tonic-gate }
39160Sstevel@tonic-gate 
39170Sstevel@tonic-gate static int32_t
i_psvc_get_attr_11_8(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)39180Sstevel@tonic-gate i_psvc_get_attr_11_8(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
39190Sstevel@tonic-gate {
39200Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
39210Sstevel@tonic-gate 	int32_t probe_status;
39220Sstevel@tonic-gate 
39230Sstevel@tonic-gate 	if (attr_id == PSVC_PROBE_RESULT_ATTR) {
39240Sstevel@tonic-gate 		probe_status = i_psvc_probe_11_8(hdlp, objp);
39250Sstevel@tonic-gate 		if (probe_status == PSVC_SUCCESS)
39260Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_OK);
39270Sstevel@tonic-gate 		else
39280Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_ERROR);
39290Sstevel@tonic-gate 		return (status);
39300Sstevel@tonic-gate 	}
39310Sstevel@tonic-gate 
39320Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
39330Sstevel@tonic-gate 
39340Sstevel@tonic-gate 	return (status);
39350Sstevel@tonic-gate }
39360Sstevel@tonic-gate 
39370Sstevel@tonic-gate static int32_t
i_psvc_get_attr_11_9(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)39380Sstevel@tonic-gate i_psvc_get_attr_11_9(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
39390Sstevel@tonic-gate {
39400Sstevel@tonic-gate 	int32_t status = PSVC_SUCCESS;
39410Sstevel@tonic-gate 	int32_t probe_status;
39420Sstevel@tonic-gate 
39430Sstevel@tonic-gate 	if (attr_id == PSVC_PROBE_RESULT_ATTR) {
39440Sstevel@tonic-gate 		probe_status = i_psvc_probe_11_9(hdlp, objp);
39450Sstevel@tonic-gate 		if (probe_status == PSVC_SUCCESS)
39460Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_OK);
39470Sstevel@tonic-gate 		else
39480Sstevel@tonic-gate 			strcpy((char *)attrp, PSVC_ERROR);
39490Sstevel@tonic-gate 		return (status);
39500Sstevel@tonic-gate 	}
39510Sstevel@tonic-gate 
39520Sstevel@tonic-gate 	status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
39530Sstevel@tonic-gate 
39540Sstevel@tonic-gate 	return (status);
39550Sstevel@tonic-gate }
39560Sstevel@tonic-gate 
39570Sstevel@tonic-gate static int32_t
i_psvc_load_generic(EHdl_t * hdlp,char * name,EObj_t ** objpp,char * buf,int32_t obj_size)39580Sstevel@tonic-gate i_psvc_load_generic(
39590Sstevel@tonic-gate 	EHdl_t	*hdlp,
39600Sstevel@tonic-gate 	char	*name,
39610Sstevel@tonic-gate 	EObj_t    **objpp,
39620Sstevel@tonic-gate 	char	  *buf,
39630Sstevel@tonic-gate 	int32_t   obj_size)
39640Sstevel@tonic-gate {
39650Sstevel@tonic-gate 	int32_t found, key, array;
39660Sstevel@tonic-gate 	EObj_t *objp;
39670Sstevel@tonic-gate 	char *start;
39680Sstevel@tonic-gate 	char  cur_device[NAMELEN];
39690Sstevel@tonic-gate 	int slot;
39700Sstevel@tonic-gate 	ETable_Array *tbl_arr;
39710Sstevel@tonic-gate 
39720Sstevel@tonic-gate 	key = psvc_get_str_key(name);
39730Sstevel@tonic-gate 	array = key % PSVC_MAX_TABLE_ARRAYS;
39740Sstevel@tonic-gate 	tbl_arr = &(hdlp->tbl_arry[array]);
39750Sstevel@tonic-gate 
39760Sstevel@tonic-gate 	if (tbl_arr->nextid == hdlp->total_obj_count) {
39770Sstevel@tonic-gate 		errno = EINVAL;
39780Sstevel@tonic-gate 		return (PSVC_FAILURE);
39790Sstevel@tonic-gate 	} else {
39800Sstevel@tonic-gate 		slot = tbl_arr->nextid++;
39810Sstevel@tonic-gate 		tbl_arr->obj_count++;
39820Sstevel@tonic-gate 	}
39830Sstevel@tonic-gate 
39840Sstevel@tonic-gate 	if (i_psvc_find_file_section(hdlp->fp, "OBJECT_INFO") != PSVC_SUCCESS)
39850Sstevel@tonic-gate 		return (PSVC_FAILURE);
39860Sstevel@tonic-gate 
39870Sstevel@tonic-gate 	fgets(buf, BUFSZ, hdlp->fp);
39880Sstevel@tonic-gate 	while (strcmp(buf, "OBJECT_INFO_END")) {
39890Sstevel@tonic-gate 		start = strrchr(buf, '/');
39900Sstevel@tonic-gate 		if (start == NULL) {
39910Sstevel@tonic-gate 			errno = EINVAL;
39920Sstevel@tonic-gate 			return (PSVC_FAILURE);
39930Sstevel@tonic-gate 		}
39940Sstevel@tonic-gate 		found = sscanf(start + 1, "%s",  cur_device);
39950Sstevel@tonic-gate 		if (found != 1) {
39960Sstevel@tonic-gate 			errno = EINVAL;
39970Sstevel@tonic-gate 			return (PSVC_FAILURE);
39980Sstevel@tonic-gate 		}
39990Sstevel@tonic-gate 		if (strcmp(name, cur_device) == 0)  /* found it */
40000Sstevel@tonic-gate 			break;
40010Sstevel@tonic-gate 		fgets(buf, BUFSZ, hdlp->fp);
40020Sstevel@tonic-gate 	}
40030Sstevel@tonic-gate 
40040Sstevel@tonic-gate 	tbl_arr->obj_tbl[slot].objp = (EObj_t *)malloc(obj_size);
40050Sstevel@tonic-gate 	if (tbl_arr->obj_tbl[slot].objp == 0)
40060Sstevel@tonic-gate 		return (PSVC_FAILURE);
40070Sstevel@tonic-gate 	objp = (EObj_t *)tbl_arr->obj_tbl[slot].objp;
40080Sstevel@tonic-gate 	tbl_arr->obj_tbl[slot].type = PSVC_OBJ;
40090Sstevel@tonic-gate 
40100Sstevel@tonic-gate 	memset(objp, 0, obj_size);
40110Sstevel@tonic-gate 	strcpy(objp->label, name);
40120Sstevel@tonic-gate 	strcpy(tbl_arr->obj_tbl[slot].name, name);
40130Sstevel@tonic-gate 
40140Sstevel@tonic-gate 	tbl_arr->obj_tbl[slot].key = key;
40150Sstevel@tonic-gate 
40160Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_CLASS_ATTR, &objp->class) != PSVC_SUCCESS) {
40170Sstevel@tonic-gate 		i_psvc_destructor(hdlp, name, objp);
40180Sstevel@tonic-gate 		return (PSVC_FAILURE);
40190Sstevel@tonic-gate 	}
40200Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_SUBCLASS_ATTR, &objp->subclass) !=
40210Sstevel@tonic-gate 		PSVC_SUCCESS) {
40220Sstevel@tonic-gate 		i_psvc_destructor(hdlp, name, objp);
40230Sstevel@tonic-gate 		return (PSVC_FAILURE);
40240Sstevel@tonic-gate 	}
40250Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_INSTANCE_ATTR, &objp->instance) !=
40260Sstevel@tonic-gate 		PSVC_SUCCESS) {
40270Sstevel@tonic-gate 		i_psvc_destructor(hdlp, name, objp);
40280Sstevel@tonic-gate 		return (PSVC_FAILURE);
40290Sstevel@tonic-gate 	}
40300Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_FEATURES_ATTR, &objp->features) !=
40310Sstevel@tonic-gate 		PSVC_SUCCESS) {
40320Sstevel@tonic-gate 		i_psvc_destructor(hdlp, name, objp);
40330Sstevel@tonic-gate 		return (PSVC_FAILURE);
40340Sstevel@tonic-gate 	}
40350Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_ADDR_SPEC_ATTR, &objp->addr_spec) !=
40360Sstevel@tonic-gate 		PSVC_SUCCESS) {
40370Sstevel@tonic-gate 		i_psvc_destructor(hdlp, name, objp);
40380Sstevel@tonic-gate 		return (PSVC_FAILURE);
40390Sstevel@tonic-gate 	}
40400Sstevel@tonic-gate 
40410Sstevel@tonic-gate 	if (objp->features & PSVC_DEV_SECONDARY)
40420Sstevel@tonic-gate 		objp->enabled = PSVC_DISABLED;
40430Sstevel@tonic-gate 	else
40440Sstevel@tonic-gate 		objp->enabled = PSVC_ENABLED;
40450Sstevel@tonic-gate 
40460Sstevel@tonic-gate 	if (PSVC_GET_VERSION(objp->addr_spec) > PSVC_VERSION) {
40470Sstevel@tonic-gate 		errno = EINVAL;
40480Sstevel@tonic-gate 		i_psvc_destructor(hdlp, name, objp);
40490Sstevel@tonic-gate 		return (PSVC_FAILURE);
40500Sstevel@tonic-gate 	}
40510Sstevel@tonic-gate 
40520Sstevel@tonic-gate 	*objpp = objp;
40530Sstevel@tonic-gate 	return (PSVC_SUCCESS);
40540Sstevel@tonic-gate 
40550Sstevel@tonic-gate }
40560Sstevel@tonic-gate 
40570Sstevel@tonic-gate 
40580Sstevel@tonic-gate static int32_t
i_psvc_not_supported()40590Sstevel@tonic-gate i_psvc_not_supported()
40600Sstevel@tonic-gate {
40610Sstevel@tonic-gate 	errno = ENOTSUP;
40620Sstevel@tonic-gate 	return (PSVC_FAILURE);
40630Sstevel@tonic-gate }
40640Sstevel@tonic-gate 
40650Sstevel@tonic-gate /* Temperature sensor */
40660Sstevel@tonic-gate /* Class 0 Subclass 0 are temperature sensors that cannot be updated */
40670Sstevel@tonic-gate static int32_t
i_psvc_constructor_0_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)40680Sstevel@tonic-gate i_psvc_constructor_0_0(
40690Sstevel@tonic-gate 	EHdl_t	*hdlp,
40700Sstevel@tonic-gate 	char	*id,
40710Sstevel@tonic-gate 	EObj_t    **objpp)
40720Sstevel@tonic-gate {
40730Sstevel@tonic-gate 	int32_t status;
40740Sstevel@tonic-gate 	char buf[BUFSZ];
40750Sstevel@tonic-gate 	ETempSensor_t *dp;
40760Sstevel@tonic-gate 
40770Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf,
40780Sstevel@tonic-gate 		sizeof (ETempSensor_t));
40790Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
40800Sstevel@tonic-gate 		return (status);
40810Sstevel@tonic-gate 
40820Sstevel@tonic-gate 	/* Load class specific info */
40830Sstevel@tonic-gate 	dp = (ETempSensor_t *)*objpp;
40840Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_LO_WARN_ATTR, &dp->lo_warn)
40850Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
40860Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
40870Sstevel@tonic-gate 		return (PSVC_FAILURE);
40880Sstevel@tonic-gate 	}
40890Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_LO_SHUT_ATTR, &dp->lo_shut)
40900Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
40910Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
40920Sstevel@tonic-gate 		return (PSVC_FAILURE);
40930Sstevel@tonic-gate 	}
40940Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_HI_WARN_ATTR, &dp->hi_warn)
40950Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
40960Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
40970Sstevel@tonic-gate 		return (PSVC_FAILURE);
40980Sstevel@tonic-gate 	}
40990Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_HI_SHUT_ATTR, &dp->hi_shut)
41000Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
41010Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
41020Sstevel@tonic-gate 		return (PSVC_FAILURE);
41030Sstevel@tonic-gate 	}
41040Sstevel@tonic-gate 
41050Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_0_0;
41060Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
41070Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_0_0;
41080Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_generic;
41090Sstevel@tonic-gate 
41100Sstevel@tonic-gate 	return (0);
41110Sstevel@tonic-gate }
41120Sstevel@tonic-gate 
41130Sstevel@tonic-gate /* Class 0 Subclass 1 are temperature sensors that can be updated */
41140Sstevel@tonic-gate static int32_t
i_psvc_constructor_0_1(EHdl_t * hdlp,char * id,EObj_t ** objpp)41150Sstevel@tonic-gate i_psvc_constructor_0_1(
41160Sstevel@tonic-gate 	EHdl_t	*hdlp,
41170Sstevel@tonic-gate 	char	*id,
41180Sstevel@tonic-gate 	EObj_t    **objpp)
41190Sstevel@tonic-gate {
41200Sstevel@tonic-gate 	int32_t status;
41210Sstevel@tonic-gate 	char buf[BUFSZ];
41220Sstevel@tonic-gate 	ETempSensor_t *dp;
41230Sstevel@tonic-gate 
41240Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf,
41250Sstevel@tonic-gate 		sizeof (ETempSensor_t));
41260Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
41270Sstevel@tonic-gate 		return (status);
41280Sstevel@tonic-gate 
41290Sstevel@tonic-gate 	/* Load class specific info */
41300Sstevel@tonic-gate 	dp = (ETempSensor_t *)*objpp;
41310Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_LO_WARN_ATTR, &dp->lo_warn)
41320Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
41330Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
41340Sstevel@tonic-gate 		return (PSVC_FAILURE);
41350Sstevel@tonic-gate 	}
41360Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_LO_SHUT_ATTR, &dp->lo_shut)
41370Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
41380Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
41390Sstevel@tonic-gate 		return (PSVC_FAILURE);
41400Sstevel@tonic-gate 	}
41410Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_HI_WARN_ATTR, &dp->hi_warn)
41420Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
41430Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
41440Sstevel@tonic-gate 		return (PSVC_FAILURE);
41450Sstevel@tonic-gate 	}
41460Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_HI_SHUT_ATTR, &dp->hi_shut)
41470Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
41480Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
41490Sstevel@tonic-gate 		return (PSVC_FAILURE);
41500Sstevel@tonic-gate 	}
41510Sstevel@tonic-gate 
41520Sstevel@tonic-gate 	if ((*objpp)->features & PSVC_OPT_TEMP) {
41530Sstevel@tonic-gate 		if (i_psvc_value(buf, PSVC_OPTIMAL_TEMP_ATTR, &dp->opt_temp)
41540Sstevel@tonic-gate 		    != PSVC_SUCCESS) {
41550Sstevel@tonic-gate 			i_psvc_destructor(hdlp, id, dp);
41560Sstevel@tonic-gate 			return (PSVC_FAILURE);
41570Sstevel@tonic-gate 		}
41580Sstevel@tonic-gate 	}
41590Sstevel@tonic-gate 	if ((*objpp)->features & PSVC_HW_LOW_SHUT) {
41600Sstevel@tonic-gate 		if (i_psvc_value(buf, PSVC_HW_LO_SHUT_ATTR, &dp->hw_lo_shut)
41610Sstevel@tonic-gate 		    != PSVC_SUCCESS) {
41620Sstevel@tonic-gate 			i_psvc_destructor(hdlp, id, dp);
41630Sstevel@tonic-gate 			return (PSVC_FAILURE);
41640Sstevel@tonic-gate 		}
41650Sstevel@tonic-gate 	}
41660Sstevel@tonic-gate 	if ((*objpp)->features & PSVC_HW_HIGH_SHUT) {
41670Sstevel@tonic-gate 		if (i_psvc_value(buf, PSVC_HW_HI_SHUT_ATTR, &dp->hw_hi_shut)
41680Sstevel@tonic-gate 		    != PSVC_SUCCESS) {
41690Sstevel@tonic-gate 			i_psvc_destructor(hdlp, id, dp);
41700Sstevel@tonic-gate 			return (PSVC_FAILURE);
41710Sstevel@tonic-gate 		}
41720Sstevel@tonic-gate 	}
41730Sstevel@tonic-gate 
41740Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_0_1;
41750Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
41760Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_0_1;
41770Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_0_1;
41780Sstevel@tonic-gate 
41790Sstevel@tonic-gate 	return (0);
41800Sstevel@tonic-gate }
41810Sstevel@tonic-gate 
41820Sstevel@tonic-gate /* Fan */
41830Sstevel@tonic-gate static int32_t
i_psvc_constructor_1_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)41840Sstevel@tonic-gate i_psvc_constructor_1_0(
41850Sstevel@tonic-gate 	EHdl_t	*hdlp,
41860Sstevel@tonic-gate 	char	*id,
41870Sstevel@tonic-gate 	EObj_t  **objpp)
41880Sstevel@tonic-gate {
41890Sstevel@tonic-gate 	int32_t status;
41900Sstevel@tonic-gate 	char buf[BUFSZ];
41910Sstevel@tonic-gate 	EFan_t *dp;
41920Sstevel@tonic-gate 
41930Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf,
41940Sstevel@tonic-gate 		sizeof (EFan_t));
41950Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
41960Sstevel@tonic-gate 		return (status);
41970Sstevel@tonic-gate 
41980Sstevel@tonic-gate 	/* Load class specific info */
41990Sstevel@tonic-gate 	dp = (EFan_t *)*objpp;
42000Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_SETPOINT_ATTR, &dp->setpoint)
42010Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
42020Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
42030Sstevel@tonic-gate 		return (PSVC_FAILURE);
42040Sstevel@tonic-gate 	}
42050Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_HYSTERESIS_ATTR, &dp->hysteresis)
42060Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
42070Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
42080Sstevel@tonic-gate 		return (PSVC_FAILURE);
42090Sstevel@tonic-gate 	}
42100Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_LOOPGAIN_ATTR, &dp->loopgain)
42110Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
42120Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
42130Sstevel@tonic-gate 		return (PSVC_FAILURE);
42140Sstevel@tonic-gate 	}
42150Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_LOOPBIAS_ATTR, &dp->loopbias)
42160Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
42170Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
42180Sstevel@tonic-gate 		return (PSVC_FAILURE);
42190Sstevel@tonic-gate 	}
42200Sstevel@tonic-gate 
42210Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_1_0;
42220Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
42230Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_1_0;
42240Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_1_0;
42250Sstevel@tonic-gate 
42260Sstevel@tonic-gate 	return (PSVC_SUCCESS);
42270Sstevel@tonic-gate }
42280Sstevel@tonic-gate 
42290Sstevel@tonic-gate 
42300Sstevel@tonic-gate /* LED */
42310Sstevel@tonic-gate static int32_t
i_psvc_constructor_2_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)42320Sstevel@tonic-gate i_psvc_constructor_2_0(
42330Sstevel@tonic-gate 	EHdl_t	*hdlp,
42340Sstevel@tonic-gate 	char	*id,
42350Sstevel@tonic-gate 	EObj_t  **objpp)
42360Sstevel@tonic-gate {
42370Sstevel@tonic-gate 	int32_t status;
42380Sstevel@tonic-gate 	char buf[BUFSZ];
42390Sstevel@tonic-gate 	ELed_t *dp;
42400Sstevel@tonic-gate 
42410Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf,
42420Sstevel@tonic-gate 		sizeof (ELed_t));
42430Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
42440Sstevel@tonic-gate 		return (status);
42450Sstevel@tonic-gate 
42460Sstevel@tonic-gate 	/* Load class specific info */
42470Sstevel@tonic-gate 	dp = (ELed_t *)*objpp;
42480Sstevel@tonic-gate 
42490Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_LED_COLOR_ATTR, dp->color)
42500Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
42510Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
42520Sstevel@tonic-gate 		return (PSVC_FAILURE);
42530Sstevel@tonic-gate 	}
42540Sstevel@tonic-gate 
42550Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_2_0;
42560Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
42570Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_2_0;
42580Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_2_0;
42590Sstevel@tonic-gate 
42600Sstevel@tonic-gate 	return (PSVC_SUCCESS);
42610Sstevel@tonic-gate }
42620Sstevel@tonic-gate 
42630Sstevel@tonic-gate static int32_t
i_psvc_constructor_2_1(EHdl_t * hdlp,char * id,EObj_t ** objpp)42640Sstevel@tonic-gate i_psvc_constructor_2_1(
42650Sstevel@tonic-gate 	EHdl_t	*hdlp,
42660Sstevel@tonic-gate 	char	*id,
42670Sstevel@tonic-gate 	EObj_t  **objpp)
42680Sstevel@tonic-gate {
42690Sstevel@tonic-gate 	int32_t status;
42700Sstevel@tonic-gate 	char buf[BUFSZ];
42710Sstevel@tonic-gate 	ELed_t *dp;
42720Sstevel@tonic-gate 
42730Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf,
42740Sstevel@tonic-gate 		sizeof (ELed_t));
42750Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
42760Sstevel@tonic-gate 		return (status);
42770Sstevel@tonic-gate 
42780Sstevel@tonic-gate 	/* Load class specific info */
42790Sstevel@tonic-gate 	dp = (ELed_t *)*objpp;
42800Sstevel@tonic-gate 
42810Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_LED_COLOR_ATTR, dp->color)
42820Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
42830Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
42840Sstevel@tonic-gate 		return (PSVC_FAILURE);
42850Sstevel@tonic-gate 	}
42860Sstevel@tonic-gate 
42870Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_2_1;
42880Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
42890Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_2_1;
42900Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_2_1;
42910Sstevel@tonic-gate 
42920Sstevel@tonic-gate 	return (PSVC_SUCCESS);
42930Sstevel@tonic-gate }
42940Sstevel@tonic-gate 
42950Sstevel@tonic-gate static int32_t
i_psvc_constructor_2_2(EHdl_t * hdlp,char * id,EObj_t ** objpp)42960Sstevel@tonic-gate i_psvc_constructor_2_2(
42970Sstevel@tonic-gate 	EHdl_t	*hdlp,
42980Sstevel@tonic-gate 	char	*id,
42990Sstevel@tonic-gate 	EObj_t  **objpp)
43000Sstevel@tonic-gate {
43010Sstevel@tonic-gate 	int32_t status;
43020Sstevel@tonic-gate 	char buf[BUFSZ];
43030Sstevel@tonic-gate 	ELed_t *dp;
43040Sstevel@tonic-gate 
43050Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf,
43060Sstevel@tonic-gate 		sizeof (ELed_t));
43070Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
43080Sstevel@tonic-gate 		return (status);
43090Sstevel@tonic-gate 
43100Sstevel@tonic-gate 	/* Load class specific info */
43110Sstevel@tonic-gate 	dp = (ELed_t *)*objpp;
43120Sstevel@tonic-gate 
43130Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_LED_COLOR_ATTR, dp->color)
43140Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
43150Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
43160Sstevel@tonic-gate 		return (PSVC_FAILURE);
43170Sstevel@tonic-gate 	}
43180Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_LED_IS_LOCATOR_ATTR, dp->is_locator)
43190Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
43200Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
43210Sstevel@tonic-gate 		return (PSVC_FAILURE);
43220Sstevel@tonic-gate 	}
43230Sstevel@tonic-gate 	if (strcmp(dp->is_locator, PSVC_LOCATOR_TRUE) == 0) {
43240Sstevel@tonic-gate 		if (i_psvc_value(buf, PSVC_LED_LOCATOR_NAME_ATTR,
43250Sstevel@tonic-gate 		    dp->locator_name) != PSVC_SUCCESS) {
43260Sstevel@tonic-gate 			i_psvc_destructor(hdlp, id, dp);
43270Sstevel@tonic-gate 			return (PSVC_FAILURE);
43280Sstevel@tonic-gate 		}
43290Sstevel@tonic-gate 	} else {
43300Sstevel@tonic-gate 		strcpy(dp->locator_name, "N/A");
43310Sstevel@tonic-gate 	}
43320Sstevel@tonic-gate 
43330Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_2_2;
43340Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
43350Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_2_2;
43360Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_2_0;
43370Sstevel@tonic-gate 
43380Sstevel@tonic-gate 	return (PSVC_SUCCESS);
43390Sstevel@tonic-gate }
43400Sstevel@tonic-gate 
43410Sstevel@tonic-gate /* System Device */
43420Sstevel@tonic-gate static int32_t
i_psvc_constructor_3_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)43430Sstevel@tonic-gate i_psvc_constructor_3_0(
43440Sstevel@tonic-gate 	EHdl_t	*hdlp,
43450Sstevel@tonic-gate 	char	*id,
43460Sstevel@tonic-gate 	EObj_t  **objpp)
43470Sstevel@tonic-gate {
43480Sstevel@tonic-gate 	int32_t status;
43490Sstevel@tonic-gate 	char buf[BUFSZ];
43500Sstevel@tonic-gate 	ESystem_t *dp;
43510Sstevel@tonic-gate 
43520Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (ESystem_t));
43530Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
43540Sstevel@tonic-gate 		return (status);
43550Sstevel@tonic-gate 
43560Sstevel@tonic-gate 	/* Load class specific info */
43570Sstevel@tonic-gate 	dp = (ESystem_t *)*objpp;
43580Sstevel@tonic-gate 
43590Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_3_0;
43600Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
43610Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_generic;
43620Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_generic;
43630Sstevel@tonic-gate 
43640Sstevel@tonic-gate 	return (PSVC_SUCCESS);
43650Sstevel@tonic-gate }
43660Sstevel@tonic-gate 
43670Sstevel@tonic-gate /* Digital Sensor */
43680Sstevel@tonic-gate static int32_t
i_psvc_constructor_4_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)43690Sstevel@tonic-gate i_psvc_constructor_4_0(
43700Sstevel@tonic-gate 	EHdl_t	*hdlp,
43710Sstevel@tonic-gate 	char	*id,
43720Sstevel@tonic-gate 	EObj_t  **objpp)
43730Sstevel@tonic-gate {
43740Sstevel@tonic-gate 	int32_t status;
43750Sstevel@tonic-gate 	char buf[BUFSZ];
43760Sstevel@tonic-gate 	EDigiSensor_t *dp;
43770Sstevel@tonic-gate 
43780Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf,
43790Sstevel@tonic-gate 		sizeof (EDigiSensor_t));
43800Sstevel@tonic-gate 	if (status != PSVC_SUCCESS) {
43810Sstevel@tonic-gate 		return (status);
43820Sstevel@tonic-gate 	}
43830Sstevel@tonic-gate 
43840Sstevel@tonic-gate 	/* Load class specific info */
43850Sstevel@tonic-gate 	dp = (EDigiSensor_t *)*objpp;
43860Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_LO_WARN_ATTR, &dp->lo_warn)
43870Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
43880Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
43890Sstevel@tonic-gate 		return (PSVC_FAILURE);
43900Sstevel@tonic-gate 	}
43910Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_LO_SHUT_ATTR, &dp->lo_shut)
43920Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
43930Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
43940Sstevel@tonic-gate 		return (PSVC_FAILURE);
43950Sstevel@tonic-gate 	}
43960Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_HI_WARN_ATTR, &dp->hi_warn)
43970Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
43980Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
43990Sstevel@tonic-gate 		return (PSVC_FAILURE);
44000Sstevel@tonic-gate 	}
44010Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_HI_SHUT_ATTR, &dp->hi_shut)
44020Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
44030Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
44040Sstevel@tonic-gate 		return (PSVC_FAILURE);
44050Sstevel@tonic-gate 	}
44060Sstevel@tonic-gate 
44070Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_4_0;
44080Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
44090Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_4_0;
44100Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_generic;
44110Sstevel@tonic-gate 
44120Sstevel@tonic-gate 	return (PSVC_SUCCESS);
44130Sstevel@tonic-gate }
44140Sstevel@tonic-gate 
44150Sstevel@tonic-gate /* Digital Control */
44160Sstevel@tonic-gate static int32_t
i_psvc_constructor_5_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)44170Sstevel@tonic-gate i_psvc_constructor_5_0(
44180Sstevel@tonic-gate 	EHdl_t	*hdlp,
44190Sstevel@tonic-gate 	char	*id,
44200Sstevel@tonic-gate 	EObj_t  **objpp)
44210Sstevel@tonic-gate {
44220Sstevel@tonic-gate 	int32_t status;
44230Sstevel@tonic-gate 	char buf[BUFSZ];
44240Sstevel@tonic-gate 	EDigiControl_t *dp;
44250Sstevel@tonic-gate 
44260Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf,
44270Sstevel@tonic-gate 		sizeof (EDigiControl_t));
44280Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
44290Sstevel@tonic-gate 		return (status);
44300Sstevel@tonic-gate 
44310Sstevel@tonic-gate 	/* Load class specific info */
44320Sstevel@tonic-gate 	dp = (EDigiControl_t *)*objpp;
44330Sstevel@tonic-gate 
44340Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_5_0;
44350Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
44360Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_5_0;
44370Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_5_0;
44380Sstevel@tonic-gate 	return (PSVC_SUCCESS);
44390Sstevel@tonic-gate }
44400Sstevel@tonic-gate 
44410Sstevel@tonic-gate /* Boolean GPIO */
44420Sstevel@tonic-gate static int32_t
i_psvc_constructor_6_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)44430Sstevel@tonic-gate i_psvc_constructor_6_0(
44440Sstevel@tonic-gate 	EHdl_t	*hdlp,
44450Sstevel@tonic-gate 	char	*id,
44460Sstevel@tonic-gate 	EObj_t  **objpp)
44470Sstevel@tonic-gate {
44480Sstevel@tonic-gate 	int32_t status;
44490Sstevel@tonic-gate 	char buf[BUFSZ];
44500Sstevel@tonic-gate 	EBoolSensor_t *dp;
44510Sstevel@tonic-gate 
44520Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf,
44530Sstevel@tonic-gate 		sizeof (EBoolSensor_t));
44540Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
44550Sstevel@tonic-gate 		return (status);
44560Sstevel@tonic-gate 
44570Sstevel@tonic-gate 	/* Load class specific info */
44580Sstevel@tonic-gate 	dp = (EBoolSensor_t *)*objpp;
44590Sstevel@tonic-gate 
44600Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_6_0;
44610Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
44620Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_6_0;
44630Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_6_0;
44640Sstevel@tonic-gate 
44650Sstevel@tonic-gate 	return (PSVC_SUCCESS);
44660Sstevel@tonic-gate }
44670Sstevel@tonic-gate 
44680Sstevel@tonic-gate /* Fan Tachometer */
44690Sstevel@tonic-gate static int32_t
i_psvc_constructor_7_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)44700Sstevel@tonic-gate i_psvc_constructor_7_0(
44710Sstevel@tonic-gate 	EHdl_t	*hdlp,
44720Sstevel@tonic-gate 	char	*id,
44730Sstevel@tonic-gate 	EObj_t  **objpp)
44740Sstevel@tonic-gate {
44750Sstevel@tonic-gate 	int32_t status;
44760Sstevel@tonic-gate 	char buf[BUFSZ];
44770Sstevel@tonic-gate 	EFanTach_t *dp;
44780Sstevel@tonic-gate 
44790Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf,
44800Sstevel@tonic-gate 		sizeof (EFanTach_t));
44810Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
44820Sstevel@tonic-gate 		return (status);
44830Sstevel@tonic-gate 
44840Sstevel@tonic-gate 	/* Load class specific info */
44850Sstevel@tonic-gate 	dp = (EFanTach_t *)*objpp;
44860Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_LO_WARN_ATTR, &dp->lo_warn)
44870Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
44880Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
44890Sstevel@tonic-gate 		return (PSVC_FAILURE);
44900Sstevel@tonic-gate 	}
44910Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_LO_SHUT_ATTR, &dp->lo_shut)
44920Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
44930Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
44940Sstevel@tonic-gate 		return (PSVC_FAILURE);
44950Sstevel@tonic-gate 	}
44960Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_HI_WARN_ATTR, &dp->hi_warn)
44970Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
44980Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
44990Sstevel@tonic-gate 		return (PSVC_FAILURE);
45000Sstevel@tonic-gate 	}
45010Sstevel@tonic-gate 	if (i_psvc_value(buf, PSVC_HI_SHUT_ATTR, &dp->hi_shut)
45020Sstevel@tonic-gate 	    != PSVC_SUCCESS) {
45030Sstevel@tonic-gate 		i_psvc_destructor(hdlp, id, dp);
45040Sstevel@tonic-gate 		return (PSVC_FAILURE);
45050Sstevel@tonic-gate 	}
45060Sstevel@tonic-gate 
45070Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_7_0;
45080Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
45090Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_7_0;
45100Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_generic;
45110Sstevel@tonic-gate 
45120Sstevel@tonic-gate 	return (PSVC_SUCCESS);
45130Sstevel@tonic-gate }
45140Sstevel@tonic-gate 
45150Sstevel@tonic-gate /* On Off Switch */
45160Sstevel@tonic-gate static int32_t
i_psvc_constructor_8_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)45170Sstevel@tonic-gate i_psvc_constructor_8_0(
45180Sstevel@tonic-gate 	EHdl_t	*hdlp,
45190Sstevel@tonic-gate 	char	*id,
45200Sstevel@tonic-gate 	EObj_t  **objpp)
45210Sstevel@tonic-gate {
45220Sstevel@tonic-gate 	int32_t status;
45230Sstevel@tonic-gate 	char buf[BUFSZ];
45240Sstevel@tonic-gate 	ESwitch_t *dp;
45250Sstevel@tonic-gate 
45260Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf,
45270Sstevel@tonic-gate 		sizeof (ESwitch_t));
45280Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
45290Sstevel@tonic-gate 		return (status);
45300Sstevel@tonic-gate 
45310Sstevel@tonic-gate 	/* Load class specific info */
45320Sstevel@tonic-gate 	dp = (ESwitch_t *)*objpp;
45330Sstevel@tonic-gate 
45340Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_8_0;
45350Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
45360Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_8_0;
45370Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_8_0;
45380Sstevel@tonic-gate 
45390Sstevel@tonic-gate 	return (PSVC_SUCCESS);
45400Sstevel@tonic-gate }
45410Sstevel@tonic-gate 
45420Sstevel@tonic-gate /* Key Switch */
45430Sstevel@tonic-gate static int32_t
i_psvc_constructor_9_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)45440Sstevel@tonic-gate i_psvc_constructor_9_0(
45450Sstevel@tonic-gate 	EHdl_t	*hdlp,
45460Sstevel@tonic-gate 	char	*id,
45470Sstevel@tonic-gate 	EObj_t  **objpp)
45480Sstevel@tonic-gate {
45490Sstevel@tonic-gate 	int32_t status;
45500Sstevel@tonic-gate 	char buf[BUFSZ];
45510Sstevel@tonic-gate 	EKeySwitch_t *dp;
45520Sstevel@tonic-gate 
45530Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf,
45540Sstevel@tonic-gate 		sizeof (EKeySwitch_t));
45550Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
45560Sstevel@tonic-gate 		return (status);
45570Sstevel@tonic-gate 
45580Sstevel@tonic-gate 	/* Load class specific info */
45590Sstevel@tonic-gate 	dp = (EKeySwitch_t *)*objpp;
45600Sstevel@tonic-gate 
45610Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_9_0;
45620Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
45630Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_9_0;
45640Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_generic;
45650Sstevel@tonic-gate 
45660Sstevel@tonic-gate 	return (PSVC_SUCCESS);
45670Sstevel@tonic-gate }
45680Sstevel@tonic-gate 
45690Sstevel@tonic-gate /* 8 Bit GPIO , devices with registers, calls get_reg()/set_reg() */
45700Sstevel@tonic-gate static int32_t
i_psvc_constructor_10_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)45710Sstevel@tonic-gate i_psvc_constructor_10_0(
45720Sstevel@tonic-gate 	EHdl_t	*hdlp,
45730Sstevel@tonic-gate 	char	*id,
45740Sstevel@tonic-gate 	EObj_t  **objpp)
45750Sstevel@tonic-gate {
45760Sstevel@tonic-gate 	int32_t status;
45770Sstevel@tonic-gate 	char buf[BUFSZ];
45780Sstevel@tonic-gate 	EGPIO8_t *dp;
45790Sstevel@tonic-gate 
45800Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EGPIO8_t));
45810Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
45820Sstevel@tonic-gate 		return (status);
45830Sstevel@tonic-gate 
45840Sstevel@tonic-gate 	/* Load class specific info */
45850Sstevel@tonic-gate 	dp = (EGPIO8_t *)*objpp;
45860Sstevel@tonic-gate 
45870Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_10_0;
45880Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
45890Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_10_0;
45900Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_10_0;
45910Sstevel@tonic-gate 
45920Sstevel@tonic-gate 	return (PSVC_SUCCESS);
45930Sstevel@tonic-gate }
45940Sstevel@tonic-gate 
45950Sstevel@tonic-gate /* 8 Bit GPIO , devices with ports, calls get_port()/set_port() */
45960Sstevel@tonic-gate static int32_t
i_psvc_constructor_10_1(EHdl_t * hdlp,char * id,EObj_t ** objpp)45970Sstevel@tonic-gate i_psvc_constructor_10_1(
45980Sstevel@tonic-gate 	EHdl_t	*hdlp,
45990Sstevel@tonic-gate 	char	*id,
46000Sstevel@tonic-gate 	EObj_t  **objpp)
46010Sstevel@tonic-gate {
46020Sstevel@tonic-gate 	int32_t status;
46030Sstevel@tonic-gate 	char buf[BUFSZ];
46040Sstevel@tonic-gate 	EGPIO8_t *dp;
46050Sstevel@tonic-gate 
46060Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EGPIO8_t));
46070Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
46080Sstevel@tonic-gate 		return (status);
46090Sstevel@tonic-gate 
46100Sstevel@tonic-gate 	/* Load class specific info */
46110Sstevel@tonic-gate 	dp = (EGPIO8_t *)*objpp;
46120Sstevel@tonic-gate 
46130Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_10_1;
46140Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
46150Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_10_1;
46160Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_10_1;
46170Sstevel@tonic-gate 
46180Sstevel@tonic-gate 	return (PSVC_SUCCESS);
46190Sstevel@tonic-gate }
46200Sstevel@tonic-gate 
46210Sstevel@tonic-gate /* AT24 */
46220Sstevel@tonic-gate static int32_t
i_psvc_constructor_11_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)46230Sstevel@tonic-gate i_psvc_constructor_11_0(
46240Sstevel@tonic-gate 	EHdl_t	*hdlp,
46250Sstevel@tonic-gate 	char	*id,
46260Sstevel@tonic-gate 	EObj_t  **objpp)
46270Sstevel@tonic-gate {
46280Sstevel@tonic-gate 	int32_t status;
46290Sstevel@tonic-gate 	char buf[BUFSZ];
46300Sstevel@tonic-gate 	EPhysDev_t *dp;
46310Sstevel@tonic-gate 
46320Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf,
46330Sstevel@tonic-gate 		sizeof (EPhysDev_t));
46340Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
46350Sstevel@tonic-gate 		return (status);
46360Sstevel@tonic-gate 
46370Sstevel@tonic-gate 	/* Load class specific info */
46380Sstevel@tonic-gate 	dp = (EPhysDev_t *)*objpp;
46390Sstevel@tonic-gate 
46400Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_11_0;
46410Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
46420Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_11_0;
46430Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_generic;
46440Sstevel@tonic-gate 	dp->get_temperature = i_psvc_not_supported;
46450Sstevel@tonic-gate 	dp->get_fanspeed = i_psvc_not_supported;
46460Sstevel@tonic-gate 	dp->get_input = i_psvc_not_supported;
46470Sstevel@tonic-gate 	dp->get_bit = i_psvc_not_supported;
46480Sstevel@tonic-gate 	dp->set_bit = i_psvc_not_supported;
46490Sstevel@tonic-gate 	dp->get_port = i_psvc_not_supported;
46500Sstevel@tonic-gate 	dp->set_port = i_psvc_not_supported;
46510Sstevel@tonic-gate 	dp->get_output = i_psvc_not_supported;
46520Sstevel@tonic-gate 	dp->set_output = i_psvc_not_supported;
46530Sstevel@tonic-gate 	dp->get_reg = i_psvc_get_reg_11_0;
46540Sstevel@tonic-gate 	dp->set_reg = i_psvc_not_supported;
46550Sstevel@tonic-gate 
46560Sstevel@tonic-gate 	return (PSVC_SUCCESS);
46570Sstevel@tonic-gate }
46580Sstevel@tonic-gate 
46590Sstevel@tonic-gate /* HPC3130 */
46600Sstevel@tonic-gate static int32_t
i_psvc_constructor_11_1(EHdl_t * hdlp,char * id,EObj_t ** objpp)46610Sstevel@tonic-gate i_psvc_constructor_11_1(
46620Sstevel@tonic-gate 	EHdl_t	*hdlp,
46630Sstevel@tonic-gate 	char	*id,
46640Sstevel@tonic-gate 	EObj_t  **objpp)
46650Sstevel@tonic-gate {
46660Sstevel@tonic-gate 	int32_t status;
46670Sstevel@tonic-gate 	char buf[BUFSZ];
46680Sstevel@tonic-gate 	EPhysDev_t *dp;
46690Sstevel@tonic-gate 
46700Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
46710Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
46720Sstevel@tonic-gate 		return (status);
46730Sstevel@tonic-gate 
46740Sstevel@tonic-gate 	/* Load class specific info */
46750Sstevel@tonic-gate 	dp = (EPhysDev_t *)*objpp;
46760Sstevel@tonic-gate 
46770Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_11_1;
46780Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
46790Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_11_1;
46800Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_generic;
46810Sstevel@tonic-gate 	dp->get_temperature = i_psvc_not_supported;
46820Sstevel@tonic-gate 	dp->get_fanspeed = i_psvc_not_supported;
46830Sstevel@tonic-gate 	dp->get_input = i_psvc_not_supported;
46840Sstevel@tonic-gate 	dp->get_bit = i_psvc_not_supported;
46850Sstevel@tonic-gate 	dp->set_bit = i_psvc_not_supported;
46860Sstevel@tonic-gate 	dp->get_port = i_psvc_not_supported;
46870Sstevel@tonic-gate 	dp->set_port = i_psvc_not_supported;
46880Sstevel@tonic-gate 	dp->get_output = i_psvc_not_supported;
46890Sstevel@tonic-gate 	dp->set_output = i_psvc_not_supported;
46900Sstevel@tonic-gate 	dp->get_reg = i_psvc_get_reg_11_1;
46910Sstevel@tonic-gate 	dp->set_reg = i_psvc_set_reg_11_1;
46920Sstevel@tonic-gate 
46930Sstevel@tonic-gate 	return (PSVC_SUCCESS);
46940Sstevel@tonic-gate }
46950Sstevel@tonic-gate 
46960Sstevel@tonic-gate /* LM75 */
46970Sstevel@tonic-gate static int32_t
i_psvc_constructor_11_2(EHdl_t * hdlp,char * id,EObj_t ** objpp)46980Sstevel@tonic-gate i_psvc_constructor_11_2(
46990Sstevel@tonic-gate 	EHdl_t	*hdlp,
47000Sstevel@tonic-gate 	char	*id,
47010Sstevel@tonic-gate 	EObj_t  **objpp)
47020Sstevel@tonic-gate {
47030Sstevel@tonic-gate 	int32_t status;
47040Sstevel@tonic-gate 	char buf[BUFSZ];
47050Sstevel@tonic-gate 	EPhysDev_t *dp;
47060Sstevel@tonic-gate 
47070Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
47080Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
47090Sstevel@tonic-gate 		return (status);
47100Sstevel@tonic-gate 
47110Sstevel@tonic-gate 	/* Load class specific info */
47120Sstevel@tonic-gate 	dp = (EPhysDev_t *)*objpp;
47130Sstevel@tonic-gate 
47140Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_11_2;
47150Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
47160Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_11_2;
47170Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_generic;
47180Sstevel@tonic-gate 	dp->get_temperature = i_psvc_get_temperature_11_2;
47190Sstevel@tonic-gate 	dp->get_fanspeed = i_psvc_not_supported;
47200Sstevel@tonic-gate 	dp->get_input = i_psvc_not_supported;
47210Sstevel@tonic-gate 	dp->get_bit = i_psvc_not_supported;
47220Sstevel@tonic-gate 	dp->set_bit = i_psvc_not_supported;
47230Sstevel@tonic-gate 	dp->get_port = i_psvc_not_supported;
47240Sstevel@tonic-gate 	dp->set_port = i_psvc_not_supported;
47250Sstevel@tonic-gate 	dp->get_output = i_psvc_not_supported;
47260Sstevel@tonic-gate 	dp->set_output = i_psvc_not_supported;
47270Sstevel@tonic-gate 	dp->get_reg = i_psvc_not_supported;
47280Sstevel@tonic-gate 	dp->set_reg = i_psvc_not_supported;
47290Sstevel@tonic-gate 
47300Sstevel@tonic-gate 	return (PSVC_SUCCESS);
47310Sstevel@tonic-gate }
47320Sstevel@tonic-gate 
47330Sstevel@tonic-gate /* LTC1427 */
47340Sstevel@tonic-gate static int32_t
i_psvc_constructor_11_3(EHdl_t * hdlp,char * id,EObj_t ** objpp)47350Sstevel@tonic-gate i_psvc_constructor_11_3(
47360Sstevel@tonic-gate 	EHdl_t	*hdlp,
47370Sstevel@tonic-gate 	char	*id,
47380Sstevel@tonic-gate 	EObj_t  **objpp)
47390Sstevel@tonic-gate {
47400Sstevel@tonic-gate 	int32_t status;
47410Sstevel@tonic-gate 	char buf[BUFSZ];
47420Sstevel@tonic-gate 	EPhysDev_t *dp;
47430Sstevel@tonic-gate 	char path[1024];
47440Sstevel@tonic-gate 
47450Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
47460Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
47470Sstevel@tonic-gate 		return (status);
47480Sstevel@tonic-gate 
47490Sstevel@tonic-gate 	/*
47500Sstevel@tonic-gate 	 * The following code upto and including the open() call is so the
47510Sstevel@tonic-gate 	 * device driver for the ltc1427 does not get unloaded by the OS at
47520Sstevel@tonic-gate 	 * any time. This is important as the device driver is a write only
47530Sstevel@tonic-gate 	 * physical device but DOES keep readable states in the device unitp
47540Sstevel@tonic-gate 	 * structure (I2C_GET_OUTPUT) as a result this device should not
47550Sstevel@tonic-gate 	 * be unload while PSVC is up and running
47560Sstevel@tonic-gate 	 */
47570Sstevel@tonic-gate 	status = i_psvc_get_devpath(hdlp, (*objpp)->addr_spec, path);
47580Sstevel@tonic-gate 	if (status != PSVC_SUCCESS) {
47590Sstevel@tonic-gate 		return (status);
47600Sstevel@tonic-gate 	}
47610Sstevel@tonic-gate 
4762*1049Sjfrank 	/*
4763*1049Sjfrank 	 * We deliberately do not close our file handle, to prevent
4764*1049Sjfrank 	 * any device instances from being detached.  If an instance
4765*1049Sjfrank 	 * is detached, the "readable states in the device unitp"
4766*1049Sjfrank 	 * will be unloaded, causing loss of control of the device
4767*1049Sjfrank 	 * and incorrect error(s) to be displayed.
4768*1049Sjfrank 	 */
4769*1049Sjfrank 	if (open(path, O_RDWR) == -1) {
47700Sstevel@tonic-gate 		return (PSVC_FAILURE);
47710Sstevel@tonic-gate 	}
47720Sstevel@tonic-gate 	/* Load class specific info */
47730Sstevel@tonic-gate 	dp = (EPhysDev_t *)*objpp;
47740Sstevel@tonic-gate 
47750Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_11_3;
47760Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
47770Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_11_3;
47780Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_generic;
47790Sstevel@tonic-gate 	dp->get_temperature = i_psvc_not_supported;
47800Sstevel@tonic-gate 	dp->get_fanspeed = i_psvc_not_supported;
47810Sstevel@tonic-gate 	dp->get_input = i_psvc_not_supported;
47820Sstevel@tonic-gate 	dp->get_bit = i_psvc_not_supported;
47830Sstevel@tonic-gate 	dp->set_bit = i_psvc_not_supported;
47840Sstevel@tonic-gate 	dp->get_port = i_psvc_not_supported;
47850Sstevel@tonic-gate 	dp->set_port = i_psvc_not_supported;
47860Sstevel@tonic-gate 	dp->get_output = i_psvc_get_output_11_3;
47870Sstevel@tonic-gate 	dp->set_output = i_psvc_set_output_11_3;
47880Sstevel@tonic-gate 	dp->get_reg = i_psvc_not_supported;
47890Sstevel@tonic-gate 	dp->set_reg = i_psvc_not_supported;
47900Sstevel@tonic-gate 
47910Sstevel@tonic-gate 	return (PSVC_SUCCESS);
47920Sstevel@tonic-gate }
47930Sstevel@tonic-gate 
47940Sstevel@tonic-gate /* MAX1617 */
47950Sstevel@tonic-gate static int32_t
i_psvc_constructor_11_4(EHdl_t * hdlp,char * id,EObj_t ** objpp)47960Sstevel@tonic-gate i_psvc_constructor_11_4(
47970Sstevel@tonic-gate 	EHdl_t	*hdlp,
47980Sstevel@tonic-gate 	char	*id,
47990Sstevel@tonic-gate 	EObj_t  **objpp)
48000Sstevel@tonic-gate {
48010Sstevel@tonic-gate 	int32_t status;
48020Sstevel@tonic-gate 	char buf[BUFSZ];
48030Sstevel@tonic-gate 	EPhysDev_t *dp;
48040Sstevel@tonic-gate 
48050Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
48060Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
48070Sstevel@tonic-gate 		return (status);
48080Sstevel@tonic-gate 
48090Sstevel@tonic-gate 	/* Load class specific info */
48100Sstevel@tonic-gate 	dp = (EPhysDev_t *)*objpp;
48110Sstevel@tonic-gate 
48120Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_11_4;
48130Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
48140Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_11_4;
48150Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_generic;
48160Sstevel@tonic-gate 	dp->get_temperature = i_psvc_get_temperature_11_4;
48170Sstevel@tonic-gate 	dp->get_fanspeed = i_psvc_not_supported;
48180Sstevel@tonic-gate 	dp->get_input = i_psvc_not_supported;
48190Sstevel@tonic-gate 	dp->get_bit = i_psvc_not_supported;
48200Sstevel@tonic-gate 	dp->set_bit = i_psvc_not_supported;
48210Sstevel@tonic-gate 	dp->get_port = i_psvc_not_supported;
48220Sstevel@tonic-gate 	dp->set_port = i_psvc_not_supported;
48230Sstevel@tonic-gate 	dp->get_output = i_psvc_not_supported;
48240Sstevel@tonic-gate 	dp->set_output = i_psvc_not_supported;
48250Sstevel@tonic-gate 	dp->get_reg = i_psvc_not_supported;
48260Sstevel@tonic-gate 	dp->set_reg = i_psvc_not_supported;
48270Sstevel@tonic-gate 
48280Sstevel@tonic-gate 	return (PSVC_SUCCESS);
48290Sstevel@tonic-gate }
48300Sstevel@tonic-gate 
48310Sstevel@tonic-gate /* PCF8574 */
48320Sstevel@tonic-gate static int32_t
i_psvc_constructor_11_5(EHdl_t * hdlp,char * id,EObj_t ** objpp)48330Sstevel@tonic-gate i_psvc_constructor_11_5(
48340Sstevel@tonic-gate 	EHdl_t	*hdlp,
48350Sstevel@tonic-gate 	char	*id,
48360Sstevel@tonic-gate 	EObj_t  **objpp)
48370Sstevel@tonic-gate {
48380Sstevel@tonic-gate 	int32_t status;
48390Sstevel@tonic-gate 	char buf[BUFSZ];
48400Sstevel@tonic-gate 	EPhysDev_t *dp;
48410Sstevel@tonic-gate 
48420Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
48430Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
48440Sstevel@tonic-gate 		return (status);
48450Sstevel@tonic-gate 
48460Sstevel@tonic-gate 	/* Load class specific info */
48470Sstevel@tonic-gate 	dp = (EPhysDev_t *)*objpp;
48480Sstevel@tonic-gate 
48490Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_11_5;
48500Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
48510Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_11_5;
48520Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_generic;
48530Sstevel@tonic-gate 	dp->get_temperature = i_psvc_not_supported;
48540Sstevel@tonic-gate 	dp->get_fanspeed = i_psvc_not_supported;
48550Sstevel@tonic-gate 	dp->get_input = i_psvc_not_supported;
48560Sstevel@tonic-gate 	dp->get_bit = i_psvc_get_bit_11_5;
48570Sstevel@tonic-gate 	dp->set_bit = i_psvc_set_bit_11_5;
48580Sstevel@tonic-gate 	dp->get_port = i_psvc_get_port_11_5;
48590Sstevel@tonic-gate 	dp->set_port = i_psvc_set_port_11_5;
48600Sstevel@tonic-gate 	dp->get_output = i_psvc_not_supported;
48610Sstevel@tonic-gate 	dp->set_output = i_psvc_not_supported;
48620Sstevel@tonic-gate 	dp->get_reg = i_psvc_not_supported;
48630Sstevel@tonic-gate 	dp->set_reg = i_psvc_not_supported;
48640Sstevel@tonic-gate 
48650Sstevel@tonic-gate 	return (PSVC_SUCCESS);
48660Sstevel@tonic-gate }
48670Sstevel@tonic-gate 
48680Sstevel@tonic-gate /* PCF8591 */
48690Sstevel@tonic-gate static int32_t
i_psvc_constructor_11_6(EHdl_t * hdlp,char * id,EObj_t ** objpp)48700Sstevel@tonic-gate i_psvc_constructor_11_6(
48710Sstevel@tonic-gate 	EHdl_t	*hdlp,
48720Sstevel@tonic-gate 	char	*id,
48730Sstevel@tonic-gate 	EObj_t  **objpp)
48740Sstevel@tonic-gate {
48750Sstevel@tonic-gate 	int32_t status;
48760Sstevel@tonic-gate 	char buf[BUFSZ];
48770Sstevel@tonic-gate 	EPhysDev_t *dp;
48780Sstevel@tonic-gate 
48790Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
48800Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
48810Sstevel@tonic-gate 		return (status);
48820Sstevel@tonic-gate 
48830Sstevel@tonic-gate 	/* Load class specific info */
48840Sstevel@tonic-gate 	dp = (EPhysDev_t *)*objpp;
48850Sstevel@tonic-gate 
48860Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_11_6;
48870Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
48880Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_11_6;
48890Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_generic;
48900Sstevel@tonic-gate 	dp->get_temperature = i_psvc_get_temperature_11_6;
48910Sstevel@tonic-gate 	dp->get_fanspeed = i_psvc_not_supported;
48920Sstevel@tonic-gate 	dp->get_input = i_psvc_get_input_11_6;
48930Sstevel@tonic-gate 	dp->get_bit = i_psvc_not_supported;
48940Sstevel@tonic-gate 	dp->set_bit = i_psvc_not_supported;
48950Sstevel@tonic-gate 	dp->get_port = i_psvc_not_supported;
48960Sstevel@tonic-gate 	dp->set_port = i_psvc_not_supported;
48970Sstevel@tonic-gate 	dp->get_output = i_psvc_get_output_11_6;
48980Sstevel@tonic-gate 	dp->set_output = i_psvc_set_output_11_6;
48990Sstevel@tonic-gate 	dp->get_reg = i_psvc_not_supported;
49000Sstevel@tonic-gate 	dp->set_reg = i_psvc_not_supported;
49010Sstevel@tonic-gate 
49020Sstevel@tonic-gate 	return (PSVC_SUCCESS);
49030Sstevel@tonic-gate }
49040Sstevel@tonic-gate 
49050Sstevel@tonic-gate /* SSC050 */
49060Sstevel@tonic-gate static int32_t
i_psvc_constructor_11_7(EHdl_t * hdlp,char * id,EObj_t ** objpp)49070Sstevel@tonic-gate i_psvc_constructor_11_7(
49080Sstevel@tonic-gate 	EHdl_t	*hdlp,
49090Sstevel@tonic-gate 	char	*id,
49100Sstevel@tonic-gate 	EObj_t  **objpp)
49110Sstevel@tonic-gate {
49120Sstevel@tonic-gate 	int32_t status;
49130Sstevel@tonic-gate 	char buf[BUFSZ];
49140Sstevel@tonic-gate 	EPhysDev_t *dp;
49150Sstevel@tonic-gate 
49160Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
49170Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
49180Sstevel@tonic-gate 		return (status);
49190Sstevel@tonic-gate 
49200Sstevel@tonic-gate 	/* Load class specific info */
49210Sstevel@tonic-gate 	dp = (EPhysDev_t *)*objpp;
49220Sstevel@tonic-gate 
49230Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_11_7;
49240Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
49250Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_11_7;
49260Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_generic;
49270Sstevel@tonic-gate 	dp->get_temperature = i_psvc_not_supported;
49280Sstevel@tonic-gate 	dp->get_fanspeed = i_psvc_get_fanspeed_11_7;
49290Sstevel@tonic-gate 	dp->get_input = i_psvc_not_supported;
49300Sstevel@tonic-gate 	dp->get_bit = i_psvc_get_bit_11_7;
49310Sstevel@tonic-gate 	dp->set_bit = i_psvc_set_bit_11_7;
49320Sstevel@tonic-gate 	dp->get_port = i_psvc_get_port_11_5;	/* same as for class = 11, 5 */
49330Sstevel@tonic-gate 	dp->set_port = i_psvc_set_port_11_5;
49340Sstevel@tonic-gate 	dp->get_output = i_psvc_not_supported;
49350Sstevel@tonic-gate 	dp->set_output = i_psvc_not_supported;
49360Sstevel@tonic-gate 	dp->get_reg = i_psvc_get_reg_11_7;
49370Sstevel@tonic-gate 	dp->set_reg = i_psvc_set_reg_11_7;
49380Sstevel@tonic-gate 
49390Sstevel@tonic-gate 	return (PSVC_SUCCESS);
49400Sstevel@tonic-gate }
49410Sstevel@tonic-gate 
49420Sstevel@tonic-gate /* TDA8444 */
49430Sstevel@tonic-gate static int32_t
i_psvc_constructor_11_8(EHdl_t * hdlp,char * id,EObj_t ** objpp)49440Sstevel@tonic-gate i_psvc_constructor_11_8(
49450Sstevel@tonic-gate 	EHdl_t	*hdlp,
49460Sstevel@tonic-gate 	char	*id,
49470Sstevel@tonic-gate 	EObj_t  **objpp)
49480Sstevel@tonic-gate {
49490Sstevel@tonic-gate 	int32_t status;
49500Sstevel@tonic-gate 	char buf[BUFSZ];
49510Sstevel@tonic-gate 	EPhysDev_t *dp;
49520Sstevel@tonic-gate 
49530Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
49540Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
49550Sstevel@tonic-gate 		return (status);
49560Sstevel@tonic-gate 
49570Sstevel@tonic-gate 	/* Load class specific info */
49580Sstevel@tonic-gate 	dp = (EPhysDev_t *)*objpp;
49590Sstevel@tonic-gate 
49600Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_11_8;
49610Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
49620Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_11_8;
49630Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_generic;
49640Sstevel@tonic-gate 	dp->get_temperature = i_psvc_not_supported;
49650Sstevel@tonic-gate 	dp->get_fanspeed = i_psvc_not_supported;
49660Sstevel@tonic-gate 	dp->get_input = i_psvc_not_supported;
49670Sstevel@tonic-gate 	dp->get_bit = i_psvc_not_supported;
49680Sstevel@tonic-gate 	dp->set_bit = i_psvc_not_supported;
49690Sstevel@tonic-gate 	dp->get_port = i_psvc_not_supported;
49700Sstevel@tonic-gate 	dp->set_port = i_psvc_not_supported;
49710Sstevel@tonic-gate 	dp->get_output = i_psvc_get_output_11_8;
49720Sstevel@tonic-gate 	dp->set_output = i_psvc_set_output_11_8;
49730Sstevel@tonic-gate 	dp->get_reg = i_psvc_not_supported;
49740Sstevel@tonic-gate 	dp->set_reg = i_psvc_not_supported;
49750Sstevel@tonic-gate 
49760Sstevel@tonic-gate 	return (PSVC_SUCCESS);
49770Sstevel@tonic-gate }
49780Sstevel@tonic-gate 
49790Sstevel@tonic-gate /* SSC100 */
49800Sstevel@tonic-gate static int32_t
i_psvc_constructor_11_9(EHdl_t * hdlp,char * id,EObj_t ** objpp)49810Sstevel@tonic-gate i_psvc_constructor_11_9(
49820Sstevel@tonic-gate 	EHdl_t	*hdlp,
49830Sstevel@tonic-gate 	char	*id,
49840Sstevel@tonic-gate 	EObj_t  **objpp)
49850Sstevel@tonic-gate {
49860Sstevel@tonic-gate 	int32_t status;
49870Sstevel@tonic-gate 	char buf[BUFSZ];
49880Sstevel@tonic-gate 	EPhysDev_t *dp;
49890Sstevel@tonic-gate 
49900Sstevel@tonic-gate 	status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
49910Sstevel@tonic-gate 	if (status != PSVC_SUCCESS)
49920Sstevel@tonic-gate 		return (status);
49930Sstevel@tonic-gate 
49940Sstevel@tonic-gate 	/* Load class specific info */
49950Sstevel@tonic-gate 	dp = (EPhysDev_t *)*objpp;
49960Sstevel@tonic-gate 
49970Sstevel@tonic-gate 	dp->ld.constructor = i_psvc_constructor_11_9;
49980Sstevel@tonic-gate 	dp->ld.destructor = i_psvc_destructor;
49990Sstevel@tonic-gate 	dp->ld.get_attr = i_psvc_get_attr_11_9;
50000Sstevel@tonic-gate 	dp->ld.set_attr = i_psvc_set_attr_generic;
50010Sstevel@tonic-gate 	dp->get_temperature = i_psvc_not_supported;
50020Sstevel@tonic-gate 	dp->get_fanspeed = i_psvc_not_supported;
50030Sstevel@tonic-gate 	dp->get_input = i_psvc_not_supported;
50040Sstevel@tonic-gate 	dp->get_bit = i_psvc_not_supported;
50050Sstevel@tonic-gate 	dp->set_bit = i_psvc_not_supported;
50060Sstevel@tonic-gate 	dp->get_port = i_psvc_get_port_11_5;	/* Same as for class = 11, 5 */
50070Sstevel@tonic-gate 	dp->set_port = i_psvc_set_port_11_5;
50080Sstevel@tonic-gate 	dp->get_output = i_psvc_not_supported;
50090Sstevel@tonic-gate 	dp->set_output = i_psvc_not_supported;
50100Sstevel@tonic-gate 	dp->get_reg = i_psvc_not_supported;
50110Sstevel@tonic-gate 	dp->set_reg = i_psvc_not_supported;
50120Sstevel@tonic-gate 
50130Sstevel@tonic-gate 	return (PSVC_SUCCESS);
50140Sstevel@tonic-gate }
50150Sstevel@tonic-gate 
50160Sstevel@tonic-gate int32_t
psvc_init(EHdl_t ** hdlpp)50170Sstevel@tonic-gate psvc_init(EHdl_t **hdlpp)
50180Sstevel@tonic-gate {
50190Sstevel@tonic-gate 	EHdl_t *hdlp;
50200Sstevel@tonic-gate 	int    i;
50210Sstevel@tonic-gate 	char   buf[BUFSZ];
50220Sstevel@tonic-gate 	char   platform[32];
50230Sstevel@tonic-gate 	char   filename[256];
50240Sstevel@tonic-gate 	int    found;
50250Sstevel@tonic-gate 	int32_t status;
50260Sstevel@tonic-gate 	pthread_mutexattr_t mutex_attr;
50270Sstevel@tonic-gate 	uint32_t table_count;
50280Sstevel@tonic-gate 	int	forward_slash = 47;
50290Sstevel@tonic-gate 	int	new_line = 10;
50300Sstevel@tonic-gate 	char	*nl_char;
50310Sstevel@tonic-gate 
50320Sstevel@tonic-gate 	hdlp = (EHdl_t *)malloc(sizeof (EHdl_t));
50330Sstevel@tonic-gate 	if (hdlp == NULL)
50340Sstevel@tonic-gate 		return (-1);
50350Sstevel@tonic-gate 	memset(hdlp, 0, sizeof (EHdl_t));
50360Sstevel@tonic-gate 
50370Sstevel@tonic-gate 	/* Initialize the lock */
50380Sstevel@tonic-gate 	status = pthread_mutexattr_init(&mutex_attr);
50390Sstevel@tonic-gate 	if (status != 0) {
50400Sstevel@tonic-gate 		errno = status;
50410Sstevel@tonic-gate 		return (-1);
50420Sstevel@tonic-gate 	}
50430Sstevel@tonic-gate 	status = pthread_mutex_init(&hdlp->mutex, &mutex_attr);
50440Sstevel@tonic-gate 	if (status != 0) {
50450Sstevel@tonic-gate 		errno = status;
50460Sstevel@tonic-gate 		return (-1);
50470Sstevel@tonic-gate 	}
50480Sstevel@tonic-gate 	pthread_mutexattr_destroy(&mutex_attr);
50490Sstevel@tonic-gate 
50500Sstevel@tonic-gate 	if (sysinfo(SI_PLATFORM, platform, sizeof (platform)) == -1) {
50510Sstevel@tonic-gate 		return (-1);
50520Sstevel@tonic-gate 	}
50530Sstevel@tonic-gate 
50540Sstevel@tonic-gate 	snprintf(filename, sizeof (filename),
50550Sstevel@tonic-gate 	    "/usr/platform/%s/lib/psvcobj.conf", platform);
50560Sstevel@tonic-gate 	if ((hdlp->fp = fopen(filename, "r")) == NULL) {
50570Sstevel@tonic-gate 		return (-1);
50580Sstevel@tonic-gate 	}
50590Sstevel@tonic-gate 
50600Sstevel@tonic-gate 
50610Sstevel@tonic-gate 	/* Build the association ID lookup table */
50620Sstevel@tonic-gate 
50630Sstevel@tonic-gate 	hdlp->othr_count = hdlp->assoc_count = ASSOC_STR_TAB_SIZE;
50640Sstevel@tonic-gate 	if ((hdlp->othr_tbl = (EStringId_t *)malloc(sizeof (EStringId_t) *
50650Sstevel@tonic-gate 		hdlp->othr_count)) == NULL) {
50660Sstevel@tonic-gate 		return (-1);
50670Sstevel@tonic-gate 	}
50680Sstevel@tonic-gate 
50690Sstevel@tonic-gate 	for (i = 0; i < hdlp->othr_count; ++i) {
50700Sstevel@tonic-gate 		hdlp->othr_tbl[i].id = i;
50710Sstevel@tonic-gate 		strcpy(hdlp->othr_tbl[i].name, assoc_str_tab[i]);
50720Sstevel@tonic-gate 	}
50730Sstevel@tonic-gate 	qsort(hdlp->othr_tbl, hdlp->othr_count, sizeof (EStringId_t),
50740Sstevel@tonic-gate 		(int (*)(const void *, const void *))i_psvc_name_compare_qsort);
50750Sstevel@tonic-gate 
50760Sstevel@tonic-gate 	/* determine total number of objects + tables */
50770Sstevel@tonic-gate 	if (i_psvc_find_file_section(hdlp->fp, "OBJECT_INFO") == -1) {
50780Sstevel@tonic-gate 		return (-1);
50790Sstevel@tonic-gate 	}
50800Sstevel@tonic-gate 	if (i_psvc_count_records(hdlp->fp, "OBJECT_INFO_END",
50810Sstevel@tonic-gate 		&hdlp->total_obj_count) == -1) {
50820Sstevel@tonic-gate 		return (-1);
50830Sstevel@tonic-gate 	}
50840Sstevel@tonic-gate 	if (i_psvc_find_file_section(hdlp->fp, "TABLES") == PSVC_SUCCESS) {
50850Sstevel@tonic-gate 		status = i_psvc_count_tables_associations(hdlp->fp,
50860Sstevel@tonic-gate 			&table_count, "TABLE_END");
50870Sstevel@tonic-gate 		if (status == PSVC_FAILURE) {
50880Sstevel@tonic-gate 			return (status);
50890Sstevel@tonic-gate 		}
50900Sstevel@tonic-gate 		hdlp->total_obj_count += table_count;
50910Sstevel@tonic-gate 	}
50920Sstevel@tonic-gate 
50930Sstevel@tonic-gate 	/* Allocate object name to object pointer translation table */
50940Sstevel@tonic-gate 	for (i = 0; i < PSVC_MAX_TABLE_ARRAYS; i++) {
50950Sstevel@tonic-gate 		if ((hdlp->tbl_arry[i].obj_tbl =
50960Sstevel@tonic-gate 			(ENamePtr_t *)malloc(
50970Sstevel@tonic-gate 		sizeof (ENamePtr_t) *hdlp->total_obj_count)) == NULL) {
50980Sstevel@tonic-gate 			return (-1);
50990Sstevel@tonic-gate 		}
51000Sstevel@tonic-gate 		memset(hdlp->tbl_arry[i].obj_tbl, 0,
51010Sstevel@tonic-gate 		    sizeof (ENamePtr_t) * hdlp->total_obj_count);
51020Sstevel@tonic-gate 		hdlp->tbl_arry[i].obj_count = 0;
51030Sstevel@tonic-gate 	}
51040Sstevel@tonic-gate 
51050Sstevel@tonic-gate 	/* Build the association table */
51060Sstevel@tonic-gate 	if (i_psvc_load_associations(hdlp, hdlp->fp) == -1)
51070Sstevel@tonic-gate 		return (-1);
51080Sstevel@tonic-gate 
51090Sstevel@tonic-gate 	/* Build the table of device paths */
51100Sstevel@tonic-gate 	if (i_psvc_find_file_section(hdlp->fp, "DEVPATHS") == -1)
51110Sstevel@tonic-gate 		return (-1);
51120Sstevel@tonic-gate 	if (i_psvc_count_records(hdlp->fp, "DEVPATHS_END",
51130Sstevel@tonic-gate 		&hdlp->dev_count) == -1)
51140Sstevel@tonic-gate 		return (-1);
51150Sstevel@tonic-gate 	if ((hdlp->dev_tbl = (EDevice_t *)malloc(sizeof (EDevice_t) *
51160Sstevel@tonic-gate 		hdlp->dev_count)) == NULL) {
51170Sstevel@tonic-gate 		return (-1);
51180Sstevel@tonic-gate 	}
51190Sstevel@tonic-gate 	for (i = 0; i < hdlp->dev_count; ++i) {
51200Sstevel@tonic-gate 		fgets(buf, BUFSZ, hdlp->fp);
51210Sstevel@tonic-gate 		found = sscanf(buf, "%d %d %x %d",
51220Sstevel@tonic-gate 			&hdlp->dev_tbl[i].controller,
51230Sstevel@tonic-gate 			&hdlp->dev_tbl[i].bus, &hdlp->dev_tbl[i].addr,
51240Sstevel@tonic-gate 			&hdlp->dev_tbl[i].port);
51250Sstevel@tonic-gate 		if (found != 4) {
51260Sstevel@tonic-gate 			errno = EINVAL;
51270Sstevel@tonic-gate 			return (-1);
51280Sstevel@tonic-gate 		}
51290Sstevel@tonic-gate 		strcpy(hdlp->dev_tbl[i].path, strchr(buf, forward_slash));
51300Sstevel@tonic-gate 		/*
51310Sstevel@tonic-gate 		 * Replace new line character with NUL character
51320Sstevel@tonic-gate 		 */
51330Sstevel@tonic-gate 		nl_char = strchr(hdlp->dev_tbl[i].path, new_line);
51340Sstevel@tonic-gate 		*nl_char = 0;
51350Sstevel@tonic-gate 	}
51360Sstevel@tonic-gate 
51370Sstevel@tonic-gate 	/* Build the table of tables */
51380Sstevel@tonic-gate 	if (i_psvc_load_tables(hdlp, hdlp->fp) == -1)
51390Sstevel@tonic-gate 		return (-1);
51400Sstevel@tonic-gate 	*hdlpp = hdlp;
51410Sstevel@tonic-gate 	return (0);
51420Sstevel@tonic-gate }
51430Sstevel@tonic-gate 
51440Sstevel@tonic-gate int32_t
psvc_fini(EHdl_t * hdlp)51450Sstevel@tonic-gate psvc_fini(EHdl_t *hdlp)
51460Sstevel@tonic-gate {
51470Sstevel@tonic-gate 	int32_t i, j;
51480Sstevel@tonic-gate 	ETable_Array *array;
51490Sstevel@tonic-gate 
51500Sstevel@tonic-gate 	if (hdlp == 0)
51510Sstevel@tonic-gate 		return (PSVC_SUCCESS);
51520Sstevel@tonic-gate 
51530Sstevel@tonic-gate 	for (j = 0; j < PSVC_MAX_TABLE_ARRAYS; j++) {
51540Sstevel@tonic-gate 		if (hdlp->tbl_arry[j].obj_tbl != 0) {
51550Sstevel@tonic-gate 			array = &(hdlp->tbl_arry[j]);
51560Sstevel@tonic-gate 			for (i = 0; i < array->obj_count; ++i) {
51570Sstevel@tonic-gate 				if (array->obj_tbl[i].type == PSVC_OBJ) {
51580Sstevel@tonic-gate 					if (!array->obj_tbl[i].objp) {
51590Sstevel@tonic-gate 						/* Skip non-existent object */
51600Sstevel@tonic-gate 						continue;
51610Sstevel@tonic-gate 					}
51620Sstevel@tonic-gate 					array->obj_tbl[i].objp->destructor(hdlp,
51630Sstevel@tonic-gate 					    array->obj_tbl[i].objp->label,
51640Sstevel@tonic-gate 					    array->obj_tbl[i].objp);
51650Sstevel@tonic-gate 				}
51660Sstevel@tonic-gate 
51670Sstevel@tonic-gate 				if (array->obj_tbl[i].type == PSVC_TBL) {
51680Sstevel@tonic-gate 					ETable_t *tblp =
51690Sstevel@tonic-gate 					    (ETable_t *)array->obj_tbl[i].objp;
51700Sstevel@tonic-gate 					if (tblp->table != 0)
51710Sstevel@tonic-gate 						free(tblp->table);
51720Sstevel@tonic-gate 				}
51730Sstevel@tonic-gate 			}
51740Sstevel@tonic-gate 
51750Sstevel@tonic-gate 			free(array->obj_tbl);
51760Sstevel@tonic-gate 		}
51770Sstevel@tonic-gate 	}
51780Sstevel@tonic-gate 
51790Sstevel@tonic-gate 	if (hdlp->othr_tbl != 0)
51800Sstevel@tonic-gate 		free(hdlp->othr_tbl);
51810Sstevel@tonic-gate 
51820Sstevel@tonic-gate 	if (hdlp->assoc_tbl != 0) {
51830Sstevel@tonic-gate 		for (i = 0; i < hdlp->assoc_count; ++i) {
51840Sstevel@tonic-gate 			if (hdlp->assoc_tbl[i].table != 0)
51850Sstevel@tonic-gate 				free(hdlp->assoc_tbl[i].table);
51860Sstevel@tonic-gate 		}
51870Sstevel@tonic-gate 		free(hdlp->assoc_tbl);
51880Sstevel@tonic-gate 	}
51890Sstevel@tonic-gate 
51900Sstevel@tonic-gate 	if (hdlp->dev_tbl != 0)
51910Sstevel@tonic-gate 		free(hdlp->dev_tbl);
51920Sstevel@tonic-gate 	if (hdlp->fp != 0)
51930Sstevel@tonic-gate 		fclose(hdlp->fp);
51940Sstevel@tonic-gate 	pthread_mutex_destroy(&hdlp->mutex);
51950Sstevel@tonic-gate 	free(hdlp);
51960Sstevel@tonic-gate 	return (PSVC_SUCCESS);
51970Sstevel@tonic-gate }
51980Sstevel@tonic-gate 
51990Sstevel@tonic-gate int32_t
ioctl_retry(int fp,int request,void * arg_pointer)52000Sstevel@tonic-gate ioctl_retry(int fp, int request, void * arg_pointer)
52010Sstevel@tonic-gate {
52020Sstevel@tonic-gate 	int32_t ret = PSVC_SUCCESS;
52030Sstevel@tonic-gate 	int32_t tries = 0;
52040Sstevel@tonic-gate 
52050Sstevel@tonic-gate 	/*
52060Sstevel@tonic-gate 	 * Becuase the i2c bus is a multimaster bus we need to protect
52070Sstevel@tonic-gate 	 * ourselves from bus masters that are not being good bus citizens.
52080Sstevel@tonic-gate 	 * A retry number of 10 should be sufficient to handle any bad bus
52090Sstevel@tonic-gate 	 * citizens.  After that we will simply say that there is something
52100Sstevel@tonic-gate 	 * wrong with the ioctl transaction and let it bubble back up.
52110Sstevel@tonic-gate 	 */
52120Sstevel@tonic-gate 	do {
52130Sstevel@tonic-gate 		ret = ioctl(fp, request, arg_pointer);
52140Sstevel@tonic-gate 		tries ++;
52150Sstevel@tonic-gate 	} while ((ret == -1) && (tries < 10));
52160Sstevel@tonic-gate 
52170Sstevel@tonic-gate 	return (ret);
52180Sstevel@tonic-gate }
52190Sstevel@tonic-gate 
52200Sstevel@tonic-gate static int32_t
psvc_get_str_key(char * object)52210Sstevel@tonic-gate psvc_get_str_key(char *object)
52220Sstevel@tonic-gate {
52230Sstevel@tonic-gate 	int32_t key = 0;
52240Sstevel@tonic-gate 	int i, length;
52250Sstevel@tonic-gate 
52260Sstevel@tonic-gate 	length = strlen(object);
52270Sstevel@tonic-gate 	for (i = 0; i < length; i++) {
52280Sstevel@tonic-gate 		if ((object[i] > 47) && (object[i] < 58)) {
52290Sstevel@tonic-gate 			key = key + ((object[i] - 50) + 2);
52300Sstevel@tonic-gate 		} else {
52310Sstevel@tonic-gate 			key = key + object[i];
52320Sstevel@tonic-gate 		}
52330Sstevel@tonic-gate 	}
52340Sstevel@tonic-gate 
52350Sstevel@tonic-gate 
52360Sstevel@tonic-gate 	return (key);
52370Sstevel@tonic-gate }
5238