aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorvin Köhne <CorvinK@beckhoff.com>2022-06-03 14:20:45 +0000
committerCorvin Köhne <corvink@FreeBSD.org>2022-12-08 12:33:16 +0000
commit6820a0512fa6616ee1da46cb0075da80478776f0 (patch)
tree8a8da3a207f3b3fab9606d94d41eb215fb15ff87
parenta76fa7bb6cb721bcccc257ddbc4398d25dc8def8 (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.h5
-rw-r--r--sys/compat/linuxkpi/common/src/linux_dmi.c17
-rw-r--r--sys/sys/param.h2
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,