openfirm: Add OF_device_unregister_xref

When a device fails to attach, or a module is unloaded, we want to be
able to unregister the xref as the device goes away.  While the device_t
may still be valid, it won't be providing whatever functionality the
consumer that follows the xref wants it for and thus, we should not
keep it discoverable.

[Commit message re-worded by kevans@]

Reviewed by:	ian, imp
Differential Revision:	https://reviews.freebsd.org/D22945
This commit is contained in:
Emannuel Vadot
2025-04-03 08:54:41 -05:00
committed by Kyle Evans
parent ef777be985
commit 944eda42fa
3 changed files with 33 additions and 1 deletions
+13 -1
View File
@@ -23,19 +23,22 @@
.\" (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 April 9, 2018
.Dd April 3, 2025
.Dt OF_DEVICE_FROM_XREF 9
.Os
.Sh NAME
.Nm OF_device_from_xref ,
.Nm OF_xref_from_device ,
.Nm OF_device_register_xref
.Nm OF_device_unregister_xref
.Nd "manage mappings between xrefs and devices"
.Sh SYNOPSIS
.In dev/ofw/ofw_bus.h
.In dev/ofw/ofw_bus_subr.h
.Ft int
.Fn OF_device_register_xref "phandle_t xref" "device_t dev"
.Ft void
.Fn OF_device_unregister_xref "phandle_t xref" "device_t dev"
.Ft device_t
.Fn OF_device_from_xref "phandle_t xref"
.Ft phandle_t
@@ -57,6 +60,15 @@ If a mapping entry for
already exists, it is replaced with the new one.
The function always returns 0.
.Pp
.Fn OF_device_unregister_xref
removes a map entry from the effective phandle
.Fa xref
to device
.Fa dev .
If a mapping entry for
.Fa xref
does not exists, it silently returns.
.Pp
.Fn OF_device_from_xref
returns a device_t instance associated with the effective phandle
.Fa xref .
+19
View File
@@ -187,6 +187,15 @@ xrefinfo_add(phandle_t node, phandle_t xref, device_t dev)
return (xi);
}
static void
xrefinfo_remove(struct xrefinfo *xi)
{
mtx_lock(&xreflist_lock);
SLIST_REMOVE(&xreflist, xi, xrefinfo, next_entry);
mtx_unlock(&xreflist_lock);
}
/*
* OFW install routines. Highest priority wins, equal priority also
* overrides allowing last-set to win.
@@ -704,6 +713,16 @@ OF_device_register_xref(phandle_t xref, device_t dev)
panic("Attempt to register device before xreflist_init");
}
void
OF_device_unregister_xref(phandle_t xref, device_t dev)
{
struct xrefinfo *xi;
if ((xi = xrefinfo_find(xref, FIND_BY_XREF)) == NULL)
return;
xrefinfo_remove(xi);
}
/* Call the method in the scope of a given instance. */
int
OF_call_method(const char *method, ihandle_t instance, int nargs, int nreturns,
+1
View File
@@ -149,6 +149,7 @@ phandle_t OF_xref_from_node(phandle_t node);
device_t OF_device_from_xref(phandle_t xref);
phandle_t OF_xref_from_device(device_t dev);
int OF_device_register_xref(phandle_t xref, device_t dev);
void OF_device_unregister_xref(phandle_t xref, device_t dev);
/* Device I/O functions */
ihandle_t OF_open(const char *path);