summaryrefslogtreecommitdiff
path: root/usr/src/lib/efcode/fcdriver/phandle.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/efcode/fcdriver/phandle.c')
-rw-r--r--usr/src/lib/efcode/fcdriver/phandle.c204
1 files changed, 204 insertions, 0 deletions
diff --git a/usr/src/lib/efcode/fcdriver/phandle.c b/usr/src/lib/efcode/fcdriver/phandle.c
new file mode 100644
index 0000000000..79a202da4e
--- /dev/null
+++ b/usr/src/lib/efcode/fcdriver/phandle.c
@@ -0,0 +1,204 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1999 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <fcode/private.h>
+#include <fcode/log.h>
+
+#include <fcdriver/fcdriver.h>
+
+
+static int use_os_handle = 1;
+
+void
+do_use_os_handles(fcode_env_t *env)
+{
+ use_os_handle = 1;
+}
+
+void
+do_use_fake_handles(fcode_env_t *env)
+{
+ log_message(MSG_ERROR, "WARNING: using fake phandles, test only\n");
+ use_os_handle = 0;
+}
+
+static int
+match_nodeid(void *s, void *d)
+{
+ my_nodeid_t *src = s;
+ my_nodeid_t *dest = d;
+ return ((src->node) == (dest->node));
+}
+
+static int
+match_handle(void *s, void *d)
+{
+ my_nodeid_t *src = s;
+ my_nodeid_t *dest = d;
+ return ((src->my_handle) == (dest->my_handle));
+}
+
+/*
+ * Convert from an OS phandle to an interpreter phandle
+ */
+device_t *
+convert_phandle(fcode_env_t *env, fstack_t d)
+{
+ fc_resource_t *t;
+ common_data_t *cdp = env->private;
+ device_t *r;
+
+ if (use_os_handle) {
+ my_nodeid_t nh;
+ nh.my_handle = (fc_phandle_t) d;
+ t = find_resource(&cdp->nodeids, &nh, match_handle);
+ if (t == NULL) {
+ r = 0;
+ } else {
+ my_nodeid_t *p = (my_nodeid_t *) t->data;
+ r = (device_t *) p->node;
+ }
+ } else
+ r = (device_t *)d;
+ return (r);
+}
+
+/*
+ * Interpreter phandle to OS phandle
+ */
+fstack_t
+revert_phandle(fcode_env_t *env, device_t *d)
+{
+ fc_resource_t *t;
+ common_data_t *cdp = env->private;
+ fstack_t r;
+
+ if (use_os_handle) {
+ my_nodeid_t nh;
+ nh.node = d;
+ t = find_resource(&cdp->nodeids, &nh, match_nodeid);
+ if (t == NULL) {
+ r = 0;
+ } else {
+ my_nodeid_t *p = (my_nodeid_t *) t->data;
+ r = (fstack_t) p->my_handle;
+ }
+ } else
+ r = (fstack_t) d;
+ return (r);
+}
+
+void
+add_my_handle(fcode_env_t *env, fc_phandle_t mh, device_t *d)
+{
+ my_nodeid_t *nh;
+ common_data_t *cdp = env->private;
+
+ nh = MALLOC(sizeof (my_nodeid_t));
+ nh->my_handle = mh;
+ nh->node = d;
+ if (add_resource(&cdp->nodeids, nh, match_handle) == NULL) {
+ log_message(MSG_ERROR, "add_my_handle: add_resource failed\n");
+ }
+}
+
+void
+allocate_phandle(fcode_env_t *env)
+{
+ private_data_t *pd;
+ common_data_t *cdp;
+ int error;
+ char *service;
+ device_t *current;
+ fc_cell_t hcell;
+
+ if ((cdp = env->private) == NULL) {
+ log_message(MSG_ERROR, "allocate_phandle: NULL common\n");
+ return;
+ }
+
+ if (!cdp->init_done)
+ return;
+
+ current = MYSELF->device;
+ ASSERT(current);
+
+ if (cdp->first_node) {
+ service = FC_CONFIG_CHILD;
+ cdp->first_node = 0;
+ } else {
+ service = FC_ALLOC_PHANDLE;
+ }
+
+ pd = MALLOC(sizeof (private_data_t));
+ pd->common = cdp;
+ pd->parent = (fc_phandle_t) revert_phandle(env, current->parent);
+ pd->upload = (cdp->init_done == 1);
+ current->private = pd;
+
+ error = fc_run_priv(cdp, service, 0, 1, &hcell);
+
+ pd->node = fc_cell2phandle(hcell);
+
+ add_my_handle(env, pd->node, current);
+}
+
+fc_phandle_t
+fc_get_ap(common_data_t *cdp)
+{
+ fc_cell_t hcell;
+ int error;
+
+ error = fc_run_priv(cdp, FC_AP_PHANDLE, 0, 1, &hcell);
+
+ if (error)
+ exit(1);
+
+ return (fc_cell2phandle(hcell));
+}
+
+
+#pragma init(_init)
+
+static void
+_init(void)
+{
+ fcode_env_t *env = initial_env;
+
+ ASSERT(env);
+ NOTICE;
+
+ env->convert_phandle = convert_phandle;
+ env->revert_phandle = revert_phandle;
+ env->allocate_phandle = allocate_phandle;
+ FORTH(0, "use-os-handles", do_use_os_handles);
+ FORTH(0, "use-fake-handles", do_use_fake_handles);
+}