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