bus: Add device_has_children predicate

Add a device_has_children() function which can be used to check if a
device has children without allocating a list of them which we aren't
going to use, or even counting them.

Also modify device_get_children() so it can be used to query the count
without allocating a list.

MFC after:	1 week
Sponsored by:	Klara, Inc.
Sponsored by:	NetApp, Inc.
Reviewed by:	imp, markj
Differential Revision:	https://reviews.freebsd.org/D53918
This commit is contained in:
Dag-Erling Smørgrav
2025-11-28 10:14:31 +01:00
parent 34d66b0c96
commit 330d4437f2
4 changed files with 59 additions and 8 deletions
+1
View File
@@ -1040,6 +1040,7 @@ MLINKS+=devfs_set_cdevpriv.9 devfs_clear_cdevpriv.9 \
MLINKS+=device_add_child.9 device_add_child_ordered.9
MLINKS+=device_enable.9 device_disable.9 \
device_enable.9 device_is_enabled.9
MLINKS+=device_get_children.9 device_has_children.9
MLINKS+=device_get_ivars.9 device_set_ivars.9
MLINKS+=device_get_name.9 device_get_nameunit.9
MLINKS+=device_get_state.9 device_busy.9 \
+39 -8
View File
@@ -1,6 +1,7 @@
.\" -*- nroff -*-
.\"
.\" Copyright (c) 1998 Doug Rabson
.\" Copyright (c) 2025 Dag-Erling Smørgrav <des@FreeBSD.org>
.\"
.\" All rights reserved.
.\"
@@ -26,21 +27,27 @@
.\" (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 August 23, 2008
.Dd November 28, 2025
.Dt DEVICE_GET_CHILDREN 9
.Os
.Sh NAME
.Nm device_get_children
.Nd get a list of devices connected to a device
.Nm device_get_children ,
.Nm device_has_children
.Nd examine devices connected to a device
.Sh SYNOPSIS
.In sys/param.h
.In sys/bus.h
.Ft int
.Fn device_get_children "device_t dev" "device_t **devlistp" "int *devcountp"
.Ft bool
.Fn device_has_children "device_t dev"
.Sh DESCRIPTION
Retrieve a list of all device instances currently connected to
.Pa dev
and return the list in
The
.Nm device_get_children
function retrieves a list of all device instances currently connected
to
.Fa dev .
It returns the list in
.Fa *devlistp
and the count in
.Fa *devcountp .
@@ -50,11 +57,35 @@ The memory allocated for the list should be freed using
and
.Fa devcountp
are not changed when an error is returned.
.Pp
As a special case, if
.Fa devlistp
is null, no memory is allocated but the count is still returned in
.Fa *devcountp .
.Pp
The
.Nm device_has_children
function returns
.Dv true
if
.Fa dev
has at least one child and
.Dv false
if it has none.
.Sh RETURN VALUES
Zero is returned on success, otherwise an appropriate error is returned.
The
.Nm device_get_children
function returns zero on success and an appropriate error otherwise.
The
.Nm device_has_children
function returns true if the specified device has at least one child
and false otherwise.
.Sh SEE ALSO
.Xr devclass 9 ,
.Xr device 9
.Sh AUTHORS
.An -nosplit
This manual page was written by
.An Doug Rabson .
.An Doug Rabson Aq Mt dfr@FreeBSD.org
and
.An Dag-Erling Sm\(/orgrav Aq Mt des@FreeBSD.org .
+18
View File
@@ -1858,6 +1858,10 @@ device_get_children(device_t dev, device_t **devlistp, int *devcountp)
TAILQ_FOREACH(child, &dev->children, link) {
count++;
}
if (devlistp == NULL) {
*devcountp = count;
return (0);
}
if (count == 0) {
*devlistp = NULL;
*devcountp = 0;
@@ -1880,6 +1884,20 @@ device_get_children(device_t dev, device_t **devlistp, int *devcountp)
return (0);
}
/**
* @brief Check if a device has children
*
* @param dev the device to examine
*
* @rerval true the device has at least one child
* @retval false the device has no children
*/
bool
device_has_children(device_t dev)
{
return (!TAILQ_EMPTY(&dev->children));
}
/**
* @brief Return the current driver for the device or @c NULL if there
* is no driver currently attached
+1
View File
@@ -713,6 +713,7 @@ device_state_t device_get_state(device_t dev);
int device_get_unit(device_t dev);
struct sysctl_ctx_list *device_get_sysctl_ctx(device_t dev);
struct sysctl_oid *device_get_sysctl_tree(device_t dev);
bool device_has_children(device_t dev);
int device_has_quiet_children(device_t dev);
int device_is_alive(device_t dev); /* did probe succeed? */
int device_is_attached(device_t dev); /* did attach succeed? */