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 /* 23ac88567aSHyon 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 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 * 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 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 * 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 * 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 * 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 * 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 * 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 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 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 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 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 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 * 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 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 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); 436*a356818eSToomas Soome if (token != NULL) { 4376bbe0590SSundeep Panicker token = tokenizer(token, "|", &item, &matched); 438*a356818eSToomas Soome while (token != NULL) { 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 */ 446*a356818eSToomas Soome if ((item != NULL) && 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); 457*a356818eSToomas Soome if (token == NULL) { 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); 464*a356818eSToomas Soome while (token != NULL) { 4656bbe0590SSundeep Panicker token = tokenizer(token, ",", &item, &matched); 466*a356818eSToomas Soome if (token == NULL) { 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); 484*a356818eSToomas Soome if (token == NULL) { 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); 491*a356818eSToomas Soome if (item == NULL) { 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 1202ac88567aSHyon 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