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
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.
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]
23 * Copyright (c) 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
37 #include <fcode/private.h>
38 #include <fcode/log.h>
40 #include <fcdriver/fcdriver.h>
43 fc_nodeop(common_data_t
*cdp
, fc_phandle_t node
, char *svc
)
48 error
= fc_run_priv(cdp
, svc
, 1, 1, fc_phandle2cell(node
), &hcell
);
51 return (fc_cell2phandle(hcell
));
55 recurse_tree(fcode_env_t
*env
, device_t
*d
,
56 void (*fn
)(fcode_env_t
*, device_t
*))
62 recurse_tree(env
, d
->child
, fn
);
63 recurse_tree(env
, d
->peer
, fn
);
68 get_prom_nodeid(fcode_env_t
*env
, device_t
*d
)
70 common_data_t
*cdp
= env
->private;
71 private_data_t
*pd
= d
->private;
76 if ((pd
!= NULL
) && (pd
->node
)) {
77 if (os_get_prop_common(cdp
, pd
->node
, "name",
78 0, &namebuf
, &namelen
))
79 namebuf
= "<unknown>";
80 debug_msg(DEBUG_UPLOAD
, "Populated: %s = %p\n", namebuf
,
85 name
= get_package_name(env
, d
);
86 debug_msg(DEBUG_UPLOAD
, "Node %s: %p (%p)\n", name
, d
, pd
);
88 private_data_t
*ppd
= (private_data_t
*) d
->parent
->private;
89 fc_phandle_t thisnode
;
91 if (os_get_prop_common(cdp
, ppd
->node
, "name",
92 0, &namebuf
, &namelen
))
93 namebuf
= "<unknown>";
94 debug_msg(DEBUG_UPLOAD
, "Parent: %p (%p) %s = %p\n", d
->parent
,
95 ppd
, namebuf
, ppd
->node
);
96 for (thisnode
= fc_nodeop(cdp
, ppd
->node
, FC_CHILD_FCODE
);
98 thisnode
= fc_nodeop(cdp
, thisnode
, FC_PEER_FCODE
)) {
103 status
= os_get_prop_common(cdp
, thisnode
, "name",
104 0, &namebuf
, &namelen
);
105 debug_msg(DEBUG_UPLOAD
, "Lookup: %p name '%s'\n"
106 " status: %d", thisnode
, namebuf
, status
);
107 if (status
== 0 && strcmp(name
, namebuf
) == 0)
111 pd
= MALLOC(sizeof (private_data_t
));
116 add_my_handle(env
, pd
->node
, d
);
117 install_property_vectors(env
, d
);
118 debug_msg(DEBUG_UPLOAD
, "Found: %p\n", thisnode
);
124 update_nodeids(fcode_env_t
*env
)
127 * We scan through the tree looking for nodes that don't have
128 * one of my structures attached, and for each of those nodes
129 * I attempt to match it with a real firmware node
131 recurse_tree(env
, env
->root_node
, get_prom_nodeid
);
135 build_nodes(fcode_env_t
*env
, common_data_t
*cdp
, fc_phandle_t h
)
139 int n
, allocd
, depth
;
141 device_t
*current
, *attach
;
143 private_data_t
**node_array
;
146 * This is not nice; new_device calls the allocate_phandle
147 * routine without exception, we need to disable the allocation
148 * while we are building the tree to the attachment point
149 * which is why the init_done variable exists.
154 allocd
= sizeof (private_data_t
*);
156 node_array
= REALLOC(node_array
, allocd
*(depth
+1));
157 pd
= MALLOC(sizeof (private_data_t
));
159 node_array
[depth
] = pd
;
161 (void) os_get_prop_common(cdp
, pd
->node
, "name", 0, &name
,
164 debug_msg(DEBUG_UPLOAD
, "Node: %p name: '%s'\n", h
,
167 log_message(MSG_ERROR
, "Node: %p Unnamed node!!\n", h
);
169 h
= fc_nodeop(cdp
, h
, FC_PARENT
);
172 for (n
= 0; n
< (depth
-1); n
++) {
176 env
->attachment_pt
= current
= attach
= env
->current_device
;
178 for (n
= 0; n
< depth
; n
++) {
181 current
->private = pd
;
182 add_my_handle(env
, pd
->node
, current
);
183 install_property_vectors(env
, current
);
184 current
= current
->parent
;
187 for (current
= attach
; current
!= NULL
; current
= current
->parent
) {
188 install_node_data(env
, current
);
201 build_tree(fcode_env_t
*env
)
203 common_data_t
*cdp
= env
->private;
207 ih
= open_instance_chain(env
, env
->current_device
, 0);
209 build_nodes(env
, cdp
, cdp
->attach
);
210 close_instance_chain(env
, ih
, 0);
216 * Installs /openprom and /packages nodes and sub-nodes.
219 install_builtin_nodes(fcode_env_t
*env
)
221 common_data_t
*cdp
= env
->private;
222 int saved_first_node
;
226 saved_first_node
= cdp
->first_node
;
227 saved_init_done
= cdp
->init_done
;
230 install_openprom_nodes(env
);
231 install_package_nodes(env
);
232 cdp
->first_node
= saved_first_node
;
233 cdp
->init_done
= saved_init_done
;
243 fcode_env_t
*env
= initial_env
;
248 FORTH(0, "update-nodes", update_nodeids
);
249 FORTH(0, "build-tree", build_tree
);