/*
* 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
* 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 2000, 2002 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* fc_ops.c: Framework generic fcode ops
*/
#include <sys/ddi_implfuncs.h>
#include <sys/ndi_impldefs.h>
#include <sys/ethernet.h>
struct fc_ops_v {
char *svc_name;
fc_ops_t *f;
};
{ "open", fc_fail_op},
{ "close", fc_fail_op},
{ "$find", fc_fail_op},
{ "encode-unit", fc_fail_op},
{ "decode-unit", fc_fail_op},
{ "child", fco_child},
{ "peer", fco_peer},
{ FC_PARENT, fco_parent},
{ FC_SVC_EXIT, fco_exit},
{ "local-ether-addr", fco_local_ether_addr},
};
/*
* Allocate a handle for the ops function .. our handle is a resource list
* Return the handle to our caller, so he can call us with it when we need it.
*/
/*ARGSUSED*/
{
char *up;
if (unit_address) {
}
/*
* Create our copy of the device tree.
*/
return (rp);
}
/*
* Free any resources associated with this handle.
*/
void
{
if (rp->unit_address)
case RT_NODEID:
break;
default:
break;
}
}
}
int
{
return (-1);
}
/*
* The interpreter can't do get-inherited-property directly,
* because we don't want to return a kernel address, so it
* has to break up the request into a get-proplen and get-prop
* call so it can allocate memory for the property and pass that
* buffer in to get-prop. The buffer should be 'suitably aligned'.
*
* XXX: We don't know the property type, so we can't return
* prop-encoded arrays, which fortunately, isn't a problem
* on big-endian machines.
*
* get-proplen has one result: proplen
* proplen is returned as -1 if the propname doesn't exist and
* as zero if the property is a boolean property.
*
* get-prop has one result: proplen, returned as -1 if propname doesn't exist.
*/
/*
* fco_getproplen ( propname phandle -- proplen )
*/
/*ARGSUSED*/
static int
{
int proplen;
int flags = 0;
fc_phandle_t h;
char *pnp;
/*
* Make sure this is a handle we gave out ...
*/
/*
* XXX: We should care if the string is longer than OBP_MAXPROPNAME
*/
proplen = -1;
}
/*
* fco_getprop ( propname buffer phandle -- proplen )
*/
/*ARGSUSED*/
static int
{
fc_phandle_t h;
/*
* Make sure this is a handle we gave out ...
*/
/*
* XXX: We should care if the string is longer than OBP_MAXPROPNAME
*/
proplen = -1;
if (proplen > 0) {
int error;
if (error)
}
}
static int
{
fc_phandle_t h;
}
static int
{
fc_phandle_t h;
/*
* Make sure this is a handle we gave out ...
*/
/*
* Find the child and if there is one, return it ...
*/
h = 0;
}
static int
{
fc_phandle_t h;
/*
* Make sure this is a handle we gave out ...
*/
/*
* Find the child and if there is one, return it ...
*/
h = 0;
}
static int
{
fc_phandle_t h;
/*
* Make sure this is a handle we gave out ...
*/
/*
* Find the parent and if there is one, return it ...
*/
h = 0;
}
/*
* Allocate a phandle ... we don't currently track the phandle.
*/
static int
{
fc_phandle_t h;
int n;
if (impl_ddi_alloc_nodeid(&n))
/*
* Log the nodeid resource so we can release it later if we need to.
*/
ip->fc_nodeid_r = n;
h = (fc_phandle_t)n;
}
static struct fc_resource *
{
continue;
if (ip->fc_nodeid_r == n)
break;
}
return (ip);
}
/*
* fco_new_device ( name-cstr unit-addr-cstr parent.phandle phandle -- )
*/
static int
{
char *s;
int createmode = 0;
/*
* Make sure these are handles we gave out ... and we have
* a corresponding parent devinfo node.
*/
switch (rp->cdip_state) {
case FC_CDIP_NOSTATE:
/*
* The first child must be a child of the attachment point.
*/
"child of the attachment point"));
/*
* If this bus has a config child, the first child must
* be the configuration child. Otherwise, the child must
* be a new (unknown) node.
*/
"child must be the "
"configuration child"));
} else {
"unknown child expected"));
}
}
break;
case FC_CDIP_DONE:
/*
* If we've already created the first child, this
* child must be unknown and the parent must be a known
* child of the attachment point.
*/
if (cdev)
"unknown child expected"));
"child of the attachment point"));
break;
default:
/*
* If we're in some other state, we shouldn't be here.
*/
/* NOTREACHED */
}
/*
* Get the nodename and the unit address.
*/
}
/*
* If cdev is NULL, we have to create the child, otherwise, the
* child already exists and we're just merging properties into
* the existing node. The node must be unbound.
*/
createmode = 1;
if (createmode) {
int nodeid;
/*
* Make sure 'ch' is a nodeid we gave the interpreter.
* It must be on our resource list.
*/
}
/*
* Allocate a self-identifying, persistent node with
* the auto-free attribute.
*/
}
/*
* Free the nodeid we just allocated here, and use
* the one we handed in. Retain the attributes of
* the original SID nodetype.
*/
/*
* Remove nodeid 'ch' from our resource list, now that it
* will be managed by the ddi framework.
*/
}
}
if (createmode)
(void) ndi_devi_free(cdev);
}
/*
* Add the dip->phandle translation to our list of known phandles.
*/
/*
* Add the new node to our copy of the subtree.
*/
}
/*
* fco_finish_device ( phandle -- )
*/
static int
{
fc_phandle_t h;
/*
* We don't want to online children of the attachment point.
* We'll 'config' them online later.
*
* XXX - APA - I've changed this a bit. The only time we don't
* want to bind the device is if the parent is the attachment point
* and the device is the same as the device that was passed to
* the interpreter. We assume the configurator will do the binding.
*/
} else {
(void) ndi_devi_bind_driver(cdev, 0);
}
}
/*
* fco_create_property ( propname-cstr buf len phandle -- )
*/
static int
{
fc_phandle_t h;
int error;
if (len != 0) {
}
}
/*
* check for propname: 'name' ... we don't allow it
* by changed here. It has to be specified when the node
* is created.
*/
char *n = ddi_node_name(dev);
if (len == 0)
}
/*
* Since we're not changing the value, and we already created
* the 'name' property when we created the node ...
*/
}
if (len != 0)
if (error)
}
/*
* Make sure any in-progress activity is completed,
* and for now, online the subtree.
* XXX: Presumably the configurator will online the subtree
* XXX: by doing an ndi_devi_online with NDI_CONFIG on the child
* XXX: if there is one. For now, we're doing it here.
* XXX: For buses without a configurator (and thus no config child),
* XXX: we have to do it here.
*
*/
static int
{
}
static void
{
/*
* Remove the subtree, depth first. Each iterative
* call gets another child at each level of the tree
* until there are no more children.
*/
/*
* Delete the subtree root and remove its record from our
* copy of the subtree.
*/
}
static int
{
/*
* If we created any children, delete them. The root node is the
* config child, if one exists for this bus, otherwise it's the
* attachment point.
*
* Our copy of the subtree only contains records of nodes we created
* under the subtree root and contains the parent->child linkage
* that isn't yet established in the real device tree.
*
* XXX: What we don't do is restore the config child node to it's
* pre-interpretive state. (We may have added properties to
* that node. It's not clear if its necessary to clean them up.)
*/
}
if (configured)
}
static int
{
}
/*
* Needed to implement 'mac-address' Fcode, no obvious place to pick this
* info up from user-land.
*/
static int
{
}
#ifdef DEBUG
void
{
}
#endif