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