diff options
author | Corvin Köhne <CorvinK@beckhoff.com> | 2022-06-03 14:20:45 +0000 |
---|---|---|
committer | Corvin Köhne <corvink@FreeBSD.org> | 2022-12-08 12:33:16 +0000 |
commit | 6820a0512fa6616ee1da46cb0075da80478776f0 (patch) | |
tree | 8a8da3a207f3b3fab9606d94d41eb215fb15ff87 | |
parent | a76fa7bb6cb721bcccc257ddbc4398d25dc8def8 (diff) |
linuxkpi/dmi: don't match exactly on DMI_MATCH
Linux has two defines to check dmi data. DMI_MATCH checks if the dmi
string includes substr. DMI_EXACT_MATCH checks if the dmi string exactly
matches substr. Compat layer should have the same behaviour.
The new definition of dmi_strmatch shouldn't break any driver. A driver
would break if it uses the highest bit of the slot field. Nevertheless,
linux uses the same definition and FreeBSD uses dmi_field values as slot
which are lower than 128.
Sponsored by: Beckhoff Automation GmbH & Co. KG
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D35395
(cherry picked from commit 99902b1c52219bae4b9f3684e3ebd83152a1add4)
LinuxKPI: Fix dmi_matches() function
Make sure to check for NULL pointers and also check all search criterias,
not only the first one!
Bump the FreeBSD version.
Reviewed by: manu@
Differential Revision: https://reviews.freebsd.org/D35403
MFC after: 1 week
Sponsored by: NVIDIA Networking
(cherry picked from commit 85d7875d42913c2cb10a007a1be05b210dc6aab2)
-rw-r--r-- | sys/compat/linuxkpi/common/include/linux/mod_devicetable.h | 5 | ||||
-rw-r--r-- | sys/compat/linuxkpi/common/src/linux_dmi.c | 17 | ||||
-rw-r--r-- | sys/sys/param.h | 2 |
3 files changed, 17 insertions, 7 deletions
diff --git a/sys/compat/linuxkpi/common/include/linux/mod_devicetable.h b/sys/compat/linuxkpi/common/include/linux/mod_devicetable.h index 89adcbc6e969..804fbb1df198 100644 --- a/sys/compat/linuxkpi/common/include/linux/mod_devicetable.h +++ b/sys/compat/linuxkpi/common/include/linux/mod_devicetable.h @@ -55,7 +55,8 @@ enum dmi_field { }; struct dmi_strmatch { - unsigned char slot; + unsigned char slot : 7; + unsigned char exact_match : 1; char substr[79]; }; @@ -67,7 +68,7 @@ struct dmi_system_id { }; #define DMI_MATCH(a, b) { .slot = a, .substr = b } -#define DMI_EXACT_MATCH(a, b) { .slot = a, .substr = b, } +#define DMI_EXACT_MATCH(a, b) { .slot = a, .substr = b, .exact_match = 1 } #define I2C_NAME_SIZE 20 #define I2C_MODULE_PREFIX "i2c:" diff --git a/sys/compat/linuxkpi/common/src/linux_dmi.c b/sys/compat/linuxkpi/common/src/linux_dmi.c index c0bb9a9f50d6..70d56c246c10 100644 --- a/sys/compat/linuxkpi/common/src/linux_dmi.c +++ b/sys/compat/linuxkpi/common/src/linux_dmi.c @@ -77,16 +77,25 @@ linux_dmi_match(enum dmi_field f, const char *str) static bool linux_dmi_matches(const struct dmi_system_id *dsi) { + enum dmi_field slot; int i; for (i = 0; i < nitems(dsi->matches); i++) { - if (dsi->matches[i].slot == DMI_NONE) + slot = dsi->matches[i].slot; + if (slot == DMI_NONE) break; - if (dmi_match(dsi->matches[i].slot, - dsi->matches[i].substr) == false) + if (slot >= DMI_STRING_MAX || + dmi_data[slot] == NULL) return (false); + if (dsi->matches[i].exact_match) { + if (dmi_match(slot, dsi->matches[i].substr)) + continue; + } else if (strstr(dmi_data[slot], + dsi->matches[i].substr) != NULL) { + continue; + } + return (false); } - return (true); } diff --git a/sys/sys/param.h b/sys/sys/param.h index e417fed4149b..57cf5937d952 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -60,7 +60,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1301509 /* Master, propagated to newvers */ +#define __FreeBSD_version 1301510 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, |