git: 91cce9c871a6 - stable/13 - stand: Add dv_match

From: Warner Losh <imp_at_FreeBSD.org>
Date: Tue, 24 Jan 2023 22:13:25 UTC
The branch stable/13 has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=91cce9c871a6d367a68ae1ada0d8e73fad994301

commit 91cce9c871a6d367a68ae1ada0d8e73fad994301
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2022-11-30 22:09:51 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2023-01-24 21:49:40 +0000

    stand: Add dv_match
    
    On OpenFirmware, and possibly kboot, we use full path names for the
    objects that are the 'device'. kboot uses a hack of knowing that all
    disk device nodes start with '/dev', but this generalizes it for
    OpenFirmware where both 'block' and 'network' devices live in the same
    namespace and one must ask the OF node its type to know if this device
    type matches.
    
    For drivers that don't specify, the current convention of using
    strncmp() is retained. This is done only in devparse(), but everything
    uses it directly (or will soon).
    
    Sponsored by:           Netflix
    Differential Revision:  https://reviews.freebsd.org/D37554
    
    (cherry picked from commit a07cef5a738642ae0a39fa513945d9f867a5e2f1)
---
 stand/libsa/dev.c   |  9 +++++++--
 stand/libsa/libsa.3 | 12 ++++++++++++
 stand/libsa/stand.h |  1 +
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/stand/libsa/dev.c b/stand/libsa/dev.c
index b16637181059..b273edb4457e 100644
--- a/stand/libsa/dev.c
+++ b/stand/libsa/dev.c
@@ -126,8 +126,13 @@ devparse(struct devdesc **dev, const char *devspec, const char **path)
 	/* look for a device that matches */
 	for (i = 0; devsw[i] != NULL; i++) {
 		dv = devsw[i];
-		if (!strncmp(devspec, dv->dv_name, strlen(dv->dv_name)))
-			break;
+		if (dv->dv_match != NULL) {
+			if (dv->dv_match(dv, devspec) != 0)
+				break;
+		} else {
+			if (!strncmp(devspec, dv->dv_name, strlen(dv->dv_name)))
+				break;
+		}
 	}
 	if (devsw[i] == NULL)
 		return (ENOENT);
diff --git a/stand/libsa/libsa.3 b/stand/libsa/libsa.3
index fcfd22cbf0d0..8e504ca2585d 100644
--- a/stand/libsa/libsa.3
+++ b/stand/libsa/libsa.3
@@ -750,6 +750,7 @@ struct devsw {
     char *	(*dv_fmtdev)(struct devdesc *);
     int		(*dv_parsedev)(struct devdesc **dev, const char *devpart,
     		const char **path);
+    bool	(*dv_match)(struct devsw *dv, const char *devspec);
 };
 .Ed
 .Bl -tag -width ".Fn dv_strategy"
@@ -823,6 +824,17 @@ in the earlier example.
 Generally, code needing to parse a path will use
 .Fa devparse
 instead of calling this routine directly.
+.It Fn dv_match
+.Dv NULL
+to specify that all device paths starting with
+.Fa dv_name
+match.
+Otherwise, this function returns 0 for a match and a non-zero
+.Dv errno
+to indicate why it didn't match.
+This is helpful when you claim the device path after using it to query
+properties on systems that have uniform naming for different types of
+devices.
 .El
 .Sh HISTORY
 The
diff --git a/stand/libsa/stand.h b/stand/libsa/stand.h
index 660337db6980..b1c48bd88b39 100644
--- a/stand/libsa/stand.h
+++ b/stand/libsa/stand.h
@@ -161,6 +161,7 @@ struct devsw {
     void	(*dv_cleanup)(void);
     char *	(*dv_fmtdev)(struct devdesc *);
     int		(*dv_parsedev)(struct devdesc **, const char *, const char **);
+    bool	(*dv_match)(struct devsw *, const char *);
 };
 
 /*