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:
committed by
Kyle Evans
parent
ef777be985
commit
944eda42fa
@@ -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 .
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user