1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 2000 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdio.h> 30 #include <unistd.h> 31 #include <stdlib.h> 32 #include <strings.h> 33 34 #include <fcode/private.h> 35 #include <fcode/log.h> 36 37 #include <fcdriver/fcdriver.h> 38 39 40 static char *prop_buf; 41 42 static int 43 getproplen(common_data_t *cdp, fc_phandle_t node, char *propname, int inherit) 44 { 45 fc_cell_t len; 46 char *service; 47 int error; 48 49 service = inherit ? FC_GET_IN_PROPLEN : FC_GET_PKG_PROPLEN; 50 51 error = fc_run_priv(cdp, service, 2, 1, fc_phandle2cell(node), 52 fc_ptr2cell(propname), &len); 53 if (error) 54 return (-1); 55 56 return (fc_cell2int(len)); 57 } 58 59 static int 60 getprop(common_data_t *cdp, fc_phandle_t node, char *propname, char *buf, 61 int inherit) 62 { 63 fc_cell_t len; 64 char *service; 65 int error; 66 67 service = inherit ? FC_GET_IN_PROP : FC_GET_PKG_PROP; 68 69 error = fc_run_priv(cdp, service, 3, 1, fc_phandle2cell(node), 70 fc_ptr2cell(buf), fc_ptr2cell(propname), &len); 71 if (error) 72 return (-1); 73 74 return (fc_cell2int(len)); 75 } 76 77 int 78 os_get_prop_common(common_data_t *cdp, fc_phandle_t node, char *name, 79 int inherit, char **buf, int *len) 80 { 81 int i, j; 82 char *bp; 83 84 i = getproplen(cdp, node, name, inherit); 85 if (i <= 0) { 86 /* 87 * OK for properties to be undefined, suppress error message 88 * unless some debug is on. 89 */ 90 if (get_interpreter_debug_level()) 91 log_message(MSG_ERROR, "os_get_prop_common:" 92 " getproplen(%s) returned %d\n", name, i); 93 return (-1); 94 } 95 bp = MALLOC(i); 96 97 j = getprop(cdp, node, name, bp, inherit); 98 if (i != j) { 99 /* 100 * It's an error if getproplen succeeded but getprop didn't 101 * return a matching length. 102 */ 103 log_message(MSG_ERROR, "os_get_prop_common: getprop(%s)" 104 " return %d, getproplen returned %d\n", name, j, i); 105 FREE(bp); 106 return (-2); 107 } 108 memcpy(prop_buf, bp, i); 109 *buf = prop_buf; 110 *len = i; 111 FREE(bp); 112 return (0); 113 } 114 115 static void 116 os_get_prop(fcode_env_t *env, int inherit, device_t *dev) 117 { 118 fc_phandle_t node; 119 char *name; 120 char *prop; 121 int len; 122 private_data_t *pd; 123 124 ASSERT(dev); 125 126 pd = dev->private; 127 ASSERT(pd); 128 129 name = pop_a_string(env, &len); 130 131 node = pd->node; 132 if (node == NULL) { 133 log_message(MSG_ERROR, "os_get_prop: NULL node: %s\n", 134 get_path(env, dev)); 135 PUSH(DS, TRUE); 136 } else if (os_get_prop_common(pd->common, node, name, inherit, &prop, 137 &len)) { 138 PUSH(DS, TRUE); 139 } else { 140 PUSH(DS, (fstack_t)prop); 141 PUSH(DS, len); 142 PUSH(DS, FALSE); 143 } 144 } 145 146 static void 147 os_get_package_prop(fcode_env_t *env) 148 { 149 device_t *dev; 150 151 CONVERT_PHANDLE(env, dev, POP(DS)); 152 os_get_prop(env, 0, dev); 153 } 154 155 static void 156 os_get_inherited_prop(fcode_env_t *env) 157 { 158 os_get_prop(env, 1, env->attachment_pt); 159 } 160 161 void 162 install_property_vectors(fcode_env_t *env, device_t *d) 163 { 164 d->vectors.get_package_prop = os_get_package_prop; 165 d->vectors.get_inherited_prop = os_get_inherited_prop; 166 } 167 168 #pragma init(_init) 169 170 static void 171 _init(void) 172 { 173 fcode_env_t *env = initial_env; 174 175 ASSERT(env); 176 NOTICE; 177 178 prop_buf = MALLOC(4096); 179 180 } 181