111015SSundeep.Panicker@Sun.COM /*
211015SSundeep.Panicker@Sun.COM * CDDL HEADER START
311015SSundeep.Panicker@Sun.COM *
411015SSundeep.Panicker@Sun.COM * The contents of this file are subject to the terms of the
511015SSundeep.Panicker@Sun.COM * Common Development and Distribution License (the "License").
611015SSundeep.Panicker@Sun.COM * You may not use this file except in compliance with the License.
711015SSundeep.Panicker@Sun.COM *
811015SSundeep.Panicker@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911015SSundeep.Panicker@Sun.COM * or http://www.opensolaris.org/os/licensing.
1011015SSundeep.Panicker@Sun.COM * See the License for the specific language governing permissions
1111015SSundeep.Panicker@Sun.COM * and limitations under the License.
1211015SSundeep.Panicker@Sun.COM *
1311015SSundeep.Panicker@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
1411015SSundeep.Panicker@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1511015SSundeep.Panicker@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
1611015SSundeep.Panicker@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
1711015SSundeep.Panicker@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
1811015SSundeep.Panicker@Sun.COM *
1911015SSundeep.Panicker@Sun.COM * CDDL HEADER END
2011015SSundeep.Panicker@Sun.COM */
2111015SSundeep.Panicker@Sun.COM
2211015SSundeep.Panicker@Sun.COM /*
23*12126SHyon.Kim@Sun.COM * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2411015SSundeep.Panicker@Sun.COM */
2511015SSundeep.Panicker@Sun.COM
2611015SSundeep.Panicker@Sun.COM #include <stdio.h>
2711015SSundeep.Panicker@Sun.COM #include <stdlib.h>
2811015SSundeep.Panicker@Sun.COM #include <stdint.h>
2911015SSundeep.Panicker@Sun.COM #include <strings.h>
3011015SSundeep.Panicker@Sun.COM #include <assert.h>
3111015SSundeep.Panicker@Sun.COM #include <pthread.h>
3211015SSundeep.Panicker@Sun.COM #include <sys/byteorder.h>
3311015SSundeep.Panicker@Sun.COM #include <sys/types.h>
3411015SSundeep.Panicker@Sun.COM #include <sys/nvpair.h>
3511015SSundeep.Panicker@Sun.COM
3611015SSundeep.Panicker@Sun.COM #include "libfru.h"
3711015SSundeep.Panicker@Sun.COM #include "libfrup.h"
3811015SSundeep.Panicker@Sun.COM #include "fru_tag.h"
3911015SSundeep.Panicker@Sun.COM #include "libfrureg.h"
4011063SSundeep.Panicker@Sun.COM #include "nvfru.h"
4111015SSundeep.Panicker@Sun.COM
4211015SSundeep.Panicker@Sun.COM #define NUM_ITER_BYTES 4
4311063SSundeep.Panicker@Sun.COM #define HEAD_ITER 0
4411015SSundeep.Panicker@Sun.COM #define TAIL_ITER 1
4511015SSundeep.Panicker@Sun.COM #define NUM_ITER 2
4611015SSundeep.Panicker@Sun.COM #define MAX_ITER 3
4711015SSundeep.Panicker@Sun.COM #define TIMESTRINGLEN 128
4811015SSundeep.Panicker@Sun.COM
4911015SSundeep.Panicker@Sun.COM #define PARSE_TIME 1
5011015SSundeep.Panicker@Sun.COM
5111015SSundeep.Panicker@Sun.COM static pthread_mutex_t gLock = PTHREAD_MUTEX_INITIALIZER;
5211015SSundeep.Panicker@Sun.COM
5311015SSundeep.Panicker@Sun.COM
5411015SSundeep.Panicker@Sun.COM
5511015SSundeep.Panicker@Sun.COM static void
convert_field(const uint8_t * field,const fru_regdef_t * def,const char * path,nvlist_t * nv)5611015SSundeep.Panicker@Sun.COM convert_field(const uint8_t *field, const fru_regdef_t *def, const char *path,
5711015SSundeep.Panicker@Sun.COM nvlist_t *nv)
5811015SSundeep.Panicker@Sun.COM {
5911015SSundeep.Panicker@Sun.COM char timestring[TIMESTRINGLEN];
6011015SSundeep.Panicker@Sun.COM int i;
6111015SSundeep.Panicker@Sun.COM uint64_t value;
6211015SSundeep.Panicker@Sun.COM time_t timefield;
6311015SSundeep.Panicker@Sun.COM
6411015SSundeep.Panicker@Sun.COM switch (def->dataType) {
6511015SSundeep.Panicker@Sun.COM case FDTYPE_Binary:
6611015SSundeep.Panicker@Sun.COM assert(def->payloadLen <= sizeof (value));
6711015SSundeep.Panicker@Sun.COM switch (def->dispType) {
6811015SSundeep.Panicker@Sun.COM #if PARSE_TIME == 1
6911015SSundeep.Panicker@Sun.COM case FDISP_Time:
7011015SSundeep.Panicker@Sun.COM if (def->payloadLen > sizeof (timefield)) {
7111015SSundeep.Panicker@Sun.COM /* too big for formatting */
7211015SSundeep.Panicker@Sun.COM return;
7311015SSundeep.Panicker@Sun.COM }
7411015SSundeep.Panicker@Sun.COM (void) memcpy(&timefield, field, sizeof (timefield));
7511015SSundeep.Panicker@Sun.COM timefield = BE_32(timefield);
7611015SSundeep.Panicker@Sun.COM if (strftime(timestring, sizeof (timestring), "%C",
7711015SSundeep.Panicker@Sun.COM localtime(&timefield)) == 0) {
7811015SSundeep.Panicker@Sun.COM /* buffer too small */
7911015SSundeep.Panicker@Sun.COM return;
8011015SSundeep.Panicker@Sun.COM }
8111015SSundeep.Panicker@Sun.COM (void) nvlist_add_string(nv, path, timestring);
8211015SSundeep.Panicker@Sun.COM return;
8311015SSundeep.Panicker@Sun.COM #endif
8411015SSundeep.Panicker@Sun.COM
8511015SSundeep.Panicker@Sun.COM case FDISP_Binary:
8611015SSundeep.Panicker@Sun.COM case FDISP_Octal:
8711015SSundeep.Panicker@Sun.COM case FDISP_Decimal:
8811015SSundeep.Panicker@Sun.COM case FDISP_Hex:
8911015SSundeep.Panicker@Sun.COM default:
9011015SSundeep.Panicker@Sun.COM value = 0;
9111015SSundeep.Panicker@Sun.COM (void) memcpy((((uint8_t *)&value) +
9211015SSundeep.Panicker@Sun.COM sizeof (value) - def->payloadLen),
9311015SSundeep.Panicker@Sun.COM field, def->payloadLen);
9411015SSundeep.Panicker@Sun.COM value = BE_64(value);
9511015SSundeep.Panicker@Sun.COM switch (def->payloadLen) {
9611015SSundeep.Panicker@Sun.COM case 1:
9711015SSundeep.Panicker@Sun.COM (void) nvlist_add_uint8(nv, path,
9811015SSundeep.Panicker@Sun.COM (uint8_t)value);
9911015SSundeep.Panicker@Sun.COM break;
10011015SSundeep.Panicker@Sun.COM case 2:
10111015SSundeep.Panicker@Sun.COM (void) nvlist_add_uint16(nv, path,
10211015SSundeep.Panicker@Sun.COM (uint16_t)value);
10311015SSundeep.Panicker@Sun.COM break;
10411015SSundeep.Panicker@Sun.COM case 4:
10511015SSundeep.Panicker@Sun.COM (void) nvlist_add_uint32(nv, path,
10611015SSundeep.Panicker@Sun.COM (uint32_t)value);
10711015SSundeep.Panicker@Sun.COM break;
10811015SSundeep.Panicker@Sun.COM default:
10911015SSundeep.Panicker@Sun.COM (void) nvlist_add_uint64(nv, path, value);
11011015SSundeep.Panicker@Sun.COM }
11111015SSundeep.Panicker@Sun.COM return;
11211015SSundeep.Panicker@Sun.COM }
11311015SSundeep.Panicker@Sun.COM
11411015SSundeep.Panicker@Sun.COM case FDTYPE_ASCII:
11511015SSundeep.Panicker@Sun.COM (void) nvlist_add_string(nv, path, (char *)field);
11611015SSundeep.Panicker@Sun.COM return;
11711015SSundeep.Panicker@Sun.COM
11811015SSundeep.Panicker@Sun.COM case FDTYPE_Enumeration:
11911015SSundeep.Panicker@Sun.COM value = 0;
12011015SSundeep.Panicker@Sun.COM (void) memcpy((((uint8_t *)&value) + sizeof (value) -
12111015SSundeep.Panicker@Sun.COM def->payloadLen), field, def->payloadLen);
12211015SSundeep.Panicker@Sun.COM value = BE_64(value);
12311015SSundeep.Panicker@Sun.COM for (i = 0; i < def->enumCount; i++) {
12411015SSundeep.Panicker@Sun.COM if (def->enumTable[i].value == value) {
12511015SSundeep.Panicker@Sun.COM (void) nvlist_add_string(nv, path,
12611015SSundeep.Panicker@Sun.COM def->enumTable[i].text);
12711015SSundeep.Panicker@Sun.COM return;
12811015SSundeep.Panicker@Sun.COM }
12911015SSundeep.Panicker@Sun.COM }
13011015SSundeep.Panicker@Sun.COM }
13111015SSundeep.Panicker@Sun.COM
13211015SSundeep.Panicker@Sun.COM /* nothing matched above, use byte array */
13311015SSundeep.Panicker@Sun.COM (void) nvlist_add_byte_array(nv, path, (uchar_t *)field,
13411015SSundeep.Panicker@Sun.COM def->payloadLen);
13511015SSundeep.Panicker@Sun.COM }
13611015SSundeep.Panicker@Sun.COM
13711015SSundeep.Panicker@Sun.COM
13811015SSundeep.Panicker@Sun.COM
13911015SSundeep.Panicker@Sun.COM static void
convert_element(const uint8_t * data,const fru_regdef_t * def,char * ppath,nvlist_t * nv,boolean_t from_iter)14011015SSundeep.Panicker@Sun.COM convert_element(const uint8_t *data, const fru_regdef_t *def, char *ppath,
14111015SSundeep.Panicker@Sun.COM nvlist_t *nv, boolean_t from_iter)
14211015SSundeep.Panicker@Sun.COM {
14311015SSundeep.Panicker@Sun.COM int i;
14411015SSundeep.Panicker@Sun.COM char *path;
14511015SSundeep.Panicker@Sun.COM
14611015SSundeep.Panicker@Sun.COM /* construct path */
14711015SSundeep.Panicker@Sun.COM if ((def->iterationCount == 0) &&
14811015SSundeep.Panicker@Sun.COM (def->iterationType != FRU_NOT_ITERATED)) {
14911015SSundeep.Panicker@Sun.COM path = ppath;
15011015SSundeep.Panicker@Sun.COM } else {
15111015SSundeep.Panicker@Sun.COM path = (char *)def->name;
15211015SSundeep.Panicker@Sun.COM }
15311015SSundeep.Panicker@Sun.COM
15411015SSundeep.Panicker@Sun.COM /* iteration, record and field */
15511015SSundeep.Panicker@Sun.COM if (def->iterationCount) {
15611015SSundeep.Panicker@Sun.COM int iterlen, n;
15711015SSundeep.Panicker@Sun.COM uint8_t head, num;
15811015SSundeep.Panicker@Sun.COM fru_regdef_t newdef;
15911015SSundeep.Panicker@Sun.COM nvlist_t **nv_elems;
16011015SSundeep.Panicker@Sun.COM char num_str[32];
16111015SSundeep.Panicker@Sun.COM
16211015SSundeep.Panicker@Sun.COM iterlen = (def->payloadLen - NUM_ITER_BYTES) /
16311015SSundeep.Panicker@Sun.COM def->iterationCount;
16411015SSundeep.Panicker@Sun.COM
16511015SSundeep.Panicker@Sun.COM /*
16611015SSundeep.Panicker@Sun.COM * make a new element definition to describe the components of
16711015SSundeep.Panicker@Sun.COM * the iteration.
16811015SSundeep.Panicker@Sun.COM */
16911015SSundeep.Panicker@Sun.COM (void) memcpy(&newdef, def, sizeof (newdef));
17011015SSundeep.Panicker@Sun.COM newdef.iterationCount = 0;
17111015SSundeep.Panicker@Sun.COM newdef.payloadLen = iterlen;
17211015SSundeep.Panicker@Sun.COM
17311015SSundeep.Panicker@Sun.COM /* validate the content of the iteration control bytes */
17411015SSundeep.Panicker@Sun.COM if ((data[HEAD_ITER] >= def->iterationCount) ||
17511015SSundeep.Panicker@Sun.COM (data[NUM_ITER] > def->iterationCount) ||
17611015SSundeep.Panicker@Sun.COM (data[MAX_ITER] != def->iterationCount)) {
17711015SSundeep.Panicker@Sun.COM /* invalid. show all iterations */
17811015SSundeep.Panicker@Sun.COM head = 0;
17911015SSundeep.Panicker@Sun.COM num = def->iterationCount;
18011015SSundeep.Panicker@Sun.COM } else {
18111015SSundeep.Panicker@Sun.COM head = data[HEAD_ITER];
18211015SSundeep.Panicker@Sun.COM num = data[NUM_ITER];
18311015SSundeep.Panicker@Sun.COM }
18411015SSundeep.Panicker@Sun.COM
18511015SSundeep.Panicker@Sun.COM nv_elems = (nvlist_t **)malloc(num * sizeof (nvlist_t *));
18611015SSundeep.Panicker@Sun.COM if (!nv_elems)
18711015SSundeep.Panicker@Sun.COM return;
18811015SSundeep.Panicker@Sun.COM for (i = head, n = 0, data += sizeof (uint32_t); n < num;
18911015SSundeep.Panicker@Sun.COM i = ((i + 1) % def->iterationCount), n++) {
190*12126SHyon.Kim@Sun.COM if (nvlist_alloc(&nv_elems[n], NV_UNIQUE_NAME, 0) != 0)
19111015SSundeep.Panicker@Sun.COM return;
19211015SSundeep.Panicker@Sun.COM (void) snprintf(num_str, sizeof (num_str), "%d", n);
19311015SSundeep.Panicker@Sun.COM convert_element((data + i*iterlen), &newdef, num_str,
19411015SSundeep.Panicker@Sun.COM nv_elems[n], B_TRUE);
19511015SSundeep.Panicker@Sun.COM }
19611015SSundeep.Panicker@Sun.COM (void) nvlist_add_nvlist_array(nv, path, nv_elems, num);
19711015SSundeep.Panicker@Sun.COM
19811015SSundeep.Panicker@Sun.COM } else if (def->dataType == FDTYPE_Record) {
19911015SSundeep.Panicker@Sun.COM const fru_regdef_t *component;
20011015SSundeep.Panicker@Sun.COM nvlist_t *nv_record;
20111015SSundeep.Panicker@Sun.COM
20211015SSundeep.Panicker@Sun.COM if (!from_iter) {
203*12126SHyon.Kim@Sun.COM if (nvlist_alloc(&nv_record, NV_UNIQUE_NAME, 0) != 0) {
20411015SSundeep.Panicker@Sun.COM return;
20511015SSundeep.Panicker@Sun.COM }
20611015SSundeep.Panicker@Sun.COM } else {
20711015SSundeep.Panicker@Sun.COM nv_record = nv;
20811015SSundeep.Panicker@Sun.COM }
20911015SSundeep.Panicker@Sun.COM
21011015SSundeep.Panicker@Sun.COM for (i = 0; i < def->enumCount; i++,
21111015SSundeep.Panicker@Sun.COM data += component->payloadLen) {
21211015SSundeep.Panicker@Sun.COM component = fru_reg_lookup_def_by_name(
21311015SSundeep.Panicker@Sun.COM def->enumTable[i].text);
21411015SSundeep.Panicker@Sun.COM convert_element(data, component, "", nv_record,
21511015SSundeep.Panicker@Sun.COM B_FALSE);
21611015SSundeep.Panicker@Sun.COM }
21711015SSundeep.Panicker@Sun.COM
21811015SSundeep.Panicker@Sun.COM (void) nvlist_add_nvlist(nv, path, nv_record);
21911015SSundeep.Panicker@Sun.COM
22011015SSundeep.Panicker@Sun.COM } else {
22111015SSundeep.Panicker@Sun.COM convert_field(data, def, path, nv);
22211015SSundeep.Panicker@Sun.COM }
22311015SSundeep.Panicker@Sun.COM }
22411015SSundeep.Panicker@Sun.COM
22511015SSundeep.Panicker@Sun.COM
22611015SSundeep.Panicker@Sun.COM static fru_regdef_t *
alloc_unknown_fru_regdef(void)22711015SSundeep.Panicker@Sun.COM alloc_unknown_fru_regdef(void)
22811015SSundeep.Panicker@Sun.COM {
22911015SSundeep.Panicker@Sun.COM fru_regdef_t *p;
23011015SSundeep.Panicker@Sun.COM
23111015SSundeep.Panicker@Sun.COM p = malloc(sizeof (fru_regdef_t));
23211015SSundeep.Panicker@Sun.COM if (!p) {
23311015SSundeep.Panicker@Sun.COM return (NULL);
23411015SSundeep.Panicker@Sun.COM }
23511015SSundeep.Panicker@Sun.COM p->version = REGDEF_VERSION;
23611015SSundeep.Panicker@Sun.COM p->name = NULL;
23711015SSundeep.Panicker@Sun.COM p->tagType = -1;
23811015SSundeep.Panicker@Sun.COM p->tagDense = -1;
23911015SSundeep.Panicker@Sun.COM p->payloadLen = -1;
24011015SSundeep.Panicker@Sun.COM p->dataLength = -1;
24111015SSundeep.Panicker@Sun.COM p->dataType = FDTYPE_ByteArray;
24211015SSundeep.Panicker@Sun.COM p->dispType = FDISP_Hex;
24311015SSundeep.Panicker@Sun.COM p->purgeable = FRU_WHICH_UNDEFINED;
24411015SSundeep.Panicker@Sun.COM p->relocatable = FRU_WHICH_UNDEFINED;
24511015SSundeep.Panicker@Sun.COM p->enumCount = 0;
24611015SSundeep.Panicker@Sun.COM p-> enumTable = NULL;
24711015SSundeep.Panicker@Sun.COM p->iterationCount = 0;
24811015SSundeep.Panicker@Sun.COM p->iterationType = FRU_NOT_ITERATED;
24911015SSundeep.Panicker@Sun.COM p->exampleString = NULL;
25011015SSundeep.Panicker@Sun.COM
25111015SSundeep.Panicker@Sun.COM return (p);
25211015SSundeep.Panicker@Sun.COM }
25311015SSundeep.Panicker@Sun.COM
25411015SSundeep.Panicker@Sun.COM static int
convert_packet(fru_tag_t * tag,uint8_t * payload,size_t length,void * args)25511015SSundeep.Panicker@Sun.COM convert_packet(fru_tag_t *tag, uint8_t *payload, size_t length, void *args)
25611015SSundeep.Panicker@Sun.COM {
25711015SSundeep.Panicker@Sun.COM int tag_type;
25811015SSundeep.Panicker@Sun.COM size_t payload_length;
25911015SSundeep.Panicker@Sun.COM const fru_regdef_t *def;
26011015SSundeep.Panicker@Sun.COM nvlist_t *nv = (nvlist_t *)args;
26111015SSundeep.Panicker@Sun.COM char tagname[sizeof ("?_0123456789_0123456789")];
26211015SSundeep.Panicker@Sun.COM tag_type = get_tag_type(tag);
26311015SSundeep.Panicker@Sun.COM payload_length = 0;
26411015SSundeep.Panicker@Sun.COM
26511015SSundeep.Panicker@Sun.COM /* check for unrecognized tag */
26611015SSundeep.Panicker@Sun.COM if ((tag_type == -1) ||
26711015SSundeep.Panicker@Sun.COM ((payload_length = get_payload_length(tag)) != length)) {
26811015SSundeep.Panicker@Sun.COM fru_regdef_t *unknown;
26911015SSundeep.Panicker@Sun.COM
27011015SSundeep.Panicker@Sun.COM unknown = alloc_unknown_fru_regdef();
27111015SSundeep.Panicker@Sun.COM unknown->payloadLen = length;
27211015SSundeep.Panicker@Sun.COM unknown->dataLength = unknown->payloadLen;
27311015SSundeep.Panicker@Sun.COM
27411015SSundeep.Panicker@Sun.COM if (tag_type == -1) {
27511015SSundeep.Panicker@Sun.COM (void) snprintf(tagname, sizeof (tagname),
27611015SSundeep.Panicker@Sun.COM "INVALID");
27711015SSundeep.Panicker@Sun.COM } else {
27811015SSundeep.Panicker@Sun.COM (void) snprintf(tagname, sizeof (tagname),
27911015SSundeep.Panicker@Sun.COM "%s_%u_%u_%u", get_tagtype_str(tag_type),
28011015SSundeep.Panicker@Sun.COM get_tag_dense(tag), payload_length, length);
28111015SSundeep.Panicker@Sun.COM }
28211015SSundeep.Panicker@Sun.COM unknown->name = tagname;
28311015SSundeep.Panicker@Sun.COM convert_element(payload, unknown, "", nv, B_FALSE);
28411015SSundeep.Panicker@Sun.COM free(unknown);
28511015SSundeep.Panicker@Sun.COM
28611015SSundeep.Panicker@Sun.COM } else if ((def = fru_reg_lookup_def_by_tag(*tag)) == NULL) {
28711015SSundeep.Panicker@Sun.COM fru_regdef_t *unknown;
28811015SSundeep.Panicker@Sun.COM
28911015SSundeep.Panicker@Sun.COM unknown = alloc_unknown_fru_regdef();
29011015SSundeep.Panicker@Sun.COM unknown->payloadLen = length;
29111015SSundeep.Panicker@Sun.COM unknown->dataLength = unknown->payloadLen;
29211015SSundeep.Panicker@Sun.COM
29311015SSundeep.Panicker@Sun.COM (void) snprintf(tagname, sizeof (tagname), "%s_%u_%u",
29411015SSundeep.Panicker@Sun.COM get_tagtype_str(tag_type),
29511015SSundeep.Panicker@Sun.COM unknown->tagDense, payload_length);
29611015SSundeep.Panicker@Sun.COM
29711015SSundeep.Panicker@Sun.COM unknown->name = tagname;
29811015SSundeep.Panicker@Sun.COM convert_element(payload, unknown, "", nv, B_FALSE);
29911015SSundeep.Panicker@Sun.COM free(unknown);
30011015SSundeep.Panicker@Sun.COM
30111015SSundeep.Panicker@Sun.COM } else {
30211015SSundeep.Panicker@Sun.COM
30311015SSundeep.Panicker@Sun.COM convert_element(payload, def, "", nv, B_FALSE);
30411015SSundeep.Panicker@Sun.COM
30511015SSundeep.Panicker@Sun.COM }
30611015SSundeep.Panicker@Sun.COM
30711015SSundeep.Panicker@Sun.COM return (FRU_SUCCESS);
30811015SSundeep.Panicker@Sun.COM }
30911015SSundeep.Panicker@Sun.COM
31011015SSundeep.Panicker@Sun.COM
31111015SSundeep.Panicker@Sun.COM static int
convert_packets_in_segment(fru_seghdl_t segment,void * args)31211015SSundeep.Panicker@Sun.COM convert_packets_in_segment(fru_seghdl_t segment, void *args)
31311015SSundeep.Panicker@Sun.COM {
31411015SSundeep.Panicker@Sun.COM char *name;
31511015SSundeep.Panicker@Sun.COM int ret;
31611015SSundeep.Panicker@Sun.COM nvlist_t *nv = (nvlist_t *)args;
31711015SSundeep.Panicker@Sun.COM nvlist_t *nv_segment;
31811015SSundeep.Panicker@Sun.COM
31911015SSundeep.Panicker@Sun.COM ret = fru_get_segment_name(segment, &name);
32011015SSundeep.Panicker@Sun.COM if (ret != FRU_SUCCESS) {
32111015SSundeep.Panicker@Sun.COM return (ret);
32211015SSundeep.Panicker@Sun.COM }
32311015SSundeep.Panicker@Sun.COM
32411015SSundeep.Panicker@Sun.COM /* create a new nvlist for each segment */
325*12126SHyon.Kim@Sun.COM ret = nvlist_alloc(&nv_segment, NV_UNIQUE_NAME, 0);
32611015SSundeep.Panicker@Sun.COM if (ret) {
32711015SSundeep.Panicker@Sun.COM free(name);
32811015SSundeep.Panicker@Sun.COM return (FRU_FAILURE);
32911015SSundeep.Panicker@Sun.COM }
33011015SSundeep.Panicker@Sun.COM
33111015SSundeep.Panicker@Sun.COM /* convert the segment to an nvlist */
33211015SSundeep.Panicker@Sun.COM ret = fru_for_each_packet(segment, convert_packet, nv_segment);
33311015SSundeep.Panicker@Sun.COM if (ret != FRU_SUCCESS) {
33411015SSundeep.Panicker@Sun.COM nvlist_free(nv_segment);
33511015SSundeep.Panicker@Sun.COM free(name);
33611015SSundeep.Panicker@Sun.COM return (ret);
33711015SSundeep.Panicker@Sun.COM }
33811015SSundeep.Panicker@Sun.COM
33911015SSundeep.Panicker@Sun.COM /* add the nvlist for this segment */
34011015SSundeep.Panicker@Sun.COM (void) nvlist_add_nvlist(nv, name, nv_segment);
34111015SSundeep.Panicker@Sun.COM
34211015SSundeep.Panicker@Sun.COM free(name);
34311015SSundeep.Panicker@Sun.COM
34411015SSundeep.Panicker@Sun.COM return (FRU_SUCCESS);
34511015SSundeep.Panicker@Sun.COM }
34611015SSundeep.Panicker@Sun.COM
34711015SSundeep.Panicker@Sun.COM
34811015SSundeep.Panicker@Sun.COM static int
convert_fru(fru_nodehdl_t hdl,nvlist_t ** nvlist)34911015SSundeep.Panicker@Sun.COM convert_fru(fru_nodehdl_t hdl, nvlist_t **nvlist)
35011015SSundeep.Panicker@Sun.COM {
35111015SSundeep.Panicker@Sun.COM int err;
35211015SSundeep.Panicker@Sun.COM nvlist_t *nv;
35311015SSundeep.Panicker@Sun.COM fru_node_t fru_type;
35411015SSundeep.Panicker@Sun.COM
35511015SSundeep.Panicker@Sun.COM if (fru_get_node_type(hdl, &fru_type) != FRU_SUCCESS) {
35611015SSundeep.Panicker@Sun.COM return (-1);
35711015SSundeep.Panicker@Sun.COM }
35811015SSundeep.Panicker@Sun.COM
35911015SSundeep.Panicker@Sun.COM if (fru_type != FRU_NODE_CONTAINER) {
36011015SSundeep.Panicker@Sun.COM return (-1);
36111015SSundeep.Panicker@Sun.COM }
36211015SSundeep.Panicker@Sun.COM
363*12126SHyon.Kim@Sun.COM err = nvlist_alloc(&nv, NV_UNIQUE_NAME, 0);
36411015SSundeep.Panicker@Sun.COM if (err) {
36511015SSundeep.Panicker@Sun.COM return (err);
36611015SSundeep.Panicker@Sun.COM }
36711015SSundeep.Panicker@Sun.COM
36811015SSundeep.Panicker@Sun.COM if (fru_for_each_segment(hdl, convert_packets_in_segment, nv) !=
36911015SSundeep.Panicker@Sun.COM FRU_SUCCESS) {
37011015SSundeep.Panicker@Sun.COM nvlist_free(nv);
37111015SSundeep.Panicker@Sun.COM return (-1);
37211015SSundeep.Panicker@Sun.COM }
37311015SSundeep.Panicker@Sun.COM
37411015SSundeep.Panicker@Sun.COM *nvlist = nv;
37511015SSundeep.Panicker@Sun.COM
37611015SSundeep.Panicker@Sun.COM return (0);
37711015SSundeep.Panicker@Sun.COM }
37811015SSundeep.Panicker@Sun.COM
37911015SSundeep.Panicker@Sun.COM
38011015SSundeep.Panicker@Sun.COM int
rawfru_to_nvlist(uint8_t * buffer,size_t bufsize,char * cont_type,nvlist_t ** nvlist)38111015SSundeep.Panicker@Sun.COM rawfru_to_nvlist(uint8_t *buffer, size_t bufsize, char *cont_type,
38211015SSundeep.Panicker@Sun.COM nvlist_t **nvlist)
38311015SSundeep.Panicker@Sun.COM {
38411015SSundeep.Panicker@Sun.COM fru_errno_t fru_err;
38511015SSundeep.Panicker@Sun.COM fru_nodehdl_t hdl;
38611015SSundeep.Panicker@Sun.COM int err;
38711015SSundeep.Panicker@Sun.COM
38811015SSundeep.Panicker@Sun.COM (void) pthread_mutex_lock(&gLock);
38911015SSundeep.Panicker@Sun.COM fru_err = fru_open_data_source("raw", buffer, bufsize, cont_type,
39011015SSundeep.Panicker@Sun.COM NULL);
39111015SSundeep.Panicker@Sun.COM if (fru_err != FRU_SUCCESS) {
39211015SSundeep.Panicker@Sun.COM (void) pthread_mutex_unlock(&gLock);
39311015SSundeep.Panicker@Sun.COM return (-1);
39411015SSundeep.Panicker@Sun.COM }
39511015SSundeep.Panicker@Sun.COM fru_err = fru_get_root(&hdl);
39611015SSundeep.Panicker@Sun.COM if (fru_err != FRU_SUCCESS) {
39711015SSundeep.Panicker@Sun.COM (void) pthread_mutex_unlock(&gLock);
39811015SSundeep.Panicker@Sun.COM return (-1);
39911015SSundeep.Panicker@Sun.COM }
40011015SSundeep.Panicker@Sun.COM
40111015SSundeep.Panicker@Sun.COM err = convert_fru(hdl, nvlist);
40211015SSundeep.Panicker@Sun.COM
40311015SSundeep.Panicker@Sun.COM fru_close_data_source();
40411015SSundeep.Panicker@Sun.COM
40511015SSundeep.Panicker@Sun.COM (void) pthread_mutex_unlock(&gLock);
40611015SSundeep.Panicker@Sun.COM
40711015SSundeep.Panicker@Sun.COM return (err);
40811015SSundeep.Panicker@Sun.COM }
409