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