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