cmd: remove sparc-only virtinfo
[unleashed.git] / usr / src / cmd / picl / plugins / sun4u / psvc / psvcobj / psvcobj.c
blobffe7703695c659d1d790e0250f3231555bc1f377
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.
28 * This file consists of routines to manage objects in the
29 * "Platform Environment Services Framework". The classes
30 * and subclasses are defined by attributes and methods.
31 * The objects, and their initial, static, attribute values are
32 * specified in a configuration file, "psvcobj.conf".
33 * psvc_init() reads the configuration file and creates a repository
34 * of environmental objects in memory. A client application may manipulate
35 * these objects by invoking the psvc_get_attr(), and psvc_set_attr()
36 * routines with the object's string ID specified as an argument.
38 #include <stdio.h>
39 #include <math.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42 #include <stropts.h>
43 #include <string.h>
44 #include <errno.h>
45 #include <fcntl.h>
46 #include <pthread.h>
47 #include <syslog.h>
48 #include <stdarg.h>
49 #include <pthread.h>
50 #include <sys/systeminfo.h>
52 #define LIBRARY_BUILD 1
53 #include <psvc_objects.h>
54 #include <psvc_objects_class.h>
55 #include <sys/i2c/clients/i2c_client.h>
57 /* Mutex used for Daktari Fan speed reading */
58 pthread_mutex_t fan_mutex = PTHREAD_MUTEX_INITIALIZER;
60 /*LINTLIBRARY*/
62 #define ENV_DEBUG(str, id) printf("%s id %s\n", (str), (id))
64 #define BUFSZ 512
66 #define CLASS_MAX 12
67 #define SUBCLASS_MAX 10
69 static int32_t i_psvc_constructor_0_0(EHdl_t *, char *, EObj_t **);
70 static int32_t i_psvc_constructor_0_1(EHdl_t *, char *, EObj_t **);
71 static int32_t i_psvc_constructor_1_0(EHdl_t *, char *, EObj_t **);
72 static int32_t i_psvc_constructor_2_0(EHdl_t *, char *, EObj_t **);
73 static int32_t i_psvc_constructor_2_1(EHdl_t *, char *, EObj_t **);
74 static int32_t i_psvc_constructor_2_2(EHdl_t *, char *, EObj_t **);
75 static int32_t i_psvc_constructor_3_0(EHdl_t *, char *, EObj_t **);
76 static int32_t i_psvc_constructor_4_0(EHdl_t *, char *, EObj_t **);
77 static int32_t i_psvc_constructor_5_0(EHdl_t *, char *, EObj_t **);
78 static int32_t i_psvc_constructor_6_0(EHdl_t *, char *, EObj_t **);
79 static int32_t i_psvc_constructor_7_0(EHdl_t *, char *, EObj_t **);
80 static int32_t i_psvc_constructor_8_0(EHdl_t *, char *, EObj_t **);
81 static int32_t i_psvc_constructor_9_0(EHdl_t *, char *, EObj_t **);
82 static int32_t i_psvc_constructor_10_0(EHdl_t *, char *, EObj_t **);
83 static int32_t i_psvc_constructor_10_1(EHdl_t *, char *, EObj_t **);
84 static int32_t i_psvc_constructor_11_0(EHdl_t *, char *, EObj_t **);
85 static int32_t i_psvc_constructor_11_1(EHdl_t *, char *, EObj_t **);
86 static int32_t i_psvc_constructor_11_2(EHdl_t *, char *, EObj_t **);
87 static int32_t i_psvc_constructor_11_3(EHdl_t *, char *, EObj_t **);
88 static int32_t i_psvc_constructor_11_4(EHdl_t *, char *, EObj_t **);
89 static int32_t i_psvc_constructor_11_5(EHdl_t *, char *, EObj_t **);
90 static int32_t i_psvc_constructor_11_6(EHdl_t *, char *, EObj_t **);
91 static int32_t i_psvc_constructor_11_7(EHdl_t *, char *, EObj_t **);
92 static int32_t i_psvc_constructor_11_8(EHdl_t *, char *, EObj_t **);
93 static int32_t i_psvc_constructor_11_9(EHdl_t *, char *, EObj_t **);
95 static int32_t i_psvc_get_obj(EHdl_t *, char *, EObj_t **);
96 static int32_t i_psvc_destructor(EHdl_t *, char *, void *);
97 static int32_t i_psvc_get_devpath(EHdl_t *, uint64_t, char *);
98 static int32_t i_psvc_get_attr_generic(EHdl_t *, EObj_t *, int32_t, void *);
99 static int32_t i_psvc_get_attr_6_0(EHdl_t *, EObj_t *, int32_t, void *);
100 static int32_t i_psvc_get_reg_11_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id,
101 void *attrp);
102 static int32_t i_psvc_get_attr_10_1(EHdl_t *, EObj_t *, int32_t, void *);
103 static int32_t psvc_get_str_key(char *object);
105 int32_t ioctl_retry(int fp, int request, void * arg_pointer);
108 * Method lookup tables
109 * Update when adding classes or subclasses.
113 /* Lookup method by class, subclass, used when calling method */
114 static int32_t (*i_psvc_constructor[CLASS_MAX][SUBCLASS_MAX])(EHdl_t *,
115 char *, EObj_t **) = {
116 {i_psvc_constructor_0_0, i_psvc_constructor_0_1, 0, 0, 0, 0, 0, 0, 0, 0},
117 {i_psvc_constructor_1_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
118 {i_psvc_constructor_2_0, i_psvc_constructor_2_1, i_psvc_constructor_2_2,
119 0, 0, 0, 0, 0, 0, 0},
120 {i_psvc_constructor_3_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
121 {i_psvc_constructor_4_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
122 {i_psvc_constructor_5_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
123 {i_psvc_constructor_6_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
124 {i_psvc_constructor_7_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
125 {i_psvc_constructor_8_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
126 {i_psvc_constructor_9_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
127 {i_psvc_constructor_10_0, i_psvc_constructor_10_1, 0, 0, 0, 0, 0, 0, 0, 0},
128 {i_psvc_constructor_11_0, i_psvc_constructor_11_1, i_psvc_constructor_11_2,
129 i_psvc_constructor_11_3, i_psvc_constructor_11_4,
130 i_psvc_constructor_11_5, i_psvc_constructor_11_6,
131 i_psvc_constructor_11_7, i_psvc_constructor_11_8,
132 i_psvc_constructor_11_9},
135 static int32_t i_psvc_cell_size[8] = {1, 1, 2, 2, 4, 4, 8, 8};
137 static struct bits {
138 uint64_t bit;
139 char *label;
140 } feature_bits[] = {
141 {PSVC_DEV_PERM, "PERM="},
142 {PSVC_DEV_HOTPLUG, "HOTPLUG="},
143 {PSVC_DEV_OPTION, "OPTION="},
144 {PSVC_DEV_PRIMARY, "PRIMARY="},
145 {PSVC_DEV_SECONDARY, "SECONDARY="},
146 {PSVC_DEV_RDONLY, "RDONLY="},
147 {PSVC_DEV_RDWR, "RDWR="},
148 {PSVC_DEV_FRU, "FRU="},
149 {PSVC_LOW_WARN, "LO_WARN_MASK="},
150 {PSVC_LOW_SHUT, "LO_SHUT_MASK="},
151 {PSVC_HIGH_WARN, "HI_WARN_MASK="},
152 {PSVC_HIGH_SHUT, "HI_SHUT_MASK="},
153 {PSVC_CONVERSION_TABLE, "CONV_TABLE="},
154 {PSVC_OPT_TEMP, "OPT_TEMP_MASK="},
155 {PSVC_HW_LOW_SHUT, "HW_LO_MASK="},
156 {PSVC_HW_HIGH_SHUT, "HW_HI_MASK="},
157 {PSVC_FAN_DRIVE_PR, "FAN_DRIVE_PR="},
158 {PSVC_TEMP_DRIVEN, "TEMP_DRIVEN="},
159 {PSVC_SPEED_CTRL_PR, "SPEED_CTRL_PR="},
160 {PSVC_FAN_ON_OFF, "FAN_ON_OFF="},
161 {PSVC_CLOSED_LOOP_CTRL, "CLOSED_LOOP_CTRL="},
162 {PSVC_FAN_DRIVE_TABLE_PR, "FAN_DRIVE_TABLE_PR="},
163 {PSVC_DIE_TEMP, "DIE_TEMP="},
164 {PSVC_AMB_TEMP, "AMB_TEMP="},
165 {PSVC_DIGI_SENSOR, "DIGI_SENSOR="},
166 {PSVC_BI_STATE, "BI_STATE="},
167 {PSVC_TRI_STATE, "TRI_STATE="},
168 {PSVC_GREEN, "GREEN="},
169 {PSVC_AMBER, "AMBER="},
170 {PSVC_OUTPUT, "OUTPUT="},
171 {PSVC_INPUT, "INPUT="},
172 {PSVC_BIDIR, "BIDIR="},
173 {PSVC_BIT_POS, "BIT_POS="},
174 {PSVC_VAL_POS, "VAL_POS="},
175 {PSVC_NORMAL_POS_AV, "NORMAL_POS_AV="},
176 {PSVC_DIAG_POS_AV, "DIAG_POS_AV="},
177 {PSVC_LOCK_POS_AV, "LOCK_POS_AV="},
178 {PSVC_OFF_POS_AV, "OFF_POS_AV="},
179 {PSVC_GPIO_PORT, "GPIO_PORT="},
180 {PSVC_GPIO_REG, "GPIO_REG="}
183 #define ASSOC_STR_TAB_SIZE 33
184 static char *assoc_str_tab[] = {
185 "PSVC_PRESENCE_SENSOR", /* 0 */
186 "PSVC_FAN_ONOFF_SENSOR", /* 1 */
187 "PSVC_FAN_SPEED_TACHOMETER", /* 2 */
188 "PSVC_FAN_PRIM_SEC_SELECTOR", /* 3 */
189 "PSVC_DEV_TEMP_SENSOR", /* 4 */
190 "PSVC_FAN_DRIVE_CONTROL", /* 5 */
191 "PSVC_KS_NORMAL_POS_SENSOR", /* 6 */
192 "PSVC_KS_DIAG_POS_SENSOR", /* 7 */
193 "PSVC_KS_LOCK_POS_SENSOR", /* 8 */
194 "PSVC_KS_OFF_POS_SENSOR", /* 9 */
195 "PSVC_SLOT_FAULT_LED", /* 10 */
196 "PSVC_SLOT_REMOVE_LED", /* 11 */
197 "PSVC_TS_OVERTEMP_LED", /* 12 */
198 "PSVC_PS_I_SENSOR", /* 13 */
199 "PSVC_DEV_FAULT_SENSOR", /* 14 */
200 "PSVC_DEV_FAULT_LED", /* 15 */
201 "PSVC_TABLE", /* 16 */
202 "PSVC_PARENT", /* 17 */
203 "PSVC_CPU", /* 18 */
204 "PSVC_ALTERNATE", /* 19 */
205 "PSVC_HOTPLUG_ENABLE_SWITCH", /* 20 */
206 "PSVC_PS", /* 21 */
207 "PSVC_FAN", /* 22 */
208 "PSVC_TS", /* 23 */
209 "PSVC_DISK", /* 24 */
210 "PSVC_LED", /* 25 */
211 "PSVC_FSP_LED", /* 26 */
212 "PSVC_KEYSWITCH", /* 27 */
213 "PSVC_PCI_CARD", /* 28 */
214 "PSVC_PHYSICAL_DEVICE", /* 29 */
215 "PSVC_DEV_TYPE_SENSOR", /* 30 */
216 "PSVC_FAN_TRAY_FANS", /* 31 */
217 "PSVC_FRU" /* 32 */
220 #define FEATURE_BITS (sizeof (feature_bits) / sizeof (struct bits))
222 static struct bitfield {
223 int8_t shift;
224 char *label;
225 char *format;
226 } addr_fields[] =
228 {PSVC_VERSION_SHIFT, "VERSION=", "%d"},
229 {PSVC_ACTIVE_LOW_SHIFT, "ACTIVE_LOW=", "%d"},
230 {PSVC_BIT_NUM_SHIFT, "BIT_NUM=", "%d"},
231 {PSVC_INVERT_SHIFT, "INVERT=", "%d"},
232 {PSVC_PORT_SHIFT, "PORT=", "%d"},
233 {PSVC_BITSHIFT_SHIFT, "BITSHIFT=", "%d"},
234 {PSVC_BYTEMASK_SHIFT, "BYTEMASK=", "%x"},
235 {PSVC_REG_SHIFT, "REG=", "%d"},
236 {PSVC_TYPE_SHIFT, "TYPE=", "%d"},
237 {PSVC_BUSADDR_SHIFT, "BUSADDR=", "%x"},
238 {PSVC_BUSNUM_SHIFT, "BUSNUM=", "%d"},
239 {PSVC_CNTLR_SHIFT, "CNTLR=", "%d"},
241 #define ADDR_BITFIELDS (sizeof (addr_fields) / sizeof (struct bitfield))
244 * record format is:
245 * pathname label1=val1,label2=val2,label3=val3
246 * Must be a space after the pathname and a comma between variables.
249 static char *
250 find_label(char *str, char *label)
252 char *start;
254 start = strchr(str, ' ');
255 if (start == NULL)
256 return (start);
258 do {
259 ++start;
260 if (strncmp(start, label, strlen(label)) == 0)
261 return (start);
263 start = strchr(start, ',');
264 } while (start != NULL);
266 return (NULL);
269 static int32_t
270 i_psvc_value(char *buf, int32_t attr_id, void *attrp)
272 char *val;
273 uint32_t temp32;
274 uint64_t temp64;
275 uint64_t result;
276 int32_t i;
277 int32_t found;
278 char label[64];
279 int val_size;
280 int label_size;
283 switch (attr_id) {
284 case PSVC_CLASS_ATTR:
285 case PSVC_SUBCLASS_ATTR:
286 case PSVC_INSTANCE_ATTR:
287 case PSVC_LO_WARN_ATTR:
288 case PSVC_LO_SHUT_ATTR:
289 case PSVC_HI_WARN_ATTR:
290 case PSVC_HI_SHUT_ATTR:
291 case PSVC_HW_HI_SHUT_ATTR:
292 case PSVC_HW_LO_SHUT_ATTR:
293 case PSVC_OPTIMAL_TEMP_ATTR:
294 snprintf(label, sizeof (label), "%s=", attr_str_tab[attr_id]);
295 val = find_label(buf, label);
296 if (val == NULL) {
297 errno = EINVAL;
298 return (PSVC_FAILURE);
300 found = sscanf(val + strlen(label),
301 "%d", (int32_t *)attrp);
302 if (found == 0)
303 *(int32_t *)attrp = 0;
304 break;
305 case PSVC_SETPOINT_ATTR:
306 case PSVC_HYSTERESIS_ATTR:
307 case PSVC_LOOPGAIN_ATTR:
308 case PSVC_LOOPBIAS_ATTR:
309 snprintf(label, sizeof (label), "%s=", attr_str_tab[attr_id]);
310 val = find_label(buf, label);
311 if (val == NULL) {
312 errno = EINVAL;
313 return (PSVC_FAILURE);
316 found = sscanf(val + strlen(label), "%hd", (int16_t *)attrp);
317 if (found == 0)
318 *(int16_t *)attrp = 0;
319 break;
320 case PSVC_LED_COLOR_ATTR:
321 case PSVC_LED_IS_LOCATOR_ATTR:
322 case PSVC_LED_LOCATOR_NAME_ATTR:
323 snprintf(label, sizeof (label), "%s=", attr_str_tab[attr_id]);
324 val = find_label(buf, label);
325 if (val == NULL) {
326 errno = EINVAL;
327 return (PSVC_FAILURE);
329 val_size = strlen(val);
330 label_size = strlen(label);
332 for (i = 0; i < val_size && val[i] != ','; i++);
333 if (i < strlen(val) - 1) {
334 strncpy((char *)attrp, val+label_size,
335 i - label_size);
336 } else
337 found = sscanf(val + label_size, "%s", (char *)attrp);
338 if (found == 0)
339 strcpy((char *)attrp, "");
340 break;
341 case PSVC_FEATURES_ATTR:
342 result = 0;
343 for (i = 0; i < FEATURE_BITS; ++i) {
344 val = find_label(buf, feature_bits[i].label);
345 if (val == NULL)
346 continue;
347 found = sscanf(val + strlen(feature_bits[i].label),
348 "%d", &temp32);
349 if (found != 0) {
350 if (temp32 == 1)
351 result |= feature_bits[i].bit;
354 *(uint64_t *)attrp = result;
355 break;
356 case PSVC_ADDR_SPEC_ATTR:
357 result = 0;
358 for (i = 0; i < ADDR_BITFIELDS; ++i) {
359 val = find_label(buf, addr_fields[i].label);
360 if (val == NULL)
361 continue;
362 found = sscanf(val + strlen(addr_fields[i].label),
363 addr_fields[i].format, &temp32);
364 if (found != 0) {
365 temp64 = temp32;
366 temp64 <<= addr_fields[i].shift;
367 result |= temp64;
370 *(uint64_t *)attrp = result;
371 break;
372 default:
373 errno = EINVAL;
374 return (PSVC_FAILURE);
376 return (PSVC_SUCCESS);
379 /* determine number of records in file section */
380 static int32_t
381 i_psvc_count_records(FILE *fp, char *end, uint32_t *countp)
383 long first_record;
384 char *ret;
385 char buf[BUFSZ];
386 uint32_t count = 0;
388 first_record = ftell(fp);
390 while ((ret = fgets(buf, BUFSZ, fp)) != NULL) {
391 if (strncmp(end, buf, strlen(end)) == 0)
392 break;
393 ++count;
396 if (ret == NULL) {
397 errno = EINVAL;
398 return (PSVC_FAILURE);
401 fseek(fp, first_record, SEEK_SET);
402 *countp = count;
403 return (PSVC_SUCCESS);
406 /* determine number of records in file section */
407 static int32_t
408 i_psvc_count_tables_associations(FILE *fp, uint32_t *countp, char *end)
410 long first_record;
411 char *ret;
412 char buf[BUFSZ];
413 uint32_t count = 0;
415 first_record = ftell(fp);
417 while ((ret = fgets(buf, BUFSZ, fp)) != NULL) {
418 if (strncmp(end, buf, strlen(end)) == 0)
419 ++count;
422 fseek(fp, first_record, SEEK_SET);
423 *countp = count;
424 return (PSVC_SUCCESS);
427 /* determine number of records in a table */
428 static int32_t
429 i_psvc_count_table_records(FILE *fp, char *end, uint32_t *countp)
431 long first_record;
432 int ret;
433 char string[BUFSZ];
434 uint32_t count = 0;
436 first_record = ftell(fp);
438 while ((ret = fscanf(fp, "%s", string)) == 1) {
439 if (strncmp(end, string, strlen(end)) == 0)
440 break;
441 ++count;
444 if (ret != 1) {
445 errno = EINVAL;
446 return (PSVC_FAILURE);
449 fseek(fp, first_record, SEEK_SET);
450 *countp = count;
451 return (PSVC_SUCCESS);
455 * Find number of matches to an antecedent_id of a certain
456 * association type.
458 static int32_t
459 i_psvc_get_assoc_matches(EHdl_t *hdlp, char *antecedent, int32_t assoc_id,
460 int32_t *matches)
462 int i;
463 int32_t key;
464 EAssocList_t *ap = hdlp->assoc_tbl + assoc_id;
466 *matches = 0;
468 if (ap->table == 0) {
469 errno = EINVAL;
470 return (PSVC_FAILURE);
473 key = psvc_get_str_key(antecedent);
475 for (i = 0; i < ap->count; ++i) {
476 if (ap->table[i].ant_key == key) {
477 if (strcmp(ap->table[i].antecedent_id, antecedent)
478 == 0)
479 ++*matches;
482 return (PSVC_SUCCESS);
486 * Find 1st m matches to an antecedent_id of a certain
487 * association type.
488 * Returns zero for success, -1 for failure.
490 static int32_t
491 i_psvc_get_assoc_id(EHdl_t *hdlp, char *antecedent, int32_t assoc_id,
492 int32_t match, char **id_list)
494 int i;
495 int found = 0;
496 int32_t key;
497 EAssocList_t *ap = &hdlp->assoc_tbl[assoc_id];
499 if (ap->table == 0) {
500 errno = EINVAL;
501 return (-1);
504 key = psvc_get_str_key(antecedent);
506 for (i = 0; i < ap->count; ++i) {
507 if (ap->table[i].ant_key == key) {
508 if (strcmp(ap->table[i].antecedent_id, antecedent)
509 == 0) {
510 if (found == match) {
511 *id_list = ap->table[i].dependent_id;
512 return (0);
514 ++found;
519 errno = EINVAL;
520 return (-1);
523 static int32_t
524 i_psvc_get_table_value(EHdl_t *hdlp, char *table_id, uint32_t index,
525 void *value)
527 int32_t i;
528 ETable_t *tblp;
529 ETable_Array *tbl_arr;
530 int32_t key, array;
532 key = psvc_get_str_key(table_id);
533 array = key % PSVC_MAX_TABLE_ARRAYS;
534 tbl_arr = &(hdlp->tbl_arry[array]);
536 for (i = 0; i < tbl_arr->obj_count; ++i) {
537 if (key == tbl_arr->obj_tbl[i].key) {
538 if (strcmp(tbl_arr->obj_tbl[i].name,
539 table_id) == 0)
540 break;
544 if (tbl_arr->obj_tbl[i].type != PSVC_TBL)
545 return (PSVC_FAILURE);
547 tblp = (ETable_t *)tbl_arr->obj_tbl[i].objp;
549 if (tblp->table == NULL)
550 return (PSVC_FAILURE);
552 if (index >= tblp->size)
553 return (PSVC_FAILURE);
555 switch (tblp->cell_type) {
556 case 0:
557 *(int8_t *)value = *((int8_t *)tblp->table + index);
558 break;
559 case 1:
560 *(uint8_t *)value = *((uint8_t *)tblp->table + index);
561 break;
562 case 2:
563 *(int16_t *)value = *((int16_t *)tblp->table + index);
564 break;
565 case 3:
566 *(uint16_t *)value = *((uint16_t *)tblp->table + index);
567 break;
568 case 4:
569 *(int32_t *)value = *((int32_t *)tblp->table + index);
570 break;
571 case 5:
572 *(uint32_t *)value = *((uint32_t *)tblp->table + index);
573 break;
574 case 6:
575 *(int64_t *)value = *((int64_t *)tblp->table + index);
576 break;
577 case 7:
578 *(uint64_t *)value = *((uint64_t *)tblp->table + index);
579 break;
580 default:
581 return (PSVC_FAILURE);
584 return (PSVC_SUCCESS);
587 int32_t
588 psvc_get_attr(EHdl_t *hdlp, char *name, int32_t attr_id, void *attr_valuep, ...)
590 EObj_t *objp;
591 int32_t status = PSVC_SUCCESS;
592 int32_t arg1, arg2;
593 va_list ap;
595 pthread_mutex_lock(&hdlp->mutex);
597 if (attr_valuep == NULL) {
598 errno = EFAULT;
599 pthread_mutex_unlock(&hdlp->mutex);
600 return (PSVC_FAILURE);
603 switch (attr_id) {
604 case PSVC_TABLE_VALUE_ATTR:
605 va_start(ap, attr_valuep);
606 status = i_psvc_get_table_value(hdlp, name,
607 va_arg(ap, uint32_t), attr_valuep);
608 va_end(ap);
609 break;
610 case PSVC_ASSOC_MATCHES_ATTR:
611 va_start(ap, attr_valuep);
612 status = i_psvc_get_assoc_matches(hdlp, name,
613 va_arg(ap, int32_t), attr_valuep);
614 va_end(ap);
615 break;
616 case PSVC_ASSOC_ID_ATTR:
617 va_start(ap, attr_valuep);
618 arg1 = va_arg(ap, int32_t);
619 arg2 = va_arg(ap, int32_t);
620 status = i_psvc_get_assoc_id(hdlp, name,
621 arg1, arg2, attr_valuep);
622 va_end(ap);
623 break;
624 default:
625 status = i_psvc_get_obj(hdlp, name, &objp);
626 if (status != PSVC_SUCCESS) {
627 pthread_mutex_unlock(&hdlp->mutex);
628 return (status);
630 status = (*objp->get_attr)(hdlp, objp, attr_id,
631 attr_valuep);
634 if (status != PSVC_SUCCESS) {
635 pthread_mutex_unlock(&hdlp->mutex);
636 return (status);
639 pthread_mutex_unlock(&hdlp->mutex);
640 return (status);
643 int32_t
644 psvc_set_attr(EHdl_t *hdlp, char *name, int32_t attr_id, void *attr_valuep)
646 EObj_t *objp;
647 int32_t status = PSVC_SUCCESS;
649 pthread_mutex_lock(&hdlp->mutex);
650 status = i_psvc_get_obj(hdlp, name, &objp);
651 if (status != PSVC_SUCCESS) {
652 pthread_mutex_unlock(&hdlp->mutex);
653 return (status);
656 if (attr_valuep == NULL) {
657 errno = EFAULT;
658 pthread_mutex_unlock(&hdlp->mutex);
659 return (PSVC_FAILURE);
662 status = (*objp->set_attr)(hdlp, objp, attr_id, attr_valuep);
663 if (status != PSVC_SUCCESS) {
664 pthread_mutex_unlock(&hdlp->mutex);
665 return (status);
668 pthread_mutex_unlock(&hdlp->mutex);
669 return (status);
673 static int32_t
674 i_psvc_get_presence(EHdl_t *hdlp, EObj_t *objp, boolean_t *pr)
676 EObj_t *pobjp, *mobjp;
677 int32_t matches;
678 char *mid;
679 char *parent_id;
680 int32_t status = PSVC_SUCCESS;
681 uint8_t value_8bit, value_8bit_inv;
682 boolean_t active_low, value;
684 if (strcmp(objp->label, PSVC_CHASSIS) == 0) {
685 *pr = PSVC_PRESENT;
686 objp->present = PSVC_PRESENT;
687 return (PSVC_SUCCESS);
690 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PARENT, 0,
691 &parent_id);
692 if (status != PSVC_SUCCESS)
693 return (status);
695 if (strcmp(parent_id, PSVC_CHASSIS)) {
696 status = i_psvc_get_obj(hdlp, parent_id, &pobjp);
697 if (status != PSVC_SUCCESS)
698 return (status);
699 if (!pobjp->present) {
700 pobjp->get_attr(hdlp, pobjp, PSVC_PRESENCE_ATTR, pr);
701 *pr = pobjp->present;
702 objp->present = pobjp->present;
703 return (status);
707 (void) i_psvc_get_assoc_matches(hdlp, objp->label,
708 PSVC_PRESENCE_SENSOR, &matches);
710 if (matches != 0) {
711 status = i_psvc_get_assoc_id(hdlp, objp->label,
712 PSVC_PRESENCE_SENSOR, 0, &mid);
713 if (status != PSVC_SUCCESS)
714 return (status);
715 status = i_psvc_get_obj(hdlp, mid, &mobjp);
716 if (status != PSVC_SUCCESS)
717 return (status);
719 active_low = PSVC_IS_ACTIVE_LOW(mobjp->addr_spec);
721 if (mobjp->class == PSVC_BOOLEAN_GPIO_CLASS) {
722 status = mobjp->get_attr(hdlp, mobjp,
723 PSVC_GPIO_VALUE_ATTR, &value);
724 if (status != PSVC_SUCCESS)
725 return (status);
726 if (active_low)
727 if (value == 0)
728 *pr = PSVC_PRESENT;
729 else
730 *pr = PSVC_ABSENT;
731 else
732 if (value == 0)
733 *pr = PSVC_ABSENT;
734 else
735 *pr = PSVC_PRESENT;
736 } else if (mobjp->class == PSVC_8BIT_GPIO_CLASS) {
737 uint8_t bitshift, bytemask;
739 status = mobjp->get_attr(hdlp, mobjp,
740 PSVC_GPIO_VALUE_ATTR, &value_8bit);
741 if (status != PSVC_SUCCESS)
742 return (status);
743 if (PSVC_HP_INVERT(mobjp->addr_spec))
744 value_8bit_inv = ~value_8bit;
745 else
746 value_8bit_inv = value_8bit;
747 bitshift = PSVC_GET_ASPEC_BITSHIFT(mobjp->addr_spec);
748 bytemask = PSVC_GET_ASPEC_BYTEMASK(mobjp->addr_spec);
749 value_8bit_inv =
750 value_8bit_inv & (bytemask >> bitshift);
751 if (active_low)
752 if (value_8bit_inv == 0)
753 *pr = PSVC_PRESENT;
754 else
755 *pr = PSVC_ABSENT;
756 else
757 if (value_8bit_inv == 0)
758 *pr = PSVC_ABSENT;
759 else
760 *pr = PSVC_PRESENT;
761 } else {
762 errno = EINVAL;
763 return (PSVC_FAILURE);
765 } else {
766 *pr = PSVC_PRESENT;
769 objp->present = *pr;
771 return (status);
774 static int32_t
775 i_psvc_get_device_value_0_0(EHdl_t *hdlp, EObj_t *objp, int32_t *temp)
777 int32_t status = PSVC_SUCCESS, m;
778 char *tid;
779 int16_t temp16;
780 char *physid;
781 EObj_t *physobjp;
783 if (objp->present != PSVC_PRESENT) {
784 errno = ENODEV;
785 return (PSVC_FAILURE);
788 status = i_psvc_get_assoc_id(
789 hdlp, objp->label, PSVC_PHYSICAL_DEVICE, 0, &physid);
790 if (status != PSVC_SUCCESS) {
791 return (status);
793 status = i_psvc_get_obj(hdlp, physid, &physobjp);
794 if (status != PSVC_SUCCESS) {
795 return (status);
798 status = ((EPhysDev_t *)physobjp)->get_temperature(hdlp,
799 objp->addr_spec, temp);
800 if (status != PSVC_SUCCESS) {
801 return (status);
804 if (objp->features & PSVC_CONVERSION_TABLE) {
805 status = i_psvc_get_assoc_matches(hdlp, objp->label,
806 PSVC_TABLE, &m);
807 if ((status != PSVC_SUCCESS) || (m != 1)) {
808 return (status);
811 (void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
812 &tid);
814 status = i_psvc_get_table_value(hdlp, tid, *temp, &temp16);
815 *temp = temp16;
817 return (status);
820 static int32_t
821 i_psvc_get_device_value_0_1(EHdl_t *hdlp, EObj_t *objp, int32_t *temp)
823 int32_t status = PSVC_SUCCESS, m;
824 char *tid;
825 int16_t temp16;
826 char *physid;
827 EObj_t *physobjp;
829 if (objp->present != PSVC_PRESENT) {
830 errno = ENODEV;
831 return (PSVC_FAILURE);
834 status = i_psvc_get_assoc_id(
835 hdlp, objp->label, PSVC_PHYSICAL_DEVICE, 0, &physid);
836 if (status != PSVC_SUCCESS) {
837 return (status);
839 status = i_psvc_get_obj(hdlp, physid, &physobjp);
840 if (status != PSVC_SUCCESS) {
841 return (status);
844 status = ((EPhysDev_t *)physobjp)->get_temperature(hdlp,
845 objp->addr_spec, temp);
846 if (status != PSVC_SUCCESS) {
847 return (status);
850 if (objp->features & PSVC_CONVERSION_TABLE) {
851 status = i_psvc_get_assoc_matches(hdlp, objp->label,
852 PSVC_TABLE, &m);
853 if ((status != PSVC_SUCCESS) || (m != 1)) {
854 return (status);
857 (void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
858 &tid);
860 status = i_psvc_get_table_value(hdlp, tid, *temp, &temp16);
861 *temp = temp16;
863 return (status);
866 static int32_t
867 i_psvc_get_device_value_4_0(EHdl_t *hdlp, EObj_t *objp, int32_t *value)
869 int32_t status = PSVC_SUCCESS;
870 char *physid;
871 EObj_t *physobjp;
873 if (objp->present != PSVC_PRESENT) {
874 errno = ENODEV;
875 return (PSVC_FAILURE);
878 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
879 0, &physid);
880 if (status != PSVC_SUCCESS)
881 return (status);
882 status = i_psvc_get_obj(hdlp, physid, &physobjp);
883 if (status != PSVC_SUCCESS)
884 return (status);
886 status = ((EPhysDev_t *)physobjp)->get_input(hdlp, objp->addr_spec,
887 value);
888 if (status != PSVC_SUCCESS)
889 return (status);
891 if (objp->features & PSVC_CONVERSION_TABLE) {
892 int32_t m;
893 char *tid;
894 int16_t temp16;
896 status = i_psvc_get_assoc_matches(hdlp, objp->label,
897 PSVC_TABLE, &m);
898 if ((status != PSVC_SUCCESS) || (m != 1)) {
899 return (status);
902 (void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
903 &tid);
905 status = i_psvc_get_table_value(hdlp, tid, *value, &temp16);
906 *value = temp16;
909 return (status);
912 static int32_t
913 i_psvc_set_device_value_5_0(EHdl_t *hdlp, EObj_t *objp, int32_t *value)
915 int32_t status = PSVC_SUCCESS;
916 char *physid;
917 EObj_t *physobjp;
919 if (objp->present != PSVC_PRESENT) {
920 errno = ENODEV;
921 return (PSVC_FAILURE);
924 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
925 0, &physid);
926 if (status != PSVC_SUCCESS)
927 return (status);
928 status = i_psvc_get_obj(hdlp, physid, &physobjp);
929 if (status != PSVC_SUCCESS)
930 return (status);
931 status = ((EPhysDev_t *)physobjp)->set_output(hdlp, objp->addr_spec,
932 *value);
933 if (status != PSVC_SUCCESS)
934 return (status);
936 return (status);
939 static int32_t
940 i_psvc_get_device_value_5_0(EHdl_t *hdlp, EObj_t *objp, int32_t *value)
942 int32_t status = PSVC_SUCCESS;
943 char *physid;
944 EObj_t *physobjp;
946 if (objp->present != PSVC_PRESENT) {
947 errno = ENODEV;
948 return (PSVC_FAILURE);
951 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
952 0, &physid);
953 if (status != PSVC_SUCCESS)
954 return (status);
955 status = i_psvc_get_obj(hdlp, physid, &physobjp);
956 if (status != PSVC_SUCCESS)
957 return (status);
959 status = ((EPhysDev_t *)physobjp)->get_output(hdlp, objp->addr_spec,
960 value);
961 if (status != PSVC_SUCCESS)
962 return (status);
964 if (objp->features & PSVC_CONVERSION_TABLE) {
965 int32_t m;
966 char *tid;
967 int16_t temp16;
969 status = i_psvc_get_assoc_matches(hdlp, objp->label,
970 PSVC_TABLE, &m);
971 if ((status != PSVC_SUCCESS) || (m != 1)) {
972 return (status);
975 (void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
976 &tid);
978 status = i_psvc_get_table_value(hdlp, tid, *value, &temp16);
979 *value = temp16;
981 return (status);
984 static int32_t
985 i_psvc_get_device_value_6_0(EHdl_t *hdlp, EObj_t *objp, boolean_t *value)
987 int32_t status = PSVC_SUCCESS;
988 int32_t bit_value;
989 char *physid;
990 EObj_t *physobjp;
992 if (objp->present != PSVC_PRESENT) {
993 errno = ENODEV;
994 return (PSVC_FAILURE);
997 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
998 0, &physid);
999 if (status != PSVC_SUCCESS)
1000 return (status);
1001 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1002 if (status != PSVC_SUCCESS)
1003 return (status);
1005 status = ((EPhysDev_t *)physobjp)->get_bit(hdlp, objp->addr_spec,
1006 &bit_value);
1007 if (status != PSVC_SUCCESS)
1008 return (status);
1010 *value = bit_value;
1012 return (status);
1015 static int32_t
1016 i_psvc_set_device_value_6_0(EHdl_t *hdlp, EObj_t *objp, boolean_t *value)
1018 int32_t status = PSVC_SUCCESS;
1019 int32_t bit_value;
1020 char *physid;
1021 EObj_t *physobjp;
1023 if (objp->present != PSVC_PRESENT) {
1024 errno = ENODEV;
1025 return (PSVC_FAILURE);
1028 bit_value = *value;
1029 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1030 0, &physid);
1031 if (status != PSVC_SUCCESS)
1032 return (status);
1033 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1034 if (status != PSVC_SUCCESS)
1035 return (status);
1037 status = ((EPhysDev_t *)physobjp)->set_bit(hdlp, objp->addr_spec,
1038 bit_value);
1039 if (status != PSVC_SUCCESS)
1040 return (status);
1042 return (status);
1045 static int32_t
1046 i_psvc_get_device_value_1_0(EHdl_t *hdlp, EObj_t *objp, int32_t *fan_speed)
1048 int32_t status = PSVC_SUCCESS;
1049 EObj_t *ftobjp;
1050 char *fan_tach;
1052 if (objp->present != PSVC_PRESENT) {
1053 errno = ENODEV;
1054 return (PSVC_FAILURE);
1057 status = i_psvc_get_assoc_id(hdlp, objp->label,
1058 PSVC_FAN_SPEED_TACHOMETER, 0, &fan_tach);
1059 if (status != PSVC_SUCCESS)
1060 return (status);
1062 status = i_psvc_get_obj(hdlp, fan_tach, &ftobjp);
1063 if (status != PSVC_SUCCESS)
1064 return (status);
1066 status = ftobjp->get_attr(hdlp, ftobjp, PSVC_SENSOR_VALUE_ATTR,
1067 fan_speed);
1068 if (status != PSVC_SUCCESS)
1069 return (status);
1071 return (status);
1074 static int32_t
1075 i_psvc_get_device_value_7_0(EHdl_t *hdlp, EObj_t *objp, int32_t *fan_speed)
1077 char *physid;
1078 EObj_t *physobjp;
1079 int32_t status = PSVC_SUCCESS;
1081 if (objp->present != PSVC_PRESENT) {
1082 errno = ENODEV;
1083 return (PSVC_FAILURE);
1086 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1087 0, &physid);
1088 if (status != PSVC_SUCCESS)
1089 return (status);
1090 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1091 if (status != PSVC_SUCCESS)
1092 return (status);
1094 status = ((EPhysDev_t *)physobjp)->get_fanspeed(hdlp, objp->addr_spec,
1095 fan_speed);
1096 if (status != PSVC_SUCCESS)
1097 return (status);
1099 if (objp->features & PSVC_CONVERSION_TABLE) {
1100 int32_t m;
1101 char *tid;
1102 int16_t temp16;
1104 status = i_psvc_get_assoc_matches(hdlp, objp->label,
1105 PSVC_TABLE, &m);
1106 if ((status != PSVC_SUCCESS) || (m != 1)) {
1107 return (status);
1110 (void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
1111 &tid);
1113 status = i_psvc_get_table_value(hdlp, tid, *fan_speed, &temp16);
1114 *fan_speed = temp16;
1116 return (status);
1119 static int32_t
1120 i_psvc_get_device_state_2_0(EHdl_t *hdlp, EObj_t *objp, char *led_state)
1122 int32_t status = PSVC_SUCCESS;
1123 int32_t bit_value;
1124 boolean_t active_low;
1125 char *physid;
1126 EObj_t *physobjp;
1128 if (objp->present != PSVC_PRESENT) {
1129 errno = ENODEV;
1130 return (PSVC_FAILURE);
1133 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1134 0, &physid);
1135 if (status != PSVC_SUCCESS)
1136 return (status);
1137 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1138 if (status != PSVC_SUCCESS)
1139 return (status);
1141 status = ((EPhysDev_t *)physobjp)->get_bit(hdlp, objp->addr_spec,
1142 &bit_value);
1143 if (status != PSVC_SUCCESS)
1144 return (status);
1146 active_low = PSVC_IS_ACTIVE_LOW(objp->addr_spec);
1147 if (active_low)
1148 if (bit_value == 0)
1149 strcpy(led_state, PSVC_LED_ON);
1150 else
1151 strcpy(led_state, PSVC_LED_OFF);
1152 else
1153 if (bit_value == 0)
1154 strcpy(led_state, PSVC_LED_OFF);
1155 else
1156 strcpy(led_state, PSVC_LED_ON);
1158 return (status);
1161 static int32_t
1162 i_psvc_set_device_state_2_0(EHdl_t *hdlp, EObj_t *objp, char *led_state)
1164 int32_t status = PSVC_SUCCESS;
1165 boolean_t active_low;
1166 int32_t bit_value;
1167 char *physid;
1168 EObj_t *physobjp;
1170 if (objp->present != PSVC_PRESENT) {
1171 errno = ENODEV;
1172 return (PSVC_FAILURE);
1175 if (strcmp(((ELed_t *)objp)->is_locator, PSVC_LOCATOR_TRUE) != 0) {
1177 * For Locator LEDs we ignore lit_count. RSC may have
1178 * altered the LED state underneath us, So we should
1179 * always just do what the user asked instead of trying
1180 * to be smart.
1183 if (strcmp(led_state, PSVC_LED_ON) == 0)
1184 ((ELed_t *)objp)->lit_count++;
1185 else if (strcmp(led_state, PSVC_LED_OFF) == 0) {
1186 if (--((ELed_t *)objp)->lit_count > 0) {
1187 return (PSVC_SUCCESS);
1188 } else if (((ELed_t *)objp)->lit_count < 0)
1189 ((ELed_t *)objp)->lit_count = 0;
1190 /* Fall through case is when lit_count is 0 */
1194 strcpy(objp->previous_state, objp->state);
1195 strcpy(objp->state, led_state);
1197 bit_value = (strcmp(led_state, PSVC_LED_ON) == 0);
1200 * Flip the bit if necessary (for active_low devices,
1201 * O ==> ON; 1 ==> OFF.
1203 active_low = PSVC_IS_ACTIVE_LOW(objp->addr_spec);
1204 bit_value ^= active_low;
1206 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1207 0, &physid);
1208 if (status != PSVC_SUCCESS)
1209 return (status);
1210 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1211 if (status != PSVC_SUCCESS)
1212 return (status);
1214 status = ((EPhysDev_t *)physobjp)->set_bit(hdlp, objp->addr_spec,
1215 bit_value);
1216 return (status);
1219 static int32_t
1220 i_psvc_get_device_state_2_1(EHdl_t *hdlp, EObj_t *objp, char *led_state)
1222 int32_t status = PSVC_SUCCESS;
1223 uint8_t value;
1224 char *physid;
1225 EObj_t *physobjp;
1227 if (objp->present != PSVC_PRESENT) {
1228 errno = ENODEV;
1229 return (PSVC_FAILURE);
1232 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1233 0, &physid);
1234 if (status != PSVC_SUCCESS)
1235 return (status);
1236 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1237 if (status != PSVC_SUCCESS)
1238 return (status);
1240 status = ((EPhysDev_t *)physobjp)->get_reg(hdlp, objp->addr_spec,
1241 &value);
1242 if (status != PSVC_SUCCESS)
1243 return (status);
1245 switch (value) {
1246 case 0:
1247 strcpy(led_state, PSVC_LED_OFF);
1248 break;
1249 case 1:
1250 strcpy(led_state, PSVC_LED_SLOW_BLINK);
1251 break;
1252 case 2:
1253 strcpy(led_state, PSVC_LED_FAST_BLINK);
1254 break;
1255 case 3:
1256 strcpy(led_state, PSVC_LED_ON);
1257 break;
1260 return (status);
1263 static int32_t
1264 i_psvc_set_device_state_2_1(EHdl_t *hdlp, EObj_t *objp, char *led_state)
1266 int32_t status = PSVC_SUCCESS;
1267 uint8_t value;
1268 char *physid;
1269 EObj_t *physobjp;
1271 if (objp->present != PSVC_PRESENT) {
1272 errno = ENODEV;
1273 return (PSVC_FAILURE);
1276 if (strcmp(led_state, PSVC_LED_ON) == 0)
1277 ((ELed_t *)objp)->lit_count++;
1278 else if (strcmp(led_state, PSVC_LED_OFF) == 0) {
1279 if (--((ELed_t *)objp)->lit_count > 0) {
1280 return (PSVC_SUCCESS);
1281 } else if (((ELed_t *)objp)->lit_count < 0)
1282 ((ELed_t *)objp)->lit_count = 0;
1284 /* Fall through case is when lit_count is 0 */
1287 strcpy(objp->previous_state, objp->state);
1288 strcpy(objp->state, led_state);
1290 if (strcmp(led_state, PSVC_LED_OFF) == 0)
1291 value = 0;
1292 else if (strcmp(led_state, PSVC_LED_SLOW_BLINK) == 0)
1293 value = 1;
1294 else if (strcmp(led_state, PSVC_LED_FAST_BLINK) == 0)
1295 value = 2;
1296 else if (strcmp(led_state, PSVC_LED_ON) == 0)
1297 value = 3;
1299 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1300 0, &physid);
1301 if (status != PSVC_SUCCESS)
1302 return (status);
1303 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1304 if (status != PSVC_SUCCESS)
1305 return (status);
1307 status = ((EPhysDev_t *)physobjp)->set_reg(hdlp, objp->addr_spec,
1308 value);
1310 return (status);
1313 static int32_t
1314 i_psvc_get_device_state_9_0(EHdl_t *hdlp, EObj_t *objp, char *pos)
1316 int32_t status = PSVC_SUCCESS, matches;
1317 char *sensorid;
1318 EObj_t *sensorp;
1319 char state[32];
1321 if (objp->present != PSVC_PRESENT) {
1322 errno = ENODEV;
1323 return (PSVC_FAILURE);
1326 if (objp->features & PSVC_NORMAL_POS_AV) {
1327 (void) i_psvc_get_assoc_matches(hdlp, objp->label,
1328 PSVC_KS_NORMAL_POS_SENSOR, &matches);
1329 if (matches == 1) {
1330 status = i_psvc_get_assoc_id(hdlp, objp->label,
1331 PSVC_KS_NORMAL_POS_SENSOR, 0, &sensorid);
1332 if (status != PSVC_SUCCESS)
1333 return (status);
1335 status = i_psvc_get_obj(hdlp, sensorid, &sensorp);
1336 if (status != PSVC_SUCCESS)
1337 return (status);
1339 status = sensorp->get_attr(hdlp, sensorp,
1340 PSVC_SWITCH_STATE_ATTR, state);
1341 if (status != PSVC_SUCCESS)
1342 return (status);
1344 if (strcmp(state, PSVC_SWITCH_ON) == 0) {
1345 strcpy(pos, PSVC_NORMAL_POS);
1346 return (PSVC_SUCCESS);
1351 if (objp->features & PSVC_DIAG_POS_AV) {
1352 (void) i_psvc_get_assoc_matches(hdlp, objp->label,
1353 PSVC_KS_DIAG_POS_SENSOR, &matches);
1354 if (matches == 1) {
1355 status = i_psvc_get_assoc_id(hdlp, objp->label,
1356 PSVC_KS_DIAG_POS_SENSOR, 0, &sensorid);
1357 if (status != PSVC_SUCCESS)
1358 return (status);
1360 status = i_psvc_get_obj(hdlp, sensorid, &sensorp);
1361 if (status != PSVC_SUCCESS)
1362 return (status);
1364 status = sensorp->get_attr(hdlp, sensorp,
1365 PSVC_SWITCH_STATE_ATTR, state);
1366 if (status != PSVC_SUCCESS)
1367 return (status);
1369 if (strcmp(state, PSVC_SWITCH_ON) == 0) {
1370 strcpy(pos, PSVC_DIAG_POS);
1371 return (PSVC_SUCCESS);
1376 if (objp->features & PSVC_LOCK_POS_AV) {
1377 (void) i_psvc_get_assoc_matches(hdlp, objp->label,
1378 PSVC_KS_LOCK_POS_SENSOR, &matches);
1379 if (matches == 1) {
1380 status = i_psvc_get_assoc_id(hdlp, objp->label,
1381 PSVC_KS_LOCK_POS_SENSOR, 0, &sensorid);
1382 if (status != PSVC_SUCCESS)
1383 return (status);
1385 status = i_psvc_get_obj(hdlp, sensorid, &sensorp);
1386 if (status != PSVC_SUCCESS)
1387 return (status);
1389 status = sensorp->get_attr(hdlp, sensorp,
1390 PSVC_SWITCH_STATE_ATTR, state);
1391 if (status != PSVC_SUCCESS)
1392 return (status);
1394 if (strcmp(state, PSVC_SWITCH_ON) == 0) {
1395 strcpy(pos, PSVC_LOCKED_POS);
1396 return (PSVC_SUCCESS);
1401 if (objp->features & PSVC_OFF_POS_AV) {
1402 (void) i_psvc_get_assoc_matches(hdlp, objp->label,
1403 PSVC_KS_OFF_POS_SENSOR, &matches);
1404 if (matches == 1) {
1405 status = i_psvc_get_assoc_id(hdlp, objp->label,
1406 PSVC_KS_OFF_POS_SENSOR, 0, &sensorid);
1407 if (status != PSVC_SUCCESS)
1408 return (status);
1410 status = i_psvc_get_obj(hdlp, sensorid, &sensorp);
1411 if (status != PSVC_SUCCESS)
1412 return (status);
1414 status = sensorp->get_attr(hdlp, sensorp,
1415 PSVC_SWITCH_STATE_ATTR, state);
1416 if (status != PSVC_SUCCESS)
1417 return (status);
1419 if (strcmp(state, PSVC_SWITCH_ON) == 0) {
1420 strcpy(pos, PSVC_OFF_POS);
1421 return (PSVC_SUCCESS);
1425 /* If we have fallen through till here, something's wrong */
1426 errno = EINVAL;
1427 return (PSVC_FAILURE);
1431 static int32_t
1432 i_psvc_get_device_value_10_0(EHdl_t *hdlp, EObj_t *objp, uint8_t *value)
1434 int32_t status = PSVC_SUCCESS;
1435 char *physid;
1436 EObj_t *physobjp;
1438 if (objp->present != PSVC_PRESENT) {
1439 errno = ENODEV;
1440 return (PSVC_FAILURE);
1443 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1444 0, &physid);
1445 if (status != PSVC_SUCCESS)
1446 return (status);
1447 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1448 if (status != PSVC_SUCCESS)
1449 return (status);
1451 status = ((EPhysDev_t *)physobjp)->get_reg(hdlp, objp->addr_spec,
1452 value);
1453 if (status != PSVC_SUCCESS)
1454 return (status);
1456 if (objp->features & PSVC_CONVERSION_TABLE) {
1457 int32_t m;
1458 char *tid;
1459 uint8_t temp8;
1461 status = i_psvc_get_assoc_matches(hdlp, objp->label,
1462 PSVC_TABLE, &m);
1463 if ((status != PSVC_SUCCESS) || (m != 1)) {
1464 return (status);
1467 (void) i_psvc_get_assoc_id(hdlp, objp->label,
1468 PSVC_TABLE, 0, &tid);
1470 status = i_psvc_get_table_value(hdlp, tid, *value, &temp8);
1471 *value = temp8;
1473 return (status);
1476 static int32_t
1477 i_psvc_get_device_value_10_1(EHdl_t *hdlp, EObj_t *objp, uint8_t *value)
1479 int32_t status = PSVC_SUCCESS;
1480 char *physid;
1481 EObj_t *physobjp;
1483 if (objp->present != PSVC_PRESENT) {
1484 errno = ENODEV;
1485 return (PSVC_FAILURE);
1488 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1489 0, &physid);
1490 if (status != PSVC_SUCCESS)
1491 return (status);
1492 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1493 if (status != PSVC_SUCCESS)
1494 return (status);
1496 status = ((EPhysDev_t *)physobjp)->get_port(hdlp, objp->addr_spec,
1497 value);
1498 if (status != PSVC_SUCCESS)
1499 return (status);
1501 return (status);
1504 static int32_t
1505 i_psvc_set_device_value_10_0(EHdl_t *hdlp, EObj_t *objp, uint8_t *value)
1507 int32_t status = PSVC_SUCCESS;
1508 char *physid;
1509 EObj_t *physobjp;
1511 if (objp->present != PSVC_PRESENT) {
1512 errno = ENODEV;
1513 return (PSVC_FAILURE);
1516 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1517 0, &physid);
1518 if (status != PSVC_SUCCESS)
1519 return (status);
1520 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1521 if (status != PSVC_SUCCESS)
1522 return (status);
1524 status = ((EPhysDev_t *)physobjp)->set_reg(hdlp, objp->addr_spec,
1525 *value);
1526 return (status);
1529 static int32_t
1530 i_psvc_set_device_value_10_1(EHdl_t *hdlp, EObj_t *objp, uint8_t *value)
1532 int32_t status = PSVC_SUCCESS;
1533 char *physid;
1534 EObj_t *physobjp;
1536 if (objp->present != PSVC_PRESENT) {
1537 errno = ENODEV;
1538 return (PSVC_FAILURE);
1541 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1542 0, &physid);
1543 if (status != PSVC_SUCCESS)
1544 return (status);
1545 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1546 if (status != PSVC_SUCCESS)
1547 return (status);
1549 status = ((EPhysDev_t *)physobjp)->set_port(hdlp, objp->addr_spec,
1550 *value);
1551 return (status);
1554 static int32_t
1555 i_psvc_get_device_state_8_0(EHdl_t *hdlp, EObj_t *objp, char *sw_state)
1557 int32_t status = PSVC_SUCCESS;
1558 boolean_t active_low;
1559 int32_t bit_value;
1560 char *physid;
1561 EObj_t *physobjp;
1563 if (objp->present != PSVC_PRESENT) {
1564 errno = ENODEV;
1565 return (PSVC_FAILURE);
1568 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1569 0, &physid);
1570 if (status != PSVC_SUCCESS)
1571 return (status);
1572 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1573 if (status != PSVC_SUCCESS)
1574 return (status);
1576 status = ((EPhysDev_t *)physobjp)->get_bit(hdlp, objp->addr_spec,
1577 &bit_value);
1578 if (status != PSVC_SUCCESS)
1579 return (status);
1581 active_low = PSVC_IS_ACTIVE_LOW(objp->addr_spec);
1582 if (active_low)
1583 if (bit_value == 0)
1584 strcpy(sw_state, PSVC_SWITCH_ON);
1585 else
1586 strcpy(sw_state, PSVC_SWITCH_OFF);
1587 else
1588 if (bit_value == 0)
1589 strcpy(sw_state, PSVC_SWITCH_OFF);
1590 else
1591 strcpy(sw_state, PSVC_SWITCH_ON);
1593 return (status);
1596 static int32_t
1597 i_psvc_set_device_state_8_0(EHdl_t *hdlp, EObj_t *objp, char *sw_state)
1599 int32_t status = PSVC_SUCCESS;
1600 boolean_t active_low;
1601 int32_t bit_value;
1602 char *physid;
1603 EObj_t *physobjp;
1605 if (objp->present != PSVC_PRESENT) {
1606 errno = ENODEV;
1607 return (PSVC_FAILURE);
1610 strcpy(objp->previous_state, objp->state);
1611 strcpy(objp->state, sw_state);
1613 active_low = PSVC_IS_ACTIVE_LOW(objp->addr_spec);
1615 if (active_low)
1616 if (strcmp(sw_state, PSVC_SWITCH_ON) == 0)
1617 bit_value = 0;
1618 else
1619 bit_value = 1;
1620 else
1621 if (strcmp(sw_state, PSVC_SWITCH_ON) == 0)
1622 bit_value = 1;
1623 else
1624 bit_value = 0;
1626 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1627 0, &physid);
1628 if (status != PSVC_SUCCESS)
1629 return (status);
1630 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1631 if (status != PSVC_SUCCESS)
1632 return (status);
1634 status = ((EPhysDev_t *)physobjp)->set_bit(hdlp, objp->addr_spec,
1635 bit_value);
1636 return (status);
1639 /* LM75 */
1640 static int32_t
1641 i_psvc_get_temperature_11_2(EHdl_t *hdlp, uint64_t aspec, int32_t *temp)
1643 int32_t status = PSVC_SUCCESS;
1644 char path[1024];
1645 int32_t fp;
1646 int16_t temp16;
1648 status = i_psvc_get_devpath(hdlp, aspec, path);
1649 if (status != PSVC_SUCCESS)
1650 return (status);
1652 fp = open(path, O_RDWR);
1653 if (fp == -1)
1654 return (PSVC_FAILURE);
1656 status = ioctl_retry(fp, I2C_GET_TEMPERATURE, (void *)&temp16);
1657 if (status == -1) {
1658 close(fp);
1659 errno = EIO;
1660 return (PSVC_FAILURE);
1662 *temp = temp16;
1664 close(fp);
1666 return (status);
1669 /* MAX1617 */
1670 static int32_t
1671 i_psvc_get_temperature_11_4(EHdl_t *hdlp, uint64_t aspec, int32_t *temp)
1673 int32_t status = PSVC_SUCCESS;
1674 char path[1024];
1675 int32_t fp;
1676 int16_t temp16;
1678 status = i_psvc_get_devpath(hdlp, aspec, path);
1679 if (status != PSVC_SUCCESS)
1680 return (status);
1682 fp = open(path, O_RDWR);
1683 if (fp == -1)
1684 return (PSVC_FAILURE);
1686 status = ioctl_retry(fp, I2C_GET_TEMPERATURE, (void *)&temp16);
1687 if (status == -1) {
1688 close(fp);
1689 errno = EIO;
1690 return (PSVC_FAILURE);
1692 *temp = temp16;
1694 close(fp);
1696 return (status);
1699 /* PCF8591 */
1700 static int32_t
1701 i_psvc_get_temperature_11_6(EHdl_t *hdlp, uint64_t aspec, int32_t *temp)
1703 int32_t status = PSVC_SUCCESS;
1704 char path[1024];
1705 int32_t fp;
1707 status = i_psvc_get_devpath(hdlp, aspec, path);
1708 if (status != PSVC_SUCCESS)
1709 return (status);
1711 fp = open(path, O_RDWR);
1712 if (fp == -1)
1713 return (PSVC_FAILURE);
1715 status = ioctl_retry(fp, I2C_GET_INPUT, (void *)temp);
1716 if (status == -1) {
1717 close(fp);
1718 errno = EIO;
1719 return (-1);
1722 close(fp);
1724 return (status);
1727 /* SSC050 */
1728 static int32_t
1729 i_psvc_get_fanspeed_11_7(EHdl_t *hdlp, uint64_t aspec, int32_t *fan_speed)
1731 int32_t ret, status = PSVC_SUCCESS;
1732 char path[1024];
1733 int32_t fp;
1735 status = i_psvc_get_devpath(hdlp, aspec, path);
1736 if (status != PSVC_SUCCESS)
1737 return (status);
1739 fp = open(path, O_RDWR);
1740 if (fp == -1)
1741 return (PSVC_FAILURE);
1743 ret = ioctl_retry(fp, I2C_GET_FAN_SPEED, (void *)fan_speed);
1744 if (ret == -1) {
1745 close(fp);
1746 errno = EIO;
1747 return (-1);
1750 close(fp);
1752 return (status);
1755 /* PCF8591 */
1756 static int32_t
1757 i_psvc_get_input_11_6(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
1759 int32_t ret, status = PSVC_SUCCESS;
1760 char path[1024];
1761 int32_t fp;
1763 status = i_psvc_get_devpath(hdlp, aspec, path);
1764 if (status != PSVC_SUCCESS)
1765 return (status);
1767 fp = open(path, O_RDWR);
1768 if (fp == -1)
1769 return (PSVC_FAILURE);
1771 ret = ioctl_retry(fp, I2C_GET_INPUT, (void *)value);
1772 if (ret == -1) {
1773 close(fp);
1774 errno = EIO;
1775 return (-1);
1778 close(fp);
1780 return (status);
1783 /* LTC1427 */
1784 static int32_t
1785 i_psvc_get_output_11_3(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
1787 int32_t ret, status = PSVC_SUCCESS;
1788 char path[1024];
1789 int32_t fp;
1791 status = i_psvc_get_devpath(hdlp, aspec, path);
1792 if (status != PSVC_SUCCESS)
1793 return (status);
1795 fp = open(path, O_RDWR);
1796 if (fp == -1)
1797 return (PSVC_FAILURE);
1799 ret = ioctl_retry(fp, I2C_GET_OUTPUT, (void *)value);
1800 if (ret == -1) {
1801 close(fp);
1802 errno = EIO;
1803 return (PSVC_FAILURE);
1806 close(fp);
1808 return (status);
1811 /* PCF8591 */
1812 static int32_t
1813 i_psvc_get_output_11_6(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
1815 int32_t ret, status = PSVC_SUCCESS;
1816 char path[1024];
1817 int32_t fp;
1819 status = i_psvc_get_devpath(hdlp, aspec, path);
1820 if (status != PSVC_SUCCESS)
1821 return (status);
1823 fp = open(path, O_RDWR);
1824 if (fp == -1)
1825 return (PSVC_FAILURE);
1827 ret = ioctl_retry(fp, I2C_GET_OUTPUT, (void *)value);
1828 if (ret == -1) {
1829 close(fp);
1830 errno = EIO;
1831 return (PSVC_FAILURE);
1834 close(fp);
1836 return (status);
1839 /* TDA8444 */
1840 static int32_t
1841 i_psvc_get_output_11_8(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
1843 int32_t ret, status = PSVC_SUCCESS;
1844 char path[1024];
1845 int32_t fp;
1846 int8_t buf;
1848 status = i_psvc_get_devpath(hdlp, aspec, path);
1849 if (status != PSVC_SUCCESS)
1850 return (status);
1852 fp = open(path, O_RDWR);
1853 if (fp == -1)
1854 return (PSVC_FAILURE);
1856 ret = read(fp, &buf, 1);
1857 if (ret == -1) {
1858 close(fp);
1859 errno = EIO;
1860 return (PSVC_FAILURE);
1862 *value = buf;
1864 close(fp);
1866 return (status);
1869 /* LTC1427 */
1870 static int32_t
1871 i_psvc_set_output_11_3(EHdl_t *hdlp, uint64_t aspec, int32_t value)
1873 int32_t ret, status = PSVC_SUCCESS;
1874 char path[1024];
1875 int32_t fp;
1877 status = i_psvc_get_devpath(hdlp, aspec, path);
1878 if (status != PSVC_SUCCESS)
1879 return (status);
1881 fp = open(path, O_RDWR);
1882 if (fp == -1)
1883 return (PSVC_FAILURE);
1885 ret = ioctl_retry(fp, I2C_SET_OUTPUT, (void *)&value);
1886 if (ret == -1) {
1887 close(fp);
1888 errno = EIO;
1889 return (PSVC_FAILURE);
1892 close(fp);
1894 return (status);
1897 /* PCF8591 */
1898 static int32_t
1899 i_psvc_set_output_11_6(EHdl_t *hdlp, uint64_t aspec, int32_t value)
1901 int32_t ret, status = PSVC_SUCCESS;
1902 char path[1024];
1903 int32_t fp;
1905 status = i_psvc_get_devpath(hdlp, aspec, path);
1906 if (status != PSVC_SUCCESS)
1907 return (status);
1909 fp = open(path, O_RDWR);
1910 if (fp == -1)
1911 return (PSVC_FAILURE);
1913 ret = ioctl_retry(fp, I2C_SET_OUTPUT, (void *)&value);
1914 if (ret == -1) {
1915 close(fp);
1916 errno = EIO;
1917 return (PSVC_FAILURE);
1920 close(fp);
1922 return (status);
1925 /* TDA8444 */
1926 static int32_t
1927 i_psvc_set_output_11_8(EHdl_t *hdlp, uint64_t aspec, int32_t value)
1929 int32_t ret, status = PSVC_SUCCESS;
1930 char path[1024];
1931 int32_t fp;
1932 int8_t buf;
1934 status = i_psvc_get_devpath(hdlp, aspec, path);
1935 if (status != PSVC_SUCCESS)
1936 return (status);
1938 fp = open(path, O_RDWR);
1939 if (fp == -1)
1940 return (PSVC_FAILURE);
1942 buf = value;
1943 ret = write(fp, &buf, 1);
1944 if (ret == -1) {
1945 close(fp);
1946 errno = EIO;
1947 return (PSVC_FAILURE);
1950 close(fp);
1952 return (status);
1955 /* HPC3130 */
1956 static int32_t
1957 i_psvc_get_reg_11_1(EHdl_t *hdlp, uint64_t aspec, uint8_t *value)
1959 int32_t ret, status = PSVC_SUCCESS;
1960 uint8_t bitshift, bytemask;
1961 char path[1024];
1962 i2c_reg_t i2cregarg;
1963 int32_t fp;
1965 status = i_psvc_get_devpath(hdlp, aspec, path);
1966 if (status != PSVC_SUCCESS)
1967 return (status);
1968 fp = open(path, O_RDWR);
1969 if (fp == -1)
1970 return (PSVC_FAILURE);
1972 i2cregarg.reg_num = PSVC_GET_ASPEC_REG(aspec);
1973 ret = ioctl_retry(fp, I2C_GET_REG, (void *)&i2cregarg);
1974 if (ret == -1) {
1975 close(fp);
1976 errno = EIO;
1977 return (-1);
1980 bitshift = PSVC_GET_ASPEC_BITSHIFT(aspec);
1981 bytemask = PSVC_GET_ASPEC_BYTEMASK(aspec);
1982 if (value != NULL)
1983 *value = (i2cregarg.reg_value & bytemask) >> bitshift;
1984 close(fp);
1986 return (status);
1989 /* SSC050 */
1990 static int32_t
1991 i_psvc_get_reg_11_7(EHdl_t *hdlp, uint64_t aspec, uint8_t *value)
1993 int32_t ret, status = PSVC_SUCCESS;
1994 uint8_t bitshift, bytemask;
1995 char path[1024];
1996 i2c_reg_t i2cregarg;
1997 int32_t fp;
1999 status = i_psvc_get_devpath(hdlp, aspec, path);
2000 if (status != PSVC_SUCCESS)
2001 return (status);
2003 fp = open(path, O_RDWR);
2004 if (fp == -1)
2005 return (PSVC_FAILURE);
2007 i2cregarg.reg_num = PSVC_GET_ASPEC_REG(aspec);
2008 ret = ioctl_retry(fp, I2C_GET_REG, (void *)&i2cregarg);
2009 if (ret == -1) {
2010 close(fp);
2011 errno = EIO;
2012 return (-1);
2015 bitshift = PSVC_GET_ASPEC_BITSHIFT(aspec);
2016 bytemask = PSVC_GET_ASPEC_BYTEMASK(aspec);
2017 if (value != NULL)
2018 *value = (i2cregarg.reg_value & bytemask) >> bitshift;
2020 close(fp);
2022 return (status);
2025 /* HPC3130 */
2026 static int32_t
2027 i_psvc_set_reg_11_1(EHdl_t *hdlp, uint64_t aspec, int32_t value)
2029 int32_t ret, status = PSVC_SUCCESS;
2030 char path[1024];
2031 i2c_reg_t i2cregarg;
2032 int8_t tval;
2033 uint8_t bitshift, bytemask;
2034 int32_t fp;
2036 status = i_psvc_get_devpath(hdlp, aspec, path);
2037 if (status != PSVC_SUCCESS)
2038 return (status);
2040 bitshift = PSVC_GET_ASPEC_BITSHIFT(aspec);
2041 bytemask = PSVC_GET_ASPEC_BYTEMASK(aspec);
2042 value = value << bitshift;
2044 fp = open(path, O_RDWR);
2045 if (fp == -1)
2046 return (PSVC_FAILURE);
2048 i2cregarg.reg_num = PSVC_GET_ASPEC_REG(aspec);
2049 if (bytemask != 0xFF) {
2050 ret = ioctl_retry(fp, I2C_GET_REG, (void *)&i2cregarg);
2051 if (ret == -1) {
2052 close(fp);
2053 errno = EIO;
2054 return (-1);
2056 tval = i2cregarg.reg_value;
2057 tval = tval & ~bytemask;
2058 } else
2059 tval = 0;
2061 value = tval | value;
2062 i2cregarg.reg_value = value;
2063 ret = ioctl_retry(fp, I2C_SET_REG, (void *)&i2cregarg);
2064 if (ret == -1) {
2065 close(fp);
2066 errno = EIO;
2067 return (-1);
2070 close(fp);
2072 return (status);
2075 /* SSC050 */
2076 static int32_t
2077 i_psvc_set_reg_11_7(EHdl_t *hdlp, uint64_t aspec, int32_t value)
2079 int32_t ret, status = PSVC_SUCCESS;
2080 char path[1024];
2081 i2c_reg_t i2cregarg;
2082 int8_t tval;
2083 uint8_t bitshift, bytemask;
2084 int32_t fp;
2086 status = i_psvc_get_devpath(hdlp, aspec, path);
2087 if (status != PSVC_SUCCESS)
2088 return (status);
2090 bitshift = PSVC_GET_ASPEC_BITSHIFT(aspec);
2091 bytemask = PSVC_GET_ASPEC_BYTEMASK(aspec);
2092 value = value << bitshift;
2094 fp = open(path, O_RDWR);
2095 if (fp == -1)
2096 return (PSVC_FAILURE);
2098 i2cregarg.reg_num = PSVC_GET_ASPEC_REG(aspec);
2099 if (bytemask != 0xFF) {
2100 ret = ioctl_retry(fp, I2C_GET_REG, (void *)&i2cregarg);
2101 if (ret == -1) {
2102 close(fp);
2103 errno = EIO;
2104 return (-1);
2106 tval = i2cregarg.reg_value;
2107 tval = tval & ~bytemask;
2108 } else
2109 tval = 0;
2111 value = tval | value;
2112 i2cregarg.reg_value = value;
2113 ret = ioctl_retry(fp, I2C_SET_REG, (void *)&i2cregarg);
2114 if (ret == -1) {
2115 close(fp);
2116 errno = EIO;
2117 return (-1);
2120 close(fp);
2122 return (status);
2125 /* PCF8574 */
2126 static int32_t
2127 i_psvc_get_bit_11_5(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
2129 int32_t ret, status = PSVC_SUCCESS;
2130 char path[1024];
2131 i2c_bit_t bitarg;
2132 int32_t fp;
2134 status = i_psvc_get_devpath(hdlp, aspec, path);
2135 if (status != PSVC_SUCCESS)
2136 return (status);
2138 bitarg.bit_num = PSVC_GET_BIT_NUM(aspec);
2139 bitarg.direction = DIR_NO_CHANGE;
2141 fp = open(path, O_RDWR);
2142 if (fp == -1)
2143 return (PSVC_FAILURE);
2145 ret = ioctl_retry(fp, I2C_GET_BIT, (void *)&bitarg);
2146 if (ret == -1) {
2147 close(fp);
2148 errno = EIO;
2149 return (-1);
2152 *value = bitarg.bit_value;
2154 close(fp);
2156 return (status);
2159 /* PCF8574 */
2160 static int32_t
2161 i_psvc_get_port_11_5(EHdl_t *hdlp, uint64_t aspec, uint8_t *value)
2163 int32_t ret, status = PSVC_SUCCESS;
2164 char path[1024];
2165 i2c_port_t port;
2166 int32_t fp;
2168 status = i_psvc_get_devpath(hdlp, aspec, path);
2169 if (status != PSVC_SUCCESS)
2170 return (status);
2172 port.direction = DIR_NO_CHANGE;
2174 fp = open(path, O_RDWR);
2175 if (fp == -1)
2176 return (PSVC_FAILURE);
2178 ret = ioctl_retry(fp, I2C_GET_PORT, (void *)&port);
2179 if (ret == -1) {
2180 close(fp);
2181 errno = EIO;
2182 return (-1);
2185 *value = port.value;
2187 close(fp);
2189 return (status);
2192 /* SSC050 */
2193 static int32_t
2194 i_psvc_get_bit_11_7(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
2196 int32_t ret, status = PSVC_SUCCESS;
2197 char path[1024];
2198 i2c_bit_t bitarg;
2199 int32_t fp;
2201 status = i_psvc_get_devpath(hdlp, aspec, path);
2202 if (status != PSVC_SUCCESS)
2203 return (status);
2205 bitarg.bit_num = PSVC_GET_BIT_NUM(aspec);
2206 bitarg.direction = DIR_NO_CHANGE;
2208 fp = open(path, O_RDWR);
2209 if (fp == -1)
2210 return (PSVC_FAILURE);
2212 ret = ioctl_retry(fp, I2C_GET_BIT, (void *)&bitarg);
2213 if (ret == -1) {
2214 close(fp);
2215 errno = EIO;
2216 return (-1);
2219 *value = bitarg.bit_value;
2221 close(fp);
2223 return (status);
2226 /* PCF8574 */
2227 static int32_t
2228 i_psvc_set_bit_11_5(EHdl_t *hdlp, uint64_t aspec, int32_t value)
2230 int32_t ret, status = PSVC_SUCCESS;
2231 char path[1024];
2232 i2c_bit_t bitarg;
2233 int32_t fp;
2235 status = i_psvc_get_devpath(hdlp, aspec, path);
2236 if (status != PSVC_SUCCESS)
2237 return (status);
2239 bitarg.bit_value = value;
2240 bitarg.bit_num = PSVC_GET_BIT_NUM(aspec);
2241 bitarg.direction = DIR_OUTPUT;
2242 fp = open(path, O_RDWR);
2243 if (fp == -1)
2244 return (PSVC_FAILURE);
2246 ret = ioctl_retry(fp, I2C_SET_BIT, (void *)&bitarg);
2247 if (ret == -1) {
2248 close(fp);
2249 errno = EIO;
2250 return (-1);
2253 close(fp);
2255 return (status);
2258 /* PCF8574 */
2259 static int32_t
2260 i_psvc_set_port_11_5(EHdl_t *hdlp, uint64_t aspec, int32_t value)
2262 int32_t ret, status = PSVC_SUCCESS;
2263 char path[1024];
2264 i2c_port_t port;
2265 int32_t fp;
2267 status = i_psvc_get_devpath(hdlp, aspec, path);
2268 if (status != PSVC_SUCCESS)
2269 return (status);
2271 port.value = (uint8_t)value;
2272 port.direction = DIR_NO_CHANGE;
2273 fp = open(path, O_RDWR);
2274 if (fp == -1)
2275 return (PSVC_FAILURE);
2277 ret = ioctl_retry(fp, I2C_SET_PORT, (void *)&port);
2278 if (ret == -1) {
2279 close(fp);
2280 errno = EIO;
2281 return (-1);
2284 close(fp);
2286 return (status);
2289 /* SSC050 */
2290 static int32_t
2291 i_psvc_set_bit_11_7(EHdl_t *hdlp, uint64_t aspec, int32_t value)
2293 int32_t ret, status = PSVC_SUCCESS;
2294 char path[1024];
2295 i2c_bit_t bitarg;
2296 int32_t fp;
2298 status = i_psvc_get_devpath(hdlp, aspec, path);
2299 if (status != PSVC_SUCCESS)
2300 return (status);
2302 bitarg.bit_value = value;
2303 bitarg.bit_num = PSVC_GET_BIT_NUM(aspec);
2304 bitarg.direction = DIR_OUTPUT;
2306 fp = open(path, O_RDWR);
2307 if (fp == -1)
2308 return (PSVC_FAILURE);
2310 ret = ioctl_retry(fp, I2C_SET_BIT, (void *)&bitarg);
2311 if (ret == -1) {
2312 close(fp);
2313 errno = EIO;
2314 return (-1);
2317 close(fp);
2319 return (status);
2322 /* AT24 */
2323 static int32_t
2324 i_psvc_probe_11_0(EHdl_t *hdlp, EObj_t *objp)
2326 int32_t ret, status = PSVC_SUCCESS;
2327 uint8_t value;
2328 char path[1024];
2329 int32_t fp;
2331 if (objp->present != PSVC_PRESENT) {
2332 errno = ENODEV;
2333 return (PSVC_FAILURE);
2336 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2337 if (status != PSVC_SUCCESS) {
2338 return (status);
2341 fp = open(path, O_RDWR);
2342 if (fp == -1) {
2343 return (PSVC_FAILURE);
2346 ret = read(fp, &value, 1);
2347 if (ret == -1) {
2348 close(fp);
2349 errno = EIO;
2350 return (-1);
2353 close(fp);
2355 return (status);
2358 /* HPC3130 */
2359 static int32_t
2360 i_psvc_probe_11_1(EHdl_t *hdlp, EObj_t *objp)
2362 int32_t ret, status = PSVC_SUCCESS;
2363 char path[1024];
2364 i2c_reg_t reg;
2365 int32_t fp;
2367 if (objp->present != PSVC_PRESENT) {
2368 errno = ENODEV;
2369 return (PSVC_FAILURE);
2372 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2373 if (status != PSVC_SUCCESS)
2374 return (status);
2376 fp = open(path, O_RDWR);
2377 if (fp == -1)
2378 return (PSVC_FAILURE);
2380 reg.reg_num = 0;
2381 ret = ioctl_retry(fp, I2C_GET_REG, (void *)&reg);
2382 if (ret == -1) {
2383 close(fp);
2384 errno = EIO;
2385 return (-1);
2388 close(fp);
2390 return (status);
2393 /* LM75 */
2394 static int32_t
2395 i_psvc_probe_11_2(EHdl_t *hdlp, EObj_t *objp)
2397 int32_t ret, status = PSVC_SUCCESS;
2398 char path[1024];
2399 int32_t fp;
2400 int16_t temp16;
2402 if (objp->present != PSVC_PRESENT) {
2403 errno = ENODEV;
2404 return (PSVC_FAILURE);
2407 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2408 if (status != PSVC_SUCCESS) {
2409 return (status);
2412 fp = open(path, O_RDWR);
2413 if (fp == -1) {
2414 return (PSVC_FAILURE);
2417 ret = ioctl_retry(fp, I2C_GET_TEMPERATURE, (void *)&temp16);
2418 if (ret == -1) {
2419 close(fp);
2420 errno = EIO;
2421 return (-1);
2424 close(fp);
2426 return (status);
2429 /* LTC1427 */
2430 static int32_t
2431 i_psvc_probe_11_3(EHdl_t *hdlp, EObj_t *objp)
2433 int32_t ret, status = PSVC_SUCCESS;
2434 int32_t value;
2435 char path[1024];
2436 int32_t fp;
2438 if (objp->present != PSVC_PRESENT) {
2439 errno = ENODEV;
2440 return (PSVC_FAILURE);
2443 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2444 if (status != PSVC_SUCCESS) {
2445 return (status);
2448 fp = open(path, O_RDWR);
2449 if (fp == -1) {
2450 return (PSVC_FAILURE);
2453 ret = ioctl_retry(fp, I2C_GET_OUTPUT, (void *)&value);
2454 if (ret == -1) {
2455 close(fp);
2456 errno = EINVAL;
2457 return (-1);
2460 ret = ioctl_retry(fp, I2C_SET_OUTPUT, (void *)&value);
2461 if (ret == -1) {
2462 close(fp);
2463 errno = EIO;
2464 return (-1);
2467 close(fp);
2468 return (status);
2471 /* MAX1617 */
2472 static int32_t
2473 i_psvc_probe_11_4(EHdl_t *hdlp, EObj_t *objp)
2475 int32_t ret, status = PSVC_SUCCESS;
2476 char path[1024];
2477 int32_t fp;
2478 int16_t temp16;
2480 if (objp->present != PSVC_PRESENT) {
2481 errno = ENODEV;
2482 return (PSVC_FAILURE);
2485 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2486 if (status != PSVC_SUCCESS) {
2487 return (status);
2490 fp = open(path, O_RDWR);
2491 if (fp == -1) {
2492 return (PSVC_FAILURE);
2495 ret = ioctl_retry(fp, I2C_GET_TEMPERATURE, (void *)&temp16);
2496 if (ret == -1) {
2497 close(fp);
2498 errno = EIO;
2499 return (-1);
2502 close(fp);
2504 return (status);
2507 /* PCF8574 */
2508 static int32_t
2509 i_psvc_probe_11_5(EHdl_t *hdlp, EObj_t *objp)
2511 int32_t ret, status = PSVC_SUCCESS;
2512 char path[1024];
2513 i2c_port_t port;
2514 int32_t fp;
2516 if (objp->present != PSVC_PRESENT) {
2517 errno = ENODEV;
2518 return (PSVC_FAILURE);
2521 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2522 if (status != PSVC_SUCCESS) {
2523 return (status);
2526 port.direction = DIR_NO_CHANGE;
2528 fp = open(path, O_RDWR);
2529 if (fp == -1) {
2530 return (PSVC_FAILURE);
2533 ret = ioctl_retry(fp, I2C_GET_PORT, (void *)&port);
2534 if (ret == -1) {
2535 close(fp);
2536 errno = EIO;
2537 return (-1);
2540 close(fp);
2542 return (status);
2545 /* PCF8591 */
2546 static int32_t
2547 i_psvc_probe_11_6(EHdl_t *hdlp, EObj_t *objp)
2549 int32_t ret, status = PSVC_SUCCESS;
2550 char path[1024];
2551 int32_t arg;
2552 int32_t fp;
2554 if (objp->present != PSVC_PRESENT) {
2555 errno = ENODEV;
2556 return (PSVC_FAILURE);
2559 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2560 if (status != PSVC_SUCCESS)
2561 return (status);
2563 fp = open(path, O_RDWR);
2564 if (fp == -1)
2565 return (PSVC_FAILURE);
2567 ret = ioctl_retry(fp, I2C_GET_INPUT, (void *)&arg);
2568 if (ret == -1) {
2569 close(fp);
2570 errno = EIO;
2571 return (-1);
2574 close(fp);
2576 return (status);
2579 /* SSC050 */
2580 static int32_t
2581 i_psvc_probe_11_7(EHdl_t *hdlp, EObj_t *objp)
2583 int32_t ret, status = PSVC_SUCCESS;
2584 char path[1024];
2585 i2c_port_t port;
2586 int32_t fp;
2588 if (objp->present != PSVC_PRESENT) {
2589 errno = ENODEV;
2590 return (PSVC_FAILURE);
2593 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2594 if (status != PSVC_SUCCESS)
2595 return (status);
2597 port.direction = DIR_NO_CHANGE;
2599 fp = open(path, O_RDWR);
2600 if (fp == -1)
2601 return (PSVC_FAILURE);
2603 ret = ioctl_retry(fp, I2C_GET_PORT, (void *)&port);
2604 if (ret == -1) {
2605 close(fp);
2606 errno = EIO;
2607 return (-1);
2610 close(fp);
2612 return (status);
2615 /* TDA8444 */
2616 static int32_t
2617 i_psvc_probe_11_8(EHdl_t *hdlp, EObj_t *objp)
2619 int32_t ret, status = PSVC_SUCCESS;
2620 uint8_t value;
2621 char path[1024];
2622 int32_t fp;
2624 if (objp->present != PSVC_PRESENT) {
2625 errno = ENODEV;
2626 return (PSVC_FAILURE);
2629 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2630 if (status != PSVC_SUCCESS)
2631 return (status);
2633 fp = open(path, O_RDWR);
2634 if (fp == -1)
2635 return (PSVC_FAILURE);
2637 ret = read(fp, &value, 1);
2638 if (ret == -1) {
2639 close(fp);
2640 errno = EIO;
2641 return (-1);
2644 close(fp);
2646 return (status);
2650 /* SSC100 */
2651 static int32_t
2652 i_psvc_probe_11_9(EHdl_t *hdlp, EObj_t *objp)
2654 int32_t ret, status = PSVC_SUCCESS;
2655 char path[1024];
2656 i2c_reg_t reg;
2657 int32_t fp;
2659 if (objp->present != PSVC_PRESENT) {
2660 errno = ENODEV;
2661 return (PSVC_FAILURE);
2664 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2665 if (status != PSVC_SUCCESS) {
2666 return (status);
2669 fp = open(path, O_RDWR);
2670 if (fp == -1) {
2671 return (PSVC_FAILURE);
2675 * There are only a few register numbers that are valid numbers to
2676 * read from. 0x10 is one of these registers. Any non-valid registers
2677 * cause unknown behavior to the ssc100 device.
2679 reg.reg_num = 0x10;
2680 ret = ioctl_retry(fp, I2C_GET_REG, (void *)&reg);
2681 if (ret == -1) {
2682 close(fp);
2683 errno = EIO;
2684 return (-1);
2687 close(fp);
2689 return (status);
2694 * Find start of a section within the config file,
2695 * Returns number of records in the section.
2696 * FILE *fd is set to first data record within section.
2698 static int32_t
2699 i_psvc_find_file_section(FILE *fd, char *start)
2701 char *ret;
2702 char buf[BUFSZ];
2703 char name[32];
2704 int found;
2706 fseek(fd, 0, SEEK_SET);
2707 while ((ret = fgets(buf, BUFSZ, fd)) != NULL) {
2708 if (strncmp(start, buf, strlen(start)) == 0)
2709 break;
2712 if (ret == NULL) {
2713 errno = EINVAL;
2714 return (-1);
2717 found = sscanf(buf, "%s", name);
2718 if (found != 1) {
2719 errno = EINVAL;
2720 return (-1);
2721 } else {
2722 return (0);
2727 /* compare routine for qsort of str_tbl */
2728 static int32_t
2729 i_psvc_name_compare_qsort(EStringId_t *s1, EStringId_t *s2)
2731 return (strcmp(s1->name, s2->name));
2734 /* compare routine for bsearch of str_tbl */
2735 static int32_t
2736 i_psvc_name_compare_bsearch(char *s1, EStringId_t *s2)
2738 return (strcmp(s1, s2->name));
2742 * Determine the initial state of a device.
2744 static int32_t
2745 i_psvc_init_state(EHdl_t *hp, EObj_t *objp)
2747 int32_t status = PSVC_SUCCESS;
2749 if (objp->class == PSVC_ON_OFF_SWITCH_CLASS) {
2750 char state[32];
2752 status = objp->get_attr(hp, objp, PSVC_SWITCH_STATE_ATTR,
2753 state);
2754 if (status != PSVC_SUCCESS)
2755 return (status);
2757 if (strcmp(state, PSVC_SWITCH_ON) == 0)
2758 strcpy(objp->state, PSVC_ON);
2759 else
2760 strcpy(objp->state, PSVC_OFF);
2763 if (objp->class == PSVC_KEYSWITCH_CLASS) {
2764 char state[32];
2766 status = objp->get_attr(hp, objp, PSVC_SWITCH_STATE_ATTR,
2767 state);
2768 if (status != PSVC_SUCCESS)
2769 return (status);
2770 strcpy(objp->state, state);
2773 return (status);
2777 * Return the object pointer for the object name passed in.
2778 * Creates the object if this is the first access,
2779 * Returns 0 if successful, -1 if not.
2781 static int32_t
2782 i_psvc_get_obj(EHdl_t *hp, char *dev_name, EObj_t **objp)
2784 int32_t i, ret;
2785 int32_t found, key, array;
2786 int32_t class, subclass;
2787 boolean_t presence;
2788 char name[NAMELEN];
2789 char buf[BUFSZ];
2790 char *start;
2791 ETable_Array *tbl_arr;
2793 key = psvc_get_str_key(dev_name);
2794 array = key % PSVC_MAX_TABLE_ARRAYS;
2795 tbl_arr = &(hp->tbl_arry[array]);
2797 for (i = 0; i < tbl_arr->obj_count; ++i) {
2798 if (key == tbl_arr->obj_tbl[i].key) {
2799 if (strcmp(dev_name, tbl_arr->obj_tbl[i].name) == 0) {
2800 if (tbl_arr->obj_tbl[i].type != PSVC_OBJ)
2801 return (-1);
2802 *objp = tbl_arr->obj_tbl[i].objp;
2803 return (0);
2808 if (i_psvc_find_file_section(hp->fp, "OBJECT_INFO") == -1) {
2809 ENV_DEBUG("Couldn't find OBJECT_INFO section", dev_name);
2810 return (-1);
2813 fgets(buf, BUFSZ, hp->fp);
2814 while (strcmp(buf, "OBJECT_INFO_END")) {
2815 start = strrchr(buf, '/');
2816 if (start == NULL) {
2817 errno = EINVAL;
2818 return (PSVC_FAILURE);
2820 found = sscanf(start + 1, "%s", name);
2821 if (found != 1) {
2822 errno = EINVAL;
2823 return (PSVC_FAILURE);
2826 if (strcmp(name, dev_name) == 0) {
2828 if (i_psvc_value(buf, PSVC_CLASS_ATTR, &class)
2829 != PSVC_SUCCESS)
2830 return (PSVC_FAILURE);
2831 if (i_psvc_value(buf, PSVC_SUBCLASS_ATTR, &subclass)
2832 != PSVC_SUCCESS)
2833 return (PSVC_FAILURE);
2834 ret = (*i_psvc_constructor[class][subclass])(hp,
2835 dev_name, objp);
2836 if (ret != PSVC_SUCCESS) {
2837 return (-1);
2839 ret = (*objp)->get_attr(hp, *objp, PSVC_PRESENCE_ATTR,
2840 &presence);
2841 (*objp)->previous_presence = presence;
2842 if (ret != PSVC_SUCCESS || presence != PSVC_PRESENT)
2843 return (ret);
2845 return (i_psvc_init_state(hp, *objp));
2847 fgets(buf, BUFSZ, hp->fp);
2850 errno = EINVAL;
2851 return (-1);
2855 * Gets the device path associated with an object id.
2856 * Returns 0 if successful, -1 if not.
2858 static int32_t
2859 i_psvc_get_devpath(EHdl_t *hp, uint64_t addr_spec, char *path)
2861 int i;
2862 EDevice_t *dp;
2863 uint32_t controller, bus, addr, port;
2865 controller = PSVC_GET_ASPEC_CNTLR(addr_spec);
2866 bus = PSVC_GET_ASPEC_BUSNUM(addr_spec);
2867 addr = PSVC_GET_ASPEC_BUSADDR(addr_spec);
2868 port = PSVC_GET_ASPEC_PORT(addr_spec);
2870 for (i = 0; i < hp->dev_count; ++i) {
2871 dp = &hp->dev_tbl[i];
2872 if (dp->controller == controller &&
2873 dp->bus == bus &&
2874 dp->addr == addr &&
2875 dp->port == port) {
2876 strcpy(path, dp->path);
2877 return (PSVC_SUCCESS);
2881 errno = EINVAL;
2882 return (PSVC_FAILURE);
2886 /* Load the association table */
2887 static int32_t
2888 i_psvc_load_associations(EHdl_t *hp, FILE *fp)
2890 uint32_t count;
2891 int found;
2892 int i, j;
2893 char name1[32], name2[32];
2894 char buf[BUFSZ];
2895 EStringId_t *namep;
2896 EAssoc_t *ap;
2897 int32_t id;
2898 int32_t status;
2901 * ignore count in the file, correct count is highest
2902 * association id + 1, now figured when loading ASSOC_STR
2903 * section.
2905 if (i_psvc_find_file_section(fp, "ASSOCIATIONS") != PSVC_SUCCESS)
2906 return (-1);
2907 if ((hp->assoc_tbl = malloc(sizeof (EAssocList_t) * hp->assoc_count))
2908 == NULL) {
2909 return (-1);
2911 memset(hp->assoc_tbl, 0, sizeof (EAssocList_t) * hp->assoc_count);
2913 for (i = 0; i < hp->assoc_count; ++i) {
2914 fgets(buf, BUFSZ, fp);
2915 found = sscanf(buf, "%s %s", name1, name2);
2916 if (strcmp("ASSOCIATIONS_END", name1) == 0)
2917 break;
2918 if (found != 2) {
2919 errno = EINVAL;
2920 return (-1);
2922 namep = (EStringId_t *)bsearch(name2, hp->othr_tbl,
2923 hp->othr_count, sizeof (EStringId_t),
2924 (int (*)(const void *, const void *))
2925 i_psvc_name_compare_bsearch);
2926 if (namep == NULL) {
2927 errno = EINVAL;
2928 return (-1);
2930 id = namep->id;
2932 status = i_psvc_count_records(fp, "ASSOCIATION_END", &count);
2933 if (status != PSVC_SUCCESS)
2934 return (status);
2935 hp->assoc_tbl[id].count = count;
2936 hp->assoc_tbl[id].table =
2937 (EAssoc_t *)malloc(sizeof (EAssoc_t) * count);
2938 if (hp->assoc_tbl[id].table == NULL)
2939 return (-1);
2941 for (j = 0; j < count; ++j) {
2942 ap = &hp->assoc_tbl[id].table[j];
2943 fgets(buf, BUFSZ, fp);
2944 found = sscanf(buf, "%s %s", ap->antecedent_id,
2945 ap->dependent_id);
2946 ap->ant_key = psvc_get_str_key(ap->antecedent_id);
2947 if (found != 2) {
2948 errno = EINVAL;
2949 return (-1);
2954 fgets(buf, BUFSZ, fp);
2955 if (strncmp(buf, "ASSOCIATION_END", 15) != 0) {
2956 errno = EINVAL;
2957 return (-1);
2961 return (0);
2964 /* Load the table of tables */
2965 static int32_t
2966 i_psvc_load_tables(EHdl_t *hp, FILE *fp)
2968 int i, j;
2969 int found;
2970 int ret;
2971 int32_t cell_type;
2972 int64_t *table;
2973 char buf[BUFSZ];
2974 int32_t status;
2975 uint32_t table_count;
2976 int32_t num, key, array;
2977 char name[NAMELEN];
2978 ETable_Array *tbl_arr;
2980 if (i_psvc_find_file_section(fp, "TABLES") != PSVC_SUCCESS)
2981 return (PSVC_SUCCESS); /* no tables */
2982 status = i_psvc_count_tables_associations(fp, &table_count,
2983 "TABLE_END");
2984 if (status != PSVC_SUCCESS || table_count == 0)
2985 return (status);
2987 for (i = 0; i < table_count; ++i) {
2988 int slot;
2989 ETable_t *tblp;
2991 fgets(buf, BUFSZ, fp);
2992 if (strncmp(buf, "TABLE", 5) != 0) {
2993 errno = EINVAL;
2994 return (-1);
2997 fgets(buf, BUFSZ, fp);
2998 found = sscanf(buf, "%s %d", name, &cell_type);
2999 key = psvc_get_str_key(name);
3000 array = key % PSVC_MAX_TABLE_ARRAYS;
3001 tbl_arr = &(hp->tbl_arry[array]);
3003 if (tbl_arr->nextid == hp->total_obj_count) {
3004 errno = EINVAL;
3005 return (PSVC_FAILURE);
3006 } else {
3007 slot = tbl_arr->nextid++;
3008 tbl_arr->obj_count++;
3011 strcpy(tbl_arr->obj_tbl[slot].name, name);
3013 tblp = (ETable_t *)malloc(sizeof (ETable_t));
3014 if (tblp == NULL)
3015 return (PSVC_FAILURE);
3016 tbl_arr->obj_tbl[slot].key = key;
3017 tbl_arr->obj_tbl[slot].objp = (EObj_t *)(void *)tblp;
3018 tbl_arr->obj_tbl[slot].type = PSVC_TBL;
3020 status = i_psvc_count_table_records(fp, "TABLE_END",
3021 &tblp->size);
3022 if (status != PSVC_SUCCESS)
3023 return (status);
3024 tblp->cell_type = (uint8_t)cell_type;
3025 if (found != 2) {
3026 errno = EINVAL;
3027 return (-1);
3030 /* allocate and load table */
3031 tblp->table = (int64_t *)malloc(tblp->size *
3032 i_psvc_cell_size[tblp->cell_type]);
3033 if (tblp->table == NULL) {
3034 return (-1);
3037 table = tblp->table;
3038 for (j = 0; j < tblp->size; ++j) {
3039 switch (cell_type) {
3040 case 0:
3041 ret = fscanf(fp, "%d", &num);
3042 *((int8_t *)table + j) = num;
3043 break;
3044 case 1:
3045 ret = fscanf(fp, "%d", &num);
3046 *((uint8_t *)table + j) = (uint8_t)num;
3047 break;
3048 case 2:
3049 ret = fscanf(fp, "%hd",
3050 ((int16_t *)table + j));
3051 break;
3052 case 3:
3053 ret = fscanf(fp, "%hd",
3054 ((uint16_t *)table + j));
3055 break;
3056 case 4:
3057 ret = fscanf(fp, "%d",
3058 ((int32_t *)table + j));
3059 break;
3060 case 5:
3061 ret = fscanf(fp, "%d",
3062 ((uint32_t *)table + j));
3063 break;
3064 case 6:
3065 ret = fscanf(fp, "%lld",
3066 ((int64_t *)table + j));
3067 break;
3068 case 7:
3069 ret = fscanf(fp, "%lld",
3070 ((uint64_t *)table + j));
3071 break;
3072 default:
3073 errno = EINVAL;
3074 return (-1);
3076 if (ret != 1) {
3077 errno = EINVAL;
3078 return (-1);
3081 fgets(buf, BUFSZ, fp); /* reads newline on data line */
3082 fgets(buf, BUFSZ, fp);
3083 if (strncmp(buf, "TABLE_END", 9) != 0) {
3084 errno = EINVAL;
3085 return (-1);
3090 return (0);
3093 static int32_t
3094 i_psvc_destructor(EHdl_t *hdlp, char *name, void *objp)
3096 int32_t i, key, array;
3098 key = psvc_get_str_key(name);
3099 array = key % PSVC_MAX_TABLE_ARRAYS;
3101 for (i = 0; i < hdlp->tbl_arry[array].obj_count; ++i) {
3102 if (key == hdlp->tbl_arry[array].obj_tbl[i].key) {
3103 if (strcmp(hdlp->tbl_arry[array].obj_tbl[i].name,
3104 name) == 0) {
3105 hdlp->tbl_arry[array].obj_tbl[i].name[0] = '\0';
3106 free(objp);
3107 return (PSVC_SUCCESS);
3112 return (PSVC_SUCCESS);
3115 static int32_t
3116 i_psvc_get_attr_generic(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id,
3117 void * attrp)
3119 int32_t status = PSVC_SUCCESS;
3120 char *parent_id;
3122 switch (attr_id) {
3123 case PSVC_ADDR_SPEC_ATTR:
3124 *(uint64_t *)attrp = objp->addr_spec;
3125 break;
3126 case PSVC_CLASS_ATTR:
3127 *(int32_t *)attrp = objp->class;
3128 break;
3129 case PSVC_SUBCLASS_ATTR:
3130 *(int32_t *)attrp = objp->subclass;
3131 break;
3132 case PSVC_PRESENCE_ATTR:
3133 status = i_psvc_get_presence(hdlp, objp, (boolean_t *)attrp);
3134 break;
3135 case PSVC_PREV_PRESENCE_ATTR:
3136 *(boolean_t *)attrp = objp->previous_presence;
3137 break;
3138 case PSVC_STATE_ATTR:
3139 strcpy((char *)attrp, objp->state);
3140 break;
3141 case PSVC_PREV_STATE_ATTR:
3142 strcpy((char *)attrp, objp->previous_state);
3143 break;
3144 case PSVC_ENABLE_ATTR:
3145 *(boolean_t *)attrp = objp->enabled;
3146 break;
3147 case PSVC_FAULTID_ATTR:
3148 strcpy((char *)attrp, objp->fault_id);
3149 break;
3150 case PSVC_FEATURES_ATTR:
3151 *(uint64_t *)attrp = objp->features;
3152 break;
3153 case PSVC_LABEL_ATTR:
3154 strcpy((char *)attrp, objp->label);
3155 break;
3156 case PSVC_FRUID_ATTR:
3157 while ((objp->features & PSVC_DEV_FRU) == 0) {
3158 status = i_psvc_get_assoc_id(hdlp, objp->label,
3159 PSVC_PARENT, 0, &parent_id);
3160 if (status != PSVC_SUCCESS)
3161 return (status);
3163 status = i_psvc_get_obj(hdlp, parent_id, &objp);
3164 if (status != PSVC_SUCCESS)
3165 return (status);
3168 strcpy((char *)attrp, objp->label);
3169 break;
3170 case PSVC_INSTANCE_ATTR:
3171 *(int32_t *)attrp = objp->instance;
3172 break;
3173 default:
3174 errno = EINVAL;
3175 return (PSVC_FAILURE);
3178 return (status);
3181 static int32_t
3182 i_psvc_set_attr_generic(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id,
3183 void * attrp)
3185 int32_t status = PSVC_SUCCESS;
3187 switch (attr_id) {
3188 case PSVC_PREV_PRESENCE_ATTR:
3189 objp->previous_presence = *(boolean_t *)attrp;
3190 break;
3191 case PSVC_STATE_ATTR:
3192 strcpy(objp->previous_state, objp->state);
3193 strcpy(objp->state, (char *)attrp);
3194 break;
3195 case PSVC_ENABLE_ATTR:
3196 objp->enabled = *(boolean_t *)attrp;
3197 break;
3198 case PSVC_FAULTID_ATTR:
3199 strcpy(objp->fault_id, (char *)attrp);
3200 break;
3201 default:
3202 errno = EINVAL;
3203 return (PSVC_FAILURE);
3205 return (status);
3208 static int32_t
3209 i_psvc_get_attr_0_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3211 int32_t status = PSVC_SUCCESS;
3213 switch (attr_id) {
3214 case PSVC_SENSOR_VALUE_ATTR:
3215 return (i_psvc_get_device_value_0_0(hdlp, objp, attrp));
3216 case PSVC_LO_WARN_ATTR:
3217 *(int32_t *)attrp = ((ETempSensor_t *)objp)->lo_warn;
3218 return (status);
3219 case PSVC_LO_SHUT_ATTR:
3220 *(int32_t *)attrp = ((ETempSensor_t *)objp)->lo_shut;
3221 return (status);
3222 case PSVC_HI_WARN_ATTR:
3223 *(int32_t *)attrp = ((ETempSensor_t *)objp)->hi_warn;
3224 return (status);
3225 case PSVC_HI_SHUT_ATTR:
3226 *(int32_t *)attrp = ((ETempSensor_t *)objp)->hi_shut;
3227 return (status);
3230 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3232 return (status);
3235 static int32_t
3236 i_psvc_get_attr_0_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3238 int32_t status = PSVC_SUCCESS;
3240 switch (attr_id) {
3241 case PSVC_SENSOR_VALUE_ATTR:
3242 return (i_psvc_get_device_value_0_1(hdlp, objp, attrp));
3243 case PSVC_LO_WARN_ATTR:
3244 *(int32_t *)attrp = ((ETempSensor_t *)objp)->lo_warn;
3245 return (status);
3246 case PSVC_LO_SHUT_ATTR:
3247 *(int32_t *)attrp = ((ETempSensor_t *)objp)->lo_shut;
3248 return (status);
3249 case PSVC_HI_WARN_ATTR:
3250 *(int32_t *)attrp = ((ETempSensor_t *)objp)->hi_warn;
3251 return (status);
3252 case PSVC_HI_SHUT_ATTR:
3253 *(int32_t *)attrp = ((ETempSensor_t *)objp)->hi_shut;
3254 return (status);
3255 case PSVC_OPTIMAL_TEMP_ATTR:
3256 *(int32_t *)attrp = ((ETempSensor_t *)objp)->opt_temp;
3257 return (status);
3258 case PSVC_HW_HI_SHUT_ATTR:
3259 *(int32_t *)attrp = ((ETempSensor_t *)objp)->hw_hi_shut;
3260 return (status);
3261 case PSVC_HW_LO_SHUT_ATTR:
3262 *(int32_t *)attrp = ((ETempSensor_t *)objp)->hw_lo_shut;
3263 return (status);
3266 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3268 return (status);
3271 static int32_t
3272 i_psvc_set_attr_0_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3274 int32_t status = PSVC_SUCCESS;
3276 switch (attr_id) {
3277 case PSVC_LO_WARN_ATTR:
3278 ((ETempSensor_t *)objp)->lo_warn = *(int32_t *)attrp;
3279 return (status);
3280 case PSVC_LO_SHUT_ATTR:
3281 ((ETempSensor_t *)objp)->lo_shut = *(int32_t *)attrp;
3282 return (status);
3283 case PSVC_HI_WARN_ATTR:
3284 ((ETempSensor_t *)objp)->hi_warn = *(int32_t *)attrp;
3285 return (status);
3286 case PSVC_HI_SHUT_ATTR:
3287 ((ETempSensor_t *)objp)->hi_shut = *(int32_t *)attrp;
3288 return (status);
3289 case PSVC_OPTIMAL_TEMP_ATTR:
3290 ((ETempSensor_t *)objp)->opt_temp = *(int32_t *)attrp;
3291 return (status);
3292 case PSVC_HW_HI_SHUT_ATTR:
3293 ((ETempSensor_t *)objp)->hw_hi_shut = *(int32_t *)attrp;
3294 return (status);
3295 case PSVC_HW_LO_SHUT_ATTR:
3296 ((ETempSensor_t *)objp)->hw_lo_shut = *(int32_t *)attrp;
3297 return (status);
3300 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3302 return (status);
3305 static int32_t
3306 i_psvc_get_attr_1_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3308 int32_t status = PSVC_SUCCESS;
3310 switch (attr_id) {
3311 case PSVC_SENSOR_VALUE_ATTR:
3312 return (i_psvc_get_device_value_1_0(hdlp, objp, attrp));
3313 case PSVC_SETPOINT_ATTR:
3314 *(int16_t *)attrp = ((EFan_t *)objp)->setpoint;
3315 return (status);
3316 case PSVC_HYSTERESIS_ATTR:
3317 *(int16_t *)attrp = ((EFan_t *)objp)->hysteresis;
3318 return (status);
3319 case PSVC_LOOPGAIN_ATTR:
3320 *(int16_t *)attrp = ((EFan_t *)objp)->loopgain;
3321 return (status);
3322 case PSVC_LOOPBIAS_ATTR:
3323 *(int16_t *)attrp = ((EFan_t *)objp)->loopbias;
3324 return (status);
3325 case PSVC_TEMP_DIFFERENTIAL_ATTR:
3326 memcpy(attrp, ((EFan_t *)objp)->temp_differential,
3327 sizeof (((EFan_t *)objp)->temp_differential));
3328 return (status);
3329 case PSVC_TEMP_DIFFERENTIAL_INDEX_ATTR:
3330 *(int16_t *)attrp = ((EFan_t *)objp)->temp_differential_index;
3331 return (status);
3334 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3336 return (status);
3339 static int32_t
3340 i_psvc_set_attr_1_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3342 int32_t status = PSVC_SUCCESS;
3344 switch (attr_id) {
3345 case PSVC_TEMP_DIFFERENTIAL_ATTR:
3346 memcpy(((EFan_t *)objp)->temp_differential, attrp,
3347 sizeof (((EFan_t *)objp)->temp_differential));
3348 return (status);
3349 case PSVC_TEMP_DIFFERENTIAL_INDEX_ATTR:
3350 ((EFan_t *)objp)->temp_differential_index = *(int16_t *)attrp;
3351 return (status);
3352 case PSVC_SETPOINT_ATTR:
3353 ((EFan_t *)objp)->setpoint = *(int16_t *)attrp;
3354 return (status);
3357 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3359 return (PSVC_SUCCESS);
3362 static int32_t
3363 i_psvc_get_attr_2_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3365 int32_t status = PSVC_SUCCESS;
3367 switch (attr_id) {
3368 case PSVC_LED_STATE_ATTR:
3369 case PSVC_STATE_ATTR:
3370 return (i_psvc_get_device_state_2_0(hdlp, objp, attrp));
3371 case PSVC_LED_COLOR_ATTR:
3372 strcpy((char *)attrp, ((ELed_t *)objp)->color);
3373 return (status);
3374 case PSVC_LIT_COUNT_ATTR:
3375 *(int16_t *)attrp = ((ELed_t *)objp)->lit_count;
3376 return (status);
3379 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3381 return (status);
3384 static int32_t
3385 i_psvc_set_attr_2_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3387 int32_t status = PSVC_SUCCESS;
3389 switch (attr_id) {
3390 case PSVC_LED_STATE_ATTR:
3391 case PSVC_STATE_ATTR:
3392 return (i_psvc_set_device_state_2_0(hdlp, objp, attrp));
3395 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3397 return (status);
3400 static int32_t
3401 i_psvc_get_attr_2_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3403 int32_t status = PSVC_SUCCESS;
3405 switch (attr_id) {
3406 case PSVC_LED_STATE_ATTR:
3407 case PSVC_STATE_ATTR:
3408 return (i_psvc_get_device_state_2_1(hdlp, objp, attrp));
3409 case PSVC_LED_COLOR_ATTR:
3410 strcpy((char *)attrp, ((ELed_t *)objp)->color);
3411 return (status);
3412 case PSVC_LIT_COUNT_ATTR:
3413 *(int16_t *)attrp = ((ELed_t *)objp)->lit_count;
3414 return (status);
3417 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3419 return (status);
3422 static int32_t
3423 i_psvc_set_attr_2_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3425 int32_t status = PSVC_SUCCESS;
3427 switch (attr_id) {
3428 case PSVC_LED_STATE_ATTR:
3429 case PSVC_STATE_ATTR:
3430 return (i_psvc_set_device_state_2_1(hdlp, objp, attrp));
3433 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3435 return (status);
3438 static int32_t
3439 i_psvc_get_attr_2_2(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3441 int32_t status = PSVC_SUCCESS;
3443 switch (attr_id) {
3444 case PSVC_LED_STATE_ATTR:
3445 case PSVC_STATE_ATTR:
3446 return (i_psvc_get_device_state_2_0(hdlp, objp, attrp));
3447 case PSVC_LED_COLOR_ATTR:
3448 strcpy((char *)attrp, ((ELed_t *)objp)->color);
3449 return (status);
3450 case PSVC_LIT_COUNT_ATTR:
3451 *(int16_t *)attrp = ((ELed_t *)objp)->lit_count;
3452 return (status);
3453 case PSVC_LED_IS_LOCATOR_ATTR:
3454 strcpy((char *)attrp, ((ELed_t *)objp)->is_locator);
3455 return (status);
3456 case PSVC_LED_LOCATOR_NAME_ATTR:
3457 strcpy((char *)attrp, ((ELed_t *)objp)->locator_name);
3458 return (status);
3461 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3463 return (status);
3466 static int32_t
3467 i_psvc_get_attr_4_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3469 int32_t status = PSVC_SUCCESS;
3471 switch (attr_id) {
3472 case PSVC_SENSOR_VALUE_ATTR:
3473 return (i_psvc_get_device_value_4_0(hdlp, objp, attrp));
3474 case PSVC_LO_WARN_ATTR:
3475 *(int32_t *)attrp = ((EDigiSensor_t *)objp)->lo_warn;
3476 return (status);
3477 case PSVC_LO_SHUT_ATTR:
3478 *(int32_t *)attrp = ((EDigiSensor_t *)objp)->lo_shut;
3479 return (status);
3480 case PSVC_HI_WARN_ATTR:
3481 *(int32_t *)attrp = ((EDigiSensor_t *)objp)->hi_warn;
3482 return (status);
3483 case PSVC_HI_SHUT_ATTR:
3484 *(int32_t *)attrp = ((EDigiSensor_t *)objp)->hi_shut;
3485 return (status);
3488 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3490 return (PSVC_SUCCESS);
3493 static int32_t
3494 i_psvc_get_attr_5_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3496 int32_t status = PSVC_SUCCESS;
3498 if (attr_id == PSVC_CONTROL_VALUE_ATTR) {
3499 return (i_psvc_get_device_value_5_0(hdlp, objp, attrp));
3502 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3504 return (status);
3507 static int32_t
3508 i_psvc_set_attr_5_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3510 int32_t status = PSVC_SUCCESS;
3512 if (attr_id == PSVC_CONTROL_VALUE_ATTR) {
3513 return (i_psvc_set_device_value_5_0(hdlp, objp, attrp));
3516 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3518 return (status);
3521 static int32_t
3522 i_psvc_get_attr_6_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3524 int32_t status = PSVC_SUCCESS;
3526 switch (attr_id) {
3527 case PSVC_GPIO_VALUE_ATTR:
3528 return (i_psvc_get_device_value_6_0(hdlp, objp, attrp));
3529 case PSVC_GPIO_BITS:
3530 *(int32_t *)attrp = 1;
3531 return (status);
3534 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3536 return (status);
3539 static int32_t
3540 i_psvc_set_attr_6_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3542 int32_t status = PSVC_SUCCESS;
3544 if (attr_id == PSVC_GPIO_VALUE_ATTR) {
3545 return (i_psvc_set_device_value_6_0(hdlp, objp, attrp));
3548 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3550 return (status);
3553 static int32_t
3554 i_psvc_get_attr_7_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3556 int32_t status = PSVC_SUCCESS;
3558 switch (attr_id) {
3559 case PSVC_SENSOR_VALUE_ATTR:
3560 return (i_psvc_get_device_value_7_0(hdlp, objp, attrp));
3561 case PSVC_LO_WARN_ATTR:
3562 *(int32_t *)attrp = ((EFanTach_t *)objp)->lo_warn;
3563 return (status);
3564 case PSVC_LO_SHUT_ATTR:
3565 *(int32_t *)attrp = ((EFanTach_t *)objp)->lo_shut;
3566 return (status);
3567 case PSVC_HI_WARN_ATTR:
3568 *(int32_t *)attrp = ((EFanTach_t *)objp)->hi_warn;
3569 return (status);
3570 case PSVC_HI_SHUT_ATTR:
3571 *(int32_t *)attrp = ((EFanTach_t *)objp)->hi_shut;
3572 return (status);
3575 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3577 return (PSVC_SUCCESS);
3580 static int32_t
3581 i_psvc_get_attr_8_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3583 int32_t status = PSVC_SUCCESS;
3585 switch (attr_id) {
3586 case PSVC_SWITCH_STATE_ATTR:
3587 case PSVC_STATE_ATTR:
3588 return (i_psvc_get_device_state_8_0(hdlp, objp, attrp));
3591 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3593 return (status);
3596 static int32_t
3597 i_psvc_set_attr_8_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3599 int32_t status = PSVC_SUCCESS;
3601 switch (attr_id) {
3602 case PSVC_SWITCH_STATE_ATTR:
3603 case PSVC_STATE_ATTR:
3604 return (i_psvc_set_device_state_8_0(hdlp, objp, attrp));
3607 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3609 return (status);
3612 static int32_t
3613 i_psvc_get_attr_9_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3615 int32_t status = PSVC_SUCCESS;
3617 switch (attr_id) {
3618 case PSVC_SWITCH_STATE_ATTR:
3619 case PSVC_STATE_ATTR:
3620 status = i_psvc_get_device_state_9_0(hdlp, objp, attrp);
3621 if ((status == PSVC_FAILURE) && (errno == EINVAL)) {
3622 strcpy((char *)attrp, PSVC_ERROR);
3623 return (PSVC_SUCCESS);
3624 } else {
3625 return (status);
3629 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3631 return (status);
3634 static int32_t
3635 i_psvc_get_attr_10_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3637 int32_t status = PSVC_SUCCESS;
3639 switch (attr_id) {
3640 case PSVC_GPIO_VALUE_ATTR:
3641 return (i_psvc_get_device_value_10_0(hdlp, objp, attrp));
3642 case PSVC_GPIO_BITS:
3643 *(int32_t *)attrp = 8;
3644 return (status);
3647 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3649 return (status);
3652 static int32_t
3653 i_psvc_set_attr_10_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3655 int32_t status = PSVC_SUCCESS;
3657 if (attr_id == PSVC_GPIO_VALUE_ATTR) {
3658 return (i_psvc_set_device_value_10_0(hdlp, objp, attrp));
3661 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3663 return (status);
3666 static int32_t
3667 i_psvc_get_attr_10_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3669 int32_t status = PSVC_SUCCESS;
3671 switch (attr_id) {
3672 case PSVC_GPIO_VALUE_ATTR:
3673 return (i_psvc_get_device_value_10_1(hdlp, objp, attrp));
3674 case PSVC_GPIO_BITS:
3675 *(int32_t *)attrp = 8;
3676 return (status);
3679 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3681 return (status);
3684 static int32_t
3685 i_psvc_set_attr_10_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3687 int32_t status = PSVC_SUCCESS;
3689 if (attr_id == PSVC_GPIO_VALUE_ATTR) {
3690 return (i_psvc_set_device_value_10_1(hdlp, objp, attrp));
3693 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3695 return (status);
3698 /* AT24 */
3699 static int32_t
3700 i_psvc_get_attr_11_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3702 int32_t status = PSVC_SUCCESS;
3703 int32_t probe_status;
3705 switch (attr_id) {
3706 case PSVC_PROBE_RESULT_ATTR:
3707 probe_status = i_psvc_probe_11_0(hdlp, objp);
3708 if (probe_status == PSVC_SUCCESS)
3709 strcpy((char *)attrp, PSVC_OK);
3710 else
3711 strcpy((char *)attrp, PSVC_ERROR);
3712 return (status);
3713 case PSVC_FRU_INFO_ATTR:
3714 status = i_psvc_get_reg_11_0(hdlp, objp, attr_id, attrp);
3715 return (status);
3718 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3720 return (status);
3723 static int32_t
3724 i_psvc_get_reg_11_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3726 int32_t status = PSVC_SUCCESS, ret;
3727 char path[1024], *data;
3728 int32_t fp, temp_errno;
3729 fru_info_t *fru_data;
3731 fru_data = (fru_info_t *)attrp;
3733 if (objp->present != PSVC_PRESENT) {
3734 errno = ENODEV;
3735 return (PSVC_FAILURE);
3738 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
3739 if (status != PSVC_SUCCESS)
3740 return (status);
3742 fp = open(path, O_RDWR);
3743 if (fp == -1) {
3744 return (PSVC_FAILURE);
3747 ret = lseek(fp, fru_data->buf_start, SEEK_SET);
3748 if (ret != fru_data->buf_start) {
3749 temp_errno = errno;
3750 close(fp);
3751 errno = temp_errno;
3752 return (PSVC_FAILURE);
3755 data = (char *)malloc(fru_data->read_size);
3756 ret = read(fp, data, fru_data->read_size);
3757 if (ret == -1) {
3758 free(data);
3759 close(fp);
3760 errno = EIO;
3761 return (-1);
3764 memcpy(fru_data->buf, data, fru_data->read_size);
3765 free(data);
3766 close(fp);
3768 return (status);
3771 static int32_t
3772 i_psvc_get_attr_11_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3774 int32_t status = PSVC_SUCCESS;
3775 int32_t probe_status;
3777 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3778 probe_status = i_psvc_probe_11_1(hdlp, objp);
3779 if (probe_status == PSVC_SUCCESS)
3780 strcpy((char *)attrp, PSVC_OK);
3781 else
3782 strcpy((char *)attrp, PSVC_ERROR);
3783 return (status);
3786 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3788 return (status);
3791 static int32_t
3792 i_psvc_get_attr_11_2(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3794 int32_t status = PSVC_SUCCESS;
3795 int32_t probe_status;
3797 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3798 probe_status = i_psvc_probe_11_2(hdlp, objp);
3799 if (probe_status == PSVC_SUCCESS)
3800 strcpy((char *)attrp, PSVC_OK);
3801 else
3802 strcpy((char *)attrp, PSVC_ERROR);
3803 return (status);
3806 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3808 return (status);
3811 static int32_t
3812 i_psvc_get_attr_11_3(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3814 int32_t status = PSVC_SUCCESS;
3815 int32_t probe_status;
3817 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3818 probe_status = i_psvc_probe_11_3(hdlp, objp);
3819 if (probe_status == PSVC_SUCCESS)
3820 strcpy((char *)attrp, PSVC_OK);
3821 else
3822 strcpy((char *)attrp, PSVC_ERROR);
3823 return (status);
3826 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3828 return (status);
3831 static int32_t
3832 i_psvc_get_attr_11_4(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3834 int32_t status = PSVC_SUCCESS;
3835 int32_t probe_status;
3837 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3838 probe_status = i_psvc_probe_11_4(hdlp, objp);
3839 if (probe_status == PSVC_SUCCESS)
3840 strcpy((char *)attrp, PSVC_OK);
3841 else
3842 strcpy((char *)attrp, PSVC_ERROR);
3843 return (status);
3846 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3848 return (status);
3851 static int32_t
3852 i_psvc_get_attr_11_5(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3854 int32_t status = PSVC_SUCCESS;
3855 int32_t probe_status;
3857 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3858 probe_status = i_psvc_probe_11_5(hdlp, objp);
3859 if (probe_status == PSVC_SUCCESS)
3860 strcpy((char *)attrp, PSVC_OK);
3861 else
3862 strcpy((char *)attrp, PSVC_ERROR);
3863 return (status);
3866 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3868 return (status);
3871 static int32_t
3872 i_psvc_get_attr_11_6(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3874 int32_t status = PSVC_SUCCESS;
3875 int32_t probe_status;
3877 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3878 probe_status = i_psvc_probe_11_6(hdlp, objp);
3879 if (probe_status == PSVC_SUCCESS)
3880 strcpy((char *)attrp, PSVC_OK);
3881 else
3882 strcpy((char *)attrp, PSVC_ERROR);
3883 return (status);
3886 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3888 return (status);
3891 static int32_t
3892 i_psvc_get_attr_11_7(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3894 int32_t status = PSVC_SUCCESS;
3895 int32_t probe_status;
3897 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3898 probe_status = i_psvc_probe_11_7(hdlp, objp);
3899 if (probe_status == PSVC_SUCCESS)
3900 strcpy((char *)attrp, PSVC_OK);
3901 else
3902 strcpy((char *)attrp, PSVC_ERROR);
3903 return (status);
3906 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3908 return (status);
3911 static int32_t
3912 i_psvc_get_attr_11_8(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3914 int32_t status = PSVC_SUCCESS;
3915 int32_t probe_status;
3917 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3918 probe_status = i_psvc_probe_11_8(hdlp, objp);
3919 if (probe_status == PSVC_SUCCESS)
3920 strcpy((char *)attrp, PSVC_OK);
3921 else
3922 strcpy((char *)attrp, PSVC_ERROR);
3923 return (status);
3926 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3928 return (status);
3931 static int32_t
3932 i_psvc_get_attr_11_9(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3934 int32_t status = PSVC_SUCCESS;
3935 int32_t probe_status;
3937 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3938 probe_status = i_psvc_probe_11_9(hdlp, objp);
3939 if (probe_status == PSVC_SUCCESS)
3940 strcpy((char *)attrp, PSVC_OK);
3941 else
3942 strcpy((char *)attrp, PSVC_ERROR);
3943 return (status);
3946 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3948 return (status);
3951 static int32_t
3952 i_psvc_load_generic(
3953 EHdl_t *hdlp,
3954 char *name,
3955 EObj_t **objpp,
3956 char *buf,
3957 int32_t obj_size)
3959 int32_t found, key, array;
3960 EObj_t *objp;
3961 char *start;
3962 char cur_device[NAMELEN];
3963 int slot;
3964 ETable_Array *tbl_arr;
3966 key = psvc_get_str_key(name);
3967 array = key % PSVC_MAX_TABLE_ARRAYS;
3968 tbl_arr = &(hdlp->tbl_arry[array]);
3970 if (tbl_arr->nextid == hdlp->total_obj_count) {
3971 errno = EINVAL;
3972 return (PSVC_FAILURE);
3973 } else {
3974 slot = tbl_arr->nextid++;
3975 tbl_arr->obj_count++;
3978 if (i_psvc_find_file_section(hdlp->fp, "OBJECT_INFO") != PSVC_SUCCESS)
3979 return (PSVC_FAILURE);
3981 fgets(buf, BUFSZ, hdlp->fp);
3982 while (strcmp(buf, "OBJECT_INFO_END")) {
3983 start = strrchr(buf, '/');
3984 if (start == NULL) {
3985 errno = EINVAL;
3986 return (PSVC_FAILURE);
3988 found = sscanf(start + 1, "%s", cur_device);
3989 if (found != 1) {
3990 errno = EINVAL;
3991 return (PSVC_FAILURE);
3993 if (strcmp(name, cur_device) == 0) /* found it */
3994 break;
3995 fgets(buf, BUFSZ, hdlp->fp);
3998 tbl_arr->obj_tbl[slot].objp = (EObj_t *)malloc(obj_size);
3999 if (tbl_arr->obj_tbl[slot].objp == 0)
4000 return (PSVC_FAILURE);
4001 objp = (EObj_t *)tbl_arr->obj_tbl[slot].objp;
4002 tbl_arr->obj_tbl[slot].type = PSVC_OBJ;
4004 memset(objp, 0, obj_size);
4005 strcpy(objp->label, name);
4006 strcpy(tbl_arr->obj_tbl[slot].name, name);
4008 tbl_arr->obj_tbl[slot].key = key;
4010 if (i_psvc_value(buf, PSVC_CLASS_ATTR, &objp->class) != PSVC_SUCCESS) {
4011 i_psvc_destructor(hdlp, name, objp);
4012 return (PSVC_FAILURE);
4014 if (i_psvc_value(buf, PSVC_SUBCLASS_ATTR, &objp->subclass) !=
4015 PSVC_SUCCESS) {
4016 i_psvc_destructor(hdlp, name, objp);
4017 return (PSVC_FAILURE);
4019 if (i_psvc_value(buf, PSVC_INSTANCE_ATTR, &objp->instance) !=
4020 PSVC_SUCCESS) {
4021 i_psvc_destructor(hdlp, name, objp);
4022 return (PSVC_FAILURE);
4024 if (i_psvc_value(buf, PSVC_FEATURES_ATTR, &objp->features) !=
4025 PSVC_SUCCESS) {
4026 i_psvc_destructor(hdlp, name, objp);
4027 return (PSVC_FAILURE);
4029 if (i_psvc_value(buf, PSVC_ADDR_SPEC_ATTR, &objp->addr_spec) !=
4030 PSVC_SUCCESS) {
4031 i_psvc_destructor(hdlp, name, objp);
4032 return (PSVC_FAILURE);
4035 if (objp->features & PSVC_DEV_SECONDARY)
4036 objp->enabled = PSVC_DISABLED;
4037 else
4038 objp->enabled = PSVC_ENABLED;
4040 if (PSVC_GET_VERSION(objp->addr_spec) > PSVC_VERSION) {
4041 errno = EINVAL;
4042 i_psvc_destructor(hdlp, name, objp);
4043 return (PSVC_FAILURE);
4046 *objpp = objp;
4047 return (PSVC_SUCCESS);
4052 static int32_t
4053 i_psvc_not_supported()
4055 errno = ENOTSUP;
4056 return (PSVC_FAILURE);
4059 /* Temperature sensor */
4060 /* Class 0 Subclass 0 are temperature sensors that cannot be updated */
4061 static int32_t
4062 i_psvc_constructor_0_0(
4063 EHdl_t *hdlp,
4064 char *id,
4065 EObj_t **objpp)
4067 int32_t status;
4068 char buf[BUFSZ];
4069 ETempSensor_t *dp;
4071 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4072 sizeof (ETempSensor_t));
4073 if (status != PSVC_SUCCESS)
4074 return (status);
4076 /* Load class specific info */
4077 dp = (ETempSensor_t *)*objpp;
4078 if (i_psvc_value(buf, PSVC_LO_WARN_ATTR, &dp->lo_warn)
4079 != PSVC_SUCCESS) {
4080 i_psvc_destructor(hdlp, id, dp);
4081 return (PSVC_FAILURE);
4083 if (i_psvc_value(buf, PSVC_LO_SHUT_ATTR, &dp->lo_shut)
4084 != PSVC_SUCCESS) {
4085 i_psvc_destructor(hdlp, id, dp);
4086 return (PSVC_FAILURE);
4088 if (i_psvc_value(buf, PSVC_HI_WARN_ATTR, &dp->hi_warn)
4089 != PSVC_SUCCESS) {
4090 i_psvc_destructor(hdlp, id, dp);
4091 return (PSVC_FAILURE);
4093 if (i_psvc_value(buf, PSVC_HI_SHUT_ATTR, &dp->hi_shut)
4094 != PSVC_SUCCESS) {
4095 i_psvc_destructor(hdlp, id, dp);
4096 return (PSVC_FAILURE);
4099 dp->ld.constructor = i_psvc_constructor_0_0;
4100 dp->ld.destructor = i_psvc_destructor;
4101 dp->ld.get_attr = i_psvc_get_attr_0_0;
4102 dp->ld.set_attr = i_psvc_set_attr_generic;
4104 return (0);
4107 /* Class 0 Subclass 1 are temperature sensors that can be updated */
4108 static int32_t
4109 i_psvc_constructor_0_1(
4110 EHdl_t *hdlp,
4111 char *id,
4112 EObj_t **objpp)
4114 int32_t status;
4115 char buf[BUFSZ];
4116 ETempSensor_t *dp;
4118 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4119 sizeof (ETempSensor_t));
4120 if (status != PSVC_SUCCESS)
4121 return (status);
4123 /* Load class specific info */
4124 dp = (ETempSensor_t *)*objpp;
4125 if (i_psvc_value(buf, PSVC_LO_WARN_ATTR, &dp->lo_warn)
4126 != PSVC_SUCCESS) {
4127 i_psvc_destructor(hdlp, id, dp);
4128 return (PSVC_FAILURE);
4130 if (i_psvc_value(buf, PSVC_LO_SHUT_ATTR, &dp->lo_shut)
4131 != PSVC_SUCCESS) {
4132 i_psvc_destructor(hdlp, id, dp);
4133 return (PSVC_FAILURE);
4135 if (i_psvc_value(buf, PSVC_HI_WARN_ATTR, &dp->hi_warn)
4136 != PSVC_SUCCESS) {
4137 i_psvc_destructor(hdlp, id, dp);
4138 return (PSVC_FAILURE);
4140 if (i_psvc_value(buf, PSVC_HI_SHUT_ATTR, &dp->hi_shut)
4141 != PSVC_SUCCESS) {
4142 i_psvc_destructor(hdlp, id, dp);
4143 return (PSVC_FAILURE);
4146 if ((*objpp)->features & PSVC_OPT_TEMP) {
4147 if (i_psvc_value(buf, PSVC_OPTIMAL_TEMP_ATTR, &dp->opt_temp)
4148 != PSVC_SUCCESS) {
4149 i_psvc_destructor(hdlp, id, dp);
4150 return (PSVC_FAILURE);
4153 if ((*objpp)->features & PSVC_HW_LOW_SHUT) {
4154 if (i_psvc_value(buf, PSVC_HW_LO_SHUT_ATTR, &dp->hw_lo_shut)
4155 != PSVC_SUCCESS) {
4156 i_psvc_destructor(hdlp, id, dp);
4157 return (PSVC_FAILURE);
4160 if ((*objpp)->features & PSVC_HW_HIGH_SHUT) {
4161 if (i_psvc_value(buf, PSVC_HW_HI_SHUT_ATTR, &dp->hw_hi_shut)
4162 != PSVC_SUCCESS) {
4163 i_psvc_destructor(hdlp, id, dp);
4164 return (PSVC_FAILURE);
4168 dp->ld.constructor = i_psvc_constructor_0_1;
4169 dp->ld.destructor = i_psvc_destructor;
4170 dp->ld.get_attr = i_psvc_get_attr_0_1;
4171 dp->ld.set_attr = i_psvc_set_attr_0_1;
4173 return (0);
4176 /* Fan */
4177 static int32_t
4178 i_psvc_constructor_1_0(
4179 EHdl_t *hdlp,
4180 char *id,
4181 EObj_t **objpp)
4183 int32_t status;
4184 char buf[BUFSZ];
4185 EFan_t *dp;
4187 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4188 sizeof (EFan_t));
4189 if (status != PSVC_SUCCESS)
4190 return (status);
4192 /* Load class specific info */
4193 dp = (EFan_t *)*objpp;
4194 if (i_psvc_value(buf, PSVC_SETPOINT_ATTR, &dp->setpoint)
4195 != PSVC_SUCCESS) {
4196 i_psvc_destructor(hdlp, id, dp);
4197 return (PSVC_FAILURE);
4199 if (i_psvc_value(buf, PSVC_HYSTERESIS_ATTR, &dp->hysteresis)
4200 != PSVC_SUCCESS) {
4201 i_psvc_destructor(hdlp, id, dp);
4202 return (PSVC_FAILURE);
4204 if (i_psvc_value(buf, PSVC_LOOPGAIN_ATTR, &dp->loopgain)
4205 != PSVC_SUCCESS) {
4206 i_psvc_destructor(hdlp, id, dp);
4207 return (PSVC_FAILURE);
4209 if (i_psvc_value(buf, PSVC_LOOPBIAS_ATTR, &dp->loopbias)
4210 != PSVC_SUCCESS) {
4211 i_psvc_destructor(hdlp, id, dp);
4212 return (PSVC_FAILURE);
4215 dp->ld.constructor = i_psvc_constructor_1_0;
4216 dp->ld.destructor = i_psvc_destructor;
4217 dp->ld.get_attr = i_psvc_get_attr_1_0;
4218 dp->ld.set_attr = i_psvc_set_attr_1_0;
4220 return (PSVC_SUCCESS);
4224 /* LED */
4225 static int32_t
4226 i_psvc_constructor_2_0(
4227 EHdl_t *hdlp,
4228 char *id,
4229 EObj_t **objpp)
4231 int32_t status;
4232 char buf[BUFSZ];
4233 ELed_t *dp;
4235 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4236 sizeof (ELed_t));
4237 if (status != PSVC_SUCCESS)
4238 return (status);
4240 /* Load class specific info */
4241 dp = (ELed_t *)*objpp;
4243 if (i_psvc_value(buf, PSVC_LED_COLOR_ATTR, dp->color)
4244 != PSVC_SUCCESS) {
4245 i_psvc_destructor(hdlp, id, dp);
4246 return (PSVC_FAILURE);
4249 dp->ld.constructor = i_psvc_constructor_2_0;
4250 dp->ld.destructor = i_psvc_destructor;
4251 dp->ld.get_attr = i_psvc_get_attr_2_0;
4252 dp->ld.set_attr = i_psvc_set_attr_2_0;
4254 return (PSVC_SUCCESS);
4257 static int32_t
4258 i_psvc_constructor_2_1(
4259 EHdl_t *hdlp,
4260 char *id,
4261 EObj_t **objpp)
4263 int32_t status;
4264 char buf[BUFSZ];
4265 ELed_t *dp;
4267 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4268 sizeof (ELed_t));
4269 if (status != PSVC_SUCCESS)
4270 return (status);
4272 /* Load class specific info */
4273 dp = (ELed_t *)*objpp;
4275 if (i_psvc_value(buf, PSVC_LED_COLOR_ATTR, dp->color)
4276 != PSVC_SUCCESS) {
4277 i_psvc_destructor(hdlp, id, dp);
4278 return (PSVC_FAILURE);
4281 dp->ld.constructor = i_psvc_constructor_2_1;
4282 dp->ld.destructor = i_psvc_destructor;
4283 dp->ld.get_attr = i_psvc_get_attr_2_1;
4284 dp->ld.set_attr = i_psvc_set_attr_2_1;
4286 return (PSVC_SUCCESS);
4289 static int32_t
4290 i_psvc_constructor_2_2(
4291 EHdl_t *hdlp,
4292 char *id,
4293 EObj_t **objpp)
4295 int32_t status;
4296 char buf[BUFSZ];
4297 ELed_t *dp;
4299 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4300 sizeof (ELed_t));
4301 if (status != PSVC_SUCCESS)
4302 return (status);
4304 /* Load class specific info */
4305 dp = (ELed_t *)*objpp;
4307 if (i_psvc_value(buf, PSVC_LED_COLOR_ATTR, dp->color)
4308 != PSVC_SUCCESS) {
4309 i_psvc_destructor(hdlp, id, dp);
4310 return (PSVC_FAILURE);
4312 if (i_psvc_value(buf, PSVC_LED_IS_LOCATOR_ATTR, dp->is_locator)
4313 != PSVC_SUCCESS) {
4314 i_psvc_destructor(hdlp, id, dp);
4315 return (PSVC_FAILURE);
4317 if (strcmp(dp->is_locator, PSVC_LOCATOR_TRUE) == 0) {
4318 if (i_psvc_value(buf, PSVC_LED_LOCATOR_NAME_ATTR,
4319 dp->locator_name) != PSVC_SUCCESS) {
4320 i_psvc_destructor(hdlp, id, dp);
4321 return (PSVC_FAILURE);
4323 } else {
4324 strcpy(dp->locator_name, "N/A");
4327 dp->ld.constructor = i_psvc_constructor_2_2;
4328 dp->ld.destructor = i_psvc_destructor;
4329 dp->ld.get_attr = i_psvc_get_attr_2_2;
4330 dp->ld.set_attr = i_psvc_set_attr_2_0;
4332 return (PSVC_SUCCESS);
4335 /* System Device */
4336 static int32_t
4337 i_psvc_constructor_3_0(
4338 EHdl_t *hdlp,
4339 char *id,
4340 EObj_t **objpp)
4342 int32_t status;
4343 char buf[BUFSZ];
4344 ESystem_t *dp;
4346 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (ESystem_t));
4347 if (status != PSVC_SUCCESS)
4348 return (status);
4350 /* Load class specific info */
4351 dp = (ESystem_t *)*objpp;
4353 dp->ld.constructor = i_psvc_constructor_3_0;
4354 dp->ld.destructor = i_psvc_destructor;
4355 dp->ld.get_attr = i_psvc_get_attr_generic;
4356 dp->ld.set_attr = i_psvc_set_attr_generic;
4358 return (PSVC_SUCCESS);
4361 /* Digital Sensor */
4362 static int32_t
4363 i_psvc_constructor_4_0(
4364 EHdl_t *hdlp,
4365 char *id,
4366 EObj_t **objpp)
4368 int32_t status;
4369 char buf[BUFSZ];
4370 EDigiSensor_t *dp;
4372 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4373 sizeof (EDigiSensor_t));
4374 if (status != PSVC_SUCCESS) {
4375 return (status);
4378 /* Load class specific info */
4379 dp = (EDigiSensor_t *)*objpp;
4380 if (i_psvc_value(buf, PSVC_LO_WARN_ATTR, &dp->lo_warn)
4381 != PSVC_SUCCESS) {
4382 i_psvc_destructor(hdlp, id, dp);
4383 return (PSVC_FAILURE);
4385 if (i_psvc_value(buf, PSVC_LO_SHUT_ATTR, &dp->lo_shut)
4386 != PSVC_SUCCESS) {
4387 i_psvc_destructor(hdlp, id, dp);
4388 return (PSVC_FAILURE);
4390 if (i_psvc_value(buf, PSVC_HI_WARN_ATTR, &dp->hi_warn)
4391 != PSVC_SUCCESS) {
4392 i_psvc_destructor(hdlp, id, dp);
4393 return (PSVC_FAILURE);
4395 if (i_psvc_value(buf, PSVC_HI_SHUT_ATTR, &dp->hi_shut)
4396 != PSVC_SUCCESS) {
4397 i_psvc_destructor(hdlp, id, dp);
4398 return (PSVC_FAILURE);
4401 dp->ld.constructor = i_psvc_constructor_4_0;
4402 dp->ld.destructor = i_psvc_destructor;
4403 dp->ld.get_attr = i_psvc_get_attr_4_0;
4404 dp->ld.set_attr = i_psvc_set_attr_generic;
4406 return (PSVC_SUCCESS);
4409 /* Digital Control */
4410 static int32_t
4411 i_psvc_constructor_5_0(
4412 EHdl_t *hdlp,
4413 char *id,
4414 EObj_t **objpp)
4416 int32_t status;
4417 char buf[BUFSZ];
4418 EDigiControl_t *dp;
4420 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4421 sizeof (EDigiControl_t));
4422 if (status != PSVC_SUCCESS)
4423 return (status);
4425 /* Load class specific info */
4426 dp = (EDigiControl_t *)*objpp;
4428 dp->ld.constructor = i_psvc_constructor_5_0;
4429 dp->ld.destructor = i_psvc_destructor;
4430 dp->ld.get_attr = i_psvc_get_attr_5_0;
4431 dp->ld.set_attr = i_psvc_set_attr_5_0;
4432 return (PSVC_SUCCESS);
4435 /* Boolean GPIO */
4436 static int32_t
4437 i_psvc_constructor_6_0(
4438 EHdl_t *hdlp,
4439 char *id,
4440 EObj_t **objpp)
4442 int32_t status;
4443 char buf[BUFSZ];
4444 EBoolSensor_t *dp;
4446 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4447 sizeof (EBoolSensor_t));
4448 if (status != PSVC_SUCCESS)
4449 return (status);
4451 /* Load class specific info */
4452 dp = (EBoolSensor_t *)*objpp;
4454 dp->ld.constructor = i_psvc_constructor_6_0;
4455 dp->ld.destructor = i_psvc_destructor;
4456 dp->ld.get_attr = i_psvc_get_attr_6_0;
4457 dp->ld.set_attr = i_psvc_set_attr_6_0;
4459 return (PSVC_SUCCESS);
4462 /* Fan Tachometer */
4463 static int32_t
4464 i_psvc_constructor_7_0(
4465 EHdl_t *hdlp,
4466 char *id,
4467 EObj_t **objpp)
4469 int32_t status;
4470 char buf[BUFSZ];
4471 EFanTach_t *dp;
4473 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4474 sizeof (EFanTach_t));
4475 if (status != PSVC_SUCCESS)
4476 return (status);
4478 /* Load class specific info */
4479 dp = (EFanTach_t *)*objpp;
4480 if (i_psvc_value(buf, PSVC_LO_WARN_ATTR, &dp->lo_warn)
4481 != PSVC_SUCCESS) {
4482 i_psvc_destructor(hdlp, id, dp);
4483 return (PSVC_FAILURE);
4485 if (i_psvc_value(buf, PSVC_LO_SHUT_ATTR, &dp->lo_shut)
4486 != PSVC_SUCCESS) {
4487 i_psvc_destructor(hdlp, id, dp);
4488 return (PSVC_FAILURE);
4490 if (i_psvc_value(buf, PSVC_HI_WARN_ATTR, &dp->hi_warn)
4491 != PSVC_SUCCESS) {
4492 i_psvc_destructor(hdlp, id, dp);
4493 return (PSVC_FAILURE);
4495 if (i_psvc_value(buf, PSVC_HI_SHUT_ATTR, &dp->hi_shut)
4496 != PSVC_SUCCESS) {
4497 i_psvc_destructor(hdlp, id, dp);
4498 return (PSVC_FAILURE);
4501 dp->ld.constructor = i_psvc_constructor_7_0;
4502 dp->ld.destructor = i_psvc_destructor;
4503 dp->ld.get_attr = i_psvc_get_attr_7_0;
4504 dp->ld.set_attr = i_psvc_set_attr_generic;
4506 return (PSVC_SUCCESS);
4509 /* On Off Switch */
4510 static int32_t
4511 i_psvc_constructor_8_0(
4512 EHdl_t *hdlp,
4513 char *id,
4514 EObj_t **objpp)
4516 int32_t status;
4517 char buf[BUFSZ];
4518 ESwitch_t *dp;
4520 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4521 sizeof (ESwitch_t));
4522 if (status != PSVC_SUCCESS)
4523 return (status);
4525 /* Load class specific info */
4526 dp = (ESwitch_t *)*objpp;
4528 dp->ld.constructor = i_psvc_constructor_8_0;
4529 dp->ld.destructor = i_psvc_destructor;
4530 dp->ld.get_attr = i_psvc_get_attr_8_0;
4531 dp->ld.set_attr = i_psvc_set_attr_8_0;
4533 return (PSVC_SUCCESS);
4536 /* Key Switch */
4537 static int32_t
4538 i_psvc_constructor_9_0(
4539 EHdl_t *hdlp,
4540 char *id,
4541 EObj_t **objpp)
4543 int32_t status;
4544 char buf[BUFSZ];
4545 EKeySwitch_t *dp;
4547 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4548 sizeof (EKeySwitch_t));
4549 if (status != PSVC_SUCCESS)
4550 return (status);
4552 /* Load class specific info */
4553 dp = (EKeySwitch_t *)*objpp;
4555 dp->ld.constructor = i_psvc_constructor_9_0;
4556 dp->ld.destructor = i_psvc_destructor;
4557 dp->ld.get_attr = i_psvc_get_attr_9_0;
4558 dp->ld.set_attr = i_psvc_set_attr_generic;
4560 return (PSVC_SUCCESS);
4563 /* 8 Bit GPIO , devices with registers, calls get_reg()/set_reg() */
4564 static int32_t
4565 i_psvc_constructor_10_0(
4566 EHdl_t *hdlp,
4567 char *id,
4568 EObj_t **objpp)
4570 int32_t status;
4571 char buf[BUFSZ];
4572 EGPIO8_t *dp;
4574 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EGPIO8_t));
4575 if (status != PSVC_SUCCESS)
4576 return (status);
4578 /* Load class specific info */
4579 dp = (EGPIO8_t *)*objpp;
4581 dp->ld.constructor = i_psvc_constructor_10_0;
4582 dp->ld.destructor = i_psvc_destructor;
4583 dp->ld.get_attr = i_psvc_get_attr_10_0;
4584 dp->ld.set_attr = i_psvc_set_attr_10_0;
4586 return (PSVC_SUCCESS);
4589 /* 8 Bit GPIO , devices with ports, calls get_port()/set_port() */
4590 static int32_t
4591 i_psvc_constructor_10_1(
4592 EHdl_t *hdlp,
4593 char *id,
4594 EObj_t **objpp)
4596 int32_t status;
4597 char buf[BUFSZ];
4598 EGPIO8_t *dp;
4600 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EGPIO8_t));
4601 if (status != PSVC_SUCCESS)
4602 return (status);
4604 /* Load class specific info */
4605 dp = (EGPIO8_t *)*objpp;
4607 dp->ld.constructor = i_psvc_constructor_10_1;
4608 dp->ld.destructor = i_psvc_destructor;
4609 dp->ld.get_attr = i_psvc_get_attr_10_1;
4610 dp->ld.set_attr = i_psvc_set_attr_10_1;
4612 return (PSVC_SUCCESS);
4615 /* AT24 */
4616 static int32_t
4617 i_psvc_constructor_11_0(
4618 EHdl_t *hdlp,
4619 char *id,
4620 EObj_t **objpp)
4622 int32_t status;
4623 char buf[BUFSZ];
4624 EPhysDev_t *dp;
4626 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4627 sizeof (EPhysDev_t));
4628 if (status != PSVC_SUCCESS)
4629 return (status);
4631 /* Load class specific info */
4632 dp = (EPhysDev_t *)*objpp;
4634 dp->ld.constructor = i_psvc_constructor_11_0;
4635 dp->ld.destructor = i_psvc_destructor;
4636 dp->ld.get_attr = i_psvc_get_attr_11_0;
4637 dp->ld.set_attr = i_psvc_set_attr_generic;
4638 dp->get_temperature = i_psvc_not_supported;
4639 dp->get_fanspeed = i_psvc_not_supported;
4640 dp->get_input = i_psvc_not_supported;
4641 dp->get_bit = i_psvc_not_supported;
4642 dp->set_bit = i_psvc_not_supported;
4643 dp->get_port = i_psvc_not_supported;
4644 dp->set_port = i_psvc_not_supported;
4645 dp->get_output = i_psvc_not_supported;
4646 dp->set_output = i_psvc_not_supported;
4647 dp->get_reg = i_psvc_get_reg_11_0;
4648 dp->set_reg = i_psvc_not_supported;
4650 return (PSVC_SUCCESS);
4653 /* HPC3130 */
4654 static int32_t
4655 i_psvc_constructor_11_1(
4656 EHdl_t *hdlp,
4657 char *id,
4658 EObj_t **objpp)
4660 int32_t status;
4661 char buf[BUFSZ];
4662 EPhysDev_t *dp;
4664 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4665 if (status != PSVC_SUCCESS)
4666 return (status);
4668 /* Load class specific info */
4669 dp = (EPhysDev_t *)*objpp;
4671 dp->ld.constructor = i_psvc_constructor_11_1;
4672 dp->ld.destructor = i_psvc_destructor;
4673 dp->ld.get_attr = i_psvc_get_attr_11_1;
4674 dp->ld.set_attr = i_psvc_set_attr_generic;
4675 dp->get_temperature = i_psvc_not_supported;
4676 dp->get_fanspeed = i_psvc_not_supported;
4677 dp->get_input = i_psvc_not_supported;
4678 dp->get_bit = i_psvc_not_supported;
4679 dp->set_bit = i_psvc_not_supported;
4680 dp->get_port = i_psvc_not_supported;
4681 dp->set_port = i_psvc_not_supported;
4682 dp->get_output = i_psvc_not_supported;
4683 dp->set_output = i_psvc_not_supported;
4684 dp->get_reg = i_psvc_get_reg_11_1;
4685 dp->set_reg = i_psvc_set_reg_11_1;
4687 return (PSVC_SUCCESS);
4690 /* LM75 */
4691 static int32_t
4692 i_psvc_constructor_11_2(
4693 EHdl_t *hdlp,
4694 char *id,
4695 EObj_t **objpp)
4697 int32_t status;
4698 char buf[BUFSZ];
4699 EPhysDev_t *dp;
4701 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4702 if (status != PSVC_SUCCESS)
4703 return (status);
4705 /* Load class specific info */
4706 dp = (EPhysDev_t *)*objpp;
4708 dp->ld.constructor = i_psvc_constructor_11_2;
4709 dp->ld.destructor = i_psvc_destructor;
4710 dp->ld.get_attr = i_psvc_get_attr_11_2;
4711 dp->ld.set_attr = i_psvc_set_attr_generic;
4712 dp->get_temperature = i_psvc_get_temperature_11_2;
4713 dp->get_fanspeed = i_psvc_not_supported;
4714 dp->get_input = i_psvc_not_supported;
4715 dp->get_bit = i_psvc_not_supported;
4716 dp->set_bit = i_psvc_not_supported;
4717 dp->get_port = i_psvc_not_supported;
4718 dp->set_port = i_psvc_not_supported;
4719 dp->get_output = i_psvc_not_supported;
4720 dp->set_output = i_psvc_not_supported;
4721 dp->get_reg = i_psvc_not_supported;
4722 dp->set_reg = i_psvc_not_supported;
4724 return (PSVC_SUCCESS);
4727 /* LTC1427 */
4728 static int32_t
4729 i_psvc_constructor_11_3(
4730 EHdl_t *hdlp,
4731 char *id,
4732 EObj_t **objpp)
4734 int32_t status;
4735 char buf[BUFSZ];
4736 EPhysDev_t *dp;
4737 char path[1024];
4739 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4740 if (status != PSVC_SUCCESS)
4741 return (status);
4744 * The following code upto and including the open() call is so the
4745 * device driver for the ltc1427 does not get unloaded by the OS at
4746 * any time. This is important as the device driver is a write only
4747 * physical device but DOES keep readable states in the device unitp
4748 * structure (I2C_GET_OUTPUT) as a result this device should not
4749 * be unload while PSVC is up and running
4751 status = i_psvc_get_devpath(hdlp, (*objpp)->addr_spec, path);
4752 if (status != PSVC_SUCCESS) {
4753 return (status);
4757 * We deliberately do not close our file handle, to prevent
4758 * any device instances from being detached. If an instance
4759 * is detached, the "readable states in the device unitp"
4760 * will be unloaded, causing loss of control of the device
4761 * and incorrect error(s) to be displayed.
4763 if (open(path, O_RDWR) == -1) {
4764 return (PSVC_FAILURE);
4766 /* Load class specific info */
4767 dp = (EPhysDev_t *)*objpp;
4769 dp->ld.constructor = i_psvc_constructor_11_3;
4770 dp->ld.destructor = i_psvc_destructor;
4771 dp->ld.get_attr = i_psvc_get_attr_11_3;
4772 dp->ld.set_attr = i_psvc_set_attr_generic;
4773 dp->get_temperature = i_psvc_not_supported;
4774 dp->get_fanspeed = i_psvc_not_supported;
4775 dp->get_input = i_psvc_not_supported;
4776 dp->get_bit = i_psvc_not_supported;
4777 dp->set_bit = i_psvc_not_supported;
4778 dp->get_port = i_psvc_not_supported;
4779 dp->set_port = i_psvc_not_supported;
4780 dp->get_output = i_psvc_get_output_11_3;
4781 dp->set_output = i_psvc_set_output_11_3;
4782 dp->get_reg = i_psvc_not_supported;
4783 dp->set_reg = i_psvc_not_supported;
4785 return (PSVC_SUCCESS);
4788 /* MAX1617 */
4789 static int32_t
4790 i_psvc_constructor_11_4(
4791 EHdl_t *hdlp,
4792 char *id,
4793 EObj_t **objpp)
4795 int32_t status;
4796 char buf[BUFSZ];
4797 EPhysDev_t *dp;
4799 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4800 if (status != PSVC_SUCCESS)
4801 return (status);
4803 /* Load class specific info */
4804 dp = (EPhysDev_t *)*objpp;
4806 dp->ld.constructor = i_psvc_constructor_11_4;
4807 dp->ld.destructor = i_psvc_destructor;
4808 dp->ld.get_attr = i_psvc_get_attr_11_4;
4809 dp->ld.set_attr = i_psvc_set_attr_generic;
4810 dp->get_temperature = i_psvc_get_temperature_11_4;
4811 dp->get_fanspeed = i_psvc_not_supported;
4812 dp->get_input = i_psvc_not_supported;
4813 dp->get_bit = i_psvc_not_supported;
4814 dp->set_bit = i_psvc_not_supported;
4815 dp->get_port = i_psvc_not_supported;
4816 dp->set_port = i_psvc_not_supported;
4817 dp->get_output = i_psvc_not_supported;
4818 dp->set_output = i_psvc_not_supported;
4819 dp->get_reg = i_psvc_not_supported;
4820 dp->set_reg = i_psvc_not_supported;
4822 return (PSVC_SUCCESS);
4825 /* PCF8574 */
4826 static int32_t
4827 i_psvc_constructor_11_5(
4828 EHdl_t *hdlp,
4829 char *id,
4830 EObj_t **objpp)
4832 int32_t status;
4833 char buf[BUFSZ];
4834 EPhysDev_t *dp;
4836 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4837 if (status != PSVC_SUCCESS)
4838 return (status);
4840 /* Load class specific info */
4841 dp = (EPhysDev_t *)*objpp;
4843 dp->ld.constructor = i_psvc_constructor_11_5;
4844 dp->ld.destructor = i_psvc_destructor;
4845 dp->ld.get_attr = i_psvc_get_attr_11_5;
4846 dp->ld.set_attr = i_psvc_set_attr_generic;
4847 dp->get_temperature = i_psvc_not_supported;
4848 dp->get_fanspeed = i_psvc_not_supported;
4849 dp->get_input = i_psvc_not_supported;
4850 dp->get_bit = i_psvc_get_bit_11_5;
4851 dp->set_bit = i_psvc_set_bit_11_5;
4852 dp->get_port = i_psvc_get_port_11_5;
4853 dp->set_port = i_psvc_set_port_11_5;
4854 dp->get_output = i_psvc_not_supported;
4855 dp->set_output = i_psvc_not_supported;
4856 dp->get_reg = i_psvc_not_supported;
4857 dp->set_reg = i_psvc_not_supported;
4859 return (PSVC_SUCCESS);
4862 /* PCF8591 */
4863 static int32_t
4864 i_psvc_constructor_11_6(
4865 EHdl_t *hdlp,
4866 char *id,
4867 EObj_t **objpp)
4869 int32_t status;
4870 char buf[BUFSZ];
4871 EPhysDev_t *dp;
4873 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4874 if (status != PSVC_SUCCESS)
4875 return (status);
4877 /* Load class specific info */
4878 dp = (EPhysDev_t *)*objpp;
4880 dp->ld.constructor = i_psvc_constructor_11_6;
4881 dp->ld.destructor = i_psvc_destructor;
4882 dp->ld.get_attr = i_psvc_get_attr_11_6;
4883 dp->ld.set_attr = i_psvc_set_attr_generic;
4884 dp->get_temperature = i_psvc_get_temperature_11_6;
4885 dp->get_fanspeed = i_psvc_not_supported;
4886 dp->get_input = i_psvc_get_input_11_6;
4887 dp->get_bit = i_psvc_not_supported;
4888 dp->set_bit = i_psvc_not_supported;
4889 dp->get_port = i_psvc_not_supported;
4890 dp->set_port = i_psvc_not_supported;
4891 dp->get_output = i_psvc_get_output_11_6;
4892 dp->set_output = i_psvc_set_output_11_6;
4893 dp->get_reg = i_psvc_not_supported;
4894 dp->set_reg = i_psvc_not_supported;
4896 return (PSVC_SUCCESS);
4899 /* SSC050 */
4900 static int32_t
4901 i_psvc_constructor_11_7(
4902 EHdl_t *hdlp,
4903 char *id,
4904 EObj_t **objpp)
4906 int32_t status;
4907 char buf[BUFSZ];
4908 EPhysDev_t *dp;
4910 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4911 if (status != PSVC_SUCCESS)
4912 return (status);
4914 /* Load class specific info */
4915 dp = (EPhysDev_t *)*objpp;
4917 dp->ld.constructor = i_psvc_constructor_11_7;
4918 dp->ld.destructor = i_psvc_destructor;
4919 dp->ld.get_attr = i_psvc_get_attr_11_7;
4920 dp->ld.set_attr = i_psvc_set_attr_generic;
4921 dp->get_temperature = i_psvc_not_supported;
4922 dp->get_fanspeed = i_psvc_get_fanspeed_11_7;
4923 dp->get_input = i_psvc_not_supported;
4924 dp->get_bit = i_psvc_get_bit_11_7;
4925 dp->set_bit = i_psvc_set_bit_11_7;
4926 dp->get_port = i_psvc_get_port_11_5; /* same as for class = 11, 5 */
4927 dp->set_port = i_psvc_set_port_11_5;
4928 dp->get_output = i_psvc_not_supported;
4929 dp->set_output = i_psvc_not_supported;
4930 dp->get_reg = i_psvc_get_reg_11_7;
4931 dp->set_reg = i_psvc_set_reg_11_7;
4933 return (PSVC_SUCCESS);
4936 /* TDA8444 */
4937 static int32_t
4938 i_psvc_constructor_11_8(
4939 EHdl_t *hdlp,
4940 char *id,
4941 EObj_t **objpp)
4943 int32_t status;
4944 char buf[BUFSZ];
4945 EPhysDev_t *dp;
4947 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4948 if (status != PSVC_SUCCESS)
4949 return (status);
4951 /* Load class specific info */
4952 dp = (EPhysDev_t *)*objpp;
4954 dp->ld.constructor = i_psvc_constructor_11_8;
4955 dp->ld.destructor = i_psvc_destructor;
4956 dp->ld.get_attr = i_psvc_get_attr_11_8;
4957 dp->ld.set_attr = i_psvc_set_attr_generic;
4958 dp->get_temperature = i_psvc_not_supported;
4959 dp->get_fanspeed = i_psvc_not_supported;
4960 dp->get_input = i_psvc_not_supported;
4961 dp->get_bit = i_psvc_not_supported;
4962 dp->set_bit = i_psvc_not_supported;
4963 dp->get_port = i_psvc_not_supported;
4964 dp->set_port = i_psvc_not_supported;
4965 dp->get_output = i_psvc_get_output_11_8;
4966 dp->set_output = i_psvc_set_output_11_8;
4967 dp->get_reg = i_psvc_not_supported;
4968 dp->set_reg = i_psvc_not_supported;
4970 return (PSVC_SUCCESS);
4973 /* SSC100 */
4974 static int32_t
4975 i_psvc_constructor_11_9(
4976 EHdl_t *hdlp,
4977 char *id,
4978 EObj_t **objpp)
4980 int32_t status;
4981 char buf[BUFSZ];
4982 EPhysDev_t *dp;
4984 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4985 if (status != PSVC_SUCCESS)
4986 return (status);
4988 /* Load class specific info */
4989 dp = (EPhysDev_t *)*objpp;
4991 dp->ld.constructor = i_psvc_constructor_11_9;
4992 dp->ld.destructor = i_psvc_destructor;
4993 dp->ld.get_attr = i_psvc_get_attr_11_9;
4994 dp->ld.set_attr = i_psvc_set_attr_generic;
4995 dp->get_temperature = i_psvc_not_supported;
4996 dp->get_fanspeed = i_psvc_not_supported;
4997 dp->get_input = i_psvc_not_supported;
4998 dp->get_bit = i_psvc_not_supported;
4999 dp->set_bit = i_psvc_not_supported;
5000 dp->get_port = i_psvc_get_port_11_5; /* Same as for class = 11, 5 */
5001 dp->set_port = i_psvc_set_port_11_5;
5002 dp->get_output = i_psvc_not_supported;
5003 dp->set_output = i_psvc_not_supported;
5004 dp->get_reg = i_psvc_not_supported;
5005 dp->set_reg = i_psvc_not_supported;
5007 return (PSVC_SUCCESS);
5010 int32_t
5011 psvc_init(EHdl_t **hdlpp)
5013 EHdl_t *hdlp;
5014 int i;
5015 char buf[BUFSZ];
5016 char platform[32];
5017 char filename[256];
5018 int found;
5019 int32_t status;
5020 pthread_mutexattr_t mutex_attr;
5021 uint32_t table_count;
5022 int forward_slash = 47;
5023 int new_line = 10;
5024 char *nl_char;
5026 hdlp = (EHdl_t *)malloc(sizeof (EHdl_t));
5027 if (hdlp == NULL)
5028 return (-1);
5029 memset(hdlp, 0, sizeof (EHdl_t));
5031 /* Initialize the lock */
5032 status = pthread_mutexattr_init(&mutex_attr);
5033 if (status != 0) {
5034 errno = status;
5035 return (-1);
5037 status = pthread_mutex_init(&hdlp->mutex, &mutex_attr);
5038 if (status != 0) {
5039 errno = status;
5040 return (-1);
5042 pthread_mutexattr_destroy(&mutex_attr);
5044 if (sysinfo(SI_PLATFORM, platform, sizeof (platform)) == -1) {
5045 return (-1);
5048 snprintf(filename, sizeof (filename),
5049 "/usr/platform/%s/lib/psvcobj.conf", platform);
5050 if ((hdlp->fp = fopen(filename, "r")) == NULL) {
5051 return (-1);
5055 /* Build the association ID lookup table */
5057 hdlp->othr_count = hdlp->assoc_count = ASSOC_STR_TAB_SIZE;
5058 if ((hdlp->othr_tbl = (EStringId_t *)malloc(sizeof (EStringId_t) *
5059 hdlp->othr_count)) == NULL) {
5060 return (-1);
5063 for (i = 0; i < hdlp->othr_count; ++i) {
5064 hdlp->othr_tbl[i].id = i;
5065 strcpy(hdlp->othr_tbl[i].name, assoc_str_tab[i]);
5067 qsort(hdlp->othr_tbl, hdlp->othr_count, sizeof (EStringId_t),
5068 (int (*)(const void *, const void *))i_psvc_name_compare_qsort);
5070 /* determine total number of objects + tables */
5071 if (i_psvc_find_file_section(hdlp->fp, "OBJECT_INFO") == -1) {
5072 return (-1);
5074 if (i_psvc_count_records(hdlp->fp, "OBJECT_INFO_END",
5075 &hdlp->total_obj_count) == -1) {
5076 return (-1);
5078 if (i_psvc_find_file_section(hdlp->fp, "TABLES") == PSVC_SUCCESS) {
5079 status = i_psvc_count_tables_associations(hdlp->fp,
5080 &table_count, "TABLE_END");
5081 if (status == PSVC_FAILURE) {
5082 return (status);
5084 hdlp->total_obj_count += table_count;
5087 /* Allocate object name to object pointer translation table */
5088 for (i = 0; i < PSVC_MAX_TABLE_ARRAYS; i++) {
5089 if ((hdlp->tbl_arry[i].obj_tbl =
5090 (ENamePtr_t *)malloc(
5091 sizeof (ENamePtr_t) *hdlp->total_obj_count)) == NULL) {
5092 return (-1);
5094 memset(hdlp->tbl_arry[i].obj_tbl, 0,
5095 sizeof (ENamePtr_t) * hdlp->total_obj_count);
5096 hdlp->tbl_arry[i].obj_count = 0;
5099 /* Build the association table */
5100 if (i_psvc_load_associations(hdlp, hdlp->fp) == -1)
5101 return (-1);
5103 /* Build the table of device paths */
5104 if (i_psvc_find_file_section(hdlp->fp, "DEVPATHS") == -1)
5105 return (-1);
5106 if (i_psvc_count_records(hdlp->fp, "DEVPATHS_END",
5107 &hdlp->dev_count) == -1)
5108 return (-1);
5109 if ((hdlp->dev_tbl = (EDevice_t *)malloc(sizeof (EDevice_t) *
5110 hdlp->dev_count)) == NULL) {
5111 return (-1);
5113 for (i = 0; i < hdlp->dev_count; ++i) {
5114 fgets(buf, BUFSZ, hdlp->fp);
5115 found = sscanf(buf, "%d %d %x %d",
5116 &hdlp->dev_tbl[i].controller,
5117 &hdlp->dev_tbl[i].bus, &hdlp->dev_tbl[i].addr,
5118 &hdlp->dev_tbl[i].port);
5119 if (found != 4) {
5120 errno = EINVAL;
5121 return (-1);
5123 strcpy(hdlp->dev_tbl[i].path, strchr(buf, forward_slash));
5125 * Replace new line character with NUL character
5127 nl_char = strchr(hdlp->dev_tbl[i].path, new_line);
5128 *nl_char = 0;
5131 /* Build the table of tables */
5132 if (i_psvc_load_tables(hdlp, hdlp->fp) == -1)
5133 return (-1);
5134 *hdlpp = hdlp;
5135 return (0);
5138 int32_t
5139 psvc_fini(EHdl_t *hdlp)
5141 int32_t i, j;
5142 ETable_Array *array;
5144 if (hdlp == 0)
5145 return (PSVC_SUCCESS);
5147 for (j = 0; j < PSVC_MAX_TABLE_ARRAYS; j++) {
5148 if (hdlp->tbl_arry[j].obj_tbl != 0) {
5149 array = &(hdlp->tbl_arry[j]);
5150 for (i = 0; i < array->obj_count; ++i) {
5151 if (array->obj_tbl[i].type == PSVC_OBJ) {
5152 if (!array->obj_tbl[i].objp) {
5153 /* Skip non-existent object */
5154 continue;
5156 array->obj_tbl[i].objp->destructor(hdlp,
5157 array->obj_tbl[i].objp->label,
5158 array->obj_tbl[i].objp);
5161 if (array->obj_tbl[i].type == PSVC_TBL) {
5162 ETable_t *tblp =
5163 (ETable_t *)array->obj_tbl[i].objp;
5164 if (tblp->table != 0)
5165 free(tblp->table);
5169 free(array->obj_tbl);
5173 if (hdlp->othr_tbl != 0)
5174 free(hdlp->othr_tbl);
5176 if (hdlp->assoc_tbl != 0) {
5177 for (i = 0; i < hdlp->assoc_count; ++i) {
5178 if (hdlp->assoc_tbl[i].table != 0)
5179 free(hdlp->assoc_tbl[i].table);
5181 free(hdlp->assoc_tbl);
5184 if (hdlp->dev_tbl != 0)
5185 free(hdlp->dev_tbl);
5186 if (hdlp->fp != 0)
5187 fclose(hdlp->fp);
5188 pthread_mutex_destroy(&hdlp->mutex);
5189 free(hdlp);
5190 return (PSVC_SUCCESS);
5193 int32_t
5194 ioctl_retry(int fp, int request, void * arg_pointer)
5196 int32_t ret = PSVC_SUCCESS;
5197 int32_t tries = 0;
5200 * Becuase the i2c bus is a multimaster bus we need to protect
5201 * ourselves from bus masters that are not being good bus citizens.
5202 * A retry number of 10 should be sufficient to handle any bad bus
5203 * citizens. After that we will simply say that there is something
5204 * wrong with the ioctl transaction and let it bubble back up.
5206 do {
5207 ret = ioctl(fp, request, arg_pointer);
5208 tries ++;
5209 } while ((ret == -1) && (tries < 10));
5211 return (ret);
5214 static int32_t
5215 psvc_get_str_key(char *object)
5217 int32_t key = 0;
5218 int i, length;
5220 length = strlen(object);
5221 for (i = 0; i < length; i++) {
5222 if ((object[i] > 47) && (object[i] < 58)) {
5223 key = key + ((object[i] - 50) + 2);
5224 } else {
5225 key = key + object[i];
5230 return (key);