Page MenuHomeFreeBSD

D15229.diff
No OneTemporary

D15229.diff

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

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)

Event Timeline