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