NAME
autoconf,
config_search_loc,
config_search_ia,
config_found_sm_loc,
config_found_ia,
config_found,
config_match,
config_attach_loc,
config_attach,
config_attach_pseudo,
config_detach,
config_detach_children,
config_deactivate,
config_defer,
config_interrupts,
config_mountroot,
config_pending_incr,
config_pending_decr,
config_finalize_register —
autoconfiguration framework
SYNOPSIS
#include <sys/param.h>
#include <sys/device.h>
#include <sys/errno.h>
cfdata_t
config_search_loc(
cfsubmatch_t
func,
device_t
parent,
const char
*ia,
const int *locs,
void *aux);
cfdata_t
config_search_ia(
cfsubmatch_t
func,
device_t
parent,
const char
*ia,
void *aux);
device_t
config_found_sm_loc(
device_t
parent,
const char
*ia,
const int *locs,
void *aux,
cfprint_t print,
cfsubmatch_t submatch);
device_t
config_found_ia(
device_t
parent,
const char
*ia,
void *aux,
cfprint_t print);
device_t
config_found(
device_t
parent,
void *aux,
cfprint_t print);
int
config_match(
device_t
parent,
cfdata_t cf,
void *aux);
device_t
config_attach_loc(
device_t
parent,
cfdata_t cf,
const int *locs,
void *aux,
cfprint_t print);
device_t
config_attach(
device_t
parent,
cfdata_t cf,
void *aux,
cfprint_t print);
device_t
config_attach_pseudo(
cfdata_t
cf);
int
config_detach(
device_t
dev,
int flags);
int
config_detach_children(
device_t
dev,
int flags);
int
config_deactivate(
device_t
dev);
int
config_defer(
device_t
dev,
void
(*func)(device_t));
void
config_interrupts(
device_t
dev,
void
(*func)(device_t));
void
config_mountroot(
device_t
dev,
void
(*func)(device_t));
void
config_pending_incr();
void
config_pending_decr();
int
config_finalize_register(
device_t
dev,
int
(*func)(device_t));
DESCRIPTION
Autoconfiguration is the process of matching hardware devices with an
appropriate device driver. In its most basic form, autoconfiguration consists
of the recursive process of finding and attaching all devices on a bus,
including other busses.
The autoconfiguration framework supports
direct configuration
where the bus driver can determine the devices present. The autoconfiguration
framework also supports
indirect configuration where the
drivers must probe the bus looking for the presence of a device. Direct
configuration is preferred since it can find hardware regardless of the
presence of proper drivers.
The autoconfiguration process occurs at system bootstrap and is driven by a
table generated from a “machine description” file by
config(1). For a description of
the
config(1) “device
definition” language, see
config(9).
Each device must have a name consisting of an alphanumeric string that ends with
a unit number. The unit number identifies an instance of the driver. Device
data structures are allocated dynamically during autoconfiguration, giving a
unique address for each instance.
FUNCTIONS
-
-
- config_search_loc(func,
parent, ia,
locs, aux)
- Performs indirect configuration of physical devices.
config_search_loc() iterates over all potential
children, calling the given function func for each
one. If func is
NULL
,
config_search_loc() applies each child's match function
instead. The argument parent is the pointer to the
parent's device structure. The argument ia is the
interface attribute on which the potential children should attach. It can
be NULL
, in which case all children attaching to
any attribute are considered. The locs argument
lists the locator values for the device and are passed to function
func. The given aux argument
describes the device that has been found and is simply passed on through
func to the child.
config_search_loc() returns a pointer to the
best-matched child or NULL
otherwise.
The role of func is to call the match function for
each device and call config_attach_loc() for any
positive matches. If func is
NULL
, then the parent should record the return
value from config_search_loc() and call
config_attach_loc() itself.
Note that this function is designed so that it can be used to apply an
arbitrary function to all potential children. In this case callers may
choose to ignore the return value.
-
-
- config_search_ia(func,
parent, ia,
aux)
- This function is equivalent to calling
config_search_loc(func,
parent, ia,
locs, aux) with
locs set to
NULL
.
-
-
- config_found_sm_loc(parent,
ia, locs,
aux, print,
submatch)
- Performs direct configuration on a physical device.
config_found_sm_loc() is called by the parent and in
turn calls the submatch function to call the match
function as determined by the configuration table. If
submatch is
NULL
, the driver
match functions are called directly. The argument
parent is the pointer to the parent's device
structure. The argument ia is the name of the
interface attribute on which the child will attach, per
config(5) syntax. The
argument locs lists the locator values for the
device. The given aux argument describes the device
that has been found. config_found_sm_loc() internally
uses config_search_loc(), passing on
submatch, ia,
locs and aux. The
softc structure for the matched device will be
allocated, and the appropriate driver attach function will be called. If
the device is matched, the system prints the name of the child and parent
devices, and then calls the print function to
produce additional information if desired. If no driver takes a match, the
same print function is called to complain. The print
function is called with the aux argument and, if the
matches failed, the full name (including unit number) of the parent
device, otherwise NULL
. The
print function must return an integer value.
Two special strings, “not configured” and
“unsupported” will be appended automatically to non-driver
reports if the return value is UNCONF or UNSUPP respectively; otherwise
the function should return the value QUIET.
config_found_sm_loc() returns a pointer to the attached
device's softc structure if the device is attached,
NULL
otherwise. Most callers can ignore this
value, since the system will already have printed a diagnostic.
-
-
- config_found_ia(parent,
ia, aux,
print)
- This function is equivalent to calling
config_found_sm_loc(parent,
ia, locs,
aux, print,
submatch) with locs and
submatch set to
NULL
. It is
provided for better source code readability with locator-less device
buses.
-
-
- config_found(parent,
aux, print)
- This function is equivalent to calling
config_found_sm_loc(parent,
ia, locs,
aux, print,
submatch) with ia,
locs and submatch set to
NULL
and is provided for compatibility with older
drivers. New code should either make the interface attribute explicit or
prefer an indirect method based on
config_search_loc().
-
-
- config_match(parent,
cf, aux)
- Match a device. Invokes the drivers match function
according to the configuration table. The config_match()
function returns a nonzero integer indicating the confidence of supporting
this device and a value of 0 if the driver doesn't support the
device.
-
-
- config_attach_loc(parent,
cf, locs,
aux, print)
- Attach a found device. Allocates the memory for the
softc structure and calls the drivers attach function
according to the configuration table. If successful,
config_attach_loc() returns the softc.
If unsuccessful, it returns
NULL
.
-
-
- config_attach(parent,
cf, aux,
print)
- This function is equivalent to calling
config_attach_loc(parent,
cf, locs,
aux, print) with
locs set to
NULL
.
-
-
- config_attach_pseudo(cf)
- Create an instance of a pseudo-device driver.
config(5) syntax allows the
creation of pseudo-devices from which regular
device_t instances can be created. Such objects are
similar to the devices that attach at the root of the device tree.
The caller is expected to allocate and fill the
cfdata_t object and pass it to
config_attach_pseudo(). The content of that object is
similar to what is returned by config_search_loc() for
regular devices.
-
-
- config_detach(dev,
flags)
- Called by the parent to detach the child device. The second
argument flags contains detachment flags. Valid values
are DETACH_FORCE (force detachment (e.g., because of hardware removal))
and DETACH_QUIET (do not print a notice).
config_detach() returns zero if successful and an error
code otherwise. config_detach() is always called from a
thread context, allowing condition variables to be used while the device
detaches itself.
-
-
- config_detach_children(dev,
flags)
- Iterate through all attached devices, calling
config_detach() for each child of
dev, passing flags. If
detaching any child results in an error, the iteration will halt and any
remaining devices will not be detached.
config_detach_children() returns zero if successful and
an error code otherwise.
-
-
- config_deactivate(dev)
- Called by the parent to deactivate the child device
dev. config_deactivate() is called
from interrupt context to immediately relinquish resources and notify
dependent kernel subsystems that the device is about to be detached. At
some later point config_detach() will be called to
finalise the removal of the device.
-
-
- config_defer(dev,
func)
- Called by the child to defer the remainder of its
configuration until all its parent's devices have been attached. At this
point, the function func is called with the argument
dev.
-
-
- config_interrupts(dev,
func)
- Called by the child to defer the remainder of its
configuration until interrupts are enabled. At this point, the function
func is called with the argument
dev.
-
-
- config_mountroot(dev,
func)
- Called by the child to defer the remainder of its
configuration until the root file system is mounted. At this point, the
function func is called with the argument
dev. This is used for devices that need to load
firmware image from a mounted file system.
-
-
- config_pending_incr()
- Increment the config_pending
semaphore. It is used to account for deferred configurations before
mounting the root file system.
-
-
- config_pending_decr()
- Decrement the config_pending
semaphore. It is used to account for deferred configurations before
mounting the root file system.
-
-
- config_finalize_register(dev,
func)
- Register a function to be called after all real devices
have been found.
Registered functions are all executed until all of them return 0. The
callbacks should return 0 to indicate they do not require to be called
another time, but they should be aware that they still might be in case
one of them returns 1.
CODE REFERENCES
The autoconfiguration framework itself is implemented within the file
sys/kern/subr_autoconf.c. Data structures and function
prototypes for the framework are located in
sys/sys/device.h.
SEE ALSO
config(1),
config(5),
condvar(9),
config(9),
driver(9)
HISTORY
Autoconfiguration first appeared in
4.1BSD. The
autoconfiguration framework was completely revised in
4.4BSD. The detach and deactivate interfaces appeared
in
NetBSD 1.5.