1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright (c) 2000-2001 by Sun Microsystems, Inc. 24*7c478bd9Sstevel@tonic-gate * All rights reserved. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 30*7c478bd9Sstevel@tonic-gate #include <string.h> 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate #include "Ancestor.h" 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 35*7c478bd9Sstevel@tonic-gate /* Ancestor object definitions. */ 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate Ancestor::Ancestor(Str field, fru_tag_t t, const fru_regdef_t *d) 38*7c478bd9Sstevel@tonic-gate : field_name(field), 39*7c478bd9Sstevel@tonic-gate tag(t), 40*7c478bd9Sstevel@tonic-gate def(d), 41*7c478bd9Sstevel@tonic-gate numInstances(0), 42*7c478bd9Sstevel@tonic-gate numBufs(1), 43*7c478bd9Sstevel@tonic-gate next(NULL) 44*7c478bd9Sstevel@tonic-gate { 45*7c478bd9Sstevel@tonic-gate offsets = (uint32_t *)malloc(sizeof (uint32_t) 46*7c478bd9Sstevel@tonic-gate * ANCESTOR_INST_BUF_SIZE); 47*7c478bd9Sstevel@tonic-gate paths = (char **)malloc(sizeof (char *) 48*7c478bd9Sstevel@tonic-gate * ANCESTOR_INST_BUF_SIZE); 49*7c478bd9Sstevel@tonic-gate } 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate Ancestor::~Ancestor() 52*7c478bd9Sstevel@tonic-gate { 53*7c478bd9Sstevel@tonic-gate free(offsets); 54*7c478bd9Sstevel@tonic-gate if (paths != NULL) { 55*7c478bd9Sstevel@tonic-gate for (int i = 0; i < numInstances; i++) { 56*7c478bd9Sstevel@tonic-gate free(paths[i]); 57*7c478bd9Sstevel@tonic-gate } 58*7c478bd9Sstevel@tonic-gate } 59*7c478bd9Sstevel@tonic-gate free(paths); 60*7c478bd9Sstevel@tonic-gate delete next; 61*7c478bd9Sstevel@tonic-gate } 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate /* 64*7c478bd9Sstevel@tonic-gate void 65*7c478bd9Sstevel@tonic-gate Ancestor::print(void) 66*7c478bd9Sstevel@tonic-gate { 67*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Ancestor Information\n"); 68*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Tag Name: %s\n", def->name); 69*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Tag Type: %s\n", 70*7c478bd9Sstevel@tonic-gate get_tagtype_str(get_tag_type(&tag))); 71*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Num instances: %d\n", numInstances); 72*7c478bd9Sstevel@tonic-gate fprintf(stderr, " offsets:\n"); 73*7c478bd9Sstevel@tonic-gate for (int i = 0; i < numInstances; i++) { 74*7c478bd9Sstevel@tonic-gate fprintf(stderr, " %d\n", offsets[i]); 75*7c478bd9Sstevel@tonic-gate } 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate if (next != NULL) { 78*7c478bd9Sstevel@tonic-gate next->print(); 79*7c478bd9Sstevel@tonic-gate } 80*7c478bd9Sstevel@tonic-gate } 81*7c478bd9Sstevel@tonic-gate */ 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate void 84*7c478bd9Sstevel@tonic-gate Ancestor::addInstance(const char *path, uint32_t offset) 85*7c478bd9Sstevel@tonic-gate { 86*7c478bd9Sstevel@tonic-gate if (numInstances >= ANCESTOR_INST_BUF_SIZE) { 87*7c478bd9Sstevel@tonic-gate numBufs++; 88*7c478bd9Sstevel@tonic-gate offsets = (uint32_t *)realloc(offsets, 89*7c478bd9Sstevel@tonic-gate (sizeof (uint32_t) * 90*7c478bd9Sstevel@tonic-gate (ANCESTOR_INST_BUF_SIZE * numBufs))); 91*7c478bd9Sstevel@tonic-gate paths = (char **)realloc(offsets, 92*7c478bd9Sstevel@tonic-gate (sizeof (char *) * 93*7c478bd9Sstevel@tonic-gate (ANCESTOR_INST_BUF_SIZE * numBufs))); 94*7c478bd9Sstevel@tonic-gate } 95*7c478bd9Sstevel@tonic-gate offsets[numInstances] = offset; 96*7c478bd9Sstevel@tonic-gate paths[numInstances++] = strdup(path); 97*7c478bd9Sstevel@tonic-gate } 98*7c478bd9Sstevel@tonic-gate 99*7c478bd9Sstevel@tonic-gate Str 100*7c478bd9Sstevel@tonic-gate Ancestor::getFieldName(void) 101*7c478bd9Sstevel@tonic-gate { 102*7c478bd9Sstevel@tonic-gate return (field_name); 103*7c478bd9Sstevel@tonic-gate } 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate fru_tag_t 106*7c478bd9Sstevel@tonic-gate Ancestor::getTag(void) 107*7c478bd9Sstevel@tonic-gate { 108*7c478bd9Sstevel@tonic-gate return (tag); 109*7c478bd9Sstevel@tonic-gate } 110*7c478bd9Sstevel@tonic-gate 111*7c478bd9Sstevel@tonic-gate const fru_regdef_t * 112*7c478bd9Sstevel@tonic-gate Ancestor::getDef(void) 113*7c478bd9Sstevel@tonic-gate { 114*7c478bd9Sstevel@tonic-gate return (def); 115*7c478bd9Sstevel@tonic-gate } 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate int 118*7c478bd9Sstevel@tonic-gate Ancestor::getNumInstances(void) 119*7c478bd9Sstevel@tonic-gate { 120*7c478bd9Sstevel@tonic-gate return (numInstances); 121*7c478bd9Sstevel@tonic-gate } 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate uint32_t 124*7c478bd9Sstevel@tonic-gate Ancestor::getInstOffset(int num) 125*7c478bd9Sstevel@tonic-gate { 126*7c478bd9Sstevel@tonic-gate if (num < numInstances) 127*7c478bd9Sstevel@tonic-gate return (offsets[num]); 128*7c478bd9Sstevel@tonic-gate else 129*7c478bd9Sstevel@tonic-gate return (offsets[numInstances]); 130*7c478bd9Sstevel@tonic-gate } 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate const char * 133*7c478bd9Sstevel@tonic-gate Ancestor::getPath(int num) 134*7c478bd9Sstevel@tonic-gate { 135*7c478bd9Sstevel@tonic-gate if (num < numInstances) 136*7c478bd9Sstevel@tonic-gate return (paths[num]); 137*7c478bd9Sstevel@tonic-gate else 138*7c478bd9Sstevel@tonic-gate return (paths[numInstances]); 139*7c478bd9Sstevel@tonic-gate } 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate Ancestor * 143*7c478bd9Sstevel@tonic-gate Ancestor::listTaggedAncestors(char *element) 144*7c478bd9Sstevel@tonic-gate { 145*7c478bd9Sstevel@tonic-gate Ancestor *rc = NULL; 146*7c478bd9Sstevel@tonic-gate fru_regdef_t *def = NULL; 147*7c478bd9Sstevel@tonic-gate int i = 0; 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate unsigned int number = 0; 150*7c478bd9Sstevel@tonic-gate char **data_elems = fru_reg_list_entries(&number); 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate if (data_elems == NULL) { 153*7c478bd9Sstevel@tonic-gate return (NULL); 154*7c478bd9Sstevel@tonic-gate } 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate // look through all the elements. 157*7c478bd9Sstevel@tonic-gate for (i = 0; i < number; i++) { 158*7c478bd9Sstevel@tonic-gate def = (fru_regdef_t *) 159*7c478bd9Sstevel@tonic-gate fru_reg_lookup_def_by_name(data_elems[i]); 160*7c478bd9Sstevel@tonic-gate Ancestor *ant = createTaggedAncestor(def, element); 161*7c478bd9Sstevel@tonic-gate if (ant != NULL) { 162*7c478bd9Sstevel@tonic-gate if (rc == NULL) { 163*7c478bd9Sstevel@tonic-gate rc = ant; 164*7c478bd9Sstevel@tonic-gate } else { 165*7c478bd9Sstevel@tonic-gate Ancestor *tmp = rc; 166*7c478bd9Sstevel@tonic-gate while (tmp->next != NULL) { 167*7c478bd9Sstevel@tonic-gate tmp = tmp->next; 168*7c478bd9Sstevel@tonic-gate } 169*7c478bd9Sstevel@tonic-gate tmp->next = ant; 170*7c478bd9Sstevel@tonic-gate } 171*7c478bd9Sstevel@tonic-gate } 172*7c478bd9Sstevel@tonic-gate } 173*7c478bd9Sstevel@tonic-gate 174*7c478bd9Sstevel@tonic-gate for (i = 0; i < number; i++) { 175*7c478bd9Sstevel@tonic-gate free(data_elems[i]); 176*7c478bd9Sstevel@tonic-gate } 177*7c478bd9Sstevel@tonic-gate free(data_elems); 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate return (rc); 180*7c478bd9Sstevel@tonic-gate } 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate Ancestor * 183*7c478bd9Sstevel@tonic-gate Ancestor::createTaggedAncestor(const fru_regdef_t *def, Str element) 184*7c478bd9Sstevel@tonic-gate { 185*7c478bd9Sstevel@tonic-gate // ancestors have to be tagged. 186*7c478bd9Sstevel@tonic-gate if (def->tagType == FRU_X) 187*7c478bd9Sstevel@tonic-gate return (NULL); 188*7c478bd9Sstevel@tonic-gate 189*7c478bd9Sstevel@tonic-gate fru_tag_t tag; 190*7c478bd9Sstevel@tonic-gate mk_tag(def->tagType, def->tagDense, def->payloadLen, &tag); 191*7c478bd9Sstevel@tonic-gate Ancestor *rc = new Ancestor(element, tag, def); 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate if (element.compare(def->name) == 0) { 194*7c478bd9Sstevel@tonic-gate rc->addInstance("", 0); 195*7c478bd9Sstevel@tonic-gate return (rc); 196*7c478bd9Sstevel@tonic-gate } 197*7c478bd9Sstevel@tonic-gate 198*7c478bd9Sstevel@tonic-gate int found = 0; 199*7c478bd9Sstevel@tonic-gate if (def->dataType == FDTYPE_Record) { 200*7c478bd9Sstevel@tonic-gate uint32_t offset = 0; 201*7c478bd9Sstevel@tonic-gate for (int i = 0; i < def->enumCount; i++) { 202*7c478bd9Sstevel@tonic-gate const fru_regdef_t *tmp 203*7c478bd9Sstevel@tonic-gate = fru_reg_lookup_def_by_name 204*7c478bd9Sstevel@tonic-gate ((char *)def->enumTable[i].text); 205*7c478bd9Sstevel@tonic-gate Str path = "/"; 206*7c478bd9Sstevel@tonic-gate path << def->name; 207*7c478bd9Sstevel@tonic-gate int f = definitionContains(tmp, def, element, 208*7c478bd9Sstevel@tonic-gate offset, rc, path); 209*7c478bd9Sstevel@tonic-gate if (f == 1) found = 1; // found needs to latch at one. 210*7c478bd9Sstevel@tonic-gate offset += tmp->payloadLen; 211*7c478bd9Sstevel@tonic-gate } 212*7c478bd9Sstevel@tonic-gate } 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate if (!found) { 215*7c478bd9Sstevel@tonic-gate delete rc; 216*7c478bd9Sstevel@tonic-gate return (NULL); 217*7c478bd9Sstevel@tonic-gate } 218*7c478bd9Sstevel@tonic-gate 219*7c478bd9Sstevel@tonic-gate return (rc); 220*7c478bd9Sstevel@tonic-gate } 221*7c478bd9Sstevel@tonic-gate 222*7c478bd9Sstevel@tonic-gate int 223*7c478bd9Sstevel@tonic-gate Ancestor::definitionContains(const fru_regdef_t *def, 224*7c478bd9Sstevel@tonic-gate const fru_regdef_t *parent_def, 225*7c478bd9Sstevel@tonic-gate Str element, 226*7c478bd9Sstevel@tonic-gate uint32_t offset, 227*7c478bd9Sstevel@tonic-gate Ancestor *ant, 228*7c478bd9Sstevel@tonic-gate Str path) 229*7c478bd9Sstevel@tonic-gate { 230*7c478bd9Sstevel@tonic-gate if (element.compare(def->name) == 0) { 231*7c478bd9Sstevel@tonic-gate if (parent_def->iterationType != FRU_NOT_ITERATED) { 232*7c478bd9Sstevel@tonic-gate offset += 4; 233*7c478bd9Sstevel@tonic-gate for (int i = 0; i < parent_def->iterationCount; i++) { 234*7c478bd9Sstevel@tonic-gate Str tmp = path; 235*7c478bd9Sstevel@tonic-gate tmp << "[" << i << "]/"; 236*7c478bd9Sstevel@tonic-gate ant->addInstance(tmp.peak(), offset); 237*7c478bd9Sstevel@tonic-gate offset += (parent_def->payloadLen - 4) / 238*7c478bd9Sstevel@tonic-gate parent_def->iterationCount; 239*7c478bd9Sstevel@tonic-gate } 240*7c478bd9Sstevel@tonic-gate } else { 241*7c478bd9Sstevel@tonic-gate path << "/"; 242*7c478bd9Sstevel@tonic-gate ant->addInstance(path.peak(), offset); 243*7c478bd9Sstevel@tonic-gate } 244*7c478bd9Sstevel@tonic-gate return (1); 245*7c478bd9Sstevel@tonic-gate } 246*7c478bd9Sstevel@tonic-gate 247*7c478bd9Sstevel@tonic-gate int found = 0; 248*7c478bd9Sstevel@tonic-gate if (def->dataType == FDTYPE_Record) { 249*7c478bd9Sstevel@tonic-gate for (int i = 0; i < def->enumCount; i++) { 250*7c478bd9Sstevel@tonic-gate const fru_regdef_t *tmp 251*7c478bd9Sstevel@tonic-gate = fru_reg_lookup_def_by_name 252*7c478bd9Sstevel@tonic-gate ((char *)def->enumTable[i].text); 253*7c478bd9Sstevel@tonic-gate Str newPath = path; 254*7c478bd9Sstevel@tonic-gate newPath << "/" << def->name; 255*7c478bd9Sstevel@tonic-gate int f = definitionContains(tmp, def, element, 256*7c478bd9Sstevel@tonic-gate offset, ant, newPath); 257*7c478bd9Sstevel@tonic-gate if (f == 1) found = 1; // found needs to latch at one. 258*7c478bd9Sstevel@tonic-gate offset += tmp->payloadLen; 259*7c478bd9Sstevel@tonic-gate } 260*7c478bd9Sstevel@tonic-gate } 261*7c478bd9Sstevel@tonic-gate 262*7c478bd9Sstevel@tonic-gate return (found); 263*7c478bd9Sstevel@tonic-gate } 264