Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144494627
D15229.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D15229.diff
View Options
Index: share/man/man9/DEVICE_ATTACH.9
===================================================================
--- share/man/man9/DEVICE_ATTACH.9
+++ share/man/man9/DEVICE_ATTACH.9
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 15, 2017
+.Dd May 20, 2018
.Dt DEVICE_ATTACH 9
.Os
.Sh NAME
@@ -57,12 +57,26 @@
If this is combined with the use of
.Xr bus_generic_attach 9
the child devices will be automatically probed and attached.
+.Pp
+If
+.Fn DEVICE_DELAY_ATTACH
+is implemented,
+.Fn DEVICE_ATTACH
+will not be called until
+.Fn DEVICE_DELAY_ATTACH
+returns true, even after a successful probe.
+This can be used to delay attachment until after other devices in
+the tree on which this device depends have successfully attached in
+cases where
+.Fn EARLY_DRIVER_MODULE
+is insufficient.
.Sh RETURN VALUES
Zero is returned on success, otherwise an appropriate error is returned.
.Sh SEE ALSO
.Xr devfs 5 ,
.Xr device 9 ,
.Xr DEVICE_DETACH 9 ,
+.Xr DEVICE_DELAY_ATTACH 9 ,
.Xr DEVICE_IDENTIFY 9 ,
.Xr DEVICE_PROBE 9 ,
.Xr DEVICE_SHUTDOWN 9
Index: share/man/man9/DEVICE_DELAY_ATTACH.9
===================================================================
--- share/man/man9/DEVICE_DELAY_ATTACH.9
+++ share/man/man9/DEVICE_DELAY_ATTACH.9
@@ -0,0 +1,79 @@
+.\" -*- nroff -*-
+.\"
+.\" Copyright (c) 2018 Nathan Whitehorn
+.\"
+.\" All rights reserved.
+.\"
+.\" This program is free software.
+.\"
+.\" 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 DEVELOPERS ``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 DEVELOPERS 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 20, 2018
+.Dt DEVICE_DELAY_ATTACH 9
+.Os
+.Sh NAME
+.Nm DEVICE_DELAY_ATTACH
+.Nd check if probed device is ready to attach
+.Sh SYNOPSIS
+.In sys/param.h
+.In sys/bus.h
+.Ft bool
+.Fn DEVICE_DELAY_ATTACH "device_t dev"
+.Sh DESCRIPTION
+Signal that
+.Fn DEVICE_ATTACH
+should not be called immediately after the
+.Fn DEVICE_PROBE
+method has been called and has indicated that
+the device exists.
+If
+.Fn DEVICE_DELAY_ATTACH
+is implemented,
+.Fn DEVICE_ATTACH
+will not be called until
+.Fn DEVICE_DELAY_ATTACH
+returns true, even after a successful probe.
+This can be used to delay attachment until after other devices in the tree
+on which this device depends have successfully attached.
+This is particularly useful in cases where
+.Fn EARLY_DRIVER_MODULE
+is insufficient, for example if the needed attach order is only known at
+runtime.
+Note that management of dependent device detachment is up to the individual
+driver.
+.Sh RETURN VALUES
+True should be returned if attachment should not be attempted yet.
+False should be returned if attachment can proceed.
+If unimplemented, returns false.
+This function (by design) provides no way to report errors; if a fatal error
+occurs, it should return false, allowing immediate attachment, with the error
+returned by
+.Fn DEVICE_ATTACH .
+.Sh SEE ALSO
+.Xr devfs 5 ,
+.Xr device 9 ,
+.Xr DEVICE_ATTACH 9 ,
+.Xr EARLY_DRIVER_MODULE 9 ,
+.Sh AUTHORS
+This manual page was written by
+.An Nathan Whitehorn Aq Mt nwhitehorn@FreeBSD.org .
Index: share/man/man9/Makefile
===================================================================
--- share/man/man9/Makefile
+++ share/man/man9/Makefile
@@ -89,6 +89,7 @@
device.9 \
device_add_child.9 \
DEVICE_ATTACH.9 \
+ DEVICE_DELAY_ATTACH.9 \
device_delete_child.9 \
DEVICE_DETACH.9 \
device_enable.9 \
Index: sys/kern/device_if.m
===================================================================
--- sys/kern/device_if.m
+++ sys/kern/device_if.m
@@ -48,6 +48,11 @@
# Default implementations of some methods.
#
CODE {
+ static bool null_delay_attach(device_t dev)
+ {
+ return FALSE;
+ }
+
static int null_shutdown(device_t dev)
{
return 0;
@@ -188,6 +193,27 @@
};
/**
+ * @brief See if a device's dependencies are present.
+ * If not, delay attach for the future but continue claiming the device.
+
+ * To include this method in a device driver, use a line like this
+ * in the driver's method list:
+ *
+ * @code
+ * KOBJMETHOD(device_delay_attach, foo_delay_attach)
+ * @endcode
+ *
+ * @param dev the device to probe
+ *
+ * @retval TRUE postpone attachment
+ * @retval FALSE attach now
+ * @see DEVICE_ATTACH()
+ */
+METHOD bool delay_attach {
+ device_t dev;
+} DEFAULT null_delay_attach;
+
+/**
* @brief Attach a device to a device driver
*
* Normally only called via device_probe_and_attach(), this is called
Index: sys/kern/subr_bus.c
===================================================================
--- sys/kern/subr_bus.c
+++ sys/kern/subr_bus.c
@@ -935,6 +935,59 @@
TAILQ_INSERT_TAIL(&passes, new, passlink);
}
+
+/*
+ * Recursively descend the device tree, trying to attach any devices
+ * left in limbo from a delayed attachment. Returns the total number of devices
+ * so attached.
+ */
+static int
+bus_try_attach_pending_children(device_t parent)
+{
+ int attachments_made = 0;
+ device_t child;
+
+ /*
+ * Try to attach anything in DS_ALIVE that is a direct child and
+ * descend to any grandchildren on fully-attached children.
+ */
+
+ TAILQ_FOREACH(child, &parent->children, link) {
+ if (child->state == DS_ALIVE) { /* Left in pending state */
+ if (device_attach(child) != EAGAIN)
+ attachments_made++;
+ } else if (child->state == DS_ATTACHED) {
+ attachments_made +=
+ bus_try_attach_pending_children(child);
+ }
+ }
+
+ return (attachments_made);
+}
+
+/*
+ * Iteratively rescan the entire device tree, trying to attach any devices
+ * left in DS_ALIVE limbo because DEVICE_DELAY_ATTACH() returned true. Will
+ * continue to rescan and attempt attachment so long as at least one pending
+ * device attaches in each round, guaranteeing the attachment of all devices
+ * with non-circular met dependencies.
+ *
+ * Returns the total number of delayed attachments completed.
+ */
+static int
+bus_try_attach_pending(void)
+{
+ int attachments_made, this_round;
+
+ attachments_made = 0;
+ do {
+ this_round = bus_try_attach_pending_children(root_bus);
+ attachments_made += this_round;
+ } while (this_round > 0);
+
+ return (attachments_made);
+}
+
/**
* @brief Raise the current bus pass
*
@@ -978,6 +1031,11 @@
if (bus_current_pass < pass)
bus_current_pass = pass;
KASSERT(bus_current_pass == pass, ("Failed to update bus pass level"));
+
+ /*
+ * Try to attach any pending devices left over at this point.
+ */
+ bus_try_attach_pending();
}
/*
@@ -1121,6 +1179,11 @@
if (dc->parent == parent)
devclass_driver_added(dc, driver);
}
+
+ /*
+ * Try to attach any pending devices left over at this point.
+ */
+ bus_try_attach_pending();
}
/**
@@ -2928,6 +2991,12 @@
return (ENXIO);
}
+ if (DEVICE_DELAY_ATTACH(dev)) {
+ if (bootverbose)
+ device_printf(dev, "attach postponed\n");
+ return (EAGAIN);
+ }
+
device_sysctl_init(dev);
if (!device_is_quiet(dev))
device_print_child(dev->parent, dev);
Index: sys/powerpc/powermac/smu.c
===================================================================
--- sys/powerpc/powermac/smu.c
+++ sys/powerpc/powermac/smu.c
@@ -154,6 +154,7 @@
/* regular bus attachment functions */
static int smu_probe(device_t);
+static bool smu_delay_attach(device_t);
static int smu_attach(device_t);
static const struct ofw_bus_devinfo *
smu_get_devinfo(device_t bus, device_t dev);
@@ -186,6 +187,7 @@
static device_method_t smu_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, smu_probe),
+ DEVMETHOD(device_delay_attach, smu_delay_attach),
DEVMETHOD(device_attach, smu_attach),
/* Clock interface */
@@ -278,6 +280,14 @@
sc->sc_cmd_phys = segs[0].ds_addr;
}
+static bool
+smu_delay_attach(device_t dev)
+{
+
+ /* Delay attachment until our GPIO has attached */
+ return (smu_doorbell == NULL);
+}
+
static int
smu_attach(device_t dev)
{
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 9, 8:24 PM (18 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28602354
Default Alt Text
D15229.diff (8 KB)
Attached To
Mode
D15229: Allow run-time delayed attachment of devices
Attached
Detach File
Event Timeline
Log In to Comment