Module Name: src Committed By: thorpej Date: Mon Jun 18 15:36:54 UTC 2018
Modified Files: src/sys/kern: subr_autoconf.c src/sys/sys: device.h Log Message: Add device_compatible_match(), a generalized routine for weighted matching of device_compatible_entry data to a device's "compatible" strings. To generate a diff of this commit: cvs rdiff -u -r1.257 -r1.258 src/sys/kern/subr_autoconf.c cvs rdiff -u -r1.152 -r1.153 src/sys/sys/device.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/subr_autoconf.c diff -u src/sys/kern/subr_autoconf.c:1.257 src/sys/kern/subr_autoconf.c:1.258 --- src/sys/kern/subr_autoconf.c:1.257 Sun Mar 4 07:12:18 2018 +++ src/sys/kern/subr_autoconf.c Mon Jun 18 15:36:54 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_autoconf.c,v 1.257 2018/03/04 07:12:18 mlelstv Exp $ */ +/* $NetBSD: subr_autoconf.c,v 1.258 2018/06/18 15:36:54 thorpej Exp $ */ /* * Copyright (c) 1996, 2000 Christopher G. Demetriou @@ -77,7 +77,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.257 2018/03/04 07:12:18 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.258 2018/06/18 15:36:54 thorpej Exp $"); #ifdef _KERNEL_OPT #include "opt_ddb.h" @@ -2275,6 +2275,69 @@ device_find_by_driver_unit(const char *n } /* + * device_compatible_entry_matches: + * + * Helper function to determine if a device_compatible_entry + * contains a match for the specified "compatible" string. + */ +static bool +device_compatible_entry_matches(const struct device_compatible_entry *dce, + const char *compatible) +{ + const char **cpp = DEVICE_COMPAT_ENTRY_GET_STRINGS(dce); + + if (cpp == NULL) + return false; + + while (*cpp != NULL) + if (strcmp(*cpp, compatible) == 0) + return true; + + return false; +} + +/* + * device_compatible_match: + * + * Match a driver's "compatible" data against a device's + * "compatible" strings. If a match is found, we return + * the matching device_compatible_entry, along with a + * matching weight. + */ +const struct device_compatible_entry * +device_compatible_match(const char **device_compats, int ndevice_compats, + const struct device_compatible_entry *driver_compats, + int *match_weightp) +{ + const struct device_compatible_entry *dce = NULL; + int i, match_weight; + + if (ndevice_compats == 0 || device_compats == NULL || + driver_compats == NULL) + return NULL; + + /* + * We take the first match because we start with the most-specific + * device compatible string. + */ + for (i = 0, match_weight = ndevice_compats - 1; + i < ndevice_compats; + i++, match_weight--) { + for (dce = driver_compats; + DEVICE_COMPAT_ENTRY_IS_TERMINATOR(dce) == false; dce++) { + if (device_compatible_entry_matches(dce, + device_compats[i])) { + KASSERT(match_weight >= 0); + if (match_weightp) + *match_weightp = match_weight; + return dce; + } + } + } + return NULL; +} + +/* * Power management related functions. */ Index: src/sys/sys/device.h diff -u src/sys/sys/device.h:1.152 src/sys/sys/device.h:1.153 --- src/sys/sys/device.h:1.152 Sun Jun 17 15:06:27 2018 +++ src/sys/sys/device.h Mon Jun 18 15:36:54 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: device.h,v 1.152 2018/06/17 15:06:27 thorpej Exp $ */ +/* $NetBSD: device.h,v 1.153 2018/06/18 15:36:54 thorpej Exp $ */ /* * Copyright (c) 1996, 2000 Christopher G. Demetriou @@ -552,6 +552,11 @@ bool device_is_a(device_t, const char * device_t device_find_by_xname(const char *); device_t device_find_by_driver_unit(const char *, int); +const struct device_compatible_entry * + device_compatible_match(const char **, int, + const struct device_compatible_entry *, + int *); + bool device_pmf_is_registered(device_t); bool device_pmf_driver_suspend(device_t, const pmf_qual_t *);