OpenSolaris_b135/lib/efcode/fcdriver/phandle.c

Compare this file to the similar file:
Show the results in this format:

/*
 * 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);
}