17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 23*35551380Skmohan * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include <alloca.h> 307c478bd9Sstevel@tonic-gate #include <picl.h> 317c478bd9Sstevel@tonic-gate #include <picltree.h> 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #include <string.h> 347c478bd9Sstevel@tonic-gate #include <stdlib.h> 357c478bd9Sstevel@tonic-gate #include <stdarg.h> 367c478bd9Sstevel@tonic-gate #include <stdio.h> 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate #include "picldefs.h" 397c478bd9Sstevel@tonic-gate #include "fru_data.h" 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate #include "libfruds.h" 427c478bd9Sstevel@tonic-gate #include "libfrup.h" 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate #define FRU_LABEL_PADDING 10 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate /* ========================================================================= */ 477c478bd9Sstevel@tonic-gate #define TREEHDL_TO_PICLHDL(treehdl) ((picl_nodehdl_t)treehdl) 487c478bd9Sstevel@tonic-gate #define PICLHDL_TO_TREEHDL(piclhdl) ((fru_treehdl_t)piclhdl) 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate #define TREESEGHDL_TO_PICLHDL(treeseghdl) ((picl_nodehdl_t)treeseghdl) 517c478bd9Sstevel@tonic-gate #define PICLHDL_TO_TREESEGHDL(piclhdl) ((fru_treeseghdl_t)piclhdl) 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate /* Cache of the root node for quick checks */ 547c478bd9Sstevel@tonic-gate static picl_nodehdl_t picl_root_node; 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate /* ========================================================================= */ 577c478bd9Sstevel@tonic-gate /* 587c478bd9Sstevel@tonic-gate * Map the PICL errors the plugin would give me to FRU errors 597c478bd9Sstevel@tonic-gate */ 607c478bd9Sstevel@tonic-gate static fru_errno_t 617c478bd9Sstevel@tonic-gate map_plugin_err(int picl_err) 627c478bd9Sstevel@tonic-gate { 637c478bd9Sstevel@tonic-gate switch (picl_err) { 647c478bd9Sstevel@tonic-gate case PICL_SUCCESS: 657c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 667c478bd9Sstevel@tonic-gate case PICL_PERMDENIED: 677c478bd9Sstevel@tonic-gate return (FRU_INVALPERM); 687c478bd9Sstevel@tonic-gate case PICL_PROPEXISTS: 697c478bd9Sstevel@tonic-gate return (FRU_DUPSEG); 707c478bd9Sstevel@tonic-gate case PICL_NOSPACE: 717c478bd9Sstevel@tonic-gate return (FRU_NOSPACE); 72*35551380Skmohan case PICL_NORESPONSE: 73*35551380Skmohan return (FRU_NORESPONSE); 74*35551380Skmohan case PICL_PROPNOTFOUND: 75*35551380Skmohan return (FRU_NODENOTFOUND); 76*35551380Skmohan case PICL_ENDOFLIST: 77*35551380Skmohan return (FRU_DATANOTFOUND); 787c478bd9Sstevel@tonic-gate } 797c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 807c478bd9Sstevel@tonic-gate } 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate /* ========================================================================= */ 837c478bd9Sstevel@tonic-gate /* 847c478bd9Sstevel@tonic-gate * cause a refresh of the sub-nodes by writing anything to the container 857c478bd9Sstevel@tonic-gate * property of the node. 867c478bd9Sstevel@tonic-gate */ 877c478bd9Sstevel@tonic-gate static fru_errno_t 887c478bd9Sstevel@tonic-gate update_data_nodes(picl_nodehdl_t handle) 897c478bd9Sstevel@tonic-gate { 907c478bd9Sstevel@tonic-gate uint32_t container = FRUDATA_DELETE_TAG_KEY; 917c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate if ((picl_err = ptree_update_propval_by_name(handle, 947c478bd9Sstevel@tonic-gate PICL_PROP_CONTAINER, (void *)&container, 957c478bd9Sstevel@tonic-gate sizeof (container))) != PICL_SUCCESS) { 967c478bd9Sstevel@tonic-gate return (map_plugin_err(picl_err)); 977c478bd9Sstevel@tonic-gate } 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 1007c478bd9Sstevel@tonic-gate } 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate /* ========================================================================= */ 1037c478bd9Sstevel@tonic-gate /* 1047c478bd9Sstevel@tonic-gate * picl like function which gets a string property with the proper length 1057c478bd9Sstevel@tonic-gate * NOTE: returns picl errno values NOT fru_errno_t 1067c478bd9Sstevel@tonic-gate */ 1077c478bd9Sstevel@tonic-gate static int 1087c478bd9Sstevel@tonic-gate get_strprop_by_name(picl_nodehdl_t handle, char *prop_name, char **string) 1097c478bd9Sstevel@tonic-gate { 1107c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 1117c478bd9Sstevel@tonic-gate picl_prophdl_t proph; 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate size_t buf_size = 0; 1147c478bd9Sstevel@tonic-gate char *tmp_buf = NULL; 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate ptree_propinfo_t prop_info; 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_prop_by_name(handle, prop_name, &proph)) 1197c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 1207c478bd9Sstevel@tonic-gate return (picl_err); 1217c478bd9Sstevel@tonic-gate } 1227c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propinfo(proph, &prop_info)) 1237c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 1247c478bd9Sstevel@tonic-gate return (picl_err); 1257c478bd9Sstevel@tonic-gate } 1267c478bd9Sstevel@tonic-gate buf_size = prop_info.piclinfo.size; 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate tmp_buf = malloc((sizeof (*tmp_buf) * buf_size)); 1297c478bd9Sstevel@tonic-gate if (tmp_buf == NULL) { 1307c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1317c478bd9Sstevel@tonic-gate } 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval(proph, tmp_buf, buf_size)) 1347c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 1357c478bd9Sstevel@tonic-gate free(tmp_buf); 1367c478bd9Sstevel@tonic-gate return (picl_err); 1377c478bd9Sstevel@tonic-gate } 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate *string = tmp_buf; 1407c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 1417c478bd9Sstevel@tonic-gate } 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate /* ========================================================================= */ 1447c478bd9Sstevel@tonic-gate static fru_errno_t 1457c478bd9Sstevel@tonic-gate fpt_get_name_from_hdl(fru_treehdl_t node, char **name) 1467c478bd9Sstevel@tonic-gate { 1477c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 1487c478bd9Sstevel@tonic-gate char *tmp_name = NULL; 1497c478bd9Sstevel@tonic-gate char *label = NULL; 1507c478bd9Sstevel@tonic-gate picl_nodehdl_t handle = TREEHDL_TO_PICLHDL(node); 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate /* get the name */ 1537c478bd9Sstevel@tonic-gate if ((picl_err = get_strprop_by_name(handle, PICL_PROP_NAME, 1547c478bd9Sstevel@tonic-gate &tmp_name)) != PICL_SUCCESS) { 155*35551380Skmohan return (map_plugin_err(picl_err)); 1567c478bd9Sstevel@tonic-gate } 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate /* get the label, if any */ 1597c478bd9Sstevel@tonic-gate if ((picl_err = get_strprop_by_name(handle, PICL_PROP_LABEL, 1607c478bd9Sstevel@tonic-gate &label)) != PICL_SUCCESS) { 1617c478bd9Sstevel@tonic-gate if (picl_err != PICL_PROPNOTFOUND) { 1627c478bd9Sstevel@tonic-gate free(tmp_name); 163*35551380Skmohan return (map_plugin_err(picl_err)); 1647c478bd9Sstevel@tonic-gate } 1657c478bd9Sstevel@tonic-gate /* else PICL_PROPNOTFOUND is OK because not all nodes */ 1667c478bd9Sstevel@tonic-gate /* will have a label. */ 1677c478bd9Sstevel@tonic-gate } 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate /* construct the name as nessecary */ 1707c478bd9Sstevel@tonic-gate if (label == NULL) { 1717c478bd9Sstevel@tonic-gate *name = strdup(tmp_name); 1727c478bd9Sstevel@tonic-gate } else { 1737c478bd9Sstevel@tonic-gate size_t buf_size = strlen(tmp_name) + strlen(label) + 1747c478bd9Sstevel@tonic-gate FRU_LABEL_PADDING; 1757c478bd9Sstevel@tonic-gate char *tmp = malloc(buf_size); 1767c478bd9Sstevel@tonic-gate if (tmp == NULL) { 1777c478bd9Sstevel@tonic-gate free(tmp_name); 1787c478bd9Sstevel@tonic-gate free(label); 1797c478bd9Sstevel@tonic-gate return (FRU_FAILURE); 1807c478bd9Sstevel@tonic-gate } 1817c478bd9Sstevel@tonic-gate snprintf(tmp, buf_size, "%s?%s=%s", tmp_name, 1827c478bd9Sstevel@tonic-gate PICL_PROP_LABEL, label); 1837c478bd9Sstevel@tonic-gate *name = tmp; 1847c478bd9Sstevel@tonic-gate } 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate free(tmp_name); 1877c478bd9Sstevel@tonic-gate free(label); 1887c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 1897c478bd9Sstevel@tonic-gate } 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate /* ========================================================================= */ 1927c478bd9Sstevel@tonic-gate /* compare the node name to the name passed */ 1937c478bd9Sstevel@tonic-gate static fru_errno_t 1947c478bd9Sstevel@tonic-gate cmp_node_name(picl_nodehdl_t node, const char *name) 1957c478bd9Sstevel@tonic-gate { 1967c478bd9Sstevel@tonic-gate char *node_name = NULL; 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate if (get_strprop_by_name(node, PICL_PROP_NAME, &node_name) 1997c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 2007c478bd9Sstevel@tonic-gate return (FRU_FAILURE); 2017c478bd9Sstevel@tonic-gate } 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate if (strcmp(node_name, name) == 0) { 2047c478bd9Sstevel@tonic-gate free(node_name); 2057c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 2067c478bd9Sstevel@tonic-gate } 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate free(node_name); 2097c478bd9Sstevel@tonic-gate return (FRU_FAILURE); 2107c478bd9Sstevel@tonic-gate } 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate /* ========================================================================= */ 2137c478bd9Sstevel@tonic-gate /* compare the node class name to the name passed */ 2147c478bd9Sstevel@tonic-gate static fru_errno_t 2157c478bd9Sstevel@tonic-gate cmp_class_name(picl_nodehdl_t node, const char *name) 2167c478bd9Sstevel@tonic-gate { 2177c478bd9Sstevel@tonic-gate char *class_name = NULL; 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate if (get_strprop_by_name(node, PICL_PROP_CLASSNAME, &class_name) 2207c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 2217c478bd9Sstevel@tonic-gate return (FRU_FAILURE); 2227c478bd9Sstevel@tonic-gate } 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate if (strcmp(class_name, name) == 0) { 2257c478bd9Sstevel@tonic-gate free(class_name); 2267c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 2277c478bd9Sstevel@tonic-gate } 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate free(class_name); 2307c478bd9Sstevel@tonic-gate return (FRU_FAILURE); 2317c478bd9Sstevel@tonic-gate } 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate 2347c478bd9Sstevel@tonic-gate /* ========================================================================= */ 2357c478bd9Sstevel@tonic-gate /* get the "frutree" root node */ 2367c478bd9Sstevel@tonic-gate static fru_errno_t 2377c478bd9Sstevel@tonic-gate fpt_get_root(fru_treehdl_t *node) 2387c478bd9Sstevel@tonic-gate { 2397c478bd9Sstevel@tonic-gate picl_nodehdl_t picl_node; 2407c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate picl_err = ptree_get_root(&picl_node); 2437c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval_by_name(picl_node, PICL_PROP_CHILD, 2447c478bd9Sstevel@tonic-gate (void *)&picl_node, sizeof (picl_node))) 2457c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 246*35551380Skmohan return (map_plugin_err(picl_err)); 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate while (cmp_node_name(picl_node, PICL_NODE_FRUTREE) 2507c478bd9Sstevel@tonic-gate != FRU_SUCCESS) { 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval_by_name(picl_node, 2537c478bd9Sstevel@tonic-gate PICL_PROP_PEER, (void *)&picl_node, 2547c478bd9Sstevel@tonic-gate sizeof (picl_node))) == PICL_PROPNOTFOUND) { 2557c478bd9Sstevel@tonic-gate return (FRU_NODENOTFOUND); 2567c478bd9Sstevel@tonic-gate } else if (picl_err != PICL_SUCCESS) { 257*35551380Skmohan return (map_plugin_err(picl_err)); 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate } 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate picl_root_node = picl_node; 2627c478bd9Sstevel@tonic-gate *node = PICLHDL_TO_TREEHDL(picl_node); 2637c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 2647c478bd9Sstevel@tonic-gate } 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate /* ========================================================================= */ 2677c478bd9Sstevel@tonic-gate static fru_errno_t 2687c478bd9Sstevel@tonic-gate fpt_get_peer(fru_treehdl_t sibling, fru_treehdl_t *peer) 2697c478bd9Sstevel@tonic-gate { 2707c478bd9Sstevel@tonic-gate int rc = PICL_SUCCESS; 2717c478bd9Sstevel@tonic-gate picl_nodehdl_t handle = TREEHDL_TO_PICLHDL(sibling); 2727c478bd9Sstevel@tonic-gate picl_nodehdl_t picl_peer; 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate rc = ptree_get_propval_by_name(handle, PICL_PROP_PEER, 2757c478bd9Sstevel@tonic-gate (void *)&picl_peer, sizeof (picl_peer)); 2767c478bd9Sstevel@tonic-gate if (rc != PICL_SUCCESS) { 277*35551380Skmohan return (map_plugin_err(rc)); 2787c478bd9Sstevel@tonic-gate } 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate *peer = PICLHDL_TO_TREEHDL(picl_peer); 2817c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 2827c478bd9Sstevel@tonic-gate } 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate /* ========================================================================= */ 2857c478bd9Sstevel@tonic-gate static fru_errno_t 2867c478bd9Sstevel@tonic-gate fpt_get_child(fru_treehdl_t handle, fru_treehdl_t *child) 2877c478bd9Sstevel@tonic-gate { 2887c478bd9Sstevel@tonic-gate picl_nodehdl_t p_child; 2897c478bd9Sstevel@tonic-gate int rc = ptree_get_propval_by_name(TREEHDL_TO_PICLHDL(handle), 2907c478bd9Sstevel@tonic-gate PICL_PROP_CHILD, (void *)&p_child, sizeof (p_child)); 2917c478bd9Sstevel@tonic-gate if (rc != PICL_SUCCESS) { 292*35551380Skmohan return (map_plugin_err(rc)); 2937c478bd9Sstevel@tonic-gate } 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate *child = PICLHDL_TO_TREEHDL(p_child); 2967c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 2977c478bd9Sstevel@tonic-gate } 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate /* ========================================================================= */ 3007c478bd9Sstevel@tonic-gate static fru_errno_t 3017c478bd9Sstevel@tonic-gate fpt_get_parent(fru_treehdl_t handle, fru_treehdl_t *parent) 3027c478bd9Sstevel@tonic-gate { 3037c478bd9Sstevel@tonic-gate int rc = PICL_SUCCESS; 3047c478bd9Sstevel@tonic-gate picl_nodehdl_t p_parent; 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate /* do not allow the libfru users to see the parent of the root */ 3077c478bd9Sstevel@tonic-gate if (TREEHDL_TO_PICLHDL(handle) == picl_root_node) { 3087c478bd9Sstevel@tonic-gate return (FRU_NODENOTFOUND); 3097c478bd9Sstevel@tonic-gate } 3107c478bd9Sstevel@tonic-gate 3117c478bd9Sstevel@tonic-gate rc = ptree_get_propval_by_name(TREEHDL_TO_PICLHDL(handle), 3127c478bd9Sstevel@tonic-gate PICL_PROP_PARENT, (void *)&p_parent, sizeof (p_parent)); 3137c478bd9Sstevel@tonic-gate if (rc != PICL_SUCCESS) { 314*35551380Skmohan return (map_plugin_err(rc)); 3157c478bd9Sstevel@tonic-gate } 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate *parent = PICLHDL_TO_TREEHDL(p_parent); 3187c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 3197c478bd9Sstevel@tonic-gate } 3207c478bd9Sstevel@tonic-gate 3217c478bd9Sstevel@tonic-gate /* ========================================================================= */ 3227c478bd9Sstevel@tonic-gate static fru_errno_t 3237c478bd9Sstevel@tonic-gate fpt_get_node_type(fru_treehdl_t node, fru_node_t *type) 3247c478bd9Sstevel@tonic-gate { 325*35551380Skmohan int rc = PICL_SUCCESS; 3267c478bd9Sstevel@tonic-gate char picl_class[PICL_PROPNAMELEN_MAX]; 3277c478bd9Sstevel@tonic-gate picl_nodehdl_t handle = TREEHDL_TO_PICLHDL(node); 3287c478bd9Sstevel@tonic-gate 329*35551380Skmohan if ((rc = ptree_get_propval_by_name(handle, PICL_PROP_CLASSNAME, 330*35551380Skmohan picl_class, sizeof (picl_class))) != PICL_SUCCESS) { 331*35551380Skmohan return (map_plugin_err(rc)); 3327c478bd9Sstevel@tonic-gate } 3337c478bd9Sstevel@tonic-gate 3347c478bd9Sstevel@tonic-gate if (strcmp(picl_class, PICL_CLASS_LOCATION) == 0) { 3357c478bd9Sstevel@tonic-gate *type = FRU_NODE_LOCATION; 3367c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 3377c478bd9Sstevel@tonic-gate } else if (strcmp(picl_class, PICL_CLASS_FRU) == 0) { 3387c478bd9Sstevel@tonic-gate picl_prophdl_t proph; 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate /* check for the CONTAINER_PROP property which indicates */ 3417c478bd9Sstevel@tonic-gate /* there is data for this node. (ie fru is a container) */ 3427c478bd9Sstevel@tonic-gate if (ptree_get_prop_by_name(handle, 3437c478bd9Sstevel@tonic-gate PICL_PROP_CONTAINER, &proph) == PICL_SUCCESS) { 3447c478bd9Sstevel@tonic-gate *type = FRU_NODE_CONTAINER; 3457c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate *type = FRU_NODE_FRU; 3487c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 3497c478bd9Sstevel@tonic-gate } 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate *type = FRU_NODE_UNKNOWN; 3527c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate /* ========================================================================= */ 3567c478bd9Sstevel@tonic-gate /* find the next section or return NODENOTFOUND */ 3577c478bd9Sstevel@tonic-gate static fru_errno_t 3587c478bd9Sstevel@tonic-gate find_next_section(picl_nodehdl_t current, picl_nodehdl_t *next) 3597c478bd9Sstevel@tonic-gate { 3607c478bd9Sstevel@tonic-gate picl_nodehdl_t rc_next; 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate if (ptree_get_propval_by_name(current, PICL_PROP_PEER, 3637c478bd9Sstevel@tonic-gate (void *)&rc_next, sizeof (rc_next)) != PICL_SUCCESS) { 3647c478bd9Sstevel@tonic-gate return (FRU_NODENOTFOUND); 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate /* Make sure this is a "Section" node */ 3687c478bd9Sstevel@tonic-gate if (cmp_class_name(rc_next, PICL_CLASS_SECTION) 3697c478bd9Sstevel@tonic-gate == FRU_SUCCESS) { 3707c478bd9Sstevel@tonic-gate *next = rc_next; 3717c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 3727c478bd9Sstevel@tonic-gate } 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate /* and if this is not good keep trying to find a peer which */ 3757c478bd9Sstevel@tonic-gate /* is a section */ 3767c478bd9Sstevel@tonic-gate return (find_next_section(rc_next, next)); 3777c478bd9Sstevel@tonic-gate } 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate /* ========================================================================= */ 3807c478bd9Sstevel@tonic-gate /* find the first section or return NODENOTFOUND */ 3817c478bd9Sstevel@tonic-gate static fru_errno_t 3827c478bd9Sstevel@tonic-gate find_first_section(picl_nodehdl_t parent, picl_nodehdl_t *section) 3837c478bd9Sstevel@tonic-gate { 3847c478bd9Sstevel@tonic-gate picl_nodehdl_t rc_section; 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate if (ptree_get_propval_by_name(parent, PICL_PROP_CHILD, 3877c478bd9Sstevel@tonic-gate (void *)&rc_section, sizeof (rc_section)) != PICL_SUCCESS) { 3887c478bd9Sstevel@tonic-gate return (FRU_NODENOTFOUND); 3897c478bd9Sstevel@tonic-gate } 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate /* Make sure this is a "Section" node */ 3927c478bd9Sstevel@tonic-gate if (cmp_class_name(rc_section, PICL_CLASS_SECTION) 3937c478bd9Sstevel@tonic-gate == FRU_SUCCESS) { 3947c478bd9Sstevel@tonic-gate *section = rc_section; 3957c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 3967c478bd9Sstevel@tonic-gate } 3977c478bd9Sstevel@tonic-gate 3987c478bd9Sstevel@tonic-gate /* and if this is not good keep trying to find a peer which */ 3997c478bd9Sstevel@tonic-gate /* is a section */ 4007c478bd9Sstevel@tonic-gate return (find_next_section(rc_section, section)); 4017c478bd9Sstevel@tonic-gate } 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate /* ========================================================================= */ 4047c478bd9Sstevel@tonic-gate /* 4057c478bd9Sstevel@tonic-gate * Find the handle of the segment node "segment". 4067c478bd9Sstevel@tonic-gate * also returns the hardware description of this segment. (read from the 4077c478bd9Sstevel@tonic-gate * section this was found in.) 4087c478bd9Sstevel@tonic-gate * If the ign_cor_flg is set this will still succeed even if the segment is 4097c478bd9Sstevel@tonic-gate * corrupt, otherwise it will return FRU_SEGCORRUPT for corrupt segments 4107c478bd9Sstevel@tonic-gate */ 4117c478bd9Sstevel@tonic-gate #define IGN_CORRUPT_YES 1 4127c478bd9Sstevel@tonic-gate #define IGN_CORRUPT_NO 0 4137c478bd9Sstevel@tonic-gate static fru_errno_t 4147c478bd9Sstevel@tonic-gate get_segment_node(picl_nodehdl_t handle, const char *segment, 4157c478bd9Sstevel@tonic-gate picl_nodehdl_t *seg_hdl, fru_seg_hwdesc_t *hw_desc, int ign_cor_flg) 4167c478bd9Sstevel@tonic-gate { 4177c478bd9Sstevel@tonic-gate fru_errno_t err = FRU_SUCCESS; 4187c478bd9Sstevel@tonic-gate picl_nodehdl_t sect_node; 4197c478bd9Sstevel@tonic-gate 4207c478bd9Sstevel@tonic-gate if ((err = update_data_nodes(handle)) != FRU_SUCCESS) { 4217c478bd9Sstevel@tonic-gate return (err); 4227c478bd9Sstevel@tonic-gate } 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate if ((err = find_first_section(handle, §_node)) != FRU_SUCCESS) { 4257c478bd9Sstevel@tonic-gate return (err); 4267c478bd9Sstevel@tonic-gate } 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate /* while there are sections. */ 4297c478bd9Sstevel@tonic-gate while (err == FRU_SUCCESS) { 4307c478bd9Sstevel@tonic-gate uint32_t num_segs = 0; 4317c478bd9Sstevel@tonic-gate int rc = PICL_SUCCESS; 4327c478bd9Sstevel@tonic-gate picl_nodehdl_t seg_node; 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate /* do this just in case the Segments have not been built. */ 4357c478bd9Sstevel@tonic-gate if ((rc = ptree_get_propval_by_name(sect_node, 4367c478bd9Sstevel@tonic-gate PICL_PROP_NUM_SEGMENTS, 4377c478bd9Sstevel@tonic-gate (void *)&num_segs, 4387c478bd9Sstevel@tonic-gate sizeof (num_segs))) != PICL_SUCCESS) { 4397c478bd9Sstevel@tonic-gate return (map_plugin_err(rc)); 4407c478bd9Sstevel@tonic-gate } 4417c478bd9Sstevel@tonic-gate 4427c478bd9Sstevel@tonic-gate /* while there are segments. */ 4437c478bd9Sstevel@tonic-gate rc = ptree_get_propval_by_name(sect_node, PICL_PROP_CHILD, 4447c478bd9Sstevel@tonic-gate (void *)&seg_node, sizeof (seg_node)); 4457c478bd9Sstevel@tonic-gate while (rc == PICL_SUCCESS) { 4467c478bd9Sstevel@tonic-gate char name[PICL_PROPNAMELEN_MAX]; 4477c478bd9Sstevel@tonic-gate ptree_get_propval_by_name(seg_node, PICL_PROP_NAME, 4487c478bd9Sstevel@tonic-gate name, sizeof (name)); 4497c478bd9Sstevel@tonic-gate if (strcmp(segment, name) == 0) { 4507c478bd9Sstevel@tonic-gate int dummy = 0; 4517c478bd9Sstevel@tonic-gate int protection = 0; 4527c478bd9Sstevel@tonic-gate /* NUM_TAGS prop exists iff segment is OK */ 4537c478bd9Sstevel@tonic-gate if ((ign_cor_flg == IGN_CORRUPT_NO) && 4547c478bd9Sstevel@tonic-gate (ptree_get_propval_by_name(seg_node, 4557c478bd9Sstevel@tonic-gate PICL_PROP_NUM_TAGS, 4567c478bd9Sstevel@tonic-gate (void *)&dummy, 4577c478bd9Sstevel@tonic-gate sizeof (dummy)) != PICL_SUCCESS)) { 4587c478bd9Sstevel@tonic-gate return (FRU_SEGCORRUPT); 4597c478bd9Sstevel@tonic-gate } 4607c478bd9Sstevel@tonic-gate /* get the HW protections of this section. */ 461*35551380Skmohan if ((rc = ptree_get_propval_by_name(sect_node, 4627c478bd9Sstevel@tonic-gate PICL_PROP_PROTECTED, 4637c478bd9Sstevel@tonic-gate (void *)&protection, 464*35551380Skmohan sizeof (protection))) 465*35551380Skmohan != PICL_SUCCESS) { 466*35551380Skmohan return (map_plugin_err(rc)); 4677c478bd9Sstevel@tonic-gate } 4687c478bd9Sstevel@tonic-gate hw_desc->all_bits = 0; 4697c478bd9Sstevel@tonic-gate hw_desc->field.read_only = protection; 4707c478bd9Sstevel@tonic-gate 4717c478bd9Sstevel@tonic-gate *seg_hdl = seg_node; 4727c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 4737c478bd9Sstevel@tonic-gate } 4747c478bd9Sstevel@tonic-gate rc = ptree_get_propval_by_name(seg_node, PICL_PROP_PEER, 4757c478bd9Sstevel@tonic-gate (void *)&seg_node, sizeof (seg_node)); 4767c478bd9Sstevel@tonic-gate } 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate /* Peer property not found is ok */ 4797c478bd9Sstevel@tonic-gate if (rc != PICL_PROPNOTFOUND) { 480*35551380Skmohan return (map_plugin_err(rc)); 4817c478bd9Sstevel@tonic-gate } 4827c478bd9Sstevel@tonic-gate 4837c478bd9Sstevel@tonic-gate err = find_next_section(sect_node, §_node); 4847c478bd9Sstevel@tonic-gate } 4857c478bd9Sstevel@tonic-gate 4867c478bd9Sstevel@tonic-gate return (FRU_INVALSEG); 4877c478bd9Sstevel@tonic-gate } 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gate /* ========================================================================= */ 4907c478bd9Sstevel@tonic-gate /* 4917c478bd9Sstevel@tonic-gate * For the section handle passed add to list all the segment names found. 4927c478bd9Sstevel@tonic-gate * Also incriments total by the number found. 4937c478bd9Sstevel@tonic-gate */ 4947c478bd9Sstevel@tonic-gate static fru_errno_t 4957c478bd9Sstevel@tonic-gate add_segs_for_section(picl_nodehdl_t section, fru_strlist_t *list) 4967c478bd9Sstevel@tonic-gate { 4977c478bd9Sstevel@tonic-gate int num_segments = 0; 4987c478bd9Sstevel@tonic-gate int rc = PICL_SUCCESS; 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate if ((rc = ptree_get_propval_by_name(section, 5017c478bd9Sstevel@tonic-gate PICL_PROP_NUM_SEGMENTS, 5027c478bd9Sstevel@tonic-gate (void *)&num_segments, 5037c478bd9Sstevel@tonic-gate sizeof (num_segments))) != PICL_SUCCESS) { 5047c478bd9Sstevel@tonic-gate fru_destroy_strlist(list); 5057c478bd9Sstevel@tonic-gate return (map_plugin_err(rc)); 5067c478bd9Sstevel@tonic-gate } 5077c478bd9Sstevel@tonic-gate 5087c478bd9Sstevel@tonic-gate if (num_segments != 0) { 5097c478bd9Sstevel@tonic-gate picl_nodehdl_t seg_node; 5107c478bd9Sstevel@tonic-gate int total_space = list->num + num_segments; 5117c478bd9Sstevel@tonic-gate 5127c478bd9Sstevel@tonic-gate list->strs = realloc(list->strs, 5137c478bd9Sstevel@tonic-gate (sizeof (*(list->strs)) * (total_space))); 5147c478bd9Sstevel@tonic-gate if (list->strs == NULL) { 5157c478bd9Sstevel@tonic-gate return (FRU_FAILURE); 5167c478bd9Sstevel@tonic-gate } 5177c478bd9Sstevel@tonic-gate 5187c478bd9Sstevel@tonic-gate /* get the first segment */ 5197c478bd9Sstevel@tonic-gate rc = ptree_get_propval_by_name(section, 5207c478bd9Sstevel@tonic-gate PICL_PROP_CHILD, (void *)&seg_node, 5217c478bd9Sstevel@tonic-gate sizeof (seg_node)); 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate /* while there are more segments. */ 5247c478bd9Sstevel@tonic-gate while (rc == PICL_SUCCESS) { 5257c478bd9Sstevel@tonic-gate char name[FRU_SEGNAMELEN +1]; 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate if ((rc = ptree_get_propval_by_name(seg_node, 5287c478bd9Sstevel@tonic-gate PICL_PROP_NAME, name, 5297c478bd9Sstevel@tonic-gate sizeof (name))) != PICL_SUCCESS) { 5307c478bd9Sstevel@tonic-gate break; 5317c478bd9Sstevel@tonic-gate } 5327c478bd9Sstevel@tonic-gate 5337c478bd9Sstevel@tonic-gate /* check array bounds */ 5347c478bd9Sstevel@tonic-gate if (list->num >= total_space) { 5357c478bd9Sstevel@tonic-gate /* PICL reported incorrect number of segs */ 5367c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 5377c478bd9Sstevel@tonic-gate } 5387c478bd9Sstevel@tonic-gate list->strs[(list->num)++] = strdup(name); 5397c478bd9Sstevel@tonic-gate 5407c478bd9Sstevel@tonic-gate rc = ptree_get_propval_by_name(seg_node, 5417c478bd9Sstevel@tonic-gate PICL_PROP_PEER, (void *)&seg_node, 5427c478bd9Sstevel@tonic-gate sizeof (seg_node)); 5437c478bd9Sstevel@tonic-gate } 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate /* Peer property not found is ok */ 5467c478bd9Sstevel@tonic-gate if (rc != PICL_PROPNOTFOUND) { 547*35551380Skmohan return (map_plugin_err(rc)); 5487c478bd9Sstevel@tonic-gate } 5497c478bd9Sstevel@tonic-gate 5507c478bd9Sstevel@tonic-gate } 5517c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 5527c478bd9Sstevel@tonic-gate } 5537c478bd9Sstevel@tonic-gate 5547c478bd9Sstevel@tonic-gate /* ========================================================================= */ 5557c478bd9Sstevel@tonic-gate static fru_errno_t 5567c478bd9Sstevel@tonic-gate fpt_get_seg_list(fru_treehdl_t handle, fru_strlist_t *list) 5577c478bd9Sstevel@tonic-gate { 5587c478bd9Sstevel@tonic-gate fru_errno_t err; 5597c478bd9Sstevel@tonic-gate picl_nodehdl_t sect_node; 5607c478bd9Sstevel@tonic-gate fru_strlist_t rc_list; 5617c478bd9Sstevel@tonic-gate rc_list.num = 0; 5627c478bd9Sstevel@tonic-gate rc_list.strs = NULL; 5637c478bd9Sstevel@tonic-gate 5647c478bd9Sstevel@tonic-gate if ((err = update_data_nodes(TREEHDL_TO_PICLHDL(handle))) 5657c478bd9Sstevel@tonic-gate != FRU_SUCCESS) { 5667c478bd9Sstevel@tonic-gate return (err); 5677c478bd9Sstevel@tonic-gate } 5687c478bd9Sstevel@tonic-gate 5697c478bd9Sstevel@tonic-gate if ((err = find_first_section(TREEHDL_TO_PICLHDL(handle), §_node)) 5707c478bd9Sstevel@tonic-gate != FRU_SUCCESS) { 5717c478bd9Sstevel@tonic-gate return (err); 5727c478bd9Sstevel@tonic-gate } 5737c478bd9Sstevel@tonic-gate 5747c478bd9Sstevel@tonic-gate /* while there are sections. */ 5757c478bd9Sstevel@tonic-gate while (err == FRU_SUCCESS) { 5767c478bd9Sstevel@tonic-gate if ((err = add_segs_for_section(sect_node, &rc_list)) 5777c478bd9Sstevel@tonic-gate != FRU_SUCCESS) { 5787c478bd9Sstevel@tonic-gate fru_destroy_strlist(&rc_list); 5797c478bd9Sstevel@tonic-gate return (err); 5807c478bd9Sstevel@tonic-gate } 5817c478bd9Sstevel@tonic-gate err = find_next_section(sect_node, §_node); 5827c478bd9Sstevel@tonic-gate } 5837c478bd9Sstevel@tonic-gate 5847c478bd9Sstevel@tonic-gate list->num = rc_list.num; 5857c478bd9Sstevel@tonic-gate list->strs = rc_list.strs; 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 5887c478bd9Sstevel@tonic-gate } 5897c478bd9Sstevel@tonic-gate 5907c478bd9Sstevel@tonic-gate /* ========================================================================= */ 5917c478bd9Sstevel@tonic-gate static fru_errno_t 5927c478bd9Sstevel@tonic-gate fpt_get_seg_def(fru_treehdl_t handle, const char *seg_name, fru_segdef_t *def) 5937c478bd9Sstevel@tonic-gate { 5947c478bd9Sstevel@tonic-gate fru_errno_t err = FRU_SUCCESS; 5957c478bd9Sstevel@tonic-gate picl_nodehdl_t seg_node; 5967c478bd9Sstevel@tonic-gate fru_seg_hwdesc_t hw_desc; 5977c478bd9Sstevel@tonic-gate 5987c478bd9Sstevel@tonic-gate fru_segdesc_t desc; 5997c478bd9Sstevel@tonic-gate uint32_t size; 6007c478bd9Sstevel@tonic-gate uint32_t address; 6017c478bd9Sstevel@tonic-gate /* LINTED */ 6027c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 6037c478bd9Sstevel@tonic-gate 6047c478bd9Sstevel@tonic-gate if ((err = get_segment_node(TREEHDL_TO_PICLHDL(handle), seg_name, 6057c478bd9Sstevel@tonic-gate &seg_node, &hw_desc, IGN_CORRUPT_YES)) != FRU_SUCCESS) 6067c478bd9Sstevel@tonic-gate return (err); 6077c478bd9Sstevel@tonic-gate 6087c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval_by_name(seg_node, 6097c478bd9Sstevel@tonic-gate PICL_PROP_DESCRIPTOR, 6107c478bd9Sstevel@tonic-gate &desc, sizeof (desc))) != PICL_SUCCESS) { 611*35551380Skmohan return (map_plugin_err(picl_err)); 6127c478bd9Sstevel@tonic-gate } 6137c478bd9Sstevel@tonic-gate 6147c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval_by_name(seg_node, 6157c478bd9Sstevel@tonic-gate PICL_PROP_LENGTH, 6167c478bd9Sstevel@tonic-gate &size, sizeof (size))) != PICL_SUCCESS) { 617*35551380Skmohan return (map_plugin_err(picl_err)); 6187c478bd9Sstevel@tonic-gate } 6197c478bd9Sstevel@tonic-gate 6207c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval_by_name(seg_node, 6217c478bd9Sstevel@tonic-gate PICL_PROP_OFFSET, 6227c478bd9Sstevel@tonic-gate &address, sizeof (address))) != PICL_SUCCESS) { 623*35551380Skmohan return (map_plugin_err(picl_err)); 6247c478bd9Sstevel@tonic-gate } 6257c478bd9Sstevel@tonic-gate 6267c478bd9Sstevel@tonic-gate def->version = LIBFRU_VERSION; 6277c478bd9Sstevel@tonic-gate strlcpy(def->name, seg_name, FRU_SEGNAMELEN+1); 6287c478bd9Sstevel@tonic-gate def->desc = desc; 6297c478bd9Sstevel@tonic-gate def->size = size; 6307c478bd9Sstevel@tonic-gate def->address = address; 6317c478bd9Sstevel@tonic-gate def->hw_desc = hw_desc; 6327c478bd9Sstevel@tonic-gate 6337c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 6347c478bd9Sstevel@tonic-gate } 6357c478bd9Sstevel@tonic-gate 6367c478bd9Sstevel@tonic-gate /* ========================================================================= */ 6377c478bd9Sstevel@tonic-gate static fru_errno_t 6387c478bd9Sstevel@tonic-gate fpt_add_seg(fru_treehdl_t handle, fru_segdef_t *def) 6397c478bd9Sstevel@tonic-gate { 6407c478bd9Sstevel@tonic-gate fru_errno_t err = FRU_SUCCESS; 6417c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 6427c478bd9Sstevel@tonic-gate picl_nodehdl_t section; 6437c478bd9Sstevel@tonic-gate 6447c478bd9Sstevel@tonic-gate /* 6457c478bd9Sstevel@tonic-gate * for every section which has a ADD_SEGMENT_PROP try and add the segment 6467c478bd9Sstevel@tonic-gate */ 6477c478bd9Sstevel@tonic-gate if ((err = find_first_section(TREEHDL_TO_PICLHDL(handle), §ion)) 6487c478bd9Sstevel@tonic-gate != FRU_SUCCESS) { 6497c478bd9Sstevel@tonic-gate return (err); 6507c478bd9Sstevel@tonic-gate } 6517c478bd9Sstevel@tonic-gate do { 6527c478bd9Sstevel@tonic-gate fru_segdef_t dummy; 6537c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval_by_name(section, 6547c478bd9Sstevel@tonic-gate PICL_PROP_ADD_SEGMENT, &dummy, sizeof (dummy))) 6557c478bd9Sstevel@tonic-gate == PICL_SUCCESS) { 6567c478bd9Sstevel@tonic-gate 6577c478bd9Sstevel@tonic-gate picl_err = ptree_update_propval_by_name(section, 6587c478bd9Sstevel@tonic-gate PICL_PROP_ADD_SEGMENT, def, sizeof (*def)); 6597c478bd9Sstevel@tonic-gate 6607c478bd9Sstevel@tonic-gate return (map_plugin_err(picl_err)); 6617c478bd9Sstevel@tonic-gate } 6627c478bd9Sstevel@tonic-gate } while (find_next_section(section, §ion) == FRU_SUCCESS); 6637c478bd9Sstevel@tonic-gate 6647c478bd9Sstevel@tonic-gate return (map_plugin_err(picl_err)); 6657c478bd9Sstevel@tonic-gate } 6667c478bd9Sstevel@tonic-gate 6677c478bd9Sstevel@tonic-gate /* ========================================================================= */ 6687c478bd9Sstevel@tonic-gate static fru_errno_t 6697c478bd9Sstevel@tonic-gate fpt_delete_seg(fru_treehdl_t handle, const char *seg_name) 6707c478bd9Sstevel@tonic-gate { 6717c478bd9Sstevel@tonic-gate picl_nodehdl_t seg_hdl; 6727c478bd9Sstevel@tonic-gate fru_seg_hwdesc_t hw_desc; 6737c478bd9Sstevel@tonic-gate fru_errno_t err; 6747c478bd9Sstevel@tonic-gate 6757c478bd9Sstevel@tonic-gate int dead_flag = FRUDATA_DELETE_TAG_KEY; 6767c478bd9Sstevel@tonic-gate int rc = PICL_SUCCESS; 6777c478bd9Sstevel@tonic-gate 6787c478bd9Sstevel@tonic-gate if ((err = get_segment_node(TREEHDL_TO_PICLHDL(handle), seg_name, 6797c478bd9Sstevel@tonic-gate &seg_hdl, &hw_desc, IGN_CORRUPT_YES)) != FRU_SUCCESS) { 6807c478bd9Sstevel@tonic-gate return (err); 6817c478bd9Sstevel@tonic-gate } 6827c478bd9Sstevel@tonic-gate 6837c478bd9Sstevel@tonic-gate rc = ptree_update_propval_by_name(seg_hdl, PICL_PROP_DELETE_SEGMENT, 6847c478bd9Sstevel@tonic-gate &dead_flag, sizeof (dead_flag)); 6857c478bd9Sstevel@tonic-gate return (map_plugin_err(rc)); 6867c478bd9Sstevel@tonic-gate } 6877c478bd9Sstevel@tonic-gate 6887c478bd9Sstevel@tonic-gate /* ========================================================================= */ 6897c478bd9Sstevel@tonic-gate static fru_errno_t 6907c478bd9Sstevel@tonic-gate fpt_add_tag_to_seg(fru_treehdl_t handle, const char *seg_name, 6917c478bd9Sstevel@tonic-gate fru_tag_t tag, uint8_t *data, size_t data_len) 6927c478bd9Sstevel@tonic-gate { 6937c478bd9Sstevel@tonic-gate fru_errno_t err = FRU_SUCCESS; 6947c478bd9Sstevel@tonic-gate picl_nodehdl_t segHdl; 6957c478bd9Sstevel@tonic-gate fru_seg_hwdesc_t hw_desc; 6967c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 6977c478bd9Sstevel@tonic-gate size_t buf_size = 0; 6987c478bd9Sstevel@tonic-gate uint8_t *buffer = NULL; 6997c478bd9Sstevel@tonic-gate picl_prophdl_t add_prop; 7007c478bd9Sstevel@tonic-gate ptree_propinfo_t add_prop_info; 7017c478bd9Sstevel@tonic-gate 7027c478bd9Sstevel@tonic-gate if ((err = get_segment_node(TREEHDL_TO_PICLHDL(handle), seg_name, 7037c478bd9Sstevel@tonic-gate &segHdl, &hw_desc, IGN_CORRUPT_NO)) != FRU_SUCCESS) { 7047c478bd9Sstevel@tonic-gate return (err); 7057c478bd9Sstevel@tonic-gate } 7067c478bd9Sstevel@tonic-gate 7077c478bd9Sstevel@tonic-gate /* get the length of the buffer required. */ 7087c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_prop_by_name(segHdl, 7097c478bd9Sstevel@tonic-gate PICL_PROP_ADD_PACKET, 7107c478bd9Sstevel@tonic-gate &add_prop)) != PICL_SUCCESS) { 711*35551380Skmohan return (map_plugin_err(picl_err)); 7127c478bd9Sstevel@tonic-gate } 7137c478bd9Sstevel@tonic-gate 7147c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propinfo(add_prop, &add_prop_info)) 7157c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 716*35551380Skmohan return (map_plugin_err(picl_err)); 7177c478bd9Sstevel@tonic-gate } 7187c478bd9Sstevel@tonic-gate buf_size = add_prop_info.piclinfo.size; 7197c478bd9Sstevel@tonic-gate 7207c478bd9Sstevel@tonic-gate if (data_len >= (buf_size - get_tag_size(get_tag_type(&tag)))) { 7217c478bd9Sstevel@tonic-gate return (FRU_NOSPACE); 7227c478bd9Sstevel@tonic-gate } 7237c478bd9Sstevel@tonic-gate 7247c478bd9Sstevel@tonic-gate buffer = malloc(buf_size); 7257c478bd9Sstevel@tonic-gate if (buffer == NULL) { 7267c478bd9Sstevel@tonic-gate return (FRU_FAILURE); 7277c478bd9Sstevel@tonic-gate } 7287c478bd9Sstevel@tonic-gate /* write the tag and data into the buffer */ 7297c478bd9Sstevel@tonic-gate memcpy(buffer, &tag, get_tag_size(get_tag_type(&tag))); 7307c478bd9Sstevel@tonic-gate memcpy((void *)(buffer+get_tag_size(get_tag_type(&tag))), 7317c478bd9Sstevel@tonic-gate data, data_len); 7327c478bd9Sstevel@tonic-gate 7337c478bd9Sstevel@tonic-gate picl_err = ptree_update_propval(add_prop, buffer, buf_size); 7347c478bd9Sstevel@tonic-gate free(buffer); 7357c478bd9Sstevel@tonic-gate return (map_plugin_err(picl_err)); 7367c478bd9Sstevel@tonic-gate } 7377c478bd9Sstevel@tonic-gate 7387c478bd9Sstevel@tonic-gate /* ========================================================================= */ 7397c478bd9Sstevel@tonic-gate static fru_errno_t 7407c478bd9Sstevel@tonic-gate fpt_get_tag_list(fru_treehdl_t handle, const char *seg_name, 7417c478bd9Sstevel@tonic-gate fru_tag_t **tags, int *number) 7427c478bd9Sstevel@tonic-gate { 7437c478bd9Sstevel@tonic-gate picl_nodehdl_t seg_node; 7447c478bd9Sstevel@tonic-gate fru_seg_hwdesc_t hw_desc; 7457c478bd9Sstevel@tonic-gate fru_errno_t err = FRU_SUCCESS; 7467c478bd9Sstevel@tonic-gate picl_prophdl_t tagTable; 7477c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 7487c478bd9Sstevel@tonic-gate unsigned int total_tags = 0; 7497c478bd9Sstevel@tonic-gate 7507c478bd9Sstevel@tonic-gate /* return variables */ 7517c478bd9Sstevel@tonic-gate fru_tag_t *rc_tags = NULL; 7527c478bd9Sstevel@tonic-gate unsigned int rc_num = 0; 7537c478bd9Sstevel@tonic-gate 7547c478bd9Sstevel@tonic-gate if ((err = get_segment_node(TREEHDL_TO_PICLHDL(handle), seg_name, 7557c478bd9Sstevel@tonic-gate &seg_node, &hw_desc, IGN_CORRUPT_NO)) != FRU_SUCCESS) { 7567c478bd9Sstevel@tonic-gate return (err); 7577c478bd9Sstevel@tonic-gate } 7587c478bd9Sstevel@tonic-gate 7597c478bd9Sstevel@tonic-gate /* get the number of tags and allocate array for them */ 7607c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval_by_name(seg_node, 7617c478bd9Sstevel@tonic-gate PICL_PROP_NUM_TAGS, 7627c478bd9Sstevel@tonic-gate (void *)&total_tags, 7637c478bd9Sstevel@tonic-gate sizeof (total_tags))) != PICL_SUCCESS) { 764*35551380Skmohan return (map_plugin_err(picl_err)); 7657c478bd9Sstevel@tonic-gate } 7667c478bd9Sstevel@tonic-gate 7677c478bd9Sstevel@tonic-gate if (total_tags == 0) { 7687c478bd9Sstevel@tonic-gate *tags = rc_tags; 7697c478bd9Sstevel@tonic-gate *number = rc_num; 7707c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 7717c478bd9Sstevel@tonic-gate } 7727c478bd9Sstevel@tonic-gate 7737c478bd9Sstevel@tonic-gate rc_tags = malloc((sizeof (*rc_tags) * total_tags)); 7747c478bd9Sstevel@tonic-gate if (rc_tags == NULL) { 7757c478bd9Sstevel@tonic-gate return (FRU_FAILURE); 7767c478bd9Sstevel@tonic-gate } 7777c478bd9Sstevel@tonic-gate 7787c478bd9Sstevel@tonic-gate /* go through the tagTable and fill in the array */ 7797c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval_by_name(seg_node, 7807c478bd9Sstevel@tonic-gate PICL_PROP_PACKET_TABLE, 7817c478bd9Sstevel@tonic-gate &tagTable, sizeof (tagTable))) != PICL_SUCCESS) { 7827c478bd9Sstevel@tonic-gate free(rc_tags); 783*35551380Skmohan return (map_plugin_err(picl_err)); 7847c478bd9Sstevel@tonic-gate } 7857c478bd9Sstevel@tonic-gate picl_err = ptree_get_next_by_col(tagTable, &tagTable); 7867c478bd9Sstevel@tonic-gate while (picl_err == PICL_SUCCESS) { 7877c478bd9Sstevel@tonic-gate /* check array bounds */ 7887c478bd9Sstevel@tonic-gate if (rc_num >= total_tags) { 7897c478bd9Sstevel@tonic-gate free(rc_tags); 7907c478bd9Sstevel@tonic-gate return (FRU_FAILURE); 7917c478bd9Sstevel@tonic-gate } 7927c478bd9Sstevel@tonic-gate /* fill in the array */ 7937c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval(tagTable, 7947c478bd9Sstevel@tonic-gate (void *)&(rc_tags[rc_num++]), 7957c478bd9Sstevel@tonic-gate sizeof (fru_tag_t))) != PICL_SUCCESS) { 7967c478bd9Sstevel@tonic-gate free(rc_tags); 797*35551380Skmohan return (map_plugin_err(picl_err)); 7987c478bd9Sstevel@tonic-gate } 7997c478bd9Sstevel@tonic-gate /* get the next tag */ 8007c478bd9Sstevel@tonic-gate picl_err = ptree_get_next_by_col(tagTable, &tagTable); 8017c478bd9Sstevel@tonic-gate } 8027c478bd9Sstevel@tonic-gate 8037c478bd9Sstevel@tonic-gate if (picl_err == PICL_ENDOFLIST) { 8047c478bd9Sstevel@tonic-gate *tags = rc_tags; 8057c478bd9Sstevel@tonic-gate *number = rc_num; 8067c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 8077c478bd9Sstevel@tonic-gate } 808*35551380Skmohan return (map_plugin_err(picl_err)); 8097c478bd9Sstevel@tonic-gate } 8107c478bd9Sstevel@tonic-gate 8117c478bd9Sstevel@tonic-gate /* ========================================================================= */ 8127c478bd9Sstevel@tonic-gate /* 8137c478bd9Sstevel@tonic-gate * From the handle, segment name, tag, and instance of the tag get me: 8147c478bd9Sstevel@tonic-gate * segHdl: The segment handle for this segment. 8157c478bd9Sstevel@tonic-gate * tagHdl: tag property handle in the tag table for this instance "tag" 8167c478bd9Sstevel@tonic-gate */ 8177c478bd9Sstevel@tonic-gate static fru_errno_t 8187c478bd9Sstevel@tonic-gate get_tag_handle(picl_nodehdl_t handle, const char *segment, 8197c478bd9Sstevel@tonic-gate fru_tag_t tag, int instance, 8207c478bd9Sstevel@tonic-gate picl_nodehdl_t *segHdl, 8217c478bd9Sstevel@tonic-gate picl_prophdl_t *tagHdl) 8227c478bd9Sstevel@tonic-gate { 8237c478bd9Sstevel@tonic-gate fru_seg_hwdesc_t hw_desc; 8247c478bd9Sstevel@tonic-gate fru_errno_t err; 8257c478bd9Sstevel@tonic-gate picl_prophdl_t tagTable = 0; 8267c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 8277c478bd9Sstevel@tonic-gate picl_nodehdl_t tmp_seg; 8287c478bd9Sstevel@tonic-gate 8297c478bd9Sstevel@tonic-gate fru_tag_t foundTag; 8307c478bd9Sstevel@tonic-gate 8317c478bd9Sstevel@tonic-gate if ((err = get_segment_node(TREEHDL_TO_PICLHDL(handle), segment, 8327c478bd9Sstevel@tonic-gate &tmp_seg, &hw_desc, IGN_CORRUPT_NO)) != FRU_SUCCESS) { 8337c478bd9Sstevel@tonic-gate return (err); 8347c478bd9Sstevel@tonic-gate } 8357c478bd9Sstevel@tonic-gate 8367c478bd9Sstevel@tonic-gate foundTag.raw_data = 0; 8377c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval_by_name(tmp_seg, 8387c478bd9Sstevel@tonic-gate PICL_PROP_PACKET_TABLE, 8397c478bd9Sstevel@tonic-gate &tagTable, sizeof (tagTable))) != PICL_SUCCESS) { 840*35551380Skmohan return (map_plugin_err(picl_err)); 8417c478bd9Sstevel@tonic-gate } 8427c478bd9Sstevel@tonic-gate 8437c478bd9Sstevel@tonic-gate picl_err = ptree_get_next_by_col(tagTable, &tagTable); 8447c478bd9Sstevel@tonic-gate while ((picl_err != PICL_ENDOFLIST) && 8457c478bd9Sstevel@tonic-gate (picl_err == PICL_SUCCESS)) { 8467c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval(tagTable, (void *)&foundTag, 8477c478bd9Sstevel@tonic-gate sizeof (foundTag))) != PICL_SUCCESS) { 848*35551380Skmohan return (map_plugin_err(picl_err)); 8497c478bd9Sstevel@tonic-gate } 8507c478bd9Sstevel@tonic-gate if ((tags_equal(tag, foundTag) == 1) && (instance-- == 0)) { 8517c478bd9Sstevel@tonic-gate *segHdl = tmp_seg; 8527c478bd9Sstevel@tonic-gate *tagHdl = tagTable; 8537c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 8547c478bd9Sstevel@tonic-gate } 8557c478bd9Sstevel@tonic-gate picl_err = ptree_get_next_by_col(tagTable, &tagTable); 8567c478bd9Sstevel@tonic-gate } 8577c478bd9Sstevel@tonic-gate 858*35551380Skmohan return (map_plugin_err(picl_err)); 8597c478bd9Sstevel@tonic-gate } 8607c478bd9Sstevel@tonic-gate 8617c478bd9Sstevel@tonic-gate /* ========================================================================= */ 8627c478bd9Sstevel@tonic-gate static fru_errno_t 8637c478bd9Sstevel@tonic-gate fpt_get_tag_data(fru_treehdl_t handle, const char *seg_name, 8647c478bd9Sstevel@tonic-gate fru_tag_t tag, int instance, 8657c478bd9Sstevel@tonic-gate uint8_t **data, size_t *data_len) 8667c478bd9Sstevel@tonic-gate { 8677c478bd9Sstevel@tonic-gate fru_errno_t err = FRU_SUCCESS; 8687c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 8697c478bd9Sstevel@tonic-gate uint8_t *buffer; 8707c478bd9Sstevel@tonic-gate int buf_len = 0; 8717c478bd9Sstevel@tonic-gate 8727c478bd9Sstevel@tonic-gate picl_nodehdl_t seg; 8737c478bd9Sstevel@tonic-gate picl_prophdl_t tagHdl; 8747c478bd9Sstevel@tonic-gate 8757c478bd9Sstevel@tonic-gate if ((err = get_tag_handle(TREEHDL_TO_PICLHDL(handle), seg_name, 8767c478bd9Sstevel@tonic-gate tag, instance, &seg, &tagHdl)) != FRU_SUCCESS) { 8777c478bd9Sstevel@tonic-gate return (err); 8787c478bd9Sstevel@tonic-gate } 8797c478bd9Sstevel@tonic-gate 8807c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_next_by_row(tagHdl, &tagHdl)) 8817c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 882*35551380Skmohan return (map_plugin_err(picl_err)); 8837c478bd9Sstevel@tonic-gate } 8847c478bd9Sstevel@tonic-gate 8857c478bd9Sstevel@tonic-gate buf_len = get_payload_length(&tag); 8867c478bd9Sstevel@tonic-gate buffer = malloc(buf_len); 8877c478bd9Sstevel@tonic-gate if (buffer == NULL) { 8887c478bd9Sstevel@tonic-gate return (FRU_FAILURE); 8897c478bd9Sstevel@tonic-gate } 8907c478bd9Sstevel@tonic-gate 8917c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval(tagHdl, buffer, buf_len)) 8927c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 8937c478bd9Sstevel@tonic-gate free(buffer); 8947c478bd9Sstevel@tonic-gate return (map_plugin_err(picl_err)); 8957c478bd9Sstevel@tonic-gate } 8967c478bd9Sstevel@tonic-gate 8977c478bd9Sstevel@tonic-gate *data = buffer; 8987c478bd9Sstevel@tonic-gate *data_len = buf_len; 8997c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 9007c478bd9Sstevel@tonic-gate } 9017c478bd9Sstevel@tonic-gate 9027c478bd9Sstevel@tonic-gate /* ========================================================================= */ 9037c478bd9Sstevel@tonic-gate static fru_errno_t 9047c478bd9Sstevel@tonic-gate fpt_set_tag_data(fru_treehdl_t handle, const char *seg_name, 9057c478bd9Sstevel@tonic-gate fru_tag_t tag, int instance, 9067c478bd9Sstevel@tonic-gate uint8_t *data, size_t data_len) 9077c478bd9Sstevel@tonic-gate { 9087c478bd9Sstevel@tonic-gate fru_errno_t rc = FRU_SUCCESS; 9097c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 9107c478bd9Sstevel@tonic-gate 9117c478bd9Sstevel@tonic-gate picl_nodehdl_t seg; 9127c478bd9Sstevel@tonic-gate picl_prophdl_t tagHdl; 9137c478bd9Sstevel@tonic-gate 9147c478bd9Sstevel@tonic-gate if ((rc = get_tag_handle(TREEHDL_TO_PICLHDL(handle), seg_name, 9157c478bd9Sstevel@tonic-gate tag, instance, &seg, &tagHdl)) != FRU_SUCCESS) { 9167c478bd9Sstevel@tonic-gate return (rc); 9177c478bd9Sstevel@tonic-gate } 9187c478bd9Sstevel@tonic-gate 9197c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_next_by_row(tagHdl, &tagHdl)) 9207c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 921*35551380Skmohan return (map_plugin_err(picl_err)); 9227c478bd9Sstevel@tonic-gate } 9237c478bd9Sstevel@tonic-gate 9247c478bd9Sstevel@tonic-gate if ((picl_err = ptree_update_propval(tagHdl, data, data_len)) 9257c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 9267c478bd9Sstevel@tonic-gate return (map_plugin_err(picl_err)); 9277c478bd9Sstevel@tonic-gate } 9287c478bd9Sstevel@tonic-gate 9297c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 9307c478bd9Sstevel@tonic-gate } 9317c478bd9Sstevel@tonic-gate 9327c478bd9Sstevel@tonic-gate /* ========================================================================= */ 9337c478bd9Sstevel@tonic-gate static fru_errno_t 9347c478bd9Sstevel@tonic-gate fpt_delete_tag(fru_treehdl_t handle, const char *seg_name, fru_tag_t tag, 9357c478bd9Sstevel@tonic-gate int instance) 9367c478bd9Sstevel@tonic-gate { 9377c478bd9Sstevel@tonic-gate fru_errno_t rc = FRU_SUCCESS; 9387c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 9397c478bd9Sstevel@tonic-gate 9407c478bd9Sstevel@tonic-gate picl_nodehdl_t segHdl; 9417c478bd9Sstevel@tonic-gate picl_prophdl_t tagHdl; 9427c478bd9Sstevel@tonic-gate 9437c478bd9Sstevel@tonic-gate /* get tag handle */ 9447c478bd9Sstevel@tonic-gate if ((rc = get_tag_handle(TREEHDL_TO_PICLHDL(handle), seg_name, 9457c478bd9Sstevel@tonic-gate tag, instance, &segHdl, &tagHdl)) != FRU_SUCCESS) { 9467c478bd9Sstevel@tonic-gate return (rc); 9477c478bd9Sstevel@tonic-gate } 9487c478bd9Sstevel@tonic-gate 9497c478bd9Sstevel@tonic-gate /* set up key */ 9507c478bd9Sstevel@tonic-gate tag.raw_data &= FRUDATA_DELETE_TAG_MASK; 9517c478bd9Sstevel@tonic-gate tag.raw_data |= FRUDATA_DELETE_TAG_KEY; 9527c478bd9Sstevel@tonic-gate 9537c478bd9Sstevel@tonic-gate /* Write back */ 9547c478bd9Sstevel@tonic-gate picl_err = ptree_update_propval(tagHdl, (void *)&(tag.raw_data), 9557c478bd9Sstevel@tonic-gate sizeof (tag.raw_data)); 9567c478bd9Sstevel@tonic-gate return (map_plugin_err(picl_err)); 9577c478bd9Sstevel@tonic-gate } 9587c478bd9Sstevel@tonic-gate 9597c478bd9Sstevel@tonic-gate /* ========================================================================= */ 9607c478bd9Sstevel@tonic-gate static fru_errno_t 9617c478bd9Sstevel@tonic-gate fpt_for_each_segment(fru_treehdl_t treenode, 9627c478bd9Sstevel@tonic-gate int (*function)(fru_treeseghdl_t segment, void *args), 9637c478bd9Sstevel@tonic-gate void *args) 9647c478bd9Sstevel@tonic-gate { 9657c478bd9Sstevel@tonic-gate int num_segments = 0, status; 9667c478bd9Sstevel@tonic-gate 9677c478bd9Sstevel@tonic-gate fru_errno_t saved_status = FRU_SUCCESS; 9687c478bd9Sstevel@tonic-gate 9697c478bd9Sstevel@tonic-gate picl_nodehdl_t container = TREEHDL_TO_PICLHDL(treenode), 9707c478bd9Sstevel@tonic-gate section, segment; 9717c478bd9Sstevel@tonic-gate 9727c478bd9Sstevel@tonic-gate 9737c478bd9Sstevel@tonic-gate if ((status = update_data_nodes(container)) != FRU_SUCCESS) 9747c478bd9Sstevel@tonic-gate return (status); 9757c478bd9Sstevel@tonic-gate 9767c478bd9Sstevel@tonic-gate /* process each section */ 9777c478bd9Sstevel@tonic-gate for (status = ptree_get_propval_by_name(container, PICL_PROP_CHILD, 9787c478bd9Sstevel@tonic-gate §ion, sizeof (section)); 9797c478bd9Sstevel@tonic-gate status == PICL_SUCCESS; 9807c478bd9Sstevel@tonic-gate status = ptree_get_propval_by_name(section, PICL_PROP_PEER, 9817c478bd9Sstevel@tonic-gate §ion, 9827c478bd9Sstevel@tonic-gate sizeof (section))) { 9837c478bd9Sstevel@tonic-gate 9847c478bd9Sstevel@tonic-gate if (cmp_class_name(section, PICL_CLASS_SECTION) != FRU_SUCCESS) 9857c478bd9Sstevel@tonic-gate continue; 9867c478bd9Sstevel@tonic-gate 9877c478bd9Sstevel@tonic-gate if ((status = ptree_get_propval_by_name(section, 9887c478bd9Sstevel@tonic-gate PICL_PROP_NUM_SEGMENTS, 9897c478bd9Sstevel@tonic-gate &num_segments, 9907c478bd9Sstevel@tonic-gate sizeof (num_segments))) 9917c478bd9Sstevel@tonic-gate == PICL_PROPNOTFOUND) { 9927c478bd9Sstevel@tonic-gate continue; 9937c478bd9Sstevel@tonic-gate } else if (status != PICL_SUCCESS) { 9947c478bd9Sstevel@tonic-gate saved_status = map_plugin_err(status); 9957c478bd9Sstevel@tonic-gate continue; 9967c478bd9Sstevel@tonic-gate } else if (num_segments == 0) { 9977c478bd9Sstevel@tonic-gate continue; 9987c478bd9Sstevel@tonic-gate } 9997c478bd9Sstevel@tonic-gate 10007c478bd9Sstevel@tonic-gate /* process each segment */ 10017c478bd9Sstevel@tonic-gate for (status = ptree_get_propval_by_name(section, 10027c478bd9Sstevel@tonic-gate PICL_PROP_CHILD, 10037c478bd9Sstevel@tonic-gate &segment, 10047c478bd9Sstevel@tonic-gate sizeof (segment)); 10057c478bd9Sstevel@tonic-gate status == PICL_SUCCESS; 10067c478bd9Sstevel@tonic-gate status = ptree_get_propval_by_name(segment, 10077c478bd9Sstevel@tonic-gate PICL_PROP_PEER, 10087c478bd9Sstevel@tonic-gate &segment, 10097c478bd9Sstevel@tonic-gate sizeof (segment))) { 10107c478bd9Sstevel@tonic-gate 10117c478bd9Sstevel@tonic-gate if (cmp_class_name(segment, PICL_CLASS_SEGMENT) 10127c478bd9Sstevel@tonic-gate != FRU_SUCCESS) continue; 10137c478bd9Sstevel@tonic-gate 10147c478bd9Sstevel@tonic-gate if ((status = function(PICLHDL_TO_TREESEGHDL(segment), 10157c478bd9Sstevel@tonic-gate args)) 10167c478bd9Sstevel@tonic-gate != FRU_SUCCESS) return (status); 10177c478bd9Sstevel@tonic-gate } 10187c478bd9Sstevel@tonic-gate 10197c478bd9Sstevel@tonic-gate if (status != PICL_PROPNOTFOUND) 10207c478bd9Sstevel@tonic-gate saved_status = map_plugin_err(status); 10217c478bd9Sstevel@tonic-gate } 10227c478bd9Sstevel@tonic-gate 10237c478bd9Sstevel@tonic-gate if (status != PICL_PROPNOTFOUND) 10247c478bd9Sstevel@tonic-gate saved_status = map_plugin_err(status); 10257c478bd9Sstevel@tonic-gate 10267c478bd9Sstevel@tonic-gate return (saved_status); 10277c478bd9Sstevel@tonic-gate } 10287c478bd9Sstevel@tonic-gate 10297c478bd9Sstevel@tonic-gate /* ========================================================================= */ 10307c478bd9Sstevel@tonic-gate static fru_errno_t 10317c478bd9Sstevel@tonic-gate fpt_get_segment_name(fru_treeseghdl_t segment, char **name) 10327c478bd9Sstevel@tonic-gate { 10337c478bd9Sstevel@tonic-gate char *propval; 10347c478bd9Sstevel@tonic-gate 10357c478bd9Sstevel@tonic-gate int status; 10367c478bd9Sstevel@tonic-gate 10377c478bd9Sstevel@tonic-gate picl_prophdl_t proph = 0; 10387c478bd9Sstevel@tonic-gate 10397c478bd9Sstevel@tonic-gate ptree_propinfo_t propinfo; 10407c478bd9Sstevel@tonic-gate 10417c478bd9Sstevel@tonic-gate 1042*35551380Skmohan if ((status = ptree_get_prop_by_name(TREESEGHDL_TO_PICLHDL(segment), 1043*35551380Skmohan PICL_PROP_NAME, &proph)) 10447c478bd9Sstevel@tonic-gate != PICL_SUCCESS) 1045*35551380Skmohan return (map_plugin_err(status)); 10467c478bd9Sstevel@tonic-gate 10477c478bd9Sstevel@tonic-gate if (ptree_get_propinfo(proph, &propinfo) != PICL_SUCCESS) 1048*35551380Skmohan return (map_plugin_err(status)); 10497c478bd9Sstevel@tonic-gate 10507c478bd9Sstevel@tonic-gate if (propinfo.piclinfo.size == 0) 10517c478bd9Sstevel@tonic-gate return (FRU_INVALDATASIZE); 10527c478bd9Sstevel@tonic-gate 10537c478bd9Sstevel@tonic-gate if ((propval = malloc(propinfo.piclinfo.size)) == NULL) 10547c478bd9Sstevel@tonic-gate return (FRU_NOSPACE); 10557c478bd9Sstevel@tonic-gate 10567c478bd9Sstevel@tonic-gate if ((status = ptree_get_propval(proph, propval, propinfo.piclinfo.size)) 10577c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 10587c478bd9Sstevel@tonic-gate free(propval); 10597c478bd9Sstevel@tonic-gate return (map_plugin_err(status)); 10607c478bd9Sstevel@tonic-gate } 10617c478bd9Sstevel@tonic-gate 10627c478bd9Sstevel@tonic-gate *name = propval; 10637c478bd9Sstevel@tonic-gate 10647c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 10657c478bd9Sstevel@tonic-gate } 10667c478bd9Sstevel@tonic-gate 10677c478bd9Sstevel@tonic-gate /* ========================================================================= */ 10687c478bd9Sstevel@tonic-gate static fru_errno_t 10697c478bd9Sstevel@tonic-gate fpt_for_each_packet(fru_treeseghdl_t treesegment, 10707c478bd9Sstevel@tonic-gate int (*function)(fru_tag_t *tag, uint8_t *payload, 10717c478bd9Sstevel@tonic-gate size_t length, 10727c478bd9Sstevel@tonic-gate void *args), 10737c478bd9Sstevel@tonic-gate void *args) 10747c478bd9Sstevel@tonic-gate { 10757c478bd9Sstevel@tonic-gate int status; 10767c478bd9Sstevel@tonic-gate 10777c478bd9Sstevel@tonic-gate uint8_t *payload; 10787c478bd9Sstevel@tonic-gate 10797c478bd9Sstevel@tonic-gate picl_nodehdl_t segment = TREESEGHDL_TO_PICLHDL(treesegment); 10807c478bd9Sstevel@tonic-gate 10817c478bd9Sstevel@tonic-gate picl_prophdl_t packet, payloadh = 0; 10827c478bd9Sstevel@tonic-gate 10837c478bd9Sstevel@tonic-gate ptree_propinfo_t propinfo; 10847c478bd9Sstevel@tonic-gate 10857c478bd9Sstevel@tonic-gate fru_segdesc_t descriptor; 10867c478bd9Sstevel@tonic-gate 10877c478bd9Sstevel@tonic-gate fru_tag_t tag; 10887c478bd9Sstevel@tonic-gate 10897c478bd9Sstevel@tonic-gate 10907c478bd9Sstevel@tonic-gate if ((status = ptree_get_propval_by_name(segment, PICL_PROP_DESCRIPTOR, 10917c478bd9Sstevel@tonic-gate &descriptor, 10927c478bd9Sstevel@tonic-gate sizeof (descriptor))) 10937c478bd9Sstevel@tonic-gate != PICL_SUCCESS) return (map_plugin_err(status)); 10947c478bd9Sstevel@tonic-gate 10957c478bd9Sstevel@tonic-gate if (descriptor.field.opaque) 10967c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 10977c478bd9Sstevel@tonic-gate 10987c478bd9Sstevel@tonic-gate if (descriptor.field.encrypted && (encrypt_func == NULL)) 10997c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 11007c478bd9Sstevel@tonic-gate 11017c478bd9Sstevel@tonic-gate if ((status = ptree_get_propval_by_name(segment, PICL_PROP_PACKET_TABLE, 11027c478bd9Sstevel@tonic-gate &packet, sizeof (packet))) 11037c478bd9Sstevel@tonic-gate == PICL_PROPNOTFOUND) 11047c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 11057c478bd9Sstevel@tonic-gate else if (status != PICL_SUCCESS) 11067c478bd9Sstevel@tonic-gate return (map_plugin_err(status)); 11077c478bd9Sstevel@tonic-gate 11087c478bd9Sstevel@tonic-gate while ((status = ptree_get_next_by_col(packet, &packet)) 11097c478bd9Sstevel@tonic-gate == PICL_SUCCESS) { 11107c478bd9Sstevel@tonic-gate if (((status = ptree_get_propval(packet, &tag, sizeof (tag))) 11117c478bd9Sstevel@tonic-gate != PICL_SUCCESS) || 11127c478bd9Sstevel@tonic-gate ((status = ptree_get_next_by_row(packet, &payloadh)) 11137c478bd9Sstevel@tonic-gate != PICL_SUCCESS) || 11147c478bd9Sstevel@tonic-gate ((status = ptree_get_propinfo(payloadh, &propinfo)) 11157c478bd9Sstevel@tonic-gate != PICL_SUCCESS)) 11167c478bd9Sstevel@tonic-gate return (map_plugin_err(status)); 11177c478bd9Sstevel@tonic-gate 11187c478bd9Sstevel@tonic-gate if (propinfo.piclinfo.size > 0) { 11197c478bd9Sstevel@tonic-gate payload = alloca(propinfo.piclinfo.size); 11207c478bd9Sstevel@tonic-gate if ((status = ptree_get_propval(payloadh, payload, 11217c478bd9Sstevel@tonic-gate propinfo.piclinfo.size)) 11227c478bd9Sstevel@tonic-gate != PICL_SUCCESS) return (map_plugin_err(status)); 11237c478bd9Sstevel@tonic-gate } else { 11247c478bd9Sstevel@tonic-gate payload = NULL; 11257c478bd9Sstevel@tonic-gate } 11267c478bd9Sstevel@tonic-gate 11277c478bd9Sstevel@tonic-gate if ((descriptor.field.encrypted) && 11287c478bd9Sstevel@tonic-gate ((status = encrypt_func(FRU_DECRYPT, payload, 11297c478bd9Sstevel@tonic-gate propinfo.piclinfo.size)) 11307c478bd9Sstevel@tonic-gate != FRU_SUCCESS)) return status; 11317c478bd9Sstevel@tonic-gate 11327c478bd9Sstevel@tonic-gate if ((status = function(&tag, payload, propinfo.piclinfo.size, 11337c478bd9Sstevel@tonic-gate args)) 11347c478bd9Sstevel@tonic-gate != FRU_SUCCESS) return (status); 11357c478bd9Sstevel@tonic-gate } 11367c478bd9Sstevel@tonic-gate 11377c478bd9Sstevel@tonic-gate if (status == PICL_ENDOFLIST) 11387c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 11397c478bd9Sstevel@tonic-gate else 11407c478bd9Sstevel@tonic-gate return (map_plugin_err(status)); 11417c478bd9Sstevel@tonic-gate } 11427c478bd9Sstevel@tonic-gate 11437c478bd9Sstevel@tonic-gate /* ========================================================================= */ 11447c478bd9Sstevel@tonic-gate /* ARGSUSED0 */ 11457c478bd9Sstevel@tonic-gate static fru_errno_t 11467c478bd9Sstevel@tonic-gate initialize(int argc, char **argv) 11477c478bd9Sstevel@tonic-gate { 11487c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 11497c478bd9Sstevel@tonic-gate } 11507c478bd9Sstevel@tonic-gate 11517c478bd9Sstevel@tonic-gate /* ========================================================================= */ 11527c478bd9Sstevel@tonic-gate static fru_errno_t 11537c478bd9Sstevel@tonic-gate shutdown(void) 11547c478bd9Sstevel@tonic-gate { 11557c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 11567c478bd9Sstevel@tonic-gate } 11577c478bd9Sstevel@tonic-gate 11587c478bd9Sstevel@tonic-gate /* ========================================================================= */ 11597c478bd9Sstevel@tonic-gate /* object for libfru to link to */ 11607c478bd9Sstevel@tonic-gate fru_datasource_t data_source = 11617c478bd9Sstevel@tonic-gate { 11627c478bd9Sstevel@tonic-gate LIBFRU_DS_VER, 11637c478bd9Sstevel@tonic-gate initialize, 11647c478bd9Sstevel@tonic-gate shutdown, 11657c478bd9Sstevel@tonic-gate fpt_get_root, 11667c478bd9Sstevel@tonic-gate fpt_get_child, 11677c478bd9Sstevel@tonic-gate fpt_get_peer, 11687c478bd9Sstevel@tonic-gate fpt_get_parent, 11697c478bd9Sstevel@tonic-gate fpt_get_name_from_hdl, 11707c478bd9Sstevel@tonic-gate fpt_get_node_type, 11717c478bd9Sstevel@tonic-gate fpt_get_seg_list, 11727c478bd9Sstevel@tonic-gate fpt_get_seg_def, 11737c478bd9Sstevel@tonic-gate fpt_add_seg, 11747c478bd9Sstevel@tonic-gate fpt_delete_seg, 11757c478bd9Sstevel@tonic-gate fpt_for_each_segment, 11767c478bd9Sstevel@tonic-gate fpt_get_segment_name, 11777c478bd9Sstevel@tonic-gate fpt_add_tag_to_seg, 11787c478bd9Sstevel@tonic-gate fpt_get_tag_list, 11797c478bd9Sstevel@tonic-gate fpt_get_tag_data, 11807c478bd9Sstevel@tonic-gate fpt_set_tag_data, 11817c478bd9Sstevel@tonic-gate fpt_delete_tag, 11827c478bd9Sstevel@tonic-gate fpt_for_each_packet 11837c478bd9Sstevel@tonic-gate }; 1184