1*6bbe0590SSundeep Panicker /*
2*6bbe0590SSundeep Panicker  * CDDL HEADER START
3*6bbe0590SSundeep Panicker  *
4*6bbe0590SSundeep Panicker  * The contents of this file are subject to the terms of the
5*6bbe0590SSundeep Panicker  * Common Development and Distribution License (the "License").
6*6bbe0590SSundeep Panicker  * You may not use this file except in compliance with the License.
7*6bbe0590SSundeep Panicker  *
8*6bbe0590SSundeep Panicker  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*6bbe0590SSundeep Panicker  * or http://www.opensolaris.org/os/licensing.
10*6bbe0590SSundeep Panicker  * See the License for the specific language governing permissions
11*6bbe0590SSundeep Panicker  * and limitations under the License.
12*6bbe0590SSundeep Panicker  *
13*6bbe0590SSundeep Panicker  * When distributing Covered Code, include this CDDL HEADER in each
14*6bbe0590SSundeep Panicker  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*6bbe0590SSundeep Panicker  * If applicable, add the following below this CDDL HEADER, with the
16*6bbe0590SSundeep Panicker  * fields enclosed by brackets "[]" replaced with your own identifying
17*6bbe0590SSundeep Panicker  * information: Portions Copyright [yyyy] [name of copyright owner]
18*6bbe0590SSundeep Panicker  *
19*6bbe0590SSundeep Panicker  * CDDL HEADER END
20*6bbe0590SSundeep Panicker  */
21*6bbe0590SSundeep Panicker 
22*6bbe0590SSundeep Panicker /*
23*6bbe0590SSundeep Panicker  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*6bbe0590SSundeep Panicker  * Use is subject to license terms.
25*6bbe0590SSundeep Panicker  */
26*6bbe0590SSundeep Panicker 
27*6bbe0590SSundeep Panicker #include <stdio.h>
28*6bbe0590SSundeep Panicker #include <stdlib.h>
29*6bbe0590SSundeep Panicker #include <alloca.h>
30*6bbe0590SSundeep Panicker #include <sys/byteorder.h>
31*6bbe0590SSundeep Panicker #include "fru_access_impl.h"
32*6bbe0590SSundeep Panicker #include "fruraw.h"
33*6bbe0590SSundeep Panicker 
34*6bbe0590SSundeep Panicker #pragma init(initialize_raw_access)
35*6bbe0590SSundeep Panicker 
36*6bbe0590SSundeep Panicker static hash_obj_t	*hash_table[TABLE_SIZE];
37*6bbe0590SSundeep Panicker extern raw_list_t 	*g_raw;
38*6bbe0590SSundeep Panicker 
39*6bbe0590SSundeep Panicker static void
40*6bbe0590SSundeep Panicker initialize_raw_access(void)
41*6bbe0590SSundeep Panicker {
42*6bbe0590SSundeep Panicker 	int	count;
43*6bbe0590SSundeep Panicker 
44*6bbe0590SSundeep Panicker 	for (count = 0; count < TABLE_SIZE; count++) {
45*6bbe0590SSundeep Panicker 		hash_table[count] = NULL;
46*6bbe0590SSundeep Panicker 	}
47*6bbe0590SSundeep Panicker }
48*6bbe0590SSundeep Panicker 
49*6bbe0590SSundeep Panicker 
50*6bbe0590SSundeep Panicker static hash_obj_t *
51*6bbe0590SSundeep Panicker lookup_handle_object(handle_t	handle, int object_type)
52*6bbe0590SSundeep Panicker {
53*6bbe0590SSundeep Panicker 	handle_t index_to_hash;
54*6bbe0590SSundeep Panicker 	hash_obj_t *first_hash_obj;
55*6bbe0590SSundeep Panicker 	hash_obj_t *next_hash_obj;
56*6bbe0590SSundeep Panicker 
57*6bbe0590SSundeep Panicker 	index_to_hash = (handle % TABLE_SIZE);
58*6bbe0590SSundeep Panicker 
59*6bbe0590SSundeep Panicker 	first_hash_obj = hash_table[index_to_hash];
60*6bbe0590SSundeep Panicker 	for (next_hash_obj = first_hash_obj; next_hash_obj != NULL;
61*6bbe0590SSundeep Panicker 	    next_hash_obj = next_hash_obj->next) {
62*6bbe0590SSundeep Panicker 		if ((handle == next_hash_obj->obj_hdl) &&
63*6bbe0590SSundeep Panicker 		    (object_type == next_hash_obj->object_type)) {
64*6bbe0590SSundeep Panicker 			return (next_hash_obj);
65*6bbe0590SSundeep Panicker 		}
66*6bbe0590SSundeep Panicker 	}
67*6bbe0590SSundeep Panicker 	return (NULL);
68*6bbe0590SSundeep Panicker }
69*6bbe0590SSundeep Panicker 
70*6bbe0590SSundeep Panicker 
71*6bbe0590SSundeep Panicker static void
72*6bbe0590SSundeep Panicker add_hashobject_to_hashtable(hash_obj_t *hash_obj)
73*6bbe0590SSundeep Panicker {
74*6bbe0590SSundeep Panicker 	handle_t index_to_hash;
75*6bbe0590SSundeep Panicker 	static	uint64_t handle_count = 0;
76*6bbe0590SSundeep Panicker 
77*6bbe0590SSundeep Panicker 	hash_obj->obj_hdl = ++handle_count;	/* store the handle */
78*6bbe0590SSundeep Panicker 
79*6bbe0590SSundeep Panicker 	/* where to add ? */
80*6bbe0590SSundeep Panicker 	index_to_hash = ((hash_obj->obj_hdl) % TABLE_SIZE);
81*6bbe0590SSundeep Panicker 
82*6bbe0590SSundeep Panicker 	hash_obj->next = hash_table[index_to_hash];
83*6bbe0590SSundeep Panicker 	hash_table[index_to_hash] = hash_obj;	/* hash obj. added */
84*6bbe0590SSundeep Panicker 
85*6bbe0590SSundeep Panicker 	if (hash_obj->next != NULL) {
86*6bbe0590SSundeep Panicker 		hash_obj->next->prev = hash_obj;
87*6bbe0590SSundeep Panicker 	}
88*6bbe0590SSundeep Panicker }
89*6bbe0590SSundeep Panicker 
90*6bbe0590SSundeep Panicker 
91*6bbe0590SSundeep Panicker static hash_obj_t *
92*6bbe0590SSundeep Panicker create_container_hash_object(void)
93*6bbe0590SSundeep Panicker {
94*6bbe0590SSundeep Panicker 	hash_obj_t *hash_obj;
95*6bbe0590SSundeep Panicker 	container_obj_t *cont_obj;
96*6bbe0590SSundeep Panicker 
97*6bbe0590SSundeep Panicker 	cont_obj = malloc(sizeof (container_obj_t));
98*6bbe0590SSundeep Panicker 	if (cont_obj == NULL) {
99*6bbe0590SSundeep Panicker 		return (NULL);
100*6bbe0590SSundeep Panicker 	}
101*6bbe0590SSundeep Panicker 
102*6bbe0590SSundeep Panicker 	hash_obj = malloc(sizeof (hash_obj_t));
103*6bbe0590SSundeep Panicker 	if (hash_obj == NULL) {
104*6bbe0590SSundeep Panicker 		free(cont_obj);
105*6bbe0590SSundeep Panicker 		return (NULL);
106*6bbe0590SSundeep Panicker 	}
107*6bbe0590SSundeep Panicker 
108*6bbe0590SSundeep Panicker 	cont_obj->sec_obj_list = NULL;
109*6bbe0590SSundeep Panicker 
110*6bbe0590SSundeep Panicker 	hash_obj->object_type = CONTAINER_TYPE;
111*6bbe0590SSundeep Panicker 	hash_obj->u.cont_obj = cont_obj;
112*6bbe0590SSundeep Panicker 	hash_obj->next = NULL;
113*6bbe0590SSundeep Panicker 	hash_obj->prev = NULL;
114*6bbe0590SSundeep Panicker 
115*6bbe0590SSundeep Panicker 	return (hash_obj);
116*6bbe0590SSundeep Panicker }
117*6bbe0590SSundeep Panicker 
118*6bbe0590SSundeep Panicker 
119*6bbe0590SSundeep Panicker static hash_obj_t *
120*6bbe0590SSundeep Panicker create_section_hash_object(void)
121*6bbe0590SSundeep Panicker {
122*6bbe0590SSundeep Panicker 	hash_obj_t *hash_obj;
123*6bbe0590SSundeep Panicker 	section_obj_t *sec_obj;
124*6bbe0590SSundeep Panicker 
125*6bbe0590SSundeep Panicker 	sec_obj	= malloc(sizeof (section_obj_t));
126*6bbe0590SSundeep Panicker 	if (sec_obj == NULL) {
127*6bbe0590SSundeep Panicker 		return (NULL);
128*6bbe0590SSundeep Panicker 	}
129*6bbe0590SSundeep Panicker 
130*6bbe0590SSundeep Panicker 	hash_obj = malloc(sizeof (hash_obj_t));
131*6bbe0590SSundeep Panicker 	if (hash_obj == NULL) {
132*6bbe0590SSundeep Panicker 		free(sec_obj);
133*6bbe0590SSundeep Panicker 		return (NULL);
134*6bbe0590SSundeep Panicker 	}
135*6bbe0590SSundeep Panicker 
136*6bbe0590SSundeep Panicker 	sec_obj->next = NULL;
137*6bbe0590SSundeep Panicker 	sec_obj->seg_obj_list = NULL;
138*6bbe0590SSundeep Panicker 
139*6bbe0590SSundeep Panicker 	hash_obj->u.sec_obj = sec_obj;
140*6bbe0590SSundeep Panicker 	hash_obj->object_type = SECTION_TYPE;
141*6bbe0590SSundeep Panicker 	hash_obj->next = NULL;
142*6bbe0590SSundeep Panicker 	hash_obj->prev = NULL;
143*6bbe0590SSundeep Panicker 
144*6bbe0590SSundeep Panicker 	return (hash_obj);
145*6bbe0590SSundeep Panicker }
146*6bbe0590SSundeep Panicker 
147*6bbe0590SSundeep Panicker 
148*6bbe0590SSundeep Panicker static hash_obj_t *
149*6bbe0590SSundeep Panicker create_segment_hash_object(void)
150*6bbe0590SSundeep Panicker {
151*6bbe0590SSundeep Panicker 	hash_obj_t *hash_obj;
152*6bbe0590SSundeep Panicker 	segment_obj_t *seg_obj;
153*6bbe0590SSundeep Panicker 
154*6bbe0590SSundeep Panicker 	seg_obj	= malloc(sizeof (segment_obj_t));
155*6bbe0590SSundeep Panicker 	if (seg_obj == NULL) {
156*6bbe0590SSundeep Panicker 		return (NULL);
157*6bbe0590SSundeep Panicker 	}
158*6bbe0590SSundeep Panicker 
159*6bbe0590SSundeep Panicker 	hash_obj = malloc(sizeof (hash_obj_t));
160*6bbe0590SSundeep Panicker 	if (hash_obj == NULL) {
161*6bbe0590SSundeep Panicker 		free(seg_obj);
162*6bbe0590SSundeep Panicker 		return (NULL);
163*6bbe0590SSundeep Panicker 	}
164*6bbe0590SSundeep Panicker 
165*6bbe0590SSundeep Panicker 	seg_obj->next = NULL;
166*6bbe0590SSundeep Panicker 	seg_obj->pkt_obj_list = NULL;
167*6bbe0590SSundeep Panicker 
168*6bbe0590SSundeep Panicker 	hash_obj->object_type = SEGMENT_TYPE;
169*6bbe0590SSundeep Panicker 	hash_obj->u.seg_obj = seg_obj;
170*6bbe0590SSundeep Panicker 	hash_obj->next = NULL;
171*6bbe0590SSundeep Panicker 	hash_obj->prev = NULL;
172*6bbe0590SSundeep Panicker 
173*6bbe0590SSundeep Panicker 	return (hash_obj);
174*6bbe0590SSundeep Panicker }
175*6bbe0590SSundeep Panicker 
176*6bbe0590SSundeep Panicker 
177*6bbe0590SSundeep Panicker static hash_obj_t *
178*6bbe0590SSundeep Panicker create_packet_hash_object(void)
179*6bbe0590SSundeep Panicker {
180*6bbe0590SSundeep Panicker 	hash_obj_t *hash_obj;
181*6bbe0590SSundeep Panicker 	packet_obj_t *pkt_obj;
182*6bbe0590SSundeep Panicker 
183*6bbe0590SSundeep Panicker 	pkt_obj	= malloc(sizeof (packet_obj_t));
184*6bbe0590SSundeep Panicker 	if (pkt_obj == NULL) {
185*6bbe0590SSundeep Panicker 		return (NULL);
186*6bbe0590SSundeep Panicker 	}
187*6bbe0590SSundeep Panicker 
188*6bbe0590SSundeep Panicker 	hash_obj = malloc(sizeof (hash_obj_t));
189*6bbe0590SSundeep Panicker 	if (hash_obj == NULL) {
190*6bbe0590SSundeep Panicker 		free(pkt_obj);
191*6bbe0590SSundeep Panicker 		return (NULL);
192*6bbe0590SSundeep Panicker 	}
193*6bbe0590SSundeep Panicker 
194*6bbe0590SSundeep Panicker 	pkt_obj->next = NULL;
195*6bbe0590SSundeep Panicker 
196*6bbe0590SSundeep Panicker 	hash_obj->object_type = PACKET_TYPE;
197*6bbe0590SSundeep Panicker 	hash_obj->u.pkt_obj = pkt_obj;
198*6bbe0590SSundeep Panicker 	hash_obj->next = NULL;
199*6bbe0590SSundeep Panicker 	hash_obj->prev = NULL;
200*6bbe0590SSundeep Panicker 
201*6bbe0590SSundeep Panicker 	return (hash_obj);
202*6bbe0590SSundeep Panicker }
203*6bbe0590SSundeep Panicker 
204*6bbe0590SSundeep Panicker 
205*6bbe0590SSundeep Panicker 
206*6bbe0590SSundeep Panicker static hash_obj_t *
207*6bbe0590SSundeep Panicker get_container_hash_object(int	object_type, handle_t	handle)
208*6bbe0590SSundeep Panicker {
209*6bbe0590SSundeep Panicker 	hash_obj_t	*hash_obj;
210*6bbe0590SSundeep Panicker 
211*6bbe0590SSundeep Panicker 	switch (object_type) {
212*6bbe0590SSundeep Panicker 	case CONTAINER_TYPE:
213*6bbe0590SSundeep Panicker 		break;
214*6bbe0590SSundeep Panicker 	case SECTION_TYPE:
215*6bbe0590SSundeep Panicker 		hash_obj = lookup_handle_object(handle, CONTAINER_TYPE);
216*6bbe0590SSundeep Panicker 		if (hash_obj == NULL) {
217*6bbe0590SSundeep Panicker 			return (NULL);
218*6bbe0590SSundeep Panicker 		}
219*6bbe0590SSundeep Panicker 		break;
220*6bbe0590SSundeep Panicker 	case SEGMENT_TYPE:
221*6bbe0590SSundeep Panicker 		hash_obj = lookup_handle_object(handle, SECTION_TYPE);
222*6bbe0590SSundeep Panicker 		if (hash_obj == NULL) {
223*6bbe0590SSundeep Panicker 			return (NULL);
224*6bbe0590SSundeep Panicker 		}
225*6bbe0590SSundeep Panicker 		hash_obj = lookup_handle_object(hash_obj->u.sec_obj->cont_hdl,
226*6bbe0590SSundeep Panicker 		    CONTAINER_TYPE);
227*6bbe0590SSundeep Panicker 		break;
228*6bbe0590SSundeep Panicker 	case PACKET_TYPE:
229*6bbe0590SSundeep Panicker 		break;
230*6bbe0590SSundeep Panicker 	default:
231*6bbe0590SSundeep Panicker 		return (NULL);
232*6bbe0590SSundeep Panicker 	}
233*6bbe0590SSundeep Panicker 
234*6bbe0590SSundeep Panicker 	return (hash_obj);
235*6bbe0590SSundeep Panicker }
236*6bbe0590SSundeep Panicker 
237*6bbe0590SSundeep Panicker 
238*6bbe0590SSundeep Panicker static void
239*6bbe0590SSundeep Panicker add_to_pkt_object_list(hash_obj_t *parent_obj, hash_obj_t *child_obj)
240*6bbe0590SSundeep Panicker {
241*6bbe0590SSundeep Panicker 	hash_obj_t *next_hash;
242*6bbe0590SSundeep Panicker 
243*6bbe0590SSundeep Panicker 	/* add the packet object in the end of list */
244*6bbe0590SSundeep Panicker 	child_obj->u.pkt_obj->segment_hdl = parent_obj->obj_hdl;
245*6bbe0590SSundeep Panicker 
246*6bbe0590SSundeep Panicker 	if (parent_obj->u.seg_obj->pkt_obj_list == NULL) {
247*6bbe0590SSundeep Panicker 		parent_obj->u.seg_obj->pkt_obj_list = child_obj;
248*6bbe0590SSundeep Panicker 		return;
249*6bbe0590SSundeep Panicker 	}
250*6bbe0590SSundeep Panicker 
251*6bbe0590SSundeep Panicker 	for (next_hash = parent_obj->u.seg_obj->pkt_obj_list;
252*6bbe0590SSundeep Panicker 	    next_hash->u.pkt_obj->next != NULL;
253*6bbe0590SSundeep Panicker 	    next_hash = next_hash->u.pkt_obj->next) {
254*6bbe0590SSundeep Panicker 		;
255*6bbe0590SSundeep Panicker 	}
256*6bbe0590SSundeep Panicker 
257*6bbe0590SSundeep Panicker 	next_hash->u.pkt_obj->next = child_obj;
258*6bbe0590SSundeep Panicker }
259*6bbe0590SSundeep Panicker 
260*6bbe0590SSundeep Panicker 
261*6bbe0590SSundeep Panicker static void
262*6bbe0590SSundeep Panicker free_pkt_object_list(hash_obj_t	*hash_obj)
263*6bbe0590SSundeep Panicker {
264*6bbe0590SSundeep Panicker 	hash_obj_t *next_obj;
265*6bbe0590SSundeep Panicker 	hash_obj_t *free_obj;
266*6bbe0590SSundeep Panicker 
267*6bbe0590SSundeep Panicker 	next_obj = hash_obj->u.seg_obj->pkt_obj_list;
268*6bbe0590SSundeep Panicker 	while (next_obj != NULL) {
269*6bbe0590SSundeep Panicker 		free_obj = next_obj;
270*6bbe0590SSundeep Panicker 		next_obj = next_obj->u.pkt_obj->next;
271*6bbe0590SSundeep Panicker 		/* if prev is NULL it's the first object in the list */
272*6bbe0590SSundeep Panicker 		if (free_obj->prev == NULL) {
273*6bbe0590SSundeep Panicker 			hash_table[(free_obj->obj_hdl % TABLE_SIZE)] =
274*6bbe0590SSundeep Panicker 			    free_obj->next;
275*6bbe0590SSundeep Panicker 			if (free_obj->next != NULL) {
276*6bbe0590SSundeep Panicker 				free_obj->next->prev = free_obj->prev;
277*6bbe0590SSundeep Panicker 			}
278*6bbe0590SSundeep Panicker 		} else {
279*6bbe0590SSundeep Panicker 			free_obj->prev->next = free_obj->next;
280*6bbe0590SSundeep Panicker 			if (free_obj->next != NULL) {
281*6bbe0590SSundeep Panicker 				free_obj->next->prev = free_obj->prev;
282*6bbe0590SSundeep Panicker 			}
283*6bbe0590SSundeep Panicker 		}
284*6bbe0590SSundeep Panicker 
285*6bbe0590SSundeep Panicker 		free(free_obj->u.pkt_obj->payload);
286*6bbe0590SSundeep Panicker 		free(free_obj->u.pkt_obj);
287*6bbe0590SSundeep Panicker 		free(free_obj);
288*6bbe0590SSundeep Panicker 	}
289*6bbe0590SSundeep Panicker 
290*6bbe0590SSundeep Panicker 	hash_obj->u.seg_obj->pkt_obj_list = NULL;
291*6bbe0590SSundeep Panicker }
292*6bbe0590SSundeep Panicker 
293*6bbe0590SSundeep Panicker 
294*6bbe0590SSundeep Panicker static void
295*6bbe0590SSundeep Panicker free_segment_hash(handle_t handle, hash_obj_t *sec_hash)
296*6bbe0590SSundeep Panicker {
297*6bbe0590SSundeep Panicker 	hash_obj_t *seg_hash;
298*6bbe0590SSundeep Panicker 	hash_obj_t *next_hash;
299*6bbe0590SSundeep Panicker 
300*6bbe0590SSundeep Panicker 	seg_hash = sec_hash->u.sec_obj->seg_obj_list;
301*6bbe0590SSundeep Panicker 	if (seg_hash == NULL) {
302*6bbe0590SSundeep Panicker 		return;
303*6bbe0590SSundeep Panicker 	}
304*6bbe0590SSundeep Panicker 
305*6bbe0590SSundeep Panicker 	if (seg_hash->obj_hdl == handle) {
306*6bbe0590SSundeep Panicker 		sec_hash->u.sec_obj->seg_obj_list = seg_hash->u.seg_obj->next;
307*6bbe0590SSundeep Panicker 	} else {
308*6bbe0590SSundeep Panicker 		while (seg_hash->obj_hdl != handle) {
309*6bbe0590SSundeep Panicker 			next_hash = seg_hash;
310*6bbe0590SSundeep Panicker 			seg_hash = seg_hash->u.seg_obj->next;
311*6bbe0590SSundeep Panicker 			if (seg_hash == NULL) {
312*6bbe0590SSundeep Panicker 				return;
313*6bbe0590SSundeep Panicker 			}
314*6bbe0590SSundeep Panicker 		}
315*6bbe0590SSundeep Panicker 		next_hash->u.seg_obj->next = seg_hash->u.seg_obj->next;
316*6bbe0590SSundeep Panicker 	}
317*6bbe0590SSundeep Panicker 
318*6bbe0590SSundeep Panicker 	if (seg_hash->prev == NULL) {
319*6bbe0590SSundeep Panicker 		hash_table[(seg_hash->obj_hdl % TABLE_SIZE)] = seg_hash->next;
320*6bbe0590SSundeep Panicker 		if (seg_hash->next != NULL) {
321*6bbe0590SSundeep Panicker 			seg_hash->next->prev = NULL;
322*6bbe0590SSundeep Panicker 		}
323*6bbe0590SSundeep Panicker 	} else {
324*6bbe0590SSundeep Panicker 		seg_hash->prev->next = seg_hash->next;
325*6bbe0590SSundeep Panicker 		if (seg_hash->next != NULL) {
326*6bbe0590SSundeep Panicker 			seg_hash->next->prev = seg_hash->prev;
327*6bbe0590SSundeep Panicker 		}
328*6bbe0590SSundeep Panicker 	}
329*6bbe0590SSundeep Panicker 
330*6bbe0590SSundeep Panicker 	free_pkt_object_list(seg_hash);
331*6bbe0590SSundeep Panicker 	free(seg_hash->u.seg_obj);
332*6bbe0590SSundeep Panicker 	free(seg_hash);
333*6bbe0590SSundeep Panicker }
334*6bbe0590SSundeep Panicker 
335*6bbe0590SSundeep Panicker 
336*6bbe0590SSundeep Panicker 
337*6bbe0590SSundeep Panicker static void
338*6bbe0590SSundeep Panicker add_to_sec_object_list(hash_obj_t *parent_obj, hash_obj_t *child_obj)
339*6bbe0590SSundeep Panicker {
340*6bbe0590SSundeep Panicker 	hash_obj_t *next_hash;
341*6bbe0590SSundeep Panicker 
342*6bbe0590SSundeep Panicker 	child_obj->u.sec_obj->cont_hdl = parent_obj->obj_hdl;
343*6bbe0590SSundeep Panicker 	if (parent_obj->u.cont_obj->sec_obj_list == NULL) {
344*6bbe0590SSundeep Panicker 		parent_obj->u.cont_obj->sec_obj_list = child_obj;
345*6bbe0590SSundeep Panicker 		return;
346*6bbe0590SSundeep Panicker 	}
347*6bbe0590SSundeep Panicker 
348*6bbe0590SSundeep Panicker 	for (next_hash = parent_obj->u.cont_obj->sec_obj_list;
349*6bbe0590SSundeep Panicker 	    next_hash->u.sec_obj->next != NULL;
350*6bbe0590SSundeep Panicker 	    next_hash = next_hash->u.sec_obj->next) {
351*6bbe0590SSundeep Panicker 		;
352*6bbe0590SSundeep Panicker 	}
353*6bbe0590SSundeep Panicker 
354*6bbe0590SSundeep Panicker 	next_hash->u.sec_obj->next = child_obj;
355*6bbe0590SSundeep Panicker }
356*6bbe0590SSundeep Panicker 
357*6bbe0590SSundeep Panicker 
358*6bbe0590SSundeep Panicker static void
359*6bbe0590SSundeep Panicker add_to_seg_object_list(hash_obj_t *parent_obj, hash_obj_t *child_obj)
360*6bbe0590SSundeep Panicker {
361*6bbe0590SSundeep Panicker 	hash_obj_t *next_hash;
362*6bbe0590SSundeep Panicker 
363*6bbe0590SSundeep Panicker 	child_obj->u.seg_obj->section_hdl = parent_obj->obj_hdl;
364*6bbe0590SSundeep Panicker 	if (parent_obj->u.sec_obj->seg_obj_list == NULL) {
365*6bbe0590SSundeep Panicker 		parent_obj->u.sec_obj->seg_obj_list = child_obj;
366*6bbe0590SSundeep Panicker 		return;
367*6bbe0590SSundeep Panicker 	}
368*6bbe0590SSundeep Panicker 
369*6bbe0590SSundeep Panicker 	for (next_hash = parent_obj->u.sec_obj->seg_obj_list;
370*6bbe0590SSundeep Panicker 	    next_hash->u.seg_obj->next != NULL;
371*6bbe0590SSundeep Panicker 	    next_hash = next_hash->u.seg_obj->next) {
372*6bbe0590SSundeep Panicker 		;
373*6bbe0590SSundeep Panicker 	}
374*6bbe0590SSundeep Panicker 
375*6bbe0590SSundeep Panicker 	next_hash->u.seg_obj->next = child_obj;
376*6bbe0590SSundeep Panicker }
377*6bbe0590SSundeep Panicker 
378*6bbe0590SSundeep Panicker 
379*6bbe0590SSundeep Panicker static char *
380*6bbe0590SSundeep Panicker tokenizer(char *buf, char *separator, char **nextBuf, char *matched)
381*6bbe0590SSundeep Panicker {
382*6bbe0590SSundeep Panicker 	int i = 0;
383*6bbe0590SSundeep Panicker 	int j = 0;
384*6bbe0590SSundeep Panicker 
385*6bbe0590SSundeep Panicker 	for (i = 0; buf[i] != '\0'; i++) {
386*6bbe0590SSundeep Panicker 		for (j = 0; j < strlen(separator); j++) {
387*6bbe0590SSundeep Panicker 			if (buf[i] == separator[j]) {
388*6bbe0590SSundeep Panicker 				buf[i] = '\0';
389*6bbe0590SSundeep Panicker 				*nextBuf = &(buf[i+1]);
390*6bbe0590SSundeep Panicker 				*matched = separator[j];
391*6bbe0590SSundeep Panicker 				return (buf);
392*6bbe0590SSundeep Panicker 			}
393*6bbe0590SSundeep Panicker 		}
394*6bbe0590SSundeep Panicker 	}
395*6bbe0590SSundeep Panicker 
396*6bbe0590SSundeep Panicker 	*nextBuf = buf;
397*6bbe0590SSundeep Panicker 	*matched = '\0';
398*6bbe0590SSundeep Panicker 	return (NULL);
399*6bbe0590SSundeep Panicker }
400*6bbe0590SSundeep Panicker 
401*6bbe0590SSundeep Panicker 
402*6bbe0590SSundeep Panicker static void
403*6bbe0590SSundeep Panicker copy_segment_layout(segment_t *seghdr, void *layout)
404*6bbe0590SSundeep Panicker {
405*6bbe0590SSundeep Panicker 	segment_layout_t *seg_layout;
406*6bbe0590SSundeep Panicker 
407*6bbe0590SSundeep Panicker 	seg_layout = (segment_layout_t *)layout;
408*6bbe0590SSundeep Panicker 	(void) memcpy(seghdr->name, &seg_layout->name, SEG_NAME_LEN);
409*6bbe0590SSundeep Panicker 	seghdr->descriptor = GET_SEGMENT_DESCRIPTOR;
410*6bbe0590SSundeep Panicker 	seghdr->offset = BE_16(seg_layout->offset);
411*6bbe0590SSundeep Panicker 	seghdr->length = BE_16(seg_layout->length);
412*6bbe0590SSundeep Panicker }
413*6bbe0590SSundeep Panicker 
414*6bbe0590SSundeep Panicker 
415*6bbe0590SSundeep Panicker static int
416*6bbe0590SSundeep Panicker get_container_info(const char *def_file, const char *cont_desc_str,
417*6bbe0590SSundeep Panicker     container_info_t *cont_info)
418*6bbe0590SSundeep Panicker {
419*6bbe0590SSundeep Panicker 	char *item;
420*6bbe0590SSundeep Panicker 	char *token;
421*6bbe0590SSundeep Panicker 	char *field;
422*6bbe0590SSundeep Panicker 	char matched;
423*6bbe0590SSundeep Panicker 	char buf[1024];
424*6bbe0590SSundeep Panicker 	int foundIt = 0;
425*6bbe0590SSundeep Panicker 	FILE *file = fopen(def_file, "r");
426*6bbe0590SSundeep Panicker 
427*6bbe0590SSundeep Panicker 	if (file == NULL)
428*6bbe0590SSundeep Panicker 		return (-1);
429*6bbe0590SSundeep Panicker 
430*6bbe0590SSundeep Panicker 	cont_info->num_sections = 0;
431*6bbe0590SSundeep Panicker 
432*6bbe0590SSundeep Panicker 	while (fgets(buf, sizeof (buf), file) != NULL) {
433*6bbe0590SSundeep Panicker 		/* ignore all comments */
434*6bbe0590SSundeep Panicker 		token = tokenizer(buf, "#", &field, &matched);
435*6bbe0590SSundeep Panicker 		/* find the names */
436*6bbe0590SSundeep Panicker 		token = tokenizer(buf, ":", &field, &matched);
437*6bbe0590SSundeep Panicker 		if (token != 0x00) {
438*6bbe0590SSundeep Panicker 			token = tokenizer(token, "|", &item, &matched);
439*6bbe0590SSundeep Panicker 			while (token != 0x00) {
440*6bbe0590SSundeep Panicker 				if (strcmp(token, cont_desc_str) == 0) {
441*6bbe0590SSundeep Panicker 					foundIt = 1;
442*6bbe0590SSundeep Panicker 					goto found;
443*6bbe0590SSundeep Panicker 				}
444*6bbe0590SSundeep Panicker 				token = tokenizer(item, "|", &item, &matched);
445*6bbe0590SSundeep Panicker 			}
446*6bbe0590SSundeep Panicker 			/* check the last remaining item */
447*6bbe0590SSundeep Panicker 			if ((item != 0x00) &&
448*6bbe0590SSundeep Panicker 			    (strcmp(item, cont_desc_str) == 0)) {
449*6bbe0590SSundeep Panicker 				foundIt = 1;
450*6bbe0590SSundeep Panicker 				goto found;
451*6bbe0590SSundeep Panicker 			}
452*6bbe0590SSundeep Panicker 		}
453*6bbe0590SSundeep Panicker 	}
454*6bbe0590SSundeep Panicker 
455*6bbe0590SSundeep Panicker found :
456*6bbe0590SSundeep Panicker 	if (foundIt == 1) {
457*6bbe0590SSundeep Panicker 		token = tokenizer(field, ":", &field, &matched);
458*6bbe0590SSundeep Panicker 		if (token == 0x00) {
459*6bbe0590SSundeep Panicker 			(void) fclose(file);
460*6bbe0590SSundeep Panicker 			return (-1);
461*6bbe0590SSundeep Panicker 		}
462*6bbe0590SSundeep Panicker 		cont_info->header_ver = (headerrev_t)atoi(token);
463*6bbe0590SSundeep Panicker 
464*6bbe0590SSundeep Panicker 		token = tokenizer(field, ":\n", &field, &matched);
465*6bbe0590SSundeep Panicker 		while (token != 0x00) {
466*6bbe0590SSundeep Panicker 			token = tokenizer(token, ",", &item, &matched);
467*6bbe0590SSundeep Panicker 			if (token == 0x00) {
468*6bbe0590SSundeep Panicker 				(void) fclose(file);
469*6bbe0590SSundeep Panicker 				return (-1);
470*6bbe0590SSundeep Panicker 			}
471*6bbe0590SSundeep Panicker 			if (atoi(token) == 1) {
472*6bbe0590SSundeep Panicker 				cont_info->section_info[cont_info->
473*6bbe0590SSundeep Panicker 				    num_sections].description.field.read_only
474*6bbe0590SSundeep Panicker 				    = 1;
475*6bbe0590SSundeep Panicker 			} else if (atoi(token) == 0) {
476*6bbe0590SSundeep Panicker 				cont_info->section_info[cont_info->
477*6bbe0590SSundeep Panicker 				    num_sections].description.field.read_only
478*6bbe0590SSundeep Panicker 				    = 0;
479*6bbe0590SSundeep Panicker 			} else {
480*6bbe0590SSundeep Panicker 				(void) fclose(file);
481*6bbe0590SSundeep Panicker 				return (-1);
482*6bbe0590SSundeep Panicker 			}
483*6bbe0590SSundeep Panicker 
484*6bbe0590SSundeep Panicker 			token = tokenizer(item, ",", &item, &matched);
485*6bbe0590SSundeep Panicker 			if (token == 0x00) {
486*6bbe0590SSundeep Panicker 				(void) fclose(file);
487*6bbe0590SSundeep Panicker 				return (-1);
488*6bbe0590SSundeep Panicker 			}
489*6bbe0590SSundeep Panicker 
490*6bbe0590SSundeep Panicker 			cont_info->section_info[cont_info->
491*6bbe0590SSundeep Panicker 			    num_sections].address = atoi(token);
492*6bbe0590SSundeep Panicker 			if (item == '\0') {
493*6bbe0590SSundeep Panicker 				(void) fclose(file);
494*6bbe0590SSundeep Panicker 				return (-1);
495*6bbe0590SSundeep Panicker 			}
496*6bbe0590SSundeep Panicker 			cont_info->section_info[cont_info->num_sections].size =
497*6bbe0590SSundeep Panicker 			    atoi(item);
498*6bbe0590SSundeep Panicker 			(cont_info->num_sections)++;
499*6bbe0590SSundeep Panicker 
500*6bbe0590SSundeep Panicker 			token = tokenizer(field, ":\n ", &field, &matched);
501*6bbe0590SSundeep Panicker 		}
502*6bbe0590SSundeep Panicker 	}
503*6bbe0590SSundeep Panicker 	(void) fclose(file);
504*6bbe0590SSundeep Panicker 
505*6bbe0590SSundeep Panicker 	return (0);
506*6bbe0590SSundeep Panicker }
507*6bbe0590SSundeep Panicker 
508*6bbe0590SSundeep Panicker 
509*6bbe0590SSundeep Panicker /* ARGSUSED */
510*6bbe0590SSundeep Panicker int
511*6bbe0590SSundeep Panicker fru_get_segments(section_hdl_t section, segment_t *segment, int maxseg,
512*6bbe0590SSundeep Panicker     door_cred_t *cred)
513*6bbe0590SSundeep Panicker {
514*6bbe0590SSundeep Panicker 	int count;
515*6bbe0590SSundeep Panicker 	hash_obj_t *sec_object;
516*6bbe0590SSundeep Panicker 	hash_obj_t *seg_object;
517*6bbe0590SSundeep Panicker 	section_obj_t *sec_obj;
518*6bbe0590SSundeep Panicker 
519*6bbe0590SSundeep Panicker 	sec_object = lookup_handle_object(section, SECTION_TYPE);
520*6bbe0590SSundeep Panicker 	if (sec_object == NULL) {
521*6bbe0590SSundeep Panicker 		return (-1);
522*6bbe0590SSundeep Panicker 	}
523*6bbe0590SSundeep Panicker 
524*6bbe0590SSundeep Panicker 	sec_obj	= sec_object->u.sec_obj;
525*6bbe0590SSundeep Panicker 	if (sec_obj == NULL) {
526*6bbe0590SSundeep Panicker 		return (-1);
527*6bbe0590SSundeep Panicker 	}
528*6bbe0590SSundeep Panicker 
529*6bbe0590SSundeep Panicker 	if (sec_obj->num_of_segment > maxseg) {
530*6bbe0590SSundeep Panicker 		return (-1);
531*6bbe0590SSundeep Panicker 	}
532*6bbe0590SSundeep Panicker 
533*6bbe0590SSundeep Panicker 	seg_object = sec_object->u.sec_obj->seg_obj_list;
534*6bbe0590SSundeep Panicker 	if (seg_object == NULL) {
535*6bbe0590SSundeep Panicker 		return (-1);
536*6bbe0590SSundeep Panicker 	}
537*6bbe0590SSundeep Panicker 
538*6bbe0590SSundeep Panicker 	for (count = 0; count < sec_obj->num_of_segment; count++) {
539*6bbe0590SSundeep Panicker 
540*6bbe0590SSundeep Panicker 		/* populate segment_t */
541*6bbe0590SSundeep Panicker 		segment->handle = seg_object->obj_hdl;
542*6bbe0590SSundeep Panicker 		(void) memcpy(segment->name,
543*6bbe0590SSundeep Panicker 		    seg_object->u.seg_obj->segment.name, SEG_NAME_LEN);
544*6bbe0590SSundeep Panicker 		segment->descriptor = seg_object->u.seg_obj->segment.descriptor;
545*6bbe0590SSundeep Panicker 
546*6bbe0590SSundeep Panicker 		segment->offset	= seg_object->u.seg_obj->segment.offset;
547*6bbe0590SSundeep Panicker 		segment->length	= seg_object->u.seg_obj->segment.length;
548*6bbe0590SSundeep Panicker 		seg_object = seg_object->u.seg_obj->next;
549*6bbe0590SSundeep Panicker 		segment++;
550*6bbe0590SSundeep Panicker 	}
551*6bbe0590SSundeep Panicker 	return (0);
552*6bbe0590SSundeep Panicker }
553*6bbe0590SSundeep Panicker 
554*6bbe0590SSundeep Panicker 
555*6bbe0590SSundeep Panicker static int
556*6bbe0590SSundeep Panicker raw_memcpy(void *buffer, raw_list_t *rawlist, int offset, int size)
557*6bbe0590SSundeep Panicker {
558*6bbe0590SSundeep Panicker 	if (offset + size > rawlist->size) {
559*6bbe0590SSundeep Panicker 		size = rawlist->size - offset;
560*6bbe0590SSundeep Panicker 	}
561*6bbe0590SSundeep Panicker 
562*6bbe0590SSundeep Panicker 	(void) memcpy(buffer, &rawlist->raw[offset], size);
563*6bbe0590SSundeep Panicker 
564*6bbe0590SSundeep Panicker 	return (size);
565*6bbe0590SSundeep Panicker }
566*6bbe0590SSundeep Panicker 
567*6bbe0590SSundeep Panicker 
568*6bbe0590SSundeep Panicker static int
569*6bbe0590SSundeep Panicker verify_header_crc8(headerrev_t head_ver, unsigned char *bytes, int length)
570*6bbe0590SSundeep Panicker {
571*6bbe0590SSundeep Panicker 	int crc_offset = 0;
572*6bbe0590SSundeep Panicker 	unsigned char orig_crc8 = 0;
573*6bbe0590SSundeep Panicker 	unsigned char calc_crc8 = 0;
574*6bbe0590SSundeep Panicker 
575*6bbe0590SSundeep Panicker 	switch (head_ver) {
576*6bbe0590SSundeep Panicker 		case SECTION_HDR_VER:
577*6bbe0590SSundeep Panicker 			crc_offset = 4;
578*6bbe0590SSundeep Panicker 			break;
579*6bbe0590SSundeep Panicker 		default:
580*6bbe0590SSundeep Panicker 			errno = EINVAL;
581*6bbe0590SSundeep Panicker 			return (0);
582*6bbe0590SSundeep Panicker 	}
583*6bbe0590SSundeep Panicker 
584*6bbe0590SSundeep Panicker 	orig_crc8 = bytes[crc_offset];
585*6bbe0590SSundeep Panicker 	bytes[crc_offset] = 0x00; /* clear for calc */
586*6bbe0590SSundeep Panicker 	calc_crc8 = compute_crc8(bytes, length);
587*6bbe0590SSundeep Panicker 	bytes[crc_offset] = orig_crc8; /* restore */
588*6bbe0590SSundeep Panicker 
589*6bbe0590SSundeep Panicker 	return (orig_crc8 == calc_crc8);
590*6bbe0590SSundeep Panicker }
591*6bbe0590SSundeep Panicker 
592*6bbe0590SSundeep Panicker 
593*6bbe0590SSundeep Panicker static int
594*6bbe0590SSundeep Panicker get_section(raw_list_t *rawlist, hash_obj_t *sec_hash, section_t *section)
595*6bbe0590SSundeep Panicker {
596*6bbe0590SSundeep Panicker 	int retval;
597*6bbe0590SSundeep Panicker 	int size;
598*6bbe0590SSundeep Panicker 	int count;
599*6bbe0590SSundeep Panicker 	uint16_t hdrver;
600*6bbe0590SSundeep Panicker 	hash_obj_t *seg_hash;
601*6bbe0590SSundeep Panicker 	unsigned char *buffer;
602*6bbe0590SSundeep Panicker 	section_obj_t *sec_obj;
603*6bbe0590SSundeep Panicker 	section_layout_t sec_hdr;
604*6bbe0590SSundeep Panicker 	segment_layout_t *seg_hdr;
605*6bbe0590SSundeep Panicker 	segment_layout_t *seg_buf;
606*6bbe0590SSundeep Panicker 
607*6bbe0590SSundeep Panicker 	sec_obj	= sec_hash->u.sec_obj;
608*6bbe0590SSundeep Panicker 	if (sec_obj == NULL) {
609*6bbe0590SSundeep Panicker 		return (-1);
610*6bbe0590SSundeep Panicker 	}
611*6bbe0590SSundeep Panicker 
612*6bbe0590SSundeep Panicker 	/* populate section_t */
613*6bbe0590SSundeep Panicker 	section->handle = sec_hash->obj_hdl;
614*6bbe0590SSundeep Panicker 	section->offset = sec_obj->section.offset;
615*6bbe0590SSundeep Panicker 	section->length = sec_obj->section.length;
616*6bbe0590SSundeep Panicker 	section->protection = sec_obj->section.protection;
617*6bbe0590SSundeep Panicker 	section->version = sec_obj->section.version;
618*6bbe0590SSundeep Panicker 
619*6bbe0590SSundeep Panicker 	/* read section header layout */
620*6bbe0590SSundeep Panicker 	retval = raw_memcpy(&sec_hdr, rawlist, sec_obj->section.offset,
621*6bbe0590SSundeep Panicker 	    sizeof (sec_hdr));
622*6bbe0590SSundeep Panicker 
623*6bbe0590SSundeep Panicker 	if (retval != sizeof (sec_hdr)) {
624*6bbe0590SSundeep Panicker 		return (-1);
625*6bbe0590SSundeep Panicker 	}
626*6bbe0590SSundeep Panicker 
627*6bbe0590SSundeep Panicker 
628*6bbe0590SSundeep Panicker 	hdrver = GET_SECTION_HDR_VERSION;
629*6bbe0590SSundeep Panicker 
630*6bbe0590SSundeep Panicker 	if ((sec_hdr.headertag != SECTION_HDR_TAG) &&
631*6bbe0590SSundeep Panicker 	    (hdrver != section->version)) {
632*6bbe0590SSundeep Panicker 		return (-1);
633*6bbe0590SSundeep Panicker 	}
634*6bbe0590SSundeep Panicker 
635*6bbe0590SSundeep Panicker 	/* size = section layout + total sizeof segment header */
636*6bbe0590SSundeep Panicker 	size = sizeof (sec_hdr) + ((sec_hdr.segmentcount)
637*6bbe0590SSundeep Panicker 	    * sizeof (segment_layout_t));
638*6bbe0590SSundeep Panicker 
639*6bbe0590SSundeep Panicker 	buffer = alloca(size);
640*6bbe0590SSundeep Panicker 	if (buffer == NULL) {
641*6bbe0590SSundeep Panicker 		return (-1);
642*6bbe0590SSundeep Panicker 	}
643*6bbe0590SSundeep Panicker 
644*6bbe0590SSundeep Panicker 	/* segment header buffer */
645*6bbe0590SSundeep Panicker 	seg_buf = alloca(size - sizeof (sec_hdr));
646*6bbe0590SSundeep Panicker 	if (seg_buf == NULL) {
647*6bbe0590SSundeep Panicker 		return (-1);
648*6bbe0590SSundeep Panicker 	}
649*6bbe0590SSundeep Panicker 
650*6bbe0590SSundeep Panicker 	/* read segment header */
651*6bbe0590SSundeep Panicker 	retval = raw_memcpy(seg_buf, rawlist,
652*6bbe0590SSundeep Panicker 	    sec_obj->section.offset + sizeof (sec_hdr),
653*6bbe0590SSundeep Panicker 	    size - sizeof (sec_hdr));
654*6bbe0590SSundeep Panicker 
655*6bbe0590SSundeep Panicker 	if (retval != (size - sizeof (sec_hdr))) {
656*6bbe0590SSundeep Panicker 		return (-1);
657*6bbe0590SSundeep Panicker 	}
658*6bbe0590SSundeep Panicker 
659*6bbe0590SSundeep Panicker 	/* copy section header layout */
660*6bbe0590SSundeep Panicker 	(void) memcpy(buffer, &sec_hdr, sizeof (sec_hdr));
661*6bbe0590SSundeep Panicker 
662*6bbe0590SSundeep Panicker 	/* copy segment header layout */
663*6bbe0590SSundeep Panicker 	(void) memcpy(buffer + sizeof (sec_hdr), seg_buf, size -
664*6bbe0590SSundeep Panicker 	    sizeof (sec_hdr));
665*6bbe0590SSundeep Panicker 
666*6bbe0590SSundeep Panicker 	/* verify crc8 */
667*6bbe0590SSundeep Panicker 	retval = verify_header_crc8(hdrver, buffer, size);
668*6bbe0590SSundeep Panicker 	if (retval != TRUE) {
669*6bbe0590SSundeep Panicker 		return (-1);
670*6bbe0590SSundeep Panicker 	}
671*6bbe0590SSundeep Panicker 
672*6bbe0590SSundeep Panicker 	section->version = hdrver;
673*6bbe0590SSundeep Panicker 	sec_obj->section.version = hdrver;
674*6bbe0590SSundeep Panicker 
675*6bbe0590SSundeep Panicker 	seg_hdr	= (segment_layout_t *)seg_buf;
676*6bbe0590SSundeep Panicker 
677*6bbe0590SSundeep Panicker 	/* bug fix for frutool */
678*6bbe0590SSundeep Panicker 	if (sec_hash->u.sec_obj->seg_obj_list != NULL) {
679*6bbe0590SSundeep Panicker 		return (0);
680*6bbe0590SSundeep Panicker 	} else {
681*6bbe0590SSundeep Panicker 		sec_obj->num_of_segment = 0;
682*6bbe0590SSundeep Panicker 	}
683*6bbe0590SSundeep Panicker 	for (count = 0; count < sec_hdr.segmentcount; count++, seg_hdr++) {
684*6bbe0590SSundeep Panicker 
685*6bbe0590SSundeep Panicker 		seg_hash = create_segment_hash_object();
686*6bbe0590SSundeep Panicker 		if (seg_hash == NULL) {
687*6bbe0590SSundeep Panicker 			return (-1);
688*6bbe0590SSundeep Panicker 		}
689*6bbe0590SSundeep Panicker 		add_hashobject_to_hashtable(seg_hash);
690*6bbe0590SSundeep Panicker 		copy_segment_layout(&seg_hash->u.seg_obj->segment, seg_hdr);
691*6bbe0590SSundeep Panicker 		add_to_seg_object_list(sec_hash, seg_hash);
692*6bbe0590SSundeep Panicker 		sec_obj->num_of_segment++;
693*6bbe0590SSundeep Panicker 	}
694*6bbe0590SSundeep Panicker 	return (0);
695*6bbe0590SSundeep Panicker }
696*6bbe0590SSundeep Panicker 
697*6bbe0590SSundeep Panicker /* ARGSUSED */
698*6bbe0590SSundeep Panicker int
699*6bbe0590SSundeep Panicker fru_get_sections(container_hdl_t container, section_t *section, int maxsec,
700*6bbe0590SSundeep Panicker     door_cred_t *cred)
701*6bbe0590SSundeep Panicker {
702*6bbe0590SSundeep Panicker 	int count;
703*6bbe0590SSundeep Panicker 	int num_sec = 0;
704*6bbe0590SSundeep Panicker 	hash_obj_t *cont_object;
705*6bbe0590SSundeep Panicker 	hash_obj_t *sec_hash;
706*6bbe0590SSundeep Panicker 
707*6bbe0590SSundeep Panicker 	cont_object = lookup_handle_object(container, CONTAINER_TYPE);
708*6bbe0590SSundeep Panicker 	if (cont_object == NULL) {
709*6bbe0590SSundeep Panicker 		return (-1);
710*6bbe0590SSundeep Panicker 	}
711*6bbe0590SSundeep Panicker 
712*6bbe0590SSundeep Panicker 	if (cont_object->u.cont_obj->num_of_section > maxsec) {
713*6bbe0590SSundeep Panicker 		return (-1);
714*6bbe0590SSundeep Panicker 	}
715*6bbe0590SSundeep Panicker 
716*6bbe0590SSundeep Panicker 	sec_hash = cont_object->u.cont_obj->sec_obj_list;
717*6bbe0590SSundeep Panicker 	if (sec_hash == NULL) {
718*6bbe0590SSundeep Panicker 		return (-1);
719*6bbe0590SSundeep Panicker 	}
720*6bbe0590SSundeep Panicker 
721*6bbe0590SSundeep Panicker 	for (count = 0; count < cont_object->u.cont_obj->num_of_section;
722*6bbe0590SSundeep Panicker 	    count++) {
723*6bbe0590SSundeep Panicker 		section->version = -1;
724*6bbe0590SSundeep Panicker 		/* populate section_t */
725*6bbe0590SSundeep Panicker 		if (get_section(g_raw, sec_hash, section) == 0) {
726*6bbe0590SSundeep Panicker 			section++;
727*6bbe0590SSundeep Panicker 			num_sec++;
728*6bbe0590SSundeep Panicker 		}
729*6bbe0590SSundeep Panicker 		sec_hash = sec_hash->u.sec_obj->next;
730*6bbe0590SSundeep Panicker 	}
731*6bbe0590SSundeep Panicker 	return (num_sec);
732*6bbe0590SSundeep Panicker }
733*6bbe0590SSundeep Panicker 
734*6bbe0590SSundeep Panicker 
735*6bbe0590SSundeep Panicker static uint32_t
736*6bbe0590SSundeep Panicker get_checksum_crc(hash_obj_t *seg_hash, int data_size)
737*6bbe0590SSundeep Panicker {
738*6bbe0590SSundeep Panicker 	int protection;
739*6bbe0590SSundeep Panicker 	int offset = 0;
740*6bbe0590SSundeep Panicker 	uint32_t crc;
741*6bbe0590SSundeep Panicker 	hash_obj_t *sec_hash;
742*6bbe0590SSundeep Panicker 	hash_obj_t *pkt_hash;
743*6bbe0590SSundeep Panicker 	unsigned char *buffer;
744*6bbe0590SSundeep Panicker 
745*6bbe0590SSundeep Panicker 	sec_hash = lookup_handle_object(seg_hash->u.seg_obj->section_hdl,
746*6bbe0590SSundeep Panicker 	    SECTION_TYPE);
747*6bbe0590SSundeep Panicker 	if (sec_hash == NULL) {
748*6bbe0590SSundeep Panicker 		return ((uint32_t)-1);
749*6bbe0590SSundeep Panicker 	}
750*6bbe0590SSundeep Panicker 
751*6bbe0590SSundeep Panicker 	buffer = alloca(data_size);
752*6bbe0590SSundeep Panicker 	if (buffer == NULL) {
753*6bbe0590SSundeep Panicker 		return ((uint32_t)-1);
754*6bbe0590SSundeep Panicker 	}
755*6bbe0590SSundeep Panicker 
756*6bbe0590SSundeep Panicker 	/* traverse the packet object list for all the tags and payload */
757*6bbe0590SSundeep Panicker 	for (pkt_hash = seg_hash->u.seg_obj->pkt_obj_list; pkt_hash != NULL;
758*6bbe0590SSundeep Panicker 	    pkt_hash = pkt_hash->u.pkt_obj->next) {
759*6bbe0590SSundeep Panicker 		(void) memcpy(buffer + offset, &pkt_hash->u.pkt_obj->tag,
760*6bbe0590SSundeep Panicker 		    pkt_hash->u.pkt_obj->tag_size);
761*6bbe0590SSundeep Panicker 		offset += pkt_hash->u.pkt_obj->tag_size;
762*6bbe0590SSundeep Panicker 		(void) memcpy(buffer + offset, pkt_hash->u.pkt_obj->payload,
763*6bbe0590SSundeep Panicker 		    pkt_hash->u.pkt_obj->paylen);
764*6bbe0590SSundeep Panicker 		offset += pkt_hash->u.pkt_obj->paylen;
765*6bbe0590SSundeep Panicker 	}
766*6bbe0590SSundeep Panicker 
767*6bbe0590SSundeep Panicker 	protection = sec_hash->u.sec_obj->section.protection;
768*6bbe0590SSundeep Panicker 
769*6bbe0590SSundeep Panicker 	if (protection == READ_ONLY_SECTION) { /* read-only section */
770*6bbe0590SSundeep Panicker 		crc = compute_crc32(buffer, data_size);
771*6bbe0590SSundeep Panicker 	} else {		/* read/write section */
772*6bbe0590SSundeep Panicker 		crc = compute_checksum32(buffer, data_size);
773*6bbe0590SSundeep Panicker 	}
774*6bbe0590SSundeep Panicker 	return (crc);	/* computed crc */
775*6bbe0590SSundeep Panicker }
776*6bbe0590SSundeep Panicker 
777*6bbe0590SSundeep Panicker 
778*6bbe0590SSundeep Panicker static int
779*6bbe0590SSundeep Panicker get_packet(raw_list_t *rawlist, void *buffer, int size, int offset)
780*6bbe0590SSundeep Panicker {
781*6bbe0590SSundeep Panicker 	int retval;
782*6bbe0590SSundeep Panicker 
783*6bbe0590SSundeep Panicker 	retval = raw_memcpy(buffer, rawlist, offset, size);
784*6bbe0590SSundeep Panicker 
785*6bbe0590SSundeep Panicker 	if (retval != -1) {
786*6bbe0590SSundeep Panicker 		return (0);
787*6bbe0590SSundeep Panicker 	}
788*6bbe0590SSundeep Panicker 	return (-1);
789*6bbe0590SSundeep Panicker }
790*6bbe0590SSundeep Panicker 
791*6bbe0590SSundeep Panicker 
792*6bbe0590SSundeep Panicker static int
793*6bbe0590SSundeep Panicker get_packets(hash_obj_t *seg_hash, raw_list_t *rawlist, int offset, int length)
794*6bbe0590SSundeep Panicker {
795*6bbe0590SSundeep Panicker 	int tag_size;
796*6bbe0590SSundeep Panicker 	int paylen;
797*6bbe0590SSundeep Panicker 	int retval;
798*6bbe0590SSundeep Panicker 	int seg_limit = 0;
799*6bbe0590SSundeep Panicker 	int pktcnt = 0;
800*6bbe0590SSundeep Panicker 	char *data;
801*6bbe0590SSundeep Panicker 	uint32_t crc;
802*6bbe0590SSundeep Panicker 	uint32_t origcrc;
803*6bbe0590SSundeep Panicker 	fru_tag_t tag;
804*6bbe0590SSundeep Panicker 	hash_obj_t *pkt_hash_obj;
805*6bbe0590SSundeep Panicker 	hash_obj_t *sec_hash;
806*6bbe0590SSundeep Panicker 	fru_segdesc_t *segdesc;
807*6bbe0590SSundeep Panicker 	fru_tagtype_t tagtype;
808*6bbe0590SSundeep Panicker 	char *ignore_flag;
809*6bbe0590SSundeep Panicker 
810*6bbe0590SSundeep Panicker 	retval = get_packet(rawlist, &tag, sizeof (fru_tag_t), offset);
811*6bbe0590SSundeep Panicker 	if (retval == -1) {
812*6bbe0590SSundeep Panicker 		return (-1);
813*6bbe0590SSundeep Panicker 	}
814*6bbe0590SSundeep Panicker 
815*6bbe0590SSundeep Panicker 	/* section hash object */
816*6bbe0590SSundeep Panicker 	sec_hash = lookup_handle_object(seg_hash->u.seg_obj->section_hdl,
817*6bbe0590SSundeep Panicker 	    SECTION_TYPE);
818*6bbe0590SSundeep Panicker 
819*6bbe0590SSundeep Panicker 	if (sec_hash == NULL) {
820*6bbe0590SSundeep Panicker 		return (-1);
821*6bbe0590SSundeep Panicker 	}
822*6bbe0590SSundeep Panicker 
823*6bbe0590SSundeep Panicker 	seg_hash->u.seg_obj->trailer_offset = offset;
824*6bbe0590SSundeep Panicker 
825*6bbe0590SSundeep Panicker 	data = (char *)&tag;
826*6bbe0590SSundeep Panicker 	while (data[0] != SEG_TRAILER_TAG) {
827*6bbe0590SSundeep Panicker 		tagtype	= get_tag_type(&tag); /* verify tag type */
828*6bbe0590SSundeep Panicker 		if (tagtype == -1) {
829*6bbe0590SSundeep Panicker 			return (-1);
830*6bbe0590SSundeep Panicker 		}
831*6bbe0590SSundeep Panicker 
832*6bbe0590SSundeep Panicker 		tag_size = get_tag_size(tagtype);
833*6bbe0590SSundeep Panicker 		if (tag_size == -1) {
834*6bbe0590SSundeep Panicker 			return (-1);
835*6bbe0590SSundeep Panicker 		}
836*6bbe0590SSundeep Panicker 
837*6bbe0590SSundeep Panicker 		seg_limit += tag_size;
838*6bbe0590SSundeep Panicker 		if (seg_limit > length) {
839*6bbe0590SSundeep Panicker 			return (-1);
840*6bbe0590SSundeep Panicker 		}
841*6bbe0590SSundeep Panicker 
842*6bbe0590SSundeep Panicker 		paylen = get_payload_length((void *)&tag);
843*6bbe0590SSundeep Panicker 		if (paylen == -1) {
844*6bbe0590SSundeep Panicker 			return (-1);
845*6bbe0590SSundeep Panicker 		}
846*6bbe0590SSundeep Panicker 
847*6bbe0590SSundeep Panicker 		seg_limit += paylen;
848*6bbe0590SSundeep Panicker 		if (seg_limit > length) {
849*6bbe0590SSundeep Panicker 			return (-1);
850*6bbe0590SSundeep Panicker 		}
851*6bbe0590SSundeep Panicker 		if ((offset + tag_size + paylen) >
852*6bbe0590SSundeep Panicker 		    (sec_hash->u.sec_obj->section.offset +
853*6bbe0590SSundeep Panicker 		    sec_hash->u.sec_obj->section.length)) {
854*6bbe0590SSundeep Panicker 			return (-1);
855*6bbe0590SSundeep Panicker 		}
856*6bbe0590SSundeep Panicker 
857*6bbe0590SSundeep Panicker 		pkt_hash_obj = create_packet_hash_object();
858*6bbe0590SSundeep Panicker 		if (pkt_hash_obj == NULL) {
859*6bbe0590SSundeep Panicker 			return (-1);
860*6bbe0590SSundeep Panicker 		}
861*6bbe0590SSundeep Panicker 
862*6bbe0590SSundeep Panicker 		pkt_hash_obj->u.pkt_obj->payload = malloc(paylen);
863*6bbe0590SSundeep Panicker 		if (pkt_hash_obj->u.pkt_obj->payload == NULL) {
864*6bbe0590SSundeep Panicker 			free(pkt_hash_obj);
865*6bbe0590SSundeep Panicker 			return (-1);
866*6bbe0590SSundeep Panicker 		}
867*6bbe0590SSundeep Panicker 
868*6bbe0590SSundeep Panicker 		offset += tag_size;
869*6bbe0590SSundeep Panicker 
870*6bbe0590SSundeep Panicker 		retval = raw_memcpy(pkt_hash_obj->u.pkt_obj->payload, rawlist,
871*6bbe0590SSundeep Panicker 		    offset, paylen);
872*6bbe0590SSundeep Panicker 
873*6bbe0590SSundeep Panicker 		if (retval != paylen) {
874*6bbe0590SSundeep Panicker 			free(pkt_hash_obj->u.pkt_obj->payload);
875*6bbe0590SSundeep Panicker 			free(pkt_hash_obj);
876*6bbe0590SSundeep Panicker 			return (-1);
877*6bbe0590SSundeep Panicker 		}
878*6bbe0590SSundeep Panicker 
879*6bbe0590SSundeep Panicker 		/* don't change this */
880*6bbe0590SSundeep Panicker 		pkt_hash_obj->u.pkt_obj->tag.raw_data = 0;
881*6bbe0590SSundeep Panicker 		(void) memcpy(&pkt_hash_obj->u.pkt_obj->tag, &tag, tag_size);
882*6bbe0590SSundeep Panicker 		pkt_hash_obj->u.pkt_obj->paylen = paylen;
883*6bbe0590SSundeep Panicker 		pkt_hash_obj->u.pkt_obj->tag_size = tag_size;
884*6bbe0590SSundeep Panicker 		pkt_hash_obj->u.pkt_obj->payload_offset = offset;
885*6bbe0590SSundeep Panicker 
886*6bbe0590SSundeep Panicker 		offset += paylen;
887*6bbe0590SSundeep Panicker 
888*6bbe0590SSundeep Panicker 		add_hashobject_to_hashtable(pkt_hash_obj);
889*6bbe0590SSundeep Panicker 		add_to_pkt_object_list(seg_hash, pkt_hash_obj);
890*6bbe0590SSundeep Panicker 
891*6bbe0590SSundeep Panicker 		pktcnt++;
892*6bbe0590SSundeep Panicker 
893*6bbe0590SSundeep Panicker 		retval = get_packet(rawlist, &tag, sizeof (fru_tag_t),
894*6bbe0590SSundeep Panicker 		    offset);
895*6bbe0590SSundeep Panicker 		if (retval == -1) {
896*6bbe0590SSundeep Panicker 			return (retval);
897*6bbe0590SSundeep Panicker 		}
898*6bbe0590SSundeep Panicker 
899*6bbe0590SSundeep Panicker 		data = (char *)&tag;
900*6bbe0590SSundeep Panicker 	}
901*6bbe0590SSundeep Panicker 
902*6bbe0590SSundeep Panicker 	segdesc	= (fru_segdesc_t *)&seg_hash->u.seg_obj->segment.descriptor;
903*6bbe0590SSundeep Panicker 
904*6bbe0590SSundeep Panicker 	seg_hash->u.seg_obj->trailer_offset = offset;
905*6bbe0590SSundeep Panicker 
906*6bbe0590SSundeep Panicker 	if (!segdesc->field.ignore_checksum)  {
907*6bbe0590SSundeep Panicker 		crc = get_checksum_crc(seg_hash, seg_limit);
908*6bbe0590SSundeep Panicker 		offset = seg_hash->u.seg_obj->segment.offset;
909*6bbe0590SSundeep Panicker 
910*6bbe0590SSundeep Panicker 		retval = raw_memcpy(&origcrc, rawlist, offset + seg_limit + 1,
911*6bbe0590SSundeep Panicker 		    sizeof (origcrc));
912*6bbe0590SSundeep Panicker 
913*6bbe0590SSundeep Panicker 		ignore_flag = getenv(IGNORE_CHECK);
914*6bbe0590SSundeep Panicker 		if (ignore_flag != NULL) {
915*6bbe0590SSundeep Panicker 			return (pktcnt);
916*6bbe0590SSundeep Panicker 		}
917*6bbe0590SSundeep Panicker 
918*6bbe0590SSundeep Panicker 		if (retval != sizeof (origcrc)) {
919*6bbe0590SSundeep Panicker 			return (-1);
920*6bbe0590SSundeep Panicker 		}
921*6bbe0590SSundeep Panicker 
922*6bbe0590SSundeep Panicker 		origcrc = BE_32(origcrc);
923*6bbe0590SSundeep Panicker 		if (origcrc != crc) {
924*6bbe0590SSundeep Panicker 			seg_hash->u.seg_obj->trailer_offset = offset;
925*6bbe0590SSundeep Panicker 			return (-1);
926*6bbe0590SSundeep Panicker 		}
927*6bbe0590SSundeep Panicker 	}
928*6bbe0590SSundeep Panicker 
929*6bbe0590SSundeep Panicker 	return (pktcnt);
930*6bbe0590SSundeep Panicker }
931*6bbe0590SSundeep Panicker 
932*6bbe0590SSundeep Panicker /* ARGSUSED */
933*6bbe0590SSundeep Panicker int
934*6bbe0590SSundeep Panicker fru_get_num_sections(container_hdl_t container, door_cred_t *cred)
935*6bbe0590SSundeep Panicker {
936*6bbe0590SSundeep Panicker 	hash_obj_t *hash_object;
937*6bbe0590SSundeep Panicker 
938*6bbe0590SSundeep Panicker 	hash_object = lookup_handle_object(container, CONTAINER_TYPE);
939*6bbe0590SSundeep Panicker 	if (hash_object == NULL) {
940*6bbe0590SSundeep Panicker 		return (-1);
941*6bbe0590SSundeep Panicker 	}
942*6bbe0590SSundeep Panicker 
943*6bbe0590SSundeep Panicker 	return (hash_object->u.cont_obj->num_of_section);
944*6bbe0590SSundeep Panicker }
945*6bbe0590SSundeep Panicker 
946*6bbe0590SSundeep Panicker /* ARGSUSED */
947*6bbe0590SSundeep Panicker int
948*6bbe0590SSundeep Panicker fru_get_num_segments(section_hdl_t section, door_cred_t *cred)
949*6bbe0590SSundeep Panicker {
950*6bbe0590SSundeep Panicker 	hash_obj_t *sec_object;
951*6bbe0590SSundeep Panicker 	section_obj_t *sec_obj;
952*6bbe0590SSundeep Panicker 
953*6bbe0590SSundeep Panicker 	sec_object = lookup_handle_object(section, SECTION_TYPE);
954*6bbe0590SSundeep Panicker 	if (sec_object == NULL) {
955*6bbe0590SSundeep Panicker 		return (-1);
956*6bbe0590SSundeep Panicker 	}
957*6bbe0590SSundeep Panicker 
958*6bbe0590SSundeep Panicker 	sec_obj	= sec_object->u.sec_obj;
959*6bbe0590SSundeep Panicker 	if (sec_obj == NULL) {
960*6bbe0590SSundeep Panicker 		return (-1);
961*6bbe0590SSundeep Panicker 	}
962*6bbe0590SSundeep Panicker 
963*6bbe0590SSundeep Panicker 	return (sec_obj->num_of_segment);
964*6bbe0590SSundeep Panicker }
965*6bbe0590SSundeep Panicker 
966*6bbe0590SSundeep Panicker /* ARGSUSED */
967*6bbe0590SSundeep Panicker int
968*6bbe0590SSundeep Panicker fru_get_num_packets(segment_hdl_t segment, door_cred_t *cred)
969*6bbe0590SSundeep Panicker {
970*6bbe0590SSundeep Panicker 	int pktcnt;
971*6bbe0590SSundeep Panicker 	int length;
972*6bbe0590SSundeep Panicker 	uint16_t offset;
973*6bbe0590SSundeep Panicker 	hash_obj_t *cont_hash_obj;
974*6bbe0590SSundeep Panicker 	hash_obj_t *seg_hash;
975*6bbe0590SSundeep Panicker 	hash_obj_t *sec_hash;
976*6bbe0590SSundeep Panicker 	fru_segdesc_t *segdesc;
977*6bbe0590SSundeep Panicker 	segment_obj_t *segment_object;
978*6bbe0590SSundeep Panicker 
979*6bbe0590SSundeep Panicker 	seg_hash = lookup_handle_object(segment, SEGMENT_TYPE);
980*6bbe0590SSundeep Panicker 	if (seg_hash == NULL) {
981*6bbe0590SSundeep Panicker 		return (-1);
982*6bbe0590SSundeep Panicker 	}
983*6bbe0590SSundeep Panicker 
984*6bbe0590SSundeep Panicker 	segment_object = seg_hash->u.seg_obj;
985*6bbe0590SSundeep Panicker 	if (segment_object == NULL) {
986*6bbe0590SSundeep Panicker 		return (-1);
987*6bbe0590SSundeep Panicker 	}
988*6bbe0590SSundeep Panicker 
989*6bbe0590SSundeep Panicker 	segdesc = (fru_segdesc_t *)&segment_object->segment.descriptor;
990*6bbe0590SSundeep Panicker 	if (segdesc->field.opaque) {
991*6bbe0590SSundeep Panicker 		return (0);
992*6bbe0590SSundeep Panicker 	}
993*6bbe0590SSundeep Panicker 
994*6bbe0590SSundeep Panicker 	offset = segment_object->segment.offset;
995*6bbe0590SSundeep Panicker 	length = segment_object->segment.length;
996*6bbe0590SSundeep Panicker 
997*6bbe0590SSundeep Panicker 	cont_hash_obj = get_container_hash_object(SEGMENT_TYPE,
998*6bbe0590SSundeep Panicker 	    segment_object->section_hdl);
999*6bbe0590SSundeep Panicker 
1000*6bbe0590SSundeep Panicker 	if (cont_hash_obj == NULL) {
1001*6bbe0590SSundeep Panicker 		return (-1);
1002*6bbe0590SSundeep Panicker 	}
1003*6bbe0590SSundeep Panicker 
1004*6bbe0590SSundeep Panicker 	if (seg_hash->u.seg_obj->pkt_obj_list != NULL) {
1005*6bbe0590SSundeep Panicker 		return (segment_object->num_of_packets);
1006*6bbe0590SSundeep Panicker 	}
1007*6bbe0590SSundeep Panicker 	/* section hash object */
1008*6bbe0590SSundeep Panicker 	sec_hash = lookup_handle_object(seg_hash->u.seg_obj->section_hdl,
1009*6bbe0590SSundeep Panicker 	    SECTION_TYPE);
1010*6bbe0590SSundeep Panicker 	if (sec_hash == NULL) {
1011*6bbe0590SSundeep Panicker 		return (-1);
1012*6bbe0590SSundeep Panicker 	}
1013*6bbe0590SSundeep Panicker 
1014*6bbe0590SSundeep Panicker 	/* valid segment header b'cos crc8 already validated */
1015*6bbe0590SSundeep Panicker 	if (offset < sec_hash->u.sec_obj->section.offset) {
1016*6bbe0590SSundeep Panicker 		return (-1);
1017*6bbe0590SSundeep Panicker 	}
1018*6bbe0590SSundeep Panicker 
1019*6bbe0590SSundeep Panicker 	segment_object->num_of_packets = 0;
1020*6bbe0590SSundeep Panicker 
1021*6bbe0590SSundeep Panicker 	pktcnt = get_packets(seg_hash, g_raw, offset, length);
1022*6bbe0590SSundeep Panicker 	if (pktcnt == -1) {
1023*6bbe0590SSundeep Panicker 		free_pkt_object_list(seg_hash);
1024*6bbe0590SSundeep Panicker 		seg_hash->u.seg_obj->pkt_obj_list = NULL;
1025*6bbe0590SSundeep Panicker 	}
1026*6bbe0590SSundeep Panicker 
1027*6bbe0590SSundeep Panicker 	segment_object->num_of_packets = pktcnt;
1028*6bbe0590SSundeep Panicker 
1029*6bbe0590SSundeep Panicker 	return (segment_object->num_of_packets);
1030*6bbe0590SSundeep Panicker }
1031*6bbe0590SSundeep Panicker 
1032*6bbe0590SSundeep Panicker /* ARGSUSED */
1033*6bbe0590SSundeep Panicker int
1034*6bbe0590SSundeep Panicker fru_get_packets(segment_hdl_t segment, packet_t *packet, int maxpackets,
1035*6bbe0590SSundeep Panicker     door_cred_t *cred)
1036*6bbe0590SSundeep Panicker {
1037*6bbe0590SSundeep Panicker 	int count;
1038*6bbe0590SSundeep Panicker 	hash_obj_t *seg_hash_obj;
1039*6bbe0590SSundeep Panicker 	hash_obj_t *pkt_hash_obj;
1040*6bbe0590SSundeep Panicker 
1041*6bbe0590SSundeep Panicker 	/* segment hash object */
1042*6bbe0590SSundeep Panicker 	seg_hash_obj = lookup_handle_object(segment, SEGMENT_TYPE);
1043*6bbe0590SSundeep Panicker 	if (seg_hash_obj == NULL) {
1044*6bbe0590SSundeep Panicker 		return (-1);
1045*6bbe0590SSundeep Panicker 	}
1046*6bbe0590SSundeep Panicker 
1047*6bbe0590SSundeep Panicker 	if (seg_hash_obj->u.seg_obj->num_of_packets != maxpackets) {
1048*6bbe0590SSundeep Panicker 		return (-1);
1049*6bbe0590SSundeep Panicker 	}
1050*6bbe0590SSundeep Panicker 
1051*6bbe0590SSundeep Panicker 	pkt_hash_obj = seg_hash_obj->u.seg_obj->pkt_obj_list;
1052*6bbe0590SSundeep Panicker 	if (pkt_hash_obj == NULL) {
1053*6bbe0590SSundeep Panicker 		return (-1);
1054*6bbe0590SSundeep Panicker 	}
1055*6bbe0590SSundeep Panicker 
1056*6bbe0590SSundeep Panicker 	for (count = 0; count < maxpackets; count++, packet++) {
1057*6bbe0590SSundeep Panicker 		packet->handle	= pkt_hash_obj->obj_hdl;
1058*6bbe0590SSundeep Panicker 		packet->tag = 0;
1059*6bbe0590SSundeep Panicker 		(void) memcpy(&packet->tag, &pkt_hash_obj->u.pkt_obj->tag,
1060*6bbe0590SSundeep Panicker 		    pkt_hash_obj->u.pkt_obj->tag_size);
1061*6bbe0590SSundeep Panicker 		pkt_hash_obj = pkt_hash_obj->u.pkt_obj->next;
1062*6bbe0590SSundeep Panicker 	}
1063*6bbe0590SSundeep Panicker 
1064*6bbe0590SSundeep Panicker 	return (0);
1065*6bbe0590SSundeep Panicker }
1066*6bbe0590SSundeep Panicker 
1067*6bbe0590SSundeep Panicker /* ARGSUSED */
1068*6bbe0590SSundeep Panicker ssize_t
1069*6bbe0590SSundeep Panicker fru_get_payload(packet_hdl_t packet, void *buffer, size_t nbytes,
1070*6bbe0590SSundeep Panicker     door_cred_t *cred)
1071*6bbe0590SSundeep Panicker {
1072*6bbe0590SSundeep Panicker 	hash_obj_t *packet_hash_obj;
1073*6bbe0590SSundeep Panicker 
1074*6bbe0590SSundeep Panicker 	/* packet hash object */
1075*6bbe0590SSundeep Panicker 	packet_hash_obj	= lookup_handle_object(packet, PACKET_TYPE);
1076*6bbe0590SSundeep Panicker 	if (packet_hash_obj == NULL) {
1077*6bbe0590SSundeep Panicker 		return (-1);
1078*6bbe0590SSundeep Panicker 	}
1079*6bbe0590SSundeep Panicker 
1080*6bbe0590SSundeep Panicker 	/* verify payload length */
1081*6bbe0590SSundeep Panicker 	if (nbytes != packet_hash_obj->u.pkt_obj->paylen) {
1082*6bbe0590SSundeep Panicker 		return (-1);
1083*6bbe0590SSundeep Panicker 	}
1084*6bbe0590SSundeep Panicker 
1085*6bbe0590SSundeep Panicker 	(void) memcpy(buffer, packet_hash_obj->u.pkt_obj->payload, nbytes);
1086*6bbe0590SSundeep Panicker 	return (nbytes);
1087*6bbe0590SSundeep Panicker }
1088*6bbe0590SSundeep Panicker 
1089*6bbe0590SSundeep Panicker 
1090*6bbe0590SSundeep Panicker container_hdl_t
1091*6bbe0590SSundeep Panicker open_raw_data(raw_list_t *node)
1092*6bbe0590SSundeep Panicker {
1093*6bbe0590SSundeep Panicker 	char *cont_conf_file = NULL;
1094*6bbe0590SSundeep Panicker 	hash_obj_t *cont_hash_obj;
1095*6bbe0590SSundeep Panicker 	hash_obj_t *sec_hash_obj;
1096*6bbe0590SSundeep Panicker 	container_info_t cont_info;
1097*6bbe0590SSundeep Panicker 	int retval;
1098*6bbe0590SSundeep Panicker 	int count;
1099*6bbe0590SSundeep Panicker 
1100*6bbe0590SSundeep Panicker 	cont_hash_obj = create_container_hash_object();
1101*6bbe0590SSundeep Panicker 	if (cont_hash_obj == NULL) {
1102*6bbe0590SSundeep Panicker 		return (NULL);
1103*6bbe0590SSundeep Panicker 	}
1104*6bbe0590SSundeep Panicker 
1105*6bbe0590SSundeep Panicker 	add_hashobject_to_hashtable(cont_hash_obj);
1106*6bbe0590SSundeep Panicker 
1107*6bbe0590SSundeep Panicker 	(void) strncpy(cont_hash_obj->u.cont_obj->device_pathname, "unknown",
1108*6bbe0590SSundeep Panicker 	    sizeof (cont_hash_obj->u.cont_obj->device_pathname));
1109*6bbe0590SSundeep Panicker 
1110*6bbe0590SSundeep Panicker 	cont_conf_file = getenv(FRU_CONT_CONF_ENV_VAR);
1111*6bbe0590SSundeep Panicker 	if (cont_conf_file == NULL) {
1112*6bbe0590SSundeep Panicker 		cont_conf_file = FRU_CONT_CONF_SPARC;
1113*6bbe0590SSundeep Panicker 		retval = get_container_info(cont_conf_file, node->cont_type,
1114*6bbe0590SSundeep Panicker 		    &cont_info);
1115*6bbe0590SSundeep Panicker 		if (retval < 0) {
1116*6bbe0590SSundeep Panicker 			cont_conf_file = FRU_CONT_CONF_X86;
1117*6bbe0590SSundeep Panicker 			retval = get_container_info(cont_conf_file,
1118*6bbe0590SSundeep Panicker 			    node->cont_type, &cont_info);
1119*6bbe0590SSundeep Panicker 		}
1120*6bbe0590SSundeep Panicker 	} else {
1121*6bbe0590SSundeep Panicker 		retval = get_container_info(cont_conf_file, node->cont_type,
1122*6bbe0590SSundeep Panicker 		    &cont_info);
1123*6bbe0590SSundeep Panicker 	}
1124*6bbe0590SSundeep Panicker 
1125*6bbe0590SSundeep Panicker 	if (retval < 0) {
1126*6bbe0590SSundeep Panicker 		return (NULL);
1127*6bbe0590SSundeep Panicker 	}
1128*6bbe0590SSundeep Panicker 
1129*6bbe0590SSundeep Panicker 	cont_hash_obj->u.cont_obj->num_of_section = cont_info.num_sections;
1130*6bbe0590SSundeep Panicker 	cont_hash_obj->u.cont_obj->sec_obj_list = NULL;
1131*6bbe0590SSundeep Panicker 
1132*6bbe0590SSundeep Panicker 	for (count = 0; count < cont_info.num_sections; count++) {
1133*6bbe0590SSundeep Panicker 		sec_hash_obj = create_section_hash_object();
1134*6bbe0590SSundeep Panicker 		if (sec_hash_obj == NULL) {
1135*6bbe0590SSundeep Panicker 			return (NULL);
1136*6bbe0590SSundeep Panicker 		}
1137*6bbe0590SSundeep Panicker 
1138*6bbe0590SSundeep Panicker 		add_hashobject_to_hashtable(sec_hash_obj);
1139*6bbe0590SSundeep Panicker 
1140*6bbe0590SSundeep Panicker 		sec_hash_obj->u.sec_obj->section.offset =
1141*6bbe0590SSundeep Panicker 		    cont_info.section_info[count].address;
1142*6bbe0590SSundeep Panicker 
1143*6bbe0590SSundeep Panicker 		sec_hash_obj->u.sec_obj->section.protection =
1144*6bbe0590SSundeep Panicker 		    cont_info.section_info[count].description.field.read_only;
1145*6bbe0590SSundeep Panicker 
1146*6bbe0590SSundeep Panicker 		sec_hash_obj->u.sec_obj->section.length =
1147*6bbe0590SSundeep Panicker 		    cont_info.section_info[count].size;
1148*6bbe0590SSundeep Panicker 		sec_hash_obj->u.sec_obj->section.version =
1149*6bbe0590SSundeep Panicker 		    cont_info.header_ver;
1150*6bbe0590SSundeep Panicker 
1151*6bbe0590SSundeep Panicker 		add_to_sec_object_list(cont_hash_obj, sec_hash_obj);
1152*6bbe0590SSundeep Panicker 	}
1153*6bbe0590SSundeep Panicker 
1154*6bbe0590SSundeep Panicker 	return (cont_hash_obj->obj_hdl);
1155*6bbe0590SSundeep Panicker }
1156*6bbe0590SSundeep Panicker 
1157*6bbe0590SSundeep Panicker 
1158*6bbe0590SSundeep Panicker int
1159*6bbe0590SSundeep Panicker fru_close_container(container_hdl_t container)
1160*6bbe0590SSundeep Panicker {
1161*6bbe0590SSundeep Panicker 	hash_obj_t *hash_obj;
1162*6bbe0590SSundeep Panicker 	hash_obj_t *prev_hash;
1163*6bbe0590SSundeep Panicker 	hash_obj_t *sec_hash_obj;
1164*6bbe0590SSundeep Panicker 	handle_t obj_hdl;
1165*6bbe0590SSundeep Panicker 
1166*6bbe0590SSundeep Panicker 	/* lookup for container hash object */
1167*6bbe0590SSundeep Panicker 	hash_obj = lookup_handle_object(container, CONTAINER_TYPE);
1168*6bbe0590SSundeep Panicker 	if (hash_obj == NULL) {
1169*6bbe0590SSundeep Panicker 		return (0);
1170*6bbe0590SSundeep Panicker 	}
1171*6bbe0590SSundeep Panicker 
1172*6bbe0590SSundeep Panicker 	/* points to section object list */
1173*6bbe0590SSundeep Panicker 	sec_hash_obj = hash_obj->u.cont_obj->sec_obj_list;
1174*6bbe0590SSundeep Panicker 
1175*6bbe0590SSundeep Panicker 	/* traverse section object list */
1176*6bbe0590SSundeep Panicker 	while (sec_hash_obj != NULL) {
1177*6bbe0590SSundeep Panicker 
1178*6bbe0590SSundeep Panicker 		/* traverse segment hash object in the section */
1179*6bbe0590SSundeep Panicker 		while (sec_hash_obj->u.sec_obj->seg_obj_list != NULL) {
1180*6bbe0590SSundeep Panicker 			/* object handle of the segment hash object */
1181*6bbe0590SSundeep Panicker 			obj_hdl	=
1182*6bbe0590SSundeep Panicker 			    sec_hash_obj->u.sec_obj->seg_obj_list->obj_hdl;
1183*6bbe0590SSundeep Panicker 			free_segment_hash(obj_hdl, sec_hash_obj);
1184*6bbe0590SSundeep Panicker 		}
1185*6bbe0590SSundeep Panicker 
1186*6bbe0590SSundeep Panicker 		/* going to free section hash object, relink the hash object */
1187*6bbe0590SSundeep Panicker 		if (sec_hash_obj->prev == NULL) {
1188*6bbe0590SSundeep Panicker 			hash_table[(sec_hash_obj->obj_hdl % TABLE_SIZE)] =
1189*6bbe0590SSundeep Panicker 			    sec_hash_obj->next;
1190*6bbe0590SSundeep Panicker 			if (sec_hash_obj->next != NULL) {
1191*6bbe0590SSundeep Panicker 				sec_hash_obj->next->prev = NULL;
1192*6bbe0590SSundeep Panicker 			}
1193*6bbe0590SSundeep Panicker 		} else {
1194*6bbe0590SSundeep Panicker 			sec_hash_obj->prev->next = sec_hash_obj->next;
1195*6bbe0590SSundeep Panicker 			if (sec_hash_obj->next != NULL) {
1196*6bbe0590SSundeep Panicker 				sec_hash_obj->next->prev = sec_hash_obj->prev;
1197*6bbe0590SSundeep Panicker 			}
1198*6bbe0590SSundeep Panicker 		}
1199*6bbe0590SSundeep Panicker 
1200*6bbe0590SSundeep Panicker 		free(sec_hash_obj->u.sec_obj); /* free section hash object */
1201*6bbe0590SSundeep Panicker 
1202*6bbe0590SSundeep Panicker 		prev_hash = sec_hash_obj;
1203*6bbe0590SSundeep Panicker 
1204*6bbe0590SSundeep Panicker 		sec_hash_obj = sec_hash_obj->u.sec_obj->next;
1205*6bbe0590SSundeep Panicker 
1206*6bbe0590SSundeep Panicker 		free(prev_hash); /* free section hash */
1207*6bbe0590SSundeep Panicker 	}
1208*6bbe0590SSundeep Panicker 
1209*6bbe0590SSundeep Panicker 	/* free container hash object */
1210*6bbe0590SSundeep Panicker 	if (hash_obj->prev == NULL) {
1211*6bbe0590SSundeep Panicker 		hash_table[(hash_obj->obj_hdl % TABLE_SIZE)] =
1212*6bbe0590SSundeep Panicker 		    hash_obj->next;
1213*6bbe0590SSundeep Panicker 		if (hash_obj->next != NULL) {
1214*6bbe0590SSundeep Panicker 			hash_obj->next->prev = NULL;
1215*6bbe0590SSundeep Panicker 		}
1216*6bbe0590SSundeep Panicker 	} else {
1217*6bbe0590SSundeep Panicker 		hash_obj->prev->next = hash_obj->next;
1218*6bbe0590SSundeep Panicker 		if (hash_obj->next != NULL) {
1219*6bbe0590SSundeep Panicker 			hash_obj->next->prev = hash_obj->prev;
1220*6bbe0590SSundeep Panicker 		}
1221*6bbe0590SSundeep Panicker 	}
1222*6bbe0590SSundeep Panicker 
1223*6bbe0590SSundeep Panicker 	free(hash_obj->u.cont_obj);
1224*6bbe0590SSundeep Panicker 	free(hash_obj);
1225*6bbe0590SSundeep Panicker 
1226*6bbe0590SSundeep Panicker 	return (0);
1227*6bbe0590SSundeep Panicker }
1228