6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker * CDDL HEADER START
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker * The contents of this file are subject to the terms of the
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker * Common Development and Distribution License (the "License").
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker * You may not use this file except in compliance with the License.
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker * or http://www.opensolaris.org/os/licensing.
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker * See the License for the specific language governing permissions
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker * and limitations under the License.
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker * When distributing Covered Code, include this CDDL HEADER in each
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker * If applicable, add the following below this CDDL HEADER, with the
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker * fields enclosed by brackets "[]" replaced with your own identifying
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker * information: Portions Copyright [yyyy] [name of copyright owner]
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker * CDDL HEADER END
ee169c7e77bc5d28a401dde8533cbd38afd24ae1Gary Mills * Copyright (c) 2014 Gary Mills
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panickerstatic pthread_mutex_t gLock = PTHREAD_MUTEX_INITIALIZER;
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panickerconvert_field(const uint8_t *field, const fru_regdef_t *def, const char *path,
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker if (def->payloadLen > sizeof (timefield)) {
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker /* too big for formatting */
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker (void) memcpy(&timefield, field, sizeof (timefield));
ee169c7e77bc5d28a401dde8533cbd38afd24ae1Gary Mills if (strftime(timestring, sizeof (timestring), "%c",
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker /* buffer too small */
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker (void) nvlist_add_string(nv, path, timestring);
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker (void) nvlist_add_string(nv, path, (char *)field);
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker (void) memcpy((((uint8_t *)&value) + sizeof (value) -
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker /* nothing matched above, use byte array */
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker (void) nvlist_add_byte_array(nv, path, (uchar_t *)field,
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panickerconvert_element(const uint8_t *data, const fru_regdef_t *def, char *ppath,
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker /* construct path */
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker (def->iterationType != FRU_NOT_ITERATED)) {
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker /* iteration, record and field */
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker iterlen = (def->payloadLen - NUM_ITER_BYTES) /
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker * make a new element definition to describe the components of
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker * the iteration.
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker (void) memcpy(&newdef, def, sizeof (newdef));
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker /* validate the content of the iteration control bytes */
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker if ((data[HEAD_ITER] >= def->iterationCount) ||
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker /* invalid. show all iterations */
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker nv_elems = (nvlist_t **)malloc(num * sizeof (nvlist_t *));
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker for (i = head, n = 0, data += sizeof (uint32_t); n < num;
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker i = ((i + 1) % def->iterationCount), n++) {
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim if (nvlist_alloc(&nv_elems[n], NV_UNIQUE_NAME, 0) != 0)
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker (void) snprintf(num_str, sizeof (num_str), "%d", n);
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker convert_element((data + i*iterlen), &newdef, num_str,
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker (void) nvlist_add_nvlist_array(nv, path, nv_elems, num);
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker } else if (def->dataType == FDTYPE_Record) {
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim if (nvlist_alloc(&nv_record, NV_UNIQUE_NAME, 0) != 0) {
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker convert_element(data, component, "", nv_record,
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker (void) nvlist_add_nvlist(nv, path, nv_record);
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panickerconvert_packet(fru_tag_t *tag, uint8_t *payload, size_t length, void *args)
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker char tagname[sizeof ("?_0123456789_0123456789")];
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker /* check for unrecognized tag */
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker ((payload_length = get_payload_length(tag)) != length)) {
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker get_tag_dense(tag), payload_length, length);
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker convert_element(payload, unknown, "", nv, B_FALSE);
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker } else if ((def = fru_reg_lookup_def_by_tag(*tag)) == NULL) {
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker (void) snprintf(tagname, sizeof (tagname), "%s_%u_%u",
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker convert_element(payload, unknown, "", nv, B_FALSE);
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker convert_element(payload, def, "", nv, B_FALSE);
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panickerconvert_packets_in_segment(fru_seghdl_t segment, void *args)
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker ret = fru_get_segment_name(segment, &name);
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker /* create a new nvlist for each segment */
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim ret = nvlist_alloc(&nv_segment, NV_UNIQUE_NAME, 0);
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker /* convert the segment to an nvlist */
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker ret = fru_for_each_packet(segment, convert_packet, nv_segment);
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker /* add the nvlist for this segment */
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker (void) nvlist_add_nvlist(nv, name, nv_segment);
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panickerconvert_fru(fru_nodehdl_t hdl, nvlist_t **nvlist)
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker if (fru_get_node_type(hdl, &fru_type) != FRU_SUCCESS) {
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panicker if (fru_for_each_segment(hdl, convert_packets_in_segment, nv) !=
6bbe05905a1c10a2703f95fb4912eb14b87f6670Sundeep Panickerrawfru_to_nvlist(uint8_t *buffer, size_t bufsize, char *cont_type,