1 /*
2 * CDDL HEADER START
3 *
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.
8 *
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.
13 *
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]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 /*
30 * This file consists of routines to manage objects in the
31 * "Platform Environment Services Framework". The classes
32 * and subclasses are defined by attributes and methods.
33 * The objects, and their initial, static, attribute values are
34 * specified in a configuration file, "psvcobj.conf".
35 * psvc_init() reads the configuration file and creates a repository
36 * of environmental objects in memory. A client application may manipulate
37 * these objects by invoking the psvc_get_attr(), and psvc_set_attr()
38 * routines with the object's string ID specified as an argument.
39 */
40 #include <stdio.h>
41 #include <math.h>
42 #include <stdlib.h>
43 #include <unistd.h>
44 #include <stropts.h>
45 #include <string.h>
46 #include <errno.h>
47 #include <fcntl.h>
48 #include <pthread.h>
49 #include <syslog.h>
50 #include <stdarg.h>
51 #include <pthread.h>
52 #include <sys/systeminfo.h>
53
54 #define LIBRARY_BUILD 1
55 #include <psvc_objects.h>
56 #include <psvc_objects_class.h>
57 #include <sys/i2c/clients/i2c_client.h>
58
59 /* Mutex used for Daktari Fan speed reading */
60 pthread_mutex_t fan_mutex = PTHREAD_MUTEX_INITIALIZER;
61
62 /*LINTLIBRARY*/
63
64 #define ENV_DEBUG(str, id) printf("%s id %s\n", (str), (id))
65
66 #define BUFSZ 512
67
68 #define CLASS_MAX 12
69 #define SUBCLASS_MAX 10
70
71 static int32_t i_psvc_constructor_0_0(EHdl_t *, char *, EObj_t **);
72 static int32_t i_psvc_constructor_0_1(EHdl_t *, char *, EObj_t **);
73 static int32_t i_psvc_constructor_1_0(EHdl_t *, char *, EObj_t **);
74 static int32_t i_psvc_constructor_2_0(EHdl_t *, char *, EObj_t **);
75 static int32_t i_psvc_constructor_2_1(EHdl_t *, char *, EObj_t **);
76 static int32_t i_psvc_constructor_2_2(EHdl_t *, char *, EObj_t **);
77 static int32_t i_psvc_constructor_3_0(EHdl_t *, char *, EObj_t **);
78 static int32_t i_psvc_constructor_4_0(EHdl_t *, char *, EObj_t **);
79 static int32_t i_psvc_constructor_5_0(EHdl_t *, char *, EObj_t **);
80 static int32_t i_psvc_constructor_6_0(EHdl_t *, char *, EObj_t **);
81 static int32_t i_psvc_constructor_7_0(EHdl_t *, char *, EObj_t **);
82 static int32_t i_psvc_constructor_8_0(EHdl_t *, char *, EObj_t **);
83 static int32_t i_psvc_constructor_9_0(EHdl_t *, char *, EObj_t **);
84 static int32_t i_psvc_constructor_10_0(EHdl_t *, char *, EObj_t **);
85 static int32_t i_psvc_constructor_10_1(EHdl_t *, char *, EObj_t **);
86 static int32_t i_psvc_constructor_11_0(EHdl_t *, char *, EObj_t **);
87 static int32_t i_psvc_constructor_11_1(EHdl_t *, char *, EObj_t **);
88 static int32_t i_psvc_constructor_11_2(EHdl_t *, char *, EObj_t **);
89 static int32_t i_psvc_constructor_11_3(EHdl_t *, char *, EObj_t **);
90 static int32_t i_psvc_constructor_11_4(EHdl_t *, char *, EObj_t **);
91 static int32_t i_psvc_constructor_11_5(EHdl_t *, char *, EObj_t **);
92 static int32_t i_psvc_constructor_11_6(EHdl_t *, char *, EObj_t **);
93 static int32_t i_psvc_constructor_11_7(EHdl_t *, char *, EObj_t **);
94 static int32_t i_psvc_constructor_11_8(EHdl_t *, char *, EObj_t **);
95 static int32_t i_psvc_constructor_11_9(EHdl_t *, char *, EObj_t **);
96
97 static int32_t i_psvc_get_obj(EHdl_t *, char *, EObj_t **);
98 static int32_t i_psvc_destructor(EHdl_t *, char *, void *);
99 static int32_t i_psvc_get_devpath(EHdl_t *, uint64_t, char *);
100 static int32_t i_psvc_get_attr_generic(EHdl_t *, EObj_t *, int32_t, void *);
101 static int32_t i_psvc_get_attr_6_0(EHdl_t *, EObj_t *, int32_t, void *);
102 static int32_t i_psvc_get_reg_11_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id,
103 void *attrp);
104 static int32_t i_psvc_get_attr_10_1(EHdl_t *, EObj_t *, int32_t, void *);
105 static int32_t psvc_get_str_key(char *object);
106
107 int32_t ioctl_retry(int fp, int request, void * arg_pointer);
108
109 /*
110 * Method lookup tables
111 * Update when adding classes or subclasses.
112 */
113
114
115 /* Lookup method by class, subclass, used when calling method */
116 static int32_t (*i_psvc_constructor[CLASS_MAX][SUBCLASS_MAX])(EHdl_t *,
117 char *, EObj_t **) = {
118 {i_psvc_constructor_0_0, i_psvc_constructor_0_1, 0, 0, 0, 0, 0, 0, 0, 0},
119 {i_psvc_constructor_1_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
120 {i_psvc_constructor_2_0, i_psvc_constructor_2_1, i_psvc_constructor_2_2,
121 0, 0, 0, 0, 0, 0, 0},
122 {i_psvc_constructor_3_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
123 {i_psvc_constructor_4_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
124 {i_psvc_constructor_5_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
125 {i_psvc_constructor_6_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
126 {i_psvc_constructor_7_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
127 {i_psvc_constructor_8_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
128 {i_psvc_constructor_9_0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
129 {i_psvc_constructor_10_0, i_psvc_constructor_10_1, 0, 0, 0, 0, 0, 0, 0, 0},
130 {i_psvc_constructor_11_0, i_psvc_constructor_11_1, i_psvc_constructor_11_2,
131 i_psvc_constructor_11_3, i_psvc_constructor_11_4,
132 i_psvc_constructor_11_5, i_psvc_constructor_11_6,
133 i_psvc_constructor_11_7, i_psvc_constructor_11_8,
134 i_psvc_constructor_11_9},
135 };
136
137 static int32_t i_psvc_cell_size[8] = {1, 1, 2, 2, 4, 4, 8, 8};
138
139 static struct bits {
140 uint64_t bit;
141 char *label;
142 } feature_bits[] = {
143 {PSVC_DEV_PERM, "PERM="},
144 {PSVC_DEV_HOTPLUG, "HOTPLUG="},
145 {PSVC_DEV_OPTION, "OPTION="},
146 {PSVC_DEV_PRIMARY, "PRIMARY="},
147 {PSVC_DEV_SECONDARY, "SECONDARY="},
148 {PSVC_DEV_RDONLY, "RDONLY="},
149 {PSVC_DEV_RDWR, "RDWR="},
150 {PSVC_DEV_FRU, "FRU="},
151 {PSVC_LOW_WARN, "LO_WARN_MASK="},
152 {PSVC_LOW_SHUT, "LO_SHUT_MASK="},
153 {PSVC_HIGH_WARN, "HI_WARN_MASK="},
154 {PSVC_HIGH_SHUT, "HI_SHUT_MASK="},
155 {PSVC_CONVERSION_TABLE, "CONV_TABLE="},
156 {PSVC_OPT_TEMP, "OPT_TEMP_MASK="},
157 {PSVC_HW_LOW_SHUT, "HW_LO_MASK="},
158 {PSVC_HW_HIGH_SHUT, "HW_HI_MASK="},
159 {PSVC_FAN_DRIVE_PR, "FAN_DRIVE_PR="},
160 {PSVC_TEMP_DRIVEN, "TEMP_DRIVEN="},
161 {PSVC_SPEED_CTRL_PR, "SPEED_CTRL_PR="},
162 {PSVC_FAN_ON_OFF, "FAN_ON_OFF="},
163 {PSVC_CLOSED_LOOP_CTRL, "CLOSED_LOOP_CTRL="},
164 {PSVC_FAN_DRIVE_TABLE_PR, "FAN_DRIVE_TABLE_PR="},
165 {PSVC_DIE_TEMP, "DIE_TEMP="},
166 {PSVC_AMB_TEMP, "AMB_TEMP="},
167 {PSVC_DIGI_SENSOR, "DIGI_SENSOR="},
168 {PSVC_BI_STATE, "BI_STATE="},
169 {PSVC_TRI_STATE, "TRI_STATE="},
170 {PSVC_GREEN, "GREEN="},
171 {PSVC_AMBER, "AMBER="},
172 {PSVC_OUTPUT, "OUTPUT="},
173 {PSVC_INPUT, "INPUT="},
174 {PSVC_BIDIR, "BIDIR="},
175 {PSVC_BIT_POS, "BIT_POS="},
176 {PSVC_VAL_POS, "VAL_POS="},
177 {PSVC_NORMAL_POS_AV, "NORMAL_POS_AV="},
178 {PSVC_DIAG_POS_AV, "DIAG_POS_AV="},
179 {PSVC_LOCK_POS_AV, "LOCK_POS_AV="},
180 {PSVC_OFF_POS_AV, "OFF_POS_AV="},
181 {PSVC_GPIO_PORT, "GPIO_PORT="},
182 {PSVC_GPIO_REG, "GPIO_REG="}
183 };
184
185 #define ASSOC_STR_TAB_SIZE 33
186 static char *assoc_str_tab[] = {
187 "PSVC_PRESENCE_SENSOR", /* 0 */
188 "PSVC_FAN_ONOFF_SENSOR", /* 1 */
189 "PSVC_FAN_SPEED_TACHOMETER", /* 2 */
190 "PSVC_FAN_PRIM_SEC_SELECTOR", /* 3 */
191 "PSVC_DEV_TEMP_SENSOR", /* 4 */
192 "PSVC_FAN_DRIVE_CONTROL", /* 5 */
193 "PSVC_KS_NORMAL_POS_SENSOR", /* 6 */
194 "PSVC_KS_DIAG_POS_SENSOR", /* 7 */
195 "PSVC_KS_LOCK_POS_SENSOR", /* 8 */
196 "PSVC_KS_OFF_POS_SENSOR", /* 9 */
197 "PSVC_SLOT_FAULT_LED", /* 10 */
198 "PSVC_SLOT_REMOVE_LED", /* 11 */
199 "PSVC_TS_OVERTEMP_LED", /* 12 */
200 "PSVC_PS_I_SENSOR", /* 13 */
201 "PSVC_DEV_FAULT_SENSOR", /* 14 */
202 "PSVC_DEV_FAULT_LED", /* 15 */
203 "PSVC_TABLE", /* 16 */
204 "PSVC_PARENT", /* 17 */
205 "PSVC_CPU", /* 18 */
206 "PSVC_ALTERNATE", /* 19 */
207 "PSVC_HOTPLUG_ENABLE_SWITCH", /* 20 */
208 "PSVC_PS", /* 21 */
209 "PSVC_FAN", /* 22 */
210 "PSVC_TS", /* 23 */
211 "PSVC_DISK", /* 24 */
212 "PSVC_LED", /* 25 */
213 "PSVC_FSP_LED", /* 26 */
214 "PSVC_KEYSWITCH", /* 27 */
215 "PSVC_PCI_CARD", /* 28 */
216 "PSVC_PHYSICAL_DEVICE", /* 29 */
217 "PSVC_DEV_TYPE_SENSOR", /* 30 */
218 "PSVC_FAN_TRAY_FANS", /* 31 */
219 "PSVC_FRU" /* 32 */
220 };
221
222 #define FEATURE_BITS (sizeof (feature_bits) / sizeof (struct bits))
223
224 static struct bitfield {
225 int8_t shift;
226 char *label;
227 char *format;
228 } addr_fields[] =
229 {
230 {PSVC_VERSION_SHIFT, "VERSION=", "%d"},
231 {PSVC_ACTIVE_LOW_SHIFT, "ACTIVE_LOW=", "%d"},
232 {PSVC_BIT_NUM_SHIFT, "BIT_NUM=", "%d"},
233 {PSVC_INVERT_SHIFT, "INVERT=", "%d"},
234 {PSVC_PORT_SHIFT, "PORT=", "%d"},
235 {PSVC_BITSHIFT_SHIFT, "BITSHIFT=", "%d"},
236 {PSVC_BYTEMASK_SHIFT, "BYTEMASK=", "%x"},
237 {PSVC_REG_SHIFT, "REG=", "%d"},
238 {PSVC_TYPE_SHIFT, "TYPE=", "%d"},
239 {PSVC_BUSADDR_SHIFT, "BUSADDR=", "%x"},
240 {PSVC_BUSNUM_SHIFT, "BUSNUM=", "%d"},
241 {PSVC_CNTLR_SHIFT, "CNTLR=", "%d"},
242 };
243 #define ADDR_BITFIELDS (sizeof (addr_fields) / sizeof (struct bitfield))
244
245 /*
246 * record format is:
247 * pathname label1=val1,label2=val2,label3=val3
248 * Must be a space after the pathname and a comma between variables.
249 */
250
251 static char *
find_label(char * str,char * label)252 find_label(char *str, char *label)
253 {
254 char *start;
255
256 start = strchr(str, ' ');
257 if (start == NULL)
258 return (start);
259
260 do {
261 ++start;
262 if (strncmp(start, label, strlen(label)) == 0)
263 return (start);
264
265 start = strchr(start, ',');
266 } while (start != NULL);
267
268 return (NULL);
269 }
270
271 static int32_t
i_psvc_value(char * buf,int32_t attr_id,void * attrp)272 i_psvc_value(char *buf, int32_t attr_id, void *attrp)
273 {
274 char *val;
275 uint32_t temp32;
276 uint64_t temp64;
277 uint64_t result;
278 int32_t i;
279 int32_t found;
280 char label[64];
281 int val_size;
282 int label_size;
283
284
285 switch (attr_id) {
286 case PSVC_CLASS_ATTR:
287 case PSVC_SUBCLASS_ATTR:
288 case PSVC_INSTANCE_ATTR:
289 case PSVC_LO_WARN_ATTR:
290 case PSVC_LO_SHUT_ATTR:
291 case PSVC_HI_WARN_ATTR:
292 case PSVC_HI_SHUT_ATTR:
293 case PSVC_HW_HI_SHUT_ATTR:
294 case PSVC_HW_LO_SHUT_ATTR:
295 case PSVC_OPTIMAL_TEMP_ATTR:
296 snprintf(label, sizeof (label), "%s=", attr_str_tab[attr_id]);
297 val = find_label(buf, label);
298 if (val == NULL) {
299 errno = EINVAL;
300 return (PSVC_FAILURE);
301 }
302 found = sscanf(val + strlen(label),
303 "%d", (int32_t *)attrp);
304 if (found == 0)
305 *(int32_t *)attrp = 0;
306 break;
307 case PSVC_SETPOINT_ATTR:
308 case PSVC_HYSTERESIS_ATTR:
309 case PSVC_LOOPGAIN_ATTR:
310 case PSVC_LOOPBIAS_ATTR:
311 snprintf(label, sizeof (label), "%s=", attr_str_tab[attr_id]);
312 val = find_label(buf, label);
313 if (val == NULL) {
314 errno = EINVAL;
315 return (PSVC_FAILURE);
316 }
317
318 found = sscanf(val + strlen(label), "%hd", (int16_t *)attrp);
319 if (found == 0)
320 *(int16_t *)attrp = 0;
321 break;
322 case PSVC_LED_COLOR_ATTR:
323 case PSVC_LED_IS_LOCATOR_ATTR:
324 case PSVC_LED_LOCATOR_NAME_ATTR:
325 snprintf(label, sizeof (label), "%s=", attr_str_tab[attr_id]);
326 val = find_label(buf, label);
327 if (val == NULL) {
328 errno = EINVAL;
329 return (PSVC_FAILURE);
330 }
331 val_size = strlen(val);
332 label_size = strlen(label);
333
334 for (i = 0; i < val_size && val[i] != ','; i++);
335 if (i < strlen(val) - 1) {
336 strncpy((char *)attrp, val+label_size,
337 i - label_size);
338 } else
339 found = sscanf(val + label_size, "%s", (char *)attrp);
340 if (found == 0)
341 strcpy((char *)attrp, "");
342 break;
343 case PSVC_FEATURES_ATTR:
344 result = 0;
345 for (i = 0; i < FEATURE_BITS; ++i) {
346 val = find_label(buf, feature_bits[i].label);
347 if (val == NULL)
348 continue;
349 found = sscanf(val + strlen(feature_bits[i].label),
350 "%d", &temp32);
351 if (found != 0) {
352 if (temp32 == 1)
353 result |= feature_bits[i].bit;
354 }
355 }
356 *(uint64_t *)attrp = result;
357 break;
358 case PSVC_ADDR_SPEC_ATTR:
359 result = 0;
360 for (i = 0; i < ADDR_BITFIELDS; ++i) {
361 val = find_label(buf, addr_fields[i].label);
362 if (val == NULL)
363 continue;
364 found = sscanf(val + strlen(addr_fields[i].label),
365 addr_fields[i].format, &temp32);
366 if (found != 0) {
367 temp64 = temp32;
368 temp64 <<= addr_fields[i].shift;
369 result |= temp64;
370 }
371 }
372 *(uint64_t *)attrp = result;
373 break;
374 default:
375 errno = EINVAL;
376 return (PSVC_FAILURE);
377 }
378 return (PSVC_SUCCESS);
379 }
380
381 /* determine number of records in file section */
382 static int32_t
i_psvc_count_records(FILE * fp,char * end,uint32_t * countp)383 i_psvc_count_records(FILE *fp, char *end, uint32_t *countp)
384 {
385 long first_record;
386 char *ret;
387 char buf[BUFSZ];
388 uint32_t count = 0;
389
390 first_record = ftell(fp);
391
392 while ((ret = fgets(buf, BUFSZ, fp)) != NULL) {
393 if (strncmp(end, buf, strlen(end)) == 0)
394 break;
395 ++count;
396 }
397
398 if (ret == NULL) {
399 errno = EINVAL;
400 return (PSVC_FAILURE);
401 }
402
403 fseek(fp, first_record, SEEK_SET);
404 *countp = count;
405 return (PSVC_SUCCESS);
406 }
407
408 /* determine number of records in file section */
409 static int32_t
i_psvc_count_tables_associations(FILE * fp,uint32_t * countp,char * end)410 i_psvc_count_tables_associations(FILE *fp, uint32_t *countp, char *end)
411 {
412 long first_record;
413 char *ret;
414 char buf[BUFSZ];
415 uint32_t count = 0;
416
417 first_record = ftell(fp);
418
419 while ((ret = fgets(buf, BUFSZ, fp)) != NULL) {
420 if (strncmp(end, buf, strlen(end)) == 0)
421 ++count;
422 }
423 #ifdef lint
424 ret = ret;
425 #endif
426
427 fseek(fp, first_record, SEEK_SET);
428 *countp = count;
429 return (PSVC_SUCCESS);
430 }
431
432 /* determine number of records in a table */
433 static int32_t
i_psvc_count_table_records(FILE * fp,char * end,uint32_t * countp)434 i_psvc_count_table_records(FILE *fp, char *end, uint32_t *countp)
435 {
436 long first_record;
437 int ret;
438 char string[BUFSZ];
439 uint32_t count = 0;
440
441 first_record = ftell(fp);
442
443 while ((ret = fscanf(fp, "%s", string)) == 1) {
444 if (strncmp(end, string, strlen(end)) == 0)
445 break;
446 ++count;
447 }
448
449 if (ret != 1) {
450 errno = EINVAL;
451 return (PSVC_FAILURE);
452 }
453
454 fseek(fp, first_record, SEEK_SET);
455 *countp = count;
456 return (PSVC_SUCCESS);
457 }
458
459 /*
460 * Find number of matches to an antecedent_id of a certain
461 * association type.
462 */
463 static int32_t
i_psvc_get_assoc_matches(EHdl_t * hdlp,char * antecedent,int32_t assoc_id,int32_t * matches)464 i_psvc_get_assoc_matches(EHdl_t *hdlp, char *antecedent, int32_t assoc_id,
465 int32_t *matches)
466 {
467 int i;
468 int32_t key;
469 EAssocList_t *ap = hdlp->assoc_tbl + assoc_id;
470
471 *matches = 0;
472
473 if (ap->table == 0) {
474 errno = EINVAL;
475 return (PSVC_FAILURE);
476 }
477
478 key = psvc_get_str_key(antecedent);
479
480 for (i = 0; i < ap->count; ++i) {
481 if (ap->table[i].ant_key == key) {
482 if (strcmp(ap->table[i].antecedent_id, antecedent)
483 == 0)
484 ++*matches;
485 }
486 }
487 return (PSVC_SUCCESS);
488 }
489
490 /*
491 * Find 1st m matches to an antecedent_id of a certain
492 * association type.
493 * Returns zero for success, -1 for failure.
494 */
495 static int32_t
i_psvc_get_assoc_id(EHdl_t * hdlp,char * antecedent,int32_t assoc_id,int32_t match,char ** id_list)496 i_psvc_get_assoc_id(EHdl_t *hdlp, char *antecedent, int32_t assoc_id,
497 int32_t match, char **id_list)
498 {
499 int i;
500 int found = 0;
501 int32_t key;
502 EAssocList_t *ap = &hdlp->assoc_tbl[assoc_id];
503
504 if (ap->table == 0) {
505 errno = EINVAL;
506 return (-1);
507 }
508
509 key = psvc_get_str_key(antecedent);
510
511 for (i = 0; i < ap->count; ++i) {
512 if (ap->table[i].ant_key == key) {
513 if (strcmp(ap->table[i].antecedent_id, antecedent)
514 == 0) {
515 if (found == match) {
516 *id_list = ap->table[i].dependent_id;
517 return (0);
518 }
519 ++found;
520 }
521 }
522 }
523
524 errno = EINVAL;
525 return (-1);
526 }
527
528 static int32_t
i_psvc_get_table_value(EHdl_t * hdlp,char * table_id,uint32_t index,void * value)529 i_psvc_get_table_value(EHdl_t *hdlp, char *table_id, uint32_t index,
530 void *value)
531 {
532 int32_t i;
533 ETable_t *tblp;
534 ETable_Array *tbl_arr;
535 int32_t key, array;
536
537 key = psvc_get_str_key(table_id);
538 array = key % PSVC_MAX_TABLE_ARRAYS;
539 tbl_arr = &(hdlp->tbl_arry[array]);
540
541 for (i = 0; i < tbl_arr->obj_count; ++i) {
542 if (key == tbl_arr->obj_tbl[i].key) {
543 if (strcmp(tbl_arr->obj_tbl[i].name,
544 table_id) == 0)
545 break;
546 }
547 }
548
549 if (tbl_arr->obj_tbl[i].type != PSVC_TBL)
550 return (PSVC_FAILURE);
551
552 tblp = (ETable_t *)tbl_arr->obj_tbl[i].objp;
553
554 if (tblp->table == NULL)
555 return (PSVC_FAILURE);
556
557 if (index >= tblp->size)
558 return (PSVC_FAILURE);
559
560 switch (tblp->cell_type) {
561 case 0:
562 *(int8_t *)value = *((int8_t *)tblp->table + index);
563 break;
564 case 1:
565 *(uint8_t *)value = *((uint8_t *)tblp->table + index);
566 break;
567 case 2:
568 *(int16_t *)value = *((int16_t *)tblp->table + index);
569 break;
570 case 3:
571 *(uint16_t *)value = *((uint16_t *)tblp->table + index);
572 break;
573 case 4:
574 *(int32_t *)value = *((int32_t *)tblp->table + index);
575 break;
576 case 5:
577 *(uint32_t *)value = *((uint32_t *)tblp->table + index);
578 break;
579 case 6:
580 *(int64_t *)value = *((int64_t *)tblp->table + index);
581 break;
582 case 7:
583 *(uint64_t *)value = *((uint64_t *)tblp->table + index);
584 break;
585 default:
586 return (PSVC_FAILURE);
587 }
588
589 return (PSVC_SUCCESS);
590 }
591
592 int32_t
psvc_get_attr(EHdl_t * hdlp,char * name,int32_t attr_id,void * attr_valuep,...)593 psvc_get_attr(EHdl_t *hdlp, char *name, int32_t attr_id, void *attr_valuep, ...)
594 {
595 EObj_t *objp;
596 int32_t status = PSVC_SUCCESS;
597 int32_t arg1, arg2;
598 va_list ap;
599
600 pthread_mutex_lock(&hdlp->mutex);
601
602 if (attr_valuep == NULL) {
603 errno = EFAULT;
604 pthread_mutex_unlock(&hdlp->mutex);
605 return (PSVC_FAILURE);
606 }
607
608 switch (attr_id) {
609 case PSVC_TABLE_VALUE_ATTR:
610 va_start(ap, attr_valuep);
611 status = i_psvc_get_table_value(hdlp, name,
612 va_arg(ap, uint32_t), attr_valuep);
613 va_end(ap);
614 break;
615 case PSVC_ASSOC_MATCHES_ATTR:
616 va_start(ap, attr_valuep);
617 status = i_psvc_get_assoc_matches(hdlp, name,
618 va_arg(ap, int32_t), attr_valuep);
619 va_end(ap);
620 break;
621 case PSVC_ASSOC_ID_ATTR:
622 va_start(ap, attr_valuep);
623 arg1 = va_arg(ap, int32_t);
624 arg2 = va_arg(ap, int32_t);
625 status = i_psvc_get_assoc_id(hdlp, name,
626 arg1, arg2, attr_valuep);
627 va_end(ap);
628 break;
629 default:
630 status = i_psvc_get_obj(hdlp, name, &objp);
631 if (status != PSVC_SUCCESS) {
632 pthread_mutex_unlock(&hdlp->mutex);
633 return (status);
634 }
635 status = (*objp->get_attr)(hdlp, objp, attr_id,
636 attr_valuep);
637 }
638
639 if (status != PSVC_SUCCESS) {
640 pthread_mutex_unlock(&hdlp->mutex);
641 return (status);
642 }
643
644 pthread_mutex_unlock(&hdlp->mutex);
645 return (status);
646 }
647
648 int32_t
psvc_set_attr(EHdl_t * hdlp,char * name,int32_t attr_id,void * attr_valuep)649 psvc_set_attr(EHdl_t *hdlp, char *name, int32_t attr_id, void *attr_valuep)
650 {
651 EObj_t *objp;
652 int32_t status = PSVC_SUCCESS;
653
654 pthread_mutex_lock(&hdlp->mutex);
655 status = i_psvc_get_obj(hdlp, name, &objp);
656 if (status != PSVC_SUCCESS) {
657 pthread_mutex_unlock(&hdlp->mutex);
658 return (status);
659 }
660
661 if (attr_valuep == NULL) {
662 errno = EFAULT;
663 pthread_mutex_unlock(&hdlp->mutex);
664 return (PSVC_FAILURE);
665 }
666
667 status = (*objp->set_attr)(hdlp, objp, attr_id, attr_valuep);
668 if (status != PSVC_SUCCESS) {
669 pthread_mutex_unlock(&hdlp->mutex);
670 return (status);
671 }
672
673 pthread_mutex_unlock(&hdlp->mutex);
674 return (status);
675 }
676
677
678 static int32_t
i_psvc_get_presence(EHdl_t * hdlp,EObj_t * objp,boolean_t * pr)679 i_psvc_get_presence(EHdl_t *hdlp, EObj_t *objp, boolean_t *pr)
680 {
681 EObj_t *pobjp, *mobjp;
682 int32_t matches;
683 char *mid;
684 char *parent_id;
685 int32_t status = PSVC_SUCCESS;
686 uint8_t value_8bit, value_8bit_inv;
687 boolean_t active_low, value;
688
689 if (strcmp(objp->label, PSVC_CHASSIS) == 0) {
690 *pr = PSVC_PRESENT;
691 objp->present = PSVC_PRESENT;
692 return (PSVC_SUCCESS);
693 }
694
695 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PARENT, 0,
696 &parent_id);
697 if (status != PSVC_SUCCESS)
698 return (status);
699
700 if (strcmp(parent_id, PSVC_CHASSIS)) {
701 status = i_psvc_get_obj(hdlp, parent_id, &pobjp);
702 if (status != PSVC_SUCCESS)
703 return (status);
704 if (!pobjp->present) {
705 pobjp->get_attr(hdlp, pobjp, PSVC_PRESENCE_ATTR, pr);
706 *pr = pobjp->present;
707 objp->present = pobjp->present;
708 return (status);
709 }
710 }
711
712 (void) i_psvc_get_assoc_matches(hdlp, objp->label,
713 PSVC_PRESENCE_SENSOR, &matches);
714
715 if (matches != 0) {
716 status = i_psvc_get_assoc_id(hdlp, objp->label,
717 PSVC_PRESENCE_SENSOR, 0, &mid);
718 if (status != PSVC_SUCCESS)
719 return (status);
720 status = i_psvc_get_obj(hdlp, mid, &mobjp);
721 if (status != PSVC_SUCCESS)
722 return (status);
723
724 active_low = PSVC_IS_ACTIVE_LOW(mobjp->addr_spec);
725
726 if (mobjp->class == PSVC_BOOLEAN_GPIO_CLASS) {
727 status = mobjp->get_attr(hdlp, mobjp,
728 PSVC_GPIO_VALUE_ATTR, &value);
729 if (status != PSVC_SUCCESS)
730 return (status);
731 if (active_low)
732 if (value == 0)
733 *pr = PSVC_PRESENT;
734 else
735 *pr = PSVC_ABSENT;
736 else
737 if (value == 0)
738 *pr = PSVC_ABSENT;
739 else
740 *pr = PSVC_PRESENT;
741 } else if (mobjp->class == PSVC_8BIT_GPIO_CLASS) {
742 uint8_t bitshift, bytemask;
743
744 status = mobjp->get_attr(hdlp, mobjp,
745 PSVC_GPIO_VALUE_ATTR, &value_8bit);
746 if (status != PSVC_SUCCESS)
747 return (status);
748 if (PSVC_HP_INVERT(mobjp->addr_spec))
749 value_8bit_inv = ~value_8bit;
750 else
751 value_8bit_inv = value_8bit;
752 bitshift = PSVC_GET_ASPEC_BITSHIFT(mobjp->addr_spec);
753 bytemask = PSVC_GET_ASPEC_BYTEMASK(mobjp->addr_spec);
754 value_8bit_inv =
755 value_8bit_inv & (bytemask >> bitshift);
756 if (active_low)
757 if (value_8bit_inv == 0)
758 *pr = PSVC_PRESENT;
759 else
760 *pr = PSVC_ABSENT;
761 else
762 if (value_8bit_inv == 0)
763 *pr = PSVC_ABSENT;
764 else
765 *pr = PSVC_PRESENT;
766 } else {
767 errno = EINVAL;
768 return (PSVC_FAILURE);
769 }
770 } else {
771 *pr = PSVC_PRESENT;
772 }
773
774 objp->present = *pr;
775
776 return (status);
777 }
778
779 static int32_t
i_psvc_get_device_value_0_0(EHdl_t * hdlp,EObj_t * objp,int32_t * temp)780 i_psvc_get_device_value_0_0(EHdl_t *hdlp, EObj_t *objp, int32_t *temp)
781 {
782 int32_t status = PSVC_SUCCESS, m;
783 char *tid;
784 int16_t temp16;
785 char *physid;
786 EObj_t *physobjp;
787
788 if (objp->present != PSVC_PRESENT) {
789 errno = ENODEV;
790 return (PSVC_FAILURE);
791 }
792
793 status = i_psvc_get_assoc_id(
794 hdlp, objp->label, PSVC_PHYSICAL_DEVICE, 0, &physid);
795 if (status != PSVC_SUCCESS) {
796 return (status);
797 }
798 status = i_psvc_get_obj(hdlp, physid, &physobjp);
799 if (status != PSVC_SUCCESS) {
800 return (status);
801 }
802
803 status = ((EPhysDev_t *)physobjp)->get_temperature(hdlp,
804 objp->addr_spec, temp);
805 if (status != PSVC_SUCCESS) {
806 return (status);
807 }
808
809 if (objp->features & PSVC_CONVERSION_TABLE) {
810 status = i_psvc_get_assoc_matches(hdlp, objp->label,
811 PSVC_TABLE, &m);
812 if ((status != PSVC_SUCCESS) || (m != 1)) {
813 return (status);
814 }
815
816 (void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
817 &tid);
818
819 status = i_psvc_get_table_value(hdlp, tid, *temp, &temp16);
820 *temp = temp16;
821 }
822 return (status);
823 }
824
825 static int32_t
i_psvc_get_device_value_0_1(EHdl_t * hdlp,EObj_t * objp,int32_t * temp)826 i_psvc_get_device_value_0_1(EHdl_t *hdlp, EObj_t *objp, int32_t *temp)
827 {
828 int32_t status = PSVC_SUCCESS, m;
829 char *tid;
830 int16_t temp16;
831 char *physid;
832 EObj_t *physobjp;
833
834 if (objp->present != PSVC_PRESENT) {
835 errno = ENODEV;
836 return (PSVC_FAILURE);
837 }
838
839 status = i_psvc_get_assoc_id(
840 hdlp, objp->label, PSVC_PHYSICAL_DEVICE, 0, &physid);
841 if (status != PSVC_SUCCESS) {
842 return (status);
843 }
844 status = i_psvc_get_obj(hdlp, physid, &physobjp);
845 if (status != PSVC_SUCCESS) {
846 return (status);
847 }
848
849 status = ((EPhysDev_t *)physobjp)->get_temperature(hdlp,
850 objp->addr_spec, temp);
851 if (status != PSVC_SUCCESS) {
852 return (status);
853 }
854
855 if (objp->features & PSVC_CONVERSION_TABLE) {
856 status = i_psvc_get_assoc_matches(hdlp, objp->label,
857 PSVC_TABLE, &m);
858 if ((status != PSVC_SUCCESS) || (m != 1)) {
859 return (status);
860 }
861
862 (void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
863 &tid);
864
865 status = i_psvc_get_table_value(hdlp, tid, *temp, &temp16);
866 *temp = temp16;
867 }
868 return (status);
869 }
870
871 static int32_t
i_psvc_get_device_value_4_0(EHdl_t * hdlp,EObj_t * objp,int32_t * value)872 i_psvc_get_device_value_4_0(EHdl_t *hdlp, EObj_t *objp, int32_t *value)
873 {
874 int32_t status = PSVC_SUCCESS;
875 char *physid;
876 EObj_t *physobjp;
877
878 if (objp->present != PSVC_PRESENT) {
879 errno = ENODEV;
880 return (PSVC_FAILURE);
881 }
882
883 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
884 0, &physid);
885 if (status != PSVC_SUCCESS)
886 return (status);
887 status = i_psvc_get_obj(hdlp, physid, &physobjp);
888 if (status != PSVC_SUCCESS)
889 return (status);
890
891 status = ((EPhysDev_t *)physobjp)->get_input(hdlp, objp->addr_spec,
892 value);
893 if (status != PSVC_SUCCESS)
894 return (status);
895
896 if (objp->features & PSVC_CONVERSION_TABLE) {
897 int32_t m;
898 char *tid;
899 int16_t temp16;
900
901 status = i_psvc_get_assoc_matches(hdlp, objp->label,
902 PSVC_TABLE, &m);
903 if ((status != PSVC_SUCCESS) || (m != 1)) {
904 return (status);
905 }
906
907 (void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
908 &tid);
909
910 status = i_psvc_get_table_value(hdlp, tid, *value, &temp16);
911 *value = temp16;
912 }
913
914 return (status);
915 }
916
917 static int32_t
i_psvc_set_device_value_5_0(EHdl_t * hdlp,EObj_t * objp,int32_t * value)918 i_psvc_set_device_value_5_0(EHdl_t *hdlp, EObj_t *objp, int32_t *value)
919 {
920 int32_t status = PSVC_SUCCESS;
921 char *physid;
922 EObj_t *physobjp;
923
924 if (objp->present != PSVC_PRESENT) {
925 errno = ENODEV;
926 return (PSVC_FAILURE);
927 }
928
929 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
930 0, &physid);
931 if (status != PSVC_SUCCESS)
932 return (status);
933 status = i_psvc_get_obj(hdlp, physid, &physobjp);
934 if (status != PSVC_SUCCESS)
935 return (status);
936 status = ((EPhysDev_t *)physobjp)->set_output(hdlp, objp->addr_spec,
937 *value);
938 if (status != PSVC_SUCCESS)
939 return (status);
940
941 return (status);
942 }
943
944 static int32_t
i_psvc_get_device_value_5_0(EHdl_t * hdlp,EObj_t * objp,int32_t * value)945 i_psvc_get_device_value_5_0(EHdl_t *hdlp, EObj_t *objp, int32_t *value)
946 {
947 int32_t status = PSVC_SUCCESS;
948 char *physid;
949 EObj_t *physobjp;
950
951 if (objp->present != PSVC_PRESENT) {
952 errno = ENODEV;
953 return (PSVC_FAILURE);
954 }
955
956 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
957 0, &physid);
958 if (status != PSVC_SUCCESS)
959 return (status);
960 status = i_psvc_get_obj(hdlp, physid, &physobjp);
961 if (status != PSVC_SUCCESS)
962 return (status);
963
964 status = ((EPhysDev_t *)physobjp)->get_output(hdlp, objp->addr_spec,
965 value);
966 if (status != PSVC_SUCCESS)
967 return (status);
968
969 if (objp->features & PSVC_CONVERSION_TABLE) {
970 int32_t m;
971 char *tid;
972 int16_t temp16;
973
974 status = i_psvc_get_assoc_matches(hdlp, objp->label,
975 PSVC_TABLE, &m);
976 if ((status != PSVC_SUCCESS) || (m != 1)) {
977 return (status);
978 }
979
980 (void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
981 &tid);
982
983 status = i_psvc_get_table_value(hdlp, tid, *value, &temp16);
984 *value = temp16;
985 }
986 return (status);
987 }
988
989 static int32_t
i_psvc_get_device_value_6_0(EHdl_t * hdlp,EObj_t * objp,boolean_t * value)990 i_psvc_get_device_value_6_0(EHdl_t *hdlp, EObj_t *objp, boolean_t *value)
991 {
992 int32_t status = PSVC_SUCCESS;
993 int32_t bit_value;
994 char *physid;
995 EObj_t *physobjp;
996
997 if (objp->present != PSVC_PRESENT) {
998 errno = ENODEV;
999 return (PSVC_FAILURE);
1000 }
1001
1002 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1003 0, &physid);
1004 if (status != PSVC_SUCCESS)
1005 return (status);
1006 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1007 if (status != PSVC_SUCCESS)
1008 return (status);
1009
1010 status = ((EPhysDev_t *)physobjp)->get_bit(hdlp, objp->addr_spec,
1011 &bit_value);
1012 if (status != PSVC_SUCCESS)
1013 return (status);
1014
1015 *value = bit_value;
1016
1017 return (status);
1018 }
1019
1020 static int32_t
i_psvc_set_device_value_6_0(EHdl_t * hdlp,EObj_t * objp,boolean_t * value)1021 i_psvc_set_device_value_6_0(EHdl_t *hdlp, EObj_t *objp, boolean_t *value)
1022 {
1023 int32_t status = PSVC_SUCCESS;
1024 int32_t bit_value;
1025 char *physid;
1026 EObj_t *physobjp;
1027
1028 if (objp->present != PSVC_PRESENT) {
1029 errno = ENODEV;
1030 return (PSVC_FAILURE);
1031 }
1032
1033 bit_value = *value;
1034 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1035 0, &physid);
1036 if (status != PSVC_SUCCESS)
1037 return (status);
1038 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1039 if (status != PSVC_SUCCESS)
1040 return (status);
1041
1042 status = ((EPhysDev_t *)physobjp)->set_bit(hdlp, objp->addr_spec,
1043 bit_value);
1044 if (status != PSVC_SUCCESS)
1045 return (status);
1046
1047 return (status);
1048 }
1049
1050 static int32_t
i_psvc_get_device_value_1_0(EHdl_t * hdlp,EObj_t * objp,int32_t * fan_speed)1051 i_psvc_get_device_value_1_0(EHdl_t *hdlp, EObj_t *objp, int32_t *fan_speed)
1052 {
1053 int32_t status = PSVC_SUCCESS;
1054 EObj_t *ftobjp;
1055 char *fan_tach;
1056
1057 if (objp->present != PSVC_PRESENT) {
1058 errno = ENODEV;
1059 return (PSVC_FAILURE);
1060 }
1061
1062 status = i_psvc_get_assoc_id(hdlp, objp->label,
1063 PSVC_FAN_SPEED_TACHOMETER, 0, &fan_tach);
1064 if (status != PSVC_SUCCESS)
1065 return (status);
1066
1067 status = i_psvc_get_obj(hdlp, fan_tach, &ftobjp);
1068 if (status != PSVC_SUCCESS)
1069 return (status);
1070
1071 status = ftobjp->get_attr(hdlp, ftobjp, PSVC_SENSOR_VALUE_ATTR,
1072 fan_speed);
1073 if (status != PSVC_SUCCESS)
1074 return (status);
1075
1076 return (status);
1077 }
1078
1079 static int32_t
i_psvc_get_device_value_7_0(EHdl_t * hdlp,EObj_t * objp,int32_t * fan_speed)1080 i_psvc_get_device_value_7_0(EHdl_t *hdlp, EObj_t *objp, int32_t *fan_speed)
1081 {
1082 char *physid;
1083 EObj_t *physobjp;
1084 int32_t status = PSVC_SUCCESS;
1085
1086 if (objp->present != PSVC_PRESENT) {
1087 errno = ENODEV;
1088 return (PSVC_FAILURE);
1089 }
1090
1091 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1092 0, &physid);
1093 if (status != PSVC_SUCCESS)
1094 return (status);
1095 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1096 if (status != PSVC_SUCCESS)
1097 return (status);
1098
1099 status = ((EPhysDev_t *)physobjp)->get_fanspeed(hdlp, objp->addr_spec,
1100 fan_speed);
1101 if (status != PSVC_SUCCESS)
1102 return (status);
1103
1104 if (objp->features & PSVC_CONVERSION_TABLE) {
1105 int32_t m;
1106 char *tid;
1107 int16_t temp16;
1108
1109 status = i_psvc_get_assoc_matches(hdlp, objp->label,
1110 PSVC_TABLE, &m);
1111 if ((status != PSVC_SUCCESS) || (m != 1)) {
1112 return (status);
1113 }
1114
1115 (void) i_psvc_get_assoc_id(hdlp, objp->label, PSVC_TABLE, 0,
1116 &tid);
1117
1118 status = i_psvc_get_table_value(hdlp, tid, *fan_speed, &temp16);
1119 *fan_speed = temp16;
1120 }
1121 return (status);
1122 }
1123
1124 static int32_t
i_psvc_get_device_state_2_0(EHdl_t * hdlp,EObj_t * objp,char * led_state)1125 i_psvc_get_device_state_2_0(EHdl_t *hdlp, EObj_t *objp, char *led_state)
1126 {
1127 int32_t status = PSVC_SUCCESS;
1128 int32_t bit_value;
1129 boolean_t active_low;
1130 char *physid;
1131 EObj_t *physobjp;
1132
1133 if (objp->present != PSVC_PRESENT) {
1134 errno = ENODEV;
1135 return (PSVC_FAILURE);
1136 }
1137
1138 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1139 0, &physid);
1140 if (status != PSVC_SUCCESS)
1141 return (status);
1142 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1143 if (status != PSVC_SUCCESS)
1144 return (status);
1145
1146 status = ((EPhysDev_t *)physobjp)->get_bit(hdlp, objp->addr_spec,
1147 &bit_value);
1148 if (status != PSVC_SUCCESS)
1149 return (status);
1150
1151 active_low = PSVC_IS_ACTIVE_LOW(objp->addr_spec);
1152 if (active_low)
1153 if (bit_value == 0)
1154 strcpy(led_state, PSVC_LED_ON);
1155 else
1156 strcpy(led_state, PSVC_LED_OFF);
1157 else
1158 if (bit_value == 0)
1159 strcpy(led_state, PSVC_LED_OFF);
1160 else
1161 strcpy(led_state, PSVC_LED_ON);
1162
1163 return (status);
1164 }
1165
1166 static int32_t
i_psvc_set_device_state_2_0(EHdl_t * hdlp,EObj_t * objp,char * led_state)1167 i_psvc_set_device_state_2_0(EHdl_t *hdlp, EObj_t *objp, char *led_state)
1168 {
1169 int32_t status = PSVC_SUCCESS;
1170 boolean_t active_low;
1171 int32_t bit_value;
1172 char *physid;
1173 EObj_t *physobjp;
1174
1175 if (objp->present != PSVC_PRESENT) {
1176 errno = ENODEV;
1177 return (PSVC_FAILURE);
1178 }
1179
1180 if (strcmp(((ELed_t *)objp)->is_locator, PSVC_LOCATOR_TRUE) != 0) {
1181 /*
1182 * For Locator LEDs we ignore lit_count. RSC may have
1183 * altered the LED state underneath us, So we should
1184 * always just do what the user asked instead of trying
1185 * to be smart.
1186 */
1187
1188 if (strcmp(led_state, PSVC_LED_ON) == 0)
1189 ((ELed_t *)objp)->lit_count++;
1190 else if (strcmp(led_state, PSVC_LED_OFF) == 0) {
1191 if (--((ELed_t *)objp)->lit_count > 0) {
1192 return (PSVC_SUCCESS);
1193 } else if (((ELed_t *)objp)->lit_count < 0)
1194 ((ELed_t *)objp)->lit_count = 0;
1195 /* Fall through case is when lit_count is 0 */
1196 }
1197 }
1198
1199 strcpy(objp->previous_state, objp->state);
1200 strcpy(objp->state, led_state);
1201
1202 bit_value = (strcmp(led_state, PSVC_LED_ON) == 0);
1203
1204 /*
1205 * Flip the bit if necessary (for active_low devices,
1206 * O ==> ON; 1 ==> OFF.
1207 */
1208 active_low = PSVC_IS_ACTIVE_LOW(objp->addr_spec);
1209 bit_value ^= active_low;
1210
1211 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1212 0, &physid);
1213 if (status != PSVC_SUCCESS)
1214 return (status);
1215 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1216 if (status != PSVC_SUCCESS)
1217 return (status);
1218
1219 status = ((EPhysDev_t *)physobjp)->set_bit(hdlp, objp->addr_spec,
1220 bit_value);
1221 return (status);
1222 }
1223
1224 static int32_t
i_psvc_get_device_state_2_1(EHdl_t * hdlp,EObj_t * objp,char * led_state)1225 i_psvc_get_device_state_2_1(EHdl_t *hdlp, EObj_t *objp, char *led_state)
1226 {
1227 int32_t status = PSVC_SUCCESS;
1228 uint8_t value;
1229 char *physid;
1230 EObj_t *physobjp;
1231
1232 if (objp->present != PSVC_PRESENT) {
1233 errno = ENODEV;
1234 return (PSVC_FAILURE);
1235 }
1236
1237 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1238 0, &physid);
1239 if (status != PSVC_SUCCESS)
1240 return (status);
1241 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1242 if (status != PSVC_SUCCESS)
1243 return (status);
1244
1245 status = ((EPhysDev_t *)physobjp)->get_reg(hdlp, objp->addr_spec,
1246 &value);
1247 if (status != PSVC_SUCCESS)
1248 return (status);
1249
1250 switch (value) {
1251 case 0:
1252 strcpy(led_state, PSVC_LED_OFF);
1253 break;
1254 case 1:
1255 strcpy(led_state, PSVC_LED_SLOW_BLINK);
1256 break;
1257 case 2:
1258 strcpy(led_state, PSVC_LED_FAST_BLINK);
1259 break;
1260 case 3:
1261 strcpy(led_state, PSVC_LED_ON);
1262 break;
1263 }
1264
1265 return (status);
1266 }
1267
1268 static int32_t
i_psvc_set_device_state_2_1(EHdl_t * hdlp,EObj_t * objp,char * led_state)1269 i_psvc_set_device_state_2_1(EHdl_t *hdlp, EObj_t *objp, char *led_state)
1270 {
1271 int32_t status = PSVC_SUCCESS;
1272 uint8_t value;
1273 char *physid;
1274 EObj_t *physobjp;
1275
1276 if (objp->present != PSVC_PRESENT) {
1277 errno = ENODEV;
1278 return (PSVC_FAILURE);
1279 }
1280
1281 if (strcmp(led_state, PSVC_LED_ON) == 0)
1282 ((ELed_t *)objp)->lit_count++;
1283 else if (strcmp(led_state, PSVC_LED_OFF) == 0) {
1284 if (--((ELed_t *)objp)->lit_count > 0) {
1285 return (PSVC_SUCCESS);
1286 } else if (((ELed_t *)objp)->lit_count < 0)
1287 ((ELed_t *)objp)->lit_count = 0;
1288
1289 /* Fall through case is when lit_count is 0 */
1290 }
1291
1292 strcpy(objp->previous_state, objp->state);
1293 strcpy(objp->state, led_state);
1294
1295 if (strcmp(led_state, PSVC_LED_OFF) == 0)
1296 value = 0;
1297 else if (strcmp(led_state, PSVC_LED_SLOW_BLINK) == 0)
1298 value = 1;
1299 else if (strcmp(led_state, PSVC_LED_FAST_BLINK) == 0)
1300 value = 2;
1301 else if (strcmp(led_state, PSVC_LED_ON) == 0)
1302 value = 3;
1303
1304 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1305 0, &physid);
1306 if (status != PSVC_SUCCESS)
1307 return (status);
1308 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1309 if (status != PSVC_SUCCESS)
1310 return (status);
1311
1312 status = ((EPhysDev_t *)physobjp)->set_reg(hdlp, objp->addr_spec,
1313 value);
1314
1315 return (status);
1316 }
1317
1318 static int32_t
i_psvc_get_device_state_9_0(EHdl_t * hdlp,EObj_t * objp,char * pos)1319 i_psvc_get_device_state_9_0(EHdl_t *hdlp, EObj_t *objp, char *pos)
1320 {
1321 int32_t status = PSVC_SUCCESS, matches;
1322 char *sensorid;
1323 EObj_t *sensorp;
1324 char state[32];
1325
1326 if (objp->present != PSVC_PRESENT) {
1327 errno = ENODEV;
1328 return (PSVC_FAILURE);
1329 }
1330
1331 if (objp->features & PSVC_NORMAL_POS_AV) {
1332 (void) i_psvc_get_assoc_matches(hdlp, objp->label,
1333 PSVC_KS_NORMAL_POS_SENSOR, &matches);
1334 if (matches == 1) {
1335 status = i_psvc_get_assoc_id(hdlp, objp->label,
1336 PSVC_KS_NORMAL_POS_SENSOR, 0, &sensorid);
1337 if (status != PSVC_SUCCESS)
1338 return (status);
1339
1340 status = i_psvc_get_obj(hdlp, sensorid, &sensorp);
1341 if (status != PSVC_SUCCESS)
1342 return (status);
1343
1344 status = sensorp->get_attr(hdlp, sensorp,
1345 PSVC_SWITCH_STATE_ATTR, state);
1346 if (status != PSVC_SUCCESS)
1347 return (status);
1348
1349 if (strcmp(state, PSVC_SWITCH_ON) == 0) {
1350 strcpy(pos, PSVC_NORMAL_POS);
1351 return (PSVC_SUCCESS);
1352 }
1353 }
1354 }
1355
1356 if (objp->features & PSVC_DIAG_POS_AV) {
1357 (void) i_psvc_get_assoc_matches(hdlp, objp->label,
1358 PSVC_KS_DIAG_POS_SENSOR, &matches);
1359 if (matches == 1) {
1360 status = i_psvc_get_assoc_id(hdlp, objp->label,
1361 PSVC_KS_DIAG_POS_SENSOR, 0, &sensorid);
1362 if (status != PSVC_SUCCESS)
1363 return (status);
1364
1365 status = i_psvc_get_obj(hdlp, sensorid, &sensorp);
1366 if (status != PSVC_SUCCESS)
1367 return (status);
1368
1369 status = sensorp->get_attr(hdlp, sensorp,
1370 PSVC_SWITCH_STATE_ATTR, state);
1371 if (status != PSVC_SUCCESS)
1372 return (status);
1373
1374 if (strcmp(state, PSVC_SWITCH_ON) == 0) {
1375 strcpy(pos, PSVC_DIAG_POS);
1376 return (PSVC_SUCCESS);
1377 }
1378 }
1379 }
1380
1381 if (objp->features & PSVC_LOCK_POS_AV) {
1382 (void) i_psvc_get_assoc_matches(hdlp, objp->label,
1383 PSVC_KS_LOCK_POS_SENSOR, &matches);
1384 if (matches == 1) {
1385 status = i_psvc_get_assoc_id(hdlp, objp->label,
1386 PSVC_KS_LOCK_POS_SENSOR, 0, &sensorid);
1387 if (status != PSVC_SUCCESS)
1388 return (status);
1389
1390 status = i_psvc_get_obj(hdlp, sensorid, &sensorp);
1391 if (status != PSVC_SUCCESS)
1392 return (status);
1393
1394 status = sensorp->get_attr(hdlp, sensorp,
1395 PSVC_SWITCH_STATE_ATTR, state);
1396 if (status != PSVC_SUCCESS)
1397 return (status);
1398
1399 if (strcmp(state, PSVC_SWITCH_ON) == 0) {
1400 strcpy(pos, PSVC_LOCKED_POS);
1401 return (PSVC_SUCCESS);
1402 }
1403 }
1404 }
1405
1406 if (objp->features & PSVC_OFF_POS_AV) {
1407 (void) i_psvc_get_assoc_matches(hdlp, objp->label,
1408 PSVC_KS_OFF_POS_SENSOR, &matches);
1409 if (matches == 1) {
1410 status = i_psvc_get_assoc_id(hdlp, objp->label,
1411 PSVC_KS_OFF_POS_SENSOR, 0, &sensorid);
1412 if (status != PSVC_SUCCESS)
1413 return (status);
1414
1415 status = i_psvc_get_obj(hdlp, sensorid, &sensorp);
1416 if (status != PSVC_SUCCESS)
1417 return (status);
1418
1419 status = sensorp->get_attr(hdlp, sensorp,
1420 PSVC_SWITCH_STATE_ATTR, state);
1421 if (status != PSVC_SUCCESS)
1422 return (status);
1423
1424 if (strcmp(state, PSVC_SWITCH_ON) == 0) {
1425 strcpy(pos, PSVC_OFF_POS);
1426 return (PSVC_SUCCESS);
1427 }
1428 }
1429 }
1430 /* If we have fallen through till here, something's wrong */
1431 errno = EINVAL;
1432 return (PSVC_FAILURE);
1433 }
1434
1435
1436 static int32_t
i_psvc_get_device_value_10_0(EHdl_t * hdlp,EObj_t * objp,uint8_t * value)1437 i_psvc_get_device_value_10_0(EHdl_t *hdlp, EObj_t *objp, uint8_t *value)
1438 {
1439 int32_t status = PSVC_SUCCESS;
1440 char *physid;
1441 EObj_t *physobjp;
1442
1443 if (objp->present != PSVC_PRESENT) {
1444 errno = ENODEV;
1445 return (PSVC_FAILURE);
1446 }
1447
1448 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1449 0, &physid);
1450 if (status != PSVC_SUCCESS)
1451 return (status);
1452 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1453 if (status != PSVC_SUCCESS)
1454 return (status);
1455
1456 status = ((EPhysDev_t *)physobjp)->get_reg(hdlp, objp->addr_spec,
1457 value);
1458 if (status != PSVC_SUCCESS)
1459 return (status);
1460
1461 if (objp->features & PSVC_CONVERSION_TABLE) {
1462 int32_t m;
1463 char *tid;
1464 uint8_t temp8;
1465
1466 status = i_psvc_get_assoc_matches(hdlp, objp->label,
1467 PSVC_TABLE, &m);
1468 if ((status != PSVC_SUCCESS) || (m != 1)) {
1469 return (status);
1470 }
1471
1472 (void) i_psvc_get_assoc_id(hdlp, objp->label,
1473 PSVC_TABLE, 0, &tid);
1474
1475 status = i_psvc_get_table_value(hdlp, tid, *value, &temp8);
1476 *value = temp8;
1477 }
1478 return (status);
1479 }
1480
1481 static int32_t
i_psvc_get_device_value_10_1(EHdl_t * hdlp,EObj_t * objp,uint8_t * value)1482 i_psvc_get_device_value_10_1(EHdl_t *hdlp, EObj_t *objp, uint8_t *value)
1483 {
1484 int32_t status = PSVC_SUCCESS;
1485 char *physid;
1486 EObj_t *physobjp;
1487
1488 if (objp->present != PSVC_PRESENT) {
1489 errno = ENODEV;
1490 return (PSVC_FAILURE);
1491 }
1492
1493 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1494 0, &physid);
1495 if (status != PSVC_SUCCESS)
1496 return (status);
1497 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1498 if (status != PSVC_SUCCESS)
1499 return (status);
1500
1501 status = ((EPhysDev_t *)physobjp)->get_port(hdlp, objp->addr_spec,
1502 value);
1503 if (status != PSVC_SUCCESS)
1504 return (status);
1505
1506 return (status);
1507 }
1508
1509 static int32_t
i_psvc_set_device_value_10_0(EHdl_t * hdlp,EObj_t * objp,uint8_t * value)1510 i_psvc_set_device_value_10_0(EHdl_t *hdlp, EObj_t *objp, uint8_t *value)
1511 {
1512 int32_t status = PSVC_SUCCESS;
1513 char *physid;
1514 EObj_t *physobjp;
1515
1516 if (objp->present != PSVC_PRESENT) {
1517 errno = ENODEV;
1518 return (PSVC_FAILURE);
1519 }
1520
1521 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1522 0, &physid);
1523 if (status != PSVC_SUCCESS)
1524 return (status);
1525 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1526 if (status != PSVC_SUCCESS)
1527 return (status);
1528
1529 status = ((EPhysDev_t *)physobjp)->set_reg(hdlp, objp->addr_spec,
1530 *value);
1531 return (status);
1532 }
1533
1534 static int32_t
i_psvc_set_device_value_10_1(EHdl_t * hdlp,EObj_t * objp,uint8_t * value)1535 i_psvc_set_device_value_10_1(EHdl_t *hdlp, EObj_t *objp, uint8_t *value)
1536 {
1537 int32_t status = PSVC_SUCCESS;
1538 char *physid;
1539 EObj_t *physobjp;
1540
1541 if (objp->present != PSVC_PRESENT) {
1542 errno = ENODEV;
1543 return (PSVC_FAILURE);
1544 }
1545
1546 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1547 0, &physid);
1548 if (status != PSVC_SUCCESS)
1549 return (status);
1550 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1551 if (status != PSVC_SUCCESS)
1552 return (status);
1553
1554 status = ((EPhysDev_t *)physobjp)->set_port(hdlp, objp->addr_spec,
1555 *value);
1556 return (status);
1557 }
1558
1559 static int32_t
i_psvc_get_device_state_8_0(EHdl_t * hdlp,EObj_t * objp,char * sw_state)1560 i_psvc_get_device_state_8_0(EHdl_t *hdlp, EObj_t *objp, char *sw_state)
1561 {
1562 int32_t status = PSVC_SUCCESS;
1563 boolean_t active_low;
1564 int32_t bit_value;
1565 char *physid;
1566 EObj_t *physobjp;
1567
1568 if (objp->present != PSVC_PRESENT) {
1569 errno = ENODEV;
1570 return (PSVC_FAILURE);
1571 }
1572
1573 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1574 0, &physid);
1575 if (status != PSVC_SUCCESS)
1576 return (status);
1577 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1578 if (status != PSVC_SUCCESS)
1579 return (status);
1580
1581 status = ((EPhysDev_t *)physobjp)->get_bit(hdlp, objp->addr_spec,
1582 &bit_value);
1583 if (status != PSVC_SUCCESS)
1584 return (status);
1585
1586 active_low = PSVC_IS_ACTIVE_LOW(objp->addr_spec);
1587 if (active_low)
1588 if (bit_value == 0)
1589 strcpy(sw_state, PSVC_SWITCH_ON);
1590 else
1591 strcpy(sw_state, PSVC_SWITCH_OFF);
1592 else
1593 if (bit_value == 0)
1594 strcpy(sw_state, PSVC_SWITCH_OFF);
1595 else
1596 strcpy(sw_state, PSVC_SWITCH_ON);
1597
1598 return (status);
1599 }
1600
1601 static int32_t
i_psvc_set_device_state_8_0(EHdl_t * hdlp,EObj_t * objp,char * sw_state)1602 i_psvc_set_device_state_8_0(EHdl_t *hdlp, EObj_t *objp, char *sw_state)
1603 {
1604 int32_t status = PSVC_SUCCESS;
1605 boolean_t active_low;
1606 int32_t bit_value;
1607 char *physid;
1608 EObj_t *physobjp;
1609
1610 if (objp->present != PSVC_PRESENT) {
1611 errno = ENODEV;
1612 return (PSVC_FAILURE);
1613 }
1614
1615 strcpy(objp->previous_state, objp->state);
1616 strcpy(objp->state, sw_state);
1617
1618 active_low = PSVC_IS_ACTIVE_LOW(objp->addr_spec);
1619
1620 if (active_low)
1621 if (strcmp(sw_state, PSVC_SWITCH_ON) == 0)
1622 bit_value = 0;
1623 else
1624 bit_value = 1;
1625 else
1626 if (strcmp(sw_state, PSVC_SWITCH_ON) == 0)
1627 bit_value = 1;
1628 else
1629 bit_value = 0;
1630
1631 status = i_psvc_get_assoc_id(hdlp, objp->label, PSVC_PHYSICAL_DEVICE,
1632 0, &physid);
1633 if (status != PSVC_SUCCESS)
1634 return (status);
1635 status = i_psvc_get_obj(hdlp, physid, &physobjp);
1636 if (status != PSVC_SUCCESS)
1637 return (status);
1638
1639 status = ((EPhysDev_t *)physobjp)->set_bit(hdlp, objp->addr_spec,
1640 bit_value);
1641 return (status);
1642 }
1643
1644 /* LM75 */
1645 static int32_t
i_psvc_get_temperature_11_2(EHdl_t * hdlp,uint64_t aspec,int32_t * temp)1646 i_psvc_get_temperature_11_2(EHdl_t *hdlp, uint64_t aspec, int32_t *temp)
1647 {
1648 int32_t status = PSVC_SUCCESS;
1649 char path[1024];
1650 int32_t fp;
1651 int16_t temp16;
1652
1653 status = i_psvc_get_devpath(hdlp, aspec, path);
1654 if (status != PSVC_SUCCESS)
1655 return (status);
1656
1657 fp = open(path, O_RDWR);
1658 if (fp == -1)
1659 return (PSVC_FAILURE);
1660
1661 status = ioctl_retry(fp, I2C_GET_TEMPERATURE, (void *)&temp16);
1662 if (status == -1) {
1663 close(fp);
1664 errno = EIO;
1665 return (PSVC_FAILURE);
1666 }
1667 *temp = temp16;
1668
1669 close(fp);
1670
1671 return (status);
1672 }
1673
1674 /* MAX1617 */
1675 static int32_t
i_psvc_get_temperature_11_4(EHdl_t * hdlp,uint64_t aspec,int32_t * temp)1676 i_psvc_get_temperature_11_4(EHdl_t *hdlp, uint64_t aspec, int32_t *temp)
1677 {
1678 int32_t status = PSVC_SUCCESS;
1679 char path[1024];
1680 int32_t fp;
1681 int16_t temp16;
1682
1683 status = i_psvc_get_devpath(hdlp, aspec, path);
1684 if (status != PSVC_SUCCESS)
1685 return (status);
1686
1687 fp = open(path, O_RDWR);
1688 if (fp == -1)
1689 return (PSVC_FAILURE);
1690
1691 status = ioctl_retry(fp, I2C_GET_TEMPERATURE, (void *)&temp16);
1692 if (status == -1) {
1693 close(fp);
1694 errno = EIO;
1695 return (PSVC_FAILURE);
1696 }
1697 *temp = temp16;
1698
1699 close(fp);
1700
1701 return (status);
1702 }
1703
1704 /* PCF8591 */
1705 static int32_t
i_psvc_get_temperature_11_6(EHdl_t * hdlp,uint64_t aspec,int32_t * temp)1706 i_psvc_get_temperature_11_6(EHdl_t *hdlp, uint64_t aspec, int32_t *temp)
1707 {
1708 int32_t status = PSVC_SUCCESS;
1709 char path[1024];
1710 int32_t fp;
1711
1712 status = i_psvc_get_devpath(hdlp, aspec, path);
1713 if (status != PSVC_SUCCESS)
1714 return (status);
1715
1716 fp = open(path, O_RDWR);
1717 if (fp == -1)
1718 return (PSVC_FAILURE);
1719
1720 status = ioctl_retry(fp, I2C_GET_INPUT, (void *)temp);
1721 if (status == -1) {
1722 close(fp);
1723 errno = EIO;
1724 return (-1);
1725 }
1726
1727 close(fp);
1728
1729 return (status);
1730 }
1731
1732 /* SSC050 */
1733 static int32_t
i_psvc_get_fanspeed_11_7(EHdl_t * hdlp,uint64_t aspec,int32_t * fan_speed)1734 i_psvc_get_fanspeed_11_7(EHdl_t *hdlp, uint64_t aspec, int32_t *fan_speed)
1735 {
1736 int32_t ret, status = PSVC_SUCCESS;
1737 char path[1024];
1738 int32_t fp;
1739
1740 status = i_psvc_get_devpath(hdlp, aspec, path);
1741 if (status != PSVC_SUCCESS)
1742 return (status);
1743
1744 fp = open(path, O_RDWR);
1745 if (fp == -1)
1746 return (PSVC_FAILURE);
1747
1748 ret = ioctl_retry(fp, I2C_GET_FAN_SPEED, (void *)fan_speed);
1749 if (ret == -1) {
1750 close(fp);
1751 errno = EIO;
1752 return (-1);
1753 }
1754
1755 close(fp);
1756
1757 return (status);
1758 }
1759
1760 /* PCF8591 */
1761 static int32_t
i_psvc_get_input_11_6(EHdl_t * hdlp,uint64_t aspec,int32_t * value)1762 i_psvc_get_input_11_6(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
1763 {
1764 int32_t ret, status = PSVC_SUCCESS;
1765 char path[1024];
1766 int32_t fp;
1767
1768 status = i_psvc_get_devpath(hdlp, aspec, path);
1769 if (status != PSVC_SUCCESS)
1770 return (status);
1771
1772 fp = open(path, O_RDWR);
1773 if (fp == -1)
1774 return (PSVC_FAILURE);
1775
1776 ret = ioctl_retry(fp, I2C_GET_INPUT, (void *)value);
1777 if (ret == -1) {
1778 close(fp);
1779 errno = EIO;
1780 return (-1);
1781 }
1782
1783 close(fp);
1784
1785 return (status);
1786 }
1787
1788 /* LTC1427 */
1789 static int32_t
i_psvc_get_output_11_3(EHdl_t * hdlp,uint64_t aspec,int32_t * value)1790 i_psvc_get_output_11_3(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
1791 {
1792 int32_t ret, status = PSVC_SUCCESS;
1793 char path[1024];
1794 int32_t fp;
1795
1796 status = i_psvc_get_devpath(hdlp, aspec, path);
1797 if (status != PSVC_SUCCESS)
1798 return (status);
1799
1800 fp = open(path, O_RDWR);
1801 if (fp == -1)
1802 return (PSVC_FAILURE);
1803
1804 ret = ioctl_retry(fp, I2C_GET_OUTPUT, (void *)value);
1805 if (ret == -1) {
1806 close(fp);
1807 errno = EIO;
1808 return (PSVC_FAILURE);
1809 }
1810
1811 close(fp);
1812
1813 return (status);
1814 }
1815
1816 /* PCF8591 */
1817 static int32_t
i_psvc_get_output_11_6(EHdl_t * hdlp,uint64_t aspec,int32_t * value)1818 i_psvc_get_output_11_6(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
1819 {
1820 int32_t ret, status = PSVC_SUCCESS;
1821 char path[1024];
1822 int32_t fp;
1823
1824 status = i_psvc_get_devpath(hdlp, aspec, path);
1825 if (status != PSVC_SUCCESS)
1826 return (status);
1827
1828 fp = open(path, O_RDWR);
1829 if (fp == -1)
1830 return (PSVC_FAILURE);
1831
1832 ret = ioctl_retry(fp, I2C_GET_OUTPUT, (void *)value);
1833 if (ret == -1) {
1834 close(fp);
1835 errno = EIO;
1836 return (PSVC_FAILURE);
1837 }
1838
1839 close(fp);
1840
1841 return (status);
1842 }
1843
1844 /* TDA8444 */
1845 static int32_t
i_psvc_get_output_11_8(EHdl_t * hdlp,uint64_t aspec,int32_t * value)1846 i_psvc_get_output_11_8(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
1847 {
1848 int32_t ret, status = PSVC_SUCCESS;
1849 char path[1024];
1850 int32_t fp;
1851 int8_t buf;
1852
1853 status = i_psvc_get_devpath(hdlp, aspec, path);
1854 if (status != PSVC_SUCCESS)
1855 return (status);
1856
1857 fp = open(path, O_RDWR);
1858 if (fp == -1)
1859 return (PSVC_FAILURE);
1860
1861 ret = read(fp, &buf, 1);
1862 if (ret == -1) {
1863 close(fp);
1864 errno = EIO;
1865 return (PSVC_FAILURE);
1866 }
1867 *value = buf;
1868
1869 close(fp);
1870
1871 return (status);
1872 }
1873
1874 /* LTC1427 */
1875 static int32_t
i_psvc_set_output_11_3(EHdl_t * hdlp,uint64_t aspec,int32_t value)1876 i_psvc_set_output_11_3(EHdl_t *hdlp, uint64_t aspec, int32_t value)
1877 {
1878 int32_t ret, status = PSVC_SUCCESS;
1879 char path[1024];
1880 int32_t fp;
1881
1882 status = i_psvc_get_devpath(hdlp, aspec, path);
1883 if (status != PSVC_SUCCESS)
1884 return (status);
1885
1886 fp = open(path, O_RDWR);
1887 if (fp == -1)
1888 return (PSVC_FAILURE);
1889
1890 ret = ioctl_retry(fp, I2C_SET_OUTPUT, (void *)&value);
1891 if (ret == -1) {
1892 close(fp);
1893 errno = EIO;
1894 return (PSVC_FAILURE);
1895 }
1896
1897 close(fp);
1898
1899 return (status);
1900 }
1901
1902 /* PCF8591 */
1903 static int32_t
i_psvc_set_output_11_6(EHdl_t * hdlp,uint64_t aspec,int32_t value)1904 i_psvc_set_output_11_6(EHdl_t *hdlp, uint64_t aspec, int32_t value)
1905 {
1906 int32_t ret, status = PSVC_SUCCESS;
1907 char path[1024];
1908 int32_t fp;
1909
1910 status = i_psvc_get_devpath(hdlp, aspec, path);
1911 if (status != PSVC_SUCCESS)
1912 return (status);
1913
1914 fp = open(path, O_RDWR);
1915 if (fp == -1)
1916 return (PSVC_FAILURE);
1917
1918 ret = ioctl_retry(fp, I2C_SET_OUTPUT, (void *)&value);
1919 if (ret == -1) {
1920 close(fp);
1921 errno = EIO;
1922 return (PSVC_FAILURE);
1923 }
1924
1925 close(fp);
1926
1927 return (status);
1928 }
1929
1930 /* TDA8444 */
1931 static int32_t
i_psvc_set_output_11_8(EHdl_t * hdlp,uint64_t aspec,int32_t value)1932 i_psvc_set_output_11_8(EHdl_t *hdlp, uint64_t aspec, int32_t value)
1933 {
1934 int32_t ret, status = PSVC_SUCCESS;
1935 char path[1024];
1936 int32_t fp;
1937 int8_t buf;
1938
1939 status = i_psvc_get_devpath(hdlp, aspec, path);
1940 if (status != PSVC_SUCCESS)
1941 return (status);
1942
1943 fp = open(path, O_RDWR);
1944 if (fp == -1)
1945 return (PSVC_FAILURE);
1946
1947 buf = value;
1948 ret = write(fp, &buf, 1);
1949 if (ret == -1) {
1950 close(fp);
1951 errno = EIO;
1952 return (PSVC_FAILURE);
1953 }
1954
1955 close(fp);
1956
1957 return (status);
1958 }
1959
1960 /* HPC3130 */
1961 static int32_t
i_psvc_get_reg_11_1(EHdl_t * hdlp,uint64_t aspec,uint8_t * value)1962 i_psvc_get_reg_11_1(EHdl_t *hdlp, uint64_t aspec, uint8_t *value)
1963 {
1964 int32_t ret, status = PSVC_SUCCESS;
1965 uint8_t bitshift, bytemask;
1966 char path[1024];
1967 i2c_reg_t i2cregarg;
1968 int32_t fp;
1969
1970 status = i_psvc_get_devpath(hdlp, aspec, path);
1971 if (status != PSVC_SUCCESS)
1972 return (status);
1973 fp = open(path, O_RDWR);
1974 if (fp == -1)
1975 return (PSVC_FAILURE);
1976
1977 i2cregarg.reg_num = PSVC_GET_ASPEC_REG(aspec);
1978 ret = ioctl_retry(fp, I2C_GET_REG, (void *)&i2cregarg);
1979 if (ret == -1) {
1980 close(fp);
1981 errno = EIO;
1982 return (-1);
1983 }
1984
1985 bitshift = PSVC_GET_ASPEC_BITSHIFT(aspec);
1986 bytemask = PSVC_GET_ASPEC_BYTEMASK(aspec);
1987 if (value != NULL)
1988 *value = (i2cregarg.reg_value & bytemask) >> bitshift;
1989 close(fp);
1990
1991 return (status);
1992 }
1993
1994 /* SSC050 */
1995 static int32_t
i_psvc_get_reg_11_7(EHdl_t * hdlp,uint64_t aspec,uint8_t * value)1996 i_psvc_get_reg_11_7(EHdl_t *hdlp, uint64_t aspec, uint8_t *value)
1997 {
1998 int32_t ret, status = PSVC_SUCCESS;
1999 uint8_t bitshift, bytemask;
2000 char path[1024];
2001 i2c_reg_t i2cregarg;
2002 int32_t fp;
2003
2004 status = i_psvc_get_devpath(hdlp, aspec, path);
2005 if (status != PSVC_SUCCESS)
2006 return (status);
2007
2008 fp = open(path, O_RDWR);
2009 if (fp == -1)
2010 return (PSVC_FAILURE);
2011
2012 i2cregarg.reg_num = PSVC_GET_ASPEC_REG(aspec);
2013 ret = ioctl_retry(fp, I2C_GET_REG, (void *)&i2cregarg);
2014 if (ret == -1) {
2015 close(fp);
2016 errno = EIO;
2017 return (-1);
2018 }
2019
2020 bitshift = PSVC_GET_ASPEC_BITSHIFT(aspec);
2021 bytemask = PSVC_GET_ASPEC_BYTEMASK(aspec);
2022 if (value != NULL)
2023 *value = (i2cregarg.reg_value & bytemask) >> bitshift;
2024
2025 close(fp);
2026
2027 return (status);
2028 }
2029
2030 /* HPC3130 */
2031 static int32_t
i_psvc_set_reg_11_1(EHdl_t * hdlp,uint64_t aspec,int32_t value)2032 i_psvc_set_reg_11_1(EHdl_t *hdlp, uint64_t aspec, int32_t value)
2033 {
2034 int32_t ret, status = PSVC_SUCCESS;
2035 char path[1024];
2036 i2c_reg_t i2cregarg;
2037 int8_t tval;
2038 uint8_t bitshift, bytemask;
2039 int32_t fp;
2040
2041 status = i_psvc_get_devpath(hdlp, aspec, path);
2042 if (status != PSVC_SUCCESS)
2043 return (status);
2044
2045 bitshift = PSVC_GET_ASPEC_BITSHIFT(aspec);
2046 bytemask = PSVC_GET_ASPEC_BYTEMASK(aspec);
2047 value = value << bitshift;
2048
2049 fp = open(path, O_RDWR);
2050 if (fp == -1)
2051 return (PSVC_FAILURE);
2052
2053 i2cregarg.reg_num = PSVC_GET_ASPEC_REG(aspec);
2054 if (bytemask != 0xFF) {
2055 ret = ioctl_retry(fp, I2C_GET_REG, (void *)&i2cregarg);
2056 if (ret == -1) {
2057 close(fp);
2058 errno = EIO;
2059 return (-1);
2060 }
2061 tval = i2cregarg.reg_value;
2062 tval = tval & ~bytemask;
2063 } else
2064 tval = 0;
2065
2066 value = tval | value;
2067 i2cregarg.reg_value = value;
2068 ret = ioctl_retry(fp, I2C_SET_REG, (void *)&i2cregarg);
2069 if (ret == -1) {
2070 close(fp);
2071 errno = EIO;
2072 return (-1);
2073 }
2074
2075 close(fp);
2076
2077 return (status);
2078 }
2079
2080 /* SSC050 */
2081 static int32_t
i_psvc_set_reg_11_7(EHdl_t * hdlp,uint64_t aspec,int32_t value)2082 i_psvc_set_reg_11_7(EHdl_t *hdlp, uint64_t aspec, int32_t value)
2083 {
2084 int32_t ret, status = PSVC_SUCCESS;
2085 char path[1024];
2086 i2c_reg_t i2cregarg;
2087 int8_t tval;
2088 uint8_t bitshift, bytemask;
2089 int32_t fp;
2090
2091 status = i_psvc_get_devpath(hdlp, aspec, path);
2092 if (status != PSVC_SUCCESS)
2093 return (status);
2094
2095 bitshift = PSVC_GET_ASPEC_BITSHIFT(aspec);
2096 bytemask = PSVC_GET_ASPEC_BYTEMASK(aspec);
2097 value = value << bitshift;
2098
2099 fp = open(path, O_RDWR);
2100 if (fp == -1)
2101 return (PSVC_FAILURE);
2102
2103 i2cregarg.reg_num = PSVC_GET_ASPEC_REG(aspec);
2104 if (bytemask != 0xFF) {
2105 ret = ioctl_retry(fp, I2C_GET_REG, (void *)&i2cregarg);
2106 if (ret == -1) {
2107 close(fp);
2108 errno = EIO;
2109 return (-1);
2110 }
2111 tval = i2cregarg.reg_value;
2112 tval = tval & ~bytemask;
2113 } else
2114 tval = 0;
2115
2116 value = tval | value;
2117 i2cregarg.reg_value = value;
2118 ret = ioctl_retry(fp, I2C_SET_REG, (void *)&i2cregarg);
2119 if (ret == -1) {
2120 close(fp);
2121 errno = EIO;
2122 return (-1);
2123 }
2124
2125 close(fp);
2126
2127 return (status);
2128 }
2129
2130 /* PCF8574 */
2131 static int32_t
i_psvc_get_bit_11_5(EHdl_t * hdlp,uint64_t aspec,int32_t * value)2132 i_psvc_get_bit_11_5(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
2133 {
2134 int32_t ret, status = PSVC_SUCCESS;
2135 char path[1024];
2136 i2c_bit_t bitarg;
2137 int32_t fp;
2138
2139 status = i_psvc_get_devpath(hdlp, aspec, path);
2140 if (status != PSVC_SUCCESS)
2141 return (status);
2142
2143 bitarg.bit_num = PSVC_GET_BIT_NUM(aspec);
2144 bitarg.direction = DIR_NO_CHANGE;
2145
2146 fp = open(path, O_RDWR);
2147 if (fp == -1)
2148 return (PSVC_FAILURE);
2149
2150 ret = ioctl_retry(fp, I2C_GET_BIT, (void *)&bitarg);
2151 if (ret == -1) {
2152 close(fp);
2153 errno = EIO;
2154 return (-1);
2155 }
2156
2157 *value = bitarg.bit_value;
2158
2159 close(fp);
2160
2161 return (status);
2162 }
2163
2164 /* PCF8574 */
2165 static int32_t
i_psvc_get_port_11_5(EHdl_t * hdlp,uint64_t aspec,uint8_t * value)2166 i_psvc_get_port_11_5(EHdl_t *hdlp, uint64_t aspec, uint8_t *value)
2167 {
2168 int32_t ret, status = PSVC_SUCCESS;
2169 char path[1024];
2170 i2c_port_t port;
2171 int32_t fp;
2172
2173 status = i_psvc_get_devpath(hdlp, aspec, path);
2174 if (status != PSVC_SUCCESS)
2175 return (status);
2176
2177 port.direction = DIR_NO_CHANGE;
2178
2179 fp = open(path, O_RDWR);
2180 if (fp == -1)
2181 return (PSVC_FAILURE);
2182
2183 ret = ioctl_retry(fp, I2C_GET_PORT, (void *)&port);
2184 if (ret == -1) {
2185 close(fp);
2186 errno = EIO;
2187 return (-1);
2188 }
2189
2190 *value = port.value;
2191
2192 close(fp);
2193
2194 return (status);
2195 }
2196
2197 /* SSC050 */
2198 static int32_t
i_psvc_get_bit_11_7(EHdl_t * hdlp,uint64_t aspec,int32_t * value)2199 i_psvc_get_bit_11_7(EHdl_t *hdlp, uint64_t aspec, int32_t *value)
2200 {
2201 int32_t ret, status = PSVC_SUCCESS;
2202 char path[1024];
2203 i2c_bit_t bitarg;
2204 int32_t fp;
2205
2206 status = i_psvc_get_devpath(hdlp, aspec, path);
2207 if (status != PSVC_SUCCESS)
2208 return (status);
2209
2210 bitarg.bit_num = PSVC_GET_BIT_NUM(aspec);
2211 bitarg.direction = DIR_NO_CHANGE;
2212
2213 fp = open(path, O_RDWR);
2214 if (fp == -1)
2215 return (PSVC_FAILURE);
2216
2217 ret = ioctl_retry(fp, I2C_GET_BIT, (void *)&bitarg);
2218 if (ret == -1) {
2219 close(fp);
2220 errno = EIO;
2221 return (-1);
2222 }
2223
2224 *value = bitarg.bit_value;
2225
2226 close(fp);
2227
2228 return (status);
2229 }
2230
2231 /* PCF8574 */
2232 static int32_t
i_psvc_set_bit_11_5(EHdl_t * hdlp,uint64_t aspec,int32_t value)2233 i_psvc_set_bit_11_5(EHdl_t *hdlp, uint64_t aspec, int32_t value)
2234 {
2235 int32_t ret, status = PSVC_SUCCESS;
2236 char path[1024];
2237 i2c_bit_t bitarg;
2238 int32_t fp;
2239
2240 status = i_psvc_get_devpath(hdlp, aspec, path);
2241 if (status != PSVC_SUCCESS)
2242 return (status);
2243
2244 bitarg.bit_value = value;
2245 bitarg.bit_num = PSVC_GET_BIT_NUM(aspec);
2246 bitarg.direction = DIR_OUTPUT;
2247 fp = open(path, O_RDWR);
2248 if (fp == -1)
2249 return (PSVC_FAILURE);
2250
2251 ret = ioctl_retry(fp, I2C_SET_BIT, (void *)&bitarg);
2252 if (ret == -1) {
2253 close(fp);
2254 errno = EIO;
2255 return (-1);
2256 }
2257
2258 close(fp);
2259
2260 return (status);
2261 }
2262
2263 /* PCF8574 */
2264 static int32_t
i_psvc_set_port_11_5(EHdl_t * hdlp,uint64_t aspec,int32_t value)2265 i_psvc_set_port_11_5(EHdl_t *hdlp, uint64_t aspec, int32_t value)
2266 {
2267 int32_t ret, status = PSVC_SUCCESS;
2268 char path[1024];
2269 i2c_port_t port;
2270 int32_t fp;
2271
2272 status = i_psvc_get_devpath(hdlp, aspec, path);
2273 if (status != PSVC_SUCCESS)
2274 return (status);
2275
2276 port.value = (uint8_t)value;
2277 port.direction = DIR_NO_CHANGE;
2278 fp = open(path, O_RDWR);
2279 if (fp == -1)
2280 return (PSVC_FAILURE);
2281
2282 ret = ioctl_retry(fp, I2C_SET_PORT, (void *)&port);
2283 if (ret == -1) {
2284 close(fp);
2285 errno = EIO;
2286 return (-1);
2287 }
2288
2289 close(fp);
2290
2291 return (status);
2292 }
2293
2294 /* SSC050 */
2295 static int32_t
i_psvc_set_bit_11_7(EHdl_t * hdlp,uint64_t aspec,int32_t value)2296 i_psvc_set_bit_11_7(EHdl_t *hdlp, uint64_t aspec, int32_t value)
2297 {
2298 int32_t ret, status = PSVC_SUCCESS;
2299 char path[1024];
2300 i2c_bit_t bitarg;
2301 int32_t fp;
2302
2303 status = i_psvc_get_devpath(hdlp, aspec, path);
2304 if (status != PSVC_SUCCESS)
2305 return (status);
2306
2307 bitarg.bit_value = value;
2308 bitarg.bit_num = PSVC_GET_BIT_NUM(aspec);
2309 bitarg.direction = DIR_OUTPUT;
2310
2311 fp = open(path, O_RDWR);
2312 if (fp == -1)
2313 return (PSVC_FAILURE);
2314
2315 ret = ioctl_retry(fp, I2C_SET_BIT, (void *)&bitarg);
2316 if (ret == -1) {
2317 close(fp);
2318 errno = EIO;
2319 return (-1);
2320 }
2321
2322 close(fp);
2323
2324 return (status);
2325 }
2326
2327 /* AT24 */
2328 static int32_t
i_psvc_probe_11_0(EHdl_t * hdlp,EObj_t * objp)2329 i_psvc_probe_11_0(EHdl_t *hdlp, EObj_t *objp)
2330 {
2331 int32_t ret, status = PSVC_SUCCESS;
2332 uint8_t value;
2333 char path[1024];
2334 int32_t fp;
2335
2336 if (objp->present != PSVC_PRESENT) {
2337 errno = ENODEV;
2338 return (PSVC_FAILURE);
2339 }
2340
2341 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2342 if (status != PSVC_SUCCESS) {
2343 return (status);
2344 }
2345
2346 fp = open(path, O_RDWR);
2347 if (fp == -1) {
2348 return (PSVC_FAILURE);
2349 }
2350
2351 ret = read(fp, &value, 1);
2352 if (ret == -1) {
2353 close(fp);
2354 errno = EIO;
2355 return (-1);
2356 }
2357
2358 close(fp);
2359
2360 return (status);
2361 }
2362
2363 /* HPC3130 */
2364 static int32_t
i_psvc_probe_11_1(EHdl_t * hdlp,EObj_t * objp)2365 i_psvc_probe_11_1(EHdl_t *hdlp, EObj_t *objp)
2366 {
2367 int32_t ret, status = PSVC_SUCCESS;
2368 char path[1024];
2369 i2c_reg_t reg;
2370 int32_t fp;
2371
2372 if (objp->present != PSVC_PRESENT) {
2373 errno = ENODEV;
2374 return (PSVC_FAILURE);
2375 }
2376
2377 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2378 if (status != PSVC_SUCCESS)
2379 return (status);
2380
2381 fp = open(path, O_RDWR);
2382 if (fp == -1)
2383 return (PSVC_FAILURE);
2384
2385 reg.reg_num = 0;
2386 ret = ioctl_retry(fp, I2C_GET_REG, (void *)®);
2387 if (ret == -1) {
2388 close(fp);
2389 errno = EIO;
2390 return (-1);
2391 }
2392
2393 close(fp);
2394
2395 return (status);
2396 }
2397
2398 /* LM75 */
2399 static int32_t
i_psvc_probe_11_2(EHdl_t * hdlp,EObj_t * objp)2400 i_psvc_probe_11_2(EHdl_t *hdlp, EObj_t *objp)
2401 {
2402 int32_t ret, status = PSVC_SUCCESS;
2403 char path[1024];
2404 int32_t fp;
2405 int16_t temp16;
2406
2407 if (objp->present != PSVC_PRESENT) {
2408 errno = ENODEV;
2409 return (PSVC_FAILURE);
2410 }
2411
2412 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2413 if (status != PSVC_SUCCESS) {
2414 return (status);
2415 }
2416
2417 fp = open(path, O_RDWR);
2418 if (fp == -1) {
2419 return (PSVC_FAILURE);
2420 }
2421
2422 ret = ioctl_retry(fp, I2C_GET_TEMPERATURE, (void *)&temp16);
2423 if (ret == -1) {
2424 close(fp);
2425 errno = EIO;
2426 return (-1);
2427 }
2428
2429 close(fp);
2430
2431 return (status);
2432 }
2433
2434 /* LTC1427 */
2435 static int32_t
i_psvc_probe_11_3(EHdl_t * hdlp,EObj_t * objp)2436 i_psvc_probe_11_3(EHdl_t *hdlp, EObj_t *objp)
2437 {
2438 int32_t ret, status = PSVC_SUCCESS;
2439 int32_t value;
2440 char path[1024];
2441 int32_t fp;
2442
2443 if (objp->present != PSVC_PRESENT) {
2444 errno = ENODEV;
2445 return (PSVC_FAILURE);
2446 }
2447
2448 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2449 if (status != PSVC_SUCCESS) {
2450 return (status);
2451 }
2452
2453 fp = open(path, O_RDWR);
2454 if (fp == -1) {
2455 return (PSVC_FAILURE);
2456 }
2457
2458 ret = ioctl_retry(fp, I2C_GET_OUTPUT, (void *)&value);
2459 if (ret == -1) {
2460 close(fp);
2461 errno = EINVAL;
2462 return (-1);
2463 }
2464
2465 ret = ioctl_retry(fp, I2C_SET_OUTPUT, (void *)&value);
2466 if (ret == -1) {
2467 close(fp);
2468 errno = EIO;
2469 return (-1);
2470 }
2471
2472 close(fp);
2473 return (status);
2474 }
2475
2476 /* MAX1617 */
2477 static int32_t
i_psvc_probe_11_4(EHdl_t * hdlp,EObj_t * objp)2478 i_psvc_probe_11_4(EHdl_t *hdlp, EObj_t *objp)
2479 {
2480 int32_t ret, status = PSVC_SUCCESS;
2481 char path[1024];
2482 int32_t fp;
2483 int16_t temp16;
2484
2485 if (objp->present != PSVC_PRESENT) {
2486 errno = ENODEV;
2487 return (PSVC_FAILURE);
2488 }
2489
2490 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2491 if (status != PSVC_SUCCESS) {
2492 return (status);
2493 }
2494
2495 fp = open(path, O_RDWR);
2496 if (fp == -1) {
2497 return (PSVC_FAILURE);
2498 }
2499
2500 ret = ioctl_retry(fp, I2C_GET_TEMPERATURE, (void *)&temp16);
2501 if (ret == -1) {
2502 close(fp);
2503 errno = EIO;
2504 return (-1);
2505 }
2506
2507 close(fp);
2508
2509 return (status);
2510 }
2511
2512 /* PCF8574 */
2513 static int32_t
i_psvc_probe_11_5(EHdl_t * hdlp,EObj_t * objp)2514 i_psvc_probe_11_5(EHdl_t *hdlp, EObj_t *objp)
2515 {
2516 int32_t ret, status = PSVC_SUCCESS;
2517 char path[1024];
2518 i2c_port_t port;
2519 int32_t fp;
2520
2521 if (objp->present != PSVC_PRESENT) {
2522 errno = ENODEV;
2523 return (PSVC_FAILURE);
2524 }
2525
2526 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2527 if (status != PSVC_SUCCESS) {
2528 return (status);
2529 }
2530
2531 port.direction = DIR_NO_CHANGE;
2532
2533 fp = open(path, O_RDWR);
2534 if (fp == -1) {
2535 return (PSVC_FAILURE);
2536 }
2537
2538 ret = ioctl_retry(fp, I2C_GET_PORT, (void *)&port);
2539 if (ret == -1) {
2540 close(fp);
2541 errno = EIO;
2542 return (-1);
2543 }
2544
2545 close(fp);
2546
2547 return (status);
2548 }
2549
2550 /* PCF8591 */
2551 static int32_t
i_psvc_probe_11_6(EHdl_t * hdlp,EObj_t * objp)2552 i_psvc_probe_11_6(EHdl_t *hdlp, EObj_t *objp)
2553 {
2554 int32_t ret, status = PSVC_SUCCESS;
2555 char path[1024];
2556 int32_t arg;
2557 int32_t fp;
2558
2559 if (objp->present != PSVC_PRESENT) {
2560 errno = ENODEV;
2561 return (PSVC_FAILURE);
2562 }
2563
2564 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2565 if (status != PSVC_SUCCESS)
2566 return (status);
2567
2568 fp = open(path, O_RDWR);
2569 if (fp == -1)
2570 return (PSVC_FAILURE);
2571
2572 ret = ioctl_retry(fp, I2C_GET_INPUT, (void *)&arg);
2573 if (ret == -1) {
2574 close(fp);
2575 errno = EIO;
2576 return (-1);
2577 }
2578
2579 close(fp);
2580
2581 return (status);
2582 }
2583
2584 /* SSC050 */
2585 static int32_t
i_psvc_probe_11_7(EHdl_t * hdlp,EObj_t * objp)2586 i_psvc_probe_11_7(EHdl_t *hdlp, EObj_t *objp)
2587 {
2588 int32_t ret, status = PSVC_SUCCESS;
2589 char path[1024];
2590 i2c_port_t port;
2591 int32_t fp;
2592
2593 if (objp->present != PSVC_PRESENT) {
2594 errno = ENODEV;
2595 return (PSVC_FAILURE);
2596 }
2597
2598 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2599 if (status != PSVC_SUCCESS)
2600 return (status);
2601
2602 port.direction = DIR_NO_CHANGE;
2603
2604 fp = open(path, O_RDWR);
2605 if (fp == -1)
2606 return (PSVC_FAILURE);
2607
2608 ret = ioctl_retry(fp, I2C_GET_PORT, (void *)&port);
2609 if (ret == -1) {
2610 close(fp);
2611 errno = EIO;
2612 return (-1);
2613 }
2614
2615 close(fp);
2616
2617 return (status);
2618 }
2619
2620 /* TDA8444 */
2621 static int32_t
i_psvc_probe_11_8(EHdl_t * hdlp,EObj_t * objp)2622 i_psvc_probe_11_8(EHdl_t *hdlp, EObj_t *objp)
2623 {
2624 int32_t ret, status = PSVC_SUCCESS;
2625 uint8_t value;
2626 char path[1024];
2627 int32_t fp;
2628
2629 if (objp->present != PSVC_PRESENT) {
2630 errno = ENODEV;
2631 return (PSVC_FAILURE);
2632 }
2633
2634 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2635 if (status != PSVC_SUCCESS)
2636 return (status);
2637
2638 fp = open(path, O_RDWR);
2639 if (fp == -1)
2640 return (PSVC_FAILURE);
2641
2642 ret = read(fp, &value, 1);
2643 if (ret == -1) {
2644 close(fp);
2645 errno = EIO;
2646 return (-1);
2647 }
2648
2649 close(fp);
2650
2651 return (status);
2652 }
2653
2654
2655 /* SSC100 */
2656 static int32_t
i_psvc_probe_11_9(EHdl_t * hdlp,EObj_t * objp)2657 i_psvc_probe_11_9(EHdl_t *hdlp, EObj_t *objp)
2658 {
2659 int32_t ret, status = PSVC_SUCCESS;
2660 char path[1024];
2661 i2c_reg_t reg;
2662 int32_t fp;
2663
2664 if (objp->present != PSVC_PRESENT) {
2665 errno = ENODEV;
2666 return (PSVC_FAILURE);
2667 }
2668
2669 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
2670 if (status != PSVC_SUCCESS) {
2671 return (status);
2672 }
2673
2674 fp = open(path, O_RDWR);
2675 if (fp == -1) {
2676 return (PSVC_FAILURE);
2677 }
2678
2679 /*
2680 * There are only a few register numbers that are valid numbers to
2681 * read from. 0x10 is one of these registers. Any non-valid registers
2682 * cause unknown behavior to the ssc100 device.
2683 */
2684 reg.reg_num = 0x10;
2685 ret = ioctl_retry(fp, I2C_GET_REG, (void *)®);
2686 if (ret == -1) {
2687 close(fp);
2688 errno = EIO;
2689 return (-1);
2690 }
2691
2692 close(fp);
2693
2694 return (status);
2695 }
2696
2697
2698 /*
2699 * Find start of a section within the config file,
2700 * Returns number of records in the section.
2701 * FILE *fd is set to first data record within section.
2702 */
2703 static int32_t
i_psvc_find_file_section(FILE * fd,char * start)2704 i_psvc_find_file_section(FILE *fd, char *start)
2705 {
2706 char *ret;
2707 char buf[BUFSZ];
2708 char name[32];
2709 int found;
2710
2711 fseek(fd, 0, SEEK_SET);
2712 while ((ret = fgets(buf, BUFSZ, fd)) != NULL) {
2713 if (strncmp(start, buf, strlen(start)) == 0)
2714 break;
2715 }
2716
2717 if (ret == NULL) {
2718 errno = EINVAL;
2719 return (-1);
2720 }
2721
2722 found = sscanf(buf, "%s", name);
2723 if (found != 1) {
2724 errno = EINVAL;
2725 return (-1);
2726 } else {
2727 return (0);
2728 }
2729
2730 }
2731
2732 /* compare routine for qsort of str_tbl */
2733 static int32_t
i_psvc_name_compare_qsort(EStringId_t * s1,EStringId_t * s2)2734 i_psvc_name_compare_qsort(EStringId_t *s1, EStringId_t *s2)
2735 {
2736 return (strcmp(s1->name, s2->name));
2737 }
2738
2739 /* compare routine for bsearch of str_tbl */
2740 static int32_t
i_psvc_name_compare_bsearch(char * s1,EStringId_t * s2)2741 i_psvc_name_compare_bsearch(char *s1, EStringId_t *s2)
2742 {
2743 return (strcmp(s1, s2->name));
2744 }
2745
2746 /*
2747 * Determine the initial state of a device.
2748 */
2749 static int32_t
i_psvc_init_state(EHdl_t * hp,EObj_t * objp)2750 i_psvc_init_state(EHdl_t *hp, EObj_t *objp)
2751 {
2752 int32_t status = PSVC_SUCCESS;
2753
2754 if (objp->class == PSVC_ON_OFF_SWITCH_CLASS) {
2755 char state[32];
2756
2757 status = objp->get_attr(hp, objp, PSVC_SWITCH_STATE_ATTR,
2758 state);
2759 if (status != PSVC_SUCCESS)
2760 return (status);
2761
2762 if (strcmp(state, PSVC_SWITCH_ON) == 0)
2763 strcpy(objp->state, PSVC_ON);
2764 else
2765 strcpy(objp->state, PSVC_OFF);
2766 }
2767
2768 if (objp->class == PSVC_KEYSWITCH_CLASS) {
2769 char state[32];
2770
2771 status = objp->get_attr(hp, objp, PSVC_SWITCH_STATE_ATTR,
2772 state);
2773 if (status != PSVC_SUCCESS)
2774 return (status);
2775 strcpy(objp->state, state);
2776 }
2777
2778 return (status);
2779 }
2780
2781 /*
2782 * Return the object pointer for the object name passed in.
2783 * Creates the object if this is the first access,
2784 * Returns 0 if successful, -1 if not.
2785 */
2786 static int32_t
i_psvc_get_obj(EHdl_t * hp,char * dev_name,EObj_t ** objp)2787 i_psvc_get_obj(EHdl_t *hp, char *dev_name, EObj_t **objp)
2788 {
2789 int32_t i, ret;
2790 int32_t found, key, array;
2791 int32_t class, subclass;
2792 boolean_t presence;
2793 char name[NAMELEN];
2794 char buf[BUFSZ];
2795 char *start;
2796 ETable_Array *tbl_arr;
2797
2798 key = psvc_get_str_key(dev_name);
2799 array = key % PSVC_MAX_TABLE_ARRAYS;
2800 tbl_arr = &(hp->tbl_arry[array]);
2801
2802 for (i = 0; i < tbl_arr->obj_count; ++i) {
2803 if (key == tbl_arr->obj_tbl[i].key) {
2804 if (strcmp(dev_name, tbl_arr->obj_tbl[i].name) == 0) {
2805 if (tbl_arr->obj_tbl[i].type != PSVC_OBJ)
2806 return (-1);
2807 *objp = tbl_arr->obj_tbl[i].objp;
2808 return (0);
2809 }
2810 }
2811 }
2812
2813 if (i_psvc_find_file_section(hp->fp, "OBJECT_INFO") == -1) {
2814 ENV_DEBUG("Couldn't find OBJECT_INFO section", dev_name);
2815 return (-1);
2816 }
2817
2818 fgets(buf, BUFSZ, hp->fp);
2819 while (strcmp(buf, "OBJECT_INFO_END")) {
2820 start = strrchr(buf, '/');
2821 if (start == NULL) {
2822 errno = EINVAL;
2823 return (PSVC_FAILURE);
2824 }
2825 found = sscanf(start + 1, "%s", name);
2826 if (found != 1) {
2827 errno = EINVAL;
2828 return (PSVC_FAILURE);
2829 }
2830
2831 if (strcmp(name, dev_name) == 0) {
2832
2833 if (i_psvc_value(buf, PSVC_CLASS_ATTR, &class)
2834 != PSVC_SUCCESS)
2835 return (PSVC_FAILURE);
2836 if (i_psvc_value(buf, PSVC_SUBCLASS_ATTR, &subclass)
2837 != PSVC_SUCCESS)
2838 return (PSVC_FAILURE);
2839 ret = (*i_psvc_constructor[class][subclass])(hp,
2840 dev_name, objp);
2841 if (ret != PSVC_SUCCESS) {
2842 return (-1);
2843 }
2844 ret = (*objp)->get_attr(hp, *objp, PSVC_PRESENCE_ATTR,
2845 &presence);
2846 (*objp)->previous_presence = presence;
2847 if (ret != PSVC_SUCCESS || presence != PSVC_PRESENT)
2848 return (ret);
2849
2850 return (i_psvc_init_state(hp, *objp));
2851 }
2852 fgets(buf, BUFSZ, hp->fp);
2853 }
2854
2855 errno = EINVAL;
2856 return (-1);
2857 }
2858
2859 /*
2860 * Gets the device path associated with an object id.
2861 * Returns 0 if successful, -1 if not.
2862 */
2863 static int32_t
i_psvc_get_devpath(EHdl_t * hp,uint64_t addr_spec,char * path)2864 i_psvc_get_devpath(EHdl_t *hp, uint64_t addr_spec, char *path)
2865 {
2866 int i;
2867 EDevice_t *dp;
2868 uint32_t controller, bus, addr, port;
2869
2870 controller = PSVC_GET_ASPEC_CNTLR(addr_spec);
2871 bus = PSVC_GET_ASPEC_BUSNUM(addr_spec);
2872 addr = PSVC_GET_ASPEC_BUSADDR(addr_spec);
2873 port = PSVC_GET_ASPEC_PORT(addr_spec);
2874
2875 for (i = 0; i < hp->dev_count; ++i) {
2876 dp = &hp->dev_tbl[i];
2877 if (dp->controller == controller &&
2878 dp->bus == bus &&
2879 dp->addr == addr &&
2880 dp->port == port) {
2881 strcpy(path, dp->path);
2882 return (PSVC_SUCCESS);
2883 }
2884 }
2885
2886 errno = EINVAL;
2887 return (PSVC_FAILURE);
2888 }
2889
2890
2891 /* Load the association table */
2892 static int32_t
i_psvc_load_associations(EHdl_t * hp,FILE * fp)2893 i_psvc_load_associations(EHdl_t *hp, FILE *fp)
2894 {
2895 uint32_t count;
2896 int found;
2897 int i, j;
2898 char name1[32], name2[32];
2899 char buf[BUFSZ];
2900 EStringId_t *namep;
2901 EAssoc_t *ap;
2902 int32_t id;
2903 int32_t status;
2904
2905 /*
2906 * ignore count in the file, correct count is highest
2907 * association id + 1, now figured when loading ASSOC_STR
2908 * section.
2909 */
2910 if (i_psvc_find_file_section(fp, "ASSOCIATIONS") != PSVC_SUCCESS)
2911 return (-1);
2912 if ((hp->assoc_tbl = malloc(sizeof (EAssocList_t) * hp->assoc_count))
2913 == NULL) {
2914 return (-1);
2915 }
2916 memset(hp->assoc_tbl, 0, sizeof (EAssocList_t) * hp->assoc_count);
2917
2918 for (i = 0; i < hp->assoc_count; ++i) {
2919 fgets(buf, BUFSZ, fp);
2920 found = sscanf(buf, "%s %s", name1, name2);
2921 if (strcmp("ASSOCIATIONS_END", name1) == 0)
2922 break;
2923 if (found != 2) {
2924 errno = EINVAL;
2925 return (-1);
2926 }
2927 namep = (EStringId_t *)bsearch(name2, hp->othr_tbl,
2928 hp->othr_count, sizeof (EStringId_t),
2929 (int (*)(const void *, const void *))
2930 i_psvc_name_compare_bsearch);
2931 if (namep == NULL) {
2932 errno = EINVAL;
2933 return (-1);
2934 }
2935 id = namep->id;
2936
2937 status = i_psvc_count_records(fp, "ASSOCIATION_END", &count);
2938 if (status != PSVC_SUCCESS)
2939 return (status);
2940 hp->assoc_tbl[id].count = count;
2941 hp->assoc_tbl[id].table =
2942 (EAssoc_t *)malloc(sizeof (EAssoc_t) * count);
2943 if (hp->assoc_tbl[id].table == NULL)
2944 return (-1);
2945
2946 for (j = 0; j < count; ++j) {
2947 ap = &hp->assoc_tbl[id].table[j];
2948 fgets(buf, BUFSZ, fp);
2949 found = sscanf(buf, "%s %s", ap->antecedent_id,
2950 ap->dependent_id);
2951 ap->ant_key = psvc_get_str_key(ap->antecedent_id);
2952 if (found != 2) {
2953 errno = EINVAL;
2954 return (-1);
2955 }
2956 }
2957
2958
2959 fgets(buf, BUFSZ, fp);
2960 if (strncmp(buf, "ASSOCIATION_END", 15) != 0) {
2961 errno = EINVAL;
2962 return (-1);
2963 }
2964 }
2965
2966 return (0);
2967 }
2968
2969 /* Load the table of tables */
2970 static int32_t
i_psvc_load_tables(EHdl_t * hp,FILE * fp)2971 i_psvc_load_tables(EHdl_t *hp, FILE *fp)
2972 {
2973 int i, j;
2974 int found;
2975 int ret;
2976 int32_t cell_type;
2977 int64_t *table;
2978 char buf[BUFSZ];
2979 int32_t status;
2980 uint32_t table_count;
2981 int32_t num, key, array;
2982 char name[NAMELEN];
2983 ETable_Array *tbl_arr;
2984
2985 if (i_psvc_find_file_section(fp, "TABLES") != PSVC_SUCCESS)
2986 return (PSVC_SUCCESS); /* no tables */
2987 status = i_psvc_count_tables_associations(fp, &table_count,
2988 "TABLE_END");
2989 if (status != PSVC_SUCCESS || table_count == 0)
2990 return (status);
2991
2992 for (i = 0; i < table_count; ++i) {
2993 int slot;
2994 ETable_t *tblp;
2995
2996 fgets(buf, BUFSZ, fp);
2997 if (strncmp(buf, "TABLE", 5) != 0) {
2998 errno = EINVAL;
2999 return (-1);
3000 }
3001
3002 fgets(buf, BUFSZ, fp);
3003 found = sscanf(buf, "%s %d", name, &cell_type);
3004 key = psvc_get_str_key(name);
3005 array = key % PSVC_MAX_TABLE_ARRAYS;
3006 tbl_arr = &(hp->tbl_arry[array]);
3007
3008 if (tbl_arr->nextid == hp->total_obj_count) {
3009 errno = EINVAL;
3010 return (PSVC_FAILURE);
3011 } else {
3012 slot = tbl_arr->nextid++;
3013 tbl_arr->obj_count++;
3014 }
3015
3016 strcpy(tbl_arr->obj_tbl[slot].name, name);
3017
3018 tblp = (ETable_t *)malloc(sizeof (ETable_t));
3019 if (tblp == NULL)
3020 return (PSVC_FAILURE);
3021 tbl_arr->obj_tbl[slot].key = key;
3022 tbl_arr->obj_tbl[slot].objp = (EObj_t *)(void *)tblp;
3023 tbl_arr->obj_tbl[slot].type = PSVC_TBL;
3024
3025 status = i_psvc_count_table_records(fp, "TABLE_END",
3026 &tblp->size);
3027 if (status != PSVC_SUCCESS)
3028 return (status);
3029 tblp->cell_type = (uint8_t)cell_type;
3030 if (found != 2) {
3031 errno = EINVAL;
3032 return (-1);
3033 }
3034
3035 /* allocate and load table */
3036 tblp->table = (int64_t *)malloc(tblp->size *
3037 i_psvc_cell_size[tblp->cell_type]);
3038 if (tblp->table == NULL) {
3039 return (-1);
3040 }
3041
3042 table = tblp->table;
3043 for (j = 0; j < tblp->size; ++j) {
3044 switch (cell_type) {
3045 case 0:
3046 ret = fscanf(fp, "%d", &num);
3047 *((int8_t *)table + j) = num;
3048 break;
3049 case 1:
3050 ret = fscanf(fp, "%d", &num);
3051 *((uint8_t *)table + j) = (uint8_t)num;
3052 break;
3053 case 2:
3054 ret = fscanf(fp, "%hd",
3055 ((int16_t *)table + j));
3056 break;
3057 case 3:
3058 ret = fscanf(fp, "%hd",
3059 ((uint16_t *)table + j));
3060 break;
3061 case 4:
3062 ret = fscanf(fp, "%d",
3063 ((int32_t *)table + j));
3064 break;
3065 case 5:
3066 ret = fscanf(fp, "%d",
3067 ((uint32_t *)table + j));
3068 break;
3069 case 6:
3070 ret = fscanf(fp, "%lld",
3071 ((int64_t *)table + j));
3072 break;
3073 case 7:
3074 ret = fscanf(fp, "%lld",
3075 ((uint64_t *)table + j));
3076 break;
3077 default:
3078 errno = EINVAL;
3079 return (-1);
3080 }
3081 if (ret != 1) {
3082 errno = EINVAL;
3083 return (-1);
3084 }
3085 }
3086 fgets(buf, BUFSZ, fp); /* reads newline on data line */
3087 fgets(buf, BUFSZ, fp);
3088 if (strncmp(buf, "TABLE_END", 9) != 0) {
3089 errno = EINVAL;
3090 return (-1);
3091 }
3092
3093 }
3094
3095 return (0);
3096 }
3097
3098 static int32_t
i_psvc_destructor(EHdl_t * hdlp,char * name,void * objp)3099 i_psvc_destructor(EHdl_t *hdlp, char *name, void *objp)
3100 {
3101 int32_t i, key, array;
3102
3103 key = psvc_get_str_key(name);
3104 array = key % PSVC_MAX_TABLE_ARRAYS;
3105
3106 for (i = 0; i < hdlp->tbl_arry[array].obj_count; ++i) {
3107 if (key == hdlp->tbl_arry[array].obj_tbl[i].key) {
3108 if (strcmp(hdlp->tbl_arry[array].obj_tbl[i].name,
3109 name) == 0) {
3110 hdlp->tbl_arry[array].obj_tbl[i].name[0] = '\0';
3111 if (objp != NULL)
3112 free(objp);
3113 return (PSVC_SUCCESS);
3114 }
3115 }
3116 }
3117
3118 return (PSVC_SUCCESS);
3119 }
3120
3121 static int32_t
i_psvc_get_attr_generic(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3122 i_psvc_get_attr_generic(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id,
3123 void * attrp)
3124 {
3125 int32_t status = PSVC_SUCCESS;
3126 char *parent_id;
3127
3128 switch (attr_id) {
3129 case PSVC_ADDR_SPEC_ATTR:
3130 *(uint64_t *)attrp = objp->addr_spec;
3131 break;
3132 case PSVC_CLASS_ATTR:
3133 *(int32_t *)attrp = objp->class;
3134 break;
3135 case PSVC_SUBCLASS_ATTR:
3136 *(int32_t *)attrp = objp->subclass;
3137 break;
3138 case PSVC_PRESENCE_ATTR:
3139 status = i_psvc_get_presence(hdlp, objp, (boolean_t *)attrp);
3140 break;
3141 case PSVC_PREV_PRESENCE_ATTR:
3142 *(boolean_t *)attrp = objp->previous_presence;
3143 break;
3144 case PSVC_STATE_ATTR:
3145 strcpy((char *)attrp, objp->state);
3146 break;
3147 case PSVC_PREV_STATE_ATTR:
3148 strcpy((char *)attrp, objp->previous_state);
3149 break;
3150 case PSVC_ENABLE_ATTR:
3151 *(boolean_t *)attrp = objp->enabled;
3152 break;
3153 case PSVC_FAULTID_ATTR:
3154 strcpy((char *)attrp, objp->fault_id);
3155 break;
3156 case PSVC_FEATURES_ATTR:
3157 *(uint64_t *)attrp = objp->features;
3158 break;
3159 case PSVC_LABEL_ATTR:
3160 strcpy((char *)attrp, objp->label);
3161 break;
3162 case PSVC_FRUID_ATTR:
3163 while ((objp->features & PSVC_DEV_FRU) == 0) {
3164 status = i_psvc_get_assoc_id(hdlp, objp->label,
3165 PSVC_PARENT, 0, &parent_id);
3166 if (status != PSVC_SUCCESS)
3167 return (status);
3168
3169 status = i_psvc_get_obj(hdlp, parent_id, &objp);
3170 if (status != PSVC_SUCCESS)
3171 return (status);
3172 }
3173
3174 strcpy((char *)attrp, objp->label);
3175 break;
3176 case PSVC_INSTANCE_ATTR:
3177 *(int32_t *)attrp = objp->instance;
3178 break;
3179 default:
3180 errno = EINVAL;
3181 return (PSVC_FAILURE);
3182 }
3183
3184 return (status);
3185 }
3186
3187 static int32_t
i_psvc_set_attr_generic(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3188 i_psvc_set_attr_generic(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id,
3189 void * attrp)
3190 {
3191 int32_t status = PSVC_SUCCESS;
3192
3193 switch (attr_id) {
3194 case PSVC_PREV_PRESENCE_ATTR:
3195 objp->previous_presence = *(boolean_t *)attrp;
3196 break;
3197 case PSVC_STATE_ATTR:
3198 strcpy(objp->previous_state, objp->state);
3199 strcpy(objp->state, (char *)attrp);
3200 break;
3201 case PSVC_ENABLE_ATTR:
3202 objp->enabled = *(boolean_t *)attrp;
3203 break;
3204 case PSVC_FAULTID_ATTR:
3205 strcpy(objp->fault_id, (char *)attrp);
3206 break;
3207 default:
3208 errno = EINVAL;
3209 return (PSVC_FAILURE);
3210 }
3211 return (status);
3212 }
3213
3214 static int32_t
i_psvc_get_attr_0_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3215 i_psvc_get_attr_0_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3216 {
3217 int32_t status = PSVC_SUCCESS;
3218
3219 switch (attr_id) {
3220 case PSVC_SENSOR_VALUE_ATTR:
3221 return (i_psvc_get_device_value_0_0(hdlp, objp, attrp));
3222 case PSVC_LO_WARN_ATTR:
3223 *(int32_t *)attrp = ((ETempSensor_t *)objp)->lo_warn;
3224 return (status);
3225 case PSVC_LO_SHUT_ATTR:
3226 *(int32_t *)attrp = ((ETempSensor_t *)objp)->lo_shut;
3227 return (status);
3228 case PSVC_HI_WARN_ATTR:
3229 *(int32_t *)attrp = ((ETempSensor_t *)objp)->hi_warn;
3230 return (status);
3231 case PSVC_HI_SHUT_ATTR:
3232 *(int32_t *)attrp = ((ETempSensor_t *)objp)->hi_shut;
3233 return (status);
3234 }
3235
3236 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3237
3238 return (status);
3239 }
3240
3241 static int32_t
i_psvc_get_attr_0_1(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3242 i_psvc_get_attr_0_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3243 {
3244 int32_t status = PSVC_SUCCESS;
3245
3246 switch (attr_id) {
3247 case PSVC_SENSOR_VALUE_ATTR:
3248 return (i_psvc_get_device_value_0_1(hdlp, objp, attrp));
3249 case PSVC_LO_WARN_ATTR:
3250 *(int32_t *)attrp = ((ETempSensor_t *)objp)->lo_warn;
3251 return (status);
3252 case PSVC_LO_SHUT_ATTR:
3253 *(int32_t *)attrp = ((ETempSensor_t *)objp)->lo_shut;
3254 return (status);
3255 case PSVC_HI_WARN_ATTR:
3256 *(int32_t *)attrp = ((ETempSensor_t *)objp)->hi_warn;
3257 return (status);
3258 case PSVC_HI_SHUT_ATTR:
3259 *(int32_t *)attrp = ((ETempSensor_t *)objp)->hi_shut;
3260 return (status);
3261 case PSVC_OPTIMAL_TEMP_ATTR:
3262 *(int32_t *)attrp = ((ETempSensor_t *)objp)->opt_temp;
3263 return (status);
3264 case PSVC_HW_HI_SHUT_ATTR:
3265 *(int32_t *)attrp = ((ETempSensor_t *)objp)->hw_hi_shut;
3266 return (status);
3267 case PSVC_HW_LO_SHUT_ATTR:
3268 *(int32_t *)attrp = ((ETempSensor_t *)objp)->hw_lo_shut;
3269 return (status);
3270 }
3271
3272 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3273
3274 return (status);
3275 }
3276
3277 static int32_t
i_psvc_set_attr_0_1(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3278 i_psvc_set_attr_0_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3279 {
3280 int32_t status = PSVC_SUCCESS;
3281
3282 switch (attr_id) {
3283 case PSVC_LO_WARN_ATTR:
3284 ((ETempSensor_t *)objp)->lo_warn = *(int32_t *)attrp;
3285 return (status);
3286 case PSVC_LO_SHUT_ATTR:
3287 ((ETempSensor_t *)objp)->lo_shut = *(int32_t *)attrp;
3288 return (status);
3289 case PSVC_HI_WARN_ATTR:
3290 ((ETempSensor_t *)objp)->hi_warn = *(int32_t *)attrp;
3291 return (status);
3292 case PSVC_HI_SHUT_ATTR:
3293 ((ETempSensor_t *)objp)->hi_shut = *(int32_t *)attrp;
3294 return (status);
3295 case PSVC_OPTIMAL_TEMP_ATTR:
3296 ((ETempSensor_t *)objp)->opt_temp = *(int32_t *)attrp;
3297 return (status);
3298 case PSVC_HW_HI_SHUT_ATTR:
3299 ((ETempSensor_t *)objp)->hw_hi_shut = *(int32_t *)attrp;
3300 return (status);
3301 case PSVC_HW_LO_SHUT_ATTR:
3302 ((ETempSensor_t *)objp)->hw_lo_shut = *(int32_t *)attrp;
3303 return (status);
3304 }
3305
3306 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3307
3308 return (status);
3309 }
3310
3311 static int32_t
i_psvc_get_attr_1_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3312 i_psvc_get_attr_1_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3313 {
3314 int32_t status = PSVC_SUCCESS;
3315
3316 switch (attr_id) {
3317 case PSVC_SENSOR_VALUE_ATTR:
3318 return (i_psvc_get_device_value_1_0(hdlp, objp, attrp));
3319 case PSVC_SETPOINT_ATTR:
3320 *(int16_t *)attrp = ((EFan_t *)objp)->setpoint;
3321 return (status);
3322 case PSVC_HYSTERESIS_ATTR:
3323 *(int16_t *)attrp = ((EFan_t *)objp)->hysteresis;
3324 return (status);
3325 case PSVC_LOOPGAIN_ATTR:
3326 *(int16_t *)attrp = ((EFan_t *)objp)->loopgain;
3327 return (status);
3328 case PSVC_LOOPBIAS_ATTR:
3329 *(int16_t *)attrp = ((EFan_t *)objp)->loopbias;
3330 return (status);
3331 case PSVC_TEMP_DIFFERENTIAL_ATTR:
3332 memcpy(attrp, ((EFan_t *)objp)->temp_differential,
3333 sizeof (((EFan_t *)objp)->temp_differential));
3334 return (status);
3335 case PSVC_TEMP_DIFFERENTIAL_INDEX_ATTR:
3336 *(int16_t *)attrp = ((EFan_t *)objp)->temp_differential_index;
3337 return (status);
3338 }
3339
3340 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3341
3342 return (status);
3343 }
3344
3345 static int32_t
i_psvc_set_attr_1_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3346 i_psvc_set_attr_1_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3347 {
3348 int32_t status = PSVC_SUCCESS;
3349
3350 switch (attr_id) {
3351 case PSVC_TEMP_DIFFERENTIAL_ATTR:
3352 memcpy(((EFan_t *)objp)->temp_differential, attrp,
3353 sizeof (((EFan_t *)objp)->temp_differential));
3354 return (status);
3355 case PSVC_TEMP_DIFFERENTIAL_INDEX_ATTR:
3356 ((EFan_t *)objp)->temp_differential_index = *(int16_t *)attrp;
3357 return (status);
3358 case PSVC_SETPOINT_ATTR:
3359 ((EFan_t *)objp)->setpoint = *(int16_t *)attrp;
3360 return (status);
3361 }
3362
3363 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3364
3365 return (PSVC_SUCCESS);
3366 }
3367
3368 static int32_t
i_psvc_get_attr_2_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3369 i_psvc_get_attr_2_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3370 {
3371 int32_t status = PSVC_SUCCESS;
3372
3373 switch (attr_id) {
3374 case PSVC_LED_STATE_ATTR:
3375 case PSVC_STATE_ATTR:
3376 return (i_psvc_get_device_state_2_0(hdlp, objp, attrp));
3377 case PSVC_LED_COLOR_ATTR:
3378 strcpy((char *)attrp, ((ELed_t *)objp)->color);
3379 return (status);
3380 case PSVC_LIT_COUNT_ATTR:
3381 *(int16_t *)attrp = ((ELed_t *)objp)->lit_count;
3382 return (status);
3383 }
3384
3385 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3386
3387 return (status);
3388 }
3389
3390 static int32_t
i_psvc_set_attr_2_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3391 i_psvc_set_attr_2_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3392 {
3393 int32_t status = PSVC_SUCCESS;
3394
3395 switch (attr_id) {
3396 case PSVC_LED_STATE_ATTR:
3397 case PSVC_STATE_ATTR:
3398 return (i_psvc_set_device_state_2_0(hdlp, objp, attrp));
3399 }
3400
3401 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3402
3403 return (status);
3404 }
3405
3406 static int32_t
i_psvc_get_attr_2_1(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3407 i_psvc_get_attr_2_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3408 {
3409 int32_t status = PSVC_SUCCESS;
3410
3411 switch (attr_id) {
3412 case PSVC_LED_STATE_ATTR:
3413 case PSVC_STATE_ATTR:
3414 return (i_psvc_get_device_state_2_1(hdlp, objp, attrp));
3415 case PSVC_LED_COLOR_ATTR:
3416 strcpy((char *)attrp, ((ELed_t *)objp)->color);
3417 return (status);
3418 case PSVC_LIT_COUNT_ATTR:
3419 *(int16_t *)attrp = ((ELed_t *)objp)->lit_count;
3420 return (status);
3421 }
3422
3423 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3424
3425 return (status);
3426 }
3427
3428 static int32_t
i_psvc_set_attr_2_1(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3429 i_psvc_set_attr_2_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3430 {
3431 int32_t status = PSVC_SUCCESS;
3432
3433 switch (attr_id) {
3434 case PSVC_LED_STATE_ATTR:
3435 case PSVC_STATE_ATTR:
3436 return (i_psvc_set_device_state_2_1(hdlp, objp, attrp));
3437 }
3438
3439 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3440
3441 return (status);
3442 }
3443
3444 static int32_t
i_psvc_get_attr_2_2(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3445 i_psvc_get_attr_2_2(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3446 {
3447 int32_t status = PSVC_SUCCESS;
3448
3449 switch (attr_id) {
3450 case PSVC_LED_STATE_ATTR:
3451 case PSVC_STATE_ATTR:
3452 return (i_psvc_get_device_state_2_0(hdlp, objp, attrp));
3453 case PSVC_LED_COLOR_ATTR:
3454 strcpy((char *)attrp, ((ELed_t *)objp)->color);
3455 return (status);
3456 case PSVC_LIT_COUNT_ATTR:
3457 *(int16_t *)attrp = ((ELed_t *)objp)->lit_count;
3458 return (status);
3459 case PSVC_LED_IS_LOCATOR_ATTR:
3460 strcpy((char *)attrp, ((ELed_t *)objp)->is_locator);
3461 return (status);
3462 case PSVC_LED_LOCATOR_NAME_ATTR:
3463 strcpy((char *)attrp, ((ELed_t *)objp)->locator_name);
3464 return (status);
3465 }
3466
3467 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3468
3469 return (status);
3470 }
3471
3472 static int32_t
i_psvc_get_attr_4_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3473 i_psvc_get_attr_4_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3474 {
3475 int32_t status = PSVC_SUCCESS;
3476
3477 switch (attr_id) {
3478 case PSVC_SENSOR_VALUE_ATTR:
3479 return (i_psvc_get_device_value_4_0(hdlp, objp, attrp));
3480 case PSVC_LO_WARN_ATTR:
3481 *(int32_t *)attrp = ((EDigiSensor_t *)objp)->lo_warn;
3482 return (status);
3483 case PSVC_LO_SHUT_ATTR:
3484 *(int32_t *)attrp = ((EDigiSensor_t *)objp)->lo_shut;
3485 return (status);
3486 case PSVC_HI_WARN_ATTR:
3487 *(int32_t *)attrp = ((EDigiSensor_t *)objp)->hi_warn;
3488 return (status);
3489 case PSVC_HI_SHUT_ATTR:
3490 *(int32_t *)attrp = ((EDigiSensor_t *)objp)->hi_shut;
3491 return (status);
3492 }
3493
3494 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3495
3496 return (PSVC_SUCCESS);
3497 }
3498
3499 static int32_t
i_psvc_get_attr_5_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3500 i_psvc_get_attr_5_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3501 {
3502 int32_t status = PSVC_SUCCESS;
3503
3504 if (attr_id == PSVC_CONTROL_VALUE_ATTR) {
3505 return (i_psvc_get_device_value_5_0(hdlp, objp, attrp));
3506 }
3507
3508 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3509
3510 return (status);
3511 }
3512
3513 static int32_t
i_psvc_set_attr_5_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3514 i_psvc_set_attr_5_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3515 {
3516 int32_t status = PSVC_SUCCESS;
3517
3518 if (attr_id == PSVC_CONTROL_VALUE_ATTR) {
3519 return (i_psvc_set_device_value_5_0(hdlp, objp, attrp));
3520 }
3521
3522 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3523
3524 return (status);
3525 }
3526
3527 static int32_t
i_psvc_get_attr_6_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3528 i_psvc_get_attr_6_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3529 {
3530 int32_t status = PSVC_SUCCESS;
3531
3532 switch (attr_id) {
3533 case PSVC_GPIO_VALUE_ATTR:
3534 return (i_psvc_get_device_value_6_0(hdlp, objp, attrp));
3535 case PSVC_GPIO_BITS:
3536 *(int32_t *)attrp = 1;
3537 return (status);
3538 }
3539
3540 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3541
3542 return (status);
3543 }
3544
3545 static int32_t
i_psvc_set_attr_6_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3546 i_psvc_set_attr_6_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3547 {
3548 int32_t status = PSVC_SUCCESS;
3549
3550 if (attr_id == PSVC_GPIO_VALUE_ATTR) {
3551 return (i_psvc_set_device_value_6_0(hdlp, objp, attrp));
3552 }
3553
3554 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3555
3556 return (status);
3557 }
3558
3559 static int32_t
i_psvc_get_attr_7_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3560 i_psvc_get_attr_7_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3561 {
3562 int32_t status = PSVC_SUCCESS;
3563
3564 switch (attr_id) {
3565 case PSVC_SENSOR_VALUE_ATTR:
3566 return (i_psvc_get_device_value_7_0(hdlp, objp, attrp));
3567 case PSVC_LO_WARN_ATTR:
3568 *(int32_t *)attrp = ((EFanTach_t *)objp)->lo_warn;
3569 return (status);
3570 case PSVC_LO_SHUT_ATTR:
3571 *(int32_t *)attrp = ((EFanTach_t *)objp)->lo_shut;
3572 return (status);
3573 case PSVC_HI_WARN_ATTR:
3574 *(int32_t *)attrp = ((EFanTach_t *)objp)->hi_warn;
3575 return (status);
3576 case PSVC_HI_SHUT_ATTR:
3577 *(int32_t *)attrp = ((EFanTach_t *)objp)->hi_shut;
3578 return (status);
3579 }
3580
3581 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3582
3583 return (PSVC_SUCCESS);
3584 }
3585
3586 static int32_t
i_psvc_get_attr_8_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3587 i_psvc_get_attr_8_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3588 {
3589 int32_t status = PSVC_SUCCESS;
3590
3591 switch (attr_id) {
3592 case PSVC_SWITCH_STATE_ATTR:
3593 case PSVC_STATE_ATTR:
3594 return (i_psvc_get_device_state_8_0(hdlp, objp, attrp));
3595 }
3596
3597 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3598
3599 return (status);
3600 }
3601
3602 static int32_t
i_psvc_set_attr_8_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3603 i_psvc_set_attr_8_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3604 {
3605 int32_t status = PSVC_SUCCESS;
3606
3607 switch (attr_id) {
3608 case PSVC_SWITCH_STATE_ATTR:
3609 case PSVC_STATE_ATTR:
3610 return (i_psvc_set_device_state_8_0(hdlp, objp, attrp));
3611 }
3612
3613 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3614
3615 return (status);
3616 }
3617
3618 static int32_t
i_psvc_get_attr_9_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3619 i_psvc_get_attr_9_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3620 {
3621 int32_t status = PSVC_SUCCESS;
3622
3623 switch (attr_id) {
3624 case PSVC_SWITCH_STATE_ATTR:
3625 case PSVC_STATE_ATTR:
3626 status = i_psvc_get_device_state_9_0(hdlp, objp, attrp);
3627 if ((status == PSVC_FAILURE) && (errno == EINVAL)) {
3628 strcpy((char *)attrp, PSVC_ERROR);
3629 return (PSVC_SUCCESS);
3630 } else {
3631 return (status);
3632 }
3633 }
3634
3635 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3636
3637 return (status);
3638 }
3639
3640 static int32_t
i_psvc_get_attr_10_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3641 i_psvc_get_attr_10_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3642 {
3643 int32_t status = PSVC_SUCCESS;
3644
3645 switch (attr_id) {
3646 case PSVC_GPIO_VALUE_ATTR:
3647 return (i_psvc_get_device_value_10_0(hdlp, objp, attrp));
3648 case PSVC_GPIO_BITS:
3649 *(int32_t *)attrp = 8;
3650 return (status);
3651 }
3652
3653 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3654
3655 return (status);
3656 }
3657
3658 static int32_t
i_psvc_set_attr_10_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3659 i_psvc_set_attr_10_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3660 {
3661 int32_t status = PSVC_SUCCESS;
3662
3663 if (attr_id == PSVC_GPIO_VALUE_ATTR) {
3664 return (i_psvc_set_device_value_10_0(hdlp, objp, attrp));
3665 }
3666
3667 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3668
3669 return (status);
3670 }
3671
3672 static int32_t
i_psvc_get_attr_10_1(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3673 i_psvc_get_attr_10_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3674 {
3675 int32_t status = PSVC_SUCCESS;
3676
3677 switch (attr_id) {
3678 case PSVC_GPIO_VALUE_ATTR:
3679 return (i_psvc_get_device_value_10_1(hdlp, objp, attrp));
3680 case PSVC_GPIO_BITS:
3681 *(int32_t *)attrp = 8;
3682 return (status);
3683 }
3684
3685 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3686
3687 return (status);
3688 }
3689
3690 static int32_t
i_psvc_set_attr_10_1(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3691 i_psvc_set_attr_10_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3692 {
3693 int32_t status = PSVC_SUCCESS;
3694
3695 if (attr_id == PSVC_GPIO_VALUE_ATTR) {
3696 return (i_psvc_set_device_value_10_1(hdlp, objp, attrp));
3697 }
3698
3699 status = i_psvc_set_attr_generic(hdlp, objp, attr_id, attrp);
3700
3701 return (status);
3702 }
3703
3704 /* AT24 */
3705 static int32_t
i_psvc_get_attr_11_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3706 i_psvc_get_attr_11_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3707 {
3708 int32_t status = PSVC_SUCCESS;
3709 int32_t probe_status;
3710
3711 switch (attr_id) {
3712 case PSVC_PROBE_RESULT_ATTR:
3713 probe_status = i_psvc_probe_11_0(hdlp, objp);
3714 if (probe_status == PSVC_SUCCESS)
3715 strcpy((char *)attrp, PSVC_OK);
3716 else
3717 strcpy((char *)attrp, PSVC_ERROR);
3718 return (status);
3719 case PSVC_FRU_INFO_ATTR:
3720 status = i_psvc_get_reg_11_0(hdlp, objp, attr_id, attrp);
3721 return (status);
3722 }
3723
3724 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3725
3726 return (status);
3727 }
3728
3729 static int32_t
i_psvc_get_reg_11_0(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3730 i_psvc_get_reg_11_0(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3731 {
3732 int32_t status = PSVC_SUCCESS, ret;
3733 char path[1024], *data;
3734 int32_t fp, temp_errno;
3735 fru_info_t *fru_data;
3736
3737 fru_data = (fru_info_t *)attrp;
3738
3739 if (objp->present != PSVC_PRESENT) {
3740 errno = ENODEV;
3741 return (PSVC_FAILURE);
3742 }
3743
3744 status = i_psvc_get_devpath(hdlp, objp->addr_spec, path);
3745 if (status != PSVC_SUCCESS)
3746 return (status);
3747
3748 fp = open(path, O_RDWR);
3749 if (fp == -1) {
3750 return (PSVC_FAILURE);
3751 }
3752
3753 ret = lseek(fp, fru_data->buf_start, SEEK_SET);
3754 if (ret != fru_data->buf_start) {
3755 temp_errno = errno;
3756 close(fp);
3757 errno = temp_errno;
3758 return (PSVC_FAILURE);
3759 }
3760
3761 data = (char *)malloc(fru_data->read_size);
3762 ret = read(fp, data, fru_data->read_size);
3763 if (ret == -1) {
3764 free(data);
3765 close(fp);
3766 errno = EIO;
3767 return (-1);
3768 }
3769
3770 memcpy(fru_data->buf, data, fru_data->read_size);
3771 free(data);
3772 close(fp);
3773
3774 return (status);
3775 }
3776
3777 static int32_t
i_psvc_get_attr_11_1(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3778 i_psvc_get_attr_11_1(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3779 {
3780 int32_t status = PSVC_SUCCESS;
3781 int32_t probe_status;
3782
3783 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3784 probe_status = i_psvc_probe_11_1(hdlp, objp);
3785 if (probe_status == PSVC_SUCCESS)
3786 strcpy((char *)attrp, PSVC_OK);
3787 else
3788 strcpy((char *)attrp, PSVC_ERROR);
3789 return (status);
3790 }
3791
3792 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3793
3794 return (status);
3795 }
3796
3797 static int32_t
i_psvc_get_attr_11_2(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3798 i_psvc_get_attr_11_2(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3799 {
3800 int32_t status = PSVC_SUCCESS;
3801 int32_t probe_status;
3802
3803 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3804 probe_status = i_psvc_probe_11_2(hdlp, objp);
3805 if (probe_status == PSVC_SUCCESS)
3806 strcpy((char *)attrp, PSVC_OK);
3807 else
3808 strcpy((char *)attrp, PSVC_ERROR);
3809 return (status);
3810 }
3811
3812 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3813
3814 return (status);
3815 }
3816
3817 static int32_t
i_psvc_get_attr_11_3(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3818 i_psvc_get_attr_11_3(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3819 {
3820 int32_t status = PSVC_SUCCESS;
3821 int32_t probe_status;
3822
3823 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3824 probe_status = i_psvc_probe_11_3(hdlp, objp);
3825 if (probe_status == PSVC_SUCCESS)
3826 strcpy((char *)attrp, PSVC_OK);
3827 else
3828 strcpy((char *)attrp, PSVC_ERROR);
3829 return (status);
3830 }
3831
3832 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3833
3834 return (status);
3835 }
3836
3837 static int32_t
i_psvc_get_attr_11_4(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3838 i_psvc_get_attr_11_4(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3839 {
3840 int32_t status = PSVC_SUCCESS;
3841 int32_t probe_status;
3842
3843 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3844 probe_status = i_psvc_probe_11_4(hdlp, objp);
3845 if (probe_status == PSVC_SUCCESS)
3846 strcpy((char *)attrp, PSVC_OK);
3847 else
3848 strcpy((char *)attrp, PSVC_ERROR);
3849 return (status);
3850 }
3851
3852 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3853
3854 return (status);
3855 }
3856
3857 static int32_t
i_psvc_get_attr_11_5(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3858 i_psvc_get_attr_11_5(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3859 {
3860 int32_t status = PSVC_SUCCESS;
3861 int32_t probe_status;
3862
3863 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3864 probe_status = i_psvc_probe_11_5(hdlp, objp);
3865 if (probe_status == PSVC_SUCCESS)
3866 strcpy((char *)attrp, PSVC_OK);
3867 else
3868 strcpy((char *)attrp, PSVC_ERROR);
3869 return (status);
3870 }
3871
3872 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3873
3874 return (status);
3875 }
3876
3877 static int32_t
i_psvc_get_attr_11_6(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3878 i_psvc_get_attr_11_6(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3879 {
3880 int32_t status = PSVC_SUCCESS;
3881 int32_t probe_status;
3882
3883 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3884 probe_status = i_psvc_probe_11_6(hdlp, objp);
3885 if (probe_status == PSVC_SUCCESS)
3886 strcpy((char *)attrp, PSVC_OK);
3887 else
3888 strcpy((char *)attrp, PSVC_ERROR);
3889 return (status);
3890 }
3891
3892 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3893
3894 return (status);
3895 }
3896
3897 static int32_t
i_psvc_get_attr_11_7(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3898 i_psvc_get_attr_11_7(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3899 {
3900 int32_t status = PSVC_SUCCESS;
3901 int32_t probe_status;
3902
3903 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3904 probe_status = i_psvc_probe_11_7(hdlp, objp);
3905 if (probe_status == PSVC_SUCCESS)
3906 strcpy((char *)attrp, PSVC_OK);
3907 else
3908 strcpy((char *)attrp, PSVC_ERROR);
3909 return (status);
3910 }
3911
3912 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3913
3914 return (status);
3915 }
3916
3917 static int32_t
i_psvc_get_attr_11_8(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3918 i_psvc_get_attr_11_8(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3919 {
3920 int32_t status = PSVC_SUCCESS;
3921 int32_t probe_status;
3922
3923 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3924 probe_status = i_psvc_probe_11_8(hdlp, objp);
3925 if (probe_status == PSVC_SUCCESS)
3926 strcpy((char *)attrp, PSVC_OK);
3927 else
3928 strcpy((char *)attrp, PSVC_ERROR);
3929 return (status);
3930 }
3931
3932 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3933
3934 return (status);
3935 }
3936
3937 static int32_t
i_psvc_get_attr_11_9(EHdl_t * hdlp,EObj_t * objp,int32_t attr_id,void * attrp)3938 i_psvc_get_attr_11_9(EHdl_t *hdlp, EObj_t *objp, int32_t attr_id, void *attrp)
3939 {
3940 int32_t status = PSVC_SUCCESS;
3941 int32_t probe_status;
3942
3943 if (attr_id == PSVC_PROBE_RESULT_ATTR) {
3944 probe_status = i_psvc_probe_11_9(hdlp, objp);
3945 if (probe_status == PSVC_SUCCESS)
3946 strcpy((char *)attrp, PSVC_OK);
3947 else
3948 strcpy((char *)attrp, PSVC_ERROR);
3949 return (status);
3950 }
3951
3952 status = i_psvc_get_attr_generic(hdlp, objp, attr_id, attrp);
3953
3954 return (status);
3955 }
3956
3957 static int32_t
i_psvc_load_generic(EHdl_t * hdlp,char * name,EObj_t ** objpp,char * buf,int32_t obj_size)3958 i_psvc_load_generic(
3959 EHdl_t *hdlp,
3960 char *name,
3961 EObj_t **objpp,
3962 char *buf,
3963 int32_t obj_size)
3964 {
3965 int32_t found, key, array;
3966 EObj_t *objp;
3967 char *start;
3968 char cur_device[NAMELEN];
3969 int slot;
3970 ETable_Array *tbl_arr;
3971
3972 key = psvc_get_str_key(name);
3973 array = key % PSVC_MAX_TABLE_ARRAYS;
3974 tbl_arr = &(hdlp->tbl_arry[array]);
3975
3976 if (tbl_arr->nextid == hdlp->total_obj_count) {
3977 errno = EINVAL;
3978 return (PSVC_FAILURE);
3979 } else {
3980 slot = tbl_arr->nextid++;
3981 tbl_arr->obj_count++;
3982 }
3983
3984 if (i_psvc_find_file_section(hdlp->fp, "OBJECT_INFO") != PSVC_SUCCESS)
3985 return (PSVC_FAILURE);
3986
3987 fgets(buf, BUFSZ, hdlp->fp);
3988 while (strcmp(buf, "OBJECT_INFO_END")) {
3989 start = strrchr(buf, '/');
3990 if (start == NULL) {
3991 errno = EINVAL;
3992 return (PSVC_FAILURE);
3993 }
3994 found = sscanf(start + 1, "%s", cur_device);
3995 if (found != 1) {
3996 errno = EINVAL;
3997 return (PSVC_FAILURE);
3998 }
3999 if (strcmp(name, cur_device) == 0) /* found it */
4000 break;
4001 fgets(buf, BUFSZ, hdlp->fp);
4002 }
4003
4004 tbl_arr->obj_tbl[slot].objp = (EObj_t *)malloc(obj_size);
4005 if (tbl_arr->obj_tbl[slot].objp == 0)
4006 return (PSVC_FAILURE);
4007 objp = (EObj_t *)tbl_arr->obj_tbl[slot].objp;
4008 tbl_arr->obj_tbl[slot].type = PSVC_OBJ;
4009
4010 memset(objp, 0, obj_size);
4011 strcpy(objp->label, name);
4012 strcpy(tbl_arr->obj_tbl[slot].name, name);
4013
4014 tbl_arr->obj_tbl[slot].key = key;
4015
4016 if (i_psvc_value(buf, PSVC_CLASS_ATTR, &objp->class) != PSVC_SUCCESS) {
4017 i_psvc_destructor(hdlp, name, objp);
4018 return (PSVC_FAILURE);
4019 }
4020 if (i_psvc_value(buf, PSVC_SUBCLASS_ATTR, &objp->subclass) !=
4021 PSVC_SUCCESS) {
4022 i_psvc_destructor(hdlp, name, objp);
4023 return (PSVC_FAILURE);
4024 }
4025 if (i_psvc_value(buf, PSVC_INSTANCE_ATTR, &objp->instance) !=
4026 PSVC_SUCCESS) {
4027 i_psvc_destructor(hdlp, name, objp);
4028 return (PSVC_FAILURE);
4029 }
4030 if (i_psvc_value(buf, PSVC_FEATURES_ATTR, &objp->features) !=
4031 PSVC_SUCCESS) {
4032 i_psvc_destructor(hdlp, name, objp);
4033 return (PSVC_FAILURE);
4034 }
4035 if (i_psvc_value(buf, PSVC_ADDR_SPEC_ATTR, &objp->addr_spec) !=
4036 PSVC_SUCCESS) {
4037 i_psvc_destructor(hdlp, name, objp);
4038 return (PSVC_FAILURE);
4039 }
4040
4041 if (objp->features & PSVC_DEV_SECONDARY)
4042 objp->enabled = PSVC_DISABLED;
4043 else
4044 objp->enabled = PSVC_ENABLED;
4045
4046 if (PSVC_GET_VERSION(objp->addr_spec) > PSVC_VERSION) {
4047 errno = EINVAL;
4048 i_psvc_destructor(hdlp, name, objp);
4049 return (PSVC_FAILURE);
4050 }
4051
4052 *objpp = objp;
4053 return (PSVC_SUCCESS);
4054
4055 }
4056
4057
4058 static int32_t
i_psvc_not_supported()4059 i_psvc_not_supported()
4060 {
4061 errno = ENOTSUP;
4062 return (PSVC_FAILURE);
4063 }
4064
4065 /* Temperature sensor */
4066 /* Class 0 Subclass 0 are temperature sensors that cannot be updated */
4067 static int32_t
i_psvc_constructor_0_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)4068 i_psvc_constructor_0_0(
4069 EHdl_t *hdlp,
4070 char *id,
4071 EObj_t **objpp)
4072 {
4073 int32_t status;
4074 char buf[BUFSZ];
4075 ETempSensor_t *dp;
4076
4077 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4078 sizeof (ETempSensor_t));
4079 if (status != PSVC_SUCCESS)
4080 return (status);
4081
4082 /* Load class specific info */
4083 dp = (ETempSensor_t *)*objpp;
4084 if (i_psvc_value(buf, PSVC_LO_WARN_ATTR, &dp->lo_warn)
4085 != PSVC_SUCCESS) {
4086 i_psvc_destructor(hdlp, id, dp);
4087 return (PSVC_FAILURE);
4088 }
4089 if (i_psvc_value(buf, PSVC_LO_SHUT_ATTR, &dp->lo_shut)
4090 != PSVC_SUCCESS) {
4091 i_psvc_destructor(hdlp, id, dp);
4092 return (PSVC_FAILURE);
4093 }
4094 if (i_psvc_value(buf, PSVC_HI_WARN_ATTR, &dp->hi_warn)
4095 != PSVC_SUCCESS) {
4096 i_psvc_destructor(hdlp, id, dp);
4097 return (PSVC_FAILURE);
4098 }
4099 if (i_psvc_value(buf, PSVC_HI_SHUT_ATTR, &dp->hi_shut)
4100 != PSVC_SUCCESS) {
4101 i_psvc_destructor(hdlp, id, dp);
4102 return (PSVC_FAILURE);
4103 }
4104
4105 dp->ld.constructor = i_psvc_constructor_0_0;
4106 dp->ld.destructor = i_psvc_destructor;
4107 dp->ld.get_attr = i_psvc_get_attr_0_0;
4108 dp->ld.set_attr = i_psvc_set_attr_generic;
4109
4110 return (0);
4111 }
4112
4113 /* Class 0 Subclass 1 are temperature sensors that can be updated */
4114 static int32_t
i_psvc_constructor_0_1(EHdl_t * hdlp,char * id,EObj_t ** objpp)4115 i_psvc_constructor_0_1(
4116 EHdl_t *hdlp,
4117 char *id,
4118 EObj_t **objpp)
4119 {
4120 int32_t status;
4121 char buf[BUFSZ];
4122 ETempSensor_t *dp;
4123
4124 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4125 sizeof (ETempSensor_t));
4126 if (status != PSVC_SUCCESS)
4127 return (status);
4128
4129 /* Load class specific info */
4130 dp = (ETempSensor_t *)*objpp;
4131 if (i_psvc_value(buf, PSVC_LO_WARN_ATTR, &dp->lo_warn)
4132 != PSVC_SUCCESS) {
4133 i_psvc_destructor(hdlp, id, dp);
4134 return (PSVC_FAILURE);
4135 }
4136 if (i_psvc_value(buf, PSVC_LO_SHUT_ATTR, &dp->lo_shut)
4137 != PSVC_SUCCESS) {
4138 i_psvc_destructor(hdlp, id, dp);
4139 return (PSVC_FAILURE);
4140 }
4141 if (i_psvc_value(buf, PSVC_HI_WARN_ATTR, &dp->hi_warn)
4142 != PSVC_SUCCESS) {
4143 i_psvc_destructor(hdlp, id, dp);
4144 return (PSVC_FAILURE);
4145 }
4146 if (i_psvc_value(buf, PSVC_HI_SHUT_ATTR, &dp->hi_shut)
4147 != PSVC_SUCCESS) {
4148 i_psvc_destructor(hdlp, id, dp);
4149 return (PSVC_FAILURE);
4150 }
4151
4152 if ((*objpp)->features & PSVC_OPT_TEMP) {
4153 if (i_psvc_value(buf, PSVC_OPTIMAL_TEMP_ATTR, &dp->opt_temp)
4154 != PSVC_SUCCESS) {
4155 i_psvc_destructor(hdlp, id, dp);
4156 return (PSVC_FAILURE);
4157 }
4158 }
4159 if ((*objpp)->features & PSVC_HW_LOW_SHUT) {
4160 if (i_psvc_value(buf, PSVC_HW_LO_SHUT_ATTR, &dp->hw_lo_shut)
4161 != PSVC_SUCCESS) {
4162 i_psvc_destructor(hdlp, id, dp);
4163 return (PSVC_FAILURE);
4164 }
4165 }
4166 if ((*objpp)->features & PSVC_HW_HIGH_SHUT) {
4167 if (i_psvc_value(buf, PSVC_HW_HI_SHUT_ATTR, &dp->hw_hi_shut)
4168 != PSVC_SUCCESS) {
4169 i_psvc_destructor(hdlp, id, dp);
4170 return (PSVC_FAILURE);
4171 }
4172 }
4173
4174 dp->ld.constructor = i_psvc_constructor_0_1;
4175 dp->ld.destructor = i_psvc_destructor;
4176 dp->ld.get_attr = i_psvc_get_attr_0_1;
4177 dp->ld.set_attr = i_psvc_set_attr_0_1;
4178
4179 return (0);
4180 }
4181
4182 /* Fan */
4183 static int32_t
i_psvc_constructor_1_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)4184 i_psvc_constructor_1_0(
4185 EHdl_t *hdlp,
4186 char *id,
4187 EObj_t **objpp)
4188 {
4189 int32_t status;
4190 char buf[BUFSZ];
4191 EFan_t *dp;
4192
4193 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4194 sizeof (EFan_t));
4195 if (status != PSVC_SUCCESS)
4196 return (status);
4197
4198 /* Load class specific info */
4199 dp = (EFan_t *)*objpp;
4200 if (i_psvc_value(buf, PSVC_SETPOINT_ATTR, &dp->setpoint)
4201 != PSVC_SUCCESS) {
4202 i_psvc_destructor(hdlp, id, dp);
4203 return (PSVC_FAILURE);
4204 }
4205 if (i_psvc_value(buf, PSVC_HYSTERESIS_ATTR, &dp->hysteresis)
4206 != PSVC_SUCCESS) {
4207 i_psvc_destructor(hdlp, id, dp);
4208 return (PSVC_FAILURE);
4209 }
4210 if (i_psvc_value(buf, PSVC_LOOPGAIN_ATTR, &dp->loopgain)
4211 != PSVC_SUCCESS) {
4212 i_psvc_destructor(hdlp, id, dp);
4213 return (PSVC_FAILURE);
4214 }
4215 if (i_psvc_value(buf, PSVC_LOOPBIAS_ATTR, &dp->loopbias)
4216 != PSVC_SUCCESS) {
4217 i_psvc_destructor(hdlp, id, dp);
4218 return (PSVC_FAILURE);
4219 }
4220
4221 dp->ld.constructor = i_psvc_constructor_1_0;
4222 dp->ld.destructor = i_psvc_destructor;
4223 dp->ld.get_attr = i_psvc_get_attr_1_0;
4224 dp->ld.set_attr = i_psvc_set_attr_1_0;
4225
4226 return (PSVC_SUCCESS);
4227 }
4228
4229
4230 /* LED */
4231 static int32_t
i_psvc_constructor_2_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)4232 i_psvc_constructor_2_0(
4233 EHdl_t *hdlp,
4234 char *id,
4235 EObj_t **objpp)
4236 {
4237 int32_t status;
4238 char buf[BUFSZ];
4239 ELed_t *dp;
4240
4241 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4242 sizeof (ELed_t));
4243 if (status != PSVC_SUCCESS)
4244 return (status);
4245
4246 /* Load class specific info */
4247 dp = (ELed_t *)*objpp;
4248
4249 if (i_psvc_value(buf, PSVC_LED_COLOR_ATTR, dp->color)
4250 != PSVC_SUCCESS) {
4251 i_psvc_destructor(hdlp, id, dp);
4252 return (PSVC_FAILURE);
4253 }
4254
4255 dp->ld.constructor = i_psvc_constructor_2_0;
4256 dp->ld.destructor = i_psvc_destructor;
4257 dp->ld.get_attr = i_psvc_get_attr_2_0;
4258 dp->ld.set_attr = i_psvc_set_attr_2_0;
4259
4260 return (PSVC_SUCCESS);
4261 }
4262
4263 static int32_t
i_psvc_constructor_2_1(EHdl_t * hdlp,char * id,EObj_t ** objpp)4264 i_psvc_constructor_2_1(
4265 EHdl_t *hdlp,
4266 char *id,
4267 EObj_t **objpp)
4268 {
4269 int32_t status;
4270 char buf[BUFSZ];
4271 ELed_t *dp;
4272
4273 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4274 sizeof (ELed_t));
4275 if (status != PSVC_SUCCESS)
4276 return (status);
4277
4278 /* Load class specific info */
4279 dp = (ELed_t *)*objpp;
4280
4281 if (i_psvc_value(buf, PSVC_LED_COLOR_ATTR, dp->color)
4282 != PSVC_SUCCESS) {
4283 i_psvc_destructor(hdlp, id, dp);
4284 return (PSVC_FAILURE);
4285 }
4286
4287 dp->ld.constructor = i_psvc_constructor_2_1;
4288 dp->ld.destructor = i_psvc_destructor;
4289 dp->ld.get_attr = i_psvc_get_attr_2_1;
4290 dp->ld.set_attr = i_psvc_set_attr_2_1;
4291
4292 return (PSVC_SUCCESS);
4293 }
4294
4295 static int32_t
i_psvc_constructor_2_2(EHdl_t * hdlp,char * id,EObj_t ** objpp)4296 i_psvc_constructor_2_2(
4297 EHdl_t *hdlp,
4298 char *id,
4299 EObj_t **objpp)
4300 {
4301 int32_t status;
4302 char buf[BUFSZ];
4303 ELed_t *dp;
4304
4305 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4306 sizeof (ELed_t));
4307 if (status != PSVC_SUCCESS)
4308 return (status);
4309
4310 /* Load class specific info */
4311 dp = (ELed_t *)*objpp;
4312
4313 if (i_psvc_value(buf, PSVC_LED_COLOR_ATTR, dp->color)
4314 != PSVC_SUCCESS) {
4315 i_psvc_destructor(hdlp, id, dp);
4316 return (PSVC_FAILURE);
4317 }
4318 if (i_psvc_value(buf, PSVC_LED_IS_LOCATOR_ATTR, dp->is_locator)
4319 != PSVC_SUCCESS) {
4320 i_psvc_destructor(hdlp, id, dp);
4321 return (PSVC_FAILURE);
4322 }
4323 if (strcmp(dp->is_locator, PSVC_LOCATOR_TRUE) == 0) {
4324 if (i_psvc_value(buf, PSVC_LED_LOCATOR_NAME_ATTR,
4325 dp->locator_name) != PSVC_SUCCESS) {
4326 i_psvc_destructor(hdlp, id, dp);
4327 return (PSVC_FAILURE);
4328 }
4329 } else {
4330 strcpy(dp->locator_name, "N/A");
4331 }
4332
4333 dp->ld.constructor = i_psvc_constructor_2_2;
4334 dp->ld.destructor = i_psvc_destructor;
4335 dp->ld.get_attr = i_psvc_get_attr_2_2;
4336 dp->ld.set_attr = i_psvc_set_attr_2_0;
4337
4338 return (PSVC_SUCCESS);
4339 }
4340
4341 /* System Device */
4342 static int32_t
i_psvc_constructor_3_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)4343 i_psvc_constructor_3_0(
4344 EHdl_t *hdlp,
4345 char *id,
4346 EObj_t **objpp)
4347 {
4348 int32_t status;
4349 char buf[BUFSZ];
4350 ESystem_t *dp;
4351
4352 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (ESystem_t));
4353 if (status != PSVC_SUCCESS)
4354 return (status);
4355
4356 /* Load class specific info */
4357 dp = (ESystem_t *)*objpp;
4358
4359 dp->ld.constructor = i_psvc_constructor_3_0;
4360 dp->ld.destructor = i_psvc_destructor;
4361 dp->ld.get_attr = i_psvc_get_attr_generic;
4362 dp->ld.set_attr = i_psvc_set_attr_generic;
4363
4364 return (PSVC_SUCCESS);
4365 }
4366
4367 /* Digital Sensor */
4368 static int32_t
i_psvc_constructor_4_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)4369 i_psvc_constructor_4_0(
4370 EHdl_t *hdlp,
4371 char *id,
4372 EObj_t **objpp)
4373 {
4374 int32_t status;
4375 char buf[BUFSZ];
4376 EDigiSensor_t *dp;
4377
4378 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4379 sizeof (EDigiSensor_t));
4380 if (status != PSVC_SUCCESS) {
4381 return (status);
4382 }
4383
4384 /* Load class specific info */
4385 dp = (EDigiSensor_t *)*objpp;
4386 if (i_psvc_value(buf, PSVC_LO_WARN_ATTR, &dp->lo_warn)
4387 != PSVC_SUCCESS) {
4388 i_psvc_destructor(hdlp, id, dp);
4389 return (PSVC_FAILURE);
4390 }
4391 if (i_psvc_value(buf, PSVC_LO_SHUT_ATTR, &dp->lo_shut)
4392 != PSVC_SUCCESS) {
4393 i_psvc_destructor(hdlp, id, dp);
4394 return (PSVC_FAILURE);
4395 }
4396 if (i_psvc_value(buf, PSVC_HI_WARN_ATTR, &dp->hi_warn)
4397 != PSVC_SUCCESS) {
4398 i_psvc_destructor(hdlp, id, dp);
4399 return (PSVC_FAILURE);
4400 }
4401 if (i_psvc_value(buf, PSVC_HI_SHUT_ATTR, &dp->hi_shut)
4402 != PSVC_SUCCESS) {
4403 i_psvc_destructor(hdlp, id, dp);
4404 return (PSVC_FAILURE);
4405 }
4406
4407 dp->ld.constructor = i_psvc_constructor_4_0;
4408 dp->ld.destructor = i_psvc_destructor;
4409 dp->ld.get_attr = i_psvc_get_attr_4_0;
4410 dp->ld.set_attr = i_psvc_set_attr_generic;
4411
4412 return (PSVC_SUCCESS);
4413 }
4414
4415 /* Digital Control */
4416 static int32_t
i_psvc_constructor_5_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)4417 i_psvc_constructor_5_0(
4418 EHdl_t *hdlp,
4419 char *id,
4420 EObj_t **objpp)
4421 {
4422 int32_t status;
4423 char buf[BUFSZ];
4424 EDigiControl_t *dp;
4425
4426 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4427 sizeof (EDigiControl_t));
4428 if (status != PSVC_SUCCESS)
4429 return (status);
4430
4431 /* Load class specific info */
4432 dp = (EDigiControl_t *)*objpp;
4433
4434 dp->ld.constructor = i_psvc_constructor_5_0;
4435 dp->ld.destructor = i_psvc_destructor;
4436 dp->ld.get_attr = i_psvc_get_attr_5_0;
4437 dp->ld.set_attr = i_psvc_set_attr_5_0;
4438 return (PSVC_SUCCESS);
4439 }
4440
4441 /* Boolean GPIO */
4442 static int32_t
i_psvc_constructor_6_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)4443 i_psvc_constructor_6_0(
4444 EHdl_t *hdlp,
4445 char *id,
4446 EObj_t **objpp)
4447 {
4448 int32_t status;
4449 char buf[BUFSZ];
4450 EBoolSensor_t *dp;
4451
4452 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4453 sizeof (EBoolSensor_t));
4454 if (status != PSVC_SUCCESS)
4455 return (status);
4456
4457 /* Load class specific info */
4458 dp = (EBoolSensor_t *)*objpp;
4459
4460 dp->ld.constructor = i_psvc_constructor_6_0;
4461 dp->ld.destructor = i_psvc_destructor;
4462 dp->ld.get_attr = i_psvc_get_attr_6_0;
4463 dp->ld.set_attr = i_psvc_set_attr_6_0;
4464
4465 return (PSVC_SUCCESS);
4466 }
4467
4468 /* Fan Tachometer */
4469 static int32_t
i_psvc_constructor_7_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)4470 i_psvc_constructor_7_0(
4471 EHdl_t *hdlp,
4472 char *id,
4473 EObj_t **objpp)
4474 {
4475 int32_t status;
4476 char buf[BUFSZ];
4477 EFanTach_t *dp;
4478
4479 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4480 sizeof (EFanTach_t));
4481 if (status != PSVC_SUCCESS)
4482 return (status);
4483
4484 /* Load class specific info */
4485 dp = (EFanTach_t *)*objpp;
4486 if (i_psvc_value(buf, PSVC_LO_WARN_ATTR, &dp->lo_warn)
4487 != PSVC_SUCCESS) {
4488 i_psvc_destructor(hdlp, id, dp);
4489 return (PSVC_FAILURE);
4490 }
4491 if (i_psvc_value(buf, PSVC_LO_SHUT_ATTR, &dp->lo_shut)
4492 != PSVC_SUCCESS) {
4493 i_psvc_destructor(hdlp, id, dp);
4494 return (PSVC_FAILURE);
4495 }
4496 if (i_psvc_value(buf, PSVC_HI_WARN_ATTR, &dp->hi_warn)
4497 != PSVC_SUCCESS) {
4498 i_psvc_destructor(hdlp, id, dp);
4499 return (PSVC_FAILURE);
4500 }
4501 if (i_psvc_value(buf, PSVC_HI_SHUT_ATTR, &dp->hi_shut)
4502 != PSVC_SUCCESS) {
4503 i_psvc_destructor(hdlp, id, dp);
4504 return (PSVC_FAILURE);
4505 }
4506
4507 dp->ld.constructor = i_psvc_constructor_7_0;
4508 dp->ld.destructor = i_psvc_destructor;
4509 dp->ld.get_attr = i_psvc_get_attr_7_0;
4510 dp->ld.set_attr = i_psvc_set_attr_generic;
4511
4512 return (PSVC_SUCCESS);
4513 }
4514
4515 /* On Off Switch */
4516 static int32_t
i_psvc_constructor_8_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)4517 i_psvc_constructor_8_0(
4518 EHdl_t *hdlp,
4519 char *id,
4520 EObj_t **objpp)
4521 {
4522 int32_t status;
4523 char buf[BUFSZ];
4524 ESwitch_t *dp;
4525
4526 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4527 sizeof (ESwitch_t));
4528 if (status != PSVC_SUCCESS)
4529 return (status);
4530
4531 /* Load class specific info */
4532 dp = (ESwitch_t *)*objpp;
4533
4534 dp->ld.constructor = i_psvc_constructor_8_0;
4535 dp->ld.destructor = i_psvc_destructor;
4536 dp->ld.get_attr = i_psvc_get_attr_8_0;
4537 dp->ld.set_attr = i_psvc_set_attr_8_0;
4538
4539 return (PSVC_SUCCESS);
4540 }
4541
4542 /* Key Switch */
4543 static int32_t
i_psvc_constructor_9_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)4544 i_psvc_constructor_9_0(
4545 EHdl_t *hdlp,
4546 char *id,
4547 EObj_t **objpp)
4548 {
4549 int32_t status;
4550 char buf[BUFSZ];
4551 EKeySwitch_t *dp;
4552
4553 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4554 sizeof (EKeySwitch_t));
4555 if (status != PSVC_SUCCESS)
4556 return (status);
4557
4558 /* Load class specific info */
4559 dp = (EKeySwitch_t *)*objpp;
4560
4561 dp->ld.constructor = i_psvc_constructor_9_0;
4562 dp->ld.destructor = i_psvc_destructor;
4563 dp->ld.get_attr = i_psvc_get_attr_9_0;
4564 dp->ld.set_attr = i_psvc_set_attr_generic;
4565
4566 return (PSVC_SUCCESS);
4567 }
4568
4569 /* 8 Bit GPIO , devices with registers, calls get_reg()/set_reg() */
4570 static int32_t
i_psvc_constructor_10_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)4571 i_psvc_constructor_10_0(
4572 EHdl_t *hdlp,
4573 char *id,
4574 EObj_t **objpp)
4575 {
4576 int32_t status;
4577 char buf[BUFSZ];
4578 EGPIO8_t *dp;
4579
4580 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EGPIO8_t));
4581 if (status != PSVC_SUCCESS)
4582 return (status);
4583
4584 /* Load class specific info */
4585 dp = (EGPIO8_t *)*objpp;
4586
4587 dp->ld.constructor = i_psvc_constructor_10_0;
4588 dp->ld.destructor = i_psvc_destructor;
4589 dp->ld.get_attr = i_psvc_get_attr_10_0;
4590 dp->ld.set_attr = i_psvc_set_attr_10_0;
4591
4592 return (PSVC_SUCCESS);
4593 }
4594
4595 /* 8 Bit GPIO , devices with ports, calls get_port()/set_port() */
4596 static int32_t
i_psvc_constructor_10_1(EHdl_t * hdlp,char * id,EObj_t ** objpp)4597 i_psvc_constructor_10_1(
4598 EHdl_t *hdlp,
4599 char *id,
4600 EObj_t **objpp)
4601 {
4602 int32_t status;
4603 char buf[BUFSZ];
4604 EGPIO8_t *dp;
4605
4606 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EGPIO8_t));
4607 if (status != PSVC_SUCCESS)
4608 return (status);
4609
4610 /* Load class specific info */
4611 dp = (EGPIO8_t *)*objpp;
4612
4613 dp->ld.constructor = i_psvc_constructor_10_1;
4614 dp->ld.destructor = i_psvc_destructor;
4615 dp->ld.get_attr = i_psvc_get_attr_10_1;
4616 dp->ld.set_attr = i_psvc_set_attr_10_1;
4617
4618 return (PSVC_SUCCESS);
4619 }
4620
4621 /* AT24 */
4622 static int32_t
i_psvc_constructor_11_0(EHdl_t * hdlp,char * id,EObj_t ** objpp)4623 i_psvc_constructor_11_0(
4624 EHdl_t *hdlp,
4625 char *id,
4626 EObj_t **objpp)
4627 {
4628 int32_t status;
4629 char buf[BUFSZ];
4630 EPhysDev_t *dp;
4631
4632 status = i_psvc_load_generic(hdlp, id, objpp, buf,
4633 sizeof (EPhysDev_t));
4634 if (status != PSVC_SUCCESS)
4635 return (status);
4636
4637 /* Load class specific info */
4638 dp = (EPhysDev_t *)*objpp;
4639
4640 dp->ld.constructor = i_psvc_constructor_11_0;
4641 dp->ld.destructor = i_psvc_destructor;
4642 dp->ld.get_attr = i_psvc_get_attr_11_0;
4643 dp->ld.set_attr = i_psvc_set_attr_generic;
4644 dp->get_temperature = i_psvc_not_supported;
4645 dp->get_fanspeed = i_psvc_not_supported;
4646 dp->get_input = i_psvc_not_supported;
4647 dp->get_bit = i_psvc_not_supported;
4648 dp->set_bit = i_psvc_not_supported;
4649 dp->get_port = i_psvc_not_supported;
4650 dp->set_port = i_psvc_not_supported;
4651 dp->get_output = i_psvc_not_supported;
4652 dp->set_output = i_psvc_not_supported;
4653 dp->get_reg = i_psvc_get_reg_11_0;
4654 dp->set_reg = i_psvc_not_supported;
4655
4656 return (PSVC_SUCCESS);
4657 }
4658
4659 /* HPC3130 */
4660 static int32_t
i_psvc_constructor_11_1(EHdl_t * hdlp,char * id,EObj_t ** objpp)4661 i_psvc_constructor_11_1(
4662 EHdl_t *hdlp,
4663 char *id,
4664 EObj_t **objpp)
4665 {
4666 int32_t status;
4667 char buf[BUFSZ];
4668 EPhysDev_t *dp;
4669
4670 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4671 if (status != PSVC_SUCCESS)
4672 return (status);
4673
4674 /* Load class specific info */
4675 dp = (EPhysDev_t *)*objpp;
4676
4677 dp->ld.constructor = i_psvc_constructor_11_1;
4678 dp->ld.destructor = i_psvc_destructor;
4679 dp->ld.get_attr = i_psvc_get_attr_11_1;
4680 dp->ld.set_attr = i_psvc_set_attr_generic;
4681 dp->get_temperature = i_psvc_not_supported;
4682 dp->get_fanspeed = i_psvc_not_supported;
4683 dp->get_input = i_psvc_not_supported;
4684 dp->get_bit = i_psvc_not_supported;
4685 dp->set_bit = i_psvc_not_supported;
4686 dp->get_port = i_psvc_not_supported;
4687 dp->set_port = i_psvc_not_supported;
4688 dp->get_output = i_psvc_not_supported;
4689 dp->set_output = i_psvc_not_supported;
4690 dp->get_reg = i_psvc_get_reg_11_1;
4691 dp->set_reg = i_psvc_set_reg_11_1;
4692
4693 return (PSVC_SUCCESS);
4694 }
4695
4696 /* LM75 */
4697 static int32_t
i_psvc_constructor_11_2(EHdl_t * hdlp,char * id,EObj_t ** objpp)4698 i_psvc_constructor_11_2(
4699 EHdl_t *hdlp,
4700 char *id,
4701 EObj_t **objpp)
4702 {
4703 int32_t status;
4704 char buf[BUFSZ];
4705 EPhysDev_t *dp;
4706
4707 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4708 if (status != PSVC_SUCCESS)
4709 return (status);
4710
4711 /* Load class specific info */
4712 dp = (EPhysDev_t *)*objpp;
4713
4714 dp->ld.constructor = i_psvc_constructor_11_2;
4715 dp->ld.destructor = i_psvc_destructor;
4716 dp->ld.get_attr = i_psvc_get_attr_11_2;
4717 dp->ld.set_attr = i_psvc_set_attr_generic;
4718 dp->get_temperature = i_psvc_get_temperature_11_2;
4719 dp->get_fanspeed = i_psvc_not_supported;
4720 dp->get_input = i_psvc_not_supported;
4721 dp->get_bit = i_psvc_not_supported;
4722 dp->set_bit = i_psvc_not_supported;
4723 dp->get_port = i_psvc_not_supported;
4724 dp->set_port = i_psvc_not_supported;
4725 dp->get_output = i_psvc_not_supported;
4726 dp->set_output = i_psvc_not_supported;
4727 dp->get_reg = i_psvc_not_supported;
4728 dp->set_reg = i_psvc_not_supported;
4729
4730 return (PSVC_SUCCESS);
4731 }
4732
4733 /* LTC1427 */
4734 static int32_t
i_psvc_constructor_11_3(EHdl_t * hdlp,char * id,EObj_t ** objpp)4735 i_psvc_constructor_11_3(
4736 EHdl_t *hdlp,
4737 char *id,
4738 EObj_t **objpp)
4739 {
4740 int32_t status;
4741 char buf[BUFSZ];
4742 EPhysDev_t *dp;
4743 char path[1024];
4744
4745 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4746 if (status != PSVC_SUCCESS)
4747 return (status);
4748
4749 /*
4750 * The following code upto and including the open() call is so the
4751 * device driver for the ltc1427 does not get unloaded by the OS at
4752 * any time. This is important as the device driver is a write only
4753 * physical device but DOES keep readable states in the device unitp
4754 * structure (I2C_GET_OUTPUT) as a result this device should not
4755 * be unload while PSVC is up and running
4756 */
4757 status = i_psvc_get_devpath(hdlp, (*objpp)->addr_spec, path);
4758 if (status != PSVC_SUCCESS) {
4759 return (status);
4760 }
4761
4762 /*
4763 * We deliberately do not close our file handle, to prevent
4764 * any device instances from being detached. If an instance
4765 * is detached, the "readable states in the device unitp"
4766 * will be unloaded, causing loss of control of the device
4767 * and incorrect error(s) to be displayed.
4768 */
4769 if (open(path, O_RDWR) == -1) {
4770 return (PSVC_FAILURE);
4771 }
4772 /* Load class specific info */
4773 dp = (EPhysDev_t *)*objpp;
4774
4775 dp->ld.constructor = i_psvc_constructor_11_3;
4776 dp->ld.destructor = i_psvc_destructor;
4777 dp->ld.get_attr = i_psvc_get_attr_11_3;
4778 dp->ld.set_attr = i_psvc_set_attr_generic;
4779 dp->get_temperature = i_psvc_not_supported;
4780 dp->get_fanspeed = i_psvc_not_supported;
4781 dp->get_input = i_psvc_not_supported;
4782 dp->get_bit = i_psvc_not_supported;
4783 dp->set_bit = i_psvc_not_supported;
4784 dp->get_port = i_psvc_not_supported;
4785 dp->set_port = i_psvc_not_supported;
4786 dp->get_output = i_psvc_get_output_11_3;
4787 dp->set_output = i_psvc_set_output_11_3;
4788 dp->get_reg = i_psvc_not_supported;
4789 dp->set_reg = i_psvc_not_supported;
4790
4791 return (PSVC_SUCCESS);
4792 }
4793
4794 /* MAX1617 */
4795 static int32_t
i_psvc_constructor_11_4(EHdl_t * hdlp,char * id,EObj_t ** objpp)4796 i_psvc_constructor_11_4(
4797 EHdl_t *hdlp,
4798 char *id,
4799 EObj_t **objpp)
4800 {
4801 int32_t status;
4802 char buf[BUFSZ];
4803 EPhysDev_t *dp;
4804
4805 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4806 if (status != PSVC_SUCCESS)
4807 return (status);
4808
4809 /* Load class specific info */
4810 dp = (EPhysDev_t *)*objpp;
4811
4812 dp->ld.constructor = i_psvc_constructor_11_4;
4813 dp->ld.destructor = i_psvc_destructor;
4814 dp->ld.get_attr = i_psvc_get_attr_11_4;
4815 dp->ld.set_attr = i_psvc_set_attr_generic;
4816 dp->get_temperature = i_psvc_get_temperature_11_4;
4817 dp->get_fanspeed = i_psvc_not_supported;
4818 dp->get_input = i_psvc_not_supported;
4819 dp->get_bit = i_psvc_not_supported;
4820 dp->set_bit = i_psvc_not_supported;
4821 dp->get_port = i_psvc_not_supported;
4822 dp->set_port = i_psvc_not_supported;
4823 dp->get_output = i_psvc_not_supported;
4824 dp->set_output = i_psvc_not_supported;
4825 dp->get_reg = i_psvc_not_supported;
4826 dp->set_reg = i_psvc_not_supported;
4827
4828 return (PSVC_SUCCESS);
4829 }
4830
4831 /* PCF8574 */
4832 static int32_t
i_psvc_constructor_11_5(EHdl_t * hdlp,char * id,EObj_t ** objpp)4833 i_psvc_constructor_11_5(
4834 EHdl_t *hdlp,
4835 char *id,
4836 EObj_t **objpp)
4837 {
4838 int32_t status;
4839 char buf[BUFSZ];
4840 EPhysDev_t *dp;
4841
4842 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4843 if (status != PSVC_SUCCESS)
4844 return (status);
4845
4846 /* Load class specific info */
4847 dp = (EPhysDev_t *)*objpp;
4848
4849 dp->ld.constructor = i_psvc_constructor_11_5;
4850 dp->ld.destructor = i_psvc_destructor;
4851 dp->ld.get_attr = i_psvc_get_attr_11_5;
4852 dp->ld.set_attr = i_psvc_set_attr_generic;
4853 dp->get_temperature = i_psvc_not_supported;
4854 dp->get_fanspeed = i_psvc_not_supported;
4855 dp->get_input = i_psvc_not_supported;
4856 dp->get_bit = i_psvc_get_bit_11_5;
4857 dp->set_bit = i_psvc_set_bit_11_5;
4858 dp->get_port = i_psvc_get_port_11_5;
4859 dp->set_port = i_psvc_set_port_11_5;
4860 dp->get_output = i_psvc_not_supported;
4861 dp->set_output = i_psvc_not_supported;
4862 dp->get_reg = i_psvc_not_supported;
4863 dp->set_reg = i_psvc_not_supported;
4864
4865 return (PSVC_SUCCESS);
4866 }
4867
4868 /* PCF8591 */
4869 static int32_t
i_psvc_constructor_11_6(EHdl_t * hdlp,char * id,EObj_t ** objpp)4870 i_psvc_constructor_11_6(
4871 EHdl_t *hdlp,
4872 char *id,
4873 EObj_t **objpp)
4874 {
4875 int32_t status;
4876 char buf[BUFSZ];
4877 EPhysDev_t *dp;
4878
4879 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4880 if (status != PSVC_SUCCESS)
4881 return (status);
4882
4883 /* Load class specific info */
4884 dp = (EPhysDev_t *)*objpp;
4885
4886 dp->ld.constructor = i_psvc_constructor_11_6;
4887 dp->ld.destructor = i_psvc_destructor;
4888 dp->ld.get_attr = i_psvc_get_attr_11_6;
4889 dp->ld.set_attr = i_psvc_set_attr_generic;
4890 dp->get_temperature = i_psvc_get_temperature_11_6;
4891 dp->get_fanspeed = i_psvc_not_supported;
4892 dp->get_input = i_psvc_get_input_11_6;
4893 dp->get_bit = i_psvc_not_supported;
4894 dp->set_bit = i_psvc_not_supported;
4895 dp->get_port = i_psvc_not_supported;
4896 dp->set_port = i_psvc_not_supported;
4897 dp->get_output = i_psvc_get_output_11_6;
4898 dp->set_output = i_psvc_set_output_11_6;
4899 dp->get_reg = i_psvc_not_supported;
4900 dp->set_reg = i_psvc_not_supported;
4901
4902 return (PSVC_SUCCESS);
4903 }
4904
4905 /* SSC050 */
4906 static int32_t
i_psvc_constructor_11_7(EHdl_t * hdlp,char * id,EObj_t ** objpp)4907 i_psvc_constructor_11_7(
4908 EHdl_t *hdlp,
4909 char *id,
4910 EObj_t **objpp)
4911 {
4912 int32_t status;
4913 char buf[BUFSZ];
4914 EPhysDev_t *dp;
4915
4916 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4917 if (status != PSVC_SUCCESS)
4918 return (status);
4919
4920 /* Load class specific info */
4921 dp = (EPhysDev_t *)*objpp;
4922
4923 dp->ld.constructor = i_psvc_constructor_11_7;
4924 dp->ld.destructor = i_psvc_destructor;
4925 dp->ld.get_attr = i_psvc_get_attr_11_7;
4926 dp->ld.set_attr = i_psvc_set_attr_generic;
4927 dp->get_temperature = i_psvc_not_supported;
4928 dp->get_fanspeed = i_psvc_get_fanspeed_11_7;
4929 dp->get_input = i_psvc_not_supported;
4930 dp->get_bit = i_psvc_get_bit_11_7;
4931 dp->set_bit = i_psvc_set_bit_11_7;
4932 dp->get_port = i_psvc_get_port_11_5; /* same as for class = 11, 5 */
4933 dp->set_port = i_psvc_set_port_11_5;
4934 dp->get_output = i_psvc_not_supported;
4935 dp->set_output = i_psvc_not_supported;
4936 dp->get_reg = i_psvc_get_reg_11_7;
4937 dp->set_reg = i_psvc_set_reg_11_7;
4938
4939 return (PSVC_SUCCESS);
4940 }
4941
4942 /* TDA8444 */
4943 static int32_t
i_psvc_constructor_11_8(EHdl_t * hdlp,char * id,EObj_t ** objpp)4944 i_psvc_constructor_11_8(
4945 EHdl_t *hdlp,
4946 char *id,
4947 EObj_t **objpp)
4948 {
4949 int32_t status;
4950 char buf[BUFSZ];
4951 EPhysDev_t *dp;
4952
4953 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4954 if (status != PSVC_SUCCESS)
4955 return (status);
4956
4957 /* Load class specific info */
4958 dp = (EPhysDev_t *)*objpp;
4959
4960 dp->ld.constructor = i_psvc_constructor_11_8;
4961 dp->ld.destructor = i_psvc_destructor;
4962 dp->ld.get_attr = i_psvc_get_attr_11_8;
4963 dp->ld.set_attr = i_psvc_set_attr_generic;
4964 dp->get_temperature = i_psvc_not_supported;
4965 dp->get_fanspeed = i_psvc_not_supported;
4966 dp->get_input = i_psvc_not_supported;
4967 dp->get_bit = i_psvc_not_supported;
4968 dp->set_bit = i_psvc_not_supported;
4969 dp->get_port = i_psvc_not_supported;
4970 dp->set_port = i_psvc_not_supported;
4971 dp->get_output = i_psvc_get_output_11_8;
4972 dp->set_output = i_psvc_set_output_11_8;
4973 dp->get_reg = i_psvc_not_supported;
4974 dp->set_reg = i_psvc_not_supported;
4975
4976 return (PSVC_SUCCESS);
4977 }
4978
4979 /* SSC100 */
4980 static int32_t
i_psvc_constructor_11_9(EHdl_t * hdlp,char * id,EObj_t ** objpp)4981 i_psvc_constructor_11_9(
4982 EHdl_t *hdlp,
4983 char *id,
4984 EObj_t **objpp)
4985 {
4986 int32_t status;
4987 char buf[BUFSZ];
4988 EPhysDev_t *dp;
4989
4990 status = i_psvc_load_generic(hdlp, id, objpp, buf, sizeof (EPhysDev_t));
4991 if (status != PSVC_SUCCESS)
4992 return (status);
4993
4994 /* Load class specific info */
4995 dp = (EPhysDev_t *)*objpp;
4996
4997 dp->ld.constructor = i_psvc_constructor_11_9;
4998 dp->ld.destructor = i_psvc_destructor;
4999 dp->ld.get_attr = i_psvc_get_attr_11_9;
5000 dp->ld.set_attr = i_psvc_set_attr_generic;
5001 dp->get_temperature = i_psvc_not_supported;
5002 dp->get_fanspeed = i_psvc_not_supported;
5003 dp->get_input = i_psvc_not_supported;
5004 dp->get_bit = i_psvc_not_supported;
5005 dp->set_bit = i_psvc_not_supported;
5006 dp->get_port = i_psvc_get_port_11_5; /* Same as for class = 11, 5 */
5007 dp->set_port = i_psvc_set_port_11_5;
5008 dp->get_output = i_psvc_not_supported;
5009 dp->set_output = i_psvc_not_supported;
5010 dp->get_reg = i_psvc_not_supported;
5011 dp->set_reg = i_psvc_not_supported;
5012
5013 return (PSVC_SUCCESS);
5014 }
5015
5016 int32_t
psvc_init(EHdl_t ** hdlpp)5017 psvc_init(EHdl_t **hdlpp)
5018 {
5019 EHdl_t *hdlp;
5020 int i;
5021 char buf[BUFSZ];
5022 char platform[32];
5023 char filename[256];
5024 int found;
5025 int32_t status;
5026 pthread_mutexattr_t mutex_attr;
5027 uint32_t table_count;
5028 int forward_slash = 47;
5029 int new_line = 10;
5030 char *nl_char;
5031
5032 hdlp = (EHdl_t *)malloc(sizeof (EHdl_t));
5033 if (hdlp == NULL)
5034 return (-1);
5035 memset(hdlp, 0, sizeof (EHdl_t));
5036
5037 /* Initialize the lock */
5038 status = pthread_mutexattr_init(&mutex_attr);
5039 if (status != 0) {
5040 errno = status;
5041 return (-1);
5042 }
5043 status = pthread_mutex_init(&hdlp->mutex, &mutex_attr);
5044 if (status != 0) {
5045 errno = status;
5046 return (-1);
5047 }
5048 pthread_mutexattr_destroy(&mutex_attr);
5049
5050 if (sysinfo(SI_PLATFORM, platform, sizeof (platform)) == -1) {
5051 return (-1);
5052 }
5053
5054 snprintf(filename, sizeof (filename),
5055 "/usr/platform/%s/lib/psvcobj.conf", platform);
5056 if ((hdlp->fp = fopen(filename, "r")) == NULL) {
5057 return (-1);
5058 }
5059
5060
5061 /* Build the association ID lookup table */
5062
5063 hdlp->othr_count = hdlp->assoc_count = ASSOC_STR_TAB_SIZE;
5064 if ((hdlp->othr_tbl = (EStringId_t *)malloc(sizeof (EStringId_t) *
5065 hdlp->othr_count)) == NULL) {
5066 return (-1);
5067 }
5068
5069 for (i = 0; i < hdlp->othr_count; ++i) {
5070 hdlp->othr_tbl[i].id = i;
5071 strcpy(hdlp->othr_tbl[i].name, assoc_str_tab[i]);
5072 }
5073 qsort(hdlp->othr_tbl, hdlp->othr_count, sizeof (EStringId_t),
5074 (int (*)(const void *, const void *))i_psvc_name_compare_qsort);
5075
5076 /* determine total number of objects + tables */
5077 if (i_psvc_find_file_section(hdlp->fp, "OBJECT_INFO") == -1) {
5078 return (-1);
5079 }
5080 if (i_psvc_count_records(hdlp->fp, "OBJECT_INFO_END",
5081 &hdlp->total_obj_count) == -1) {
5082 return (-1);
5083 }
5084 if (i_psvc_find_file_section(hdlp->fp, "TABLES") == PSVC_SUCCESS) {
5085 status = i_psvc_count_tables_associations(hdlp->fp,
5086 &table_count, "TABLE_END");
5087 if (status == PSVC_FAILURE) {
5088 return (status);
5089 }
5090 hdlp->total_obj_count += table_count;
5091 }
5092
5093 /* Allocate object name to object pointer translation table */
5094 for (i = 0; i < PSVC_MAX_TABLE_ARRAYS; i++) {
5095 if ((hdlp->tbl_arry[i].obj_tbl =
5096 (ENamePtr_t *)malloc(
5097 sizeof (ENamePtr_t) *hdlp->total_obj_count)) == NULL) {
5098 return (-1);
5099 }
5100 memset(hdlp->tbl_arry[i].obj_tbl, 0,
5101 sizeof (ENamePtr_t) * hdlp->total_obj_count);
5102 hdlp->tbl_arry[i].obj_count = 0;
5103 }
5104
5105 /* Build the association table */
5106 if (i_psvc_load_associations(hdlp, hdlp->fp) == -1)
5107 return (-1);
5108
5109 /* Build the table of device paths */
5110 if (i_psvc_find_file_section(hdlp->fp, "DEVPATHS") == -1)
5111 return (-1);
5112 if (i_psvc_count_records(hdlp->fp, "DEVPATHS_END",
5113 &hdlp->dev_count) == -1)
5114 return (-1);
5115 if ((hdlp->dev_tbl = (EDevice_t *)malloc(sizeof (EDevice_t) *
5116 hdlp->dev_count)) == NULL) {
5117 return (-1);
5118 }
5119 for (i = 0; i < hdlp->dev_count; ++i) {
5120 fgets(buf, BUFSZ, hdlp->fp);
5121 found = sscanf(buf, "%d %d %x %d",
5122 &hdlp->dev_tbl[i].controller,
5123 &hdlp->dev_tbl[i].bus, &hdlp->dev_tbl[i].addr,
5124 &hdlp->dev_tbl[i].port);
5125 if (found != 4) {
5126 errno = EINVAL;
5127 return (-1);
5128 }
5129 strcpy(hdlp->dev_tbl[i].path, strchr(buf, forward_slash));
5130 /*
5131 * Replace new line character with NUL character
5132 */
5133 nl_char = strchr(hdlp->dev_tbl[i].path, new_line);
5134 *nl_char = 0;
5135 }
5136
5137 /* Build the table of tables */
5138 if (i_psvc_load_tables(hdlp, hdlp->fp) == -1)
5139 return (-1);
5140 *hdlpp = hdlp;
5141 return (0);
5142 }
5143
5144 int32_t
psvc_fini(EHdl_t * hdlp)5145 psvc_fini(EHdl_t *hdlp)
5146 {
5147 int32_t i, j;
5148 ETable_Array *array;
5149
5150 if (hdlp == 0)
5151 return (PSVC_SUCCESS);
5152
5153 for (j = 0; j < PSVC_MAX_TABLE_ARRAYS; j++) {
5154 if (hdlp->tbl_arry[j].obj_tbl != 0) {
5155 array = &(hdlp->tbl_arry[j]);
5156 for (i = 0; i < array->obj_count; ++i) {
5157 if (array->obj_tbl[i].type == PSVC_OBJ) {
5158 if (!array->obj_tbl[i].objp) {
5159 /* Skip non-existent object */
5160 continue;
5161 }
5162 array->obj_tbl[i].objp->destructor(hdlp,
5163 array->obj_tbl[i].objp->label,
5164 array->obj_tbl[i].objp);
5165 }
5166
5167 if (array->obj_tbl[i].type == PSVC_TBL) {
5168 ETable_t *tblp =
5169 (ETable_t *)array->obj_tbl[i].objp;
5170 if (tblp->table != 0)
5171 free(tblp->table);
5172 }
5173 }
5174
5175 free(array->obj_tbl);
5176 }
5177 }
5178
5179 if (hdlp->othr_tbl != 0)
5180 free(hdlp->othr_tbl);
5181
5182 if (hdlp->assoc_tbl != 0) {
5183 for (i = 0; i < hdlp->assoc_count; ++i) {
5184 if (hdlp->assoc_tbl[i].table != 0)
5185 free(hdlp->assoc_tbl[i].table);
5186 }
5187 free(hdlp->assoc_tbl);
5188 }
5189
5190 if (hdlp->dev_tbl != 0)
5191 free(hdlp->dev_tbl);
5192 if (hdlp->fp != 0)
5193 fclose(hdlp->fp);
5194 pthread_mutex_destroy(&hdlp->mutex);
5195 free(hdlp);
5196 return (PSVC_SUCCESS);
5197 }
5198
5199 int32_t
ioctl_retry(int fp,int request,void * arg_pointer)5200 ioctl_retry(int fp, int request, void * arg_pointer)
5201 {
5202 int32_t ret = PSVC_SUCCESS;
5203 int32_t tries = 0;
5204
5205 /*
5206 * Becuase the i2c bus is a multimaster bus we need to protect
5207 * ourselves from bus masters that are not being good bus citizens.
5208 * A retry number of 10 should be sufficient to handle any bad bus
5209 * citizens. After that we will simply say that there is something
5210 * wrong with the ioctl transaction and let it bubble back up.
5211 */
5212 do {
5213 ret = ioctl(fp, request, arg_pointer);
5214 tries ++;
5215 } while ((ret == -1) && (tries < 10));
5216
5217 return (ret);
5218 }
5219
5220 static int32_t
psvc_get_str_key(char * object)5221 psvc_get_str_key(char *object)
5222 {
5223 int32_t key = 0;
5224 int i, length;
5225
5226 length = strlen(object);
5227 for (i = 0; i < length; i++) {
5228 if ((object[i] > 47) && (object[i] < 58)) {
5229 key = key + ((object[i] - 50) + 2);
5230 } else {
5231 key = key + object[i];
5232 }
5233 }
5234
5235
5236 return (key);
5237 }
5238