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