1a91b408aSEmmanuel Vadot /*-
2a91b408aSEmmanuel Vadot * Copyright (c) 2020 The FreeBSD Foundation
3a91b408aSEmmanuel Vadot *
4a91b408aSEmmanuel Vadot * This software was developed by Emmanuel Vadot under sponsorship
5a91b408aSEmmanuel Vadot * from the FreeBSD Foundation.
6a91b408aSEmmanuel Vadot *
7a91b408aSEmmanuel Vadot * Redistribution and use in source and binary forms, with or without
8a91b408aSEmmanuel Vadot * modification, are permitted provided that the following conditions
9a91b408aSEmmanuel Vadot * are met:
10a91b408aSEmmanuel Vadot * 1. Redistributions of source code must retain the above copyright
11a91b408aSEmmanuel Vadot * notice, this list of conditions and the following disclaimer.
12a91b408aSEmmanuel Vadot * 2. Redistributions in binary form must reproduce the above copyright
13a91b408aSEmmanuel Vadot * notice, this list of conditions and the following disclaimer in the
14a91b408aSEmmanuel Vadot * documentation and/or other materials provided with the distribution.
15a91b408aSEmmanuel Vadot *
16a91b408aSEmmanuel Vadot * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17a91b408aSEmmanuel Vadot * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18a91b408aSEmmanuel Vadot * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19a91b408aSEmmanuel Vadot * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20a91b408aSEmmanuel Vadot * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21a91b408aSEmmanuel Vadot * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22a91b408aSEmmanuel Vadot * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23a91b408aSEmmanuel Vadot * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24a91b408aSEmmanuel Vadot * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25a91b408aSEmmanuel Vadot * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26a91b408aSEmmanuel Vadot * SUCH DAMAGE.
27a91b408aSEmmanuel Vadot */
28a91b408aSEmmanuel Vadot
29a91b408aSEmmanuel Vadot #include <sys/param.h>
30a91b408aSEmmanuel Vadot #include <sys/systm.h>
31a91b408aSEmmanuel Vadot #include <sys/kernel.h>
32a91b408aSEmmanuel Vadot
33a91b408aSEmmanuel Vadot #include <linux/dmi.h>
34a91b408aSEmmanuel Vadot
35a91b408aSEmmanuel Vadot static char *dmi_data[DMI_STRING_MAX];
36a91b408aSEmmanuel Vadot
37a91b408aSEmmanuel Vadot static void
linux_dmi_preload(void * arg)38a91b408aSEmmanuel Vadot linux_dmi_preload(void *arg)
39a91b408aSEmmanuel Vadot {
40a91b408aSEmmanuel Vadot
41a91b408aSEmmanuel Vadot dmi_data[DMI_BIOS_VENDOR] = kern_getenv("smbios.bios.vendor");
42a91b408aSEmmanuel Vadot dmi_data[DMI_BIOS_VERSION] = kern_getenv("smbios.bios.version");
43a91b408aSEmmanuel Vadot dmi_data[DMI_BIOS_DATE] = kern_getenv("smbios.bios.reldate");
44a91b408aSEmmanuel Vadot dmi_data[DMI_SYS_VENDOR] = kern_getenv("smbios.system.maker");
45a91b408aSEmmanuel Vadot dmi_data[DMI_PRODUCT_NAME] = kern_getenv("smbios.system.product");
46a91b408aSEmmanuel Vadot dmi_data[DMI_PRODUCT_VERSION] = kern_getenv("smbios.system.version");
47a91b408aSEmmanuel Vadot dmi_data[DMI_PRODUCT_SERIAL] = kern_getenv("smbios.system.serial");
48a91b408aSEmmanuel Vadot dmi_data[DMI_PRODUCT_UUID] = kern_getenv("smbios.system.uuid");
49a91b408aSEmmanuel Vadot dmi_data[DMI_BOARD_VENDOR] = kern_getenv("smbios.planar.maker");
50a91b408aSEmmanuel Vadot dmi_data[DMI_BOARD_NAME] = kern_getenv("smbios.planar.product");
51a91b408aSEmmanuel Vadot dmi_data[DMI_BOARD_VERSION] = kern_getenv("smbios.planar.version");
52a91b408aSEmmanuel Vadot dmi_data[DMI_BOARD_SERIAL] = kern_getenv("smbios.planar.serial");
53a91b408aSEmmanuel Vadot dmi_data[DMI_BOARD_ASSET_TAG] = kern_getenv("smbios.planar.tag");
54a91b408aSEmmanuel Vadot dmi_data[DMI_CHASSIS_VENDOR] = kern_getenv("smbios.chassis.maker");
55a91b408aSEmmanuel Vadot dmi_data[DMI_CHASSIS_TYPE] = kern_getenv("smbios.chassis.type");
56a91b408aSEmmanuel Vadot dmi_data[DMI_CHASSIS_VERSION] = kern_getenv("smbios.chassis.version");
57a91b408aSEmmanuel Vadot dmi_data[DMI_CHASSIS_SERIAL] = kern_getenv("smbios.chassis.serial");
58a91b408aSEmmanuel Vadot dmi_data[DMI_CHASSIS_ASSET_TAG] = kern_getenv("smbios.chassis.tag");
59a91b408aSEmmanuel Vadot }
60a91b408aSEmmanuel Vadot SYSINIT(linux_dmi_preload, SI_SUB_DRIVERS, SI_ORDER_ANY, linux_dmi_preload, NULL);
61a91b408aSEmmanuel Vadot
62a91b408aSEmmanuel Vadot /* Match a system against a field */
63a91b408aSEmmanuel Vadot bool
linux_dmi_match(enum dmi_field f,const char * str)64a91b408aSEmmanuel Vadot linux_dmi_match(enum dmi_field f, const char *str)
65a91b408aSEmmanuel Vadot {
66a91b408aSEmmanuel Vadot
67a91b408aSEmmanuel Vadot if (f < DMI_STRING_MAX &&
68a91b408aSEmmanuel Vadot dmi_data[f] != NULL &&
69a91b408aSEmmanuel Vadot strcmp(dmi_data[f], str) == 0)
70a91b408aSEmmanuel Vadot return(true);
71a91b408aSEmmanuel Vadot return (false);
72a91b408aSEmmanuel Vadot }
73a91b408aSEmmanuel Vadot
74a91b408aSEmmanuel Vadot /* Match a system against the struct, all matches must be ok */
75a91b408aSEmmanuel Vadot static bool
linux_dmi_matches(const struct dmi_system_id * dsi)76a91b408aSEmmanuel Vadot linux_dmi_matches(const struct dmi_system_id *dsi)
77a91b408aSEmmanuel Vadot {
78*85d7875dSHans Petter Selasky enum dmi_field slot;
79a91b408aSEmmanuel Vadot int i;
80a91b408aSEmmanuel Vadot
81a91b408aSEmmanuel Vadot for (i = 0; i < nitems(dsi->matches); i++) {
82*85d7875dSHans Petter Selasky slot = dsi->matches[i].slot;
83*85d7875dSHans Petter Selasky if (slot == DMI_NONE)
84a91b408aSEmmanuel Vadot break;
85*85d7875dSHans Petter Selasky if (slot >= DMI_STRING_MAX ||
86*85d7875dSHans Petter Selasky dmi_data[slot] == NULL)
87*85d7875dSHans Petter Selasky return (false);
8899902b1cSCorvin Köhne if (dsi->matches[i].exact_match) {
89*85d7875dSHans Petter Selasky if (dmi_match(slot, dsi->matches[i].substr))
90*85d7875dSHans Petter Selasky continue;
91*85d7875dSHans Petter Selasky } else if (strstr(dmi_data[slot],
92*85d7875dSHans Petter Selasky dsi->matches[i].substr) != NULL) {
93*85d7875dSHans Petter Selasky continue;
9499902b1cSCorvin Köhne }
95*85d7875dSHans Petter Selasky return (false);
96a91b408aSEmmanuel Vadot }
97a91b408aSEmmanuel Vadot return (true);
98a91b408aSEmmanuel Vadot }
99a91b408aSEmmanuel Vadot
100a91b408aSEmmanuel Vadot /* Return the string matching the field */
101a91b408aSEmmanuel Vadot const char *
linux_dmi_get_system_info(int field)102a91b408aSEmmanuel Vadot linux_dmi_get_system_info(int field)
103a91b408aSEmmanuel Vadot {
104a91b408aSEmmanuel Vadot
105a91b408aSEmmanuel Vadot if (field < DMI_STRING_MAX)
106a91b408aSEmmanuel Vadot return (dmi_data[field]);
107a91b408aSEmmanuel Vadot return (NULL);
108a91b408aSEmmanuel Vadot }
109a91b408aSEmmanuel Vadot
110a91b408aSEmmanuel Vadot /*
111a91b408aSEmmanuel Vadot * Match a system against the structs list
112a91b408aSEmmanuel Vadot * If a match is found return the corresponding structure.
113a91b408aSEmmanuel Vadot */
114a91b408aSEmmanuel Vadot const struct dmi_system_id *
linux_dmi_first_match(const struct dmi_system_id * list)115a91b408aSEmmanuel Vadot linux_dmi_first_match(const struct dmi_system_id *list)
116a91b408aSEmmanuel Vadot {
117a91b408aSEmmanuel Vadot const struct dmi_system_id *dsi;
118a91b408aSEmmanuel Vadot
119a91b408aSEmmanuel Vadot for (dsi = list; dsi->matches[0].slot != 0; dsi++) {
120a91b408aSEmmanuel Vadot if (linux_dmi_matches(dsi))
121a91b408aSEmmanuel Vadot return (dsi);
122a91b408aSEmmanuel Vadot }
123a91b408aSEmmanuel Vadot
124a91b408aSEmmanuel Vadot return (NULL);
125a91b408aSEmmanuel Vadot }
126a91b408aSEmmanuel Vadot
127a91b408aSEmmanuel Vadot /*
128a91b408aSEmmanuel Vadot * Match a system against the structs list
129a91b408aSEmmanuel Vadot * For each match call the callback with the corresponding data
130a91b408aSEmmanuel Vadot * Return the number of matches.
131a91b408aSEmmanuel Vadot */
132a91b408aSEmmanuel Vadot int
linux_dmi_check_system(const struct dmi_system_id * sysid)133a91b408aSEmmanuel Vadot linux_dmi_check_system(const struct dmi_system_id *sysid)
134a91b408aSEmmanuel Vadot {
135a91b408aSEmmanuel Vadot const struct dmi_system_id *dsi;
136a91b408aSEmmanuel Vadot int matches = 0;
137a91b408aSEmmanuel Vadot
138a91b408aSEmmanuel Vadot for (dsi = sysid; dsi->matches[0].slot != 0; dsi++) {
139a91b408aSEmmanuel Vadot if (linux_dmi_matches(dsi)) {
140a91b408aSEmmanuel Vadot matches++;
141a91b408aSEmmanuel Vadot if (dsi->callback && dsi->callback(dsi))
142a91b408aSEmmanuel Vadot break;
143a91b408aSEmmanuel Vadot }
144a91b408aSEmmanuel Vadot }
145a91b408aSEmmanuel Vadot
146a91b408aSEmmanuel Vadot return (matches);
147a91b408aSEmmanuel Vadot }
148