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 /* 30*7c478bd9Sstevel@tonic-gate * This module implements the PICL Interface used by PICL clients 31*7c478bd9Sstevel@tonic-gate * to access services of the PICL daemon 32*7c478bd9Sstevel@tonic-gate * 33*7c478bd9Sstevel@tonic-gate * Locking Strategy 34*7c478bd9Sstevel@tonic-gate * A single reader/writer lock (icl_lock) protects the access to the interface 35*7c478bd9Sstevel@tonic-gate * to the picl daemon, and the reference count, refcnt, variable. 36*7c478bd9Sstevel@tonic-gate * A reader lock is obtained to send a request to the daemon. 37*7c478bd9Sstevel@tonic-gate * A writer lock is obtained to initialize, reinitialize, or shutdown 38*7c478bd9Sstevel@tonic-gate * the interface. 39*7c478bd9Sstevel@tonic-gate */ 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate #include <stdio.h> 42*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 43*7c478bd9Sstevel@tonic-gate #include <string.h> 44*7c478bd9Sstevel@tonic-gate #include <unistd.h> 45*7c478bd9Sstevel@tonic-gate #include <alloca.h> 46*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 47*7c478bd9Sstevel@tonic-gate #include <libintl.h> 48*7c478bd9Sstevel@tonic-gate #include <errno.h> 49*7c478bd9Sstevel@tonic-gate #include <sys/mman.h> 50*7c478bd9Sstevel@tonic-gate #include <door.h> 51*7c478bd9Sstevel@tonic-gate #include <sys/door.h> 52*7c478bd9Sstevel@tonic-gate #include <sys/time.h> 53*7c478bd9Sstevel@tonic-gate #include <assert.h> 54*7c478bd9Sstevel@tonic-gate #include <synch.h> 55*7c478bd9Sstevel@tonic-gate #include <limits.h> 56*7c478bd9Sstevel@tonic-gate #include <picl.h> 57*7c478bd9Sstevel@tonic-gate #include "picl2door.h" 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate /* 60*7c478bd9Sstevel@tonic-gate * Module variables 61*7c478bd9Sstevel@tonic-gate */ 62*7c478bd9Sstevel@tonic-gate static int door_handle = -1; 63*7c478bd9Sstevel@tonic-gate static uint32_t refcnt = 0; 64*7c478bd9Sstevel@tonic-gate static rwlock_t picl_lock = DEFAULTRWLOCK; 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate static char *picl_errmsg[] = { 67*7c478bd9Sstevel@tonic-gate "No error", 68*7c478bd9Sstevel@tonic-gate "General system failure", 69*7c478bd9Sstevel@tonic-gate "Daemon not responding", 70*7c478bd9Sstevel@tonic-gate "Unknown PICL service", 71*7c478bd9Sstevel@tonic-gate "Session not initialized", 72*7c478bd9Sstevel@tonic-gate "Invalid arguments", 73*7c478bd9Sstevel@tonic-gate "Argument too big", 74*7c478bd9Sstevel@tonic-gate "Property not found", 75*7c478bd9Sstevel@tonic-gate "Not a table property handle", 76*7c478bd9Sstevel@tonic-gate "Not a node handle", 77*7c478bd9Sstevel@tonic-gate "Not a property handle", 78*7c478bd9Sstevel@tonic-gate "End of property list", 79*7c478bd9Sstevel@tonic-gate "Property already exists", 80*7c478bd9Sstevel@tonic-gate "Property not writable", 81*7c478bd9Sstevel@tonic-gate "Insufficient permissions", 82*7c478bd9Sstevel@tonic-gate "Invalid handle", 83*7c478bd9Sstevel@tonic-gate "Stale handle", 84*7c478bd9Sstevel@tonic-gate "Unsupported version", 85*7c478bd9Sstevel@tonic-gate "Wait timed out", 86*7c478bd9Sstevel@tonic-gate "Attempting to destroy before delete", 87*7c478bd9Sstevel@tonic-gate "PICL Tree is busy", 88*7c478bd9Sstevel@tonic-gate "Already has a parent", 89*7c478bd9Sstevel@tonic-gate "Property name is reserved", 90*7c478bd9Sstevel@tonic-gate "Invalid reference value", 91*7c478bd9Sstevel@tonic-gate "Continue tree walk", 92*7c478bd9Sstevel@tonic-gate "Terminate tree walk", 93*7c478bd9Sstevel@tonic-gate "Node not found", 94*7c478bd9Sstevel@tonic-gate "Not enough space available", 95*7c478bd9Sstevel@tonic-gate "Property not readable", 96*7c478bd9Sstevel@tonic-gate "Property value unavailable" 97*7c478bd9Sstevel@tonic-gate }; 98*7c478bd9Sstevel@tonic-gate 99*7c478bd9Sstevel@tonic-gate #define N_ERRORS (sizeof (picl_errmsg)/sizeof (picl_errmsg[0])) 100*7c478bd9Sstevel@tonic-gate #define SEND_REQ_TRYCOUNT 1 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate /* 103*7c478bd9Sstevel@tonic-gate * This function sends the client request to the daemon using a door call. 104*7c478bd9Sstevel@tonic-gate * If door_handle is -1, it returns PICL_NOTINITIALIZED. 105*7c478bd9Sstevel@tonic-gate * If the door_call fails, it returns PICL_NORESPONSE. Otherwise, it 106*7c478bd9Sstevel@tonic-gate * checks the response from the daemon for error. If an error is returned 107*7c478bd9Sstevel@tonic-gate * this function returns the error code returned and unmaps any 108*7c478bd9Sstevel@tonic-gate * memory mapped by the door call. For successful results, the caller is 109*7c478bd9Sstevel@tonic-gate * responsible to unmap the mapped memory after retrieving the results. 110*7c478bd9Sstevel@tonic-gate * 111*7c478bd9Sstevel@tonic-gate * This function does not attempt to reinitialize the interface if the 112*7c478bd9Sstevel@tonic-gate * initial door_call fails. It is called from handshake() , shutdown() 113*7c478bd9Sstevel@tonic-gate * and trysend_req() routines. 114*7c478bd9Sstevel@tonic-gate */ 115*7c478bd9Sstevel@tonic-gate static int 116*7c478bd9Sstevel@tonic-gate post_req(door_arg_t *dargp, void *data_ptr, size_t data_size, 117*7c478bd9Sstevel@tonic-gate door_desc_t *desc_ptr, uint_t desc_num, void *rbuf, size_t rsize) 118*7c478bd9Sstevel@tonic-gate { 119*7c478bd9Sstevel@tonic-gate int err; 120*7c478bd9Sstevel@tonic-gate picl_service_t *ret; 121*7c478bd9Sstevel@tonic-gate int req_cnum; 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate req_cnum = ((picl_service_t *)data_ptr)->in.cnum; 124*7c478bd9Sstevel@tonic-gate dargp->data_ptr = data_ptr; 125*7c478bd9Sstevel@tonic-gate dargp->data_size = data_size; 126*7c478bd9Sstevel@tonic-gate dargp->desc_ptr = desc_ptr; 127*7c478bd9Sstevel@tonic-gate dargp->desc_num = desc_num; 128*7c478bd9Sstevel@tonic-gate dargp->rbuf = rbuf; 129*7c478bd9Sstevel@tonic-gate dargp->rsize = rsize; 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate if (door_call(door_handle, dargp) < 0) 132*7c478bd9Sstevel@tonic-gate return (PICL_NORESPONSE); 133*7c478bd9Sstevel@tonic-gate 134*7c478bd9Sstevel@tonic-gate /*LINTED*/ 135*7c478bd9Sstevel@tonic-gate ret = (picl_service_t *)dargp->rbuf; 136*7c478bd9Sstevel@tonic-gate if (ret->in.cnum == req_cnum) 137*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 138*7c478bd9Sstevel@tonic-gate else if ((ret->in.cnum == PICL_CNUM_ERROR) && 139*7c478bd9Sstevel@tonic-gate (ret->ret_error.in_cnum == req_cnum)) 140*7c478bd9Sstevel@tonic-gate err = ret->ret_error.errnum; 141*7c478bd9Sstevel@tonic-gate else 142*7c478bd9Sstevel@tonic-gate err = PICL_UNKNOWNSERVICE; 143*7c478bd9Sstevel@tonic-gate if (dargp->rbuf != rbuf) 144*7c478bd9Sstevel@tonic-gate (void) munmap(dargp->rbuf, dargp->rsize); 145*7c478bd9Sstevel@tonic-gate return (err); 146*7c478bd9Sstevel@tonic-gate } 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate /* 149*7c478bd9Sstevel@tonic-gate * This function posts an INIT message to the daemon to 150*7c478bd9Sstevel@tonic-gate * verify communication channel. 151*7c478bd9Sstevel@tonic-gate */ 152*7c478bd9Sstevel@tonic-gate static int 153*7c478bd9Sstevel@tonic-gate handshake(void) 154*7c478bd9Sstevel@tonic-gate { 155*7c478bd9Sstevel@tonic-gate int err; 156*7c478bd9Sstevel@tonic-gate door_arg_t darg; 157*7c478bd9Sstevel@tonic-gate picl_reqinit_t req; 158*7c478bd9Sstevel@tonic-gate picl_retinit_t outargs; 159*7c478bd9Sstevel@tonic-gate 160*7c478bd9Sstevel@tonic-gate req.cnum = PICL_CNUM_INIT; 161*7c478bd9Sstevel@tonic-gate req.clrev = PICL_VERSION_1; 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate if ((err = post_req(&darg, &req, sizeof (picl_reqinit_t), NULL, 164*7c478bd9Sstevel@tonic-gate 0, &outargs, sizeof (picl_retinit_t))) != PICL_SUCCESS) 165*7c478bd9Sstevel@tonic-gate return (err); 166*7c478bd9Sstevel@tonic-gate 167*7c478bd9Sstevel@tonic-gate if (darg.rbuf != (char *)&outargs) 168*7c478bd9Sstevel@tonic-gate (void) munmap(darg.rbuf, darg.rsize); 169*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 170*7c478bd9Sstevel@tonic-gate } 171*7c478bd9Sstevel@tonic-gate 172*7c478bd9Sstevel@tonic-gate /* 173*7c478bd9Sstevel@tonic-gate * This function calls post_req() to make door_call and reinitializes 174*7c478bd9Sstevel@tonic-gate * the interface is post_req() fails. 175*7c478bd9Sstevel@tonic-gate */ 176*7c478bd9Sstevel@tonic-gate static int 177*7c478bd9Sstevel@tonic-gate trysend_req(door_arg_t *dargp, void *data_ptr, size_t data_size, 178*7c478bd9Sstevel@tonic-gate door_desc_t *desc_ptr, uint_t desc_num, void *rbuf, size_t rsize, 179*7c478bd9Sstevel@tonic-gate unsigned int trycount) 180*7c478bd9Sstevel@tonic-gate { 181*7c478bd9Sstevel@tonic-gate int err; 182*7c478bd9Sstevel@tonic-gate int write_locked; 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate write_locked = 0; 185*7c478bd9Sstevel@tonic-gate (void) rw_rdlock(&picl_lock); 186*7c478bd9Sstevel@tonic-gate if (refcnt == 0) { 187*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&picl_lock); /* read unlock */ 188*7c478bd9Sstevel@tonic-gate return (PICL_NOTINITIALIZED); 189*7c478bd9Sstevel@tonic-gate } 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate while ((err = post_req(dargp, data_ptr, data_size, desc_ptr, desc_num, 192*7c478bd9Sstevel@tonic-gate rbuf, rsize)) == PICL_NORESPONSE) { 193*7c478bd9Sstevel@tonic-gate if (trycount == 0) /* no more retry */ 194*7c478bd9Sstevel@tonic-gate break; 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate if (write_locked == 1) { /* close and open door */ 197*7c478bd9Sstevel@tonic-gate (void) close(door_handle); 198*7c478bd9Sstevel@tonic-gate if ((door_handle = open(PICLD_DOOR, O_RDONLY)) < 0) { 199*7c478bd9Sstevel@tonic-gate err = PICL_NORESPONSE; 200*7c478bd9Sstevel@tonic-gate break; 201*7c478bd9Sstevel@tonic-gate } 202*7c478bd9Sstevel@tonic-gate --trycount; 203*7c478bd9Sstevel@tonic-gate continue; 204*7c478bd9Sstevel@tonic-gate } 205*7c478bd9Sstevel@tonic-gate /* 206*7c478bd9Sstevel@tonic-gate * Upgrade read to a write lock 207*7c478bd9Sstevel@tonic-gate */ 208*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&picl_lock); 209*7c478bd9Sstevel@tonic-gate (void) rw_wrlock(&picl_lock); 210*7c478bd9Sstevel@tonic-gate 211*7c478bd9Sstevel@tonic-gate /* 212*7c478bd9Sstevel@tonic-gate * if picl_shutdown happens during lock upgrade 213*7c478bd9Sstevel@tonic-gate */ 214*7c478bd9Sstevel@tonic-gate if (refcnt == 0) { 215*7c478bd9Sstevel@tonic-gate err = PICL_NOTINITIALIZED; 216*7c478bd9Sstevel@tonic-gate break; 217*7c478bd9Sstevel@tonic-gate } 218*7c478bd9Sstevel@tonic-gate write_locked = 1; 219*7c478bd9Sstevel@tonic-gate continue; 220*7c478bd9Sstevel@tonic-gate } 221*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&picl_lock); /* read or write unlock */ 222*7c478bd9Sstevel@tonic-gate return (err); 223*7c478bd9Sstevel@tonic-gate } 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate /* 226*7c478bd9Sstevel@tonic-gate * Initialize the PICL interface 227*7c478bd9Sstevel@tonic-gate * Increment the reference count. 228*7c478bd9Sstevel@tonic-gate */ 229*7c478bd9Sstevel@tonic-gate int 230*7c478bd9Sstevel@tonic-gate picl_initialize(void) 231*7c478bd9Sstevel@tonic-gate { 232*7c478bd9Sstevel@tonic-gate int err; 233*7c478bd9Sstevel@tonic-gate 234*7c478bd9Sstevel@tonic-gate (void) rw_wrlock(&picl_lock); 235*7c478bd9Sstevel@tonic-gate if (refcnt > 0) { /* previously initialized */ 236*7c478bd9Sstevel@tonic-gate err = handshake(); 237*7c478bd9Sstevel@tonic-gate if (err == PICL_SUCCESS) { 238*7c478bd9Sstevel@tonic-gate ++refcnt; 239*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&picl_lock); /* write unlock */ 240*7c478bd9Sstevel@tonic-gate return (err); 241*7c478bd9Sstevel@tonic-gate } 242*7c478bd9Sstevel@tonic-gate if (err != PICL_NORESPONSE) { 243*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&picl_lock); /* write unlock */ 244*7c478bd9Sstevel@tonic-gate return (err); 245*7c478bd9Sstevel@tonic-gate } 246*7c478bd9Sstevel@tonic-gate (void) close(door_handle); /* close bad door */ 247*7c478bd9Sstevel@tonic-gate } 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate /* 250*7c478bd9Sstevel@tonic-gate * Open picld door and initialize door_handle 251*7c478bd9Sstevel@tonic-gate */ 252*7c478bd9Sstevel@tonic-gate if ((door_handle = open(PICLD_DOOR, O_RDONLY)) < 0) { 253*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&picl_lock); /* write unlock */ 254*7c478bd9Sstevel@tonic-gate return (PICL_NORESPONSE); 255*7c478bd9Sstevel@tonic-gate } 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate err = handshake(); 258*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 259*7c478bd9Sstevel@tonic-gate (void) close(door_handle); 260*7c478bd9Sstevel@tonic-gate else 261*7c478bd9Sstevel@tonic-gate ++refcnt; 262*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&picl_lock); /* write unlock */ 263*7c478bd9Sstevel@tonic-gate return (err); 264*7c478bd9Sstevel@tonic-gate } 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate /* 267*7c478bd9Sstevel@tonic-gate * Shutdown the PICL interface 268*7c478bd9Sstevel@tonic-gate * Decrement the reference count and close the door_handle if refcnt is zero 269*7c478bd9Sstevel@tonic-gate */ 270*7c478bd9Sstevel@tonic-gate int 271*7c478bd9Sstevel@tonic-gate picl_shutdown(void) 272*7c478bd9Sstevel@tonic-gate { 273*7c478bd9Sstevel@tonic-gate int err; 274*7c478bd9Sstevel@tonic-gate door_arg_t darg; 275*7c478bd9Sstevel@tonic-gate picl_reqfini_t req_fini; 276*7c478bd9Sstevel@tonic-gate picl_retfini_t outargs; 277*7c478bd9Sstevel@tonic-gate 278*7c478bd9Sstevel@tonic-gate (void) rw_wrlock(&picl_lock); /* write lock */ 279*7c478bd9Sstevel@tonic-gate if (refcnt == 0) { 280*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&picl_lock); /* write unlock */ 281*7c478bd9Sstevel@tonic-gate return (PICL_NOTINITIALIZED); 282*7c478bd9Sstevel@tonic-gate } 283*7c478bd9Sstevel@tonic-gate req_fini.cnum = PICL_CNUM_FINI; 284*7c478bd9Sstevel@tonic-gate err = post_req(&darg, &req_fini, sizeof (picl_reqfini_t), 285*7c478bd9Sstevel@tonic-gate NULL, 0, &outargs, sizeof (picl_retfini_t)); 286*7c478bd9Sstevel@tonic-gate --refcnt; 287*7c478bd9Sstevel@tonic-gate if (refcnt == 0) 288*7c478bd9Sstevel@tonic-gate (void) close(door_handle); 289*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&picl_lock); /* write unlock */ 290*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 291*7c478bd9Sstevel@tonic-gate return (err); 292*7c478bd9Sstevel@tonic-gate if (darg.rbuf != (char *)&outargs) 293*7c478bd9Sstevel@tonic-gate (void) munmap(darg.rbuf, darg.rsize); 294*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 295*7c478bd9Sstevel@tonic-gate } 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate /* 298*7c478bd9Sstevel@tonic-gate * This function waits for the specified number of seconds for a PICL 299*7c478bd9Sstevel@tonic-gate * tree refresh. 300*7c478bd9Sstevel@tonic-gate */ 301*7c478bd9Sstevel@tonic-gate int 302*7c478bd9Sstevel@tonic-gate picl_wait(unsigned int secs) 303*7c478bd9Sstevel@tonic-gate { 304*7c478bd9Sstevel@tonic-gate door_arg_t darg; 305*7c478bd9Sstevel@tonic-gate picl_reqwait_t req_wait; 306*7c478bd9Sstevel@tonic-gate picl_retwait_t outargs; 307*7c478bd9Sstevel@tonic-gate picl_service_t *ret; 308*7c478bd9Sstevel@tonic-gate int err; 309*7c478bd9Sstevel@tonic-gate 310*7c478bd9Sstevel@tonic-gate req_wait.cnum = PICL_CNUM_WAIT; 311*7c478bd9Sstevel@tonic-gate req_wait.secs = secs; 312*7c478bd9Sstevel@tonic-gate err = trysend_req(&darg, &req_wait, sizeof (picl_reqwait_t), 313*7c478bd9Sstevel@tonic-gate NULL, 0, &outargs, sizeof (picl_retwait_t), SEND_REQ_TRYCOUNT); 314*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 315*7c478bd9Sstevel@tonic-gate return (err); 316*7c478bd9Sstevel@tonic-gate 317*7c478bd9Sstevel@tonic-gate /*LINTED*/ 318*7c478bd9Sstevel@tonic-gate ret = (picl_service_t *)darg.rbuf; 319*7c478bd9Sstevel@tonic-gate err = ret->ret_wait.retcode; 320*7c478bd9Sstevel@tonic-gate if (darg.rbuf != (char *)&outargs) 321*7c478bd9Sstevel@tonic-gate (void) munmap(darg.rbuf, darg.rsize); 322*7c478bd9Sstevel@tonic-gate return (err); 323*7c478bd9Sstevel@tonic-gate } 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate /* 326*7c478bd9Sstevel@tonic-gate * This function copies the handle of the root node of the PICL tree into 327*7c478bd9Sstevel@tonic-gate * the buffer <rooth> 328*7c478bd9Sstevel@tonic-gate */ 329*7c478bd9Sstevel@tonic-gate int 330*7c478bd9Sstevel@tonic-gate picl_get_root(picl_nodehdl_t *rooth) 331*7c478bd9Sstevel@tonic-gate { 332*7c478bd9Sstevel@tonic-gate door_arg_t darg; 333*7c478bd9Sstevel@tonic-gate picl_reqroot_t req_root; 334*7c478bd9Sstevel@tonic-gate picl_retroot_t outargs; 335*7c478bd9Sstevel@tonic-gate picl_service_t *ret; 336*7c478bd9Sstevel@tonic-gate int err; 337*7c478bd9Sstevel@tonic-gate 338*7c478bd9Sstevel@tonic-gate req_root.cnum = PICL_CNUM_GETROOT; 339*7c478bd9Sstevel@tonic-gate err = trysend_req(&darg, &req_root, sizeof (picl_reqroot_t), NULL, 340*7c478bd9Sstevel@tonic-gate 0, &outargs, sizeof (picl_retroot_t), SEND_REQ_TRYCOUNT); 341*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 342*7c478bd9Sstevel@tonic-gate return (err); 343*7c478bd9Sstevel@tonic-gate /*LINTED*/ 344*7c478bd9Sstevel@tonic-gate ret = (picl_service_t *)darg.rbuf; 345*7c478bd9Sstevel@tonic-gate *rooth = ret->ret_root.rnode; 346*7c478bd9Sstevel@tonic-gate if (darg.rbuf != (char *)&outargs) 347*7c478bd9Sstevel@tonic-gate (void) munmap(darg.rbuf, darg.rsize); 348*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 349*7c478bd9Sstevel@tonic-gate } 350*7c478bd9Sstevel@tonic-gate 351*7c478bd9Sstevel@tonic-gate /* 352*7c478bd9Sstevel@tonic-gate * This function copies the value of the property specified by its handle 353*7c478bd9Sstevel@tonic-gate * into the buffer <valbuf>. 354*7c478bd9Sstevel@tonic-gate */ 355*7c478bd9Sstevel@tonic-gate int 356*7c478bd9Sstevel@tonic-gate picl_get_propval(picl_prophdl_t proph, void *valbuf, size_t nbytes) 357*7c478bd9Sstevel@tonic-gate { 358*7c478bd9Sstevel@tonic-gate door_arg_t darg; 359*7c478bd9Sstevel@tonic-gate picl_reqattrval_t req_attrval; 360*7c478bd9Sstevel@tonic-gate picl_service_t *ret; 361*7c478bd9Sstevel@tonic-gate picl_retattrval_t *outargs; 362*7c478bd9Sstevel@tonic-gate int err; 363*7c478bd9Sstevel@tonic-gate 364*7c478bd9Sstevel@tonic-gate req_attrval.cnum = PICL_CNUM_GETATTRVAL; 365*7c478bd9Sstevel@tonic-gate req_attrval.attr = proph; 366*7c478bd9Sstevel@tonic-gate req_attrval.bufsize = (uint32_t)nbytes; 367*7c478bd9Sstevel@tonic-gate if ((size_t)req_attrval.bufsize != nbytes) 368*7c478bd9Sstevel@tonic-gate return (PICL_VALUETOOBIG); 369*7c478bd9Sstevel@tonic-gate outargs = alloca(sizeof (picl_retattrval_t) + nbytes); 370*7c478bd9Sstevel@tonic-gate 371*7c478bd9Sstevel@tonic-gate err = trysend_req(&darg, &req_attrval, sizeof (picl_reqattrval_t), 372*7c478bd9Sstevel@tonic-gate NULL, 0, outargs, sizeof (picl_retattrval_t) + nbytes, 373*7c478bd9Sstevel@tonic-gate SEND_REQ_TRYCOUNT); 374*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 375*7c478bd9Sstevel@tonic-gate return (err); 376*7c478bd9Sstevel@tonic-gate 377*7c478bd9Sstevel@tonic-gate /*LINTED*/ 378*7c478bd9Sstevel@tonic-gate ret = (picl_service_t *)darg.rbuf; 379*7c478bd9Sstevel@tonic-gate if (ret->ret_attrval.nbytes > (uint32_t)nbytes) 380*7c478bd9Sstevel@tonic-gate err = PICL_VALUETOOBIG; 381*7c478bd9Sstevel@tonic-gate else 382*7c478bd9Sstevel@tonic-gate (void) memcpy(valbuf, ret->ret_attrval.ret_buf, 383*7c478bd9Sstevel@tonic-gate (size_t)ret->ret_attrval.nbytes); 384*7c478bd9Sstevel@tonic-gate if (darg.rbuf != (char *)outargs) 385*7c478bd9Sstevel@tonic-gate (void) munmap(darg.rbuf, darg.rsize); 386*7c478bd9Sstevel@tonic-gate return (err); 387*7c478bd9Sstevel@tonic-gate } 388*7c478bd9Sstevel@tonic-gate 389*7c478bd9Sstevel@tonic-gate /* 390*7c478bd9Sstevel@tonic-gate * This function copies the value of the property specified by its 391*7c478bd9Sstevel@tonic-gate * name into the buffer <valbuf> 392*7c478bd9Sstevel@tonic-gate */ 393*7c478bd9Sstevel@tonic-gate int 394*7c478bd9Sstevel@tonic-gate picl_get_propval_by_name(picl_nodehdl_t nodeh, const char *propname, 395*7c478bd9Sstevel@tonic-gate void *valbuf, size_t nbytes) 396*7c478bd9Sstevel@tonic-gate { 397*7c478bd9Sstevel@tonic-gate door_arg_t darg; 398*7c478bd9Sstevel@tonic-gate picl_reqattrvalbyname_t req_attrvalbyname; 399*7c478bd9Sstevel@tonic-gate picl_service_t *ret; 400*7c478bd9Sstevel@tonic-gate picl_retattrvalbyname_t *outargs; 401*7c478bd9Sstevel@tonic-gate int err; 402*7c478bd9Sstevel@tonic-gate 403*7c478bd9Sstevel@tonic-gate req_attrvalbyname.cnum = PICL_CNUM_GETATTRVALBYNAME; 404*7c478bd9Sstevel@tonic-gate req_attrvalbyname.nodeh = nodeh; 405*7c478bd9Sstevel@tonic-gate (void) strcpy(req_attrvalbyname.propname, propname); 406*7c478bd9Sstevel@tonic-gate req_attrvalbyname.bufsize = (uint32_t)nbytes; 407*7c478bd9Sstevel@tonic-gate if ((size_t)req_attrvalbyname.bufsize != nbytes) 408*7c478bd9Sstevel@tonic-gate return (PICL_VALUETOOBIG); 409*7c478bd9Sstevel@tonic-gate outargs = alloca(sizeof (picl_retattrvalbyname_t) + nbytes); 410*7c478bd9Sstevel@tonic-gate 411*7c478bd9Sstevel@tonic-gate err = trysend_req(&darg, &req_attrvalbyname, 412*7c478bd9Sstevel@tonic-gate sizeof (picl_reqattrvalbyname_t), NULL, 0, outargs, 413*7c478bd9Sstevel@tonic-gate sizeof (picl_retattrvalbyname_t) + nbytes, SEND_REQ_TRYCOUNT); 414*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 415*7c478bd9Sstevel@tonic-gate return (err); 416*7c478bd9Sstevel@tonic-gate 417*7c478bd9Sstevel@tonic-gate /*LINTED*/ 418*7c478bd9Sstevel@tonic-gate ret = (picl_service_t *)darg.rbuf; 419*7c478bd9Sstevel@tonic-gate if (ret->ret_attrvalbyname.nbytes > (uint32_t)nbytes) 420*7c478bd9Sstevel@tonic-gate err = PICL_VALUETOOBIG; 421*7c478bd9Sstevel@tonic-gate else 422*7c478bd9Sstevel@tonic-gate (void) memcpy(valbuf, ret->ret_attrvalbyname.ret_buf, 423*7c478bd9Sstevel@tonic-gate (size_t)ret->ret_attrvalbyname.nbytes); 424*7c478bd9Sstevel@tonic-gate if (darg.rbuf != (char *)outargs) 425*7c478bd9Sstevel@tonic-gate (void) munmap(darg.rbuf, darg.rsize); 426*7c478bd9Sstevel@tonic-gate return (err); 427*7c478bd9Sstevel@tonic-gate } 428*7c478bd9Sstevel@tonic-gate 429*7c478bd9Sstevel@tonic-gate /* 430*7c478bd9Sstevel@tonic-gate * This function sets the value of the property specified by its 431*7c478bd9Sstevel@tonic-gate * handle with the value specified in <valbuf>. 432*7c478bd9Sstevel@tonic-gate */ 433*7c478bd9Sstevel@tonic-gate int 434*7c478bd9Sstevel@tonic-gate picl_set_propval(picl_prophdl_t proph, void *valbuf, size_t nbytes) 435*7c478bd9Sstevel@tonic-gate { 436*7c478bd9Sstevel@tonic-gate door_arg_t darg; 437*7c478bd9Sstevel@tonic-gate picl_reqsetattrval_t ret_setattrval; 438*7c478bd9Sstevel@tonic-gate picl_reqsetattrval_t *inargs; 439*7c478bd9Sstevel@tonic-gate int err; 440*7c478bd9Sstevel@tonic-gate 441*7c478bd9Sstevel@tonic-gate if (nbytes >= (size_t)PICL_PROPSIZE_MAX) 442*7c478bd9Sstevel@tonic-gate return (PICL_VALUETOOBIG); 443*7c478bd9Sstevel@tonic-gate 444*7c478bd9Sstevel@tonic-gate inargs = alloca(sizeof (picl_reqsetattrval_t) + nbytes); 445*7c478bd9Sstevel@tonic-gate inargs->cnum = PICL_CNUM_SETATTRVAL; 446*7c478bd9Sstevel@tonic-gate inargs->attr = proph; 447*7c478bd9Sstevel@tonic-gate inargs->bufsize = (uint32_t)nbytes; 448*7c478bd9Sstevel@tonic-gate if ((size_t)inargs->bufsize != nbytes) 449*7c478bd9Sstevel@tonic-gate return (PICL_VALUETOOBIG); 450*7c478bd9Sstevel@tonic-gate (void) memcpy(inargs->valbuf, valbuf, nbytes); 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate err = trysend_req(&darg, inargs, sizeof (picl_reqsetattrval_t) + 453*7c478bd9Sstevel@tonic-gate nbytes, NULL, 0, &ret_setattrval, 454*7c478bd9Sstevel@tonic-gate sizeof (picl_retsetattrval_t), SEND_REQ_TRYCOUNT); 455*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 456*7c478bd9Sstevel@tonic-gate return (err); 457*7c478bd9Sstevel@tonic-gate 458*7c478bd9Sstevel@tonic-gate if (darg.rbuf != (char *)&ret_setattrval) 459*7c478bd9Sstevel@tonic-gate (void) munmap(darg.rbuf, darg.rsize); 460*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 461*7c478bd9Sstevel@tonic-gate } 462*7c478bd9Sstevel@tonic-gate 463*7c478bd9Sstevel@tonic-gate /* 464*7c478bd9Sstevel@tonic-gate * This function sets the value of the property specified by its 465*7c478bd9Sstevel@tonic-gate * name with the value given in <valbuf> 466*7c478bd9Sstevel@tonic-gate */ 467*7c478bd9Sstevel@tonic-gate int 468*7c478bd9Sstevel@tonic-gate picl_set_propval_by_name(picl_nodehdl_t nodeh, const char *propname, 469*7c478bd9Sstevel@tonic-gate void *valbuf, size_t nbytes) 470*7c478bd9Sstevel@tonic-gate { 471*7c478bd9Sstevel@tonic-gate door_arg_t darg; 472*7c478bd9Sstevel@tonic-gate picl_retsetattrvalbyname_t ret_setattrvalbyname; 473*7c478bd9Sstevel@tonic-gate picl_reqsetattrvalbyname_t *inargs; 474*7c478bd9Sstevel@tonic-gate int err; 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate if (nbytes >= (size_t)PICL_PROPSIZE_MAX) 477*7c478bd9Sstevel@tonic-gate return (PICL_VALUETOOBIG); 478*7c478bd9Sstevel@tonic-gate 479*7c478bd9Sstevel@tonic-gate inargs = alloca(sizeof (picl_reqsetattrvalbyname_t) + nbytes); 480*7c478bd9Sstevel@tonic-gate inargs->cnum = PICL_CNUM_SETATTRVALBYNAME; 481*7c478bd9Sstevel@tonic-gate inargs->nodeh = nodeh; 482*7c478bd9Sstevel@tonic-gate (void) strcpy(inargs->propname, propname); 483*7c478bd9Sstevel@tonic-gate inargs->bufsize = (uint32_t)nbytes; 484*7c478bd9Sstevel@tonic-gate if ((size_t)inargs->bufsize != nbytes) 485*7c478bd9Sstevel@tonic-gate return (PICL_VALUETOOBIG); 486*7c478bd9Sstevel@tonic-gate (void) memcpy(inargs->valbuf, valbuf, nbytes); 487*7c478bd9Sstevel@tonic-gate 488*7c478bd9Sstevel@tonic-gate err = trysend_req(&darg, inargs, 489*7c478bd9Sstevel@tonic-gate sizeof (picl_reqsetattrvalbyname_t) + nbytes, NULL, 0, 490*7c478bd9Sstevel@tonic-gate &ret_setattrvalbyname, sizeof (picl_retsetattrvalbyname_t), 491*7c478bd9Sstevel@tonic-gate SEND_REQ_TRYCOUNT); 492*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 493*7c478bd9Sstevel@tonic-gate return (err); 494*7c478bd9Sstevel@tonic-gate 495*7c478bd9Sstevel@tonic-gate if (darg.rbuf != (char *)&ret_setattrvalbyname) 496*7c478bd9Sstevel@tonic-gate (void) munmap(darg.rbuf, darg.rsize); 497*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 498*7c478bd9Sstevel@tonic-gate } 499*7c478bd9Sstevel@tonic-gate 500*7c478bd9Sstevel@tonic-gate /* 501*7c478bd9Sstevel@tonic-gate * This function copies the information of the specified property 502*7c478bd9Sstevel@tonic-gate * into <pinfo> 503*7c478bd9Sstevel@tonic-gate */ 504*7c478bd9Sstevel@tonic-gate int 505*7c478bd9Sstevel@tonic-gate picl_get_propinfo(picl_prophdl_t proph, picl_propinfo_t *pinfo) 506*7c478bd9Sstevel@tonic-gate { 507*7c478bd9Sstevel@tonic-gate door_arg_t darg; 508*7c478bd9Sstevel@tonic-gate picl_reqattrinfo_t req_attrinfo; 509*7c478bd9Sstevel@tonic-gate picl_service_t *ret; 510*7c478bd9Sstevel@tonic-gate picl_retattrinfo_t outargs; 511*7c478bd9Sstevel@tonic-gate int err; 512*7c478bd9Sstevel@tonic-gate 513*7c478bd9Sstevel@tonic-gate req_attrinfo.cnum = PICL_CNUM_GETATTRINFO; 514*7c478bd9Sstevel@tonic-gate req_attrinfo.attr = proph; 515*7c478bd9Sstevel@tonic-gate 516*7c478bd9Sstevel@tonic-gate err = trysend_req(&darg, &req_attrinfo, 517*7c478bd9Sstevel@tonic-gate sizeof (picl_reqattrinfo_t), NULL, 0, &outargs, 518*7c478bd9Sstevel@tonic-gate sizeof (picl_retattrinfo_t), SEND_REQ_TRYCOUNT); 519*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 520*7c478bd9Sstevel@tonic-gate return (err); 521*7c478bd9Sstevel@tonic-gate 522*7c478bd9Sstevel@tonic-gate /*LINTED*/ 523*7c478bd9Sstevel@tonic-gate ret = (picl_service_t *)darg.rbuf; 524*7c478bd9Sstevel@tonic-gate pinfo->type = ret->ret_attrinfo.type; 525*7c478bd9Sstevel@tonic-gate pinfo->accessmode = ret->ret_attrinfo.accessmode; 526*7c478bd9Sstevel@tonic-gate pinfo->size = (size_t)ret->ret_attrinfo.size; 527*7c478bd9Sstevel@tonic-gate (void) strcpy(pinfo->name, ret->ret_attrinfo.name); 528*7c478bd9Sstevel@tonic-gate if (darg.rbuf != (char *)&outargs) 529*7c478bd9Sstevel@tonic-gate (void) munmap(darg.rbuf, darg.rsize); 530*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 531*7c478bd9Sstevel@tonic-gate } 532*7c478bd9Sstevel@tonic-gate 533*7c478bd9Sstevel@tonic-gate /* 534*7c478bd9Sstevel@tonic-gate * This function copies the handle of the first property of a node into 535*7c478bd9Sstevel@tonic-gate * <proph> 536*7c478bd9Sstevel@tonic-gate */ 537*7c478bd9Sstevel@tonic-gate int 538*7c478bd9Sstevel@tonic-gate picl_get_first_prop(picl_nodehdl_t nodeh, picl_prophdl_t *proph) 539*7c478bd9Sstevel@tonic-gate { 540*7c478bd9Sstevel@tonic-gate door_arg_t darg; 541*7c478bd9Sstevel@tonic-gate picl_reqfirstattr_t req_firstattr; 542*7c478bd9Sstevel@tonic-gate picl_service_t *ret; 543*7c478bd9Sstevel@tonic-gate picl_retfirstattr_t outargs; 544*7c478bd9Sstevel@tonic-gate int err; 545*7c478bd9Sstevel@tonic-gate 546*7c478bd9Sstevel@tonic-gate req_firstattr.cnum = PICL_CNUM_GETFIRSTATTR; 547*7c478bd9Sstevel@tonic-gate req_firstattr.nodeh = nodeh; 548*7c478bd9Sstevel@tonic-gate 549*7c478bd9Sstevel@tonic-gate err = trysend_req(&darg, &req_firstattr, 550*7c478bd9Sstevel@tonic-gate sizeof (picl_reqfirstattr_t), NULL, 0, &outargs, 551*7c478bd9Sstevel@tonic-gate sizeof (picl_retfirstattr_t), SEND_REQ_TRYCOUNT); 552*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 553*7c478bd9Sstevel@tonic-gate return (err); 554*7c478bd9Sstevel@tonic-gate 555*7c478bd9Sstevel@tonic-gate /*LINTED*/ 556*7c478bd9Sstevel@tonic-gate ret = (picl_service_t *)darg.rbuf; 557*7c478bd9Sstevel@tonic-gate *proph = ret->ret_firstattr.attr; 558*7c478bd9Sstevel@tonic-gate if (darg.rbuf != (char *)&outargs) 559*7c478bd9Sstevel@tonic-gate (void) munmap(darg.rbuf, darg.rsize); 560*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 561*7c478bd9Sstevel@tonic-gate } 562*7c478bd9Sstevel@tonic-gate 563*7c478bd9Sstevel@tonic-gate /* 564*7c478bd9Sstevel@tonic-gate * This function copies the handle of the next property in list 565*7c478bd9Sstevel@tonic-gate * into <nextprop>. 566*7c478bd9Sstevel@tonic-gate */ 567*7c478bd9Sstevel@tonic-gate int 568*7c478bd9Sstevel@tonic-gate picl_get_next_prop(picl_prophdl_t proph, picl_prophdl_t *nextprop) 569*7c478bd9Sstevel@tonic-gate { 570*7c478bd9Sstevel@tonic-gate door_arg_t darg; 571*7c478bd9Sstevel@tonic-gate picl_reqnextattr_t req_nextattr; 572*7c478bd9Sstevel@tonic-gate picl_service_t *ret; 573*7c478bd9Sstevel@tonic-gate picl_retnextattr_t outargs; 574*7c478bd9Sstevel@tonic-gate int err; 575*7c478bd9Sstevel@tonic-gate 576*7c478bd9Sstevel@tonic-gate 577*7c478bd9Sstevel@tonic-gate req_nextattr.cnum = PICL_CNUM_GETNEXTATTR; 578*7c478bd9Sstevel@tonic-gate req_nextattr.attr = proph; 579*7c478bd9Sstevel@tonic-gate 580*7c478bd9Sstevel@tonic-gate err = trysend_req(&darg, &req_nextattr, 581*7c478bd9Sstevel@tonic-gate sizeof (picl_reqnextattr_t), NULL, 0, &outargs, 582*7c478bd9Sstevel@tonic-gate sizeof (picl_retnextattr_t), SEND_REQ_TRYCOUNT); 583*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 584*7c478bd9Sstevel@tonic-gate return (err); 585*7c478bd9Sstevel@tonic-gate 586*7c478bd9Sstevel@tonic-gate /*LINTED*/ 587*7c478bd9Sstevel@tonic-gate ret = (picl_service_t *)darg.rbuf; 588*7c478bd9Sstevel@tonic-gate *nextprop = ret->ret_nextattr.nextattr; 589*7c478bd9Sstevel@tonic-gate if (darg.rbuf != (char *)&outargs) 590*7c478bd9Sstevel@tonic-gate (void) munmap(darg.rbuf, darg.rsize); 591*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 592*7c478bd9Sstevel@tonic-gate } 593*7c478bd9Sstevel@tonic-gate 594*7c478bd9Sstevel@tonic-gate /* 595*7c478bd9Sstevel@tonic-gate * This function copies the handle of the property specified by its 596*7c478bd9Sstevel@tonic-gate * name into <proph>. 597*7c478bd9Sstevel@tonic-gate */ 598*7c478bd9Sstevel@tonic-gate int 599*7c478bd9Sstevel@tonic-gate picl_get_prop_by_name(picl_nodehdl_t nodeh, const char *name, 600*7c478bd9Sstevel@tonic-gate picl_prophdl_t *proph) 601*7c478bd9Sstevel@tonic-gate { 602*7c478bd9Sstevel@tonic-gate door_arg_t darg; 603*7c478bd9Sstevel@tonic-gate picl_reqattrbyname_t req_attrbyname; 604*7c478bd9Sstevel@tonic-gate picl_service_t *ret; 605*7c478bd9Sstevel@tonic-gate picl_retattrbyname_t outargs; 606*7c478bd9Sstevel@tonic-gate int err; 607*7c478bd9Sstevel@tonic-gate 608*7c478bd9Sstevel@tonic-gate req_attrbyname.cnum = PICL_CNUM_GETATTRBYNAME; 609*7c478bd9Sstevel@tonic-gate req_attrbyname.nodeh = nodeh; 610*7c478bd9Sstevel@tonic-gate (void) strcpy(req_attrbyname.propname, name); 611*7c478bd9Sstevel@tonic-gate 612*7c478bd9Sstevel@tonic-gate err = trysend_req(&darg, &req_attrbyname, 613*7c478bd9Sstevel@tonic-gate sizeof (picl_reqattrbyname_t), NULL, 0, &outargs, 614*7c478bd9Sstevel@tonic-gate sizeof (picl_retattrbyname_t), SEND_REQ_TRYCOUNT); 615*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 616*7c478bd9Sstevel@tonic-gate return (err); 617*7c478bd9Sstevel@tonic-gate 618*7c478bd9Sstevel@tonic-gate /*LINTED*/ 619*7c478bd9Sstevel@tonic-gate ret = (picl_service_t *)darg.rbuf; 620*7c478bd9Sstevel@tonic-gate *proph = ret->ret_attrbyname.attr; 621*7c478bd9Sstevel@tonic-gate if (darg.rbuf != (char *)&outargs) 622*7c478bd9Sstevel@tonic-gate (void) munmap(darg.rbuf, darg.rsize); 623*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 624*7c478bd9Sstevel@tonic-gate } 625*7c478bd9Sstevel@tonic-gate 626*7c478bd9Sstevel@tonic-gate /* 627*7c478bd9Sstevel@tonic-gate * This function copies the handle of the next property on the same 628*7c478bd9Sstevel@tonic-gate * row of the table into <rowproph>. 629*7c478bd9Sstevel@tonic-gate * When proph is the table handle, the handle of the property that is 630*7c478bd9Sstevel@tonic-gate * in first row and first column is copied. 631*7c478bd9Sstevel@tonic-gate */ 632*7c478bd9Sstevel@tonic-gate int 633*7c478bd9Sstevel@tonic-gate picl_get_next_by_row(picl_prophdl_t proph, picl_prophdl_t *rowproph) 634*7c478bd9Sstevel@tonic-gate { 635*7c478bd9Sstevel@tonic-gate door_arg_t darg; 636*7c478bd9Sstevel@tonic-gate picl_reqattrbyrow_t req_attrbyrow; 637*7c478bd9Sstevel@tonic-gate picl_service_t *ret; 638*7c478bd9Sstevel@tonic-gate picl_retattrbyrow_t outargs; 639*7c478bd9Sstevel@tonic-gate int err; 640*7c478bd9Sstevel@tonic-gate 641*7c478bd9Sstevel@tonic-gate req_attrbyrow.cnum = PICL_CNUM_GETATTRBYROW; 642*7c478bd9Sstevel@tonic-gate req_attrbyrow.attr = proph; 643*7c478bd9Sstevel@tonic-gate 644*7c478bd9Sstevel@tonic-gate err = trysend_req(&darg, &req_attrbyrow, 645*7c478bd9Sstevel@tonic-gate sizeof (picl_reqattrbyrow_t), NULL, 0, &outargs, 646*7c478bd9Sstevel@tonic-gate sizeof (picl_retattrbyrow_t), SEND_REQ_TRYCOUNT); 647*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 648*7c478bd9Sstevel@tonic-gate return (err); 649*7c478bd9Sstevel@tonic-gate 650*7c478bd9Sstevel@tonic-gate /*LINTED*/ 651*7c478bd9Sstevel@tonic-gate ret = (picl_service_t *)darg.rbuf; 652*7c478bd9Sstevel@tonic-gate *rowproph = ret->ret_attrbyrow.rowattr; 653*7c478bd9Sstevel@tonic-gate if (darg.rbuf != (char *)&outargs) 654*7c478bd9Sstevel@tonic-gate (void) munmap(darg.rbuf, darg.rsize); 655*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 656*7c478bd9Sstevel@tonic-gate } 657*7c478bd9Sstevel@tonic-gate 658*7c478bd9Sstevel@tonic-gate /* 659*7c478bd9Sstevel@tonic-gate * This function copies the handle of the next property on the same 660*7c478bd9Sstevel@tonic-gate * column of the table into <colproph>. 661*7c478bd9Sstevel@tonic-gate * When proph is the table handle, the handle of the property that is 662*7c478bd9Sstevel@tonic-gate * in the first row and first column is copied. 663*7c478bd9Sstevel@tonic-gate */ 664*7c478bd9Sstevel@tonic-gate int 665*7c478bd9Sstevel@tonic-gate picl_get_next_by_col(picl_prophdl_t proph, picl_prophdl_t *colproph) 666*7c478bd9Sstevel@tonic-gate { 667*7c478bd9Sstevel@tonic-gate door_arg_t darg; 668*7c478bd9Sstevel@tonic-gate picl_reqattrbycol_t req_attrbycol; 669*7c478bd9Sstevel@tonic-gate picl_service_t *ret; 670*7c478bd9Sstevel@tonic-gate picl_retattrbycol_t outargs; 671*7c478bd9Sstevel@tonic-gate int err; 672*7c478bd9Sstevel@tonic-gate 673*7c478bd9Sstevel@tonic-gate req_attrbycol.cnum = PICL_CNUM_GETATTRBYCOL; 674*7c478bd9Sstevel@tonic-gate req_attrbycol.attr = proph; 675*7c478bd9Sstevel@tonic-gate 676*7c478bd9Sstevel@tonic-gate err = trysend_req(&darg, (char *)&req_attrbycol, 677*7c478bd9Sstevel@tonic-gate sizeof (picl_reqattrbycol_t), NULL, 0, (char *)&outargs, 678*7c478bd9Sstevel@tonic-gate sizeof (picl_retattrbycol_t), SEND_REQ_TRYCOUNT); 679*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 680*7c478bd9Sstevel@tonic-gate return (err); 681*7c478bd9Sstevel@tonic-gate 682*7c478bd9Sstevel@tonic-gate /*LINTED*/ 683*7c478bd9Sstevel@tonic-gate ret = (picl_service_t *)darg.rbuf; 684*7c478bd9Sstevel@tonic-gate *colproph = ret->ret_attrbycol.colattr; 685*7c478bd9Sstevel@tonic-gate if (darg.rbuf != (char *)&outargs) 686*7c478bd9Sstevel@tonic-gate (void) munmap(darg.rbuf, darg.rsize); 687*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 688*7c478bd9Sstevel@tonic-gate } 689*7c478bd9Sstevel@tonic-gate 690*7c478bd9Sstevel@tonic-gate /* 691*7c478bd9Sstevel@tonic-gate * This function returns the picl error messages corresponding to the 692*7c478bd9Sstevel@tonic-gate * error number. 693*7c478bd9Sstevel@tonic-gate */ 694*7c478bd9Sstevel@tonic-gate char * 695*7c478bd9Sstevel@tonic-gate picl_strerror(int err) 696*7c478bd9Sstevel@tonic-gate { 697*7c478bd9Sstevel@tonic-gate if ((err < N_ERRORS) && (err >= 0)) { 698*7c478bd9Sstevel@tonic-gate return (gettext(picl_errmsg[err])); 699*7c478bd9Sstevel@tonic-gate } 700*7c478bd9Sstevel@tonic-gate return ((char *)NULL); 701*7c478bd9Sstevel@tonic-gate } 702*7c478bd9Sstevel@tonic-gate 703*7c478bd9Sstevel@tonic-gate /* 704*7c478bd9Sstevel@tonic-gate * recursively visit all nodes 705*7c478bd9Sstevel@tonic-gate */ 706*7c478bd9Sstevel@tonic-gate static int 707*7c478bd9Sstevel@tonic-gate do_walk(picl_nodehdl_t rooth, const char *classname, 708*7c478bd9Sstevel@tonic-gate void *c_args, int (*callback_fn)(picl_nodehdl_t hdl, void *args)) 709*7c478bd9Sstevel@tonic-gate { 710*7c478bd9Sstevel@tonic-gate int err; 711*7c478bd9Sstevel@tonic-gate picl_nodehdl_t chdh; 712*7c478bd9Sstevel@tonic-gate char classval[PICL_CLASSNAMELEN_MAX]; 713*7c478bd9Sstevel@tonic-gate 714*7c478bd9Sstevel@tonic-gate err = picl_get_propval_by_name(rooth, PICL_PROP_CHILD, &chdh, 715*7c478bd9Sstevel@tonic-gate sizeof (chdh)); 716*7c478bd9Sstevel@tonic-gate while (err == PICL_SUCCESS) { 717*7c478bd9Sstevel@tonic-gate err = picl_get_propval_by_name(chdh, PICL_PROP_CLASSNAME, 718*7c478bd9Sstevel@tonic-gate classval, sizeof (classval)); 719*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 720*7c478bd9Sstevel@tonic-gate return (err); 721*7c478bd9Sstevel@tonic-gate 722*7c478bd9Sstevel@tonic-gate if ((classname == NULL) || (strcmp(classname, classval) == 0)) { 723*7c478bd9Sstevel@tonic-gate err = callback_fn(chdh, c_args); 724*7c478bd9Sstevel@tonic-gate if (err != PICL_WALK_CONTINUE) 725*7c478bd9Sstevel@tonic-gate return (err); 726*7c478bd9Sstevel@tonic-gate } 727*7c478bd9Sstevel@tonic-gate 728*7c478bd9Sstevel@tonic-gate if ((err = do_walk(chdh, classname, c_args, callback_fn)) != 729*7c478bd9Sstevel@tonic-gate PICL_WALK_CONTINUE) 730*7c478bd9Sstevel@tonic-gate return (err); 731*7c478bd9Sstevel@tonic-gate 732*7c478bd9Sstevel@tonic-gate err = picl_get_propval_by_name(chdh, PICL_PROP_PEER, &chdh, 733*7c478bd9Sstevel@tonic-gate sizeof (chdh)); 734*7c478bd9Sstevel@tonic-gate } 735*7c478bd9Sstevel@tonic-gate if (err == PICL_PROPNOTFOUND) /* end of a branch */ 736*7c478bd9Sstevel@tonic-gate return (PICL_WALK_CONTINUE); 737*7c478bd9Sstevel@tonic-gate return (err); 738*7c478bd9Sstevel@tonic-gate 739*7c478bd9Sstevel@tonic-gate } 740*7c478bd9Sstevel@tonic-gate 741*7c478bd9Sstevel@tonic-gate /* 742*7c478bd9Sstevel@tonic-gate * This function walks the tree by class and invokes the callback 743*7c478bd9Sstevel@tonic-gate * function on class name matches. 744*7c478bd9Sstevel@tonic-gate */ 745*7c478bd9Sstevel@tonic-gate int 746*7c478bd9Sstevel@tonic-gate picl_walk_tree_by_class(picl_nodehdl_t rooth, const char *classname, 747*7c478bd9Sstevel@tonic-gate void *c_args, int (*callback_fn)(picl_nodehdl_t hdl, void *args)) 748*7c478bd9Sstevel@tonic-gate { 749*7c478bd9Sstevel@tonic-gate int err; 750*7c478bd9Sstevel@tonic-gate 751*7c478bd9Sstevel@tonic-gate if (callback_fn == NULL) 752*7c478bd9Sstevel@tonic-gate return (PICL_INVALIDARG); 753*7c478bd9Sstevel@tonic-gate err = do_walk(rooth, classname, c_args, callback_fn); 754*7c478bd9Sstevel@tonic-gate if ((err == PICL_WALK_CONTINUE) || (err == PICL_WALK_TERMINATE)) 755*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 756*7c478bd9Sstevel@tonic-gate return (err); 757*7c478bd9Sstevel@tonic-gate } 758*7c478bd9Sstevel@tonic-gate 759*7c478bd9Sstevel@tonic-gate /* 760*7c478bd9Sstevel@tonic-gate * This function gets propinfo and prop handle of the named property 761*7c478bd9Sstevel@tonic-gate */ 762*7c478bd9Sstevel@tonic-gate int 763*7c478bd9Sstevel@tonic-gate picl_get_propinfo_by_name(picl_nodehdl_t nodeh, const char *prop_name, 764*7c478bd9Sstevel@tonic-gate picl_propinfo_t *pinfo, picl_prophdl_t *proph) 765*7c478bd9Sstevel@tonic-gate { 766*7c478bd9Sstevel@tonic-gate int err; 767*7c478bd9Sstevel@tonic-gate picl_prophdl_t tmpproph; 768*7c478bd9Sstevel@tonic-gate picl_propinfo_t tmppinfo; 769*7c478bd9Sstevel@tonic-gate 770*7c478bd9Sstevel@tonic-gate err = picl_get_prop_by_name(nodeh, prop_name, &tmpproph); 771*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 772*7c478bd9Sstevel@tonic-gate return (err); 773*7c478bd9Sstevel@tonic-gate 774*7c478bd9Sstevel@tonic-gate err = picl_get_propinfo(tmpproph, &tmppinfo); 775*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 776*7c478bd9Sstevel@tonic-gate return (err); 777*7c478bd9Sstevel@tonic-gate 778*7c478bd9Sstevel@tonic-gate *proph = tmpproph; 779*7c478bd9Sstevel@tonic-gate *pinfo = tmppinfo; 780*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 781*7c478bd9Sstevel@tonic-gate } 782*7c478bd9Sstevel@tonic-gate 783*7c478bd9Sstevel@tonic-gate int 784*7c478bd9Sstevel@tonic-gate picl_get_node_by_path(const char *piclpath, picl_nodehdl_t *nodeh) 785*7c478bd9Sstevel@tonic-gate { 786*7c478bd9Sstevel@tonic-gate door_arg_t darg; 787*7c478bd9Sstevel@tonic-gate picl_reqnodebypath_t req; 788*7c478bd9Sstevel@tonic-gate picl_retnodebypath_t out; 789*7c478bd9Sstevel@tonic-gate picl_service_t *ret; 790*7c478bd9Sstevel@tonic-gate int err; 791*7c478bd9Sstevel@tonic-gate 792*7c478bd9Sstevel@tonic-gate req.cnum = PICL_CNUM_NODEBYPATH; 793*7c478bd9Sstevel@tonic-gate req.psize = PATH_MAX; 794*7c478bd9Sstevel@tonic-gate if (strlen(piclpath) >= PATH_MAX) 795*7c478bd9Sstevel@tonic-gate return (PICL_VALUETOOBIG); 796*7c478bd9Sstevel@tonic-gate (void) strncpy(req.pathbuf, piclpath, PATH_MAX); 797*7c478bd9Sstevel@tonic-gate 798*7c478bd9Sstevel@tonic-gate err = trysend_req(&darg, &req, sizeof (req), NULL, 0, &out, 799*7c478bd9Sstevel@tonic-gate sizeof (out), SEND_REQ_TRYCOUNT); 800*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 801*7c478bd9Sstevel@tonic-gate return (err); 802*7c478bd9Sstevel@tonic-gate 803*7c478bd9Sstevel@tonic-gate /*LINTED*/ 804*7c478bd9Sstevel@tonic-gate ret = (picl_service_t *)darg.rbuf; 805*7c478bd9Sstevel@tonic-gate *nodeh = ret->ret_nodebypath.nodeh; 806*7c478bd9Sstevel@tonic-gate if (darg.rbuf != (char *)&out) 807*7c478bd9Sstevel@tonic-gate (void) munmap(darg.rbuf, darg.rsize); 808*7c478bd9Sstevel@tonic-gate return (err); 809*7c478bd9Sstevel@tonic-gate } 810*7c478bd9Sstevel@tonic-gate 811*7c478bd9Sstevel@tonic-gate int 812*7c478bd9Sstevel@tonic-gate picl_find_node(picl_nodehdl_t rooth, char *pname, picl_prop_type_t ptype, 813*7c478bd9Sstevel@tonic-gate void *pval, size_t valsize, picl_nodehdl_t *retnodeh) 814*7c478bd9Sstevel@tonic-gate { 815*7c478bd9Sstevel@tonic-gate door_arg_t darg; 816*7c478bd9Sstevel@tonic-gate picl_reqfindnode_t *req; 817*7c478bd9Sstevel@tonic-gate picl_service_t *ret; 818*7c478bd9Sstevel@tonic-gate picl_retfindnode_t out; 819*7c478bd9Sstevel@tonic-gate int err; 820*7c478bd9Sstevel@tonic-gate 821*7c478bd9Sstevel@tonic-gate req = alloca(sizeof (picl_reqfindnode_t) + valsize); 822*7c478bd9Sstevel@tonic-gate req->cnum = PICL_CNUM_FINDNODE; 823*7c478bd9Sstevel@tonic-gate req->nodeh = rooth; 824*7c478bd9Sstevel@tonic-gate if (strlen(pname) >= PICL_PROPNAMELEN_MAX) 825*7c478bd9Sstevel@tonic-gate return (PICL_VALUETOOBIG); 826*7c478bd9Sstevel@tonic-gate (void) strncpy(req->propname, pname, PICL_PROPNAMELEN_MAX); 827*7c478bd9Sstevel@tonic-gate req->ptype = ptype; 828*7c478bd9Sstevel@tonic-gate req->valsize = (uint32_t)valsize; 829*7c478bd9Sstevel@tonic-gate if ((size_t)req->valsize != valsize) 830*7c478bd9Sstevel@tonic-gate return (PICL_VALUETOOBIG); 831*7c478bd9Sstevel@tonic-gate (void) memcpy(req->valbuf, pval, valsize); 832*7c478bd9Sstevel@tonic-gate 833*7c478bd9Sstevel@tonic-gate err = trysend_req(&darg, req, sizeof (picl_reqfindnode_t) + valsize, 834*7c478bd9Sstevel@tonic-gate NULL, 0, &out, sizeof (out), SEND_REQ_TRYCOUNT); 835*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 836*7c478bd9Sstevel@tonic-gate return (err); 837*7c478bd9Sstevel@tonic-gate 838*7c478bd9Sstevel@tonic-gate /*LINTED*/ 839*7c478bd9Sstevel@tonic-gate ret = (picl_service_t *)darg.rbuf; 840*7c478bd9Sstevel@tonic-gate *retnodeh = ret->ret_findnode.rnodeh; 841*7c478bd9Sstevel@tonic-gate if (darg.rbuf != (char *)&out) 842*7c478bd9Sstevel@tonic-gate (void) munmap(darg.rbuf, darg.rsize); 843*7c478bd9Sstevel@tonic-gate return (err); 844*7c478bd9Sstevel@tonic-gate } 845*7c478bd9Sstevel@tonic-gate 846*7c478bd9Sstevel@tonic-gate int 847*7c478bd9Sstevel@tonic-gate picl_get_frutree_parent(picl_nodehdl_t devh, picl_nodehdl_t *fruh) 848*7c478bd9Sstevel@tonic-gate { 849*7c478bd9Sstevel@tonic-gate door_arg_t darg; 850*7c478bd9Sstevel@tonic-gate picl_reqfruparent_t req; 851*7c478bd9Sstevel@tonic-gate picl_retfruparent_t out; 852*7c478bd9Sstevel@tonic-gate picl_service_t *ret; 853*7c478bd9Sstevel@tonic-gate int err; 854*7c478bd9Sstevel@tonic-gate 855*7c478bd9Sstevel@tonic-gate req.cnum = PICL_CNUM_FRUTREEPARENT; 856*7c478bd9Sstevel@tonic-gate req.devh = devh; 857*7c478bd9Sstevel@tonic-gate 858*7c478bd9Sstevel@tonic-gate err = trysend_req(&darg, &req, sizeof (req), NULL, 0, &out, 859*7c478bd9Sstevel@tonic-gate sizeof (out), SEND_REQ_TRYCOUNT); 860*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 861*7c478bd9Sstevel@tonic-gate return (err); 862*7c478bd9Sstevel@tonic-gate 863*7c478bd9Sstevel@tonic-gate /*LINTED*/ 864*7c478bd9Sstevel@tonic-gate ret = (picl_service_t *)darg.rbuf; 865*7c478bd9Sstevel@tonic-gate *fruh = ret->ret_fruparent.fruh; 866*7c478bd9Sstevel@tonic-gate if (darg.rbuf != (char *)&out) 867*7c478bd9Sstevel@tonic-gate (void) munmap(darg.rbuf, darg.rsize); 868*7c478bd9Sstevel@tonic-gate return (err); 869*7c478bd9Sstevel@tonic-gate } 870