xref: /onnv-gate/usr/src/lib/libfru/libfruraw/fruraw.c (revision 12126:60364f3f65c7)
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 <stdarg.h>
2811015SSundeep.Panicker@Sun.COM #include <stdlib.h>
2911015SSundeep.Panicker@Sun.COM #include <errno.h>
3011015SSundeep.Panicker@Sun.COM #include <string.h>
3111015SSundeep.Panicker@Sun.COM 
3211015SSundeep.Panicker@Sun.COM #include "fru_access_impl.h"
3311015SSundeep.Panicker@Sun.COM 
3411015SSundeep.Panicker@Sun.COM #include "libfruds.h"
3511015SSundeep.Panicker@Sun.COM #include "libfrup.h"
3611015SSundeep.Panicker@Sun.COM #include "fru_access.h"
3711015SSundeep.Panicker@Sun.COM #include "fruraw.h"
3811015SSundeep.Panicker@Sun.COM 
3911015SSundeep.Panicker@Sun.COM 
4011015SSundeep.Panicker@Sun.COM raw_list_t *g_raw = NULL;
4111015SSundeep.Panicker@Sun.COM 
4211015SSundeep.Panicker@Sun.COM 
4311015SSundeep.Panicker@Sun.COM /* ARGSUSED */
4411015SSundeep.Panicker@Sun.COM static raw_list_t *
treehdl_to_rawlist(fru_treehdl_t handle)4511015SSundeep.Panicker@Sun.COM treehdl_to_rawlist(fru_treehdl_t handle)
4611015SSundeep.Panicker@Sun.COM {
4711015SSundeep.Panicker@Sun.COM 	return (g_raw);
4811015SSundeep.Panicker@Sun.COM }
4911015SSundeep.Panicker@Sun.COM 
5011015SSundeep.Panicker@Sun.COM 
5111015SSundeep.Panicker@Sun.COM static container_hdl_t
treehdl_to_conthdl(fru_treehdl_t handle)5211015SSundeep.Panicker@Sun.COM treehdl_to_conthdl(fru_treehdl_t handle)
5311015SSundeep.Panicker@Sun.COM {
5411015SSundeep.Panicker@Sun.COM 	raw_list_t *ptr;
5511015SSundeep.Panicker@Sun.COM 
5611015SSundeep.Panicker@Sun.COM 	ptr = treehdl_to_rawlist(handle);
5711015SSundeep.Panicker@Sun.COM 	if (ptr == NULL) {
5811015SSundeep.Panicker@Sun.COM 		return (-1);
5911015SSundeep.Panicker@Sun.COM 	}
6011015SSundeep.Panicker@Sun.COM 
6111015SSundeep.Panicker@Sun.COM 	return (ptr->cont);
6211015SSundeep.Panicker@Sun.COM }
6311015SSundeep.Panicker@Sun.COM 
6411015SSundeep.Panicker@Sun.COM 
6511015SSundeep.Panicker@Sun.COM static fru_errno_t
map_errno(int err)6611015SSundeep.Panicker@Sun.COM map_errno(int err)
6711015SSundeep.Panicker@Sun.COM {
6811015SSundeep.Panicker@Sun.COM 	switch (err) {
6911015SSundeep.Panicker@Sun.COM 	case ENFILE:
7011015SSundeep.Panicker@Sun.COM 	case EEXIST:
7111015SSundeep.Panicker@Sun.COM 		return (FRU_DUPSEG);
7211015SSundeep.Panicker@Sun.COM 	case EAGAIN:
7311015SSundeep.Panicker@Sun.COM 		return (FRU_NOSPACE);
7411015SSundeep.Panicker@Sun.COM 	case EPERM:
7511015SSundeep.Panicker@Sun.COM 		return (FRU_INVALPERM);
7611015SSundeep.Panicker@Sun.COM 	default :
7711015SSundeep.Panicker@Sun.COM 		return (FRU_IOERROR);
7811015SSundeep.Panicker@Sun.COM 	}
7911015SSundeep.Panicker@Sun.COM }
8011015SSundeep.Panicker@Sun.COM 
8111015SSundeep.Panicker@Sun.COM 
8211015SSundeep.Panicker@Sun.COM static raw_list_t *
make_raw(uint8_t * buffer,size_t size,char * cont_type)8311015SSundeep.Panicker@Sun.COM make_raw(uint8_t *buffer, size_t size, char *cont_type)
8411015SSundeep.Panicker@Sun.COM {
8511015SSundeep.Panicker@Sun.COM 	raw_list_t *node;
8611015SSundeep.Panicker@Sun.COM 
8711015SSundeep.Panicker@Sun.COM 	node = (raw_list_t *)malloc(sizeof (raw_list_t));
8811015SSundeep.Panicker@Sun.COM 	if (node == NULL) {
8911015SSundeep.Panicker@Sun.COM 		return (NULL);
9011015SSundeep.Panicker@Sun.COM 	}
9111015SSundeep.Panicker@Sun.COM 
9211015SSundeep.Panicker@Sun.COM 	node->hdl = 0;
9311015SSundeep.Panicker@Sun.COM 	node->raw = buffer;
9411015SSundeep.Panicker@Sun.COM 	node->size = size;
9511015SSundeep.Panicker@Sun.COM 	node->cont_type = strdup(cont_type);
9611015SSundeep.Panicker@Sun.COM 	if (node->cont_type == NULL) {
9711015SSundeep.Panicker@Sun.COM 		free(node);
9811015SSundeep.Panicker@Sun.COM 		return (NULL);
9911015SSundeep.Panicker@Sun.COM 	}
10011015SSundeep.Panicker@Sun.COM 	node->segs = NULL;
10111015SSundeep.Panicker@Sun.COM 
10211015SSundeep.Panicker@Sun.COM 	return (node);
10311015SSundeep.Panicker@Sun.COM }
10411015SSundeep.Panicker@Sun.COM 
10511015SSundeep.Panicker@Sun.COM 
10611015SSundeep.Panicker@Sun.COM /*
10711015SSundeep.Panicker@Sun.COM  * Arguments :
10811015SSundeep.Panicker@Sun.COM  * 0 - pointer to byte buffer (in)
10911015SSundeep.Panicker@Sun.COM  * 1 - size of buffer (in)
11011015SSundeep.Panicker@Sun.COM  * 2 - container type, string (in)
11111015SSundeep.Panicker@Sun.COM  */
11211015SSundeep.Panicker@Sun.COM static fru_errno_t
frt_initialize(int num,char ** args)11311015SSundeep.Panicker@Sun.COM frt_initialize(int num, char **args)
11411015SSundeep.Panicker@Sun.COM {
11511015SSundeep.Panicker@Sun.COM 
11611015SSundeep.Panicker@Sun.COM 
11711015SSundeep.Panicker@Sun.COM 	if (num != 3) {
11811015SSundeep.Panicker@Sun.COM 		return (FRU_FAILURE);
11911015SSundeep.Panicker@Sun.COM 	}
12011015SSundeep.Panicker@Sun.COM 
12111015SSundeep.Panicker@Sun.COM 	g_raw = make_raw((uint8_t *)args[0], (size_t)args[1], args[2]);
12211015SSundeep.Panicker@Sun.COM 	if (g_raw == NULL) {
12311015SSundeep.Panicker@Sun.COM 		return (FRU_FAILURE);
12411015SSundeep.Panicker@Sun.COM 	}
12511015SSundeep.Panicker@Sun.COM 
12611015SSundeep.Panicker@Sun.COM 	g_raw->cont = open_raw_data(g_raw);
12711015SSundeep.Panicker@Sun.COM 	if (g_raw->cont == NULL) {
12811015SSundeep.Panicker@Sun.COM 		return (FRU_FAILURE);
12911015SSundeep.Panicker@Sun.COM 	}
13011015SSundeep.Panicker@Sun.COM 
13111015SSundeep.Panicker@Sun.COM 	return (FRU_SUCCESS);
13211015SSundeep.Panicker@Sun.COM }
13311015SSundeep.Panicker@Sun.COM 
13411015SSundeep.Panicker@Sun.COM 
13511015SSundeep.Panicker@Sun.COM static fru_errno_t
frt_shutdown(void)13611015SSundeep.Panicker@Sun.COM frt_shutdown(void)
13711015SSundeep.Panicker@Sun.COM {
13811015SSundeep.Panicker@Sun.COM 	segment_list_t *lptr, *lptr2;
13911015SSundeep.Panicker@Sun.COM 
14011015SSundeep.Panicker@Sun.COM 	(void) fru_close_container(g_raw->cont);
14111015SSundeep.Panicker@Sun.COM 	free(g_raw->cont_type);
14211015SSundeep.Panicker@Sun.COM 	lptr = g_raw->segs;
14311015SSundeep.Panicker@Sun.COM 	while (lptr) {
14411015SSundeep.Panicker@Sun.COM 		lptr2 = lptr;
14511015SSundeep.Panicker@Sun.COM 		lptr = lptr->next;
14611015SSundeep.Panicker@Sun.COM 		free(lptr2);
14711015SSundeep.Panicker@Sun.COM 	}
14811015SSundeep.Panicker@Sun.COM 	g_raw = NULL;
14911015SSundeep.Panicker@Sun.COM 
15011015SSundeep.Panicker@Sun.COM 	return (FRU_SUCCESS);
15111015SSundeep.Panicker@Sun.COM }
15211015SSundeep.Panicker@Sun.COM 
15311015SSundeep.Panicker@Sun.COM 
15411015SSundeep.Panicker@Sun.COM static fru_errno_t
frt_get_root(fru_treehdl_t * node)15511015SSundeep.Panicker@Sun.COM frt_get_root(fru_treehdl_t *node)
15611015SSundeep.Panicker@Sun.COM {
15711015SSundeep.Panicker@Sun.COM 	*node = g_raw->hdl;
15811015SSundeep.Panicker@Sun.COM 
15911015SSundeep.Panicker@Sun.COM 	return (FRU_SUCCESS);
16011015SSundeep.Panicker@Sun.COM }
16111015SSundeep.Panicker@Sun.COM 
16211015SSundeep.Panicker@Sun.COM /* ARGSUSED */
16311015SSundeep.Panicker@Sun.COM static fru_errno_t
frt_get_peer(fru_treehdl_t sibling,fru_treehdl_t * peer)16411015SSundeep.Panicker@Sun.COM frt_get_peer(fru_treehdl_t sibling, fru_treehdl_t *peer)
16511015SSundeep.Panicker@Sun.COM {
16611015SSundeep.Panicker@Sun.COM 	return (FRU_NODENOTFOUND);
16711015SSundeep.Panicker@Sun.COM }
16811015SSundeep.Panicker@Sun.COM /* ARGSUSED */
16911015SSundeep.Panicker@Sun.COM static fru_errno_t
frt_get_child(fru_treehdl_t handle,fru_treehdl_t * child)17011015SSundeep.Panicker@Sun.COM frt_get_child(fru_treehdl_t handle, fru_treehdl_t *child)
17111015SSundeep.Panicker@Sun.COM {
17211015SSundeep.Panicker@Sun.COM 	return (FRU_NODENOTFOUND);
17311015SSundeep.Panicker@Sun.COM }
17411015SSundeep.Panicker@Sun.COM 
17511015SSundeep.Panicker@Sun.COM /* ARGSUSED */
17611015SSundeep.Panicker@Sun.COM static fru_errno_t
frt_get_parent(fru_treehdl_t handle,fru_treehdl_t * parent)17711015SSundeep.Panicker@Sun.COM frt_get_parent(fru_treehdl_t handle, fru_treehdl_t *parent)
17811015SSundeep.Panicker@Sun.COM {
17911015SSundeep.Panicker@Sun.COM 	return (FRU_NODENOTFOUND);
18011015SSundeep.Panicker@Sun.COM }
18111015SSundeep.Panicker@Sun.COM 
18211015SSundeep.Panicker@Sun.COM /* ARGSUSED */
18311015SSundeep.Panicker@Sun.COM static fru_errno_t
frt_get_name_from_hdl(fru_treehdl_t handle,char ** name)18411015SSundeep.Panicker@Sun.COM frt_get_name_from_hdl(fru_treehdl_t handle, char **name)
18511015SSundeep.Panicker@Sun.COM {
18611015SSundeep.Panicker@Sun.COM 	*name = strdup("unknown");
18711015SSundeep.Panicker@Sun.COM 	return (FRU_SUCCESS);
18811015SSundeep.Panicker@Sun.COM }
18911015SSundeep.Panicker@Sun.COM 
19011015SSundeep.Panicker@Sun.COM /* ARGSUSED */
19111015SSundeep.Panicker@Sun.COM static fru_errno_t
frt_get_node_type(fru_treehdl_t node,fru_node_t * type)19211015SSundeep.Panicker@Sun.COM frt_get_node_type(fru_treehdl_t node, fru_node_t *type)
19311015SSundeep.Panicker@Sun.COM {
19411015SSundeep.Panicker@Sun.COM 	*type = FRU_NODE_CONTAINER;
19511015SSundeep.Panicker@Sun.COM 	return (FRU_SUCCESS);
19611015SSundeep.Panicker@Sun.COM }
19711015SSundeep.Panicker@Sun.COM 
19811015SSundeep.Panicker@Sun.COM 
19911015SSundeep.Panicker@Sun.COM 
20011015SSundeep.Panicker@Sun.COM static fru_errno_t
add_segs_for_section(section_t * section,fru_strlist_t * list)20111015SSundeep.Panicker@Sun.COM add_segs_for_section(section_t *section, fru_strlist_t *list)
20211015SSundeep.Panicker@Sun.COM {
20311015SSundeep.Panicker@Sun.COM 	int i = 0;
20411015SSundeep.Panicker@Sun.COM 	segment_t *segs = NULL;
20511015SSundeep.Panicker@Sun.COM 	int acc_err = 0;
20611015SSundeep.Panicker@Sun.COM 
20711015SSundeep.Panicker@Sun.COM 	int num_segment = fru_get_num_segments(section->handle, NULL);
20811015SSundeep.Panicker@Sun.COM 	if (num_segment == -1) {
20911015SSundeep.Panicker@Sun.COM 		return (map_errno(errno));
21011015SSundeep.Panicker@Sun.COM 	} else if (num_segment == 0) {
21111015SSundeep.Panicker@Sun.COM 		return (FRU_SUCCESS);
21211015SSundeep.Panicker@Sun.COM 	}
21311015SSundeep.Panicker@Sun.COM 
21411015SSundeep.Panicker@Sun.COM 	segs = malloc(sizeof (*segs) * (num_segment));
21511015SSundeep.Panicker@Sun.COM 	if (segs == NULL) {
21611015SSundeep.Panicker@Sun.COM 		return (FRU_FAILURE);
21711015SSundeep.Panicker@Sun.COM 	}
21811015SSundeep.Panicker@Sun.COM 
21911015SSundeep.Panicker@Sun.COM 	acc_err = fru_get_segments(section->handle, segs, num_segment, NULL);
22011015SSundeep.Panicker@Sun.COM 	if (acc_err == -1) {
22111015SSundeep.Panicker@Sun.COM 		free(segs);
22211015SSundeep.Panicker@Sun.COM 		return (map_errno(errno));
22311015SSundeep.Panicker@Sun.COM 	}
22411015SSundeep.Panicker@Sun.COM 
22511015SSundeep.Panicker@Sun.COM 	list->strs = realloc(list->strs, sizeof (char *)
22611015SSundeep.Panicker@Sun.COM 	    * (list->num + num_segment));
22711015SSundeep.Panicker@Sun.COM 
22811015SSundeep.Panicker@Sun.COM 	for (i = 0; i < num_segment; i++) {
22911015SSundeep.Panicker@Sun.COM 		/* ensure NULL terminated. */
23011015SSundeep.Panicker@Sun.COM 		char *tmp = malloc(sizeof (*tmp) * (sizeof (segs[i].name)+1));
23111015SSundeep.Panicker@Sun.COM 		if (tmp == NULL) {
23211015SSundeep.Panicker@Sun.COM 			free(segs);
23311015SSundeep.Panicker@Sun.COM 			return (FRU_FAILURE);
23411015SSundeep.Panicker@Sun.COM 		}
23511015SSundeep.Panicker@Sun.COM 		(void) memcpy(tmp, segs[i].name, sizeof (segs[i].name));
23611015SSundeep.Panicker@Sun.COM 		tmp[sizeof (segs[i].name)] = '\0';
23711015SSundeep.Panicker@Sun.COM 
23811015SSundeep.Panicker@Sun.COM 		list->strs[(list->num)++] = tmp;
23911015SSundeep.Panicker@Sun.COM 	}
24011015SSundeep.Panicker@Sun.COM 
24111015SSundeep.Panicker@Sun.COM 	free(segs);
24211015SSundeep.Panicker@Sun.COM 
24311015SSundeep.Panicker@Sun.COM 	return (FRU_SUCCESS);
24411015SSundeep.Panicker@Sun.COM }
24511015SSundeep.Panicker@Sun.COM 
24611015SSundeep.Panicker@Sun.COM 
24711015SSundeep.Panicker@Sun.COM 
24811015SSundeep.Panicker@Sun.COM static fru_errno_t
frt_get_seg_list(fru_treehdl_t handle,fru_strlist_t * list)24911015SSundeep.Panicker@Sun.COM frt_get_seg_list(fru_treehdl_t handle, fru_strlist_t *list)
25011015SSundeep.Panicker@Sun.COM {
25111015SSundeep.Panicker@Sun.COM 	fru_strlist_t rc_list;
25211015SSundeep.Panicker@Sun.COM 	fru_errno_t err = FRU_SUCCESS;
25311015SSundeep.Panicker@Sun.COM 	int acc_err = 0;
25411015SSundeep.Panicker@Sun.COM 	int i = 0;
25511015SSundeep.Panicker@Sun.COM 	int num_section = 0;
25611015SSundeep.Panicker@Sun.COM 	section_t *sects = NULL;
25711015SSundeep.Panicker@Sun.COM 	container_hdl_t cont;
25811015SSundeep.Panicker@Sun.COM 
25911015SSundeep.Panicker@Sun.COM 	cont = treehdl_to_conthdl(handle);
26011015SSundeep.Panicker@Sun.COM 
26111015SSundeep.Panicker@Sun.COM 	num_section = fru_get_num_sections(cont, NULL);
26211015SSundeep.Panicker@Sun.COM 	if (num_section == -1) {
26311015SSundeep.Panicker@Sun.COM 		return (map_errno(errno));
26411015SSundeep.Panicker@Sun.COM 	}
26511015SSundeep.Panicker@Sun.COM 
26611015SSundeep.Panicker@Sun.COM 	sects = malloc(sizeof (*sects) * (num_section));
26711015SSundeep.Panicker@Sun.COM 	if (sects == NULL) {
26811015SSundeep.Panicker@Sun.COM 		return (FRU_FAILURE);
26911015SSundeep.Panicker@Sun.COM 	}
27011015SSundeep.Panicker@Sun.COM 
27111015SSundeep.Panicker@Sun.COM 	acc_err = fru_get_sections(cont, sects, num_section, NULL);
27211015SSundeep.Panicker@Sun.COM 	if (acc_err == -1) {
27311015SSundeep.Panicker@Sun.COM 		free(sects);
27411015SSundeep.Panicker@Sun.COM 		return (map_errno(errno));
27511015SSundeep.Panicker@Sun.COM 	}
27611015SSundeep.Panicker@Sun.COM 
27711015SSundeep.Panicker@Sun.COM 	rc_list.num = 0;
27811015SSundeep.Panicker@Sun.COM 	rc_list.strs = NULL;
27911015SSundeep.Panicker@Sun.COM 	for (i = 0; i < num_section; i++) {
28011015SSundeep.Panicker@Sun.COM 		if ((err = add_segs_for_section(&(sects[i]), &rc_list))
28111015SSundeep.Panicker@Sun.COM 		    != FRU_SUCCESS) {
28211015SSundeep.Panicker@Sun.COM 			fru_destroy_strlist(&rc_list);
28311015SSundeep.Panicker@Sun.COM 			free(sects);
28411015SSundeep.Panicker@Sun.COM 			return (err);
28511015SSundeep.Panicker@Sun.COM 		}
28611015SSundeep.Panicker@Sun.COM 	}
28711015SSundeep.Panicker@Sun.COM 
28811015SSundeep.Panicker@Sun.COM 	list->strs = rc_list.strs;
28911015SSundeep.Panicker@Sun.COM 	list->num = rc_list.num;
29011015SSundeep.Panicker@Sun.COM 
29111015SSundeep.Panicker@Sun.COM 	return (FRU_SUCCESS);
29211015SSundeep.Panicker@Sun.COM }
29311015SSundeep.Panicker@Sun.COM 
29411015SSundeep.Panicker@Sun.COM 
29511015SSundeep.Panicker@Sun.COM static fru_errno_t
find_seg_in_sect(section_t * sect,const char * seg_name,int * prot_flg,segment_t * segment)29611015SSundeep.Panicker@Sun.COM find_seg_in_sect(section_t *sect, const char *seg_name, int *prot_flg,
29711015SSundeep.Panicker@Sun.COM     segment_t *segment)
29811015SSundeep.Panicker@Sun.COM {
29911015SSundeep.Panicker@Sun.COM 	int j = 0;
30011015SSundeep.Panicker@Sun.COM 	int acc_err = 0;
30111015SSundeep.Panicker@Sun.COM 	segment_t *segs = NULL;
30211015SSundeep.Panicker@Sun.COM 
30311015SSundeep.Panicker@Sun.COM 	int num_seg = fru_get_num_segments(sect->handle, NULL);
30411015SSundeep.Panicker@Sun.COM 	if (num_seg == -1) {
30511015SSundeep.Panicker@Sun.COM 		return (FRU_FAILURE);
30611015SSundeep.Panicker@Sun.COM 	}
30711015SSundeep.Panicker@Sun.COM 
30811015SSundeep.Panicker@Sun.COM 	segs = malloc(sizeof (*segs) * (num_seg));
30911015SSundeep.Panicker@Sun.COM 	if (segs == NULL) {
31011015SSundeep.Panicker@Sun.COM 		return (FRU_FAILURE);
31111015SSundeep.Panicker@Sun.COM 	}
31211015SSundeep.Panicker@Sun.COM 
31311015SSundeep.Panicker@Sun.COM 	acc_err = fru_get_segments(sect->handle, segs, num_seg, NULL);
31411015SSundeep.Panicker@Sun.COM 	if (acc_err == -1) {
31511015SSundeep.Panicker@Sun.COM 		free(segs);
31611015SSundeep.Panicker@Sun.COM 		return (map_errno(errno));
31711015SSundeep.Panicker@Sun.COM 	}
31811015SSundeep.Panicker@Sun.COM 
31911015SSundeep.Panicker@Sun.COM 	for (j = 0; j < num_seg; j++) {
32011015SSundeep.Panicker@Sun.COM 		/* NULL terminate */
32111015SSundeep.Panicker@Sun.COM 		char tmp[SEG_NAME_LEN+1];
32211015SSundeep.Panicker@Sun.COM 		(void) memcpy(tmp, segs[j].name, SEG_NAME_LEN);
32311015SSundeep.Panicker@Sun.COM 		tmp[SEG_NAME_LEN] = '\0';
32411015SSundeep.Panicker@Sun.COM 		if (strcmp(tmp, seg_name) == 0) {
32511015SSundeep.Panicker@Sun.COM 			*segment = segs[j];
32611015SSundeep.Panicker@Sun.COM 			*prot_flg = (sect->protection ? 1 : 0);
32711015SSundeep.Panicker@Sun.COM 			free(segs);
32811015SSundeep.Panicker@Sun.COM 			return (FRU_SUCCESS);
32911015SSundeep.Panicker@Sun.COM 		}
33011015SSundeep.Panicker@Sun.COM 	}
33111015SSundeep.Panicker@Sun.COM 
33211015SSundeep.Panicker@Sun.COM 	free(segs);
33311015SSundeep.Panicker@Sun.COM 	return (FRU_INVALSEG);
33411015SSundeep.Panicker@Sun.COM }
33511015SSundeep.Panicker@Sun.COM 
33611015SSundeep.Panicker@Sun.COM 
33711015SSundeep.Panicker@Sun.COM static fru_errno_t
find_segment(fru_treehdl_t handle,const char * seg_name,int * prot_flg,segment_t * segment)33811015SSundeep.Panicker@Sun.COM find_segment(fru_treehdl_t handle, const char *seg_name, int *prot_flg,
33911015SSundeep.Panicker@Sun.COM     segment_t *segment)
34011015SSundeep.Panicker@Sun.COM {
34111015SSundeep.Panicker@Sun.COM 	int i = 0;
34211015SSundeep.Panicker@Sun.COM 	int acc_err = 0;
34311015SSundeep.Panicker@Sun.COM 	section_t *sect = NULL;
34411015SSundeep.Panicker@Sun.COM 	container_hdl_t cont;
34511015SSundeep.Panicker@Sun.COM 	int num_sect;
34611015SSundeep.Panicker@Sun.COM 
34711015SSundeep.Panicker@Sun.COM 	cont = treehdl_to_conthdl(handle);
34811015SSundeep.Panicker@Sun.COM 
34911015SSundeep.Panicker@Sun.COM 	num_sect = fru_get_num_sections(cont, NULL);
35011015SSundeep.Panicker@Sun.COM 	if (num_sect == -1) {
35111015SSundeep.Panicker@Sun.COM 		return (map_errno(errno));
35211015SSundeep.Panicker@Sun.COM 	}
35311015SSundeep.Panicker@Sun.COM 
35411015SSundeep.Panicker@Sun.COM 	sect = malloc(sizeof (*sect) * (num_sect));
35511015SSundeep.Panicker@Sun.COM 	if (sect == NULL) {
35611015SSundeep.Panicker@Sun.COM 		return (FRU_FAILURE);
35711015SSundeep.Panicker@Sun.COM 	}
35811015SSundeep.Panicker@Sun.COM 
35911015SSundeep.Panicker@Sun.COM 	acc_err = fru_get_sections(cont, sect, num_sect, NULL);
36011015SSundeep.Panicker@Sun.COM 	if (acc_err == -1) {
36111015SSundeep.Panicker@Sun.COM 		free(sect);
36211015SSundeep.Panicker@Sun.COM 		return (map_errno(errno));
36311015SSundeep.Panicker@Sun.COM 	}
36411015SSundeep.Panicker@Sun.COM 
36511015SSundeep.Panicker@Sun.COM 	for (i = 0; i < num_sect; i++) {
36611015SSundeep.Panicker@Sun.COM 		if (find_seg_in_sect(&(sect[i]), seg_name, prot_flg, segment)
36711015SSundeep.Panicker@Sun.COM 		    == FRU_SUCCESS) {
36811015SSundeep.Panicker@Sun.COM 			free(sect);
36911015SSundeep.Panicker@Sun.COM 			return (FRU_SUCCESS);
37011015SSundeep.Panicker@Sun.COM 		}
37111015SSundeep.Panicker@Sun.COM 	}
37211015SSundeep.Panicker@Sun.COM 
37311015SSundeep.Panicker@Sun.COM 	free(sect);
37411015SSundeep.Panicker@Sun.COM 	return (FRU_INVALSEG);
37511015SSundeep.Panicker@Sun.COM }
37611015SSundeep.Panicker@Sun.COM 
37711015SSundeep.Panicker@Sun.COM 
37811015SSundeep.Panicker@Sun.COM static fru_errno_t
frt_get_seg_def(fru_treehdl_t handle,const char * seg_name,fru_segdef_t * def)37911015SSundeep.Panicker@Sun.COM frt_get_seg_def(fru_treehdl_t handle, const char *seg_name, fru_segdef_t *def)
38011015SSundeep.Panicker@Sun.COM {
38111015SSundeep.Panicker@Sun.COM 	fru_errno_t err = FRU_SUCCESS;
38211015SSundeep.Panicker@Sun.COM 	int prot_flg = 0;
38311015SSundeep.Panicker@Sun.COM 	segment_t segment;
38411015SSundeep.Panicker@Sun.COM 
38511015SSundeep.Panicker@Sun.COM 	if ((err = find_segment(handle, seg_name, &prot_flg, &segment))
38611015SSundeep.Panicker@Sun.COM 	    != FRU_SUCCESS) {
38711015SSundeep.Panicker@Sun.COM 		return (err);
38811015SSundeep.Panicker@Sun.COM 	}
38911015SSundeep.Panicker@Sun.COM 
39011015SSundeep.Panicker@Sun.COM 	(void) memcpy(def->name, segment.name, SEG_NAME_LEN);
39111015SSundeep.Panicker@Sun.COM 	def->name[SEG_NAME_LEN] = '\0';
39211015SSundeep.Panicker@Sun.COM 	def->desc.raw_data = segment.descriptor;
39311015SSundeep.Panicker@Sun.COM 	def->size = segment.length;
39411015SSundeep.Panicker@Sun.COM 	def->address = segment.offset;
39511015SSundeep.Panicker@Sun.COM 
39611015SSundeep.Panicker@Sun.COM 	if (prot_flg == 0)
39711015SSundeep.Panicker@Sun.COM 		def->hw_desc.field.read_only = 0;
39811015SSundeep.Panicker@Sun.COM 	else
39911015SSundeep.Panicker@Sun.COM 		def->hw_desc.field.read_only = 1;
40011015SSundeep.Panicker@Sun.COM 
40111015SSundeep.Panicker@Sun.COM 	return (FRU_SUCCESS);
40211015SSundeep.Panicker@Sun.COM 
40311015SSundeep.Panicker@Sun.COM }
40411015SSundeep.Panicker@Sun.COM 
40511015SSundeep.Panicker@Sun.COM /* ARGSUSED */
40611015SSundeep.Panicker@Sun.COM static fru_errno_t
frt_add_seg(fru_treehdl_t handle,fru_segdef_t * def)40711015SSundeep.Panicker@Sun.COM frt_add_seg(fru_treehdl_t handle, fru_segdef_t *def)
40811015SSundeep.Panicker@Sun.COM {
40911015SSundeep.Panicker@Sun.COM 	/* NOT SUPPORTED */
41011015SSundeep.Panicker@Sun.COM 	return (FRU_NOTSUP);
41111015SSundeep.Panicker@Sun.COM }
41211015SSundeep.Panicker@Sun.COM 
41311015SSundeep.Panicker@Sun.COM /* ARGSUSED */
41411015SSundeep.Panicker@Sun.COM static fru_errno_t
frt_delete_seg(fru_treehdl_t handle,const char * seg_name)41511015SSundeep.Panicker@Sun.COM frt_delete_seg(fru_treehdl_t handle, const char *seg_name)
41611015SSundeep.Panicker@Sun.COM {
41711015SSundeep.Panicker@Sun.COM 	/* NOT SUPPORTED */
41811015SSundeep.Panicker@Sun.COM 	return (FRU_NOTSUP);
41911015SSundeep.Panicker@Sun.COM }
42011015SSundeep.Panicker@Sun.COM 
42111015SSundeep.Panicker@Sun.COM /* ARGSUSED */
42211015SSundeep.Panicker@Sun.COM static fru_errno_t
frt_for_each_segment(fru_nodehdl_t node,int (* function)(fru_seghdl_t hdl,void * args),void * args)42311015SSundeep.Panicker@Sun.COM frt_for_each_segment(fru_nodehdl_t node,
42411015SSundeep.Panicker@Sun.COM     int (*function)(fru_seghdl_t hdl, void *args), void *args)
42511015SSundeep.Panicker@Sun.COM {
42611015SSundeep.Panicker@Sun.COM 	int num_segment;
42711015SSundeep.Panicker@Sun.COM 	int cnt;
42811015SSundeep.Panicker@Sun.COM 	int num_sect;
42911015SSundeep.Panicker@Sun.COM 	int each_seg;
43011015SSundeep.Panicker@Sun.COM 	section_t *sects;
43111015SSundeep.Panicker@Sun.COM 	segment_t *segs;
43211015SSundeep.Panicker@Sun.COM 	segment_list_t *tmp_list;
43311015SSundeep.Panicker@Sun.COM 	int acc_err;
43411015SSundeep.Panicker@Sun.COM 	int status;
43511015SSundeep.Panicker@Sun.COM 	container_hdl_t cont;
43611015SSundeep.Panicker@Sun.COM 
43711015SSundeep.Panicker@Sun.COM 	cont = g_raw->cont;
43811015SSundeep.Panicker@Sun.COM 
43911015SSundeep.Panicker@Sun.COM 	num_sect = fru_get_num_sections(cont, NULL);
44011015SSundeep.Panicker@Sun.COM 	if (num_sect == -1) {
44111015SSundeep.Panicker@Sun.COM 		return (map_errno(errno));
44211015SSundeep.Panicker@Sun.COM 	}
44311015SSundeep.Panicker@Sun.COM 
44411015SSundeep.Panicker@Sun.COM 	sects = malloc((num_sect + 1) * sizeof (section_t));
44511015SSundeep.Panicker@Sun.COM 	if (sects == NULL) {
44611015SSundeep.Panicker@Sun.COM 		return (FRU_FAILURE);
44711015SSundeep.Panicker@Sun.COM 	}
44811015SSundeep.Panicker@Sun.COM 	num_sect = fru_get_sections(cont, sects, num_sect, NULL);
44911015SSundeep.Panicker@Sun.COM 	if (num_sect == -1) {
45011015SSundeep.Panicker@Sun.COM 		free(sects);
45111015SSundeep.Panicker@Sun.COM 		return (map_errno(errno));
45211015SSundeep.Panicker@Sun.COM 	}
45311015SSundeep.Panicker@Sun.COM 	for (cnt = 0; cnt < num_sect; cnt++) {
45411015SSundeep.Panicker@Sun.COM 		num_segment = fru_get_num_segments(sects[cnt].handle, NULL);
45511015SSundeep.Panicker@Sun.COM 		if (num_segment == -1) {
45611015SSundeep.Panicker@Sun.COM 			return (map_errno(errno));
45711015SSundeep.Panicker@Sun.COM 		} else if (num_segment == 0) {
45811015SSundeep.Panicker@Sun.COM 			continue;
45911015SSundeep.Panicker@Sun.COM 		}
46011015SSundeep.Panicker@Sun.COM 		segs = malloc((num_segment + 1) * sizeof (segment_t));
46111015SSundeep.Panicker@Sun.COM 		if (segs == NULL) {
46211015SSundeep.Panicker@Sun.COM 			free(sects);
46311015SSundeep.Panicker@Sun.COM 			return (FRU_FAILURE);
46411015SSundeep.Panicker@Sun.COM 		}
46511015SSundeep.Panicker@Sun.COM 		acc_err = fru_get_segments(sects[cnt].handle, segs,
46611015SSundeep.Panicker@Sun.COM 		    num_segment, NULL);
46711015SSundeep.Panicker@Sun.COM 		if (acc_err == -1) {
46811015SSundeep.Panicker@Sun.COM 			free(sects);
46911015SSundeep.Panicker@Sun.COM 			free(segs);
47011015SSundeep.Panicker@Sun.COM 			return (map_errno(errno));
47111015SSundeep.Panicker@Sun.COM 		}
47211015SSundeep.Panicker@Sun.COM 		for (each_seg = 0; each_seg < num_segment; each_seg++) {
47311015SSundeep.Panicker@Sun.COM 			tmp_list = malloc(sizeof (segment_list_t));
47411015SSundeep.Panicker@Sun.COM 			tmp_list->segment = &segs[each_seg];
47511015SSundeep.Panicker@Sun.COM 			tmp_list->next = NULL;
47611015SSundeep.Panicker@Sun.COM 			if (g_raw->segs == NULL) {
47711015SSundeep.Panicker@Sun.COM 				g_raw->segs = tmp_list;
47811015SSundeep.Panicker@Sun.COM 			} else {
47911015SSundeep.Panicker@Sun.COM 				tmp_list->next = g_raw->segs;
48011015SSundeep.Panicker@Sun.COM 				g_raw->segs = tmp_list;
48111015SSundeep.Panicker@Sun.COM 			}
48211015SSundeep.Panicker@Sun.COM 
48311015SSundeep.Panicker@Sun.COM 			if ((status = function(segs[each_seg].handle, args))
48411015SSundeep.Panicker@Sun.COM 			    != FRU_SUCCESS) {
48511015SSundeep.Panicker@Sun.COM 				free(segs);
48611015SSundeep.Panicker@Sun.COM 				free(sects);
48711015SSundeep.Panicker@Sun.COM 				return (status);
48811015SSundeep.Panicker@Sun.COM 			}
48911015SSundeep.Panicker@Sun.COM 		}
49011015SSundeep.Panicker@Sun.COM 		free(segs);
49111015SSundeep.Panicker@Sun.COM 		free(sects);
49211015SSundeep.Panicker@Sun.COM 
49311015SSundeep.Panicker@Sun.COM 	}
49411015SSundeep.Panicker@Sun.COM 	return (FRU_SUCCESS);
49511015SSundeep.Panicker@Sun.COM }
49611015SSundeep.Panicker@Sun.COM 
49711015SSundeep.Panicker@Sun.COM 
49811015SSundeep.Panicker@Sun.COM static fru_errno_t
frt_get_segment_name(fru_seghdl_t node,char ** name)49911015SSundeep.Panicker@Sun.COM frt_get_segment_name(fru_seghdl_t node, char **name)
50011015SSundeep.Panicker@Sun.COM {
50111015SSundeep.Panicker@Sun.COM 	int num_sect;
50211015SSundeep.Panicker@Sun.COM 	int acc_err;
50311015SSundeep.Panicker@Sun.COM 	int cnt;
50411015SSundeep.Panicker@Sun.COM 	int num_segment;
50511015SSundeep.Panicker@Sun.COM 	section_t *sects;
50611015SSundeep.Panicker@Sun.COM 	segment_t *segs;
50711015SSundeep.Panicker@Sun.COM 	int each_seg;
50811015SSundeep.Panicker@Sun.COM 	container_hdl_t cont;
50911015SSundeep.Panicker@Sun.COM 
51011015SSundeep.Panicker@Sun.COM 	cont = treehdl_to_conthdl(node);
51111015SSundeep.Panicker@Sun.COM 
51211015SSundeep.Panicker@Sun.COM 	num_sect = fru_get_num_sections(cont, NULL);
51311015SSundeep.Panicker@Sun.COM 	if (num_sect == -1) {
51411015SSundeep.Panicker@Sun.COM 		return (map_errno(errno));
51511015SSundeep.Panicker@Sun.COM 	}
51611015SSundeep.Panicker@Sun.COM 
51711015SSundeep.Panicker@Sun.COM 	sects = malloc(sizeof (*sects) * (num_sect));
51811015SSundeep.Panicker@Sun.COM 	if (sects == NULL) {
51911015SSundeep.Panicker@Sun.COM 		return (FRU_FAILURE);
52011015SSundeep.Panicker@Sun.COM 	}
52111015SSundeep.Panicker@Sun.COM 	acc_err = fru_get_sections(cont, sects, num_sect, NULL);
52211015SSundeep.Panicker@Sun.COM 	if (acc_err == -1) {
52311015SSundeep.Panicker@Sun.COM 		free(sects);
52411015SSundeep.Panicker@Sun.COM 		return (map_errno(errno));
52511015SSundeep.Panicker@Sun.COM 	}
52611015SSundeep.Panicker@Sun.COM 
52711015SSundeep.Panicker@Sun.COM 	for (cnt = 0; cnt < num_sect; cnt++) {
52811015SSundeep.Panicker@Sun.COM 		num_segment = fru_get_num_segments(sects[cnt].handle, NULL);
52911015SSundeep.Panicker@Sun.COM 		if (num_segment == -1) {
53011015SSundeep.Panicker@Sun.COM 			free(sects);
53111015SSundeep.Panicker@Sun.COM 			return (map_errno(errno));
53211015SSundeep.Panicker@Sun.COM 		} else if (num_segment == 0) {
53311015SSundeep.Panicker@Sun.COM 			continue;
53411015SSundeep.Panicker@Sun.COM 		}
53511015SSundeep.Panicker@Sun.COM 
53611015SSundeep.Panicker@Sun.COM 		segs = malloc(sizeof (*segs) * (num_segment));
53711015SSundeep.Panicker@Sun.COM 		if (segs == NULL) {
53811015SSundeep.Panicker@Sun.COM 			free(sects);
53911015SSundeep.Panicker@Sun.COM 			return (FRU_FAILURE);
54011015SSundeep.Panicker@Sun.COM 		}
54111015SSundeep.Panicker@Sun.COM 
54211015SSundeep.Panicker@Sun.COM 		acc_err = fru_get_segments(sects[cnt].handle, segs,
54311015SSundeep.Panicker@Sun.COM 		    num_segment, NULL);
54411015SSundeep.Panicker@Sun.COM 		if (acc_err == -1) {
54511015SSundeep.Panicker@Sun.COM 			free(sects);
54611015SSundeep.Panicker@Sun.COM 			free(segs);
54711015SSundeep.Panicker@Sun.COM 			return (map_errno(errno));
54811015SSundeep.Panicker@Sun.COM 		}
54911015SSundeep.Panicker@Sun.COM 
55011015SSundeep.Panicker@Sun.COM 		for (each_seg = 0; each_seg < num_segment; each_seg++) {
55111015SSundeep.Panicker@Sun.COM 			if (segs[each_seg].handle == node) {
55211015SSundeep.Panicker@Sun.COM 				segs[each_seg].name[FRU_SEGNAMELEN] = '\0';
553*12126SHyon.Kim@Sun.COM 				*name = strdup(segs[each_seg].name);
55411015SSundeep.Panicker@Sun.COM 				free(sects);
555*12126SHyon.Kim@Sun.COM 				free(segs);
55611015SSundeep.Panicker@Sun.COM 				return (FRU_SUCCESS);
55711015SSundeep.Panicker@Sun.COM 			}
55811015SSundeep.Panicker@Sun.COM 		}
55911015SSundeep.Panicker@Sun.COM 		free(segs);
56011015SSundeep.Panicker@Sun.COM 	}
56111015SSundeep.Panicker@Sun.COM 
56211015SSundeep.Panicker@Sun.COM 	return (FRU_FAILURE);
56311015SSundeep.Panicker@Sun.COM }
56411015SSundeep.Panicker@Sun.COM 
56511015SSundeep.Panicker@Sun.COM 
56611015SSundeep.Panicker@Sun.COM /* ARGSUSED */
56711015SSundeep.Panicker@Sun.COM static fru_errno_t
frt_add_tag_to_seg(fru_treehdl_t handle,const char * seg_name,fru_tag_t tag,uint8_t * data,size_t data_len)56811015SSundeep.Panicker@Sun.COM frt_add_tag_to_seg(fru_treehdl_t handle, const char *seg_name,
56911015SSundeep.Panicker@Sun.COM     fru_tag_t tag, uint8_t *data, size_t data_len)
57011015SSundeep.Panicker@Sun.COM {
57111015SSundeep.Panicker@Sun.COM 	/* NOT SUPPORTED */
57211015SSundeep.Panicker@Sun.COM 	return (FRU_NOTSUP);
57311015SSundeep.Panicker@Sun.COM }
57411015SSundeep.Panicker@Sun.COM 
57511015SSundeep.Panicker@Sun.COM 
57611015SSundeep.Panicker@Sun.COM /* ARGSUSED */
57711015SSundeep.Panicker@Sun.COM static fru_errno_t
frt_get_tag_list(fru_treehdl_t handle,const char * seg_name,fru_tag_t ** tags,int * number)57811015SSundeep.Panicker@Sun.COM frt_get_tag_list(fru_treehdl_t handle, const char *seg_name,
57911015SSundeep.Panicker@Sun.COM 		fru_tag_t **tags, int *number)
58011015SSundeep.Panicker@Sun.COM {
58111015SSundeep.Panicker@Sun.COM 	/* NOT SUPPORTED */
58211015SSundeep.Panicker@Sun.COM 	return (FRU_NOTSUP);
58311015SSundeep.Panicker@Sun.COM }
58411015SSundeep.Panicker@Sun.COM 
58511015SSundeep.Panicker@Sun.COM 
58611015SSundeep.Panicker@Sun.COM /* ARGSUSED */
58711015SSundeep.Panicker@Sun.COM static fru_errno_t
frt_get_tag_data(fru_treehdl_t handle,const char * seg_name,fru_tag_t tag,int instance,uint8_t ** data,size_t * data_len)58811015SSundeep.Panicker@Sun.COM frt_get_tag_data(fru_treehdl_t handle, const char *seg_name,
58911015SSundeep.Panicker@Sun.COM 		fru_tag_t tag, int instance,
59011015SSundeep.Panicker@Sun.COM 		uint8_t **data, size_t *data_len)
59111015SSundeep.Panicker@Sun.COM {
59211015SSundeep.Panicker@Sun.COM 	/* NOT SUPPORTED */
59311015SSundeep.Panicker@Sun.COM 	return (FRU_NOTSUP);
59411015SSundeep.Panicker@Sun.COM }
59511015SSundeep.Panicker@Sun.COM 
59611015SSundeep.Panicker@Sun.COM 
59711015SSundeep.Panicker@Sun.COM /* ARGSUSED */
59811015SSundeep.Panicker@Sun.COM static fru_errno_t
frt_set_tag_data(fru_treehdl_t handle,const char * seg_name,fru_tag_t tag,int instance,uint8_t * data,size_t data_len)59911015SSundeep.Panicker@Sun.COM frt_set_tag_data(fru_treehdl_t handle, const char *seg_name,
60011015SSundeep.Panicker@Sun.COM 		fru_tag_t tag, int instance,
60111015SSundeep.Panicker@Sun.COM 		uint8_t *data, size_t data_len)
60211015SSundeep.Panicker@Sun.COM {
60311015SSundeep.Panicker@Sun.COM 	/* NOT SUPPORTED */
60411015SSundeep.Panicker@Sun.COM 	return (FRU_NOTSUP);
60511015SSundeep.Panicker@Sun.COM }
60611015SSundeep.Panicker@Sun.COM 
60711015SSundeep.Panicker@Sun.COM 
60811015SSundeep.Panicker@Sun.COM /* ARGSUSED */
60911015SSundeep.Panicker@Sun.COM static fru_errno_t
frt_delete_tag(fru_treehdl_t handle,const char * seg_name,fru_tag_t tag,int instance)61011015SSundeep.Panicker@Sun.COM frt_delete_tag(fru_treehdl_t handle, const char *seg_name, fru_tag_t tag,
61111015SSundeep.Panicker@Sun.COM     int instance)
61211015SSundeep.Panicker@Sun.COM {
61311015SSundeep.Panicker@Sun.COM 	/* NOT SUPPORTED */
61411015SSundeep.Panicker@Sun.COM 	return (FRU_NOTSUP);
61511015SSundeep.Panicker@Sun.COM }
61611015SSundeep.Panicker@Sun.COM 
61711015SSundeep.Panicker@Sun.COM 
61811015SSundeep.Panicker@Sun.COM static fru_errno_t
frt_for_each_packet(fru_seghdl_t node,int (* function)(fru_tag_t * tag,uint8_t * payload,size_t length,void * args),void * args)61911015SSundeep.Panicker@Sun.COM frt_for_each_packet(fru_seghdl_t node,
62011015SSundeep.Panicker@Sun.COM     int (*function)(fru_tag_t *tag, uint8_t *payload, size_t length,
62111015SSundeep.Panicker@Sun.COM 	void *args), void *args)
62211015SSundeep.Panicker@Sun.COM {
62311015SSundeep.Panicker@Sun.COM 	int rc_num;
62411015SSundeep.Panicker@Sun.COM 	int status;
62511015SSundeep.Panicker@Sun.COM 	char *rc_tags;
62611015SSundeep.Panicker@Sun.COM 	char *rc_data;
62711015SSundeep.Panicker@Sun.COM 	int i;
62811015SSundeep.Panicker@Sun.COM 	packet_t *packets = NULL;
62911015SSundeep.Panicker@Sun.COM 	segment_list_t *tmp_list;
63011015SSundeep.Panicker@Sun.COM 	fru_segdesc_t *descriptor;
63111015SSundeep.Panicker@Sun.COM 
63211015SSundeep.Panicker@Sun.COM 	tmp_list = g_raw->segs;
63311015SSundeep.Panicker@Sun.COM 
63411015SSundeep.Panicker@Sun.COM 	/* num of packet */
63511015SSundeep.Panicker@Sun.COM 	rc_num = fru_get_num_packets(node, NULL);
63611015SSundeep.Panicker@Sun.COM 	if (rc_num == -1) {
63711015SSundeep.Panicker@Sun.COM 		return (map_errno(errno));
63811015SSundeep.Panicker@Sun.COM 	} else if (rc_num == 0) {
63911015SSundeep.Panicker@Sun.COM 		return (FRU_SUCCESS);
64011015SSundeep.Panicker@Sun.COM 	}
64111015SSundeep.Panicker@Sun.COM 	while (tmp_list) {
64211015SSundeep.Panicker@Sun.COM 		if (node == tmp_list->segment->handle) {
64311015SSundeep.Panicker@Sun.COM 			break;
64411015SSundeep.Panicker@Sun.COM 		}
64511015SSundeep.Panicker@Sun.COM 		tmp_list = tmp_list->next;
64611015SSundeep.Panicker@Sun.COM 	}
64711015SSundeep.Panicker@Sun.COM 	if (tmp_list) {
64811015SSundeep.Panicker@Sun.COM 		descriptor = (fru_segdesc_t *)&tmp_list->segment->descriptor;
64911015SSundeep.Panicker@Sun.COM 		if (descriptor->field.opaque) {
65011015SSundeep.Panicker@Sun.COM 			return (FRU_SUCCESS);
65111015SSundeep.Panicker@Sun.COM 		}
65211015SSundeep.Panicker@Sun.COM 
65311015SSundeep.Panicker@Sun.COM 		if (descriptor->field.encrypted && (encrypt_func == NULL)) {
65411015SSundeep.Panicker@Sun.COM 			return (FRU_SUCCESS);
65511015SSundeep.Panicker@Sun.COM 		}
65611015SSundeep.Panicker@Sun.COM 	}
65711015SSundeep.Panicker@Sun.COM 
65811015SSundeep.Panicker@Sun.COM 	packets = malloc(sizeof (*packets) * (rc_num));
65911015SSundeep.Panicker@Sun.COM 	if (packets == NULL) {
66011015SSundeep.Panicker@Sun.COM 		return (FRU_FAILURE);
66111015SSundeep.Panicker@Sun.COM 	}
66211015SSundeep.Panicker@Sun.COM 	/* get all packets */
66311015SSundeep.Panicker@Sun.COM 	if (fru_get_packets(node, packets, rc_num, NULL) == -1) {
66411015SSundeep.Panicker@Sun.COM 		free(packets);
66511015SSundeep.Panicker@Sun.COM 		return (map_errno(errno));
66611015SSundeep.Panicker@Sun.COM 	}
66711015SSundeep.Panicker@Sun.COM 
66811015SSundeep.Panicker@Sun.COM 	rc_tags = malloc(sizeof (*rc_tags) * (rc_num));
66911015SSundeep.Panicker@Sun.COM 	if (rc_tags == NULL) {
67011015SSundeep.Panicker@Sun.COM 		free(packets);
67111015SSundeep.Panicker@Sun.COM 		return (FRU_FAILURE);
67211015SSundeep.Panicker@Sun.COM 	}
67311015SSundeep.Panicker@Sun.COM 
67411015SSundeep.Panicker@Sun.COM 	/* number of tags */
67511015SSundeep.Panicker@Sun.COM 	for (i = 0; i < rc_num; i++) {
67611015SSundeep.Panicker@Sun.COM 		size_t rc_len =
67711015SSundeep.Panicker@Sun.COM 		    get_payload_length((fru_tag_t *)&packets[i].tag);
67811015SSundeep.Panicker@Sun.COM 
67911015SSundeep.Panicker@Sun.COM 		rc_data = malloc(sizeof (*rc_data) * (rc_len));
68011015SSundeep.Panicker@Sun.COM 		if (rc_data == NULL) {
68111015SSundeep.Panicker@Sun.COM 			free(packets);
68211015SSundeep.Panicker@Sun.COM 			return (FRU_FAILURE);
68311015SSundeep.Panicker@Sun.COM 		}
68411015SSundeep.Panicker@Sun.COM 		/* get the payload data */
68511015SSundeep.Panicker@Sun.COM 		(void) fru_get_payload(packets[i].handle, (void *)rc_data,
68611015SSundeep.Panicker@Sun.COM 		    rc_len, NULL);
68711015SSundeep.Panicker@Sun.COM 
68811015SSundeep.Panicker@Sun.COM 		if (tmp_list) {
68911015SSundeep.Panicker@Sun.COM 			descriptor =
69011015SSundeep.Panicker@Sun.COM 			    (fru_segdesc_t *)&tmp_list->segment->descriptor;
69111015SSundeep.Panicker@Sun.COM 
69211015SSundeep.Panicker@Sun.COM 			if ((descriptor->field.encrypted) &&
69311015SSundeep.Panicker@Sun.COM 			    ((status = encrypt_func(FRU_DECRYPT,
69411015SSundeep.Panicker@Sun.COM 			    (void *)rc_data, rc_len))
69511015SSundeep.Panicker@Sun.COM 			    != FRU_SUCCESS)) {
69611015SSundeep.Panicker@Sun.COM 				return (status);
69711015SSundeep.Panicker@Sun.COM 			}
69811015SSundeep.Panicker@Sun.COM 		}
69911015SSundeep.Panicker@Sun.COM 		/* print packet */
70011015SSundeep.Panicker@Sun.COM 		if ((status = function((fru_tag_t *)&packets[i].tag,
70111015SSundeep.Panicker@Sun.COM 		    (uint8_t *)rc_data, rc_len, args)) != FRU_SUCCESS) {
70211015SSundeep.Panicker@Sun.COM 			free(rc_data);
70311015SSundeep.Panicker@Sun.COM 			free(packets);
70411015SSundeep.Panicker@Sun.COM 			return (status);
70511015SSundeep.Panicker@Sun.COM 		}
70611015SSundeep.Panicker@Sun.COM 		free(rc_data);
70711015SSundeep.Panicker@Sun.COM 	}
70811015SSundeep.Panicker@Sun.COM 	return (FRU_SUCCESS);
70911015SSundeep.Panicker@Sun.COM 
71011015SSundeep.Panicker@Sun.COM }
71111015SSundeep.Panicker@Sun.COM 
71211015SSundeep.Panicker@Sun.COM 
71311015SSundeep.Panicker@Sun.COM /* object for libfru to link to */
71411015SSundeep.Panicker@Sun.COM fru_datasource_t data_source =
71511015SSundeep.Panicker@Sun.COM {
71611015SSundeep.Panicker@Sun.COM 	LIBFRU_DS_VER,
71711015SSundeep.Panicker@Sun.COM 	frt_initialize,
71811015SSundeep.Panicker@Sun.COM 	frt_shutdown,
71911015SSundeep.Panicker@Sun.COM 	frt_get_root,
72011015SSundeep.Panicker@Sun.COM 	frt_get_child,
72111015SSundeep.Panicker@Sun.COM 	frt_get_peer,
72211015SSundeep.Panicker@Sun.COM 	frt_get_parent,
72311015SSundeep.Panicker@Sun.COM 	frt_get_name_from_hdl,
72411015SSundeep.Panicker@Sun.COM 	frt_get_node_type,
72511015SSundeep.Panicker@Sun.COM 	frt_get_seg_list,
72611015SSundeep.Panicker@Sun.COM 	frt_get_seg_def,
72711015SSundeep.Panicker@Sun.COM 	frt_add_seg,
72811015SSundeep.Panicker@Sun.COM 	frt_delete_seg,
72911015SSundeep.Panicker@Sun.COM 	frt_for_each_segment,
73011015SSundeep.Panicker@Sun.COM 	frt_get_segment_name,
73111015SSundeep.Panicker@Sun.COM 	frt_add_tag_to_seg,
73211015SSundeep.Panicker@Sun.COM 	frt_get_tag_list,
73311015SSundeep.Panicker@Sun.COM 	frt_get_tag_data,
73411015SSundeep.Panicker@Sun.COM 	frt_set_tag_data,
73511015SSundeep.Panicker@Sun.COM 	frt_delete_tag,
73611015SSundeep.Panicker@Sun.COM 	frt_for_each_packet
73711015SSundeep.Panicker@Sun.COM };
738