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 (c) 2000-2001 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdlib.h> 30 #include <string.h> 31 32 #include "Ancestor.h" 33 34 /* ========================================================================= */ 35 /* Ancestor object definitions. */ 36 37 Ancestor::Ancestor(Str field, fru_tag_t t, const fru_regdef_t *d) 38 : field_name(field), 39 tag(t), 40 def(d), 41 numInstances(0), 42 numBufs(1), 43 next(NULL) 44 { 45 offsets = (uint32_t *)malloc(sizeof (uint32_t) 46 * ANCESTOR_INST_BUF_SIZE); 47 paths = (char **)malloc(sizeof (char *) 48 * ANCESTOR_INST_BUF_SIZE); 49 } 50 51 Ancestor::~Ancestor() 52 { 53 free(offsets); 54 if (paths != NULL) { 55 for (int i = 0; i < numInstances; i++) { 56 free(paths[i]); 57 } 58 } 59 free(paths); 60 delete next; 61 } 62 63 /* 64 void 65 Ancestor::print(void) 66 { 67 fprintf(stderr, "Ancestor Information\n"); 68 fprintf(stderr, "Tag Name: %s\n", def->name); 69 fprintf(stderr, "Tag Type: %s\n", 70 get_tagtype_str(get_tag_type(&tag))); 71 fprintf(stderr, "Num instances: %d\n", numInstances); 72 fprintf(stderr, " offsets:\n"); 73 for (int i = 0; i < numInstances; i++) { 74 fprintf(stderr, " %d\n", offsets[i]); 75 } 76 77 if (next != NULL) { 78 next->print(); 79 } 80 } 81 */ 82 83 void 84 Ancestor::addInstance(const char *path, uint32_t offset) 85 { 86 if (numInstances >= ANCESTOR_INST_BUF_SIZE) { 87 numBufs++; 88 offsets = (uint32_t *)realloc(offsets, 89 (sizeof (uint32_t) * 90 (ANCESTOR_INST_BUF_SIZE * numBufs))); 91 paths = (char **)realloc(offsets, 92 (sizeof (char *) * 93 (ANCESTOR_INST_BUF_SIZE * numBufs))); 94 } 95 offsets[numInstances] = offset; 96 paths[numInstances++] = strdup(path); 97 } 98 99 Str 100 Ancestor::getFieldName(void) 101 { 102 return (field_name); 103 } 104 105 fru_tag_t 106 Ancestor::getTag(void) 107 { 108 return (tag); 109 } 110 111 const fru_regdef_t * 112 Ancestor::getDef(void) 113 { 114 return (def); 115 } 116 117 int 118 Ancestor::getNumInstances(void) 119 { 120 return (numInstances); 121 } 122 123 uint32_t 124 Ancestor::getInstOffset(int num) 125 { 126 if (num < numInstances) 127 return (offsets[num]); 128 else 129 return (offsets[numInstances]); 130 } 131 132 const char * 133 Ancestor::getPath(int num) 134 { 135 if (num < numInstances) 136 return (paths[num]); 137 else 138 return (paths[numInstances]); 139 } 140 141 142 Ancestor * 143 Ancestor::listTaggedAncestors(char *element) 144 { 145 Ancestor *rc = NULL; 146 fru_regdef_t *def = NULL; 147 int i = 0; 148 149 unsigned int number = 0; 150 char **data_elems = fru_reg_list_entries(&number); 151 152 if (data_elems == NULL) { 153 return (NULL); 154 } 155 156 // look through all the elements. 157 for (i = 0; i < number; i++) { 158 def = (fru_regdef_t *) 159 fru_reg_lookup_def_by_name(data_elems[i]); 160 Ancestor *ant = createTaggedAncestor(def, element); 161 if (ant != NULL) { 162 if (rc == NULL) { 163 rc = ant; 164 } else { 165 Ancestor *tmp = rc; 166 while (tmp->next != NULL) { 167 tmp = tmp->next; 168 } 169 tmp->next = ant; 170 } 171 } 172 } 173 174 for (i = 0; i < number; i++) { 175 free(data_elems[i]); 176 } 177 free(data_elems); 178 179 return (rc); 180 } 181 182 Ancestor * 183 Ancestor::createTaggedAncestor(const fru_regdef_t *def, Str element) 184 { 185 // ancestors have to be tagged. 186 if (def->tagType == FRU_X) 187 return (NULL); 188 189 fru_tag_t tag; 190 mk_tag(def->tagType, def->tagDense, def->payloadLen, &tag); 191 Ancestor *rc = new Ancestor(element, tag, def); 192 193 if (element.compare(def->name) == 0) { 194 rc->addInstance("", 0); 195 return (rc); 196 } 197 198 int found = 0; 199 if (def->dataType == FDTYPE_Record) { 200 uint32_t offset = 0; 201 for (int i = 0; i < def->enumCount; i++) { 202 const fru_regdef_t *tmp 203 = fru_reg_lookup_def_by_name 204 ((char *)def->enumTable[i].text); 205 Str path = "/"; 206 path << def->name; 207 int f = definitionContains(tmp, def, element, 208 offset, rc, path); 209 if (f == 1) found = 1; // found needs to latch at one. 210 offset += tmp->payloadLen; 211 } 212 } 213 214 if (!found) { 215 delete rc; 216 return (NULL); 217 } 218 219 return (rc); 220 } 221 222 int 223 Ancestor::definitionContains(const fru_regdef_t *def, 224 const fru_regdef_t *parent_def, 225 Str element, 226 uint32_t offset, 227 Ancestor *ant, 228 Str path) 229 { 230 if (element.compare(def->name) == 0) { 231 if (parent_def->iterationType != FRU_NOT_ITERATED) { 232 offset += 4; 233 for (int i = 0; i < parent_def->iterationCount; i++) { 234 Str tmp = path; 235 tmp << "[" << i << "]/"; 236 ant->addInstance(tmp.peak(), offset); 237 offset += (parent_def->payloadLen - 4) / 238 parent_def->iterationCount; 239 } 240 } else { 241 path << "/"; 242 ant->addInstance(path.peak(), offset); 243 } 244 return (1); 245 } 246 247 int found = 0; 248 if (def->dataType == FDTYPE_Record) { 249 for (int i = 0; i < def->enumCount; i++) { 250 const fru_regdef_t *tmp 251 = fru_reg_lookup_def_by_name 252 ((char *)def->enumTable[i].text); 253 Str newPath = path; 254 newPath << "/" << def->name; 255 int f = definitionContains(tmp, def, element, 256 offset, ant, newPath); 257 if (f == 1) found = 1; // found needs to latch at one. 258 offset += tmp->payloadLen; 259 } 260 } 261 262 return (found); 263 } 264