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 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
41 /* ========================================================================= */
42 #define TREEHDL_TO_PICLHDL(treehdl) ((picl_nodehdl_t)treehdl)
43 #define PICLHDL_TO_TREEHDL(piclhdl) ((fru_treehdl_t)piclhdl)
45 #define TREESEGHDL_TO_PICLHDL(treeseghdl) ((picl_nodehdl_t)treeseghdl)
46 #define PICLHDL_TO_TREESEGHDL(piclhdl) ((fru_treeseghdl_t)piclhdl)
48 /* Cache of the root node for quick checks */
49 static picl_nodehdl_t picl_root_node
;
52 /* ========================================================================= */
54 * Map the PICL errors the plugin would give me to FRU errors
57 map_plugin_err(int picl_err
)
63 return (FRU_INVALPERM
);
69 return (FRU_NORESPONSE
);
70 case PICL_PROPNOTFOUND
:
71 return (FRU_NODENOTFOUND
);
73 return (FRU_DATANOTFOUND
);
78 /* ========================================================================= */
80 * cause a refresh of the sub-nodes by writing anything to the container
81 * property of the node.
84 update_data_nodes(picl_nodehdl_t handle
)
86 uint32_t container
= FRUDATA_DELETE_TAG_KEY
;
87 int picl_err
= PICL_SUCCESS
;
89 if ((picl_err
= picl_set_propval_by_name(handle
,
90 PICL_PROP_CONTAINER
, (void *)&container
,
91 sizeof (container
))) != PICL_SUCCESS
) {
92 return (map_plugin_err(picl_err
));
98 /* ========================================================================= */
100 * picl like function which gets a string property with the proper length
101 * NOTE: returns picl errno values NOT fru_errno_t
104 get_strprop_by_name(picl_nodehdl_t handle
, char *prop_name
, char **string
)
106 int picl_err
= PICL_SUCCESS
;
107 picl_prophdl_t proph
;
108 picl_propinfo_t prop_info
;
109 char *tmp_buf
= NULL
;
111 if ((picl_err
= picl_get_propinfo_by_name(handle
, prop_name
,
112 &prop_info
, &proph
)) != PICL_SUCCESS
) {
116 tmp_buf
= malloc((sizeof (*tmp_buf
) * prop_info
.size
));
117 if (tmp_buf
== NULL
) {
118 return (PICL_FAILURE
);
121 if ((picl_err
= picl_get_propval(proph
, tmp_buf
, prop_info
.size
))
128 return (PICL_SUCCESS
);
131 /* ========================================================================= */
133 fpt_get_name_from_hdl(fru_treehdl_t node
, char **name
)
135 int picl_err
= PICL_SUCCESS
;
136 char *tmp_name
= NULL
;
138 picl_nodehdl_t handle
= TREEHDL_TO_PICLHDL(node
);
141 if ((picl_err
= get_strprop_by_name(handle
, PICL_PROP_NAME
,
142 &tmp_name
)) != PICL_SUCCESS
) {
143 return (map_plugin_err(picl_err
));
146 /* get the label, if any */
147 if ((picl_err
= get_strprop_by_name(handle
, PICL_PROP_LABEL
,
148 &label
)) != PICL_SUCCESS
) {
149 if (picl_err
!= PICL_PROPNOTFOUND
) {
151 return (map_plugin_err(picl_err
));
153 /* else PICL_PROPNOTFOUND is OK because not all nodes */
154 /* will have a label. */
157 /* construct the name as nessecary */
159 *name
= strdup(tmp_name
);
161 #define FRU_LABEL_PADDING 10
162 size_t buf_size
= strlen(tmp_name
) + strlen(label
) +
164 char *tmp
= malloc(buf_size
);
168 return (FRU_FAILURE
);
170 snprintf(tmp
, buf_size
, "%s?%s=%s", tmp_name
,
171 PICL_PROP_LABEL
, label
);
177 return (FRU_SUCCESS
);
180 /* ========================================================================= */
181 /* compare the node name to the name passed */
183 cmp_node_name(picl_nodehdl_t node
, const char *name
)
185 char *node_name
= NULL
;
187 if (get_strprop_by_name(node
, PICL_PROP_NAME
, &node_name
)
189 return (FRU_FAILURE
);
192 if (strcmp(node_name
, name
) == 0) {
194 return (FRU_SUCCESS
);
198 return (FRU_FAILURE
);
201 /* ========================================================================= */
202 /* compare the node class name to the name passed */
204 cmp_class_name(picl_nodehdl_t node
, const char *name
)
206 char *class_name
= NULL
;
208 if (get_strprop_by_name(node
, PICL_PROP_CLASSNAME
, &class_name
)
210 return (FRU_FAILURE
);
213 if (strcmp(class_name
, name
) == 0) {
215 return (FRU_SUCCESS
);
219 return (FRU_FAILURE
);
223 /* ========================================================================= */
224 /* get the "frutree" root node */
226 fpt_get_root(fru_treehdl_t
*node
)
228 picl_nodehdl_t picl_node
;
229 int picl_err
= PICL_SUCCESS
;
231 picl_err
= picl_get_root(&picl_node
);
232 if ((picl_err
= picl_get_propval_by_name(picl_node
, PICL_PROP_CHILD
,
233 (void *)&picl_node
, sizeof (picl_node
)))
235 return (map_plugin_err(picl_err
));
238 while (cmp_node_name(picl_node
, PICL_NODE_FRUTREE
)
241 if ((picl_err
= picl_get_propval_by_name(picl_node
,
242 PICL_PROP_PEER
, (void *)&picl_node
,
243 sizeof (picl_node
))) == PICL_PROPNOTFOUND
) {
244 return (FRU_NODENOTFOUND
);
245 } else if (picl_err
!= PICL_SUCCESS
) {
246 return (map_plugin_err(picl_err
));
250 picl_root_node
= picl_node
;
251 *node
= PICLHDL_TO_TREEHDL(picl_node
);
252 return (FRU_SUCCESS
);
255 /* ========================================================================= */
257 fpt_get_peer(fru_treehdl_t sibling
, fru_treehdl_t
*peer
)
259 int rc
= PICL_SUCCESS
;
260 picl_nodehdl_t handle
= TREEHDL_TO_PICLHDL(sibling
);
261 picl_nodehdl_t picl_peer
;
263 rc
= picl_get_propval_by_name(handle
, PICL_PROP_PEER
,
264 (void *)&picl_peer
, sizeof (picl_peer
));
265 if (rc
!= PICL_SUCCESS
) {
266 return (map_plugin_err(rc
));
269 *peer
= PICLHDL_TO_TREEHDL(picl_peer
);
270 return (FRU_SUCCESS
);
273 /* ========================================================================= */
275 fpt_get_child(fru_treehdl_t handle
, fru_treehdl_t
*child
)
277 picl_nodehdl_t p_child
;
278 int rc
= picl_get_propval_by_name(TREEHDL_TO_PICLHDL(handle
),
279 PICL_PROP_CHILD
, (void *)&p_child
, sizeof (p_child
));
280 if (rc
!= PICL_SUCCESS
) {
281 return (map_plugin_err(rc
));
284 *child
= PICLHDL_TO_TREEHDL(p_child
);
285 return (FRU_SUCCESS
);
288 /* ========================================================================= */
290 fpt_get_parent(fru_treehdl_t handle
, fru_treehdl_t
*parent
)
292 int rc
= PICL_SUCCESS
;
293 picl_nodehdl_t p_parent
;
295 /* do not allow the libfru users to see the parent of the root */
296 if (TREEHDL_TO_PICLHDL(handle
) == picl_root_node
) {
297 return (FRU_NODENOTFOUND
);
300 rc
= picl_get_propval_by_name(TREEHDL_TO_PICLHDL(handle
),
301 PICL_PROP_PARENT
, (void *)&p_parent
, sizeof (p_parent
));
302 if (rc
!= PICL_SUCCESS
) {
303 return (map_plugin_err(rc
));
306 *parent
= PICLHDL_TO_TREEHDL(p_parent
);
307 return (FRU_SUCCESS
);
310 /* ========================================================================= */
312 fpt_get_node_type(fru_treehdl_t node
, fru_node_t
*type
)
314 int rc
= PICL_SUCCESS
;
315 char picl_class
[PICL_PROPNAMELEN_MAX
];
316 picl_nodehdl_t handle
= TREEHDL_TO_PICLHDL(node
);
318 if ((rc
= picl_get_propval_by_name(handle
, PICL_PROP_CLASSNAME
,
319 picl_class
, sizeof (picl_class
))) != PICL_SUCCESS
) {
320 return (map_plugin_err(rc
));
323 if (strcmp(picl_class
, PICL_CLASS_LOCATION
) == 0) {
324 *type
= FRU_NODE_LOCATION
;
325 return (FRU_SUCCESS
);
326 } else if (strcmp(picl_class
, PICL_CLASS_FRU
) == 0) {
327 picl_prophdl_t proph
;
329 /* check for the CONTAINER_PROP property which indicates */
330 /* there is data for this node. (ie fru is a container) */
331 if (picl_get_prop_by_name(handle
,
332 PICL_PROP_CONTAINER
, &proph
) == PICL_SUCCESS
) {
333 *type
= FRU_NODE_CONTAINER
;
334 return (FRU_SUCCESS
);
336 *type
= FRU_NODE_FRU
;
337 return (FRU_SUCCESS
);
340 *type
= FRU_NODE_UNKNOWN
;
341 return (FRU_SUCCESS
);
344 /* ========================================================================= */
345 /* find the next section or return NODENOTFOUND */
347 find_next_section(picl_nodehdl_t current
, picl_nodehdl_t
*next
)
349 picl_nodehdl_t rc_next
;
351 if (picl_get_propval_by_name(current
, PICL_PROP_PEER
,
352 (void *)&rc_next
, sizeof (rc_next
)) != PICL_SUCCESS
) {
353 return (FRU_NODENOTFOUND
);
356 /* Make sure this is a "Section" node */
357 if (cmp_class_name(rc_next
, PICL_CLASS_SECTION
)
360 return (FRU_SUCCESS
);
363 /* and if this is not good keep trying to find a peer which */
365 return (find_next_section(rc_next
, next
));
368 /* ========================================================================= */
369 /* find the first section or return NODENOTFOUND */
371 find_first_section(picl_nodehdl_t parent
, picl_nodehdl_t
*section
)
373 picl_nodehdl_t rc_section
;
375 if (picl_get_propval_by_name(parent
, PICL_PROP_CHILD
,
376 (void *)&rc_section
, sizeof (rc_section
)) != PICL_SUCCESS
) {
377 return (FRU_NODENOTFOUND
);
380 /* Make sure this is a "Section" node */
381 if (cmp_class_name(rc_section
, PICL_CLASS_SECTION
)
383 *section
= rc_section
;
384 return (FRU_SUCCESS
);
387 /* and if this is not good keep trying to find a peer which */
389 return (find_next_section(rc_section
, section
));
392 /* ========================================================================= */
394 * Find the handle of the segment node "segment".
395 * also returns the hardware description of this segment. (read from the
396 * section this was found in.)
397 * If the ign_cor_flg is set this will still succeed even if the segment is
398 * corrupt, otherwise it will return FRU_SEGCORRUPT for corrupt segments
400 #define IGN_CORRUPT_YES 1
401 #define IGN_CORRUPT_NO 0
403 get_segment_node(picl_nodehdl_t handle
, const char *segment
,
404 picl_nodehdl_t
*seg_hdl
, fru_seg_hwdesc_t
*hw_desc
, int ign_cor_flg
)
406 fru_errno_t err
= FRU_SUCCESS
;
407 picl_nodehdl_t sect_node
;
409 if ((err
= update_data_nodes(handle
)) != FRU_SUCCESS
) {
413 if ((err
= find_first_section(handle
, §_node
)) != FRU_SUCCESS
) {
417 /* while there are sections. */
418 while (err
== FRU_SUCCESS
) {
419 uint32_t num_segs
= 0;
420 int rc
= PICL_SUCCESS
;
421 picl_nodehdl_t seg_node
;
423 /* do this just in case the Segments have not been built. */
424 if ((rc
= picl_get_propval_by_name(sect_node
,
425 PICL_PROP_NUM_SEGMENTS
,
427 sizeof (num_segs
))) != PICL_SUCCESS
) {
428 return (map_plugin_err(rc
));
431 /* while there are segments. */
432 rc
= picl_get_propval_by_name(sect_node
, PICL_PROP_CHILD
,
433 (void *)&seg_node
, sizeof (seg_node
));
434 while (rc
== PICL_SUCCESS
) {
435 char name
[PICL_PROPNAMELEN_MAX
];
436 picl_get_propval_by_name(seg_node
, PICL_PROP_NAME
,
437 name
, sizeof (name
));
438 if (strcmp(segment
, name
) == 0) {
441 /* NUM_TAGS prop exists iff segment is OK */
442 if ((ign_cor_flg
== IGN_CORRUPT_NO
) &&
443 (picl_get_propval_by_name(seg_node
,
446 sizeof (dummy
)) != PICL_SUCCESS
)) {
447 return (FRU_SEGCORRUPT
);
449 /* get the HW protections of this section. */
450 if ((rc
= picl_get_propval_by_name(sect_node
,
453 sizeof (protection
)))
455 return (map_plugin_err(rc
));
457 hw_desc
->all_bits
= 0;
458 hw_desc
->field
.read_only
= protection
;
461 return (FRU_SUCCESS
);
463 rc
= picl_get_propval_by_name(seg_node
, PICL_PROP_PEER
,
464 (void *)&seg_node
, sizeof (seg_node
));
467 /* Peer property not found is ok */
468 if (rc
!= PICL_PROPNOTFOUND
) {
469 return (map_plugin_err(rc
));
472 err
= find_next_section(sect_node
, §_node
);
475 return (FRU_INVALSEG
);
478 /* ========================================================================= */
480 * For the section handle passed add to list all the segment names found.
481 * Also incriments total by the number found.
484 add_segs_for_section(picl_nodehdl_t section
, fru_strlist_t
*list
)
486 uint32_t num_segments
= 0;
487 int rc
= PICL_SUCCESS
;
489 if ((rc
= picl_get_propval_by_name(section
,
490 PICL_PROP_NUM_SEGMENTS
,
491 (void *)&num_segments
,
492 sizeof (num_segments
))) != PICL_SUCCESS
) {
493 fru_destroy_strlist(list
);
494 return (map_plugin_err(rc
));
497 if (num_segments
!= 0) {
498 picl_nodehdl_t seg_node
;
499 int total_space
= list
->num
+ num_segments
;
501 list
->strs
= realloc(list
->strs
,
502 (sizeof (*(list
->strs
)) * (total_space
)));
503 if (list
->strs
== NULL
) {
504 return (FRU_FAILURE
);
507 /* get the first segment */
508 rc
= picl_get_propval_by_name(section
,
509 PICL_PROP_CHILD
, (void *)&seg_node
,
512 /* while there are more segments. */
513 while (rc
== PICL_SUCCESS
) {
514 char name
[FRU_SEGNAMELEN
+1];
516 if ((rc
= picl_get_propval_by_name(seg_node
,
517 PICL_PROP_NAME
, name
,
518 sizeof (name
))) != PICL_SUCCESS
) {
522 /* check array bounds */
523 if (list
->num
>= total_space
) {
524 /* PICL reported incorrect number of segs */
525 return (FRU_IOERROR
);
527 list
->strs
[(list
->num
)++] = strdup(name
);
529 rc
= picl_get_propval_by_name(seg_node
,
530 PICL_PROP_PEER
, (void *)&seg_node
,
534 /* Peer property not found is ok */
535 if (rc
!= PICL_PROPNOTFOUND
) {
536 return (map_plugin_err(rc
));
540 return (FRU_SUCCESS
);
543 /* ========================================================================= */
545 fpt_get_seg_list(fru_treehdl_t handle
, fru_strlist_t
*list
)
548 picl_nodehdl_t sect_node
;
549 fru_strlist_t rc_list
;
553 if ((err
= update_data_nodes(TREEHDL_TO_PICLHDL(handle
)))
558 if ((err
= find_first_section(TREEHDL_TO_PICLHDL(handle
), §_node
))
563 /* while there are sections. */
564 while (err
== FRU_SUCCESS
) {
565 if ((err
= add_segs_for_section(sect_node
, &rc_list
))
567 fru_destroy_strlist(&rc_list
);
570 err
= find_next_section(sect_node
, §_node
);
573 list
->num
= rc_list
.num
;
574 list
->strs
= rc_list
.strs
;
576 return (FRU_SUCCESS
);
579 /* ========================================================================= */
581 fpt_get_seg_def(fru_treehdl_t handle
, const char *seg_name
, fru_segdef_t
*def
)
583 fru_errno_t err
= FRU_SUCCESS
;
584 picl_nodehdl_t seg_node
;
585 fru_seg_hwdesc_t hw_desc
;
591 int picl_err
= PICL_SUCCESS
;
593 if ((err
= get_segment_node(TREEHDL_TO_PICLHDL(handle
), seg_name
,
594 &seg_node
, &hw_desc
, IGN_CORRUPT_YES
)) != FRU_SUCCESS
)
597 if ((picl_err
= picl_get_propval_by_name(seg_node
,
598 PICL_PROP_DESCRIPTOR
,
599 &desc
, sizeof (desc
))) != PICL_SUCCESS
) {
600 return (map_plugin_err(picl_err
));
603 if ((picl_err
= picl_get_propval_by_name(seg_node
,
605 &size
, sizeof (size
))) != PICL_SUCCESS
) {
606 return (map_plugin_err(picl_err
));
609 if ((picl_err
= picl_get_propval_by_name(seg_node
,
611 &address
, sizeof (address
))) != PICL_SUCCESS
) {
612 return (map_plugin_err(picl_err
));
615 def
->version
= LIBFRU_VERSION
;
616 strlcpy(def
->name
, seg_name
, FRU_SEGNAMELEN
+1);
619 def
->address
= address
;
620 def
->hw_desc
= hw_desc
;
622 return (FRU_SUCCESS
);
625 /* ========================================================================= */
627 fpt_add_seg(fru_treehdl_t handle
, fru_segdef_t
*def
)
629 fru_errno_t err
= FRU_SUCCESS
;
630 int picl_err
= PICL_SUCCESS
;
631 picl_nodehdl_t section
;
634 * for every section which has a ADD_SEGMENT_PROP try and add the segment
636 if ((err
= find_first_section(TREEHDL_TO_PICLHDL(handle
), §ion
))
642 if ((picl_err
= picl_get_propval_by_name(section
,
643 PICL_PROP_ADD_SEGMENT
, &dummy
, sizeof (dummy
)))
646 picl_err
= picl_set_propval_by_name(section
,
647 PICL_PROP_ADD_SEGMENT
, def
, sizeof (*def
));
649 return (map_plugin_err(picl_err
));
651 } while (find_next_section(section
, §ion
) == FRU_SUCCESS
);
653 return (map_plugin_err(picl_err
));
656 /* ========================================================================= */
658 fpt_delete_seg(fru_treehdl_t handle
, const char *seg_name
)
660 picl_nodehdl_t seg_hdl
;
661 fru_seg_hwdesc_t hw_desc
;
664 int dead_flag
= FRUDATA_DELETE_TAG_KEY
;
665 int rc
= PICL_SUCCESS
;
667 if ((err
= get_segment_node(TREEHDL_TO_PICLHDL(handle
), seg_name
,
668 &seg_hdl
, &hw_desc
, IGN_CORRUPT_YES
)) != FRU_SUCCESS
) {
672 rc
= picl_set_propval_by_name(seg_hdl
, PICL_PROP_DELETE_SEGMENT
,
673 &dead_flag
, sizeof (dead_flag
));
674 return (map_plugin_err(rc
));
677 /* ========================================================================= */
679 fpt_add_tag_to_seg(fru_treehdl_t handle
, const char *seg_name
,
680 fru_tag_t tag
, uint8_t *data
, size_t data_len
)
682 fru_errno_t err
= FRU_SUCCESS
;
683 picl_nodehdl_t segHdl
;
684 fru_seg_hwdesc_t hw_desc
;
685 int picl_err
= PICL_SUCCESS
;
687 uint8_t *buffer
= NULL
;
688 picl_prophdl_t add_prop
;
689 picl_propinfo_t add_prop_info
;
691 if ((err
= get_segment_node(TREEHDL_TO_PICLHDL(handle
), seg_name
,
692 &segHdl
, &hw_desc
, IGN_CORRUPT_NO
)) != FRU_SUCCESS
) {
696 /* get the length of the buffer required. */
697 if ((picl_err
= picl_get_prop_by_name(segHdl
,
698 PICL_PROP_ADD_PACKET
,
699 &add_prop
)) != PICL_SUCCESS
) {
700 return (map_plugin_err(picl_err
));
702 if ((picl_err
= picl_get_propinfo(add_prop
, &add_prop_info
))
704 return (map_plugin_err(picl_err
));
707 buf_size
= add_prop_info
.size
;
708 if (data_len
>= (buf_size
- get_tag_size(get_tag_type(&tag
)))) {
709 return (FRU_NOSPACE
);
712 buffer
= malloc(buf_size
);
713 if (buffer
== NULL
) {
714 return (FRU_FAILURE
);
716 /* write the tag and data into the buffer */
717 memcpy(buffer
, &tag
, get_tag_size(get_tag_type(&tag
)));
718 memcpy((void *)(buffer
+get_tag_size(get_tag_type(&tag
))),
721 picl_err
= picl_set_propval(add_prop
, buffer
, buf_size
);
723 return (map_plugin_err(picl_err
));
726 /* ========================================================================= */
728 fpt_get_tag_list(fru_treehdl_t handle
, const char *seg_name
,
729 fru_tag_t
**tags
, int *number
)
731 picl_nodehdl_t seg_node
;
732 fru_seg_hwdesc_t hw_desc
;
733 fru_errno_t err
= FRU_SUCCESS
;
734 picl_prophdl_t tagTable
;
735 int picl_err
= PICL_SUCCESS
;
736 unsigned int total_tags
= 0;
738 /* return variables */
739 fru_tag_t
*rc_tags
= NULL
;
740 unsigned int rc_num
= 0;
742 if ((err
= get_segment_node(TREEHDL_TO_PICLHDL(handle
), seg_name
,
743 &seg_node
, &hw_desc
, IGN_CORRUPT_NO
)) != FRU_SUCCESS
) {
747 /* get the number of tags and allocate array for them */
748 if ((picl_err
= picl_get_propval_by_name(seg_node
,
751 sizeof (total_tags
))) != PICL_SUCCESS
) {
752 return (map_plugin_err(picl_err
));
755 if (total_tags
== 0) {
758 return (FRU_SUCCESS
);
761 rc_tags
= malloc((sizeof (*rc_tags
) * total_tags
));
762 if (rc_tags
== NULL
) {
763 return (FRU_FAILURE
);
766 /* go through the tagTable and fill in the array */
767 if ((picl_err
= picl_get_propval_by_name(seg_node
,
768 PICL_PROP_PACKET_TABLE
,
769 &tagTable
, sizeof (tagTable
))) != PICL_SUCCESS
) {
771 return (map_plugin_err(picl_err
));
773 picl_err
= picl_get_next_by_col(tagTable
, &tagTable
);
774 while (picl_err
== PICL_SUCCESS
) {
775 /* check array bounds */
776 if (rc_num
>= total_tags
) {
778 return (FRU_FAILURE
);
780 /* fill in the array */
781 if ((picl_err
= picl_get_propval(tagTable
,
782 (void *)&(rc_tags
[rc_num
++]),
783 sizeof (fru_tag_t
))) != PICL_SUCCESS
) {
785 return (map_plugin_err(picl_err
));
787 /* get the next tag */
788 picl_err
= picl_get_next_by_col(tagTable
, &tagTable
);
791 if (picl_err
== PICL_ENDOFLIST
) {
794 return (FRU_SUCCESS
);
796 return (map_plugin_err(picl_err
));
799 /* ========================================================================= */
801 * From the handle, segment name, tag, and instance of the tag get me:
802 * segHdl: The segment handle for this segment.
803 * tagHdl: tag property handle in the tag table for this instance "tag"
806 get_tag_handle(picl_nodehdl_t handle
, const char *segment
,
807 fru_tag_t tag
, int instance
,
808 picl_nodehdl_t
*segHdl
,
809 picl_prophdl_t
*tagHdl
)
811 fru_seg_hwdesc_t hw_desc
;
813 picl_prophdl_t tagTable
= 0;
814 int picl_err
= PICL_SUCCESS
;
815 picl_nodehdl_t tmp_seg
;
819 if ((err
= get_segment_node(TREEHDL_TO_PICLHDL(handle
), segment
,
820 &tmp_seg
, &hw_desc
, IGN_CORRUPT_NO
)) != FRU_SUCCESS
) {
824 foundTag
.raw_data
= 0;
825 if ((picl_err
= picl_get_propval_by_name(tmp_seg
,
826 PICL_PROP_PACKET_TABLE
,
827 &tagTable
, sizeof (tagTable
))) != PICL_SUCCESS
) {
828 return (map_plugin_err(picl_err
));
831 picl_err
= picl_get_next_by_col(tagTable
, &tagTable
);
832 while ((picl_err
!= PICL_ENDOFLIST
) &&
833 (picl_err
== PICL_SUCCESS
)) {
834 if ((picl_err
= picl_get_propval(tagTable
, (void *)&foundTag
,
835 sizeof (foundTag
))) != PICL_SUCCESS
) {
836 return (map_plugin_err(picl_err
));
838 if ((tags_equal(tag
, foundTag
) == 1) && (instance
-- == 0)) {
841 return (FRU_SUCCESS
);
843 picl_err
= picl_get_next_by_col(tagTable
, &tagTable
);
846 return (map_plugin_err(picl_err
));
849 /* ========================================================================= */
851 fpt_get_tag_data(fru_treehdl_t handle
, const char *seg_name
,
852 fru_tag_t tag
, int instance
,
853 uint8_t **data
, size_t *data_len
)
855 fru_errno_t err
= FRU_SUCCESS
;
856 int picl_err
= PICL_SUCCESS
;
861 picl_prophdl_t tagHdl
;
863 if ((err
= get_tag_handle(TREEHDL_TO_PICLHDL(handle
), seg_name
,
864 tag
, instance
, &seg
, &tagHdl
)) != FRU_SUCCESS
) {
868 if ((picl_err
= picl_get_next_by_row(tagHdl
, &tagHdl
))
870 return (map_plugin_err(picl_err
));
873 buf_len
= get_payload_length(&tag
);
874 buffer
= malloc(buf_len
);
875 if (buffer
== NULL
) {
876 return (FRU_FAILURE
);
879 if ((picl_err
= picl_get_propval(tagHdl
, buffer
, buf_len
))
882 return (map_plugin_err(picl_err
));
887 return (FRU_SUCCESS
);
890 /* ========================================================================= */
892 fpt_set_tag_data(fru_treehdl_t handle
, const char *seg_name
,
893 fru_tag_t tag
, int instance
,
894 uint8_t *data
, size_t data_len
)
896 fru_errno_t rc
= FRU_SUCCESS
;
897 int picl_err
= PICL_SUCCESS
;
900 picl_prophdl_t tagHdl
;
902 if ((rc
= get_tag_handle(TREEHDL_TO_PICLHDL(handle
), seg_name
,
903 tag
, instance
, &seg
, &tagHdl
)) != FRU_SUCCESS
) {
907 if ((picl_err
= picl_get_next_by_row(tagHdl
, &tagHdl
))
909 return (map_plugin_err(picl_err
));
912 if ((picl_err
= picl_set_propval(tagHdl
, data
, data_len
))
914 return (map_plugin_err(picl_err
));
917 return (FRU_SUCCESS
);
920 /* ========================================================================= */
922 fpt_delete_tag(fru_treehdl_t handle
, const char *seg_name
, fru_tag_t tag
,
925 fru_errno_t rc
= FRU_SUCCESS
;
926 int picl_err
= PICL_SUCCESS
;
928 picl_nodehdl_t segHdl
;
929 picl_prophdl_t tagHdl
;
932 if ((rc
= get_tag_handle(TREEHDL_TO_PICLHDL(handle
), seg_name
,
933 tag
, instance
, &segHdl
, &tagHdl
)) != FRU_SUCCESS
) {
938 tag
.raw_data
&= FRUDATA_DELETE_TAG_MASK
;
939 tag
.raw_data
|= FRUDATA_DELETE_TAG_KEY
;
942 picl_err
= picl_set_propval(tagHdl
, (void *)&(tag
.raw_data
),
943 sizeof (tag
.raw_data
));
944 return (map_plugin_err(picl_err
));
947 /* ========================================================================= */
949 fpt_for_each_segment(fru_treehdl_t treenode
,
950 int (*function
)(fru_treeseghdl_t segment
, void *args
),
953 int num_segments
= 0, status
;
955 fru_errno_t saved_status
= FRU_SUCCESS
;
957 picl_nodehdl_t container
= TREEHDL_TO_PICLHDL(treenode
),
961 if ((status
= update_data_nodes(container
)) != FRU_SUCCESS
)
964 /* process each section */
965 for (status
= picl_get_propval_by_name(container
, PICL_PROP_CHILD
,
966 §ion
, sizeof (section
));
967 status
== PICL_SUCCESS
;
968 status
= picl_get_propval_by_name(section
, PICL_PROP_PEER
,
972 if (cmp_class_name(section
, PICL_CLASS_SECTION
) != FRU_SUCCESS
)
975 if ((status
= picl_get_propval_by_name(section
,
976 PICL_PROP_NUM_SEGMENTS
,
978 sizeof (num_segments
)))
979 == PICL_PROPNOTFOUND
) {
981 } else if (status
!= PICL_SUCCESS
) {
982 saved_status
= map_plugin_err(status
);
984 } else if (num_segments
== 0) {
988 /* process each segment */
989 for (status
= picl_get_propval_by_name(section
,
993 status
== PICL_SUCCESS
;
994 status
= picl_get_propval_by_name(segment
,
999 if (cmp_class_name(segment
, PICL_CLASS_SEGMENT
)
1000 != FRU_SUCCESS
) continue;
1002 if ((status
= function(PICLHDL_TO_TREESEGHDL(segment
),
1004 != FRU_SUCCESS
) return (status
);
1007 if (status
!= PICL_PROPNOTFOUND
)
1008 saved_status
= map_plugin_err(status
);
1011 if (status
!= PICL_PROPNOTFOUND
)
1012 saved_status
= map_plugin_err(status
);
1014 return (saved_status
);
1017 /* ========================================================================= */
1019 fpt_get_segment_name(fru_treeseghdl_t segment
, char **name
)
1025 picl_prophdl_t proph
= 0;
1027 picl_propinfo_t propinfo
;
1030 if ((status
= picl_get_propinfo_by_name(TREESEGHDL_TO_PICLHDL(segment
),
1031 PICL_PROP_NAME
, &propinfo
, &proph
))
1033 return (map_plugin_err(status
));
1035 if (propinfo
.size
== 0)
1036 return (FRU_INVALDATASIZE
);
1038 if ((propval
= malloc(propinfo
.size
)) == NULL
)
1039 return (FRU_NOSPACE
);
1041 if ((status
= picl_get_propval(proph
, propval
, propinfo
.size
))
1044 return (map_plugin_err(status
));
1049 return (FRU_SUCCESS
);
1052 /* ========================================================================= */
1054 fpt_for_each_packet(fru_treeseghdl_t treesegment
,
1055 int (*function
)(fru_tag_t
*tag
, uint8_t *payload
,
1064 picl_nodehdl_t segment
= TREESEGHDL_TO_PICLHDL(treesegment
);
1066 picl_prophdl_t packet
, payloadh
= 0;
1068 picl_propinfo_t propinfo
;
1070 fru_segdesc_t descriptor
;
1075 if ((status
= picl_get_propval_by_name(segment
, PICL_PROP_DESCRIPTOR
,
1077 sizeof (descriptor
)))
1078 != PICL_SUCCESS
) return (map_plugin_err(status
));
1080 if (descriptor
.field
.opaque
)
1081 return (FRU_SUCCESS
);
1083 if (descriptor
.field
.encrypted
&& (encrypt_func
== NULL
))
1084 return (FRU_SUCCESS
);
1086 if ((status
= picl_get_propval_by_name(segment
, PICL_PROP_PACKET_TABLE
,
1087 &packet
, sizeof (packet
)))
1088 == PICL_PROPNOTFOUND
)
1089 return (FRU_SUCCESS
);
1090 else if (status
!= PICL_SUCCESS
)
1091 return (map_plugin_err(status
));
1093 while ((status
= picl_get_next_by_col(packet
, &packet
))
1095 if (((status
= picl_get_propval(packet
, &tag
, sizeof (tag
)))
1097 ((status
= picl_get_next_by_row(packet
, &payloadh
))
1099 ((status
= picl_get_propinfo(payloadh
, &propinfo
))
1101 return (map_plugin_err(status
));
1103 if (propinfo
.size
> 0) {
1104 payload
= alloca(propinfo
.size
);
1105 if ((status
= picl_get_propval(payloadh
, payload
,
1107 != PICL_SUCCESS
) return (map_plugin_err(status
));
1112 if ((descriptor
.field
.encrypted
) &&
1113 ((status
= encrypt_func(FRU_DECRYPT
, payload
,
1115 != FRU_SUCCESS
)) return status
;
1117 if ((status
= function(&tag
, payload
, propinfo
.size
, args
))
1118 != FRU_SUCCESS
) return (status
);
1121 if (status
== PICL_ENDOFLIST
)
1122 return (FRU_SUCCESS
);
1124 return (map_plugin_err(status
));
1127 /* ========================================================================= */
1130 initialize(int argc
, char **argv
)
1133 int rc
= PICL_SUCCESS
;
1134 if ((rc
= picl_initialize()) != PICL_SUCCESS
) {
1135 return (FRU_FAILURE
);
1138 return (FRU_SUCCESS
);
1141 /* ========================================================================= */
1145 if (picl_shutdown() != PICL_SUCCESS
) {
1146 return (FRU_FAILURE
);
1148 return (FRU_SUCCESS
);
1151 /* ========================================================================= */
1152 /* object for libfru to link to */
1153 fru_datasource_t data_source
=
1162 fpt_get_name_from_hdl
,
1168 fpt_for_each_segment
,
1169 fpt_get_segment_name
,