16bbe0590SSundeep Panicker /* 26bbe0590SSundeep Panicker * CDDL HEADER START 36bbe0590SSundeep Panicker * 46bbe0590SSundeep Panicker * The contents of this file are subject to the terms of the 56bbe0590SSundeep Panicker * Common Development and Distribution License (the "License"). 66bbe0590SSundeep Panicker * You may not use this file except in compliance with the License. 76bbe0590SSundeep Panicker * 86bbe0590SSundeep Panicker * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 96bbe0590SSundeep Panicker * or http://www.opensolaris.org/os/licensing. 106bbe0590SSundeep Panicker * See the License for the specific language governing permissions 116bbe0590SSundeep Panicker * and limitations under the License. 126bbe0590SSundeep Panicker * 136bbe0590SSundeep Panicker * When distributing Covered Code, include this CDDL HEADER in each 146bbe0590SSundeep Panicker * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 156bbe0590SSundeep Panicker * If applicable, add the following below this CDDL HEADER, with the 166bbe0590SSundeep Panicker * fields enclosed by brackets "[]" replaced with your own identifying 176bbe0590SSundeep Panicker * information: Portions Copyright [yyyy] [name of copyright owner] 186bbe0590SSundeep Panicker * 196bbe0590SSundeep Panicker * CDDL HEADER END 206bbe0590SSundeep Panicker */ 216bbe0590SSundeep Panicker 226bbe0590SSundeep Panicker /* 23*ac88567aSHyon Kim * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 246bbe0590SSundeep Panicker */ 256bbe0590SSundeep Panicker 266bbe0590SSundeep Panicker #include <stdio.h> 276bbe0590SSundeep Panicker #include <stdlib.h> 286bbe0590SSundeep Panicker #include <stdint.h> 296bbe0590SSundeep Panicker #include <strings.h> 306bbe0590SSundeep Panicker #include <assert.h> 316bbe0590SSundeep Panicker #include <pthread.h> 326bbe0590SSundeep Panicker #include <sys/byteorder.h> 336bbe0590SSundeep Panicker #include <sys/types.h> 346bbe0590SSundeep Panicker #include <sys/nvpair.h> 356bbe0590SSundeep Panicker 366bbe0590SSundeep Panicker #include "libfru.h" 376bbe0590SSundeep Panicker #include "libfrup.h" 386bbe0590SSundeep Panicker #include "fru_tag.h" 396bbe0590SSundeep Panicker #include "libfrureg.h" 40d946b6ceSSundeep Panicker #include "nvfru.h" 416bbe0590SSundeep Panicker 426bbe0590SSundeep Panicker #define NUM_ITER_BYTES 4 436bbe0590SSundeep Panicker #define HEAD_ITER 0 446bbe0590SSundeep Panicker #define TAIL_ITER 1 456bbe0590SSundeep Panicker #define NUM_ITER 2 466bbe0590SSundeep Panicker #define MAX_ITER 3 476bbe0590SSundeep Panicker #define TIMESTRINGLEN 128 486bbe0590SSundeep Panicker 496bbe0590SSundeep Panicker #define PARSE_TIME 1 506bbe0590SSundeep Panicker 516bbe0590SSundeep Panicker static pthread_mutex_t gLock = PTHREAD_MUTEX_INITIALIZER; 526bbe0590SSundeep Panicker 536bbe0590SSundeep Panicker 546bbe0590SSundeep Panicker 556bbe0590SSundeep Panicker static void 566bbe0590SSundeep Panicker convert_field(const uint8_t *field, const fru_regdef_t *def, const char *path, 576bbe0590SSundeep Panicker nvlist_t *nv) 586bbe0590SSundeep Panicker { 596bbe0590SSundeep Panicker char timestring[TIMESTRINGLEN]; 606bbe0590SSundeep Panicker int i; 616bbe0590SSundeep Panicker uint64_t value; 626bbe0590SSundeep Panicker time_t timefield; 636bbe0590SSundeep Panicker 646bbe0590SSundeep Panicker switch (def->dataType) { 656bbe0590SSundeep Panicker case FDTYPE_Binary: 666bbe0590SSundeep Panicker assert(def->payloadLen <= sizeof (value)); 676bbe0590SSundeep Panicker switch (def->dispType) { 686bbe0590SSundeep Panicker #if PARSE_TIME == 1 696bbe0590SSundeep Panicker case FDISP_Time: 706bbe0590SSundeep Panicker if (def->payloadLen > sizeof (timefield)) { 716bbe0590SSundeep Panicker /* too big for formatting */ 726bbe0590SSundeep Panicker return; 736bbe0590SSundeep Panicker } 746bbe0590SSundeep Panicker (void) memcpy(&timefield, field, sizeof (timefield)); 756bbe0590SSundeep Panicker timefield = BE_32(timefield); 766bbe0590SSundeep Panicker if (strftime(timestring, sizeof (timestring), "%C", 776bbe0590SSundeep Panicker localtime(&timefield)) == 0) { 786bbe0590SSundeep Panicker /* buffer too small */ 796bbe0590SSundeep Panicker return; 806bbe0590SSundeep Panicker } 816bbe0590SSundeep Panicker (void) nvlist_add_string(nv, path, timestring); 826bbe0590SSundeep Panicker return; 836bbe0590SSundeep Panicker #endif 846bbe0590SSundeep Panicker 856bbe0590SSundeep Panicker case FDISP_Binary: 866bbe0590SSundeep Panicker case FDISP_Octal: 876bbe0590SSundeep Panicker case FDISP_Decimal: 886bbe0590SSundeep Panicker case FDISP_Hex: 896bbe0590SSundeep Panicker default: 906bbe0590SSundeep Panicker value = 0; 916bbe0590SSundeep Panicker (void) memcpy((((uint8_t *)&value) + 926bbe0590SSundeep Panicker sizeof (value) - def->payloadLen), 936bbe0590SSundeep Panicker field, def->payloadLen); 946bbe0590SSundeep Panicker value = BE_64(value); 956bbe0590SSundeep Panicker switch (def->payloadLen) { 966bbe0590SSundeep Panicker case 1: 976bbe0590SSundeep Panicker (void) nvlist_add_uint8(nv, path, 986bbe0590SSundeep Panicker (uint8_t)value); 996bbe0590SSundeep Panicker break; 1006bbe0590SSundeep Panicker case 2: 1016bbe0590SSundeep Panicker (void) nvlist_add_uint16(nv, path, 1026bbe0590SSundeep Panicker (uint16_t)value); 1036bbe0590SSundeep Panicker break; 1046bbe0590SSundeep Panicker case 4: 1056bbe0590SSundeep Panicker (void) nvlist_add_uint32(nv, path, 1066bbe0590SSundeep Panicker (uint32_t)value); 1076bbe0590SSundeep Panicker break; 1086bbe0590SSundeep Panicker default: 1096bbe0590SSundeep Panicker (void) nvlist_add_uint64(nv, path, value); 1106bbe0590SSundeep Panicker } 1116bbe0590SSundeep Panicker return; 1126bbe0590SSundeep Panicker } 1136bbe0590SSundeep Panicker 1146bbe0590SSundeep Panicker case FDTYPE_ASCII: 1156bbe0590SSundeep Panicker (void) nvlist_add_string(nv, path, (char *)field); 1166bbe0590SSundeep Panicker return; 1176bbe0590SSundeep Panicker 1186bbe0590SSundeep Panicker case FDTYPE_Enumeration: 1196bbe0590SSundeep Panicker value = 0; 1206bbe0590SSundeep Panicker (void) memcpy((((uint8_t *)&value) + sizeof (value) - 1216bbe0590SSundeep Panicker def->payloadLen), field, def->payloadLen); 1226bbe0590SSundeep Panicker value = BE_64(value); 1236bbe0590SSundeep Panicker for (i = 0; i < def->enumCount; i++) { 1246bbe0590SSundeep Panicker if (def->enumTable[i].value == value) { 1256bbe0590SSundeep Panicker (void) nvlist_add_string(nv, path, 1266bbe0590SSundeep Panicker def->enumTable[i].text); 1276bbe0590SSundeep Panicker return; 1286bbe0590SSundeep Panicker } 1296bbe0590SSundeep Panicker } 1306bbe0590SSundeep Panicker } 1316bbe0590SSundeep Panicker 1326bbe0590SSundeep Panicker /* nothing matched above, use byte array */ 1336bbe0590SSundeep Panicker (void) nvlist_add_byte_array(nv, path, (uchar_t *)field, 1346bbe0590SSundeep Panicker def->payloadLen); 1356bbe0590SSundeep Panicker } 1366bbe0590SSundeep Panicker 1376bbe0590SSundeep Panicker 1386bbe0590SSundeep Panicker 1396bbe0590SSundeep Panicker static void 1406bbe0590SSundeep Panicker convert_element(const uint8_t *data, const fru_regdef_t *def, char *ppath, 1416bbe0590SSundeep Panicker nvlist_t *nv, boolean_t from_iter) 1426bbe0590SSundeep Panicker { 1436bbe0590SSundeep Panicker int i; 1446bbe0590SSundeep Panicker char *path; 1456bbe0590SSundeep Panicker 1466bbe0590SSundeep Panicker /* construct path */ 1476bbe0590SSundeep Panicker if ((def->iterationCount == 0) && 1486bbe0590SSundeep Panicker (def->iterationType != FRU_NOT_ITERATED)) { 1496bbe0590SSundeep Panicker path = ppath; 1506bbe0590SSundeep Panicker } else { 1516bbe0590SSundeep Panicker path = (char *)def->name; 1526bbe0590SSundeep Panicker } 1536bbe0590SSundeep Panicker 1546bbe0590SSundeep Panicker /* iteration, record and field */ 1556bbe0590SSundeep Panicker if (def->iterationCount) { 1566bbe0590SSundeep Panicker int iterlen, n; 1576bbe0590SSundeep Panicker uint8_t head, num; 1586bbe0590SSundeep Panicker fru_regdef_t newdef; 1596bbe0590SSundeep Panicker nvlist_t **nv_elems; 1606bbe0590SSundeep Panicker char num_str[32]; 1616bbe0590SSundeep Panicker 1626bbe0590SSundeep Panicker iterlen = (def->payloadLen - NUM_ITER_BYTES) / 1636bbe0590SSundeep Panicker def->iterationCount; 1646bbe0590SSundeep Panicker 1656bbe0590SSundeep Panicker /* 1666bbe0590SSundeep Panicker * make a new element definition to describe the components of 1676bbe0590SSundeep Panicker * the iteration. 1686bbe0590SSundeep Panicker */ 1696bbe0590SSundeep Panicker (void) memcpy(&newdef, def, sizeof (newdef)); 1706bbe0590SSundeep Panicker newdef.iterationCount = 0; 1716bbe0590SSundeep Panicker newdef.payloadLen = iterlen; 1726bbe0590SSundeep Panicker 1736bbe0590SSundeep Panicker /* validate the content of the iteration control bytes */ 1746bbe0590SSundeep Panicker if ((data[HEAD_ITER] >= def->iterationCount) || 1756bbe0590SSundeep Panicker (data[NUM_ITER] > def->iterationCount) || 1766bbe0590SSundeep Panicker (data[MAX_ITER] != def->iterationCount)) { 1776bbe0590SSundeep Panicker /* invalid. show all iterations */ 1786bbe0590SSundeep Panicker head = 0; 1796bbe0590SSundeep Panicker num = def->iterationCount; 1806bbe0590SSundeep Panicker } else { 1816bbe0590SSundeep Panicker head = data[HEAD_ITER]; 1826bbe0590SSundeep Panicker num = data[NUM_ITER]; 1836bbe0590SSundeep Panicker } 1846bbe0590SSundeep Panicker 1856bbe0590SSundeep Panicker nv_elems = (nvlist_t **)malloc(num * sizeof (nvlist_t *)); 1866bbe0590SSundeep Panicker if (!nv_elems) 1876bbe0590SSundeep Panicker return; 1886bbe0590SSundeep Panicker for (i = head, n = 0, data += sizeof (uint32_t); n < num; 1896bbe0590SSundeep Panicker i = ((i + 1) % def->iterationCount), n++) { 190*ac88567aSHyon Kim if (nvlist_alloc(&nv_elems[n], NV_UNIQUE_NAME, 0) != 0) 1916bbe0590SSundeep Panicker return; 1926bbe0590SSundeep Panicker (void) snprintf(num_str, sizeof (num_str), "%d", n); 1936bbe0590SSundeep Panicker convert_element((data + i*iterlen), &newdef, num_str, 1946bbe0590SSundeep Panicker nv_elems[n], B_TRUE); 1956bbe0590SSundeep Panicker } 1966bbe0590SSundeep Panicker (void) nvlist_add_nvlist_array(nv, path, nv_elems, num); 1976bbe0590SSundeep Panicker 1986bbe0590SSundeep Panicker } else if (def->dataType == FDTYPE_Record) { 1996bbe0590SSundeep Panicker const fru_regdef_t *component; 2006bbe0590SSundeep Panicker nvlist_t *nv_record; 2016bbe0590SSundeep Panicker 2026bbe0590SSundeep Panicker if (!from_iter) { 203*ac88567aSHyon Kim if (nvlist_alloc(&nv_record, NV_UNIQUE_NAME, 0) != 0) { 2046bbe0590SSundeep Panicker return; 2056bbe0590SSundeep Panicker } 2066bbe0590SSundeep Panicker } else { 2076bbe0590SSundeep Panicker nv_record = nv; 2086bbe0590SSundeep Panicker } 2096bbe0590SSundeep Panicker 2106bbe0590SSundeep Panicker for (i = 0; i < def->enumCount; i++, 2116bbe0590SSundeep Panicker data += component->payloadLen) { 2126bbe0590SSundeep Panicker component = fru_reg_lookup_def_by_name( 2136bbe0590SSundeep Panicker def->enumTable[i].text); 2146bbe0590SSundeep Panicker convert_element(data, component, "", nv_record, 2156bbe0590SSundeep Panicker B_FALSE); 2166bbe0590SSundeep Panicker } 2176bbe0590SSundeep Panicker 2186bbe0590SSundeep Panicker (void) nvlist_add_nvlist(nv, path, nv_record); 2196bbe0590SSundeep Panicker 2206bbe0590SSundeep Panicker } else { 2216bbe0590SSundeep Panicker convert_field(data, def, path, nv); 2226bbe0590SSundeep Panicker } 2236bbe0590SSundeep Panicker } 2246bbe0590SSundeep Panicker 2256bbe0590SSundeep Panicker 2266bbe0590SSundeep Panicker static fru_regdef_t * 2276bbe0590SSundeep Panicker alloc_unknown_fru_regdef(void) 2286bbe0590SSundeep Panicker { 2296bbe0590SSundeep Panicker fru_regdef_t *p; 2306bbe0590SSundeep Panicker 2316bbe0590SSundeep Panicker p = malloc(sizeof (fru_regdef_t)); 2326bbe0590SSundeep Panicker if (!p) { 2336bbe0590SSundeep Panicker return (NULL); 2346bbe0590SSundeep Panicker } 2356bbe0590SSundeep Panicker p->version = REGDEF_VERSION; 2366bbe0590SSundeep Panicker p->name = NULL; 2376bbe0590SSundeep Panicker p->tagType = -1; 2386bbe0590SSundeep Panicker p->tagDense = -1; 2396bbe0590SSundeep Panicker p->payloadLen = -1; 2406bbe0590SSundeep Panicker p->dataLength = -1; 2416bbe0590SSundeep Panicker p->dataType = FDTYPE_ByteArray; 2426bbe0590SSundeep Panicker p->dispType = FDISP_Hex; 2436bbe0590SSundeep Panicker p->purgeable = FRU_WHICH_UNDEFINED; 2446bbe0590SSundeep Panicker p->relocatable = FRU_WHICH_UNDEFINED; 2456bbe0590SSundeep Panicker p->enumCount = 0; 2466bbe0590SSundeep Panicker p-> enumTable = NULL; 2476bbe0590SSundeep Panicker p->iterationCount = 0; 2486bbe0590SSundeep Panicker p->iterationType = FRU_NOT_ITERATED; 2496bbe0590SSundeep Panicker p->exampleString = NULL; 2506bbe0590SSundeep Panicker 2516bbe0590SSundeep Panicker return (p); 2526bbe0590SSundeep Panicker } 2536bbe0590SSundeep Panicker 2546bbe0590SSundeep Panicker static int 2556bbe0590SSundeep Panicker convert_packet(fru_tag_t *tag, uint8_t *payload, size_t length, void *args) 2566bbe0590SSundeep Panicker { 2576bbe0590SSundeep Panicker int tag_type; 2586bbe0590SSundeep Panicker size_t payload_length; 2596bbe0590SSundeep Panicker const fru_regdef_t *def; 2606bbe0590SSundeep Panicker nvlist_t *nv = (nvlist_t *)args; 2616bbe0590SSundeep Panicker char tagname[sizeof ("?_0123456789_0123456789")]; 2626bbe0590SSundeep Panicker tag_type = get_tag_type(tag); 2636bbe0590SSundeep Panicker payload_length = 0; 2646bbe0590SSundeep Panicker 2656bbe0590SSundeep Panicker /* check for unrecognized tag */ 2666bbe0590SSundeep Panicker if ((tag_type == -1) || 2676bbe0590SSundeep Panicker ((payload_length = get_payload_length(tag)) != length)) { 2686bbe0590SSundeep Panicker fru_regdef_t *unknown; 2696bbe0590SSundeep Panicker 2706bbe0590SSundeep Panicker unknown = alloc_unknown_fru_regdef(); 2716bbe0590SSundeep Panicker unknown->payloadLen = length; 2726bbe0590SSundeep Panicker unknown->dataLength = unknown->payloadLen; 2736bbe0590SSundeep Panicker 2746bbe0590SSundeep Panicker if (tag_type == -1) { 2756bbe0590SSundeep Panicker (void) snprintf(tagname, sizeof (tagname), 2766bbe0590SSundeep Panicker "INVALID"); 2776bbe0590SSundeep Panicker } else { 2786bbe0590SSundeep Panicker (void) snprintf(tagname, sizeof (tagname), 2796bbe0590SSundeep Panicker "%s_%u_%u_%u", get_tagtype_str(tag_type), 2806bbe0590SSundeep Panicker get_tag_dense(tag), payload_length, length); 2816bbe0590SSundeep Panicker } 2826bbe0590SSundeep Panicker unknown->name = tagname; 2836bbe0590SSundeep Panicker convert_element(payload, unknown, "", nv, B_FALSE); 2846bbe0590SSundeep Panicker free(unknown); 2856bbe0590SSundeep Panicker 2866bbe0590SSundeep Panicker } else if ((def = fru_reg_lookup_def_by_tag(*tag)) == NULL) { 2876bbe0590SSundeep Panicker fru_regdef_t *unknown; 2886bbe0590SSundeep Panicker 2896bbe0590SSundeep Panicker unknown = alloc_unknown_fru_regdef(); 2906bbe0590SSundeep Panicker unknown->payloadLen = length; 2916bbe0590SSundeep Panicker unknown->dataLength = unknown->payloadLen; 2926bbe0590SSundeep Panicker 2936bbe0590SSundeep Panicker (void) snprintf(tagname, sizeof (tagname), "%s_%u_%u", 2946bbe0590SSundeep Panicker get_tagtype_str(tag_type), 2956bbe0590SSundeep Panicker unknown->tagDense, payload_length); 2966bbe0590SSundeep Panicker 2976bbe0590SSundeep Panicker unknown->name = tagname; 2986bbe0590SSundeep Panicker convert_element(payload, unknown, "", nv, B_FALSE); 2996bbe0590SSundeep Panicker free(unknown); 3006bbe0590SSundeep Panicker 3016bbe0590SSundeep Panicker } else { 3026bbe0590SSundeep Panicker 3036bbe0590SSundeep Panicker convert_element(payload, def, "", nv, B_FALSE); 3046bbe0590SSundeep Panicker 3056bbe0590SSundeep Panicker } 3066bbe0590SSundeep Panicker 3076bbe0590SSundeep Panicker return (FRU_SUCCESS); 3086bbe0590SSundeep Panicker } 3096bbe0590SSundeep Panicker 3106bbe0590SSundeep Panicker 3116bbe0590SSundeep Panicker static int 3126bbe0590SSundeep Panicker convert_packets_in_segment(fru_seghdl_t segment, void *args) 3136bbe0590SSundeep Panicker { 3146bbe0590SSundeep Panicker char *name; 3156bbe0590SSundeep Panicker int ret; 3166bbe0590SSundeep Panicker nvlist_t *nv = (nvlist_t *)args; 3176bbe0590SSundeep Panicker nvlist_t *nv_segment; 3186bbe0590SSundeep Panicker 3196bbe0590SSundeep Panicker ret = fru_get_segment_name(segment, &name); 3206bbe0590SSundeep Panicker if (ret != FRU_SUCCESS) { 3216bbe0590SSundeep Panicker return (ret); 3226bbe0590SSundeep Panicker } 3236bbe0590SSundeep Panicker 3246bbe0590SSundeep Panicker /* create a new nvlist for each segment */ 325*ac88567aSHyon Kim ret = nvlist_alloc(&nv_segment, NV_UNIQUE_NAME, 0); 3266bbe0590SSundeep Panicker if (ret) { 3276bbe0590SSundeep Panicker free(name); 3286bbe0590SSundeep Panicker return (FRU_FAILURE); 3296bbe0590SSundeep Panicker } 3306bbe0590SSundeep Panicker 3316bbe0590SSundeep Panicker /* convert the segment to an nvlist */ 3326bbe0590SSundeep Panicker ret = fru_for_each_packet(segment, convert_packet, nv_segment); 3336bbe0590SSundeep Panicker if (ret != FRU_SUCCESS) { 3346bbe0590SSundeep Panicker nvlist_free(nv_segment); 3356bbe0590SSundeep Panicker free(name); 3366bbe0590SSundeep Panicker return (ret); 3376bbe0590SSundeep Panicker } 3386bbe0590SSundeep Panicker 3396bbe0590SSundeep Panicker /* add the nvlist for this segment */ 3406bbe0590SSundeep Panicker (void) nvlist_add_nvlist(nv, name, nv_segment); 3416bbe0590SSundeep Panicker 3426bbe0590SSundeep Panicker free(name); 3436bbe0590SSundeep Panicker 3446bbe0590SSundeep Panicker return (FRU_SUCCESS); 3456bbe0590SSundeep Panicker } 3466bbe0590SSundeep Panicker 3476bbe0590SSundeep Panicker 3486bbe0590SSundeep Panicker static int 3496bbe0590SSundeep Panicker convert_fru(fru_nodehdl_t hdl, nvlist_t **nvlist) 3506bbe0590SSundeep Panicker { 3516bbe0590SSundeep Panicker int err; 3526bbe0590SSundeep Panicker nvlist_t *nv; 3536bbe0590SSundeep Panicker fru_node_t fru_type; 3546bbe0590SSundeep Panicker 3556bbe0590SSundeep Panicker if (fru_get_node_type(hdl, &fru_type) != FRU_SUCCESS) { 3566bbe0590SSundeep Panicker return (-1); 3576bbe0590SSundeep Panicker } 3586bbe0590SSundeep Panicker 3596bbe0590SSundeep Panicker if (fru_type != FRU_NODE_CONTAINER) { 3606bbe0590SSundeep Panicker return (-1); 3616bbe0590SSundeep Panicker } 3626bbe0590SSundeep Panicker 363*ac88567aSHyon Kim err = nvlist_alloc(&nv, NV_UNIQUE_NAME, 0); 3646bbe0590SSundeep Panicker if (err) { 3656bbe0590SSundeep Panicker return (err); 3666bbe0590SSundeep Panicker } 3676bbe0590SSundeep Panicker 3686bbe0590SSundeep Panicker if (fru_for_each_segment(hdl, convert_packets_in_segment, nv) != 3696bbe0590SSundeep Panicker FRU_SUCCESS) { 3706bbe0590SSundeep Panicker nvlist_free(nv); 3716bbe0590SSundeep Panicker return (-1); 3726bbe0590SSundeep Panicker } 3736bbe0590SSundeep Panicker 3746bbe0590SSundeep Panicker *nvlist = nv; 3756bbe0590SSundeep Panicker 3766bbe0590SSundeep Panicker return (0); 3776bbe0590SSundeep Panicker } 3786bbe0590SSundeep Panicker 3796bbe0590SSundeep Panicker 3806bbe0590SSundeep Panicker int 3816bbe0590SSundeep Panicker rawfru_to_nvlist(uint8_t *buffer, size_t bufsize, char *cont_type, 3826bbe0590SSundeep Panicker nvlist_t **nvlist) 3836bbe0590SSundeep Panicker { 3846bbe0590SSundeep Panicker fru_errno_t fru_err; 3856bbe0590SSundeep Panicker fru_nodehdl_t hdl; 3866bbe0590SSundeep Panicker int err; 3876bbe0590SSundeep Panicker 3886bbe0590SSundeep Panicker (void) pthread_mutex_lock(&gLock); 3896bbe0590SSundeep Panicker fru_err = fru_open_data_source("raw", buffer, bufsize, cont_type, 3906bbe0590SSundeep Panicker NULL); 3916bbe0590SSundeep Panicker if (fru_err != FRU_SUCCESS) { 3926bbe0590SSundeep Panicker (void) pthread_mutex_unlock(&gLock); 3936bbe0590SSundeep Panicker return (-1); 3946bbe0590SSundeep Panicker } 3956bbe0590SSundeep Panicker fru_err = fru_get_root(&hdl); 3966bbe0590SSundeep Panicker if (fru_err != FRU_SUCCESS) { 3976bbe0590SSundeep Panicker (void) pthread_mutex_unlock(&gLock); 3986bbe0590SSundeep Panicker return (-1); 3996bbe0590SSundeep Panicker } 4006bbe0590SSundeep Panicker 4016bbe0590SSundeep Panicker err = convert_fru(hdl, nvlist); 4026bbe0590SSundeep Panicker 4036bbe0590SSundeep Panicker fru_close_data_source(); 4046bbe0590SSundeep Panicker 4056bbe0590SSundeep Panicker (void) pthread_mutex_unlock(&gLock); 4066bbe0590SSundeep Panicker 4076bbe0590SSundeep Panicker return (err); 4086bbe0590SSundeep Panicker } 409