xref: /titanic_52/usr/src/lib/efcode/fcdriver/phandle.c (revision 911106dfb16696472af8c1b7b4c554a829354fa8)
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