16bbe0590SSundeep Panicker /*
26bbe0590SSundeep Panicker * CDDL HEADER START
36bbe0590SSundeep Panicker *
46bbe0590SSundeep Panicker * The contents of this file are subject to the terms of the
56bbe0590SSundeep Panicker * Common Development and Distribution License (the "License").
66bbe0590SSundeep Panicker * You may not use this file except in compliance with the License.
76bbe0590SSundeep Panicker *
86bbe0590SSundeep Panicker * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96bbe0590SSundeep Panicker * or http://www.opensolaris.org/os/licensing.
106bbe0590SSundeep Panicker * See the License for the specific language governing permissions
116bbe0590SSundeep Panicker * and limitations under the License.
126bbe0590SSundeep Panicker *
136bbe0590SSundeep Panicker * When distributing Covered Code, include this CDDL HEADER in each
146bbe0590SSundeep Panicker * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156bbe0590SSundeep Panicker * If applicable, add the following below this CDDL HEADER, with the
166bbe0590SSundeep Panicker * fields enclosed by brackets "[]" replaced with your own identifying
176bbe0590SSundeep Panicker * information: Portions Copyright [yyyy] [name of copyright owner]
186bbe0590SSundeep Panicker *
196bbe0590SSundeep Panicker * CDDL HEADER END
206bbe0590SSundeep Panicker */
216bbe0590SSundeep Panicker
226bbe0590SSundeep Panicker /*
23*ac88567aSHyon Kim * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
246bbe0590SSundeep Panicker */
256bbe0590SSundeep Panicker
266bbe0590SSundeep Panicker #include <stdio.h>
276bbe0590SSundeep Panicker #include <stdlib.h>
286bbe0590SSundeep Panicker #include <alloca.h>
296bbe0590SSundeep Panicker #include <sys/byteorder.h>
306bbe0590SSundeep Panicker #include "fru_access_impl.h"
316bbe0590SSundeep Panicker #include "fruraw.h"
326bbe0590SSundeep Panicker
336bbe0590SSundeep Panicker #pragma init(initialize_raw_access)
346bbe0590SSundeep Panicker
356bbe0590SSundeep Panicker static hash_obj_t *hash_table[TABLE_SIZE];
366bbe0590SSundeep Panicker extern raw_list_t *g_raw;
376bbe0590SSundeep Panicker
386bbe0590SSundeep Panicker static void
initialize_raw_access(void)396bbe0590SSundeep Panicker initialize_raw_access(void)
406bbe0590SSundeep Panicker {
416bbe0590SSundeep Panicker int count;
426bbe0590SSundeep Panicker
436bbe0590SSundeep Panicker for (count = 0; count < TABLE_SIZE; count++) {
446bbe0590SSundeep Panicker hash_table[count] = NULL;
456bbe0590SSundeep Panicker }
466bbe0590SSundeep Panicker }
476bbe0590SSundeep Panicker
486bbe0590SSundeep Panicker
496bbe0590SSundeep Panicker static hash_obj_t *
lookup_handle_object(handle_t handle,int object_type)506bbe0590SSundeep Panicker lookup_handle_object(handle_t handle, int object_type)
516bbe0590SSundeep Panicker {
526bbe0590SSundeep Panicker handle_t index_to_hash;
536bbe0590SSundeep Panicker hash_obj_t *first_hash_obj;
546bbe0590SSundeep Panicker hash_obj_t *next_hash_obj;
556bbe0590SSundeep Panicker
566bbe0590SSundeep Panicker index_to_hash = (handle % TABLE_SIZE);
576bbe0590SSundeep Panicker
586bbe0590SSundeep Panicker first_hash_obj = hash_table[index_to_hash];
596bbe0590SSundeep Panicker for (next_hash_obj = first_hash_obj; next_hash_obj != NULL;
606bbe0590SSundeep Panicker next_hash_obj = next_hash_obj->next) {
616bbe0590SSundeep Panicker if ((handle == next_hash_obj->obj_hdl) &&
626bbe0590SSundeep Panicker (object_type == next_hash_obj->object_type)) {
636bbe0590SSundeep Panicker return (next_hash_obj);
646bbe0590SSundeep Panicker }
656bbe0590SSundeep Panicker }
666bbe0590SSundeep Panicker return (NULL);
676bbe0590SSundeep Panicker }
686bbe0590SSundeep Panicker
696bbe0590SSundeep Panicker
706bbe0590SSundeep Panicker static void
add_hashobject_to_hashtable(hash_obj_t * hash_obj)716bbe0590SSundeep Panicker add_hashobject_to_hashtable(hash_obj_t *hash_obj)
726bbe0590SSundeep Panicker {
736bbe0590SSundeep Panicker handle_t index_to_hash;
746bbe0590SSundeep Panicker static uint64_t handle_count = 0;
756bbe0590SSundeep Panicker
766bbe0590SSundeep Panicker hash_obj->obj_hdl = ++handle_count; /* store the handle */
776bbe0590SSundeep Panicker
786bbe0590SSundeep Panicker /* where to add ? */
796bbe0590SSundeep Panicker index_to_hash = ((hash_obj->obj_hdl) % TABLE_SIZE);
806bbe0590SSundeep Panicker
816bbe0590SSundeep Panicker hash_obj->next = hash_table[index_to_hash];
826bbe0590SSundeep Panicker hash_table[index_to_hash] = hash_obj; /* hash obj. added */
836bbe0590SSundeep Panicker
846bbe0590SSundeep Panicker if (hash_obj->next != NULL) {
856bbe0590SSundeep Panicker hash_obj->next->prev = hash_obj;
866bbe0590SSundeep Panicker }
876bbe0590SSundeep Panicker }
886bbe0590SSundeep Panicker
896bbe0590SSundeep Panicker
906bbe0590SSundeep Panicker static hash_obj_t *
create_container_hash_object(void)916bbe0590SSundeep Panicker create_container_hash_object(void)
926bbe0590SSundeep Panicker {
936bbe0590SSundeep Panicker hash_obj_t *hash_obj;
946bbe0590SSundeep Panicker container_obj_t *cont_obj;
956bbe0590SSundeep Panicker
966bbe0590SSundeep Panicker cont_obj = malloc(sizeof (container_obj_t));
976bbe0590SSundeep Panicker if (cont_obj == NULL) {
986bbe0590SSundeep Panicker return (NULL);
996bbe0590SSundeep Panicker }
1006bbe0590SSundeep Panicker
1016bbe0590SSundeep Panicker hash_obj = malloc(sizeof (hash_obj_t));
1026bbe0590SSundeep Panicker if (hash_obj == NULL) {
1036bbe0590SSundeep Panicker free(cont_obj);
1046bbe0590SSundeep Panicker return (NULL);
1056bbe0590SSundeep Panicker }
1066bbe0590SSundeep Panicker
1076bbe0590SSundeep Panicker cont_obj->sec_obj_list = NULL;
1086bbe0590SSundeep Panicker
1096bbe0590SSundeep Panicker hash_obj->object_type = CONTAINER_TYPE;
1106bbe0590SSundeep Panicker hash_obj->u.cont_obj = cont_obj;
1116bbe0590SSundeep Panicker hash_obj->next = NULL;
1126bbe0590SSundeep Panicker hash_obj->prev = NULL;
1136bbe0590SSundeep Panicker
1146bbe0590SSundeep Panicker return (hash_obj);
1156bbe0590SSundeep Panicker }
1166bbe0590SSundeep Panicker
1176bbe0590SSundeep Panicker
1186bbe0590SSundeep Panicker static hash_obj_t *
create_section_hash_object(void)1196bbe0590SSundeep Panicker create_section_hash_object(void)
1206bbe0590SSundeep Panicker {
1216bbe0590SSundeep Panicker hash_obj_t *hash_obj;
1226bbe0590SSundeep Panicker section_obj_t *sec_obj;
1236bbe0590SSundeep Panicker
1246bbe0590SSundeep Panicker sec_obj = malloc(sizeof (section_obj_t));
1256bbe0590SSundeep Panicker if (sec_obj == NULL) {
1266bbe0590SSundeep Panicker return (NULL);
1276bbe0590SSundeep Panicker }
1286bbe0590SSundeep Panicker
1296bbe0590SSundeep Panicker hash_obj = malloc(sizeof (hash_obj_t));
1306bbe0590SSundeep Panicker if (hash_obj == NULL) {
1316bbe0590SSundeep Panicker free(sec_obj);
1326bbe0590SSundeep Panicker return (NULL);
1336bbe0590SSundeep Panicker }
1346bbe0590SSundeep Panicker
1356bbe0590SSundeep Panicker sec_obj->next = NULL;
1366bbe0590SSundeep Panicker sec_obj->seg_obj_list = NULL;
1376bbe0590SSundeep Panicker
1386bbe0590SSundeep Panicker hash_obj->u.sec_obj = sec_obj;
1396bbe0590SSundeep Panicker hash_obj->object_type = SECTION_TYPE;
1406bbe0590SSundeep Panicker hash_obj->next = NULL;
1416bbe0590SSundeep Panicker hash_obj->prev = NULL;
1426bbe0590SSundeep Panicker
1436bbe0590SSundeep Panicker return (hash_obj);
1446bbe0590SSundeep Panicker }
1456bbe0590SSundeep Panicker
1466bbe0590SSundeep Panicker
1476bbe0590SSundeep Panicker static hash_obj_t *
create_segment_hash_object(void)1486bbe0590SSundeep Panicker create_segment_hash_object(void)
1496bbe0590SSundeep Panicker {
1506bbe0590SSundeep Panicker hash_obj_t *hash_obj;
1516bbe0590SSundeep Panicker segment_obj_t *seg_obj;
1526bbe0590SSundeep Panicker
1536bbe0590SSundeep Panicker seg_obj = malloc(sizeof (segment_obj_t));
1546bbe0590SSundeep Panicker if (seg_obj == NULL) {
1556bbe0590SSundeep Panicker return (NULL);
1566bbe0590SSundeep Panicker }
1576bbe0590SSundeep Panicker
1586bbe0590SSundeep Panicker hash_obj = malloc(sizeof (hash_obj_t));
1596bbe0590SSundeep Panicker if (hash_obj == NULL) {
1606bbe0590SSundeep Panicker free(seg_obj);
1616bbe0590SSundeep Panicker return (NULL);
1626bbe0590SSundeep Panicker }
1636bbe0590SSundeep Panicker
1646bbe0590SSundeep Panicker seg_obj->next = NULL;
1656bbe0590SSundeep Panicker seg_obj->pkt_obj_list = NULL;
1666bbe0590SSundeep Panicker
1676bbe0590SSundeep Panicker hash_obj->object_type = SEGMENT_TYPE;
1686bbe0590SSundeep Panicker hash_obj->u.seg_obj = seg_obj;
1696bbe0590SSundeep Panicker hash_obj->next = NULL;
1706bbe0590SSundeep Panicker hash_obj->prev = NULL;
1716bbe0590SSundeep Panicker
1726bbe0590SSundeep Panicker return (hash_obj);
1736bbe0590SSundeep Panicker }
1746bbe0590SSundeep Panicker
1756bbe0590SSundeep Panicker
1766bbe0590SSundeep Panicker static hash_obj_t *
create_packet_hash_object(void)1776bbe0590SSundeep Panicker create_packet_hash_object(void)
1786bbe0590SSundeep Panicker {
1796bbe0590SSundeep Panicker hash_obj_t *hash_obj;
1806bbe0590SSundeep Panicker packet_obj_t *pkt_obj;
1816bbe0590SSundeep Panicker
1826bbe0590SSundeep Panicker pkt_obj = malloc(sizeof (packet_obj_t));
1836bbe0590SSundeep Panicker if (pkt_obj == NULL) {
1846bbe0590SSundeep Panicker return (NULL);
1856bbe0590SSundeep Panicker }
1866bbe0590SSundeep Panicker
1876bbe0590SSundeep Panicker hash_obj = malloc(sizeof (hash_obj_t));
1886bbe0590SSundeep Panicker if (hash_obj == NULL) {
1896bbe0590SSundeep Panicker free(pkt_obj);
1906bbe0590SSundeep Panicker return (NULL);
1916bbe0590SSundeep Panicker }
1926bbe0590SSundeep Panicker
1936bbe0590SSundeep Panicker pkt_obj->next = NULL;
1946bbe0590SSundeep Panicker
1956bbe0590SSundeep Panicker hash_obj->object_type = PACKET_TYPE;
1966bbe0590SSundeep Panicker hash_obj->u.pkt_obj = pkt_obj;
1976bbe0590SSundeep Panicker hash_obj->next = NULL;
1986bbe0590SSundeep Panicker hash_obj->prev = NULL;
1996bbe0590SSundeep Panicker
2006bbe0590SSundeep Panicker return (hash_obj);
2016bbe0590SSundeep Panicker }
2026bbe0590SSundeep Panicker
2036bbe0590SSundeep Panicker
2046bbe0590SSundeep Panicker
2056bbe0590SSundeep Panicker static hash_obj_t *
get_container_hash_object(int object_type,handle_t handle)2066bbe0590SSundeep Panicker get_container_hash_object(int object_type, handle_t handle)
2076bbe0590SSundeep Panicker {
2086bbe0590SSundeep Panicker hash_obj_t *hash_obj;
2096bbe0590SSundeep Panicker
2106bbe0590SSundeep Panicker switch (object_type) {
2116bbe0590SSundeep Panicker case CONTAINER_TYPE:
2126bbe0590SSundeep Panicker break;
2136bbe0590SSundeep Panicker case SECTION_TYPE:
2146bbe0590SSundeep Panicker hash_obj = lookup_handle_object(handle, CONTAINER_TYPE);
2156bbe0590SSundeep Panicker if (hash_obj == NULL) {
2166bbe0590SSundeep Panicker return (NULL);
2176bbe0590SSundeep Panicker }
2186bbe0590SSundeep Panicker break;
2196bbe0590SSundeep Panicker case SEGMENT_TYPE:
2206bbe0590SSundeep Panicker hash_obj = lookup_handle_object(handle, SECTION_TYPE);
2216bbe0590SSundeep Panicker if (hash_obj == NULL) {
2226bbe0590SSundeep Panicker return (NULL);
2236bbe0590SSundeep Panicker }
2246bbe0590SSundeep Panicker hash_obj = lookup_handle_object(hash_obj->u.sec_obj->cont_hdl,
2256bbe0590SSundeep Panicker CONTAINER_TYPE);
2266bbe0590SSundeep Panicker break;
2276bbe0590SSundeep Panicker case PACKET_TYPE:
2286bbe0590SSundeep Panicker break;
2296bbe0590SSundeep Panicker default:
2306bbe0590SSundeep Panicker return (NULL);
2316bbe0590SSundeep Panicker }
2326bbe0590SSundeep Panicker
2336bbe0590SSundeep Panicker return (hash_obj);
2346bbe0590SSundeep Panicker }
2356bbe0590SSundeep Panicker
2366bbe0590SSundeep Panicker
2376bbe0590SSundeep Panicker static void
add_to_pkt_object_list(hash_obj_t * parent_obj,hash_obj_t * child_obj)2386bbe0590SSundeep Panicker add_to_pkt_object_list(hash_obj_t *parent_obj, hash_obj_t *child_obj)
2396bbe0590SSundeep Panicker {
2406bbe0590SSundeep Panicker hash_obj_t *next_hash;
2416bbe0590SSundeep Panicker
2426bbe0590SSundeep Panicker /* add the packet object in the end of list */
2436bbe0590SSundeep Panicker child_obj->u.pkt_obj->segment_hdl = parent_obj->obj_hdl;
2446bbe0590SSundeep Panicker
2456bbe0590SSundeep Panicker if (parent_obj->u.seg_obj->pkt_obj_list == NULL) {
2466bbe0590SSundeep Panicker parent_obj->u.seg_obj->pkt_obj_list = child_obj;
2476bbe0590SSundeep Panicker return;
2486bbe0590SSundeep Panicker }
2496bbe0590SSundeep Panicker
2506bbe0590SSundeep Panicker for (next_hash = parent_obj->u.seg_obj->pkt_obj_list;
2516bbe0590SSundeep Panicker next_hash->u.pkt_obj->next != NULL;
2526bbe0590SSundeep Panicker next_hash = next_hash->u.pkt_obj->next) {
2536bbe0590SSundeep Panicker ;
2546bbe0590SSundeep Panicker }
2556bbe0590SSundeep Panicker
2566bbe0590SSundeep Panicker next_hash->u.pkt_obj->next = child_obj;
2576bbe0590SSundeep Panicker }
2586bbe0590SSundeep Panicker
2596bbe0590SSundeep Panicker
2606bbe0590SSundeep Panicker static void
free_pkt_object_list(hash_obj_t * hash_obj)2616bbe0590SSundeep Panicker free_pkt_object_list(hash_obj_t *hash_obj)
2626bbe0590SSundeep Panicker {
2636bbe0590SSundeep Panicker hash_obj_t *next_obj;
2646bbe0590SSundeep Panicker hash_obj_t *free_obj;
2656bbe0590SSundeep Panicker
2666bbe0590SSundeep Panicker next_obj = hash_obj->u.seg_obj->pkt_obj_list;
2676bbe0590SSundeep Panicker while (next_obj != NULL) {
2686bbe0590SSundeep Panicker free_obj = next_obj;
2696bbe0590SSundeep Panicker next_obj = next_obj->u.pkt_obj->next;
2706bbe0590SSundeep Panicker /* if prev is NULL it's the first object in the list */
2716bbe0590SSundeep Panicker if (free_obj->prev == NULL) {
2726bbe0590SSundeep Panicker hash_table[(free_obj->obj_hdl % TABLE_SIZE)] =
2736bbe0590SSundeep Panicker free_obj->next;
2746bbe0590SSundeep Panicker if (free_obj->next != NULL) {
2756bbe0590SSundeep Panicker free_obj->next->prev = free_obj->prev;
2766bbe0590SSundeep Panicker }
2776bbe0590SSundeep Panicker } else {
2786bbe0590SSundeep Panicker free_obj->prev->next = free_obj->next;
2796bbe0590SSundeep Panicker if (free_obj->next != NULL) {
2806bbe0590SSundeep Panicker free_obj->next->prev = free_obj->prev;
2816bbe0590SSundeep Panicker }
2826bbe0590SSundeep Panicker }
2836bbe0590SSundeep Panicker
2846bbe0590SSundeep Panicker free(free_obj->u.pkt_obj->payload);
2856bbe0590SSundeep Panicker free(free_obj->u.pkt_obj);
2866bbe0590SSundeep Panicker free(free_obj);
2876bbe0590SSundeep Panicker }
2886bbe0590SSundeep Panicker
2896bbe0590SSundeep Panicker hash_obj->u.seg_obj->pkt_obj_list = NULL;
2906bbe0590SSundeep Panicker }
2916bbe0590SSundeep Panicker
2926bbe0590SSundeep Panicker
2936bbe0590SSundeep Panicker static void
free_segment_hash(handle_t handle,hash_obj_t * sec_hash)2946bbe0590SSundeep Panicker free_segment_hash(handle_t handle, hash_obj_t *sec_hash)
2956bbe0590SSundeep Panicker {
2966bbe0590SSundeep Panicker hash_obj_t *seg_hash;
2976bbe0590SSundeep Panicker hash_obj_t *next_hash;
2986bbe0590SSundeep Panicker
2996bbe0590SSundeep Panicker seg_hash = sec_hash->u.sec_obj->seg_obj_list;
3006bbe0590SSundeep Panicker if (seg_hash == NULL) {
3016bbe0590SSundeep Panicker return;
3026bbe0590SSundeep Panicker }
3036bbe0590SSundeep Panicker
3046bbe0590SSundeep Panicker if (seg_hash->obj_hdl == handle) {
3056bbe0590SSundeep Panicker sec_hash->u.sec_obj->seg_obj_list = seg_hash->u.seg_obj->next;
3066bbe0590SSundeep Panicker } else {
3076bbe0590SSundeep Panicker while (seg_hash->obj_hdl != handle) {
3086bbe0590SSundeep Panicker next_hash = seg_hash;
3096bbe0590SSundeep Panicker seg_hash = seg_hash->u.seg_obj->next;
3106bbe0590SSundeep Panicker if (seg_hash == NULL) {
3116bbe0590SSundeep Panicker return;
3126bbe0590SSundeep Panicker }
3136bbe0590SSundeep Panicker }
3146bbe0590SSundeep Panicker next_hash->u.seg_obj->next = seg_hash->u.seg_obj->next;
3156bbe0590SSundeep Panicker }
3166bbe0590SSundeep Panicker
3176bbe0590SSundeep Panicker if (seg_hash->prev == NULL) {
3186bbe0590SSundeep Panicker hash_table[(seg_hash->obj_hdl % TABLE_SIZE)] = seg_hash->next;
3196bbe0590SSundeep Panicker if (seg_hash->next != NULL) {
3206bbe0590SSundeep Panicker seg_hash->next->prev = NULL;
3216bbe0590SSundeep Panicker }
3226bbe0590SSundeep Panicker } else {
3236bbe0590SSundeep Panicker seg_hash->prev->next = seg_hash->next;
3246bbe0590SSundeep Panicker if (seg_hash->next != NULL) {
3256bbe0590SSundeep Panicker seg_hash->next->prev = seg_hash->prev;
3266bbe0590SSundeep Panicker }
3276bbe0590SSundeep Panicker }
3286bbe0590SSundeep Panicker
3296bbe0590SSundeep Panicker free_pkt_object_list(seg_hash);
3306bbe0590SSundeep Panicker free(seg_hash->u.seg_obj);
3316bbe0590SSundeep Panicker free(seg_hash);
3326bbe0590SSundeep Panicker }
3336bbe0590SSundeep Panicker
3346bbe0590SSundeep Panicker
3356bbe0590SSundeep Panicker
3366bbe0590SSundeep Panicker static void
add_to_sec_object_list(hash_obj_t * parent_obj,hash_obj_t * child_obj)3376bbe0590SSundeep Panicker add_to_sec_object_list(hash_obj_t *parent_obj, hash_obj_t *child_obj)
3386bbe0590SSundeep Panicker {
3396bbe0590SSundeep Panicker hash_obj_t *next_hash;
3406bbe0590SSundeep Panicker
3416bbe0590SSundeep Panicker child_obj->u.sec_obj->cont_hdl = parent_obj->obj_hdl;
3426bbe0590SSundeep Panicker if (parent_obj->u.cont_obj->sec_obj_list == NULL) {
3436bbe0590SSundeep Panicker parent_obj->u.cont_obj->sec_obj_list = child_obj;
3446bbe0590SSundeep Panicker return;
3456bbe0590SSundeep Panicker }
3466bbe0590SSundeep Panicker
3476bbe0590SSundeep Panicker for (next_hash = parent_obj->u.cont_obj->sec_obj_list;
3486bbe0590SSundeep Panicker next_hash->u.sec_obj->next != NULL;
3496bbe0590SSundeep Panicker next_hash = next_hash->u.sec_obj->next) {
3506bbe0590SSundeep Panicker ;
3516bbe0590SSundeep Panicker }
3526bbe0590SSundeep Panicker
3536bbe0590SSundeep Panicker next_hash->u.sec_obj->next = child_obj;
3546bbe0590SSundeep Panicker }
3556bbe0590SSundeep Panicker
3566bbe0590SSundeep Panicker
3576bbe0590SSundeep Panicker static void
add_to_seg_object_list(hash_obj_t * parent_obj,hash_obj_t * child_obj)3586bbe0590SSundeep Panicker add_to_seg_object_list(hash_obj_t *parent_obj, hash_obj_t *child_obj)
3596bbe0590SSundeep Panicker {
3606bbe0590SSundeep Panicker hash_obj_t *next_hash;
3616bbe0590SSundeep Panicker
3626bbe0590SSundeep Panicker child_obj->u.seg_obj->section_hdl = parent_obj->obj_hdl;
3636bbe0590SSundeep Panicker if (parent_obj->u.sec_obj->seg_obj_list == NULL) {
3646bbe0590SSundeep Panicker parent_obj->u.sec_obj->seg_obj_list = child_obj;
3656bbe0590SSundeep Panicker return;
3666bbe0590SSundeep Panicker }
3676bbe0590SSundeep Panicker
3686bbe0590SSundeep Panicker for (next_hash = parent_obj->u.sec_obj->seg_obj_list;
3696bbe0590SSundeep Panicker next_hash->u.seg_obj->next != NULL;
3706bbe0590SSundeep Panicker next_hash = next_hash->u.seg_obj->next) {
3716bbe0590SSundeep Panicker ;
3726bbe0590SSundeep Panicker }
3736bbe0590SSundeep Panicker
3746bbe0590SSundeep Panicker next_hash->u.seg_obj->next = child_obj;
3756bbe0590SSundeep Panicker }
3766bbe0590SSundeep Panicker
3776bbe0590SSundeep Panicker
3786bbe0590SSundeep Panicker static char *
tokenizer(char * buf,char * separator,char ** nextBuf,char * matched)3796bbe0590SSundeep Panicker tokenizer(char *buf, char *separator, char **nextBuf, char *matched)
3806bbe0590SSundeep Panicker {
3816bbe0590SSundeep Panicker int i = 0;
3826bbe0590SSundeep Panicker int j = 0;
3836bbe0590SSundeep Panicker
3846bbe0590SSundeep Panicker for (i = 0; buf[i] != '\0'; i++) {
3856bbe0590SSundeep Panicker for (j = 0; j < strlen(separator); j++) {
3866bbe0590SSundeep Panicker if (buf[i] == separator[j]) {
3876bbe0590SSundeep Panicker buf[i] = '\0';
3886bbe0590SSundeep Panicker *nextBuf = &(buf[i+1]);
3896bbe0590SSundeep Panicker *matched = separator[j];
3906bbe0590SSundeep Panicker return (buf);
3916bbe0590SSundeep Panicker }
3926bbe0590SSundeep Panicker }
3936bbe0590SSundeep Panicker }
3946bbe0590SSundeep Panicker
3956bbe0590SSundeep Panicker *nextBuf = buf;
3966bbe0590SSundeep Panicker *matched = '\0';
3976bbe0590SSundeep Panicker return (NULL);
3986bbe0590SSundeep Panicker }
3996bbe0590SSundeep Panicker
4006bbe0590SSundeep Panicker
4016bbe0590SSundeep Panicker static void
copy_segment_layout(segment_t * seghdr,void * layout)4026bbe0590SSundeep Panicker copy_segment_layout(segment_t *seghdr, void *layout)
4036bbe0590SSundeep Panicker {
4046bbe0590SSundeep Panicker segment_layout_t *seg_layout;
4056bbe0590SSundeep Panicker
4066bbe0590SSundeep Panicker seg_layout = (segment_layout_t *)layout;
4076bbe0590SSundeep Panicker (void) memcpy(seghdr->name, &seg_layout->name, SEG_NAME_LEN);
4086bbe0590SSundeep Panicker seghdr->descriptor = GET_SEGMENT_DESCRIPTOR;
4096bbe0590SSundeep Panicker seghdr->offset = BE_16(seg_layout->offset);
4106bbe0590SSundeep Panicker seghdr->length = BE_16(seg_layout->length);
4116bbe0590SSundeep Panicker }
4126bbe0590SSundeep Panicker
4136bbe0590SSundeep Panicker
4146bbe0590SSundeep Panicker static int
get_container_info(const char * def_file,const char * cont_desc_str,container_info_t * cont_info)4156bbe0590SSundeep Panicker get_container_info(const char *def_file, const char *cont_desc_str,
4166bbe0590SSundeep Panicker container_info_t *cont_info)
4176bbe0590SSundeep Panicker {
4186bbe0590SSundeep Panicker char *item;
4196bbe0590SSundeep Panicker char *token;
4206bbe0590SSundeep Panicker char *field;
4216bbe0590SSundeep Panicker char matched;
4226bbe0590SSundeep Panicker char buf[1024];
4236bbe0590SSundeep Panicker int foundIt = 0;
4246bbe0590SSundeep Panicker FILE *file = fopen(def_file, "r");
4256bbe0590SSundeep Panicker
4266bbe0590SSundeep Panicker if (file == NULL)
4276bbe0590SSundeep Panicker return (-1);
4286bbe0590SSundeep Panicker
4296bbe0590SSundeep Panicker cont_info->num_sections = 0;
4306bbe0590SSundeep Panicker
4316bbe0590SSundeep Panicker while (fgets(buf, sizeof (buf), file) != NULL) {
4326bbe0590SSundeep Panicker /* ignore all comments */
4336bbe0590SSundeep Panicker token = tokenizer(buf, "#", &field, &matched);
4346bbe0590SSundeep Panicker /* find the names */
4356bbe0590SSundeep Panicker token = tokenizer(buf, ":", &field, &matched);
4366bbe0590SSundeep Panicker if (token != 0x00) {
4376bbe0590SSundeep Panicker token = tokenizer(token, "|", &item, &matched);
4386bbe0590SSundeep Panicker while (token != 0x00) {
4396bbe0590SSundeep Panicker if (strcmp(token, cont_desc_str) == 0) {
4406bbe0590SSundeep Panicker foundIt = 1;
4416bbe0590SSundeep Panicker goto found;
4426bbe0590SSundeep Panicker }
4436bbe0590SSundeep Panicker token = tokenizer(item, "|", &item, &matched);
4446bbe0590SSundeep Panicker }
4456bbe0590SSundeep Panicker /* check the last remaining item */
4466bbe0590SSundeep Panicker if ((item != 0x00) &&
4476bbe0590SSundeep Panicker (strcmp(item, cont_desc_str) == 0)) {
4486bbe0590SSundeep Panicker foundIt = 1;
4496bbe0590SSundeep Panicker goto found;
4506bbe0590SSundeep Panicker }
4516bbe0590SSundeep Panicker }
4526bbe0590SSundeep Panicker }
4536bbe0590SSundeep Panicker
4546bbe0590SSundeep Panicker found :
4556bbe0590SSundeep Panicker if (foundIt == 1) {
4566bbe0590SSundeep Panicker token = tokenizer(field, ":", &field, &matched);
4576bbe0590SSundeep Panicker if (token == 0x00) {
4586bbe0590SSundeep Panicker (void) fclose(file);
4596bbe0590SSundeep Panicker return (-1);
4606bbe0590SSundeep Panicker }
4616bbe0590SSundeep Panicker cont_info->header_ver = (headerrev_t)atoi(token);
4626bbe0590SSundeep Panicker
4636bbe0590SSundeep Panicker token = tokenizer(field, ":\n", &field, &matched);
4646bbe0590SSundeep Panicker while (token != 0x00) {
4656bbe0590SSundeep Panicker token = tokenizer(token, ",", &item, &matched);
4666bbe0590SSundeep Panicker if (token == 0x00) {
4676bbe0590SSundeep Panicker (void) fclose(file);
4686bbe0590SSundeep Panicker return (-1);
4696bbe0590SSundeep Panicker }
4706bbe0590SSundeep Panicker if (atoi(token) == 1) {
4716bbe0590SSundeep Panicker cont_info->section_info[cont_info->
4726bbe0590SSundeep Panicker num_sections].description.field.read_only
4736bbe0590SSundeep Panicker = 1;
4746bbe0590SSundeep Panicker } else if (atoi(token) == 0) {
4756bbe0590SSundeep Panicker cont_info->section_info[cont_info->
4766bbe0590SSundeep Panicker num_sections].description.field.read_only
4776bbe0590SSundeep Panicker = 0;
4786bbe0590SSundeep Panicker } else {
4796bbe0590SSundeep Panicker (void) fclose(file);
4806bbe0590SSundeep Panicker return (-1);
4816bbe0590SSundeep Panicker }
4826bbe0590SSundeep Panicker
4836bbe0590SSundeep Panicker token = tokenizer(item, ",", &item, &matched);
4846bbe0590SSundeep Panicker if (token == 0x00) {
4856bbe0590SSundeep Panicker (void) fclose(file);
4866bbe0590SSundeep Panicker return (-1);
4876bbe0590SSundeep Panicker }
4886bbe0590SSundeep Panicker
4896bbe0590SSundeep Panicker cont_info->section_info[cont_info->
4906bbe0590SSundeep Panicker num_sections].address = atoi(token);
4916bbe0590SSundeep Panicker if (item == '\0') {
4926bbe0590SSundeep Panicker (void) fclose(file);
4936bbe0590SSundeep Panicker return (-1);
4946bbe0590SSundeep Panicker }
4956bbe0590SSundeep Panicker cont_info->section_info[cont_info->num_sections].size =
4966bbe0590SSundeep Panicker atoi(item);
4976bbe0590SSundeep Panicker (cont_info->num_sections)++;
4986bbe0590SSundeep Panicker
4996bbe0590SSundeep Panicker token = tokenizer(field, ":\n ", &field, &matched);
5006bbe0590SSundeep Panicker }
5016bbe0590SSundeep Panicker }
5026bbe0590SSundeep Panicker (void) fclose(file);
5036bbe0590SSundeep Panicker
5046bbe0590SSundeep Panicker return (0);
5056bbe0590SSundeep Panicker }
5066bbe0590SSundeep Panicker
5076bbe0590SSundeep Panicker
5086bbe0590SSundeep Panicker /* ARGSUSED */
5096bbe0590SSundeep Panicker int
fru_get_segments(section_hdl_t section,segment_t * segment,int maxseg,door_cred_t * cred)5106bbe0590SSundeep Panicker fru_get_segments(section_hdl_t section, segment_t *segment, int maxseg,
5116bbe0590SSundeep Panicker door_cred_t *cred)
5126bbe0590SSundeep Panicker {
5136bbe0590SSundeep Panicker int count;
5146bbe0590SSundeep Panicker hash_obj_t *sec_object;
5156bbe0590SSundeep Panicker hash_obj_t *seg_object;
5166bbe0590SSundeep Panicker section_obj_t *sec_obj;
5176bbe0590SSundeep Panicker
5186bbe0590SSundeep Panicker sec_object = lookup_handle_object(section, SECTION_TYPE);
5196bbe0590SSundeep Panicker if (sec_object == NULL) {
5206bbe0590SSundeep Panicker return (-1);
5216bbe0590SSundeep Panicker }
5226bbe0590SSundeep Panicker
5236bbe0590SSundeep Panicker sec_obj = sec_object->u.sec_obj;
5246bbe0590SSundeep Panicker if (sec_obj == NULL) {
5256bbe0590SSundeep Panicker return (-1);
5266bbe0590SSundeep Panicker }
5276bbe0590SSundeep Panicker
5286bbe0590SSundeep Panicker if (sec_obj->num_of_segment > maxseg) {
5296bbe0590SSundeep Panicker return (-1);
5306bbe0590SSundeep Panicker }
5316bbe0590SSundeep Panicker
5326bbe0590SSundeep Panicker seg_object = sec_object->u.sec_obj->seg_obj_list;
5336bbe0590SSundeep Panicker if (seg_object == NULL) {
5346bbe0590SSundeep Panicker return (-1);
5356bbe0590SSundeep Panicker }
5366bbe0590SSundeep Panicker
5376bbe0590SSundeep Panicker for (count = 0; count < sec_obj->num_of_segment; count++) {
5386bbe0590SSundeep Panicker
5396bbe0590SSundeep Panicker /* populate segment_t */
5406bbe0590SSundeep Panicker segment->handle = seg_object->obj_hdl;
5416bbe0590SSundeep Panicker (void) memcpy(segment->name,
5426bbe0590SSundeep Panicker seg_object->u.seg_obj->segment.name, SEG_NAME_LEN);
5436bbe0590SSundeep Panicker segment->descriptor = seg_object->u.seg_obj->segment.descriptor;
5446bbe0590SSundeep Panicker
5456bbe0590SSundeep Panicker segment->offset = seg_object->u.seg_obj->segment.offset;
5466bbe0590SSundeep Panicker segment->length = seg_object->u.seg_obj->segment.length;
5476bbe0590SSundeep Panicker seg_object = seg_object->u.seg_obj->next;
5486bbe0590SSundeep Panicker segment++;
5496bbe0590SSundeep Panicker }
5506bbe0590SSundeep Panicker return (0);
5516bbe0590SSundeep Panicker }
5526bbe0590SSundeep Panicker
5536bbe0590SSundeep Panicker
5546bbe0590SSundeep Panicker static int
raw_memcpy(void * buffer,raw_list_t * rawlist,int offset,int size)5556bbe0590SSundeep Panicker raw_memcpy(void *buffer, raw_list_t *rawlist, int offset, int size)
5566bbe0590SSundeep Panicker {
5576bbe0590SSundeep Panicker if (offset + size > rawlist->size) {
5586bbe0590SSundeep Panicker size = rawlist->size - offset;
5596bbe0590SSundeep Panicker }
5606bbe0590SSundeep Panicker
5616bbe0590SSundeep Panicker (void) memcpy(buffer, &rawlist->raw[offset], size);
5626bbe0590SSundeep Panicker
5636bbe0590SSundeep Panicker return (size);
5646bbe0590SSundeep Panicker }
5656bbe0590SSundeep Panicker
5666bbe0590SSundeep Panicker
5676bbe0590SSundeep Panicker static int
verify_header_crc8(headerrev_t head_ver,unsigned char * bytes,int length)5686bbe0590SSundeep Panicker verify_header_crc8(headerrev_t head_ver, unsigned char *bytes, int length)
5696bbe0590SSundeep Panicker {
5706bbe0590SSundeep Panicker int crc_offset = 0;
5716bbe0590SSundeep Panicker unsigned char orig_crc8 = 0;
5726bbe0590SSundeep Panicker unsigned char calc_crc8 = 0;
5736bbe0590SSundeep Panicker
5746bbe0590SSundeep Panicker switch (head_ver) {
5756bbe0590SSundeep Panicker case SECTION_HDR_VER:
5766bbe0590SSundeep Panicker crc_offset = 4;
5776bbe0590SSundeep Panicker break;
5786bbe0590SSundeep Panicker default:
5796bbe0590SSundeep Panicker errno = EINVAL;
5806bbe0590SSundeep Panicker return (0);
5816bbe0590SSundeep Panicker }
5826bbe0590SSundeep Panicker
5836bbe0590SSundeep Panicker orig_crc8 = bytes[crc_offset];
5846bbe0590SSundeep Panicker bytes[crc_offset] = 0x00; /* clear for calc */
5856bbe0590SSundeep Panicker calc_crc8 = compute_crc8(bytes, length);
5866bbe0590SSundeep Panicker bytes[crc_offset] = orig_crc8; /* restore */
5876bbe0590SSundeep Panicker
5886bbe0590SSundeep Panicker return (orig_crc8 == calc_crc8);
5896bbe0590SSundeep Panicker }
5906bbe0590SSundeep Panicker
5916bbe0590SSundeep Panicker
5926bbe0590SSundeep Panicker static int
get_section(raw_list_t * rawlist,hash_obj_t * sec_hash,section_t * section)5936bbe0590SSundeep Panicker get_section(raw_list_t *rawlist, hash_obj_t *sec_hash, section_t *section)
5946bbe0590SSundeep Panicker {
5956bbe0590SSundeep Panicker int retval;
5966bbe0590SSundeep Panicker int size;
5976bbe0590SSundeep Panicker int count;
5986bbe0590SSundeep Panicker uint16_t hdrver;
5996bbe0590SSundeep Panicker hash_obj_t *seg_hash;
6006bbe0590SSundeep Panicker unsigned char *buffer;
6016bbe0590SSundeep Panicker section_obj_t *sec_obj;
6026bbe0590SSundeep Panicker section_layout_t sec_hdr;
6036bbe0590SSundeep Panicker segment_layout_t *seg_hdr;
6046bbe0590SSundeep Panicker segment_layout_t *seg_buf;
6056bbe0590SSundeep Panicker
6066bbe0590SSundeep Panicker sec_obj = sec_hash->u.sec_obj;
6076bbe0590SSundeep Panicker if (sec_obj == NULL) {
6086bbe0590SSundeep Panicker return (-1);
6096bbe0590SSundeep Panicker }
6106bbe0590SSundeep Panicker
6116bbe0590SSundeep Panicker /* populate section_t */
6126bbe0590SSundeep Panicker section->handle = sec_hash->obj_hdl;
6136bbe0590SSundeep Panicker section->offset = sec_obj->section.offset;
6146bbe0590SSundeep Panicker section->length = sec_obj->section.length;
6156bbe0590SSundeep Panicker section->protection = sec_obj->section.protection;
6166bbe0590SSundeep Panicker section->version = sec_obj->section.version;
6176bbe0590SSundeep Panicker
6186bbe0590SSundeep Panicker /* read section header layout */
6196bbe0590SSundeep Panicker retval = raw_memcpy(&sec_hdr, rawlist, sec_obj->section.offset,
6206bbe0590SSundeep Panicker sizeof (sec_hdr));
6216bbe0590SSundeep Panicker
6226bbe0590SSundeep Panicker if (retval != sizeof (sec_hdr)) {
6236bbe0590SSundeep Panicker return (-1);
6246bbe0590SSundeep Panicker }
6256bbe0590SSundeep Panicker
6266bbe0590SSundeep Panicker
6276bbe0590SSundeep Panicker hdrver = GET_SECTION_HDR_VERSION;
6286bbe0590SSundeep Panicker
6296bbe0590SSundeep Panicker if ((sec_hdr.headertag != SECTION_HDR_TAG) &&
6306bbe0590SSundeep Panicker (hdrver != section->version)) {
6316bbe0590SSundeep Panicker return (-1);
6326bbe0590SSundeep Panicker }
6336bbe0590SSundeep Panicker
6346bbe0590SSundeep Panicker /* size = section layout + total sizeof segment header */
6356bbe0590SSundeep Panicker size = sizeof (sec_hdr) + ((sec_hdr.segmentcount)
6366bbe0590SSundeep Panicker * sizeof (segment_layout_t));
6376bbe0590SSundeep Panicker
6386bbe0590SSundeep Panicker buffer = alloca(size);
6396bbe0590SSundeep Panicker if (buffer == NULL) {
6406bbe0590SSundeep Panicker return (-1);
6416bbe0590SSundeep Panicker }
6426bbe0590SSundeep Panicker
6436bbe0590SSundeep Panicker /* segment header buffer */
6446bbe0590SSundeep Panicker seg_buf = alloca(size - sizeof (sec_hdr));
6456bbe0590SSundeep Panicker if (seg_buf == NULL) {
6466bbe0590SSundeep Panicker return (-1);
6476bbe0590SSundeep Panicker }
6486bbe0590SSundeep Panicker
6496bbe0590SSundeep Panicker /* read segment header */
6506bbe0590SSundeep Panicker retval = raw_memcpy(seg_buf, rawlist,
6516bbe0590SSundeep Panicker sec_obj->section.offset + sizeof (sec_hdr),
6526bbe0590SSundeep Panicker size - sizeof (sec_hdr));
6536bbe0590SSundeep Panicker
6546bbe0590SSundeep Panicker if (retval != (size - sizeof (sec_hdr))) {
6556bbe0590SSundeep Panicker return (-1);
6566bbe0590SSundeep Panicker }
6576bbe0590SSundeep Panicker
6586bbe0590SSundeep Panicker /* copy section header layout */
6596bbe0590SSundeep Panicker (void) memcpy(buffer, &sec_hdr, sizeof (sec_hdr));
6606bbe0590SSundeep Panicker
6616bbe0590SSundeep Panicker /* copy segment header layout */
6626bbe0590SSundeep Panicker (void) memcpy(buffer + sizeof (sec_hdr), seg_buf, size -
6636bbe0590SSundeep Panicker sizeof (sec_hdr));
6646bbe0590SSundeep Panicker
6656bbe0590SSundeep Panicker /* verify crc8 */
6666bbe0590SSundeep Panicker retval = verify_header_crc8(hdrver, buffer, size);
6676bbe0590SSundeep Panicker if (retval != TRUE) {
6686bbe0590SSundeep Panicker return (-1);
6696bbe0590SSundeep Panicker }
6706bbe0590SSundeep Panicker
6716bbe0590SSundeep Panicker section->version = hdrver;
6726bbe0590SSundeep Panicker sec_obj->section.version = hdrver;
6736bbe0590SSundeep Panicker
6746bbe0590SSundeep Panicker seg_hdr = (segment_layout_t *)seg_buf;
6756bbe0590SSundeep Panicker
6766bbe0590SSundeep Panicker /* bug fix for frutool */
6776bbe0590SSundeep Panicker if (sec_hash->u.sec_obj->seg_obj_list != NULL) {
6786bbe0590SSundeep Panicker return (0);
6796bbe0590SSundeep Panicker } else {
6806bbe0590SSundeep Panicker sec_obj->num_of_segment = 0;
6816bbe0590SSundeep Panicker }
6826bbe0590SSundeep Panicker for (count = 0; count < sec_hdr.segmentcount; count++, seg_hdr++) {
6836bbe0590SSundeep Panicker
6846bbe0590SSundeep Panicker seg_hash = create_segment_hash_object();
6856bbe0590SSundeep Panicker if (seg_hash == NULL) {
6866bbe0590SSundeep Panicker return (-1);
6876bbe0590SSundeep Panicker }
6886bbe0590SSundeep Panicker add_hashobject_to_hashtable(seg_hash);
6896bbe0590SSundeep Panicker copy_segment_layout(&seg_hash->u.seg_obj->segment, seg_hdr);
6906bbe0590SSundeep Panicker add_to_seg_object_list(sec_hash, seg_hash);
6916bbe0590SSundeep Panicker sec_obj->num_of_segment++;
6926bbe0590SSundeep Panicker }
6936bbe0590SSundeep Panicker return (0);
6946bbe0590SSundeep Panicker }
6956bbe0590SSundeep Panicker
6966bbe0590SSundeep Panicker /* ARGSUSED */
6976bbe0590SSundeep Panicker int
fru_get_sections(container_hdl_t container,section_t * section,int maxsec,door_cred_t * cred)6986bbe0590SSundeep Panicker fru_get_sections(container_hdl_t container, section_t *section, int maxsec,
6996bbe0590SSundeep Panicker door_cred_t *cred)
7006bbe0590SSundeep Panicker {
7016bbe0590SSundeep Panicker int count;
7026bbe0590SSundeep Panicker int num_sec = 0;
7036bbe0590SSundeep Panicker hash_obj_t *cont_object;
7046bbe0590SSundeep Panicker hash_obj_t *sec_hash;
7056bbe0590SSundeep Panicker
7066bbe0590SSundeep Panicker cont_object = lookup_handle_object(container, CONTAINER_TYPE);
7076bbe0590SSundeep Panicker if (cont_object == NULL) {
7086bbe0590SSundeep Panicker return (-1);
7096bbe0590SSundeep Panicker }
7106bbe0590SSundeep Panicker
7116bbe0590SSundeep Panicker if (cont_object->u.cont_obj->num_of_section > maxsec) {
7126bbe0590SSundeep Panicker return (-1);
7136bbe0590SSundeep Panicker }
7146bbe0590SSundeep Panicker
7156bbe0590SSundeep Panicker sec_hash = cont_object->u.cont_obj->sec_obj_list;
7166bbe0590SSundeep Panicker if (sec_hash == NULL) {
7176bbe0590SSundeep Panicker return (-1);
7186bbe0590SSundeep Panicker }
7196bbe0590SSundeep Panicker
7206bbe0590SSundeep Panicker for (count = 0; count < cont_object->u.cont_obj->num_of_section;
7216bbe0590SSundeep Panicker count++) {
7226bbe0590SSundeep Panicker section->version = -1;
7236bbe0590SSundeep Panicker /* populate section_t */
7246bbe0590SSundeep Panicker if (get_section(g_raw, sec_hash, section) == 0) {
7256bbe0590SSundeep Panicker section++;
7266bbe0590SSundeep Panicker num_sec++;
7276bbe0590SSundeep Panicker }
7286bbe0590SSundeep Panicker sec_hash = sec_hash->u.sec_obj->next;
7296bbe0590SSundeep Panicker }
7306bbe0590SSundeep Panicker return (num_sec);
7316bbe0590SSundeep Panicker }
7326bbe0590SSundeep Panicker
7336bbe0590SSundeep Panicker
7346bbe0590SSundeep Panicker static uint32_t
get_checksum_crc(hash_obj_t * seg_hash,int data_size)7356bbe0590SSundeep Panicker get_checksum_crc(hash_obj_t *seg_hash, int data_size)
7366bbe0590SSundeep Panicker {
7376bbe0590SSundeep Panicker int protection;
7386bbe0590SSundeep Panicker int offset = 0;
7396bbe0590SSundeep Panicker uint32_t crc;
7406bbe0590SSundeep Panicker hash_obj_t *sec_hash;
7416bbe0590SSundeep Panicker hash_obj_t *pkt_hash;
7426bbe0590SSundeep Panicker unsigned char *buffer;
7436bbe0590SSundeep Panicker
7446bbe0590SSundeep Panicker sec_hash = lookup_handle_object(seg_hash->u.seg_obj->section_hdl,
7456bbe0590SSundeep Panicker SECTION_TYPE);
7466bbe0590SSundeep Panicker if (sec_hash == NULL) {
7476bbe0590SSundeep Panicker return ((uint32_t)-1);
7486bbe0590SSundeep Panicker }
7496bbe0590SSundeep Panicker
7506bbe0590SSundeep Panicker buffer = alloca(data_size);
7516bbe0590SSundeep Panicker if (buffer == NULL) {
7526bbe0590SSundeep Panicker return ((uint32_t)-1);
7536bbe0590SSundeep Panicker }
7546bbe0590SSundeep Panicker
7556bbe0590SSundeep Panicker /* traverse the packet object list for all the tags and payload */
7566bbe0590SSundeep Panicker for (pkt_hash = seg_hash->u.seg_obj->pkt_obj_list; pkt_hash != NULL;
7576bbe0590SSundeep Panicker pkt_hash = pkt_hash->u.pkt_obj->next) {
7586bbe0590SSundeep Panicker (void) memcpy(buffer + offset, &pkt_hash->u.pkt_obj->tag,
7596bbe0590SSundeep Panicker pkt_hash->u.pkt_obj->tag_size);
7606bbe0590SSundeep Panicker offset += pkt_hash->u.pkt_obj->tag_size;
7616bbe0590SSundeep Panicker (void) memcpy(buffer + offset, pkt_hash->u.pkt_obj->payload,
7626bbe0590SSundeep Panicker pkt_hash->u.pkt_obj->paylen);
7636bbe0590SSundeep Panicker offset += pkt_hash->u.pkt_obj->paylen;
7646bbe0590SSundeep Panicker }
7656bbe0590SSundeep Panicker
7666bbe0590SSundeep Panicker protection = sec_hash->u.sec_obj->section.protection;
7676bbe0590SSundeep Panicker
7686bbe0590SSundeep Panicker if (protection == READ_ONLY_SECTION) { /* read-only section */
7696bbe0590SSundeep Panicker crc = compute_crc32(buffer, data_size);
7706bbe0590SSundeep Panicker } else { /* read/write section */
7716bbe0590SSundeep Panicker crc = compute_checksum32(buffer, data_size);
7726bbe0590SSundeep Panicker }
7736bbe0590SSundeep Panicker return (crc); /* computed crc */
7746bbe0590SSundeep Panicker }
7756bbe0590SSundeep Panicker
7766bbe0590SSundeep Panicker
7776bbe0590SSundeep Panicker static int
get_packet(raw_list_t * rawlist,void * buffer,int size,int offset)7786bbe0590SSundeep Panicker get_packet(raw_list_t *rawlist, void *buffer, int size, int offset)
7796bbe0590SSundeep Panicker {
7806bbe0590SSundeep Panicker int retval;
7816bbe0590SSundeep Panicker
7826bbe0590SSundeep Panicker retval = raw_memcpy(buffer, rawlist, offset, size);
7836bbe0590SSundeep Panicker
7846bbe0590SSundeep Panicker if (retval != -1) {
7856bbe0590SSundeep Panicker return (0);
7866bbe0590SSundeep Panicker }
7876bbe0590SSundeep Panicker return (-1);
7886bbe0590SSundeep Panicker }
7896bbe0590SSundeep Panicker
7906bbe0590SSundeep Panicker
7916bbe0590SSundeep Panicker static int
get_packets(hash_obj_t * seg_hash,raw_list_t * rawlist,int offset,int length)7926bbe0590SSundeep Panicker get_packets(hash_obj_t *seg_hash, raw_list_t *rawlist, int offset, int length)
7936bbe0590SSundeep Panicker {
7946bbe0590SSundeep Panicker int tag_size;
7956bbe0590SSundeep Panicker int paylen;
7966bbe0590SSundeep Panicker int retval;
7976bbe0590SSundeep Panicker int seg_limit = 0;
7986bbe0590SSundeep Panicker int pktcnt = 0;
7996bbe0590SSundeep Panicker char *data;
8006bbe0590SSundeep Panicker uint32_t crc;
8016bbe0590SSundeep Panicker uint32_t origcrc;
8026bbe0590SSundeep Panicker fru_tag_t tag;
8036bbe0590SSundeep Panicker hash_obj_t *pkt_hash_obj;
8046bbe0590SSundeep Panicker hash_obj_t *sec_hash;
8056bbe0590SSundeep Panicker fru_segdesc_t *segdesc;
8066bbe0590SSundeep Panicker fru_tagtype_t tagtype;
8076bbe0590SSundeep Panicker char *ignore_flag;
8086bbe0590SSundeep Panicker
8096bbe0590SSundeep Panicker retval = get_packet(rawlist, &tag, sizeof (fru_tag_t), offset);
8106bbe0590SSundeep Panicker if (retval == -1) {
8116bbe0590SSundeep Panicker return (-1);
8126bbe0590SSundeep Panicker }
8136bbe0590SSundeep Panicker
8146bbe0590SSundeep Panicker /* section hash object */
8156bbe0590SSundeep Panicker sec_hash = lookup_handle_object(seg_hash->u.seg_obj->section_hdl,
8166bbe0590SSundeep Panicker SECTION_TYPE);
8176bbe0590SSundeep Panicker
8186bbe0590SSundeep Panicker if (sec_hash == NULL) {
8196bbe0590SSundeep Panicker return (-1);
8206bbe0590SSundeep Panicker }
8216bbe0590SSundeep Panicker
8226bbe0590SSundeep Panicker seg_hash->u.seg_obj->trailer_offset = offset;
8236bbe0590SSundeep Panicker
8246bbe0590SSundeep Panicker data = (char *)&tag;
8256bbe0590SSundeep Panicker while (data[0] != SEG_TRAILER_TAG) {
8266bbe0590SSundeep Panicker tagtype = get_tag_type(&tag); /* verify tag type */
8276bbe0590SSundeep Panicker if (tagtype == -1) {
8286bbe0590SSundeep Panicker return (-1);
8296bbe0590SSundeep Panicker }
8306bbe0590SSundeep Panicker
8316bbe0590SSundeep Panicker tag_size = get_tag_size(tagtype);
8326bbe0590SSundeep Panicker if (tag_size == -1) {
8336bbe0590SSundeep Panicker return (-1);
8346bbe0590SSundeep Panicker }
8356bbe0590SSundeep Panicker
8366bbe0590SSundeep Panicker seg_limit += tag_size;
8376bbe0590SSundeep Panicker if (seg_limit > length) {
8386bbe0590SSundeep Panicker return (-1);
8396bbe0590SSundeep Panicker }
8406bbe0590SSundeep Panicker
8416bbe0590SSundeep Panicker paylen = get_payload_length((void *)&tag);
8426bbe0590SSundeep Panicker if (paylen == -1) {
8436bbe0590SSundeep Panicker return (-1);
8446bbe0590SSundeep Panicker }
8456bbe0590SSundeep Panicker
8466bbe0590SSundeep Panicker seg_limit += paylen;
8476bbe0590SSundeep Panicker if (seg_limit > length) {
8486bbe0590SSundeep Panicker return (-1);
8496bbe0590SSundeep Panicker }
8506bbe0590SSundeep Panicker if ((offset + tag_size + paylen) >
8516bbe0590SSundeep Panicker (sec_hash->u.sec_obj->section.offset +
8526bbe0590SSundeep Panicker sec_hash->u.sec_obj->section.length)) {
8536bbe0590SSundeep Panicker return (-1);
8546bbe0590SSundeep Panicker }
8556bbe0590SSundeep Panicker
8566bbe0590SSundeep Panicker pkt_hash_obj = create_packet_hash_object();
8576bbe0590SSundeep Panicker if (pkt_hash_obj == NULL) {
8586bbe0590SSundeep Panicker return (-1);
8596bbe0590SSundeep Panicker }
8606bbe0590SSundeep Panicker
8616bbe0590SSundeep Panicker pkt_hash_obj->u.pkt_obj->payload = malloc(paylen);
8626bbe0590SSundeep Panicker if (pkt_hash_obj->u.pkt_obj->payload == NULL) {
8636bbe0590SSundeep Panicker free(pkt_hash_obj);
8646bbe0590SSundeep Panicker return (-1);
8656bbe0590SSundeep Panicker }
8666bbe0590SSundeep Panicker
8676bbe0590SSundeep Panicker offset += tag_size;
8686bbe0590SSundeep Panicker
8696bbe0590SSundeep Panicker retval = raw_memcpy(pkt_hash_obj->u.pkt_obj->payload, rawlist,
8706bbe0590SSundeep Panicker offset, paylen);
8716bbe0590SSundeep Panicker
8726bbe0590SSundeep Panicker if (retval != paylen) {
8736bbe0590SSundeep Panicker free(pkt_hash_obj->u.pkt_obj->payload);
8746bbe0590SSundeep Panicker free(pkt_hash_obj);
8756bbe0590SSundeep Panicker return (-1);
8766bbe0590SSundeep Panicker }
8776bbe0590SSundeep Panicker
8786bbe0590SSundeep Panicker /* don't change this */
8796bbe0590SSundeep Panicker pkt_hash_obj->u.pkt_obj->tag.raw_data = 0;
8806bbe0590SSundeep Panicker (void) memcpy(&pkt_hash_obj->u.pkt_obj->tag, &tag, tag_size);
8816bbe0590SSundeep Panicker pkt_hash_obj->u.pkt_obj->paylen = paylen;
8826bbe0590SSundeep Panicker pkt_hash_obj->u.pkt_obj->tag_size = tag_size;
8836bbe0590SSundeep Panicker pkt_hash_obj->u.pkt_obj->payload_offset = offset;
8846bbe0590SSundeep Panicker
8856bbe0590SSundeep Panicker offset += paylen;
8866bbe0590SSundeep Panicker
8876bbe0590SSundeep Panicker add_hashobject_to_hashtable(pkt_hash_obj);
8886bbe0590SSundeep Panicker add_to_pkt_object_list(seg_hash, pkt_hash_obj);
8896bbe0590SSundeep Panicker
8906bbe0590SSundeep Panicker pktcnt++;
8916bbe0590SSundeep Panicker
8926bbe0590SSundeep Panicker retval = get_packet(rawlist, &tag, sizeof (fru_tag_t),
8936bbe0590SSundeep Panicker offset);
8946bbe0590SSundeep Panicker if (retval == -1) {
8956bbe0590SSundeep Panicker return (retval);
8966bbe0590SSundeep Panicker }
8976bbe0590SSundeep Panicker
8986bbe0590SSundeep Panicker data = (char *)&tag;
8996bbe0590SSundeep Panicker }
9006bbe0590SSundeep Panicker
9016bbe0590SSundeep Panicker segdesc = (fru_segdesc_t *)&seg_hash->u.seg_obj->segment.descriptor;
9026bbe0590SSundeep Panicker
9036bbe0590SSundeep Panicker seg_hash->u.seg_obj->trailer_offset = offset;
9046bbe0590SSundeep Panicker
9056bbe0590SSundeep Panicker if (!segdesc->field.ignore_checksum) {
9066bbe0590SSundeep Panicker crc = get_checksum_crc(seg_hash, seg_limit);
9076bbe0590SSundeep Panicker offset = seg_hash->u.seg_obj->segment.offset;
9086bbe0590SSundeep Panicker
9096bbe0590SSundeep Panicker retval = raw_memcpy(&origcrc, rawlist, offset + seg_limit + 1,
9106bbe0590SSundeep Panicker sizeof (origcrc));
9116bbe0590SSundeep Panicker
9126bbe0590SSundeep Panicker ignore_flag = getenv(IGNORE_CHECK);
9136bbe0590SSundeep Panicker if (ignore_flag != NULL) {
9146bbe0590SSundeep Panicker return (pktcnt);
9156bbe0590SSundeep Panicker }
9166bbe0590SSundeep Panicker
9176bbe0590SSundeep Panicker if (retval != sizeof (origcrc)) {
9186bbe0590SSundeep Panicker return (-1);
9196bbe0590SSundeep Panicker }
9206bbe0590SSundeep Panicker
9216bbe0590SSundeep Panicker origcrc = BE_32(origcrc);
9226bbe0590SSundeep Panicker if (origcrc != crc) {
9236bbe0590SSundeep Panicker seg_hash->u.seg_obj->trailer_offset = offset;
9246bbe0590SSundeep Panicker return (-1);
9256bbe0590SSundeep Panicker }
9266bbe0590SSundeep Panicker }
9276bbe0590SSundeep Panicker
9286bbe0590SSundeep Panicker return (pktcnt);
9296bbe0590SSundeep Panicker }
9306bbe0590SSundeep Panicker
9316bbe0590SSundeep Panicker /* ARGSUSED */
9326bbe0590SSundeep Panicker int
fru_get_num_sections(container_hdl_t container,door_cred_t * cred)9336bbe0590SSundeep Panicker fru_get_num_sections(container_hdl_t container, door_cred_t *cred)
9346bbe0590SSundeep Panicker {
9356bbe0590SSundeep Panicker hash_obj_t *hash_object;
9366bbe0590SSundeep Panicker
9376bbe0590SSundeep Panicker hash_object = lookup_handle_object(container, CONTAINER_TYPE);
9386bbe0590SSundeep Panicker if (hash_object == NULL) {
9396bbe0590SSundeep Panicker return (-1);
9406bbe0590SSundeep Panicker }
9416bbe0590SSundeep Panicker
9426bbe0590SSundeep Panicker return (hash_object->u.cont_obj->num_of_section);
9436bbe0590SSundeep Panicker }
9446bbe0590SSundeep Panicker
9456bbe0590SSundeep Panicker /* ARGSUSED */
9466bbe0590SSundeep Panicker int
fru_get_num_segments(section_hdl_t section,door_cred_t * cred)9476bbe0590SSundeep Panicker fru_get_num_segments(section_hdl_t section, door_cred_t *cred)
9486bbe0590SSundeep Panicker {
9496bbe0590SSundeep Panicker hash_obj_t *sec_object;
9506bbe0590SSundeep Panicker section_obj_t *sec_obj;
9516bbe0590SSundeep Panicker
9526bbe0590SSundeep Panicker sec_object = lookup_handle_object(section, SECTION_TYPE);
9536bbe0590SSundeep Panicker if (sec_object == NULL) {
9546bbe0590SSundeep Panicker return (-1);
9556bbe0590SSundeep Panicker }
9566bbe0590SSundeep Panicker
9576bbe0590SSundeep Panicker sec_obj = sec_object->u.sec_obj;
9586bbe0590SSundeep Panicker if (sec_obj == NULL) {
9596bbe0590SSundeep Panicker return (-1);
9606bbe0590SSundeep Panicker }
9616bbe0590SSundeep Panicker
9626bbe0590SSundeep Panicker return (sec_obj->num_of_segment);
9636bbe0590SSundeep Panicker }
9646bbe0590SSundeep Panicker
9656bbe0590SSundeep Panicker /* ARGSUSED */
9666bbe0590SSundeep Panicker int
fru_get_num_packets(segment_hdl_t segment,door_cred_t * cred)9676bbe0590SSundeep Panicker fru_get_num_packets(segment_hdl_t segment, door_cred_t *cred)
9686bbe0590SSundeep Panicker {
9696bbe0590SSundeep Panicker int pktcnt;
9706bbe0590SSundeep Panicker int length;
9716bbe0590SSundeep Panicker uint16_t offset;
9726bbe0590SSundeep Panicker hash_obj_t *cont_hash_obj;
9736bbe0590SSundeep Panicker hash_obj_t *seg_hash;
9746bbe0590SSundeep Panicker hash_obj_t *sec_hash;
9756bbe0590SSundeep Panicker fru_segdesc_t *segdesc;
9766bbe0590SSundeep Panicker segment_obj_t *segment_object;
9776bbe0590SSundeep Panicker
9786bbe0590SSundeep Panicker seg_hash = lookup_handle_object(segment, SEGMENT_TYPE);
9796bbe0590SSundeep Panicker if (seg_hash == NULL) {
9806bbe0590SSundeep Panicker return (-1);
9816bbe0590SSundeep Panicker }
9826bbe0590SSundeep Panicker
9836bbe0590SSundeep Panicker segment_object = seg_hash->u.seg_obj;
9846bbe0590SSundeep Panicker if (segment_object == NULL) {
9856bbe0590SSundeep Panicker return (-1);
9866bbe0590SSundeep Panicker }
9876bbe0590SSundeep Panicker
9886bbe0590SSundeep Panicker segdesc = (fru_segdesc_t *)&segment_object->segment.descriptor;
9896bbe0590SSundeep Panicker if (segdesc->field.opaque) {
9906bbe0590SSundeep Panicker return (0);
9916bbe0590SSundeep Panicker }
9926bbe0590SSundeep Panicker
9936bbe0590SSundeep Panicker offset = segment_object->segment.offset;
9946bbe0590SSundeep Panicker length = segment_object->segment.length;
9956bbe0590SSundeep Panicker
9966bbe0590SSundeep Panicker cont_hash_obj = get_container_hash_object(SEGMENT_TYPE,
9976bbe0590SSundeep Panicker segment_object->section_hdl);
9986bbe0590SSundeep Panicker
9996bbe0590SSundeep Panicker if (cont_hash_obj == NULL) {
10006bbe0590SSundeep Panicker return (-1);
10016bbe0590SSundeep Panicker }
10026bbe0590SSundeep Panicker
10036bbe0590SSundeep Panicker if (seg_hash->u.seg_obj->pkt_obj_list != NULL) {
10046bbe0590SSundeep Panicker return (segment_object->num_of_packets);
10056bbe0590SSundeep Panicker }
10066bbe0590SSundeep Panicker /* section hash object */
10076bbe0590SSundeep Panicker sec_hash = lookup_handle_object(seg_hash->u.seg_obj->section_hdl,
10086bbe0590SSundeep Panicker SECTION_TYPE);
10096bbe0590SSundeep Panicker if (sec_hash == NULL) {
10106bbe0590SSundeep Panicker return (-1);
10116bbe0590SSundeep Panicker }
10126bbe0590SSundeep Panicker
10136bbe0590SSundeep Panicker /* valid segment header b'cos crc8 already validated */
10146bbe0590SSundeep Panicker if (offset < sec_hash->u.sec_obj->section.offset) {
10156bbe0590SSundeep Panicker return (-1);
10166bbe0590SSundeep Panicker }
10176bbe0590SSundeep Panicker
10186bbe0590SSundeep Panicker segment_object->num_of_packets = 0;
10196bbe0590SSundeep Panicker
10206bbe0590SSundeep Panicker pktcnt = get_packets(seg_hash, g_raw, offset, length);
10216bbe0590SSundeep Panicker if (pktcnt == -1) {
10226bbe0590SSundeep Panicker free_pkt_object_list(seg_hash);
10236bbe0590SSundeep Panicker seg_hash->u.seg_obj->pkt_obj_list = NULL;
10246bbe0590SSundeep Panicker }
10256bbe0590SSundeep Panicker
10266bbe0590SSundeep Panicker segment_object->num_of_packets = pktcnt;
10276bbe0590SSundeep Panicker
10286bbe0590SSundeep Panicker return (segment_object->num_of_packets);
10296bbe0590SSundeep Panicker }
10306bbe0590SSundeep Panicker
10316bbe0590SSundeep Panicker /* ARGSUSED */
10326bbe0590SSundeep Panicker int
fru_get_packets(segment_hdl_t segment,packet_t * packet,int maxpackets,door_cred_t * cred)10336bbe0590SSundeep Panicker fru_get_packets(segment_hdl_t segment, packet_t *packet, int maxpackets,
10346bbe0590SSundeep Panicker door_cred_t *cred)
10356bbe0590SSundeep Panicker {
10366bbe0590SSundeep Panicker int count;
10376bbe0590SSundeep Panicker hash_obj_t *seg_hash_obj;
10386bbe0590SSundeep Panicker hash_obj_t *pkt_hash_obj;
10396bbe0590SSundeep Panicker
10406bbe0590SSundeep Panicker /* segment hash object */
10416bbe0590SSundeep Panicker seg_hash_obj = lookup_handle_object(segment, SEGMENT_TYPE);
10426bbe0590SSundeep Panicker if (seg_hash_obj == NULL) {
10436bbe0590SSundeep Panicker return (-1);
10446bbe0590SSundeep Panicker }
10456bbe0590SSundeep Panicker
10466bbe0590SSundeep Panicker if (seg_hash_obj->u.seg_obj->num_of_packets != maxpackets) {
10476bbe0590SSundeep Panicker return (-1);
10486bbe0590SSundeep Panicker }
10496bbe0590SSundeep Panicker
10506bbe0590SSundeep Panicker pkt_hash_obj = seg_hash_obj->u.seg_obj->pkt_obj_list;
10516bbe0590SSundeep Panicker if (pkt_hash_obj == NULL) {
10526bbe0590SSundeep Panicker return (-1);
10536bbe0590SSundeep Panicker }
10546bbe0590SSundeep Panicker
10556bbe0590SSundeep Panicker for (count = 0; count < maxpackets; count++, packet++) {
10566bbe0590SSundeep Panicker packet->handle = pkt_hash_obj->obj_hdl;
10576bbe0590SSundeep Panicker packet->tag = 0;
10586bbe0590SSundeep Panicker (void) memcpy(&packet->tag, &pkt_hash_obj->u.pkt_obj->tag,
10596bbe0590SSundeep Panicker pkt_hash_obj->u.pkt_obj->tag_size);
10606bbe0590SSundeep Panicker pkt_hash_obj = pkt_hash_obj->u.pkt_obj->next;
10616bbe0590SSundeep Panicker }
10626bbe0590SSundeep Panicker
10636bbe0590SSundeep Panicker return (0);
10646bbe0590SSundeep Panicker }
10656bbe0590SSundeep Panicker
10666bbe0590SSundeep Panicker /* ARGSUSED */
10676bbe0590SSundeep Panicker ssize_t
fru_get_payload(packet_hdl_t packet,void * buffer,size_t nbytes,door_cred_t * cred)10686bbe0590SSundeep Panicker fru_get_payload(packet_hdl_t packet, void *buffer, size_t nbytes,
10696bbe0590SSundeep Panicker door_cred_t *cred)
10706bbe0590SSundeep Panicker {
10716bbe0590SSundeep Panicker hash_obj_t *packet_hash_obj;
10726bbe0590SSundeep Panicker
10736bbe0590SSundeep Panicker /* packet hash object */
10746bbe0590SSundeep Panicker packet_hash_obj = lookup_handle_object(packet, PACKET_TYPE);
10756bbe0590SSundeep Panicker if (packet_hash_obj == NULL) {
10766bbe0590SSundeep Panicker return (-1);
10776bbe0590SSundeep Panicker }
10786bbe0590SSundeep Panicker
10796bbe0590SSundeep Panicker /* verify payload length */
10806bbe0590SSundeep Panicker if (nbytes != packet_hash_obj->u.pkt_obj->paylen) {
10816bbe0590SSundeep Panicker return (-1);
10826bbe0590SSundeep Panicker }
10836bbe0590SSundeep Panicker
10846bbe0590SSundeep Panicker (void) memcpy(buffer, packet_hash_obj->u.pkt_obj->payload, nbytes);
10856bbe0590SSundeep Panicker return (nbytes);
10866bbe0590SSundeep Panicker }
10876bbe0590SSundeep Panicker
10886bbe0590SSundeep Panicker
10896bbe0590SSundeep Panicker container_hdl_t
open_raw_data(raw_list_t * node)10906bbe0590SSundeep Panicker open_raw_data(raw_list_t *node)
10916bbe0590SSundeep Panicker {
10926bbe0590SSundeep Panicker char *cont_conf_file = NULL;
10936bbe0590SSundeep Panicker hash_obj_t *cont_hash_obj;
10946bbe0590SSundeep Panicker hash_obj_t *sec_hash_obj;
10956bbe0590SSundeep Panicker container_info_t cont_info;
10966bbe0590SSundeep Panicker int retval;
10976bbe0590SSundeep Panicker int count;
10986bbe0590SSundeep Panicker
10996bbe0590SSundeep Panicker cont_hash_obj = create_container_hash_object();
11006bbe0590SSundeep Panicker if (cont_hash_obj == NULL) {
11016bbe0590SSundeep Panicker return (NULL);
11026bbe0590SSundeep Panicker }
11036bbe0590SSundeep Panicker
11046bbe0590SSundeep Panicker add_hashobject_to_hashtable(cont_hash_obj);
11056bbe0590SSundeep Panicker
11066bbe0590SSundeep Panicker (void) strncpy(cont_hash_obj->u.cont_obj->device_pathname, "unknown",
11076bbe0590SSundeep Panicker sizeof (cont_hash_obj->u.cont_obj->device_pathname));
11086bbe0590SSundeep Panicker
11096bbe0590SSundeep Panicker cont_conf_file = getenv(FRU_CONT_CONF_ENV_VAR);
11106bbe0590SSundeep Panicker if (cont_conf_file == NULL) {
11116bbe0590SSundeep Panicker cont_conf_file = FRU_CONT_CONF_SPARC;
11126bbe0590SSundeep Panicker retval = get_container_info(cont_conf_file, node->cont_type,
11136bbe0590SSundeep Panicker &cont_info);
11146bbe0590SSundeep Panicker if (retval < 0) {
11156bbe0590SSundeep Panicker cont_conf_file = FRU_CONT_CONF_X86;
11166bbe0590SSundeep Panicker retval = get_container_info(cont_conf_file,
11176bbe0590SSundeep Panicker node->cont_type, &cont_info);
11186bbe0590SSundeep Panicker }
11196bbe0590SSundeep Panicker } else {
11206bbe0590SSundeep Panicker retval = get_container_info(cont_conf_file, node->cont_type,
11216bbe0590SSundeep Panicker &cont_info);
11226bbe0590SSundeep Panicker }
11236bbe0590SSundeep Panicker
11246bbe0590SSundeep Panicker if (retval < 0) {
11256bbe0590SSundeep Panicker return (NULL);
11266bbe0590SSundeep Panicker }
11276bbe0590SSundeep Panicker
11286bbe0590SSundeep Panicker cont_hash_obj->u.cont_obj->num_of_section = cont_info.num_sections;
11296bbe0590SSundeep Panicker cont_hash_obj->u.cont_obj->sec_obj_list = NULL;
11306bbe0590SSundeep Panicker
11316bbe0590SSundeep Panicker for (count = 0; count < cont_info.num_sections; count++) {
11326bbe0590SSundeep Panicker sec_hash_obj = create_section_hash_object();
11336bbe0590SSundeep Panicker if (sec_hash_obj == NULL) {
11346bbe0590SSundeep Panicker return (NULL);
11356bbe0590SSundeep Panicker }
11366bbe0590SSundeep Panicker
11376bbe0590SSundeep Panicker add_hashobject_to_hashtable(sec_hash_obj);
11386bbe0590SSundeep Panicker
11396bbe0590SSundeep Panicker sec_hash_obj->u.sec_obj->section.offset =
11406bbe0590SSundeep Panicker cont_info.section_info[count].address;
11416bbe0590SSundeep Panicker
11426bbe0590SSundeep Panicker sec_hash_obj->u.sec_obj->section.protection =
11436bbe0590SSundeep Panicker cont_info.section_info[count].description.field.read_only;
11446bbe0590SSundeep Panicker
11456bbe0590SSundeep Panicker sec_hash_obj->u.sec_obj->section.length =
11466bbe0590SSundeep Panicker cont_info.section_info[count].size;
11476bbe0590SSundeep Panicker sec_hash_obj->u.sec_obj->section.version =
11486bbe0590SSundeep Panicker cont_info.header_ver;
11496bbe0590SSundeep Panicker
11506bbe0590SSundeep Panicker add_to_sec_object_list(cont_hash_obj, sec_hash_obj);
11516bbe0590SSundeep Panicker }
11526bbe0590SSundeep Panicker
11536bbe0590SSundeep Panicker return (cont_hash_obj->obj_hdl);
11546bbe0590SSundeep Panicker }
11556bbe0590SSundeep Panicker
11566bbe0590SSundeep Panicker
11576bbe0590SSundeep Panicker int
fru_close_container(container_hdl_t container)11586bbe0590SSundeep Panicker fru_close_container(container_hdl_t container)
11596bbe0590SSundeep Panicker {
11606bbe0590SSundeep Panicker hash_obj_t *hash_obj;
11616bbe0590SSundeep Panicker hash_obj_t *prev_hash;
11626bbe0590SSundeep Panicker hash_obj_t *sec_hash_obj;
11636bbe0590SSundeep Panicker handle_t obj_hdl;
11646bbe0590SSundeep Panicker
11656bbe0590SSundeep Panicker /* lookup for container hash object */
11666bbe0590SSundeep Panicker hash_obj = lookup_handle_object(container, CONTAINER_TYPE);
11676bbe0590SSundeep Panicker if (hash_obj == NULL) {
11686bbe0590SSundeep Panicker return (0);
11696bbe0590SSundeep Panicker }
11706bbe0590SSundeep Panicker
11716bbe0590SSundeep Panicker /* points to section object list */
11726bbe0590SSundeep Panicker sec_hash_obj = hash_obj->u.cont_obj->sec_obj_list;
11736bbe0590SSundeep Panicker
11746bbe0590SSundeep Panicker /* traverse section object list */
11756bbe0590SSundeep Panicker while (sec_hash_obj != NULL) {
11766bbe0590SSundeep Panicker
11776bbe0590SSundeep Panicker /* traverse segment hash object in the section */
11786bbe0590SSundeep Panicker while (sec_hash_obj->u.sec_obj->seg_obj_list != NULL) {
11796bbe0590SSundeep Panicker /* object handle of the segment hash object */
11806bbe0590SSundeep Panicker obj_hdl =
11816bbe0590SSundeep Panicker sec_hash_obj->u.sec_obj->seg_obj_list->obj_hdl;
11826bbe0590SSundeep Panicker free_segment_hash(obj_hdl, sec_hash_obj);
11836bbe0590SSundeep Panicker }
11846bbe0590SSundeep Panicker
11856bbe0590SSundeep Panicker /* going to free section hash object, relink the hash object */
11866bbe0590SSundeep Panicker if (sec_hash_obj->prev == NULL) {
11876bbe0590SSundeep Panicker hash_table[(sec_hash_obj->obj_hdl % TABLE_SIZE)] =
11886bbe0590SSundeep Panicker sec_hash_obj->next;
11896bbe0590SSundeep Panicker if (sec_hash_obj->next != NULL) {
11906bbe0590SSundeep Panicker sec_hash_obj->next->prev = NULL;
11916bbe0590SSundeep Panicker }
11926bbe0590SSundeep Panicker } else {
11936bbe0590SSundeep Panicker sec_hash_obj->prev->next = sec_hash_obj->next;
11946bbe0590SSundeep Panicker if (sec_hash_obj->next != NULL) {
11956bbe0590SSundeep Panicker sec_hash_obj->next->prev = sec_hash_obj->prev;
11966bbe0590SSundeep Panicker }
11976bbe0590SSundeep Panicker }
11986bbe0590SSundeep Panicker
11996bbe0590SSundeep Panicker prev_hash = sec_hash_obj;
12006bbe0590SSundeep Panicker sec_hash_obj = sec_hash_obj->u.sec_obj->next;
12016bbe0590SSundeep Panicker
1202*ac88567aSHyon Kim free(prev_hash->u.sec_obj); /* free section hash object */
12036bbe0590SSundeep Panicker free(prev_hash); /* free section hash */
12046bbe0590SSundeep Panicker }
12056bbe0590SSundeep Panicker
12066bbe0590SSundeep Panicker /* free container hash object */
12076bbe0590SSundeep Panicker if (hash_obj->prev == NULL) {
12086bbe0590SSundeep Panicker hash_table[(hash_obj->obj_hdl % TABLE_SIZE)] =
12096bbe0590SSundeep Panicker hash_obj->next;
12106bbe0590SSundeep Panicker if (hash_obj->next != NULL) {
12116bbe0590SSundeep Panicker hash_obj->next->prev = NULL;
12126bbe0590SSundeep Panicker }
12136bbe0590SSundeep Panicker } else {
12146bbe0590SSundeep Panicker hash_obj->prev->next = hash_obj->next;
12156bbe0590SSundeep Panicker if (hash_obj->next != NULL) {
12166bbe0590SSundeep Panicker hash_obj->next->prev = hash_obj->prev;
12176bbe0590SSundeep Panicker }
12186bbe0590SSundeep Panicker }
12196bbe0590SSundeep Panicker
12206bbe0590SSundeep Panicker free(hash_obj->u.cont_obj);
12216bbe0590SSundeep Panicker free(hash_obj);
12226bbe0590SSundeep Panicker
12236bbe0590SSundeep Panicker return (0);
12246bbe0590SSundeep Panicker }
1225