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