374 lines
11 KiB
Groff
374 lines
11 KiB
Groff
.\" $NetBSD: driver.9,v 1.32 2017/11/17 07:42:29 wiz Exp $
|
|
.\"
|
|
.\" Copyright (c) 2001 The NetBSD Foundation, Inc.
|
|
.\" All rights reserved.
|
|
.\"
|
|
.\" This code is derived from software contributed to The NetBSD Foundation
|
|
.\" by Gregory McGarry.
|
|
.\"
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
.\" modification, are permitted provided that the following conditions
|
|
.\" are met:
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
.\"
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
|
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
|
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
.\" POSSIBILITY OF SUCH DAMAGE.
|
|
.\"
|
|
.Dd April 30, 2017
|
|
.Dt DRIVER 9
|
|
.Os
|
|
.Sh NAME
|
|
.Nm driver
|
|
.Nd description of a device driver
|
|
.Sh SYNOPSIS
|
|
.In sys/param.h
|
|
.In sys/device.h
|
|
.In sys/errno.h
|
|
.Ft static int
|
|
.Fn foo_match "device_t parent" "cfdata_t match" "void *aux"
|
|
.Ft static void
|
|
.Fn foo_attach "device_t parent" "device_t self" "void *aux"
|
|
.Ft static int
|
|
.Fn foo_detach "device_t self" "int flags"
|
|
.Ft static int
|
|
.Fn foo_activate "device_t self" "enum devact act"
|
|
.Sh DESCRIPTION
|
|
This page briefly describes the basic
|
|
.Nx
|
|
autoconfiguration interface used by device drivers.
|
|
For a detailed overview of the autoconfiguration framework see
|
|
.Xr autoconf 9 .
|
|
.Pp
|
|
Each device driver must present to the system a standard
|
|
autoconfiguration interface.
|
|
This interface is provided by the
|
|
.Em cfattach
|
|
structure.
|
|
The interface to the driver is constant and is defined
|
|
statically inside the driver.
|
|
For example, the interface to driver
|
|
.Dq foo
|
|
is defined with:
|
|
.Bd -literal
|
|
CFATTACH_DECL_NEW(foo, /* driver name */
|
|
sizeof(struct foo_softc), /* size of instance data */
|
|
foo_match, /* match/probe function */
|
|
foo_attach, /* attach function */
|
|
foo_detach, /* detach function */
|
|
foo_activate); /* activate function */
|
|
.Ed
|
|
.Pp
|
|
For each device instance controlled by the driver, the
|
|
autoconfiguration framework allocates a block of memory to record
|
|
device-instance-specific driver variables.
|
|
The size of this memory block is specified by the second argument in the
|
|
.Em CFATTACH_DECL
|
|
macro.
|
|
The memory block is referred to as the driver's
|
|
.Em softc
|
|
structure.
|
|
The
|
|
.Em softc
|
|
structure is only accessed within the driver, so its definition is
|
|
local to the driver.
|
|
Nevertheless, the
|
|
.Em softc
|
|
structure should adopt the standard
|
|
.Nx
|
|
configuration and naming conventions.
|
|
For example, the
|
|
.Em softc
|
|
structure for driver
|
|
.Dq foo
|
|
is defined with:
|
|
.Bd -literal
|
|
struct foo_softc {
|
|
device_t sc_dev; /* generic device info */
|
|
/* device-specific state */
|
|
};
|
|
.Ed
|
|
.Pp
|
|
The autoconfiguration framework mandates that the first member of the
|
|
.Em softc
|
|
structure must be the driver-independent
|
|
.Em device_t .
|
|
Probably its most useful aspect to the driver is that it contains the
|
|
device-instance name
|
|
.Em dv_xname .
|
|
.Pp
|
|
If a driver has character device interfaces accessed from userland, the driver
|
|
must define the
|
|
.Em cdevsw
|
|
structure.
|
|
The structure is constant and is defined inside the driver.
|
|
For example, the
|
|
.Em cdevsw
|
|
structure for driver
|
|
.Dq foo
|
|
is defined with:
|
|
.Bd -literal
|
|
const struct cdevsw foo_cdevsw {
|
|
int (*d_open)(dev_t, int, int, struct lwp *);
|
|
int (*d_close)(dev_t, int, int, struct lwp *);
|
|
int (*d_read)(dev_t, struct uio *, int);
|
|
int (*d_write)(dev_t, struct uio *, int);
|
|
int (*d_ioctl)(dev_t, u_long, void *, int, struct lwp *);
|
|
void (*d_stop)(struct tty *, int);
|
|
struct tty *(*d_tty)(dev_t);
|
|
int (*d_poll)(dev_t, int, struct lwp *);
|
|
paddr_t (*d_mmap)(dev_t, off_t, int);
|
|
int (*d_kqfilter)(dev_t, struct knote *);
|
|
int d_flag;
|
|
};
|
|
.Ed
|
|
.Pp
|
|
The structure variable must be named foo_cdevsw by appending the letters
|
|
.Dq _cdevsw
|
|
to the driver's base name.
|
|
This convention is mandated by the autoconfiguration framework.
|
|
.Pp
|
|
If the driver
|
|
.Dq foo
|
|
has also block device interfaces, the driver must define the
|
|
.Em bdevsw
|
|
structure.
|
|
The structure is constant and is defined inside the driver.
|
|
For example, the
|
|
.Em bdevsw
|
|
structure for driver
|
|
.Dq foo
|
|
is defined with:
|
|
.Bd -literal
|
|
const struct bdevsw foo_bdevsw {
|
|
int (*d_open)(dev_t, int, int, struct lwp *);
|
|
int (*d_close)(dev_t, int, int, struct lwp *);
|
|
void (*d_strategy)(struct buf *);
|
|
int (*d_ioctl)(dev_t, u_long, void *, int, struct lwp *);
|
|
int (*d_dump)(dev_t, daddr_t, void *, size_t);
|
|
int (*d_psize)(dev_t);
|
|
int d_flag;
|
|
};
|
|
.Ed
|
|
.Pp
|
|
The structure variable must be named foo_bdevsw by appending the letters
|
|
.Dq _bdevsw
|
|
to the driver's base name.
|
|
This convention is mandated by the autoconfiguration framework.
|
|
.Pp
|
|
During system bootstrap, the autoconfiguration framework searches the
|
|
system for devices.
|
|
For each device driver, its match function is called (via its
|
|
.Em cfattach
|
|
structure) to match the driver with a device instance.
|
|
The match function is called with three arguments.
|
|
This first argument
|
|
.Fa parent
|
|
is a pointer to the driver's parent device structure.
|
|
The second argument
|
|
.Fa match
|
|
is a pointer to a data structure describing the autoconfiguration
|
|
framework's understanding of the driver.
|
|
Both the
|
|
.Fa parent
|
|
and
|
|
.Fa match
|
|
arguments are ignored by most drivers.
|
|
The third argument
|
|
.Fa aux
|
|
contains a pointer to a structure describing a potential
|
|
device-instance.
|
|
It is passed to the driver from the parent.
|
|
The match function would type-cast the
|
|
.Fa aux
|
|
argument to its appropriate attachment structure and use its contents
|
|
to determine whether it supports the device.
|
|
Depending on the device hardware, the contents of the attachment
|
|
structure may contain
|
|
.Dq locators
|
|
to locate the device instance so that the driver can probe it for its
|
|
identity.
|
|
If the probe process identifies additional device properties, it may
|
|
modify the members of the attachment structure.
|
|
For these devices, the
|
|
.Nx
|
|
convention is to
|
|
call the match routine
|
|
.Fn foo_probe
|
|
instead of
|
|
.Fn foo_match
|
|
to make this distinction clear.
|
|
Either way, the 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.
|
|
Generally, only a single driver exists for a device, so the match
|
|
function returns 1 for a positive match.
|
|
.Pp
|
|
The autoconfiguration framework will call the attach function
|
|
(via its
|
|
.Em cfattach
|
|
structure)
|
|
of the driver which returns the highest value from its match function.
|
|
The attach function is called with three arguments.
|
|
The attach function performs the necessary process to initialise the
|
|
device for operation.
|
|
The first argument
|
|
.Fa parent
|
|
is a pointer to the driver's parent device structure.
|
|
The second argument
|
|
.Fa self
|
|
is a pointer to the driver's device structure.
|
|
The device's
|
|
.Em softc
|
|
structure can be obtained from it using the
|
|
.Fn device_private
|
|
function (see
|
|
.Xr disk 9 ) .
|
|
The third argument
|
|
.Fa aux
|
|
is a pointer to the attachment structure.
|
|
The
|
|
.Fa parent
|
|
and
|
|
.Fa aux
|
|
arguments are the same as passed to the match function.
|
|
.Pp
|
|
The driver's attach function is called before system interrupts are
|
|
enabled.
|
|
If interrupts are required during initialisation, then the attach
|
|
function should make use of
|
|
.Fn config_interrupts
|
|
(see
|
|
.Xr autoconf 9 ) .
|
|
.Pp
|
|
Some devices can be removed from the system without requiring a system
|
|
reboot.
|
|
The autoconfiguration framework calls the driver's detach function
|
|
(via its
|
|
.Em cfattach
|
|
structure) during device detachment.
|
|
If the device does not support detachment, then the driver does not
|
|
have to provide a detach function.
|
|
The detach function is used to relinquish resources allocated to the
|
|
driver which are no longer needed.
|
|
The first argument
|
|
.Fa self
|
|
is a pointer to the driver's device structure.
|
|
It is the same structure as passed to the attach function.
|
|
The second argument
|
|
.Fa flags
|
|
contains detachment flags.
|
|
Valid values are
|
|
.Dv DETACH_FORCE
|
|
(force detachment; hardware gone) and
|
|
.Dv DETACH_QUIET
|
|
(do not print a notice).
|
|
.Pp
|
|
The autoconfiguration framework may call the driver's activate function
|
|
to notify the driver of a change in the resources that have been
|
|
allocated to it.
|
|
For example, an Ethernet driver has to be notified if the network stack
|
|
is being added or removed from the kernel.
|
|
The first argument to the activate function
|
|
.Fa self
|
|
is a pointer to the driver's device structure.
|
|
It is the same argument as passed to the attach function.
|
|
The second argument
|
|
.Fa act
|
|
describes the action.
|
|
Valid actions are
|
|
.Dv DVACT_ACTIVATE
|
|
(activate the device) and
|
|
.Dv DVACT_DEACTIVATE
|
|
(deactivate the device).
|
|
If the action is not supported the activate function should return
|
|
.Er EOPNOTSUPP .
|
|
The
|
|
.Dv DVACT_DEACTIVATE
|
|
call will only be made if the
|
|
.Dv DVACT_ACTIVATE
|
|
call was successful.
|
|
The activate function is called in interrupt context.
|
|
.Pp
|
|
Most drivers will want to make use of interrupt facilities.
|
|
Interrupt locators provided through the attachment structure should be
|
|
used to establish interrupts within the system.
|
|
Generally, an interrupt interface is provided by the parent.
|
|
The interface will require a handler and a driver-specific argument
|
|
to be specified.
|
|
This argument is usually a pointer to the device-instance-specific
|
|
softc structure.
|
|
When a hardware interrupt for the device occurs the handler is called
|
|
with the argument.
|
|
Interrupt handlers should return 0 for
|
|
.Dq interrupt not for me ,
|
|
1 for
|
|
.Dq I took care of it ,
|
|
or -1 for
|
|
.Do
|
|
I guess it was mine, but I wasn't expecting it
|
|
.Dc .
|
|
.Pp
|
|
For a driver to be compiled into the kernel,
|
|
.Xr config 1
|
|
must be aware of its existence.
|
|
This is done by including an entry in files.<bus> in the
|
|
directory containing the driver.
|
|
For example, the driver
|
|
.Dq foo
|
|
attaching to bus
|
|
.Dq bar
|
|
with dependency on kernel module
|
|
.Dq baz
|
|
has the entry:
|
|
.Bd -literal
|
|
device foo: baz
|
|
attach foo at bar
|
|
file dev/bar/foo.c foo
|
|
.Ed
|
|
.Pp
|
|
An entry can now be added to the machine description file:
|
|
.Bd -literal
|
|
foo* at bar?
|
|
.Ed
|
|
.Pp
|
|
For device interfaces of a driver to be compiled into the kernel,
|
|
.Xr config 1
|
|
must be aware of its existence.
|
|
This is done by including an entry in majors.<arch>.
|
|
For example, the driver
|
|
.Dq foo
|
|
with character device interfaces, a character major device number
|
|
.Dq cmaj ,
|
|
block device interfaces, a block device major number
|
|
.Dq bmaj
|
|
and dependency on kernel module
|
|
.Dq baz
|
|
has the entry:
|
|
.Bd -literal
|
|
device-major foo char cmaj block bmaj baz
|
|
.Ed
|
|
.Pp
|
|
For a detailed description of the machine description file and the
|
|
.Dq device definition
|
|
language see
|
|
.Xr config 9 .
|
|
.Sh SEE ALSO
|
|
.Xr config 1 ,
|
|
.Xr autoconf 9 ,
|
|
.Xr config 9 ,
|
|
.Xr devsw 9 ,
|
|
.Xr pmf 9
|