4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
29 #include <sys/byteorder.h>
30 #include "fru_access_impl.h"
33 #pragma init(initialize_raw_access)
35 static hash_obj_t
*hash_table
[TABLE_SIZE
];
36 extern raw_list_t
*g_raw
;
39 initialize_raw_access(void)
43 for (count
= 0; count
< TABLE_SIZE
; count
++) {
44 hash_table
[count
] = NULL
;
50 lookup_handle_object(handle_t handle
, int object_type
)
52 handle_t index_to_hash
;
53 hash_obj_t
*first_hash_obj
;
54 hash_obj_t
*next_hash_obj
;
56 index_to_hash
= (handle
% TABLE_SIZE
);
58 first_hash_obj
= hash_table
[index_to_hash
];
59 for (next_hash_obj
= first_hash_obj
; next_hash_obj
!= NULL
;
60 next_hash_obj
= next_hash_obj
->next
) {
61 if ((handle
== next_hash_obj
->obj_hdl
) &&
62 (object_type
== next_hash_obj
->object_type
)) {
63 return (next_hash_obj
);
71 add_hashobject_to_hashtable(hash_obj_t
*hash_obj
)
73 handle_t index_to_hash
;
74 static uint64_t handle_count
= 0;
76 hash_obj
->obj_hdl
= ++handle_count
; /* store the handle */
79 index_to_hash
= ((hash_obj
->obj_hdl
) % TABLE_SIZE
);
81 hash_obj
->next
= hash_table
[index_to_hash
];
82 hash_table
[index_to_hash
] = hash_obj
; /* hash obj. added */
84 if (hash_obj
->next
!= NULL
) {
85 hash_obj
->next
->prev
= hash_obj
;
91 create_container_hash_object(void)
94 container_obj_t
*cont_obj
;
96 cont_obj
= malloc(sizeof (container_obj_t
));
97 if (cont_obj
== NULL
) {
101 hash_obj
= malloc(sizeof (hash_obj_t
));
102 if (hash_obj
== NULL
) {
107 cont_obj
->sec_obj_list
= NULL
;
109 hash_obj
->object_type
= CONTAINER_TYPE
;
110 hash_obj
->u
.cont_obj
= cont_obj
;
111 hash_obj
->next
= NULL
;
112 hash_obj
->prev
= NULL
;
119 create_section_hash_object(void)
121 hash_obj_t
*hash_obj
;
122 section_obj_t
*sec_obj
;
124 sec_obj
= malloc(sizeof (section_obj_t
));
125 if (sec_obj
== NULL
) {
129 hash_obj
= malloc(sizeof (hash_obj_t
));
130 if (hash_obj
== NULL
) {
135 sec_obj
->next
= NULL
;
136 sec_obj
->seg_obj_list
= NULL
;
138 hash_obj
->u
.sec_obj
= sec_obj
;
139 hash_obj
->object_type
= SECTION_TYPE
;
140 hash_obj
->next
= NULL
;
141 hash_obj
->prev
= NULL
;
148 create_segment_hash_object(void)
150 hash_obj_t
*hash_obj
;
151 segment_obj_t
*seg_obj
;
153 seg_obj
= malloc(sizeof (segment_obj_t
));
154 if (seg_obj
== NULL
) {
158 hash_obj
= malloc(sizeof (hash_obj_t
));
159 if (hash_obj
== NULL
) {
164 seg_obj
->next
= NULL
;
165 seg_obj
->pkt_obj_list
= NULL
;
167 hash_obj
->object_type
= SEGMENT_TYPE
;
168 hash_obj
->u
.seg_obj
= seg_obj
;
169 hash_obj
->next
= NULL
;
170 hash_obj
->prev
= NULL
;
177 create_packet_hash_object(void)
179 hash_obj_t
*hash_obj
;
180 packet_obj_t
*pkt_obj
;
182 pkt_obj
= malloc(sizeof (packet_obj_t
));
183 if (pkt_obj
== NULL
) {
187 hash_obj
= malloc(sizeof (hash_obj_t
));
188 if (hash_obj
== NULL
) {
193 pkt_obj
->next
= NULL
;
195 hash_obj
->object_type
= PACKET_TYPE
;
196 hash_obj
->u
.pkt_obj
= pkt_obj
;
197 hash_obj
->next
= NULL
;
198 hash_obj
->prev
= NULL
;
206 get_container_hash_object(int object_type
, handle_t handle
)
208 hash_obj_t
*hash_obj
;
210 switch (object_type
) {
214 hash_obj
= lookup_handle_object(handle
, CONTAINER_TYPE
);
215 if (hash_obj
== NULL
) {
220 hash_obj
= lookup_handle_object(handle
, SECTION_TYPE
);
221 if (hash_obj
== NULL
) {
224 hash_obj
= lookup_handle_object(hash_obj
->u
.sec_obj
->cont_hdl
,
238 add_to_pkt_object_list(hash_obj_t
*parent_obj
, hash_obj_t
*child_obj
)
240 hash_obj_t
*next_hash
;
242 /* add the packet object in the end of list */
243 child_obj
->u
.pkt_obj
->segment_hdl
= parent_obj
->obj_hdl
;
245 if (parent_obj
->u
.seg_obj
->pkt_obj_list
== NULL
) {
246 parent_obj
->u
.seg_obj
->pkt_obj_list
= child_obj
;
250 for (next_hash
= parent_obj
->u
.seg_obj
->pkt_obj_list
;
251 next_hash
->u
.pkt_obj
->next
!= NULL
;
252 next_hash
= next_hash
->u
.pkt_obj
->next
) {
256 next_hash
->u
.pkt_obj
->next
= child_obj
;
261 free_pkt_object_list(hash_obj_t
*hash_obj
)
263 hash_obj_t
*next_obj
;
264 hash_obj_t
*free_obj
;
266 next_obj
= hash_obj
->u
.seg_obj
->pkt_obj_list
;
267 while (next_obj
!= NULL
) {
269 next_obj
= next_obj
->u
.pkt_obj
->next
;
270 /* if prev is NULL it's the first object in the list */
271 if (free_obj
->prev
== NULL
) {
272 hash_table
[(free_obj
->obj_hdl
% TABLE_SIZE
)] =
274 if (free_obj
->next
!= NULL
) {
275 free_obj
->next
->prev
= free_obj
->prev
;
278 free_obj
->prev
->next
= free_obj
->next
;
279 if (free_obj
->next
!= NULL
) {
280 free_obj
->next
->prev
= free_obj
->prev
;
284 free(free_obj
->u
.pkt_obj
->payload
);
285 free(free_obj
->u
.pkt_obj
);
289 hash_obj
->u
.seg_obj
->pkt_obj_list
= NULL
;
294 free_segment_hash(handle_t handle
, hash_obj_t
*sec_hash
)
296 hash_obj_t
*seg_hash
;
297 hash_obj_t
*next_hash
;
299 seg_hash
= sec_hash
->u
.sec_obj
->seg_obj_list
;
300 if (seg_hash
== NULL
) {
304 if (seg_hash
->obj_hdl
== handle
) {
305 sec_hash
->u
.sec_obj
->seg_obj_list
= seg_hash
->u
.seg_obj
->next
;
307 while (seg_hash
->obj_hdl
!= handle
) {
308 next_hash
= seg_hash
;
309 seg_hash
= seg_hash
->u
.seg_obj
->next
;
310 if (seg_hash
== NULL
) {
314 next_hash
->u
.seg_obj
->next
= seg_hash
->u
.seg_obj
->next
;
317 if (seg_hash
->prev
== NULL
) {
318 hash_table
[(seg_hash
->obj_hdl
% TABLE_SIZE
)] = seg_hash
->next
;
319 if (seg_hash
->next
!= NULL
) {
320 seg_hash
->next
->prev
= NULL
;
323 seg_hash
->prev
->next
= seg_hash
->next
;
324 if (seg_hash
->next
!= NULL
) {
325 seg_hash
->next
->prev
= seg_hash
->prev
;
329 free_pkt_object_list(seg_hash
);
330 free(seg_hash
->u
.seg_obj
);
337 add_to_sec_object_list(hash_obj_t
*parent_obj
, hash_obj_t
*child_obj
)
339 hash_obj_t
*next_hash
;
341 child_obj
->u
.sec_obj
->cont_hdl
= parent_obj
->obj_hdl
;
342 if (parent_obj
->u
.cont_obj
->sec_obj_list
== NULL
) {
343 parent_obj
->u
.cont_obj
->sec_obj_list
= child_obj
;
347 for (next_hash
= parent_obj
->u
.cont_obj
->sec_obj_list
;
348 next_hash
->u
.sec_obj
->next
!= NULL
;
349 next_hash
= next_hash
->u
.sec_obj
->next
) {
353 next_hash
->u
.sec_obj
->next
= child_obj
;
358 add_to_seg_object_list(hash_obj_t
*parent_obj
, hash_obj_t
*child_obj
)
360 hash_obj_t
*next_hash
;
362 child_obj
->u
.seg_obj
->section_hdl
= parent_obj
->obj_hdl
;
363 if (parent_obj
->u
.sec_obj
->seg_obj_list
== NULL
) {
364 parent_obj
->u
.sec_obj
->seg_obj_list
= child_obj
;
368 for (next_hash
= parent_obj
->u
.sec_obj
->seg_obj_list
;
369 next_hash
->u
.seg_obj
->next
!= NULL
;
370 next_hash
= next_hash
->u
.seg_obj
->next
) {
374 next_hash
->u
.seg_obj
->next
= child_obj
;
379 tokenizer(char *buf
, char *separator
, char **nextBuf
, char *matched
)
384 for (i
= 0; buf
[i
] != '\0'; i
++) {
385 for (j
= 0; j
< strlen(separator
); j
++) {
386 if (buf
[i
] == separator
[j
]) {
388 *nextBuf
= &(buf
[i
+1]);
389 *matched
= separator
[j
];
402 copy_segment_layout(segment_t
*seghdr
, void *layout
)
404 segment_layout_t
*seg_layout
;
406 seg_layout
= (segment_layout_t
*)layout
;
407 (void) memcpy(seghdr
->name
, &seg_layout
->name
, SEG_NAME_LEN
);
408 seghdr
->descriptor
= GET_SEGMENT_DESCRIPTOR
;
409 seghdr
->offset
= BE_16(seg_layout
->offset
);
410 seghdr
->length
= BE_16(seg_layout
->length
);
415 get_container_info(const char *def_file
, const char *cont_desc_str
,
416 container_info_t
*cont_info
)
424 FILE *file
= fopen(def_file
, "r");
429 cont_info
->num_sections
= 0;
431 while (fgets(buf
, sizeof (buf
), file
) != NULL
) {
432 /* ignore all comments */
433 token
= tokenizer(buf
, "#", &field
, &matched
);
435 token
= tokenizer(buf
, ":", &field
, &matched
);
437 token
= tokenizer(token
, "|", &item
, &matched
);
438 while (token
!= 0x00) {
439 if (strcmp(token
, cont_desc_str
) == 0) {
443 token
= tokenizer(item
, "|", &item
, &matched
);
445 /* check the last remaining item */
446 if ((item
!= 0x00) &&
447 (strcmp(item
, cont_desc_str
) == 0)) {
456 token
= tokenizer(field
, ":", &field
, &matched
);
461 cont_info
->header_ver
= (headerrev_t
)atoi(token
);
463 token
= tokenizer(field
, ":\n", &field
, &matched
);
464 while (token
!= 0x00) {
465 token
= tokenizer(token
, ",", &item
, &matched
);
470 if (atoi(token
) == 1) {
471 cont_info
->section_info
[cont_info
->
472 num_sections
].description
.field
.read_only
474 } else if (atoi(token
) == 0) {
475 cont_info
->section_info
[cont_info
->
476 num_sections
].description
.field
.read_only
483 token
= tokenizer(item
, ",", &item
, &matched
);
489 cont_info
->section_info
[cont_info
->
490 num_sections
].address
= atoi(token
);
495 cont_info
->section_info
[cont_info
->num_sections
].size
=
497 (cont_info
->num_sections
)++;
499 token
= tokenizer(field
, ":\n ", &field
, &matched
);
510 fru_get_segments(section_hdl_t section
, segment_t
*segment
, int maxseg
,
514 hash_obj_t
*sec_object
;
515 hash_obj_t
*seg_object
;
516 section_obj_t
*sec_obj
;
518 sec_object
= lookup_handle_object(section
, SECTION_TYPE
);
519 if (sec_object
== NULL
) {
523 sec_obj
= sec_object
->u
.sec_obj
;
524 if (sec_obj
== NULL
) {
528 if (sec_obj
->num_of_segment
> maxseg
) {
532 seg_object
= sec_object
->u
.sec_obj
->seg_obj_list
;
533 if (seg_object
== NULL
) {
537 for (count
= 0; count
< sec_obj
->num_of_segment
; count
++) {
539 /* populate segment_t */
540 segment
->handle
= seg_object
->obj_hdl
;
541 (void) memcpy(segment
->name
,
542 seg_object
->u
.seg_obj
->segment
.name
, SEG_NAME_LEN
);
543 segment
->descriptor
= seg_object
->u
.seg_obj
->segment
.descriptor
;
545 segment
->offset
= seg_object
->u
.seg_obj
->segment
.offset
;
546 segment
->length
= seg_object
->u
.seg_obj
->segment
.length
;
547 seg_object
= seg_object
->u
.seg_obj
->next
;
555 raw_memcpy(void *buffer
, raw_list_t
*rawlist
, int offset
, int size
)
557 if (offset
+ size
> rawlist
->size
) {
558 size
= rawlist
->size
- offset
;
561 (void) memcpy(buffer
, &rawlist
->raw
[offset
], size
);
568 verify_header_crc8(headerrev_t head_ver
, unsigned char *bytes
, int length
)
571 unsigned char orig_crc8
= 0;
572 unsigned char calc_crc8
= 0;
575 case SECTION_HDR_VER
:
583 orig_crc8
= bytes
[crc_offset
];
584 bytes
[crc_offset
] = 0x00; /* clear for calc */
585 calc_crc8
= compute_crc8(bytes
, length
);
586 bytes
[crc_offset
] = orig_crc8
; /* restore */
588 return (orig_crc8
== calc_crc8
);
593 get_section(raw_list_t
*rawlist
, hash_obj_t
*sec_hash
, section_t
*section
)
599 hash_obj_t
*seg_hash
;
600 unsigned char *buffer
;
601 section_obj_t
*sec_obj
;
602 section_layout_t sec_hdr
;
603 segment_layout_t
*seg_hdr
;
604 segment_layout_t
*seg_buf
;
606 sec_obj
= sec_hash
->u
.sec_obj
;
607 if (sec_obj
== NULL
) {
611 /* populate section_t */
612 section
->handle
= sec_hash
->obj_hdl
;
613 section
->offset
= sec_obj
->section
.offset
;
614 section
->length
= sec_obj
->section
.length
;
615 section
->protection
= sec_obj
->section
.protection
;
616 section
->version
= sec_obj
->section
.version
;
618 /* read section header layout */
619 retval
= raw_memcpy(&sec_hdr
, rawlist
, sec_obj
->section
.offset
,
622 if (retval
!= sizeof (sec_hdr
)) {
627 hdrver
= GET_SECTION_HDR_VERSION
;
629 if ((sec_hdr
.headertag
!= SECTION_HDR_TAG
) &&
630 (hdrver
!= section
->version
)) {
634 /* size = section layout + total sizeof segment header */
635 size
= sizeof (sec_hdr
) + ((sec_hdr
.segmentcount
)
636 * sizeof (segment_layout_t
));
638 buffer
= alloca(size
);
639 if (buffer
== NULL
) {
643 /* segment header buffer */
644 seg_buf
= alloca(size
- sizeof (sec_hdr
));
645 if (seg_buf
== NULL
) {
649 /* read segment header */
650 retval
= raw_memcpy(seg_buf
, rawlist
,
651 sec_obj
->section
.offset
+ sizeof (sec_hdr
),
652 size
- sizeof (sec_hdr
));
654 if (retval
!= (size
- sizeof (sec_hdr
))) {
658 /* copy section header layout */
659 (void) memcpy(buffer
, &sec_hdr
, sizeof (sec_hdr
));
661 /* copy segment header layout */
662 (void) memcpy(buffer
+ sizeof (sec_hdr
), seg_buf
, size
-
666 retval
= verify_header_crc8(hdrver
, buffer
, size
);
667 if (retval
!= TRUE
) {
671 section
->version
= hdrver
;
672 sec_obj
->section
.version
= hdrver
;
674 seg_hdr
= (segment_layout_t
*)seg_buf
;
676 /* bug fix for frutool */
677 if (sec_hash
->u
.sec_obj
->seg_obj_list
!= NULL
) {
680 sec_obj
->num_of_segment
= 0;
682 for (count
= 0; count
< sec_hdr
.segmentcount
; count
++, seg_hdr
++) {
684 seg_hash
= create_segment_hash_object();
685 if (seg_hash
== NULL
) {
688 add_hashobject_to_hashtable(seg_hash
);
689 copy_segment_layout(&seg_hash
->u
.seg_obj
->segment
, seg_hdr
);
690 add_to_seg_object_list(sec_hash
, seg_hash
);
691 sec_obj
->num_of_segment
++;
698 fru_get_sections(container_hdl_t container
, section_t
*section
, int maxsec
,
703 hash_obj_t
*cont_object
;
704 hash_obj_t
*sec_hash
;
706 cont_object
= lookup_handle_object(container
, CONTAINER_TYPE
);
707 if (cont_object
== NULL
) {
711 if (cont_object
->u
.cont_obj
->num_of_section
> maxsec
) {
715 sec_hash
= cont_object
->u
.cont_obj
->sec_obj_list
;
716 if (sec_hash
== NULL
) {
720 for (count
= 0; count
< cont_object
->u
.cont_obj
->num_of_section
;
722 section
->version
= -1;
723 /* populate section_t */
724 if (get_section(g_raw
, sec_hash
, section
) == 0) {
728 sec_hash
= sec_hash
->u
.sec_obj
->next
;
735 get_checksum_crc(hash_obj_t
*seg_hash
, int data_size
)
740 hash_obj_t
*sec_hash
;
741 hash_obj_t
*pkt_hash
;
742 unsigned char *buffer
;
744 sec_hash
= lookup_handle_object(seg_hash
->u
.seg_obj
->section_hdl
,
746 if (sec_hash
== NULL
) {
747 return ((uint32_t)-1);
750 buffer
= alloca(data_size
);
751 if (buffer
== NULL
) {
752 return ((uint32_t)-1);
755 /* traverse the packet object list for all the tags and payload */
756 for (pkt_hash
= seg_hash
->u
.seg_obj
->pkt_obj_list
; pkt_hash
!= NULL
;
757 pkt_hash
= pkt_hash
->u
.pkt_obj
->next
) {
758 (void) memcpy(buffer
+ offset
, &pkt_hash
->u
.pkt_obj
->tag
,
759 pkt_hash
->u
.pkt_obj
->tag_size
);
760 offset
+= pkt_hash
->u
.pkt_obj
->tag_size
;
761 (void) memcpy(buffer
+ offset
, pkt_hash
->u
.pkt_obj
->payload
,
762 pkt_hash
->u
.pkt_obj
->paylen
);
763 offset
+= pkt_hash
->u
.pkt_obj
->paylen
;
766 protection
= sec_hash
->u
.sec_obj
->section
.protection
;
768 if (protection
== READ_ONLY_SECTION
) { /* read-only section */
769 crc
= compute_crc32(buffer
, data_size
);
770 } else { /* read/write section */
771 crc
= compute_checksum32(buffer
, data_size
);
773 return (crc
); /* computed crc */
778 get_packet(raw_list_t
*rawlist
, void *buffer
, int size
, int offset
)
782 retval
= raw_memcpy(buffer
, rawlist
, offset
, size
);
792 get_packets(hash_obj_t
*seg_hash
, raw_list_t
*rawlist
, int offset
, int length
)
803 hash_obj_t
*pkt_hash_obj
;
804 hash_obj_t
*sec_hash
;
805 fru_segdesc_t
*segdesc
;
806 fru_tagtype_t tagtype
;
809 retval
= get_packet(rawlist
, &tag
, sizeof (fru_tag_t
), offset
);
814 /* section hash object */
815 sec_hash
= lookup_handle_object(seg_hash
->u
.seg_obj
->section_hdl
,
818 if (sec_hash
== NULL
) {
822 seg_hash
->u
.seg_obj
->trailer_offset
= offset
;
825 while (data
[0] != SEG_TRAILER_TAG
) {
826 tagtype
= get_tag_type(&tag
); /* verify tag type */
831 tag_size
= get_tag_size(tagtype
);
832 if (tag_size
== -1) {
836 seg_limit
+= tag_size
;
837 if (seg_limit
> length
) {
841 paylen
= get_payload_length((void *)&tag
);
847 if (seg_limit
> length
) {
850 if ((offset
+ tag_size
+ paylen
) >
851 (sec_hash
->u
.sec_obj
->section
.offset
+
852 sec_hash
->u
.sec_obj
->section
.length
)) {
856 pkt_hash_obj
= create_packet_hash_object();
857 if (pkt_hash_obj
== NULL
) {
861 pkt_hash_obj
->u
.pkt_obj
->payload
= malloc(paylen
);
862 if (pkt_hash_obj
->u
.pkt_obj
->payload
== NULL
) {
869 retval
= raw_memcpy(pkt_hash_obj
->u
.pkt_obj
->payload
, rawlist
,
872 if (retval
!= paylen
) {
873 free(pkt_hash_obj
->u
.pkt_obj
->payload
);
878 /* don't change this */
879 pkt_hash_obj
->u
.pkt_obj
->tag
.raw_data
= 0;
880 (void) memcpy(&pkt_hash_obj
->u
.pkt_obj
->tag
, &tag
, tag_size
);
881 pkt_hash_obj
->u
.pkt_obj
->paylen
= paylen
;
882 pkt_hash_obj
->u
.pkt_obj
->tag_size
= tag_size
;
883 pkt_hash_obj
->u
.pkt_obj
->payload_offset
= offset
;
887 add_hashobject_to_hashtable(pkt_hash_obj
);
888 add_to_pkt_object_list(seg_hash
, pkt_hash_obj
);
892 retval
= get_packet(rawlist
, &tag
, sizeof (fru_tag_t
),
901 segdesc
= (fru_segdesc_t
*)&seg_hash
->u
.seg_obj
->segment
.descriptor
;
903 seg_hash
->u
.seg_obj
->trailer_offset
= offset
;
905 if (!segdesc
->field
.ignore_checksum
) {
906 crc
= get_checksum_crc(seg_hash
, seg_limit
);
907 offset
= seg_hash
->u
.seg_obj
->segment
.offset
;
909 retval
= raw_memcpy(&origcrc
, rawlist
, offset
+ seg_limit
+ 1,
912 ignore_flag
= getenv(IGNORE_CHECK
);
913 if (ignore_flag
!= NULL
) {
917 if (retval
!= sizeof (origcrc
)) {
921 origcrc
= BE_32(origcrc
);
922 if (origcrc
!= crc
) {
923 seg_hash
->u
.seg_obj
->trailer_offset
= offset
;
933 fru_get_num_sections(container_hdl_t container
, door_cred_t
*cred
)
935 hash_obj_t
*hash_object
;
937 hash_object
= lookup_handle_object(container
, CONTAINER_TYPE
);
938 if (hash_object
== NULL
) {
942 return (hash_object
->u
.cont_obj
->num_of_section
);
947 fru_get_num_segments(section_hdl_t section
, door_cred_t
*cred
)
949 hash_obj_t
*sec_object
;
950 section_obj_t
*sec_obj
;
952 sec_object
= lookup_handle_object(section
, SECTION_TYPE
);
953 if (sec_object
== NULL
) {
957 sec_obj
= sec_object
->u
.sec_obj
;
958 if (sec_obj
== NULL
) {
962 return (sec_obj
->num_of_segment
);
967 fru_get_num_packets(segment_hdl_t segment
, door_cred_t
*cred
)
972 hash_obj_t
*cont_hash_obj
;
973 hash_obj_t
*seg_hash
;
974 hash_obj_t
*sec_hash
;
975 fru_segdesc_t
*segdesc
;
976 segment_obj_t
*segment_object
;
978 seg_hash
= lookup_handle_object(segment
, SEGMENT_TYPE
);
979 if (seg_hash
== NULL
) {
983 segment_object
= seg_hash
->u
.seg_obj
;
984 if (segment_object
== NULL
) {
988 segdesc
= (fru_segdesc_t
*)&segment_object
->segment
.descriptor
;
989 if (segdesc
->field
.opaque
) {
993 offset
= segment_object
->segment
.offset
;
994 length
= segment_object
->segment
.length
;
996 cont_hash_obj
= get_container_hash_object(SEGMENT_TYPE
,
997 segment_object
->section_hdl
);
999 if (cont_hash_obj
== NULL
) {
1003 if (seg_hash
->u
.seg_obj
->pkt_obj_list
!= NULL
) {
1004 return (segment_object
->num_of_packets
);
1006 /* section hash object */
1007 sec_hash
= lookup_handle_object(seg_hash
->u
.seg_obj
->section_hdl
,
1009 if (sec_hash
== NULL
) {
1013 /* valid segment header b'cos crc8 already validated */
1014 if (offset
< sec_hash
->u
.sec_obj
->section
.offset
) {
1018 segment_object
->num_of_packets
= 0;
1020 pktcnt
= get_packets(seg_hash
, g_raw
, offset
, length
);
1022 free_pkt_object_list(seg_hash
);
1023 seg_hash
->u
.seg_obj
->pkt_obj_list
= NULL
;
1026 segment_object
->num_of_packets
= pktcnt
;
1028 return (segment_object
->num_of_packets
);
1033 fru_get_packets(segment_hdl_t segment
, packet_t
*packet
, int maxpackets
,
1037 hash_obj_t
*seg_hash_obj
;
1038 hash_obj_t
*pkt_hash_obj
;
1040 /* segment hash object */
1041 seg_hash_obj
= lookup_handle_object(segment
, SEGMENT_TYPE
);
1042 if (seg_hash_obj
== NULL
) {
1046 if (seg_hash_obj
->u
.seg_obj
->num_of_packets
!= maxpackets
) {
1050 pkt_hash_obj
= seg_hash_obj
->u
.seg_obj
->pkt_obj_list
;
1051 if (pkt_hash_obj
== NULL
) {
1055 for (count
= 0; count
< maxpackets
; count
++, packet
++) {
1056 packet
->handle
= pkt_hash_obj
->obj_hdl
;
1058 (void) memcpy(&packet
->tag
, &pkt_hash_obj
->u
.pkt_obj
->tag
,
1059 pkt_hash_obj
->u
.pkt_obj
->tag_size
);
1060 pkt_hash_obj
= pkt_hash_obj
->u
.pkt_obj
->next
;
1068 fru_get_payload(packet_hdl_t packet
, void *buffer
, size_t nbytes
,
1071 hash_obj_t
*packet_hash_obj
;
1073 /* packet hash object */
1074 packet_hash_obj
= lookup_handle_object(packet
, PACKET_TYPE
);
1075 if (packet_hash_obj
== NULL
) {
1079 /* verify payload length */
1080 if (nbytes
!= packet_hash_obj
->u
.pkt_obj
->paylen
) {
1084 (void) memcpy(buffer
, packet_hash_obj
->u
.pkt_obj
->payload
, nbytes
);
1090 open_raw_data(raw_list_t
*node
)
1092 char *cont_conf_file
= NULL
;
1093 hash_obj_t
*cont_hash_obj
;
1094 hash_obj_t
*sec_hash_obj
;
1095 container_info_t cont_info
;
1099 cont_hash_obj
= create_container_hash_object();
1100 if (cont_hash_obj
== NULL
) {
1104 add_hashobject_to_hashtable(cont_hash_obj
);
1106 (void) strncpy(cont_hash_obj
->u
.cont_obj
->device_pathname
, "unknown",
1107 sizeof (cont_hash_obj
->u
.cont_obj
->device_pathname
));
1109 cont_conf_file
= getenv(FRU_CONT_CONF_ENV_VAR
);
1110 if (cont_conf_file
== NULL
) {
1111 cont_conf_file
= FRU_CONT_CONF_SPARC
;
1112 retval
= get_container_info(cont_conf_file
, node
->cont_type
,
1115 cont_conf_file
= FRU_CONT_CONF_X86
;
1116 retval
= get_container_info(cont_conf_file
,
1117 node
->cont_type
, &cont_info
);
1120 retval
= get_container_info(cont_conf_file
, node
->cont_type
,
1128 cont_hash_obj
->u
.cont_obj
->num_of_section
= cont_info
.num_sections
;
1129 cont_hash_obj
->u
.cont_obj
->sec_obj_list
= NULL
;
1131 for (count
= 0; count
< cont_info
.num_sections
; count
++) {
1132 sec_hash_obj
= create_section_hash_object();
1133 if (sec_hash_obj
== NULL
) {
1137 add_hashobject_to_hashtable(sec_hash_obj
);
1139 sec_hash_obj
->u
.sec_obj
->section
.offset
=
1140 cont_info
.section_info
[count
].address
;
1142 sec_hash_obj
->u
.sec_obj
->section
.protection
=
1143 cont_info
.section_info
[count
].description
.field
.read_only
;
1145 sec_hash_obj
->u
.sec_obj
->section
.length
=
1146 cont_info
.section_info
[count
].size
;
1147 sec_hash_obj
->u
.sec_obj
->section
.version
=
1148 cont_info
.header_ver
;
1150 add_to_sec_object_list(cont_hash_obj
, sec_hash_obj
);
1153 return (cont_hash_obj
->obj_hdl
);
1158 fru_close_container(container_hdl_t container
)
1160 hash_obj_t
*hash_obj
;
1161 hash_obj_t
*prev_hash
;
1162 hash_obj_t
*sec_hash_obj
;
1165 /* lookup for container hash object */
1166 hash_obj
= lookup_handle_object(container
, CONTAINER_TYPE
);
1167 if (hash_obj
== NULL
) {
1171 /* points to section object list */
1172 sec_hash_obj
= hash_obj
->u
.cont_obj
->sec_obj_list
;
1174 /* traverse section object list */
1175 while (sec_hash_obj
!= NULL
) {
1177 /* traverse segment hash object in the section */
1178 while (sec_hash_obj
->u
.sec_obj
->seg_obj_list
!= NULL
) {
1179 /* object handle of the segment hash object */
1181 sec_hash_obj
->u
.sec_obj
->seg_obj_list
->obj_hdl
;
1182 free_segment_hash(obj_hdl
, sec_hash_obj
);
1185 /* going to free section hash object, relink the hash object */
1186 if (sec_hash_obj
->prev
== NULL
) {
1187 hash_table
[(sec_hash_obj
->obj_hdl
% TABLE_SIZE
)] =
1189 if (sec_hash_obj
->next
!= NULL
) {
1190 sec_hash_obj
->next
->prev
= NULL
;
1193 sec_hash_obj
->prev
->next
= sec_hash_obj
->next
;
1194 if (sec_hash_obj
->next
!= NULL
) {
1195 sec_hash_obj
->next
->prev
= sec_hash_obj
->prev
;
1199 prev_hash
= sec_hash_obj
;
1200 sec_hash_obj
= sec_hash_obj
->u
.sec_obj
->next
;
1202 free(prev_hash
->u
.sec_obj
); /* free section hash object */
1203 free(prev_hash
); /* free section hash */
1206 /* free container hash object */
1207 if (hash_obj
->prev
== NULL
) {
1208 hash_table
[(hash_obj
->obj_hdl
% TABLE_SIZE
)] =
1210 if (hash_obj
->next
!= NULL
) {
1211 hash_obj
->next
->prev
= NULL
;
1214 hash_obj
->prev
->next
= hash_obj
->next
;
1215 if (hash_obj
->next
!= NULL
) {
1216 hash_obj
->next
->prev
= hash_obj
->prev
;
1220 free(hash_obj
->u
.cont_obj
);