8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / picl / plugins / sun4u / psvc / psvcobj / psvcobj.c
blob5a6c88c6919246bbda2f109cdc63a2b6091bbc7d
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * This file consists of routines to manage objects in the
31 * "Platform Environment Services Framework". The classes
32 * and subclasses are defined by attributes and methods.
33 * The objects, and their initial, static, attribute values are
34 * specified in a configuration file, "psvcobj.conf".
35 * psvc_init() reads the configuration file and creates a repository
36 * of environmental objects in memory. A client application may manipulate
37 * these objects by invoking the psvc_get_attr(), and psvc_set_attr()
38 * routines with the object's string ID specified as an argument.
40 #include <stdio.h>
41 #include <math.h>
42 #include <stdlib.h>
43 #include <unistd.h>
44 #include <stropts.h>
45 #include <string.h>
46 #include <errno.h>
47 #include <fcntl.h>
48 #include <pthread.h>
49 #include <syslog.h>
50 #include <stdarg.h>
51 #include <pthread.h>
52 #include <sys/systeminfo.h>
54 #define LIBRARY_BUILD 1
55 #include <psvc_objects.h>
56 #include <psvc_objects_class.h>
57 #include <sys/i2c/clients/i2c_client.h>
59 /* Mutex used for Daktari Fan speed reading */
60 pthread_mutex_t fan_mutex = PTHREAD_MUTEX_INITIALIZER;
62 /*LINTLIBRARY*/
64 #define ENV_DEBUG(str, id) printf("%s id %s\n", (str), (id))
66 #define BUFSZ 512
68 #define CLASS_MAX 12
69 #define SUBCLASS_MAX 10
71 static int32_t i_psvc_constructor_0_0(EHdl_t *, char *, EObj_t **);
72 static int32_t i_psvc_constructor_0_1(EHdl_t *, char *, EObj_t **);
73 static int32_t i_psvc_constructor_1_0(EHdl_t *, char *, EObj_t **);
74 static int32_t i_psvc_constructor_2_0(EHdl_t *, char *, EObj_t **);
75 static int32_t i_psvc_constructor_2_1(EHdl_t *, char *, EObj_t **);
76 static int32_t i_psvc_constructor_2_2(EHdl_t *, char *, EObj_t **);
77 static int32_t i_psvc_constructor_3_0(EHdl_t *, char *, EObj_t **);
78 static int32_t i_psvc_constructor_4_0(EHdl_t *, char *, EObj_t **);
79 static int32_t i_psvc_constructor_5_0(EHdl_t *, char *, EObj_t **);
80 static int32_t i_psvc_constructor_6_0(EHdl_t *, char *, EObj_t **);
81 static int32_t i_psvc_constructor_7_0(EHdl_t *, char *, EObj_t **);
82 static int32_t i_psvc_constructor_8_0(EHdl_t *, char *, EObj_t **);
83 static int32_t i_psvc_constructor_9_0(EHdl_t *, char *, EObj_t **);
84 static int32_t i_psvc_constructor_10_0(EHdl_t *, char *, EObj_t **);
85 static int32_t i_psvc_constructor_10_1(EHdl_t *, char *, EObj_t **);
86 static int32_t i_psvc_constructor_11_0(EHdl_t *, char *, EObj_t **);
87 static int32_t i_psvc_constructor_11_1(EHdl_t *, char *, EObj_t **);
88 static int32_t i_psvc_constructor_11_2(EHdl_t *, char *, EObj_t **);
89 static int32_t i_psvc_constructor_11_3(EHdl_t *, char *, EObj_t **);
90 static int32_t i_psvc_constructor_11_4(EHdl_t *, char *, EObj_t **);
91 static int32_t i_psvc_constructor_11_5(EHdl_t *, char *, EObj_t **);
92 static int32_t i_psvc_constructor_11_6(EHdl_t *, char *, EObj_t **);
93 static int32_t i_psvc_constructor_11_7(EHdl_t *, char *, EObj_t **);
94 static int32_t i_psvc_constructor_11_8(EHdl_t *, char *, EObj_t **);
95 static int32_t i_psvc_constructor_11_9(EHdl_t *, char *, EObj_t **);
97 static int32_t i_psvc_get_obj(EHdl_t *, char *, EObj_t **);
98 static int32_t i_psvc_destructor(EHdl_t *, char *, void *);
99 static int32_t i_psvc_get_devpath(EHdl_t *, uint64_t, char *);
100 static int32_t i_psvc_get_attr_generic(EHdl_t *, EObj_t *, int32_t, void *);
101 static int32_t i_psvc_get_attr_6_0(EHdl_t *, EObj_t *, int32_t, void *);
102 static int32_t i_psvc_get_reg_11_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id,
103 void *attrp);
104 static int32_t i_psvc_get_attr_10_1(EHdl_t *, EObj_t *, int32_t, void *);
105 static int32_t psvc_get_str_key(char *object);
107 int32_t ioctl_retry(int fp, int request, void * arg_pointer);
110 * Method lookup tables
111 * Update when adding classes or subclasses.
115 /* Lookup method by class, subclass, used when calling method */
116 static int32_t (*i_psvc_constructor[CLASS_MAX][SUBCLASS_MAX])(EHdl_t *,
117 char *, EObj_t **) = {
118 {i_psvc_constructor_0_0, i_psvc_constructor_0_1, 0, 0, 0, 0, 0, 0, 0, 0},
119 {i_psvc_constructor_1_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
120 {i_psvc_constructor_2_0, i_psvc_constructor_2_1, i_psvc_constructor_2_2,
121 0, 0, 0, 0, 0, 0, 0},
122 {i_psvc_constructor_3_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
123 {i_psvc_constructor_4_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
124 {i_psvc_constructor_5_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
125 {i_psvc_constructor_6_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
126 {i_psvc_constructor_7_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
127 {i_psvc_constructor_8_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
128 {i_psvc_constructor_9_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
129 {i_psvc_constructor_10_0, i_psvc_constructor_10_1, 0, 0, 0, 0, 0, 0, 0, 0},
130 {i_psvc_constructor_11_0, i_psvc_constructor_11_1, i_psvc_constructor_11_2,
131 i_psvc_constructor_11_3, i_psvc_constructor_11_4,
132 i_psvc_constructor_11_5, i_psvc_constructor_11_6,
133 i_psvc_constructor_11_7, i_psvc_constructor_11_8,
134 i_psvc_constructor_11_9},
137 static int32_t i_psvc_cell_size[8] = {1, 1, 2, 2, 4, 4, 8, 8};
139 static struct bits {
140 uint64_t bit;
141 char *label;
142 } feature_bits[] = {
143 {PSVC_DEV_PERM, "PERM="},
144 {PSVC_DEV_HOTPLUG, "HOTPLUG="},
145 {PSVC_DEV_OPTION, "OPTION="},
146 {PSVC_DEV_PRIMARY, "PRIMARY="},
147 {PSVC_DEV_SECONDARY, "SECONDARY="},
148 {PSVC_DEV_RDONLY, "RDONLY="},
149 {PSVC_DEV_RDWR, "RDWR="},
150 {PSVC_DEV_FRU, "FRU="},
151 {PSVC_LOW_WARN, "LO_WARN_MASK="},
152 {PSVC_LOW_SHUT, "LO_SHUT_MASK="},
153 {PSVC_HIGH_WARN, "HI_WARN_MASK="},
154 {PSVC_HIGH_SHUT, "HI_SHUT_MASK="},
155 {PSVC_CONVERSION_TABLE, "CONV_TABLE="},
156 {PSVC_OPT_TEMP, "OPT_TEMP_MASK="},
157 {PSVC_HW_LOW_SHUT, "HW_LO_MASK="},
158 {PSVC_HW_HIGH_SHUT, "HW_HI_MASK="},
159 {PSVC_FAN_DRIVE_PR, "FAN_DRIVE_PR="},
160 {PSVC_TEMP_DRIVEN, "TEMP_DRIVEN="},
161 {PSVC_SPEED_CTRL_PR, "SPEED_CTRL_PR="},
162 {PSVC_FAN_ON_OFF, "FAN_ON_OFF="},
163 {PSVC_CLOSED_LOOP_CTRL, "CLOSED_LOOP_CTRL="},
164 {PSVC_FAN_DRIVE_TABLE_PR, "FAN_DRIVE_TABLE_PR="},
165 {PSVC_DIE_TEMP, "DIE_TEMP="},
166 {PSVC_AMB_TEMP, "AMB_TEMP="},
167 {PSVC_DIGI_SENSOR, "DIGI_SENSOR="},
168 {PSVC_BI_STATE, "BI_STATE="},
169 {PSVC_TRI_STATE, "TRI_STATE="},
170 {PSVC_GREEN, "GREEN="},
171 {PSVC_AMBER, "AMBER="},
172 {PSVC_OUTPUT, "OUTPUT="},
173 {PSVC_INPUT, "INPUT="},
174 {PSVC_BIDIR, "BIDIR="},
175 {PSVC_BIT_POS, "BIT_POS="},
176 {PSVC_VAL_POS, "VAL_POS="},
177 {PSVC_NORMAL_POS_AV, "NORMAL_POS_AV="},
178 {PSVC_DIAG_POS_AV, "DIAG_POS_AV="},
179 {PSVC_LOCK_POS_AV, "LOCK_POS_AV="},
180 {PSVC_OFF_POS_AV, "OFF_POS_AV="},
181 {PSVC_GPIO_PORT, "GPIO_PORT="},
182 {PSVC_GPIO_REG, "GPIO_REG="}
185 #define ASSOC_STR_TAB_SIZE 33
186 static char *assoc_str_tab[] = {
187 "PSVC_PRESENCE_SENSOR", /* 0 */
188 "PSVC_FAN_ONOFF_SENSOR", /* 1 */
189 "PSVC_FAN_SPEED_TACHOMETER", /* 2 */
190 "PSVC_FAN_PRIM_SEC_SELECTOR", /* 3 */
191 "PSVC_DEV_TEMP_SENSOR", /* 4 */
192 "PSVC_FAN_DRIVE_CONTROL", /* 5 */
193 "PSVC_KS_NORMAL_POS_SENSOR", /* 6 */
194 "PSVC_KS_DIAG_POS_SENSOR", /* 7 */
195 "PSVC_KS_LOCK_POS_SENSOR", /* 8 */
196 "PSVC_KS_OFF_POS_SENSOR", /* 9 */
197 "PSVC_SLOT_FAULT_LED", /* 10 */
198 "PSVC_SLOT_REMOVE_LED", /* 11 */
199 "PSVC_TS_OVERTEMP_LED", /* 12 */
200 "PSVC_PS_I_SENSOR", /* 13 */
201 "PSVC_DEV_FAULT_SENSOR", /* 14 */
202 "PSVC_DEV_FAULT_LED", /* 15 */
203 "PSVC_TABLE", /* 16 */
204 "PSVC_PARENT", /* 17 */
205 "PSVC_CPU", /* 18 */
206 "PSVC_ALTERNATE", /* 19 */
207 "PSVC_HOTPLUG_ENABLE_SWITCH", /* 20 */
208 "PSVC_PS", /* 21 */
209 "PSVC_FAN", /* 22 */
210 "PSVC_TS", /* 23 */
211 "PSVC_DISK", /* 24 */
212 "PSVC_LED", /* 25 */
213 "PSVC_FSP_LED", /* 26 */
214 "PSVC_KEYSWITCH", /* 27 */
215 "PSVC_PCI_CARD", /* 28 */
216 "PSVC_PHYSICAL_DEVICE", /* 29 */
217 "PSVC_DEV_TYPE_SENSOR", /* 30 */
218 "PSVC_FAN_TRAY_FANS", /* 31 */
219 "PSVC_FRU" /* 32 */
222 #define FEATURE_BITS (sizeof (feature_bits) / sizeof (struct bits))
224 static struct bitfield {
225 int8_t shift;
226 char *label;
227 char *format;
228 } addr_fields[] =
230 {PSVC_VERSION_SHIFT, "VERSION=", "%d"},
231 {PSVC_ACTIVE_LOW_SHIFT, "ACTIVE_LOW=", "%d"},
232 {PSVC_BIT_NUM_SHIFT, "BIT_NUM=", "%d"},
233 {PSVC_INVERT_SHIFT, "INVERT=", "%d"},
234 {PSVC_PORT_SHIFT, "PORT=", "%d"},
235 {PSVC_BITSHIFT_SHIFT, "BITSHIFT=", "%d"},
236 {PSVC_BYTEMASK_SHIFT, "BYTEMASK=", "%x"},
237 {PSVC_REG_SHIFT, "REG=", "%d"},
238 {PSVC_TYPE_SHIFT, "TYPE=", "%d"},
239 {PSVC_BUSADDR_SHIFT, "BUSADDR=", "%x"},
240 {PSVC_BUSNUM_SHIFT, "BUSNUM=", "%d"},
241 {PSVC_CNTLR_SHIFT, "CNTLR=", "%d"},
243 #define ADDR_BITFIELDS (sizeof (addr_fields) / sizeof (struct bitfield))
246 * record format is:
247 * pathname label1=val1,label2=val2,label3=val3
248 * Must be a space after the pathname and a comma between variables.
251 static char *
252 find_label(char *str, char *label)
254 char *start;
256 start = strchr(str, ' ');
257 if (start == NULL)
258 return (start);
260 do {
261 ++start;
262 if (strncmp(start, label, strlen(label)) == 0)
263 return (start);
265 start = strchr(start, ',');
266 } while (start != NULL);
268 return (NULL);
271 static int32_t
272 i_psvc_value(char *buf, int32_t attr_id, void *attrp)
274 char *val;
275 uint32_t temp32;
276 uint64_t temp64;
277 uint64_t result;
278 int32_t i;
279 int32_t found;
280 char label[64];
281 int val_size;
282 int label_size;
285 switch (attr_id) {
286 case PSVC_CLASS_ATTR:
287 case PSVC_SUBCLASS_ATTR:
288 case PSVC_INSTANCE_ATTR:
289 case PSVC_LO_WARN_ATTR:
290 case PSVC_LO_SHUT_ATTR:
291 case PSVC_HI_WARN_ATTR:
292 case PSVC_HI_SHUT_ATTR:
293 case PSVC_HW_HI_SHUT_ATTR:
294 case PSVC_HW_LO_SHUT_ATTR:
295 case PSVC_OPTIMAL_TEMP_ATTR:
296 snprintf(label, sizeof (label), "%s=", attr_str_tab[attr_id]);
297 val = find_label(buf, label);
298 if (val == NULL) {
299 errno = EINVAL;
300 return (PSVC_FAILURE);
302 found = sscanf(val + strlen(label),
303 "%d", (int32_t *)attrp);
304 if (found == 0)
305 *(int32_t *)attrp = 0;
306 break;
307 case PSVC_SETPOINT_ATTR:
308 case PSVC_HYSTERESIS_ATTR:
309 case PSVC_LOOPGAIN_ATTR:
310 case PSVC_LOOPBIAS_ATTR:
311 snprintf(label, sizeof (label), "%s=", attr_str_tab[attr_id]);
312 val = find_label(buf, label);
313 if (val == NULL) {
314 errno = EINVAL;
315 return (PSVC_FAILURE);
318 found = sscanf(val + strlen(label), "%hd", (int16_t *)attrp);
319 if (found == 0)
320 *(int16_t *)attrp = 0;
321 break;
322 case PSVC_LED_COLOR_ATTR:
323 case PSVC_LED_IS_LOCATOR_ATTR:
324 case PSVC_LED_LOCATOR_NAME_ATTR:
325 snprintf(label, sizeof (label), "%s=", attr_str_tab[attr_id]);
326 val = find_label(buf, label);
327 if (val == NULL) {
328 errno = EINVAL;
329 return (PSVC_FAILURE);
331 val_size = strlen(val);
332 label_size = strlen(label);
334 for (i = 0; i < val_size && val[i] != ','; i++);
335 if (i < strlen(val) - 1) {
336 strncpy((char *)attrp, val+label_size,
337 i - label_size);
338 } else
339 found = sscanf(val + label_size, "%s", (char *)attrp);
340 if (found == 0)
341 strcpy((char *)attrp, "");
342 break;
343 case PSVC_FEATURES_ATTR:
344 result = 0;
345 for (i = 0; i < FEATURE_BITS; ++i) {
346 val = find_label(buf, feature_bits[i].label);
347 if (val == NULL)
348 continue;
349 found = sscanf(val + strlen(feature_bits[i].label),
350 "%d", &temp32);
351 if (found != 0) {
352 if (temp32 == 1)
353 result |= feature_bits[i].bit;
356 *(uint64_t *)attrp = result;
357 break;
358 case PSVC_ADDR_SPEC_ATTR:
359 result = 0;
360 for (i = 0; i < ADDR_BITFIELDS; ++i) {
361 val = find_label(buf, addr_fields[i].label);
362 if (val == NULL)
363 continue;
364 found = sscanf(val + strlen(addr_fields[i].label),
365 addr_fields[i].format, &temp32);
366 if (found != 0) {
367 temp64 = temp32;
368 temp64 <<= addr_fields[i].shift;
369 result |= temp64;
372 *(uint64_t *)attrp = result;
373 break;
374 default:
375 errno = EINVAL;
376 return (PSVC_FAILURE);
378 return (PSVC_SUCCESS);
381 /* determine number of records in file section */
382 static int32_t
383 i_psvc_count_records(FILE *fp, char *end, uint32_t *countp)
385 long first_record;
386 char *ret;
387 char buf[BUFSZ];
388 uint32_t count = 0;
390 first_record = ftell(fp);
392 while ((ret = fgets(buf, BUFSZ, fp)) != NULL) {
393 if (strncmp(end, buf, strlen(end)) == 0)
394 break;
395 ++count;
398 if (ret == NULL) {
399 errno = EINVAL;
400 return (PSVC_FAILURE);
403 fseek(fp, first_record, SEEK_SET);
404 *countp = count;
405 return (PSVC_SUCCESS);
408 /* determine number of records in file section */
409 static int32_t
410 i_psvc_count_tables_associations(FILE *fp, uint32_t *countp, char *end)
412 long first_record;
413 char *ret;
414 char buf[BUFSZ];
415 uint32_t count = 0;
417 first_record = ftell(fp);
419 while ((ret = fgets(buf, BUFSZ, fp)) != NULL) {
420 if (strncmp(end, buf, strlen(end)) == 0)
421 ++count;
423 #ifdef lint
424 ret = ret;
425 #endif
427 fseek(fp, first_record, SEEK_SET);
428 *countp = count;
429 return (PSVC_SUCCESS);
432 /* determine number of records in a table */
433 static int32_t
434 i_psvc_count_table_records(FILE *fp, char *end, uint32_t *countp)
436 long first_record;
437 int ret;
438 char string[BUFSZ];
439 uint32_t count = 0;
441 first_record = ftell(fp);
443 while ((ret = fscanf(fp, "%s", string)) == 1) {
444 if (strncmp(end, string, strlen(end)) == 0)
445 break;
446 ++count;
449 if (ret != 1) {
450 errno = EINVAL;
451 return (PSVC_FAILURE);
454 fseek(fp, first_record, SEEK_SET);
455 *countp = count;
456 return (PSVC_SUCCESS);
460 * Find number of matches to an antecedent_id of a certain
461 * association type.
463 static int32_t
464 i_psvc_get_assoc_matches(EHdl_t *hdlp, char *antecedent, int32_t assoc_id,
465 int32_t *matches)
467 int i;
468 int32_t key;
469 EAssocList_t *ap = hdlp->assoc_tbl + assoc_id;
471 *matches = 0;
473 if (ap->table == 0) {
474 errno = EINVAL;
475 return (PSVC_FAILURE);
478 key = psvc_get_str_key(antecedent);
480 for (i = 0; i < ap->count; ++i) {
481 if (ap->table[i].ant_key == key) {
482 if (strcmp(ap->table[i].antecedent_id, antecedent)
483 == 0)
484 ++*matches;
487 return (PSVC_SUCCESS);
491 * Find 1st m matches to an antecedent_id of a certain
492 * association type.
493 * Returns zero for success, -1 for failure.
495 static int32_t
496 i_psvc_get_assoc_id(EHdl_t *hdlp, char *antecedent, int32_t assoc_id,
497 int32_t match, char **id_list)
499 int i;
500 int found = 0;
501 int32_t key;
502 EAssocList_t *ap = &hdlp->assoc_tbl[assoc_id];
504 if (ap->table == 0) {
505 errno = EINVAL;
506 return (-1);
509 key = psvc_get_str_key(antecedent);
511 for (i = 0; i < ap->count; ++i) {
512 if (ap->table[i].ant_key == key) {
513 if (strcmp(ap->table[i].antecedent_id, antecedent)
514 == 0) {
515 if (found == match) {
516 *id_list = ap->table[i].dependent_id;
517 return (0);
519 ++found;
524 errno = EINVAL;
525 return (-1);
528 static int32_t
529 i_psvc_get_table_value(EHdl_t *hdlp, char *table_id, uint32_t index,
530 void *value)
532 int32_t i;
533 ETable_t *tblp;
534 ETable_Array *tbl_arr;
535 int32_t key, array;
537 key = psvc_get_str_key(table_id);
538 array = key % PSVC_MAX_TABLE_ARRAYS;
539 tbl_arr = &(hdlp->tbl_arry[array]);
541 for (i = 0; i < tbl_arr->obj_count; ++i) {
542 if (key == tbl_arr->obj_tbl[i].key) {
543 if (strcmp(tbl_arr->obj_tbl[i].name,
544 table_id) == 0)
545 break;
549 if (tbl_arr->obj_tbl[i].type != PSVC_TBL)
550 return (PSVC_FAILURE);
552 tblp = (ETable_t *)tbl_arr->obj_tbl[i].objp;
554 if (tblp->table == NULL)
555 return (PSVC_FAILURE);
557 if (index >= tblp->size)
558 return (PSVC_FAILURE);
560 switch (tblp->cell_type) {
561 case 0:
562 *(int8_t *)value = *((int8_t *)tblp->table + index);
563 break;
564 case 1:
565 *(uint8_t *)value = *((uint8_t *)tblp->table + index);
566 break;
567 case 2:
568 *(int16_t *)value = *((int16_t *)tblp->table + index);
569 break;
570 case 3:
571 *(uint16_t *)value = *((uint16_t *)tblp->table + index);
572 break;
573 case 4:
574 *(int32_t *)value = *((int32_t *)tblp->table + index);
575 break;
576 case 5:
577 *(uint32_t *)value = *((uint32_t *)tblp->table + index);
578 break;
579 case 6:
580 *(int64_t *)value = *((int64_t *)tblp->table + index);
581 break;
582 case 7:
583 *(uint64_t *)value = *((uint64_t *)tblp->table + index);
584 break;
585 default:
586 return (PSVC_FAILURE);
589 return (PSVC_SUCCESS);
592 int32_t
593 psvc_get_attr(EHdl_t *hdlp, char *name, int32_t attr_id, void *attr_valuep, ...)
595 EObj_t *objp;
596 int32_t status = PSVC_SUCCESS;
597 int32_t arg1, arg2;
598 va_list ap;
600 pthread_mutex_lock(&hdlp->mutex);
602 if (attr_valuep == NULL) {
603 errno = EFAULT;
604 pthread_mutex_unlock(&hdlp->mutex);
605 return (PSVC_FAILURE);
608 switch (attr_id) {
609 case PSVC_TABLE_VALUE_ATTR:
610 va_start(ap, attr_valuep);
611 status = i_psvc_get_table_value(hdlp, name,
612 va_arg(ap, uint32_t), attr_valuep);
613 va_end(ap);
614 break;
615 case PSVC_ASSOC_MATCHES_ATTR:
616 va_start(ap, attr_valuep);
617 status = i_psvc_get_assoc_matches(hdlp, name,
618 va_arg(ap, int32_t), attr_valuep);
619 va_end(ap);
620 break;
621 case PSVC_ASSOC_ID_ATTR:
622 va_start(ap, attr_valuep);
623 arg1 = va_arg(ap, int32_t);
624 arg2 = va_arg(ap, int32_t);
625 status = i_psvc_get_assoc_id(hdlp, name,
626 arg1, arg2, attr_valuep);
627 va_end(ap);
628 break;
629 default:
630 status = i_psvc_get_obj(hdlp, name, &objp);
631 if (status != PSVC_SUCCESS) {
632 pthread_mutex_unlock(&hdlp->mutex);
633 return (status);
635 status = (*objp->get_attr)(hdlp, objp, attr_id,
636 attr_valuep);
639 if (status != PSVC_SUCCESS) {
640 pthread_mutex_unlock(&hdlp->mutex);
641 return (status);
644 pthread_mutex_unlock(&hdlp->mutex);
645 return (status);
648 int32_t
649 psvc_set_attr(EHdl_t *hdlp, char *name, int32_t attr_id, void *attr_valuep)
651 EObj_t *objp;
652 int32_t status = PSVC_SUCCESS;
654 pthread_mutex_lock(&hdlp->mutex);
655 status = i_psvc_get_obj(hdlp, name, &objp);
656 if (status != PSVC_SUCCESS) {
657 pthread_mutex_unlock(&hdlp->mutex);
658 return (status);
661 if (attr_valuep == NULL) {
662 errno = EFAULT;
663 pthread_mutex_unlock(&hdlp->mutex);
664 return (PSVC_FAILURE);
667 status = (*objp->set_attr)(hdlp, objp, attr_id, attr_valuep);
668 if (status != PSVC_SUCCESS) {
669 pthread_mutex_unlock(&hdlp->mutex);
670 return (status);
673 pthread_mutex_unlock(&hdlp->mutex);
674 return (status);
678 static int32_t
679 i_psvc_get_presence(EHdl_t *hdlp, EObj_t *objp, boolean_t *pr)
681 EObj_t *pobjp, *mobjp;
682 int32_t matches;
683 char *mid;
684 char *parent_id;
685 int32_t status = PSVC_SUCCESS;
686 uint8_t value_8bit, value_8bit_inv;
687 boolean_t active_low, value;
689 if (strcmp(objp->label, PSVC_CHASSIS) == 0) {
690 *pr = PSVC_PRESENT;
691 objp->present = PSVC_PRESENT;
692 return (PSVC_SUCCESS);
695 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PARENT, 0,
696 &parent_id);
697 if (status != PSVC_SUCCESS)
698 return (status);
700 if (strcmp(parent_id, PSVC_CHASSIS)) {
701 status = i_psvc_get_obj(hdlp, parent_id, &pobjp);
702 if (status != PSVC_SUCCESS)
703 return (status);
704 if (!pobjp->present) {
705 pobjp->get_attr(hdlp, pobjp, PSVC_PRESENCE_ATTR, pr);
706 *pr = pobjp->present;
707 objp->present = pobjp->present;
708 return (status);
712 (void) i_psvc_get_assoc_matches(hdlp, objp->label,
713 PSVC_PRESENCE_SENSOR, &matches);
715 if (matches != 0) {
716 status = i_psvc_get_assoc_id(hdlp, objp->label,
717 PSVC_PRESENCE_SENSOR, 0, &mid);
718 if (status != PSVC_SUCCESS)
719 return (status);
720 status = i_psvc_get_obj(hdlp, mid, &mobjp);
721 if (status != PSVC_SUCCESS)
722 return (status);
724 active_low = PSVC_IS_ACTIVE_LOW(mobjp->addr_spec);
726 if (mobjp->class == PSVC_BOOLEAN_GPIO_CLASS) {
727 status = mobjp->get_attr(hdlp, mobjp,
728 PSVC_GPIO_VALUE_ATTR, &value);
729 if (status != PSVC_SUCCESS)
730 return (status);
731 if (active_low)
732 if (value == 0)
733 *pr = PSVC_PRESENT;
734 else
735 *pr = PSVC_ABSENT;
736 else
737 if (value == 0)
738 *pr = PSVC_ABSENT;
739 else
740 *pr = PSVC_PRESENT;
741 } else if (mobjp->class == PSVC_8BIT_GPIO_CLASS) {
742 uint8_t bitshift, bytemask;
744 status = mobjp->get_attr(hdlp, mobjp,
745 PSVC_GPIO_VALUE_ATTR, &value_8bit);
746 if (status != PSVC_SUCCESS)
747 return (status);
748 if (PSVC_HP_INVERT(mobjp->addr_spec))
749 value_8bit_inv = ~value_8bit;
750 else
751 value_8bit_inv = value_8bit;
752 bitshift = PSVC_GET_ASPEC_BITSHIFT(mobjp->addr_spec);
753 bytemask = PSVC_GET_ASPEC_BYTEMASK(mobjp->addr_spec);
754 value_8bit_inv =
755 value_8bit_inv & (bytemask >> bitshift);
756 if (active_low)
757 if (value_8bit_inv == 0)
758 *pr = PSVC_PRESENT;
759 else
760 *pr = PSVC_ABSENT;
761 else
762 if (value_8bit_inv == 0)
763 *pr = PSVC_ABSENT;
764 else
765 *pr = PSVC_PRESENT;
766 } else {
767 errno = EINVAL;
768 return (PSVC_FAILURE);
770 } else {
771 *pr = PSVC_PRESENT;
774 objp->present = *pr;
776 return (status);
779 static int32_t
780 i_psvc_get_device_value_0_0(EHdl_t *hdlp, EObj_t *objp, int32_t *temp)
782 int32_t status = PSVC_SUCCESS, m;
783 char *tid;
784 int16_t temp16;
785 char *physid;
786 EObj_t *physobjp;
788 if (objp->present != PSVC_PRESENT) {
789 errno = ENODEV;
790 return (PSVC_FAILURE);
793 status = i_psvc_get_assoc_id(
794 hdlp, objp->label, PSVC_PHYSICAL_DEVICE, 0, &physid);
795 if (status != PSVC_SUCCESS) {
796 return (status);
798 status = i_psvc_get_obj(hdlp, physid, &physobjp);
799 if (status != PSVC_SUCCESS) {
800 return (status);
803 status = ((EPhysDev_t *)physobjp)->get_temperature(hdlp,
804 objp->addr_spec, temp);
805 if (status != PSVC_SUCCESS) {
806 return (status);
809 if (objp->features & PSVC_CONVERSION_TABLE) {
810 status = i_psvc_get_assoc_matches(hdlp, objp->label,
811 PSVC_TABLE, &m);
812 if ((status != PSVC_SUCCESS) || (m != 1)) {
813 return (status);
816 (void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
817 &tid);
819 status = i_psvc_get_table_value(hdlp, tid, *temp, &temp16);
820 *temp = temp16;
822 return (status);
825 static int32_t
826 i_psvc_get_device_value_0_1(EHdl_t *hdlp, EObj_t *objp, int32_t *temp)
828 int32_t status = PSVC_SUCCESS, m;
829 char *tid;
830 int16_t temp16;
831 char *physid;
832 EObj_t *physobjp;
834 if (objp->present != PSVC_PRESENT) {
835 errno = ENODEV;
836 return (PSVC_FAILURE);
839 status = i_psvc_get_assoc_id(
840 hdlp, objp->label, PSVC_PHYSICAL_DEVICE, 0, &physid);
841 if (status != PSVC_SUCCESS) {
842 return (status);
844 status = i_psvc_get_obj(hdlp, physid, &physobjp);
845 if (status != PSVC_SUCCESS) {
846 return (status);
849 status = ((EPhysDev_t *)physobjp)->get_temperature(hdlp,
850 objp->addr_spec, temp);
851 if (status != PSVC_SUCCESS) {
852 return (status);
855 if (objp->features & PSVC_CONVERSION_TABLE) {
856 status = i_psvc_get_assoc_matches(hdlp, objp->label,
857 PSVC_TABLE, &m);
858 if ((status != PSVC_SUCCESS) || (m != 1)) {
859 return (status);
862 (void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
863 &tid);
865 status = i_psvc_get_table_value(hdlp, tid, *temp, &temp16);
866 *temp = temp16;
868 return (status);
871 static int32_t
872 i_psvc_get_device_value_4_0(EHdl_t *hdlp, EObj_t *objp, int32_t *value)
874 int32_t status = PSVC_SUCCESS;
875 char *physid;
876 EObj_t *physobjp;
878 if (objp->present != PSVC_PRESENT) {
879 errno = ENODEV;
880 return (PSVC_FAILURE);
883 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
884 0, &physid);
885 if (status != PSVC_SUCCESS)
886 return (status);
887 status = i_psvc_get_obj(hdlp, physid, &physobjp);
888 if (status != PSVC_SUCCESS)
889 return (status);
891 status = ((EPhysDev_t *)physobjp)->get_input(hdlp, objp->addr_spec,
892 value);
893 if (status != PSVC_SUCCESS)
894 return (status);
896 if (objp->features & PSVC_CONVERSION_TABLE) {
897 int32_t m;
898 char *tid;
899 int16_t temp16;
901 status = i_psvc_get_assoc_matches(hdlp, objp->label,
902 PSVC_TABLE, &m);
903 if ((status != PSVC_SUCCESS) || (m != 1)) {
904 return (status);
907 (void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
908 &tid);
910 status = i_psvc_get_table_value(hdlp, tid, *value, &temp16);
911 *value = temp16;
914 return (status);
917 static int32_t
918 i_psvc_set_device_value_5_0(EHdl_t *hdlp, EObj_t *objp, int32_t *value)
920 int32_t status = PSVC_SUCCESS;
921 char *physid;
922 EObj_t *physobjp;
924 if (objp->present != PSVC_PRESENT) {
925 errno = ENODEV;
926 return (PSVC_FAILURE);
929 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
930 0, &physid);
931 if (status != PSVC_SUCCESS)
932 return (status);
933 status = i_psvc_get_obj(hdlp, physid, &physobjp);
934 if (status != PSVC_SUCCESS)
935 return (status);
936 status = ((EPhysDev_t *)physobjp)->set_output(hdlp, objp->addr_spec,
937 *value);
938 if (status != PSVC_SUCCESS)
939 return (status);
941 return (status);
944 static int32_t
945 i_psvc_get_device_value_5_0(EHdl_t *hdlp, EObj_t *objp, int32_t *value)
947 int32_t status = PSVC_SUCCESS;
948 char *physid;
949 EObj_t *physobjp;
951 if (objp->present != PSVC_PRESENT) {
952 errno = ENODEV;
953 return (PSVC_FAILURE);
956 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
957 0, &physid);
958 if (status != PSVC_SUCCESS)
959 return (status);
960 status = i_psvc_get_obj(hdlp, physid, &physobjp);
961 if (status != PSVC_SUCCESS)
962 return (status);
964 status = ((EPhysDev_t *)physobjp)->get_output(hdlp, objp->addr_spec,
965 value);
966 if (status != PSVC_SUCCESS)
967 return (status);
969 if (objp->features & PSVC_CONVERSION_TABLE) {
970 int32_t m;
971 char *tid;
972 int16_t temp16;
974 status = i_psvc_get_assoc_matches(hdlp, objp->label,
975 PSVC_TABLE, &m);
976 if ((status != PSVC_SUCCESS) || (m != 1)) {
977 return (status);
980 (void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
981 &tid);
983 status = i_psvc_get_table_value(hdlp, tid, *value, &temp16);
984 *value = temp16;
986 return (status);
989 static int32_t
990 i_psvc_get_device_value_6_0(EHdl_t *hdlp, EObj_t *objp, boolean_t *value)
992 int32_t status = PSVC_SUCCESS;
993 int32_t bit_value;
994 char *physid;
995 EObj_t *physobjp;
997 if (objp->present != PSVC_PRESENT) {
998 errno = ENODEV;
999 return (PSVC_FAILURE);
1002 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1003 0, &physid);
1004 if (status != PSVC_SUCCESS)
1005 return (status);
1006 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1007 if (status != PSVC_SUCCESS)
1008 return (status);
1010 status = ((EPhysDev_t *)physobjp)->get_bit(hdlp, objp->addr_spec,
1011 &bit_value);
1012 if (status != PSVC_SUCCESS)
1013 return (status);
1015 *value = bit_value;
1017 return (status);
1020 static int32_t
1021 i_psvc_set_device_value_6_0(EHdl_t *hdlp, EObj_t *objp, boolean_t *value)
1023 int32_t status = PSVC_SUCCESS;
1024 int32_t bit_value;
1025 char *physid;
1026 EObj_t *physobjp;
1028 if (objp->present != PSVC_PRESENT) {
1029 errno = ENODEV;
1030 return (PSVC_FAILURE);
1033 bit_value = *value;
1034 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1035 0, &physid);
1036 if (status != PSVC_SUCCESS)
1037 return (status);
1038 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1039 if (status != PSVC_SUCCESS)
1040 return (status);
1042 status = ((EPhysDev_t *)physobjp)->set_bit(hdlp, objp->addr_spec,
1043 bit_value);
1044 if (status != PSVC_SUCCESS)
1045 return (status);
1047 return (status);
1050 static int32_t
1051 i_psvc_get_device_value_1_0(EHdl_t *hdlp, EObj_t *objp, int32_t *fan_speed)
1053 int32_t status = PSVC_SUCCESS;
1054 EObj_t *ftobjp;
1055 char *fan_tach;
1057 if (objp->present != PSVC_PRESENT) {
1058 errno = ENODEV;
1059 return (PSVC_FAILURE);
1062 status = i_psvc_get_assoc_id(hdlp, objp->label,
1063 PSVC_FAN_SPEED_TACHOMETER, 0, &fan_tach);
1064 if (status != PSVC_SUCCESS)
1065 return (status);
1067 status = i_psvc_get_obj(hdlp, fan_tach, &ftobjp);
1068 if (status != PSVC_SUCCESS)
1069 return (status);
1071 status = ftobjp->get_attr(hdlp, ftobjp, PSVC_SENSOR_VALUE_ATTR,
1072 fan_speed);
1073 if (status != PSVC_SUCCESS)
1074 return (status);
1076 return (status);
1079 static int32_t
1080 i_psvc_get_device_value_7_0(EHdl_t *hdlp, EObj_t *objp, int32_t *fan_speed)
1082 char *physid;
1083 EObj_t *physobjp;
1084 int32_t status = PSVC_SUCCESS;
1086 if (objp->present != PSVC_PRESENT) {
1087 errno = ENODEV;
1088 return (PSVC_FAILURE);
1091 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1092 0, &physid);
1093 if (status != PSVC_SUCCESS)
1094 return (status);
1095 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1096 if (status != PSVC_SUCCESS)
1097 return (status);
1099 status = ((EPhysDev_t *)physobjp)->get_fanspeed(hdlp, objp->addr_spec,
1100 fan_speed);
1101 if (status != PSVC_SUCCESS)
1102 return (status);
1104 if (objp->features & PSVC_CONVERSION_TABLE) {
1105 int32_t m;
1106 char *tid;
1107 int16_t temp16;
1109 status = i_psvc_get_assoc_matches(hdlp, objp->label,
1110 PSVC_TABLE, &m);
1111 if ((status != PSVC_SUCCESS) || (m != 1)) {
1112 return (status);
1115 (void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
1116 &tid);
1118 status = i_psvc_get_table_value(hdlp, tid, *fan_speed, &temp16);
1119 *fan_speed = temp16;
1121 return (status);
1124 static int32_t
1125 i_psvc_get_device_state_2_0(EHdl_t *hdlp, EObj_t *objp, char *led_state)
1127 int32_t status = PSVC_SUCCESS;
1128 int32_t bit_value;
1129 boolean_t active_low;
1130 char *physid;
1131 EObj_t *physobjp;
1133 if (objp->present != PSVC_PRESENT) {
1134 errno = ENODEV;
1135 return (PSVC_FAILURE);
1138 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1139 0, &physid);
1140 if (status != PSVC_SUCCESS)
1141 return (status);
1142 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1143 if (status != PSVC_SUCCESS)
1144 return (status);
1146 status = ((EPhysDev_t *)physobjp)->get_bit(hdlp, objp->addr_spec,
1147 &bit_value);
1148 if (status != PSVC_SUCCESS)
1149 return (status);
1151 active_low = PSVC_IS_ACTIVE_LOW(objp->addr_spec);
1152 if (active_low)
1153 if (bit_value == 0)
1154 strcpy(led_state, PSVC_LED_ON);
1155 else
1156 strcpy(led_state, PSVC_LED_OFF);
1157 else
1158 if (bit_value == 0)
1159 strcpy(led_state, PSVC_LED_OFF);
1160 else
1161 strcpy(led_state, PSVC_LED_ON);
1163 return (status);
1166 static int32_t
1167 i_psvc_set_device_state_2_0(EHdl_t *hdlp, EObj_t *objp, char *led_state)
1169 int32_t status = PSVC_SUCCESS;
1170 boolean_t active_low;
1171 int32_t bit_value;
1172 char *physid;
1173 EObj_t *physobjp;
1175 if (objp->present != PSVC_PRESENT) {
1176 errno = ENODEV;
1177 return (PSVC_FAILURE);
1180 if (strcmp(((ELed_t *)objp)->is_locator, PSVC_LOCATOR_TRUE) != 0) {
1182 * For Locator LEDs we ignore lit_count. RSC may have
1183 * altered the LED state underneath us, So we should
1184 * always just do what the user asked instead of trying
1185 * to be smart.
1188 if (strcmp(led_state, PSVC_LED_ON) == 0)
1189 ((ELed_t *)objp)->lit_count++;
1190 else if (strcmp(led_state, PSVC_LED_OFF) == 0) {
1191 if (--((ELed_t *)objp)->lit_count > 0) {
1192 return (PSVC_SUCCESS);
1193 } else if (((ELed_t *)objp)->lit_count < 0)
1194 ((ELed_t *)objp)->lit_count = 0;
1195 /* Fall through case is when lit_count is 0 */
1199 strcpy(objp->previous_state, objp->state);
1200 strcpy(objp->state, led_state);
1202 bit_value = (strcmp(led_state, PSVC_LED_ON) == 0);
1205 * Flip the bit if necessary (for active_low devices,
1206 * O ==> ON; 1 ==> OFF.
1208 active_low = PSVC_IS_ACTIVE_LOW(objp->addr_spec);
1209 bit_value ^= active_low;
1211 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1212 0, &physid);
1213 if (status != PSVC_SUCCESS)
1214 return (status);
1215 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1216 if (status != PSVC_SUCCESS)
1217 return (status);
1219 status = ((EPhysDev_t *)physobjp)->set_bit(hdlp, objp->addr_spec,
1220 bit_value);
1221 return (status);
1224 static int32_t
1225 i_psvc_get_device_state_2_1(EHdl_t *hdlp, EObj_t *objp, char *led_state)
1227 int32_t status = PSVC_SUCCESS;
1228 uint8_t value;
1229 char *physid;
1230 EObj_t *physobjp;
1232 if (objp->present != PSVC_PRESENT) {
1233 errno = ENODEV;
1234 return (PSVC_FAILURE);
1237 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1238 0, &physid);
1239 if (status != PSVC_SUCCESS)
1240 return (status);
1241 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1242 if (status != PSVC_SUCCESS)
1243 return (status);
1245 status = ((EPhysDev_t *)physobjp)->get_reg(hdlp, objp->addr_spec,
1246 &value);
1247 if (status != PSVC_SUCCESS)
1248 return (status);
1250 switch (value) {
1251 case 0:
1252 strcpy(led_state, PSVC_LED_OFF);
1253 break;
1254 case 1:
1255 strcpy(led_state, PSVC_LED_SLOW_BLINK);
1256 break;
1257 case 2:
1258 strcpy(led_state, PSVC_LED_FAST_BLINK);
1259 break;
1260 case 3:
1261 strcpy(led_state, PSVC_LED_ON);
1262 break;
1265 return (status);
1268 static int32_t
1269 i_psvc_set_device_state_2_1(EHdl_t *hdlp, EObj_t *objp, char *led_state)
1271 int32_t status = PSVC_SUCCESS;
1272 uint8_t value;
1273 char *physid;
1274 EObj_t *physobjp;
1276 if (objp->present != PSVC_PRESENT) {
1277 errno = ENODEV;
1278 return (PSVC_FAILURE);
1281 if (strcmp(led_state, PSVC_LED_ON) == 0)
1282 ((ELed_t *)objp)->lit_count++;
1283 else if (strcmp(led_state, PSVC_LED_OFF) == 0) {
1284 if (--((ELed_t *)objp)->lit_count > 0) {
1285 return (PSVC_SUCCESS);
1286 } else if (((ELed_t *)objp)->lit_count < 0)
1287 ((ELed_t *)objp)->lit_count = 0;
1289 /* Fall through case is when lit_count is 0 */
1292 strcpy(objp->previous_state, objp->state);
1293 strcpy(objp->state, led_state);
1295 if (strcmp(led_state, PSVC_LED_OFF) == 0)
1296 value = 0;
1297 else if (strcmp(led_state, PSVC_LED_SLOW_BLINK) == 0)
1298 value = 1;
1299 else if (strcmp(led_state, PSVC_LED_FAST_BLINK) == 0)
1300 value = 2;
1301 else if (strcmp(led_state, PSVC_LED_ON) == 0)
1302 value = 3;
1304 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1305 0, &physid);
1306 if (status != PSVC_SUCCESS)
1307 return (status);
1308 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1309 if (status != PSVC_SUCCESS)
1310 return (status);
1312 status = ((EPhysDev_t *)physobjp)->set_reg(hdlp, objp->addr_spec,
1313 value);
1315 return (status);
1318 static int32_t
1319 i_psvc_get_device_state_9_0(EHdl_t *hdlp, EObj_t *objp, char *pos)
1321 int32_t status = PSVC_SUCCESS, matches;
1322 char *sensorid;
1323 EObj_t *sensorp;
1324 char state[32];
1326 if (objp->present != PSVC_PRESENT) {
1327 errno = ENODEV;
1328 return (PSVC_FAILURE);
1331 if (objp->features & PSVC_NORMAL_POS_AV) {
1332 (void) i_psvc_get_assoc_matches(hdlp, objp->label,
1333 PSVC_KS_NORMAL_POS_SENSOR, &matches);
1334 if (matches == 1) {
1335 status = i_psvc_get_assoc_id(hdlp, objp->label,
1336 PSVC_KS_NORMAL_POS_SENSOR, 0, &sensorid);
1337 if (status != PSVC_SUCCESS)
1338 return (status);
1340 status = i_psvc_get_obj(hdlp, sensorid, &sensorp);
1341 if (status != PSVC_SUCCESS)
1342 return (status);
1344 status = sensorp->get_attr(hdlp, sensorp,
1345 PSVC_SWITCH_STATE_ATTR, state);
1346 if (status != PSVC_SUCCESS)
1347 return (status);
1349 if (strcmp(state, PSVC_SWITCH_ON) == 0) {
1350 strcpy(pos, PSVC_NORMAL_POS);
1351 return (PSVC_SUCCESS);
1356 if (objp->features & PSVC_DIAG_POS_AV) {
1357 (void) i_psvc_get_assoc_matches(hdlp, objp->label,
1358 PSVC_KS_DIAG_POS_SENSOR, &matches);
1359 if (matches == 1) {
1360 status = i_psvc_get_assoc_id(hdlp, objp->label,
1361 PSVC_KS_DIAG_POS_SENSOR, 0, &sensorid);
1362 if (status != PSVC_SUCCESS)
1363 return (status);
1365 status = i_psvc_get_obj(hdlp, sensorid, &sensorp);
1366 if (status != PSVC_SUCCESS)
1367 return (status);
1369 status = sensorp->get_attr(hdlp, sensorp,
1370 PSVC_SWITCH_STATE_ATTR, state);
1371 if (status != PSVC_SUCCESS)
1372 return (status);
1374 if (strcmp(state, PSVC_SWITCH_ON) == 0) {
1375 strcpy(pos, PSVC_DIAG_POS);
1376 return (PSVC_SUCCESS);
1381 if (objp->features & PSVC_LOCK_POS_AV) {
1382 (void) i_psvc_get_assoc_matches(hdlp, objp->label,
1383 PSVC_KS_LOCK_POS_SENSOR, &matches);
1384 if (matches == 1) {
1385 status = i_psvc_get_assoc_id(hdlp, objp->label,
1386 PSVC_KS_LOCK_POS_SENSOR, 0, &sensorid);
1387 if (status != PSVC_SUCCESS)
1388 return (status);
1390 status = i_psvc_get_obj(hdlp, sensorid, &sensorp);
1391 if (status != PSVC_SUCCESS)
1392 return (status);
1394 status = sensorp->get_attr(hdlp, sensorp,
1395 PSVC_SWITCH_STATE_ATTR, state);
1396 if (status != PSVC_SUCCESS)
1397 return (status);
1399 if (strcmp(state, PSVC_SWITCH_ON) == 0) {
1400 strcpy(pos, PSVC_LOCKED_POS);
1401 return (PSVC_SUCCESS);
1406 if (objp->features & PSVC_OFF_POS_AV) {
1407 (void) i_psvc_get_assoc_matches(hdlp, objp->label,
1408 PSVC_KS_OFF_POS_SENSOR, &matches);
1409 if (matches == 1) {
1410 status = i_psvc_get_assoc_id(hdlp, objp->label,
1411 PSVC_KS_OFF_POS_SENSOR, 0, &sensorid);
1412 if (status != PSVC_SUCCESS)
1413 return (status);
1415 status = i_psvc_get_obj(hdlp, sensorid, &sensorp);
1416 if (status != PSVC_SUCCESS)
1417 return (status);
1419 status = sensorp->get_attr(hdlp, sensorp,
1420 PSVC_SWITCH_STATE_ATTR, state);
1421 if (status != PSVC_SUCCESS)
1422 return (status);
1424 if (strcmp(state, PSVC_SWITCH_ON) == 0) {
1425 strcpy(pos, PSVC_OFF_POS);
1426 return (PSVC_SUCCESS);
1430 /* If we have fallen through till here, something's wrong */
1431 errno = EINVAL;
1432 return (PSVC_FAILURE);
1436 static int32_t
1437 i_psvc_get_device_value_10_0(EHdl_t *hdlp, EObj_t *objp, uint8_t *value)
1439 int32_t status = PSVC_SUCCESS;
1440 char *physid;
1441 EObj_t *physobjp;
1443 if (objp->present != PSVC_PRESENT) {
1444 errno = ENODEV;
1445 return (PSVC_FAILURE);
1448 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1449 0, &physid);
1450 if (status != PSVC_SUCCESS)
1451 return (status);
1452 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1453 if (status != PSVC_SUCCESS)
1454 return (status);
1456 status = ((EPhysDev_t *)physobjp)->get_reg(hdlp, objp->addr_spec,
1457 value);
1458 if (status != PSVC_SUCCESS)
1459 return (status);
1461 if (objp->features & PSVC_CONVERSION_TABLE) {
1462 int32_t m;
1463 char *tid;
1464 uint8_t temp8;
1466 status = i_psvc_get_assoc_matches(hdlp, objp->label,
1467 PSVC_TABLE, &m);
1468 if ((status != PSVC_SUCCESS) || (m != 1)) {
1469 return (status);
1472 (void) i_psvc_get_assoc_id(hdlp, objp->label,
1473 PSVC_TABLE, 0, &tid);
1475 status = i_psvc_get_table_value(hdlp, tid, *value, &temp8);
1476 *value = temp8;
1478 return (status);
1481 static int32_t
1482 i_psvc_get_device_value_10_1(EHdl_t *hdlp, EObj_t *objp, uint8_t *value)
1484 int32_t status = PSVC_SUCCESS;
1485 char *physid;
1486 EObj_t *physobjp;
1488 if (objp->present != PSVC_PRESENT) {
1489 errno = ENODEV;
1490 return (PSVC_FAILURE);
1493 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1494 0, &physid);
1495 if (status != PSVC_SUCCESS)
1496 return (status);
1497 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1498 if (status != PSVC_SUCCESS)
1499 return (status);
1501 status = ((EPhysDev_t *)physobjp)->get_port(hdlp, objp->addr_spec,
1502 value);
1503 if (status != PSVC_SUCCESS)
1504 return (status);
1506 return (status);
1509 static int32_t
1510 i_psvc_set_device_value_10_0(EHdl_t *hdlp, EObj_t *objp, uint8_t *value)
1512 int32_t status = PSVC_SUCCESS;
1513 char *physid;
1514 EObj_t *physobjp;
1516 if (objp->present != PSVC_PRESENT) {
1517 errno = ENODEV;
1518 return (PSVC_FAILURE);
1521 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1522 0, &physid);
1523 if (status != PSVC_SUCCESS)
1524 return (status);
1525 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1526 if (status != PSVC_SUCCESS)
1527 return (status);
1529 status = ((EPhysDev_t *)physobjp)->set_reg(hdlp, objp->addr_spec,
1530 *value);
1531 return (status);
1534 static int32_t
1535 i_psvc_set_device_value_10_1(EHdl_t *hdlp, EObj_t *objp, uint8_t *value)
1537 int32_t status = PSVC_SUCCESS;
1538 char *physid;
1539 EObj_t *physobjp;
1541 if (objp->present != PSVC_PRESENT) {
1542 errno = ENODEV;
1543 return (PSVC_FAILURE);
1546 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1547 0, &physid);
1548 if (status != PSVC_SUCCESS)
1549 return (status);
1550 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1551 if (status != PSVC_SUCCESS)
1552 return (status);
1554 status = ((EPhysDev_t *)physobjp)->set_port(hdlp, objp->addr_spec,
1555 *value);
1556 return (status);
1559 static int32_t
1560 i_psvc_get_device_state_8_0(EHdl_t *hdlp, EObj_t *objp, char *sw_state)
1562 int32_t status = PSVC_SUCCESS;
1563 boolean_t active_low;
1564 int32_t bit_value;
1565 char *physid;
1566 EObj_t *physobjp;
1568 if (objp->present != PSVC_PRESENT) {
1569 errno = ENODEV;
1570 return (PSVC_FAILURE);
1573 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1574 0, &physid);
1575 if (status != PSVC_SUCCESS)
1576 return (status);
1577 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1578 if (status != PSVC_SUCCESS)
1579 return (status);
1581 status = ((EPhysDev_t *)physobjp)->get_bit(hdlp, objp->addr_spec,
1582 &bit_value);
1583 if (status != PSVC_SUCCESS)
1584 return (status);
1586 active_low = PSVC_IS_ACTIVE_LOW(objp->addr_spec);
1587 if (active_low)
1588 if (bit_value == 0)
1589 strcpy(sw_state, PSVC_SWITCH_ON);
1590 else
1591 strcpy(sw_state, PSVC_SWITCH_OFF);
1592 else
1593 if (bit_value == 0)
1594 strcpy(sw_state, PSVC_SWITCH_OFF);
1595 else
1596 strcpy(sw_state, PSVC_SWITCH_ON);
1598 return (status);
1601 static int32_t
1602 i_psvc_set_device_state_8_0(EHdl_t *hdlp, EObj_t *objp, char *sw_state)
1604 int32_t status = PSVC_SUCCESS;
1605 boolean_t active_low;
1606 int32_t bit_value;
1607 char *physid;
1608 EObj_t *physobjp;
1610 if (objp->present != PSVC_PRESENT) {
1611 errno = ENODEV;
1612 return (PSVC_FAILURE);
1615 strcpy(objp->previous_state, objp->state);
1616 strcpy(objp->state, sw_state);
1618 active_low = PSVC_IS_ACTIVE_LOW(objp->addr_spec);
1620 if (active_low)
1621 if (strcmp(sw_state, PSVC_SWITCH_ON) == 0)
1622 bit_value = 0;
1623 else
1624 bit_value = 1;
1625 else
1626 if (strcmp(sw_state, PSVC_SWITCH_ON) == 0)
1627 bit_value = 1;
1628 else
1629 bit_value = 0;
1631 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1632 0, &physid);
1633 if (status != PSVC_SUCCESS)
1634 return (status);
1635 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1636 if (status != PSVC_SUCCESS)
1637 return (status);
1639 status = ((EPhysDev_t *)physobjp)->set_bit(hdlp, objp->addr_spec,
1640 bit_value);
1641 return (status);
1644 /* LM75 */
1645 static int32_t
1646 i_psvc_get_temperature_11_2(EHdl_t *hdlp, uint64_t aspec, int32_t *temp)
1648 int32_t status = PSVC_SUCCESS;
1649 char path[1024];
1650 int32_t fp;
1651 int16_t temp16;
1653 status = i_psvc_get_devpath(hdlp, aspec, path);
1654 if (status != PSVC_SUCCESS)
1655 return (status);
1657 fp = open(path, O_RDWR);
1658 if (fp == -1)
1659 return (PSVC_FAILURE);
1661 status = ioctl_retry(fp, I2C_GET_TEMPERATURE, (void *)&temp16);
1662 if (status == -1) {
1663 close(fp);
1664 errno = EIO;
1665 return (PSVC_FAILURE);
1667 *temp = temp16;
1669 close(fp);
1671 return (status);
1674 /* MAX1617 */
1675 static int32_t
1676 i_psvc_get_temperature_11_4(EHdl_t *hdlp, uint64_t aspec, int32_t *temp)
1678 int32_t status = PSVC_SUCCESS;
1679 char path[1024];
1680 int32_t fp;
1681 int16_t temp16;
1683 status = i_psvc_get_devpath(hdlp, aspec, path);
1684 if (status != PSVC_SUCCESS)
1685 return (status);
1687 fp = open(path, O_RDWR);
1688 if (fp == -1)
1689 return (PSVC_FAILURE);
1691 status = ioctl_retry(fp, I2C_GET_TEMPERATURE, (void *)&temp16);
1692 if (status == -1) {
1693 close(fp);
1694 errno = EIO;
1695 return (PSVC_FAILURE);
1697 *temp = temp16;
1699 close(fp);
1701 return (status);
1704 /* PCF8591 */
1705 static int32_t
1706 i_psvc_get_temperature_11_6(EHdl_t *hdlp, uint64_t aspec, int32_t *temp)
1708 int32_t status = PSVC_SUCCESS;
1709 char path[1024];
1710 int32_t fp;
1712 status = i_psvc_get_devpath(hdlp, aspec, path);
1713 if (status != PSVC_SUCCESS)
1714 return (status);
1716 fp = open(path, O_RDWR);
1717 if (fp == -1)
1718 return (PSVC_FAILURE);
1720 status = ioctl_retry(fp, I2C_GET_INPUT, (void *)temp);
1721 if (status == -1) {
1722 close(fp);
1723 errno = EIO;
1724 return (-1);
1727 close(fp);
1729 return (status);
1732 /* SSC050 */
1733 static int32_t
1734 i_psvc_get_fanspeed_11_7(EHdl_t *hdlp, uint64_t aspec, int32_t *fan_speed)
1736 int32_t ret, status = PSVC_SUCCESS;
1737 char path[1024];
1738 int32_t fp;
1740 status = i_psvc_get_devpath(hdlp, aspec, path);
1741 if (status != PSVC_SUCCESS)
1742 return (status);
1744 fp = open(path, O_RDWR);
1745 if (fp == -1)
1746 return (PSVC_FAILURE);
1748 ret = ioctl_retry(fp, I2C_GET_FAN_SPEED, (void *)fan_speed);
1749 if (ret == -1) {
1750 close(fp);
1751 errno = EIO;
1752 return (-1);
1755 close(fp);
1757 return (status);
1760 /* PCF8591 */
1761 static int32_t
1762 i_psvc_get_input_11_6(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
1764 int32_t ret, status = PSVC_SUCCESS;
1765 char path[1024];
1766 int32_t fp;
1768 status = i_psvc_get_devpath(hdlp, aspec, path);
1769 if (status != PSVC_SUCCESS)
1770 return (status);
1772 fp = open(path, O_RDWR);
1773 if (fp == -1)
1774 return (PSVC_FAILURE);
1776 ret = ioctl_retry(fp, I2C_GET_INPUT, (void *)value);
1777 if (ret == -1) {
1778 close(fp);
1779 errno = EIO;
1780 return (-1);
1783 close(fp);
1785 return (status);
1788 /* LTC1427 */
1789 static int32_t
1790 i_psvc_get_output_11_3(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
1792 int32_t ret, status = PSVC_SUCCESS;
1793 char path[1024];
1794 int32_t fp;
1796 status = i_psvc_get_devpath(hdlp, aspec, path);
1797 if (status != PSVC_SUCCESS)
1798 return (status);
1800 fp = open(path, O_RDWR);
1801 if (fp == -1)
1802 return (PSVC_FAILURE);
1804 ret = ioctl_retry(fp, I2C_GET_OUTPUT, (void *)value);
1805 if (ret == -1) {
1806 close(fp);
1807 errno = EIO;
1808 return (PSVC_FAILURE);
1811 close(fp);
1813 return (status);
1816 /* PCF8591 */
1817 static int32_t
1818 i_psvc_get_output_11_6(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
1820 int32_t ret, status = PSVC_SUCCESS;
1821 char path[1024];
1822 int32_t fp;
1824 status = i_psvc_get_devpath(hdlp, aspec, path);
1825 if (status != PSVC_SUCCESS)
1826 return (status);
1828 fp = open(path, O_RDWR);
1829 if (fp == -1)
1830 return (PSVC_FAILURE);
1832 ret = ioctl_retry(fp, I2C_GET_OUTPUT, (void *)value);
1833 if (ret == -1) {
1834 close(fp);
1835 errno = EIO;
1836 return (PSVC_FAILURE);
1839 close(fp);
1841 return (status);
1844 /* TDA8444 */
1845 static int32_t
1846 i_psvc_get_output_11_8(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
1848 int32_t ret, status = PSVC_SUCCESS;
1849 char path[1024];
1850 int32_t fp;
1851 int8_t buf;
1853 status = i_psvc_get_devpath(hdlp, aspec, path);
1854 if (status != PSVC_SUCCESS)
1855 return (status);
1857 fp = open(path, O_RDWR);
1858 if (fp == -1)
1859 return (PSVC_FAILURE);
1861 ret = read(fp, &buf, 1);
1862 if (ret == -1) {
1863 close(fp);
1864 errno = EIO;
1865 return (PSVC_FAILURE);
1867 *value = buf;
1869 close(fp);
1871 return (status);
1874 /* LTC1427 */
1875 static int32_t
1876 i_psvc_set_output_11_3(EHdl_t *hdlp, uint64_t aspec, int32_t value)
1878 int32_t ret, status = PSVC_SUCCESS;
1879 char path[1024];
1880 int32_t fp;
1882 status = i_psvc_get_devpath(hdlp, aspec, path);
1883 if (status != PSVC_SUCCESS)
1884 return (status);
1886 fp = open(path, O_RDWR);
1887 if (fp == -1)
1888 return (PSVC_FAILURE);
1890 ret = ioctl_retry(fp, I2C_SET_OUTPUT, (void *)&value);
1891 if (ret == -1) {
1892 close(fp);
1893 errno = EIO;
1894 return (PSVC_FAILURE);
1897 close(fp);
1899 return (status);
1902 /* PCF8591 */
1903 static int32_t
1904 i_psvc_set_output_11_6(EHdl_t *hdlp, uint64_t aspec, int32_t value)
1906 int32_t ret, status = PSVC_SUCCESS;
1907 char path[1024];
1908 int32_t fp;
1910 status = i_psvc_get_devpath(hdlp, aspec, path);
1911 if (status != PSVC_SUCCESS)
1912 return (status);
1914 fp = open(path, O_RDWR);
1915 if (fp == -1)
1916 return (PSVC_FAILURE);
1918 ret = ioctl_retry(fp, I2C_SET_OUTPUT, (void *)&value);
1919 if (ret == -1) {
1920 close(fp);
1921 errno = EIO;
1922 return (PSVC_FAILURE);
1925 close(fp);
1927 return (status);
1930 /* TDA8444 */
1931 static int32_t
1932 i_psvc_set_output_11_8(EHdl_t *hdlp, uint64_t aspec, int32_t value)
1934 int32_t ret, status = PSVC_SUCCESS;
1935 char path[1024];
1936 int32_t fp;
1937 int8_t buf;
1939 status = i_psvc_get_devpath(hdlp, aspec, path);
1940 if (status != PSVC_SUCCESS)
1941 return (status);
1943 fp = open(path, O_RDWR);
1944 if (fp == -1)
1945 return (PSVC_FAILURE);
1947 buf = value;
1948 ret = write(fp, &buf, 1);
1949 if (ret == -1) {
1950 close(fp);
1951 errno = EIO;
1952 return (PSVC_FAILURE);
1955 close(fp);
1957 return (status);
1960 /* HPC3130 */
1961 static int32_t
1962 i_psvc_get_reg_11_1(EHdl_t *hdlp, uint64_t aspec, uint8_t *value)
1964 int32_t ret, status = PSVC_SUCCESS;
1965 uint8_t bitshift, bytemask;
1966 char path[1024];
1967 i2c_reg_t i2cregarg;
1968 int32_t fp;
1970 status = i_psvc_get_devpath(hdlp, aspec, path);
1971 if (status != PSVC_SUCCESS)
1972 return (status);
1973 fp = open(path, O_RDWR);
1974 if (fp == -1)
1975 return (PSVC_FAILURE);
1977 i2cregarg.reg_num = PSVC_GET_ASPEC_REG(aspec);
1978 ret = ioctl_retry(fp, I2C_GET_REG, (void *)&i2cregarg);
1979 if (ret == -1) {
1980 close(fp);
1981 errno = EIO;
1982 return (-1);
1985 bitshift = PSVC_GET_ASPEC_BITSHIFT(aspec);
1986 bytemask = PSVC_GET_ASPEC_BYTEMASK(aspec);
1987 if (value != NULL)
1988 *value = (i2cregarg.reg_value & bytemask) >> bitshift;
1989 close(fp);
1991 return (status);
1994 /* SSC050 */
1995 static int32_t
1996 i_psvc_get_reg_11_7(EHdl_t *hdlp, uint64_t aspec, uint8_t *value)
1998 int32_t ret, status = PSVC_SUCCESS;
1999 uint8_t bitshift, bytemask;
2000 char path[1024];
2001 i2c_reg_t i2cregarg;
2002 int32_t fp;
2004 status = i_psvc_get_devpath(hdlp, aspec, path);
2005 if (status != PSVC_SUCCESS)
2006 return (status);
2008 fp = open(path, O_RDWR);
2009 if (fp == -1)
2010 return (PSVC_FAILURE);
2012 i2cregarg.reg_num = PSVC_GET_ASPEC_REG(aspec);
2013 ret = ioctl_retry(fp, I2C_GET_REG, (void *)&i2cregarg);
2014 if (ret == -1) {
2015 close(fp);
2016 errno = EIO;
2017 return (-1);
2020 bitshift = PSVC_GET_ASPEC_BITSHIFT(aspec);
2021 bytemask = PSVC_GET_ASPEC_BYTEMASK(aspec);
2022 if (value != NULL)
2023 *value = (i2cregarg.reg_value & bytemask) >> bitshift;
2025 close(fp);
2027 return (status);
2030 /* HPC3130 */
2031 static int32_t
2032 i_psvc_set_reg_11_1(EHdl_t *hdlp, uint64_t aspec, int32_t value)
2034 int32_t ret, status = PSVC_SUCCESS;
2035 char path[1024];
2036 i2c_reg_t i2cregarg;
2037 int8_t tval;
2038 uint8_t bitshift, bytemask;
2039 int32_t fp;
2041 status = i_psvc_get_devpath(hdlp, aspec, path);
2042 if (status != PSVC_SUCCESS)
2043 return (status);
2045 bitshift = PSVC_GET_ASPEC_BITSHIFT(aspec);
2046 bytemask = PSVC_GET_ASPEC_BYTEMASK(aspec);
2047 value = value << bitshift;
2049 fp = open(path, O_RDWR);
2050 if (fp == -1)
2051 return (PSVC_FAILURE);
2053 i2cregarg.reg_num = PSVC_GET_ASPEC_REG(aspec);
2054 if (bytemask != 0xFF) {
2055 ret = ioctl_retry(fp, I2C_GET_REG, (void *)&i2cregarg);
2056 if (ret == -1) {
2057 close(fp);
2058 errno = EIO;
2059 return (-1);
2061 tval = i2cregarg.reg_value;
2062 tval = tval & ~bytemask;
2063 } else
2064 tval = 0;
2066 value = tval | value;
2067 i2cregarg.reg_value = value;
2068 ret = ioctl_retry(fp, I2C_SET_REG, (void *)&i2cregarg);
2069 if (ret == -1) {
2070 close(fp);
2071 errno = EIO;
2072 return (-1);
2075 close(fp);
2077 return (status);
2080 /* SSC050 */
2081 static int32_t
2082 i_psvc_set_reg_11_7(EHdl_t *hdlp, uint64_t aspec, int32_t value)
2084 int32_t ret, status = PSVC_SUCCESS;
2085 char path[1024];
2086 i2c_reg_t i2cregarg;
2087 int8_t tval;
2088 uint8_t bitshift, bytemask;
2089 int32_t fp;
2091 status = i_psvc_get_devpath(hdlp, aspec, path);
2092 if (status != PSVC_SUCCESS)
2093 return (status);
2095 bitshift = PSVC_GET_ASPEC_BITSHIFT(aspec);
2096 bytemask = PSVC_GET_ASPEC_BYTEMASK(aspec);
2097 value = value << bitshift;
2099 fp = open(path, O_RDWR);
2100 if (fp == -1)
2101 return (PSVC_FAILURE);
2103 i2cregarg.reg_num = PSVC_GET_ASPEC_REG(aspec);
2104 if (bytemask != 0xFF) {
2105 ret = ioctl_retry(fp, I2C_GET_REG, (void *)&i2cregarg);
2106 if (ret == -1) {
2107 close(fp);
2108 errno = EIO;
2109 return (-1);
2111 tval = i2cregarg.reg_value;
2112 tval = tval & ~bytemask;
2113 } else
2114 tval = 0;
2116 value = tval | value;
2117 i2cregarg.reg_value = value;
2118 ret = ioctl_retry(fp, I2C_SET_REG, (void *)&i2cregarg);
2119 if (ret == -1) {
2120 close(fp);
2121 errno = EIO;
2122 return (-1);
2125 close(fp);
2127 return (status);
2130 /* PCF8574 */
2131 static int32_t
2132 i_psvc_get_bit_11_5(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
2134 int32_t ret, status = PSVC_SUCCESS;
2135 char path[1024];
2136 i2c_bit_t bitarg;
2137 int32_t fp;
2139 status = i_psvc_get_devpath(hdlp, aspec, path);
2140 if (status != PSVC_SUCCESS)
2141 return (status);
2143 bitarg.bit_num = PSVC_GET_BIT_NUM(aspec);
2144 bitarg.direction = DIR_NO_CHANGE;
2146 fp = open(path, O_RDWR);
2147 if (fp == -1)
2148 return (PSVC_FAILURE);
2150 ret = ioctl_retry(fp, I2C_GET_BIT, (void *)&bitarg);
2151 if (ret == -1) {
2152 close(fp);
2153 errno = EIO;
2154 return (-1);
2157 *value = bitarg.bit_value;
2159 close(fp);
2161 return (status);
2164 /* PCF8574 */
2165 static int32_t
2166 i_psvc_get_port_11_5(EHdl_t *hdlp, uint64_t aspec, uint8_t *value)
2168 int32_t ret, status = PSVC_SUCCESS;
2169 char path[1024];
2170 i2c_port_t port;
2171 int32_t fp;
2173 status = i_psvc_get_devpath(hdlp, aspec, path);
2174 if (status != PSVC_SUCCESS)
2175 return (status);
2177 port.direction = DIR_NO_CHANGE;
2179 fp = open(path, O_RDWR);
2180 if (fp == -1)
2181 return (PSVC_FAILURE);
2183 ret = ioctl_retry(fp, I2C_GET_PORT, (void *)&port);
2184 if (ret == -1) {
2185 close(fp);
2186 errno = EIO;
2187 return (-1);
2190 *value = port.value;
2192 close(fp);
2194 return (status);
2197 /* SSC050 */
2198 static int32_t
2199 i_psvc_get_bit_11_7(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
2201 int32_t ret, status = PSVC_SUCCESS;
2202 char path[1024];
2203 i2c_bit_t bitarg;
2204 int32_t fp;
2206 status = i_psvc_get_devpath(hdlp, aspec, path);
2207 if (status != PSVC_SUCCESS)
2208 return (status);
2210 bitarg.bit_num = PSVC_GET_BIT_NUM(aspec);
2211 bitarg.direction = DIR_NO_CHANGE;
2213 fp = open(path, O_RDWR);
2214 if (fp == -1)
2215 return (PSVC_FAILURE);
2217 ret = ioctl_retry(fp, I2C_GET_BIT, (void *)&bitarg);
2218 if (ret == -1) {
2219 close(fp);
2220 errno = EIO;
2221 return (-1);
2224 *value = bitarg.bit_value;
2226 close(fp);
2228 return (status);
2231 /* PCF8574 */
2232 static int32_t
2233 i_psvc_set_bit_11_5(EHdl_t *hdlp, uint64_t aspec, int32_t value)
2235 int32_t ret, status = PSVC_SUCCESS;
2236 char path[1024];
2237 i2c_bit_t bitarg;
2238 int32_t fp;
2240 status = i_psvc_get_devpath(hdlp, aspec, path);
2241 if (status != PSVC_SUCCESS)
2242 return (status);
2244 bitarg.bit_value = value;
2245 bitarg.bit_num = PSVC_GET_BIT_NUM(aspec);
2246 bitarg.direction = DIR_OUTPUT;
2247 fp = open(path, O_RDWR);
2248 if (fp == -1)
2249 return (PSVC_FAILURE);
2251 ret = ioctl_retry(fp, I2C_SET_BIT, (void *)&bitarg);
2252 if (ret == -1) {
2253 close(fp);
2254 errno = EIO;
2255 return (-1);
2258 close(fp);
2260 return (status);
2263 /* PCF8574 */
2264 static int32_t
2265 i_psvc_set_port_11_5(EHdl_t *hdlp, uint64_t aspec, int32_t value)
2267 int32_t ret, status = PSVC_SUCCESS;
2268 char path[1024];
2269 i2c_port_t port;
2270 int32_t fp;
2272 status = i_psvc_get_devpath(hdlp, aspec, path);
2273 if (status != PSVC_SUCCESS)
2274 return (status);
2276 port.value = (uint8_t)value;
2277 port.direction = DIR_NO_CHANGE;
2278 fp = open(path, O_RDWR);
2279 if (fp == -1)
2280 return (PSVC_FAILURE);
2282 ret = ioctl_retry(fp, I2C_SET_PORT, (void *)&port);
2283 if (ret == -1) {
2284 close(fp);
2285 errno = EIO;
2286 return (-1);
2289 close(fp);
2291 return (status);
2294 /* SSC050 */
2295 static int32_t
2296 i_psvc_set_bit_11_7(EHdl_t *hdlp, uint64_t aspec, int32_t value)
2298 int32_t ret, status = PSVC_SUCCESS;
2299 char path[1024];
2300 i2c_bit_t bitarg;
2301 int32_t fp;
2303 status = i_psvc_get_devpath(hdlp, aspec, path);
2304 if (status != PSVC_SUCCESS)
2305 return (status);
2307 bitarg.bit_value = value;
2308 bitarg.bit_num = PSVC_GET_BIT_NUM(aspec);
2309 bitarg.direction = DIR_OUTPUT;
2311 fp = open(path, O_RDWR);
2312 if (fp == -1)
2313 return (PSVC_FAILURE);
2315 ret = ioctl_retry(fp, I2C_SET_BIT, (void *)&bitarg);
2316 if (ret == -1) {
2317 close(fp);
2318 errno = EIO;
2319 return (-1);
2322 close(fp);
2324 return (status);
2327 /* AT24 */
2328 static int32_t
2329 i_psvc_probe_11_0(EHdl_t *hdlp, EObj_t *objp)
2331 int32_t ret, status = PSVC_SUCCESS;
2332 uint8_t value;
2333 char path[1024];
2334 int32_t fp;
2336 if (objp->present != PSVC_PRESENT) {
2337 errno = ENODEV;
2338 return (PSVC_FAILURE);
2341 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2342 if (status != PSVC_SUCCESS) {
2343 return (status);
2346 fp = open(path, O_RDWR);
2347 if (fp == -1) {
2348 return (PSVC_FAILURE);
2351 ret = read(fp, &value, 1);
2352 if (ret == -1) {
2353 close(fp);
2354 errno = EIO;
2355 return (-1);
2358 close(fp);
2360 return (status);
2363 /* HPC3130 */
2364 static int32_t
2365 i_psvc_probe_11_1(EHdl_t *hdlp, EObj_t *objp)
2367 int32_t ret, status = PSVC_SUCCESS;
2368 char path[1024];
2369 i2c_reg_t reg;
2370 int32_t fp;
2372 if (objp->present != PSVC_PRESENT) {
2373 errno = ENODEV;
2374 return (PSVC_FAILURE);
2377 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2378 if (status != PSVC_SUCCESS)
2379 return (status);
2381 fp = open(path, O_RDWR);
2382 if (fp == -1)
2383 return (PSVC_FAILURE);
2385 reg.reg_num = 0;
2386 ret = ioctl_retry(fp, I2C_GET_REG, (void *)&reg);
2387 if (ret == -1) {
2388 close(fp);
2389 errno = EIO;
2390 return (-1);
2393 close(fp);
2395 return (status);
2398 /* LM75 */
2399 static int32_t
2400 i_psvc_probe_11_2(EHdl_t *hdlp, EObj_t *objp)
2402 int32_t ret, status = PSVC_SUCCESS;
2403 char path[1024];
2404 int32_t fp;
2405 int16_t temp16;
2407 if (objp->present != PSVC_PRESENT) {
2408 errno = ENODEV;
2409 return (PSVC_FAILURE);
2412 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2413 if (status != PSVC_SUCCESS) {
2414 return (status);
2417 fp = open(path, O_RDWR);
2418 if (fp == -1) {
2419 return (PSVC_FAILURE);
2422 ret = ioctl_retry(fp, I2C_GET_TEMPERATURE, (void *)&temp16);
2423 if (ret == -1) {
2424 close(fp);
2425 errno = EIO;
2426 return (-1);
2429 close(fp);
2431 return (status);
2434 /* LTC1427 */
2435 static int32_t
2436 i_psvc_probe_11_3(EHdl_t *hdlp, EObj_t *objp)
2438 int32_t ret, status = PSVC_SUCCESS;
2439 int32_t value;
2440 char path[1024];
2441 int32_t fp;
2443 if (objp->present != PSVC_PRESENT) {
2444 errno = ENODEV;
2445 return (PSVC_FAILURE);
2448 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2449 if (status != PSVC_SUCCESS) {
2450 return (status);
2453 fp = open(path, O_RDWR);
2454 if (fp == -1) {
2455 return (PSVC_FAILURE);
2458 ret = ioctl_retry(fp, I2C_GET_OUTPUT, (void *)&value);
2459 if (ret == -1) {
2460 close(fp);
2461 errno = EINVAL;
2462 return (-1);
2465 ret = ioctl_retry(fp, I2C_SET_OUTPUT, (void *)&value);
2466 if (ret == -1) {
2467 close(fp);
2468 errno = EIO;
2469 return (-1);
2472 close(fp);
2473 return (status);
2476 /* MAX1617 */
2477 static int32_t
2478 i_psvc_probe_11_4(EHdl_t *hdlp, EObj_t *objp)
2480 int32_t ret, status = PSVC_SUCCESS;
2481 char path[1024];
2482 int32_t fp;
2483 int16_t temp16;
2485 if (objp->present != PSVC_PRESENT) {
2486 errno = ENODEV;
2487 return (PSVC_FAILURE);
2490 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2491 if (status != PSVC_SUCCESS) {
2492 return (status);
2495 fp = open(path, O_RDWR);
2496 if (fp == -1) {
2497 return (PSVC_FAILURE);
2500 ret = ioctl_retry(fp, I2C_GET_TEMPERATURE, (void *)&temp16);
2501 if (ret == -1) {
2502 close(fp);
2503 errno = EIO;
2504 return (-1);
2507 close(fp);
2509 return (status);
2512 /* PCF8574 */
2513 static int32_t
2514 i_psvc_probe_11_5(EHdl_t *hdlp, EObj_t *objp)
2516 int32_t ret, status = PSVC_SUCCESS;
2517 char path[1024];
2518 i2c_port_t port;
2519 int32_t fp;
2521 if (objp->present != PSVC_PRESENT) {
2522 errno = ENODEV;
2523 return (PSVC_FAILURE);
2526 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2527 if (status != PSVC_SUCCESS) {
2528 return (status);
2531 port.direction = DIR_NO_CHANGE;
2533 fp = open(path, O_RDWR);
2534 if (fp == -1) {
2535 return (PSVC_FAILURE);
2538 ret = ioctl_retry(fp, I2C_GET_PORT, (void *)&port);
2539 if (ret == -1) {
2540 close(fp);
2541 errno = EIO;
2542 return (-1);
2545 close(fp);
2547 return (status);
2550 /* PCF8591 */
2551 static int32_t
2552 i_psvc_probe_11_6(EHdl_t *hdlp, EObj_t *objp)
2554 int32_t ret, status = PSVC_SUCCESS;
2555 char path[1024];
2556 int32_t arg;
2557 int32_t fp;
2559 if (objp->present != PSVC_PRESENT) {
2560 errno = ENODEV;
2561 return (PSVC_FAILURE);
2564 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2565 if (status != PSVC_SUCCESS)
2566 return (status);
2568 fp = open(path, O_RDWR);
2569 if (fp == -1)
2570 return (PSVC_FAILURE);
2572 ret = ioctl_retry(fp, I2C_GET_INPUT, (void *)&arg);
2573 if (ret == -1) {
2574 close(fp);
2575 errno = EIO;
2576 return (-1);
2579 close(fp);
2581 return (status);
2584 /* SSC050 */
2585 static int32_t
2586 i_psvc_probe_11_7(EHdl_t *hdlp, EObj_t *objp)
2588 int32_t ret, status = PSVC_SUCCESS;
2589 char path[1024];
2590 i2c_port_t port;
2591 int32_t fp;
2593 if (objp->present != PSVC_PRESENT) {
2594 errno = ENODEV;
2595 return (PSVC_FAILURE);
2598 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2599 if (status != PSVC_SUCCESS)
2600 return (status);
2602 port.direction = DIR_NO_CHANGE;
2604 fp = open(path, O_RDWR);
2605 if (fp == -1)
2606 return (PSVC_FAILURE);
2608 ret = ioctl_retry(fp, I2C_GET_PORT, (void *)&port);
2609 if (ret == -1) {
2610 close(fp);
2611 errno = EIO;
2612 return (-1);
2615 close(fp);
2617 return (status);
2620 /* TDA8444 */
2621 static int32_t
2622 i_psvc_probe_11_8(EHdl_t *hdlp, EObj_t *objp)
2624 int32_t ret, status = PSVC_SUCCESS;
2625 uint8_t value;
2626 char path[1024];
2627 int32_t fp;
2629 if (objp->present != PSVC_PRESENT) {
2630 errno = ENODEV;
2631 return (PSVC_FAILURE);
2634 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2635 if (status != PSVC_SUCCESS)
2636 return (status);
2638 fp = open(path, O_RDWR);
2639 if (fp == -1)
2640 return (PSVC_FAILURE);
2642 ret = read(fp, &value, 1);
2643 if (ret == -1) {
2644 close(fp);
2645 errno = EIO;
2646 return (-1);
2649 close(fp);
2651 return (status);
2655 /* SSC100 */
2656 static int32_t
2657 i_psvc_probe_11_9(EHdl_t *hdlp, EObj_t *objp)
2659 int32_t ret, status = PSVC_SUCCESS;
2660 char path[1024];
2661 i2c_reg_t reg;
2662 int32_t fp;
2664 if (objp->present != PSVC_PRESENT) {
2665 errno = ENODEV;
2666 return (PSVC_FAILURE);
2669 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2670 if (status != PSVC_SUCCESS) {
2671 return (status);
2674 fp = open(path, O_RDWR);
2675 if (fp == -1) {
2676 return (PSVC_FAILURE);
2680 * There are only a few register numbers that are valid numbers to
2681 * read from. 0x10 is one of these registers. Any non-valid registers
2682 * cause unknown behavior to the ssc100 device.
2684 reg.reg_num = 0x10;
2685 ret = ioctl_retry(fp, I2C_GET_REG, (void *)&reg);
2686 if (ret == -1) {
2687 close(fp);
2688 errno = EIO;
2689 return (-1);
2692 close(fp);
2694 return (status);
2699 * Find start of a section within the config file,
2700 * Returns number of records in the section.
2701 * FILE *fd is set to first data record within section.
2703 static int32_t
2704 i_psvc_find_file_section(FILE *fd, char *start)
2706 char *ret;
2707 char buf[BUFSZ];
2708 char name[32];
2709 int found;
2711 fseek(fd, 0, SEEK_SET);
2712 while ((ret = fgets(buf, BUFSZ, fd)) != NULL) {
2713 if (strncmp(start, buf, strlen(start)) == 0)
2714 break;
2717 if (ret == NULL) {
2718 errno = EINVAL;
2719 return (-1);
2722 found = sscanf(buf, "%s", name);
2723 if (found != 1) {
2724 errno = EINVAL;
2725 return (-1);
2726 } else {
2727 return (0);
2732 /* compare routine for qsort of str_tbl */
2733 static int32_t
2734 i_psvc_name_compare_qsort(EStringId_t *s1, EStringId_t *s2)
2736 return (strcmp(s1->name, s2->name));
2739 /* compare routine for bsearch of str_tbl */
2740 static int32_t
2741 i_psvc_name_compare_bsearch(char *s1, EStringId_t *s2)
2743 return (strcmp(s1, s2->name));
2747 * Determine the initial state of a device.
2749 static int32_t
2750 i_psvc_init_state(EHdl_t *hp, EObj_t *objp)
2752 int32_t status = PSVC_SUCCESS;
2754 if (objp->class == PSVC_ON_OFF_SWITCH_CLASS) {
2755 char state[32];
2757 status = objp->get_attr(hp, objp, PSVC_SWITCH_STATE_ATTR,
2758 state);
2759 if (status != PSVC_SUCCESS)
2760 return (status);
2762 if (strcmp(state, PSVC_SWITCH_ON) == 0)
2763 strcpy(objp->state, PSVC_ON);
2764 else
2765 strcpy(objp->state, PSVC_OFF);
2768 if (objp->class == PSVC_KEYSWITCH_CLASS) {
2769 char state[32];
2771 status = objp->get_attr(hp, objp, PSVC_SWITCH_STATE_ATTR,
2772 state);
2773 if (status != PSVC_SUCCESS)
2774 return (status);
2775 strcpy(objp->state, state);
2778 return (status);
2782 * Return the object pointer for the object name passed in.
2783 * Creates the object if this is the first access,
2784 * Returns 0 if successful, -1 if not.
2786 static int32_t
2787 i_psvc_get_obj(EHdl_t *hp, char *dev_name, EObj_t **objp)
2789 int32_t i, ret;
2790 int32_t found, key, array;
2791 int32_t class, subclass;
2792 boolean_t presence;
2793 char name[NAMELEN];
2794 char buf[BUFSZ];
2795 char *start;
2796 ETable_Array *tbl_arr;
2798 key = psvc_get_str_key(dev_name);
2799 array = key % PSVC_MAX_TABLE_ARRAYS;
2800 tbl_arr = &(hp->tbl_arry[array]);
2802 for (i = 0; i < tbl_arr->obj_count; ++i) {
2803 if (key == tbl_arr->obj_tbl[i].key) {
2804 if (strcmp(dev_name, tbl_arr->obj_tbl[i].name) == 0) {
2805 if (tbl_arr->obj_tbl[i].type != PSVC_OBJ)
2806 return (-1);
2807 *objp = tbl_arr->obj_tbl[i].objp;
2808 return (0);
2813 if (i_psvc_find_file_section(hp->fp, "OBJECT_INFO") == -1) {
2814 ENV_DEBUG("Couldn't find OBJECT_INFO section", dev_name);
2815 return (-1);
2818 fgets(buf, BUFSZ, hp->fp);
2819 while (strcmp(buf, "OBJECT_INFO_END")) {
2820 start = strrchr(buf, '/');
2821 if (start == NULL) {
2822 errno = EINVAL;
2823 return (PSVC_FAILURE);
2825 found = sscanf(start + 1, "%s", name);
2826 if (found != 1) {
2827 errno = EINVAL;
2828 return (PSVC_FAILURE);
2831 if (strcmp(name, dev_name) == 0) {
2833 if (i_psvc_value(buf, PSVC_CLASS_ATTR, &class)
2834 != PSVC_SUCCESS)
2835 return (PSVC_FAILURE);
2836 if (i_psvc_value(buf, PSVC_SUBCLASS_ATTR, &subclass)
2837 != PSVC_SUCCESS)
2838 return (PSVC_FAILURE);
2839 ret = (*i_psvc_constructor[class][subclass])(hp,
2840 dev_name, objp);
2841 if (ret != PSVC_SUCCESS) {
2842 return (-1);
2844 ret = (*objp)->get_attr(hp, *objp, PSVC_PRESENCE_ATTR,
2845 &presence);
2846 (*objp)->previous_presence = presence;
2847 if (ret != PSVC_SUCCESS || presence != PSVC_PRESENT)
2848 return (ret);
2850 return (i_psvc_init_state(hp, *objp));
2852 fgets(buf, BUFSZ, hp->fp);
2855 errno = EINVAL;
2856 return (-1);
2860 * Gets the device path associated with an object id.
2861 * Returns 0 if successful, -1 if not.
2863 static int32_t
2864 i_psvc_get_devpath(EHdl_t *hp, uint64_t addr_spec, char *path)
2866 int i;
2867 EDevice_t *dp;
2868 uint32_t controller, bus, addr, port;
2870 controller = PSVC_GET_ASPEC_CNTLR(addr_spec);
2871 bus = PSVC_GET_ASPEC_BUSNUM(addr_spec);
2872 addr = PSVC_GET_ASPEC_BUSADDR(addr_spec);
2873 port = PSVC_GET_ASPEC_PORT(addr_spec);
2875 for (i = 0; i < hp->dev_count; ++i) {
2876 dp = &hp->dev_tbl[i];
2877 if (dp->controller == controller &&
2878 dp->bus == bus &&
2879 dp->addr == addr &&
2880 dp->port == port) {
2881 strcpy(path, dp->path);
2882 return (PSVC_SUCCESS);
2886 errno = EINVAL;
2887 return (PSVC_FAILURE);
2891 /* Load the association table */
2892 static int32_t
2893 i_psvc_load_associations(EHdl_t *hp, FILE *fp)
2895 uint32_t count;
2896 int found;
2897 int i, j;
2898 char name1[32], name2[32];
2899 char buf[BUFSZ];
2900 EStringId_t *namep;
2901 EAssoc_t *ap;
2902 int32_t id;
2903 int32_t status;
2906 * ignore count in the file, correct count is highest
2907 * association id + 1, now figured when loading ASSOC_STR
2908 * section.
2910 if (i_psvc_find_file_section(fp, "ASSOCIATIONS") != PSVC_SUCCESS)
2911 return (-1);
2912 if ((hp->assoc_tbl = malloc(sizeof (EAssocList_t) * hp->assoc_count))
2913 == NULL) {
2914 return (-1);
2916 memset(hp->assoc_tbl, 0, sizeof (EAssocList_t) * hp->assoc_count);
2918 for (i = 0; i < hp->assoc_count; ++i) {
2919 fgets(buf, BUFSZ, fp);
2920 found = sscanf(buf, "%s %s", name1, name2);
2921 if (strcmp("ASSOCIATIONS_END", name1) == 0)
2922 break;
2923 if (found != 2) {
2924 errno = EINVAL;
2925 return (-1);
2927 namep = (EStringId_t *)bsearch(name2, hp->othr_tbl,
2928 hp->othr_count, sizeof (EStringId_t),
2929 (int (*)(const void *, const void *))
2930 i_psvc_name_compare_bsearch);
2931 if (namep == NULL) {
2932 errno = EINVAL;
2933 return (-1);
2935 id = namep->id;
2937 status = i_psvc_count_records(fp, "ASSOCIATION_END", &count);
2938 if (status != PSVC_SUCCESS)
2939 return (status);
2940 hp->assoc_tbl[id].count = count;
2941 hp->assoc_tbl[id].table =
2942 (EAssoc_t *)malloc(sizeof (EAssoc_t) * count);
2943 if (hp->assoc_tbl[id].table == NULL)
2944 return (-1);
2946 for (j = 0; j < count; ++j) {
2947 ap = &hp->assoc_tbl[id].table[j];
2948 fgets(buf, BUFSZ, fp);
2949 found = sscanf(buf, "%s %s", ap->antecedent_id,
2950 ap->dependent_id);
2951 ap->ant_key = psvc_get_str_key(ap->antecedent_id);
2952 if (found != 2) {
2953 errno = EINVAL;
2954 return (-1);
2959 fgets(buf, BUFSZ, fp);
2960 if (strncmp(buf, "ASSOCIATION_END", 15) != 0) {
2961 errno = EINVAL;
2962 return (-1);
2966 return (0);
2969 /* Load the table of tables */
2970 static int32_t
2971 i_psvc_load_tables(EHdl_t *hp, FILE *fp)
2973 int i, j;
2974 int found;
2975 int ret;
2976 int32_t cell_type;
2977 int64_t *table;
2978 char buf[BUFSZ];
2979 int32_t status;
2980 uint32_t table_count;
2981 int32_t num, key, array;
2982 char name[NAMELEN];
2983 ETable_Array *tbl_arr;
2985 if (i_psvc_find_file_section(fp, "TABLES") != PSVC_SUCCESS)
2986 return (PSVC_SUCCESS); /* no tables */
2987 status = i_psvc_count_tables_associations(fp, &table_count,
2988 "TABLE_END");
2989 if (status != PSVC_SUCCESS || table_count == 0)
2990 return (status);
2992 for (i = 0; i < table_count; ++i) {
2993 int slot;
2994 ETable_t *tblp;
2996 fgets(buf, BUFSZ, fp);
2997 if (strncmp(buf, "TABLE", 5) != 0) {
2998 errno = EINVAL;
2999 return (-1);
3002 fgets(buf, BUFSZ, fp);
3003 found = sscanf(buf, "%s %d", name, &cell_type);
3004 key = psvc_get_str_key(name);
3005 array = key % PSVC_MAX_TABLE_ARRAYS;
3006 tbl_arr = &(hp->tbl_arry[array]);
3008 if (tbl_arr->nextid == hp->total_obj_count) {
3009 errno = EINVAL;
3010 return (PSVC_FAILURE);
3011 } else {
3012 slot = tbl_arr->nextid++;
3013 tbl_arr->obj_count++;
3016 strcpy(tbl_arr->obj_tbl[slot].name, name);
3018 tblp = (ETable_t *)malloc(sizeof (ETable_t));
3019 if (tblp == NULL)
3020 return (PSVC_FAILURE);
3021 tbl_arr->obj_tbl[slot].key = key;
3022 tbl_arr->obj_tbl[slot].objp = (EObj_t *)(void *)tblp;
3023 tbl_arr->obj_tbl[slot].type = PSVC_TBL;
3025 status = i_psvc_count_table_records(fp, "TABLE_END",
3026 &tblp->size);
3027 if (status != PSVC_SUCCESS)
3028 return (status);
3029 tblp->cell_type = (uint8_t)cell_type;
3030 if (found != 2) {
3031 errno = EINVAL;
3032 return (-1);
3035 /* allocate and load table */
3036 tblp->table = (int64_t *)malloc(tblp->size *
3037 i_psvc_cell_size[tblp->cell_type]);
3038 if (tblp->table == NULL) {
3039 return (-1);
3042 table = tblp->table;
3043 for (j = 0; j < tblp->size; ++j) {
3044 switch (cell_type) {
3045 case 0:
3046 ret = fscanf(fp, "%d", &num);
3047 *((int8_t *)table + j) = num;
3048 break;
3049 case 1:
3050 ret = fscanf(fp, "%d", &num);
3051 *((uint8_t *)table + j) = (uint8_t)num;
3052 break;
3053 case 2:
3054 ret = fscanf(fp, "%hd",
3055 ((int16_t *)table + j));
3056 break;
3057 case 3:
3058 ret = fscanf(fp, "%hd",
3059 ((uint16_t *)table + j));
3060 break;
3061 case 4:
3062 ret = fscanf(fp, "%d",
3063 ((int32_t *)table + j));
3064 break;
3065 case 5:
3066 ret = fscanf(fp, "%d",
3067 ((uint32_t *)table + j));
3068 break;
3069 case 6:
3070 ret = fscanf(fp, "%lld",
3071 ((int64_t *)table + j));
3072 break;
3073 case 7:
3074 ret = fscanf(fp, "%lld",
3075 ((uint64_t *)table + j));
3076 break;
3077 default:
3078 errno = EINVAL;
3079 return (-1);
3081 if (ret != 1) {
3082 errno = EINVAL;
3083 return (-1);
3086 fgets(buf, BUFSZ, fp); /* reads newline on data line */
3087 fgets(buf, BUFSZ, fp);
3088 if (strncmp(buf, "TABLE_END", 9) != 0) {
3089 errno = EINVAL;
3090 return (-1);
3095 return (0);
3098 static int32_t
3099 i_psvc_destructor(EHdl_t *hdlp, char *name, void *objp)
3101 int32_t i, key, array;
3103 key = psvc_get_str_key(name);
3104 array = key % PSVC_MAX_TABLE_ARRAYS;
3106 for (i = 0; i < hdlp->tbl_arry[array].obj_count; ++i) {
3107 if (key == hdlp->tbl_arry[array].obj_tbl[i].key) {
3108 if (strcmp(hdlp->tbl_arry[array].obj_tbl[i].name,
3109 name) == 0) {
3110 hdlp->tbl_arry[array].obj_tbl[i].name[0] = '\0';
3111 if (objp != NULL)
3112 free(objp);
3113 return (PSVC_SUCCESS);
3118 return (PSVC_SUCCESS);
3121 static int32_t
3122 i_psvc_get_attr_generic(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id,
3123 void * attrp)
3125 int32_t status = PSVC_SUCCESS;
3126 char *parent_id;
3128 switch (attr_id) {
3129 case PSVC_ADDR_SPEC_ATTR:
3130 *(uint64_t *)attrp = objp->addr_spec;
3131 break;
3132 case PSVC_CLASS_ATTR:
3133 *(int32_t *)attrp = objp->class;
3134 break;
3135 case PSVC_SUBCLASS_ATTR:
3136 *(int32_t *)attrp = objp->subclass;
3137 break;
3138 case PSVC_PRESENCE_ATTR:
3139 status = i_psvc_get_presence(hdlp, objp, (boolean_t *)attrp);
3140 break;
3141 case PSVC_PREV_PRESENCE_ATTR:
3142 *(boolean_t *)attrp = objp->previous_presence;
3143 break;
3144 case PSVC_STATE_ATTR:
3145 strcpy((char *)attrp, objp->state);
3146 break;
3147 case PSVC_PREV_STATE_ATTR:
3148 strcpy((char *)attrp, objp->previous_state);
3149 break;
3150 case PSVC_ENABLE_ATTR:
3151 *(boolean_t *)attrp = objp->enabled;
3152 break;
3153 case PSVC_FAULTID_ATTR:
3154 strcpy((char *)attrp, objp->fault_id);
3155 break;
3156 case PSVC_FEATURES_ATTR:
3157 *(uint64_t *)attrp = objp->features;
3158 break;
3159 case PSVC_LABEL_ATTR:
3160 strcpy((char *)attrp, objp->label);
3161 break;
3162 case PSVC_FRUID_ATTR:
3163 while ((objp->features & PSVC_DEV_FRU) == 0) {
3164 status = i_psvc_get_assoc_id(hdlp, objp->label,
3165 PSVC_PARENT, 0, &parent_id);
3166 if (status != PSVC_SUCCESS)
3167 return (status);
3169 status = i_psvc_get_obj(hdlp, parent_id, &objp);
3170 if (status != PSVC_SUCCESS)
3171 return (status);
3174 strcpy((char *)attrp, objp->label);
3175 break;
3176 case PSVC_INSTANCE_ATTR:
3177 *(int32_t *)attrp = objp->instance;
3178 break;
3179 default:
3180 errno = EINVAL;
3181 return (PSVC_FAILURE);
3184 return (status);
3187 static int32_t
3188 i_psvc_set_attr_generic(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id,
3189 void * attrp)
3191 int32_t status = PSVC_SUCCESS;
3193 switch (attr_id) {
3194 case PSVC_PREV_PRESENCE_ATTR:
3195 objp->previous_presence = *(boolean_t *)attrp;
3196 break;
3197 case PSVC_STATE_ATTR:
3198 strcpy(objp->previous_state, objp->state);
3199 strcpy(objp->state, (char *)attrp);
3200 break;
3201 case PSVC_ENABLE_ATTR:
3202 objp->enabled = *(boolean_t *)attrp;
3203 break;
3204 case PSVC_FAULTID_ATTR:
3205 strcpy(objp->fault_id, (char *)attrp);
3206 break;
3207 default:
3208 errno = EINVAL;
3209 return (PSVC_FAILURE);
3211 return (status);
3214 static int32_t
3215 i_psvc_get_attr_0_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3217 int32_t status = PSVC_SUCCESS;
3219 switch (attr_id) {
3220 case PSVC_SENSOR_VALUE_ATTR:
3221 return (i_psvc_get_device_value_0_0(hdlp, objp, attrp));
3222 case PSVC_LO_WARN_ATTR:
3223 *(int32_t *)attrp = ((ETempSensor_t *)objp)->lo_warn;
3224 return (status);
3225 case PSVC_LO_SHUT_ATTR:
3226 *(int32_t *)attrp = ((ETempSensor_t *)objp)->lo_shut;
3227 return (status);
3228 case PSVC_HI_WARN_ATTR:
3229 *(int32_t *)attrp = ((ETempSensor_t *)objp)->hi_warn;
3230 return (status);
3231 case PSVC_HI_SHUT_ATTR:
3232 *(int32_t *)attrp = ((ETempSensor_t *)objp)->hi_shut;
3233 return (status);
3236 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3238 return (status);
3241 static int32_t
3242 i_psvc_get_attr_0_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3244 int32_t status = PSVC_SUCCESS;
3246 switch (attr_id) {
3247 case PSVC_SENSOR_VALUE_ATTR:
3248 return (i_psvc_get_device_value_0_1(hdlp, objp, attrp));
3249 case PSVC_LO_WARN_ATTR:
3250 *(int32_t *)attrp = ((ETempSensor_t *)objp)->lo_warn;
3251 return (status);
3252 case PSVC_LO_SHUT_ATTR:
3253 *(int32_t *)attrp = ((ETempSensor_t *)objp)->lo_shut;
3254 return (status);
3255 case PSVC_HI_WARN_ATTR:
3256 *(int32_t *)attrp = ((ETempSensor_t *)objp)->hi_warn;
3257 return (status);
3258 case PSVC_HI_SHUT_ATTR:
3259 *(int32_t *)attrp = ((ETempSensor_t *)objp)->hi_shut;
3260 return (status);
3261 case PSVC_OPTIMAL_TEMP_ATTR:
3262 *(int32_t *)attrp = ((ETempSensor_t *)objp)->opt_temp;
3263 return (status);
3264 case PSVC_HW_HI_SHUT_ATTR:
3265 *(int32_t *)attrp = ((ETempSensor_t *)objp)->hw_hi_shut;
3266 return (status);
3267 case PSVC_HW_LO_SHUT_ATTR:
3268 *(int32_t *)attrp = ((ETempSensor_t *)objp)->hw_lo_shut;
3269 return (status);
3272 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3274 return (status);
3277 static int32_t
3278 i_psvc_set_attr_0_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3280 int32_t status = PSVC_SUCCESS;
3282 switch (attr_id) {
3283 case PSVC_LO_WARN_ATTR:
3284 ((ETempSensor_t *)objp)->lo_warn = *(int32_t *)attrp;
3285 return (status);
3286 case PSVC_LO_SHUT_ATTR:
3287 ((ETempSensor_t *)objp)->lo_shut = *(int32_t *)attrp;
3288 return (status);
3289 case PSVC_HI_WARN_ATTR:
3290 ((ETempSensor_t *)objp)->hi_warn = *(int32_t *)attrp;
3291 return (status);
3292 case PSVC_HI_SHUT_ATTR:
3293 ((ETempSensor_t *)objp)->hi_shut = *(int32_t *)attrp;
3294 return (status);
3295 case PSVC_OPTIMAL_TEMP_ATTR:
3296 ((ETempSensor_t *)objp)->opt_temp = *(int32_t *)attrp;
3297 return (status);
3298 case PSVC_HW_HI_SHUT_ATTR:
3299 ((ETempSensor_t *)objp)->hw_hi_shut = *(int32_t *)attrp;
3300 return (status);
3301 case PSVC_HW_LO_SHUT_ATTR:
3302 ((ETempSensor_t *)objp)->hw_lo_shut = *(int32_t *)attrp;
3303 return (status);
3306 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3308 return (status);
3311 static int32_t
3312 i_psvc_get_attr_1_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3314 int32_t status = PSVC_SUCCESS;
3316 switch (attr_id) {
3317 case PSVC_SENSOR_VALUE_ATTR:
3318 return (i_psvc_get_device_value_1_0(hdlp, objp, attrp));
3319 case PSVC_SETPOINT_ATTR:
3320 *(int16_t *)attrp = ((EFan_t *)objp)->setpoint;
3321 return (status);
3322 case PSVC_HYSTERESIS_ATTR:
3323 *(int16_t *)attrp = ((EFan_t *)objp)->hysteresis;
3324 return (status);
3325 case PSVC_LOOPGAIN_ATTR:
3326 *(int16_t *)attrp = ((EFan_t *)objp)->loopgain;
3327 return (status);
3328 case PSVC_LOOPBIAS_ATTR:
3329 *(int16_t *)attrp = ((EFan_t *)objp)->loopbias;
3330 return (status);
3331 case PSVC_TEMP_DIFFERENTIAL_ATTR:
3332 memcpy(attrp, ((EFan_t *)objp)->temp_differential,
3333 sizeof (((EFan_t *)objp)->temp_differential));
3334 return (status);
3335 case PSVC_TEMP_DIFFERENTIAL_INDEX_ATTR:
3336 *(int16_t *)attrp = ((EFan_t *)objp)->temp_differential_index;
3337 return (status);
3340 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3342 return (status);
3345 static int32_t
3346 i_psvc_set_attr_1_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3348 int32_t status = PSVC_SUCCESS;
3350 switch (attr_id) {
3351 case PSVC_TEMP_DIFFERENTIAL_ATTR:
3352 memcpy(((EFan_t *)objp)->temp_differential, attrp,
3353 sizeof (((EFan_t *)objp)->temp_differential));
3354 return (status);
3355 case PSVC_TEMP_DIFFERENTIAL_INDEX_ATTR:
3356 ((EFan_t *)objp)->temp_differential_index = *(int16_t *)attrp;
3357 return (status);
3358 case PSVC_SETPOINT_ATTR:
3359 ((EFan_t *)objp)->setpoint = *(int16_t *)attrp;
3360 return (status);
3363 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3365 return (PSVC_SUCCESS);
3368 static int32_t
3369 i_psvc_get_attr_2_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3371 int32_t status = PSVC_SUCCESS;
3373 switch (attr_id) {
3374 case PSVC_LED_STATE_ATTR:
3375 case PSVC_STATE_ATTR:
3376 return (i_psvc_get_device_state_2_0(hdlp, objp, attrp));
3377 case PSVC_LED_COLOR_ATTR:
3378 strcpy((char *)attrp, ((ELed_t *)objp)->color);
3379 return (status);
3380 case PSVC_LIT_COUNT_ATTR:
3381 *(int16_t *)attrp = ((ELed_t *)objp)->lit_count;
3382 return (status);
3385 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3387 return (status);
3390 static int32_t
3391 i_psvc_set_attr_2_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3393 int32_t status = PSVC_SUCCESS;
3395 switch (attr_id) {
3396 case PSVC_LED_STATE_ATTR:
3397 case PSVC_STATE_ATTR:
3398 return (i_psvc_set_device_state_2_0(hdlp, objp, attrp));
3401 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3403 return (status);
3406 static int32_t
3407 i_psvc_get_attr_2_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3409 int32_t status = PSVC_SUCCESS;
3411 switch (attr_id) {
3412 case PSVC_LED_STATE_ATTR:
3413 case PSVC_STATE_ATTR:
3414 return (i_psvc_get_device_state_2_1(hdlp, objp, attrp));
3415 case PSVC_LED_COLOR_ATTR:
3416 strcpy((char *)attrp, ((ELed_t *)objp)->color);
3417 return (status);
3418 case PSVC_LIT_COUNT_ATTR:
3419 *(int16_t *)attrp = ((ELed_t *)objp)->lit_count;
3420 return (status);
3423 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3425 return (status);
3428 static int32_t
3429 i_psvc_set_attr_2_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3431 int32_t status = PSVC_SUCCESS;
3433 switch (attr_id) {
3434 case PSVC_LED_STATE_ATTR:
3435 case PSVC_STATE_ATTR:
3436 return (i_psvc_set_device_state_2_1(hdlp, objp, attrp));
3439 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3441 return (status);
3444 static int32_t
3445 i_psvc_get_attr_2_2(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3447 int32_t status = PSVC_SUCCESS;
3449 switch (attr_id) {
3450 case PSVC_LED_STATE_ATTR:
3451 case PSVC_STATE_ATTR:
3452 return (i_psvc_get_device_state_2_0(hdlp, objp, attrp));
3453 case PSVC_LED_COLOR_ATTR:
3454 strcpy((char *)attrp, ((ELed_t *)objp)->color);
3455 return (status);
3456 case PSVC_LIT_COUNT_ATTR:
3457 *(int16_t *)attrp = ((ELed_t *)objp)->lit_count;
3458 return (status);
3459 case PSVC_LED_IS_LOCATOR_ATTR:
3460 strcpy((char *)attrp, ((ELed_t *)objp)->is_locator);
3461 return (status);
3462 case PSVC_LED_LOCATOR_NAME_ATTR:
3463 strcpy((char *)attrp, ((ELed_t *)objp)->locator_name);
3464 return (status);
3467 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3469 return (status);
3472 static int32_t
3473 i_psvc_get_attr_4_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3475 int32_t status = PSVC_SUCCESS;
3477 switch (attr_id) {
3478 case PSVC_SENSOR_VALUE_ATTR:
3479 return (i_psvc_get_device_value_4_0(hdlp, objp, attrp));
3480 case PSVC_LO_WARN_ATTR:
3481 *(int32_t *)attrp = ((EDigiSensor_t *)objp)->lo_warn;
3482 return (status);
3483 case PSVC_LO_SHUT_ATTR:
3484 *(int32_t *)attrp = ((EDigiSensor_t *)objp)->lo_shut;
3485 return (status);
3486 case PSVC_HI_WARN_ATTR:
3487 *(int32_t *)attrp = ((EDigiSensor_t *)objp)->hi_warn;
3488 return (status);
3489 case PSVC_HI_SHUT_ATTR:
3490 *(int32_t *)attrp = ((EDigiSensor_t *)objp)->hi_shut;
3491 return (status);
3494 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3496 return (PSVC_SUCCESS);
3499 static int32_t
3500 i_psvc_get_attr_5_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3502 int32_t status = PSVC_SUCCESS;
3504 if (attr_id == PSVC_CONTROL_VALUE_ATTR) {
3505 return (i_psvc_get_device_value_5_0(hdlp, objp, attrp));
3508 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3510 return (status);
3513 static int32_t
3514 i_psvc_set_attr_5_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3516 int32_t status = PSVC_SUCCESS;
3518 if (attr_id == PSVC_CONTROL_VALUE_ATTR) {
3519 return (i_psvc_set_device_value_5_0(hdlp, objp, attrp));
3522 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3524 return (status);
3527 static int32_t
3528 i_psvc_get_attr_6_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3530 int32_t status = PSVC_SUCCESS;
3532 switch (attr_id) {
3533 case PSVC_GPIO_VALUE_ATTR:
3534 return (i_psvc_get_device_value_6_0(hdlp, objp, attrp));
3535 case PSVC_GPIO_BITS:
3536 *(int32_t *)attrp = 1;
3537 return (status);
3540 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3542 return (status);
3545 static int32_t
3546 i_psvc_set_attr_6_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3548 int32_t status = PSVC_SUCCESS;
3550 if (attr_id == PSVC_GPIO_VALUE_ATTR) {
3551 return (i_psvc_set_device_value_6_0(hdlp, objp, attrp));
3554 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3556 return (status);
3559 static int32_t
3560 i_psvc_get_attr_7_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3562 int32_t status = PSVC_SUCCESS;
3564 switch (attr_id) {
3565 case PSVC_SENSOR_VALUE_ATTR:
3566 return (i_psvc_get_device_value_7_0(hdlp, objp, attrp));
3567 case PSVC_LO_WARN_ATTR:
3568 *(int32_t *)attrp = ((EFanTach_t *)objp)->lo_warn;
3569 return (status);
3570 case PSVC_LO_SHUT_ATTR:
3571 *(int32_t *)attrp = ((EFanTach_t *)objp)->lo_shut;
3572 return (status);
3573 case PSVC_HI_WARN_ATTR:
3574 *(int32_t *)attrp = ((EFanTach_t *)objp)->hi_warn;
3575 return (status);
3576 case PSVC_HI_SHUT_ATTR:
3577 *(int32_t *)attrp = ((EFanTach_t *)objp)->hi_shut;
3578 return (status);
3581 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3583 return (PSVC_SUCCESS);
3586 static int32_t
3587 i_psvc_get_attr_8_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3589 int32_t status = PSVC_SUCCESS;
3591 switch (attr_id) {
3592 case PSVC_SWITCH_STATE_ATTR:
3593 case PSVC_STATE_ATTR:
3594 return (i_psvc_get_device_state_8_0(hdlp, objp, attrp));
3597 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3599 return (status);
3602 static int32_t
3603 i_psvc_set_attr_8_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3605 int32_t status = PSVC_SUCCESS;
3607 switch (attr_id) {
3608 case PSVC_SWITCH_STATE_ATTR:
3609 case PSVC_STATE_ATTR:
3610 return (i_psvc_set_device_state_8_0(hdlp, objp, attrp));
3613 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3615 return (status);
3618 static int32_t
3619 i_psvc_get_attr_9_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3621 int32_t status = PSVC_SUCCESS;
3623 switch (attr_id) {
3624 case PSVC_SWITCH_STATE_ATTR:
3625 case PSVC_STATE_ATTR:
3626 status = i_psvc_get_device_state_9_0(hdlp, objp, attrp);
3627 if ((status == PSVC_FAILURE) && (errno == EINVAL)) {
3628 strcpy((char *)attrp, PSVC_ERROR);
3629 return (PSVC_SUCCESS);
3630 } else {
3631 return (status);
3635 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3637 return (status);
3640 static int32_t
3641 i_psvc_get_attr_10_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3643 int32_t status = PSVC_SUCCESS;
3645 switch (attr_id) {
3646 case PSVC_GPIO_VALUE_ATTR:
3647 return (i_psvc_get_device_value_10_0(hdlp, objp, attrp));
3648 case PSVC_GPIO_BITS:
3649 *(int32_t *)attrp = 8;
3650 return (status);
3653 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3655 return (status);
3658 static int32_t
3659 i_psvc_set_attr_10_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3661 int32_t status = PSVC_SUCCESS;
3663 if (attr_id == PSVC_GPIO_VALUE_ATTR) {
3664 return (i_psvc_set_device_value_10_0(hdlp, objp, attrp));
3667 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3669 return (status);
3672 static int32_t
3673 i_psvc_get_attr_10_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3675 int32_t status = PSVC_SUCCESS;
3677 switch (attr_id) {
3678 case PSVC_GPIO_VALUE_ATTR:
3679 return (i_psvc_get_device_value_10_1(hdlp, objp, attrp));
3680 case PSVC_GPIO_BITS:
3681 *(int32_t *)attrp = 8;
3682 return (status);
3685 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3687 return (status);
3690 static int32_t
3691 i_psvc_set_attr_10_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3693 int32_t status = PSVC_SUCCESS;
3695 if (attr_id == PSVC_GPIO_VALUE_ATTR) {
3696 return (i_psvc_set_device_value_10_1(hdlp, objp, attrp));
3699 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3701 return (status);
3704 /* AT24 */
3705 static int32_t
3706 i_psvc_get_attr_11_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3708 int32_t status = PSVC_SUCCESS;
3709 int32_t probe_status;
3711 switch (attr_id) {
3712 case PSVC_PROBE_RESULT_ATTR:
3713 probe_status = i_psvc_probe_11_0(hdlp, objp);
3714 if (probe_status == PSVC_SUCCESS)
3715 strcpy((char *)attrp, PSVC_OK);
3716 else
3717 strcpy((char *)attrp, PSVC_ERROR);
3718 return (status);
3719 case PSVC_FRU_INFO_ATTR:
3720 status = i_psvc_get_reg_11_0(hdlp, objp, attr_id, attrp);
3721 return (status);
3724 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3726 return (status);
3729 static int32_t
3730 i_psvc_get_reg_11_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3732 int32_t status = PSVC_SUCCESS, ret;
3733 char path[1024], *data;
3734 int32_t fp, temp_errno;
3735 fru_info_t *fru_data;
3737 fru_data = (fru_info_t *)attrp;
3739 if (objp->present != PSVC_PRESENT) {
3740 errno = ENODEV;
3741 return (PSVC_FAILURE);
3744 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
3745 if (status != PSVC_SUCCESS)
3746 return (status);
3748 fp = open(path, O_RDWR);
3749 if (fp == -1) {
3750 return (PSVC_FAILURE);
3753 ret = lseek(fp, fru_data->buf_start, SEEK_SET);
3754 if (ret != fru_data->buf_start) {
3755 temp_errno = errno;
3756 close(fp);
3757 errno = temp_errno;
3758 return (PSVC_FAILURE);
3761 data = (char *)malloc(fru_data->read_size);
3762 ret = read(fp, data, fru_data->read_size);
3763 if (ret == -1) {
3764 free(data);
3765 close(fp);
3766 errno = EIO;
3767 return (-1);
3770 memcpy(fru_data->buf, data, fru_data->read_size);
3771 free(data);
3772 close(fp);
3774 return (status);
3777 static int32_t
3778 i_psvc_get_attr_11_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3780 int32_t status = PSVC_SUCCESS;
3781 int32_t probe_status;
3783 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3784 probe_status = i_psvc_probe_11_1(hdlp, objp);
3785 if (probe_status == PSVC_SUCCESS)
3786 strcpy((char *)attrp, PSVC_OK);
3787 else
3788 strcpy((char *)attrp, PSVC_ERROR);
3789 return (status);
3792 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3794 return (status);
3797 static int32_t
3798 i_psvc_get_attr_11_2(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3800 int32_t status = PSVC_SUCCESS;
3801 int32_t probe_status;
3803 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3804 probe_status = i_psvc_probe_11_2(hdlp, objp);
3805 if (probe_status == PSVC_SUCCESS)
3806 strcpy((char *)attrp, PSVC_OK);
3807 else
3808 strcpy((char *)attrp, PSVC_ERROR);
3809 return (status);
3812 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3814 return (status);
3817 static int32_t
3818 i_psvc_get_attr_11_3(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3820 int32_t status = PSVC_SUCCESS;
3821 int32_t probe_status;
3823 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3824 probe_status = i_psvc_probe_11_3(hdlp, objp);
3825 if (probe_status == PSVC_SUCCESS)
3826 strcpy((char *)attrp, PSVC_OK);
3827 else
3828 strcpy((char *)attrp, PSVC_ERROR);
3829 return (status);
3832 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3834 return (status);
3837 static int32_t
3838 i_psvc_get_attr_11_4(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3840 int32_t status = PSVC_SUCCESS;
3841 int32_t probe_status;
3843 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3844 probe_status = i_psvc_probe_11_4(hdlp, objp);
3845 if (probe_status == PSVC_SUCCESS)
3846 strcpy((char *)attrp, PSVC_OK);
3847 else
3848 strcpy((char *)attrp, PSVC_ERROR);
3849 return (status);
3852 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3854 return (status);
3857 static int32_t
3858 i_psvc_get_attr_11_5(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3860 int32_t status = PSVC_SUCCESS;
3861 int32_t probe_status;
3863 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3864 probe_status = i_psvc_probe_11_5(hdlp, objp);
3865 if (probe_status == PSVC_SUCCESS)
3866 strcpy((char *)attrp, PSVC_OK);
3867 else
3868 strcpy((char *)attrp, PSVC_ERROR);
3869 return (status);
3872 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3874 return (status);
3877 static int32_t
3878 i_psvc_get_attr_11_6(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3880 int32_t status = PSVC_SUCCESS;
3881 int32_t probe_status;
3883 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3884 probe_status = i_psvc_probe_11_6(hdlp, objp);
3885 if (probe_status == PSVC_SUCCESS)
3886 strcpy((char *)attrp, PSVC_OK);
3887 else
3888 strcpy((char *)attrp, PSVC_ERROR);
3889 return (status);
3892 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3894 return (status);
3897 static int32_t
3898 i_psvc_get_attr_11_7(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3900 int32_t status = PSVC_SUCCESS;
3901 int32_t probe_status;
3903 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3904 probe_status = i_psvc_probe_11_7(hdlp, objp);
3905 if (probe_status == PSVC_SUCCESS)
3906 strcpy((char *)attrp, PSVC_OK);
3907 else
3908 strcpy((char *)attrp, PSVC_ERROR);
3909 return (status);
3912 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3914 return (status);
3917 static int32_t
3918 i_psvc_get_attr_11_8(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3920 int32_t status = PSVC_SUCCESS;
3921 int32_t probe_status;
3923 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3924 probe_status = i_psvc_probe_11_8(hdlp, objp);
3925 if (probe_status == PSVC_SUCCESS)
3926 strcpy((char *)attrp, PSVC_OK);
3927 else
3928 strcpy((char *)attrp, PSVC_ERROR);
3929 return (status);
3932 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3934 return (status);
3937 static int32_t
3938 i_psvc_get_attr_11_9(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3940 int32_t status = PSVC_SUCCESS;
3941 int32_t probe_status;
3943 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3944 probe_status = i_psvc_probe_11_9(hdlp, objp);
3945 if (probe_status == PSVC_SUCCESS)
3946 strcpy((char *)attrp, PSVC_OK);
3947 else
3948 strcpy((char *)attrp, PSVC_ERROR);
3949 return (status);
3952 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3954 return (status);
3957 static int32_t
3958 i_psvc_load_generic(
3959 EHdl_t *hdlp,
3960 char *name,
3961 EObj_t **objpp,
3962 char *buf,
3963 int32_t obj_size)
3965 int32_t found, key, array;
3966 EObj_t *objp;
3967 char *start;
3968 char cur_device[NAMELEN];
3969 int slot;
3970 ETable_Array *tbl_arr;
3972 key = psvc_get_str_key(name);
3973 array = key % PSVC_MAX_TABLE_ARRAYS;
3974 tbl_arr = &(hdlp->tbl_arry[array]);
3976 if (tbl_arr->nextid == hdlp->total_obj_count) {
3977 errno = EINVAL;
3978 return (PSVC_FAILURE);
3979 } else {
3980 slot = tbl_arr->nextid++;
3981 tbl_arr->obj_count++;
3984 if (i_psvc_find_file_section(hdlp->fp, "OBJECT_INFO") != PSVC_SUCCESS)
3985 return (PSVC_FAILURE);
3987 fgets(buf, BUFSZ, hdlp->fp);
3988 while (strcmp(buf, "OBJECT_INFO_END")) {
3989 start = strrchr(buf, '/');
3990 if (start == NULL) {
3991 errno = EINVAL;
3992 return (PSVC_FAILURE);
3994 found = sscanf(start + 1, "%s", cur_device);
3995 if (found != 1) {
3996 errno = EINVAL;
3997 return (PSVC_FAILURE);
3999 if (strcmp(name, cur_device) == 0) /* found it */
4000 break;
4001 fgets(buf, BUFSZ, hdlp->fp);
4004 tbl_arr->obj_tbl[slot].objp = (EObj_t *)malloc(obj_size);
4005 if (tbl_arr->obj_tbl[slot].objp == 0)
4006 return (PSVC_FAILURE);
4007 objp = (EObj_t *)tbl_arr->obj_tbl[slot].objp;
4008 tbl_arr->obj_tbl[slot].type = PSVC_OBJ;
4010 memset(objp, 0, obj_size);
4011 strcpy(objp->label, name);
4012 strcpy(tbl_arr->obj_tbl[slot].name, name);
4014 tbl_arr->obj_tbl[slot].key = key;
4016 if (i_psvc_value(buf, PSVC_CLASS_ATTR, &objp->class) != PSVC_SUCCESS) {
4017 i_psvc_destructor(hdlp, name, objp);
4018 return (PSVC_FAILURE);
4020 if (i_psvc_value(buf, PSVC_SUBCLASS_ATTR, &objp->subclass) !=
4021 PSVC_SUCCESS) {
4022 i_psvc_destructor(hdlp, name, objp);
4023 return (PSVC_FAILURE);
4025 if (i_psvc_value(buf, PSVC_INSTANCE_ATTR, &objp->instance) !=
4026 PSVC_SUCCESS) {
4027 i_psvc_destructor(hdlp, name, objp);
4028 return (PSVC_FAILURE);
4030 if (i_psvc_value(buf, PSVC_FEATURES_ATTR, &objp->features) !=
4031 PSVC_SUCCESS) {
4032 i_psvc_destructor(hdlp, name, objp);
4033 return (PSVC_FAILURE);
4035 if (i_psvc_value(buf, PSVC_ADDR_SPEC_ATTR, &objp->addr_spec) !=
4036 PSVC_SUCCESS) {
4037 i_psvc_destructor(hdlp, name, objp);
4038 return (PSVC_FAILURE);
4041 if (objp->features & PSVC_DEV_SECONDARY)
4042 objp->enabled = PSVC_DISABLED;
4043 else
4044 objp->enabled = PSVC_ENABLED;
4046 if (PSVC_GET_VERSION(objp->addr_spec) > PSVC_VERSION) {
4047 errno = EINVAL;
4048 i_psvc_destructor(hdlp, name, objp);
4049 return (PSVC_FAILURE);
4052 *objpp = objp;
4053 return (PSVC_SUCCESS);
4058 static int32_t
4059 i_psvc_not_supported()
4061 errno = ENOTSUP;
4062 return (PSVC_FAILURE);
4065 /* Temperature sensor */
4066 /* Class 0 Subclass 0 are temperature sensors that cannot be updated */
4067 static int32_t
4068 i_psvc_constructor_0_0(
4069 EHdl_t *hdlp,
4070 char *id,
4071 EObj_t **objpp)
4073 int32_t status;
4074 char buf[BUFSZ];
4075 ETempSensor_t *dp;
4077 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4078 sizeof (ETempSensor_t));
4079 if (status != PSVC_SUCCESS)
4080 return (status);
4082 /* Load class specific info */
4083 dp = (ETempSensor_t *)*objpp;
4084 if (i_psvc_value(buf, PSVC_LO_WARN_ATTR, &dp->lo_warn)
4085 != PSVC_SUCCESS) {
4086 i_psvc_destructor(hdlp, id, dp);
4087 return (PSVC_FAILURE);
4089 if (i_psvc_value(buf, PSVC_LO_SHUT_ATTR, &dp->lo_shut)
4090 != PSVC_SUCCESS) {
4091 i_psvc_destructor(hdlp, id, dp);
4092 return (PSVC_FAILURE);
4094 if (i_psvc_value(buf, PSVC_HI_WARN_ATTR, &dp->hi_warn)
4095 != PSVC_SUCCESS) {
4096 i_psvc_destructor(hdlp, id, dp);
4097 return (PSVC_FAILURE);
4099 if (i_psvc_value(buf, PSVC_HI_SHUT_ATTR, &dp->hi_shut)
4100 != PSVC_SUCCESS) {
4101 i_psvc_destructor(hdlp, id, dp);
4102 return (PSVC_FAILURE);
4105 dp->ld.constructor = i_psvc_constructor_0_0;
4106 dp->ld.destructor = i_psvc_destructor;
4107 dp->ld.get_attr = i_psvc_get_attr_0_0;
4108 dp->ld.set_attr = i_psvc_set_attr_generic;
4110 return (0);
4113 /* Class 0 Subclass 1 are temperature sensors that can be updated */
4114 static int32_t
4115 i_psvc_constructor_0_1(
4116 EHdl_t *hdlp,
4117 char *id,
4118 EObj_t **objpp)
4120 int32_t status;
4121 char buf[BUFSZ];
4122 ETempSensor_t *dp;
4124 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4125 sizeof (ETempSensor_t));
4126 if (status != PSVC_SUCCESS)
4127 return (status);
4129 /* Load class specific info */
4130 dp = (ETempSensor_t *)*objpp;
4131 if (i_psvc_value(buf, PSVC_LO_WARN_ATTR, &dp->lo_warn)
4132 != PSVC_SUCCESS) {
4133 i_psvc_destructor(hdlp, id, dp);
4134 return (PSVC_FAILURE);
4136 if (i_psvc_value(buf, PSVC_LO_SHUT_ATTR, &dp->lo_shut)
4137 != PSVC_SUCCESS) {
4138 i_psvc_destructor(hdlp, id, dp);
4139 return (PSVC_FAILURE);
4141 if (i_psvc_value(buf, PSVC_HI_WARN_ATTR, &dp->hi_warn)
4142 != PSVC_SUCCESS) {
4143 i_psvc_destructor(hdlp, id, dp);
4144 return (PSVC_FAILURE);
4146 if (i_psvc_value(buf, PSVC_HI_SHUT_ATTR, &dp->hi_shut)
4147 != PSVC_SUCCESS) {
4148 i_psvc_destructor(hdlp, id, dp);
4149 return (PSVC_FAILURE);
4152 if ((*objpp)->features & PSVC_OPT_TEMP) {
4153 if (i_psvc_value(buf, PSVC_OPTIMAL_TEMP_ATTR, &dp->opt_temp)
4154 != PSVC_SUCCESS) {
4155 i_psvc_destructor(hdlp, id, dp);
4156 return (PSVC_FAILURE);
4159 if ((*objpp)->features & PSVC_HW_LOW_SHUT) {
4160 if (i_psvc_value(buf, PSVC_HW_LO_SHUT_ATTR, &dp->hw_lo_shut)
4161 != PSVC_SUCCESS) {
4162 i_psvc_destructor(hdlp, id, dp);
4163 return (PSVC_FAILURE);
4166 if ((*objpp)->features & PSVC_HW_HIGH_SHUT) {
4167 if (i_psvc_value(buf, PSVC_HW_HI_SHUT_ATTR, &dp->hw_hi_shut)
4168 != PSVC_SUCCESS) {
4169 i_psvc_destructor(hdlp, id, dp);
4170 return (PSVC_FAILURE);
4174 dp->ld.constructor = i_psvc_constructor_0_1;
4175 dp->ld.destructor = i_psvc_destructor;
4176 dp->ld.get_attr = i_psvc_get_attr_0_1;
4177 dp->ld.set_attr = i_psvc_set_attr_0_1;
4179 return (0);
4182 /* Fan */
4183 static int32_t
4184 i_psvc_constructor_1_0(
4185 EHdl_t *hdlp,
4186 char *id,
4187 EObj_t **objpp)
4189 int32_t status;
4190 char buf[BUFSZ];
4191 EFan_t *dp;
4193 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4194 sizeof (EFan_t));
4195 if (status != PSVC_SUCCESS)
4196 return (status);
4198 /* Load class specific info */
4199 dp = (EFan_t *)*objpp;
4200 if (i_psvc_value(buf, PSVC_SETPOINT_ATTR, &dp->setpoint)
4201 != PSVC_SUCCESS) {
4202 i_psvc_destructor(hdlp, id, dp);
4203 return (PSVC_FAILURE);
4205 if (i_psvc_value(buf, PSVC_HYSTERESIS_ATTR, &dp->hysteresis)
4206 != PSVC_SUCCESS) {
4207 i_psvc_destructor(hdlp, id, dp);
4208 return (PSVC_FAILURE);
4210 if (i_psvc_value(buf, PSVC_LOOPGAIN_ATTR, &dp->loopgain)
4211 != PSVC_SUCCESS) {
4212 i_psvc_destructor(hdlp, id, dp);
4213 return (PSVC_FAILURE);
4215 if (i_psvc_value(buf, PSVC_LOOPBIAS_ATTR, &dp->loopbias)
4216 != PSVC_SUCCESS) {
4217 i_psvc_destructor(hdlp, id, dp);
4218 return (PSVC_FAILURE);
4221 dp->ld.constructor = i_psvc_constructor_1_0;
4222 dp->ld.destructor = i_psvc_destructor;
4223 dp->ld.get_attr = i_psvc_get_attr_1_0;
4224 dp->ld.set_attr = i_psvc_set_attr_1_0;
4226 return (PSVC_SUCCESS);
4230 /* LED */
4231 static int32_t
4232 i_psvc_constructor_2_0(
4233 EHdl_t *hdlp,
4234 char *id,
4235 EObj_t **objpp)
4237 int32_t status;
4238 char buf[BUFSZ];
4239 ELed_t *dp;
4241 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4242 sizeof (ELed_t));
4243 if (status != PSVC_SUCCESS)
4244 return (status);
4246 /* Load class specific info */
4247 dp = (ELed_t *)*objpp;
4249 if (i_psvc_value(buf, PSVC_LED_COLOR_ATTR, dp->color)
4250 != PSVC_SUCCESS) {
4251 i_psvc_destructor(hdlp, id, dp);
4252 return (PSVC_FAILURE);
4255 dp->ld.constructor = i_psvc_constructor_2_0;
4256 dp->ld.destructor = i_psvc_destructor;
4257 dp->ld.get_attr = i_psvc_get_attr_2_0;
4258 dp->ld.set_attr = i_psvc_set_attr_2_0;
4260 return (PSVC_SUCCESS);
4263 static int32_t
4264 i_psvc_constructor_2_1(
4265 EHdl_t *hdlp,
4266 char *id,
4267 EObj_t **objpp)
4269 int32_t status;
4270 char buf[BUFSZ];
4271 ELed_t *dp;
4273 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4274 sizeof (ELed_t));
4275 if (status != PSVC_SUCCESS)
4276 return (status);
4278 /* Load class specific info */
4279 dp = (ELed_t *)*objpp;
4281 if (i_psvc_value(buf, PSVC_LED_COLOR_ATTR, dp->color)
4282 != PSVC_SUCCESS) {
4283 i_psvc_destructor(hdlp, id, dp);
4284 return (PSVC_FAILURE);
4287 dp->ld.constructor = i_psvc_constructor_2_1;
4288 dp->ld.destructor = i_psvc_destructor;
4289 dp->ld.get_attr = i_psvc_get_attr_2_1;
4290 dp->ld.set_attr = i_psvc_set_attr_2_1;
4292 return (PSVC_SUCCESS);
4295 static int32_t
4296 i_psvc_constructor_2_2(
4297 EHdl_t *hdlp,
4298 char *id,
4299 EObj_t **objpp)
4301 int32_t status;
4302 char buf[BUFSZ];
4303 ELed_t *dp;
4305 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4306 sizeof (ELed_t));
4307 if (status != PSVC_SUCCESS)
4308 return (status);
4310 /* Load class specific info */
4311 dp = (ELed_t *)*objpp;
4313 if (i_psvc_value(buf, PSVC_LED_COLOR_ATTR, dp->color)
4314 != PSVC_SUCCESS) {
4315 i_psvc_destructor(hdlp, id, dp);
4316 return (PSVC_FAILURE);
4318 if (i_psvc_value(buf, PSVC_LED_IS_LOCATOR_ATTR, dp->is_locator)
4319 != PSVC_SUCCESS) {
4320 i_psvc_destructor(hdlp, id, dp);
4321 return (PSVC_FAILURE);
4323 if (strcmp(dp->is_locator, PSVC_LOCATOR_TRUE) == 0) {
4324 if (i_psvc_value(buf, PSVC_LED_LOCATOR_NAME_ATTR,
4325 dp->locator_name) != PSVC_SUCCESS) {
4326 i_psvc_destructor(hdlp, id, dp);
4327 return (PSVC_FAILURE);
4329 } else {
4330 strcpy(dp->locator_name, "N/A");
4333 dp->ld.constructor = i_psvc_constructor_2_2;
4334 dp->ld.destructor = i_psvc_destructor;
4335 dp->ld.get_attr = i_psvc_get_attr_2_2;
4336 dp->ld.set_attr = i_psvc_set_attr_2_0;
4338 return (PSVC_SUCCESS);
4341 /* System Device */
4342 static int32_t
4343 i_psvc_constructor_3_0(
4344 EHdl_t *hdlp,
4345 char *id,
4346 EObj_t **objpp)
4348 int32_t status;
4349 char buf[BUFSZ];
4350 ESystem_t *dp;
4352 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (ESystem_t));
4353 if (status != PSVC_SUCCESS)
4354 return (status);
4356 /* Load class specific info */
4357 dp = (ESystem_t *)*objpp;
4359 dp->ld.constructor = i_psvc_constructor_3_0;
4360 dp->ld.destructor = i_psvc_destructor;
4361 dp->ld.get_attr = i_psvc_get_attr_generic;
4362 dp->ld.set_attr = i_psvc_set_attr_generic;
4364 return (PSVC_SUCCESS);
4367 /* Digital Sensor */
4368 static int32_t
4369 i_psvc_constructor_4_0(
4370 EHdl_t *hdlp,
4371 char *id,
4372 EObj_t **objpp)
4374 int32_t status;
4375 char buf[BUFSZ];
4376 EDigiSensor_t *dp;
4378 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4379 sizeof (EDigiSensor_t));
4380 if (status != PSVC_SUCCESS) {
4381 return (status);
4384 /* Load class specific info */
4385 dp = (EDigiSensor_t *)*objpp;
4386 if (i_psvc_value(buf, PSVC_LO_WARN_ATTR, &dp->lo_warn)
4387 != PSVC_SUCCESS) {
4388 i_psvc_destructor(hdlp, id, dp);
4389 return (PSVC_FAILURE);
4391 if (i_psvc_value(buf, PSVC_LO_SHUT_ATTR, &dp->lo_shut)
4392 != PSVC_SUCCESS) {
4393 i_psvc_destructor(hdlp, id, dp);
4394 return (PSVC_FAILURE);
4396 if (i_psvc_value(buf, PSVC_HI_WARN_ATTR, &dp->hi_warn)
4397 != PSVC_SUCCESS) {
4398 i_psvc_destructor(hdlp, id, dp);
4399 return (PSVC_FAILURE);
4401 if (i_psvc_value(buf, PSVC_HI_SHUT_ATTR, &dp->hi_shut)
4402 != PSVC_SUCCESS) {
4403 i_psvc_destructor(hdlp, id, dp);
4404 return (PSVC_FAILURE);
4407 dp->ld.constructor = i_psvc_constructor_4_0;
4408 dp->ld.destructor = i_psvc_destructor;
4409 dp->ld.get_attr = i_psvc_get_attr_4_0;
4410 dp->ld.set_attr = i_psvc_set_attr_generic;
4412 return (PSVC_SUCCESS);
4415 /* Digital Control */
4416 static int32_t
4417 i_psvc_constructor_5_0(
4418 EHdl_t *hdlp,
4419 char *id,
4420 EObj_t **objpp)
4422 int32_t status;
4423 char buf[BUFSZ];
4424 EDigiControl_t *dp;
4426 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4427 sizeof (EDigiControl_t));
4428 if (status != PSVC_SUCCESS)
4429 return (status);
4431 /* Load class specific info */
4432 dp = (EDigiControl_t *)*objpp;
4434 dp->ld.constructor = i_psvc_constructor_5_0;
4435 dp->ld.destructor = i_psvc_destructor;
4436 dp->ld.get_attr = i_psvc_get_attr_5_0;
4437 dp->ld.set_attr = i_psvc_set_attr_5_0;
4438 return (PSVC_SUCCESS);
4441 /* Boolean GPIO */
4442 static int32_t
4443 i_psvc_constructor_6_0(
4444 EHdl_t *hdlp,
4445 char *id,
4446 EObj_t **objpp)
4448 int32_t status;
4449 char buf[BUFSZ];
4450 EBoolSensor_t *dp;
4452 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4453 sizeof (EBoolSensor_t));
4454 if (status != PSVC_SUCCESS)
4455 return (status);
4457 /* Load class specific info */
4458 dp = (EBoolSensor_t *)*objpp;
4460 dp->ld.constructor = i_psvc_constructor_6_0;
4461 dp->ld.destructor = i_psvc_destructor;
4462 dp->ld.get_attr = i_psvc_get_attr_6_0;
4463 dp->ld.set_attr = i_psvc_set_attr_6_0;
4465 return (PSVC_SUCCESS);
4468 /* Fan Tachometer */
4469 static int32_t
4470 i_psvc_constructor_7_0(
4471 EHdl_t *hdlp,
4472 char *id,
4473 EObj_t **objpp)
4475 int32_t status;
4476 char buf[BUFSZ];
4477 EFanTach_t *dp;
4479 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4480 sizeof (EFanTach_t));
4481 if (status != PSVC_SUCCESS)
4482 return (status);
4484 /* Load class specific info */
4485 dp = (EFanTach_t *)*objpp;
4486 if (i_psvc_value(buf, PSVC_LO_WARN_ATTR, &dp->lo_warn)
4487 != PSVC_SUCCESS) {
4488 i_psvc_destructor(hdlp, id, dp);
4489 return (PSVC_FAILURE);
4491 if (i_psvc_value(buf, PSVC_LO_SHUT_ATTR, &dp->lo_shut)
4492 != PSVC_SUCCESS) {
4493 i_psvc_destructor(hdlp, id, dp);
4494 return (PSVC_FAILURE);
4496 if (i_psvc_value(buf, PSVC_HI_WARN_ATTR, &dp->hi_warn)
4497 != PSVC_SUCCESS) {
4498 i_psvc_destructor(hdlp, id, dp);
4499 return (PSVC_FAILURE);
4501 if (i_psvc_value(buf, PSVC_HI_SHUT_ATTR, &dp->hi_shut)
4502 != PSVC_SUCCESS) {
4503 i_psvc_destructor(hdlp, id, dp);
4504 return (PSVC_FAILURE);
4507 dp->ld.constructor = i_psvc_constructor_7_0;
4508 dp->ld.destructor = i_psvc_destructor;
4509 dp->ld.get_attr = i_psvc_get_attr_7_0;
4510 dp->ld.set_attr = i_psvc_set_attr_generic;
4512 return (PSVC_SUCCESS);
4515 /* On Off Switch */
4516 static int32_t
4517 i_psvc_constructor_8_0(
4518 EHdl_t *hdlp,
4519 char *id,
4520 EObj_t **objpp)
4522 int32_t status;
4523 char buf[BUFSZ];
4524 ESwitch_t *dp;
4526 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4527 sizeof (ESwitch_t));
4528 if (status != PSVC_SUCCESS)
4529 return (status);
4531 /* Load class specific info */
4532 dp = (ESwitch_t *)*objpp;
4534 dp->ld.constructor = i_psvc_constructor_8_0;
4535 dp->ld.destructor = i_psvc_destructor;
4536 dp->ld.get_attr = i_psvc_get_attr_8_0;
4537 dp->ld.set_attr = i_psvc_set_attr_8_0;
4539 return (PSVC_SUCCESS);
4542 /* Key Switch */
4543 static int32_t
4544 i_psvc_constructor_9_0(
4545 EHdl_t *hdlp,
4546 char *id,
4547 EObj_t **objpp)
4549 int32_t status;
4550 char buf[BUFSZ];
4551 EKeySwitch_t *dp;
4553 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4554 sizeof (EKeySwitch_t));
4555 if (status != PSVC_SUCCESS)
4556 return (status);
4558 /* Load class specific info */
4559 dp = (EKeySwitch_t *)*objpp;
4561 dp->ld.constructor = i_psvc_constructor_9_0;
4562 dp->ld.destructor = i_psvc_destructor;
4563 dp->ld.get_attr = i_psvc_get_attr_9_0;
4564 dp->ld.set_attr = i_psvc_set_attr_generic;
4566 return (PSVC_SUCCESS);
4569 /* 8 Bit GPIO , devices with registers, calls get_reg()/set_reg() */
4570 static int32_t
4571 i_psvc_constructor_10_0(
4572 EHdl_t *hdlp,
4573 char *id,
4574 EObj_t **objpp)
4576 int32_t status;
4577 char buf[BUFSZ];
4578 EGPIO8_t *dp;
4580 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EGPIO8_t));
4581 if (status != PSVC_SUCCESS)
4582 return (status);
4584 /* Load class specific info */
4585 dp = (EGPIO8_t *)*objpp;
4587 dp->ld.constructor = i_psvc_constructor_10_0;
4588 dp->ld.destructor = i_psvc_destructor;
4589 dp->ld.get_attr = i_psvc_get_attr_10_0;
4590 dp->ld.set_attr = i_psvc_set_attr_10_0;
4592 return (PSVC_SUCCESS);
4595 /* 8 Bit GPIO , devices with ports, calls get_port()/set_port() */
4596 static int32_t
4597 i_psvc_constructor_10_1(
4598 EHdl_t *hdlp,
4599 char *id,
4600 EObj_t **objpp)
4602 int32_t status;
4603 char buf[BUFSZ];
4604 EGPIO8_t *dp;
4606 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EGPIO8_t));
4607 if (status != PSVC_SUCCESS)
4608 return (status);
4610 /* Load class specific info */
4611 dp = (EGPIO8_t *)*objpp;
4613 dp->ld.constructor = i_psvc_constructor_10_1;
4614 dp->ld.destructor = i_psvc_destructor;
4615 dp->ld.get_attr = i_psvc_get_attr_10_1;
4616 dp->ld.set_attr = i_psvc_set_attr_10_1;
4618 return (PSVC_SUCCESS);
4621 /* AT24 */
4622 static int32_t
4623 i_psvc_constructor_11_0(
4624 EHdl_t *hdlp,
4625 char *id,
4626 EObj_t **objpp)
4628 int32_t status;
4629 char buf[BUFSZ];
4630 EPhysDev_t *dp;
4632 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4633 sizeof (EPhysDev_t));
4634 if (status != PSVC_SUCCESS)
4635 return (status);
4637 /* Load class specific info */
4638 dp = (EPhysDev_t *)*objpp;
4640 dp->ld.constructor = i_psvc_constructor_11_0;
4641 dp->ld.destructor = i_psvc_destructor;
4642 dp->ld.get_attr = i_psvc_get_attr_11_0;
4643 dp->ld.set_attr = i_psvc_set_attr_generic;
4644 dp->get_temperature = i_psvc_not_supported;
4645 dp->get_fanspeed = i_psvc_not_supported;
4646 dp->get_input = i_psvc_not_supported;
4647 dp->get_bit = i_psvc_not_supported;
4648 dp->set_bit = i_psvc_not_supported;
4649 dp->get_port = i_psvc_not_supported;
4650 dp->set_port = i_psvc_not_supported;
4651 dp->get_output = i_psvc_not_supported;
4652 dp->set_output = i_psvc_not_supported;
4653 dp->get_reg = i_psvc_get_reg_11_0;
4654 dp->set_reg = i_psvc_not_supported;
4656 return (PSVC_SUCCESS);
4659 /* HPC3130 */
4660 static int32_t
4661 i_psvc_constructor_11_1(
4662 EHdl_t *hdlp,
4663 char *id,
4664 EObj_t **objpp)
4666 int32_t status;
4667 char buf[BUFSZ];
4668 EPhysDev_t *dp;
4670 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4671 if (status != PSVC_SUCCESS)
4672 return (status);
4674 /* Load class specific info */
4675 dp = (EPhysDev_t *)*objpp;
4677 dp->ld.constructor = i_psvc_constructor_11_1;
4678 dp->ld.destructor = i_psvc_destructor;
4679 dp->ld.get_attr = i_psvc_get_attr_11_1;
4680 dp->ld.set_attr = i_psvc_set_attr_generic;
4681 dp->get_temperature = i_psvc_not_supported;
4682 dp->get_fanspeed = i_psvc_not_supported;
4683 dp->get_input = i_psvc_not_supported;
4684 dp->get_bit = i_psvc_not_supported;
4685 dp->set_bit = i_psvc_not_supported;
4686 dp->get_port = i_psvc_not_supported;
4687 dp->set_port = i_psvc_not_supported;
4688 dp->get_output = i_psvc_not_supported;
4689 dp->set_output = i_psvc_not_supported;
4690 dp->get_reg = i_psvc_get_reg_11_1;
4691 dp->set_reg = i_psvc_set_reg_11_1;
4693 return (PSVC_SUCCESS);
4696 /* LM75 */
4697 static int32_t
4698 i_psvc_constructor_11_2(
4699 EHdl_t *hdlp,
4700 char *id,
4701 EObj_t **objpp)
4703 int32_t status;
4704 char buf[BUFSZ];
4705 EPhysDev_t *dp;
4707 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4708 if (status != PSVC_SUCCESS)
4709 return (status);
4711 /* Load class specific info */
4712 dp = (EPhysDev_t *)*objpp;
4714 dp->ld.constructor = i_psvc_constructor_11_2;
4715 dp->ld.destructor = i_psvc_destructor;
4716 dp->ld.get_attr = i_psvc_get_attr_11_2;
4717 dp->ld.set_attr = i_psvc_set_attr_generic;
4718 dp->get_temperature = i_psvc_get_temperature_11_2;
4719 dp->get_fanspeed = i_psvc_not_supported;
4720 dp->get_input = i_psvc_not_supported;
4721 dp->get_bit = i_psvc_not_supported;
4722 dp->set_bit = i_psvc_not_supported;
4723 dp->get_port = i_psvc_not_supported;
4724 dp->set_port = i_psvc_not_supported;
4725 dp->get_output = i_psvc_not_supported;
4726 dp->set_output = i_psvc_not_supported;
4727 dp->get_reg = i_psvc_not_supported;
4728 dp->set_reg = i_psvc_not_supported;
4730 return (PSVC_SUCCESS);
4733 /* LTC1427 */
4734 static int32_t
4735 i_psvc_constructor_11_3(
4736 EHdl_t *hdlp,
4737 char *id,
4738 EObj_t **objpp)
4740 int32_t status;
4741 char buf[BUFSZ];
4742 EPhysDev_t *dp;
4743 char path[1024];
4745 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4746 if (status != PSVC_SUCCESS)
4747 return (status);
4750 * The following code upto and including the open() call is so the
4751 * device driver for the ltc1427 does not get unloaded by the OS at
4752 * any time. This is important as the device driver is a write only
4753 * physical device but DOES keep readable states in the device unitp
4754 * structure (I2C_GET_OUTPUT) as a result this device should not
4755 * be unload while PSVC is up and running
4757 status = i_psvc_get_devpath(hdlp, (*objpp)->addr_spec, path);
4758 if (status != PSVC_SUCCESS) {
4759 return (status);
4763 * We deliberately do not close our file handle, to prevent
4764 * any device instances from being detached. If an instance
4765 * is detached, the "readable states in the device unitp"
4766 * will be unloaded, causing loss of control of the device
4767 * and incorrect error(s) to be displayed.
4769 if (open(path, O_RDWR) == -1) {
4770 return (PSVC_FAILURE);
4772 /* Load class specific info */
4773 dp = (EPhysDev_t *)*objpp;
4775 dp->ld.constructor = i_psvc_constructor_11_3;
4776 dp->ld.destructor = i_psvc_destructor;
4777 dp->ld.get_attr = i_psvc_get_attr_11_3;
4778 dp->ld.set_attr = i_psvc_set_attr_generic;
4779 dp->get_temperature = i_psvc_not_supported;
4780 dp->get_fanspeed = i_psvc_not_supported;
4781 dp->get_input = i_psvc_not_supported;
4782 dp->get_bit = i_psvc_not_supported;
4783 dp->set_bit = i_psvc_not_supported;
4784 dp->get_port = i_psvc_not_supported;
4785 dp->set_port = i_psvc_not_supported;
4786 dp->get_output = i_psvc_get_output_11_3;
4787 dp->set_output = i_psvc_set_output_11_3;
4788 dp->get_reg = i_psvc_not_supported;
4789 dp->set_reg = i_psvc_not_supported;
4791 return (PSVC_SUCCESS);
4794 /* MAX1617 */
4795 static int32_t
4796 i_psvc_constructor_11_4(
4797 EHdl_t *hdlp,
4798 char *id,
4799 EObj_t **objpp)
4801 int32_t status;
4802 char buf[BUFSZ];
4803 EPhysDev_t *dp;
4805 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4806 if (status != PSVC_SUCCESS)
4807 return (status);
4809 /* Load class specific info */
4810 dp = (EPhysDev_t *)*objpp;
4812 dp->ld.constructor = i_psvc_constructor_11_4;
4813 dp->ld.destructor = i_psvc_destructor;
4814 dp->ld.get_attr = i_psvc_get_attr_11_4;
4815 dp->ld.set_attr = i_psvc_set_attr_generic;
4816 dp->get_temperature = i_psvc_get_temperature_11_4;
4817 dp->get_fanspeed = i_psvc_not_supported;
4818 dp->get_input = i_psvc_not_supported;
4819 dp->get_bit = i_psvc_not_supported;
4820 dp->set_bit = i_psvc_not_supported;
4821 dp->get_port = i_psvc_not_supported;
4822 dp->set_port = i_psvc_not_supported;
4823 dp->get_output = i_psvc_not_supported;
4824 dp->set_output = i_psvc_not_supported;
4825 dp->get_reg = i_psvc_not_supported;
4826 dp->set_reg = i_psvc_not_supported;
4828 return (PSVC_SUCCESS);
4831 /* PCF8574 */
4832 static int32_t
4833 i_psvc_constructor_11_5(
4834 EHdl_t *hdlp,
4835 char *id,
4836 EObj_t **objpp)
4838 int32_t status;
4839 char buf[BUFSZ];
4840 EPhysDev_t *dp;
4842 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4843 if (status != PSVC_SUCCESS)
4844 return (status);
4846 /* Load class specific info */
4847 dp = (EPhysDev_t *)*objpp;
4849 dp->ld.constructor = i_psvc_constructor_11_5;
4850 dp->ld.destructor = i_psvc_destructor;
4851 dp->ld.get_attr = i_psvc_get_attr_11_5;
4852 dp->ld.set_attr = i_psvc_set_attr_generic;
4853 dp->get_temperature = i_psvc_not_supported;
4854 dp->get_fanspeed = i_psvc_not_supported;
4855 dp->get_input = i_psvc_not_supported;
4856 dp->get_bit = i_psvc_get_bit_11_5;
4857 dp->set_bit = i_psvc_set_bit_11_5;
4858 dp->get_port = i_psvc_get_port_11_5;
4859 dp->set_port = i_psvc_set_port_11_5;
4860 dp->get_output = i_psvc_not_supported;
4861 dp->set_output = i_psvc_not_supported;
4862 dp->get_reg = i_psvc_not_supported;
4863 dp->set_reg = i_psvc_not_supported;
4865 return (PSVC_SUCCESS);
4868 /* PCF8591 */
4869 static int32_t
4870 i_psvc_constructor_11_6(
4871 EHdl_t *hdlp,
4872 char *id,
4873 EObj_t **objpp)
4875 int32_t status;
4876 char buf[BUFSZ];
4877 EPhysDev_t *dp;
4879 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4880 if (status != PSVC_SUCCESS)
4881 return (status);
4883 /* Load class specific info */
4884 dp = (EPhysDev_t *)*objpp;
4886 dp->ld.constructor = i_psvc_constructor_11_6;
4887 dp->ld.destructor = i_psvc_destructor;
4888 dp->ld.get_attr = i_psvc_get_attr_11_6;
4889 dp->ld.set_attr = i_psvc_set_attr_generic;
4890 dp->get_temperature = i_psvc_get_temperature_11_6;
4891 dp->get_fanspeed = i_psvc_not_supported;
4892 dp->get_input = i_psvc_get_input_11_6;
4893 dp->get_bit = i_psvc_not_supported;
4894 dp->set_bit = i_psvc_not_supported;
4895 dp->get_port = i_psvc_not_supported;
4896 dp->set_port = i_psvc_not_supported;
4897 dp->get_output = i_psvc_get_output_11_6;
4898 dp->set_output = i_psvc_set_output_11_6;
4899 dp->get_reg = i_psvc_not_supported;
4900 dp->set_reg = i_psvc_not_supported;
4902 return (PSVC_SUCCESS);
4905 /* SSC050 */
4906 static int32_t
4907 i_psvc_constructor_11_7(
4908 EHdl_t *hdlp,
4909 char *id,
4910 EObj_t **objpp)
4912 int32_t status;
4913 char buf[BUFSZ];
4914 EPhysDev_t *dp;
4916 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4917 if (status != PSVC_SUCCESS)
4918 return (status);
4920 /* Load class specific info */
4921 dp = (EPhysDev_t *)*objpp;
4923 dp->ld.constructor = i_psvc_constructor_11_7;
4924 dp->ld.destructor = i_psvc_destructor;
4925 dp->ld.get_attr = i_psvc_get_attr_11_7;
4926 dp->ld.set_attr = i_psvc_set_attr_generic;
4927 dp->get_temperature = i_psvc_not_supported;
4928 dp->get_fanspeed = i_psvc_get_fanspeed_11_7;
4929 dp->get_input = i_psvc_not_supported;
4930 dp->get_bit = i_psvc_get_bit_11_7;
4931 dp->set_bit = i_psvc_set_bit_11_7;
4932 dp->get_port = i_psvc_get_port_11_5; /* same as for class = 11, 5 */
4933 dp->set_port = i_psvc_set_port_11_5;
4934 dp->get_output = i_psvc_not_supported;
4935 dp->set_output = i_psvc_not_supported;
4936 dp->get_reg = i_psvc_get_reg_11_7;
4937 dp->set_reg = i_psvc_set_reg_11_7;
4939 return (PSVC_SUCCESS);
4942 /* TDA8444 */
4943 static int32_t
4944 i_psvc_constructor_11_8(
4945 EHdl_t *hdlp,
4946 char *id,
4947 EObj_t **objpp)
4949 int32_t status;
4950 char buf[BUFSZ];
4951 EPhysDev_t *dp;
4953 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4954 if (status != PSVC_SUCCESS)
4955 return (status);
4957 /* Load class specific info */
4958 dp = (EPhysDev_t *)*objpp;
4960 dp->ld.constructor = i_psvc_constructor_11_8;
4961 dp->ld.destructor = i_psvc_destructor;
4962 dp->ld.get_attr = i_psvc_get_attr_11_8;
4963 dp->ld.set_attr = i_psvc_set_attr_generic;
4964 dp->get_temperature = i_psvc_not_supported;
4965 dp->get_fanspeed = i_psvc_not_supported;
4966 dp->get_input = i_psvc_not_supported;
4967 dp->get_bit = i_psvc_not_supported;
4968 dp->set_bit = i_psvc_not_supported;
4969 dp->get_port = i_psvc_not_supported;
4970 dp->set_port = i_psvc_not_supported;
4971 dp->get_output = i_psvc_get_output_11_8;
4972 dp->set_output = i_psvc_set_output_11_8;
4973 dp->get_reg = i_psvc_not_supported;
4974 dp->set_reg = i_psvc_not_supported;
4976 return (PSVC_SUCCESS);
4979 /* SSC100 */
4980 static int32_t
4981 i_psvc_constructor_11_9(
4982 EHdl_t *hdlp,
4983 char *id,
4984 EObj_t **objpp)
4986 int32_t status;
4987 char buf[BUFSZ];
4988 EPhysDev_t *dp;
4990 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4991 if (status != PSVC_SUCCESS)
4992 return (status);
4994 /* Load class specific info */
4995 dp = (EPhysDev_t *)*objpp;
4997 dp->ld.constructor = i_psvc_constructor_11_9;
4998 dp->ld.destructor = i_psvc_destructor;
4999 dp->ld.get_attr = i_psvc_get_attr_11_9;
5000 dp->ld.set_attr = i_psvc_set_attr_generic;
5001 dp->get_temperature = i_psvc_not_supported;
5002 dp->get_fanspeed = i_psvc_not_supported;
5003 dp->get_input = i_psvc_not_supported;
5004 dp->get_bit = i_psvc_not_supported;
5005 dp->set_bit = i_psvc_not_supported;
5006 dp->get_port = i_psvc_get_port_11_5; /* Same as for class = 11, 5 */
5007 dp->set_port = i_psvc_set_port_11_5;
5008 dp->get_output = i_psvc_not_supported;
5009 dp->set_output = i_psvc_not_supported;
5010 dp->get_reg = i_psvc_not_supported;
5011 dp->set_reg = i_psvc_not_supported;
5013 return (PSVC_SUCCESS);
5016 int32_t
5017 psvc_init(EHdl_t **hdlpp)
5019 EHdl_t *hdlp;
5020 int i;
5021 char buf[BUFSZ];
5022 char platform[32];
5023 char filename[256];
5024 int found;
5025 int32_t status;
5026 pthread_mutexattr_t mutex_attr;
5027 uint32_t table_count;
5028 int forward_slash = 47;
5029 int new_line = 10;
5030 char *nl_char;
5032 hdlp = (EHdl_t *)malloc(sizeof (EHdl_t));
5033 if (hdlp == NULL)
5034 return (-1);
5035 memset(hdlp, 0, sizeof (EHdl_t));
5037 /* Initialize the lock */
5038 status = pthread_mutexattr_init(&mutex_attr);
5039 if (status != 0) {
5040 errno = status;
5041 return (-1);
5043 status = pthread_mutex_init(&hdlp->mutex, &mutex_attr);
5044 if (status != 0) {
5045 errno = status;
5046 return (-1);
5048 pthread_mutexattr_destroy(&mutex_attr);
5050 if (sysinfo(SI_PLATFORM, platform, sizeof (platform)) == -1) {
5051 return (-1);
5054 snprintf(filename, sizeof (filename),
5055 "/usr/platform/%s/lib/psvcobj.conf", platform);
5056 if ((hdlp->fp = fopen(filename, "r")) == NULL) {
5057 return (-1);
5061 /* Build the association ID lookup table */
5063 hdlp->othr_count = hdlp->assoc_count = ASSOC_STR_TAB_SIZE;
5064 if ((hdlp->othr_tbl = (EStringId_t *)malloc(sizeof (EStringId_t) *
5065 hdlp->othr_count)) == NULL) {
5066 return (-1);
5069 for (i = 0; i < hdlp->othr_count; ++i) {
5070 hdlp->othr_tbl[i].id = i;
5071 strcpy(hdlp->othr_tbl[i].name, assoc_str_tab[i]);
5073 qsort(hdlp->othr_tbl, hdlp->othr_count, sizeof (EStringId_t),
5074 (int (*)(const void *, const void *))i_psvc_name_compare_qsort);
5076 /* determine total number of objects + tables */
5077 if (i_psvc_find_file_section(hdlp->fp, "OBJECT_INFO") == -1) {
5078 return (-1);
5080 if (i_psvc_count_records(hdlp->fp, "OBJECT_INFO_END",
5081 &hdlp->total_obj_count) == -1) {
5082 return (-1);
5084 if (i_psvc_find_file_section(hdlp->fp, "TABLES") == PSVC_SUCCESS) {
5085 status = i_psvc_count_tables_associations(hdlp->fp,
5086 &table_count, "TABLE_END");
5087 if (status == PSVC_FAILURE) {
5088 return (status);
5090 hdlp->total_obj_count += table_count;
5093 /* Allocate object name to object pointer translation table */
5094 for (i = 0; i < PSVC_MAX_TABLE_ARRAYS; i++) {
5095 if ((hdlp->tbl_arry[i].obj_tbl =
5096 (ENamePtr_t *)malloc(
5097 sizeof (ENamePtr_t) *hdlp->total_obj_count)) == NULL) {
5098 return (-1);
5100 memset(hdlp->tbl_arry[i].obj_tbl, 0,
5101 sizeof (ENamePtr_t) * hdlp->total_obj_count);
5102 hdlp->tbl_arry[i].obj_count = 0;
5105 /* Build the association table */
5106 if (i_psvc_load_associations(hdlp, hdlp->fp) == -1)
5107 return (-1);
5109 /* Build the table of device paths */
5110 if (i_psvc_find_file_section(hdlp->fp, "DEVPATHS") == -1)
5111 return (-1);
5112 if (i_psvc_count_records(hdlp->fp, "DEVPATHS_END",
5113 &hdlp->dev_count) == -1)
5114 return (-1);
5115 if ((hdlp->dev_tbl = (EDevice_t *)malloc(sizeof (EDevice_t) *
5116 hdlp->dev_count)) == NULL) {
5117 return (-1);
5119 for (i = 0; i < hdlp->dev_count; ++i) {
5120 fgets(buf, BUFSZ, hdlp->fp);
5121 found = sscanf(buf, "%d %d %x %d",
5122 &hdlp->dev_tbl[i].controller,
5123 &hdlp->dev_tbl[i].bus, &hdlp->dev_tbl[i].addr,
5124 &hdlp->dev_tbl[i].port);
5125 if (found != 4) {
5126 errno = EINVAL;
5127 return (-1);
5129 strcpy(hdlp->dev_tbl[i].path, strchr(buf, forward_slash));
5131 * Replace new line character with NUL character
5133 nl_char = strchr(hdlp->dev_tbl[i].path, new_line);
5134 *nl_char = 0;
5137 /* Build the table of tables */
5138 if (i_psvc_load_tables(hdlp, hdlp->fp) == -1)
5139 return (-1);
5140 *hdlpp = hdlp;
5141 return (0);
5144 int32_t
5145 psvc_fini(EHdl_t *hdlp)
5147 int32_t i, j;
5148 ETable_Array *array;
5150 if (hdlp == 0)
5151 return (PSVC_SUCCESS);
5153 for (j = 0; j < PSVC_MAX_TABLE_ARRAYS; j++) {
5154 if (hdlp->tbl_arry[j].obj_tbl != 0) {
5155 array = &(hdlp->tbl_arry[j]);
5156 for (i = 0; i < array->obj_count; ++i) {
5157 if (array->obj_tbl[i].type == PSVC_OBJ) {
5158 if (!array->obj_tbl[i].objp) {
5159 /* Skip non-existent object */
5160 continue;
5162 array->obj_tbl[i].objp->destructor(hdlp,
5163 array->obj_tbl[i].objp->label,
5164 array->obj_tbl[i].objp);
5167 if (array->obj_tbl[i].type == PSVC_TBL) {
5168 ETable_t *tblp =
5169 (ETable_t *)array->obj_tbl[i].objp;
5170 if (tblp->table != 0)
5171 free(tblp->table);
5175 free(array->obj_tbl);
5179 if (hdlp->othr_tbl != 0)
5180 free(hdlp->othr_tbl);
5182 if (hdlp->assoc_tbl != 0) {
5183 for (i = 0; i < hdlp->assoc_count; ++i) {
5184 if (hdlp->assoc_tbl[i].table != 0)
5185 free(hdlp->assoc_tbl[i].table);
5187 free(hdlp->assoc_tbl);
5190 if (hdlp->dev_tbl != 0)
5191 free(hdlp->dev_tbl);
5192 if (hdlp->fp != 0)
5193 fclose(hdlp->fp);
5194 pthread_mutex_destroy(&hdlp->mutex);
5195 free(hdlp);
5196 return (PSVC_SUCCESS);
5199 int32_t
5200 ioctl_retry(int fp, int request, void * arg_pointer)
5202 int32_t ret = PSVC_SUCCESS;
5203 int32_t tries = 0;
5206 * Becuase the i2c bus is a multimaster bus we need to protect
5207 * ourselves from bus masters that are not being good bus citizens.
5208 * A retry number of 10 should be sufficient to handle any bad bus
5209 * citizens. After that we will simply say that there is something
5210 * wrong with the ioctl transaction and let it bubble back up.
5212 do {
5213 ret = ioctl(fp, request, arg_pointer);
5214 tries ++;
5215 } while ((ret == -1) && (tries < 10));
5217 return (ret);
5220 static int32_t
5221 psvc_get_str_key(char *object)
5223 int32_t key = 0;
5224 int i, length;
5226 length = strlen(object);
5227 for (i = 0; i < length; i++) {
5228 if ((object[i] > 47) && (object[i] < 58)) {
5229 key = key + ((object[i] - 50) + 2);
5230 } else {
5231 key = key + object[i];
5236 return (key);