/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* DACF (Device Autoconfiguration Framework) client code.
*
* DACF has two clients. the first is dacf modules which implement
* configuration operations; the second is the set of hooks in the kernel
* which do rule matching and invoke configuration operations.
*
* This file implements the second part, the kernel hooks.
*
* Currently implemented are post-attach and pre-detach handlers, and the hook
* for ddi_create_minor_common() which sets up post-attach and pre-detach
* reservations.
*
* This code depends on the core dacf code (in dacf.c) but the converse should
* never be true.
*
* This file also implements '__kernel', the kernel-supplied dacf module.
* For now, this is pretty much empty, except under DEBUG, in which case it
* contains some debugging code.
*/
#include <sys/sysmacros.h>
#include <sys/pathname.h>
#include <sys/ddi_impldefs.h>
#include <sys/autoconf.h>
#include <sys/dacf_impl.h>
/*
* dacfc_match_create_minor()
* Check to see if this minor node creation sequence matches a dacf
* (device autoconfiguration framework) rule. If so make a reservation
*/
void
{
dacf_rule_t *r;
/*
* Check the dacf rule for non-clone devices or for network devices.
*/
return;
}
/*
* Because dacf currently only implements post-attach and pre-detach
* processing, we only care about minor nodes created during attach.
* However, there is no restriction on drivers about when to create
* minor nodes.
*/
return;
}
if (name) {
drv_name = "???";
}
/*
* Ensure that we don't wind up in a 'matching loop' against a devinfo
* node, which could cause deadlock. This could happen as follows:
*
* We match (just below)
* We invoke a task (later, at the end of devi_attach)
* this means we have taken the per-devinfo lock
* The task invoke winds up causing the same driver (that has
* just finished attaching) to create another minor node.
* We try to re-acquire the per-devinfo list lock again in the
* process of making another reservation
*/
if (DEVI_IS_INVOKING_DACF(dip)) {
"!dacf detected deadlock, aborting matching procedure\n");
if (drv_mname) {
}
return;
}
/*
* Do rule matching. It's possible to construct two rules that would
* match against the same minor node, so we match from most to least
* specific:
* device path
* minor node name (concatenation of drv_name:name
* node type
*
* Future additions to the set of device-specifiers should be
* sensitive to this ordering.
*/
/*
* post-attach matching
*/
r = NULL;
if (dev_pathp) {
}
if (!r && drv_mname) {
}
if (!r && node_type) {
}
if (r) {
if (dacfdebug & DACF_DBG_MSGS)
printf("dacf: made 'post-attach' reservation for "
} else {
}
/*
* pre-detach matching
*/
r = NULL;
if (dev_pathp) {
}
if (!r && drv_mname) {
}
if (!r && node_type) {
}
if (r) {
if (dacfdebug & DACF_DBG_MSGS) {
printf("dacf: made 'pre-detach' reservation for "
}
} else {
}
if (drv_mname) {
}
}
/*
* dacfc_postattach()
* autoconfiguration for post-attach events.
*
* strategy: try to configure. If some of the configuration operations
* fail, emit a warning.
*/
int
{
/*
* Instruct dacf_process_rsrvs() to invoke each POSTATTACH op.
*/
/*
* Check to see that all POSTATTACH's succeeded.
*/
continue;
continue;
if (dacfdebug & DACF_DBG_DEVI) {
op->rsrv_result);
}
err = DACF_FAILURE;
break;
}
/*
* If one or more postattach's failed, give up.
*/
pathp = "<unknown>";
pathp);
}
return (err);
}
/*
* dacfc_predetach()
* auto-unconfiguration for pre-detach events.
*
* strategy: call the pre-detach operation for all matching reservations.
* If any of these fail, make (one) attempt to reconfigure things back
* into a sane state. if that fails, our state is uncertain.
*/
int
{
/*
* Instruct dacf_process_rsrvs() to invoke each PREDETACH op.
*/
/*
* Check to see that all PREDETACH's succeeded.
*/
continue;
if (op->rsrv_result == 0)
continue;
err = DDI_FAILURE;
break;
}
/*
* If one or more predetach's failed, make one attempt to fix things
* by re-running all of the POST-ATTACH operations. If any of those
* fail, give up.
*/
if (err == DDI_FAILURE) {
int pa_err;
if (dacfdebug & DACF_DBG_DEVI) {
pathp = "<unknown>";
"attempting to reconfigure...", pathp);
}
if (dacfdebug & DACF_DBG_DEVI) {
pathp = "<unknown>";
if (pa_err == DDI_FAILURE) {
"auto-unconfigure, and could not be "
"re-autoconfigured.", pathp);
} else {
"auto-unconfigure, but was successfully "
"re-autoconfigured.", pathp);
}
}
}
return (err);
}
/*
* kmod_dacfsw:
* This is the declaration for the kernel-supplied '__kernel' dacf module.
* DACF supplies a framework based around loadable modules. However, it
* may be convenient (in the future) to have a module provided by the
* kernel. This is useful in cases when a module can't be loaded (early in
* boot), or for code that would never get unloaded anyway.
*/
#ifdef DEBUG
/*ARGSUSED*/
static int
{
}
return (0);
}
#endif
#ifdef DEBUG
#endif
{ DACF_OPID_END, NULL },
};
#ifdef DEBUG
{ "kmod_test", kmod_op_test },
#endif
};
};