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.
32 #include "fru_access_impl.h"
36 #include "fru_access.h"
40 raw_list_t
*g_raw
= NULL
;
45 treehdl_to_rawlist(fru_treehdl_t handle
)
51 static container_hdl_t
52 treehdl_to_conthdl(fru_treehdl_t handle
)
56 ptr
= treehdl_to_rawlist(handle
);
75 return (FRU_INVALPERM
);
83 make_raw(uint8_t *buffer
, size_t size
, char *cont_type
)
87 node
= (raw_list_t
*)malloc(sizeof (raw_list_t
));
95 node
->cont_type
= strdup(cont_type
);
96 if (node
->cont_type
== NULL
) {
108 * 0 - pointer to byte buffer (in)
109 * 1 - size of buffer (in)
110 * 2 - container type, string (in)
113 frt_initialize(int num
, char **args
)
118 return (FRU_FAILURE
);
121 g_raw
= make_raw((uint8_t *)args
[0], (size_t)args
[1], args
[2]);
123 return (FRU_FAILURE
);
126 g_raw
->cont
= open_raw_data(g_raw
);
127 if (g_raw
->cont
== NULL
) {
128 return (FRU_FAILURE
);
131 return (FRU_SUCCESS
);
138 segment_list_t
*lptr
, *lptr2
;
140 (void) fru_close_container(g_raw
->cont
);
141 free(g_raw
->cont_type
);
150 return (FRU_SUCCESS
);
155 frt_get_root(fru_treehdl_t
*node
)
159 return (FRU_SUCCESS
);
164 frt_get_peer(fru_treehdl_t sibling
, fru_treehdl_t
*peer
)
166 return (FRU_NODENOTFOUND
);
170 frt_get_child(fru_treehdl_t handle
, fru_treehdl_t
*child
)
172 return (FRU_NODENOTFOUND
);
177 frt_get_parent(fru_treehdl_t handle
, fru_treehdl_t
*parent
)
179 return (FRU_NODENOTFOUND
);
184 frt_get_name_from_hdl(fru_treehdl_t handle
, char **name
)
186 *name
= strdup("unknown");
187 return (FRU_SUCCESS
);
192 frt_get_node_type(fru_treehdl_t node
, fru_node_t
*type
)
194 *type
= FRU_NODE_CONTAINER
;
195 return (FRU_SUCCESS
);
201 add_segs_for_section(section_t
*section
, fru_strlist_t
*list
)
204 segment_t
*segs
= NULL
;
207 int num_segment
= fru_get_num_segments(section
->handle
, NULL
);
208 if (num_segment
== -1) {
209 return (map_errno(errno
));
210 } else if (num_segment
== 0) {
211 return (FRU_SUCCESS
);
214 segs
= malloc(sizeof (*segs
) * (num_segment
));
216 return (FRU_FAILURE
);
219 acc_err
= fru_get_segments(section
->handle
, segs
, num_segment
, NULL
);
222 return (map_errno(errno
));
225 list
->strs
= realloc(list
->strs
, sizeof (char *)
226 * (list
->num
+ num_segment
));
228 for (i
= 0; i
< num_segment
; i
++) {
229 /* ensure NULL terminated. */
230 char *tmp
= malloc(sizeof (*tmp
) * (sizeof (segs
[i
].name
)+1));
233 return (FRU_FAILURE
);
235 (void) memcpy(tmp
, segs
[i
].name
, sizeof (segs
[i
].name
));
236 tmp
[sizeof (segs
[i
].name
)] = '\0';
238 list
->strs
[(list
->num
)++] = tmp
;
243 return (FRU_SUCCESS
);
249 frt_get_seg_list(fru_treehdl_t handle
, fru_strlist_t
*list
)
251 fru_strlist_t rc_list
;
252 fru_errno_t err
= FRU_SUCCESS
;
256 section_t
*sects
= NULL
;
257 container_hdl_t cont
;
259 cont
= treehdl_to_conthdl(handle
);
261 num_section
= fru_get_num_sections(cont
, NULL
);
262 if (num_section
== -1) {
263 return (map_errno(errno
));
266 sects
= malloc(sizeof (*sects
) * (num_section
));
268 return (FRU_FAILURE
);
271 acc_err
= fru_get_sections(cont
, sects
, num_section
, NULL
);
274 return (map_errno(errno
));
279 for (i
= 0; i
< num_section
; i
++) {
280 if ((err
= add_segs_for_section(&(sects
[i
]), &rc_list
))
282 fru_destroy_strlist(&rc_list
);
288 list
->strs
= rc_list
.strs
;
289 list
->num
= rc_list
.num
;
291 return (FRU_SUCCESS
);
296 find_seg_in_sect(section_t
*sect
, const char *seg_name
, int *prot_flg
,
301 segment_t
*segs
= NULL
;
303 int num_seg
= fru_get_num_segments(sect
->handle
, NULL
);
305 return (FRU_FAILURE
);
308 segs
= malloc(sizeof (*segs
) * (num_seg
));
310 return (FRU_FAILURE
);
313 acc_err
= fru_get_segments(sect
->handle
, segs
, num_seg
, NULL
);
316 return (map_errno(errno
));
319 for (j
= 0; j
< num_seg
; j
++) {
321 char tmp
[SEG_NAME_LEN
+1];
322 (void) memcpy(tmp
, segs
[j
].name
, SEG_NAME_LEN
);
323 tmp
[SEG_NAME_LEN
] = '\0';
324 if (strcmp(tmp
, seg_name
) == 0) {
326 *prot_flg
= (sect
->protection
? 1 : 0);
328 return (FRU_SUCCESS
);
333 return (FRU_INVALSEG
);
338 find_segment(fru_treehdl_t handle
, const char *seg_name
, int *prot_flg
,
343 section_t
*sect
= NULL
;
344 container_hdl_t cont
;
347 cont
= treehdl_to_conthdl(handle
);
349 num_sect
= fru_get_num_sections(cont
, NULL
);
350 if (num_sect
== -1) {
351 return (map_errno(errno
));
354 sect
= malloc(sizeof (*sect
) * (num_sect
));
356 return (FRU_FAILURE
);
359 acc_err
= fru_get_sections(cont
, sect
, num_sect
, NULL
);
362 return (map_errno(errno
));
365 for (i
= 0; i
< num_sect
; i
++) {
366 if (find_seg_in_sect(&(sect
[i
]), seg_name
, prot_flg
, segment
)
369 return (FRU_SUCCESS
);
374 return (FRU_INVALSEG
);
379 frt_get_seg_def(fru_treehdl_t handle
, const char *seg_name
, fru_segdef_t
*def
)
381 fru_errno_t err
= FRU_SUCCESS
;
385 if ((err
= find_segment(handle
, seg_name
, &prot_flg
, &segment
))
390 (void) memcpy(def
->name
, segment
.name
, SEG_NAME_LEN
);
391 def
->name
[SEG_NAME_LEN
] = '\0';
392 def
->desc
.raw_data
= segment
.descriptor
;
393 def
->size
= segment
.length
;
394 def
->address
= segment
.offset
;
397 def
->hw_desc
.field
.read_only
= 0;
399 def
->hw_desc
.field
.read_only
= 1;
401 return (FRU_SUCCESS
);
407 frt_add_seg(fru_treehdl_t handle
, fru_segdef_t
*def
)
415 frt_delete_seg(fru_treehdl_t handle
, const char *seg_name
)
423 frt_for_each_segment(fru_nodehdl_t node
,
424 int (*function
)(fru_seghdl_t hdl
, void *args
), void *args
)
432 segment_list_t
*tmp_list
;
435 container_hdl_t cont
;
439 num_sect
= fru_get_num_sections(cont
, NULL
);
440 if (num_sect
== -1) {
441 return (map_errno(errno
));
444 sects
= malloc((num_sect
+ 1) * sizeof (section_t
));
446 return (FRU_FAILURE
);
448 num_sect
= fru_get_sections(cont
, sects
, num_sect
, NULL
);
449 if (num_sect
== -1) {
451 return (map_errno(errno
));
453 for (cnt
= 0; cnt
< num_sect
; cnt
++) {
454 num_segment
= fru_get_num_segments(sects
[cnt
].handle
, NULL
);
455 if (num_segment
== -1) {
456 return (map_errno(errno
));
457 } else if (num_segment
== 0) {
460 segs
= malloc((num_segment
+ 1) * sizeof (segment_t
));
463 return (FRU_FAILURE
);
465 acc_err
= fru_get_segments(sects
[cnt
].handle
, segs
,
470 return (map_errno(errno
));
472 for (each_seg
= 0; each_seg
< num_segment
; each_seg
++) {
473 tmp_list
= malloc(sizeof (segment_list_t
));
474 tmp_list
->segment
= &segs
[each_seg
];
475 tmp_list
->next
= NULL
;
476 if (g_raw
->segs
== NULL
) {
477 g_raw
->segs
= tmp_list
;
479 tmp_list
->next
= g_raw
->segs
;
480 g_raw
->segs
= tmp_list
;
483 if ((status
= function(segs
[each_seg
].handle
, args
))
494 return (FRU_SUCCESS
);
499 frt_get_segment_name(fru_seghdl_t node
, char **name
)
508 container_hdl_t cont
;
510 cont
= treehdl_to_conthdl(node
);
512 num_sect
= fru_get_num_sections(cont
, NULL
);
513 if (num_sect
== -1) {
514 return (map_errno(errno
));
517 sects
= malloc(sizeof (*sects
) * (num_sect
));
519 return (FRU_FAILURE
);
521 acc_err
= fru_get_sections(cont
, sects
, num_sect
, NULL
);
524 return (map_errno(errno
));
527 for (cnt
= 0; cnt
< num_sect
; cnt
++) {
528 num_segment
= fru_get_num_segments(sects
[cnt
].handle
, NULL
);
529 if (num_segment
== -1) {
531 return (map_errno(errno
));
532 } else if (num_segment
== 0) {
536 segs
= malloc(sizeof (*segs
) * (num_segment
));
539 return (FRU_FAILURE
);
542 acc_err
= fru_get_segments(sects
[cnt
].handle
, segs
,
547 return (map_errno(errno
));
550 for (each_seg
= 0; each_seg
< num_segment
; each_seg
++) {
551 if (segs
[each_seg
].handle
== node
) {
552 segs
[each_seg
].name
[FRU_SEGNAMELEN
] = '\0';
553 *name
= strdup(segs
[each_seg
].name
);
556 return (FRU_SUCCESS
);
562 return (FRU_FAILURE
);
568 frt_add_tag_to_seg(fru_treehdl_t handle
, const char *seg_name
,
569 fru_tag_t tag
, uint8_t *data
, size_t data_len
)
578 frt_get_tag_list(fru_treehdl_t handle
, const char *seg_name
,
579 fru_tag_t
**tags
, int *number
)
588 frt_get_tag_data(fru_treehdl_t handle
, const char *seg_name
, fru_tag_t tag
,
589 int instance
, uint8_t **data
, size_t *data_len
)
598 frt_set_tag_data(fru_treehdl_t handle
, const char *seg_name
, fru_tag_t tag
,
599 int instance
, uint8_t *data
, size_t data_len
)
608 frt_delete_tag(fru_treehdl_t handle
, const char *seg_name
, fru_tag_t tag
,
617 frt_for_each_packet(fru_seghdl_t node
, int (*function
)(fru_tag_t
*tag
,
618 uint8_t *payload
, size_t length
, void *args
), void *args
)
624 packet_t
*packets
= NULL
;
625 segment_list_t
*tmp_list
;
626 fru_segdesc_t
*descriptor
;
628 tmp_list
= g_raw
->segs
;
631 rc_num
= fru_get_num_packets(node
, NULL
);
633 return (map_errno(errno
));
634 } else if (rc_num
== 0) {
635 return (FRU_SUCCESS
);
638 if (node
== tmp_list
->segment
->handle
) {
641 tmp_list
= tmp_list
->next
;
644 descriptor
= (fru_segdesc_t
*)&tmp_list
->segment
->descriptor
;
645 if (descriptor
->field
.opaque
) {
646 return (FRU_SUCCESS
);
649 if (descriptor
->field
.encrypted
&& (encrypt_func
== NULL
)) {
650 return (FRU_SUCCESS
);
654 packets
= malloc(sizeof (*packets
) * (rc_num
));
655 if (packets
== NULL
) {
656 return (FRU_FAILURE
);
658 /* get all packets */
659 if (fru_get_packets(node
, packets
, rc_num
, NULL
) == -1) {
661 return (map_errno(errno
));
665 for (i
= 0; i
< rc_num
; i
++) {
667 get_payload_length((fru_tag_t
*)&packets
[i
].tag
);
669 rc_data
= malloc(sizeof (*rc_data
) * (rc_len
));
670 if (rc_data
== NULL
) {
672 return (FRU_FAILURE
);
674 /* get the payload data */
675 (void) fru_get_payload(packets
[i
].handle
, (void *)rc_data
,
680 (fru_segdesc_t
*)&tmp_list
->segment
->descriptor
;
682 if ((descriptor
->field
.encrypted
) &&
683 ((status
= encrypt_func(FRU_DECRYPT
,
684 (void *)rc_data
, rc_len
))
690 if ((status
= function((fru_tag_t
*)&packets
[i
].tag
,
691 (uint8_t *)rc_data
, rc_len
, args
)) != FRU_SUCCESS
) {
698 return (FRU_SUCCESS
);
703 /* object for libfru to link to */
704 fru_datasource_t data_source
=
713 frt_get_name_from_hdl
,
719 frt_for_each_segment
,
720 frt_get_segment_name
,