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) 1999 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 <stdlib.h> 31 #include <strings.h> 32 #include <fcode/private.h> 33 #include <fcode/log.h> 34 35 #include <fcdriver/fcdriver.h> 36 37 38 static int use_os_handle = 1; 39 40 void 41 do_use_os_handles(fcode_env_t *env) 42 { 43 use_os_handle = 1; 44 } 45 46 void 47 do_use_fake_handles(fcode_env_t *env) 48 { 49 log_message(MSG_ERROR, "WARNING: using fake phandles, test only\n"); 50 use_os_handle = 0; 51 } 52 53 static int 54 match_nodeid(void *s, void *d) 55 { 56 my_nodeid_t *src = s; 57 my_nodeid_t *dest = d; 58 return ((src->node) == (dest->node)); 59 } 60 61 static int 62 match_handle(void *s, void *d) 63 { 64 my_nodeid_t *src = s; 65 my_nodeid_t *dest = d; 66 return ((src->my_handle) == (dest->my_handle)); 67 } 68 69 /* 70 * Convert from an OS phandle to an interpreter phandle 71 */ 72 device_t * 73 convert_phandle(fcode_env_t *env, fstack_t d) 74 { 75 fc_resource_t *t; 76 common_data_t *cdp = env->private; 77 device_t *r; 78 79 if (use_os_handle) { 80 my_nodeid_t nh; 81 nh.my_handle = (fc_phandle_t) d; 82 t = find_resource(&cdp->nodeids, &nh, match_handle); 83 if (t == NULL) { 84 r = 0; 85 } else { 86 my_nodeid_t *p = (my_nodeid_t *) t->data; 87 r = (device_t *) p->node; 88 } 89 } else 90 r = (device_t *)d; 91 return (r); 92 } 93 94 /* 95 * Interpreter phandle to OS phandle 96 */ 97 fstack_t 98 revert_phandle(fcode_env_t *env, device_t *d) 99 { 100 fc_resource_t *t; 101 common_data_t *cdp = env->private; 102 fstack_t r; 103 104 if (use_os_handle) { 105 my_nodeid_t nh; 106 nh.node = d; 107 t = find_resource(&cdp->nodeids, &nh, match_nodeid); 108 if (t == NULL) { 109 r = 0; 110 } else { 111 my_nodeid_t *p = (my_nodeid_t *) t->data; 112 r = (fstack_t) p->my_handle; 113 } 114 } else 115 r = (fstack_t) d; 116 return (r); 117 } 118 119 void 120 add_my_handle(fcode_env_t *env, fc_phandle_t mh, device_t *d) 121 { 122 my_nodeid_t *nh; 123 common_data_t *cdp = env->private; 124 125 nh = MALLOC(sizeof (my_nodeid_t)); 126 nh->my_handle = mh; 127 nh->node = d; 128 if (add_resource(&cdp->nodeids, nh, match_handle) == NULL) { 129 log_message(MSG_ERROR, "add_my_handle: add_resource failed\n"); 130 } 131 } 132 133 void 134 allocate_phandle(fcode_env_t *env) 135 { 136 private_data_t *pd; 137 common_data_t *cdp; 138 int error; 139 char *service; 140 device_t *current; 141 fc_cell_t hcell; 142 143 if ((cdp = env->private) == NULL) { 144 log_message(MSG_ERROR, "allocate_phandle: NULL common\n"); 145 return; 146 } 147 148 if (!cdp->init_done) 149 return; 150 151 current = MYSELF->device; 152 ASSERT(current); 153 154 if (cdp->first_node) { 155 service = FC_CONFIG_CHILD; 156 cdp->first_node = 0; 157 } else { 158 service = FC_ALLOC_PHANDLE; 159 } 160 161 pd = MALLOC(sizeof (private_data_t)); 162 pd->common = cdp; 163 pd->parent = (fc_phandle_t) revert_phandle(env, current->parent); 164 pd->upload = (cdp->init_done == 1); 165 current->private = pd; 166 167 error = fc_run_priv(cdp, service, 0, 1, &hcell); 168 169 pd->node = fc_cell2phandle(hcell); 170 171 add_my_handle(env, pd->node, current); 172 } 173 174 fc_phandle_t 175 fc_get_ap(common_data_t *cdp) 176 { 177 fc_cell_t hcell; 178 int error; 179 180 error = fc_run_priv(cdp, FC_AP_PHANDLE, 0, 1, &hcell); 181 182 if (error) 183 exit(1); 184 185 return (fc_cell2phandle(hcell)); 186 } 187 188 189 #pragma init(_init) 190 191 static void 192 _init(void) 193 { 194 fcode_env_t *env = initial_env; 195 196 ASSERT(env); 197 NOTICE; 198 199 env->convert_phandle = convert_phandle; 200 env->revert_phandle = revert_phandle; 201 env->allocate_phandle = allocate_phandle; 202 FORTH(0, "use-os-handles", do_use_os_handles); 203 FORTH(0, "use-fake-handles", do_use_fake_handles); 204 } 205