aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2024-12-06 22:25:04 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2024-12-06 22:25:42 +0000
commit46297859a74563dde6fc5bff9f9ecded9fb61ba6 (patch)
treea99903284ebe9daebe512b1a55561ff712a9b331
parent831531a82e0f1d1d7b97e50c0587639322ed8d2e (diff)
new-bus: Add bus_(identify|attach|detach)_children
These correspond to the current implementations of bus_generic_(probe|attach|detach) but with more accurate names and semantics. The intention is to deprecate bus_generic_(probe|attach) and reimplement bus_generic_detach in a future commit. Reviewed by: imp Differential Revision: https://reviews.freebsd.org/D47673
-rw-r--r--sys/kern/subr_bus.c65
-rw-r--r--sys/sys/bus.h4
-rw-r--r--sys/sys/param.h2
3 files changed, 65 insertions, 6 deletions
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 32ddcaa9f643..945d91d951d6 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -3409,6 +3409,22 @@ bus_generic_add_child(device_t dev, u_int order, const char *name, int unit)
int
bus_generic_probe(device_t dev)
{
+ bus_identify_children(dev);
+ return (0);
+}
+
+/**
+ * @brief Ask drivers to add child devices of the given device.
+ *
+ * This function allows drivers for child devices of a bus to identify
+ * child devices and add them as children of the given device. NB:
+ * The driver for @param dev must implement the BUS_ADD_CHILD method.
+ *
+ * @param dev the parent device
+ */
+void
+bus_identify_children(device_t dev)
+{
devclass_t dc = dev->devclass;
driverlink_t dl;
@@ -3426,8 +3442,6 @@ bus_generic_probe(device_t dev)
continue;
DEVICE_IDENTIFY(dl->driver, dev);
}
-
- return (0);
}
/**
@@ -3440,13 +3454,28 @@ bus_generic_probe(device_t dev)
int
bus_generic_attach(device_t dev)
{
+ bus_attach_children(dev);
+ return (0);
+}
+
+/**
+ * @brief Probe and attach all children of the given device
+ *
+ * This function attempts to attach a device driver to each unattached
+ * child of the given device using device_probe_and_attach(). If an
+ * individual child fails to attach this function continues attaching
+ * other children.
+ *
+ * @param dev the parent device
+ */
+void
+bus_attach_children(device_t dev)
+{
device_t child;
TAILQ_FOREACH(child, &dev->children, link) {
device_probe_and_attach(child);
}
-
- return (0);
}
/**
@@ -3460,7 +3489,7 @@ int
bus_delayed_attach_children(device_t dev)
{
/* Probe and attach the bus children when interrupts are available */
- config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev);
+ config_intrhook_oneshot((ich_func_t)bus_attach_children, dev);
return (0);
}
@@ -3475,6 +3504,32 @@ bus_delayed_attach_children(device_t dev)
int
bus_generic_detach(device_t dev)
{
+ int error;
+
+ error = bus_detach_children(dev);
+ if (error != 0)
+ return (error);
+
+ return (0);
+}
+
+/**
+ * @brief Detach drivers from all children of a device
+ *
+ * This function attempts to detach a device driver from each attached
+ * child of the given device using device_detach(). If an individual
+ * child fails to detach this function stops and returns an error.
+ * NB: Children that were successfully detached are not re-attached if
+ * an error occurs.
+ *
+ * @param dev the parent device
+ *
+ * @retval 0 success
+ * @retval non-zero a device would not detach
+ */
+int
+bus_detach_children(device_t dev)
+{
device_t child;
int error;
diff --git a/sys/sys/bus.h b/sys/sys/bus.h
index 1f5e074cfe5a..c712e37fd34d 100644
--- a/sys/sys/bus.h
+++ b/sys/sys/bus.h
@@ -591,8 +591,12 @@ void bus_delete_resource(device_t dev, int type, int rid);
int bus_child_present(device_t child);
int bus_child_pnpinfo(device_t child, struct sbuf *sb);
int bus_child_location(device_t child, struct sbuf *sb);
+
+void bus_attach_children(device_t dev);
+int bus_detach_children(device_t dev);
void bus_enumerate_hinted_children(device_t bus);
int bus_delayed_attach_children(device_t bus);
+void bus_identify_children(device_t dev);
static __inline struct resource *
bus_alloc_resource_any(device_t dev, int type, int *rid, u_int flags)
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 550ea1fc61f6..f675dd024ee0 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -73,7 +73,7 @@
* cannot include sys/param.h and should only be updated here.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1500028
+#define __FreeBSD_version 1500029
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,