xref: /titanic_51/usr/src/lib/libfru/libfruraw/fruraw.c (revision ac88567a7a5bb7f01cf22cf366bc9d6203e24d7a)
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 <stdarg.h>
286bbe0590SSundeep Panicker #include <stdlib.h>
296bbe0590SSundeep Panicker #include <errno.h>
306bbe0590SSundeep Panicker #include <string.h>
316bbe0590SSundeep Panicker 
326bbe0590SSundeep Panicker #include "fru_access_impl.h"
336bbe0590SSundeep Panicker 
346bbe0590SSundeep Panicker #include "libfruds.h"
356bbe0590SSundeep Panicker #include "libfrup.h"
366bbe0590SSundeep Panicker #include "fru_access.h"
376bbe0590SSundeep Panicker #include "fruraw.h"
386bbe0590SSundeep Panicker 
396bbe0590SSundeep Panicker 
406bbe0590SSundeep Panicker raw_list_t *g_raw = NULL;
416bbe0590SSundeep Panicker 
426bbe0590SSundeep Panicker 
436bbe0590SSundeep Panicker /* ARGSUSED */
446bbe0590SSundeep Panicker static raw_list_t *
456bbe0590SSundeep Panicker treehdl_to_rawlist(fru_treehdl_t handle)
466bbe0590SSundeep Panicker {
476bbe0590SSundeep Panicker 	return (g_raw);
486bbe0590SSundeep Panicker }
496bbe0590SSundeep Panicker 
506bbe0590SSundeep Panicker 
516bbe0590SSundeep Panicker static container_hdl_t
526bbe0590SSundeep Panicker treehdl_to_conthdl(fru_treehdl_t handle)
536bbe0590SSundeep Panicker {
546bbe0590SSundeep Panicker 	raw_list_t *ptr;
556bbe0590SSundeep Panicker 
566bbe0590SSundeep Panicker 	ptr = treehdl_to_rawlist(handle);
576bbe0590SSundeep Panicker 	if (ptr == NULL) {
586bbe0590SSundeep Panicker 		return (-1);
596bbe0590SSundeep Panicker 	}
606bbe0590SSundeep Panicker 
616bbe0590SSundeep Panicker 	return (ptr->cont);
626bbe0590SSundeep Panicker }
636bbe0590SSundeep Panicker 
646bbe0590SSundeep Panicker 
656bbe0590SSundeep Panicker static fru_errno_t
666bbe0590SSundeep Panicker map_errno(int err)
676bbe0590SSundeep Panicker {
686bbe0590SSundeep Panicker 	switch (err) {
696bbe0590SSundeep Panicker 	case ENFILE:
706bbe0590SSundeep Panicker 	case EEXIST:
716bbe0590SSundeep Panicker 		return (FRU_DUPSEG);
726bbe0590SSundeep Panicker 	case EAGAIN:
736bbe0590SSundeep Panicker 		return (FRU_NOSPACE);
746bbe0590SSundeep Panicker 	case EPERM:
756bbe0590SSundeep Panicker 		return (FRU_INVALPERM);
766bbe0590SSundeep Panicker 	default :
776bbe0590SSundeep Panicker 		return (FRU_IOERROR);
786bbe0590SSundeep Panicker 	}
796bbe0590SSundeep Panicker }
806bbe0590SSundeep Panicker 
816bbe0590SSundeep Panicker 
826bbe0590SSundeep Panicker static raw_list_t *
836bbe0590SSundeep Panicker make_raw(uint8_t *buffer, size_t size, char *cont_type)
846bbe0590SSundeep Panicker {
856bbe0590SSundeep Panicker 	raw_list_t *node;
866bbe0590SSundeep Panicker 
876bbe0590SSundeep Panicker 	node = (raw_list_t *)malloc(sizeof (raw_list_t));
886bbe0590SSundeep Panicker 	if (node == NULL) {
896bbe0590SSundeep Panicker 		return (NULL);
906bbe0590SSundeep Panicker 	}
916bbe0590SSundeep Panicker 
926bbe0590SSundeep Panicker 	node->hdl = 0;
936bbe0590SSundeep Panicker 	node->raw = buffer;
946bbe0590SSundeep Panicker 	node->size = size;
956bbe0590SSundeep Panicker 	node->cont_type = strdup(cont_type);
966bbe0590SSundeep Panicker 	if (node->cont_type == NULL) {
976bbe0590SSundeep Panicker 		free(node);
986bbe0590SSundeep Panicker 		return (NULL);
996bbe0590SSundeep Panicker 	}
1006bbe0590SSundeep Panicker 	node->segs = NULL;
1016bbe0590SSundeep Panicker 
1026bbe0590SSundeep Panicker 	return (node);
1036bbe0590SSundeep Panicker }
1046bbe0590SSundeep Panicker 
1056bbe0590SSundeep Panicker 
1066bbe0590SSundeep Panicker /*
1076bbe0590SSundeep Panicker  * Arguments :
1086bbe0590SSundeep Panicker  * 0 - pointer to byte buffer (in)
1096bbe0590SSundeep Panicker  * 1 - size of buffer (in)
1106bbe0590SSundeep Panicker  * 2 - container type, string (in)
1116bbe0590SSundeep Panicker  */
1126bbe0590SSundeep Panicker static fru_errno_t
1136bbe0590SSundeep Panicker frt_initialize(int num, char **args)
1146bbe0590SSundeep Panicker {
1156bbe0590SSundeep Panicker 
1166bbe0590SSundeep Panicker 
1176bbe0590SSundeep Panicker 	if (num != 3) {
1186bbe0590SSundeep Panicker 		return (FRU_FAILURE);
1196bbe0590SSundeep Panicker 	}
1206bbe0590SSundeep Panicker 
1216bbe0590SSundeep Panicker 	g_raw = make_raw((uint8_t *)args[0], (size_t)args[1], args[2]);
1226bbe0590SSundeep Panicker 	if (g_raw == NULL) {
1236bbe0590SSundeep Panicker 		return (FRU_FAILURE);
1246bbe0590SSundeep Panicker 	}
1256bbe0590SSundeep Panicker 
1266bbe0590SSundeep Panicker 	g_raw->cont = open_raw_data(g_raw);
1276bbe0590SSundeep Panicker 	if (g_raw->cont == NULL) {
1286bbe0590SSundeep Panicker 		return (FRU_FAILURE);
1296bbe0590SSundeep Panicker 	}
1306bbe0590SSundeep Panicker 
1316bbe0590SSundeep Panicker 	return (FRU_SUCCESS);
1326bbe0590SSundeep Panicker }
1336bbe0590SSundeep Panicker 
1346bbe0590SSundeep Panicker 
1356bbe0590SSundeep Panicker static fru_errno_t
1366bbe0590SSundeep Panicker frt_shutdown(void)
1376bbe0590SSundeep Panicker {
1386bbe0590SSundeep Panicker 	segment_list_t *lptr, *lptr2;
1396bbe0590SSundeep Panicker 
1406bbe0590SSundeep Panicker 	(void) fru_close_container(g_raw->cont);
1416bbe0590SSundeep Panicker 	free(g_raw->cont_type);
1426bbe0590SSundeep Panicker 	lptr = g_raw->segs;
1436bbe0590SSundeep Panicker 	while (lptr) {
1446bbe0590SSundeep Panicker 		lptr2 = lptr;
1456bbe0590SSundeep Panicker 		lptr = lptr->next;
1466bbe0590SSundeep Panicker 		free(lptr2);
1476bbe0590SSundeep Panicker 	}
1486bbe0590SSundeep Panicker 	g_raw = NULL;
1496bbe0590SSundeep Panicker 
1506bbe0590SSundeep Panicker 	return (FRU_SUCCESS);
1516bbe0590SSundeep Panicker }
1526bbe0590SSundeep Panicker 
1536bbe0590SSundeep Panicker 
1546bbe0590SSundeep Panicker static fru_errno_t
1556bbe0590SSundeep Panicker frt_get_root(fru_treehdl_t *node)
1566bbe0590SSundeep Panicker {
1576bbe0590SSundeep Panicker 	*node = g_raw->hdl;
1586bbe0590SSundeep Panicker 
1596bbe0590SSundeep Panicker 	return (FRU_SUCCESS);
1606bbe0590SSundeep Panicker }
1616bbe0590SSundeep Panicker 
1626bbe0590SSundeep Panicker /* ARGSUSED */
1636bbe0590SSundeep Panicker static fru_errno_t
1646bbe0590SSundeep Panicker frt_get_peer(fru_treehdl_t sibling, fru_treehdl_t *peer)
1656bbe0590SSundeep Panicker {
1666bbe0590SSundeep Panicker 	return (FRU_NODENOTFOUND);
1676bbe0590SSundeep Panicker }
1686bbe0590SSundeep Panicker /* ARGSUSED */
1696bbe0590SSundeep Panicker static fru_errno_t
1706bbe0590SSundeep Panicker frt_get_child(fru_treehdl_t handle, fru_treehdl_t *child)
1716bbe0590SSundeep Panicker {
1726bbe0590SSundeep Panicker 	return (FRU_NODENOTFOUND);
1736bbe0590SSundeep Panicker }
1746bbe0590SSundeep Panicker 
1756bbe0590SSundeep Panicker /* ARGSUSED */
1766bbe0590SSundeep Panicker static fru_errno_t
1776bbe0590SSundeep Panicker frt_get_parent(fru_treehdl_t handle, fru_treehdl_t *parent)
1786bbe0590SSundeep Panicker {
1796bbe0590SSundeep Panicker 	return (FRU_NODENOTFOUND);
1806bbe0590SSundeep Panicker }
1816bbe0590SSundeep Panicker 
1826bbe0590SSundeep Panicker /* ARGSUSED */
1836bbe0590SSundeep Panicker static fru_errno_t
1846bbe0590SSundeep Panicker frt_get_name_from_hdl(fru_treehdl_t handle, char **name)
1856bbe0590SSundeep Panicker {
1866bbe0590SSundeep Panicker 	*name = strdup("unknown");
1876bbe0590SSundeep Panicker 	return (FRU_SUCCESS);
1886bbe0590SSundeep Panicker }
1896bbe0590SSundeep Panicker 
1906bbe0590SSundeep Panicker /* ARGSUSED */
1916bbe0590SSundeep Panicker static fru_errno_t
1926bbe0590SSundeep Panicker frt_get_node_type(fru_treehdl_t node, fru_node_t *type)
1936bbe0590SSundeep Panicker {
1946bbe0590SSundeep Panicker 	*type = FRU_NODE_CONTAINER;
1956bbe0590SSundeep Panicker 	return (FRU_SUCCESS);
1966bbe0590SSundeep Panicker }
1976bbe0590SSundeep Panicker 
1986bbe0590SSundeep Panicker 
1996bbe0590SSundeep Panicker 
2006bbe0590SSundeep Panicker static fru_errno_t
2016bbe0590SSundeep Panicker add_segs_for_section(section_t *section, fru_strlist_t *list)
2026bbe0590SSundeep Panicker {
2036bbe0590SSundeep Panicker 	int i = 0;
2046bbe0590SSundeep Panicker 	segment_t *segs = NULL;
2056bbe0590SSundeep Panicker 	int acc_err = 0;
2066bbe0590SSundeep Panicker 
2076bbe0590SSundeep Panicker 	int num_segment = fru_get_num_segments(section->handle, NULL);
2086bbe0590SSundeep Panicker 	if (num_segment == -1) {
2096bbe0590SSundeep Panicker 		return (map_errno(errno));
2106bbe0590SSundeep Panicker 	} else if (num_segment == 0) {
2116bbe0590SSundeep Panicker 		return (FRU_SUCCESS);
2126bbe0590SSundeep Panicker 	}
2136bbe0590SSundeep Panicker 
2146bbe0590SSundeep Panicker 	segs = malloc(sizeof (*segs) * (num_segment));
2156bbe0590SSundeep Panicker 	if (segs == NULL) {
2166bbe0590SSundeep Panicker 		return (FRU_FAILURE);
2176bbe0590SSundeep Panicker 	}
2186bbe0590SSundeep Panicker 
2196bbe0590SSundeep Panicker 	acc_err = fru_get_segments(section->handle, segs, num_segment, NULL);
2206bbe0590SSundeep Panicker 	if (acc_err == -1) {
2216bbe0590SSundeep Panicker 		free(segs);
2226bbe0590SSundeep Panicker 		return (map_errno(errno));
2236bbe0590SSundeep Panicker 	}
2246bbe0590SSundeep Panicker 
2256bbe0590SSundeep Panicker 	list->strs = realloc(list->strs, sizeof (char *)
2266bbe0590SSundeep Panicker 	    * (list->num + num_segment));
2276bbe0590SSundeep Panicker 
2286bbe0590SSundeep Panicker 	for (i = 0; i < num_segment; i++) {
2296bbe0590SSundeep Panicker 		/* ensure NULL terminated. */
2306bbe0590SSundeep Panicker 		char *tmp = malloc(sizeof (*tmp) * (sizeof (segs[i].name)+1));
2316bbe0590SSundeep Panicker 		if (tmp == NULL) {
2326bbe0590SSundeep Panicker 			free(segs);
2336bbe0590SSundeep Panicker 			return (FRU_FAILURE);
2346bbe0590SSundeep Panicker 		}
2356bbe0590SSundeep Panicker 		(void) memcpy(tmp, segs[i].name, sizeof (segs[i].name));
2366bbe0590SSundeep Panicker 		tmp[sizeof (segs[i].name)] = '\0';
2376bbe0590SSundeep Panicker 
2386bbe0590SSundeep Panicker 		list->strs[(list->num)++] = tmp;
2396bbe0590SSundeep Panicker 	}
2406bbe0590SSundeep Panicker 
2416bbe0590SSundeep Panicker 	free(segs);
2426bbe0590SSundeep Panicker 
2436bbe0590SSundeep Panicker 	return (FRU_SUCCESS);
2446bbe0590SSundeep Panicker }
2456bbe0590SSundeep Panicker 
2466bbe0590SSundeep Panicker 
2476bbe0590SSundeep Panicker 
2486bbe0590SSundeep Panicker static fru_errno_t
2496bbe0590SSundeep Panicker frt_get_seg_list(fru_treehdl_t handle, fru_strlist_t *list)
2506bbe0590SSundeep Panicker {
2516bbe0590SSundeep Panicker 	fru_strlist_t rc_list;
2526bbe0590SSundeep Panicker 	fru_errno_t err = FRU_SUCCESS;
2536bbe0590SSundeep Panicker 	int acc_err = 0;
2546bbe0590SSundeep Panicker 	int i = 0;
2556bbe0590SSundeep Panicker 	int num_section = 0;
2566bbe0590SSundeep Panicker 	section_t *sects = NULL;
2576bbe0590SSundeep Panicker 	container_hdl_t cont;
2586bbe0590SSundeep Panicker 
2596bbe0590SSundeep Panicker 	cont = treehdl_to_conthdl(handle);
2606bbe0590SSundeep Panicker 
2616bbe0590SSundeep Panicker 	num_section = fru_get_num_sections(cont, NULL);
2626bbe0590SSundeep Panicker 	if (num_section == -1) {
2636bbe0590SSundeep Panicker 		return (map_errno(errno));
2646bbe0590SSundeep Panicker 	}
2656bbe0590SSundeep Panicker 
2666bbe0590SSundeep Panicker 	sects = malloc(sizeof (*sects) * (num_section));
2676bbe0590SSundeep Panicker 	if (sects == NULL) {
2686bbe0590SSundeep Panicker 		return (FRU_FAILURE);
2696bbe0590SSundeep Panicker 	}
2706bbe0590SSundeep Panicker 
2716bbe0590SSundeep Panicker 	acc_err = fru_get_sections(cont, sects, num_section, NULL);
2726bbe0590SSundeep Panicker 	if (acc_err == -1) {
2736bbe0590SSundeep Panicker 		free(sects);
2746bbe0590SSundeep Panicker 		return (map_errno(errno));
2756bbe0590SSundeep Panicker 	}
2766bbe0590SSundeep Panicker 
2776bbe0590SSundeep Panicker 	rc_list.num = 0;
2786bbe0590SSundeep Panicker 	rc_list.strs = NULL;
2796bbe0590SSundeep Panicker 	for (i = 0; i < num_section; i++) {
2806bbe0590SSundeep Panicker 		if ((err = add_segs_for_section(&(sects[i]), &rc_list))
2816bbe0590SSundeep Panicker 		    != FRU_SUCCESS) {
2826bbe0590SSundeep Panicker 			fru_destroy_strlist(&rc_list);
2836bbe0590SSundeep Panicker 			free(sects);
2846bbe0590SSundeep Panicker 			return (err);
2856bbe0590SSundeep Panicker 		}
2866bbe0590SSundeep Panicker 	}
2876bbe0590SSundeep Panicker 
2886bbe0590SSundeep Panicker 	list->strs = rc_list.strs;
2896bbe0590SSundeep Panicker 	list->num = rc_list.num;
2906bbe0590SSundeep Panicker 
2916bbe0590SSundeep Panicker 	return (FRU_SUCCESS);
2926bbe0590SSundeep Panicker }
2936bbe0590SSundeep Panicker 
2946bbe0590SSundeep Panicker 
2956bbe0590SSundeep Panicker static fru_errno_t
2966bbe0590SSundeep Panicker find_seg_in_sect(section_t *sect, const char *seg_name, int *prot_flg,
2976bbe0590SSundeep Panicker     segment_t *segment)
2986bbe0590SSundeep Panicker {
2996bbe0590SSundeep Panicker 	int j = 0;
3006bbe0590SSundeep Panicker 	int acc_err = 0;
3016bbe0590SSundeep Panicker 	segment_t *segs = NULL;
3026bbe0590SSundeep Panicker 
3036bbe0590SSundeep Panicker 	int num_seg = fru_get_num_segments(sect->handle, NULL);
3046bbe0590SSundeep Panicker 	if (num_seg == -1) {
3056bbe0590SSundeep Panicker 		return (FRU_FAILURE);
3066bbe0590SSundeep Panicker 	}
3076bbe0590SSundeep Panicker 
3086bbe0590SSundeep Panicker 	segs = malloc(sizeof (*segs) * (num_seg));
3096bbe0590SSundeep Panicker 	if (segs == NULL) {
3106bbe0590SSundeep Panicker 		return (FRU_FAILURE);
3116bbe0590SSundeep Panicker 	}
3126bbe0590SSundeep Panicker 
3136bbe0590SSundeep Panicker 	acc_err = fru_get_segments(sect->handle, segs, num_seg, NULL);
3146bbe0590SSundeep Panicker 	if (acc_err == -1) {
3156bbe0590SSundeep Panicker 		free(segs);
3166bbe0590SSundeep Panicker 		return (map_errno(errno));
3176bbe0590SSundeep Panicker 	}
3186bbe0590SSundeep Panicker 
3196bbe0590SSundeep Panicker 	for (j = 0; j < num_seg; j++) {
3206bbe0590SSundeep Panicker 		/* NULL terminate */
3216bbe0590SSundeep Panicker 		char tmp[SEG_NAME_LEN+1];
3226bbe0590SSundeep Panicker 		(void) memcpy(tmp, segs[j].name, SEG_NAME_LEN);
3236bbe0590SSundeep Panicker 		tmp[SEG_NAME_LEN] = '\0';
3246bbe0590SSundeep Panicker 		if (strcmp(tmp, seg_name) == 0) {
3256bbe0590SSundeep Panicker 			*segment = segs[j];
3266bbe0590SSundeep Panicker 			*prot_flg = (sect->protection ? 1 : 0);
3276bbe0590SSundeep Panicker 			free(segs);
3286bbe0590SSundeep Panicker 			return (FRU_SUCCESS);
3296bbe0590SSundeep Panicker 		}
3306bbe0590SSundeep Panicker 	}
3316bbe0590SSundeep Panicker 
3326bbe0590SSundeep Panicker 	free(segs);
3336bbe0590SSundeep Panicker 	return (FRU_INVALSEG);
3346bbe0590SSundeep Panicker }
3356bbe0590SSundeep Panicker 
3366bbe0590SSundeep Panicker 
3376bbe0590SSundeep Panicker static fru_errno_t
3386bbe0590SSundeep Panicker find_segment(fru_treehdl_t handle, const char *seg_name, int *prot_flg,
3396bbe0590SSundeep Panicker     segment_t *segment)
3406bbe0590SSundeep Panicker {
3416bbe0590SSundeep Panicker 	int i = 0;
3426bbe0590SSundeep Panicker 	int acc_err = 0;
3436bbe0590SSundeep Panicker 	section_t *sect = NULL;
3446bbe0590SSundeep Panicker 	container_hdl_t cont;
3456bbe0590SSundeep Panicker 	int num_sect;
3466bbe0590SSundeep Panicker 
3476bbe0590SSundeep Panicker 	cont = treehdl_to_conthdl(handle);
3486bbe0590SSundeep Panicker 
3496bbe0590SSundeep Panicker 	num_sect = fru_get_num_sections(cont, NULL);
3506bbe0590SSundeep Panicker 	if (num_sect == -1) {
3516bbe0590SSundeep Panicker 		return (map_errno(errno));
3526bbe0590SSundeep Panicker 	}
3536bbe0590SSundeep Panicker 
3546bbe0590SSundeep Panicker 	sect = malloc(sizeof (*sect) * (num_sect));
3556bbe0590SSundeep Panicker 	if (sect == NULL) {
3566bbe0590SSundeep Panicker 		return (FRU_FAILURE);
3576bbe0590SSundeep Panicker 	}
3586bbe0590SSundeep Panicker 
3596bbe0590SSundeep Panicker 	acc_err = fru_get_sections(cont, sect, num_sect, NULL);
3606bbe0590SSundeep Panicker 	if (acc_err == -1) {
3616bbe0590SSundeep Panicker 		free(sect);
3626bbe0590SSundeep Panicker 		return (map_errno(errno));
3636bbe0590SSundeep Panicker 	}
3646bbe0590SSundeep Panicker 
3656bbe0590SSundeep Panicker 	for (i = 0; i < num_sect; i++) {
3666bbe0590SSundeep Panicker 		if (find_seg_in_sect(&(sect[i]), seg_name, prot_flg, segment)
3676bbe0590SSundeep Panicker 		    == FRU_SUCCESS) {
3686bbe0590SSundeep Panicker 			free(sect);
3696bbe0590SSundeep Panicker 			return (FRU_SUCCESS);
3706bbe0590SSundeep Panicker 		}
3716bbe0590SSundeep Panicker 	}
3726bbe0590SSundeep Panicker 
3736bbe0590SSundeep Panicker 	free(sect);
3746bbe0590SSundeep Panicker 	return (FRU_INVALSEG);
3756bbe0590SSundeep Panicker }
3766bbe0590SSundeep Panicker 
3776bbe0590SSundeep Panicker 
3786bbe0590SSundeep Panicker static fru_errno_t
3796bbe0590SSundeep Panicker frt_get_seg_def(fru_treehdl_t handle, const char *seg_name, fru_segdef_t *def)
3806bbe0590SSundeep Panicker {
3816bbe0590SSundeep Panicker 	fru_errno_t err = FRU_SUCCESS;
3826bbe0590SSundeep Panicker 	int prot_flg = 0;
3836bbe0590SSundeep Panicker 	segment_t segment;
3846bbe0590SSundeep Panicker 
3856bbe0590SSundeep Panicker 	if ((err = find_segment(handle, seg_name, &prot_flg, &segment))
3866bbe0590SSundeep Panicker 	    != FRU_SUCCESS) {
3876bbe0590SSundeep Panicker 		return (err);
3886bbe0590SSundeep Panicker 	}
3896bbe0590SSundeep Panicker 
3906bbe0590SSundeep Panicker 	(void) memcpy(def->name, segment.name, SEG_NAME_LEN);
3916bbe0590SSundeep Panicker 	def->name[SEG_NAME_LEN] = '\0';
3926bbe0590SSundeep Panicker 	def->desc.raw_data = segment.descriptor;
3936bbe0590SSundeep Panicker 	def->size = segment.length;
3946bbe0590SSundeep Panicker 	def->address = segment.offset;
3956bbe0590SSundeep Panicker 
3966bbe0590SSundeep Panicker 	if (prot_flg == 0)
3976bbe0590SSundeep Panicker 		def->hw_desc.field.read_only = 0;
3986bbe0590SSundeep Panicker 	else
3996bbe0590SSundeep Panicker 		def->hw_desc.field.read_only = 1;
4006bbe0590SSundeep Panicker 
4016bbe0590SSundeep Panicker 	return (FRU_SUCCESS);
4026bbe0590SSundeep Panicker 
4036bbe0590SSundeep Panicker }
4046bbe0590SSundeep Panicker 
4056bbe0590SSundeep Panicker /* ARGSUSED */
4066bbe0590SSundeep Panicker static fru_errno_t
4076bbe0590SSundeep Panicker frt_add_seg(fru_treehdl_t handle, fru_segdef_t *def)
4086bbe0590SSundeep Panicker {
4096bbe0590SSundeep Panicker 	/* NOT SUPPORTED */
4106bbe0590SSundeep Panicker 	return (FRU_NOTSUP);
4116bbe0590SSundeep Panicker }
4126bbe0590SSundeep Panicker 
4136bbe0590SSundeep Panicker /* ARGSUSED */
4146bbe0590SSundeep Panicker static fru_errno_t
4156bbe0590SSundeep Panicker frt_delete_seg(fru_treehdl_t handle, const char *seg_name)
4166bbe0590SSundeep Panicker {
4176bbe0590SSundeep Panicker 	/* NOT SUPPORTED */
4186bbe0590SSundeep Panicker 	return (FRU_NOTSUP);
4196bbe0590SSundeep Panicker }
4206bbe0590SSundeep Panicker 
4216bbe0590SSundeep Panicker /* ARGSUSED */
4226bbe0590SSundeep Panicker static fru_errno_t
4236bbe0590SSundeep Panicker frt_for_each_segment(fru_nodehdl_t node,
4246bbe0590SSundeep Panicker     int (*function)(fru_seghdl_t hdl, void *args), void *args)
4256bbe0590SSundeep Panicker {
4266bbe0590SSundeep Panicker 	int num_segment;
4276bbe0590SSundeep Panicker 	int cnt;
4286bbe0590SSundeep Panicker 	int num_sect;
4296bbe0590SSundeep Panicker 	int each_seg;
4306bbe0590SSundeep Panicker 	section_t *sects;
4316bbe0590SSundeep Panicker 	segment_t *segs;
4326bbe0590SSundeep Panicker 	segment_list_t *tmp_list;
4336bbe0590SSundeep Panicker 	int acc_err;
4346bbe0590SSundeep Panicker 	int status;
4356bbe0590SSundeep Panicker 	container_hdl_t cont;
4366bbe0590SSundeep Panicker 
4376bbe0590SSundeep Panicker 	cont = g_raw->cont;
4386bbe0590SSundeep Panicker 
4396bbe0590SSundeep Panicker 	num_sect = fru_get_num_sections(cont, NULL);
4406bbe0590SSundeep Panicker 	if (num_sect == -1) {
4416bbe0590SSundeep Panicker 		return (map_errno(errno));
4426bbe0590SSundeep Panicker 	}
4436bbe0590SSundeep Panicker 
4446bbe0590SSundeep Panicker 	sects = malloc((num_sect + 1) * sizeof (section_t));
4456bbe0590SSundeep Panicker 	if (sects == NULL) {
4466bbe0590SSundeep Panicker 		return (FRU_FAILURE);
4476bbe0590SSundeep Panicker 	}
4486bbe0590SSundeep Panicker 	num_sect = fru_get_sections(cont, sects, num_sect, NULL);
4496bbe0590SSundeep Panicker 	if (num_sect == -1) {
4506bbe0590SSundeep Panicker 		free(sects);
4516bbe0590SSundeep Panicker 		return (map_errno(errno));
4526bbe0590SSundeep Panicker 	}
4536bbe0590SSundeep Panicker 	for (cnt = 0; cnt < num_sect; cnt++) {
4546bbe0590SSundeep Panicker 		num_segment = fru_get_num_segments(sects[cnt].handle, NULL);
4556bbe0590SSundeep Panicker 		if (num_segment == -1) {
4566bbe0590SSundeep Panicker 			return (map_errno(errno));
4576bbe0590SSundeep Panicker 		} else if (num_segment == 0) {
4586bbe0590SSundeep Panicker 			continue;
4596bbe0590SSundeep Panicker 		}
4606bbe0590SSundeep Panicker 		segs = malloc((num_segment + 1) * sizeof (segment_t));
4616bbe0590SSundeep Panicker 		if (segs == NULL) {
4626bbe0590SSundeep Panicker 			free(sects);
4636bbe0590SSundeep Panicker 			return (FRU_FAILURE);
4646bbe0590SSundeep Panicker 		}
4656bbe0590SSundeep Panicker 		acc_err = fru_get_segments(sects[cnt].handle, segs,
4666bbe0590SSundeep Panicker 		    num_segment, NULL);
4676bbe0590SSundeep Panicker 		if (acc_err == -1) {
4686bbe0590SSundeep Panicker 			free(sects);
4696bbe0590SSundeep Panicker 			free(segs);
4706bbe0590SSundeep Panicker 			return (map_errno(errno));
4716bbe0590SSundeep Panicker 		}
4726bbe0590SSundeep Panicker 		for (each_seg = 0; each_seg < num_segment; each_seg++) {
4736bbe0590SSundeep Panicker 			tmp_list = malloc(sizeof (segment_list_t));
4746bbe0590SSundeep Panicker 			tmp_list->segment = &segs[each_seg];
4756bbe0590SSundeep Panicker 			tmp_list->next = NULL;
4766bbe0590SSundeep Panicker 			if (g_raw->segs == NULL) {
4776bbe0590SSundeep Panicker 				g_raw->segs = tmp_list;
4786bbe0590SSundeep Panicker 			} else {
4796bbe0590SSundeep Panicker 				tmp_list->next = g_raw->segs;
4806bbe0590SSundeep Panicker 				g_raw->segs = tmp_list;
4816bbe0590SSundeep Panicker 			}
4826bbe0590SSundeep Panicker 
4836bbe0590SSundeep Panicker 			if ((status = function(segs[each_seg].handle, args))
4846bbe0590SSundeep Panicker 			    != FRU_SUCCESS) {
4856bbe0590SSundeep Panicker 				free(segs);
4866bbe0590SSundeep Panicker 				free(sects);
4876bbe0590SSundeep Panicker 				return (status);
4886bbe0590SSundeep Panicker 			}
4896bbe0590SSundeep Panicker 		}
4906bbe0590SSundeep Panicker 		free(segs);
4916bbe0590SSundeep Panicker 		free(sects);
4926bbe0590SSundeep Panicker 
4936bbe0590SSundeep Panicker 	}
4946bbe0590SSundeep Panicker 	return (FRU_SUCCESS);
4956bbe0590SSundeep Panicker }
4966bbe0590SSundeep Panicker 
4976bbe0590SSundeep Panicker 
4986bbe0590SSundeep Panicker static fru_errno_t
4996bbe0590SSundeep Panicker frt_get_segment_name(fru_seghdl_t node, char **name)
5006bbe0590SSundeep Panicker {
5016bbe0590SSundeep Panicker 	int num_sect;
5026bbe0590SSundeep Panicker 	int acc_err;
5036bbe0590SSundeep Panicker 	int cnt;
5046bbe0590SSundeep Panicker 	int num_segment;
5056bbe0590SSundeep Panicker 	section_t *sects;
5066bbe0590SSundeep Panicker 	segment_t *segs;
5076bbe0590SSundeep Panicker 	int each_seg;
5086bbe0590SSundeep Panicker 	container_hdl_t cont;
5096bbe0590SSundeep Panicker 
5106bbe0590SSundeep Panicker 	cont = treehdl_to_conthdl(node);
5116bbe0590SSundeep Panicker 
5126bbe0590SSundeep Panicker 	num_sect = fru_get_num_sections(cont, NULL);
5136bbe0590SSundeep Panicker 	if (num_sect == -1) {
5146bbe0590SSundeep Panicker 		return (map_errno(errno));
5156bbe0590SSundeep Panicker 	}
5166bbe0590SSundeep Panicker 
5176bbe0590SSundeep Panicker 	sects = malloc(sizeof (*sects) * (num_sect));
5186bbe0590SSundeep Panicker 	if (sects == NULL) {
5196bbe0590SSundeep Panicker 		return (FRU_FAILURE);
5206bbe0590SSundeep Panicker 	}
5216bbe0590SSundeep Panicker 	acc_err = fru_get_sections(cont, sects, num_sect, NULL);
5226bbe0590SSundeep Panicker 	if (acc_err == -1) {
5236bbe0590SSundeep Panicker 		free(sects);
5246bbe0590SSundeep Panicker 		return (map_errno(errno));
5256bbe0590SSundeep Panicker 	}
5266bbe0590SSundeep Panicker 
5276bbe0590SSundeep Panicker 	for (cnt = 0; cnt < num_sect; cnt++) {
5286bbe0590SSundeep Panicker 		num_segment = fru_get_num_segments(sects[cnt].handle, NULL);
5296bbe0590SSundeep Panicker 		if (num_segment == -1) {
5306bbe0590SSundeep Panicker 			free(sects);
5316bbe0590SSundeep Panicker 			return (map_errno(errno));
5326bbe0590SSundeep Panicker 		} else if (num_segment == 0) {
5336bbe0590SSundeep Panicker 			continue;
5346bbe0590SSundeep Panicker 		}
5356bbe0590SSundeep Panicker 
5366bbe0590SSundeep Panicker 		segs = malloc(sizeof (*segs) * (num_segment));
5376bbe0590SSundeep Panicker 		if (segs == NULL) {
5386bbe0590SSundeep Panicker 			free(sects);
5396bbe0590SSundeep Panicker 			return (FRU_FAILURE);
5406bbe0590SSundeep Panicker 		}
5416bbe0590SSundeep Panicker 
5426bbe0590SSundeep Panicker 		acc_err = fru_get_segments(sects[cnt].handle, segs,
5436bbe0590SSundeep Panicker 		    num_segment, NULL);
5446bbe0590SSundeep Panicker 		if (acc_err == -1) {
5456bbe0590SSundeep Panicker 			free(sects);
5466bbe0590SSundeep Panicker 			free(segs);
5476bbe0590SSundeep Panicker 			return (map_errno(errno));
5486bbe0590SSundeep Panicker 		}
5496bbe0590SSundeep Panicker 
5506bbe0590SSundeep Panicker 		for (each_seg = 0; each_seg < num_segment; each_seg++) {
5516bbe0590SSundeep Panicker 			if (segs[each_seg].handle == node) {
5526bbe0590SSundeep Panicker 				segs[each_seg].name[FRU_SEGNAMELEN] = '\0';
553*ac88567aSHyon Kim 				*name = strdup(segs[each_seg].name);
5546bbe0590SSundeep Panicker 				free(sects);
555*ac88567aSHyon Kim 				free(segs);
5566bbe0590SSundeep Panicker 				return (FRU_SUCCESS);
5576bbe0590SSundeep Panicker 			}
5586bbe0590SSundeep Panicker 		}
5596bbe0590SSundeep Panicker 		free(segs);
5606bbe0590SSundeep Panicker 	}
5616bbe0590SSundeep Panicker 
5626bbe0590SSundeep Panicker 	return (FRU_FAILURE);
5636bbe0590SSundeep Panicker }
5646bbe0590SSundeep Panicker 
5656bbe0590SSundeep Panicker 
5666bbe0590SSundeep Panicker /* ARGSUSED */
5676bbe0590SSundeep Panicker static fru_errno_t
5686bbe0590SSundeep Panicker frt_add_tag_to_seg(fru_treehdl_t handle, const char *seg_name,
5696bbe0590SSundeep Panicker     fru_tag_t tag, uint8_t *data, size_t data_len)
5706bbe0590SSundeep Panicker {
5716bbe0590SSundeep Panicker 	/* NOT SUPPORTED */
5726bbe0590SSundeep Panicker 	return (FRU_NOTSUP);
5736bbe0590SSundeep Panicker }
5746bbe0590SSundeep Panicker 
5756bbe0590SSundeep Panicker 
5766bbe0590SSundeep Panicker /* ARGSUSED */
5776bbe0590SSundeep Panicker static fru_errno_t
5786bbe0590SSundeep Panicker frt_get_tag_list(fru_treehdl_t handle, const char *seg_name,
5796bbe0590SSundeep Panicker 		fru_tag_t **tags, int *number)
5806bbe0590SSundeep Panicker {
5816bbe0590SSundeep Panicker 	/* NOT SUPPORTED */
5826bbe0590SSundeep Panicker 	return (FRU_NOTSUP);
5836bbe0590SSundeep Panicker }
5846bbe0590SSundeep Panicker 
5856bbe0590SSundeep Panicker 
5866bbe0590SSundeep Panicker /* ARGSUSED */
5876bbe0590SSundeep Panicker static fru_errno_t
5886bbe0590SSundeep Panicker frt_get_tag_data(fru_treehdl_t handle, const char *seg_name,
5896bbe0590SSundeep Panicker 		fru_tag_t tag, int instance,
5906bbe0590SSundeep Panicker 		uint8_t **data, size_t *data_len)
5916bbe0590SSundeep Panicker {
5926bbe0590SSundeep Panicker 	/* NOT SUPPORTED */
5936bbe0590SSundeep Panicker 	return (FRU_NOTSUP);
5946bbe0590SSundeep Panicker }
5956bbe0590SSundeep Panicker 
5966bbe0590SSundeep Panicker 
5976bbe0590SSundeep Panicker /* ARGSUSED */
5986bbe0590SSundeep Panicker static fru_errno_t
5996bbe0590SSundeep Panicker frt_set_tag_data(fru_treehdl_t handle, const char *seg_name,
6006bbe0590SSundeep Panicker 		fru_tag_t tag, int instance,
6016bbe0590SSundeep Panicker 		uint8_t *data, size_t data_len)
6026bbe0590SSundeep Panicker {
6036bbe0590SSundeep Panicker 	/* NOT SUPPORTED */
6046bbe0590SSundeep Panicker 	return (FRU_NOTSUP);
6056bbe0590SSundeep Panicker }
6066bbe0590SSundeep Panicker 
6076bbe0590SSundeep Panicker 
6086bbe0590SSundeep Panicker /* ARGSUSED */
6096bbe0590SSundeep Panicker static fru_errno_t
6106bbe0590SSundeep Panicker frt_delete_tag(fru_treehdl_t handle, const char *seg_name, fru_tag_t tag,
6116bbe0590SSundeep Panicker     int instance)
6126bbe0590SSundeep Panicker {
6136bbe0590SSundeep Panicker 	/* NOT SUPPORTED */
6146bbe0590SSundeep Panicker 	return (FRU_NOTSUP);
6156bbe0590SSundeep Panicker }
6166bbe0590SSundeep Panicker 
6176bbe0590SSundeep Panicker 
6186bbe0590SSundeep Panicker static fru_errno_t
6196bbe0590SSundeep Panicker frt_for_each_packet(fru_seghdl_t node,
6206bbe0590SSundeep Panicker     int (*function)(fru_tag_t *tag, uint8_t *payload, size_t length,
6216bbe0590SSundeep Panicker 	void *args), void *args)
6226bbe0590SSundeep Panicker {
6236bbe0590SSundeep Panicker 	int rc_num;
6246bbe0590SSundeep Panicker 	int status;
6256bbe0590SSundeep Panicker 	char *rc_tags;
6266bbe0590SSundeep Panicker 	char *rc_data;
6276bbe0590SSundeep Panicker 	int i;
6286bbe0590SSundeep Panicker 	packet_t *packets = NULL;
6296bbe0590SSundeep Panicker 	segment_list_t *tmp_list;
6306bbe0590SSundeep Panicker 	fru_segdesc_t *descriptor;
6316bbe0590SSundeep Panicker 
6326bbe0590SSundeep Panicker 	tmp_list = g_raw->segs;
6336bbe0590SSundeep Panicker 
6346bbe0590SSundeep Panicker 	/* num of packet */
6356bbe0590SSundeep Panicker 	rc_num = fru_get_num_packets(node, NULL);
6366bbe0590SSundeep Panicker 	if (rc_num == -1) {
6376bbe0590SSundeep Panicker 		return (map_errno(errno));
6386bbe0590SSundeep Panicker 	} else if (rc_num == 0) {
6396bbe0590SSundeep Panicker 		return (FRU_SUCCESS);
6406bbe0590SSundeep Panicker 	}
6416bbe0590SSundeep Panicker 	while (tmp_list) {
6426bbe0590SSundeep Panicker 		if (node == tmp_list->segment->handle) {
6436bbe0590SSundeep Panicker 			break;
6446bbe0590SSundeep Panicker 		}
6456bbe0590SSundeep Panicker 		tmp_list = tmp_list->next;
6466bbe0590SSundeep Panicker 	}
6476bbe0590SSundeep Panicker 	if (tmp_list) {
6486bbe0590SSundeep Panicker 		descriptor = (fru_segdesc_t *)&tmp_list->segment->descriptor;
6496bbe0590SSundeep Panicker 		if (descriptor->field.opaque) {
6506bbe0590SSundeep Panicker 			return (FRU_SUCCESS);
6516bbe0590SSundeep Panicker 		}
6526bbe0590SSundeep Panicker 
6536bbe0590SSundeep Panicker 		if (descriptor->field.encrypted && (encrypt_func == NULL)) {
6546bbe0590SSundeep Panicker 			return (FRU_SUCCESS);
6556bbe0590SSundeep Panicker 		}
6566bbe0590SSundeep Panicker 	}
6576bbe0590SSundeep Panicker 
6586bbe0590SSundeep Panicker 	packets = malloc(sizeof (*packets) * (rc_num));
6596bbe0590SSundeep Panicker 	if (packets == NULL) {
6606bbe0590SSundeep Panicker 		return (FRU_FAILURE);
6616bbe0590SSundeep Panicker 	}
6626bbe0590SSundeep Panicker 	/* get all packets */
6636bbe0590SSundeep Panicker 	if (fru_get_packets(node, packets, rc_num, NULL) == -1) {
6646bbe0590SSundeep Panicker 		free(packets);
6656bbe0590SSundeep Panicker 		return (map_errno(errno));
6666bbe0590SSundeep Panicker 	}
6676bbe0590SSundeep Panicker 
6686bbe0590SSundeep Panicker 	rc_tags = malloc(sizeof (*rc_tags) * (rc_num));
6696bbe0590SSundeep Panicker 	if (rc_tags == NULL) {
6706bbe0590SSundeep Panicker 		free(packets);
6716bbe0590SSundeep Panicker 		return (FRU_FAILURE);
6726bbe0590SSundeep Panicker 	}
6736bbe0590SSundeep Panicker 
6746bbe0590SSundeep Panicker 	/* number of tags */
6756bbe0590SSundeep Panicker 	for (i = 0; i < rc_num; i++) {
6766bbe0590SSundeep Panicker 		size_t rc_len =
6776bbe0590SSundeep Panicker 		    get_payload_length((fru_tag_t *)&packets[i].tag);
6786bbe0590SSundeep Panicker 
6796bbe0590SSundeep Panicker 		rc_data = malloc(sizeof (*rc_data) * (rc_len));
6806bbe0590SSundeep Panicker 		if (rc_data == NULL) {
6816bbe0590SSundeep Panicker 			free(packets);
6826bbe0590SSundeep Panicker 			return (FRU_FAILURE);
6836bbe0590SSundeep Panicker 		}
6846bbe0590SSundeep Panicker 		/* get the payload data */
6856bbe0590SSundeep Panicker 		(void) fru_get_payload(packets[i].handle, (void *)rc_data,
6866bbe0590SSundeep Panicker 		    rc_len, NULL);
6876bbe0590SSundeep Panicker 
6886bbe0590SSundeep Panicker 		if (tmp_list) {
6896bbe0590SSundeep Panicker 			descriptor =
6906bbe0590SSundeep Panicker 			    (fru_segdesc_t *)&tmp_list->segment->descriptor;
6916bbe0590SSundeep Panicker 
6926bbe0590SSundeep Panicker 			if ((descriptor->field.encrypted) &&
6936bbe0590SSundeep Panicker 			    ((status = encrypt_func(FRU_DECRYPT,
6946bbe0590SSundeep Panicker 			    (void *)rc_data, rc_len))
6956bbe0590SSundeep Panicker 			    != FRU_SUCCESS)) {
6966bbe0590SSundeep Panicker 				return (status);
6976bbe0590SSundeep Panicker 			}
6986bbe0590SSundeep Panicker 		}
6996bbe0590SSundeep Panicker 		/* print packet */
7006bbe0590SSundeep Panicker 		if ((status = function((fru_tag_t *)&packets[i].tag,
7016bbe0590SSundeep Panicker 		    (uint8_t *)rc_data, rc_len, args)) != FRU_SUCCESS) {
7026bbe0590SSundeep Panicker 			free(rc_data);
7036bbe0590SSundeep Panicker 			free(packets);
7046bbe0590SSundeep Panicker 			return (status);
7056bbe0590SSundeep Panicker 		}
7066bbe0590SSundeep Panicker 		free(rc_data);
7076bbe0590SSundeep Panicker 	}
7086bbe0590SSundeep Panicker 	return (FRU_SUCCESS);
7096bbe0590SSundeep Panicker 
7106bbe0590SSundeep Panicker }
7116bbe0590SSundeep Panicker 
7126bbe0590SSundeep Panicker 
7136bbe0590SSundeep Panicker /* object for libfru to link to */
7146bbe0590SSundeep Panicker fru_datasource_t data_source =
7156bbe0590SSundeep Panicker {
7166bbe0590SSundeep Panicker 	LIBFRU_DS_VER,
7176bbe0590SSundeep Panicker 	frt_initialize,
7186bbe0590SSundeep Panicker 	frt_shutdown,
7196bbe0590SSundeep Panicker 	frt_get_root,
7206bbe0590SSundeep Panicker 	frt_get_child,
7216bbe0590SSundeep Panicker 	frt_get_peer,
7226bbe0590SSundeep Panicker 	frt_get_parent,
7236bbe0590SSundeep Panicker 	frt_get_name_from_hdl,
7246bbe0590SSundeep Panicker 	frt_get_node_type,
7256bbe0590SSundeep Panicker 	frt_get_seg_list,
7266bbe0590SSundeep Panicker 	frt_get_seg_def,
7276bbe0590SSundeep Panicker 	frt_add_seg,
7286bbe0590SSundeep Panicker 	frt_delete_seg,
7296bbe0590SSundeep Panicker 	frt_for_each_segment,
7306bbe0590SSundeep Panicker 	frt_get_segment_name,
7316bbe0590SSundeep Panicker 	frt_add_tag_to_seg,
7326bbe0590SSundeep Panicker 	frt_get_tag_list,
7336bbe0590SSundeep Panicker 	frt_get_tag_data,
7346bbe0590SSundeep Panicker 	frt_set_tag_data,
7356bbe0590SSundeep Panicker 	frt_delete_tag,
7366bbe0590SSundeep Panicker 	frt_for_each_packet
7376bbe0590SSundeep Panicker };
738