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
do_use_os_handles(fcode_env_t * env)41 do_use_os_handles(fcode_env_t *env)
42 {
43 use_os_handle = 1;
44 }
45
46 void
do_use_fake_handles(fcode_env_t * env)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
match_nodeid(void * s,void * d)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
match_handle(void * s,void * d)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 *
convert_phandle(fcode_env_t * env,fstack_t d)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
revert_phandle(fcode_env_t * env,device_t * d)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
add_my_handle(fcode_env_t * env,fc_phandle_t mh,device_t * d)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
allocate_phandle(fcode_env_t * env)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
fc_get_ap(common_data_t * cdp)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
_init(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