111015SSundeep.Panicker@Sun.COM /*
211015SSundeep.Panicker@Sun.COM * CDDL HEADER START
311015SSundeep.Panicker@Sun.COM *
411015SSundeep.Panicker@Sun.COM * The contents of this file are subject to the terms of the
511015SSundeep.Panicker@Sun.COM * Common Development and Distribution License (the "License").
611015SSundeep.Panicker@Sun.COM * You may not use this file except in compliance with the License.
711015SSundeep.Panicker@Sun.COM *
811015SSundeep.Panicker@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911015SSundeep.Panicker@Sun.COM * or http://www.opensolaris.org/os/licensing.
1011015SSundeep.Panicker@Sun.COM * See the License for the specific language governing permissions
1111015SSundeep.Panicker@Sun.COM * and limitations under the License.
1211015SSundeep.Panicker@Sun.COM *
1311015SSundeep.Panicker@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
1411015SSundeep.Panicker@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1511015SSundeep.Panicker@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
1611015SSundeep.Panicker@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
1711015SSundeep.Panicker@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
1811015SSundeep.Panicker@Sun.COM *
1911015SSundeep.Panicker@Sun.COM * CDDL HEADER END
2011015SSundeep.Panicker@Sun.COM */
2111015SSundeep.Panicker@Sun.COM
2211015SSundeep.Panicker@Sun.COM /*
23*12126SHyon.Kim@Sun.COM * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2411015SSundeep.Panicker@Sun.COM */
2511015SSundeep.Panicker@Sun.COM
2611015SSundeep.Panicker@Sun.COM #include <stdio.h>
2711015SSundeep.Panicker@Sun.COM #include <stdlib.h>
2811015SSundeep.Panicker@Sun.COM #include <alloca.h>
2911015SSundeep.Panicker@Sun.COM #include <sys/byteorder.h>
3011015SSundeep.Panicker@Sun.COM #include "fru_access_impl.h"
3111015SSundeep.Panicker@Sun.COM #include "fruraw.h"
3211015SSundeep.Panicker@Sun.COM
3311015SSundeep.Panicker@Sun.COM #pragma init(initialize_raw_access)
3411015SSundeep.Panicker@Sun.COM
3511015SSundeep.Panicker@Sun.COM static hash_obj_t *hash_table[TABLE_SIZE];
3611015SSundeep.Panicker@Sun.COM extern raw_list_t *g_raw;
3711015SSundeep.Panicker@Sun.COM
3811015SSundeep.Panicker@Sun.COM static void
initialize_raw_access(void)3911015SSundeep.Panicker@Sun.COM initialize_raw_access(void)
4011015SSundeep.Panicker@Sun.COM {
4111015SSundeep.Panicker@Sun.COM int count;
4211015SSundeep.Panicker@Sun.COM
4311015SSundeep.Panicker@Sun.COM for (count = 0; count < TABLE_SIZE; count++) {
4411015SSundeep.Panicker@Sun.COM hash_table[count] = NULL;
4511015SSundeep.Panicker@Sun.COM }
4611015SSundeep.Panicker@Sun.COM }
4711015SSundeep.Panicker@Sun.COM
4811015SSundeep.Panicker@Sun.COM
4911015SSundeep.Panicker@Sun.COM static hash_obj_t *
lookup_handle_object(handle_t handle,int object_type)5011015SSundeep.Panicker@Sun.COM lookup_handle_object(handle_t handle, int object_type)
5111015SSundeep.Panicker@Sun.COM {
5211015SSundeep.Panicker@Sun.COM handle_t index_to_hash;
5311015SSundeep.Panicker@Sun.COM hash_obj_t *first_hash_obj;
5411015SSundeep.Panicker@Sun.COM hash_obj_t *next_hash_obj;
5511015SSundeep.Panicker@Sun.COM
5611015SSundeep.Panicker@Sun.COM index_to_hash = (handle % TABLE_SIZE);
5711015SSundeep.Panicker@Sun.COM
5811015SSundeep.Panicker@Sun.COM first_hash_obj = hash_table[index_to_hash];
5911015SSundeep.Panicker@Sun.COM for (next_hash_obj = first_hash_obj; next_hash_obj != NULL;
6011015SSundeep.Panicker@Sun.COM next_hash_obj = next_hash_obj->next) {
6111015SSundeep.Panicker@Sun.COM if ((handle == next_hash_obj->obj_hdl) &&
6211015SSundeep.Panicker@Sun.COM (object_type == next_hash_obj->object_type)) {
6311015SSundeep.Panicker@Sun.COM return (next_hash_obj);
6411015SSundeep.Panicker@Sun.COM }
6511015SSundeep.Panicker@Sun.COM }
6611015SSundeep.Panicker@Sun.COM return (NULL);
6711015SSundeep.Panicker@Sun.COM }
6811015SSundeep.Panicker@Sun.COM
6911015SSundeep.Panicker@Sun.COM
7011015SSundeep.Panicker@Sun.COM static void
add_hashobject_to_hashtable(hash_obj_t * hash_obj)7111015SSundeep.Panicker@Sun.COM add_hashobject_to_hashtable(hash_obj_t *hash_obj)
7211015SSundeep.Panicker@Sun.COM {
7311015SSundeep.Panicker@Sun.COM handle_t index_to_hash;
7411015SSundeep.Panicker@Sun.COM static uint64_t handle_count = 0;
7511015SSundeep.Panicker@Sun.COM
7611015SSundeep.Panicker@Sun.COM hash_obj->obj_hdl = ++handle_count; /* store the handle */
7711015SSundeep.Panicker@Sun.COM
7811015SSundeep.Panicker@Sun.COM /* where to add ? */
7911015SSundeep.Panicker@Sun.COM index_to_hash = ((hash_obj->obj_hdl) % TABLE_SIZE);
8011015SSundeep.Panicker@Sun.COM
8111015SSundeep.Panicker@Sun.COM hash_obj->next = hash_table[index_to_hash];
8211015SSundeep.Panicker@Sun.COM hash_table[index_to_hash] = hash_obj; /* hash obj. added */
8311015SSundeep.Panicker@Sun.COM
8411015SSundeep.Panicker@Sun.COM if (hash_obj->next != NULL) {
8511015SSundeep.Panicker@Sun.COM hash_obj->next->prev = hash_obj;
8611015SSundeep.Panicker@Sun.COM }
8711015SSundeep.Panicker@Sun.COM }
8811015SSundeep.Panicker@Sun.COM
8911015SSundeep.Panicker@Sun.COM
9011015SSundeep.Panicker@Sun.COM static hash_obj_t *
create_container_hash_object(void)9111015SSundeep.Panicker@Sun.COM create_container_hash_object(void)
9211015SSundeep.Panicker@Sun.COM {
9311015SSundeep.Panicker@Sun.COM hash_obj_t *hash_obj;
9411015SSundeep.Panicker@Sun.COM container_obj_t *cont_obj;
9511015SSundeep.Panicker@Sun.COM
9611015SSundeep.Panicker@Sun.COM cont_obj = malloc(sizeof (container_obj_t));
9711015SSundeep.Panicker@Sun.COM if (cont_obj == NULL) {
9811015SSundeep.Panicker@Sun.COM return (NULL);
9911015SSundeep.Panicker@Sun.COM }
10011015SSundeep.Panicker@Sun.COM
10111015SSundeep.Panicker@Sun.COM hash_obj = malloc(sizeof (hash_obj_t));
10211015SSundeep.Panicker@Sun.COM if (hash_obj == NULL) {
10311015SSundeep.Panicker@Sun.COM free(cont_obj);
10411015SSundeep.Panicker@Sun.COM return (NULL);
10511015SSundeep.Panicker@Sun.COM }
10611015SSundeep.Panicker@Sun.COM
10711015SSundeep.Panicker@Sun.COM cont_obj->sec_obj_list = NULL;
10811015SSundeep.Panicker@Sun.COM
10911015SSundeep.Panicker@Sun.COM hash_obj->object_type = CONTAINER_TYPE;
11011015SSundeep.Panicker@Sun.COM hash_obj->u.cont_obj = cont_obj;
11111015SSundeep.Panicker@Sun.COM hash_obj->next = NULL;
11211015SSundeep.Panicker@Sun.COM hash_obj->prev = NULL;
11311015SSundeep.Panicker@Sun.COM
11411015SSundeep.Panicker@Sun.COM return (hash_obj);
11511015SSundeep.Panicker@Sun.COM }
11611015SSundeep.Panicker@Sun.COM
11711015SSundeep.Panicker@Sun.COM
11811015SSundeep.Panicker@Sun.COM static hash_obj_t *
create_section_hash_object(void)11911015SSundeep.Panicker@Sun.COM create_section_hash_object(void)
12011015SSundeep.Panicker@Sun.COM {
12111015SSundeep.Panicker@Sun.COM hash_obj_t *hash_obj;
12211015SSundeep.Panicker@Sun.COM section_obj_t *sec_obj;
12311015SSundeep.Panicker@Sun.COM
12411015SSundeep.Panicker@Sun.COM sec_obj = malloc(sizeof (section_obj_t));
12511015SSundeep.Panicker@Sun.COM if (sec_obj == NULL) {
12611015SSundeep.Panicker@Sun.COM return (NULL);
12711015SSundeep.Panicker@Sun.COM }
12811015SSundeep.Panicker@Sun.COM
12911015SSundeep.Panicker@Sun.COM hash_obj = malloc(sizeof (hash_obj_t));
13011015SSundeep.Panicker@Sun.COM if (hash_obj == NULL) {
13111015SSundeep.Panicker@Sun.COM free(sec_obj);
13211015SSundeep.Panicker@Sun.COM return (NULL);
13311015SSundeep.Panicker@Sun.COM }
13411015SSundeep.Panicker@Sun.COM
13511015SSundeep.Panicker@Sun.COM sec_obj->next = NULL;
13611015SSundeep.Panicker@Sun.COM sec_obj->seg_obj_list = NULL;
13711015SSundeep.Panicker@Sun.COM
13811015SSundeep.Panicker@Sun.COM hash_obj->u.sec_obj = sec_obj;
13911015SSundeep.Panicker@Sun.COM hash_obj->object_type = SECTION_TYPE;
14011015SSundeep.Panicker@Sun.COM hash_obj->next = NULL;
14111015SSundeep.Panicker@Sun.COM hash_obj->prev = NULL;
14211015SSundeep.Panicker@Sun.COM
14311015SSundeep.Panicker@Sun.COM return (hash_obj);
14411015SSundeep.Panicker@Sun.COM }
14511015SSundeep.Panicker@Sun.COM
14611015SSundeep.Panicker@Sun.COM
14711015SSundeep.Panicker@Sun.COM static hash_obj_t *
create_segment_hash_object(void)14811015SSundeep.Panicker@Sun.COM create_segment_hash_object(void)
14911015SSundeep.Panicker@Sun.COM {
15011015SSundeep.Panicker@Sun.COM hash_obj_t *hash_obj;
15111015SSundeep.Panicker@Sun.COM segment_obj_t *seg_obj;
15211015SSundeep.Panicker@Sun.COM
15311015SSundeep.Panicker@Sun.COM seg_obj = malloc(sizeof (segment_obj_t));
15411015SSundeep.Panicker@Sun.COM if (seg_obj == NULL) {
15511015SSundeep.Panicker@Sun.COM return (NULL);
15611015SSundeep.Panicker@Sun.COM }
15711015SSundeep.Panicker@Sun.COM
15811015SSundeep.Panicker@Sun.COM hash_obj = malloc(sizeof (hash_obj_t));
15911015SSundeep.Panicker@Sun.COM if (hash_obj == NULL) {
16011015SSundeep.Panicker@Sun.COM free(seg_obj);
16111015SSundeep.Panicker@Sun.COM return (NULL);
16211015SSundeep.Panicker@Sun.COM }
16311015SSundeep.Panicker@Sun.COM
16411015SSundeep.Panicker@Sun.COM seg_obj->next = NULL;
16511015SSundeep.Panicker@Sun.COM seg_obj->pkt_obj_list = NULL;
16611015SSundeep.Panicker@Sun.COM
16711015SSundeep.Panicker@Sun.COM hash_obj->object_type = SEGMENT_TYPE;
16811015SSundeep.Panicker@Sun.COM hash_obj->u.seg_obj = seg_obj;
16911015SSundeep.Panicker@Sun.COM hash_obj->next = NULL;
17011015SSundeep.Panicker@Sun.COM hash_obj->prev = NULL;
17111015SSundeep.Panicker@Sun.COM
17211015SSundeep.Panicker@Sun.COM return (hash_obj);
17311015SSundeep.Panicker@Sun.COM }
17411015SSundeep.Panicker@Sun.COM
17511015SSundeep.Panicker@Sun.COM
17611015SSundeep.Panicker@Sun.COM static hash_obj_t *
create_packet_hash_object(void)17711015SSundeep.Panicker@Sun.COM create_packet_hash_object(void)
17811015SSundeep.Panicker@Sun.COM {
17911015SSundeep.Panicker@Sun.COM hash_obj_t *hash_obj;
18011015SSundeep.Panicker@Sun.COM packet_obj_t *pkt_obj;
18111015SSundeep.Panicker@Sun.COM
18211015SSundeep.Panicker@Sun.COM pkt_obj = malloc(sizeof (packet_obj_t));
18311015SSundeep.Panicker@Sun.COM if (pkt_obj == NULL) {
18411015SSundeep.Panicker@Sun.COM return (NULL);
18511015SSundeep.Panicker@Sun.COM }
18611015SSundeep.Panicker@Sun.COM
18711015SSundeep.Panicker@Sun.COM hash_obj = malloc(sizeof (hash_obj_t));
18811015SSundeep.Panicker@Sun.COM if (hash_obj == NULL) {
18911015SSundeep.Panicker@Sun.COM free(pkt_obj);
19011015SSundeep.Panicker@Sun.COM return (NULL);
19111015SSundeep.Panicker@Sun.COM }
19211015SSundeep.Panicker@Sun.COM
19311015SSundeep.Panicker@Sun.COM pkt_obj->next = NULL;
19411015SSundeep.Panicker@Sun.COM
19511015SSundeep.Panicker@Sun.COM hash_obj->object_type = PACKET_TYPE;
19611015SSundeep.Panicker@Sun.COM hash_obj->u.pkt_obj = pkt_obj;
19711015SSundeep.Panicker@Sun.COM hash_obj->next = NULL;
19811015SSundeep.Panicker@Sun.COM hash_obj->prev = NULL;
19911015SSundeep.Panicker@Sun.COM
20011015SSundeep.Panicker@Sun.COM return (hash_obj);
20111015SSundeep.Panicker@Sun.COM }
20211015SSundeep.Panicker@Sun.COM
20311015SSundeep.Panicker@Sun.COM
20411015SSundeep.Panicker@Sun.COM
20511015SSundeep.Panicker@Sun.COM static hash_obj_t *
get_container_hash_object(int object_type,handle_t handle)20611015SSundeep.Panicker@Sun.COM get_container_hash_object(int object_type, handle_t handle)
20711015SSundeep.Panicker@Sun.COM {
20811015SSundeep.Panicker@Sun.COM hash_obj_t *hash_obj;
20911015SSundeep.Panicker@Sun.COM
21011015SSundeep.Panicker@Sun.COM switch (object_type) {
21111015SSundeep.Panicker@Sun.COM case CONTAINER_TYPE:
21211015SSundeep.Panicker@Sun.COM break;
21311015SSundeep.Panicker@Sun.COM case SECTION_TYPE:
21411015SSundeep.Panicker@Sun.COM hash_obj = lookup_handle_object(handle, CONTAINER_TYPE);
21511015SSundeep.Panicker@Sun.COM if (hash_obj == NULL) {
21611015SSundeep.Panicker@Sun.COM return (NULL);
21711015SSundeep.Panicker@Sun.COM }
21811015SSundeep.Panicker@Sun.COM break;
21911015SSundeep.Panicker@Sun.COM case SEGMENT_TYPE:
22011015SSundeep.Panicker@Sun.COM hash_obj = lookup_handle_object(handle, SECTION_TYPE);
22111015SSundeep.Panicker@Sun.COM if (hash_obj == NULL) {
22211015SSundeep.Panicker@Sun.COM return (NULL);
22311015SSundeep.Panicker@Sun.COM }
22411015SSundeep.Panicker@Sun.COM hash_obj = lookup_handle_object(hash_obj->u.sec_obj->cont_hdl,
22511015SSundeep.Panicker@Sun.COM CONTAINER_TYPE);
22611015SSundeep.Panicker@Sun.COM break;
22711015SSundeep.Panicker@Sun.COM case PACKET_TYPE:
22811015SSundeep.Panicker@Sun.COM break;
22911015SSundeep.Panicker@Sun.COM default:
23011015SSundeep.Panicker@Sun.COM return (NULL);
23111015SSundeep.Panicker@Sun.COM }
23211015SSundeep.Panicker@Sun.COM
23311015SSundeep.Panicker@Sun.COM return (hash_obj);
23411015SSundeep.Panicker@Sun.COM }
23511015SSundeep.Panicker@Sun.COM
23611015SSundeep.Panicker@Sun.COM
23711015SSundeep.Panicker@Sun.COM static void
add_to_pkt_object_list(hash_obj_t * parent_obj,hash_obj_t * child_obj)23811015SSundeep.Panicker@Sun.COM add_to_pkt_object_list(hash_obj_t *parent_obj, hash_obj_t *child_obj)
23911015SSundeep.Panicker@Sun.COM {
24011015SSundeep.Panicker@Sun.COM hash_obj_t *next_hash;
24111015SSundeep.Panicker@Sun.COM
24211015SSundeep.Panicker@Sun.COM /* add the packet object in the end of list */
24311015SSundeep.Panicker@Sun.COM child_obj->u.pkt_obj->segment_hdl = parent_obj->obj_hdl;
24411015SSundeep.Panicker@Sun.COM
24511015SSundeep.Panicker@Sun.COM if (parent_obj->u.seg_obj->pkt_obj_list == NULL) {
24611015SSundeep.Panicker@Sun.COM parent_obj->u.seg_obj->pkt_obj_list = child_obj;
24711015SSundeep.Panicker@Sun.COM return;
24811015SSundeep.Panicker@Sun.COM }
24911015SSundeep.Panicker@Sun.COM
25011015SSundeep.Panicker@Sun.COM for (next_hash = parent_obj->u.seg_obj->pkt_obj_list;
25111015SSundeep.Panicker@Sun.COM next_hash->u.pkt_obj->next != NULL;
25211015SSundeep.Panicker@Sun.COM next_hash = next_hash->u.pkt_obj->next) {
25311015SSundeep.Panicker@Sun.COM ;
25411015SSundeep.Panicker@Sun.COM }
25511015SSundeep.Panicker@Sun.COM
25611015SSundeep.Panicker@Sun.COM next_hash->u.pkt_obj->next = child_obj;
25711015SSundeep.Panicker@Sun.COM }
25811015SSundeep.Panicker@Sun.COM
25911015SSundeep.Panicker@Sun.COM
26011015SSundeep.Panicker@Sun.COM static void
free_pkt_object_list(hash_obj_t * hash_obj)26111015SSundeep.Panicker@Sun.COM free_pkt_object_list(hash_obj_t *hash_obj)
26211015SSundeep.Panicker@Sun.COM {
26311015SSundeep.Panicker@Sun.COM hash_obj_t *next_obj;
26411015SSundeep.Panicker@Sun.COM hash_obj_t *free_obj;
26511015SSundeep.Panicker@Sun.COM
26611015SSundeep.Panicker@Sun.COM next_obj = hash_obj->u.seg_obj->pkt_obj_list;
26711015SSundeep.Panicker@Sun.COM while (next_obj != NULL) {
26811015SSundeep.Panicker@Sun.COM free_obj = next_obj;
26911015SSundeep.Panicker@Sun.COM next_obj = next_obj->u.pkt_obj->next;
27011015SSundeep.Panicker@Sun.COM /* if prev is NULL it's the first object in the list */
27111015SSundeep.Panicker@Sun.COM if (free_obj->prev == NULL) {
27211015SSundeep.Panicker@Sun.COM hash_table[(free_obj->obj_hdl % TABLE_SIZE)] =
27311015SSundeep.Panicker@Sun.COM free_obj->next;
27411015SSundeep.Panicker@Sun.COM if (free_obj->next != NULL) {
27511015SSundeep.Panicker@Sun.COM free_obj->next->prev = free_obj->prev;
27611015SSundeep.Panicker@Sun.COM }
27711015SSundeep.Panicker@Sun.COM } else {
27811015SSundeep.Panicker@Sun.COM free_obj->prev->next = free_obj->next;
27911015SSundeep.Panicker@Sun.COM if (free_obj->next != NULL) {
28011015SSundeep.Panicker@Sun.COM free_obj->next->prev = free_obj->prev;
28111015SSundeep.Panicker@Sun.COM }
28211015SSundeep.Panicker@Sun.COM }
28311015SSundeep.Panicker@Sun.COM
28411015SSundeep.Panicker@Sun.COM free(free_obj->u.pkt_obj->payload);
28511015SSundeep.Panicker@Sun.COM free(free_obj->u.pkt_obj);
28611015SSundeep.Panicker@Sun.COM free(free_obj);
28711015SSundeep.Panicker@Sun.COM }
28811015SSundeep.Panicker@Sun.COM
28911015SSundeep.Panicker@Sun.COM hash_obj->u.seg_obj->pkt_obj_list = NULL;
29011015SSundeep.Panicker@Sun.COM }
29111015SSundeep.Panicker@Sun.COM
29211015SSundeep.Panicker@Sun.COM
29311015SSundeep.Panicker@Sun.COM static void
free_segment_hash(handle_t handle,hash_obj_t * sec_hash)29411015SSundeep.Panicker@Sun.COM free_segment_hash(handle_t handle, hash_obj_t *sec_hash)
29511015SSundeep.Panicker@Sun.COM {
29611015SSundeep.Panicker@Sun.COM hash_obj_t *seg_hash;
29711015SSundeep.Panicker@Sun.COM hash_obj_t *next_hash;
29811015SSundeep.Panicker@Sun.COM
29911015SSundeep.Panicker@Sun.COM seg_hash = sec_hash->u.sec_obj->seg_obj_list;
30011015SSundeep.Panicker@Sun.COM if (seg_hash == NULL) {
30111015SSundeep.Panicker@Sun.COM return;
30211015SSundeep.Panicker@Sun.COM }
30311015SSundeep.Panicker@Sun.COM
30411015SSundeep.Panicker@Sun.COM if (seg_hash->obj_hdl == handle) {
30511015SSundeep.Panicker@Sun.COM sec_hash->u.sec_obj->seg_obj_list = seg_hash->u.seg_obj->next;
30611015SSundeep.Panicker@Sun.COM } else {
30711015SSundeep.Panicker@Sun.COM while (seg_hash->obj_hdl != handle) {
30811015SSundeep.Panicker@Sun.COM next_hash = seg_hash;
30911015SSundeep.Panicker@Sun.COM seg_hash = seg_hash->u.seg_obj->next;
31011015SSundeep.Panicker@Sun.COM if (seg_hash == NULL) {
31111015SSundeep.Panicker@Sun.COM return;
31211015SSundeep.Panicker@Sun.COM }
31311015SSundeep.Panicker@Sun.COM }
31411015SSundeep.Panicker@Sun.COM next_hash->u.seg_obj->next = seg_hash->u.seg_obj->next;
31511015SSundeep.Panicker@Sun.COM }
31611015SSundeep.Panicker@Sun.COM
31711015SSundeep.Panicker@Sun.COM if (seg_hash->prev == NULL) {
31811015SSundeep.Panicker@Sun.COM hash_table[(seg_hash->obj_hdl % TABLE_SIZE)] = seg_hash->next;
31911015SSundeep.Panicker@Sun.COM if (seg_hash->next != NULL) {
32011015SSundeep.Panicker@Sun.COM seg_hash->next->prev = NULL;
32111015SSundeep.Panicker@Sun.COM }
32211015SSundeep.Panicker@Sun.COM } else {
32311015SSundeep.Panicker@Sun.COM seg_hash->prev->next = seg_hash->next;
32411015SSundeep.Panicker@Sun.COM if (seg_hash->next != NULL) {
32511015SSundeep.Panicker@Sun.COM seg_hash->next->prev = seg_hash->prev;
32611015SSundeep.Panicker@Sun.COM }
32711015SSundeep.Panicker@Sun.COM }
32811015SSundeep.Panicker@Sun.COM
32911015SSundeep.Panicker@Sun.COM free_pkt_object_list(seg_hash);
33011015SSundeep.Panicker@Sun.COM free(seg_hash->u.seg_obj);
33111015SSundeep.Panicker@Sun.COM free(seg_hash);
33211015SSundeep.Panicker@Sun.COM }
33311015SSundeep.Panicker@Sun.COM
33411015SSundeep.Panicker@Sun.COM
33511015SSundeep.Panicker@Sun.COM
33611015SSundeep.Panicker@Sun.COM static void
add_to_sec_object_list(hash_obj_t * parent_obj,hash_obj_t * child_obj)33711015SSundeep.Panicker@Sun.COM add_to_sec_object_list(hash_obj_t *parent_obj, hash_obj_t *child_obj)
33811015SSundeep.Panicker@Sun.COM {
33911015SSundeep.Panicker@Sun.COM hash_obj_t *next_hash;
34011015SSundeep.Panicker@Sun.COM
34111015SSundeep.Panicker@Sun.COM child_obj->u.sec_obj->cont_hdl = parent_obj->obj_hdl;
34211015SSundeep.Panicker@Sun.COM if (parent_obj->u.cont_obj->sec_obj_list == NULL) {
34311015SSundeep.Panicker@Sun.COM parent_obj->u.cont_obj->sec_obj_list = child_obj;
34411015SSundeep.Panicker@Sun.COM return;
34511015SSundeep.Panicker@Sun.COM }
34611015SSundeep.Panicker@Sun.COM
34711015SSundeep.Panicker@Sun.COM for (next_hash = parent_obj->u.cont_obj->sec_obj_list;
34811015SSundeep.Panicker@Sun.COM next_hash->u.sec_obj->next != NULL;
34911015SSundeep.Panicker@Sun.COM next_hash = next_hash->u.sec_obj->next) {
35011015SSundeep.Panicker@Sun.COM ;
35111015SSundeep.Panicker@Sun.COM }
35211015SSundeep.Panicker@Sun.COM
35311015SSundeep.Panicker@Sun.COM next_hash->u.sec_obj->next = child_obj;
35411015SSundeep.Panicker@Sun.COM }
35511015SSundeep.Panicker@Sun.COM
35611015SSundeep.Panicker@Sun.COM
35711015SSundeep.Panicker@Sun.COM static void
add_to_seg_object_list(hash_obj_t * parent_obj,hash_obj_t * child_obj)35811015SSundeep.Panicker@Sun.COM add_to_seg_object_list(hash_obj_t *parent_obj, hash_obj_t *child_obj)
35911015SSundeep.Panicker@Sun.COM {
36011015SSundeep.Panicker@Sun.COM hash_obj_t *next_hash;
36111015SSundeep.Panicker@Sun.COM
36211015SSundeep.Panicker@Sun.COM child_obj->u.seg_obj->section_hdl = parent_obj->obj_hdl;
36311015SSundeep.Panicker@Sun.COM if (parent_obj->u.sec_obj->seg_obj_list == NULL) {
36411015SSundeep.Panicker@Sun.COM parent_obj->u.sec_obj->seg_obj_list = child_obj;
36511015SSundeep.Panicker@Sun.COM return;
36611015SSundeep.Panicker@Sun.COM }
36711015SSundeep.Panicker@Sun.COM
36811015SSundeep.Panicker@Sun.COM for (next_hash = parent_obj->u.sec_obj->seg_obj_list;
36911015SSundeep.Panicker@Sun.COM next_hash->u.seg_obj->next != NULL;
37011015SSundeep.Panicker@Sun.COM next_hash = next_hash->u.seg_obj->next) {
37111015SSundeep.Panicker@Sun.COM ;
37211015SSundeep.Panicker@Sun.COM }
37311015SSundeep.Panicker@Sun.COM
37411015SSundeep.Panicker@Sun.COM next_hash->u.seg_obj->next = child_obj;
37511015SSundeep.Panicker@Sun.COM }
37611015SSundeep.Panicker@Sun.COM
37711015SSundeep.Panicker@Sun.COM
37811015SSundeep.Panicker@Sun.COM static char *
tokenizer(char * buf,char * separator,char ** nextBuf,char * matched)37911015SSundeep.Panicker@Sun.COM tokenizer(char *buf, char *separator, char **nextBuf, char *matched)
38011015SSundeep.Panicker@Sun.COM {
38111015SSundeep.Panicker@Sun.COM int i = 0;
38211015SSundeep.Panicker@Sun.COM int j = 0;
38311015SSundeep.Panicker@Sun.COM
38411015SSundeep.Panicker@Sun.COM for (i = 0; buf[i] != '\0'; i++) {
38511015SSundeep.Panicker@Sun.COM for (j = 0; j < strlen(separator); j++) {
38611015SSundeep.Panicker@Sun.COM if (buf[i] == separator[j]) {
38711015SSundeep.Panicker@Sun.COM buf[i] = '\0';
38811015SSundeep.Panicker@Sun.COM *nextBuf = &(buf[i+1]);
38911015SSundeep.Panicker@Sun.COM *matched = separator[j];
39011015SSundeep.Panicker@Sun.COM return (buf);
39111015SSundeep.Panicker@Sun.COM }
39211015SSundeep.Panicker@Sun.COM }
39311015SSundeep.Panicker@Sun.COM }
39411015SSundeep.Panicker@Sun.COM
39511015SSundeep.Panicker@Sun.COM *nextBuf = buf;
39611015SSundeep.Panicker@Sun.COM *matched = '\0';
39711015SSundeep.Panicker@Sun.COM return (NULL);
39811015SSundeep.Panicker@Sun.COM }
39911015SSundeep.Panicker@Sun.COM
40011015SSundeep.Panicker@Sun.COM
40111015SSundeep.Panicker@Sun.COM static void
copy_segment_layout(segment_t * seghdr,void * layout)40211015SSundeep.Panicker@Sun.COM copy_segment_layout(segment_t *seghdr, void *layout)
40311015SSundeep.Panicker@Sun.COM {
40411015SSundeep.Panicker@Sun.COM segment_layout_t *seg_layout;
40511015SSundeep.Panicker@Sun.COM
40611015SSundeep.Panicker@Sun.COM seg_layout = (segment_layout_t *)layout;
40711015SSundeep.Panicker@Sun.COM (void) memcpy(seghdr->name, &seg_layout->name, SEG_NAME_LEN);
40811015SSundeep.Panicker@Sun.COM seghdr->descriptor = GET_SEGMENT_DESCRIPTOR;
40911015SSundeep.Panicker@Sun.COM seghdr->offset = BE_16(seg_layout->offset);
41011015SSundeep.Panicker@Sun.COM seghdr->length = BE_16(seg_layout->length);
41111015SSundeep.Panicker@Sun.COM }
41211015SSundeep.Panicker@Sun.COM
41311015SSundeep.Panicker@Sun.COM
41411015SSundeep.Panicker@Sun.COM static int
get_container_info(const char * def_file,const char * cont_desc_str,container_info_t * cont_info)41511015SSundeep.Panicker@Sun.COM get_container_info(const char *def_file, const char *cont_desc_str,
41611015SSundeep.Panicker@Sun.COM container_info_t *cont_info)
41711015SSundeep.Panicker@Sun.COM {
41811015SSundeep.Panicker@Sun.COM char *item;
41911015SSundeep.Panicker@Sun.COM char *token;
42011015SSundeep.Panicker@Sun.COM char *field;
42111015SSundeep.Panicker@Sun.COM char matched;
42211015SSundeep.Panicker@Sun.COM char buf[1024];
42311015SSundeep.Panicker@Sun.COM int foundIt = 0;
42411015SSundeep.Panicker@Sun.COM FILE *file = fopen(def_file, "r");
42511015SSundeep.Panicker@Sun.COM
42611015SSundeep.Panicker@Sun.COM if (file == NULL)
42711015SSundeep.Panicker@Sun.COM return (-1);
42811015SSundeep.Panicker@Sun.COM
42911015SSundeep.Panicker@Sun.COM cont_info->num_sections = 0;
43011015SSundeep.Panicker@Sun.COM
43111015SSundeep.Panicker@Sun.COM while (fgets(buf, sizeof (buf), file) != NULL) {
43211015SSundeep.Panicker@Sun.COM /* ignore all comments */
43311015SSundeep.Panicker@Sun.COM token = tokenizer(buf, "#", &field, &matched);
43411015SSundeep.Panicker@Sun.COM /* find the names */
43511015SSundeep.Panicker@Sun.COM token = tokenizer(buf, ":", &field, &matched);
43611015SSundeep.Panicker@Sun.COM if (token != 0x00) {
43711015SSundeep.Panicker@Sun.COM token = tokenizer(token, "|", &item, &matched);
43811015SSundeep.Panicker@Sun.COM while (token != 0x00) {
43911015SSundeep.Panicker@Sun.COM if (strcmp(token, cont_desc_str) == 0) {
44011015SSundeep.Panicker@Sun.COM foundIt = 1;
44111015SSundeep.Panicker@Sun.COM goto found;
44211015SSundeep.Panicker@Sun.COM }
44311015SSundeep.Panicker@Sun.COM token = tokenizer(item, "|", &item, &matched);
44411015SSundeep.Panicker@Sun.COM }
44511015SSundeep.Panicker@Sun.COM /* check the last remaining item */
44611015SSundeep.Panicker@Sun.COM if ((item != 0x00) &&
44711015SSundeep.Panicker@Sun.COM (strcmp(item, cont_desc_str) == 0)) {
44811015SSundeep.Panicker@Sun.COM foundIt = 1;
44911015SSundeep.Panicker@Sun.COM goto found;
45011015SSundeep.Panicker@Sun.COM }
45111015SSundeep.Panicker@Sun.COM }
45211015SSundeep.Panicker@Sun.COM }
45311015SSundeep.Panicker@Sun.COM
45411015SSundeep.Panicker@Sun.COM found :
45511015SSundeep.Panicker@Sun.COM if (foundIt == 1) {
45611015SSundeep.Panicker@Sun.COM token = tokenizer(field, ":", &field, &matched);
45711015SSundeep.Panicker@Sun.COM if (token == 0x00) {
45811015SSundeep.Panicker@Sun.COM (void) fclose(file);
45911015SSundeep.Panicker@Sun.COM return (-1);
46011015SSundeep.Panicker@Sun.COM }
46111015SSundeep.Panicker@Sun.COM cont_info->header_ver = (headerrev_t)atoi(token);
46211015SSundeep.Panicker@Sun.COM
46311015SSundeep.Panicker@Sun.COM token = tokenizer(field, ":\n", &field, &matched);
46411015SSundeep.Panicker@Sun.COM while (token != 0x00) {
46511015SSundeep.Panicker@Sun.COM token = tokenizer(token, ",", &item, &matched);
46611015SSundeep.Panicker@Sun.COM if (token == 0x00) {
46711015SSundeep.Panicker@Sun.COM (void) fclose(file);
46811015SSundeep.Panicker@Sun.COM return (-1);
46911015SSundeep.Panicker@Sun.COM }
47011015SSundeep.Panicker@Sun.COM if (atoi(token) == 1) {
47111015SSundeep.Panicker@Sun.COM cont_info->section_info[cont_info->
47211015SSundeep.Panicker@Sun.COM num_sections].description.field.read_only
47311015SSundeep.Panicker@Sun.COM = 1;
47411015SSundeep.Panicker@Sun.COM } else if (atoi(token) == 0) {
47511015SSundeep.Panicker@Sun.COM cont_info->section_info[cont_info->
47611015SSundeep.Panicker@Sun.COM num_sections].description.field.read_only
47711015SSundeep.Panicker@Sun.COM = 0;
47811015SSundeep.Panicker@Sun.COM } else {
47911015SSundeep.Panicker@Sun.COM (void) fclose(file);
48011015SSundeep.Panicker@Sun.COM return (-1);
48111015SSundeep.Panicker@Sun.COM }
48211015SSundeep.Panicker@Sun.COM
48311015SSundeep.Panicker@Sun.COM token = tokenizer(item, ",", &item, &matched);
48411015SSundeep.Panicker@Sun.COM if (token == 0x00) {
48511015SSundeep.Panicker@Sun.COM (void) fclose(file);
48611015SSundeep.Panicker@Sun.COM return (-1);
48711015SSundeep.Panicker@Sun.COM }
48811015SSundeep.Panicker@Sun.COM
48911015SSundeep.Panicker@Sun.COM cont_info->section_info[cont_info->
49011015SSundeep.Panicker@Sun.COM num_sections].address = atoi(token);
49111015SSundeep.Panicker@Sun.COM if (item == '\0') {
49211015SSundeep.Panicker@Sun.COM (void) fclose(file);
49311015SSundeep.Panicker@Sun.COM return (-1);
49411015SSundeep.Panicker@Sun.COM }
49511015SSundeep.Panicker@Sun.COM cont_info->section_info[cont_info->num_sections].size =
49611015SSundeep.Panicker@Sun.COM atoi(item);
49711015SSundeep.Panicker@Sun.COM (cont_info->num_sections)++;
49811015SSundeep.Panicker@Sun.COM
49911015SSundeep.Panicker@Sun.COM token = tokenizer(field, ":\n ", &field, &matched);
50011015SSundeep.Panicker@Sun.COM }
50111015SSundeep.Panicker@Sun.COM }
50211015SSundeep.Panicker@Sun.COM (void) fclose(file);
50311015SSundeep.Panicker@Sun.COM
50411015SSundeep.Panicker@Sun.COM return (0);
50511015SSundeep.Panicker@Sun.COM }
50611015SSundeep.Panicker@Sun.COM
50711015SSundeep.Panicker@Sun.COM
50811015SSundeep.Panicker@Sun.COM /* ARGSUSED */
50911015SSundeep.Panicker@Sun.COM int
fru_get_segments(section_hdl_t section,segment_t * segment,int maxseg,door_cred_t * cred)51011015SSundeep.Panicker@Sun.COM fru_get_segments(section_hdl_t section, segment_t *segment, int maxseg,
51111015SSundeep.Panicker@Sun.COM door_cred_t *cred)
51211015SSundeep.Panicker@Sun.COM {
51311015SSundeep.Panicker@Sun.COM int count;
51411015SSundeep.Panicker@Sun.COM hash_obj_t *sec_object;
51511015SSundeep.Panicker@Sun.COM hash_obj_t *seg_object;
51611015SSundeep.Panicker@Sun.COM section_obj_t *sec_obj;
51711015SSundeep.Panicker@Sun.COM
51811015SSundeep.Panicker@Sun.COM sec_object = lookup_handle_object(section, SECTION_TYPE);
51911015SSundeep.Panicker@Sun.COM if (sec_object == NULL) {
52011015SSundeep.Panicker@Sun.COM return (-1);
52111015SSundeep.Panicker@Sun.COM }
52211015SSundeep.Panicker@Sun.COM
52311015SSundeep.Panicker@Sun.COM sec_obj = sec_object->u.sec_obj;
52411015SSundeep.Panicker@Sun.COM if (sec_obj == NULL) {
52511015SSundeep.Panicker@Sun.COM return (-1);
52611015SSundeep.Panicker@Sun.COM }
52711015SSundeep.Panicker@Sun.COM
52811015SSundeep.Panicker@Sun.COM if (sec_obj->num_of_segment > maxseg) {
52911015SSundeep.Panicker@Sun.COM return (-1);
53011015SSundeep.Panicker@Sun.COM }
53111015SSundeep.Panicker@Sun.COM
53211015SSundeep.Panicker@Sun.COM seg_object = sec_object->u.sec_obj->seg_obj_list;
53311015SSundeep.Panicker@Sun.COM if (seg_object == NULL) {
53411015SSundeep.Panicker@Sun.COM return (-1);
53511015SSundeep.Panicker@Sun.COM }
53611015SSundeep.Panicker@Sun.COM
53711015SSundeep.Panicker@Sun.COM for (count = 0; count < sec_obj->num_of_segment; count++) {
53811015SSundeep.Panicker@Sun.COM
53911015SSundeep.Panicker@Sun.COM /* populate segment_t */
54011015SSundeep.Panicker@Sun.COM segment->handle = seg_object->obj_hdl;
54111015SSundeep.Panicker@Sun.COM (void) memcpy(segment->name,
54211015SSundeep.Panicker@Sun.COM seg_object->u.seg_obj->segment.name, SEG_NAME_LEN);
54311015SSundeep.Panicker@Sun.COM segment->descriptor = seg_object->u.seg_obj->segment.descriptor;
54411015SSundeep.Panicker@Sun.COM
54511015SSundeep.Panicker@Sun.COM segment->offset = seg_object->u.seg_obj->segment.offset;
54611015SSundeep.Panicker@Sun.COM segment->length = seg_object->u.seg_obj->segment.length;
54711015SSundeep.Panicker@Sun.COM seg_object = seg_object->u.seg_obj->next;
54811015SSundeep.Panicker@Sun.COM segment++;
54911015SSundeep.Panicker@Sun.COM }
55011015SSundeep.Panicker@Sun.COM return (0);
55111015SSundeep.Panicker@Sun.COM }
55211015SSundeep.Panicker@Sun.COM
55311015SSundeep.Panicker@Sun.COM
55411015SSundeep.Panicker@Sun.COM static int
raw_memcpy(void * buffer,raw_list_t * rawlist,int offset,int size)55511015SSundeep.Panicker@Sun.COM raw_memcpy(void *buffer, raw_list_t *rawlist, int offset, int size)
55611015SSundeep.Panicker@Sun.COM {
55711015SSundeep.Panicker@Sun.COM if (offset + size > rawlist->size) {
55811015SSundeep.Panicker@Sun.COM size = rawlist->size - offset;
55911015SSundeep.Panicker@Sun.COM }
56011015SSundeep.Panicker@Sun.COM
56111015SSundeep.Panicker@Sun.COM (void) memcpy(buffer, &rawlist->raw[offset], size);
56211015SSundeep.Panicker@Sun.COM
56311015SSundeep.Panicker@Sun.COM return (size);
56411015SSundeep.Panicker@Sun.COM }
56511015SSundeep.Panicker@Sun.COM
56611015SSundeep.Panicker@Sun.COM
56711015SSundeep.Panicker@Sun.COM static int
verify_header_crc8(headerrev_t head_ver,unsigned char * bytes,int length)56811015SSundeep.Panicker@Sun.COM verify_header_crc8(headerrev_t head_ver, unsigned char *bytes, int length)
56911015SSundeep.Panicker@Sun.COM {
57011015SSundeep.Panicker@Sun.COM int crc_offset = 0;
57111015SSundeep.Panicker@Sun.COM unsigned char orig_crc8 = 0;
57211015SSundeep.Panicker@Sun.COM unsigned char calc_crc8 = 0;
57311015SSundeep.Panicker@Sun.COM
57411015SSundeep.Panicker@Sun.COM switch (head_ver) {
57511015SSundeep.Panicker@Sun.COM case SECTION_HDR_VER:
57611015SSundeep.Panicker@Sun.COM crc_offset = 4;
57711015SSundeep.Panicker@Sun.COM break;
57811015SSundeep.Panicker@Sun.COM default:
57911015SSundeep.Panicker@Sun.COM errno = EINVAL;
58011015SSundeep.Panicker@Sun.COM return (0);
58111015SSundeep.Panicker@Sun.COM }
58211015SSundeep.Panicker@Sun.COM
58311015SSundeep.Panicker@Sun.COM orig_crc8 = bytes[crc_offset];
58411015SSundeep.Panicker@Sun.COM bytes[crc_offset] = 0x00; /* clear for calc */
58511015SSundeep.Panicker@Sun.COM calc_crc8 = compute_crc8(bytes, length);
58611015SSundeep.Panicker@Sun.COM bytes[crc_offset] = orig_crc8; /* restore */
58711015SSundeep.Panicker@Sun.COM
58811015SSundeep.Panicker@Sun.COM return (orig_crc8 == calc_crc8);
58911015SSundeep.Panicker@Sun.COM }
59011015SSundeep.Panicker@Sun.COM
59111015SSundeep.Panicker@Sun.COM
59211015SSundeep.Panicker@Sun.COM static int
get_section(raw_list_t * rawlist,hash_obj_t * sec_hash,section_t * section)59311015SSundeep.Panicker@Sun.COM get_section(raw_list_t *rawlist, hash_obj_t *sec_hash, section_t *section)
59411015SSundeep.Panicker@Sun.COM {
59511015SSundeep.Panicker@Sun.COM int retval;
59611015SSundeep.Panicker@Sun.COM int size;
59711015SSundeep.Panicker@Sun.COM int count;
59811015SSundeep.Panicker@Sun.COM uint16_t hdrver;
59911015SSundeep.Panicker@Sun.COM hash_obj_t *seg_hash;
60011015SSundeep.Panicker@Sun.COM unsigned char *buffer;
60111015SSundeep.Panicker@Sun.COM section_obj_t *sec_obj;
60211015SSundeep.Panicker@Sun.COM section_layout_t sec_hdr;
60311015SSundeep.Panicker@Sun.COM segment_layout_t *seg_hdr;
60411015SSundeep.Panicker@Sun.COM segment_layout_t *seg_buf;
60511015SSundeep.Panicker@Sun.COM
60611015SSundeep.Panicker@Sun.COM sec_obj = sec_hash->u.sec_obj;
60711015SSundeep.Panicker@Sun.COM if (sec_obj == NULL) {
60811015SSundeep.Panicker@Sun.COM return (-1);
60911015SSundeep.Panicker@Sun.COM }
61011015SSundeep.Panicker@Sun.COM
61111015SSundeep.Panicker@Sun.COM /* populate section_t */
61211015SSundeep.Panicker@Sun.COM section->handle = sec_hash->obj_hdl;
61311015SSundeep.Panicker@Sun.COM section->offset = sec_obj->section.offset;
61411015SSundeep.Panicker@Sun.COM section->length = sec_obj->section.length;
61511015SSundeep.Panicker@Sun.COM section->protection = sec_obj->section.protection;
61611015SSundeep.Panicker@Sun.COM section->version = sec_obj->section.version;
61711015SSundeep.Panicker@Sun.COM
61811015SSundeep.Panicker@Sun.COM /* read section header layout */
61911015SSundeep.Panicker@Sun.COM retval = raw_memcpy(&sec_hdr, rawlist, sec_obj->section.offset,
62011015SSundeep.Panicker@Sun.COM sizeof (sec_hdr));
62111015SSundeep.Panicker@Sun.COM
62211015SSundeep.Panicker@Sun.COM if (retval != sizeof (sec_hdr)) {
62311015SSundeep.Panicker@Sun.COM return (-1);
62411015SSundeep.Panicker@Sun.COM }
62511015SSundeep.Panicker@Sun.COM
62611015SSundeep.Panicker@Sun.COM
62711015SSundeep.Panicker@Sun.COM hdrver = GET_SECTION_HDR_VERSION;
62811015SSundeep.Panicker@Sun.COM
62911015SSundeep.Panicker@Sun.COM if ((sec_hdr.headertag != SECTION_HDR_TAG) &&
63011015SSundeep.Panicker@Sun.COM (hdrver != section->version)) {
63111015SSundeep.Panicker@Sun.COM return (-1);
63211015SSundeep.Panicker@Sun.COM }
63311015SSundeep.Panicker@Sun.COM
63411015SSundeep.Panicker@Sun.COM /* size = section layout + total sizeof segment header */
63511015SSundeep.Panicker@Sun.COM size = sizeof (sec_hdr) + ((sec_hdr.segmentcount)
63611015SSundeep.Panicker@Sun.COM * sizeof (segment_layout_t));
63711015SSundeep.Panicker@Sun.COM
63811015SSundeep.Panicker@Sun.COM buffer = alloca(size);
63911015SSundeep.Panicker@Sun.COM if (buffer == NULL) {
64011015SSundeep.Panicker@Sun.COM return (-1);
64111015SSundeep.Panicker@Sun.COM }
64211015SSundeep.Panicker@Sun.COM
64311015SSundeep.Panicker@Sun.COM /* segment header buffer */
64411015SSundeep.Panicker@Sun.COM seg_buf = alloca(size - sizeof (sec_hdr));
64511015SSundeep.Panicker@Sun.COM if (seg_buf == NULL) {
64611015SSundeep.Panicker@Sun.COM return (-1);
64711015SSundeep.Panicker@Sun.COM }
64811015SSundeep.Panicker@Sun.COM
64911015SSundeep.Panicker@Sun.COM /* read segment header */
65011015SSundeep.Panicker@Sun.COM retval = raw_memcpy(seg_buf, rawlist,
65111015SSundeep.Panicker@Sun.COM sec_obj->section.offset + sizeof (sec_hdr),
65211015SSundeep.Panicker@Sun.COM size - sizeof (sec_hdr));
65311015SSundeep.Panicker@Sun.COM
65411015SSundeep.Panicker@Sun.COM if (retval != (size - sizeof (sec_hdr))) {
65511015SSundeep.Panicker@Sun.COM return (-1);
65611015SSundeep.Panicker@Sun.COM }
65711015SSundeep.Panicker@Sun.COM
65811015SSundeep.Panicker@Sun.COM /* copy section header layout */
65911015SSundeep.Panicker@Sun.COM (void) memcpy(buffer, &sec_hdr, sizeof (sec_hdr));
66011015SSundeep.Panicker@Sun.COM
66111015SSundeep.Panicker@Sun.COM /* copy segment header layout */
66211015SSundeep.Panicker@Sun.COM (void) memcpy(buffer + sizeof (sec_hdr), seg_buf, size -
66311015SSundeep.Panicker@Sun.COM sizeof (sec_hdr));
66411015SSundeep.Panicker@Sun.COM
66511015SSundeep.Panicker@Sun.COM /* verify crc8 */
66611015SSundeep.Panicker@Sun.COM retval = verify_header_crc8(hdrver, buffer, size);
66711015SSundeep.Panicker@Sun.COM if (retval != TRUE) {
66811015SSundeep.Panicker@Sun.COM return (-1);
66911015SSundeep.Panicker@Sun.COM }
67011015SSundeep.Panicker@Sun.COM
67111015SSundeep.Panicker@Sun.COM section->version = hdrver;
67211015SSundeep.Panicker@Sun.COM sec_obj->section.version = hdrver;
67311015SSundeep.Panicker@Sun.COM
67411015SSundeep.Panicker@Sun.COM seg_hdr = (segment_layout_t *)seg_buf;
67511015SSundeep.Panicker@Sun.COM
67611015SSundeep.Panicker@Sun.COM /* bug fix for frutool */
67711015SSundeep.Panicker@Sun.COM if (sec_hash->u.sec_obj->seg_obj_list != NULL) {
67811015SSundeep.Panicker@Sun.COM return (0);
67911015SSundeep.Panicker@Sun.COM } else {
68011015SSundeep.Panicker@Sun.COM sec_obj->num_of_segment = 0;
68111015SSundeep.Panicker@Sun.COM }
68211015SSundeep.Panicker@Sun.COM for (count = 0; count < sec_hdr.segmentcount; count++, seg_hdr++) {
68311015SSundeep.Panicker@Sun.COM
68411015SSundeep.Panicker@Sun.COM seg_hash = create_segment_hash_object();
68511015SSundeep.Panicker@Sun.COM if (seg_hash == NULL) {
68611015SSundeep.Panicker@Sun.COM return (-1);
68711015SSundeep.Panicker@Sun.COM }
68811015SSundeep.Panicker@Sun.COM add_hashobject_to_hashtable(seg_hash);
68911015SSundeep.Panicker@Sun.COM copy_segment_layout(&seg_hash->u.seg_obj->segment, seg_hdr);
69011015SSundeep.Panicker@Sun.COM add_to_seg_object_list(sec_hash, seg_hash);
69111015SSundeep.Panicker@Sun.COM sec_obj->num_of_segment++;
69211015SSundeep.Panicker@Sun.COM }
69311015SSundeep.Panicker@Sun.COM return (0);
69411015SSundeep.Panicker@Sun.COM }
69511015SSundeep.Panicker@Sun.COM
69611015SSundeep.Panicker@Sun.COM /* ARGSUSED */
69711015SSundeep.Panicker@Sun.COM int
fru_get_sections(container_hdl_t container,section_t * section,int maxsec,door_cred_t * cred)69811015SSundeep.Panicker@Sun.COM fru_get_sections(container_hdl_t container, section_t *section, int maxsec,
69911015SSundeep.Panicker@Sun.COM door_cred_t *cred)
70011015SSundeep.Panicker@Sun.COM {
70111015SSundeep.Panicker@Sun.COM int count;
70211015SSundeep.Panicker@Sun.COM int num_sec = 0;
70311015SSundeep.Panicker@Sun.COM hash_obj_t *cont_object;
70411015SSundeep.Panicker@Sun.COM hash_obj_t *sec_hash;
70511015SSundeep.Panicker@Sun.COM
70611015SSundeep.Panicker@Sun.COM cont_object = lookup_handle_object(container, CONTAINER_TYPE);
70711015SSundeep.Panicker@Sun.COM if (cont_object == NULL) {
70811015SSundeep.Panicker@Sun.COM return (-1);
70911015SSundeep.Panicker@Sun.COM }
71011015SSundeep.Panicker@Sun.COM
71111015SSundeep.Panicker@Sun.COM if (cont_object->u.cont_obj->num_of_section > maxsec) {
71211015SSundeep.Panicker@Sun.COM return (-1);
71311015SSundeep.Panicker@Sun.COM }
71411015SSundeep.Panicker@Sun.COM
71511015SSundeep.Panicker@Sun.COM sec_hash = cont_object->u.cont_obj->sec_obj_list;
71611015SSundeep.Panicker@Sun.COM if (sec_hash == NULL) {
71711015SSundeep.Panicker@Sun.COM return (-1);
71811015SSundeep.Panicker@Sun.COM }
71911015SSundeep.Panicker@Sun.COM
72011015SSundeep.Panicker@Sun.COM for (count = 0; count < cont_object->u.cont_obj->num_of_section;
72111015SSundeep.Panicker@Sun.COM count++) {
72211015SSundeep.Panicker@Sun.COM section->version = -1;
72311015SSundeep.Panicker@Sun.COM /* populate section_t */
72411015SSundeep.Panicker@Sun.COM if (get_section(g_raw, sec_hash, section) == 0) {
72511015SSundeep.Panicker@Sun.COM section++;
72611015SSundeep.Panicker@Sun.COM num_sec++;
72711015SSundeep.Panicker@Sun.COM }
72811015SSundeep.Panicker@Sun.COM sec_hash = sec_hash->u.sec_obj->next;
72911015SSundeep.Panicker@Sun.COM }
73011015SSundeep.Panicker@Sun.COM return (num_sec);
73111015SSundeep.Panicker@Sun.COM }
73211015SSundeep.Panicker@Sun.COM
73311015SSundeep.Panicker@Sun.COM
73411015SSundeep.Panicker@Sun.COM static uint32_t
get_checksum_crc(hash_obj_t * seg_hash,int data_size)73511015SSundeep.Panicker@Sun.COM get_checksum_crc(hash_obj_t *seg_hash, int data_size)
73611015SSundeep.Panicker@Sun.COM {
73711015SSundeep.Panicker@Sun.COM int protection;
73811015SSundeep.Panicker@Sun.COM int offset = 0;
73911015SSundeep.Panicker@Sun.COM uint32_t crc;
74011015SSundeep.Panicker@Sun.COM hash_obj_t *sec_hash;
74111015SSundeep.Panicker@Sun.COM hash_obj_t *pkt_hash;
74211015SSundeep.Panicker@Sun.COM unsigned char *buffer;
74311015SSundeep.Panicker@Sun.COM
74411015SSundeep.Panicker@Sun.COM sec_hash = lookup_handle_object(seg_hash->u.seg_obj->section_hdl,
74511015SSundeep.Panicker@Sun.COM SECTION_TYPE);
74611015SSundeep.Panicker@Sun.COM if (sec_hash == NULL) {
74711015SSundeep.Panicker@Sun.COM return ((uint32_t)-1);
74811015SSundeep.Panicker@Sun.COM }
74911015SSundeep.Panicker@Sun.COM
75011015SSundeep.Panicker@Sun.COM buffer = alloca(data_size);
75111015SSundeep.Panicker@Sun.COM if (buffer == NULL) {
75211015SSundeep.Panicker@Sun.COM return ((uint32_t)-1);
75311015SSundeep.Panicker@Sun.COM }
75411015SSundeep.Panicker@Sun.COM
75511015SSundeep.Panicker@Sun.COM /* traverse the packet object list for all the tags and payload */
75611015SSundeep.Panicker@Sun.COM for (pkt_hash = seg_hash->u.seg_obj->pkt_obj_list; pkt_hash != NULL;
75711015SSundeep.Panicker@Sun.COM pkt_hash = pkt_hash->u.pkt_obj->next) {
75811015SSundeep.Panicker@Sun.COM (void) memcpy(buffer + offset, &pkt_hash->u.pkt_obj->tag,
75911015SSundeep.Panicker@Sun.COM pkt_hash->u.pkt_obj->tag_size);
76011015SSundeep.Panicker@Sun.COM offset += pkt_hash->u.pkt_obj->tag_size;
76111015SSundeep.Panicker@Sun.COM (void) memcpy(buffer + offset, pkt_hash->u.pkt_obj->payload,
76211015SSundeep.Panicker@Sun.COM pkt_hash->u.pkt_obj->paylen);
76311015SSundeep.Panicker@Sun.COM offset += pkt_hash->u.pkt_obj->paylen;
76411015SSundeep.Panicker@Sun.COM }
76511015SSundeep.Panicker@Sun.COM
76611015SSundeep.Panicker@Sun.COM protection = sec_hash->u.sec_obj->section.protection;
76711015SSundeep.Panicker@Sun.COM
76811015SSundeep.Panicker@Sun.COM if (protection == READ_ONLY_SECTION) { /* read-only section */
76911015SSundeep.Panicker@Sun.COM crc = compute_crc32(buffer, data_size);
77011015SSundeep.Panicker@Sun.COM } else { /* read/write section */
77111015SSundeep.Panicker@Sun.COM crc = compute_checksum32(buffer, data_size);
77211015SSundeep.Panicker@Sun.COM }
77311015SSundeep.Panicker@Sun.COM return (crc); /* computed crc */
77411015SSundeep.Panicker@Sun.COM }
77511015SSundeep.Panicker@Sun.COM
77611015SSundeep.Panicker@Sun.COM
77711015SSundeep.Panicker@Sun.COM static int
get_packet(raw_list_t * rawlist,void * buffer,int size,int offset)77811015SSundeep.Panicker@Sun.COM get_packet(raw_list_t *rawlist, void *buffer, int size, int offset)
77911015SSundeep.Panicker@Sun.COM {
78011015SSundeep.Panicker@Sun.COM int retval;
78111015SSundeep.Panicker@Sun.COM
78211015SSundeep.Panicker@Sun.COM retval = raw_memcpy(buffer, rawlist, offset, size);
78311015SSundeep.Panicker@Sun.COM
78411015SSundeep.Panicker@Sun.COM if (retval != -1) {
78511015SSundeep.Panicker@Sun.COM return (0);
78611015SSundeep.Panicker@Sun.COM }
78711015SSundeep.Panicker@Sun.COM return (-1);
78811015SSundeep.Panicker@Sun.COM }
78911015SSundeep.Panicker@Sun.COM
79011015SSundeep.Panicker@Sun.COM
79111015SSundeep.Panicker@Sun.COM static int
get_packets(hash_obj_t * seg_hash,raw_list_t * rawlist,int offset,int length)79211015SSundeep.Panicker@Sun.COM get_packets(hash_obj_t *seg_hash, raw_list_t *rawlist, int offset, int length)
79311015SSundeep.Panicker@Sun.COM {
79411015SSundeep.Panicker@Sun.COM int tag_size;
79511015SSundeep.Panicker@Sun.COM int paylen;
79611015SSundeep.Panicker@Sun.COM int retval;
79711015SSundeep.Panicker@Sun.COM int seg_limit = 0;
79811015SSundeep.Panicker@Sun.COM int pktcnt = 0;
79911015SSundeep.Panicker@Sun.COM char *data;
80011015SSundeep.Panicker@Sun.COM uint32_t crc;
80111015SSundeep.Panicker@Sun.COM uint32_t origcrc;
80211015SSundeep.Panicker@Sun.COM fru_tag_t tag;
80311015SSundeep.Panicker@Sun.COM hash_obj_t *pkt_hash_obj;
80411015SSundeep.Panicker@Sun.COM hash_obj_t *sec_hash;
80511015SSundeep.Panicker@Sun.COM fru_segdesc_t *segdesc;
80611015SSundeep.Panicker@Sun.COM fru_tagtype_t tagtype;
80711015SSundeep.Panicker@Sun.COM char *ignore_flag;
80811015SSundeep.Panicker@Sun.COM
80911015SSundeep.Panicker@Sun.COM retval = get_packet(rawlist, &tag, sizeof (fru_tag_t), offset);
81011015SSundeep.Panicker@Sun.COM if (retval == -1) {
81111015SSundeep.Panicker@Sun.COM return (-1);
81211015SSundeep.Panicker@Sun.COM }
81311015SSundeep.Panicker@Sun.COM
81411015SSundeep.Panicker@Sun.COM /* section hash object */
81511015SSundeep.Panicker@Sun.COM sec_hash = lookup_handle_object(seg_hash->u.seg_obj->section_hdl,
81611015SSundeep.Panicker@Sun.COM SECTION_TYPE);
81711015SSundeep.Panicker@Sun.COM
81811015SSundeep.Panicker@Sun.COM if (sec_hash == NULL) {
81911015SSundeep.Panicker@Sun.COM return (-1);
82011015SSundeep.Panicker@Sun.COM }
82111015SSundeep.Panicker@Sun.COM
82211015SSundeep.Panicker@Sun.COM seg_hash->u.seg_obj->trailer_offset = offset;
82311015SSundeep.Panicker@Sun.COM
82411015SSundeep.Panicker@Sun.COM data = (char *)&tag;
82511015SSundeep.Panicker@Sun.COM while (data[0] != SEG_TRAILER_TAG) {
82611015SSundeep.Panicker@Sun.COM tagtype = get_tag_type(&tag); /* verify tag type */
82711015SSundeep.Panicker@Sun.COM if (tagtype == -1) {
82811015SSundeep.Panicker@Sun.COM return (-1);
82911015SSundeep.Panicker@Sun.COM }
83011015SSundeep.Panicker@Sun.COM
83111015SSundeep.Panicker@Sun.COM tag_size = get_tag_size(tagtype);
83211015SSundeep.Panicker@Sun.COM if (tag_size == -1) {
83311015SSundeep.Panicker@Sun.COM return (-1);
83411015SSundeep.Panicker@Sun.COM }
83511015SSundeep.Panicker@Sun.COM
83611015SSundeep.Panicker@Sun.COM seg_limit += tag_size;
83711015SSundeep.Panicker@Sun.COM if (seg_limit > length) {
83811015SSundeep.Panicker@Sun.COM return (-1);
83911015SSundeep.Panicker@Sun.COM }
84011015SSundeep.Panicker@Sun.COM
84111015SSundeep.Panicker@Sun.COM paylen = get_payload_length((void *)&tag);
84211015SSundeep.Panicker@Sun.COM if (paylen == -1) {
84311015SSundeep.Panicker@Sun.COM return (-1);
84411015SSundeep.Panicker@Sun.COM }
84511015SSundeep.Panicker@Sun.COM
84611015SSundeep.Panicker@Sun.COM seg_limit += paylen;
84711015SSundeep.Panicker@Sun.COM if (seg_limit > length) {
84811015SSundeep.Panicker@Sun.COM return (-1);
84911015SSundeep.Panicker@Sun.COM }
85011015SSundeep.Panicker@Sun.COM if ((offset + tag_size + paylen) >
85111015SSundeep.Panicker@Sun.COM (sec_hash->u.sec_obj->section.offset +
85211015SSundeep.Panicker@Sun.COM sec_hash->u.sec_obj->section.length)) {
85311015SSundeep.Panicker@Sun.COM return (-1);
85411015SSundeep.Panicker@Sun.COM }
85511015SSundeep.Panicker@Sun.COM
85611015SSundeep.Panicker@Sun.COM pkt_hash_obj = create_packet_hash_object();
85711015SSundeep.Panicker@Sun.COM if (pkt_hash_obj == NULL) {
85811015SSundeep.Panicker@Sun.COM return (-1);
85911015SSundeep.Panicker@Sun.COM }
86011015SSundeep.Panicker@Sun.COM
86111015SSundeep.Panicker@Sun.COM pkt_hash_obj->u.pkt_obj->payload = malloc(paylen);
86211015SSundeep.Panicker@Sun.COM if (pkt_hash_obj->u.pkt_obj->payload == NULL) {
86311015SSundeep.Panicker@Sun.COM free(pkt_hash_obj);
86411015SSundeep.Panicker@Sun.COM return (-1);
86511015SSundeep.Panicker@Sun.COM }
86611015SSundeep.Panicker@Sun.COM
86711015SSundeep.Panicker@Sun.COM offset += tag_size;
86811015SSundeep.Panicker@Sun.COM
86911015SSundeep.Panicker@Sun.COM retval = raw_memcpy(pkt_hash_obj->u.pkt_obj->payload, rawlist,
87011015SSundeep.Panicker@Sun.COM offset, paylen);
87111015SSundeep.Panicker@Sun.COM
87211015SSundeep.Panicker@Sun.COM if (retval != paylen) {
87311015SSundeep.Panicker@Sun.COM free(pkt_hash_obj->u.pkt_obj->payload);
87411015SSundeep.Panicker@Sun.COM free(pkt_hash_obj);
87511015SSundeep.Panicker@Sun.COM return (-1);
87611015SSundeep.Panicker@Sun.COM }
87711015SSundeep.Panicker@Sun.COM
87811015SSundeep.Panicker@Sun.COM /* don't change this */
87911015SSundeep.Panicker@Sun.COM pkt_hash_obj->u.pkt_obj->tag.raw_data = 0;
88011015SSundeep.Panicker@Sun.COM (void) memcpy(&pkt_hash_obj->u.pkt_obj->tag, &tag, tag_size);
88111015SSundeep.Panicker@Sun.COM pkt_hash_obj->u.pkt_obj->paylen = paylen;
88211015SSundeep.Panicker@Sun.COM pkt_hash_obj->u.pkt_obj->tag_size = tag_size;
88311015SSundeep.Panicker@Sun.COM pkt_hash_obj->u.pkt_obj->payload_offset = offset;
88411015SSundeep.Panicker@Sun.COM
88511015SSundeep.Panicker@Sun.COM offset += paylen;
88611015SSundeep.Panicker@Sun.COM
88711015SSundeep.Panicker@Sun.COM add_hashobject_to_hashtable(pkt_hash_obj);
88811015SSundeep.Panicker@Sun.COM add_to_pkt_object_list(seg_hash, pkt_hash_obj);
88911015SSundeep.Panicker@Sun.COM
89011015SSundeep.Panicker@Sun.COM pktcnt++;
89111015SSundeep.Panicker@Sun.COM
89211015SSundeep.Panicker@Sun.COM retval = get_packet(rawlist, &tag, sizeof (fru_tag_t),
89311015SSundeep.Panicker@Sun.COM offset);
89411015SSundeep.Panicker@Sun.COM if (retval == -1) {
89511015SSundeep.Panicker@Sun.COM return (retval);
89611015SSundeep.Panicker@Sun.COM }
89711015SSundeep.Panicker@Sun.COM
89811015SSundeep.Panicker@Sun.COM data = (char *)&tag;
89911015SSundeep.Panicker@Sun.COM }
90011015SSundeep.Panicker@Sun.COM
90111015SSundeep.Panicker@Sun.COM segdesc = (fru_segdesc_t *)&seg_hash->u.seg_obj->segment.descriptor;
90211015SSundeep.Panicker@Sun.COM
90311015SSundeep.Panicker@Sun.COM seg_hash->u.seg_obj->trailer_offset = offset;
90411015SSundeep.Panicker@Sun.COM
90511015SSundeep.Panicker@Sun.COM if (!segdesc->field.ignore_checksum) {
90611015SSundeep.Panicker@Sun.COM crc = get_checksum_crc(seg_hash, seg_limit);
90711015SSundeep.Panicker@Sun.COM offset = seg_hash->u.seg_obj->segment.offset;
90811015SSundeep.Panicker@Sun.COM
90911015SSundeep.Panicker@Sun.COM retval = raw_memcpy(&origcrc, rawlist, offset + seg_limit + 1,
91011015SSundeep.Panicker@Sun.COM sizeof (origcrc));
91111015SSundeep.Panicker@Sun.COM
91211015SSundeep.Panicker@Sun.COM ignore_flag = getenv(IGNORE_CHECK);
91311015SSundeep.Panicker@Sun.COM if (ignore_flag != NULL) {
91411015SSundeep.Panicker@Sun.COM return (pktcnt);
91511015SSundeep.Panicker@Sun.COM }
91611015SSundeep.Panicker@Sun.COM
91711015SSundeep.Panicker@Sun.COM if (retval != sizeof (origcrc)) {
91811015SSundeep.Panicker@Sun.COM return (-1);
91911015SSundeep.Panicker@Sun.COM }
92011015SSundeep.Panicker@Sun.COM
92111015SSundeep.Panicker@Sun.COM origcrc = BE_32(origcrc);
92211015SSundeep.Panicker@Sun.COM if (origcrc != crc) {
92311015SSundeep.Panicker@Sun.COM seg_hash->u.seg_obj->trailer_offset = offset;
92411015SSundeep.Panicker@Sun.COM return (-1);
92511015SSundeep.Panicker@Sun.COM }
92611015SSundeep.Panicker@Sun.COM }
92711015SSundeep.Panicker@Sun.COM
92811015SSundeep.Panicker@Sun.COM return (pktcnt);
92911015SSundeep.Panicker@Sun.COM }
93011015SSundeep.Panicker@Sun.COM
93111015SSundeep.Panicker@Sun.COM /* ARGSUSED */
93211015SSundeep.Panicker@Sun.COM int
fru_get_num_sections(container_hdl_t container,door_cred_t * cred)93311015SSundeep.Panicker@Sun.COM fru_get_num_sections(container_hdl_t container, door_cred_t *cred)
93411015SSundeep.Panicker@Sun.COM {
93511015SSundeep.Panicker@Sun.COM hash_obj_t *hash_object;
93611015SSundeep.Panicker@Sun.COM
93711015SSundeep.Panicker@Sun.COM hash_object = lookup_handle_object(container, CONTAINER_TYPE);
93811015SSundeep.Panicker@Sun.COM if (hash_object == NULL) {
93911015SSundeep.Panicker@Sun.COM return (-1);
94011015SSundeep.Panicker@Sun.COM }
94111015SSundeep.Panicker@Sun.COM
94211015SSundeep.Panicker@Sun.COM return (hash_object->u.cont_obj->num_of_section);
94311015SSundeep.Panicker@Sun.COM }
94411015SSundeep.Panicker@Sun.COM
94511015SSundeep.Panicker@Sun.COM /* ARGSUSED */
94611015SSundeep.Panicker@Sun.COM int
fru_get_num_segments(section_hdl_t section,door_cred_t * cred)94711015SSundeep.Panicker@Sun.COM fru_get_num_segments(section_hdl_t section, door_cred_t *cred)
94811015SSundeep.Panicker@Sun.COM {
94911015SSundeep.Panicker@Sun.COM hash_obj_t *sec_object;
95011015SSundeep.Panicker@Sun.COM section_obj_t *sec_obj;
95111015SSundeep.Panicker@Sun.COM
95211015SSundeep.Panicker@Sun.COM sec_object = lookup_handle_object(section, SECTION_TYPE);
95311015SSundeep.Panicker@Sun.COM if (sec_object == NULL) {
95411015SSundeep.Panicker@Sun.COM return (-1);
95511015SSundeep.Panicker@Sun.COM }
95611015SSundeep.Panicker@Sun.COM
95711015SSundeep.Panicker@Sun.COM sec_obj = sec_object->u.sec_obj;
95811015SSundeep.Panicker@Sun.COM if (sec_obj == NULL) {
95911015SSundeep.Panicker@Sun.COM return (-1);
96011015SSundeep.Panicker@Sun.COM }
96111015SSundeep.Panicker@Sun.COM
96211015SSundeep.Panicker@Sun.COM return (sec_obj->num_of_segment);
96311015SSundeep.Panicker@Sun.COM }
96411015SSundeep.Panicker@Sun.COM
96511015SSundeep.Panicker@Sun.COM /* ARGSUSED */
96611015SSundeep.Panicker@Sun.COM int
fru_get_num_packets(segment_hdl_t segment,door_cred_t * cred)96711015SSundeep.Panicker@Sun.COM fru_get_num_packets(segment_hdl_t segment, door_cred_t *cred)
96811015SSundeep.Panicker@Sun.COM {
96911015SSundeep.Panicker@Sun.COM int pktcnt;
97011015SSundeep.Panicker@Sun.COM int length;
97111015SSundeep.Panicker@Sun.COM uint16_t offset;
97211015SSundeep.Panicker@Sun.COM hash_obj_t *cont_hash_obj;
97311015SSundeep.Panicker@Sun.COM hash_obj_t *seg_hash;
97411015SSundeep.Panicker@Sun.COM hash_obj_t *sec_hash;
97511015SSundeep.Panicker@Sun.COM fru_segdesc_t *segdesc;
97611015SSundeep.Panicker@Sun.COM segment_obj_t *segment_object;
97711015SSundeep.Panicker@Sun.COM
97811015SSundeep.Panicker@Sun.COM seg_hash = lookup_handle_object(segment, SEGMENT_TYPE);
97911015SSundeep.Panicker@Sun.COM if (seg_hash == NULL) {
98011015SSundeep.Panicker@Sun.COM return (-1);
98111015SSundeep.Panicker@Sun.COM }
98211015SSundeep.Panicker@Sun.COM
98311015SSundeep.Panicker@Sun.COM segment_object = seg_hash->u.seg_obj;
98411015SSundeep.Panicker@Sun.COM if (segment_object == NULL) {
98511015SSundeep.Panicker@Sun.COM return (-1);
98611015SSundeep.Panicker@Sun.COM }
98711015SSundeep.Panicker@Sun.COM
98811015SSundeep.Panicker@Sun.COM segdesc = (fru_segdesc_t *)&segment_object->segment.descriptor;
98911015SSundeep.Panicker@Sun.COM if (segdesc->field.opaque) {
99011015SSundeep.Panicker@Sun.COM return (0);
99111015SSundeep.Panicker@Sun.COM }
99211015SSundeep.Panicker@Sun.COM
99311015SSundeep.Panicker@Sun.COM offset = segment_object->segment.offset;
99411015SSundeep.Panicker@Sun.COM length = segment_object->segment.length;
99511015SSundeep.Panicker@Sun.COM
99611015SSundeep.Panicker@Sun.COM cont_hash_obj = get_container_hash_object(SEGMENT_TYPE,
99711015SSundeep.Panicker@Sun.COM segment_object->section_hdl);
99811015SSundeep.Panicker@Sun.COM
99911015SSundeep.Panicker@Sun.COM if (cont_hash_obj == NULL) {
100011015SSundeep.Panicker@Sun.COM return (-1);
100111015SSundeep.Panicker@Sun.COM }
100211015SSundeep.Panicker@Sun.COM
100311015SSundeep.Panicker@Sun.COM if (seg_hash->u.seg_obj->pkt_obj_list != NULL) {
100411015SSundeep.Panicker@Sun.COM return (segment_object->num_of_packets);
100511015SSundeep.Panicker@Sun.COM }
100611015SSundeep.Panicker@Sun.COM /* section hash object */
100711015SSundeep.Panicker@Sun.COM sec_hash = lookup_handle_object(seg_hash->u.seg_obj->section_hdl,
100811015SSundeep.Panicker@Sun.COM SECTION_TYPE);
100911015SSundeep.Panicker@Sun.COM if (sec_hash == NULL) {
101011015SSundeep.Panicker@Sun.COM return (-1);
101111015SSundeep.Panicker@Sun.COM }
101211015SSundeep.Panicker@Sun.COM
101311015SSundeep.Panicker@Sun.COM /* valid segment header b'cos crc8 already validated */
101411015SSundeep.Panicker@Sun.COM if (offset < sec_hash->u.sec_obj->section.offset) {
101511015SSundeep.Panicker@Sun.COM return (-1);
101611015SSundeep.Panicker@Sun.COM }
101711015SSundeep.Panicker@Sun.COM
101811015SSundeep.Panicker@Sun.COM segment_object->num_of_packets = 0;
101911015SSundeep.Panicker@Sun.COM
102011015SSundeep.Panicker@Sun.COM pktcnt = get_packets(seg_hash, g_raw, offset, length);
102111015SSundeep.Panicker@Sun.COM if (pktcnt == -1) {
102211015SSundeep.Panicker@Sun.COM free_pkt_object_list(seg_hash);
102311015SSundeep.Panicker@Sun.COM seg_hash->u.seg_obj->pkt_obj_list = NULL;
102411015SSundeep.Panicker@Sun.COM }
102511015SSundeep.Panicker@Sun.COM
102611015SSundeep.Panicker@Sun.COM segment_object->num_of_packets = pktcnt;
102711015SSundeep.Panicker@Sun.COM
102811015SSundeep.Panicker@Sun.COM return (segment_object->num_of_packets);
102911015SSundeep.Panicker@Sun.COM }
103011015SSundeep.Panicker@Sun.COM
103111015SSundeep.Panicker@Sun.COM /* ARGSUSED */
103211015SSundeep.Panicker@Sun.COM int
fru_get_packets(segment_hdl_t segment,packet_t * packet,int maxpackets,door_cred_t * cred)103311015SSundeep.Panicker@Sun.COM fru_get_packets(segment_hdl_t segment, packet_t *packet, int maxpackets,
103411015SSundeep.Panicker@Sun.COM door_cred_t *cred)
103511015SSundeep.Panicker@Sun.COM {
103611015SSundeep.Panicker@Sun.COM int count;
103711015SSundeep.Panicker@Sun.COM hash_obj_t *seg_hash_obj;
103811015SSundeep.Panicker@Sun.COM hash_obj_t *pkt_hash_obj;
103911015SSundeep.Panicker@Sun.COM
104011015SSundeep.Panicker@Sun.COM /* segment hash object */
104111015SSundeep.Panicker@Sun.COM seg_hash_obj = lookup_handle_object(segment, SEGMENT_TYPE);
104211015SSundeep.Panicker@Sun.COM if (seg_hash_obj == NULL) {
104311015SSundeep.Panicker@Sun.COM return (-1);
104411015SSundeep.Panicker@Sun.COM }
104511015SSundeep.Panicker@Sun.COM
104611015SSundeep.Panicker@Sun.COM if (seg_hash_obj->u.seg_obj->num_of_packets != maxpackets) {
104711015SSundeep.Panicker@Sun.COM return (-1);
104811015SSundeep.Panicker@Sun.COM }
104911015SSundeep.Panicker@Sun.COM
105011015SSundeep.Panicker@Sun.COM pkt_hash_obj = seg_hash_obj->u.seg_obj->pkt_obj_list;
105111015SSundeep.Panicker@Sun.COM if (pkt_hash_obj == NULL) {
105211015SSundeep.Panicker@Sun.COM return (-1);
105311015SSundeep.Panicker@Sun.COM }
105411015SSundeep.Panicker@Sun.COM
105511015SSundeep.Panicker@Sun.COM for (count = 0; count < maxpackets; count++, packet++) {
105611015SSundeep.Panicker@Sun.COM packet->handle = pkt_hash_obj->obj_hdl;
105711015SSundeep.Panicker@Sun.COM packet->tag = 0;
105811015SSundeep.Panicker@Sun.COM (void) memcpy(&packet->tag, &pkt_hash_obj->u.pkt_obj->tag,
105911015SSundeep.Panicker@Sun.COM pkt_hash_obj->u.pkt_obj->tag_size);
106011015SSundeep.Panicker@Sun.COM pkt_hash_obj = pkt_hash_obj->u.pkt_obj->next;
106111015SSundeep.Panicker@Sun.COM }
106211015SSundeep.Panicker@Sun.COM
106311015SSundeep.Panicker@Sun.COM return (0);
106411015SSundeep.Panicker@Sun.COM }
106511015SSundeep.Panicker@Sun.COM
106611015SSundeep.Panicker@Sun.COM /* ARGSUSED */
106711015SSundeep.Panicker@Sun.COM ssize_t
fru_get_payload(packet_hdl_t packet,void * buffer,size_t nbytes,door_cred_t * cred)106811015SSundeep.Panicker@Sun.COM fru_get_payload(packet_hdl_t packet, void *buffer, size_t nbytes,
106911015SSundeep.Panicker@Sun.COM door_cred_t *cred)
107011015SSundeep.Panicker@Sun.COM {
107111015SSundeep.Panicker@Sun.COM hash_obj_t *packet_hash_obj;
107211015SSundeep.Panicker@Sun.COM
107311015SSundeep.Panicker@Sun.COM /* packet hash object */
107411015SSundeep.Panicker@Sun.COM packet_hash_obj = lookup_handle_object(packet, PACKET_TYPE);
107511015SSundeep.Panicker@Sun.COM if (packet_hash_obj == NULL) {
107611015SSundeep.Panicker@Sun.COM return (-1);
107711015SSundeep.Panicker@Sun.COM }
107811015SSundeep.Panicker@Sun.COM
107911015SSundeep.Panicker@Sun.COM /* verify payload length */
108011015SSundeep.Panicker@Sun.COM if (nbytes != packet_hash_obj->u.pkt_obj->paylen) {
108111015SSundeep.Panicker@Sun.COM return (-1);
108211015SSundeep.Panicker@Sun.COM }
108311015SSundeep.Panicker@Sun.COM
108411015SSundeep.Panicker@Sun.COM (void) memcpy(buffer, packet_hash_obj->u.pkt_obj->payload, nbytes);
108511015SSundeep.Panicker@Sun.COM return (nbytes);
108611015SSundeep.Panicker@Sun.COM }
108711015SSundeep.Panicker@Sun.COM
108811015SSundeep.Panicker@Sun.COM
108911015SSundeep.Panicker@Sun.COM container_hdl_t
open_raw_data(raw_list_t * node)109011015SSundeep.Panicker@Sun.COM open_raw_data(raw_list_t *node)
109111015SSundeep.Panicker@Sun.COM {
109211015SSundeep.Panicker@Sun.COM char *cont_conf_file = NULL;
109311015SSundeep.Panicker@Sun.COM hash_obj_t *cont_hash_obj;
109411015SSundeep.Panicker@Sun.COM hash_obj_t *sec_hash_obj;
109511015SSundeep.Panicker@Sun.COM container_info_t cont_info;
109611015SSundeep.Panicker@Sun.COM int retval;
109711015SSundeep.Panicker@Sun.COM int count;
109811015SSundeep.Panicker@Sun.COM
109911015SSundeep.Panicker@Sun.COM cont_hash_obj = create_container_hash_object();
110011015SSundeep.Panicker@Sun.COM if (cont_hash_obj == NULL) {
110111015SSundeep.Panicker@Sun.COM return (NULL);
110211015SSundeep.Panicker@Sun.COM }
110311015SSundeep.Panicker@Sun.COM
110411015SSundeep.Panicker@Sun.COM add_hashobject_to_hashtable(cont_hash_obj);
110511015SSundeep.Panicker@Sun.COM
110611015SSundeep.Panicker@Sun.COM (void) strncpy(cont_hash_obj->u.cont_obj->device_pathname, "unknown",
110711015SSundeep.Panicker@Sun.COM sizeof (cont_hash_obj->u.cont_obj->device_pathname));
110811015SSundeep.Panicker@Sun.COM
110911015SSundeep.Panicker@Sun.COM cont_conf_file = getenv(FRU_CONT_CONF_ENV_VAR);
111011015SSundeep.Panicker@Sun.COM if (cont_conf_file == NULL) {
111111015SSundeep.Panicker@Sun.COM cont_conf_file = FRU_CONT_CONF_SPARC;
111211015SSundeep.Panicker@Sun.COM retval = get_container_info(cont_conf_file, node->cont_type,
111311015SSundeep.Panicker@Sun.COM &cont_info);
111411015SSundeep.Panicker@Sun.COM if (retval < 0) {
111511015SSundeep.Panicker@Sun.COM cont_conf_file = FRU_CONT_CONF_X86;
111611015SSundeep.Panicker@Sun.COM retval = get_container_info(cont_conf_file,
111711015SSundeep.Panicker@Sun.COM node->cont_type, &cont_info);
111811015SSundeep.Panicker@Sun.COM }
111911015SSundeep.Panicker@Sun.COM } else {
112011015SSundeep.Panicker@Sun.COM retval = get_container_info(cont_conf_file, node->cont_type,
112111015SSundeep.Panicker@Sun.COM &cont_info);
112211015SSundeep.Panicker@Sun.COM }
112311015SSundeep.Panicker@Sun.COM
112411015SSundeep.Panicker@Sun.COM if (retval < 0) {
112511015SSundeep.Panicker@Sun.COM return (NULL);
112611015SSundeep.Panicker@Sun.COM }
112711015SSundeep.Panicker@Sun.COM
112811015SSundeep.Panicker@Sun.COM cont_hash_obj->u.cont_obj->num_of_section = cont_info.num_sections;
112911015SSundeep.Panicker@Sun.COM cont_hash_obj->u.cont_obj->sec_obj_list = NULL;
113011015SSundeep.Panicker@Sun.COM
113111015SSundeep.Panicker@Sun.COM for (count = 0; count < cont_info.num_sections; count++) {
113211015SSundeep.Panicker@Sun.COM sec_hash_obj = create_section_hash_object();
113311015SSundeep.Panicker@Sun.COM if (sec_hash_obj == NULL) {
113411015SSundeep.Panicker@Sun.COM return (NULL);
113511015SSundeep.Panicker@Sun.COM }
113611015SSundeep.Panicker@Sun.COM
113711015SSundeep.Panicker@Sun.COM add_hashobject_to_hashtable(sec_hash_obj);
113811015SSundeep.Panicker@Sun.COM
113911015SSundeep.Panicker@Sun.COM sec_hash_obj->u.sec_obj->section.offset =
114011015SSundeep.Panicker@Sun.COM cont_info.section_info[count].address;
114111015SSundeep.Panicker@Sun.COM
114211015SSundeep.Panicker@Sun.COM sec_hash_obj->u.sec_obj->section.protection =
114311015SSundeep.Panicker@Sun.COM cont_info.section_info[count].description.field.read_only;
114411015SSundeep.Panicker@Sun.COM
114511015SSundeep.Panicker@Sun.COM sec_hash_obj->u.sec_obj->section.length =
114611015SSundeep.Panicker@Sun.COM cont_info.section_info[count].size;
114711015SSundeep.Panicker@Sun.COM sec_hash_obj->u.sec_obj->section.version =
114811015SSundeep.Panicker@Sun.COM cont_info.header_ver;
114911015SSundeep.Panicker@Sun.COM
115011015SSundeep.Panicker@Sun.COM add_to_sec_object_list(cont_hash_obj, sec_hash_obj);
115111015SSundeep.Panicker@Sun.COM }
115211015SSundeep.Panicker@Sun.COM
115311015SSundeep.Panicker@Sun.COM return (cont_hash_obj->obj_hdl);
115411015SSundeep.Panicker@Sun.COM }
115511015SSundeep.Panicker@Sun.COM
115611015SSundeep.Panicker@Sun.COM
115711015SSundeep.Panicker@Sun.COM int
fru_close_container(container_hdl_t container)115811015SSundeep.Panicker@Sun.COM fru_close_container(container_hdl_t container)
115911015SSundeep.Panicker@Sun.COM {
116011015SSundeep.Panicker@Sun.COM hash_obj_t *hash_obj;
116111015SSundeep.Panicker@Sun.COM hash_obj_t *prev_hash;
116211015SSundeep.Panicker@Sun.COM hash_obj_t *sec_hash_obj;
116311015SSundeep.Panicker@Sun.COM handle_t obj_hdl;
116411015SSundeep.Panicker@Sun.COM
116511015SSundeep.Panicker@Sun.COM /* lookup for container hash object */
116611015SSundeep.Panicker@Sun.COM hash_obj = lookup_handle_object(container, CONTAINER_TYPE);
116711015SSundeep.Panicker@Sun.COM if (hash_obj == NULL) {
116811015SSundeep.Panicker@Sun.COM return (0);
116911015SSundeep.Panicker@Sun.COM }
117011015SSundeep.Panicker@Sun.COM
117111015SSundeep.Panicker@Sun.COM /* points to section object list */
117211015SSundeep.Panicker@Sun.COM sec_hash_obj = hash_obj->u.cont_obj->sec_obj_list;
117311015SSundeep.Panicker@Sun.COM
117411015SSundeep.Panicker@Sun.COM /* traverse section object list */
117511015SSundeep.Panicker@Sun.COM while (sec_hash_obj != NULL) {
117611015SSundeep.Panicker@Sun.COM
117711015SSundeep.Panicker@Sun.COM /* traverse segment hash object in the section */
117811015SSundeep.Panicker@Sun.COM while (sec_hash_obj->u.sec_obj->seg_obj_list != NULL) {
117911015SSundeep.Panicker@Sun.COM /* object handle of the segment hash object */
118011015SSundeep.Panicker@Sun.COM obj_hdl =
118111015SSundeep.Panicker@Sun.COM sec_hash_obj->u.sec_obj->seg_obj_list->obj_hdl;
118211015SSundeep.Panicker@Sun.COM free_segment_hash(obj_hdl, sec_hash_obj);
118311015SSundeep.Panicker@Sun.COM }
118411015SSundeep.Panicker@Sun.COM
118511015SSundeep.Panicker@Sun.COM /* going to free section hash object, relink the hash object */
118611015SSundeep.Panicker@Sun.COM if (sec_hash_obj->prev == NULL) {
118711015SSundeep.Panicker@Sun.COM hash_table[(sec_hash_obj->obj_hdl % TABLE_SIZE)] =
118811015SSundeep.Panicker@Sun.COM sec_hash_obj->next;
118911015SSundeep.Panicker@Sun.COM if (sec_hash_obj->next != NULL) {
119011015SSundeep.Panicker@Sun.COM sec_hash_obj->next->prev = NULL;
119111015SSundeep.Panicker@Sun.COM }
119211015SSundeep.Panicker@Sun.COM } else {
119311015SSundeep.Panicker@Sun.COM sec_hash_obj->prev->next = sec_hash_obj->next;
119411015SSundeep.Panicker@Sun.COM if (sec_hash_obj->next != NULL) {
119511015SSundeep.Panicker@Sun.COM sec_hash_obj->next->prev = sec_hash_obj->prev;
119611015SSundeep.Panicker@Sun.COM }
119711015SSundeep.Panicker@Sun.COM }
119811015SSundeep.Panicker@Sun.COM
119911015SSundeep.Panicker@Sun.COM prev_hash = sec_hash_obj;
120011015SSundeep.Panicker@Sun.COM sec_hash_obj = sec_hash_obj->u.sec_obj->next;
120111015SSundeep.Panicker@Sun.COM
1202*12126SHyon.Kim@Sun.COM free(prev_hash->u.sec_obj); /* free section hash object */
120311015SSundeep.Panicker@Sun.COM free(prev_hash); /* free section hash */
120411015SSundeep.Panicker@Sun.COM }
120511015SSundeep.Panicker@Sun.COM
120611015SSundeep.Panicker@Sun.COM /* free container hash object */
120711015SSundeep.Panicker@Sun.COM if (hash_obj->prev == NULL) {
120811015SSundeep.Panicker@Sun.COM hash_table[(hash_obj->obj_hdl % TABLE_SIZE)] =
120911015SSundeep.Panicker@Sun.COM hash_obj->next;
121011015SSundeep.Panicker@Sun.COM if (hash_obj->next != NULL) {
121111015SSundeep.Panicker@Sun.COM hash_obj->next->prev = NULL;
121211015SSundeep.Panicker@Sun.COM }
121311015SSundeep.Panicker@Sun.COM } else {
121411015SSundeep.Panicker@Sun.COM hash_obj->prev->next = hash_obj->next;
121511015SSundeep.Panicker@Sun.COM if (hash_obj->next != NULL) {
121611015SSundeep.Panicker@Sun.COM hash_obj->next->prev = hash_obj->prev;
121711015SSundeep.Panicker@Sun.COM }
121811015SSundeep.Panicker@Sun.COM }
121911015SSundeep.Panicker@Sun.COM
122011015SSundeep.Panicker@Sun.COM free(hash_obj->u.cont_obj);
122111015SSundeep.Panicker@Sun.COM free(hash_obj);
122211015SSundeep.Panicker@Sun.COM
122311015SSundeep.Panicker@Sun.COM return (0);
122411015SSundeep.Panicker@Sun.COM }
1225