1*6bbe0590SSundeep Panicker /* 2*6bbe0590SSundeep Panicker * CDDL HEADER START 3*6bbe0590SSundeep Panicker * 4*6bbe0590SSundeep Panicker * The contents of this file are subject to the terms of the 5*6bbe0590SSundeep Panicker * Common Development and Distribution License (the "License"). 6*6bbe0590SSundeep Panicker * You may not use this file except in compliance with the License. 7*6bbe0590SSundeep Panicker * 8*6bbe0590SSundeep Panicker * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*6bbe0590SSundeep Panicker * or http://www.opensolaris.org/os/licensing. 10*6bbe0590SSundeep Panicker * See the License for the specific language governing permissions 11*6bbe0590SSundeep Panicker * and limitations under the License. 12*6bbe0590SSundeep Panicker * 13*6bbe0590SSundeep Panicker * When distributing Covered Code, include this CDDL HEADER in each 14*6bbe0590SSundeep Panicker * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*6bbe0590SSundeep Panicker * If applicable, add the following below this CDDL HEADER, with the 16*6bbe0590SSundeep Panicker * fields enclosed by brackets "[]" replaced with your own identifying 17*6bbe0590SSundeep Panicker * information: Portions Copyright [yyyy] [name of copyright owner] 18*6bbe0590SSundeep Panicker * 19*6bbe0590SSundeep Panicker * CDDL HEADER END 20*6bbe0590SSundeep Panicker */ 21*6bbe0590SSundeep Panicker 22*6bbe0590SSundeep Panicker /* 23*6bbe0590SSundeep Panicker * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*6bbe0590SSundeep Panicker * Use is subject to license terms. 25*6bbe0590SSundeep Panicker */ 26*6bbe0590SSundeep Panicker 27*6bbe0590SSundeep Panicker #include <stdio.h> 28*6bbe0590SSundeep Panicker #include <stdlib.h> 29*6bbe0590SSundeep Panicker #include <stdint.h> 30*6bbe0590SSundeep Panicker #include <strings.h> 31*6bbe0590SSundeep Panicker #include <assert.h> 32*6bbe0590SSundeep Panicker #include <pthread.h> 33*6bbe0590SSundeep Panicker #include <sys/byteorder.h> 34*6bbe0590SSundeep Panicker #include <sys/types.h> 35*6bbe0590SSundeep Panicker #include <sys/nvpair.h> 36*6bbe0590SSundeep Panicker 37*6bbe0590SSundeep Panicker #include "libfru.h" 38*6bbe0590SSundeep Panicker #include "libfrup.h" 39*6bbe0590SSundeep Panicker #include "fru_tag.h" 40*6bbe0590SSundeep Panicker #include "libfrureg.h" 41*6bbe0590SSundeep Panicker 42*6bbe0590SSundeep Panicker 43*6bbe0590SSundeep Panicker #define NUM_ITER_BYTES 4 44*6bbe0590SSundeep Panicker #define HEAD_ITER 0 45*6bbe0590SSundeep Panicker #define TAIL_ITER 1 46*6bbe0590SSundeep Panicker #define NUM_ITER 2 47*6bbe0590SSundeep Panicker #define MAX_ITER 3 48*6bbe0590SSundeep Panicker #define TIMESTRINGLEN 128 49*6bbe0590SSundeep Panicker 50*6bbe0590SSundeep Panicker #define PARSE_TIME 1 51*6bbe0590SSundeep Panicker 52*6bbe0590SSundeep Panicker static pthread_mutex_t gLock = PTHREAD_MUTEX_INITIALIZER; 53*6bbe0590SSundeep Panicker 54*6bbe0590SSundeep Panicker 55*6bbe0590SSundeep Panicker 56*6bbe0590SSundeep Panicker static void 57*6bbe0590SSundeep Panicker convert_field(const uint8_t *field, const fru_regdef_t *def, const char *path, 58*6bbe0590SSundeep Panicker nvlist_t *nv) 59*6bbe0590SSundeep Panicker { 60*6bbe0590SSundeep Panicker char timestring[TIMESTRINGLEN]; 61*6bbe0590SSundeep Panicker int i; 62*6bbe0590SSundeep Panicker uint64_t value; 63*6bbe0590SSundeep Panicker time_t timefield; 64*6bbe0590SSundeep Panicker 65*6bbe0590SSundeep Panicker switch (def->dataType) { 66*6bbe0590SSundeep Panicker case FDTYPE_Binary: 67*6bbe0590SSundeep Panicker assert(def->payloadLen <= sizeof (value)); 68*6bbe0590SSundeep Panicker switch (def->dispType) { 69*6bbe0590SSundeep Panicker #if PARSE_TIME == 1 70*6bbe0590SSundeep Panicker case FDISP_Time: 71*6bbe0590SSundeep Panicker if (def->payloadLen > sizeof (timefield)) { 72*6bbe0590SSundeep Panicker /* too big for formatting */ 73*6bbe0590SSundeep Panicker return; 74*6bbe0590SSundeep Panicker } 75*6bbe0590SSundeep Panicker (void) memcpy(&timefield, field, sizeof (timefield)); 76*6bbe0590SSundeep Panicker timefield = BE_32(timefield); 77*6bbe0590SSundeep Panicker if (strftime(timestring, sizeof (timestring), "%C", 78*6bbe0590SSundeep Panicker localtime(&timefield)) == 0) { 79*6bbe0590SSundeep Panicker /* buffer too small */ 80*6bbe0590SSundeep Panicker return; 81*6bbe0590SSundeep Panicker } 82*6bbe0590SSundeep Panicker (void) nvlist_add_string(nv, path, timestring); 83*6bbe0590SSundeep Panicker return; 84*6bbe0590SSundeep Panicker #endif 85*6bbe0590SSundeep Panicker 86*6bbe0590SSundeep Panicker case FDISP_Binary: 87*6bbe0590SSundeep Panicker case FDISP_Octal: 88*6bbe0590SSundeep Panicker case FDISP_Decimal: 89*6bbe0590SSundeep Panicker case FDISP_Hex: 90*6bbe0590SSundeep Panicker default: 91*6bbe0590SSundeep Panicker value = 0; 92*6bbe0590SSundeep Panicker (void) memcpy((((uint8_t *)&value) + 93*6bbe0590SSundeep Panicker sizeof (value) - def->payloadLen), 94*6bbe0590SSundeep Panicker field, def->payloadLen); 95*6bbe0590SSundeep Panicker value = BE_64(value); 96*6bbe0590SSundeep Panicker switch (def->payloadLen) { 97*6bbe0590SSundeep Panicker case 1: 98*6bbe0590SSundeep Panicker (void) nvlist_add_uint8(nv, path, 99*6bbe0590SSundeep Panicker (uint8_t)value); 100*6bbe0590SSundeep Panicker break; 101*6bbe0590SSundeep Panicker case 2: 102*6bbe0590SSundeep Panicker (void) nvlist_add_uint16(nv, path, 103*6bbe0590SSundeep Panicker (uint16_t)value); 104*6bbe0590SSundeep Panicker break; 105*6bbe0590SSundeep Panicker case 4: 106*6bbe0590SSundeep Panicker (void) nvlist_add_uint32(nv, path, 107*6bbe0590SSundeep Panicker (uint32_t)value); 108*6bbe0590SSundeep Panicker break; 109*6bbe0590SSundeep Panicker default: 110*6bbe0590SSundeep Panicker (void) nvlist_add_uint64(nv, path, value); 111*6bbe0590SSundeep Panicker } 112*6bbe0590SSundeep Panicker return; 113*6bbe0590SSundeep Panicker } 114*6bbe0590SSundeep Panicker 115*6bbe0590SSundeep Panicker case FDTYPE_ASCII: 116*6bbe0590SSundeep Panicker (void) nvlist_add_string(nv, path, (char *)field); 117*6bbe0590SSundeep Panicker return; 118*6bbe0590SSundeep Panicker 119*6bbe0590SSundeep Panicker case FDTYPE_Enumeration: 120*6bbe0590SSundeep Panicker value = 0; 121*6bbe0590SSundeep Panicker (void) memcpy((((uint8_t *)&value) + sizeof (value) - 122*6bbe0590SSundeep Panicker def->payloadLen), field, def->payloadLen); 123*6bbe0590SSundeep Panicker value = BE_64(value); 124*6bbe0590SSundeep Panicker for (i = 0; i < def->enumCount; i++) { 125*6bbe0590SSundeep Panicker if (def->enumTable[i].value == value) { 126*6bbe0590SSundeep Panicker (void) nvlist_add_string(nv, path, 127*6bbe0590SSundeep Panicker def->enumTable[i].text); 128*6bbe0590SSundeep Panicker return; 129*6bbe0590SSundeep Panicker } 130*6bbe0590SSundeep Panicker } 131*6bbe0590SSundeep Panicker } 132*6bbe0590SSundeep Panicker 133*6bbe0590SSundeep Panicker /* nothing matched above, use byte array */ 134*6bbe0590SSundeep Panicker (void) nvlist_add_byte_array(nv, path, (uchar_t *)field, 135*6bbe0590SSundeep Panicker def->payloadLen); 136*6bbe0590SSundeep Panicker } 137*6bbe0590SSundeep Panicker 138*6bbe0590SSundeep Panicker 139*6bbe0590SSundeep Panicker 140*6bbe0590SSundeep Panicker static void 141*6bbe0590SSundeep Panicker convert_element(const uint8_t *data, const fru_regdef_t *def, char *ppath, 142*6bbe0590SSundeep Panicker nvlist_t *nv, boolean_t from_iter) 143*6bbe0590SSundeep Panicker { 144*6bbe0590SSundeep Panicker int i; 145*6bbe0590SSundeep Panicker char *path; 146*6bbe0590SSundeep Panicker 147*6bbe0590SSundeep Panicker /* construct path */ 148*6bbe0590SSundeep Panicker if ((def->iterationCount == 0) && 149*6bbe0590SSundeep Panicker (def->iterationType != FRU_NOT_ITERATED)) { 150*6bbe0590SSundeep Panicker path = ppath; 151*6bbe0590SSundeep Panicker } else { 152*6bbe0590SSundeep Panicker path = (char *)def->name; 153*6bbe0590SSundeep Panicker } 154*6bbe0590SSundeep Panicker 155*6bbe0590SSundeep Panicker /* iteration, record and field */ 156*6bbe0590SSundeep Panicker if (def->iterationCount) { 157*6bbe0590SSundeep Panicker int iterlen, n; 158*6bbe0590SSundeep Panicker uint8_t head, num; 159*6bbe0590SSundeep Panicker fru_regdef_t newdef; 160*6bbe0590SSundeep Panicker nvlist_t **nv_elems; 161*6bbe0590SSundeep Panicker char num_str[32]; 162*6bbe0590SSundeep Panicker 163*6bbe0590SSundeep Panicker iterlen = (def->payloadLen - NUM_ITER_BYTES) / 164*6bbe0590SSundeep Panicker def->iterationCount; 165*6bbe0590SSundeep Panicker 166*6bbe0590SSundeep Panicker /* 167*6bbe0590SSundeep Panicker * make a new element definition to describe the components of 168*6bbe0590SSundeep Panicker * the iteration. 169*6bbe0590SSundeep Panicker */ 170*6bbe0590SSundeep Panicker (void) memcpy(&newdef, def, sizeof (newdef)); 171*6bbe0590SSundeep Panicker newdef.iterationCount = 0; 172*6bbe0590SSundeep Panicker newdef.payloadLen = iterlen; 173*6bbe0590SSundeep Panicker 174*6bbe0590SSundeep Panicker /* validate the content of the iteration control bytes */ 175*6bbe0590SSundeep Panicker if ((data[HEAD_ITER] >= def->iterationCount) || 176*6bbe0590SSundeep Panicker (data[NUM_ITER] > def->iterationCount) || 177*6bbe0590SSundeep Panicker (data[MAX_ITER] != def->iterationCount)) { 178*6bbe0590SSundeep Panicker /* invalid. show all iterations */ 179*6bbe0590SSundeep Panicker head = 0; 180*6bbe0590SSundeep Panicker num = def->iterationCount; 181*6bbe0590SSundeep Panicker } else { 182*6bbe0590SSundeep Panicker head = data[HEAD_ITER]; 183*6bbe0590SSundeep Panicker num = data[NUM_ITER]; 184*6bbe0590SSundeep Panicker } 185*6bbe0590SSundeep Panicker 186*6bbe0590SSundeep Panicker nv_elems = (nvlist_t **)malloc(num * sizeof (nvlist_t *)); 187*6bbe0590SSundeep Panicker if (!nv_elems) 188*6bbe0590SSundeep Panicker return; 189*6bbe0590SSundeep Panicker for (i = head, n = 0, data += sizeof (uint32_t); n < num; 190*6bbe0590SSundeep Panicker i = ((i + 1) % def->iterationCount), n++) { 191*6bbe0590SSundeep Panicker if (nvlist_alloc(&nv_elems[n], 0, 0) != 0) 192*6bbe0590SSundeep Panicker return; 193*6bbe0590SSundeep Panicker (void) snprintf(num_str, sizeof (num_str), "%d", n); 194*6bbe0590SSundeep Panicker convert_element((data + i*iterlen), &newdef, num_str, 195*6bbe0590SSundeep Panicker nv_elems[n], B_TRUE); 196*6bbe0590SSundeep Panicker } 197*6bbe0590SSundeep Panicker (void) nvlist_add_nvlist_array(nv, path, nv_elems, num); 198*6bbe0590SSundeep Panicker 199*6bbe0590SSundeep Panicker } else if (def->dataType == FDTYPE_Record) { 200*6bbe0590SSundeep Panicker const fru_regdef_t *component; 201*6bbe0590SSundeep Panicker nvlist_t *nv_record; 202*6bbe0590SSundeep Panicker 203*6bbe0590SSundeep Panicker if (!from_iter) { 204*6bbe0590SSundeep Panicker if (nvlist_alloc(&nv_record, 0, 0) != 0) { 205*6bbe0590SSundeep Panicker return; 206*6bbe0590SSundeep Panicker } 207*6bbe0590SSundeep Panicker } else { 208*6bbe0590SSundeep Panicker nv_record = nv; 209*6bbe0590SSundeep Panicker } 210*6bbe0590SSundeep Panicker 211*6bbe0590SSundeep Panicker for (i = 0; i < def->enumCount; i++, 212*6bbe0590SSundeep Panicker data += component->payloadLen) { 213*6bbe0590SSundeep Panicker component = fru_reg_lookup_def_by_name( 214*6bbe0590SSundeep Panicker def->enumTable[i].text); 215*6bbe0590SSundeep Panicker convert_element(data, component, "", nv_record, 216*6bbe0590SSundeep Panicker B_FALSE); 217*6bbe0590SSundeep Panicker } 218*6bbe0590SSundeep Panicker 219*6bbe0590SSundeep Panicker (void) nvlist_add_nvlist(nv, path, nv_record); 220*6bbe0590SSundeep Panicker 221*6bbe0590SSundeep Panicker } else { 222*6bbe0590SSundeep Panicker convert_field(data, def, path, nv); 223*6bbe0590SSundeep Panicker } 224*6bbe0590SSundeep Panicker } 225*6bbe0590SSundeep Panicker 226*6bbe0590SSundeep Panicker 227*6bbe0590SSundeep Panicker static fru_regdef_t * 228*6bbe0590SSundeep Panicker alloc_unknown_fru_regdef(void) 229*6bbe0590SSundeep Panicker { 230*6bbe0590SSundeep Panicker fru_regdef_t *p; 231*6bbe0590SSundeep Panicker 232*6bbe0590SSundeep Panicker p = malloc(sizeof (fru_regdef_t)); 233*6bbe0590SSundeep Panicker if (!p) { 234*6bbe0590SSundeep Panicker return (NULL); 235*6bbe0590SSundeep Panicker } 236*6bbe0590SSundeep Panicker p->version = REGDEF_VERSION; 237*6bbe0590SSundeep Panicker p->name = NULL; 238*6bbe0590SSundeep Panicker p->tagType = -1; 239*6bbe0590SSundeep Panicker p->tagDense = -1; 240*6bbe0590SSundeep Panicker p->payloadLen = -1; 241*6bbe0590SSundeep Panicker p->dataLength = -1; 242*6bbe0590SSundeep Panicker p->dataType = FDTYPE_ByteArray; 243*6bbe0590SSundeep Panicker p->dispType = FDISP_Hex; 244*6bbe0590SSundeep Panicker p->purgeable = FRU_WHICH_UNDEFINED; 245*6bbe0590SSundeep Panicker p->relocatable = FRU_WHICH_UNDEFINED; 246*6bbe0590SSundeep Panicker p->enumCount = 0; 247*6bbe0590SSundeep Panicker p-> enumTable = NULL; 248*6bbe0590SSundeep Panicker p->iterationCount = 0; 249*6bbe0590SSundeep Panicker p->iterationType = FRU_NOT_ITERATED; 250*6bbe0590SSundeep Panicker p->exampleString = NULL; 251*6bbe0590SSundeep Panicker 252*6bbe0590SSundeep Panicker return (p); 253*6bbe0590SSundeep Panicker } 254*6bbe0590SSundeep Panicker 255*6bbe0590SSundeep Panicker static int 256*6bbe0590SSundeep Panicker convert_packet(fru_tag_t *tag, uint8_t *payload, size_t length, void *args) 257*6bbe0590SSundeep Panicker { 258*6bbe0590SSundeep Panicker int tag_type; 259*6bbe0590SSundeep Panicker size_t payload_length; 260*6bbe0590SSundeep Panicker const fru_regdef_t *def; 261*6bbe0590SSundeep Panicker nvlist_t *nv = (nvlist_t *)args; 262*6bbe0590SSundeep Panicker char tagname[sizeof ("?_0123456789_0123456789")]; 263*6bbe0590SSundeep Panicker tag_type = get_tag_type(tag); 264*6bbe0590SSundeep Panicker payload_length = 0; 265*6bbe0590SSundeep Panicker 266*6bbe0590SSundeep Panicker /* check for unrecognized tag */ 267*6bbe0590SSundeep Panicker if ((tag_type == -1) || 268*6bbe0590SSundeep Panicker ((payload_length = get_payload_length(tag)) != length)) { 269*6bbe0590SSundeep Panicker fru_regdef_t *unknown; 270*6bbe0590SSundeep Panicker 271*6bbe0590SSundeep Panicker unknown = alloc_unknown_fru_regdef(); 272*6bbe0590SSundeep Panicker unknown->payloadLen = length; 273*6bbe0590SSundeep Panicker unknown->dataLength = unknown->payloadLen; 274*6bbe0590SSundeep Panicker 275*6bbe0590SSundeep Panicker if (tag_type == -1) { 276*6bbe0590SSundeep Panicker (void) snprintf(tagname, sizeof (tagname), 277*6bbe0590SSundeep Panicker "INVALID"); 278*6bbe0590SSundeep Panicker } else { 279*6bbe0590SSundeep Panicker (void) snprintf(tagname, sizeof (tagname), 280*6bbe0590SSundeep Panicker "%s_%u_%u_%u", get_tagtype_str(tag_type), 281*6bbe0590SSundeep Panicker get_tag_dense(tag), payload_length, length); 282*6bbe0590SSundeep Panicker } 283*6bbe0590SSundeep Panicker unknown->name = tagname; 284*6bbe0590SSundeep Panicker convert_element(payload, unknown, "", nv, B_FALSE); 285*6bbe0590SSundeep Panicker free(unknown); 286*6bbe0590SSundeep Panicker 287*6bbe0590SSundeep Panicker } else if ((def = fru_reg_lookup_def_by_tag(*tag)) == NULL) { 288*6bbe0590SSundeep Panicker fru_regdef_t *unknown; 289*6bbe0590SSundeep Panicker 290*6bbe0590SSundeep Panicker unknown = alloc_unknown_fru_regdef(); 291*6bbe0590SSundeep Panicker unknown->payloadLen = length; 292*6bbe0590SSundeep Panicker unknown->dataLength = unknown->payloadLen; 293*6bbe0590SSundeep Panicker 294*6bbe0590SSundeep Panicker (void) snprintf(tagname, sizeof (tagname), "%s_%u_%u", 295*6bbe0590SSundeep Panicker get_tagtype_str(tag_type), 296*6bbe0590SSundeep Panicker unknown->tagDense, payload_length); 297*6bbe0590SSundeep Panicker 298*6bbe0590SSundeep Panicker unknown->name = tagname; 299*6bbe0590SSundeep Panicker convert_element(payload, unknown, "", nv, B_FALSE); 300*6bbe0590SSundeep Panicker free(unknown); 301*6bbe0590SSundeep Panicker 302*6bbe0590SSundeep Panicker } else { 303*6bbe0590SSundeep Panicker 304*6bbe0590SSundeep Panicker convert_element(payload, def, "", nv, B_FALSE); 305*6bbe0590SSundeep Panicker 306*6bbe0590SSundeep Panicker } 307*6bbe0590SSundeep Panicker 308*6bbe0590SSundeep Panicker return (FRU_SUCCESS); 309*6bbe0590SSundeep Panicker } 310*6bbe0590SSundeep Panicker 311*6bbe0590SSundeep Panicker 312*6bbe0590SSundeep Panicker static int 313*6bbe0590SSundeep Panicker convert_packets_in_segment(fru_seghdl_t segment, void *args) 314*6bbe0590SSundeep Panicker { 315*6bbe0590SSundeep Panicker char *name; 316*6bbe0590SSundeep Panicker int ret; 317*6bbe0590SSundeep Panicker nvlist_t *nv = (nvlist_t *)args; 318*6bbe0590SSundeep Panicker nvlist_t *nv_segment; 319*6bbe0590SSundeep Panicker 320*6bbe0590SSundeep Panicker ret = fru_get_segment_name(segment, &name); 321*6bbe0590SSundeep Panicker if (ret != FRU_SUCCESS) { 322*6bbe0590SSundeep Panicker return (ret); 323*6bbe0590SSundeep Panicker } 324*6bbe0590SSundeep Panicker 325*6bbe0590SSundeep Panicker /* create a new nvlist for each segment */ 326*6bbe0590SSundeep Panicker ret = nvlist_alloc(&nv_segment, 0, 0); 327*6bbe0590SSundeep Panicker if (ret) { 328*6bbe0590SSundeep Panicker free(name); 329*6bbe0590SSundeep Panicker return (FRU_FAILURE); 330*6bbe0590SSundeep Panicker } 331*6bbe0590SSundeep Panicker 332*6bbe0590SSundeep Panicker /* convert the segment to an nvlist */ 333*6bbe0590SSundeep Panicker ret = fru_for_each_packet(segment, convert_packet, nv_segment); 334*6bbe0590SSundeep Panicker if (ret != FRU_SUCCESS) { 335*6bbe0590SSundeep Panicker nvlist_free(nv_segment); 336*6bbe0590SSundeep Panicker free(name); 337*6bbe0590SSundeep Panicker return (ret); 338*6bbe0590SSundeep Panicker } 339*6bbe0590SSundeep Panicker 340*6bbe0590SSundeep Panicker /* add the nvlist for this segment */ 341*6bbe0590SSundeep Panicker (void) nvlist_add_nvlist(nv, name, nv_segment); 342*6bbe0590SSundeep Panicker 343*6bbe0590SSundeep Panicker free(name); 344*6bbe0590SSundeep Panicker 345*6bbe0590SSundeep Panicker return (FRU_SUCCESS); 346*6bbe0590SSundeep Panicker } 347*6bbe0590SSundeep Panicker 348*6bbe0590SSundeep Panicker 349*6bbe0590SSundeep Panicker static int 350*6bbe0590SSundeep Panicker convert_fru(fru_nodehdl_t hdl, nvlist_t **nvlist) 351*6bbe0590SSundeep Panicker { 352*6bbe0590SSundeep Panicker int err; 353*6bbe0590SSundeep Panicker nvlist_t *nv; 354*6bbe0590SSundeep Panicker fru_node_t fru_type; 355*6bbe0590SSundeep Panicker 356*6bbe0590SSundeep Panicker if (fru_get_node_type(hdl, &fru_type) != FRU_SUCCESS) { 357*6bbe0590SSundeep Panicker return (-1); 358*6bbe0590SSundeep Panicker } 359*6bbe0590SSundeep Panicker 360*6bbe0590SSundeep Panicker if (fru_type != FRU_NODE_CONTAINER) { 361*6bbe0590SSundeep Panicker return (-1); 362*6bbe0590SSundeep Panicker } 363*6bbe0590SSundeep Panicker 364*6bbe0590SSundeep Panicker err = nvlist_alloc(&nv, 0, 0); 365*6bbe0590SSundeep Panicker if (err) { 366*6bbe0590SSundeep Panicker return (err); 367*6bbe0590SSundeep Panicker } 368*6bbe0590SSundeep Panicker 369*6bbe0590SSundeep Panicker if (fru_for_each_segment(hdl, convert_packets_in_segment, nv) != 370*6bbe0590SSundeep Panicker FRU_SUCCESS) { 371*6bbe0590SSundeep Panicker nvlist_free(nv); 372*6bbe0590SSundeep Panicker return (-1); 373*6bbe0590SSundeep Panicker } 374*6bbe0590SSundeep Panicker 375*6bbe0590SSundeep Panicker *nvlist = nv; 376*6bbe0590SSundeep Panicker 377*6bbe0590SSundeep Panicker return (0); 378*6bbe0590SSundeep Panicker } 379*6bbe0590SSundeep Panicker 380*6bbe0590SSundeep Panicker 381*6bbe0590SSundeep Panicker int 382*6bbe0590SSundeep Panicker rawfru_to_nvlist(uint8_t *buffer, size_t bufsize, char *cont_type, 383*6bbe0590SSundeep Panicker nvlist_t **nvlist) 384*6bbe0590SSundeep Panicker { 385*6bbe0590SSundeep Panicker fru_errno_t fru_err; 386*6bbe0590SSundeep Panicker fru_nodehdl_t hdl; 387*6bbe0590SSundeep Panicker int err; 388*6bbe0590SSundeep Panicker 389*6bbe0590SSundeep Panicker (void) pthread_mutex_lock(&gLock); 390*6bbe0590SSundeep Panicker fru_err = fru_open_data_source("raw", buffer, bufsize, cont_type, 391*6bbe0590SSundeep Panicker NULL); 392*6bbe0590SSundeep Panicker if (fru_err != FRU_SUCCESS) { 393*6bbe0590SSundeep Panicker (void) pthread_mutex_unlock(&gLock); 394*6bbe0590SSundeep Panicker return (-1); 395*6bbe0590SSundeep Panicker } 396*6bbe0590SSundeep Panicker fru_err = fru_get_root(&hdl); 397*6bbe0590SSundeep Panicker if (fru_err != FRU_SUCCESS) { 398*6bbe0590SSundeep Panicker (void) pthread_mutex_unlock(&gLock); 399*6bbe0590SSundeep Panicker return (-1); 400*6bbe0590SSundeep Panicker } 401*6bbe0590SSundeep Panicker 402*6bbe0590SSundeep Panicker err = convert_fru(hdl, nvlist); 403*6bbe0590SSundeep Panicker 404*6bbe0590SSundeep Panicker fru_close_data_source(); 405*6bbe0590SSundeep Panicker 406*6bbe0590SSundeep Panicker (void) pthread_mutex_unlock(&gLock); 407*6bbe0590SSundeep Panicker 408*6bbe0590SSundeep Panicker return (err); 409*6bbe0590SSundeep Panicker } 410