1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2000-2002 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <alloca.h> 30*7c478bd9Sstevel@tonic-gate #include <picl.h> 31*7c478bd9Sstevel@tonic-gate #include <picltree.h> 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate #include <string.h> 34*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 35*7c478bd9Sstevel@tonic-gate #include <stdarg.h> 36*7c478bd9Sstevel@tonic-gate #include <stdio.h> 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate #include "picldefs.h" 39*7c478bd9Sstevel@tonic-gate #include "fru_data.h" 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate #include "libfruds.h" 42*7c478bd9Sstevel@tonic-gate #include "libfrup.h" 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate #define FRU_LABEL_PADDING 10 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 47*7c478bd9Sstevel@tonic-gate #define TREEHDL_TO_PICLHDL(treehdl) ((picl_nodehdl_t)treehdl) 48*7c478bd9Sstevel@tonic-gate #define PICLHDL_TO_TREEHDL(piclhdl) ((fru_treehdl_t)piclhdl) 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate #define TREESEGHDL_TO_PICLHDL(treeseghdl) ((picl_nodehdl_t)treeseghdl) 51*7c478bd9Sstevel@tonic-gate #define PICLHDL_TO_TREESEGHDL(piclhdl) ((fru_treeseghdl_t)piclhdl) 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate /* Cache of the root node for quick checks */ 54*7c478bd9Sstevel@tonic-gate static picl_nodehdl_t picl_root_node; 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 57*7c478bd9Sstevel@tonic-gate /* 58*7c478bd9Sstevel@tonic-gate * Map the PICL errors the plugin would give me to FRU errors 59*7c478bd9Sstevel@tonic-gate */ 60*7c478bd9Sstevel@tonic-gate static fru_errno_t 61*7c478bd9Sstevel@tonic-gate map_plugin_err(int picl_err) 62*7c478bd9Sstevel@tonic-gate { 63*7c478bd9Sstevel@tonic-gate switch (picl_err) { 64*7c478bd9Sstevel@tonic-gate case PICL_SUCCESS: 65*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 66*7c478bd9Sstevel@tonic-gate case PICL_PERMDENIED: 67*7c478bd9Sstevel@tonic-gate return (FRU_INVALPERM); 68*7c478bd9Sstevel@tonic-gate case PICL_PROPEXISTS: 69*7c478bd9Sstevel@tonic-gate return (FRU_DUPSEG); 70*7c478bd9Sstevel@tonic-gate case PICL_NOSPACE: 71*7c478bd9Sstevel@tonic-gate return (FRU_NOSPACE); 72*7c478bd9Sstevel@tonic-gate } 73*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 74*7c478bd9Sstevel@tonic-gate } 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 77*7c478bd9Sstevel@tonic-gate /* 78*7c478bd9Sstevel@tonic-gate * cause a refresh of the sub-nodes by writing anything to the container 79*7c478bd9Sstevel@tonic-gate * property of the node. 80*7c478bd9Sstevel@tonic-gate */ 81*7c478bd9Sstevel@tonic-gate static fru_errno_t 82*7c478bd9Sstevel@tonic-gate update_data_nodes(picl_nodehdl_t handle) 83*7c478bd9Sstevel@tonic-gate { 84*7c478bd9Sstevel@tonic-gate uint32_t container = FRUDATA_DELETE_TAG_KEY; 85*7c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_update_propval_by_name(handle, 88*7c478bd9Sstevel@tonic-gate PICL_PROP_CONTAINER, (void *)&container, 89*7c478bd9Sstevel@tonic-gate sizeof (container))) != PICL_SUCCESS) { 90*7c478bd9Sstevel@tonic-gate return (map_plugin_err(picl_err)); 91*7c478bd9Sstevel@tonic-gate } 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 94*7c478bd9Sstevel@tonic-gate } 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 97*7c478bd9Sstevel@tonic-gate /* 98*7c478bd9Sstevel@tonic-gate * picl like function which gets a string property with the proper length 99*7c478bd9Sstevel@tonic-gate * NOTE: returns picl errno values NOT fru_errno_t 100*7c478bd9Sstevel@tonic-gate */ 101*7c478bd9Sstevel@tonic-gate static int 102*7c478bd9Sstevel@tonic-gate get_strprop_by_name(picl_nodehdl_t handle, char *prop_name, char **string) 103*7c478bd9Sstevel@tonic-gate { 104*7c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 105*7c478bd9Sstevel@tonic-gate picl_prophdl_t proph; 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate size_t buf_size = 0; 108*7c478bd9Sstevel@tonic-gate char *tmp_buf = NULL; 109*7c478bd9Sstevel@tonic-gate 110*7c478bd9Sstevel@tonic-gate ptree_propinfo_t prop_info; 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_prop_by_name(handle, prop_name, &proph)) 113*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 114*7c478bd9Sstevel@tonic-gate return (picl_err); 115*7c478bd9Sstevel@tonic-gate } 116*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propinfo(proph, &prop_info)) 117*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 118*7c478bd9Sstevel@tonic-gate return (picl_err); 119*7c478bd9Sstevel@tonic-gate } 120*7c478bd9Sstevel@tonic-gate buf_size = prop_info.piclinfo.size; 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate tmp_buf = malloc((sizeof (*tmp_buf) * buf_size)); 123*7c478bd9Sstevel@tonic-gate if (tmp_buf == NULL) { 124*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 125*7c478bd9Sstevel@tonic-gate } 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval(proph, tmp_buf, buf_size)) 128*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 129*7c478bd9Sstevel@tonic-gate free(tmp_buf); 130*7c478bd9Sstevel@tonic-gate return (picl_err); 131*7c478bd9Sstevel@tonic-gate } 132*7c478bd9Sstevel@tonic-gate 133*7c478bd9Sstevel@tonic-gate *string = tmp_buf; 134*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 135*7c478bd9Sstevel@tonic-gate } 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 138*7c478bd9Sstevel@tonic-gate static fru_errno_t 139*7c478bd9Sstevel@tonic-gate fpt_get_name_from_hdl(fru_treehdl_t node, char **name) 140*7c478bd9Sstevel@tonic-gate { 141*7c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 142*7c478bd9Sstevel@tonic-gate char *tmp_name = NULL; 143*7c478bd9Sstevel@tonic-gate char *label = NULL; 144*7c478bd9Sstevel@tonic-gate picl_nodehdl_t handle = TREEHDL_TO_PICLHDL(node); 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate /* get the name */ 147*7c478bd9Sstevel@tonic-gate if ((picl_err = get_strprop_by_name(handle, PICL_PROP_NAME, 148*7c478bd9Sstevel@tonic-gate &tmp_name)) != PICL_SUCCESS) { 149*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate /* get the label, if any */ 153*7c478bd9Sstevel@tonic-gate if ((picl_err = get_strprop_by_name(handle, PICL_PROP_LABEL, 154*7c478bd9Sstevel@tonic-gate &label)) != PICL_SUCCESS) { 155*7c478bd9Sstevel@tonic-gate if (picl_err != PICL_PROPNOTFOUND) { 156*7c478bd9Sstevel@tonic-gate free(tmp_name); 157*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 158*7c478bd9Sstevel@tonic-gate } 159*7c478bd9Sstevel@tonic-gate /* else PICL_PROPNOTFOUND is OK because not all nodes */ 160*7c478bd9Sstevel@tonic-gate /* will have a label. */ 161*7c478bd9Sstevel@tonic-gate } 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate /* construct the name as nessecary */ 164*7c478bd9Sstevel@tonic-gate if (label == NULL) { 165*7c478bd9Sstevel@tonic-gate *name = strdup(tmp_name); 166*7c478bd9Sstevel@tonic-gate } else { 167*7c478bd9Sstevel@tonic-gate size_t buf_size = strlen(tmp_name) + strlen(label) + 168*7c478bd9Sstevel@tonic-gate FRU_LABEL_PADDING; 169*7c478bd9Sstevel@tonic-gate char *tmp = malloc(buf_size); 170*7c478bd9Sstevel@tonic-gate if (tmp == NULL) { 171*7c478bd9Sstevel@tonic-gate free(tmp_name); 172*7c478bd9Sstevel@tonic-gate free(label); 173*7c478bd9Sstevel@tonic-gate return (FRU_FAILURE); 174*7c478bd9Sstevel@tonic-gate } 175*7c478bd9Sstevel@tonic-gate snprintf(tmp, buf_size, "%s?%s=%s", tmp_name, 176*7c478bd9Sstevel@tonic-gate PICL_PROP_LABEL, label); 177*7c478bd9Sstevel@tonic-gate *name = tmp; 178*7c478bd9Sstevel@tonic-gate } 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate free(tmp_name); 181*7c478bd9Sstevel@tonic-gate free(label); 182*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 183*7c478bd9Sstevel@tonic-gate } 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 186*7c478bd9Sstevel@tonic-gate /* compare the node name to the name passed */ 187*7c478bd9Sstevel@tonic-gate static fru_errno_t 188*7c478bd9Sstevel@tonic-gate cmp_node_name(picl_nodehdl_t node, const char *name) 189*7c478bd9Sstevel@tonic-gate { 190*7c478bd9Sstevel@tonic-gate char *node_name = NULL; 191*7c478bd9Sstevel@tonic-gate 192*7c478bd9Sstevel@tonic-gate if (get_strprop_by_name(node, PICL_PROP_NAME, &node_name) 193*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 194*7c478bd9Sstevel@tonic-gate return (FRU_FAILURE); 195*7c478bd9Sstevel@tonic-gate } 196*7c478bd9Sstevel@tonic-gate 197*7c478bd9Sstevel@tonic-gate if (strcmp(node_name, name) == 0) { 198*7c478bd9Sstevel@tonic-gate free(node_name); 199*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 200*7c478bd9Sstevel@tonic-gate } 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate free(node_name); 203*7c478bd9Sstevel@tonic-gate return (FRU_FAILURE); 204*7c478bd9Sstevel@tonic-gate } 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 207*7c478bd9Sstevel@tonic-gate /* compare the node class name to the name passed */ 208*7c478bd9Sstevel@tonic-gate static fru_errno_t 209*7c478bd9Sstevel@tonic-gate cmp_class_name(picl_nodehdl_t node, const char *name) 210*7c478bd9Sstevel@tonic-gate { 211*7c478bd9Sstevel@tonic-gate char *class_name = NULL; 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate if (get_strprop_by_name(node, PICL_PROP_CLASSNAME, &class_name) 214*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 215*7c478bd9Sstevel@tonic-gate return (FRU_FAILURE); 216*7c478bd9Sstevel@tonic-gate } 217*7c478bd9Sstevel@tonic-gate 218*7c478bd9Sstevel@tonic-gate if (strcmp(class_name, name) == 0) { 219*7c478bd9Sstevel@tonic-gate free(class_name); 220*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 221*7c478bd9Sstevel@tonic-gate } 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate free(class_name); 224*7c478bd9Sstevel@tonic-gate return (FRU_FAILURE); 225*7c478bd9Sstevel@tonic-gate } 226*7c478bd9Sstevel@tonic-gate 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 229*7c478bd9Sstevel@tonic-gate /* get the "frutree" root node */ 230*7c478bd9Sstevel@tonic-gate static fru_errno_t 231*7c478bd9Sstevel@tonic-gate fpt_get_root(fru_treehdl_t *node) 232*7c478bd9Sstevel@tonic-gate { 233*7c478bd9Sstevel@tonic-gate picl_nodehdl_t picl_node; 234*7c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 235*7c478bd9Sstevel@tonic-gate 236*7c478bd9Sstevel@tonic-gate picl_err = ptree_get_root(&picl_node); 237*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval_by_name(picl_node, PICL_PROP_CHILD, 238*7c478bd9Sstevel@tonic-gate (void *)&picl_node, sizeof (picl_node))) 239*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 240*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 241*7c478bd9Sstevel@tonic-gate } 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate while (cmp_node_name(picl_node, PICL_NODE_FRUTREE) 244*7c478bd9Sstevel@tonic-gate != FRU_SUCCESS) { 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval_by_name(picl_node, 247*7c478bd9Sstevel@tonic-gate PICL_PROP_PEER, (void *)&picl_node, 248*7c478bd9Sstevel@tonic-gate sizeof (picl_node))) == PICL_PROPNOTFOUND) { 249*7c478bd9Sstevel@tonic-gate return (FRU_NODENOTFOUND); 250*7c478bd9Sstevel@tonic-gate } else if (picl_err != PICL_SUCCESS) { 251*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 252*7c478bd9Sstevel@tonic-gate } 253*7c478bd9Sstevel@tonic-gate } 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate picl_root_node = picl_node; 256*7c478bd9Sstevel@tonic-gate *node = PICLHDL_TO_TREEHDL(picl_node); 257*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 258*7c478bd9Sstevel@tonic-gate } 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 261*7c478bd9Sstevel@tonic-gate static fru_errno_t 262*7c478bd9Sstevel@tonic-gate fpt_get_peer(fru_treehdl_t sibling, fru_treehdl_t *peer) 263*7c478bd9Sstevel@tonic-gate { 264*7c478bd9Sstevel@tonic-gate int rc = PICL_SUCCESS; 265*7c478bd9Sstevel@tonic-gate picl_nodehdl_t handle = TREEHDL_TO_PICLHDL(sibling); 266*7c478bd9Sstevel@tonic-gate picl_nodehdl_t picl_peer; 267*7c478bd9Sstevel@tonic-gate 268*7c478bd9Sstevel@tonic-gate rc = ptree_get_propval_by_name(handle, PICL_PROP_PEER, 269*7c478bd9Sstevel@tonic-gate (void *)&picl_peer, sizeof (picl_peer)); 270*7c478bd9Sstevel@tonic-gate if (rc != PICL_SUCCESS) { 271*7c478bd9Sstevel@tonic-gate if (rc == PICL_PROPNOTFOUND) 272*7c478bd9Sstevel@tonic-gate return (FRU_NODENOTFOUND); 273*7c478bd9Sstevel@tonic-gate else 274*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 275*7c478bd9Sstevel@tonic-gate } 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate *peer = PICLHDL_TO_TREEHDL(picl_peer); 278*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 279*7c478bd9Sstevel@tonic-gate } 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 282*7c478bd9Sstevel@tonic-gate static fru_errno_t 283*7c478bd9Sstevel@tonic-gate fpt_get_child(fru_treehdl_t handle, fru_treehdl_t *child) 284*7c478bd9Sstevel@tonic-gate { 285*7c478bd9Sstevel@tonic-gate picl_nodehdl_t p_child; 286*7c478bd9Sstevel@tonic-gate int rc = ptree_get_propval_by_name(TREEHDL_TO_PICLHDL(handle), 287*7c478bd9Sstevel@tonic-gate PICL_PROP_CHILD, (void *)&p_child, sizeof (p_child)); 288*7c478bd9Sstevel@tonic-gate if (rc != PICL_SUCCESS) { 289*7c478bd9Sstevel@tonic-gate if (rc == PICL_PROPNOTFOUND) 290*7c478bd9Sstevel@tonic-gate return (FRU_NODENOTFOUND); 291*7c478bd9Sstevel@tonic-gate else 292*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 293*7c478bd9Sstevel@tonic-gate } 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate *child = PICLHDL_TO_TREEHDL(p_child); 296*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 297*7c478bd9Sstevel@tonic-gate } 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 300*7c478bd9Sstevel@tonic-gate static fru_errno_t 301*7c478bd9Sstevel@tonic-gate fpt_get_parent(fru_treehdl_t handle, fru_treehdl_t *parent) 302*7c478bd9Sstevel@tonic-gate { 303*7c478bd9Sstevel@tonic-gate int rc = PICL_SUCCESS; 304*7c478bd9Sstevel@tonic-gate picl_nodehdl_t p_parent; 305*7c478bd9Sstevel@tonic-gate 306*7c478bd9Sstevel@tonic-gate /* do not allow the libfru users to see the parent of the root */ 307*7c478bd9Sstevel@tonic-gate if (TREEHDL_TO_PICLHDL(handle) == picl_root_node) { 308*7c478bd9Sstevel@tonic-gate return (FRU_NODENOTFOUND); 309*7c478bd9Sstevel@tonic-gate } 310*7c478bd9Sstevel@tonic-gate 311*7c478bd9Sstevel@tonic-gate rc = ptree_get_propval_by_name(TREEHDL_TO_PICLHDL(handle), 312*7c478bd9Sstevel@tonic-gate PICL_PROP_PARENT, (void *)&p_parent, sizeof (p_parent)); 313*7c478bd9Sstevel@tonic-gate if (rc != PICL_SUCCESS) { 314*7c478bd9Sstevel@tonic-gate if (rc == PICL_PROPNOTFOUND) 315*7c478bd9Sstevel@tonic-gate return (FRU_NODENOTFOUND); 316*7c478bd9Sstevel@tonic-gate else 317*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 318*7c478bd9Sstevel@tonic-gate } 319*7c478bd9Sstevel@tonic-gate 320*7c478bd9Sstevel@tonic-gate *parent = PICLHDL_TO_TREEHDL(p_parent); 321*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 322*7c478bd9Sstevel@tonic-gate } 323*7c478bd9Sstevel@tonic-gate 324*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 325*7c478bd9Sstevel@tonic-gate static fru_errno_t 326*7c478bd9Sstevel@tonic-gate fpt_get_node_type(fru_treehdl_t node, fru_node_t *type) 327*7c478bd9Sstevel@tonic-gate { 328*7c478bd9Sstevel@tonic-gate char picl_class[PICL_PROPNAMELEN_MAX]; 329*7c478bd9Sstevel@tonic-gate picl_nodehdl_t handle = TREEHDL_TO_PICLHDL(node); 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate if (ptree_get_propval_by_name(handle, PICL_PROP_CLASSNAME, 332*7c478bd9Sstevel@tonic-gate picl_class, sizeof (picl_class)) != PICL_SUCCESS) { 333*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 334*7c478bd9Sstevel@tonic-gate } 335*7c478bd9Sstevel@tonic-gate 336*7c478bd9Sstevel@tonic-gate if (strcmp(picl_class, PICL_CLASS_LOCATION) == 0) { 337*7c478bd9Sstevel@tonic-gate *type = FRU_NODE_LOCATION; 338*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 339*7c478bd9Sstevel@tonic-gate } else if (strcmp(picl_class, PICL_CLASS_FRU) == 0) { 340*7c478bd9Sstevel@tonic-gate picl_prophdl_t proph; 341*7c478bd9Sstevel@tonic-gate 342*7c478bd9Sstevel@tonic-gate /* check for the CONTAINER_PROP property which indicates */ 343*7c478bd9Sstevel@tonic-gate /* there is data for this node. (ie fru is a container) */ 344*7c478bd9Sstevel@tonic-gate if (ptree_get_prop_by_name(handle, 345*7c478bd9Sstevel@tonic-gate PICL_PROP_CONTAINER, &proph) == PICL_SUCCESS) { 346*7c478bd9Sstevel@tonic-gate *type = FRU_NODE_CONTAINER; 347*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 348*7c478bd9Sstevel@tonic-gate } 349*7c478bd9Sstevel@tonic-gate *type = FRU_NODE_FRU; 350*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 351*7c478bd9Sstevel@tonic-gate } 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate *type = FRU_NODE_UNKNOWN; 354*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 355*7c478bd9Sstevel@tonic-gate } 356*7c478bd9Sstevel@tonic-gate 357*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 358*7c478bd9Sstevel@tonic-gate /* find the next section or return NODENOTFOUND */ 359*7c478bd9Sstevel@tonic-gate static fru_errno_t 360*7c478bd9Sstevel@tonic-gate find_next_section(picl_nodehdl_t current, picl_nodehdl_t *next) 361*7c478bd9Sstevel@tonic-gate { 362*7c478bd9Sstevel@tonic-gate picl_nodehdl_t rc_next; 363*7c478bd9Sstevel@tonic-gate 364*7c478bd9Sstevel@tonic-gate if (ptree_get_propval_by_name(current, PICL_PROP_PEER, 365*7c478bd9Sstevel@tonic-gate (void *)&rc_next, sizeof (rc_next)) != PICL_SUCCESS) { 366*7c478bd9Sstevel@tonic-gate return (FRU_NODENOTFOUND); 367*7c478bd9Sstevel@tonic-gate } 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate /* Make sure this is a "Section" node */ 370*7c478bd9Sstevel@tonic-gate if (cmp_class_name(rc_next, PICL_CLASS_SECTION) 371*7c478bd9Sstevel@tonic-gate == FRU_SUCCESS) { 372*7c478bd9Sstevel@tonic-gate *next = rc_next; 373*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 374*7c478bd9Sstevel@tonic-gate } 375*7c478bd9Sstevel@tonic-gate 376*7c478bd9Sstevel@tonic-gate /* and if this is not good keep trying to find a peer which */ 377*7c478bd9Sstevel@tonic-gate /* is a section */ 378*7c478bd9Sstevel@tonic-gate return (find_next_section(rc_next, next)); 379*7c478bd9Sstevel@tonic-gate } 380*7c478bd9Sstevel@tonic-gate 381*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 382*7c478bd9Sstevel@tonic-gate /* find the first section or return NODENOTFOUND */ 383*7c478bd9Sstevel@tonic-gate static fru_errno_t 384*7c478bd9Sstevel@tonic-gate find_first_section(picl_nodehdl_t parent, picl_nodehdl_t *section) 385*7c478bd9Sstevel@tonic-gate { 386*7c478bd9Sstevel@tonic-gate picl_nodehdl_t rc_section; 387*7c478bd9Sstevel@tonic-gate 388*7c478bd9Sstevel@tonic-gate if (ptree_get_propval_by_name(parent, PICL_PROP_CHILD, 389*7c478bd9Sstevel@tonic-gate (void *)&rc_section, sizeof (rc_section)) != PICL_SUCCESS) { 390*7c478bd9Sstevel@tonic-gate return (FRU_NODENOTFOUND); 391*7c478bd9Sstevel@tonic-gate } 392*7c478bd9Sstevel@tonic-gate 393*7c478bd9Sstevel@tonic-gate /* Make sure this is a "Section" node */ 394*7c478bd9Sstevel@tonic-gate if (cmp_class_name(rc_section, PICL_CLASS_SECTION) 395*7c478bd9Sstevel@tonic-gate == FRU_SUCCESS) { 396*7c478bd9Sstevel@tonic-gate *section = rc_section; 397*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 398*7c478bd9Sstevel@tonic-gate } 399*7c478bd9Sstevel@tonic-gate 400*7c478bd9Sstevel@tonic-gate /* and if this is not good keep trying to find a peer which */ 401*7c478bd9Sstevel@tonic-gate /* is a section */ 402*7c478bd9Sstevel@tonic-gate return (find_next_section(rc_section, section)); 403*7c478bd9Sstevel@tonic-gate } 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 406*7c478bd9Sstevel@tonic-gate /* 407*7c478bd9Sstevel@tonic-gate * Find the handle of the segment node "segment". 408*7c478bd9Sstevel@tonic-gate * also returns the hardware description of this segment. (read from the 409*7c478bd9Sstevel@tonic-gate * section this was found in.) 410*7c478bd9Sstevel@tonic-gate * If the ign_cor_flg is set this will still succeed even if the segment is 411*7c478bd9Sstevel@tonic-gate * corrupt, otherwise it will return FRU_SEGCORRUPT for corrupt segments 412*7c478bd9Sstevel@tonic-gate */ 413*7c478bd9Sstevel@tonic-gate #define IGN_CORRUPT_YES 1 414*7c478bd9Sstevel@tonic-gate #define IGN_CORRUPT_NO 0 415*7c478bd9Sstevel@tonic-gate static fru_errno_t 416*7c478bd9Sstevel@tonic-gate get_segment_node(picl_nodehdl_t handle, const char *segment, 417*7c478bd9Sstevel@tonic-gate picl_nodehdl_t *seg_hdl, fru_seg_hwdesc_t *hw_desc, int ign_cor_flg) 418*7c478bd9Sstevel@tonic-gate { 419*7c478bd9Sstevel@tonic-gate fru_errno_t err = FRU_SUCCESS; 420*7c478bd9Sstevel@tonic-gate picl_nodehdl_t sect_node; 421*7c478bd9Sstevel@tonic-gate 422*7c478bd9Sstevel@tonic-gate if ((err = update_data_nodes(handle)) != FRU_SUCCESS) { 423*7c478bd9Sstevel@tonic-gate return (err); 424*7c478bd9Sstevel@tonic-gate } 425*7c478bd9Sstevel@tonic-gate 426*7c478bd9Sstevel@tonic-gate if ((err = find_first_section(handle, §_node)) != FRU_SUCCESS) { 427*7c478bd9Sstevel@tonic-gate return (err); 428*7c478bd9Sstevel@tonic-gate } 429*7c478bd9Sstevel@tonic-gate 430*7c478bd9Sstevel@tonic-gate /* while there are sections. */ 431*7c478bd9Sstevel@tonic-gate while (err == FRU_SUCCESS) { 432*7c478bd9Sstevel@tonic-gate uint32_t num_segs = 0; 433*7c478bd9Sstevel@tonic-gate int rc = PICL_SUCCESS; 434*7c478bd9Sstevel@tonic-gate picl_nodehdl_t seg_node; 435*7c478bd9Sstevel@tonic-gate 436*7c478bd9Sstevel@tonic-gate /* do this just in case the Segments have not been built. */ 437*7c478bd9Sstevel@tonic-gate if ((rc = ptree_get_propval_by_name(sect_node, 438*7c478bd9Sstevel@tonic-gate PICL_PROP_NUM_SEGMENTS, 439*7c478bd9Sstevel@tonic-gate (void *)&num_segs, 440*7c478bd9Sstevel@tonic-gate sizeof (num_segs))) != PICL_SUCCESS) { 441*7c478bd9Sstevel@tonic-gate return (map_plugin_err(rc)); 442*7c478bd9Sstevel@tonic-gate } 443*7c478bd9Sstevel@tonic-gate 444*7c478bd9Sstevel@tonic-gate /* while there are segments. */ 445*7c478bd9Sstevel@tonic-gate rc = ptree_get_propval_by_name(sect_node, PICL_PROP_CHILD, 446*7c478bd9Sstevel@tonic-gate (void *)&seg_node, sizeof (seg_node)); 447*7c478bd9Sstevel@tonic-gate while (rc == PICL_SUCCESS) { 448*7c478bd9Sstevel@tonic-gate char name[PICL_PROPNAMELEN_MAX]; 449*7c478bd9Sstevel@tonic-gate ptree_get_propval_by_name(seg_node, PICL_PROP_NAME, 450*7c478bd9Sstevel@tonic-gate name, sizeof (name)); 451*7c478bd9Sstevel@tonic-gate if (strcmp(segment, name) == 0) { 452*7c478bd9Sstevel@tonic-gate int dummy = 0; 453*7c478bd9Sstevel@tonic-gate int protection = 0; 454*7c478bd9Sstevel@tonic-gate /* NUM_TAGS prop exists iff segment is OK */ 455*7c478bd9Sstevel@tonic-gate if ((ign_cor_flg == IGN_CORRUPT_NO) && 456*7c478bd9Sstevel@tonic-gate (ptree_get_propval_by_name(seg_node, 457*7c478bd9Sstevel@tonic-gate PICL_PROP_NUM_TAGS, 458*7c478bd9Sstevel@tonic-gate (void *)&dummy, 459*7c478bd9Sstevel@tonic-gate sizeof (dummy)) != PICL_SUCCESS)) { 460*7c478bd9Sstevel@tonic-gate return (FRU_SEGCORRUPT); 461*7c478bd9Sstevel@tonic-gate } 462*7c478bd9Sstevel@tonic-gate /* get the HW protections of this section. */ 463*7c478bd9Sstevel@tonic-gate if (ptree_get_propval_by_name(sect_node, 464*7c478bd9Sstevel@tonic-gate PICL_PROP_PROTECTED, 465*7c478bd9Sstevel@tonic-gate (void *)&protection, 466*7c478bd9Sstevel@tonic-gate sizeof (protection)) != PICL_SUCCESS) { 467*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 468*7c478bd9Sstevel@tonic-gate } 469*7c478bd9Sstevel@tonic-gate hw_desc->all_bits = 0; 470*7c478bd9Sstevel@tonic-gate hw_desc->field.read_only = protection; 471*7c478bd9Sstevel@tonic-gate 472*7c478bd9Sstevel@tonic-gate *seg_hdl = seg_node; 473*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 474*7c478bd9Sstevel@tonic-gate } 475*7c478bd9Sstevel@tonic-gate rc = ptree_get_propval_by_name(seg_node, PICL_PROP_PEER, 476*7c478bd9Sstevel@tonic-gate (void *)&seg_node, sizeof (seg_node)); 477*7c478bd9Sstevel@tonic-gate } 478*7c478bd9Sstevel@tonic-gate 479*7c478bd9Sstevel@tonic-gate /* Peer property not found is ok */ 480*7c478bd9Sstevel@tonic-gate if (rc != PICL_PROPNOTFOUND) { 481*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 482*7c478bd9Sstevel@tonic-gate } 483*7c478bd9Sstevel@tonic-gate 484*7c478bd9Sstevel@tonic-gate err = find_next_section(sect_node, §_node); 485*7c478bd9Sstevel@tonic-gate } 486*7c478bd9Sstevel@tonic-gate 487*7c478bd9Sstevel@tonic-gate return (FRU_INVALSEG); 488*7c478bd9Sstevel@tonic-gate } 489*7c478bd9Sstevel@tonic-gate 490*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 491*7c478bd9Sstevel@tonic-gate /* 492*7c478bd9Sstevel@tonic-gate * For the section handle passed add to list all the segment names found. 493*7c478bd9Sstevel@tonic-gate * Also incriments total by the number found. 494*7c478bd9Sstevel@tonic-gate */ 495*7c478bd9Sstevel@tonic-gate static fru_errno_t 496*7c478bd9Sstevel@tonic-gate add_segs_for_section(picl_nodehdl_t section, fru_strlist_t *list) 497*7c478bd9Sstevel@tonic-gate { 498*7c478bd9Sstevel@tonic-gate int num_segments = 0; 499*7c478bd9Sstevel@tonic-gate int rc = PICL_SUCCESS; 500*7c478bd9Sstevel@tonic-gate 501*7c478bd9Sstevel@tonic-gate if ((rc = ptree_get_propval_by_name(section, 502*7c478bd9Sstevel@tonic-gate PICL_PROP_NUM_SEGMENTS, 503*7c478bd9Sstevel@tonic-gate (void *)&num_segments, 504*7c478bd9Sstevel@tonic-gate sizeof (num_segments))) != PICL_SUCCESS) { 505*7c478bd9Sstevel@tonic-gate fru_destroy_strlist(list); 506*7c478bd9Sstevel@tonic-gate return (map_plugin_err(rc)); 507*7c478bd9Sstevel@tonic-gate } 508*7c478bd9Sstevel@tonic-gate 509*7c478bd9Sstevel@tonic-gate if (num_segments != 0) { 510*7c478bd9Sstevel@tonic-gate picl_nodehdl_t seg_node; 511*7c478bd9Sstevel@tonic-gate int total_space = list->num + num_segments; 512*7c478bd9Sstevel@tonic-gate 513*7c478bd9Sstevel@tonic-gate list->strs = realloc(list->strs, 514*7c478bd9Sstevel@tonic-gate (sizeof (*(list->strs)) * (total_space))); 515*7c478bd9Sstevel@tonic-gate if (list->strs == NULL) { 516*7c478bd9Sstevel@tonic-gate return (FRU_FAILURE); 517*7c478bd9Sstevel@tonic-gate } 518*7c478bd9Sstevel@tonic-gate 519*7c478bd9Sstevel@tonic-gate /* get the first segment */ 520*7c478bd9Sstevel@tonic-gate rc = ptree_get_propval_by_name(section, 521*7c478bd9Sstevel@tonic-gate PICL_PROP_CHILD, (void *)&seg_node, 522*7c478bd9Sstevel@tonic-gate sizeof (seg_node)); 523*7c478bd9Sstevel@tonic-gate 524*7c478bd9Sstevel@tonic-gate /* while there are more segments. */ 525*7c478bd9Sstevel@tonic-gate while (rc == PICL_SUCCESS) { 526*7c478bd9Sstevel@tonic-gate char name[FRU_SEGNAMELEN +1]; 527*7c478bd9Sstevel@tonic-gate 528*7c478bd9Sstevel@tonic-gate if ((rc = ptree_get_propval_by_name(seg_node, 529*7c478bd9Sstevel@tonic-gate PICL_PROP_NAME, name, 530*7c478bd9Sstevel@tonic-gate sizeof (name))) != PICL_SUCCESS) { 531*7c478bd9Sstevel@tonic-gate break; 532*7c478bd9Sstevel@tonic-gate } 533*7c478bd9Sstevel@tonic-gate 534*7c478bd9Sstevel@tonic-gate /* check array bounds */ 535*7c478bd9Sstevel@tonic-gate if (list->num >= total_space) { 536*7c478bd9Sstevel@tonic-gate /* PICL reported incorrect number of segs */ 537*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 538*7c478bd9Sstevel@tonic-gate } 539*7c478bd9Sstevel@tonic-gate list->strs[(list->num)++] = strdup(name); 540*7c478bd9Sstevel@tonic-gate 541*7c478bd9Sstevel@tonic-gate rc = ptree_get_propval_by_name(seg_node, 542*7c478bd9Sstevel@tonic-gate PICL_PROP_PEER, (void *)&seg_node, 543*7c478bd9Sstevel@tonic-gate sizeof (seg_node)); 544*7c478bd9Sstevel@tonic-gate } 545*7c478bd9Sstevel@tonic-gate 546*7c478bd9Sstevel@tonic-gate /* Peer property not found is ok */ 547*7c478bd9Sstevel@tonic-gate if (rc != PICL_PROPNOTFOUND) { 548*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 549*7c478bd9Sstevel@tonic-gate } 550*7c478bd9Sstevel@tonic-gate 551*7c478bd9Sstevel@tonic-gate } 552*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 553*7c478bd9Sstevel@tonic-gate } 554*7c478bd9Sstevel@tonic-gate 555*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 556*7c478bd9Sstevel@tonic-gate static fru_errno_t 557*7c478bd9Sstevel@tonic-gate fpt_get_seg_list(fru_treehdl_t handle, fru_strlist_t *list) 558*7c478bd9Sstevel@tonic-gate { 559*7c478bd9Sstevel@tonic-gate fru_errno_t err; 560*7c478bd9Sstevel@tonic-gate picl_nodehdl_t sect_node; 561*7c478bd9Sstevel@tonic-gate fru_strlist_t rc_list; 562*7c478bd9Sstevel@tonic-gate rc_list.num = 0; 563*7c478bd9Sstevel@tonic-gate rc_list.strs = NULL; 564*7c478bd9Sstevel@tonic-gate 565*7c478bd9Sstevel@tonic-gate if ((err = update_data_nodes(TREEHDL_TO_PICLHDL(handle))) 566*7c478bd9Sstevel@tonic-gate != FRU_SUCCESS) { 567*7c478bd9Sstevel@tonic-gate return (err); 568*7c478bd9Sstevel@tonic-gate } 569*7c478bd9Sstevel@tonic-gate 570*7c478bd9Sstevel@tonic-gate if ((err = find_first_section(TREEHDL_TO_PICLHDL(handle), §_node)) 571*7c478bd9Sstevel@tonic-gate != FRU_SUCCESS) { 572*7c478bd9Sstevel@tonic-gate return (err); 573*7c478bd9Sstevel@tonic-gate } 574*7c478bd9Sstevel@tonic-gate 575*7c478bd9Sstevel@tonic-gate /* while there are sections. */ 576*7c478bd9Sstevel@tonic-gate while (err == FRU_SUCCESS) { 577*7c478bd9Sstevel@tonic-gate if ((err = add_segs_for_section(sect_node, &rc_list)) 578*7c478bd9Sstevel@tonic-gate != FRU_SUCCESS) { 579*7c478bd9Sstevel@tonic-gate fru_destroy_strlist(&rc_list); 580*7c478bd9Sstevel@tonic-gate return (err); 581*7c478bd9Sstevel@tonic-gate } 582*7c478bd9Sstevel@tonic-gate err = find_next_section(sect_node, §_node); 583*7c478bd9Sstevel@tonic-gate } 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate list->num = rc_list.num; 586*7c478bd9Sstevel@tonic-gate list->strs = rc_list.strs; 587*7c478bd9Sstevel@tonic-gate 588*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 589*7c478bd9Sstevel@tonic-gate } 590*7c478bd9Sstevel@tonic-gate 591*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 592*7c478bd9Sstevel@tonic-gate static fru_errno_t 593*7c478bd9Sstevel@tonic-gate fpt_get_seg_def(fru_treehdl_t handle, const char *seg_name, fru_segdef_t *def) 594*7c478bd9Sstevel@tonic-gate { 595*7c478bd9Sstevel@tonic-gate fru_errno_t err = FRU_SUCCESS; 596*7c478bd9Sstevel@tonic-gate picl_nodehdl_t seg_node; 597*7c478bd9Sstevel@tonic-gate fru_seg_hwdesc_t hw_desc; 598*7c478bd9Sstevel@tonic-gate 599*7c478bd9Sstevel@tonic-gate fru_segdesc_t desc; 600*7c478bd9Sstevel@tonic-gate uint32_t size; 601*7c478bd9Sstevel@tonic-gate uint32_t address; 602*7c478bd9Sstevel@tonic-gate /* LINTED */ 603*7c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 604*7c478bd9Sstevel@tonic-gate 605*7c478bd9Sstevel@tonic-gate if ((err = get_segment_node(TREEHDL_TO_PICLHDL(handle), seg_name, 606*7c478bd9Sstevel@tonic-gate &seg_node, &hw_desc, IGN_CORRUPT_YES)) != FRU_SUCCESS) 607*7c478bd9Sstevel@tonic-gate return (err); 608*7c478bd9Sstevel@tonic-gate 609*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval_by_name(seg_node, 610*7c478bd9Sstevel@tonic-gate PICL_PROP_DESCRIPTOR, 611*7c478bd9Sstevel@tonic-gate &desc, sizeof (desc))) != PICL_SUCCESS) { 612*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 613*7c478bd9Sstevel@tonic-gate } 614*7c478bd9Sstevel@tonic-gate 615*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval_by_name(seg_node, 616*7c478bd9Sstevel@tonic-gate PICL_PROP_LENGTH, 617*7c478bd9Sstevel@tonic-gate &size, sizeof (size))) != PICL_SUCCESS) { 618*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 619*7c478bd9Sstevel@tonic-gate } 620*7c478bd9Sstevel@tonic-gate 621*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval_by_name(seg_node, 622*7c478bd9Sstevel@tonic-gate PICL_PROP_OFFSET, 623*7c478bd9Sstevel@tonic-gate &address, sizeof (address))) != PICL_SUCCESS) { 624*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 625*7c478bd9Sstevel@tonic-gate } 626*7c478bd9Sstevel@tonic-gate 627*7c478bd9Sstevel@tonic-gate def->version = LIBFRU_VERSION; 628*7c478bd9Sstevel@tonic-gate strlcpy(def->name, seg_name, FRU_SEGNAMELEN+1); 629*7c478bd9Sstevel@tonic-gate def->desc = desc; 630*7c478bd9Sstevel@tonic-gate def->size = size; 631*7c478bd9Sstevel@tonic-gate def->address = address; 632*7c478bd9Sstevel@tonic-gate def->hw_desc = hw_desc; 633*7c478bd9Sstevel@tonic-gate 634*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 635*7c478bd9Sstevel@tonic-gate } 636*7c478bd9Sstevel@tonic-gate 637*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 638*7c478bd9Sstevel@tonic-gate static fru_errno_t 639*7c478bd9Sstevel@tonic-gate fpt_add_seg(fru_treehdl_t handle, fru_segdef_t *def) 640*7c478bd9Sstevel@tonic-gate { 641*7c478bd9Sstevel@tonic-gate fru_errno_t err = FRU_SUCCESS; 642*7c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 643*7c478bd9Sstevel@tonic-gate picl_nodehdl_t section; 644*7c478bd9Sstevel@tonic-gate 645*7c478bd9Sstevel@tonic-gate /* 646*7c478bd9Sstevel@tonic-gate * for every section which has a ADD_SEGMENT_PROP try and add the segment 647*7c478bd9Sstevel@tonic-gate */ 648*7c478bd9Sstevel@tonic-gate if ((err = find_first_section(TREEHDL_TO_PICLHDL(handle), §ion)) 649*7c478bd9Sstevel@tonic-gate != FRU_SUCCESS) { 650*7c478bd9Sstevel@tonic-gate return (err); 651*7c478bd9Sstevel@tonic-gate } 652*7c478bd9Sstevel@tonic-gate do { 653*7c478bd9Sstevel@tonic-gate fru_segdef_t dummy; 654*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval_by_name(section, 655*7c478bd9Sstevel@tonic-gate PICL_PROP_ADD_SEGMENT, &dummy, sizeof (dummy))) 656*7c478bd9Sstevel@tonic-gate == PICL_SUCCESS) { 657*7c478bd9Sstevel@tonic-gate 658*7c478bd9Sstevel@tonic-gate picl_err = ptree_update_propval_by_name(section, 659*7c478bd9Sstevel@tonic-gate PICL_PROP_ADD_SEGMENT, def, sizeof (*def)); 660*7c478bd9Sstevel@tonic-gate 661*7c478bd9Sstevel@tonic-gate return (map_plugin_err(picl_err)); 662*7c478bd9Sstevel@tonic-gate } 663*7c478bd9Sstevel@tonic-gate } while (find_next_section(section, §ion) == FRU_SUCCESS); 664*7c478bd9Sstevel@tonic-gate 665*7c478bd9Sstevel@tonic-gate return (map_plugin_err(picl_err)); 666*7c478bd9Sstevel@tonic-gate } 667*7c478bd9Sstevel@tonic-gate 668*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 669*7c478bd9Sstevel@tonic-gate static fru_errno_t 670*7c478bd9Sstevel@tonic-gate fpt_delete_seg(fru_treehdl_t handle, const char *seg_name) 671*7c478bd9Sstevel@tonic-gate { 672*7c478bd9Sstevel@tonic-gate picl_nodehdl_t seg_hdl; 673*7c478bd9Sstevel@tonic-gate fru_seg_hwdesc_t hw_desc; 674*7c478bd9Sstevel@tonic-gate fru_errno_t err; 675*7c478bd9Sstevel@tonic-gate 676*7c478bd9Sstevel@tonic-gate int dead_flag = FRUDATA_DELETE_TAG_KEY; 677*7c478bd9Sstevel@tonic-gate int rc = PICL_SUCCESS; 678*7c478bd9Sstevel@tonic-gate 679*7c478bd9Sstevel@tonic-gate if ((err = get_segment_node(TREEHDL_TO_PICLHDL(handle), seg_name, 680*7c478bd9Sstevel@tonic-gate &seg_hdl, &hw_desc, IGN_CORRUPT_YES)) != FRU_SUCCESS) { 681*7c478bd9Sstevel@tonic-gate return (err); 682*7c478bd9Sstevel@tonic-gate } 683*7c478bd9Sstevel@tonic-gate 684*7c478bd9Sstevel@tonic-gate rc = ptree_update_propval_by_name(seg_hdl, PICL_PROP_DELETE_SEGMENT, 685*7c478bd9Sstevel@tonic-gate &dead_flag, sizeof (dead_flag)); 686*7c478bd9Sstevel@tonic-gate return (map_plugin_err(rc)); 687*7c478bd9Sstevel@tonic-gate } 688*7c478bd9Sstevel@tonic-gate 689*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 690*7c478bd9Sstevel@tonic-gate static fru_errno_t 691*7c478bd9Sstevel@tonic-gate fpt_add_tag_to_seg(fru_treehdl_t handle, const char *seg_name, 692*7c478bd9Sstevel@tonic-gate fru_tag_t tag, uint8_t *data, size_t data_len) 693*7c478bd9Sstevel@tonic-gate { 694*7c478bd9Sstevel@tonic-gate fru_errno_t err = FRU_SUCCESS; 695*7c478bd9Sstevel@tonic-gate picl_nodehdl_t segHdl; 696*7c478bd9Sstevel@tonic-gate fru_seg_hwdesc_t hw_desc; 697*7c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 698*7c478bd9Sstevel@tonic-gate size_t buf_size = 0; 699*7c478bd9Sstevel@tonic-gate uint8_t *buffer = NULL; 700*7c478bd9Sstevel@tonic-gate picl_prophdl_t add_prop; 701*7c478bd9Sstevel@tonic-gate ptree_propinfo_t add_prop_info; 702*7c478bd9Sstevel@tonic-gate 703*7c478bd9Sstevel@tonic-gate if ((err = get_segment_node(TREEHDL_TO_PICLHDL(handle), seg_name, 704*7c478bd9Sstevel@tonic-gate &segHdl, &hw_desc, IGN_CORRUPT_NO)) != FRU_SUCCESS) { 705*7c478bd9Sstevel@tonic-gate return (err); 706*7c478bd9Sstevel@tonic-gate } 707*7c478bd9Sstevel@tonic-gate 708*7c478bd9Sstevel@tonic-gate /* get the length of the buffer required. */ 709*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_prop_by_name(segHdl, 710*7c478bd9Sstevel@tonic-gate PICL_PROP_ADD_PACKET, 711*7c478bd9Sstevel@tonic-gate &add_prop)) != PICL_SUCCESS) { 712*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 713*7c478bd9Sstevel@tonic-gate } 714*7c478bd9Sstevel@tonic-gate 715*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propinfo(add_prop, &add_prop_info)) 716*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 717*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 718*7c478bd9Sstevel@tonic-gate } 719*7c478bd9Sstevel@tonic-gate buf_size = add_prop_info.piclinfo.size; 720*7c478bd9Sstevel@tonic-gate 721*7c478bd9Sstevel@tonic-gate if (data_len >= (buf_size - get_tag_size(get_tag_type(&tag)))) { 722*7c478bd9Sstevel@tonic-gate return (FRU_NOSPACE); 723*7c478bd9Sstevel@tonic-gate } 724*7c478bd9Sstevel@tonic-gate 725*7c478bd9Sstevel@tonic-gate buffer = malloc(buf_size); 726*7c478bd9Sstevel@tonic-gate if (buffer == NULL) { 727*7c478bd9Sstevel@tonic-gate return (FRU_FAILURE); 728*7c478bd9Sstevel@tonic-gate } 729*7c478bd9Sstevel@tonic-gate /* write the tag and data into the buffer */ 730*7c478bd9Sstevel@tonic-gate memcpy(buffer, &tag, get_tag_size(get_tag_type(&tag))); 731*7c478bd9Sstevel@tonic-gate memcpy((void *)(buffer+get_tag_size(get_tag_type(&tag))), 732*7c478bd9Sstevel@tonic-gate data, data_len); 733*7c478bd9Sstevel@tonic-gate 734*7c478bd9Sstevel@tonic-gate picl_err = ptree_update_propval(add_prop, buffer, buf_size); 735*7c478bd9Sstevel@tonic-gate free(buffer); 736*7c478bd9Sstevel@tonic-gate return (map_plugin_err(picl_err)); 737*7c478bd9Sstevel@tonic-gate } 738*7c478bd9Sstevel@tonic-gate 739*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 740*7c478bd9Sstevel@tonic-gate static fru_errno_t 741*7c478bd9Sstevel@tonic-gate fpt_get_tag_list(fru_treehdl_t handle, const char *seg_name, 742*7c478bd9Sstevel@tonic-gate fru_tag_t **tags, int *number) 743*7c478bd9Sstevel@tonic-gate { 744*7c478bd9Sstevel@tonic-gate picl_nodehdl_t seg_node; 745*7c478bd9Sstevel@tonic-gate fru_seg_hwdesc_t hw_desc; 746*7c478bd9Sstevel@tonic-gate fru_errno_t err = FRU_SUCCESS; 747*7c478bd9Sstevel@tonic-gate picl_prophdl_t tagTable; 748*7c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 749*7c478bd9Sstevel@tonic-gate unsigned int total_tags = 0; 750*7c478bd9Sstevel@tonic-gate 751*7c478bd9Sstevel@tonic-gate /* return variables */ 752*7c478bd9Sstevel@tonic-gate fru_tag_t *rc_tags = NULL; 753*7c478bd9Sstevel@tonic-gate unsigned int rc_num = 0; 754*7c478bd9Sstevel@tonic-gate 755*7c478bd9Sstevel@tonic-gate if ((err = get_segment_node(TREEHDL_TO_PICLHDL(handle), seg_name, 756*7c478bd9Sstevel@tonic-gate &seg_node, &hw_desc, IGN_CORRUPT_NO)) != FRU_SUCCESS) { 757*7c478bd9Sstevel@tonic-gate return (err); 758*7c478bd9Sstevel@tonic-gate } 759*7c478bd9Sstevel@tonic-gate 760*7c478bd9Sstevel@tonic-gate /* get the number of tags and allocate array for them */ 761*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval_by_name(seg_node, 762*7c478bd9Sstevel@tonic-gate PICL_PROP_NUM_TAGS, 763*7c478bd9Sstevel@tonic-gate (void *)&total_tags, 764*7c478bd9Sstevel@tonic-gate sizeof (total_tags))) != PICL_SUCCESS) { 765*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 766*7c478bd9Sstevel@tonic-gate } 767*7c478bd9Sstevel@tonic-gate 768*7c478bd9Sstevel@tonic-gate if (total_tags == 0) { 769*7c478bd9Sstevel@tonic-gate *tags = rc_tags; 770*7c478bd9Sstevel@tonic-gate *number = rc_num; 771*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 772*7c478bd9Sstevel@tonic-gate } 773*7c478bd9Sstevel@tonic-gate 774*7c478bd9Sstevel@tonic-gate rc_tags = malloc((sizeof (*rc_tags) * total_tags)); 775*7c478bd9Sstevel@tonic-gate if (rc_tags == NULL) { 776*7c478bd9Sstevel@tonic-gate return (FRU_FAILURE); 777*7c478bd9Sstevel@tonic-gate } 778*7c478bd9Sstevel@tonic-gate 779*7c478bd9Sstevel@tonic-gate /* go through the tagTable and fill in the array */ 780*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval_by_name(seg_node, 781*7c478bd9Sstevel@tonic-gate PICL_PROP_PACKET_TABLE, 782*7c478bd9Sstevel@tonic-gate &tagTable, sizeof (tagTable))) != PICL_SUCCESS) { 783*7c478bd9Sstevel@tonic-gate free(rc_tags); 784*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 785*7c478bd9Sstevel@tonic-gate } 786*7c478bd9Sstevel@tonic-gate picl_err = ptree_get_next_by_col(tagTable, &tagTable); 787*7c478bd9Sstevel@tonic-gate while (picl_err == PICL_SUCCESS) { 788*7c478bd9Sstevel@tonic-gate /* check array bounds */ 789*7c478bd9Sstevel@tonic-gate if (rc_num >= total_tags) { 790*7c478bd9Sstevel@tonic-gate free(rc_tags); 791*7c478bd9Sstevel@tonic-gate return (FRU_FAILURE); 792*7c478bd9Sstevel@tonic-gate } 793*7c478bd9Sstevel@tonic-gate /* fill in the array */ 794*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval(tagTable, 795*7c478bd9Sstevel@tonic-gate (void *)&(rc_tags[rc_num++]), 796*7c478bd9Sstevel@tonic-gate sizeof (fru_tag_t))) != PICL_SUCCESS) { 797*7c478bd9Sstevel@tonic-gate free(rc_tags); 798*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 799*7c478bd9Sstevel@tonic-gate } 800*7c478bd9Sstevel@tonic-gate /* get the next tag */ 801*7c478bd9Sstevel@tonic-gate picl_err = ptree_get_next_by_col(tagTable, &tagTable); 802*7c478bd9Sstevel@tonic-gate } 803*7c478bd9Sstevel@tonic-gate 804*7c478bd9Sstevel@tonic-gate if (picl_err == PICL_ENDOFLIST) { 805*7c478bd9Sstevel@tonic-gate *tags = rc_tags; 806*7c478bd9Sstevel@tonic-gate *number = rc_num; 807*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 808*7c478bd9Sstevel@tonic-gate } 809*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 810*7c478bd9Sstevel@tonic-gate } 811*7c478bd9Sstevel@tonic-gate 812*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 813*7c478bd9Sstevel@tonic-gate /* 814*7c478bd9Sstevel@tonic-gate * From the handle, segment name, tag, and instance of the tag get me: 815*7c478bd9Sstevel@tonic-gate * segHdl: The segment handle for this segment. 816*7c478bd9Sstevel@tonic-gate * tagHdl: tag property handle in the tag table for this instance "tag" 817*7c478bd9Sstevel@tonic-gate */ 818*7c478bd9Sstevel@tonic-gate static fru_errno_t 819*7c478bd9Sstevel@tonic-gate get_tag_handle(picl_nodehdl_t handle, const char *segment, 820*7c478bd9Sstevel@tonic-gate fru_tag_t tag, int instance, 821*7c478bd9Sstevel@tonic-gate picl_nodehdl_t *segHdl, 822*7c478bd9Sstevel@tonic-gate picl_prophdl_t *tagHdl) 823*7c478bd9Sstevel@tonic-gate { 824*7c478bd9Sstevel@tonic-gate fru_seg_hwdesc_t hw_desc; 825*7c478bd9Sstevel@tonic-gate fru_errno_t err; 826*7c478bd9Sstevel@tonic-gate picl_prophdl_t tagTable = 0; 827*7c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 828*7c478bd9Sstevel@tonic-gate picl_nodehdl_t tmp_seg; 829*7c478bd9Sstevel@tonic-gate 830*7c478bd9Sstevel@tonic-gate fru_tag_t foundTag; 831*7c478bd9Sstevel@tonic-gate 832*7c478bd9Sstevel@tonic-gate if ((err = get_segment_node(TREEHDL_TO_PICLHDL(handle), segment, 833*7c478bd9Sstevel@tonic-gate &tmp_seg, &hw_desc, IGN_CORRUPT_NO)) != FRU_SUCCESS) { 834*7c478bd9Sstevel@tonic-gate return (err); 835*7c478bd9Sstevel@tonic-gate } 836*7c478bd9Sstevel@tonic-gate 837*7c478bd9Sstevel@tonic-gate foundTag.raw_data = 0; 838*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval_by_name(tmp_seg, 839*7c478bd9Sstevel@tonic-gate PICL_PROP_PACKET_TABLE, 840*7c478bd9Sstevel@tonic-gate &tagTable, sizeof (tagTable))) != PICL_SUCCESS) { 841*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 842*7c478bd9Sstevel@tonic-gate } 843*7c478bd9Sstevel@tonic-gate 844*7c478bd9Sstevel@tonic-gate picl_err = ptree_get_next_by_col(tagTable, &tagTable); 845*7c478bd9Sstevel@tonic-gate while ((picl_err != PICL_ENDOFLIST) && 846*7c478bd9Sstevel@tonic-gate (picl_err == PICL_SUCCESS)) { 847*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval(tagTable, (void *)&foundTag, 848*7c478bd9Sstevel@tonic-gate sizeof (foundTag))) != PICL_SUCCESS) { 849*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 850*7c478bd9Sstevel@tonic-gate } 851*7c478bd9Sstevel@tonic-gate if ((tags_equal(tag, foundTag) == 1) && (instance-- == 0)) { 852*7c478bd9Sstevel@tonic-gate *segHdl = tmp_seg; 853*7c478bd9Sstevel@tonic-gate *tagHdl = tagTable; 854*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 855*7c478bd9Sstevel@tonic-gate } 856*7c478bd9Sstevel@tonic-gate picl_err = ptree_get_next_by_col(tagTable, &tagTable); 857*7c478bd9Sstevel@tonic-gate } 858*7c478bd9Sstevel@tonic-gate 859*7c478bd9Sstevel@tonic-gate if (picl_err == PICL_ENDOFLIST) 860*7c478bd9Sstevel@tonic-gate return (FRU_DATANOTFOUND); 861*7c478bd9Sstevel@tonic-gate 862*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 863*7c478bd9Sstevel@tonic-gate } 864*7c478bd9Sstevel@tonic-gate 865*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 866*7c478bd9Sstevel@tonic-gate static fru_errno_t 867*7c478bd9Sstevel@tonic-gate fpt_get_tag_data(fru_treehdl_t handle, const char *seg_name, 868*7c478bd9Sstevel@tonic-gate fru_tag_t tag, int instance, 869*7c478bd9Sstevel@tonic-gate uint8_t **data, size_t *data_len) 870*7c478bd9Sstevel@tonic-gate { 871*7c478bd9Sstevel@tonic-gate fru_errno_t err = FRU_SUCCESS; 872*7c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 873*7c478bd9Sstevel@tonic-gate uint8_t *buffer; 874*7c478bd9Sstevel@tonic-gate int buf_len = 0; 875*7c478bd9Sstevel@tonic-gate 876*7c478bd9Sstevel@tonic-gate picl_nodehdl_t seg; 877*7c478bd9Sstevel@tonic-gate picl_prophdl_t tagHdl; 878*7c478bd9Sstevel@tonic-gate 879*7c478bd9Sstevel@tonic-gate if ((err = get_tag_handle(TREEHDL_TO_PICLHDL(handle), seg_name, 880*7c478bd9Sstevel@tonic-gate tag, instance, &seg, &tagHdl)) != FRU_SUCCESS) { 881*7c478bd9Sstevel@tonic-gate return (err); 882*7c478bd9Sstevel@tonic-gate } 883*7c478bd9Sstevel@tonic-gate 884*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_next_by_row(tagHdl, &tagHdl)) 885*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 886*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 887*7c478bd9Sstevel@tonic-gate } 888*7c478bd9Sstevel@tonic-gate 889*7c478bd9Sstevel@tonic-gate buf_len = get_payload_length(&tag); 890*7c478bd9Sstevel@tonic-gate buffer = malloc(buf_len); 891*7c478bd9Sstevel@tonic-gate if (buffer == NULL) { 892*7c478bd9Sstevel@tonic-gate return (FRU_FAILURE); 893*7c478bd9Sstevel@tonic-gate } 894*7c478bd9Sstevel@tonic-gate 895*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_propval(tagHdl, buffer, buf_len)) 896*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 897*7c478bd9Sstevel@tonic-gate free(buffer); 898*7c478bd9Sstevel@tonic-gate return (map_plugin_err(picl_err)); 899*7c478bd9Sstevel@tonic-gate } 900*7c478bd9Sstevel@tonic-gate 901*7c478bd9Sstevel@tonic-gate *data = buffer; 902*7c478bd9Sstevel@tonic-gate *data_len = buf_len; 903*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 904*7c478bd9Sstevel@tonic-gate } 905*7c478bd9Sstevel@tonic-gate 906*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 907*7c478bd9Sstevel@tonic-gate static fru_errno_t 908*7c478bd9Sstevel@tonic-gate fpt_set_tag_data(fru_treehdl_t handle, const char *seg_name, 909*7c478bd9Sstevel@tonic-gate fru_tag_t tag, int instance, 910*7c478bd9Sstevel@tonic-gate uint8_t *data, size_t data_len) 911*7c478bd9Sstevel@tonic-gate { 912*7c478bd9Sstevel@tonic-gate fru_errno_t rc = FRU_SUCCESS; 913*7c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 914*7c478bd9Sstevel@tonic-gate 915*7c478bd9Sstevel@tonic-gate picl_nodehdl_t seg; 916*7c478bd9Sstevel@tonic-gate picl_prophdl_t tagHdl; 917*7c478bd9Sstevel@tonic-gate 918*7c478bd9Sstevel@tonic-gate if ((rc = get_tag_handle(TREEHDL_TO_PICLHDL(handle), seg_name, 919*7c478bd9Sstevel@tonic-gate tag, instance, &seg, &tagHdl)) != FRU_SUCCESS) { 920*7c478bd9Sstevel@tonic-gate return (rc); 921*7c478bd9Sstevel@tonic-gate } 922*7c478bd9Sstevel@tonic-gate 923*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_get_next_by_row(tagHdl, &tagHdl)) 924*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 925*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 926*7c478bd9Sstevel@tonic-gate } 927*7c478bd9Sstevel@tonic-gate 928*7c478bd9Sstevel@tonic-gate if ((picl_err = ptree_update_propval(tagHdl, data, data_len)) 929*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 930*7c478bd9Sstevel@tonic-gate return (map_plugin_err(picl_err)); 931*7c478bd9Sstevel@tonic-gate } 932*7c478bd9Sstevel@tonic-gate 933*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 934*7c478bd9Sstevel@tonic-gate } 935*7c478bd9Sstevel@tonic-gate 936*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 937*7c478bd9Sstevel@tonic-gate static fru_errno_t 938*7c478bd9Sstevel@tonic-gate fpt_delete_tag(fru_treehdl_t handle, const char *seg_name, fru_tag_t tag, 939*7c478bd9Sstevel@tonic-gate int instance) 940*7c478bd9Sstevel@tonic-gate { 941*7c478bd9Sstevel@tonic-gate fru_errno_t rc = FRU_SUCCESS; 942*7c478bd9Sstevel@tonic-gate int picl_err = PICL_SUCCESS; 943*7c478bd9Sstevel@tonic-gate 944*7c478bd9Sstevel@tonic-gate picl_nodehdl_t segHdl; 945*7c478bd9Sstevel@tonic-gate picl_prophdl_t tagHdl; 946*7c478bd9Sstevel@tonic-gate 947*7c478bd9Sstevel@tonic-gate /* get tag handle */ 948*7c478bd9Sstevel@tonic-gate if ((rc = get_tag_handle(TREEHDL_TO_PICLHDL(handle), seg_name, 949*7c478bd9Sstevel@tonic-gate tag, instance, &segHdl, &tagHdl)) != FRU_SUCCESS) { 950*7c478bd9Sstevel@tonic-gate return (rc); 951*7c478bd9Sstevel@tonic-gate } 952*7c478bd9Sstevel@tonic-gate 953*7c478bd9Sstevel@tonic-gate /* set up key */ 954*7c478bd9Sstevel@tonic-gate tag.raw_data &= FRUDATA_DELETE_TAG_MASK; 955*7c478bd9Sstevel@tonic-gate tag.raw_data |= FRUDATA_DELETE_TAG_KEY; 956*7c478bd9Sstevel@tonic-gate 957*7c478bd9Sstevel@tonic-gate /* Write back */ 958*7c478bd9Sstevel@tonic-gate picl_err = ptree_update_propval(tagHdl, (void *)&(tag.raw_data), 959*7c478bd9Sstevel@tonic-gate sizeof (tag.raw_data)); 960*7c478bd9Sstevel@tonic-gate return (map_plugin_err(picl_err)); 961*7c478bd9Sstevel@tonic-gate } 962*7c478bd9Sstevel@tonic-gate 963*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 964*7c478bd9Sstevel@tonic-gate static fru_errno_t 965*7c478bd9Sstevel@tonic-gate fpt_for_each_segment(fru_treehdl_t treenode, 966*7c478bd9Sstevel@tonic-gate int (*function)(fru_treeseghdl_t segment, void *args), 967*7c478bd9Sstevel@tonic-gate void *args) 968*7c478bd9Sstevel@tonic-gate { 969*7c478bd9Sstevel@tonic-gate int num_segments = 0, status; 970*7c478bd9Sstevel@tonic-gate 971*7c478bd9Sstevel@tonic-gate fru_errno_t saved_status = FRU_SUCCESS; 972*7c478bd9Sstevel@tonic-gate 973*7c478bd9Sstevel@tonic-gate picl_nodehdl_t container = TREEHDL_TO_PICLHDL(treenode), 974*7c478bd9Sstevel@tonic-gate section, segment; 975*7c478bd9Sstevel@tonic-gate 976*7c478bd9Sstevel@tonic-gate 977*7c478bd9Sstevel@tonic-gate if ((status = update_data_nodes(container)) != FRU_SUCCESS) 978*7c478bd9Sstevel@tonic-gate return (status); 979*7c478bd9Sstevel@tonic-gate 980*7c478bd9Sstevel@tonic-gate /* process each section */ 981*7c478bd9Sstevel@tonic-gate for (status = ptree_get_propval_by_name(container, PICL_PROP_CHILD, 982*7c478bd9Sstevel@tonic-gate §ion, sizeof (section)); 983*7c478bd9Sstevel@tonic-gate status == PICL_SUCCESS; 984*7c478bd9Sstevel@tonic-gate status = ptree_get_propval_by_name(section, PICL_PROP_PEER, 985*7c478bd9Sstevel@tonic-gate §ion, 986*7c478bd9Sstevel@tonic-gate sizeof (section))) { 987*7c478bd9Sstevel@tonic-gate 988*7c478bd9Sstevel@tonic-gate if (cmp_class_name(section, PICL_CLASS_SECTION) != FRU_SUCCESS) 989*7c478bd9Sstevel@tonic-gate continue; 990*7c478bd9Sstevel@tonic-gate 991*7c478bd9Sstevel@tonic-gate if ((status = ptree_get_propval_by_name(section, 992*7c478bd9Sstevel@tonic-gate PICL_PROP_NUM_SEGMENTS, 993*7c478bd9Sstevel@tonic-gate &num_segments, 994*7c478bd9Sstevel@tonic-gate sizeof (num_segments))) 995*7c478bd9Sstevel@tonic-gate == PICL_PROPNOTFOUND) { 996*7c478bd9Sstevel@tonic-gate continue; 997*7c478bd9Sstevel@tonic-gate } else if (status != PICL_SUCCESS) { 998*7c478bd9Sstevel@tonic-gate saved_status = map_plugin_err(status); 999*7c478bd9Sstevel@tonic-gate continue; 1000*7c478bd9Sstevel@tonic-gate } else if (num_segments == 0) { 1001*7c478bd9Sstevel@tonic-gate continue; 1002*7c478bd9Sstevel@tonic-gate } 1003*7c478bd9Sstevel@tonic-gate 1004*7c478bd9Sstevel@tonic-gate /* process each segment */ 1005*7c478bd9Sstevel@tonic-gate for (status = ptree_get_propval_by_name(section, 1006*7c478bd9Sstevel@tonic-gate PICL_PROP_CHILD, 1007*7c478bd9Sstevel@tonic-gate &segment, 1008*7c478bd9Sstevel@tonic-gate sizeof (segment)); 1009*7c478bd9Sstevel@tonic-gate status == PICL_SUCCESS; 1010*7c478bd9Sstevel@tonic-gate status = ptree_get_propval_by_name(segment, 1011*7c478bd9Sstevel@tonic-gate PICL_PROP_PEER, 1012*7c478bd9Sstevel@tonic-gate &segment, 1013*7c478bd9Sstevel@tonic-gate sizeof (segment))) { 1014*7c478bd9Sstevel@tonic-gate 1015*7c478bd9Sstevel@tonic-gate if (cmp_class_name(segment, PICL_CLASS_SEGMENT) 1016*7c478bd9Sstevel@tonic-gate != FRU_SUCCESS) continue; 1017*7c478bd9Sstevel@tonic-gate 1018*7c478bd9Sstevel@tonic-gate if ((status = function(PICLHDL_TO_TREESEGHDL(segment), 1019*7c478bd9Sstevel@tonic-gate args)) 1020*7c478bd9Sstevel@tonic-gate != FRU_SUCCESS) return (status); 1021*7c478bd9Sstevel@tonic-gate } 1022*7c478bd9Sstevel@tonic-gate 1023*7c478bd9Sstevel@tonic-gate if (status != PICL_PROPNOTFOUND) 1024*7c478bd9Sstevel@tonic-gate saved_status = map_plugin_err(status); 1025*7c478bd9Sstevel@tonic-gate } 1026*7c478bd9Sstevel@tonic-gate 1027*7c478bd9Sstevel@tonic-gate if (status != PICL_PROPNOTFOUND) 1028*7c478bd9Sstevel@tonic-gate saved_status = map_plugin_err(status); 1029*7c478bd9Sstevel@tonic-gate 1030*7c478bd9Sstevel@tonic-gate return (saved_status); 1031*7c478bd9Sstevel@tonic-gate } 1032*7c478bd9Sstevel@tonic-gate 1033*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 1034*7c478bd9Sstevel@tonic-gate static fru_errno_t 1035*7c478bd9Sstevel@tonic-gate fpt_get_segment_name(fru_treeseghdl_t segment, char **name) 1036*7c478bd9Sstevel@tonic-gate { 1037*7c478bd9Sstevel@tonic-gate char *propval; 1038*7c478bd9Sstevel@tonic-gate 1039*7c478bd9Sstevel@tonic-gate int status; 1040*7c478bd9Sstevel@tonic-gate 1041*7c478bd9Sstevel@tonic-gate picl_prophdl_t proph = 0; 1042*7c478bd9Sstevel@tonic-gate 1043*7c478bd9Sstevel@tonic-gate ptree_propinfo_t propinfo; 1044*7c478bd9Sstevel@tonic-gate 1045*7c478bd9Sstevel@tonic-gate 1046*7c478bd9Sstevel@tonic-gate if (ptree_get_prop_by_name(TREESEGHDL_TO_PICLHDL(segment), 1047*7c478bd9Sstevel@tonic-gate PICL_PROP_NAME, &proph) 1048*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) 1049*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 1050*7c478bd9Sstevel@tonic-gate 1051*7c478bd9Sstevel@tonic-gate if (ptree_get_propinfo(proph, &propinfo) != PICL_SUCCESS) 1052*7c478bd9Sstevel@tonic-gate return (FRU_IOERROR); 1053*7c478bd9Sstevel@tonic-gate 1054*7c478bd9Sstevel@tonic-gate if (propinfo.piclinfo.size == 0) 1055*7c478bd9Sstevel@tonic-gate return (FRU_INVALDATASIZE); 1056*7c478bd9Sstevel@tonic-gate 1057*7c478bd9Sstevel@tonic-gate if ((propval = malloc(propinfo.piclinfo.size)) == NULL) 1058*7c478bd9Sstevel@tonic-gate return (FRU_NOSPACE); 1059*7c478bd9Sstevel@tonic-gate 1060*7c478bd9Sstevel@tonic-gate if ((status = ptree_get_propval(proph, propval, propinfo.piclinfo.size)) 1061*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 1062*7c478bd9Sstevel@tonic-gate free(propval); 1063*7c478bd9Sstevel@tonic-gate return (map_plugin_err(status)); 1064*7c478bd9Sstevel@tonic-gate } 1065*7c478bd9Sstevel@tonic-gate 1066*7c478bd9Sstevel@tonic-gate *name = propval; 1067*7c478bd9Sstevel@tonic-gate 1068*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 1069*7c478bd9Sstevel@tonic-gate } 1070*7c478bd9Sstevel@tonic-gate 1071*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 1072*7c478bd9Sstevel@tonic-gate static fru_errno_t 1073*7c478bd9Sstevel@tonic-gate fpt_for_each_packet(fru_treeseghdl_t treesegment, 1074*7c478bd9Sstevel@tonic-gate int (*function)(fru_tag_t *tag, uint8_t *payload, 1075*7c478bd9Sstevel@tonic-gate size_t length, 1076*7c478bd9Sstevel@tonic-gate void *args), 1077*7c478bd9Sstevel@tonic-gate void *args) 1078*7c478bd9Sstevel@tonic-gate { 1079*7c478bd9Sstevel@tonic-gate int status; 1080*7c478bd9Sstevel@tonic-gate 1081*7c478bd9Sstevel@tonic-gate uint8_t *payload; 1082*7c478bd9Sstevel@tonic-gate 1083*7c478bd9Sstevel@tonic-gate picl_nodehdl_t segment = TREESEGHDL_TO_PICLHDL(treesegment); 1084*7c478bd9Sstevel@tonic-gate 1085*7c478bd9Sstevel@tonic-gate picl_prophdl_t packet, payloadh = 0; 1086*7c478bd9Sstevel@tonic-gate 1087*7c478bd9Sstevel@tonic-gate ptree_propinfo_t propinfo; 1088*7c478bd9Sstevel@tonic-gate 1089*7c478bd9Sstevel@tonic-gate fru_segdesc_t descriptor; 1090*7c478bd9Sstevel@tonic-gate 1091*7c478bd9Sstevel@tonic-gate fru_tag_t tag; 1092*7c478bd9Sstevel@tonic-gate 1093*7c478bd9Sstevel@tonic-gate 1094*7c478bd9Sstevel@tonic-gate if ((status = ptree_get_propval_by_name(segment, PICL_PROP_DESCRIPTOR, 1095*7c478bd9Sstevel@tonic-gate &descriptor, 1096*7c478bd9Sstevel@tonic-gate sizeof (descriptor))) 1097*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) return (map_plugin_err(status)); 1098*7c478bd9Sstevel@tonic-gate 1099*7c478bd9Sstevel@tonic-gate if (descriptor.field.opaque) 1100*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 1101*7c478bd9Sstevel@tonic-gate 1102*7c478bd9Sstevel@tonic-gate if (descriptor.field.encrypted && (encrypt_func == NULL)) 1103*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 1104*7c478bd9Sstevel@tonic-gate 1105*7c478bd9Sstevel@tonic-gate if ((status = ptree_get_propval_by_name(segment, PICL_PROP_PACKET_TABLE, 1106*7c478bd9Sstevel@tonic-gate &packet, sizeof (packet))) 1107*7c478bd9Sstevel@tonic-gate == PICL_PROPNOTFOUND) 1108*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 1109*7c478bd9Sstevel@tonic-gate else if (status != PICL_SUCCESS) 1110*7c478bd9Sstevel@tonic-gate return (map_plugin_err(status)); 1111*7c478bd9Sstevel@tonic-gate 1112*7c478bd9Sstevel@tonic-gate while ((status = ptree_get_next_by_col(packet, &packet)) 1113*7c478bd9Sstevel@tonic-gate == PICL_SUCCESS) { 1114*7c478bd9Sstevel@tonic-gate if (((status = ptree_get_propval(packet, &tag, sizeof (tag))) 1115*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) || 1116*7c478bd9Sstevel@tonic-gate ((status = ptree_get_next_by_row(packet, &payloadh)) 1117*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) || 1118*7c478bd9Sstevel@tonic-gate ((status = ptree_get_propinfo(payloadh, &propinfo)) 1119*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS)) 1120*7c478bd9Sstevel@tonic-gate return (map_plugin_err(status)); 1121*7c478bd9Sstevel@tonic-gate 1122*7c478bd9Sstevel@tonic-gate if (propinfo.piclinfo.size > 0) { 1123*7c478bd9Sstevel@tonic-gate payload = alloca(propinfo.piclinfo.size); 1124*7c478bd9Sstevel@tonic-gate if ((status = ptree_get_propval(payloadh, payload, 1125*7c478bd9Sstevel@tonic-gate propinfo.piclinfo.size)) 1126*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) return (map_plugin_err(status)); 1127*7c478bd9Sstevel@tonic-gate } else { 1128*7c478bd9Sstevel@tonic-gate payload = NULL; 1129*7c478bd9Sstevel@tonic-gate } 1130*7c478bd9Sstevel@tonic-gate 1131*7c478bd9Sstevel@tonic-gate if ((descriptor.field.encrypted) && 1132*7c478bd9Sstevel@tonic-gate ((status = encrypt_func(FRU_DECRYPT, payload, 1133*7c478bd9Sstevel@tonic-gate propinfo.piclinfo.size)) 1134*7c478bd9Sstevel@tonic-gate != FRU_SUCCESS)) return status; 1135*7c478bd9Sstevel@tonic-gate 1136*7c478bd9Sstevel@tonic-gate if ((status = function(&tag, payload, propinfo.piclinfo.size, 1137*7c478bd9Sstevel@tonic-gate args)) 1138*7c478bd9Sstevel@tonic-gate != FRU_SUCCESS) return (status); 1139*7c478bd9Sstevel@tonic-gate } 1140*7c478bd9Sstevel@tonic-gate 1141*7c478bd9Sstevel@tonic-gate if (status == PICL_ENDOFLIST) 1142*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 1143*7c478bd9Sstevel@tonic-gate else 1144*7c478bd9Sstevel@tonic-gate return (map_plugin_err(status)); 1145*7c478bd9Sstevel@tonic-gate } 1146*7c478bd9Sstevel@tonic-gate 1147*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 1148*7c478bd9Sstevel@tonic-gate /* ARGSUSED0 */ 1149*7c478bd9Sstevel@tonic-gate static fru_errno_t 1150*7c478bd9Sstevel@tonic-gate initialize(int argc, char **argv) 1151*7c478bd9Sstevel@tonic-gate { 1152*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 1153*7c478bd9Sstevel@tonic-gate } 1154*7c478bd9Sstevel@tonic-gate 1155*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 1156*7c478bd9Sstevel@tonic-gate static fru_errno_t 1157*7c478bd9Sstevel@tonic-gate shutdown(void) 1158*7c478bd9Sstevel@tonic-gate { 1159*7c478bd9Sstevel@tonic-gate return (FRU_SUCCESS); 1160*7c478bd9Sstevel@tonic-gate } 1161*7c478bd9Sstevel@tonic-gate 1162*7c478bd9Sstevel@tonic-gate /* ========================================================================= */ 1163*7c478bd9Sstevel@tonic-gate /* object for libfru to link to */ 1164*7c478bd9Sstevel@tonic-gate fru_datasource_t data_source = 1165*7c478bd9Sstevel@tonic-gate { 1166*7c478bd9Sstevel@tonic-gate LIBFRU_DS_VER, 1167*7c478bd9Sstevel@tonic-gate initialize, 1168*7c478bd9Sstevel@tonic-gate shutdown, 1169*7c478bd9Sstevel@tonic-gate fpt_get_root, 1170*7c478bd9Sstevel@tonic-gate fpt_get_child, 1171*7c478bd9Sstevel@tonic-gate fpt_get_peer, 1172*7c478bd9Sstevel@tonic-gate fpt_get_parent, 1173*7c478bd9Sstevel@tonic-gate fpt_get_name_from_hdl, 1174*7c478bd9Sstevel@tonic-gate fpt_get_node_type, 1175*7c478bd9Sstevel@tonic-gate fpt_get_seg_list, 1176*7c478bd9Sstevel@tonic-gate fpt_get_seg_def, 1177*7c478bd9Sstevel@tonic-gate fpt_add_seg, 1178*7c478bd9Sstevel@tonic-gate fpt_delete_seg, 1179*7c478bd9Sstevel@tonic-gate fpt_for_each_segment, 1180*7c478bd9Sstevel@tonic-gate fpt_get_segment_name, 1181*7c478bd9Sstevel@tonic-gate fpt_add_tag_to_seg, 1182*7c478bd9Sstevel@tonic-gate fpt_get_tag_list, 1183*7c478bd9Sstevel@tonic-gate fpt_get_tag_data, 1184*7c478bd9Sstevel@tonic-gate fpt_set_tag_data, 1185*7c478bd9Sstevel@tonic-gate fpt_delete_tag, 1186*7c478bd9Sstevel@tonic-gate fpt_for_each_packet 1187*7c478bd9Sstevel@tonic-gate }; 1188