4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
33 #include "fru_access_impl.h"
35 #pragma init(initialize_fruaccess) /* .init section */
38 * This module translates all the frudata plugin requests into platform
39 * specific commands and provides information back to frudata plugin.
43 * precedence for format.
44 * define an ENV variable (SUNW_FRUACCESS_IPMI_PRECEDENCE) to make
45 * ipmi format has more precedence than sun format.
47 static int precedence
= SUN_FORMAT
; /* by default */
48 #define FRUACCESS_PRECEDENCE "SUNW_FRUACCESS_IPMI_PRECEDENCE"
50 extern ssize_t
pread_new(int, void *, size_t, off_t
, format_t
*);
51 extern ssize_t
pwrite_new(int, const void *, size_t, off_t
, format_t
*);
52 extern int get_manr(format_t
*, payload_t
*);
53 extern int is_fru_data_available(int, int, format_t
*);
54 extern picl_errno_t
fruaccess_platmod_init_format(uint8_t, format_t
*);
55 extern int fruaccess_platmod_check_chassis();
56 extern int fruaccess_platmod_check_fru(picl_nodehdl_t parenth
);
58 static container_hdl_t
sun_fru_open_container(picl_nodehdl_t
);
59 static int sun_fru_close_container(container_hdl_t
);
60 static int sun_fru_get_num_sections(container_hdl_t
, door_cred_t
*);
61 static int sun_fru_get_sections(container_hdl_t
, section_t
*,
63 static int sun_fru_get_num_segments(section_hdl_t
, door_cred_t
*);
64 static int sun_fru_get_segments(section_hdl_t
, segment_t
*,
66 static int sun_fru_add_segment(section_hdl_t
, segment_t
*,
67 section_hdl_t
*, door_cred_t
*);
68 static int sun_fru_delete_segment(segment_hdl_t
, section_hdl_t
*,
70 static ssize_t
sun_fru_read_segment(segment_hdl_t
, void *, size_t,
72 static int sun_fru_write_segment(segment_hdl_t
, const void *, size_t,
73 segment_hdl_t
*, door_cred_t
*);
74 static int sun_fru_get_num_packets(segment_hdl_t
, door_cred_t
*);
75 static int sun_fru_get_packets(segment_hdl_t
, packet_t
*,
77 static ssize_t
sun_fru_get_payload(packet_hdl_t
, void *, size_t,
79 static int sun_fru_update_payload(packet_hdl_t
, const void *, size_t,
80 packet_hdl_t
*, door_cred_t
*);
81 static int sun_fru_append_packet(segment_hdl_t
, packet_t
*,
82 const void *, size_t, segment_hdl_t
*,
84 static int sun_fru_delete_packet(packet_hdl_t
, segment_hdl_t
*, door_cred_t
*);
86 static container_hdl_t
ipmi_fru_open_container(picl_nodehdl_t
);
87 static int ipmi_fru_close_container(container_hdl_t
);
88 static int ipmi_fru_get_num_sections(container_hdl_t
, door_cred_t
*);
89 static int ipmi_fru_get_sections(container_hdl_t
, section_t
*,
91 static int ipmi_fru_get_num_segments(section_hdl_t
, door_cred_t
*);
92 static int ipmi_fru_get_segments(section_hdl_t
, segment_t
*,
94 static int ipmi_fru_add_segment(section_hdl_t
, segment_t
*,
95 section_hdl_t
*, door_cred_t
*);
96 static int ipmi_fru_delete_segment(segment_hdl_t
, section_hdl_t
*,
98 static ssize_t
ipmi_fru_read_segment(segment_hdl_t
, void *, size_t,
100 static int ipmi_fru_write_segment(segment_hdl_t
, const void *, size_t,
101 segment_hdl_t
*, door_cred_t
*);
102 static int ipmi_fru_get_num_packets(segment_hdl_t
, door_cred_t
*);
103 static int ipmi_fru_get_packets(segment_hdl_t
, packet_t
*,
105 static ssize_t
ipmi_fru_get_payload(packet_hdl_t
, void *, size_t,
107 static int ipmi_fru_update_payload(packet_hdl_t
, const void *, size_t,
108 packet_hdl_t
*, door_cred_t
*);
109 static int ipmi_fru_append_packet(segment_hdl_t
, packet_t
*,
110 const void *, size_t, segment_hdl_t
*,
112 static int ipmi_fru_delete_packet(packet_hdl_t
, segment_hdl_t
*, door_cred_t
*);
115 container_hdl_t (* open_container
)(picl_nodehdl_t
);
116 int (* close_container
)(container_hdl_t
);
117 int (* get_num_sections
)(container_hdl_t
, door_cred_t
*);
118 int (* get_sections
)(container_hdl_t
, section_t
*,
120 int (* get_num_segments
)(section_hdl_t
, door_cred_t
*);
121 int (* get_segments
)(section_hdl_t
, segment_t
*,
123 int (* add_segment
)(section_hdl_t
, segment_t
*,
124 section_hdl_t
*, door_cred_t
*);
125 int (* delete_segment
)(segment_hdl_t
, section_hdl_t
*,
127 ssize_t (* read_segment
)(segment_hdl_t
, void *, size_t,
129 int (* write_segment
)(segment_hdl_t
, const void *, size_t,
130 segment_hdl_t
*, door_cred_t
*);
131 int (* get_num_packets
)(segment_hdl_t
, door_cred_t
*);
132 int (* get_packets
)(segment_hdl_t
, packet_t
*,
134 ssize_t (* get_payload
)(packet_hdl_t
, void *, size_t,
136 int (* update_payload
)(packet_hdl_t
, const void *, size_t,
137 packet_hdl_t
*, door_cred_t
*);
138 int (* append_packet
)(segment_hdl_t
, packet_t
*,
139 const void *, size_t, segment_hdl_t
*,
141 int (* delete_packet
)(packet_hdl_t
, segment_hdl_t
*, door_cred_t
*);
142 } fruaccess_func_ptrs_t
;
144 static fruaccess_func_ptrs_t fruaccess_func
[2] = {
146 ipmi_fru_open_container
,
147 ipmi_fru_close_container
,
148 ipmi_fru_get_num_sections
,
149 ipmi_fru_get_sections
,
150 ipmi_fru_get_num_segments
,
151 ipmi_fru_get_segments
,
152 ipmi_fru_add_segment
,
153 ipmi_fru_delete_segment
,
154 ipmi_fru_read_segment
,
155 ipmi_fru_write_segment
,
156 ipmi_fru_get_num_packets
,
157 ipmi_fru_get_packets
,
158 ipmi_fru_get_payload
,
159 ipmi_fru_update_payload
,
160 ipmi_fru_append_packet
,
161 ipmi_fru_delete_packet
,
164 sun_fru_open_container
,
165 sun_fru_close_container
,
166 sun_fru_get_num_sections
,
167 sun_fru_get_sections
,
168 sun_fru_get_num_segments
,
169 sun_fru_get_segments
,
171 sun_fru_delete_segment
,
172 sun_fru_read_segment
,
173 sun_fru_write_segment
,
174 sun_fru_get_num_packets
,
177 sun_fru_update_payload
,
178 sun_fru_append_packet
,
179 sun_fru_delete_packet
,
183 static int is_valid_chassis
= -1;
184 static hash_obj_t
*hash_table
[TABLE_SIZE
];
187 initialize_fruaccess(void)
190 for (count
= 0; count
< TABLE_SIZE
; count
++) {
191 hash_table
[count
] = NULL
;
194 /* check if ipmi format has precedence */
195 if (getenv(FRUACCESS_PRECEDENCE
)) {
196 precedence
= IPMI_FORMAT
;
200 /* called to lookup hash object for specified handle in the hash table. */
202 lookup_handle_object(handle_t handle
, int object_type
)
204 handle_t index_to_hash
;
205 hash_obj_t
*first_hash_obj
;
206 hash_obj_t
*next_hash_obj
;
208 index_to_hash
= (handle
% TABLE_SIZE
);
210 first_hash_obj
= hash_table
[index_to_hash
];
211 for (next_hash_obj
= first_hash_obj
; next_hash_obj
!= NULL
;
212 next_hash_obj
= next_hash_obj
->next
) {
213 if ((handle
== next_hash_obj
->obj_hdl
) &&
214 (object_type
== next_hash_obj
->object_type
)) {
215 return (next_hash_obj
);
221 /* called to allocate container hash object */
223 create_container_hash_object(void)
225 hash_obj_t
*hash_obj
;
226 container_obj_t
*cont_obj
;
228 cont_obj
= malloc(sizeof (container_obj_t
));
229 if (cont_obj
== NULL
) {
233 hash_obj
= malloc(sizeof (hash_obj_t
));
234 if (hash_obj
== NULL
) {
239 cont_obj
->sec_obj_list
= NULL
;
241 hash_obj
->object_type
= CONTAINER_TYPE
;
242 hash_obj
->u
.cont_obj
= cont_obj
;
243 hash_obj
->next
= NULL
;
244 hash_obj
->prev
= NULL
;
249 /* called to allocate section hash object */
251 create_section_hash_object(void)
253 hash_obj_t
*hash_obj
;
254 section_obj_t
*sec_obj
;
256 sec_obj
= malloc(sizeof (section_obj_t
));
257 if (sec_obj
== NULL
) {
261 hash_obj
= malloc(sizeof (hash_obj_t
));
262 if (hash_obj
== NULL
) {
267 sec_obj
->next
= NULL
;
268 sec_obj
->seg_obj_list
= NULL
;
270 hash_obj
->u
.sec_obj
= sec_obj
;
271 hash_obj
->object_type
= SECTION_TYPE
;
272 hash_obj
->next
= NULL
;
273 hash_obj
->prev
= NULL
;
278 /* called to allocate segment hash object */
280 create_segment_hash_object(void)
282 hash_obj_t
*hash_obj
;
283 segment_obj_t
*seg_obj
;
285 seg_obj
= malloc(sizeof (segment_obj_t
));
286 if (seg_obj
== NULL
) {
290 hash_obj
= malloc(sizeof (hash_obj_t
));
291 if (hash_obj
== NULL
) {
296 seg_obj
->next
= NULL
;
297 seg_obj
->pkt_obj_list
= NULL
;
299 hash_obj
->object_type
= SEGMENT_TYPE
;
300 hash_obj
->u
.seg_obj
= seg_obj
;
301 hash_obj
->next
= NULL
;
302 hash_obj
->prev
= NULL
;
307 /* called to allocate packet hash object */
309 create_packet_hash_object(void)
311 hash_obj_t
*hash_obj
;
312 packet_obj_t
*pkt_obj
;
314 pkt_obj
= malloc(sizeof (packet_obj_t
));
315 if (pkt_obj
== NULL
) {
319 hash_obj
= malloc(sizeof (hash_obj_t
));
320 if (hash_obj
== NULL
) {
325 pkt_obj
->next
= NULL
;
327 hash_obj
->object_type
= PACKET_TYPE
;
328 hash_obj
->u
.pkt_obj
= pkt_obj
;
329 hash_obj
->next
= NULL
;
330 hash_obj
->prev
= NULL
;
335 /* called to add allocated hash object into the hash table */
337 add_hashobject_to_hashtable(hash_obj_t
*hash_obj
, int object_type
)
339 handle_t index_to_hash
;
340 static uint64_t handle_count
= 0;
342 if (object_type
!= CONTAINER_TYPE
) {
343 hash_obj
->obj_hdl
= ++handle_count
;
347 index_to_hash
= ((hash_obj
->obj_hdl
) % TABLE_SIZE
);
349 hash_obj
->next
= hash_table
[index_to_hash
];
350 hash_table
[index_to_hash
] = hash_obj
; /* hash obj. added */
352 if (hash_obj
->next
!= NULL
) {
353 hash_obj
->next
->prev
= hash_obj
;
357 /* called to add section object list into the section list */
359 add_to_sec_object_list(hash_obj_t
*parent_obj
, hash_obj_t
*child_obj
)
361 hash_obj_t
*next_hash
;
363 child_obj
->u
.sec_obj
->cont_hdl
= parent_obj
->obj_hdl
;
364 if (parent_obj
->u
.cont_obj
->sec_obj_list
== NULL
) {
365 parent_obj
->u
.cont_obj
->sec_obj_list
= child_obj
;
369 for (next_hash
= parent_obj
->u
.cont_obj
->sec_obj_list
;
370 next_hash
->u
.sec_obj
->next
!= NULL
;
371 next_hash
= next_hash
->u
.sec_obj
->next
) {
375 next_hash
->u
.sec_obj
->next
= child_obj
;
378 /* called to add segment object list into segment list */
380 add_to_seg_object_list(hash_obj_t
*parent_obj
, hash_obj_t
*child_obj
)
382 hash_obj_t
*next_hash
;
384 child_obj
->u
.seg_obj
->section_hdl
= parent_obj
->obj_hdl
;
385 if (parent_obj
->u
.sec_obj
->seg_obj_list
== NULL
) {
386 parent_obj
->u
.sec_obj
->seg_obj_list
= child_obj
;
390 for (next_hash
= parent_obj
->u
.sec_obj
->seg_obj_list
;
391 next_hash
->u
.seg_obj
->next
!= NULL
;
392 next_hash
= next_hash
->u
.seg_obj
->next
) {
396 next_hash
->u
.seg_obj
->next
= child_obj
;
399 /* called to add packet object list into packet list */
401 add_to_pkt_object_list(hash_obj_t
*parent_obj
, hash_obj_t
*child_obj
)
403 hash_obj_t
*next_hash
;
405 /* add the packet object in the end of list */
406 child_obj
->u
.pkt_obj
->segment_hdl
= parent_obj
->obj_hdl
;
408 if (parent_obj
->u
.seg_obj
->pkt_obj_list
== NULL
) {
409 parent_obj
->u
.seg_obj
->pkt_obj_list
= child_obj
;
413 for (next_hash
= parent_obj
->u
.seg_obj
->pkt_obj_list
;
414 next_hash
->u
.pkt_obj
->next
!= NULL
;
415 next_hash
= next_hash
->u
.pkt_obj
->next
) {
419 next_hash
->u
.pkt_obj
->next
= child_obj
;
422 /* fill the information, payload in the conatiner */
425 initialize_ipmi_container(picl_nodehdl_t fru
, hash_obj_t
*cont_hash_obj
)
428 hash_obj_t
*seg_hash_obj
, *sec_hash_obj
, *pkt_hash_obj
;
431 format
= cont_hash_obj
->u
.cont_obj
->format
;
432 /* plug to SMC driver to fetch the data */
433 if (get_manr(&format
, &manr
) != 0) {
437 cont_hash_obj
->u
.cont_obj
->num_of_section
= 1;
438 cont_hash_obj
->u
.cont_obj
->sec_obj_list
= NULL
;
440 sec_hash_obj
= create_section_hash_object();
441 if (sec_hash_obj
== NULL
) {
445 add_hashobject_to_hashtable(sec_hash_obj
, SECTION_TYPE
);
447 /* create fake section info here */
448 sec_hash_obj
->u
.sec_obj
->num_of_segment
= 1;
449 sec_hash_obj
->u
.sec_obj
->section
.handle
= sec_hash_obj
->obj_hdl
;
450 sec_hash_obj
->u
.sec_obj
->section
.offset
= 0;
451 sec_hash_obj
->u
.sec_obj
->section
.protection
= READ_ONLY_SECTION
;
453 sec_hash_obj
->u
.sec_obj
->section
.length
= STATIC_LENGTH
;
454 sec_hash_obj
->u
.sec_obj
->section
.version
= SECTION_HDR_VER
;
455 add_to_sec_object_list(cont_hash_obj
, sec_hash_obj
);
457 seg_hash_obj
= create_segment_hash_object();
458 if (seg_hash_obj
== NULL
) {
462 add_hashobject_to_hashtable(seg_hash_obj
, SEGMENT_TYPE
);
464 seg_hash_obj
->u
.seg_obj
->num_of_packets
= 1;
465 seg_hash_obj
->u
.seg_obj
->segment
.handle
= seg_hash_obj
->obj_hdl
;
466 (void) strncpy(seg_hash_obj
->u
.seg_obj
->segment
.name
,
468 sizeof (seg_hash_obj
->u
.seg_obj
->segment
.name
));
469 seg_hash_obj
->u
.seg_obj
->segment
.descriptor
= SD_SEGMENT_DESCRIPTOR
;
471 seg_hash_obj
->u
.seg_obj
->segment
.length
= MANR_SIZE
+
472 SEGMENT_TRAILER_LEN
+ SEGMENT_CHKSM_LEN
;
473 add_to_seg_object_list(sec_hash_obj
, seg_hash_obj
);
475 pkt_hash_obj
= create_packet_hash_object();
476 if (pkt_hash_obj
== NULL
) {
479 add_hashobject_to_hashtable(pkt_hash_obj
, PACKET_TYPE
);
481 pkt_hash_obj
->u
.pkt_obj
->payload_data
= manr
;
482 if (mk_tag(FRU_F
, 0x001, 0x0B7, &pkt_hash_obj
->u
.pkt_obj
->tag
) == 4) {
483 add_to_pkt_object_list(seg_hash_obj
, pkt_hash_obj
);
488 /* Look up the container_hdl in the PICL tree. */
489 static container_hdl_t
490 ipmi_fru_open_container(picl_nodehdl_t fruh
)
493 hash_obj_t
*cont_hash_obj
;
495 err
= ptree_get_propval_by_name(fruh
, PICL_PROP_FRUDATA_AVAIL
,
497 if (err
!= PICL_SUCCESS
) {
501 cont_hash_obj
= lookup_handle_object((handle_t
)fruh
, CONTAINER_TYPE
);
502 if (cont_hash_obj
== NULL
) {
506 /* initialize the container */
507 if (initialize_ipmi_container(fruh
, cont_hash_obj
) != 0) {
510 return (cont_hash_obj
->obj_hdl
);
515 ipmi_fru_get_num_sections(container_hdl_t container
, door_cred_t
*cred
)
517 hash_obj_t
*cont_hash_obj
;
519 cont_hash_obj
= lookup_handle_object((handle_t
)container
,
521 if (cont_hash_obj
== NULL
) {
524 return (cont_hash_obj
->u
.cont_obj
->num_of_section
);
529 ipmi_fru_get_sections(container_hdl_t container
, section_t
*section
,
530 int max_sections
, door_cred_t
*cred
)
533 hash_obj_t
*cont_object
;
534 hash_obj_t
*sec_hash
;
536 cont_object
= lookup_handle_object((handle_t
)container
,
538 if (cont_object
== NULL
) {
542 if (cont_object
->u
.cont_obj
->num_of_section
> max_sections
) {
545 sec_hash
= cont_object
->u
.cont_obj
->sec_obj_list
;
547 for (count
= 0; count
< cont_object
->u
.cont_obj
->num_of_section
&&
548 sec_hash
!= NULL
; count
++, section
++) {
549 /* populate section_t */
550 section
->handle
= sec_hash
->u
.sec_obj
->section
.handle
;
551 section
->offset
= sec_hash
->u
.sec_obj
->section
.offset
;
552 section
->length
= sec_hash
->u
.sec_obj
->section
.length
;
553 section
->protection
= sec_hash
->u
.sec_obj
->section
.protection
;
554 section
->version
= sec_hash
->u
.sec_obj
->section
.version
;
555 sec_hash
= sec_hash
->u
.sec_obj
->next
;
562 ipmi_fru_get_num_segments(section_hdl_t section
, door_cred_t
*cred
)
564 hash_obj_t
*sec_object
;
566 sec_object
= lookup_handle_object((handle_t
)section
, SECTION_TYPE
);
567 if (sec_object
== NULL
) {
570 return (sec_object
->u
.sec_obj
->num_of_segment
);
575 ipmi_fru_get_segments(section_hdl_t section
, segment_t
*segment
,
576 int max_segments
, door_cred_t
*cred
)
579 hash_obj_t
*seg_hash
;
580 hash_obj_t
*sec_object
;
582 sec_object
= lookup_handle_object((handle_t
)section
, SECTION_TYPE
);
583 if (sec_object
== NULL
) {
587 if (sec_object
->u
.sec_obj
->num_of_segment
> max_segments
) {
591 seg_hash
= sec_object
->u
.sec_obj
->seg_obj_list
;
593 for (count
= 0; count
< sec_object
->u
.sec_obj
->num_of_segment
&&
594 seg_hash
!= NULL
; count
++, segment
++) {
595 /* populate the segment info */
596 segment
->handle
= seg_hash
->u
.seg_obj
->segment
.handle
;
597 (void) memcpy(segment
->name
, seg_hash
->u
.seg_obj
->segment
.name
,
599 segment
->descriptor
= seg_hash
->u
.seg_obj
->segment
.descriptor
;
600 segment
->offset
= seg_hash
->u
.seg_obj
->segment
.offset
;
601 segment
->length
= seg_hash
->u
.seg_obj
->segment
.length
;
602 seg_hash
= seg_hash
->u
.seg_obj
->next
;
609 ipmi_fru_get_num_packets(segment_hdl_t segment
, door_cred_t
*cred
)
611 hash_obj_t
*seg_object
;
613 seg_object
= lookup_handle_object((handle_t
)segment
, SEGMENT_TYPE
);
614 if (seg_object
== NULL
) {
617 return (seg_object
->u
.seg_obj
->num_of_packets
);
622 ipmi_fru_get_packets(segment_hdl_t segment
, packet_t
*packet
,
623 int max_packets
, door_cred_t
*cred
)
626 hash_obj_t
*pkt_hash
;
627 hash_obj_t
*seg_object
;
629 seg_object
= lookup_handle_object((handle_t
)segment
, SEGMENT_TYPE
);
630 if (seg_object
== NULL
) {
634 if (seg_object
->u
.seg_obj
->num_of_packets
> max_packets
) {
638 pkt_hash
= seg_object
->u
.seg_obj
->pkt_obj_list
;
640 for (count
= 0; count
< seg_object
->u
.seg_obj
->num_of_packets
&&
641 pkt_hash
!= NULL
; count
++, packet
++) {
642 /* populate the segment info */
643 packet
->handle
= pkt_hash
->obj_hdl
;
644 (void) memcpy(&packet
->tag
, &pkt_hash
->u
.pkt_obj
->tag
, 4);
645 pkt_hash
= pkt_hash
->u
.pkt_obj
->next
;
653 ipmi_fru_read_segment(segment_hdl_t segment
, void *buffer
, size_t nbytes
,
656 hash_obj_t
*seg_hash
;
657 hash_obj_t
*pkt_hash
;
659 /* segment hash object */
660 seg_hash
= lookup_handle_object(segment
, SEGMENT_TYPE
);
661 if (seg_hash
== NULL
) {
665 if (seg_hash
->u
.seg_obj
->segment
.length
< nbytes
) {
669 pkt_hash
= seg_hash
->u
.seg_obj
->pkt_obj_list
;
671 if (pkt_hash
== NULL
) {
675 (void) memcpy(buffer
, &pkt_hash
->u
.pkt_obj
->payload_data
,
682 ipmi_fru_get_payload(packet_hdl_t packet
, void *buffer
, size_t nbytes
,
685 hash_obj_t
*packet_hash_obj
;
687 /* size = size of ManR */
688 if (nbytes
!= MANR_SIZE
) {
692 /* packet hash object */
693 packet_hash_obj
= lookup_handle_object(packet
, PACKET_TYPE
);
694 if (packet_hash_obj
== NULL
) {
698 (void) memcpy(buffer
, &(packet_hash_obj
->u
.pkt_obj
->payload_data
),
705 ipmi_fru_add_segment(section_hdl_t section
, segment_t
*segment
,
706 section_hdl_t
*newsection
, door_cred_t
*cred
)
714 ipmi_fru_delete_segment(segment_hdl_t segment
,
715 section_hdl_t
*newsection
, door_cred_t
*cred
)
724 ipmi_fru_write_segment(segment_hdl_t segment
, const void *data
,
725 size_t nbytes
, segment_hdl_t
*newsegment
, door_cred_t
*cred
)
733 ipmi_fru_update_payload(packet_hdl_t packet
, const void *data
,
734 size_t nbytes
, packet_hdl_t
*newpacket
, door_cred_t
*cred
)
742 ipmi_fru_append_packet(segment_hdl_t segment
, packet_t
*packet
,
743 const void *payload
, size_t nbytes
, segment_hdl_t
*newsegment
,
752 ipmi_fru_delete_packet(packet_hdl_t packet
,
753 segment_hdl_t
*newsegment
, door_cred_t
*cred
)
760 free_pkt_object_list(hash_obj_t
*hash_obj
)
762 hash_obj_t
*next_obj
;
763 hash_obj_t
*free_obj
;
765 next_obj
= hash_obj
->u
.seg_obj
->pkt_obj_list
;
766 while (next_obj
!= NULL
) {
768 next_obj
= next_obj
->u
.pkt_obj
->next
;
769 /* if prev is NULL it's the first object in the list */
770 if (free_obj
->prev
== NULL
) {
771 hash_table
[(free_obj
->obj_hdl
% TABLE_SIZE
)] =
773 if (free_obj
->next
!= NULL
) {
774 free_obj
->next
->prev
= free_obj
->prev
;
777 free_obj
->prev
->next
= free_obj
->next
;
778 if (free_obj
->next
!= NULL
) {
779 free_obj
->next
->prev
= free_obj
->prev
;
783 free(free_obj
->u
.pkt_obj
);
787 hash_obj
->u
.seg_obj
->pkt_obj_list
= NULL
;
791 free_segment_hash(handle_t handle
, hash_obj_t
*sec_hash
)
793 hash_obj_t
*seg_hash
;
794 hash_obj_t
*next_hash
;
796 seg_hash
= sec_hash
->u
.sec_obj
->seg_obj_list
;
797 if (seg_hash
== NULL
) {
801 if (seg_hash
->obj_hdl
== handle
) {
802 sec_hash
->u
.sec_obj
->seg_obj_list
= seg_hash
->u
.seg_obj
->next
;
804 while (seg_hash
->obj_hdl
!= handle
) {
805 next_hash
= seg_hash
;
806 seg_hash
= seg_hash
->u
.seg_obj
->next
;
807 if (seg_hash
== NULL
) {
811 next_hash
->u
.seg_obj
->next
= seg_hash
->u
.seg_obj
->next
;
814 if (seg_hash
->prev
== NULL
) {
815 hash_table
[(seg_hash
->obj_hdl
% TABLE_SIZE
)] = seg_hash
->next
;
816 if (seg_hash
->next
!= NULL
) {
817 seg_hash
->next
->prev
= NULL
;
820 seg_hash
->prev
->next
= seg_hash
->next
;
821 if (seg_hash
->next
!= NULL
) {
822 seg_hash
->next
->prev
= seg_hash
->prev
;
826 free_pkt_object_list(seg_hash
);
827 free(seg_hash
->u
.seg_obj
);
832 ipmi_fru_close_container(container_hdl_t container
)
834 hash_obj_t
*hash_obj
;
835 hash_obj_t
*prev_hash
;
836 hash_obj_t
*sec_hash_obj
;
839 /* lookup for container hash object */
840 hash_obj
= lookup_handle_object(container
, CONTAINER_TYPE
);
841 if (hash_obj
== NULL
) {
845 /* points to section object list */
846 sec_hash_obj
= hash_obj
->u
.cont_obj
->sec_obj_list
;
848 /* traverse section object list */
849 while (sec_hash_obj
!= NULL
) {
851 /* traverse segment hash object in the section */
852 while (sec_hash_obj
->u
.sec_obj
->seg_obj_list
!= NULL
) {
853 /* object handle of the segment hash object */
855 sec_hash_obj
->u
.sec_obj
->seg_obj_list
->obj_hdl
;
856 free_segment_hash(obj_hdl
, sec_hash_obj
);
859 /* going to free section hash object, relink the hash object */
860 if (sec_hash_obj
->prev
== NULL
) {
861 hash_table
[(sec_hash_obj
->obj_hdl
% TABLE_SIZE
)]
862 = sec_hash_obj
->next
;
863 if (sec_hash_obj
->next
!= NULL
) {
864 sec_hash_obj
->next
->prev
= NULL
;
867 sec_hash_obj
->prev
->next
= sec_hash_obj
->next
;
868 if (sec_hash_obj
->next
!= NULL
) {
869 sec_hash_obj
->next
->prev
= sec_hash_obj
->prev
;
873 free(sec_hash_obj
->u
.sec_obj
); /* free section hash object */
875 prev_hash
= sec_hash_obj
;
877 sec_hash_obj
= sec_hash_obj
->u
.sec_obj
->next
;
879 free(prev_hash
); /* free section hash */
882 /* free container hash object */
883 if (hash_obj
->prev
== NULL
) {
884 hash_table
[(sec_hash_obj
->obj_hdl
% TABLE_SIZE
)] =
886 if (hash_obj
->next
!= NULL
) {
887 hash_obj
->next
->prev
= NULL
;
890 hash_obj
->prev
->next
= hash_obj
->next
;
891 if (hash_obj
->next
!= NULL
) {
892 hash_obj
->next
->prev
= hash_obj
->prev
;
896 free(hash_obj
->u
.cont_obj
);
901 /* opens the binary file and returns the file descriptor */
907 if ((fd
= open(INPUT_FILE
, O_RDWR
)) == -1) {
914 copy_segment_layout(segment_t
*seghdr
, void *layout
)
916 segment_layout_t
*seg_layout
;
918 seg_layout
= (segment_layout_t
*)layout
;
919 (void) memcpy(seghdr
->name
, &seg_layout
->name
, SEG_NAME_LEN
);
920 seghdr
->descriptor
= GET_SEGMENT_DESCRIPTOR
;
921 seghdr
->offset
= seg_layout
->offset
;
922 seghdr
->length
= seg_layout
->length
;
926 get_container_hash_object(int object_type
, handle_t handle
)
928 hash_obj_t
*hash_obj
;
930 switch (object_type
) {
931 case CONTAINER_TYPE
:
935 hash_obj
= lookup_handle_object(handle
, CONTAINER_TYPE
);
936 if (hash_obj
== NULL
) {
941 hash_obj
= lookup_handle_object(handle
, SECTION_TYPE
);
942 if (hash_obj
== NULL
) {
945 hash_obj
= lookup_handle_object(hash_obj
->u
.sec_obj
->cont_hdl
,
950 hash_obj
= lookup_handle_object(handle
, SEGMENT_TYPE
);
951 if (hash_obj
== NULL
) {
954 hash_obj
= lookup_handle_object(
955 hash_obj
->u
.seg_obj
->section_hdl
, SECTION_TYPE
);
956 if (hash_obj
== NULL
) {
959 hash_obj
= lookup_handle_object(hash_obj
->u
.sec_obj
->cont_hdl
,
969 sort_offsettbl(int segcnt
, seg_info_t
*offset_tbl
)
975 for (cntx
= 0; cntx
< segcnt
+2; cntx
++) {
976 for (cnty
= cntx
+1; cnty
< segcnt
+ 2; cnty
++) {
977 if (offset_tbl
[cntx
].offset
>
978 offset_tbl
[cnty
].offset
) {
979 (void) memcpy(&tmp
, &offset_tbl
[cnty
],
980 sizeof (seg_info_t
));
981 (void) memcpy(&offset_tbl
[cnty
],
983 sizeof (seg_info_t
));
985 (void) memcpy(&offset_tbl
[cntx
], &tmp
,
986 sizeof (seg_info_t
));
993 * Description : move_segment_data() reads the segment data and writes it
994 * back to the new segment offset.
998 move_segment_data(void *seghdr
, int newoffset
, container_hdl_t contfd
)
1002 segment_layout_t
*segment
;
1004 hash_obj_t
*cont_hash
;
1006 segment
= (segment_layout_t
*)seghdr
;
1008 buffer
= alloca(segment
->length
);
1009 if (buffer
== NULL
) {
1013 cont_hash
= lookup_handle_object((handle_t
)contfd
, CONTAINER_TYPE
);
1014 if (cont_hash
== NULL
) {
1018 format
= cont_hash
->u
.cont_obj
->format
;
1020 ret
= pread_new(contfd
, buffer
,
1021 segment
->length
, segment
->offset
, &format
);
1022 if (ret
!= segment
->length
) {
1026 segment
->offset
= newoffset
;
1028 ret
= pwrite_new(contfd
, buffer
, segment
->length
, segment
->offset
,
1030 if (ret
!= segment
->length
) {
1036 * Description : pack_segment_data() moves the segment data if there is
1037 * a hole between two segments.
1041 pack_segment_data(char *seghdr
, int segcnt
, container_hdl_t contfd
,
1042 seg_info_t
*offset_tbl
)
1048 for (cnt
= segcnt
+ 1; cnt
> 0; cnt
--) {
1049 if (!offset_tbl
[cnt
- 1].fixed
) {
1050 if (offset_tbl
[cnt
].offset
1051 - (offset_tbl
[cnt
-1 ].offset
1052 + offset_tbl
[cnt
- 1].length
) > 0) {
1054 diff
= offset_tbl
[cnt
].offset
-
1055 (offset_tbl
[cnt
- 1].offset
1056 + offset_tbl
[cnt
- 1].length
);
1057 newoffset
= offset_tbl
[cnt
- 1].offset
1060 move_segment_data(seghdr
, newoffset
,
1063 offset_tbl
[cnt
- 1].offset
= newoffset
;
1065 sort_offsettbl(segcnt
, offset_tbl
);
1072 * Description : build_offset_tbl() builds the offset table by reading all the
1073 * segment header. it makes two more entry into the table one for
1074 * section size and another with start of the section after the
1079 build_offset_tbl(void *seghdr
, int segcnt
, int secsize
,
1080 seg_info_t
*offset_tbl
)
1083 fru_segdesc_t segdesc
;
1084 segment_layout_t
*segment
;
1086 for (cnt
= 0; cnt
< segcnt
; cnt
++) {
1087 segment
= (segment_layout_t
*)(seghdr
) + cnt
;
1089 (void) memcpy(&segdesc
, &segment
->descriptor
,
1091 offset_tbl
[cnt
].segnum
= cnt
;
1092 offset_tbl
[cnt
].offset
= segment
->offset
;
1093 offset_tbl
[cnt
].length
= segment
->length
;
1094 offset_tbl
[cnt
].fixed
= segdesc
.field
.fixed
;
1097 /* upper boundary of segment area (lower address bytes) */
1098 offset_tbl
[cnt
].segnum
= -1;
1099 offset_tbl
[cnt
].offset
= sizeof (section_layout_t
) + ((cnt
+ 1)
1100 * sizeof (segment_layout_t
));
1102 offset_tbl
[cnt
].length
= 0;
1103 offset_tbl
[cnt
].fixed
= 1;
1104 /* lower boundary of segment area (higher address bytes) */
1106 offset_tbl
[cnt
+1].segnum
= -1;
1107 offset_tbl
[cnt
+1].offset
= secsize
;
1108 offset_tbl
[cnt
+1].length
= 0;
1109 offset_tbl
[cnt
+1].fixed
= 1;
1114 hole_discovery(int bytes
, int segcnt
, int *totsize
, seg_info_t
*offset_tbl
)
1119 for (cnt
= segcnt
+ 1; cnt
> 0; cnt
--) {
1120 if (bytes
<= offset_tbl
[cnt
].offset
-
1121 (offset_tbl
[cnt
- 1].offset
+
1122 offset_tbl
[cnt
- 1].length
)) {
1123 return (offset_tbl
[cnt
].offset
- bytes
);
1126 *totsize
+= offset_tbl
[cnt
].offset
-
1127 (offset_tbl
[cnt
- 1].offset
+
1128 offset_tbl
[cnt
- 1].length
);
1135 * Description : segment_hdr_present() verify space for new segment header to
1140 segment_hdr_present(int segoffset
, int size
, seg_info_t
*offset_tbl
)
1142 if ((segoffset
+ size
) <= offset_tbl
[0].offset
)
1149 * Description : find_offset() is called from fru_add_segment routine to find
1154 find_offset(char *seghdr
, int segcnt
, int secsize
, int *sectionoffset
,
1155 int segsize
, int fix
, container_hdl_t contfd
)
1160 seg_info_t
*offset_tbl
;
1163 if (!fix
) { /* if not fixed segment */
1164 *sectionoffset
= secsize
- segsize
;
1170 * two extra segment info structure are allocated for start of segment
1171 * and other end of segment. first segment offset is first available
1172 * space and length is 0. second segment offset is is segment length and
1173 * offset is 0. build_offset_tbl() explains how upper boundary and lower
1174 * boudary segment area are initialized in seg_info_t table.
1177 offset_tbl
= malloc((segcnt
+ 2) * sizeof (seg_info_t
));
1178 if (offset_tbl
== NULL
) {
1182 /* read all the segment header to make offset table */
1183 ret
= build_offset_tbl(seghdr
, segcnt
, secsize
, offset_tbl
);
1189 /* sort the table */
1190 sort_offsettbl(segcnt
, offset_tbl
);
1192 /* new segment header offset */
1193 newoffset
= sizeof (section_layout_t
) + segcnt
*
1194 sizeof (segment_layout_t
);
1196 /* do? new segment header overlap any existing data */
1197 ret
= segment_hdr_present(newoffset
, sizeof (segment_layout_t
),
1199 if (ret
!= 0) { /* make room for new segment if possible */
1201 /* look for hole in order to move segment data */
1202 if (offset_tbl
[0].fixed
== SEGMENT_FIXED
) { /* fixed segment */
1207 newoffset
= hole_discovery(offset_tbl
[0].length
,
1208 segcnt
, &totsize
, offset_tbl
);
1209 if (newoffset
!= 0) { /* found new offset */
1210 /* now new offset */
1211 offset_tbl
[0].offset
= newoffset
;
1213 /* move the segment data */
1214 move_segment_data(seghdr
, newoffset
, contfd
);
1215 /* again sort the offset table */
1216 sort_offsettbl(segcnt
, offset_tbl
);
1218 /* pack the existing hole */
1219 if (totsize
> offset_tbl
[0].length
) {
1220 pack_segment_data(seghdr
, segcnt
,
1221 contfd
, offset_tbl
);
1230 newoffset
= hole_discovery(segsize
, segcnt
, &totsize
, offset_tbl
);
1232 if (newoffset
== 0) { /* No hole found */
1233 if (totsize
>= segsize
) {
1234 pack_segment_data(seghdr
, segcnt
, contfd
,
1236 newoffset
= hole_discovery(segsize
, segcnt
,
1237 &totsize
, offset_tbl
);
1238 if (newoffset
!= 0) {
1239 *sectionoffset
= newoffset
;
1245 *sectionoffset
= newoffset
;
1254 * Description :sun_fru_open_container() opens the container associated with
1255 * a fru. it's called by data plugin module before creating
1256 * container property. it calls picltree library routine to get
1257 * the device path and driver binding name for the fru to get the
1258 * corresponding fru name that describe the fru layout.
1260 * Arguments :picl_hdl_t fru
1261 * A handle for PICL tree node of class "fru" representing the
1262 * FRU with the container to open.
1265 * On Success, a Positive integer container handle. is returned
1266 * for use in subsequent fru operations;on error, 0 is returned
1267 * and "errno" is set appropriately.
1269 static container_hdl_t
1270 sun_fru_open_container(picl_nodehdl_t fruhdl
)
1273 hash_obj_t
*cont_hash_obj
;
1274 hash_obj_t
*sec_hash_obj
;
1276 cont_hash_obj
= lookup_handle_object((handle_t
)fruhdl
, CONTAINER_TYPE
);
1277 if (cont_hash_obj
== NULL
) {
1281 cont_hash_obj
->u
.cont_obj
->num_of_section
= NUM_OF_SECTIONS
;
1282 cont_hash_obj
->u
.cont_obj
->sec_obj_list
= NULL
;
1284 for (count
= 0; count
< NUM_OF_SECTIONS
; count
++) {
1285 sec_hash_obj
= create_section_hash_object();
1286 if (sec_hash_obj
== NULL
) {
1290 add_hashobject_to_hashtable(sec_hash_obj
, SECTION_TYPE
);
1293 sec_hash_obj
->u
.sec_obj
->section
.offset
=
1295 sec_hash_obj
->u
.sec_obj
->section
.protection
=
1297 sec_hash_obj
->u
.sec_obj
->section
.length
=
1300 sec_hash_obj
->u
.sec_obj
->section
.offset
= STATIC_OFFSET
;
1301 sec_hash_obj
->u
.sec_obj
->section
.protection
=
1303 sec_hash_obj
->u
.sec_obj
->section
.length
= STATIC_LENGTH
;
1306 sec_hash_obj
->u
.sec_obj
->section
.version
= SECTION_HDR_VER
;
1308 add_to_sec_object_list(cont_hash_obj
, sec_hash_obj
);
1311 return (cont_hash_obj
->obj_hdl
);
1315 verify_header_crc8(headerrev_t head_ver
, unsigned char *bytes
, int length
)
1318 unsigned char orig_crc8
= 0;
1319 unsigned char calc_crc8
= 0;
1322 case SECTION_HDR_VER
:
1330 orig_crc8
= bytes
[crc_offset
];
1331 bytes
[crc_offset
] = 0x00; /* clear for calc */
1332 calc_crc8
= compute_crc8(bytes
, length
);
1333 bytes
[crc_offset
] = orig_crc8
; /* restore */
1335 return (orig_crc8
== calc_crc8
);
1340 * sun_fru_get_num_sections() returns number of sections in a
1341 * container. it calls get_container_index() to get the container
1342 * index number in the container list.
1345 * container_hdl_t : container handle.
1349 * On success, returns number of sections in a container.
1354 sun_fru_get_num_sections(container_hdl_t container
, door_cred_t
*cred
)
1356 hash_obj_t
*hash_object
;
1358 hash_object
= lookup_handle_object(container
, CONTAINER_TYPE
);
1359 if (hash_object
== NULL
) {
1363 return (hash_object
->u
.cont_obj
->num_of_section
);
1367 * called from fru_get_sections()
1371 get_section(int fd
, hash_obj_t
*sec_hash
, section_t
*section
)
1377 hash_obj_t
*seg_hash
;
1378 unsigned char *buffer
;
1379 section_obj_t
*sec_obj
;
1380 section_layout_t sec_hdr
;
1381 segment_layout_t
*seg_hdr
;
1382 segment_layout_t
*seg_buf
;
1384 hash_obj_t
*cont_hash
;
1386 sec_obj
= sec_hash
->u
.sec_obj
;
1387 if (sec_obj
== NULL
) {
1391 /* populate section_t */
1392 section
->handle
= sec_hash
->obj_hdl
;
1393 section
->offset
= sec_obj
->section
.offset
;
1394 section
->length
= sec_obj
->section
.length
;
1395 section
->protection
= sec_obj
->section
.protection
;
1396 section
->version
= sec_obj
->section
.version
;
1397 sec_obj
->num_of_segment
= 0;
1399 cont_hash
= get_container_hash_object(SEGMENT_TYPE
, sec_hash
->obj_hdl
);
1400 if (cont_hash
== NULL
) {
1404 format
= cont_hash
->u
.cont_obj
->format
;
1406 /* read section header layout */
1407 retval
= pread_new(fd
, &sec_hdr
, sizeof (sec_hdr
),
1408 sec_obj
->section
.offset
, &format
);
1409 if (retval
!= sizeof (sec_hdr
)) {
1413 hdrver
= GET_SECTION_HDR_VERSION
;
1415 if ((sec_hdr
.headertag
!= SECTION_HDR_TAG
) &&
1416 (hdrver
!= section
->version
)) {
1420 /* size = section layout + total sizeof segment header */
1421 size
= sizeof (sec_hdr
) + ((sec_hdr
.segmentcount
)
1422 * sizeof (segment_layout_t
));
1423 buffer
= alloca(size
);
1424 if (buffer
== NULL
) {
1428 /* segment header buffer */
1429 seg_buf
= alloca(size
- sizeof (sec_hdr
));
1430 if (seg_buf
== NULL
) {
1434 /* read segment header */
1435 retval
= pread_new(fd
, seg_buf
, size
- sizeof (sec_hdr
),
1436 sec_obj
->section
.offset
+ sizeof (sec_hdr
), &format
);
1437 if (retval
!= (size
- sizeof (sec_hdr
))) {
1441 /* copy section header layout */
1442 (void) memcpy(buffer
, &sec_hdr
, sizeof (sec_hdr
));
1444 /* copy segment header layout */
1445 (void) memcpy(buffer
+ sizeof (sec_hdr
), seg_buf
, size
-
1449 retval
= verify_header_crc8(hdrver
, buffer
, size
);
1450 if (retval
!= TRUE
) {
1454 section
->version
= hdrver
;
1455 sec_obj
->section
.version
= hdrver
;
1457 seg_hdr
= (segment_layout_t
*)seg_buf
;
1459 for (count
= 0; count
< sec_hdr
.segmentcount
; count
++, seg_hdr
++) {
1460 seg_hash
= create_segment_hash_object();
1461 if (seg_hash
== NULL
) {
1465 add_hashobject_to_hashtable(seg_hash
, SEGMENT_TYPE
);
1467 copy_segment_layout(&seg_hash
->u
.seg_obj
->segment
, seg_hdr
);
1469 add_to_seg_object_list(sec_hash
, seg_hash
);
1471 sec_obj
->num_of_segment
++;
1477 * sun_fru_get_sections() fills an array of section structures
1478 * passed as an argument.
1481 * container_hdl_t : container handle(device descriptor).
1482 * section_t : array of section structure.
1483 * int : maximum number of section in a container.
1487 * On success,the number of section structures written is returned;
1488 * on error, -1 is returned and "errno" is set appropriately.
1493 sun_fru_get_sections(container_hdl_t container
, section_t
*section
, int maxsec
,
1498 hash_obj_t
*cont_object
;
1499 hash_obj_t
*sec_hash
;
1501 cont_object
= lookup_handle_object(container
, CONTAINER_TYPE
);
1502 if (cont_object
== NULL
) {
1506 if (cont_object
->u
.cont_obj
->num_of_section
> maxsec
) {
1510 sec_hash
= cont_object
->u
.cont_obj
->sec_obj_list
;
1511 if (sec_hash
== NULL
) {
1515 device_fd
= open_file();
1517 if (device_fd
< 0) {
1521 for (count
= 0; count
< cont_object
->u
.cont_obj
->num_of_section
;
1522 count
++, section
++) {
1523 section
->version
= -1;
1524 /* populate section_t */
1525 get_section(device_fd
, sec_hash
, section
);
1526 sec_hash
= sec_hash
->u
.sec_obj
->next
;
1529 (void) close(device_fd
);
1536 * sun_fru_get_num_segments() returns the current number of
1537 * segments in a section.
1540 * section_hdl_t : section header holding section information.
1544 * On success, the number of segments in the argument section is
1545 * returned; on error -1 is returned.
1549 sun_fru_get_num_segments(section_hdl_t section
, door_cred_t
*cred
)
1551 hash_obj_t
*sec_object
;
1552 section_obj_t
*sec_obj
;
1554 sec_object
= lookup_handle_object(section
, SECTION_TYPE
);
1555 if (sec_object
== NULL
) {
1559 sec_obj
= sec_object
->u
.sec_obj
;
1560 if (sec_obj
== NULL
) {
1564 return (sec_obj
->num_of_segment
);
1569 * sun_fru_get_segments() fills an array of structures
1570 * representing the segments in a section.
1573 * section_hdl_t : holds section number.
1574 * segment_t : on success will hold segment information.
1575 * int : maximum number of segment.
1579 * On success, the number of segment structures written is
1580 * returned; on errno -1 is returned.
1584 sun_fru_get_segments(section_hdl_t section
, segment_t
*segment
, int maxseg
,
1588 hash_obj_t
*sec_object
;
1589 hash_obj_t
*seg_object
;
1590 section_obj_t
*sec_obj
;
1592 sec_object
= lookup_handle_object(section
, SECTION_TYPE
);
1593 if (sec_object
== NULL
) {
1597 sec_obj
= sec_object
->u
.sec_obj
;
1598 if (sec_obj
== NULL
) {
1602 if (sec_obj
->num_of_segment
> maxseg
) {
1606 seg_object
= sec_object
->u
.sec_obj
->seg_obj_list
;
1607 if (seg_object
== NULL
) {
1611 for (count
= 0; count
< sec_obj
->num_of_segment
; count
++) {
1613 /* populate segment_t */
1614 segment
->handle
= seg_object
->obj_hdl
;
1615 (void) memcpy(segment
->name
,
1616 seg_object
->u
.seg_obj
->segment
.name
, SEG_NAME_LEN
);
1617 segment
->descriptor
= seg_object
->u
.seg_obj
->segment
.descriptor
;
1618 segment
->offset
= seg_object
->u
.seg_obj
->segment
.offset
;
1619 segment
->length
= seg_object
->u
.seg_obj
->segment
.length
;
1620 seg_object
= seg_object
->u
.seg_obj
->next
;
1628 * sun_fru_add_segment() adds a segment to a section.
1631 * section_hdl_t section
1632 * A handle for the section in which to add the segment.
1634 * segment_t *segment
1635 * On entry, the "handle" component of "segment" is ignored and the
1636 * remaining components specify the parameters of the segment to be
1637 * added. On return, the "handle" component is set to the handle
1638 * for the added segment. The segment offset is mandatory for FIXED
1639 * segments; otherwise, the offset is advisory.
1643 * On success, 0 is returned; on error -1 is returned.
1647 sun_fru_add_segment(section_hdl_t section
, segment_t
*segment
,
1648 section_hdl_t
*newsection
, door_cred_t
*cred
)
1659 char trailer
[] = { 0x0c, 0x00, 0x00, 0x00, 0x00 };
1660 hash_obj_t
*cont_hash
;
1661 hash_obj_t
*sec_hash
;
1662 hash_obj_t
*seg_hash
;
1663 fru_segdesc_t
*new_seg_desc
;
1664 unsigned char *crcbuf
;
1665 section_layout_t sec_layout
;
1666 segment_layout_t
*seg_layout
;
1667 segment_layout_t
*segment_buf
;
1670 /* check the effective uid of the client */
1671 if (cred
->dc_euid
!= 0) {
1673 return (-1); /* not a root */
1677 sec_hash
= lookup_handle_object(section
, SECTION_TYPE
);
1678 if (sec_hash
== NULL
) {
1682 /* check for read-only section */
1683 if (sec_hash
->u
.sec_obj
->section
.protection
== READ_ONLY_SECTION
) {
1688 /* look for duplicate segment */
1689 seg_hash
= sec_hash
->u
.sec_obj
->seg_obj_list
;
1690 while (seg_hash
!= NULL
) {
1691 if (strncmp(segment
->name
, seg_hash
->u
.seg_obj
->segment
.name
,
1692 SEG_NAME_LEN
) == 0) {
1694 return (-1); /* can't add duplicate segment */
1696 seg_hash
= seg_hash
->u
.seg_obj
->next
;
1699 /* get the container hash */
1700 cont_hash
= lookup_handle_object(sec_hash
->u
.sec_obj
->cont_hdl
,
1702 if (cont_hash
== NULL
) {
1706 format
= cont_hash
->u
.cont_obj
->format
;
1708 /* open the container */
1714 /* section start here */
1715 offset
= sec_hash
->u
.sec_obj
->section
.offset
;
1717 /* read section header layout */
1718 retval
= pread_new(fd
, &sec_layout
, sizeof (sec_layout
), offset
,
1720 if (retval
!= sizeof (sec_layout
)) {
1725 /* check for valid section header */
1726 if (sec_layout
.headertag
!= SECTION_HDR_TAG
) {
1727 /* write a new one */
1728 sec_layout
.headertag
= SECTION_HDR_TAG
;
1729 sec_layout
.headerversion
[0] = SECTION_HDR_VER_BIT0
;
1730 sec_layout
.headerversion
[1] = SECTION_HDR_VER_BIT1
;
1731 sec_layout
.headerlength
= sizeof (sec_layout
);
1732 sec_layout
.segmentcount
= 0;
1736 sec_size
= sec_hash
->u
.sec_obj
->section
.length
;
1738 /* number of segment in the section */
1739 seg_cnt
= sec_layout
.segmentcount
;
1741 /* total sizeof segment + new segment */
1742 bufsize
= sizeof (segment_layout_t
) * (seg_cnt
+ 1);
1743 segment_buf
= alloca(bufsize
);
1744 if (segment_buf
== NULL
) {
1748 /* read entire segment header */
1749 retval
= pread_new(fd
, segment_buf
,
1750 (bufsize
- sizeof (segment_layout_t
)),
1751 offset
+ sizeof (section_layout_t
), &format
);
1752 if (retval
!= (bufsize
- sizeof (segment_layout_t
))) {
1757 new_seg_offset
= segment
->offset
; /* new segment offset */
1758 new_seg_length
= segment
->length
; /* new segment length */
1760 new_seg_desc
= (fru_segdesc_t
*)&segment
->descriptor
;
1762 fixed_segment
= new_seg_desc
->field
.fixed
;
1764 /* get new offset for new segment to be addedd */
1765 retval
= find_offset((char *)segment_buf
, seg_cnt
, sec_size
,
1766 &new_seg_offset
, new_seg_length
, fixed_segment
, fd
);
1774 /* copy new segment data in segment layout */
1775 seg_layout
= (segment_layout_t
*)(segment_buf
+ seg_cnt
);
1776 (void) memcpy(&seg_layout
->name
, segment
->name
, SEG_NAME_LEN
);
1777 (void) memcpy(seg_layout
->descriptor
, &segment
->descriptor
,
1779 seg_layout
->length
= segment
->length
;
1780 seg_layout
->offset
= new_seg_offset
; /* new segment offset */
1782 sec_layout
.segmentcount
+= 1;
1784 crcbuf
= alloca(sizeof (section_layout_t
) + bufsize
);
1785 if (crcbuf
== NULL
) {
1790 sec_layout
.headercrc8
= 0;
1791 sec_layout
.headerlength
+= sizeof (segment_layout_t
);
1793 (void) memcpy(crcbuf
, (char *)&sec_layout
, sizeof (section_layout_t
));
1794 (void) memcpy(crcbuf
+ sizeof (section_layout_t
), segment_buf
, bufsize
);
1796 sec_layout
.headercrc8
= compute_crc8(crcbuf
, bufsize
+
1797 sizeof (section_layout_t
));
1799 /* write section header */
1800 retval
= pwrite_new(fd
, &sec_layout
, sizeof (section_layout_t
),
1802 if (retval
!= sizeof (section_layout_t
)) {
1807 /* write segment header */
1808 retval
= pwrite_new(fd
, segment_buf
, bufsize
, offset
+
1809 sizeof (section_layout_t
), &format
);
1810 if (retval
!= bufsize
) {
1815 /* write segment trailer */
1816 retval
= pwrite_new(fd
, &trailer
, sizeof (trailer
), new_seg_offset
,
1818 if (retval
!= sizeof (trailer
)) {
1825 /* create new segment hash object */
1826 seg_hash
= create_segment_hash_object();
1827 if (seg_hash
== NULL
) {
1831 add_hashobject_to_hashtable(seg_hash
, SEGMENT_TYPE
);
1833 copy_segment_layout(&seg_hash
->u
.seg_obj
->segment
, seg_layout
);
1835 add_to_seg_object_list(sec_hash
, seg_hash
);
1837 sec_hash
->u
.sec_obj
->num_of_segment
+= 1;
1838 seg_hash
->u
.seg_obj
->trailer_offset
= new_seg_offset
;
1839 *newsection
= section
; /* return the new section handle */
1845 * sun_fru_delete_segment() deletes a segment from a section; the
1846 * associated container data is not altered.
1848 * Arguments : segment_hdl_t segment handle.
1849 * section_hdl_t new section handle.
1853 * On success, 0 returned; On error -1 is returned.
1856 sun_fru_delete_segment(segment_hdl_t segment
, section_hdl_t
*newsection
,
1865 hash_obj_t
*seg_hash
;
1866 hash_obj_t
*sec_hash
;
1867 hash_obj_t
*cont_hash
;
1868 hash_obj_t
*tmp_hash
;
1869 unsigned char *buffer
;
1870 fru_segdesc_t
*desc
;
1871 segment_layout_t
*seg_buf
;
1872 section_layout_t
*sec_layout
;
1873 segment_layout_t
*seg_layout
;
1874 segment_layout_t
*next_layout
;
1877 /* check the effective uid of the client */
1878 if (cred
->dc_euid
!= 0) {
1880 return (-1); /* not a root */
1883 seg_hash
= lookup_handle_object(segment
, SEGMENT_TYPE
);
1884 if (seg_hash
== NULL
) {
1888 desc
= (fru_segdesc_t
*)&seg_hash
->u
.seg_obj
->segment
.descriptor
;
1889 if (!(desc
->field
.field_perm
& SEGMENT_DELETE
)) {
1891 return (-1); /* can't delete this segment */
1894 sec_hash
= lookup_handle_object(seg_hash
->u
.seg_obj
->section_hdl
,
1896 if (sec_hash
== NULL
) {
1900 if (sec_hash
->u
.sec_obj
->section
.protection
== READ_ONLY_SECTION
) {
1905 num_of_seg
= sec_hash
->u
.sec_obj
->num_of_segment
;
1907 bufsize
= (sizeof (segment_layout_t
) * num_of_seg
);
1909 seg_buf
= alloca(bufsize
);
1910 if (seg_buf
== NULL
) {
1915 for (tmp_hash
= sec_hash
->u
.sec_obj
->seg_obj_list
; tmp_hash
!= NULL
;
1916 tmp_hash
= tmp_hash
->u
.seg_obj
->next
) {
1917 if (tmp_hash
->obj_hdl
== segment
) {
1923 cont_hash
= lookup_handle_object(sec_hash
->u
.sec_obj
->cont_hdl
,
1925 if (cont_hash
== NULL
) {
1928 format
= cont_hash
->u
.cont_obj
->format
;
1935 sec_layout
= alloca(sizeof (section_layout_t
));
1936 if (sec_layout
== NULL
) {
1941 /* read section layout header */
1942 retval
= pread_new(fd
, sec_layout
, sizeof (section_layout_t
),
1943 sec_hash
->u
.sec_obj
->section
.offset
, &format
);
1944 if (retval
!= sizeof (section_layout_t
)) {
1949 /* read segment header layout */
1950 retval
= pread_new(fd
, seg_buf
, bufsize
,
1951 sec_hash
->u
.sec_obj
->section
.offset
+
1952 sizeof (section_layout_t
), &format
);
1953 if (retval
!= bufsize
) {
1958 seg_layout
= (segment_layout_t
*)(seg_buf
+ segnum
);
1959 next_layout
= seg_layout
;
1960 for (count
= segnum
; count
< sec_hash
->u
.sec_obj
->num_of_segment
-1;
1963 (void) memcpy(seg_layout
, next_layout
,
1964 sizeof (segment_layout_t
));
1968 (void) memset(seg_layout
, '\0', sizeof (segment_layout_t
));
1970 sec_layout
->headercrc8
= 0;
1972 sec_layout
->headerlength
-= sizeof (segment_layout_t
);
1973 sec_layout
->segmentcount
-= 1;
1975 buffer
= alloca(sec_layout
->headerlength
);
1976 if (buffer
== NULL
) {
1981 (void) memcpy(buffer
, sec_layout
, sizeof (section_layout_t
));
1982 (void) memcpy(buffer
+ sizeof (section_layout_t
), seg_buf
, bufsize
1983 - sizeof (segment_layout_t
));
1984 sec_layout
->headercrc8
= compute_crc8(buffer
,
1985 sec_layout
->headerlength
);
1987 /* write section header with update crc8 and header length */
1988 retval
= pwrite_new(fd
, sec_layout
, sizeof (section_layout_t
),
1989 sec_hash
->u
.sec_obj
->section
.offset
, &format
);
1990 if (retval
!= sizeof (section_layout_t
)) {
1995 /* write the update segment header */
1996 retval
= pwrite_new(fd
, seg_buf
, bufsize
,
1997 sec_hash
->u
.sec_obj
->section
.offset
+
1998 sizeof (section_layout_t
), &format
);
2000 if (retval
!= bufsize
) {
2004 free_segment_hash(segment
, sec_hash
);
2006 *newsection
= sec_hash
->obj_hdl
;
2007 sec_hash
->u
.sec_obj
->num_of_segment
= sec_layout
->segmentcount
;
2014 * sun_fru_read_segment() reads the raw contents of a segment.
2016 * Arguments : segment_hdl_t : segment handle.
2017 * void * : buffer containing segment data when function returns.
2018 * size_t :number of bytes.
2022 * On success, the number of bytes read is returned;
2025 * Segments containing packets can be read in structured fashion
2026 * using the fru_get_packets() and fru_get_payload() primitives;the
2027 * entire byte range of a segment can be read using
2028 * fru_read_segment().
2032 sun_fru_read_segment(segment_hdl_t segment
, void *buffer
, size_t nbytes
,
2037 hash_obj_t
*seg_hash
;
2038 hash_obj_t
*sec_hash
;
2039 hash_obj_t
*cont_hash
;
2042 /* segment hash object */
2043 seg_hash
= lookup_handle_object(segment
, SEGMENT_TYPE
);
2044 if (seg_hash
== NULL
) {
2048 /* section hash object */
2049 sec_hash
= lookup_handle_object(seg_hash
->u
.seg_obj
->section_hdl
,
2051 if (sec_hash
== NULL
) {
2055 /* container hash object */
2056 cont_hash
= lookup_handle_object(sec_hash
->u
.sec_obj
->cont_hdl
,
2058 if (cont_hash
== NULL
) {
2061 format
= cont_hash
->u
.cont_obj
->format
;
2063 if (seg_hash
->u
.seg_obj
->segment
.length
< nbytes
) {
2072 retval
= pread_new(fd
, buffer
, nbytes
,
2073 seg_hash
->u
.seg_obj
->segment
.offset
, &format
);
2075 if (retval
!= nbytes
) {
2083 * sun_fru_write_segment() writes a raw segment.
2085 * Arguments : segment_hdl_t :segment handle.
2086 * const void * : data buffer.
2087 * size_t : number of bytes.
2088 * segment_hdl_t : new segment handle.
2092 * On success, the number of bytes written is returned
2097 sun_fru_write_segment(segment_hdl_t segment
, const void *data
, size_t nbytes
,
2098 segment_hdl_t
*newsegment
, door_cred_t
*cred
)
2105 get_packet(int device_fd
, void *buffer
, int size
, int offset
, format_t
*format
)
2109 retval
= pread_new(device_fd
, (char *)buffer
, size
, offset
, format
);
2117 get_checksum_crc(hash_obj_t
*seg_hash
, int data_size
)
2122 hash_obj_t
*sec_hash
;
2123 hash_obj_t
*pkt_hash
;
2124 unsigned char *buffer
;
2126 sec_hash
= lookup_handle_object(seg_hash
->u
.seg_obj
->section_hdl
,
2128 if (sec_hash
== NULL
) {
2129 return ((uint32_t)-1);
2132 buffer
= alloca(data_size
);
2133 if (buffer
== NULL
) {
2134 return ((uint32_t)-1);
2137 /* traverse the packet object list for all the tags and payload */
2138 for (pkt_hash
= seg_hash
->u
.seg_obj
->pkt_obj_list
; pkt_hash
!= NULL
;
2139 pkt_hash
= pkt_hash
->u
.pkt_obj
->next
) {
2140 (void) memcpy(buffer
+ offset
, &pkt_hash
->u
.pkt_obj
->tag
,
2141 pkt_hash
->u
.pkt_obj
->tag_size
);
2142 offset
+= pkt_hash
->u
.pkt_obj
->tag_size
;
2143 (void) memcpy(buffer
+ offset
, pkt_hash
->u
.pkt_obj
->payload
,
2144 pkt_hash
->u
.pkt_obj
->paylen
);
2145 offset
+= pkt_hash
->u
.pkt_obj
->paylen
;
2148 protection
= sec_hash
->u
.sec_obj
->section
.protection
;
2150 if (protection
== READ_ONLY_SECTION
) { /* read-only section */
2151 crc
= compute_crc32(buffer
, data_size
);
2152 } else { /* read/write section */
2153 crc
= compute_checksum32(buffer
, data_size
);
2155 return (crc
); /* computed crc */
2159 get_packets(hash_obj_t
*seg_hash
, int device_fd
, int offset
, int length
)
2170 hash_obj_t
*pkt_hash_obj
;
2171 fru_segdesc_t
*segdesc
;
2172 fru_tagtype_t tagtype
;
2174 hash_obj_t
*cont_hash
;
2176 cont_hash
= get_container_hash_object(PACKET_TYPE
, seg_hash
->obj_hdl
);
2177 if (cont_hash
== NULL
) {
2180 format
= cont_hash
->u
.cont_obj
->format
;
2182 retval
= get_packet(device_fd
, &tag
, sizeof (fru_tag_t
), offset
,
2188 seg_hash
->u
.seg_obj
->trailer_offset
= offset
;
2190 data
= (char *)&tag
;
2191 while (data
[0] != SEG_TRAILER_TAG
) {
2192 tagtype
= get_tag_type(&tag
); /* verify tag type */
2193 if (tagtype
== -1) {
2197 tag_size
= get_tag_size(tagtype
);
2198 if (tag_size
== -1) {
2202 seg_limit
+= tag_size
;
2203 if (seg_limit
> length
) {
2207 paylen
= get_payload_length((void *)&tag
);
2212 seg_limit
+= paylen
;
2213 if (seg_limit
> length
) {
2217 pkt_hash_obj
= create_packet_hash_object();
2218 if (pkt_hash_obj
== NULL
) {
2222 pkt_hash_obj
->u
.pkt_obj
->payload
= malloc(paylen
);
2223 if (pkt_hash_obj
->u
.pkt_obj
->payload
== NULL
) {
2229 retval
= pread_new(device_fd
, pkt_hash_obj
->u
.pkt_obj
->payload
,
2230 paylen
, offset
, &format
);
2231 if (retval
!= paylen
) {
2232 free(pkt_hash_obj
->u
.pkt_obj
->payload
);
2237 /* don't change this */
2238 pkt_hash_obj
->u
.pkt_obj
->tag
.raw_data
= 0;
2239 (void) memcpy(&pkt_hash_obj
->u
.pkt_obj
->tag
, &tag
, tag_size
);
2240 pkt_hash_obj
->u
.pkt_obj
->paylen
= paylen
;
2241 pkt_hash_obj
->u
.pkt_obj
->tag_size
= tag_size
;
2242 pkt_hash_obj
->u
.pkt_obj
->payload_offset
= offset
;
2246 add_hashobject_to_hashtable(pkt_hash_obj
, PACKET_TYPE
);
2247 add_to_pkt_object_list(seg_hash
, pkt_hash_obj
);
2251 retval
= get_packet(device_fd
, &tag
, sizeof (fru_tag_t
),
2257 data
= (char *)&tag
;
2260 segdesc
= (fru_segdesc_t
*)&seg_hash
->u
.seg_obj
->segment
.descriptor
;
2262 seg_hash
->u
.seg_obj
->trailer_offset
= offset
;
2264 if (!segdesc
->field
.ignore_checksum
) {
2265 crc
= get_checksum_crc(seg_hash
, seg_limit
);
2266 offset
= seg_hash
->u
.seg_obj
->segment
.offset
;
2268 retval
= pread_new(device_fd
, &origcrc
, sizeof (origcrc
),
2269 offset
+ seg_limit
+ 1, &format
);
2270 if (retval
!= sizeof (origcrc
)) {
2274 if (origcrc
!= crc
) {
2275 seg_hash
->u
.seg_obj
->trailer_offset
= offset
;
2284 * sun_fru_get_num_packets() returns the current number of packets
2287 * Arguments : segment_hdl_t : segment handle.
2291 * On success, the number of packets is returned;
2296 sun_fru_get_num_packets(segment_hdl_t segment
, door_cred_t
*cred
)
2302 hash_obj_t
*cont_hash_obj
;
2303 hash_obj_t
*seg_hash
;
2304 fru_segdesc_t
*segdesc
;
2305 segment_obj_t
*segment_object
;
2307 seg_hash
= lookup_handle_object(segment
, SEGMENT_TYPE
);
2308 if (seg_hash
== NULL
) {
2312 segment_object
= seg_hash
->u
.seg_obj
;
2313 if (segment_object
== NULL
) {
2318 segdesc
= (fru_segdesc_t
*)&segment_object
->segment
.descriptor
;
2319 if (segdesc
->field
.opaque
) {
2323 offset
= segment_object
->segment
.offset
;
2324 length
= segment_object
->segment
.length
;
2326 cont_hash_obj
= get_container_hash_object(SEGMENT_TYPE
,
2327 segment_object
->section_hdl
);
2329 if (cont_hash_obj
== NULL
) {
2333 if (seg_hash
->u
.seg_obj
->pkt_obj_list
!= NULL
) {
2334 return (segment_object
->num_of_packets
);
2337 segment_object
->num_of_packets
= 0;
2338 device_fd
= open_file();
2339 if (device_fd
< 0) {
2343 pktcnt
= get_packets(seg_hash
, device_fd
, offset
,
2346 free_pkt_object_list(seg_hash
);
2347 seg_hash
->u
.seg_obj
->pkt_obj_list
= NULL
;
2350 segment_object
->num_of_packets
= pktcnt
;
2351 (void) close(device_fd
);
2353 return (segment_object
->num_of_packets
);
2358 * sun_fru_get_packets() fills an array of structures
2359 * representing the packets in a segment.
2361 * Arguments : segment_hdl_t : segment handle.
2362 * packet_t : packet buffer.
2363 * int : maximum number of packets.
2367 * On success, the number of packet structures written is returned;
2368 * On failure -1 is returned;
2373 sun_fru_get_packets(segment_hdl_t segment
, packet_t
*packet
, int maxpackets
,
2377 hash_obj_t
*seg_hash_obj
;
2378 hash_obj_t
*pkt_hash_obj
;
2380 /* segment hash object */
2381 seg_hash_obj
= lookup_handle_object(segment
, SEGMENT_TYPE
);
2382 if (seg_hash_obj
== NULL
) {
2386 if (seg_hash_obj
->u
.seg_obj
->num_of_packets
!= maxpackets
) {
2390 pkt_hash_obj
= seg_hash_obj
->u
.seg_obj
->pkt_obj_list
;
2391 if (pkt_hash_obj
== NULL
) {
2395 for (count
= 0; count
< maxpackets
; count
++, packet
++) {
2396 packet
->handle
= pkt_hash_obj
->obj_hdl
;
2398 (void) memcpy(&packet
->tag
, &pkt_hash_obj
->u
.pkt_obj
->tag
,
2399 pkt_hash_obj
->u
.pkt_obj
->tag_size
);
2400 pkt_hash_obj
= pkt_hash_obj
->u
.pkt_obj
->next
;
2408 * sun_fru_get_payload() copies the contents of a packet's payload.
2410 * Arguments : packet_hdl_t : packet handle.
2411 * void * : payload buffer.
2412 * size_t : sizeof the buffer.
2416 * On success, the number of bytes copied is returned; On error
2421 sun_fru_get_payload(packet_hdl_t packet
, void *buffer
, size_t nbytes
,
2424 hash_obj_t
*packet_hash_obj
;
2426 /* packet hash object */
2427 packet_hash_obj
= lookup_handle_object(packet
, PACKET_TYPE
);
2428 if (packet_hash_obj
== NULL
) {
2432 /* verify payload length */
2433 if (nbytes
!= packet_hash_obj
->u
.pkt_obj
->paylen
) {
2437 (void) memcpy(buffer
, packet_hash_obj
->u
.pkt_obj
->payload
, nbytes
);
2443 * sun_fru_update_payload() writes the contents of a packet's
2446 * Arguments : packet_hdl_t : packet handle.
2447 * const void * : data buffer.
2448 * size_t : buffer size.
2449 * packet_hdl_t : new packet handle.
2453 * On success, 0 is returned; on failure
2458 sun_fru_update_payload(packet_hdl_t packet
, const void *data
, size_t nbytes
,
2459 packet_hdl_t
*newpacket
, door_cred_t
*cred
)
2466 hash_obj_t
*pkt_hash
;
2467 hash_obj_t
*seg_hash
;
2468 hash_obj_t
*sec_hash
;
2469 hash_obj_t
*cont_hash
;
2470 fru_segdesc_t
*desc
;
2473 /* check the effective uid of the client */
2474 if (cred
->dc_euid
!= 0) {
2476 return (-1); /* not a root */
2479 /* packet hash object */
2480 pkt_hash
= lookup_handle_object(packet
, PACKET_TYPE
);
2481 if (pkt_hash
== NULL
) {
2485 /* segment hash object */
2486 seg_hash
= lookup_handle_object(pkt_hash
->u
.pkt_obj
->segment_hdl
,
2488 if (seg_hash
== NULL
) {
2492 /* check for write perm. */
2493 desc
= (fru_segdesc_t
*)&seg_hash
->u
.seg_obj
->segment
.descriptor
;
2494 if (!(desc
->field
.field_perm
& SEGMENT_WRITE
)) {
2496 return (-1); /* write not allowed */
2499 sec_hash
= lookup_handle_object(seg_hash
->u
.seg_obj
->section_hdl
,
2501 if (sec_hash
== NULL
) {
2505 if (sec_hash
->u
.sec_obj
->section
.protection
== READ_ONLY_SECTION
) {
2507 return (-1); /* read-only section */
2510 cont_hash
= lookup_handle_object(sec_hash
->u
.sec_obj
->cont_hdl
,
2512 if (cont_hash
== NULL
) {
2516 format
= cont_hash
->u
.cont_obj
->format
;
2518 if (pkt_hash
->u
.pkt_obj
->paylen
!= nbytes
) {
2522 (void) memcpy(pkt_hash
->u
.pkt_obj
->payload
, (char *)data
, nbytes
);
2528 trailer_offset
= seg_hash
->u
.seg_obj
->trailer_offset
;
2529 segment_offset
= seg_hash
->u
.seg_obj
->segment
.offset
;
2531 crc
= get_checksum_crc(seg_hash
, (trailer_offset
- segment_offset
));
2532 retval
= pwrite_new(fd
, data
, nbytes
,
2533 pkt_hash
->u
.pkt_obj
->payload_offset
, &format
);
2534 if (retval
!= nbytes
) {
2539 retval
= pwrite_new(fd
, &crc
, sizeof (crc
),
2540 trailer_offset
+ 1, &format
);
2542 if (retval
!= sizeof (crc
)) {
2545 *newpacket
= packet
;
2551 * sun_fru_append_packet() appends a packet to a segment.
2554 * segment_hdl_t segment
2555 * A handle for the segment to which the packet will be appended.
2558 * On entry, the "tag" component of "packet" specifies the tag
2559 * value for the added packet; the "handle" component is ignored.
2560 * On return, the "handle" component is set to the handle of the
2563 * const void *payload
2564 * A pointer to the caller's buffer containing the payload data for
2565 * the appended packet.
2568 * The size of the caller buffer.
2572 * On success, 0 is returned; on error -1 is returned;
2575 sun_fru_append_packet(segment_hdl_t segment
, packet_t
*packet
,
2576 const void *payload
, size_t nbytes
, segment_hdl_t
*newsegment
,
2583 char trailer
[] = {0x0c, 0x00, 0x00, 0x00, 0x00};
2585 hash_obj_t
*seg_hash
;
2586 hash_obj_t
*sec_hash
;
2587 hash_obj_t
*pkt_hash
;
2588 hash_obj_t
*cont_hash
;
2589 fru_tagtype_t tagtype
;
2590 fru_segdesc_t
*desc
;
2593 /* check the effective uid of the client */
2594 if (cred
->dc_euid
!= 0) {
2596 return (-1); /* not a root */
2599 seg_hash
= lookup_handle_object(segment
, SEGMENT_TYPE
);
2600 if (seg_hash
== NULL
) {
2604 /* check for write perm. */
2605 desc
= (fru_segdesc_t
*)&seg_hash
->u
.seg_obj
->segment
.descriptor
;
2606 if (!(desc
->field
.field_perm
& SEGMENT_WRITE
)) {
2608 return (-1); /* write not allowed */
2611 sec_hash
= lookup_handle_object(seg_hash
->u
.seg_obj
->section_hdl
,
2613 if (sec_hash
== NULL
) {
2617 if (sec_hash
->u
.sec_obj
->section
.protection
== READ_ONLY_SECTION
) {
2619 return (-1); /* read-only section */
2622 trailer_offset
= seg_hash
->u
.seg_obj
->trailer_offset
;
2625 * if trailer offset is 0 than parse the segment data to get the trailer
2626 * offset to compute the remaining space left in the segment area for
2627 * new packet to be added.
2629 if (trailer_offset
== 0) {
2630 (void) sun_fru_get_num_packets(segment
, cred
);
2631 trailer_offset
= seg_hash
->u
.seg_obj
->trailer_offset
;
2634 tagtype
= get_tag_type((void *)&packet
->tag
);
2635 if (tagtype
== -1) {
2639 tag_size
= get_tag_size(tagtype
);
2640 if (tag_size
== -1) {
2644 if (seg_hash
->u
.seg_obj
->segment
.length
>
2645 ((trailer_offset
- seg_hash
->u
.seg_obj
->segment
.offset
) +
2647 sizeof (char) + sizeof (uint32_t))) {
2648 /* create new packet hash */
2649 pkt_hash
= create_packet_hash_object();
2650 if (pkt_hash
== NULL
) {
2654 /* tag initialization */
2655 (void) memcpy(&pkt_hash
->u
.pkt_obj
->tag
, &packet
->tag
,
2657 pkt_hash
->u
.pkt_obj
->tag_size
= tag_size
;
2659 /* payload inititalization */
2660 pkt_hash
->u
.pkt_obj
->payload
= malloc(nbytes
);
2661 if (pkt_hash
->u
.pkt_obj
->payload
== NULL
) {
2666 (void) memcpy(pkt_hash
->u
.pkt_obj
->payload
, payload
, nbytes
);
2667 pkt_hash
->u
.pkt_obj
->paylen
= nbytes
;
2668 pkt_hash
->u
.pkt_obj
->payload_offset
= trailer_offset
+ tag_size
;
2670 /* add to hash table */
2671 add_hashobject_to_hashtable(pkt_hash
, PACKET_TYPE
);
2673 add_to_pkt_object_list(seg_hash
, pkt_hash
);
2675 cont_hash
= lookup_handle_object(sec_hash
->u
.sec_obj
->cont_hdl
,
2677 if (cont_hash
== NULL
) {
2680 format
= cont_hash
->u
.cont_obj
->format
;
2687 /* update the trailer offset */
2688 trailer_offset
+= tag_size
+ nbytes
;
2690 /* calculate new checksum */
2691 crc
= get_checksum_crc(seg_hash
, (trailer_offset
-
2692 seg_hash
->u
.seg_obj
->segment
.offset
));
2694 retval
= pwrite_new(fd
, &packet
->tag
, tag_size
, trailer_offset
2695 - (tag_size
+ nbytes
), &format
);
2696 if (retval
!= tag_size
) {
2701 retval
= pwrite_new(fd
, payload
, nbytes
,
2702 trailer_offset
- nbytes
, &format
);
2703 if (retval
!= nbytes
) {
2708 retval
= pwrite_new(fd
, trailer
, sizeof (trailer
),
2709 trailer_offset
, &format
);
2710 if (retval
!= sizeof (trailer
)) {
2715 retval
= pwrite_new(fd
, &crc
, sizeof (crc
),
2716 trailer_offset
+ 1, &format
);
2718 if (retval
!= sizeof (crc
)) {
2722 seg_hash
->u
.seg_obj
->trailer_offset
= trailer_offset
;
2723 seg_hash
->u
.seg_obj
->num_of_packets
+= 1;
2725 *newsegment
= segment
; /* return new segment handle */
2735 adjust_packets(int fd
, hash_obj_t
*free_obj
, hash_obj_t
*object_list
)
2738 uint32_t new_offset
;
2739 hash_obj_t
*hash_ptr
;
2741 hash_obj_t
*hash_obj
;
2743 hash_obj
= lookup_handle_object(free_obj
->obj_hdl
, PACKET_TYPE
);
2744 if (hash_obj
== NULL
) {
2747 hash_obj
= get_container_hash_object(PACKET_TYPE
,
2748 hash_obj
->u
.pkt_obj
->segment_hdl
);
2749 if (hash_obj
== NULL
) {
2752 format
= hash_obj
->u
.cont_obj
->format
;
2754 new_offset
= free_obj
->u
.pkt_obj
->payload_offset
2755 - free_obj
->u
.pkt_obj
->tag_size
;
2756 for (hash_ptr
= object_list
; hash_ptr
!= NULL
;
2757 hash_ptr
= hash_ptr
->u
.pkt_obj
->next
) {
2758 retval
= pwrite_new(fd
, &hash_ptr
->u
.pkt_obj
->tag
,
2759 hash_ptr
->u
.pkt_obj
->tag_size
, new_offset
, &format
);
2760 if (retval
!= hash_ptr
->u
.pkt_obj
->tag_size
) {
2763 new_offset
+= hash_ptr
->u
.pkt_obj
->tag_size
;
2764 hash_ptr
->u
.pkt_obj
->payload_offset
= new_offset
;
2765 retval
= pwrite_new(fd
, hash_ptr
->u
.pkt_obj
->payload
,
2766 hash_ptr
->u
.pkt_obj
->paylen
, new_offset
, &format
);
2767 if (retval
!= hash_ptr
->u
.pkt_obj
->paylen
) {
2770 new_offset
+= hash_ptr
->u
.pkt_obj
->paylen
;
2775 free_packet_object(handle_t handle
, hash_obj_t
*seg_hash
)
2777 hash_obj_t
*pkt_hash
;
2778 hash_obj_t
*next_hash
;
2780 pkt_hash
= seg_hash
->u
.seg_obj
->pkt_obj_list
;
2781 if (pkt_hash
== NULL
) {
2785 if (pkt_hash
->obj_hdl
== handle
) {
2786 seg_hash
->u
.seg_obj
->pkt_obj_list
= pkt_hash
->u
.pkt_obj
->next
;
2788 while (pkt_hash
->obj_hdl
!= handle
) {
2789 next_hash
= pkt_hash
;
2790 pkt_hash
= pkt_hash
->u
.pkt_obj
->next
;
2791 if (pkt_hash
== NULL
) {
2795 next_hash
->u
.pkt_obj
->next
= pkt_hash
->u
.pkt_obj
->next
;
2798 if (pkt_hash
->prev
== NULL
) {
2799 hash_table
[(pkt_hash
->obj_hdl
% TABLE_SIZE
)] = pkt_hash
->next
;
2800 if (pkt_hash
->next
!= NULL
) {
2801 pkt_hash
->next
->prev
= NULL
;
2804 pkt_hash
->prev
->next
= pkt_hash
->next
;
2805 if (pkt_hash
->next
!= NULL
) {
2806 pkt_hash
->next
->prev
= pkt_hash
->prev
;
2810 free(pkt_hash
->u
.pkt_obj
->payload
);
2811 free(pkt_hash
->u
.pkt_obj
);
2817 * sun_fru_delete_packet() deletes a packet from a segment.
2819 * Arguments : packet_hdl_t : packet number to be deleted.
2820 * segment_hdl_t : new segment handler.
2824 * On success, 0 is returned; on error, -1.
2827 * Packets are adjacent; thus, deleting a packet requires moving
2828 * succeeding packets to compact the resulting hole.
2831 sun_fru_delete_packet(packet_hdl_t packet
, segment_hdl_t
*newsegment
,
2836 char trailer
[] = { 0x0c, 0x00, 0x00, 0x00, 0x00};
2838 hash_obj_t
*tmp_obj
;
2839 hash_obj_t
*pkt_hash
;
2840 hash_obj_t
*sec_hash
;
2841 hash_obj_t
*cont_hash
;
2842 hash_obj_t
*prev_obj
;
2843 hash_obj_t
*seg_hash
;
2844 fru_segdesc_t
*desc
;
2847 /* check the effective uid of the client */
2848 if (cred
->dc_euid
!= 0) {
2850 return (-1); /* not a root */
2853 /* packet hash object */
2854 pkt_hash
= lookup_handle_object(packet
, PACKET_TYPE
);
2855 if (pkt_hash
== NULL
) {
2859 /* segment hash object */
2860 seg_hash
= lookup_handle_object(pkt_hash
->u
.pkt_obj
->segment_hdl
,
2862 if (seg_hash
== NULL
) {
2866 /* check for write perm. */
2867 desc
= (fru_segdesc_t
*)&seg_hash
->u
.seg_obj
->segment
.descriptor
;
2868 if (!(desc
->field
.field_perm
& SEGMENT_WRITE
)) {
2870 return (-1); /* write not allowed */
2873 /* section hash object */
2874 sec_hash
= lookup_handle_object(seg_hash
->u
.seg_obj
->section_hdl
,
2876 if (sec_hash
== NULL
) {
2880 if (sec_hash
->u
.sec_obj
->section
.protection
== READ_ONLY_SECTION
) {
2882 return (-1); /* read-only section */
2885 prev_obj
= seg_hash
->u
.seg_obj
->pkt_obj_list
;
2886 if (prev_obj
== NULL
) {
2890 /* container hash object */
2891 cont_hash
= lookup_handle_object(sec_hash
->u
.sec_obj
->cont_hdl
,
2893 if (cont_hash
== NULL
) {
2897 format
= cont_hash
->u
.cont_obj
->format
;
2904 if (prev_obj
->obj_hdl
== packet
) { /* first object to be deleted */
2905 adjust_packets(fd
, prev_obj
, prev_obj
->u
.pkt_obj
->next
);
2906 seg_hash
->u
.seg_obj
->trailer_offset
-=
2907 (prev_obj
->u
.pkt_obj
->tag_size
2908 + prev_obj
->u
.pkt_obj
->paylen
);
2909 free_packet_object(packet
, seg_hash
);
2911 for (tmp_obj
= prev_obj
;
2912 tmp_obj
!= NULL
; tmp_obj
= tmp_obj
->u
.pkt_obj
->next
) {
2913 /* found the object */
2914 if (tmp_obj
->obj_hdl
== packet
) {
2915 adjust_packets(fd
, tmp_obj
,
2916 tmp_obj
->u
.pkt_obj
->next
);
2917 seg_hash
->u
.seg_obj
->trailer_offset
-=
2918 (tmp_obj
->u
.pkt_obj
->tag_size
2919 + tmp_obj
->u
.pkt_obj
->paylen
);
2920 free_packet_object(packet
, seg_hash
);
2925 seg_hash
->u
.seg_obj
->num_of_packets
-= 1;
2927 /* calculate checksum */
2928 crc
= get_checksum_crc(seg_hash
, (seg_hash
->u
.seg_obj
->trailer_offset
2929 - seg_hash
->u
.seg_obj
->segment
.offset
));
2930 /* write trailer at new offset */
2931 retval
= pwrite_new(fd
, &trailer
, sizeof (trailer
),
2932 seg_hash
->u
.seg_obj
->trailer_offset
, &format
);
2933 if (retval
!= sizeof (trailer
)) {
2938 /* write the checksum value */
2939 retval
= pwrite_new(fd
, &crc
, sizeof (crc
),
2940 seg_hash
->u
.seg_obj
->trailer_offset
+ 1, &format
);
2942 if (retval
!= sizeof (crc
)) {
2946 *newsegment
= seg_hash
->obj_hdl
; /* return new segment handle */
2952 * sun_fru_close_container() removes the association between a
2953 * container and its handle. this routines free's up all the
2954 * hash object contained under container.
2957 * container_hdl_t holds the file descriptor of the fru.
2966 sun_fru_close_container(container_hdl_t container
)
2968 hash_obj_t
*hash_obj
;
2969 hash_obj_t
*prev_hash
;
2970 hash_obj_t
*sec_hash_obj
;
2973 /* lookup for container hash object */
2974 hash_obj
= lookup_handle_object(container
, CONTAINER_TYPE
);
2975 if (hash_obj
== NULL
) {
2979 /* points to section object list */
2980 sec_hash_obj
= hash_obj
->u
.cont_obj
->sec_obj_list
;
2982 /* traverse section object list */
2983 while (sec_hash_obj
!= NULL
) {
2985 /* traverse segment hash object in the section */
2986 while (sec_hash_obj
->u
.sec_obj
->seg_obj_list
!= NULL
) {
2987 /* object handle of the segment hash object */
2989 sec_hash_obj
->u
.sec_obj
->seg_obj_list
->obj_hdl
;
2990 free_segment_hash(obj_hdl
, sec_hash_obj
);
2993 /* going to free section hash object, relink the hash object */
2994 if (sec_hash_obj
->prev
== NULL
) {
2995 hash_table
[(sec_hash_obj
->obj_hdl
% TABLE_SIZE
)]
2996 = sec_hash_obj
->next
;
2997 if (sec_hash_obj
->next
!= NULL
) {
2998 sec_hash_obj
->next
->prev
= NULL
;
3001 sec_hash_obj
->prev
->next
= sec_hash_obj
->next
;
3002 if (sec_hash_obj
->next
!= NULL
) {
3003 sec_hash_obj
->next
->prev
= sec_hash_obj
->prev
;
3007 free(sec_hash_obj
->u
.sec_obj
); /* free section hash object */
3009 prev_hash
= sec_hash_obj
;
3011 sec_hash_obj
= sec_hash_obj
->u
.sec_obj
->next
;
3013 free(prev_hash
); /* free section hash */
3016 /* free container hash object */
3017 if (hash_obj
->prev
== NULL
) {
3018 hash_table
[(sec_hash_obj
->obj_hdl
% TABLE_SIZE
)] =
3020 if (hash_obj
->next
!= NULL
) {
3021 hash_obj
->next
->prev
= NULL
;
3024 hash_obj
->prev
->next
= hash_obj
->next
;
3025 if (hash_obj
->next
!= NULL
) {
3026 hash_obj
->next
->prev
= hash_obj
->prev
;
3030 free(hash_obj
->u
.cont_obj
);
3041 * fru_is_data_available checks if the fruid information
3042 * is available or not on a give fru
3045 * picl_nodehdl_t hold picl node handle of the fru.
3049 * return 0 - if fruid is not present.
3050 * return 1 - if fruid is present.
3053 fru_is_data_available(picl_nodehdl_t fruh
)
3057 picl_nodehdl_t parenth
;
3058 format_t fru_format
;
3059 hash_obj_t
*cont_hash_obj
;
3061 if (is_valid_chassis
== -1) {
3062 if (fruaccess_platmod_check_chassis() == 0) {
3063 is_valid_chassis
= 1;
3065 is_valid_chassis
= 0;
3069 if (!is_valid_chassis
) {
3073 retval
= ptree_get_propval_by_name(fruh
, PICL_PROP_PARENT
,
3074 &parenth
, sizeof (picl_nodehdl_t
));
3075 if (retval
!= PICL_SUCCESS
) {
3079 if (fruaccess_platmod_check_fru(parenth
) != 0) {
3083 retval
= ptree_get_propval_by_name(parenth
, PICL_PROP_GEO_ADDR
,
3084 &slot_no
, sizeof (uint8_t));
3085 if (retval
!= PICL_SUCCESS
) {
3089 if (fruaccess_platmod_init_format(slot_no
, &fru_format
) !=
3094 ret
= is_fru_data_available(precedence
, slot_no
, &fru_format
);
3095 if (ret
&& (fru_format
.format
!= NO_FRUDATA
)) {
3102 cont_hash_obj
= create_container_hash_object();
3103 if (cont_hash_obj
== NULL
) {
3107 cont_hash_obj
->obj_hdl
= fruh
;
3108 cont_hash_obj
->u
.cont_obj
->format
= fru_format
;
3110 /* if both formats are present follow the precedence */
3111 if (fru_format
.format
== 0x3) {
3112 if (precedence
== IPMI_FORMAT
) {
3113 cont_hash_obj
->u
.cont_obj
->format
.format
= IPMI_FORMAT
;
3115 cont_hash_obj
->u
.cont_obj
->format
.format
= SUN_FORMAT
;
3118 add_hashobject_to_hashtable(cont_hash_obj
, CONTAINER_TYPE
);
3127 * All the routines check the fruid format and redirects the call to
3128 * to appropriate routines depending on fruid format.
3129 * All SUN format routines start with sun_ prefix.
3130 * All IPMI format routines start with ipmi_ prefix.
3133 fru_open_container(picl_nodehdl_t fru
)
3135 hash_obj_t
*hash_obj
;
3136 format_t fru_format
;
3138 hash_obj
= lookup_handle_object((handle_t
)fru
, CONTAINER_TYPE
);
3139 if (hash_obj
== NULL
) {
3142 fru_format
= hash_obj
->u
.cont_obj
->format
;
3143 return (fruaccess_func
[fru_format
.format
- 1].open_container(fru
));
3147 fru_close_container(container_hdl_t container
)
3150 format_t fru_format
;
3151 hash_obj_t
*hash_obj
;
3153 hash_obj
= lookup_handle_object(container
, CONTAINER_TYPE
);
3154 if (hash_obj
== NULL
) {
3158 fru_format
= hash_obj
->u
.cont_obj
->format
;
3159 ret
= fruaccess_func
[fru_format
.format
- 1].close_container(container
);
3164 fru_get_num_sections(container_hdl_t container
, door_cred_t
*cred
)
3167 format_t fru_format
;
3168 hash_obj_t
*hash_obj
;
3170 hash_obj
= lookup_handle_object(container
, CONTAINER_TYPE
);
3171 if (hash_obj
== NULL
) {
3174 fru_format
= hash_obj
->u
.cont_obj
->format
;
3175 ret
= fruaccess_func
[fru_format
.format
- 1].get_num_sections(container
,
3181 fru_get_sections(container_hdl_t container
, section_t
*section
,
3182 int max_sections
, door_cred_t
*cred
)
3185 format_t fru_format
;
3186 hash_obj_t
*hash_obj
;
3188 hash_obj
= lookup_handle_object(container
, CONTAINER_TYPE
);
3189 if (hash_obj
== NULL
) {
3192 fru_format
= hash_obj
->u
.cont_obj
->format
;
3194 ret
= fruaccess_func
[fru_format
.format
- 1].get_sections(container
,
3195 section
, max_sections
, cred
);
3200 fru_get_num_segments(section_hdl_t section
, door_cred_t
*rarg
)
3203 format_t fru_format
;
3204 hash_obj_t
*hash_obj
;
3206 hash_obj
= get_container_hash_object(SEGMENT_TYPE
, section
);
3207 if (hash_obj
== NULL
) {
3210 fru_format
= hash_obj
->u
.cont_obj
->format
;
3212 ret
= fruaccess_func
[fru_format
.format
- 1].get_num_segments(section
,
3218 fru_get_segments(section_hdl_t section
, segment_t
*segment
,
3219 int max_segments
, door_cred_t
*rarg
)
3222 format_t fru_format
;
3223 hash_obj_t
*hash_obj
;
3225 hash_obj
= get_container_hash_object(SEGMENT_TYPE
, section
);
3226 if (hash_obj
== NULL
) {
3229 fru_format
= hash_obj
->u
.cont_obj
->format
;
3230 ret
= fruaccess_func
[fru_format
.format
- 1].get_segments(section
,
3231 segment
, max_segments
, rarg
);
3236 fru_add_segment(section_hdl_t section
, segment_t
*segment
,
3237 section_hdl_t
*newsection
, door_cred_t
*cred
)
3240 format_t fru_format
;
3241 hash_obj_t
*hash_obj
;
3243 hash_obj
= get_container_hash_object(SEGMENT_TYPE
, section
);
3244 if (hash_obj
== NULL
) {
3247 fru_format
= hash_obj
->u
.cont_obj
->format
;
3249 ret
= fruaccess_func
[fru_format
.format
- 1].add_segment(section
,
3250 segment
, newsection
, cred
);
3255 fru_delete_segment(segment_hdl_t segment
, section_hdl_t
*newsection
,
3259 format_t fru_format
;
3260 hash_obj_t
*hash_obj
;
3262 hash_obj
= get_container_hash_object(PACKET_TYPE
, segment
);
3263 if (hash_obj
== NULL
) {
3266 fru_format
= hash_obj
->u
.cont_obj
->format
;
3267 ret
= fruaccess_func
[fru_format
.format
- 1].delete_segment(segment
,
3273 fru_read_segment(segment_hdl_t segment
, void *buffer
, size_t nbytes
,
3277 format_t fru_format
;
3278 hash_obj_t
*hash_obj
;
3280 hash_obj
= get_container_hash_object(PACKET_TYPE
, segment
);
3281 if (hash_obj
== NULL
) {
3284 fru_format
= hash_obj
->u
.cont_obj
->format
;
3285 ret
= fruaccess_func
[fru_format
.format
- 1].read_segment(segment
,
3286 buffer
, nbytes
, cred
);
3291 fru_write_segment(segment_hdl_t segment
, const void *data
, size_t nbytes
,
3292 segment_hdl_t
*newsegment
, door_cred_t
*cred
)
3295 format_t fru_format
;
3296 hash_obj_t
*hash_obj
;
3298 hash_obj
= get_container_hash_object(PACKET_TYPE
, segment
);
3299 if (hash_obj
== NULL
) {
3302 fru_format
= hash_obj
->u
.cont_obj
->format
;
3304 ret
= fruaccess_func
[fru_format
.format
- 1].write_segment(segment
,
3305 data
, nbytes
, newsegment
, cred
);
3310 fru_get_num_packets(segment_hdl_t segment
, door_cred_t
*cred
)
3313 format_t fru_format
;
3314 hash_obj_t
*hash_obj
;
3316 hash_obj
= get_container_hash_object(PACKET_TYPE
, segment
);
3317 if (hash_obj
== NULL
) {
3320 fru_format
= hash_obj
->u
.cont_obj
->format
;
3322 ret
= fruaccess_func
[fru_format
.format
- 1].get_num_packets(segment
,
3328 fru_get_packets(segment_hdl_t segment
, packet_t
*packet
,
3329 int max_packets
, door_cred_t
*cred
)
3332 format_t fru_format
;
3333 hash_obj_t
*hash_obj
;
3335 hash_obj
= get_container_hash_object(PACKET_TYPE
, segment
);
3336 if (hash_obj
== NULL
) {
3339 fru_format
= hash_obj
->u
.cont_obj
->format
;
3341 ret
= fruaccess_func
[fru_format
.format
- 1].get_packets(segment
,
3342 packet
, max_packets
, cred
);
3347 fru_get_payload(packet_hdl_t packet
, void *buffer
,
3348 size_t nbytes
, door_cred_t
*cred
)
3351 format_t fru_format
;
3352 hash_obj_t
*hash_obj
;
3354 hash_obj
= lookup_handle_object(packet
, PACKET_TYPE
);
3355 if (hash_obj
== NULL
) {
3359 hash_obj
= get_container_hash_object(PACKET_TYPE
,
3360 hash_obj
->u
.pkt_obj
->segment_hdl
);
3361 if (hash_obj
== NULL
) {
3364 fru_format
= hash_obj
->u
.cont_obj
->format
;
3366 ret
= fruaccess_func
[fru_format
.format
- 1].get_payload(packet
, buffer
,
3372 fru_update_payload(packet_hdl_t packet
, const void *data
, size_t nbytes
,
3373 packet_hdl_t
*newpacket
, door_cred_t
*cred
)
3376 format_t fru_format
;
3377 hash_obj_t
*hash_obj
;
3379 hash_obj
= lookup_handle_object(packet
, PACKET_TYPE
);
3380 if (hash_obj
== NULL
) {
3384 hash_obj
= get_container_hash_object(PACKET_TYPE
,
3385 hash_obj
->u
.pkt_obj
->segment_hdl
);
3386 if (hash_obj
== NULL
) {
3389 fru_format
= hash_obj
->u
.cont_obj
->format
;
3390 ret
= fruaccess_func
[fru_format
.format
- 1].update_payload(packet
, data
,
3391 nbytes
, newpacket
, cred
);
3396 fru_append_packet(segment_hdl_t segment
, packet_t
*packet
,
3397 const void *payload
, size_t nbytes
, segment_hdl_t
*newsegment
,
3401 format_t fru_format
;
3402 hash_obj_t
*hash_obj
;
3404 hash_obj
= get_container_hash_object(PACKET_TYPE
, segment
);
3405 if (hash_obj
== NULL
) {
3408 fru_format
= hash_obj
->u
.cont_obj
->format
;
3410 ret
= fruaccess_func
[fru_format
.format
- 1].append_packet(segment
,
3411 packet
, payload
, nbytes
, newsegment
, cred
);
3416 fru_delete_packet(packet_hdl_t packet
, segment_hdl_t
*newsegment
,
3420 format_t fru_format
;
3421 hash_obj_t
*hash_obj
;
3423 hash_obj
= lookup_handle_object(packet
, PACKET_TYPE
);
3424 if (hash_obj
== NULL
) {
3428 hash_obj
= get_container_hash_object(PACKET_TYPE
,
3429 hash_obj
->u
.pkt_obj
->segment_hdl
);
3430 if (hash_obj
== NULL
) {
3433 fru_format
= hash_obj
->u
.cont_obj
->format
;
3435 ret
= fruaccess_func
[fru_format
.format
- 1].delete_packet(packet
,