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
This commit is contained in:
Warner Losh 2022-11-30 15:09:51 -07:00
parent 33bbe5ddcb
commit a07cef5a73
3 changed files with 20 additions and 2 deletions

View file

@ -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);

View file

@ -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

View file

@ -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 *);
};
/*