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