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 2004 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 <picl.h> 30*7c478bd9Sstevel@tonic-gate #include <syslog.h> 31*7c478bd9Sstevel@tonic-gate #include <strings.h> 32*7c478bd9Sstevel@tonic-gate #include <alloca.h> 33*7c478bd9Sstevel@tonic-gate #include <pthread.h> 34*7c478bd9Sstevel@tonic-gate #include <synch.h> 35*7c478bd9Sstevel@tonic-gate #include <limits.h> 36*7c478bd9Sstevel@tonic-gate #include <ctype.h> 37*7c478bd9Sstevel@tonic-gate #include <unistd.h> 38*7c478bd9Sstevel@tonic-gate #include <picltree.h> 39*7c478bd9Sstevel@tonic-gate #include <signal.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/utsname.h> 41*7c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h> 42*7c478bd9Sstevel@tonic-gate #include <libnvpair.h> 43*7c478bd9Sstevel@tonic-gate #include "fru_tag.h" 44*7c478bd9Sstevel@tonic-gate #include "fru_data_impl.h" 45*7c478bd9Sstevel@tonic-gate #include "fru_data.h" 46*7c478bd9Sstevel@tonic-gate #include "picld_pluginutil.h" 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate #pragma init(frudata_plugin_register) /* .init section */ 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate static void frudata_plugin_init(void); 51*7c478bd9Sstevel@tonic-gate static void frudata_plugin_fini(void); 52*7c478bd9Sstevel@tonic-gate static container_tbl_t *container_table[TABLE_SIZE]; 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate /* 55*7c478bd9Sstevel@tonic-gate * Locking Stragtegy : 56*7c478bd9Sstevel@tonic-gate * calling thread should hold the cont_tbl_lock during the course 57*7c478bd9Sstevel@tonic-gate * of container table lookup. release the cont_tbl_lock on lookup 58*7c478bd9Sstevel@tonic-gate * failure or on the condition wait. 59*7c478bd9Sstevel@tonic-gate * 60*7c478bd9Sstevel@tonic-gate * thread holding the container object rwlock should release lock 61*7c478bd9Sstevel@tonic-gate * and signal to unblock threads blocked on the condition variable 62*7c478bd9Sstevel@tonic-gate * upon i/o completion. 63*7c478bd9Sstevel@tonic-gate * 64*7c478bd9Sstevel@tonic-gate */ 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate static pthread_mutex_t cont_tbl_lock = PTHREAD_MUTEX_INITIALIZER; 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate static int add_row_to_table(hash_obj_t *, picl_nodehdl_t, 69*7c478bd9Sstevel@tonic-gate packet_t *, container_tbl_t *); 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate static picld_plugin_reg_t frudata_reg_info = { 72*7c478bd9Sstevel@tonic-gate PICLD_PLUGIN_VERSION_1, 73*7c478bd9Sstevel@tonic-gate PICLD_PLUGIN_NON_CRITICAL, 74*7c478bd9Sstevel@tonic-gate "SUNW_piclfrudata", 75*7c478bd9Sstevel@tonic-gate frudata_plugin_init, /* init entry point */ 76*7c478bd9Sstevel@tonic-gate frudata_plugin_fini /* cleanup entry point */ 77*7c478bd9Sstevel@tonic-gate }; 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate /* initialization function */ 80*7c478bd9Sstevel@tonic-gate static void 81*7c478bd9Sstevel@tonic-gate frudata_plugin_register(void) 82*7c478bd9Sstevel@tonic-gate { 83*7c478bd9Sstevel@tonic-gate /* register plugin with daemon */ 84*7c478bd9Sstevel@tonic-gate if (picld_plugin_register(&frudata_reg_info) != PICL_SUCCESS) { 85*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "SUNW_piclfrudata plugin registration failed"); 86*7c478bd9Sstevel@tonic-gate } 87*7c478bd9Sstevel@tonic-gate } 88*7c478bd9Sstevel@tonic-gate 89*7c478bd9Sstevel@tonic-gate static int 90*7c478bd9Sstevel@tonic-gate map_access_err(int err) 91*7c478bd9Sstevel@tonic-gate { 92*7c478bd9Sstevel@tonic-gate switch (err) { 93*7c478bd9Sstevel@tonic-gate case ENFILE : 94*7c478bd9Sstevel@tonic-gate return (PICL_PROPEXISTS); 95*7c478bd9Sstevel@tonic-gate case EAGAIN : 96*7c478bd9Sstevel@tonic-gate return (PICL_NOSPACE); 97*7c478bd9Sstevel@tonic-gate case EPERM : 98*7c478bd9Sstevel@tonic-gate return (PICL_PERMDENIED); 99*7c478bd9Sstevel@tonic-gate case EEXIST : 100*7c478bd9Sstevel@tonic-gate return (PICL_PROPEXISTS); 101*7c478bd9Sstevel@tonic-gate default : 102*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 103*7c478bd9Sstevel@tonic-gate } 104*7c478bd9Sstevel@tonic-gate } 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate /* 107*7c478bd9Sstevel@tonic-gate * unlock_container_lock() should be always called by the thread holding the 108*7c478bd9Sstevel@tonic-gate * container object lock. it will signal block thread waiting on the condition 109*7c478bd9Sstevel@tonic-gate * variable. 110*7c478bd9Sstevel@tonic-gate */ 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate static void 113*7c478bd9Sstevel@tonic-gate unlock_container_lock(container_tbl_t *cont_hash) 114*7c478bd9Sstevel@tonic-gate { 115*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&cont_hash->rwlock); 116*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&cont_tbl_lock); 117*7c478bd9Sstevel@tonic-gate (void) pthread_cond_signal(&cont_hash->cond_var); 118*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&cont_tbl_lock); 119*7c478bd9Sstevel@tonic-gate } 120*7c478bd9Sstevel@tonic-gate 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate /* volatile callback read routine */ 123*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 124*7c478bd9Sstevel@tonic-gate static int 125*7c478bd9Sstevel@tonic-gate frudata_read_callback(ptree_rarg_t *rarg, void *buf) 126*7c478bd9Sstevel@tonic-gate { 127*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 128*7c478bd9Sstevel@tonic-gate } 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate /* 131*7c478bd9Sstevel@tonic-gate * called to get hash object for specified node and object type from 132*7c478bd9Sstevel@tonic-gate * hash table. 133*7c478bd9Sstevel@tonic-gate */ 134*7c478bd9Sstevel@tonic-gate static container_tbl_t * 135*7c478bd9Sstevel@tonic-gate lookup_container_table(picl_nodehdl_t nodehdl, int object_type) 136*7c478bd9Sstevel@tonic-gate { 137*7c478bd9Sstevel@tonic-gate int index_to_hash; 138*7c478bd9Sstevel@tonic-gate int retval = PICL_SUCCESS; 139*7c478bd9Sstevel@tonic-gate container_tbl_t *first_hash; 140*7c478bd9Sstevel@tonic-gate container_tbl_t *next_hash; 141*7c478bd9Sstevel@tonic-gate picl_nodehdl_t parenthdl = 0; 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate switch (object_type) { 144*7c478bd9Sstevel@tonic-gate case SECTION_NODE: 145*7c478bd9Sstevel@tonic-gate retval = ptree_get_propval_by_name(nodehdl, PICL_PROP_PARENT, 146*7c478bd9Sstevel@tonic-gate &parenthdl, sizeof (picl_nodehdl_t)); 147*7c478bd9Sstevel@tonic-gate break; 148*7c478bd9Sstevel@tonic-gate case SEGMENT_NODE: 149*7c478bd9Sstevel@tonic-gate retval = ptree_get_propval_by_name(nodehdl, PICL_PROP_PARENT, 150*7c478bd9Sstevel@tonic-gate &parenthdl, sizeof (picl_nodehdl_t)); 151*7c478bd9Sstevel@tonic-gate retval = ptree_get_propval_by_name(parenthdl, PICL_PROP_PARENT, 152*7c478bd9Sstevel@tonic-gate &parenthdl, sizeof (picl_nodehdl_t)); 153*7c478bd9Sstevel@tonic-gate break; 154*7c478bd9Sstevel@tonic-gate case CONTAINER_NODE : 155*7c478bd9Sstevel@tonic-gate parenthdl = nodehdl; 156*7c478bd9Sstevel@tonic-gate break; 157*7c478bd9Sstevel@tonic-gate default : 158*7c478bd9Sstevel@tonic-gate return (NULL); 159*7c478bd9Sstevel@tonic-gate } 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) { 162*7c478bd9Sstevel@tonic-gate return (NULL); 163*7c478bd9Sstevel@tonic-gate } 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate index_to_hash = (parenthdl % TABLE_SIZE); 166*7c478bd9Sstevel@tonic-gate 167*7c478bd9Sstevel@tonic-gate first_hash = container_table[index_to_hash]; 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate for (next_hash = first_hash; next_hash != NULL; 170*7c478bd9Sstevel@tonic-gate next_hash = next_hash->next) { 171*7c478bd9Sstevel@tonic-gate if (parenthdl == next_hash->picl_hdl) { 172*7c478bd9Sstevel@tonic-gate return (next_hash); 173*7c478bd9Sstevel@tonic-gate } 174*7c478bd9Sstevel@tonic-gate } 175*7c478bd9Sstevel@tonic-gate return (NULL); 176*7c478bd9Sstevel@tonic-gate } 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate static int 179*7c478bd9Sstevel@tonic-gate lock_readwrite_lock(container_tbl_t *cont_obj, int operation) 180*7c478bd9Sstevel@tonic-gate { 181*7c478bd9Sstevel@tonic-gate /* if write operation */ 182*7c478bd9Sstevel@tonic-gate if (operation == PICL_WRITE) { 183*7c478bd9Sstevel@tonic-gate return (pthread_rwlock_trywrlock(&cont_obj->rwlock)); 184*7c478bd9Sstevel@tonic-gate } 185*7c478bd9Sstevel@tonic-gate /* read operation */ 186*7c478bd9Sstevel@tonic-gate return (pthread_rwlock_tryrdlock(&cont_obj->rwlock)); 187*7c478bd9Sstevel@tonic-gate } 188*7c478bd9Sstevel@tonic-gate 189*7c478bd9Sstevel@tonic-gate /* 190*7c478bd9Sstevel@tonic-gate * lock the container table, do lookup for the container object 191*7c478bd9Sstevel@tonic-gate * in the container table. if container object found try to lock 192*7c478bd9Sstevel@tonic-gate * the container object, if lock on container object is busy wait 193*7c478bd9Sstevel@tonic-gate * on condition variable till the thread holding the container 194*7c478bd9Sstevel@tonic-gate * object lock signal it. 195*7c478bd9Sstevel@tonic-gate */ 196*7c478bd9Sstevel@tonic-gate 197*7c478bd9Sstevel@tonic-gate static container_tbl_t * 198*7c478bd9Sstevel@tonic-gate lock_container_lock(picl_nodehdl_t nodehdl, int object_type, int operation) 199*7c478bd9Sstevel@tonic-gate { 200*7c478bd9Sstevel@tonic-gate container_tbl_t *cont_obj = NULL; 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&cont_tbl_lock); 203*7c478bd9Sstevel@tonic-gate 204*7c478bd9Sstevel@tonic-gate while (((cont_obj = lookup_container_table(nodehdl, object_type)) != 205*7c478bd9Sstevel@tonic-gate NULL) && (lock_readwrite_lock(cont_obj, operation) == EBUSY)) { 206*7c478bd9Sstevel@tonic-gate pthread_cond_wait(&cont_obj->cond_var, &cont_tbl_lock); 207*7c478bd9Sstevel@tonic-gate } 208*7c478bd9Sstevel@tonic-gate 209*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&cont_tbl_lock); 210*7c478bd9Sstevel@tonic-gate 211*7c478bd9Sstevel@tonic-gate return (cont_obj); 212*7c478bd9Sstevel@tonic-gate } 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate static hash_obj_t * 215*7c478bd9Sstevel@tonic-gate lookup_node_object(picl_nodehdl_t nodehdl, int object_type, 216*7c478bd9Sstevel@tonic-gate container_tbl_t *cont_tbl) 217*7c478bd9Sstevel@tonic-gate { 218*7c478bd9Sstevel@tonic-gate int index_to_hash; 219*7c478bd9Sstevel@tonic-gate hash_obj_t *first_hash; 220*7c478bd9Sstevel@tonic-gate hash_obj_t *next_hash; 221*7c478bd9Sstevel@tonic-gate 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate index_to_hash = (nodehdl % TABLE_SIZE); 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate first_hash = &cont_tbl->hash_obj[index_to_hash]; 226*7c478bd9Sstevel@tonic-gate 227*7c478bd9Sstevel@tonic-gate for (next_hash = first_hash->next; next_hash != NULL; 228*7c478bd9Sstevel@tonic-gate next_hash = next_hash->next) { 229*7c478bd9Sstevel@tonic-gate if ((nodehdl == next_hash->picl_hdl) && 230*7c478bd9Sstevel@tonic-gate (object_type == next_hash->object_type)) { 231*7c478bd9Sstevel@tonic-gate return (next_hash); 232*7c478bd9Sstevel@tonic-gate } 233*7c478bd9Sstevel@tonic-gate } 234*7c478bd9Sstevel@tonic-gate return (NULL); 235*7c478bd9Sstevel@tonic-gate } 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate /* 238*7c478bd9Sstevel@tonic-gate * called to add newly created container hash table into container hash table. 239*7c478bd9Sstevel@tonic-gate * 240*7c478bd9Sstevel@tonic-gate */ 241*7c478bd9Sstevel@tonic-gate static void 242*7c478bd9Sstevel@tonic-gate add_tblobject_to_container_tbl(container_tbl_t *cont_tbl) 243*7c478bd9Sstevel@tonic-gate { 244*7c478bd9Sstevel@tonic-gate int cnt; 245*7c478bd9Sstevel@tonic-gate int index_to_hash; 246*7c478bd9Sstevel@tonic-gate hash_obj_t *hash_ptr; 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate index_to_hash = ((cont_tbl->picl_hdl) % TABLE_SIZE); 249*7c478bd9Sstevel@tonic-gate 250*7c478bd9Sstevel@tonic-gate cont_tbl->next = container_table[index_to_hash]; 251*7c478bd9Sstevel@tonic-gate container_table[index_to_hash] = cont_tbl; 252*7c478bd9Sstevel@tonic-gate hash_ptr = cont_tbl->hash_obj; 253*7c478bd9Sstevel@tonic-gate 254*7c478bd9Sstevel@tonic-gate /* initialize the bucket of this container hash table. */ 255*7c478bd9Sstevel@tonic-gate 256*7c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < TABLE_SIZE; cnt++) { 257*7c478bd9Sstevel@tonic-gate hash_ptr->next = NULL; 258*7c478bd9Sstevel@tonic-gate hash_ptr->prev = NULL; 259*7c478bd9Sstevel@tonic-gate hash_ptr++; 260*7c478bd9Sstevel@tonic-gate } 261*7c478bd9Sstevel@tonic-gate if (cont_tbl->next != NULL) { 262*7c478bd9Sstevel@tonic-gate cont_tbl->next->prev = cont_tbl; 263*7c478bd9Sstevel@tonic-gate } 264*7c478bd9Sstevel@tonic-gate } 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate static void 267*7c478bd9Sstevel@tonic-gate add_nodeobject_to_hashtable(hash_obj_t *hash_obj, container_tbl_t *cont_tbl) 268*7c478bd9Sstevel@tonic-gate { 269*7c478bd9Sstevel@tonic-gate int index_to_hash; 270*7c478bd9Sstevel@tonic-gate hash_obj_t *hash_table; 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate index_to_hash = ((hash_obj->picl_hdl) % TABLE_SIZE); 273*7c478bd9Sstevel@tonic-gate hash_table = &cont_tbl->hash_obj[index_to_hash]; 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate hash_obj->next = hash_table->next; 276*7c478bd9Sstevel@tonic-gate hash_table->next = hash_obj; 277*7c478bd9Sstevel@tonic-gate 278*7c478bd9Sstevel@tonic-gate if (hash_obj->next != NULL) { 279*7c478bd9Sstevel@tonic-gate hash_obj->next->prev = hash_obj; 280*7c478bd9Sstevel@tonic-gate } 281*7c478bd9Sstevel@tonic-gate } 282*7c478bd9Sstevel@tonic-gate 283*7c478bd9Sstevel@tonic-gate static container_tbl_t * 284*7c478bd9Sstevel@tonic-gate alloc_container_table(picl_nodehdl_t nodehdl) 285*7c478bd9Sstevel@tonic-gate { 286*7c478bd9Sstevel@tonic-gate container_tbl_t *cont_tbl; 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gate cont_tbl = malloc(sizeof (container_tbl_t)); 289*7c478bd9Sstevel@tonic-gate if (cont_tbl == NULL) { 290*7c478bd9Sstevel@tonic-gate return (NULL); 291*7c478bd9Sstevel@tonic-gate } 292*7c478bd9Sstevel@tonic-gate 293*7c478bd9Sstevel@tonic-gate cont_tbl->picl_hdl = nodehdl; 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate cont_tbl->hash_obj = malloc(sizeof (hash_obj_t[TABLE_SIZE])); 296*7c478bd9Sstevel@tonic-gate cont_tbl->next = NULL; 297*7c478bd9Sstevel@tonic-gate cont_tbl->prev = NULL; 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate if (cont_tbl->hash_obj == NULL) { 300*7c478bd9Sstevel@tonic-gate (void) free(cont_tbl); 301*7c478bd9Sstevel@tonic-gate return (NULL); 302*7c478bd9Sstevel@tonic-gate } 303*7c478bd9Sstevel@tonic-gate 304*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_init(&cont_tbl->rwlock, NULL); 305*7c478bd9Sstevel@tonic-gate (void) pthread_cond_init(&cont_tbl->cond_var, NULL); 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate return (cont_tbl); 308*7c478bd9Sstevel@tonic-gate } 309*7c478bd9Sstevel@tonic-gate 310*7c478bd9Sstevel@tonic-gate /* 311*7c478bd9Sstevel@tonic-gate * called to allocate container node object for container property and a 312*7c478bd9Sstevel@tonic-gate * container table. 313*7c478bd9Sstevel@tonic-gate */ 314*7c478bd9Sstevel@tonic-gate 315*7c478bd9Sstevel@tonic-gate static hash_obj_t * 316*7c478bd9Sstevel@tonic-gate alloc_container_node_object(picl_nodehdl_t nodehdl) 317*7c478bd9Sstevel@tonic-gate { 318*7c478bd9Sstevel@tonic-gate hash_obj_t *hash_obj; 319*7c478bd9Sstevel@tonic-gate fru_access_hdl_t acc_hdl; 320*7c478bd9Sstevel@tonic-gate container_node_t *cont_node; 321*7c478bd9Sstevel@tonic-gate 322*7c478bd9Sstevel@tonic-gate /* open the container (call fruaccess) */ 323*7c478bd9Sstevel@tonic-gate acc_hdl = fru_open_container(nodehdl); 324*7c478bd9Sstevel@tonic-gate if (acc_hdl == (container_hdl_t)0) { 325*7c478bd9Sstevel@tonic-gate return (NULL); 326*7c478bd9Sstevel@tonic-gate } 327*7c478bd9Sstevel@tonic-gate 328*7c478bd9Sstevel@tonic-gate /* allocate container node object */ 329*7c478bd9Sstevel@tonic-gate cont_node = malloc(sizeof (container_node_t)); 330*7c478bd9Sstevel@tonic-gate if (cont_node == NULL) { 331*7c478bd9Sstevel@tonic-gate return (NULL); 332*7c478bd9Sstevel@tonic-gate } 333*7c478bd9Sstevel@tonic-gate 334*7c478bd9Sstevel@tonic-gate /* allocate container hash object */ 335*7c478bd9Sstevel@tonic-gate hash_obj = malloc(sizeof (hash_obj_t)); 336*7c478bd9Sstevel@tonic-gate if (hash_obj == NULL) { 337*7c478bd9Sstevel@tonic-gate (void) free(cont_node); 338*7c478bd9Sstevel@tonic-gate return (NULL); 339*7c478bd9Sstevel@tonic-gate } 340*7c478bd9Sstevel@tonic-gate 341*7c478bd9Sstevel@tonic-gate cont_node->cont_hdl = acc_hdl; /* fruaccess handle */ 342*7c478bd9Sstevel@tonic-gate cont_node->section_list = NULL; 343*7c478bd9Sstevel@tonic-gate hash_obj->picl_hdl = nodehdl; /* picl node handle */ 344*7c478bd9Sstevel@tonic-gate hash_obj->object_type = CONTAINER_NODE; 345*7c478bd9Sstevel@tonic-gate hash_obj->u.cont_node = cont_node; 346*7c478bd9Sstevel@tonic-gate hash_obj->next = NULL; 347*7c478bd9Sstevel@tonic-gate hash_obj->prev = NULL; 348*7c478bd9Sstevel@tonic-gate 349*7c478bd9Sstevel@tonic-gate return (hash_obj); 350*7c478bd9Sstevel@tonic-gate } 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate /* 353*7c478bd9Sstevel@tonic-gate * called to allocate node object for section node. 354*7c478bd9Sstevel@tonic-gate */ 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate static hash_obj_t * 357*7c478bd9Sstevel@tonic-gate alloc_section_node_object(picl_nodehdl_t nodehdl, section_t *section) 358*7c478bd9Sstevel@tonic-gate { 359*7c478bd9Sstevel@tonic-gate hash_obj_t *hash_obj; 360*7c478bd9Sstevel@tonic-gate section_node_t *sec_node; 361*7c478bd9Sstevel@tonic-gate 362*7c478bd9Sstevel@tonic-gate /* allocate section node object */ 363*7c478bd9Sstevel@tonic-gate sec_node = malloc(sizeof (section_node_t)); 364*7c478bd9Sstevel@tonic-gate if (sec_node == NULL) { 365*7c478bd9Sstevel@tonic-gate return (NULL); 366*7c478bd9Sstevel@tonic-gate } 367*7c478bd9Sstevel@tonic-gate 368*7c478bd9Sstevel@tonic-gate /* allocate section hash object */ 369*7c478bd9Sstevel@tonic-gate hash_obj = malloc(sizeof (hash_obj_t)); 370*7c478bd9Sstevel@tonic-gate if (hash_obj == NULL) { 371*7c478bd9Sstevel@tonic-gate (void) free(sec_node); 372*7c478bd9Sstevel@tonic-gate return (NULL); 373*7c478bd9Sstevel@tonic-gate } 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate sec_node->section_hdl = section->handle; /* fruaccess hdl. */ 376*7c478bd9Sstevel@tonic-gate sec_node->segment_list = NULL; 377*7c478bd9Sstevel@tonic-gate sec_node->next = NULL; 378*7c478bd9Sstevel@tonic-gate sec_node->num_of_segment = -1; 379*7c478bd9Sstevel@tonic-gate 380*7c478bd9Sstevel@tonic-gate hash_obj->picl_hdl = nodehdl; /* picl node handle */ 381*7c478bd9Sstevel@tonic-gate hash_obj->object_type = SECTION_NODE; 382*7c478bd9Sstevel@tonic-gate hash_obj->u.sec_node = sec_node; 383*7c478bd9Sstevel@tonic-gate hash_obj->next = NULL; 384*7c478bd9Sstevel@tonic-gate hash_obj->prev = NULL; 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate return (hash_obj); 387*7c478bd9Sstevel@tonic-gate } 388*7c478bd9Sstevel@tonic-gate 389*7c478bd9Sstevel@tonic-gate /* 390*7c478bd9Sstevel@tonic-gate * called to allocate segment node object. 391*7c478bd9Sstevel@tonic-gate */ 392*7c478bd9Sstevel@tonic-gate 393*7c478bd9Sstevel@tonic-gate static hash_obj_t * 394*7c478bd9Sstevel@tonic-gate alloc_segment_node_object(picl_nodehdl_t nodehdl, segment_t *segment) 395*7c478bd9Sstevel@tonic-gate { 396*7c478bd9Sstevel@tonic-gate hash_obj_t *hash_obj; 397*7c478bd9Sstevel@tonic-gate segment_node_t *seg_node; 398*7c478bd9Sstevel@tonic-gate 399*7c478bd9Sstevel@tonic-gate /* allocate segment node object */ 400*7c478bd9Sstevel@tonic-gate seg_node = malloc(sizeof (segment_node_t)); 401*7c478bd9Sstevel@tonic-gate if (seg_node == NULL) { 402*7c478bd9Sstevel@tonic-gate return (NULL); 403*7c478bd9Sstevel@tonic-gate } 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate /* allocate segment hash object */ 406*7c478bd9Sstevel@tonic-gate hash_obj = malloc(sizeof (hash_obj_t)); 407*7c478bd9Sstevel@tonic-gate if (hash_obj == NULL) { 408*7c478bd9Sstevel@tonic-gate free(seg_node); 409*7c478bd9Sstevel@tonic-gate return (NULL); 410*7c478bd9Sstevel@tonic-gate } 411*7c478bd9Sstevel@tonic-gate 412*7c478bd9Sstevel@tonic-gate /* fruaccess handle */ 413*7c478bd9Sstevel@tonic-gate seg_node->segment_hdl = segment->handle; 414*7c478bd9Sstevel@tonic-gate seg_node->packet_list = NULL; 415*7c478bd9Sstevel@tonic-gate seg_node->next = NULL; 416*7c478bd9Sstevel@tonic-gate seg_node->num_of_pkt = -1; 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate /* picl node handle */ 419*7c478bd9Sstevel@tonic-gate hash_obj->picl_hdl = nodehdl; 420*7c478bd9Sstevel@tonic-gate hash_obj->object_type = SEGMENT_NODE; 421*7c478bd9Sstevel@tonic-gate hash_obj->u.seg_node = seg_node; 422*7c478bd9Sstevel@tonic-gate hash_obj->next = NULL; 423*7c478bd9Sstevel@tonic-gate hash_obj->prev = NULL; 424*7c478bd9Sstevel@tonic-gate 425*7c478bd9Sstevel@tonic-gate return (hash_obj); 426*7c478bd9Sstevel@tonic-gate } 427*7c478bd9Sstevel@tonic-gate 428*7c478bd9Sstevel@tonic-gate /* 429*7c478bd9Sstevel@tonic-gate * called to allocate node object for packet. 430*7c478bd9Sstevel@tonic-gate */ 431*7c478bd9Sstevel@tonic-gate 432*7c478bd9Sstevel@tonic-gate static hash_obj_t * 433*7c478bd9Sstevel@tonic-gate alloc_packet_node_object(picl_nodehdl_t nodehdl, packet_t *packet) 434*7c478bd9Sstevel@tonic-gate { 435*7c478bd9Sstevel@tonic-gate hash_obj_t *hash_obj; 436*7c478bd9Sstevel@tonic-gate packet_node_t *pkt_node; 437*7c478bd9Sstevel@tonic-gate 438*7c478bd9Sstevel@tonic-gate /* allocate packet node object */ 439*7c478bd9Sstevel@tonic-gate pkt_node = malloc(sizeof (packet_node_t)); 440*7c478bd9Sstevel@tonic-gate if (pkt_node == NULL) { 441*7c478bd9Sstevel@tonic-gate return (NULL); 442*7c478bd9Sstevel@tonic-gate } 443*7c478bd9Sstevel@tonic-gate 444*7c478bd9Sstevel@tonic-gate /* allocate packet hash object */ 445*7c478bd9Sstevel@tonic-gate hash_obj = malloc(sizeof (hash_obj_t)); 446*7c478bd9Sstevel@tonic-gate if (hash_obj == NULL) { 447*7c478bd9Sstevel@tonic-gate free(pkt_node); 448*7c478bd9Sstevel@tonic-gate return (NULL); 449*7c478bd9Sstevel@tonic-gate } 450*7c478bd9Sstevel@tonic-gate 451*7c478bd9Sstevel@tonic-gate /* fruaccess handle */ 452*7c478bd9Sstevel@tonic-gate pkt_node->pkt_handle = packet->handle; 453*7c478bd9Sstevel@tonic-gate pkt_node->next = NULL; 454*7c478bd9Sstevel@tonic-gate 455*7c478bd9Sstevel@tonic-gate hash_obj->picl_hdl = nodehdl; /* picl node handle */ 456*7c478bd9Sstevel@tonic-gate hash_obj->object_type = PACKET_NODE; 457*7c478bd9Sstevel@tonic-gate hash_obj->u.pkt_node = pkt_node; 458*7c478bd9Sstevel@tonic-gate hash_obj->next = NULL; 459*7c478bd9Sstevel@tonic-gate hash_obj->prev = NULL; 460*7c478bd9Sstevel@tonic-gate 461*7c478bd9Sstevel@tonic-gate return (hash_obj); 462*7c478bd9Sstevel@tonic-gate } 463*7c478bd9Sstevel@tonic-gate 464*7c478bd9Sstevel@tonic-gate /* add new section hash object to the section list */ 465*7c478bd9Sstevel@tonic-gate static void 466*7c478bd9Sstevel@tonic-gate add_to_section_list(hash_obj_t *container_hash, hash_obj_t *sect_hash) 467*7c478bd9Sstevel@tonic-gate { 468*7c478bd9Sstevel@tonic-gate hash_obj_t *next_hash; 469*7c478bd9Sstevel@tonic-gate 470*7c478bd9Sstevel@tonic-gate sect_hash->u.sec_node->container_hdl = container_hash->picl_hdl; 471*7c478bd9Sstevel@tonic-gate if (container_hash->u.cont_node->section_list == NULL) { 472*7c478bd9Sstevel@tonic-gate container_hash->u.cont_node->section_list = sect_hash; 473*7c478bd9Sstevel@tonic-gate return; 474*7c478bd9Sstevel@tonic-gate } 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate for (next_hash = container_hash->u.cont_node->section_list; 477*7c478bd9Sstevel@tonic-gate next_hash->u.sec_node->next != NULL; 478*7c478bd9Sstevel@tonic-gate next_hash = next_hash->u.sec_node->next) { 479*7c478bd9Sstevel@tonic-gate ; 480*7c478bd9Sstevel@tonic-gate } 481*7c478bd9Sstevel@tonic-gate 482*7c478bd9Sstevel@tonic-gate next_hash->u.sec_node->next = sect_hash; 483*7c478bd9Sstevel@tonic-gate } 484*7c478bd9Sstevel@tonic-gate 485*7c478bd9Sstevel@tonic-gate /* add new segment hash object to the existing list */ 486*7c478bd9Sstevel@tonic-gate 487*7c478bd9Sstevel@tonic-gate static void 488*7c478bd9Sstevel@tonic-gate add_to_segment_list(hash_obj_t *parent_obj, hash_obj_t *child_obj) 489*7c478bd9Sstevel@tonic-gate { 490*7c478bd9Sstevel@tonic-gate hash_obj_t *next_hash; 491*7c478bd9Sstevel@tonic-gate 492*7c478bd9Sstevel@tonic-gate child_obj->u.seg_node->sec_nodehdl = parent_obj->picl_hdl; 493*7c478bd9Sstevel@tonic-gate if (parent_obj->u.sec_node->segment_list == NULL) { 494*7c478bd9Sstevel@tonic-gate parent_obj->u.sec_node->segment_list = child_obj; 495*7c478bd9Sstevel@tonic-gate return; 496*7c478bd9Sstevel@tonic-gate } 497*7c478bd9Sstevel@tonic-gate 498*7c478bd9Sstevel@tonic-gate for (next_hash = parent_obj->u.sec_node->segment_list; 499*7c478bd9Sstevel@tonic-gate next_hash->u.seg_node->next != NULL; 500*7c478bd9Sstevel@tonic-gate next_hash = next_hash->u.seg_node->next) { 501*7c478bd9Sstevel@tonic-gate ; 502*7c478bd9Sstevel@tonic-gate } 503*7c478bd9Sstevel@tonic-gate next_hash->u.seg_node->next = child_obj; 504*7c478bd9Sstevel@tonic-gate } 505*7c478bd9Sstevel@tonic-gate 506*7c478bd9Sstevel@tonic-gate /* 507*7c478bd9Sstevel@tonic-gate * called to add packet node object to the existing packet list. 508*7c478bd9Sstevel@tonic-gate */ 509*7c478bd9Sstevel@tonic-gate static void 510*7c478bd9Sstevel@tonic-gate add_to_packet_list(hash_obj_t *parent_obj, hash_obj_t *child_obj) 511*7c478bd9Sstevel@tonic-gate { 512*7c478bd9Sstevel@tonic-gate hash_obj_t *next_hash; 513*7c478bd9Sstevel@tonic-gate 514*7c478bd9Sstevel@tonic-gate if (parent_obj->u.seg_node->packet_list == NULL) { 515*7c478bd9Sstevel@tonic-gate parent_obj->u.seg_node->packet_list = child_obj; 516*7c478bd9Sstevel@tonic-gate return; 517*7c478bd9Sstevel@tonic-gate } 518*7c478bd9Sstevel@tonic-gate 519*7c478bd9Sstevel@tonic-gate for (next_hash = parent_obj->u.seg_node->packet_list; 520*7c478bd9Sstevel@tonic-gate next_hash->u.pkt_node->next != NULL; 521*7c478bd9Sstevel@tonic-gate next_hash = next_hash->u.pkt_node->next) { 522*7c478bd9Sstevel@tonic-gate ; 523*7c478bd9Sstevel@tonic-gate } 524*7c478bd9Sstevel@tonic-gate next_hash->u.pkt_node->next = child_obj; 525*7c478bd9Sstevel@tonic-gate } 526*7c478bd9Sstevel@tonic-gate 527*7c478bd9Sstevel@tonic-gate /* 528*7c478bd9Sstevel@tonic-gate * free the packet hash list. 529*7c478bd9Sstevel@tonic-gate */ 530*7c478bd9Sstevel@tonic-gate 531*7c478bd9Sstevel@tonic-gate static void 532*7c478bd9Sstevel@tonic-gate free_packet_list(hash_obj_t *hash_obj, container_tbl_t *cont_tbl) 533*7c478bd9Sstevel@tonic-gate { 534*7c478bd9Sstevel@tonic-gate hash_obj_t *next_obj; 535*7c478bd9Sstevel@tonic-gate hash_obj_t *free_obj; 536*7c478bd9Sstevel@tonic-gate 537*7c478bd9Sstevel@tonic-gate /* packet hash object list */ 538*7c478bd9Sstevel@tonic-gate next_obj = hash_obj->u.seg_node->packet_list; 539*7c478bd9Sstevel@tonic-gate while (next_obj != NULL) { 540*7c478bd9Sstevel@tonic-gate free_obj = next_obj; 541*7c478bd9Sstevel@tonic-gate next_obj = next_obj->u.pkt_node->next; 542*7c478bd9Sstevel@tonic-gate if (free_obj->prev == NULL) { /* first node object */ 543*7c478bd9Sstevel@tonic-gate cont_tbl->hash_obj[(free_obj->picl_hdl % 544*7c478bd9Sstevel@tonic-gate TABLE_SIZE)].next = free_obj->next; 545*7c478bd9Sstevel@tonic-gate if (free_obj->next != NULL) { 546*7c478bd9Sstevel@tonic-gate free_obj->next->prev = NULL; 547*7c478bd9Sstevel@tonic-gate } 548*7c478bd9Sstevel@tonic-gate } else { 549*7c478bd9Sstevel@tonic-gate free_obj->prev->next = free_obj->next; 550*7c478bd9Sstevel@tonic-gate if (free_obj->next != NULL) { 551*7c478bd9Sstevel@tonic-gate free_obj->next->prev = free_obj->prev; 552*7c478bd9Sstevel@tonic-gate } 553*7c478bd9Sstevel@tonic-gate } 554*7c478bd9Sstevel@tonic-gate 555*7c478bd9Sstevel@tonic-gate free(free_obj->u.pkt_node); 556*7c478bd9Sstevel@tonic-gate free(free_obj); 557*7c478bd9Sstevel@tonic-gate } 558*7c478bd9Sstevel@tonic-gate hash_obj->u.seg_node->packet_list = NULL; 559*7c478bd9Sstevel@tonic-gate } 560*7c478bd9Sstevel@tonic-gate 561*7c478bd9Sstevel@tonic-gate /* 562*7c478bd9Sstevel@tonic-gate * free the segment hash node object. 563*7c478bd9Sstevel@tonic-gate */ 564*7c478bd9Sstevel@tonic-gate 565*7c478bd9Sstevel@tonic-gate static void 566*7c478bd9Sstevel@tonic-gate free_segment_node(hash_obj_t *hash_obj, picl_nodehdl_t nodehdl, 567*7c478bd9Sstevel@tonic-gate container_tbl_t *cont_tbl) 568*7c478bd9Sstevel@tonic-gate { 569*7c478bd9Sstevel@tonic-gate hash_obj_t *prev_hash_obj; 570*7c478bd9Sstevel@tonic-gate hash_obj_t *next_obj; 571*7c478bd9Sstevel@tonic-gate 572*7c478bd9Sstevel@tonic-gate /* segment hash object list */ 573*7c478bd9Sstevel@tonic-gate next_obj = hash_obj->u.sec_node->segment_list; 574*7c478bd9Sstevel@tonic-gate if (next_obj == NULL) { 575*7c478bd9Sstevel@tonic-gate return; 576*7c478bd9Sstevel@tonic-gate } 577*7c478bd9Sstevel@tonic-gate 578*7c478bd9Sstevel@tonic-gate /* find the segment hash from the segment list to be deleted. */ 579*7c478bd9Sstevel@tonic-gate if (next_obj->picl_hdl == nodehdl) { 580*7c478bd9Sstevel@tonic-gate hash_obj->u.sec_node->segment_list = 581*7c478bd9Sstevel@tonic-gate next_obj->u.seg_node->next; 582*7c478bd9Sstevel@tonic-gate } else { 583*7c478bd9Sstevel@tonic-gate while (next_obj != NULL) { 584*7c478bd9Sstevel@tonic-gate if (next_obj->picl_hdl != nodehdl) { 585*7c478bd9Sstevel@tonic-gate prev_hash_obj = next_obj; 586*7c478bd9Sstevel@tonic-gate next_obj = next_obj->u.seg_node->next; 587*7c478bd9Sstevel@tonic-gate } else { 588*7c478bd9Sstevel@tonic-gate prev_hash_obj->u.seg_node->next = 589*7c478bd9Sstevel@tonic-gate next_obj->u.seg_node->next; 590*7c478bd9Sstevel@tonic-gate break; 591*7c478bd9Sstevel@tonic-gate } 592*7c478bd9Sstevel@tonic-gate } 593*7c478bd9Sstevel@tonic-gate 594*7c478bd9Sstevel@tonic-gate if (next_obj == NULL) { 595*7c478bd9Sstevel@tonic-gate return; 596*7c478bd9Sstevel@tonic-gate } 597*7c478bd9Sstevel@tonic-gate 598*7c478bd9Sstevel@tonic-gate } 599*7c478bd9Sstevel@tonic-gate 600*7c478bd9Sstevel@tonic-gate if (next_obj->prev == NULL) { 601*7c478bd9Sstevel@tonic-gate cont_tbl->hash_obj[(next_obj->picl_hdl % TABLE_SIZE)].next = 602*7c478bd9Sstevel@tonic-gate next_obj->next; 603*7c478bd9Sstevel@tonic-gate if (next_obj->next != NULL) 604*7c478bd9Sstevel@tonic-gate next_obj->next->prev = NULL; 605*7c478bd9Sstevel@tonic-gate } else { 606*7c478bd9Sstevel@tonic-gate next_obj->prev->next = next_obj->next; 607*7c478bd9Sstevel@tonic-gate if (next_obj->next != NULL) { 608*7c478bd9Sstevel@tonic-gate next_obj->next->prev = next_obj->prev; 609*7c478bd9Sstevel@tonic-gate } 610*7c478bd9Sstevel@tonic-gate } 611*7c478bd9Sstevel@tonic-gate 612*7c478bd9Sstevel@tonic-gate free_packet_list(next_obj, cont_tbl); 613*7c478bd9Sstevel@tonic-gate free(next_obj->u.seg_node); 614*7c478bd9Sstevel@tonic-gate free(next_obj); 615*7c478bd9Sstevel@tonic-gate } 616*7c478bd9Sstevel@tonic-gate 617*7c478bd9Sstevel@tonic-gate 618*7c478bd9Sstevel@tonic-gate /* 619*7c478bd9Sstevel@tonic-gate * Description : frudata_delete_segment is called when volatile property 620*7c478bd9Sstevel@tonic-gate * delete_segment under class segment is accessed. 621*7c478bd9Sstevel@tonic-gate * 622*7c478bd9Sstevel@tonic-gate * Arguments : ptree_warg_t is holds node handle of segment node and property 623*7c478bd9Sstevel@tonic-gate * handle of delete_segment property. 624*7c478bd9Sstevel@tonic-gate */ 625*7c478bd9Sstevel@tonic-gate 626*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 627*7c478bd9Sstevel@tonic-gate static int 628*7c478bd9Sstevel@tonic-gate frudata_delete_segment(ptree_warg_t *warg, const void *buf) 629*7c478bd9Sstevel@tonic-gate { 630*7c478bd9Sstevel@tonic-gate int retval; 631*7c478bd9Sstevel@tonic-gate int num_of_segment; 632*7c478bd9Sstevel@tonic-gate int num_of_pkt; 633*7c478bd9Sstevel@tonic-gate int pkt_cnt; 634*7c478bd9Sstevel@tonic-gate int count; 635*7c478bd9Sstevel@tonic-gate packet_t *pkt_buf; 636*7c478bd9Sstevel@tonic-gate segment_t *seg_buffer; 637*7c478bd9Sstevel@tonic-gate hash_obj_t *seg_hash; 638*7c478bd9Sstevel@tonic-gate hash_obj_t *pkt_hash; 639*7c478bd9Sstevel@tonic-gate hash_obj_t *hash_obj; 640*7c478bd9Sstevel@tonic-gate fru_segdesc_t *desc; 641*7c478bd9Sstevel@tonic-gate picl_nodehdl_t sec_nodehdl; 642*7c478bd9Sstevel@tonic-gate container_tbl_t *cont_tbl; 643*7c478bd9Sstevel@tonic-gate fru_access_hdl_t seg_acc_hdl; 644*7c478bd9Sstevel@tonic-gate fru_access_hdl_t new_sec_acc_hdl; 645*7c478bd9Sstevel@tonic-gate 646*7c478bd9Sstevel@tonic-gate cont_tbl = lock_container_lock(warg->nodeh, SEGMENT_NODE, PICL_WRITE); 647*7c478bd9Sstevel@tonic-gate if (!cont_tbl) { 648*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 649*7c478bd9Sstevel@tonic-gate } 650*7c478bd9Sstevel@tonic-gate 651*7c478bd9Sstevel@tonic-gate /* segment hash */ 652*7c478bd9Sstevel@tonic-gate hash_obj = lookup_node_object(warg->nodeh, SEGMENT_NODE, cont_tbl); 653*7c478bd9Sstevel@tonic-gate if (hash_obj == NULL) { 654*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 655*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 656*7c478bd9Sstevel@tonic-gate } 657*7c478bd9Sstevel@tonic-gate 658*7c478bd9Sstevel@tonic-gate /* fruaccess segment handle */ 659*7c478bd9Sstevel@tonic-gate seg_acc_hdl = hash_obj->u.seg_node->segment_hdl; 660*7c478bd9Sstevel@tonic-gate 661*7c478bd9Sstevel@tonic-gate /* call fruaccess to get new section handle */ 662*7c478bd9Sstevel@tonic-gate if (fru_delete_segment(seg_acc_hdl, &new_sec_acc_hdl, &warg->cred) 663*7c478bd9Sstevel@tonic-gate == -1) { 664*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 665*7c478bd9Sstevel@tonic-gate return (map_access_err(errno)); 666*7c478bd9Sstevel@tonic-gate } 667*7c478bd9Sstevel@tonic-gate 668*7c478bd9Sstevel@tonic-gate if (ptree_delete_node(warg->nodeh) != PICL_SUCCESS) { 669*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 670*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 671*7c478bd9Sstevel@tonic-gate } 672*7c478bd9Sstevel@tonic-gate 673*7c478bd9Sstevel@tonic-gate if (ptree_destroy_node(warg->nodeh) != PICL_SUCCESS) { 674*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 675*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 676*7c478bd9Sstevel@tonic-gate } 677*7c478bd9Sstevel@tonic-gate 678*7c478bd9Sstevel@tonic-gate 679*7c478bd9Sstevel@tonic-gate /* get section node handle */ 680*7c478bd9Sstevel@tonic-gate sec_nodehdl = hash_obj->u.seg_node->sec_nodehdl; 681*7c478bd9Sstevel@tonic-gate /* get section hash */ 682*7c478bd9Sstevel@tonic-gate hash_obj = lookup_node_object(sec_nodehdl, SECTION_NODE, cont_tbl); 683*7c478bd9Sstevel@tonic-gate if (hash_obj == NULL) { 684*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 685*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 686*7c478bd9Sstevel@tonic-gate } 687*7c478bd9Sstevel@tonic-gate 688*7c478bd9Sstevel@tonic-gate free_segment_node(hash_obj, warg->nodeh, cont_tbl); 689*7c478bd9Sstevel@tonic-gate 690*7c478bd9Sstevel@tonic-gate hash_obj->u.sec_node->num_of_segment = 0; 691*7c478bd9Sstevel@tonic-gate 692*7c478bd9Sstevel@tonic-gate /* call fruaccess with new section handle */ 693*7c478bd9Sstevel@tonic-gate num_of_segment = fru_get_num_segments(new_sec_acc_hdl, &warg->cred); 694*7c478bd9Sstevel@tonic-gate if (num_of_segment <= 0) { 695*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 696*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 697*7c478bd9Sstevel@tonic-gate } 698*7c478bd9Sstevel@tonic-gate 699*7c478bd9Sstevel@tonic-gate seg_buffer = alloca(sizeof (segment_t) * num_of_segment); 700*7c478bd9Sstevel@tonic-gate if (seg_buffer == NULL) { 701*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 702*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 703*7c478bd9Sstevel@tonic-gate } 704*7c478bd9Sstevel@tonic-gate 705*7c478bd9Sstevel@tonic-gate /* get all the segments */ 706*7c478bd9Sstevel@tonic-gate retval = fru_get_segments(new_sec_acc_hdl, seg_buffer, 707*7c478bd9Sstevel@tonic-gate num_of_segment, &warg->cred); 708*7c478bd9Sstevel@tonic-gate if (retval == -1) { 709*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 710*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 711*7c478bd9Sstevel@tonic-gate } 712*7c478bd9Sstevel@tonic-gate 713*7c478bd9Sstevel@tonic-gate seg_hash = hash_obj->u.sec_node->segment_list; 714*7c478bd9Sstevel@tonic-gate if (seg_hash == NULL) { 715*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 716*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 717*7c478bd9Sstevel@tonic-gate } 718*7c478bd9Sstevel@tonic-gate 719*7c478bd9Sstevel@tonic-gate /* rebuild the segment list */ 720*7c478bd9Sstevel@tonic-gate for (count = 0; count < num_of_segment; count++) { 721*7c478bd9Sstevel@tonic-gate desc = (fru_segdesc_t *)&seg_buffer[count].descriptor; 722*7c478bd9Sstevel@tonic-gate if (!(desc->field.field_perm & SEGMENT_READ)) { 723*7c478bd9Sstevel@tonic-gate continue; 724*7c478bd9Sstevel@tonic-gate } 725*7c478bd9Sstevel@tonic-gate 726*7c478bd9Sstevel@tonic-gate if (desc->field.opaque) { 727*7c478bd9Sstevel@tonic-gate continue; 728*7c478bd9Sstevel@tonic-gate } 729*7c478bd9Sstevel@tonic-gate 730*7c478bd9Sstevel@tonic-gate hash_obj->u.sec_node->num_of_segment++; 731*7c478bd9Sstevel@tonic-gate 732*7c478bd9Sstevel@tonic-gate seg_hash->u.seg_node->segment_hdl = seg_buffer[count].handle; 733*7c478bd9Sstevel@tonic-gate 734*7c478bd9Sstevel@tonic-gate num_of_pkt = 735*7c478bd9Sstevel@tonic-gate fru_get_num_packets(seg_buffer[count].handle, 736*7c478bd9Sstevel@tonic-gate &warg->cred); 737*7c478bd9Sstevel@tonic-gate if (num_of_pkt <= 0) { 738*7c478bd9Sstevel@tonic-gate continue; 739*7c478bd9Sstevel@tonic-gate } 740*7c478bd9Sstevel@tonic-gate 741*7c478bd9Sstevel@tonic-gate pkt_buf = alloca(sizeof (packet_t) * num_of_pkt); 742*7c478bd9Sstevel@tonic-gate if (pkt_buf == NULL) { 743*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 744*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 745*7c478bd9Sstevel@tonic-gate } 746*7c478bd9Sstevel@tonic-gate 747*7c478bd9Sstevel@tonic-gate retval = fru_get_packets(seg_buffer[count].handle, pkt_buf, 748*7c478bd9Sstevel@tonic-gate num_of_pkt, &warg->cred); 749*7c478bd9Sstevel@tonic-gate if (retval == -1) { 750*7c478bd9Sstevel@tonic-gate continue; 751*7c478bd9Sstevel@tonic-gate } 752*7c478bd9Sstevel@tonic-gate 753*7c478bd9Sstevel@tonic-gate pkt_hash = seg_hash->u.seg_node->packet_list; 754*7c478bd9Sstevel@tonic-gate if (pkt_hash == NULL) { 755*7c478bd9Sstevel@tonic-gate continue; 756*7c478bd9Sstevel@tonic-gate } 757*7c478bd9Sstevel@tonic-gate 758*7c478bd9Sstevel@tonic-gate /* rebuild the packet list */ 759*7c478bd9Sstevel@tonic-gate for (pkt_cnt = 0; pkt_cnt < num_of_pkt; pkt_cnt++) { 760*7c478bd9Sstevel@tonic-gate pkt_hash->u.pkt_node->pkt_handle = 761*7c478bd9Sstevel@tonic-gate pkt_buf[pkt_cnt].handle; 762*7c478bd9Sstevel@tonic-gate pkt_hash = pkt_hash->u.pkt_node->next; 763*7c478bd9Sstevel@tonic-gate } 764*7c478bd9Sstevel@tonic-gate 765*7c478bd9Sstevel@tonic-gate seg_hash = seg_hash->u.seg_node->next; 766*7c478bd9Sstevel@tonic-gate if (seg_hash == NULL) { 767*7c478bd9Sstevel@tonic-gate break; 768*7c478bd9Sstevel@tonic-gate } 769*7c478bd9Sstevel@tonic-gate } 770*7c478bd9Sstevel@tonic-gate 771*7c478bd9Sstevel@tonic-gate /* updated with new section handle */ 772*7c478bd9Sstevel@tonic-gate hash_obj->u.sec_node->section_hdl = new_sec_acc_hdl; 773*7c478bd9Sstevel@tonic-gate 774*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 775*7c478bd9Sstevel@tonic-gate 776*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 777*7c478bd9Sstevel@tonic-gate } 778*7c478bd9Sstevel@tonic-gate 779*7c478bd9Sstevel@tonic-gate /* 780*7c478bd9Sstevel@tonic-gate * Description : frudata_read_payload is called when volatile property 781*7c478bd9Sstevel@tonic-gate * payload is read. 782*7c478bd9Sstevel@tonic-gate * 783*7c478bd9Sstevel@tonic-gate * Arguments : ptree_rarg_t holds node handle of the table property. 784*7c478bd9Sstevel@tonic-gate * and property handle of the payload cell. 785*7c478bd9Sstevel@tonic-gate * p_buf contains payload data when function returns. 786*7c478bd9Sstevel@tonic-gate * 787*7c478bd9Sstevel@tonic-gate * Returns : PICL_SUCCESS on success. 788*7c478bd9Sstevel@tonic-gate * PICL_FAILURE on failure. 789*7c478bd9Sstevel@tonic-gate */ 790*7c478bd9Sstevel@tonic-gate 791*7c478bd9Sstevel@tonic-gate static int 792*7c478bd9Sstevel@tonic-gate frudata_read_payload(ptree_rarg_t *rarg, void *buf) 793*7c478bd9Sstevel@tonic-gate { 794*7c478bd9Sstevel@tonic-gate int num_bytes; 795*7c478bd9Sstevel@tonic-gate hash_obj_t *hash_obj; 796*7c478bd9Sstevel@tonic-gate fru_access_hdl_t pkt_acc_hdl; 797*7c478bd9Sstevel@tonic-gate container_tbl_t *cont_tbl; 798*7c478bd9Sstevel@tonic-gate 799*7c478bd9Sstevel@tonic-gate 800*7c478bd9Sstevel@tonic-gate cont_tbl = lock_container_lock(rarg->nodeh, SEGMENT_NODE, PICL_READ); 801*7c478bd9Sstevel@tonic-gate if (!cont_tbl) { 802*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 803*7c478bd9Sstevel@tonic-gate } 804*7c478bd9Sstevel@tonic-gate 805*7c478bd9Sstevel@tonic-gate hash_obj = lookup_node_object(rarg->proph, PACKET_NODE, cont_tbl); 806*7c478bd9Sstevel@tonic-gate if (hash_obj == NULL) { 807*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 808*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 809*7c478bd9Sstevel@tonic-gate } 810*7c478bd9Sstevel@tonic-gate 811*7c478bd9Sstevel@tonic-gate pkt_acc_hdl = hash_obj->u.pkt_node->pkt_handle; 812*7c478bd9Sstevel@tonic-gate 813*7c478bd9Sstevel@tonic-gate num_bytes = fru_get_payload(pkt_acc_hdl, buf, 814*7c478bd9Sstevel@tonic-gate hash_obj->u.pkt_node->paylen, &rarg->cred); 815*7c478bd9Sstevel@tonic-gate if (num_bytes != hash_obj->u.pkt_node->paylen) { 816*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 817*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 818*7c478bd9Sstevel@tonic-gate } 819*7c478bd9Sstevel@tonic-gate 820*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 821*7c478bd9Sstevel@tonic-gate 822*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 823*7c478bd9Sstevel@tonic-gate } 824*7c478bd9Sstevel@tonic-gate 825*7c478bd9Sstevel@tonic-gate /* 826*7c478bd9Sstevel@tonic-gate * Description : frudata_write_payload is called when payload property cell 827*7c478bd9Sstevel@tonic-gate * is accessed. 828*7c478bd9Sstevel@tonic-gate * 829*7c478bd9Sstevel@tonic-gate * Arguments : ptree_warg_t holds node handle of the packet-table. 830*7c478bd9Sstevel@tonic-gate * and property handle of the payload cell. 831*7c478bd9Sstevel@tonic-gate * p_buf contains payload data. 832*7c478bd9Sstevel@tonic-gate * 833*7c478bd9Sstevel@tonic-gate * Returns : PICL_SUCCESS on success. 834*7c478bd9Sstevel@tonic-gate * 835*7c478bd9Sstevel@tonic-gate */ 836*7c478bd9Sstevel@tonic-gate 837*7c478bd9Sstevel@tonic-gate static int 838*7c478bd9Sstevel@tonic-gate frudata_write_payload(ptree_warg_t *warg, const void *buf) 839*7c478bd9Sstevel@tonic-gate { 840*7c478bd9Sstevel@tonic-gate int retval; 841*7c478bd9Sstevel@tonic-gate hash_obj_t *hash_obj; 842*7c478bd9Sstevel@tonic-gate fru_access_hdl_t pkt_acc_hdl; 843*7c478bd9Sstevel@tonic-gate container_tbl_t *cont_tbl; 844*7c478bd9Sstevel@tonic-gate 845*7c478bd9Sstevel@tonic-gate cont_tbl = lock_container_lock(warg->nodeh, SEGMENT_NODE, PICL_WRITE); 846*7c478bd9Sstevel@tonic-gate if (!cont_tbl) { 847*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 848*7c478bd9Sstevel@tonic-gate } 849*7c478bd9Sstevel@tonic-gate 850*7c478bd9Sstevel@tonic-gate hash_obj = lookup_node_object(warg->proph, PACKET_NODE, cont_tbl); 851*7c478bd9Sstevel@tonic-gate if (hash_obj == NULL) { 852*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 853*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 854*7c478bd9Sstevel@tonic-gate } 855*7c478bd9Sstevel@tonic-gate 856*7c478bd9Sstevel@tonic-gate pkt_acc_hdl = hash_obj->u.pkt_node->pkt_handle; 857*7c478bd9Sstevel@tonic-gate 858*7c478bd9Sstevel@tonic-gate retval = fru_update_payload(pkt_acc_hdl, buf, 859*7c478bd9Sstevel@tonic-gate hash_obj->u.pkt_node->paylen, 860*7c478bd9Sstevel@tonic-gate &pkt_acc_hdl, &warg->cred); 861*7c478bd9Sstevel@tonic-gate if (retval == -1) { 862*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 863*7c478bd9Sstevel@tonic-gate return (map_access_err(errno)); 864*7c478bd9Sstevel@tonic-gate } 865*7c478bd9Sstevel@tonic-gate 866*7c478bd9Sstevel@tonic-gate hash_obj->u.pkt_node->pkt_handle = pkt_acc_hdl; 867*7c478bd9Sstevel@tonic-gate 868*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 869*7c478bd9Sstevel@tonic-gate 870*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 871*7c478bd9Sstevel@tonic-gate } 872*7c478bd9Sstevel@tonic-gate 873*7c478bd9Sstevel@tonic-gate /* 874*7c478bd9Sstevel@tonic-gate * callback volatile function is called when tag volatile property 875*7c478bd9Sstevel@tonic-gate * is accessed. this routine holds a read lock over the hash table 876*7c478bd9Sstevel@tonic-gate * and do a lookup over the property handle i.e property handle of 877*7c478bd9Sstevel@tonic-gate * the tag property passed in rarg parameter. 878*7c478bd9Sstevel@tonic-gate * tag value is copied into the buffer (void *buf). 879*7c478bd9Sstevel@tonic-gate */ 880*7c478bd9Sstevel@tonic-gate 881*7c478bd9Sstevel@tonic-gate static int 882*7c478bd9Sstevel@tonic-gate frudata_read_tag(ptree_rarg_t *rarg, void *buf) 883*7c478bd9Sstevel@tonic-gate { 884*7c478bd9Sstevel@tonic-gate int retval; 885*7c478bd9Sstevel@tonic-gate hash_obj_t *hash_obj; 886*7c478bd9Sstevel@tonic-gate picl_prophdl_t rowproph; 887*7c478bd9Sstevel@tonic-gate container_tbl_t *cont_tbl; 888*7c478bd9Sstevel@tonic-gate 889*7c478bd9Sstevel@tonic-gate cont_tbl = lock_container_lock(rarg->nodeh, SEGMENT_NODE, PICL_READ); 890*7c478bd9Sstevel@tonic-gate if (!cont_tbl) { 891*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 892*7c478bd9Sstevel@tonic-gate } 893*7c478bd9Sstevel@tonic-gate 894*7c478bd9Sstevel@tonic-gate retval = ptree_get_next_by_row(rarg->proph, &rowproph); 895*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) { 896*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 897*7c478bd9Sstevel@tonic-gate return (retval); 898*7c478bd9Sstevel@tonic-gate } 899*7c478bd9Sstevel@tonic-gate 900*7c478bd9Sstevel@tonic-gate hash_obj = lookup_node_object(rowproph, PACKET_NODE, cont_tbl); 901*7c478bd9Sstevel@tonic-gate if (hash_obj == NULL) { 902*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 903*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 904*7c478bd9Sstevel@tonic-gate } 905*7c478bd9Sstevel@tonic-gate 906*7c478bd9Sstevel@tonic-gate (void) memcpy(buf, &hash_obj->u.pkt_node->tag, sizeof (tag_t)); 907*7c478bd9Sstevel@tonic-gate 908*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 909*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 910*7c478bd9Sstevel@tonic-gate } 911*7c478bd9Sstevel@tonic-gate 912*7c478bd9Sstevel@tonic-gate 913*7c478bd9Sstevel@tonic-gate /* 914*7c478bd9Sstevel@tonic-gate * Description : create_packet_table() is called by fru_delete_packet_row(), 915*7c478bd9Sstevel@tonic-gate * to create a packet-table volatile property. it's called after 916*7c478bd9Sstevel@tonic-gate * deleting the packet-table. fru_delete_packet_row() calls 917*7c478bd9Sstevel@tonic-gate * frudata_read_packet_table() to add rows into the table. 918*7c478bd9Sstevel@tonic-gate */ 919*7c478bd9Sstevel@tonic-gate 920*7c478bd9Sstevel@tonic-gate static int 921*7c478bd9Sstevel@tonic-gate create_packet_table(picl_nodehdl_t seghdl, picl_prophdl_t *thdl) 922*7c478bd9Sstevel@tonic-gate { 923*7c478bd9Sstevel@tonic-gate int retval; 924*7c478bd9Sstevel@tonic-gate picl_prophdl_t tblhdl; 925*7c478bd9Sstevel@tonic-gate picl_nodehdl_t prophdl; 926*7c478bd9Sstevel@tonic-gate ptree_propinfo_t prop; 927*7c478bd9Sstevel@tonic-gate 928*7c478bd9Sstevel@tonic-gate retval = ptree_create_table(&tblhdl); 929*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) { 930*7c478bd9Sstevel@tonic-gate return (retval); 931*7c478bd9Sstevel@tonic-gate } 932*7c478bd9Sstevel@tonic-gate 933*7c478bd9Sstevel@tonic-gate prop.version = PTREE_PROPINFO_VERSION; 934*7c478bd9Sstevel@tonic-gate prop.piclinfo.type = PICL_PTYPE_TABLE; 935*7c478bd9Sstevel@tonic-gate prop.piclinfo.accessmode = PICL_READ|PICL_WRITE; 936*7c478bd9Sstevel@tonic-gate prop.piclinfo.size = sizeof (picl_prophdl_t); 937*7c478bd9Sstevel@tonic-gate prop.read = NULL; 938*7c478bd9Sstevel@tonic-gate prop.write = NULL; 939*7c478bd9Sstevel@tonic-gate (void) strcpy(prop.piclinfo.name, PICL_PROP_PACKET_TABLE); 940*7c478bd9Sstevel@tonic-gate 941*7c478bd9Sstevel@tonic-gate retval = ptree_create_and_add_prop(seghdl, &prop, &tblhdl, 942*7c478bd9Sstevel@tonic-gate &prophdl); 943*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) { 944*7c478bd9Sstevel@tonic-gate return (retval); 945*7c478bd9Sstevel@tonic-gate } 946*7c478bd9Sstevel@tonic-gate 947*7c478bd9Sstevel@tonic-gate /* hold the table handle */ 948*7c478bd9Sstevel@tonic-gate *thdl = tblhdl; 949*7c478bd9Sstevel@tonic-gate 950*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 951*7c478bd9Sstevel@tonic-gate } 952*7c478bd9Sstevel@tonic-gate 953*7c478bd9Sstevel@tonic-gate /* 954*7c478bd9Sstevel@tonic-gate * Description : frudata_delete_packet is called when write operation is 955*7c478bd9Sstevel@tonic-gate * performed on tag volatile property. 956*7c478bd9Sstevel@tonic-gate * 957*7c478bd9Sstevel@tonic-gate * 958*7c478bd9Sstevel@tonic-gate * Arguments : ptree_warg_t holds node handle to the segment node. 959*7c478bd9Sstevel@tonic-gate * and property handle of the tag cell in the packet table to be 960*7c478bd9Sstevel@tonic-gate * deleted. 961*7c478bd9Sstevel@tonic-gate * buf contains the tag data + plus DELETE_KEY_TAG 962*7c478bd9Sstevel@tonic-gate * 963*7c478bd9Sstevel@tonic-gate * Returns : PICL_SUCCESS on success 964*7c478bd9Sstevel@tonic-gate * 965*7c478bd9Sstevel@tonic-gate */ 966*7c478bd9Sstevel@tonic-gate 967*7c478bd9Sstevel@tonic-gate static int 968*7c478bd9Sstevel@tonic-gate frudata_delete_packet(ptree_warg_t *warg, const void *buf) 969*7c478bd9Sstevel@tonic-gate { 970*7c478bd9Sstevel@tonic-gate int count = 0; 971*7c478bd9Sstevel@tonic-gate int retval; 972*7c478bd9Sstevel@tonic-gate int num_of_pkt; 973*7c478bd9Sstevel@tonic-gate uint64_t tag; 974*7c478bd9Sstevel@tonic-gate packet_t *packet; 975*7c478bd9Sstevel@tonic-gate hash_obj_t *seg_hash_obj; 976*7c478bd9Sstevel@tonic-gate hash_obj_t *pkt_hash_obj; 977*7c478bd9Sstevel@tonic-gate container_tbl_t *cont_tbl; 978*7c478bd9Sstevel@tonic-gate picl_prophdl_t tblhdl; 979*7c478bd9Sstevel@tonic-gate picl_prophdl_t rowproph; 980*7c478bd9Sstevel@tonic-gate fru_access_hdl_t new_seg_acc_hdl; 981*7c478bd9Sstevel@tonic-gate 982*7c478bd9Sstevel@tonic-gate cont_tbl = lock_container_lock(warg->nodeh, SEGMENT_NODE, PICL_WRITE); 983*7c478bd9Sstevel@tonic-gate if (!cont_tbl) { 984*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 985*7c478bd9Sstevel@tonic-gate } 986*7c478bd9Sstevel@tonic-gate 987*7c478bd9Sstevel@tonic-gate /* get the payload property handle */ 988*7c478bd9Sstevel@tonic-gate retval = ptree_get_next_by_row(warg->proph, &rowproph); 989*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) { 990*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 991*7c478bd9Sstevel@tonic-gate return (retval); 992*7c478bd9Sstevel@tonic-gate } 993*7c478bd9Sstevel@tonic-gate 994*7c478bd9Sstevel@tonic-gate /* do lookup on payload property handle */ 995*7c478bd9Sstevel@tonic-gate pkt_hash_obj = lookup_node_object(rowproph, PACKET_NODE, cont_tbl); 996*7c478bd9Sstevel@tonic-gate if (pkt_hash_obj == NULL) { 997*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 998*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 999*7c478bd9Sstevel@tonic-gate } 1000*7c478bd9Sstevel@tonic-gate 1001*7c478bd9Sstevel@tonic-gate /* verify the tag */ 1002*7c478bd9Sstevel@tonic-gate tag = pkt_hash_obj->u.pkt_node->tag.raw_data; 1003*7c478bd9Sstevel@tonic-gate tag &= FRUDATA_DELETE_TAG_MASK; 1004*7c478bd9Sstevel@tonic-gate tag |= FRUDATA_DELETE_TAG_KEY; 1005*7c478bd9Sstevel@tonic-gate if (*(uint64_t *)buf != tag) { 1006*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1007*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1008*7c478bd9Sstevel@tonic-gate } 1009*7c478bd9Sstevel@tonic-gate 1010*7c478bd9Sstevel@tonic-gate /* call fruaccess module */ 1011*7c478bd9Sstevel@tonic-gate retval = fru_delete_packet(pkt_hash_obj->u.pkt_node->pkt_handle, 1012*7c478bd9Sstevel@tonic-gate &new_seg_acc_hdl, &warg->cred); 1013*7c478bd9Sstevel@tonic-gate if (retval == -1) { 1014*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1015*7c478bd9Sstevel@tonic-gate return (map_access_err(errno)); 1016*7c478bd9Sstevel@tonic-gate } 1017*7c478bd9Sstevel@tonic-gate 1018*7c478bd9Sstevel@tonic-gate /* delete the packet table */ 1019*7c478bd9Sstevel@tonic-gate retval = ptree_get_prop_by_name(warg->nodeh, PICL_PROP_PACKET_TABLE, 1020*7c478bd9Sstevel@tonic-gate &tblhdl); 1021*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) { 1022*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1023*7c478bd9Sstevel@tonic-gate return (retval); 1024*7c478bd9Sstevel@tonic-gate } 1025*7c478bd9Sstevel@tonic-gate 1026*7c478bd9Sstevel@tonic-gate retval = ptree_delete_prop(tblhdl); 1027*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) { 1028*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1029*7c478bd9Sstevel@tonic-gate return (retval); 1030*7c478bd9Sstevel@tonic-gate } 1031*7c478bd9Sstevel@tonic-gate 1032*7c478bd9Sstevel@tonic-gate retval = ptree_destroy_prop(tblhdl); 1033*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) { 1034*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1035*7c478bd9Sstevel@tonic-gate return (retval); 1036*7c478bd9Sstevel@tonic-gate } 1037*7c478bd9Sstevel@tonic-gate 1038*7c478bd9Sstevel@tonic-gate 1039*7c478bd9Sstevel@tonic-gate seg_hash_obj = lookup_node_object(warg->nodeh, SEGMENT_NODE, 1040*7c478bd9Sstevel@tonic-gate cont_tbl); 1041*7c478bd9Sstevel@tonic-gate if (seg_hash_obj == NULL) { 1042*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1043*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1044*7c478bd9Sstevel@tonic-gate } 1045*7c478bd9Sstevel@tonic-gate 1046*7c478bd9Sstevel@tonic-gate /* free all packet hash object */ 1047*7c478bd9Sstevel@tonic-gate free_packet_list(seg_hash_obj, cont_tbl); 1048*7c478bd9Sstevel@tonic-gate 1049*7c478bd9Sstevel@tonic-gate /* recreate the packet table */ 1050*7c478bd9Sstevel@tonic-gate retval = create_packet_table(warg->nodeh, &tblhdl); 1051*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) { 1052*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1053*7c478bd9Sstevel@tonic-gate return (retval); 1054*7c478bd9Sstevel@tonic-gate } 1055*7c478bd9Sstevel@tonic-gate 1056*7c478bd9Sstevel@tonic-gate seg_hash_obj->u.seg_node->segment_hdl = new_seg_acc_hdl; 1057*7c478bd9Sstevel@tonic-gate 1058*7c478bd9Sstevel@tonic-gate seg_hash_obj->u.seg_node->num_of_pkt = 0; 1059*7c478bd9Sstevel@tonic-gate 1060*7c478bd9Sstevel@tonic-gate num_of_pkt = fru_get_num_packets(new_seg_acc_hdl, &warg->cred); 1061*7c478bd9Sstevel@tonic-gate if (num_of_pkt == -1) { 1062*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1063*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1064*7c478bd9Sstevel@tonic-gate } 1065*7c478bd9Sstevel@tonic-gate 1066*7c478bd9Sstevel@tonic-gate if (num_of_pkt == 0) { 1067*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1068*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 1069*7c478bd9Sstevel@tonic-gate } 1070*7c478bd9Sstevel@tonic-gate 1071*7c478bd9Sstevel@tonic-gate packet = alloca(sizeof (packet_t) * num_of_pkt); 1072*7c478bd9Sstevel@tonic-gate if (packet == NULL) { 1073*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1074*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1075*7c478bd9Sstevel@tonic-gate } 1076*7c478bd9Sstevel@tonic-gate 1077*7c478bd9Sstevel@tonic-gate retval = fru_get_packets(new_seg_acc_hdl, packet, 1078*7c478bd9Sstevel@tonic-gate num_of_pkt, &warg->cred); 1079*7c478bd9Sstevel@tonic-gate if (retval == -1) { 1080*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1081*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1082*7c478bd9Sstevel@tonic-gate } 1083*7c478bd9Sstevel@tonic-gate 1084*7c478bd9Sstevel@tonic-gate /* rebuild the packet hash object */ 1085*7c478bd9Sstevel@tonic-gate for (count = 0; count < num_of_pkt; count++) { 1086*7c478bd9Sstevel@tonic-gate (void) add_row_to_table(seg_hash_obj, tblhdl, packet+count, 1087*7c478bd9Sstevel@tonic-gate cont_tbl); 1088*7c478bd9Sstevel@tonic-gate } 1089*7c478bd9Sstevel@tonic-gate 1090*7c478bd9Sstevel@tonic-gate seg_hash_obj->u.seg_node->num_of_pkt = num_of_pkt; 1091*7c478bd9Sstevel@tonic-gate 1092*7c478bd9Sstevel@tonic-gate (void) ptree_update_propval_by_name(warg->nodeh, PICL_PROP_NUM_TAGS, 1093*7c478bd9Sstevel@tonic-gate &num_of_pkt, sizeof (uint32_t)); 1094*7c478bd9Sstevel@tonic-gate 1095*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1096*7c478bd9Sstevel@tonic-gate 1097*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 1098*7c478bd9Sstevel@tonic-gate } 1099*7c478bd9Sstevel@tonic-gate 1100*7c478bd9Sstevel@tonic-gate /* 1101*7c478bd9Sstevel@tonic-gate * called from frudata_delete_packet(), frudata_add_packet(), 1102*7c478bd9Sstevel@tonic-gate * frudata_read_packet() callback routine to add packet into 1103*7c478bd9Sstevel@tonic-gate * the packet table. it also create hash node object for each 1104*7c478bd9Sstevel@tonic-gate * individual packet and add the object to the packet list. 1105*7c478bd9Sstevel@tonic-gate */ 1106*7c478bd9Sstevel@tonic-gate 1107*7c478bd9Sstevel@tonic-gate static int 1108*7c478bd9Sstevel@tonic-gate add_row_to_table(hash_obj_t *seg_obj, picl_nodehdl_t tblhdl, packet_t *pkt, 1109*7c478bd9Sstevel@tonic-gate container_tbl_t *cont_tbl) 1110*7c478bd9Sstevel@tonic-gate { 1111*7c478bd9Sstevel@tonic-gate int retval; 1112*7c478bd9Sstevel@tonic-gate int paylen; 1113*7c478bd9Sstevel@tonic-gate size_t tag_size; 1114*7c478bd9Sstevel@tonic-gate hash_obj_t *hash_obj; 1115*7c478bd9Sstevel@tonic-gate fru_tagtype_t tagtype; 1116*7c478bd9Sstevel@tonic-gate picl_prophdl_t prophdl[NUM_OF_COL_IN_PKT_TABLE]; 1117*7c478bd9Sstevel@tonic-gate ptree_propinfo_t prop; 1118*7c478bd9Sstevel@tonic-gate 1119*7c478bd9Sstevel@tonic-gate prop.version = PTREE_PROPINFO_VERSION; 1120*7c478bd9Sstevel@tonic-gate 1121*7c478bd9Sstevel@tonic-gate prop.piclinfo.type = PICL_PTYPE_BYTEARRAY; 1122*7c478bd9Sstevel@tonic-gate prop.piclinfo.accessmode = PICL_READ|PICL_WRITE|PICL_VOLATILE; 1123*7c478bd9Sstevel@tonic-gate prop.piclinfo.size = sizeof (fru_tag_t); 1124*7c478bd9Sstevel@tonic-gate prop.read = frudata_read_tag; 1125*7c478bd9Sstevel@tonic-gate prop.write = frudata_delete_packet; 1126*7c478bd9Sstevel@tonic-gate 1127*7c478bd9Sstevel@tonic-gate /* tag property node */ 1128*7c478bd9Sstevel@tonic-gate (void) strcpy(prop.piclinfo.name, PICL_PROP_TAG); 1129*7c478bd9Sstevel@tonic-gate 1130*7c478bd9Sstevel@tonic-gate paylen = get_payload_length((void *)&pkt->tag); 1131*7c478bd9Sstevel@tonic-gate if (paylen < 0) { 1132*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1133*7c478bd9Sstevel@tonic-gate } 1134*7c478bd9Sstevel@tonic-gate 1135*7c478bd9Sstevel@tonic-gate retval = ptree_create_prop(&prop, NULL, &prophdl[0]); 1136*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) { 1137*7c478bd9Sstevel@tonic-gate return (retval); 1138*7c478bd9Sstevel@tonic-gate } 1139*7c478bd9Sstevel@tonic-gate 1140*7c478bd9Sstevel@tonic-gate 1141*7c478bd9Sstevel@tonic-gate /* payload property node */ 1142*7c478bd9Sstevel@tonic-gate prop.piclinfo.type = PICL_PTYPE_BYTEARRAY; 1143*7c478bd9Sstevel@tonic-gate prop.piclinfo.size = paylen; 1144*7c478bd9Sstevel@tonic-gate (void) strcpy(prop.piclinfo.name, PICL_PROP_PAYLOAD); 1145*7c478bd9Sstevel@tonic-gate prop.piclinfo.accessmode = PICL_READ|PICL_WRITE|PICL_VOLATILE; 1146*7c478bd9Sstevel@tonic-gate prop.read = frudata_read_payload; 1147*7c478bd9Sstevel@tonic-gate prop.write = frudata_write_payload; 1148*7c478bd9Sstevel@tonic-gate 1149*7c478bd9Sstevel@tonic-gate retval = ptree_create_prop(&prop, NULL, &prophdl[1]); 1150*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) { 1151*7c478bd9Sstevel@tonic-gate return (retval); 1152*7c478bd9Sstevel@tonic-gate } 1153*7c478bd9Sstevel@tonic-gate 1154*7c478bd9Sstevel@tonic-gate hash_obj = alloc_packet_node_object(prophdl[1], pkt); 1155*7c478bd9Sstevel@tonic-gate if (hash_obj == NULL) { 1156*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1157*7c478bd9Sstevel@tonic-gate } 1158*7c478bd9Sstevel@tonic-gate 1159*7c478bd9Sstevel@tonic-gate retval = ptree_add_row_to_table(tblhdl, NUM_OF_COL_IN_PKT_TABLE, 1160*7c478bd9Sstevel@tonic-gate prophdl); 1161*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) { 1162*7c478bd9Sstevel@tonic-gate free(hash_obj); 1163*7c478bd9Sstevel@tonic-gate return (retval); 1164*7c478bd9Sstevel@tonic-gate } 1165*7c478bd9Sstevel@tonic-gate 1166*7c478bd9Sstevel@tonic-gate tagtype = get_tag_type((fru_tag_t *)&pkt->tag); 1167*7c478bd9Sstevel@tonic-gate if (tagtype == -1) { 1168*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1169*7c478bd9Sstevel@tonic-gate } 1170*7c478bd9Sstevel@tonic-gate 1171*7c478bd9Sstevel@tonic-gate tag_size = get_tag_size(tagtype); 1172*7c478bd9Sstevel@tonic-gate if (tag_size == (size_t)-1) { 1173*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1174*7c478bd9Sstevel@tonic-gate } 1175*7c478bd9Sstevel@tonic-gate 1176*7c478bd9Sstevel@tonic-gate hash_obj->u.pkt_node->paylen = paylen; 1177*7c478bd9Sstevel@tonic-gate hash_obj->u.pkt_node->tag.raw_data = 0; 1178*7c478bd9Sstevel@tonic-gate (void) memcpy(&hash_obj->u.pkt_node->tag, &pkt->tag, tag_size); 1179*7c478bd9Sstevel@tonic-gate 1180*7c478bd9Sstevel@tonic-gate add_nodeobject_to_hashtable(hash_obj, cont_tbl); 1181*7c478bd9Sstevel@tonic-gate 1182*7c478bd9Sstevel@tonic-gate add_to_packet_list(seg_obj, hash_obj); 1183*7c478bd9Sstevel@tonic-gate 1184*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 1185*7c478bd9Sstevel@tonic-gate } 1186*7c478bd9Sstevel@tonic-gate 1187*7c478bd9Sstevel@tonic-gate /* 1188*7c478bd9Sstevel@tonic-gate * called from frudata_read_segment() callback routine. it's called after 1189*7c478bd9Sstevel@tonic-gate * creating the packet table under class segment. this routine reads the 1190*7c478bd9Sstevel@tonic-gate * segment data to get total number of packets in the segments and add 1191*7c478bd9Sstevel@tonic-gate * the tag and payload data into the table. it calls add_row_to_table 1192*7c478bd9Sstevel@tonic-gate * routine to add individual row into the packet table. 1193*7c478bd9Sstevel@tonic-gate */ 1194*7c478bd9Sstevel@tonic-gate 1195*7c478bd9Sstevel@tonic-gate static int 1196*7c478bd9Sstevel@tonic-gate frudata_read_packet(picl_nodehdl_t nodeh, picl_prophdl_t *tblhdl, 1197*7c478bd9Sstevel@tonic-gate container_tbl_t *cont_tbl, door_cred_t *cred) 1198*7c478bd9Sstevel@tonic-gate { 1199*7c478bd9Sstevel@tonic-gate int cnt; 1200*7c478bd9Sstevel@tonic-gate int retval; 1201*7c478bd9Sstevel@tonic-gate int num_of_pkt; 1202*7c478bd9Sstevel@tonic-gate packet_t *packet; 1203*7c478bd9Sstevel@tonic-gate hash_obj_t *hash_obj; 1204*7c478bd9Sstevel@tonic-gate fru_access_hdl_t seg_acc_hdl; 1205*7c478bd9Sstevel@tonic-gate 1206*7c478bd9Sstevel@tonic-gate hash_obj = lookup_node_object(nodeh, SEGMENT_NODE, cont_tbl); 1207*7c478bd9Sstevel@tonic-gate if (hash_obj == NULL) { 1208*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1209*7c478bd9Sstevel@tonic-gate } 1210*7c478bd9Sstevel@tonic-gate 1211*7c478bd9Sstevel@tonic-gate if (hash_obj->u.seg_node->num_of_pkt == -1) { 1212*7c478bd9Sstevel@tonic-gate /* get the access handle */ 1213*7c478bd9Sstevel@tonic-gate seg_acc_hdl = hash_obj->u.seg_node->segment_hdl; 1214*7c478bd9Sstevel@tonic-gate /* get total number of packets */ 1215*7c478bd9Sstevel@tonic-gate num_of_pkt = fru_get_num_packets(seg_acc_hdl, cred); 1216*7c478bd9Sstevel@tonic-gate if (num_of_pkt < 0) { 1217*7c478bd9Sstevel@tonic-gate hash_obj->u.seg_node->num_of_pkt = 0; 1218*7c478bd9Sstevel@tonic-gate return (map_access_err(errno)); 1219*7c478bd9Sstevel@tonic-gate } 1220*7c478bd9Sstevel@tonic-gate 1221*7c478bd9Sstevel@tonic-gate if (num_of_pkt == 0) { 1222*7c478bd9Sstevel@tonic-gate hash_obj->u.seg_node->num_of_pkt = 0; 1223*7c478bd9Sstevel@tonic-gate return (0); 1224*7c478bd9Sstevel@tonic-gate } 1225*7c478bd9Sstevel@tonic-gate 1226*7c478bd9Sstevel@tonic-gate /* allocate buffer */ 1227*7c478bd9Sstevel@tonic-gate packet = alloca(sizeof (packet_t) * num_of_pkt); 1228*7c478bd9Sstevel@tonic-gate if (packet == NULL) { 1229*7c478bd9Sstevel@tonic-gate hash_obj->u.seg_node->num_of_pkt = 0; 1230*7c478bd9Sstevel@tonic-gate return (0); 1231*7c478bd9Sstevel@tonic-gate } 1232*7c478bd9Sstevel@tonic-gate 1233*7c478bd9Sstevel@tonic-gate /* get all the packet into the packet buffer */ 1234*7c478bd9Sstevel@tonic-gate retval = fru_get_packets(seg_acc_hdl, packet, num_of_pkt, cred); 1235*7c478bd9Sstevel@tonic-gate if (retval == -1) { 1236*7c478bd9Sstevel@tonic-gate return (0); 1237*7c478bd9Sstevel@tonic-gate } 1238*7c478bd9Sstevel@tonic-gate 1239*7c478bd9Sstevel@tonic-gate /* add payload and tag into the table. */ 1240*7c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < num_of_pkt; cnt++) { 1241*7c478bd9Sstevel@tonic-gate (void) add_row_to_table(hash_obj, *tblhdl, packet+cnt, 1242*7c478bd9Sstevel@tonic-gate cont_tbl); 1243*7c478bd9Sstevel@tonic-gate } 1244*7c478bd9Sstevel@tonic-gate 1245*7c478bd9Sstevel@tonic-gate hash_obj->u.seg_node->num_of_pkt = num_of_pkt; 1246*7c478bd9Sstevel@tonic-gate } 1247*7c478bd9Sstevel@tonic-gate return (0); 1248*7c478bd9Sstevel@tonic-gate } 1249*7c478bd9Sstevel@tonic-gate 1250*7c478bd9Sstevel@tonic-gate 1251*7c478bd9Sstevel@tonic-gate /* 1252*7c478bd9Sstevel@tonic-gate * Description : frudata_add_packet is called when add-packet volatile 1253*7c478bd9Sstevel@tonic-gate * property is accessed. 1254*7c478bd9Sstevel@tonic-gate * 1255*7c478bd9Sstevel@tonic-gate * Arguments : ptree_warg_t holds node handle of the segment node and 1256*7c478bd9Sstevel@tonic-gate * property handle of add-packet property. 1257*7c478bd9Sstevel@tonic-gate * p_buf- contains packet data to be added. 1258*7c478bd9Sstevel@tonic-gate * 1259*7c478bd9Sstevel@tonic-gate * Return : PICL_SUCCESS on success. 1260*7c478bd9Sstevel@tonic-gate * 1261*7c478bd9Sstevel@tonic-gate */ 1262*7c478bd9Sstevel@tonic-gate 1263*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 1264*7c478bd9Sstevel@tonic-gate static int 1265*7c478bd9Sstevel@tonic-gate frudata_add_packet(ptree_warg_t *warg, const void *buf) 1266*7c478bd9Sstevel@tonic-gate { 1267*7c478bd9Sstevel@tonic-gate size_t tag_size; 1268*7c478bd9Sstevel@tonic-gate int paylen; 1269*7c478bd9Sstevel@tonic-gate int retval; 1270*7c478bd9Sstevel@tonic-gate int num_of_pkt; 1271*7c478bd9Sstevel@tonic-gate int cnt; 1272*7c478bd9Sstevel@tonic-gate packet_t packet; 1273*7c478bd9Sstevel@tonic-gate packet_t *pkt_buf; 1274*7c478bd9Sstevel@tonic-gate hash_obj_t *hash_obj; 1275*7c478bd9Sstevel@tonic-gate hash_obj_t *pkt_hash; 1276*7c478bd9Sstevel@tonic-gate container_tbl_t *cont_tbl; 1277*7c478bd9Sstevel@tonic-gate fru_tagtype_t tagtype; 1278*7c478bd9Sstevel@tonic-gate picl_prophdl_t tblhdl; 1279*7c478bd9Sstevel@tonic-gate fru_access_hdl_t seg_acc_hdl; 1280*7c478bd9Sstevel@tonic-gate fru_access_hdl_t new_seg_acc_hdl; 1281*7c478bd9Sstevel@tonic-gate 1282*7c478bd9Sstevel@tonic-gate cont_tbl = lock_container_lock(warg->nodeh, SEGMENT_NODE, PICL_WRITE); 1283*7c478bd9Sstevel@tonic-gate if (!cont_tbl) { 1284*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1285*7c478bd9Sstevel@tonic-gate } 1286*7c478bd9Sstevel@tonic-gate 1287*7c478bd9Sstevel@tonic-gate hash_obj = lookup_node_object(warg->nodeh, SEGMENT_NODE, cont_tbl); 1288*7c478bd9Sstevel@tonic-gate if (hash_obj == NULL) { 1289*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1290*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1291*7c478bd9Sstevel@tonic-gate } 1292*7c478bd9Sstevel@tonic-gate 1293*7c478bd9Sstevel@tonic-gate seg_acc_hdl = hash_obj->u.seg_node->segment_hdl; 1294*7c478bd9Sstevel@tonic-gate 1295*7c478bd9Sstevel@tonic-gate tagtype = get_tag_type((void *)buf); 1296*7c478bd9Sstevel@tonic-gate if (tagtype == -1) { 1297*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1298*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1299*7c478bd9Sstevel@tonic-gate } 1300*7c478bd9Sstevel@tonic-gate 1301*7c478bd9Sstevel@tonic-gate tag_size = get_tag_size(tagtype); 1302*7c478bd9Sstevel@tonic-gate if (tag_size == (size_t)-1) { 1303*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1304*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1305*7c478bd9Sstevel@tonic-gate } 1306*7c478bd9Sstevel@tonic-gate 1307*7c478bd9Sstevel@tonic-gate paylen = get_payload_length((void *)buf); 1308*7c478bd9Sstevel@tonic-gate if (paylen == -1) { 1309*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1310*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1311*7c478bd9Sstevel@tonic-gate } 1312*7c478bd9Sstevel@tonic-gate 1313*7c478bd9Sstevel@tonic-gate packet.tag = 0; 1314*7c478bd9Sstevel@tonic-gate (void) memcpy(&packet.tag, buf, tag_size); 1315*7c478bd9Sstevel@tonic-gate 1316*7c478bd9Sstevel@tonic-gate retval = fru_append_packet(seg_acc_hdl, &packet, (char *)buf + tag_size, 1317*7c478bd9Sstevel@tonic-gate paylen, &new_seg_acc_hdl, &warg->cred); 1318*7c478bd9Sstevel@tonic-gate if (retval == -1) { 1319*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1320*7c478bd9Sstevel@tonic-gate return (map_access_err(errno)); 1321*7c478bd9Sstevel@tonic-gate } 1322*7c478bd9Sstevel@tonic-gate 1323*7c478bd9Sstevel@tonic-gate retval = ptree_get_propval_by_name(warg->nodeh, 1324*7c478bd9Sstevel@tonic-gate PICL_PROP_PACKET_TABLE, &tblhdl, sizeof (picl_prophdl_t)); 1325*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) { 1326*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1327*7c478bd9Sstevel@tonic-gate return (retval); 1328*7c478bd9Sstevel@tonic-gate } 1329*7c478bd9Sstevel@tonic-gate retval = add_row_to_table(hash_obj, tblhdl, &packet, cont_tbl); 1330*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) { 1331*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1332*7c478bd9Sstevel@tonic-gate return (retval); 1333*7c478bd9Sstevel@tonic-gate } 1334*7c478bd9Sstevel@tonic-gate 1335*7c478bd9Sstevel@tonic-gate num_of_pkt = fru_get_num_packets(new_seg_acc_hdl, &warg->cred); 1336*7c478bd9Sstevel@tonic-gate if (num_of_pkt == -1) { 1337*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1338*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1339*7c478bd9Sstevel@tonic-gate } 1340*7c478bd9Sstevel@tonic-gate 1341*7c478bd9Sstevel@tonic-gate pkt_buf = alloca(sizeof (packet_t) * num_of_pkt); 1342*7c478bd9Sstevel@tonic-gate if (pkt_buf == NULL) { 1343*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1344*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1345*7c478bd9Sstevel@tonic-gate } 1346*7c478bd9Sstevel@tonic-gate 1347*7c478bd9Sstevel@tonic-gate retval = fru_get_packets(new_seg_acc_hdl, pkt_buf, 1348*7c478bd9Sstevel@tonic-gate num_of_pkt, &warg->cred); 1349*7c478bd9Sstevel@tonic-gate if (retval == -1) { 1350*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1351*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1352*7c478bd9Sstevel@tonic-gate } 1353*7c478bd9Sstevel@tonic-gate 1354*7c478bd9Sstevel@tonic-gate pkt_hash = hash_obj->u.seg_node->packet_list; 1355*7c478bd9Sstevel@tonic-gate if (pkt_hash == NULL) { 1356*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1357*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1358*7c478bd9Sstevel@tonic-gate } 1359*7c478bd9Sstevel@tonic-gate 1360*7c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < num_of_pkt; cnt++) { 1361*7c478bd9Sstevel@tonic-gate pkt_hash->u.pkt_node->pkt_handle = pkt_buf[cnt].handle; 1362*7c478bd9Sstevel@tonic-gate pkt_hash = pkt_hash->u.pkt_node->next; 1363*7c478bd9Sstevel@tonic-gate } 1364*7c478bd9Sstevel@tonic-gate 1365*7c478bd9Sstevel@tonic-gate hash_obj->u.seg_node->num_of_pkt = num_of_pkt; 1366*7c478bd9Sstevel@tonic-gate 1367*7c478bd9Sstevel@tonic-gate (void) ptree_update_propval_by_name(warg->nodeh, PICL_PROP_NUM_TAGS, 1368*7c478bd9Sstevel@tonic-gate &num_of_pkt, sizeof (uint32_t)); 1369*7c478bd9Sstevel@tonic-gate 1370*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1371*7c478bd9Sstevel@tonic-gate 1372*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 1373*7c478bd9Sstevel@tonic-gate } 1374*7c478bd9Sstevel@tonic-gate 1375*7c478bd9Sstevel@tonic-gate static void 1376*7c478bd9Sstevel@tonic-gate freeup(picl_nodehdl_t nodeh) 1377*7c478bd9Sstevel@tonic-gate { 1378*7c478bd9Sstevel@tonic-gate (void) ptree_delete_node(nodeh); 1379*7c478bd9Sstevel@tonic-gate (void) ptree_destroy_node(nodeh); 1380*7c478bd9Sstevel@tonic-gate } 1381*7c478bd9Sstevel@tonic-gate 1382*7c478bd9Sstevel@tonic-gate /* 1383*7c478bd9Sstevel@tonic-gate * called by frudata_read_segment() and fru_data_add_segment() callback routine. 1384*7c478bd9Sstevel@tonic-gate * it's called to create a segment node and all it's property beneith the 1385*7c478bd9Sstevel@tonic-gate * segment node in the picl tree. 1386*7c478bd9Sstevel@tonic-gate */ 1387*7c478bd9Sstevel@tonic-gate 1388*7c478bd9Sstevel@tonic-gate static int 1389*7c478bd9Sstevel@tonic-gate create_segment_node(hash_obj_t *sec_obj, picl_nodehdl_t sec_node, 1390*7c478bd9Sstevel@tonic-gate segment_t *segment, container_tbl_t *cont_tbl, door_cred_t *cred) 1391*7c478bd9Sstevel@tonic-gate { 1392*7c478bd9Sstevel@tonic-gate 1393*7c478bd9Sstevel@tonic-gate int retval; 1394*7c478bd9Sstevel@tonic-gate char segname[SEG_NAME_LEN + 1]; 1395*7c478bd9Sstevel@tonic-gate uint32_t numoftags = 0; 1396*7c478bd9Sstevel@tonic-gate uint32_t protection; 1397*7c478bd9Sstevel@tonic-gate hash_obj_t *hash_obj; 1398*7c478bd9Sstevel@tonic-gate picl_nodehdl_t nodehdl; 1399*7c478bd9Sstevel@tonic-gate picl_prophdl_t prophdl; 1400*7c478bd9Sstevel@tonic-gate picl_nodehdl_t tblhdl; 1401*7c478bd9Sstevel@tonic-gate ptree_propinfo_t prop; 1402*7c478bd9Sstevel@tonic-gate 1403*7c478bd9Sstevel@tonic-gate (void) strlcpy(segname, segment->name, SEG_NAME_LEN + 1); 1404*7c478bd9Sstevel@tonic-gate segname[SEG_NAME_LEN] = '\0'; 1405*7c478bd9Sstevel@tonic-gate 1406*7c478bd9Sstevel@tonic-gate if (!(isprint(segname[0]) || isprint(segname[1]))) { 1407*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1408*7c478bd9Sstevel@tonic-gate } 1409*7c478bd9Sstevel@tonic-gate 1410*7c478bd9Sstevel@tonic-gate if (ptree_create_node(segname, PICL_CLASS_SEGMENT, &nodehdl) 1411*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 1412*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1413*7c478bd9Sstevel@tonic-gate } 1414*7c478bd9Sstevel@tonic-gate 1415*7c478bd9Sstevel@tonic-gate 1416*7c478bd9Sstevel@tonic-gate /* create property node */ 1417*7c478bd9Sstevel@tonic-gate prop.version = PTREE_PROPINFO_VERSION; 1418*7c478bd9Sstevel@tonic-gate prop.piclinfo.accessmode = PICL_READ; 1419*7c478bd9Sstevel@tonic-gate prop.read = NULL; 1420*7c478bd9Sstevel@tonic-gate prop.write = NULL; 1421*7c478bd9Sstevel@tonic-gate 1422*7c478bd9Sstevel@tonic-gate prop.piclinfo.type = PICL_PTYPE_UNSIGNED_INT; 1423*7c478bd9Sstevel@tonic-gate prop.piclinfo.size = sizeof (uint32_t); 1424*7c478bd9Sstevel@tonic-gate 1425*7c478bd9Sstevel@tonic-gate /* descriptor property */ 1426*7c478bd9Sstevel@tonic-gate (void) strcpy(prop.piclinfo.name, PICL_PROP_DESCRIPTOR); 1427*7c478bd9Sstevel@tonic-gate if (ptree_create_and_add_prop(nodehdl, &prop, &segment->descriptor, 1428*7c478bd9Sstevel@tonic-gate &prophdl) != PICL_SUCCESS) { 1429*7c478bd9Sstevel@tonic-gate freeup(nodehdl); 1430*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1431*7c478bd9Sstevel@tonic-gate } 1432*7c478bd9Sstevel@tonic-gate 1433*7c478bd9Sstevel@tonic-gate 1434*7c478bd9Sstevel@tonic-gate /* offset property */ 1435*7c478bd9Sstevel@tonic-gate (void) strcpy(prop.piclinfo.name, PICL_PROP_OFFSET); 1436*7c478bd9Sstevel@tonic-gate if (ptree_create_and_add_prop(nodehdl, &prop, &segment->offset, 1437*7c478bd9Sstevel@tonic-gate &prophdl) != PICL_SUCCESS) { 1438*7c478bd9Sstevel@tonic-gate freeup(nodehdl); 1439*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1440*7c478bd9Sstevel@tonic-gate } 1441*7c478bd9Sstevel@tonic-gate 1442*7c478bd9Sstevel@tonic-gate 1443*7c478bd9Sstevel@tonic-gate /* length property */ 1444*7c478bd9Sstevel@tonic-gate (void) strcpy(prop.piclinfo.name, PICL_PROP_LENGTH); 1445*7c478bd9Sstevel@tonic-gate if (ptree_create_and_add_prop(nodehdl, &prop, &segment->length, 1446*7c478bd9Sstevel@tonic-gate &prophdl) != PICL_SUCCESS) { 1447*7c478bd9Sstevel@tonic-gate freeup(nodehdl); 1448*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1449*7c478bd9Sstevel@tonic-gate } 1450*7c478bd9Sstevel@tonic-gate 1451*7c478bd9Sstevel@tonic-gate /* Number of Tags */ 1452*7c478bd9Sstevel@tonic-gate (void) strcpy(prop.piclinfo.name, PICL_PROP_NUM_TAGS); 1453*7c478bd9Sstevel@tonic-gate if (ptree_create_and_add_prop(nodehdl, &prop, &numoftags, &prophdl) 1454*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 1455*7c478bd9Sstevel@tonic-gate freeup(nodehdl); 1456*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1457*7c478bd9Sstevel@tonic-gate } 1458*7c478bd9Sstevel@tonic-gate 1459*7c478bd9Sstevel@tonic-gate if (create_packet_table(nodehdl, &tblhdl) != PICL_SUCCESS) { 1460*7c478bd9Sstevel@tonic-gate freeup(nodehdl); 1461*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1462*7c478bd9Sstevel@tonic-gate } 1463*7c478bd9Sstevel@tonic-gate 1464*7c478bd9Sstevel@tonic-gate retval = ptree_get_propval_by_name(sec_node, 1465*7c478bd9Sstevel@tonic-gate PICL_PROP_PROTECTED, &protection, sizeof (uint32_t)); 1466*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) { 1467*7c478bd9Sstevel@tonic-gate freeup(nodehdl); 1468*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1469*7c478bd9Sstevel@tonic-gate } 1470*7c478bd9Sstevel@tonic-gate 1471*7c478bd9Sstevel@tonic-gate if (protection == 0) { /* to be added only read/write section */ 1472*7c478bd9Sstevel@tonic-gate /* delete segment volatile property */ 1473*7c478bd9Sstevel@tonic-gate prop.piclinfo.type = PICL_PTYPE_UNSIGNED_INT; 1474*7c478bd9Sstevel@tonic-gate prop.piclinfo.size = sizeof (uint32_t); 1475*7c478bd9Sstevel@tonic-gate prop.piclinfo.accessmode = PICL_WRITE|PICL_VOLATILE; 1476*7c478bd9Sstevel@tonic-gate prop.write = frudata_delete_segment; 1477*7c478bd9Sstevel@tonic-gate prop.read = frudata_read_callback; 1478*7c478bd9Sstevel@tonic-gate 1479*7c478bd9Sstevel@tonic-gate (void) strcpy(prop.piclinfo.name, PICL_PROP_DELETE_SEGMENT); 1480*7c478bd9Sstevel@tonic-gate if (ptree_create_and_add_prop(nodehdl, &prop, NULL, &prophdl) 1481*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 1482*7c478bd9Sstevel@tonic-gate freeup(nodehdl); 1483*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1484*7c478bd9Sstevel@tonic-gate } 1485*7c478bd9Sstevel@tonic-gate 1486*7c478bd9Sstevel@tonic-gate 1487*7c478bd9Sstevel@tonic-gate /* add packet volatile property */ 1488*7c478bd9Sstevel@tonic-gate prop.piclinfo.type = PICL_PTYPE_BYTEARRAY; 1489*7c478bd9Sstevel@tonic-gate prop.piclinfo.size = segment->length; /* segment length */ 1490*7c478bd9Sstevel@tonic-gate prop.piclinfo.accessmode = PICL_READ|PICL_WRITE|PICL_VOLATILE; 1491*7c478bd9Sstevel@tonic-gate prop.read = frudata_read_callback; 1492*7c478bd9Sstevel@tonic-gate prop.write = frudata_add_packet; 1493*7c478bd9Sstevel@tonic-gate 1494*7c478bd9Sstevel@tonic-gate (void) strcpy(prop.piclinfo.name, PICL_PROP_ADD_PACKET); 1495*7c478bd9Sstevel@tonic-gate if (ptree_create_and_add_prop(nodehdl, &prop, NULL, &prophdl) 1496*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 1497*7c478bd9Sstevel@tonic-gate freeup(nodehdl); 1498*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1499*7c478bd9Sstevel@tonic-gate } 1500*7c478bd9Sstevel@tonic-gate } 1501*7c478bd9Sstevel@tonic-gate 1502*7c478bd9Sstevel@tonic-gate if (ptree_add_node(sec_node, nodehdl) != PICL_SUCCESS) { 1503*7c478bd9Sstevel@tonic-gate freeup(nodehdl); 1504*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1505*7c478bd9Sstevel@tonic-gate } 1506*7c478bd9Sstevel@tonic-gate 1507*7c478bd9Sstevel@tonic-gate hash_obj = alloc_segment_node_object(nodehdl, segment); 1508*7c478bd9Sstevel@tonic-gate if (hash_obj == NULL) { 1509*7c478bd9Sstevel@tonic-gate freeup(nodehdl); 1510*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1511*7c478bd9Sstevel@tonic-gate } 1512*7c478bd9Sstevel@tonic-gate 1513*7c478bd9Sstevel@tonic-gate add_nodeobject_to_hashtable(hash_obj, cont_tbl); 1514*7c478bd9Sstevel@tonic-gate 1515*7c478bd9Sstevel@tonic-gate add_to_segment_list(sec_obj, hash_obj); 1516*7c478bd9Sstevel@tonic-gate 1517*7c478bd9Sstevel@tonic-gate retval = frudata_read_packet(nodehdl, &tblhdl, cont_tbl, cred); 1518*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1519*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 1520*7c478bd9Sstevel@tonic-gate } 1521*7c478bd9Sstevel@tonic-gate 1522*7c478bd9Sstevel@tonic-gate (void) ptree_update_propval_by_name(nodehdl, PICL_PROP_NUM_TAGS, 1523*7c478bd9Sstevel@tonic-gate &hash_obj->u.seg_node->num_of_pkt, sizeof (uint32_t)); 1524*7c478bd9Sstevel@tonic-gate 1525*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 1526*7c478bd9Sstevel@tonic-gate } 1527*7c478bd9Sstevel@tonic-gate 1528*7c478bd9Sstevel@tonic-gate /* 1529*7c478bd9Sstevel@tonic-gate * Description :frudata_read_segment is called when num_segment volatile 1530*7c478bd9Sstevel@tonic-gate * property is accessed. 1531*7c478bd9Sstevel@tonic-gate * 1532*7c478bd9Sstevel@tonic-gate * Arguments : ptree_rarg_t contains node handle of the section node. 1533*7c478bd9Sstevel@tonic-gate * and property node of num_segments. 1534*7c478bd9Sstevel@tonic-gate * void * will hold number of segment. 1535*7c478bd9Sstevel@tonic-gate * 1536*7c478bd9Sstevel@tonic-gate * Returns : PICL_SUCCESS on success. 1537*7c478bd9Sstevel@tonic-gate * PICL_FAILURE on failure. 1538*7c478bd9Sstevel@tonic-gate */ 1539*7c478bd9Sstevel@tonic-gate 1540*7c478bd9Sstevel@tonic-gate static int 1541*7c478bd9Sstevel@tonic-gate frudata_read_segment(ptree_rarg_t *rarg, void *buf) 1542*7c478bd9Sstevel@tonic-gate { 1543*7c478bd9Sstevel@tonic-gate int num_of_segment; 1544*7c478bd9Sstevel@tonic-gate int cnt; 1545*7c478bd9Sstevel@tonic-gate int retval; 1546*7c478bd9Sstevel@tonic-gate segment_t *segment; 1547*7c478bd9Sstevel@tonic-gate hash_obj_t *hash_obj; 1548*7c478bd9Sstevel@tonic-gate fru_segdesc_t *desc; 1549*7c478bd9Sstevel@tonic-gate fru_access_hdl_t sec_acc_hdl; 1550*7c478bd9Sstevel@tonic-gate container_tbl_t *cont_tbl; 1551*7c478bd9Sstevel@tonic-gate 1552*7c478bd9Sstevel@tonic-gate cont_tbl = lock_container_lock(rarg->nodeh, SECTION_NODE, PICL_READ); 1553*7c478bd9Sstevel@tonic-gate if (!cont_tbl) { 1554*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1555*7c478bd9Sstevel@tonic-gate } 1556*7c478bd9Sstevel@tonic-gate 1557*7c478bd9Sstevel@tonic-gate hash_obj = lookup_node_object(rarg->nodeh, SECTION_NODE, cont_tbl); 1558*7c478bd9Sstevel@tonic-gate if (hash_obj == NULL) { 1559*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1560*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1561*7c478bd9Sstevel@tonic-gate } 1562*7c478bd9Sstevel@tonic-gate 1563*7c478bd9Sstevel@tonic-gate if (hash_obj->u.sec_node->num_of_segment == -1) { 1564*7c478bd9Sstevel@tonic-gate sec_acc_hdl = hash_obj->u.sec_node->section_hdl; 1565*7c478bd9Sstevel@tonic-gate 1566*7c478bd9Sstevel@tonic-gate hash_obj->u.sec_node->num_of_segment = 0; 1567*7c478bd9Sstevel@tonic-gate 1568*7c478bd9Sstevel@tonic-gate num_of_segment = fru_get_num_segments(sec_acc_hdl, 1569*7c478bd9Sstevel@tonic-gate &rarg->cred); 1570*7c478bd9Sstevel@tonic-gate if (num_of_segment < 0) { 1571*7c478bd9Sstevel@tonic-gate *(int *)buf = 0; 1572*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1573*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1574*7c478bd9Sstevel@tonic-gate } 1575*7c478bd9Sstevel@tonic-gate 1576*7c478bd9Sstevel@tonic-gate if (num_of_segment == 0) { 1577*7c478bd9Sstevel@tonic-gate *(int *)buf = 0; 1578*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1579*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 1580*7c478bd9Sstevel@tonic-gate } 1581*7c478bd9Sstevel@tonic-gate 1582*7c478bd9Sstevel@tonic-gate segment = alloca(sizeof (segment_t) * num_of_segment); 1583*7c478bd9Sstevel@tonic-gate if (segment == NULL) { 1584*7c478bd9Sstevel@tonic-gate *(int *)buf = 0; 1585*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1586*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 1587*7c478bd9Sstevel@tonic-gate } 1588*7c478bd9Sstevel@tonic-gate 1589*7c478bd9Sstevel@tonic-gate retval = fru_get_segments(sec_acc_hdl, segment, 1590*7c478bd9Sstevel@tonic-gate num_of_segment, &rarg->cred); 1591*7c478bd9Sstevel@tonic-gate if (retval == -1) { 1592*7c478bd9Sstevel@tonic-gate *(int *)buf = 0; 1593*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1594*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 1595*7c478bd9Sstevel@tonic-gate } 1596*7c478bd9Sstevel@tonic-gate 1597*7c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < num_of_segment; cnt++) { 1598*7c478bd9Sstevel@tonic-gate 1599*7c478bd9Sstevel@tonic-gate desc = (fru_segdesc_t *)&segment[cnt].descriptor; 1600*7c478bd9Sstevel@tonic-gate if (!(desc->field.field_perm & SEGMENT_READ)) { 1601*7c478bd9Sstevel@tonic-gate continue; 1602*7c478bd9Sstevel@tonic-gate } 1603*7c478bd9Sstevel@tonic-gate 1604*7c478bd9Sstevel@tonic-gate /* if opaque segment don't create segment node */ 1605*7c478bd9Sstevel@tonic-gate if (desc->field.opaque) { 1606*7c478bd9Sstevel@tonic-gate continue; 1607*7c478bd9Sstevel@tonic-gate } 1608*7c478bd9Sstevel@tonic-gate (void) create_segment_node(hash_obj, rarg->nodeh, 1609*7c478bd9Sstevel@tonic-gate &segment[cnt], cont_tbl, &rarg->cred); 1610*7c478bd9Sstevel@tonic-gate hash_obj->u.sec_node->num_of_segment++; 1611*7c478bd9Sstevel@tonic-gate } 1612*7c478bd9Sstevel@tonic-gate } 1613*7c478bd9Sstevel@tonic-gate 1614*7c478bd9Sstevel@tonic-gate /* return number of segment in the section */ 1615*7c478bd9Sstevel@tonic-gate *(int *)buf = hash_obj->u.sec_node->num_of_segment; 1616*7c478bd9Sstevel@tonic-gate 1617*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1618*7c478bd9Sstevel@tonic-gate 1619*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 1620*7c478bd9Sstevel@tonic-gate } 1621*7c478bd9Sstevel@tonic-gate 1622*7c478bd9Sstevel@tonic-gate 1623*7c478bd9Sstevel@tonic-gate /* 1624*7c478bd9Sstevel@tonic-gate * Description : frudata_add_segment is called when volatile property 1625*7c478bd9Sstevel@tonic-gate * add_segment under class node section is accessed. 1626*7c478bd9Sstevel@tonic-gate * 1627*7c478bd9Sstevel@tonic-gate * Arguments : ptree_warg_t holds node handle for the section node. 1628*7c478bd9Sstevel@tonic-gate * property handle for the add_segment property. 1629*7c478bd9Sstevel@tonic-gate * 1630*7c478bd9Sstevel@tonic-gate * Returns : PICL_SUCCESS on success. 1631*7c478bd9Sstevel@tonic-gate * PICL_FAILURE on failure. 1632*7c478bd9Sstevel@tonic-gate */ 1633*7c478bd9Sstevel@tonic-gate 1634*7c478bd9Sstevel@tonic-gate static int 1635*7c478bd9Sstevel@tonic-gate frudata_add_segment(ptree_warg_t *warg, const void *buf) 1636*7c478bd9Sstevel@tonic-gate { 1637*7c478bd9Sstevel@tonic-gate int retval; 1638*7c478bd9Sstevel@tonic-gate int cnt; 1639*7c478bd9Sstevel@tonic-gate int num_of_segment; 1640*7c478bd9Sstevel@tonic-gate segment_t *seg_buf; 1641*7c478bd9Sstevel@tonic-gate segment_t segment; 1642*7c478bd9Sstevel@tonic-gate hash_obj_t *seg_hash; 1643*7c478bd9Sstevel@tonic-gate hash_obj_t *hash_obj; 1644*7c478bd9Sstevel@tonic-gate container_tbl_t *cont_tbl; 1645*7c478bd9Sstevel@tonic-gate fru_segdef_t *seg_def; 1646*7c478bd9Sstevel@tonic-gate fru_segdesc_t *desc; 1647*7c478bd9Sstevel@tonic-gate fru_access_hdl_t new_sec_acc_hdl; 1648*7c478bd9Sstevel@tonic-gate 1649*7c478bd9Sstevel@tonic-gate seg_def = (fru_segdef_t *)buf; 1650*7c478bd9Sstevel@tonic-gate 1651*7c478bd9Sstevel@tonic-gate /* initialize segment_t */ 1652*7c478bd9Sstevel@tonic-gate segment.handle = 0; 1653*7c478bd9Sstevel@tonic-gate (void) memcpy(segment.name, seg_def->name, SEG_NAME_LEN); 1654*7c478bd9Sstevel@tonic-gate segment.descriptor = seg_def->desc.raw_data; 1655*7c478bd9Sstevel@tonic-gate segment.length = seg_def->size; /* segment length */ 1656*7c478bd9Sstevel@tonic-gate segment.offset = seg_def->address; /* segment offset */ 1657*7c478bd9Sstevel@tonic-gate 1658*7c478bd9Sstevel@tonic-gate desc = (fru_segdesc_t *)&segment.descriptor; 1659*7c478bd9Sstevel@tonic-gate if (!(desc->field.field_perm & SEGMENT_READ)) { 1660*7c478bd9Sstevel@tonic-gate return (PICL_PERMDENIED); 1661*7c478bd9Sstevel@tonic-gate } 1662*7c478bd9Sstevel@tonic-gate 1663*7c478bd9Sstevel@tonic-gate cont_tbl = lock_container_lock(warg->nodeh, SECTION_NODE, PICL_WRITE); 1664*7c478bd9Sstevel@tonic-gate if (!cont_tbl) { 1665*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1666*7c478bd9Sstevel@tonic-gate } 1667*7c478bd9Sstevel@tonic-gate 1668*7c478bd9Sstevel@tonic-gate hash_obj = lookup_node_object(warg->nodeh, SECTION_NODE, cont_tbl); 1669*7c478bd9Sstevel@tonic-gate if (hash_obj == NULL) { 1670*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1671*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1672*7c478bd9Sstevel@tonic-gate } 1673*7c478bd9Sstevel@tonic-gate 1674*7c478bd9Sstevel@tonic-gate /* call fruaccess module, get the new section handle. */ 1675*7c478bd9Sstevel@tonic-gate retval = fru_add_segment(hash_obj->u.sec_node->section_hdl, 1676*7c478bd9Sstevel@tonic-gate &segment, &new_sec_acc_hdl, &warg->cred); 1677*7c478bd9Sstevel@tonic-gate if (retval == -1) { 1678*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1679*7c478bd9Sstevel@tonic-gate return (map_access_err(errno)); 1680*7c478bd9Sstevel@tonic-gate } 1681*7c478bd9Sstevel@tonic-gate 1682*7c478bd9Sstevel@tonic-gate /* call access module with new section handle */ 1683*7c478bd9Sstevel@tonic-gate num_of_segment = fru_get_num_segments(new_sec_acc_hdl, &warg->cred); 1684*7c478bd9Sstevel@tonic-gate 1685*7c478bd9Sstevel@tonic-gate seg_buf = alloca(sizeof (segment_t) * num_of_segment); 1686*7c478bd9Sstevel@tonic-gate if (seg_buf == NULL) { 1687*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1688*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1689*7c478bd9Sstevel@tonic-gate } 1690*7c478bd9Sstevel@tonic-gate 1691*7c478bd9Sstevel@tonic-gate retval = fru_get_segments(new_sec_acc_hdl, seg_buf, 1692*7c478bd9Sstevel@tonic-gate num_of_segment, &warg->cred); 1693*7c478bd9Sstevel@tonic-gate if (retval == -1) { 1694*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1695*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1696*7c478bd9Sstevel@tonic-gate } 1697*7c478bd9Sstevel@tonic-gate 1698*7c478bd9Sstevel@tonic-gate segment.offset = seg_buf[(num_of_segment -1)].offset; 1699*7c478bd9Sstevel@tonic-gate segment.handle = seg_buf[(num_of_segment-1)].handle; 1700*7c478bd9Sstevel@tonic-gate 1701*7c478bd9Sstevel@tonic-gate (void) create_segment_node(hash_obj, warg->nodeh, &segment, 1702*7c478bd9Sstevel@tonic-gate cont_tbl, &warg->cred); 1703*7c478bd9Sstevel@tonic-gate 1704*7c478bd9Sstevel@tonic-gate /* rebuild segment list */ 1705*7c478bd9Sstevel@tonic-gate seg_hash = hash_obj->u.sec_node->segment_list; 1706*7c478bd9Sstevel@tonic-gate if (seg_hash == NULL) { 1707*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1708*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1709*7c478bd9Sstevel@tonic-gate } 1710*7c478bd9Sstevel@tonic-gate 1711*7c478bd9Sstevel@tonic-gate hash_obj->u.sec_node->num_of_segment = 0; 1712*7c478bd9Sstevel@tonic-gate 1713*7c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < num_of_segment; cnt++) { 1714*7c478bd9Sstevel@tonic-gate desc = (fru_segdesc_t *)&seg_buf[cnt].descriptor; 1715*7c478bd9Sstevel@tonic-gate if (!(desc->field.field_perm & SEGMENT_READ)) { 1716*7c478bd9Sstevel@tonic-gate continue; 1717*7c478bd9Sstevel@tonic-gate } 1718*7c478bd9Sstevel@tonic-gate 1719*7c478bd9Sstevel@tonic-gate /* if opaque segment don't create segment node */ 1720*7c478bd9Sstevel@tonic-gate if (desc->field.opaque) { 1721*7c478bd9Sstevel@tonic-gate continue; 1722*7c478bd9Sstevel@tonic-gate } 1723*7c478bd9Sstevel@tonic-gate 1724*7c478bd9Sstevel@tonic-gate seg_hash->u.seg_node->segment_hdl = 1725*7c478bd9Sstevel@tonic-gate seg_buf[cnt].handle; 1726*7c478bd9Sstevel@tonic-gate seg_hash = seg_hash->u.seg_node->next; 1727*7c478bd9Sstevel@tonic-gate hash_obj->u.sec_node->num_of_segment++; 1728*7c478bd9Sstevel@tonic-gate } 1729*7c478bd9Sstevel@tonic-gate 1730*7c478bd9Sstevel@tonic-gate /* update with new section handle */ 1731*7c478bd9Sstevel@tonic-gate hash_obj->u.sec_node->section_hdl = new_sec_acc_hdl; 1732*7c478bd9Sstevel@tonic-gate 1733*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1734*7c478bd9Sstevel@tonic-gate 1735*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 1736*7c478bd9Sstevel@tonic-gate } 1737*7c478bd9Sstevel@tonic-gate 1738*7c478bd9Sstevel@tonic-gate /* 1739*7c478bd9Sstevel@tonic-gate * called from frudata_write_section() callback routine to create 1740*7c478bd9Sstevel@tonic-gate * section node and all the property under class section. it also 1741*7c478bd9Sstevel@tonic-gate * allocate hash node object for each section in the container and 1742*7c478bd9Sstevel@tonic-gate * add the section node object in the section list. 1743*7c478bd9Sstevel@tonic-gate */ 1744*7c478bd9Sstevel@tonic-gate 1745*7c478bd9Sstevel@tonic-gate static int 1746*7c478bd9Sstevel@tonic-gate create_section_node(picl_nodehdl_t nodehdl, int section_count, 1747*7c478bd9Sstevel@tonic-gate section_t *section, container_tbl_t *cont_tbl) 1748*7c478bd9Sstevel@tonic-gate { 1749*7c478bd9Sstevel@tonic-gate char sec_name[SECNAMESIZE]; 1750*7c478bd9Sstevel@tonic-gate hash_obj_t *hash_obj; 1751*7c478bd9Sstevel@tonic-gate hash_obj_t *cont_hash; 1752*7c478bd9Sstevel@tonic-gate picl_nodehdl_t chld_node; 1753*7c478bd9Sstevel@tonic-gate picl_prophdl_t prophdl; 1754*7c478bd9Sstevel@tonic-gate ptree_propinfo_t prop; 1755*7c478bd9Sstevel@tonic-gate 1756*7c478bd9Sstevel@tonic-gate (void) snprintf(sec_name, SECNAMESIZE, "section%d", section_count); 1757*7c478bd9Sstevel@tonic-gate 1758*7c478bd9Sstevel@tonic-gate if (ptree_create_node(sec_name, PICL_CLASS_SECTION, &chld_node) 1759*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 1760*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1761*7c478bd9Sstevel@tonic-gate } 1762*7c478bd9Sstevel@tonic-gate prop.version = PTREE_PROPINFO_VERSION; 1763*7c478bd9Sstevel@tonic-gate prop.piclinfo.type = PICL_PTYPE_UNSIGNED_INT; 1764*7c478bd9Sstevel@tonic-gate prop.piclinfo.accessmode = PICL_READ; 1765*7c478bd9Sstevel@tonic-gate prop.piclinfo.size = sizeof (uint32_t); 1766*7c478bd9Sstevel@tonic-gate prop.read = NULL; 1767*7c478bd9Sstevel@tonic-gate prop.write = NULL; 1768*7c478bd9Sstevel@tonic-gate 1769*7c478bd9Sstevel@tonic-gate /* offset */ 1770*7c478bd9Sstevel@tonic-gate (void) strcpy(prop.piclinfo.name, PICL_PROP_OFFSET); 1771*7c478bd9Sstevel@tonic-gate if (ptree_create_and_add_prop(chld_node, &prop, §ion->offset, 1772*7c478bd9Sstevel@tonic-gate &prophdl) != PICL_SUCCESS) { 1773*7c478bd9Sstevel@tonic-gate freeup(chld_node); 1774*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1775*7c478bd9Sstevel@tonic-gate } 1776*7c478bd9Sstevel@tonic-gate 1777*7c478bd9Sstevel@tonic-gate /* length */ 1778*7c478bd9Sstevel@tonic-gate (void) strcpy(prop.piclinfo.name, PICL_PROP_LENGTH); 1779*7c478bd9Sstevel@tonic-gate if (ptree_create_and_add_prop(chld_node, &prop, §ion->length, 1780*7c478bd9Sstevel@tonic-gate &prophdl) != PICL_SUCCESS) { 1781*7c478bd9Sstevel@tonic-gate freeup(chld_node); 1782*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1783*7c478bd9Sstevel@tonic-gate } 1784*7c478bd9Sstevel@tonic-gate 1785*7c478bd9Sstevel@tonic-gate 1786*7c478bd9Sstevel@tonic-gate /* protected */ 1787*7c478bd9Sstevel@tonic-gate (void) strcpy(prop.piclinfo.name, PICL_PROP_PROTECTED); 1788*7c478bd9Sstevel@tonic-gate if (ptree_create_and_add_prop(chld_node, &prop, §ion->protection, 1789*7c478bd9Sstevel@tonic-gate &prophdl) != PICL_SUCCESS) { 1790*7c478bd9Sstevel@tonic-gate freeup(chld_node); 1791*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1792*7c478bd9Sstevel@tonic-gate } 1793*7c478bd9Sstevel@tonic-gate 1794*7c478bd9Sstevel@tonic-gate prop.piclinfo.accessmode = PICL_READ|PICL_VOLATILE; 1795*7c478bd9Sstevel@tonic-gate prop.read = frudata_read_segment; 1796*7c478bd9Sstevel@tonic-gate 1797*7c478bd9Sstevel@tonic-gate (void) strcpy(prop.piclinfo.name, PICL_PROP_NUM_SEGMENTS); 1798*7c478bd9Sstevel@tonic-gate 1799*7c478bd9Sstevel@tonic-gate if (ptree_create_and_add_prop(chld_node, &prop, NULL, &prophdl) 1800*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 1801*7c478bd9Sstevel@tonic-gate freeup(chld_node); 1802*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1803*7c478bd9Sstevel@tonic-gate } 1804*7c478bd9Sstevel@tonic-gate 1805*7c478bd9Sstevel@tonic-gate 1806*7c478bd9Sstevel@tonic-gate prop.piclinfo.type = PICL_PTYPE_BYTEARRAY; 1807*7c478bd9Sstevel@tonic-gate prop.piclinfo.size = sizeof (fru_segdef_t); 1808*7c478bd9Sstevel@tonic-gate 1809*7c478bd9Sstevel@tonic-gate prop.piclinfo.accessmode = PICL_WRITE|PICL_READ|PICL_VOLATILE; 1810*7c478bd9Sstevel@tonic-gate prop.write = frudata_add_segment; /* callback routine */ 1811*7c478bd9Sstevel@tonic-gate prop.read = frudata_read_callback; 1812*7c478bd9Sstevel@tonic-gate 1813*7c478bd9Sstevel@tonic-gate (void) strcpy(prop.piclinfo.name, PICL_PROP_ADD_SEGMENT); 1814*7c478bd9Sstevel@tonic-gate /* add-segment prop if read/write section */ 1815*7c478bd9Sstevel@tonic-gate if (section->protection == 0) { 1816*7c478bd9Sstevel@tonic-gate if (ptree_create_and_add_prop(chld_node, &prop, NULL, &prophdl) 1817*7c478bd9Sstevel@tonic-gate != PICL_SUCCESS) { 1818*7c478bd9Sstevel@tonic-gate freeup(chld_node); 1819*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1820*7c478bd9Sstevel@tonic-gate } 1821*7c478bd9Sstevel@tonic-gate } 1822*7c478bd9Sstevel@tonic-gate 1823*7c478bd9Sstevel@tonic-gate if (ptree_add_node(nodehdl, chld_node) != PICL_SUCCESS) { 1824*7c478bd9Sstevel@tonic-gate freeup(chld_node); 1825*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1826*7c478bd9Sstevel@tonic-gate } 1827*7c478bd9Sstevel@tonic-gate 1828*7c478bd9Sstevel@tonic-gate /* lookup for container handle */ 1829*7c478bd9Sstevel@tonic-gate cont_hash = lookup_node_object(nodehdl, CONTAINER_NODE, cont_tbl); 1830*7c478bd9Sstevel@tonic-gate if (cont_hash == NULL) { 1831*7c478bd9Sstevel@tonic-gate freeup(chld_node); 1832*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1833*7c478bd9Sstevel@tonic-gate } 1834*7c478bd9Sstevel@tonic-gate 1835*7c478bd9Sstevel@tonic-gate hash_obj = alloc_section_node_object(chld_node, section); 1836*7c478bd9Sstevel@tonic-gate if (hash_obj == NULL) { 1837*7c478bd9Sstevel@tonic-gate freeup(chld_node); 1838*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1839*7c478bd9Sstevel@tonic-gate } 1840*7c478bd9Sstevel@tonic-gate 1841*7c478bd9Sstevel@tonic-gate add_nodeobject_to_hashtable(hash_obj, cont_tbl); 1842*7c478bd9Sstevel@tonic-gate 1843*7c478bd9Sstevel@tonic-gate add_to_section_list(cont_hash, hash_obj); 1844*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 1845*7c478bd9Sstevel@tonic-gate } 1846*7c478bd9Sstevel@tonic-gate 1847*7c478bd9Sstevel@tonic-gate 1848*7c478bd9Sstevel@tonic-gate /* 1849*7c478bd9Sstevel@tonic-gate * Description :frudata_write_section is called when volatile container 1850*7c478bd9Sstevel@tonic-gate * property is accessed. it reads the section table associated 1851*7c478bd9Sstevel@tonic-gate * with the specified node handle(container) in ptree_rarg_t. 1852*7c478bd9Sstevel@tonic-gate * it calls search_root_node to search the node handle to open the 1853*7c478bd9Sstevel@tonic-gate * device associated with the node handle. it creates section 1854*7c478bd9Sstevel@tonic-gate * node and it's associated property. it also creates 1855*7c478bd9Sstevel@tonic-gate * volatile property num_segments. 1856*7c478bd9Sstevel@tonic-gate * 1857*7c478bd9Sstevel@tonic-gate * Argument : ptree_rarg_t : contains node handle of fru container the 1858*7c478bd9Sstevel@tonic-gate * container. 1859*7c478bd9Sstevel@tonic-gate * property handle of the container. 1860*7c478bd9Sstevel@tonic-gate * 1861*7c478bd9Sstevel@tonic-gate * Return : PICL_SUCCESS on success. 1862*7c478bd9Sstevel@tonic-gate * 1863*7c478bd9Sstevel@tonic-gate */ 1864*7c478bd9Sstevel@tonic-gate 1865*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 1866*7c478bd9Sstevel@tonic-gate 1867*7c478bd9Sstevel@tonic-gate static int 1868*7c478bd9Sstevel@tonic-gate frudata_write_section(ptree_warg_t *warg, const void *buf) 1869*7c478bd9Sstevel@tonic-gate { 1870*7c478bd9Sstevel@tonic-gate int retval; 1871*7c478bd9Sstevel@tonic-gate int num_of_section; 1872*7c478bd9Sstevel@tonic-gate int count; 1873*7c478bd9Sstevel@tonic-gate section_t *section; 1874*7c478bd9Sstevel@tonic-gate hash_obj_t *hash_obj; 1875*7c478bd9Sstevel@tonic-gate container_tbl_t *cont_tbl = NULL; 1876*7c478bd9Sstevel@tonic-gate fru_access_hdl_t cont_acc_hdl; 1877*7c478bd9Sstevel@tonic-gate 1878*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&cont_tbl_lock); 1879*7c478bd9Sstevel@tonic-gate 1880*7c478bd9Sstevel@tonic-gate /* 1881*7c478bd9Sstevel@tonic-gate * if lookup succeed return from this function with PICL_SUCCESS 1882*7c478bd9Sstevel@tonic-gate * because first write operation has already occurred on this container, 1883*7c478bd9Sstevel@tonic-gate * it also means that the container has been already initialzed. 1884*7c478bd9Sstevel@tonic-gate */ 1885*7c478bd9Sstevel@tonic-gate 1886*7c478bd9Sstevel@tonic-gate cont_tbl = lookup_container_table(warg->nodeh, CONTAINER_NODE); 1887*7c478bd9Sstevel@tonic-gate if (cont_tbl != NULL) { /* found the hash obj in the hash table */ 1888*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&cont_tbl_lock); 1889*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 1890*7c478bd9Sstevel@tonic-gate } 1891*7c478bd9Sstevel@tonic-gate 1892*7c478bd9Sstevel@tonic-gate /* 1893*7c478bd9Sstevel@tonic-gate * lookup failed that means this is first write on the 1894*7c478bd9Sstevel@tonic-gate * container property. allocate a new container hash table for this 1895*7c478bd9Sstevel@tonic-gate * new container and add to the cont_tbl hash table. 1896*7c478bd9Sstevel@tonic-gate */ 1897*7c478bd9Sstevel@tonic-gate 1898*7c478bd9Sstevel@tonic-gate cont_tbl = alloc_container_table(warg->nodeh); 1899*7c478bd9Sstevel@tonic-gate if (cont_tbl == NULL) { 1900*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&cont_tbl_lock); 1901*7c478bd9Sstevel@tonic-gate return (map_access_err(errno)); 1902*7c478bd9Sstevel@tonic-gate } 1903*7c478bd9Sstevel@tonic-gate 1904*7c478bd9Sstevel@tonic-gate hash_obj = alloc_container_node_object(warg->nodeh); 1905*7c478bd9Sstevel@tonic-gate if (hash_obj == NULL) { 1906*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&cont_tbl_lock); 1907*7c478bd9Sstevel@tonic-gate return (map_access_err(errno)); 1908*7c478bd9Sstevel@tonic-gate } 1909*7c478bd9Sstevel@tonic-gate 1910*7c478bd9Sstevel@tonic-gate /* add container table object to container table */ 1911*7c478bd9Sstevel@tonic-gate add_tblobject_to_container_tbl(cont_tbl); 1912*7c478bd9Sstevel@tonic-gate 1913*7c478bd9Sstevel@tonic-gate /* add the hash object to container hash table. */ 1914*7c478bd9Sstevel@tonic-gate add_nodeobject_to_hashtable(hash_obj, cont_tbl); 1915*7c478bd9Sstevel@tonic-gate 1916*7c478bd9Sstevel@tonic-gate while (pthread_rwlock_trywrlock(&cont_tbl->rwlock) == EBUSY) { 1917*7c478bd9Sstevel@tonic-gate pthread_cond_wait(&cont_tbl->cond_var, &cont_tbl_lock); 1918*7c478bd9Sstevel@tonic-gate } 1919*7c478bd9Sstevel@tonic-gate 1920*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&cont_tbl_lock); 1921*7c478bd9Sstevel@tonic-gate 1922*7c478bd9Sstevel@tonic-gate /* fruaccess handle */ 1923*7c478bd9Sstevel@tonic-gate cont_acc_hdl = hash_obj->u.cont_node->cont_hdl; 1924*7c478bd9Sstevel@tonic-gate 1925*7c478bd9Sstevel@tonic-gate num_of_section = fru_get_num_sections(cont_acc_hdl, &warg->cred); 1926*7c478bd9Sstevel@tonic-gate 1927*7c478bd9Sstevel@tonic-gate if (num_of_section == -1) { 1928*7c478bd9Sstevel@tonic-gate free(hash_obj); 1929*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1930*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1931*7c478bd9Sstevel@tonic-gate } 1932*7c478bd9Sstevel@tonic-gate 1933*7c478bd9Sstevel@tonic-gate section = alloca(num_of_section * sizeof (section_t)); 1934*7c478bd9Sstevel@tonic-gate 1935*7c478bd9Sstevel@tonic-gate retval = fru_get_sections(cont_acc_hdl, section, 1936*7c478bd9Sstevel@tonic-gate num_of_section, &warg->cred); 1937*7c478bd9Sstevel@tonic-gate if (retval == -1) { 1938*7c478bd9Sstevel@tonic-gate free(hash_obj); 1939*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1940*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1941*7c478bd9Sstevel@tonic-gate } 1942*7c478bd9Sstevel@tonic-gate 1943*7c478bd9Sstevel@tonic-gate hash_obj->u.cont_node->num_of_section = num_of_section; 1944*7c478bd9Sstevel@tonic-gate 1945*7c478bd9Sstevel@tonic-gate for (count = 0; count < num_of_section; count++) { 1946*7c478bd9Sstevel@tonic-gate (void) create_section_node(warg->nodeh, count, 1947*7c478bd9Sstevel@tonic-gate section + count, cont_tbl); 1948*7c478bd9Sstevel@tonic-gate } 1949*7c478bd9Sstevel@tonic-gate 1950*7c478bd9Sstevel@tonic-gate unlock_container_lock(cont_tbl); 1951*7c478bd9Sstevel@tonic-gate 1952*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 1953*7c478bd9Sstevel@tonic-gate } 1954*7c478bd9Sstevel@tonic-gate 1955*7c478bd9Sstevel@tonic-gate /* create container and add-segment property */ 1956*7c478bd9Sstevel@tonic-gate 1957*7c478bd9Sstevel@tonic-gate static int 1958*7c478bd9Sstevel@tonic-gate create_container_prop(picl_nodehdl_t fruhdl) 1959*7c478bd9Sstevel@tonic-gate { 1960*7c478bd9Sstevel@tonic-gate int retval; 1961*7c478bd9Sstevel@tonic-gate picl_prophdl_t prophdl; 1962*7c478bd9Sstevel@tonic-gate ptree_propinfo_t prop; 1963*7c478bd9Sstevel@tonic-gate 1964*7c478bd9Sstevel@tonic-gate prop.version = PTREE_PROPINFO_VERSION; 1965*7c478bd9Sstevel@tonic-gate prop.piclinfo.type = PICL_PTYPE_UNSIGNED_INT; 1966*7c478bd9Sstevel@tonic-gate prop.piclinfo.size = sizeof (uint32_t); 1967*7c478bd9Sstevel@tonic-gate prop.piclinfo.accessmode = PICL_WRITE|PICL_VOLATILE; 1968*7c478bd9Sstevel@tonic-gate (void) strcpy(prop.piclinfo.name, PICL_PROP_CONTAINER); 1969*7c478bd9Sstevel@tonic-gate prop.read = frudata_read_callback; 1970*7c478bd9Sstevel@tonic-gate prop.write = frudata_write_section; /* callback routine */ 1971*7c478bd9Sstevel@tonic-gate 1972*7c478bd9Sstevel@tonic-gate /* create a property */ 1973*7c478bd9Sstevel@tonic-gate retval = ptree_create_and_add_prop(fruhdl, &prop, NULL, &prophdl); 1974*7c478bd9Sstevel@tonic-gate 1975*7c478bd9Sstevel@tonic-gate return (retval); 1976*7c478bd9Sstevel@tonic-gate } 1977*7c478bd9Sstevel@tonic-gate 1978*7c478bd9Sstevel@tonic-gate /* search for FRUDataAvailable and create container and add segment property */ 1979*7c478bd9Sstevel@tonic-gate 1980*7c478bd9Sstevel@tonic-gate static void 1981*7c478bd9Sstevel@tonic-gate create_frudata_props(picl_prophdl_t fruhdl) 1982*7c478bd9Sstevel@tonic-gate { 1983*7c478bd9Sstevel@tonic-gate int retval; 1984*7c478bd9Sstevel@tonic-gate picl_nodehdl_t chldhdl; 1985*7c478bd9Sstevel@tonic-gate picl_nodehdl_t tmphdl; 1986*7c478bd9Sstevel@tonic-gate 1987*7c478bd9Sstevel@tonic-gate for (retval = ptree_get_propval_by_name(fruhdl, PICL_PROP_CHILD, 1988*7c478bd9Sstevel@tonic-gate &chldhdl, sizeof (picl_nodehdl_t)); retval != PICL_PROPNOTFOUND; 1989*7c478bd9Sstevel@tonic-gate retval = ptree_get_propval_by_name(chldhdl, PICL_PROP_PEER, 1990*7c478bd9Sstevel@tonic-gate &chldhdl, sizeof (picl_nodehdl_t))) { 1991*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) 1992*7c478bd9Sstevel@tonic-gate return; 1993*7c478bd9Sstevel@tonic-gate 1994*7c478bd9Sstevel@tonic-gate /* Does it have a FRUDataAvailable property */ 1995*7c478bd9Sstevel@tonic-gate retval = ptree_get_prop_by_name(chldhdl, 1996*7c478bd9Sstevel@tonic-gate PICL_PROP_FRUDATA_AVAIL, &tmphdl); 1997*7c478bd9Sstevel@tonic-gate if (retval == PICL_SUCCESS) { 1998*7c478bd9Sstevel@tonic-gate (void) create_container_prop(chldhdl); 1999*7c478bd9Sstevel@tonic-gate } 2000*7c478bd9Sstevel@tonic-gate 2001*7c478bd9Sstevel@tonic-gate /* Traverse tree recursively */ 2002*7c478bd9Sstevel@tonic-gate (void) create_frudata_props(chldhdl); 2003*7c478bd9Sstevel@tonic-gate } 2004*7c478bd9Sstevel@tonic-gate } 2005*7c478bd9Sstevel@tonic-gate 2006*7c478bd9Sstevel@tonic-gate /* 2007*7c478bd9Sstevel@tonic-gate * Search for the frutree config file from the platform specific 2008*7c478bd9Sstevel@tonic-gate * directory to the common directory. 2009*7c478bd9Sstevel@tonic-gate * 2010*7c478bd9Sstevel@tonic-gate * The size of outfilename must be PATH_MAX 2011*7c478bd9Sstevel@tonic-gate */ 2012*7c478bd9Sstevel@tonic-gate static int 2013*7c478bd9Sstevel@tonic-gate get_config_file(char *outfilename) 2014*7c478bd9Sstevel@tonic-gate { 2015*7c478bd9Sstevel@tonic-gate char nmbuf[SYS_NMLN]; 2016*7c478bd9Sstevel@tonic-gate char pname[PATH_MAX]; 2017*7c478bd9Sstevel@tonic-gate 2018*7c478bd9Sstevel@tonic-gate if (sysinfo(SI_PLATFORM, nmbuf, sizeof (nmbuf)) != -1) { 2019*7c478bd9Sstevel@tonic-gate (void) snprintf(pname, PATH_MAX, FRUDATA_CONFFILE_NAME, nmbuf); 2020*7c478bd9Sstevel@tonic-gate if (access(pname, R_OK) == 0) { 2021*7c478bd9Sstevel@tonic-gate (void) strlcpy(outfilename, pname, PATH_MAX); 2022*7c478bd9Sstevel@tonic-gate return (0); 2023*7c478bd9Sstevel@tonic-gate } 2024*7c478bd9Sstevel@tonic-gate } 2025*7c478bd9Sstevel@tonic-gate 2026*7c478bd9Sstevel@tonic-gate if (sysinfo(SI_MACHINE, nmbuf, sizeof (nmbuf)) != -1) { 2027*7c478bd9Sstevel@tonic-gate (void) snprintf(pname, PATH_MAX, FRUDATA_CONFFILE_NAME, nmbuf); 2028*7c478bd9Sstevel@tonic-gate if (access(pname, R_OK) == 0) { 2029*7c478bd9Sstevel@tonic-gate (void) strlcpy(outfilename, pname, PATH_MAX); 2030*7c478bd9Sstevel@tonic-gate return (0); 2031*7c478bd9Sstevel@tonic-gate } 2032*7c478bd9Sstevel@tonic-gate } 2033*7c478bd9Sstevel@tonic-gate 2034*7c478bd9Sstevel@tonic-gate (void) snprintf(pname, PATH_MAX, "%s/%s", PICLD_COMMON_PLUGIN_DIR, 2035*7c478bd9Sstevel@tonic-gate FRUDATA_CONFFILE_NAME); 2036*7c478bd9Sstevel@tonic-gate if (access(pname, R_OK) == 0) { 2037*7c478bd9Sstevel@tonic-gate (void) strlcpy(outfilename, pname, PATH_MAX); 2038*7c478bd9Sstevel@tonic-gate return (0); 2039*7c478bd9Sstevel@tonic-gate } 2040*7c478bd9Sstevel@tonic-gate return (-1); 2041*7c478bd9Sstevel@tonic-gate } 2042*7c478bd9Sstevel@tonic-gate 2043*7c478bd9Sstevel@tonic-gate /* 2044*7c478bd9Sstevel@tonic-gate * called from delete_frudata_props(), this routine delete the section node 2045*7c478bd9Sstevel@tonic-gate * and free's the section hash object. it calls free_segment_node() to 2046*7c478bd9Sstevel@tonic-gate * delete segment node beneath it. 2047*7c478bd9Sstevel@tonic-gate */ 2048*7c478bd9Sstevel@tonic-gate 2049*7c478bd9Sstevel@tonic-gate static void 2050*7c478bd9Sstevel@tonic-gate free_section_node(hash_obj_t *sec_hash, container_tbl_t *cont_tbl) 2051*7c478bd9Sstevel@tonic-gate { 2052*7c478bd9Sstevel@tonic-gate hash_obj_t *seg_hash; 2053*7c478bd9Sstevel@tonic-gate 2054*7c478bd9Sstevel@tonic-gate for (seg_hash = sec_hash->u.sec_node->segment_list; seg_hash != NULL; 2055*7c478bd9Sstevel@tonic-gate seg_hash = seg_hash->u.seg_node->next) { 2056*7c478bd9Sstevel@tonic-gate free_segment_node(seg_hash, seg_hash->picl_hdl, cont_tbl); 2057*7c478bd9Sstevel@tonic-gate } 2058*7c478bd9Sstevel@tonic-gate 2059*7c478bd9Sstevel@tonic-gate if (sec_hash->prev == NULL) { 2060*7c478bd9Sstevel@tonic-gate cont_tbl->hash_obj[(sec_hash->picl_hdl % TABLE_SIZE)].next = 2061*7c478bd9Sstevel@tonic-gate sec_hash->next; 2062*7c478bd9Sstevel@tonic-gate if (sec_hash->next != NULL) { 2063*7c478bd9Sstevel@tonic-gate sec_hash->next->prev = NULL; 2064*7c478bd9Sstevel@tonic-gate } 2065*7c478bd9Sstevel@tonic-gate } else { 2066*7c478bd9Sstevel@tonic-gate sec_hash->prev->next = sec_hash->next; 2067*7c478bd9Sstevel@tonic-gate if (sec_hash->next != NULL) { 2068*7c478bd9Sstevel@tonic-gate sec_hash->next->prev = sec_hash->prev; 2069*7c478bd9Sstevel@tonic-gate } 2070*7c478bd9Sstevel@tonic-gate } 2071*7c478bd9Sstevel@tonic-gate 2072*7c478bd9Sstevel@tonic-gate /* delete & destroy section node */ 2073*7c478bd9Sstevel@tonic-gate (void) ptree_delete_node(sec_hash->picl_hdl); 2074*7c478bd9Sstevel@tonic-gate (void) ptree_destroy_node(sec_hash->picl_hdl); 2075*7c478bd9Sstevel@tonic-gate 2076*7c478bd9Sstevel@tonic-gate free(sec_hash->u.sec_node); 2077*7c478bd9Sstevel@tonic-gate free(sec_hash); 2078*7c478bd9Sstevel@tonic-gate } 2079*7c478bd9Sstevel@tonic-gate 2080*7c478bd9Sstevel@tonic-gate /* 2081*7c478bd9Sstevel@tonic-gate * called from delete_frudata_props(), this routine free's the container 2082*7c478bd9Sstevel@tonic-gate * hash object. 2083*7c478bd9Sstevel@tonic-gate */ 2084*7c478bd9Sstevel@tonic-gate 2085*7c478bd9Sstevel@tonic-gate static void 2086*7c478bd9Sstevel@tonic-gate unlink_container_node(container_tbl_t *cont_hash) 2087*7c478bd9Sstevel@tonic-gate { 2088*7c478bd9Sstevel@tonic-gate if (cont_hash->prev == NULL) { 2089*7c478bd9Sstevel@tonic-gate container_table[(cont_hash->picl_hdl % TABLE_SIZE)] = 2090*7c478bd9Sstevel@tonic-gate cont_hash->next; 2091*7c478bd9Sstevel@tonic-gate if (cont_hash->next != NULL) { 2092*7c478bd9Sstevel@tonic-gate cont_hash->next->prev = NULL; 2093*7c478bd9Sstevel@tonic-gate } 2094*7c478bd9Sstevel@tonic-gate } else { 2095*7c478bd9Sstevel@tonic-gate cont_hash->prev->next = cont_hash->next; 2096*7c478bd9Sstevel@tonic-gate if (cont_hash->next != NULL) { 2097*7c478bd9Sstevel@tonic-gate cont_hash->next->prev = cont_hash->prev; 2098*7c478bd9Sstevel@tonic-gate } 2099*7c478bd9Sstevel@tonic-gate } 2100*7c478bd9Sstevel@tonic-gate } 2101*7c478bd9Sstevel@tonic-gate 2102*7c478bd9Sstevel@tonic-gate /* 2103*7c478bd9Sstevel@tonic-gate * called from frudata_event_handler() to free the corresponding hash object 2104*7c478bd9Sstevel@tonic-gate * of the removed fru. 2105*7c478bd9Sstevel@tonic-gate */ 2106*7c478bd9Sstevel@tonic-gate 2107*7c478bd9Sstevel@tonic-gate static void 2108*7c478bd9Sstevel@tonic-gate delete_frudata_props(picl_nodehdl_t fru_hdl) 2109*7c478bd9Sstevel@tonic-gate { 2110*7c478bd9Sstevel@tonic-gate hash_obj_t *cont_hash; 2111*7c478bd9Sstevel@tonic-gate hash_obj_t *free_obj; 2112*7c478bd9Sstevel@tonic-gate hash_obj_t *sec_hash; 2113*7c478bd9Sstevel@tonic-gate container_tbl_t *cont_tbl; 2114*7c478bd9Sstevel@tonic-gate 2115*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&cont_tbl_lock); 2116*7c478bd9Sstevel@tonic-gate 2117*7c478bd9Sstevel@tonic-gate cont_tbl = lookup_container_table(fru_hdl, CONTAINER_NODE); 2118*7c478bd9Sstevel@tonic-gate if (cont_tbl == NULL) { 2119*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&cont_tbl_lock); 2120*7c478bd9Sstevel@tonic-gate return; 2121*7c478bd9Sstevel@tonic-gate } 2122*7c478bd9Sstevel@tonic-gate 2123*7c478bd9Sstevel@tonic-gate /* remove the container object from the container table */ 2124*7c478bd9Sstevel@tonic-gate unlink_container_node(cont_tbl); 2125*7c478bd9Sstevel@tonic-gate 2126*7c478bd9Sstevel@tonic-gate (void) pthread_cond_broadcast(&cont_tbl->cond_var); 2127*7c478bd9Sstevel@tonic-gate 2128*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&cont_tbl_lock); 2129*7c478bd9Sstevel@tonic-gate 2130*7c478bd9Sstevel@tonic-gate /* 2131*7c478bd9Sstevel@tonic-gate * waiting/blocking calling thread for all I/O in 2132*7c478bd9Sstevel@tonic-gate * progress to complete. don't free the container 2133*7c478bd9Sstevel@tonic-gate * hash before all I/O is complete. 2134*7c478bd9Sstevel@tonic-gate */ 2135*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_wrlock(&cont_tbl->rwlock); 2136*7c478bd9Sstevel@tonic-gate 2137*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&cont_tbl->rwlock); 2138*7c478bd9Sstevel@tonic-gate 2139*7c478bd9Sstevel@tonic-gate 2140*7c478bd9Sstevel@tonic-gate cont_hash = lookup_node_object(fru_hdl, CONTAINER_NODE, cont_tbl); 2141*7c478bd9Sstevel@tonic-gate if (cont_hash == NULL) { 2142*7c478bd9Sstevel@tonic-gate return; 2143*7c478bd9Sstevel@tonic-gate } 2144*7c478bd9Sstevel@tonic-gate 2145*7c478bd9Sstevel@tonic-gate free_obj = cont_hash->u.cont_node->section_list; 2146*7c478bd9Sstevel@tonic-gate /* walk through the section list */ 2147*7c478bd9Sstevel@tonic-gate for (sec_hash = free_obj; sec_hash != NULL; free_obj = sec_hash) { 2148*7c478bd9Sstevel@tonic-gate sec_hash = sec_hash->u.sec_node->next; 2149*7c478bd9Sstevel@tonic-gate free_section_node(free_obj, cont_tbl); 2150*7c478bd9Sstevel@tonic-gate } 2151*7c478bd9Sstevel@tonic-gate (void) fru_close_container(cont_hash->u.cont_node->cont_hdl); 2152*7c478bd9Sstevel@tonic-gate 2153*7c478bd9Sstevel@tonic-gate free(cont_hash->u.cont_node); 2154*7c478bd9Sstevel@tonic-gate free(cont_hash); 2155*7c478bd9Sstevel@tonic-gate 2156*7c478bd9Sstevel@tonic-gate free(cont_tbl->hash_obj); 2157*7c478bd9Sstevel@tonic-gate free(cont_tbl); 2158*7c478bd9Sstevel@tonic-gate } 2159*7c478bd9Sstevel@tonic-gate 2160*7c478bd9Sstevel@tonic-gate /* 2161*7c478bd9Sstevel@tonic-gate * called when there is any state-change in location, fru, port nodes. 2162*7c478bd9Sstevel@tonic-gate * this event handler handles only location state-changes. 2163*7c478bd9Sstevel@tonic-gate */ 2164*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 2165*7c478bd9Sstevel@tonic-gate static void 2166*7c478bd9Sstevel@tonic-gate frudata_state_change_evhandler(const char *event_name, const void *event_arg, 2167*7c478bd9Sstevel@tonic-gate size_t size, void *cookie) 2168*7c478bd9Sstevel@tonic-gate { 2169*7c478bd9Sstevel@tonic-gate int rc; 2170*7c478bd9Sstevel@tonic-gate nvlist_t *nvlp; 2171*7c478bd9Sstevel@tonic-gate ptree_propinfo_t prop; 2172*7c478bd9Sstevel@tonic-gate picl_nodehdl_t loch, fruh; 2173*7c478bd9Sstevel@tonic-gate picl_prophdl_t proph, prophdl; 2174*7c478bd9Sstevel@tonic-gate char *present_state, *last_state; 2175*7c478bd9Sstevel@tonic-gate char name[PICL_PROPNAMELEN_MAX]; 2176*7c478bd9Sstevel@tonic-gate 2177*7c478bd9Sstevel@tonic-gate if (strcmp(event_name, PICLEVENT_STATE_CHANGE) != 0) 2178*7c478bd9Sstevel@tonic-gate return; 2179*7c478bd9Sstevel@tonic-gate 2180*7c478bd9Sstevel@tonic-gate if (nvlist_unpack((char *)event_arg, size, &nvlp, NULL)) { 2181*7c478bd9Sstevel@tonic-gate return; 2182*7c478bd9Sstevel@tonic-gate } 2183*7c478bd9Sstevel@tonic-gate 2184*7c478bd9Sstevel@tonic-gate if (nvlist_lookup_uint64(nvlp, PICLEVENTARG_NODEHANDLE, 2185*7c478bd9Sstevel@tonic-gate &loch) == -1) { 2186*7c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 2187*7c478bd9Sstevel@tonic-gate return; 2188*7c478bd9Sstevel@tonic-gate } 2189*7c478bd9Sstevel@tonic-gate 2190*7c478bd9Sstevel@tonic-gate if (ptree_get_propval_by_name(loch, PICL_PROP_CLASSNAME, name, 2191*7c478bd9Sstevel@tonic-gate sizeof (name)) != PICL_SUCCESS) { 2192*7c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 2193*7c478bd9Sstevel@tonic-gate return; 2194*7c478bd9Sstevel@tonic-gate } 2195*7c478bd9Sstevel@tonic-gate 2196*7c478bd9Sstevel@tonic-gate /* handle only location events */ 2197*7c478bd9Sstevel@tonic-gate if (strcmp(name, PICL_CLASS_LOCATION) != 0) { 2198*7c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 2199*7c478bd9Sstevel@tonic-gate return; 2200*7c478bd9Sstevel@tonic-gate } 2201*7c478bd9Sstevel@tonic-gate 2202*7c478bd9Sstevel@tonic-gate if (nvlist_lookup_string(nvlp, PICLEVENTARG_STATE, 2203*7c478bd9Sstevel@tonic-gate &present_state)) { 2204*7c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 2205*7c478bd9Sstevel@tonic-gate return; 2206*7c478bd9Sstevel@tonic-gate } 2207*7c478bd9Sstevel@tonic-gate 2208*7c478bd9Sstevel@tonic-gate rc = ptree_get_propval_by_name(loch, PICL_PROP_CHILD, 2209*7c478bd9Sstevel@tonic-gate &fruh, sizeof (picl_nodehdl_t)); 2210*7c478bd9Sstevel@tonic-gate if (rc != PICL_SUCCESS) { 2211*7c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 2212*7c478bd9Sstevel@tonic-gate return; 2213*7c478bd9Sstevel@tonic-gate } 2214*7c478bd9Sstevel@tonic-gate 2215*7c478bd9Sstevel@tonic-gate /* fru removed */ 2216*7c478bd9Sstevel@tonic-gate if (strcmp(present_state, PICLEVENTARGVAL_EMPTY) == 0) { 2217*7c478bd9Sstevel@tonic-gate delete_frudata_props(fruh); 2218*7c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 2219*7c478bd9Sstevel@tonic-gate return; 2220*7c478bd9Sstevel@tonic-gate } 2221*7c478bd9Sstevel@tonic-gate 2222*7c478bd9Sstevel@tonic-gate if (nvlist_lookup_string(nvlp, PICLEVENTARG_LAST_STATE, 2223*7c478bd9Sstevel@tonic-gate &last_state)) { 2224*7c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 2225*7c478bd9Sstevel@tonic-gate return; 2226*7c478bd9Sstevel@tonic-gate } 2227*7c478bd9Sstevel@tonic-gate 2228*7c478bd9Sstevel@tonic-gate /* fru added */ 2229*7c478bd9Sstevel@tonic-gate if ((strcmp(last_state, PICLEVENTARGVAL_EMPTY) == 0) || 2230*7c478bd9Sstevel@tonic-gate (strcmp(last_state, PICLEVENTARGVAL_UNKNOWN) == 0)) { 2231*7c478bd9Sstevel@tonic-gate rc = ptree_get_prop_by_name(fruh, PICL_PROP_FRUDATA_AVAIL, 2232*7c478bd9Sstevel@tonic-gate &proph); 2233*7c478bd9Sstevel@tonic-gate if (rc != PICL_SUCCESS) { 2234*7c478bd9Sstevel@tonic-gate if (fru_is_data_available(fruh) == 0) { 2235*7c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 2236*7c478bd9Sstevel@tonic-gate return; 2237*7c478bd9Sstevel@tonic-gate } 2238*7c478bd9Sstevel@tonic-gate /* create the property */ 2239*7c478bd9Sstevel@tonic-gate prop.version = PTREE_PROPINFO_VERSION; 2240*7c478bd9Sstevel@tonic-gate prop.piclinfo.type = PICL_PTYPE_VOID; 2241*7c478bd9Sstevel@tonic-gate prop.piclinfo.accessmode = PICL_READ; 2242*7c478bd9Sstevel@tonic-gate prop.piclinfo.size = 0; 2243*7c478bd9Sstevel@tonic-gate (void) strncpy(prop.piclinfo.name, 2244*7c478bd9Sstevel@tonic-gate PICL_PROP_FRUDATA_AVAIL, 2245*7c478bd9Sstevel@tonic-gate sizeof (prop.piclinfo.name)); 2246*7c478bd9Sstevel@tonic-gate 2247*7c478bd9Sstevel@tonic-gate rc = ptree_create_prop(&prop, NULL, &prophdl); 2248*7c478bd9Sstevel@tonic-gate if (rc != PICL_SUCCESS) { 2249*7c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 2250*7c478bd9Sstevel@tonic-gate return; 2251*7c478bd9Sstevel@tonic-gate } 2252*7c478bd9Sstevel@tonic-gate rc = ptree_add_prop(fruh, prophdl); 2253*7c478bd9Sstevel@tonic-gate if (rc != PICL_SUCCESS) { 2254*7c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 2255*7c478bd9Sstevel@tonic-gate return; 2256*7c478bd9Sstevel@tonic-gate } 2257*7c478bd9Sstevel@tonic-gate } 2258*7c478bd9Sstevel@tonic-gate (void) create_container_prop(fruh); 2259*7c478bd9Sstevel@tonic-gate } 2260*7c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 2261*7c478bd9Sstevel@tonic-gate } 2262*7c478bd9Sstevel@tonic-gate 2263*7c478bd9Sstevel@tonic-gate /* 2264*7c478bd9Sstevel@tonic-gate * called when event is posted when is fru is either added or removed from 2265*7c478bd9Sstevel@tonic-gate * the picltree. 2266*7c478bd9Sstevel@tonic-gate */ 2267*7c478bd9Sstevel@tonic-gate 2268*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 2269*7c478bd9Sstevel@tonic-gate static void 2270*7c478bd9Sstevel@tonic-gate frudata_event_handler(const char *event_name, const void *event_arg, 2271*7c478bd9Sstevel@tonic-gate size_t size, void *cookie) 2272*7c478bd9Sstevel@tonic-gate { 2273*7c478bd9Sstevel@tonic-gate int retval; 2274*7c478bd9Sstevel@tonic-gate char fullfilename[PATH_MAX]; 2275*7c478bd9Sstevel@tonic-gate picl_nodehdl_t fru_picl_hdl; 2276*7c478bd9Sstevel@tonic-gate picl_nodehdl_t roothdl; 2277*7c478bd9Sstevel@tonic-gate 2278*7c478bd9Sstevel@tonic-gate if (strcmp(event_name, PICL_FRU_REMOVED) == 0) { 2279*7c478bd9Sstevel@tonic-gate 2280*7c478bd9Sstevel@tonic-gate retval = nvlist_lookup_uint64((nvlist_t *)event_arg, 2281*7c478bd9Sstevel@tonic-gate PICLEVENTARG_FRUHANDLE, &fru_picl_hdl); 2282*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) { 2283*7c478bd9Sstevel@tonic-gate return; 2284*7c478bd9Sstevel@tonic-gate } 2285*7c478bd9Sstevel@tonic-gate 2286*7c478bd9Sstevel@tonic-gate /* free the hash object */ 2287*7c478bd9Sstevel@tonic-gate delete_frudata_props(fru_picl_hdl); 2288*7c478bd9Sstevel@tonic-gate 2289*7c478bd9Sstevel@tonic-gate } else if (strcmp(event_name, PICL_FRU_ADDED) == 0) { 2290*7c478bd9Sstevel@tonic-gate /* 2291*7c478bd9Sstevel@tonic-gate * reparse the configuration file to create 2292*7c478bd9Sstevel@tonic-gate * FRUDevicePath Prop. 2293*7c478bd9Sstevel@tonic-gate */ 2294*7c478bd9Sstevel@tonic-gate (void) get_config_file(fullfilename); 2295*7c478bd9Sstevel@tonic-gate retval = ptree_get_root(&roothdl); 2296*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) { 2297*7c478bd9Sstevel@tonic-gate return; 2298*7c478bd9Sstevel@tonic-gate } 2299*7c478bd9Sstevel@tonic-gate 2300*7c478bd9Sstevel@tonic-gate (void) picld_pluginutil_parse_config_file(roothdl, 2301*7c478bd9Sstevel@tonic-gate fullfilename); 2302*7c478bd9Sstevel@tonic-gate 2303*7c478bd9Sstevel@tonic-gate retval = nvlist_lookup_uint64((nvlist_t *)event_arg, 2304*7c478bd9Sstevel@tonic-gate PICLEVENTARG_PARENTHANDLE, &fru_picl_hdl); 2305*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) { 2306*7c478bd9Sstevel@tonic-gate return; 2307*7c478bd9Sstevel@tonic-gate } 2308*7c478bd9Sstevel@tonic-gate 2309*7c478bd9Sstevel@tonic-gate /* create container property */ 2310*7c478bd9Sstevel@tonic-gate create_frudata_props(fru_picl_hdl); 2311*7c478bd9Sstevel@tonic-gate } 2312*7c478bd9Sstevel@tonic-gate } 2313*7c478bd9Sstevel@tonic-gate 2314*7c478bd9Sstevel@tonic-gate /* 2315*7c478bd9Sstevel@tonic-gate * Function : plugin_init() is called by daemon. this routine is specified 2316*7c478bd9Sstevel@tonic-gate * while registering with daemon. it performs the initialization 2317*7c478bd9Sstevel@tonic-gate * of plugin module. 2318*7c478bd9Sstevel@tonic-gate */ 2319*7c478bd9Sstevel@tonic-gate 2320*7c478bd9Sstevel@tonic-gate static void 2321*7c478bd9Sstevel@tonic-gate frudata_plugin_init(void) 2322*7c478bd9Sstevel@tonic-gate { 2323*7c478bd9Sstevel@tonic-gate int retval; 2324*7c478bd9Sstevel@tonic-gate int count; 2325*7c478bd9Sstevel@tonic-gate char fullfilename[PATH_MAX]; 2326*7c478bd9Sstevel@tonic-gate picl_nodehdl_t fru_nodehdl; 2327*7c478bd9Sstevel@tonic-gate picl_nodehdl_t roothdl; 2328*7c478bd9Sstevel@tonic-gate 2329*7c478bd9Sstevel@tonic-gate retval = ptree_get_root(&roothdl); 2330*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) { 2331*7c478bd9Sstevel@tonic-gate return; 2332*7c478bd9Sstevel@tonic-gate } 2333*7c478bd9Sstevel@tonic-gate 2334*7c478bd9Sstevel@tonic-gate (void) ptree_register_handler(PICL_FRU_ADDED, 2335*7c478bd9Sstevel@tonic-gate frudata_event_handler, NULL); 2336*7c478bd9Sstevel@tonic-gate 2337*7c478bd9Sstevel@tonic-gate (void) ptree_register_handler(PICL_FRU_REMOVED, 2338*7c478bd9Sstevel@tonic-gate frudata_event_handler, NULL); 2339*7c478bd9Sstevel@tonic-gate 2340*7c478bd9Sstevel@tonic-gate (void) ptree_register_handler(PICLEVENT_STATE_CHANGE, 2341*7c478bd9Sstevel@tonic-gate frudata_state_change_evhandler, NULL); 2342*7c478bd9Sstevel@tonic-gate 2343*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&cont_tbl_lock); 2344*7c478bd9Sstevel@tonic-gate for (count = 0; count < TABLE_SIZE; count++) { 2345*7c478bd9Sstevel@tonic-gate container_table[count] = NULL; 2346*7c478bd9Sstevel@tonic-gate } 2347*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&cont_tbl_lock); 2348*7c478bd9Sstevel@tonic-gate 2349*7c478bd9Sstevel@tonic-gate (void) get_config_file(fullfilename); 2350*7c478bd9Sstevel@tonic-gate 2351*7c478bd9Sstevel@tonic-gate (void) picld_pluginutil_parse_config_file(roothdl, fullfilename); 2352*7c478bd9Sstevel@tonic-gate 2353*7c478bd9Sstevel@tonic-gate retval = ptree_get_node_by_path(FRUTREE_PATH, &fru_nodehdl); 2354*7c478bd9Sstevel@tonic-gate 2355*7c478bd9Sstevel@tonic-gate if (retval != PICL_SUCCESS) { 2356*7c478bd9Sstevel@tonic-gate return; 2357*7c478bd9Sstevel@tonic-gate } 2358*7c478bd9Sstevel@tonic-gate 2359*7c478bd9Sstevel@tonic-gate create_frudata_props(fru_nodehdl); 2360*7c478bd9Sstevel@tonic-gate 2361*7c478bd9Sstevel@tonic-gate } 2362*7c478bd9Sstevel@tonic-gate 2363*7c478bd9Sstevel@tonic-gate static void 2364*7c478bd9Sstevel@tonic-gate free_packet_hash_object(hash_obj_t *pkt_obj) 2365*7c478bd9Sstevel@tonic-gate { 2366*7c478bd9Sstevel@tonic-gate hash_obj_t *tmp_obj; 2367*7c478bd9Sstevel@tonic-gate 2368*7c478bd9Sstevel@tonic-gate while (pkt_obj != NULL) { 2369*7c478bd9Sstevel@tonic-gate tmp_obj = pkt_obj->u.pkt_node->next; 2370*7c478bd9Sstevel@tonic-gate free(pkt_obj->u.pkt_node); 2371*7c478bd9Sstevel@tonic-gate free(pkt_obj); 2372*7c478bd9Sstevel@tonic-gate pkt_obj = tmp_obj; 2373*7c478bd9Sstevel@tonic-gate } 2374*7c478bd9Sstevel@tonic-gate } 2375*7c478bd9Sstevel@tonic-gate 2376*7c478bd9Sstevel@tonic-gate static void 2377*7c478bd9Sstevel@tonic-gate free_segment_hash_object(hash_obj_t *seg_obj) 2378*7c478bd9Sstevel@tonic-gate { 2379*7c478bd9Sstevel@tonic-gate hash_obj_t *tmp_obj; 2380*7c478bd9Sstevel@tonic-gate 2381*7c478bd9Sstevel@tonic-gate while (seg_obj != NULL) { 2382*7c478bd9Sstevel@tonic-gate free_packet_hash_object(seg_obj->u.seg_node->packet_list); 2383*7c478bd9Sstevel@tonic-gate tmp_obj = seg_obj->u.seg_node->next; 2384*7c478bd9Sstevel@tonic-gate free(seg_obj->u.seg_node); 2385*7c478bd9Sstevel@tonic-gate free(seg_obj); 2386*7c478bd9Sstevel@tonic-gate seg_obj = tmp_obj; 2387*7c478bd9Sstevel@tonic-gate } 2388*7c478bd9Sstevel@tonic-gate } 2389*7c478bd9Sstevel@tonic-gate 2390*7c478bd9Sstevel@tonic-gate static void 2391*7c478bd9Sstevel@tonic-gate free_hash_objects(hash_obj_t *sec_obj) 2392*7c478bd9Sstevel@tonic-gate { 2393*7c478bd9Sstevel@tonic-gate hash_obj_t *tmp_obj; 2394*7c478bd9Sstevel@tonic-gate 2395*7c478bd9Sstevel@tonic-gate while (sec_obj != NULL) { 2396*7c478bd9Sstevel@tonic-gate free_segment_hash_object(sec_obj->u.sec_node->segment_list); 2397*7c478bd9Sstevel@tonic-gate tmp_obj = sec_obj->u.sec_node->next; 2398*7c478bd9Sstevel@tonic-gate free(sec_obj->u.sec_node); 2399*7c478bd9Sstevel@tonic-gate free(sec_obj); 2400*7c478bd9Sstevel@tonic-gate sec_obj = tmp_obj; 2401*7c478bd9Sstevel@tonic-gate } 2402*7c478bd9Sstevel@tonic-gate } 2403*7c478bd9Sstevel@tonic-gate 2404*7c478bd9Sstevel@tonic-gate /* 2405*7c478bd9Sstevel@tonic-gate * called from frudata_plugin_fini() this routine walks through 2406*7c478bd9Sstevel@tonic-gate * the hash table to free each and very hash object in the hash table. 2407*7c478bd9Sstevel@tonic-gate */ 2408*7c478bd9Sstevel@tonic-gate 2409*7c478bd9Sstevel@tonic-gate static void 2410*7c478bd9Sstevel@tonic-gate free_hash_table(void) 2411*7c478bd9Sstevel@tonic-gate { 2412*7c478bd9Sstevel@tonic-gate int cnt; 2413*7c478bd9Sstevel@tonic-gate picl_nodehdl_t nodehdl; 2414*7c478bd9Sstevel@tonic-gate hash_obj_t *next_obj; 2415*7c478bd9Sstevel@tonic-gate hash_obj_t *sec_obj; 2416*7c478bd9Sstevel@tonic-gate container_tbl_t *cont_tbl; 2417*7c478bd9Sstevel@tonic-gate 2418*7c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < TABLE_SIZE; cnt++) { 2419*7c478bd9Sstevel@tonic-gate 2420*7c478bd9Sstevel@tonic-gate while (container_table[cnt]) { 2421*7c478bd9Sstevel@tonic-gate 2422*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&cont_tbl_lock); 2423*7c478bd9Sstevel@tonic-gate 2424*7c478bd9Sstevel@tonic-gate cont_tbl = container_table[cnt]; 2425*7c478bd9Sstevel@tonic-gate nodehdl = cont_tbl->picl_hdl; 2426*7c478bd9Sstevel@tonic-gate 2427*7c478bd9Sstevel@tonic-gate cont_tbl = lookup_container_table(nodehdl, 2428*7c478bd9Sstevel@tonic-gate CONTAINER_NODE); 2429*7c478bd9Sstevel@tonic-gate if (cont_tbl == NULL) { 2430*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&cont_tbl_lock); 2431*7c478bd9Sstevel@tonic-gate break; 2432*7c478bd9Sstevel@tonic-gate } 2433*7c478bd9Sstevel@tonic-gate 2434*7c478bd9Sstevel@tonic-gate unlink_container_node(cont_tbl); 2435*7c478bd9Sstevel@tonic-gate 2436*7c478bd9Sstevel@tonic-gate pthread_cond_broadcast(&cont_tbl->cond_var); 2437*7c478bd9Sstevel@tonic-gate 2438*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&cont_tbl_lock); 2439*7c478bd9Sstevel@tonic-gate 2440*7c478bd9Sstevel@tonic-gate /* 2441*7c478bd9Sstevel@tonic-gate * waiting/blocking calling thread for all I/O in 2442*7c478bd9Sstevel@tonic-gate * progress to complete. don't free the container 2443*7c478bd9Sstevel@tonic-gate * hash until all I/O is complete. 2444*7c478bd9Sstevel@tonic-gate */ 2445*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_wrlock(&cont_tbl->rwlock); 2446*7c478bd9Sstevel@tonic-gate 2447*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&cont_tbl->rwlock); 2448*7c478bd9Sstevel@tonic-gate 2449*7c478bd9Sstevel@tonic-gate next_obj = cont_tbl->hash_obj->next; 2450*7c478bd9Sstevel@tonic-gate if (next_obj == NULL) { 2451*7c478bd9Sstevel@tonic-gate break; 2452*7c478bd9Sstevel@tonic-gate } 2453*7c478bd9Sstevel@tonic-gate 2454*7c478bd9Sstevel@tonic-gate if (next_obj->object_type == CONTAINER_NODE) { 2455*7c478bd9Sstevel@tonic-gate sec_obj = next_obj->u.cont_node->section_list; 2456*7c478bd9Sstevel@tonic-gate free_hash_objects(sec_obj); 2457*7c478bd9Sstevel@tonic-gate } 2458*7c478bd9Sstevel@tonic-gate 2459*7c478bd9Sstevel@tonic-gate free(next_obj->u.cont_node); 2460*7c478bd9Sstevel@tonic-gate free(next_obj); 2461*7c478bd9Sstevel@tonic-gate container_table[cnt] = cont_tbl->next; 2462*7c478bd9Sstevel@tonic-gate 2463*7c478bd9Sstevel@tonic-gate free(cont_tbl); 2464*7c478bd9Sstevel@tonic-gate } 2465*7c478bd9Sstevel@tonic-gate } 2466*7c478bd9Sstevel@tonic-gate } 2467*7c478bd9Sstevel@tonic-gate 2468*7c478bd9Sstevel@tonic-gate /* 2469*7c478bd9Sstevel@tonic-gate * called by the daemon and perform frudata cleanup. hold the write lock 2470*7c478bd9Sstevel@tonic-gate * over the entire hash table to free each and every hash object. 2471*7c478bd9Sstevel@tonic-gate */ 2472*7c478bd9Sstevel@tonic-gate 2473*7c478bd9Sstevel@tonic-gate static void 2474*7c478bd9Sstevel@tonic-gate frudata_plugin_fini(void) 2475*7c478bd9Sstevel@tonic-gate { 2476*7c478bd9Sstevel@tonic-gate 2477*7c478bd9Sstevel@tonic-gate free_hash_table(); 2478*7c478bd9Sstevel@tonic-gate 2479*7c478bd9Sstevel@tonic-gate (void) ptree_unregister_handler(PICL_FRU_ADDED, 2480*7c478bd9Sstevel@tonic-gate frudata_event_handler, NULL); 2481*7c478bd9Sstevel@tonic-gate 2482*7c478bd9Sstevel@tonic-gate (void) ptree_unregister_handler(PICL_FRU_REMOVED, 2483*7c478bd9Sstevel@tonic-gate frudata_event_handler, NULL); 2484*7c478bd9Sstevel@tonic-gate 2485*7c478bd9Sstevel@tonic-gate (void) ptree_unregister_handler(PICLEVENT_STATE_CHANGE, 2486*7c478bd9Sstevel@tonic-gate frudata_state_change_evhandler, NULL); 2487*7c478bd9Sstevel@tonic-gate } 2488