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