DEVICE_IDENTIFY.9: Modernize description and use cases

Mention adding devices based on firmware tables and software-only
pseudo-devices as use cases for identify methods as those are more
common than reading random I/O ports to identify a legacy ISA device.

Describe how device_find_chid can be used to avoid duplicates.  While
here, explicitly note that devices added in identify methods typically
use a fixed device name.

Trim the cross-references a bit.

Reviewed by:	ziaee, imp
Differential Revision:	https://reviews.freebsd.org/D48367
This commit is contained in:
John Baldwin
2025-01-09 15:20:16 -05:00
parent 6af088c736
commit ccabc7c2e5
+25 -27
View File
@@ -26,44 +26,46 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd January 15, 2017 .Dd January 9, 2025
.Dt DEVICE_IDENTIFY 9 .Dt DEVICE_IDENTIFY 9
.Os .Os
.Sh NAME .Sh NAME
.Nm DEVICE_IDENTIFY .Nm DEVICE_IDENTIFY
.Nd identify a device, register it .Nd identify new child devices and register them
.Sh SYNOPSIS .Sh SYNOPSIS
.In sys/param.h .In sys/param.h
.In sys/bus.h .In sys/bus.h
.Ft void .Ft void
.Fn DEVICE_IDENTIFY "driver_t *driver" "device_t parent" .Fn DEVICE_IDENTIFY "driver_t *driver" "device_t parent"
.Sh DESCRIPTION .Sh DESCRIPTION
The identify function for a device is only needed for devices on buses The identify method of a device driver is used to add devices that cannot be
that cannot identify their children independently, e.g.\& the ISA bus. enumerated by the standard method on a bus device.
It is used to recognize the device (usually done by accessing non-ambiguous Devices can be enumerated in various ways including accessing non-ambiguous
registers in the hardware) and to tell the kernel about it and thus device registers and parsing firmware tables.
creating a new device instance. Software-only pseudo devices are also often enumerated via identify methods.
.Pp .Pp
For each newly identified device,
a new device instance should be created by invoking the
.Xr BUS_ADD_CHILD 9 .Xr BUS_ADD_CHILD 9
is used to register the device as a child of the bus. method.
The device's resources (such as IRQ and I/O ports) are registered If the identify method is able to discover other properties about the new
with the kernel by calling device, those should also be set.
.Fn bus_set_resource For example, device resources should be added to the device by calling
for each resource (refer to
.Xr bus_set_resource 9 .Xr bus_set_resource 9
for more information). for each resource.
.Pp .Pp
Since the device tree and the device driver tree are disjoint, the An identify method might be invoked multiple times.
.Fn DEVICE_IDENTIFY If a device driver is unloaded and loaded,
routine needs to take this into account. the identify method will be called a second time after being reloaded.
If you load and unload your device driver that has the identify As a result, the identify method should avoid duplicate devices.
routine, the child node has the potential for adding the same node Devices added by identify methods typically use a fixed device name
multiple times unless specific measure are taken to preclude that in which case
possibility. .Xr device_find_child 9
can be used to detect existing devices.
.Sh EXAMPLES .Sh EXAMPLES
The following pseudo-code shows an example of a function that The following pseudo-code shows an example of a function that
probes for a piece of hardware and registers it and its resource probes for a piece of hardware and registers it and its resource
(an I/O port) with the kernel. (an I/O port) with the parent bus device.
.Bd -literal .Bd -literal
void void
foo_identify(driver_t *driver, device_t parent) foo_identify(driver_t *driver, device_t parent)
@@ -72,7 +74,7 @@ foo_identify(driver_t *driver, device_t parent)
retrieve_device_information; retrieve_device_information;
if (devices matches one of your supported devices && if (devices matches one of your supported devices &&
not already in device tree) { device_get_child(parent, "foo", DEVICE_UNIT_ANY) == NULL) {
child = BUS_ADD_CHILD(parent, 0, "foo", DEVICE_UNIT_ANY); child = BUS_ADD_CHILD(parent, 0, "foo", DEVICE_UNIT_ANY);
bus_set_resource(child, SYS_RES_IOPORT, 0, FOO_IOADDR, 1); bus_set_resource(child, SYS_RES_IOPORT, 0, FOO_IOADDR, 1);
} }
@@ -82,11 +84,7 @@ foo_identify(driver_t *driver, device_t parent)
.Xr BUS_ADD_CHILD 9 , .Xr BUS_ADD_CHILD 9 ,
.Xr bus_set_resource 9 , .Xr bus_set_resource 9 ,
.Xr device 9 , .Xr device 9 ,
.Xr device_add_child 9 , .Xr device_find_child 9
.Xr DEVICE_ATTACH 9 ,
.Xr DEVICE_DETACH 9 ,
.Xr DEVICE_PROBE 9 ,
.Xr DEVICE_SHUTDOWN 9
.Sh AUTHORS .Sh AUTHORS
This manual page was written by This manual page was written by
.An Alexander Langer Aq Mt alex@FreeBSD.org . .An Alexander Langer Aq Mt alex@FreeBSD.org .