[flashrom] DMI matching patch

Michael Karcher flashrom at mkarcher.dialup.fu-berlin.de
Mon Jan 4 15:15:11 CET 2010


Hello Carl-Daniel,

thanks for your review.

There seems to be a fundamental opinion difference what DMI is used for
between you on the one side and me and Luc on the other side. You seem
to want to use DMI for a good board identification (which is fair
enough, I also started with that intention), whereas now we decided to
use DMI only as an emergency helper in case the PCI IDs seem obviously
not good enough, which should be the exception instead of the regular
case.

Using DMI as emergency rescue has the advantage that it still works on
most systems even if DMI is unavailable (boards having DMI info can not
be matched by PCI IDs with the matching policy of this patch).
Collecting DMI info on boards with good PCI subsystem IDs (like the MSI
boards that have the internal 4-digit product number BCD-coded in the
subsystem IDs) is not useful, in my opinion.

The usage of DMI as breaker explains the loose matching policy of "any
DMI string matches", as the IDs that should go into the table should be
unique enough even with this weak policy (I for example can't imagine
any HP system, as the manufacturer has already been established by
subsystem manufacturer IDs, where "^VL420$" is going to match in the
wrong string). If you want to use DMI as general board identification
mechanism, independent of the PCI IDs, one would of course have to check
more than one field.

Am Montag, den 04.01.2010, 04:53 +0100 schrieb Carl-Daniel Hailfinger:
[...]

> > +int has_dmi_support = 0;
> > +char dmistrings[DMI_ID_INVALID][80];
> I'm not so happy about the static allocation here. Can't we use malloc()
> for the read buffer and strdup() for filling in dmistrings?
Of course we can. On the other hand, I don't really see the point in
using dynamic allocation here. If it's about wasted memory, we should
approach "struct flashchips" first. The fixed-size arrays in it waste a
lot more. Nevertheless, I change it to dynamic allocation. Too bad the
nice getline function that reads one line and allocates dynamically is
GNU-only and not standard C or at least POSIX.

> > +		fgets(dmistrings[i], sizeof(dmistrings[i]), dmidecode_pipe);
> Hm. Check the result of fgets()?
Omitted by choice. The result of fgets is useless. It returns NULL if an
error occurred (we would like to know) or if EOF occurred with no
characters read (which is valid if the BIOS doesn't specify the string
we are trying to read). So instead of checking the ambiguous return
value of fgets, I check the ferror flag afterwards.

> > +int dmi_match(const char * identifier)
> > +{
> > +	int i;
> > +	if (!has_dmi_support)
> > +		return 0;
> > +	for (i = 0;i < DMI_ID_INVALID; i++)
> > +		if (dmi_compare(dmistrings[i], identifier))
> I believe the "match any of the strings" policy is fundamentally wrong.
> If you and Luc think specifying multiple strings for the match is
> overkill/overdesign, please do at least allow specifying the DMI string
> this should be compared with.
Fair enough. I added it. Specifying one string to match is not
increasing complexity much, although it will be a three-character hit on
the board_enable table (if you specify like "bp:^A8V MX$" for baseboard
product match for example). Luc, please NACK if you think the it is too
much.

> Since this is a policy decision, we could have the inner loop here
> inside #ifdef FIXME_POLICY_DECISION or whatever (resulting in a
> non-match for all inputs) to get the infrstructure merged, then finish
> the policy decision in a separate patch.
I don't see the point in getting the infrastructure merged until this
policy decision is made. And it seems to violate the "Don't comment
code" coding standard of coresystems.

> > + * If PCI IDs are not sufficient for board matching, the match can be further
> > + * constrained by a string that has to be present in the DMI database for
> > + * the baseboard or the system entry. The match type is case-sensitive
> > + * substring match.
> Maybe add some text which tells people to always include DMI IDs if they
> create new board matches. Not sure. It would certainly tighten board
> matching, and we don't know how bad the subsystem ID overlap between
> different boards is.
As written in the introduction text, this is something I would like to
avoid. You have a point in "it's nice if it's always there", but this
makes the "we have DMI because it's nice" and "we *need* to match the
DMI info to be sure we have the right board" indistinguishable. I
understand your point of tighter matches being better, but I don't think
that's worth a hard dependency on dmidecode if we get along nicely
without.

> Some of the indentation in the block above uses spaces instead of tabs.
> Spaces are only OK if they are less than 8 and if they are preceded by
> tabs. The most common use case for spaces is indenting function
> arguments or expressions.
Yeah, I agree on that statement too. Fixed also at this place.

Please check the following patch.

<<commit message starts here>>

Matching via DMI: If a board is not uniquely identifiable by PCI
device/subsystem IDs, a string can be specified to be looked for
(case-sensitive, substring or anchored) for now in one of the following
DMI items in addition to matching the PCI IDs:
 - System Manufacturer
 - System Product Name
 - System Version
 - Baseboard Manufacturer
 - Baseboard Product Name
 - Baseboard Version

Strings are anchored re-like (^ at the beginning, $ at the end), but
there are no plans to support full regular expressions. The field to
match is specified in a two-character prefix followed by a colon.

The match is only made if DMI info is available and the string matches.
If no DMI info is available and the PCI IDs match, a warning is printed
as the board can not be autodetected.

It's still open to discussion whether we add an DMI override switch to
specify a string that will definitely match, and whether this switch is
only used if no DMI is available or whether it overrides or augments DMI
data.

DMI data is currently read using dmidecode. This tool is available for
all major platforms except MacOS X. I heard that there also is a MacOS X
version of dmidecode, but didn't investigate that.

Signed-Off-By: Michael Karcher <flashrom at mkarcher.dialup.fu-berlin.de>
---
Changes in 3rd revision of the patch (all issues found by carldani):
  - Fixed spaces/tabs issues.
  - error checking on popen
  - DMI strings are dynamically allocated (size limit of 4096 shouldn't
matter and avoids reallocations)
  - Specification of field to match is needed now
  - Added a DMI match for the P5A mainboard as example (untestd. Source
for DMI info: http://enrico-scholz.de/hw/londo/dmidecode .
  - Minor coding style changes (spaces after "*" in pointer declaration,
on pair of parentheses)


Index: flash.h
===================================================================
--- flash.h	(Revision 824)
+++ flash.h	(Arbeitskopie)
@@ -251,6 +251,9 @@
 	uint16_t second_card_vendor;
 	uint16_t second_card_device;
 
+	/* Pattern to match DMI entries */
+	const char *dmi_pattern;
+
 	/* The vendor / part name from the coreboot table. */
 	const char *lb_vendor;
 	const char *lb_part;
@@ -330,6 +333,11 @@
 extern char *lb_part, *lb_vendor;
 extern int partvendor_from_cbtable;
 
+/* dmi.c */
+extern int has_dmi_support;
+void dmi_init(void);
+int dmi_match(const char *pattern);
+
 /* internal.c */
 #if NEED_PCI == 1
 struct superio {
Index: Makefile
===================================================================
--- Makefile	(Revision 824)
+++ Makefile	(Arbeitskopie)
@@ -101,7 +101,7 @@
 
 ifeq ($(CONFIG_INTERNAL), yes)
 FEATURE_CFLAGS += -D'INTERNAL_SUPPORT=1'
-PROGRAMMER_OBJS += chipset_enable.o board_enable.o cbtable.o it87spi.o ichspi.o sb600spi.o wbsio_spi.o
+PROGRAMMER_OBJS += chipset_enable.o board_enable.o cbtable.o dmi.o it87spi.o ichspi.o sb600spi.o wbsio_spi.o
 NEED_PCI := yes
 endif
 
Index: dmi.c
===================================================================
--- dmi.c	(Revision 0)
+++ dmi.c	(Revision 0)
@@ -0,0 +1,175 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright (C) 2009,2010 Michael Karcher
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "flash.h"
+
+enum dmi_strings {
+	DMI_SYS_MANUFACTURER,
+	DMI_SYS_PRODUCT,
+	DMI_SYS_VERSION,
+	DMI_BB_MANUFACTURER,
+	DMI_BB_PRODUCT,
+	DMI_BB_VERSION,
+	DMI_ID_INVALID /* This must always be the last entry */
+};
+
+/* The short_id for baseboard starts with "m" as in mainboard to leave
+   "b" available for BIOS */
+struct {
+	const char *dmidecode_name;
+	char short_id[3];
+} dmi_properties[DMI_ID_INVALID] = {
+	{"system-manufacturer", "sm"},
+	{"system-product-name", "sp"},
+	{"system-version", "sv"},
+	{"baseboard-manufacturer", "mm"},
+	{"baseboard-product-name", "mp"},
+	{"baseboard-version", "mv"}
+};
+
+#define DMI_COMMAND_LEN_MAX 260
+const char *dmidecode_command = "dmidecode";
+
+int has_dmi_support = 0;
+char *dmistrings[DMI_ID_INVALID];
+
+/* strings longer than 4096 in DMI are just insane */
+#define DMI_MAX_ANSWER_LEN 4096
+
+void dmi_init(void)
+{
+	FILE *dmidecode_pipe;
+	int i;
+	char *answerbuf = malloc(DMI_MAX_ANSWER_LEN);
+	if(!answerbuf)
+	{
+		fprintf(stderr, "DMI: couldn't alloc answer buffer\n");
+		return;
+	}
+	for (i = 0; i < DMI_ID_INVALID; i++)
+	{
+		char commandline[DMI_COMMAND_LEN_MAX+40];
+		snprintf(commandline, sizeof(commandline),
+		         "%s -s %s", dmidecode_command,
+		         dmi_properties[i].dmidecode_name);
+		dmidecode_pipe = popen(commandline, "r");
+		if (!dmidecode_pipe)
+		{
+			printf_debug("DMI pipe open error\n");
+			goto out_free;
+		}
+		fgets(answerbuf, DMI_MAX_ANSWER_LEN, dmidecode_pipe);
+		if (ferror(dmidecode_pipe))
+		{
+			printf_debug("DMI pipe read error\n");
+			pclose(dmidecode_pipe);
+			goto out_free;
+		}
+		/* Toss all output above DMI_MAX_ANSWER_LEN away to prevent
+		   deadlock on pclose. */
+		while (!feof(dmidecode_pipe))
+			getc(dmidecode_pipe);
+		if (pclose(dmidecode_pipe) != 0)
+		{
+			printf_debug("DMI pipe close error\n");
+			goto out_free;
+		}
+
+		/* chomp trailing newline */
+		if (answerbuf[0] != 0 &&
+		    answerbuf[strlen(answerbuf) - 1] == '\n')
+			answerbuf[strlen(answerbuf) - 1] = 0;
+		printf_debug("DMI string %d: \"%s\"\n", i, answerbuf);
+		dmistrings[i] = strdup(answerbuf);
+	}
+	has_dmi_support = 1;
+out_free:
+	free(answerbuf);
+}
+
+/**
+ * Does an substring/prefix/postfix/whole-string match.
+ *
+ * The pattern is matched as-is. The only metacharacters supported are '^'
+ * at the beginning and '$' at the end. So you can look for "^prefix",
+ * "suffix$", "substring" or "^complete string$".
+ *
+ * @param value The string to check.
+ * @param pattern The pattern.
+ * @return Nonzero if pattern matches.
+ */
+static int dmi_compare(const char *value, const char *pattern)
+{
+	int anchored = 0;
+	int patternlen;
+	printf_debug("matching %s against %s\n", value, pattern);
+	/* The empty string is part of all strings */
+	if (pattern[0] == 0)
+		return 1;
+
+	if (pattern[0] == '^') {
+		anchored = 1;
+		pattern++;
+	}
+
+	patternlen = strlen(pattern);
+	if (pattern[patternlen - 1] == '$') {
+		int valuelen = strlen(value);
+		patternlen--;
+		if(patternlen > valuelen)
+			return 0;
+
+		/* full string match: require same length */
+		if(anchored && (valuelen != patternlen))
+			return 0;
+
+		/* start character to make ends match */
+		value += valuelen - patternlen;
+		anchored = 1;
+	}
+
+	if (anchored)
+		return strncmp(value, pattern, patternlen) == 0;
+	else
+		return strstr(value, pattern) != NULL;
+}
+
+int dmi_match(const char *pattern)
+{
+	int i;
+	if (!has_dmi_support)
+		return 0;
+	if (strlen(pattern) < 3 || pattern[2] != ':')
+	{
+		fprintf(stderr, "BUG: broken DMI pattern %s!\n", pattern);
+		return 0;
+	}
+	for (i = 0;i < DMI_ID_INVALID; i++)
+	{
+		if (strncmp(pattern, dmi_properties[i].short_id, 2) == 0)
+			return dmi_compare(dmistrings[i], pattern+3);
+	}
+	fprintf(stderr, "BUG: no DMI property %.2s\n", pattern);
+	return 0;
+}
Index: internal.c
===================================================================
--- internal.c	(Revision 824)
+++ internal.c	(Arbeitskopie)
@@ -152,6 +152,7 @@
 	 * mainboard specific flash enable sequence.
 	 */
 	coreboot_init();
+	dmi_init();
 
 	/* Probe for the SuperI/O chip and fill global struct superio. */
 	probe_superio();
Index: board_enable.c
===================================================================
--- board_enable.c	(Revision 824)
+++ board_enable.c	(Arbeitskopie)
@@ -1162,6 +1162,18 @@
  * provide an as complete set of pci ids as possible; autodetection is the
  * preferred behaviour and we would like to make sure that matches are unique.
  *
+ * If PCI IDs are not sufficient for board matching, the match can be further
+ * constrained by a string that has to be present in the DMI database for
+ * the baseboard or the system entry. The DMI match uses a special pattern
+ * syntax: A field specifier (2 characters) followed by a colon and a pattern
+ * to match that field to. The field specifier can be "sm", "sp", "sv", "mm",
+ * "mp", "mv" for system manufacturer, system product name, system version,
+ * mainboard (aka base board) manufacturer, mainboard product name and
+ * mainboard version. The pattern after the colon is matched by case sensitve
+ * substring match, unless it is anchored to the beginning (with a ^ in front)
+ * or the end (with a $ at the end). Both anchors may be specified at the
+ * same time to match the full field.
+ *
  * The coreboot ids are used two fold. When running with a coreboot firmware,
  * the ids uniquely matches the coreboot board identification string. When a
  * legacy bios is installed and when autodetection is not possible, these ids
@@ -1173,61 +1185,61 @@
 
 /* Please keep this list alphabetically ordered by vendor/board name. */
 struct board_pciid_enable board_pciid_enables[] = {
-	/* first pci-id set [4],          second pci-id set [4],          coreboot id [2],             vendor name    board name            flash enable */
-	{0x8086, 0x2926, 0x147b, 0x1084,  0x11ab, 0x4364, 0x147b, 0x1084, NULL,         NULL,          "Abit",        "IP35",               intel_ich_gpio16_raise},
-	{0x105a, 0x0d30, 0x105a, 0x4d33,  0x8086, 0x1130, 0x8086,      0, NULL,         NULL,          "Acorp",       "6A815EPD",           board_acorp_6a815epd},
-	{0x8086, 0x24D4, 0x1849, 0x24D0,  0x8086, 0x24D5, 0x1849, 0x9739, NULL,         NULL,          "ASRock",      "P4i65GV",            intel_ich_gpio23_raise},
-	{0x1022, 0x746B,      0,      0,       0,      0,      0,      0, "AGAMI",      "ARUMA",       "agami",       "Aruma",              w83627hf_gpio24_raise_2e},
-	{0x1106, 0x3177, 0x17F2, 0x3177,  0x1106, 0x3148, 0x17F2, 0x3148, NULL,         NULL,          "Albatron",    "PM266A",             w836xx_memw_enable_2e},
-	{0x1106, 0x3205, 0x1106, 0x3205,  0x10EC, 0x8139, 0xA0A0, 0x0477, NULL,         NULL,          "AOpen",       "vKM400Am-S",         it8705_rom_write_enable},
-	{0x1022, 0x2090,      0,      0,  0x1022, 0x2080,      0,      0, "artecgroup", "dbe61",       "Artec Group", "DBE61",              board_artecgroup_dbe6x},
-	{0x1022, 0x2090,      0,      0,  0x1022, 0x2080,      0,      0, "artecgroup", "dbe62",       "Artec Group", "DBE62",              board_artecgroup_dbe6x},
-	{0x1106, 0x3189, 0x1043, 0x807F,  0x1106, 0x3065, 0x1043, 0x80ED, NULL,         NULL,          "ASUS",        "A7V600-X",           board_asus_a7v600x},
-	{0x1106, 0x3189, 0x1043, 0x807F,  0x1106, 0x3177, 0x1043, 0x808C, NULL,         NULL,          "ASUS",        "A7V8X",              board_asus_a7v8x},
-	{0x1106, 0x3177, 0x1043, 0x80A1,  0x1106, 0x3205, 0x1043, 0x8118, NULL,         NULL,          "ASUS",        "A7V8X-MX SE",        w836xx_memw_enable_2e},
-	{0x1106, 0x1336, 0x1043, 0x80ed,  0x1106, 0x3288, 0x1043, 0x8249, NULL,         NULL,          "ASUS",        "M2V-MX",             via_vt823x_gpio5_raise},
-	{0x8086, 0x1a30, 0x1043, 0x8070,  0x8086, 0x244b, 0x1043, 0x8028, NULL,         NULL,          "ASUS",        "P4B266",             intel_ich_gpio22_raise},
-	{0x8086, 0x1A30, 0x1043, 0x8025,  0x8086, 0x244B, 0x104D, 0x80F0, NULL,         NULL,          "ASUS",        "P4B266-LM",          intel_ich_gpio21_raise},
-	{0x8086, 0x2570, 0x1043, 0x80F2,  0x105A, 0x3373, 0x1043, 0x80F5, NULL,         NULL,          "ASUS",        "P4P800-E Deluxe",    intel_ich_gpio21_raise},
-	{0x10B9, 0x1541,      0,      0,  0x10B9, 0x1533,      0,      0, "asus",       "p5a",         "ASUS",        "P5A",                board_asus_p5a},
-	{0x10DE, 0x0030, 0x1043, 0x818a,  0x8086, 0x100E, 0x1043, 0x80EE, NULL,         NULL,          "ASUS",        "P5ND2-SLI Deluxe",   nvidia_mcp_gpio10_raise},
-	{0x1106, 0x3149, 0x1565, 0x3206,  0x1106, 0x3344, 0x1565, 0x1202, NULL,         NULL,          "Biostar",     "P4M80-M4",           it8705_rom_write_enable},
-	{0x8086, 0x3590, 0x1028, 0x016c,  0x1000, 0x0030, 0x1028, 0x016c, NULL,         NULL,          "Dell",        "PowerEdge 1850",     intel_ich_gpio23_raise},
-	{0x1039, 0x5513, 0x1019, 0x0A41,  0x1039, 0x0018,      0,      0, NULL,         NULL,          "Elitegroup",  "K7S6A",              elitegroup_k7vta3},
-	{0x1106, 0x3038, 0x1019, 0x0996,  0x1106, 0x3177, 0x1019, 0x0996, NULL,         NULL,          "Elitegroup",  "K7VTA3",             elitegroup_k7vta3},
-	{0x1106, 0x3177, 0x1106, 0x3177,  0x1106, 0x3059, 0x1695, 0x3005, NULL,         NULL,          "EPoX",        "EP-8K5A2",           w836xx_memw_enable_2e},
-	{0x10EC, 0x8139, 0x1695, 0x9001,  0x11C1, 0x5811, 0x1695, 0x9015, NULL,         NULL,          "EPoX",        "EP-8RDA3+",          nvidia_mcp_gpio31_raise},
-	{0x8086, 0x7110,      0,      0,  0x8086, 0x7190,      0,      0, "epox",       "ep-bx3",      "EPoX",        "EP-BX3",             board_epox_ep_bx3},
-	{0x1039, 0x0761,      0,      0,  0x10EC, 0x8168,      0,      0, "gigabyte",   "2761gxdk",    "GIGABYTE",    "GA-2761GXDK",        it87xx_probe_spi_flash},
-	{0x1106, 0x3227, 0x1458, 0x5001,  0x10ec, 0x8139, 0x1458, 0xe000, NULL,         NULL,          "GIGABYTE",    "GA-7VT600",          it8705_rom_write_enable},
-	{0x10DE, 0x0050, 0x1458, 0x0C11,  0x10DE, 0x005e, 0x1458, 0x5000, NULL,         NULL,          "GIGABYTE",    "GA-K8N-SLI",         nvidia_mcp_gpio21_raise},
-	{0x10DE, 0x0360, 0x1458, 0x0C11,  0x10DE, 0x0369, 0x1458, 0x5001, "gigabyte",   "m57sli",      "GIGABYTE",    "GA-M57SLI-S4",       it87xx_probe_spi_flash},
-	{0x10de, 0x03e0,      0,      0,  0x10DE, 0x03D0,      0,      0, NULL,         NULL,          "GIGABYTE",    "GA-M61P-S3",         it87xx_probe_spi_flash},
-	{0x1002, 0x4398, 0x1458, 0x5004,  0x1002, 0x4391, 0x1458, 0xb000, NULL,         NULL,          "GIGABYTE",    "GA-MA78G-DS3H",      it87xx_probe_spi_flash},
-	{0x1002, 0x4398, 0x1458, 0x5004,  0x1002, 0x4391, 0x1458, 0xb002, NULL,         NULL,          "GIGABYTE",    "GA-MA78GM-S2H",      it87xx_probe_spi_flash},
-	{0x1002, 0x438d, 0x1458, 0x5001,  0x1002, 0x5956, 0x1002, 0x5956, NULL,         NULL,          "GIGABYTE",    "GA-MA790FX-DQ6",     it87xx_probe_spi_flash},
-	{0x1166, 0x0223, 0x103c, 0x320d,  0x102b, 0x0522, 0x103c, 0x31fa, "hp",         "dl145_g3",    "HP",          "DL145 G3",           board_hp_dl145_g3_enable},
-	{0x1166, 0x0205, 0x1014, 0x0347,  0x1002, 0x515E, 0x1014, 0x0325, NULL,         NULL,          "IBM",         "x3455",              board_ibm_x3455},
-	{0x1039, 0x5513, 0x8086, 0xd61f,  0x1039, 0x6330, 0x8086, 0xd61f, NULL,         NULL,          "Intel",       "D201GLY",            wbsio_check_for_spi},
-	{0x1022, 0x7468,      0,      0,       0,      0,      0,      0, "iwill",      "dk8_htx",     "IWILL",       "DK8-HTX",            w83627hf_gpio24_raise_2e},
-	{0x8086, 0x27A0,      0,      0,  0x8086, 0x27b8,      0,      0, "kontron",    "986lcd-m",    "Kontron",     "986LCD-M",           board_kontron_986lcd_m},
-	{0x8086, 0x2411, 0x8086, 0x2411,  0x8086, 0x7125, 0x0e11, 0xb165, NULL,         NULL,          "Mitac",       "6513WU",             board_mitac_6513wu},
-	{0x13f6, 0x0111, 0x1462, 0x5900,  0x1106, 0x3177, 0x1106,      0, NULL,         NULL,          "MSI",         "MS-6590 (KT4 Ultra)",board_msi_kt4v},
-	{0x1106, 0x3149, 0x1462, 0x7094,  0x10ec, 0x8167, 0x1462, 0x094c, NULL,         NULL,          "MSI",         "MS-6702E (K8T Neo2-F)",w83627thf_gpio4_4_raise_2e},
-	{0x1106, 0x0571, 0x1462, 0x7120,  0x1106, 0x3065, 0x1462, 0x7120, NULL,         NULL,          "MSI",         "MS-6712 (KT4V)",     board_msi_kt4v},
-	{0x8086, 0x2658, 0x1462, 0x7046,  0x1106, 0x3044, 0x1462, 0x046d, NULL,         NULL,          "MSI",         "MS-7046",            intel_ich_gpio19_raise},
-	{0x10DE, 0x005E, 0x1462, 0x7135,  0x10DE, 0x0050, 0x1462, 0x7135, "msi",        "k8n-neo3",    "MSI",         "MS-7135 (K8N Neo3)", w83627thf_gpio4_4_raise_4e},
-	{0x10DE, 0x005E, 0x1462, 0x7125,  0x10DE, 0x0052, 0x1462, 0x7125, NULL,         NULL,          "MSI",         "K8N Neo4-F",         nvidia_mcp_gpio2_raise},
-	{0x1106, 0x3099,      0,      0,  0x1106, 0x3074,      0,      0, "shuttle",    "ak31",        "Shuttle",     "AK31",               w836xx_memw_enable_2e},
-	{0x1106, 0x3104, 0x1297, 0xa238,  0x1106, 0x3059, 0x1297, 0xc063, NULL,         NULL,          "Shuttle",     "AK38N",              shuttle_ak38n},
-	{0x10DE, 0x0050, 0x1297, 0x5036,  0x1412, 0x1724, 0x1297, 0x5036, NULL,         NULL,          "Shuttle",     "FN25",               board_shuttle_fn25},
-	{0x1106, 0x3038, 0x0925, 0x1234,  0x1106, 0x3058, 0x15DD, 0x7609, NULL,         NULL,          "Soyo",        "SY-7VCA",            board_soyo_sy_7vca},
-	{0x8086, 0x1076, 0x8086, 0x1176,  0x1106, 0x3059, 0x10f1, 0x2498, NULL,         NULL,          "Tyan",        "S2498 (Tomcat K7M)", w836xx_memw_enable_2e},
-	{0x1106, 0x3177, 0x1106, 0xAA01,  0x1106, 0x3123, 0x1106, 0xAA01, NULL,         NULL,          "VIA",         "EPIA M/MII/...",     via_vt823x_gpio15_raise},
-	{0x1106, 0x0259, 0x1106, 0x3227,  0x1106, 0x3065, 0x1106, 0x3149, NULL,         NULL,          "VIA",         "EPIA-N/NL",          via_vt823x_gpio9_raise},
-	{0x1106, 0x5337, 0x1458, 0xb003,  0x1106, 0x287e, 0x1106, 0x337e, NULL,         NULL,          "VIA",         "PC3500G",            it87xx_probe_spi_flash},
+	/* first pci-id set [4],          second pci-id set [4],          dmi_identifier, coreboot id [2],             vendor name    board name            flash enable */
+	{0x8086, 0x2926, 0x147b, 0x1084,  0x11ab, 0x4364, 0x147b, 0x1084, NULL,           NULL,         NULL,          "Abit",        "IP35",               intel_ich_gpio16_raise},
+	{0x105a, 0x0d30, 0x105a, 0x4d33,  0x8086, 0x1130, 0x8086,      0, NULL,           NULL,         NULL,          "Acorp",       "6A815EPD",           board_acorp_6a815epd},
+	{0x8086, 0x24D4, 0x1849, 0x24D0,  0x8086, 0x24D5, 0x1849, 0x9739, NULL,           NULL,         NULL,          "ASRock",      "P4i65GV",            intel_ich_gpio23_raise},
+	{0x1022, 0x746B,      0,      0,       0,      0,      0,      0, NULL,           "AGAMI",      "ARUMA",       "agami",       "Aruma",              w83627hf_gpio24_raise_2e},
+	{0x1106, 0x3177, 0x17F2, 0x3177,  0x1106, 0x3148, 0x17F2, 0x3148, NULL,           NULL,         NULL,          "Albatron",    "PM266A",             w836xx_memw_enable_2e},
+	{0x1106, 0x3205, 0x1106, 0x3205,  0x10EC, 0x8139, 0xA0A0, 0x0477, NULL,           NULL,         NULL,          "AOpen",       "vKM400Am-S",         it8705_rom_write_enable},
+	{0x1022, 0x2090,      0,      0,  0x1022, 0x2080,      0,      0, NULL,           "artecgroup", "dbe61",       "Artec Group", "DBE61",              board_artecgroup_dbe6x},
+	{0x1022, 0x2090,      0,      0,  0x1022, 0x2080,      0,      0, NULL,           "artecgroup", "dbe62",       "Artec Group", "DBE62",              board_artecgroup_dbe6x},
+	{0x1106, 0x3189, 0x1043, 0x807F,  0x1106, 0x3065, 0x1043, 0x80ED, NULL,           NULL,         NULL,          "ASUS",        "A7V600-X",           board_asus_a7v600x},
+	{0x1106, 0x3189, 0x1043, 0x807F,  0x1106, 0x3177, 0x1043, 0x808C, NULL,           NULL,         NULL,          "ASUS",        "A7V8X",              board_asus_a7v8x},
+	{0x1106, 0x3177, 0x1043, 0x80A1,  0x1106, 0x3205, 0x1043, 0x8118, NULL,           NULL,         NULL,          "ASUS",        "A7V8X-MX SE",        w836xx_memw_enable_2e},
+	{0x1106, 0x1336, 0x1043, 0x80ed,  0x1106, 0x3288, 0x1043, 0x8249, NULL,           NULL,         NULL,          "ASUS",        "M2V-MX",             via_vt823x_gpio5_raise},
+	{0x8086, 0x1a30, 0x1043, 0x8070,  0x8086, 0x244b, 0x1043, 0x8028, NULL,           NULL,         NULL,          "ASUS",        "P4B266",             intel_ich_gpio22_raise},
+	{0x8086, 0x1A30, 0x1043, 0x8025,  0x8086, 0x244B, 0x104D, 0x80F0, NULL,           NULL,         NULL,          "ASUS",        "P4B266-LM",          intel_ich_gpio21_raise},
+	{0x8086, 0x2570, 0x1043, 0x80F2,  0x105A, 0x3373, 0x1043, 0x80F5, NULL,           NULL,         NULL,          "ASUS",        "P4P800-E Deluxe",    intel_ich_gpio21_raise},
+	{0x10B9, 0x1541,      0,      0,  0x10B9, 0x1533,      0,      0, "mp:^P5A$",     "asus",       "p5a",         "ASUS",        "P5A",                board_asus_p5a},
+	{0x10DE, 0x0030, 0x1043, 0x818a,  0x8086, 0x100E, 0x1043, 0x80EE, NULL,           NULL,         NULL,          "ASUS",        "P5ND2-SLI Deluxe",   nvidia_mcp_gpio10_raise},
+	{0x1106, 0x3149, 0x1565, 0x3206,  0x1106, 0x3344, 0x1565, 0x1202, NULL,           NULL,         NULL,          "Biostar",     "P4M80-M4",           it8705_rom_write_enable},
+	{0x8086, 0x3590, 0x1028, 0x016c,  0x1000, 0x0030, 0x1028, 0x016c, NULL,           NULL,         NULL,          "Dell",        "PowerEdge 1850",     intel_ich_gpio23_raise},
+	{0x1039, 0x5513, 0x1019, 0x0A41,  0x1039, 0x0018,      0,      0, NULL,           NULL,         NULL,          "Elitegroup",  "K7S6A",              elitegroup_k7vta3},
+	{0x1106, 0x3038, 0x1019, 0x0996,  0x1106, 0x3177, 0x1019, 0x0996, NULL,           NULL,         NULL,          "Elitegroup",  "K7VTA3",             elitegroup_k7vta3},
+	{0x1106, 0x3177, 0x1106, 0x3177,  0x1106, 0x3059, 0x1695, 0x3005, NULL,           NULL,         NULL,          "EPoX",        "EP-8K5A2",           w836xx_memw_enable_2e},
+	{0x10EC, 0x8139, 0x1695, 0x9001,  0x11C1, 0x5811, 0x1695, 0x9015, NULL,           NULL,         NULL,          "EPoX",        "EP-8RDA3+",          nvidia_mcp_gpio31_raise},
+	{0x8086, 0x7110,      0,      0,  0x8086, 0x7190,      0,      0, NULL,           "epox",       "ep-bx3",      "EPoX",        "EP-BX3",             board_epox_ep_bx3},
+	{0x1039, 0x0761,      0,      0,  0x10EC, 0x8168,      0,      0, NULL,           "gigabyte",   "2761gxdk",    "GIGABYTE",    "GA-2761GXDK",        it87xx_probe_spi_flash},
+	{0x1106, 0x3227, 0x1458, 0x5001,  0x10ec, 0x8139, 0x1458, 0xe000, NULL,           NULL,         NULL,          "GIGABYTE",    "GA-7VT600",          it8705_rom_write_enable},
+	{0x10DE, 0x0050, 0x1458, 0x0C11,  0x10DE, 0x005e, 0x1458, 0x5000, NULL,           NULL,         NULL,          "GIGABYTE",    "GA-K8N-SLI",         nvidia_mcp_gpio21_raise},
+	{0x10DE, 0x0360, 0x1458, 0x0C11,  0x10DE, 0x0369, 0x1458, 0x5001, NULL,           "gigabyte",   "m57sli",      "GIGABYTE",    "GA-M57SLI-S4",       it87xx_probe_spi_flash},
+	{0x10de, 0x03e0,      0,      0,  0x10DE, 0x03D0,      0,      0, NULL,           NULL,         NULL,          "GIGABYTE",    "GA-M61P-S3",         it87xx_probe_spi_flash},
+	{0x1002, 0x4398, 0x1458, 0x5004,  0x1002, 0x4391, 0x1458, 0xb000, NULL,           NULL,         NULL,          "GIGABYTE",    "GA-MA78G-DS3H",      it87xx_probe_spi_flash},
+	{0x1002, 0x4398, 0x1458, 0x5004,  0x1002, 0x4391, 0x1458, 0xb002, NULL,           NULL,         NULL,          "GIGABYTE",    "GA-MA78GM-S2H",      it87xx_probe_spi_flash},
+	{0x1002, 0x438d, 0x1458, 0x5001,  0x1002, 0x5956, 0x1002, 0x5956, NULL,           NULL,         NULL,          "GIGABYTE",    "GA-MA790FX-DQ6",     it87xx_probe_spi_flash},
+	{0x1166, 0x0223, 0x103c, 0x320d,  0x102b, 0x0522, 0x103c, 0x31fa, NULL,           "hp",         "dl145_g3",    "HP",          "DL145 G3",           board_hp_dl145_g3_enable},
+	{0x1166, 0x0205, 0x1014, 0x0347,  0x1002, 0x515E, 0x1014, 0x0325, NULL,           NULL,         NULL,          "IBM",         "x3455",              board_ibm_x3455},
+	{0x1039, 0x5513, 0x8086, 0xd61f,  0x1039, 0x6330, 0x8086, 0xd61f, NULL,           NULL,         NULL,          "Intel",       "D201GLY",            wbsio_check_for_spi},
+	{0x1022, 0x7468,      0,      0,       0,      0,      0,      0, NULL,           "iwill",      "dk8_htx",     "IWILL",       "DK8-HTX",            w83627hf_gpio24_raise_2e},
+	{0x8086, 0x27A0,      0,      0,  0x8086, 0x27b8,      0,      0, NULL,           "kontron",    "986lcd-m",    "Kontron",     "986LCD-M",           board_kontron_986lcd_m},
+	{0x8086, 0x2411, 0x8086, 0x2411,  0x8086, 0x7125, 0x0e11, 0xb165, NULL,           NULL,         NULL,          "Mitac",       "6513WU",             board_mitac_6513wu},
+	{0x13f6, 0x0111, 0x1462, 0x5900,  0x1106, 0x3177, 0x1106,      0, NULL,           NULL,         NULL,          "MSI",         "MS-6590 (KT4 Ultra)",board_msi_kt4v},
+	{0x1106, 0x3149, 0x1462, 0x7094,  0x10ec, 0x8167, 0x1462, 0x094c, NULL,           NULL,         NULL,          "MSI",         "MS-6702E (K8T Neo2-F)",w83627thf_gpio4_4_raise_2e},
+	{0x1106, 0x0571, 0x1462, 0x7120,  0x1106, 0x3065, 0x1462, 0x7120, NULL,           NULL,         NULL,          "MSI",         "MS-6712 (KT4V)",     board_msi_kt4v},
+	{0x8086, 0x2658, 0x1462, 0x7046,  0x1106, 0x3044, 0x1462, 0x046d, NULL,           NULL,         NULL,          "MSI",         "MS-7046",            intel_ich_gpio19_raise},
+	{0x10DE, 0x005E, 0x1462, 0x7135,  0x10DE, 0x0050, 0x1462, 0x7135, NULL,           "msi",        "k8n-neo3",    "MSI",         "MS-7135 (K8N Neo3)", w83627thf_gpio4_4_raise_4e},
+	{0x10DE, 0x005E, 0x1462, 0x7125,  0x10DE, 0x0052, 0x1462, 0x7125, NULL,           NULL,         NULL,          "MSI",         "K8N Neo4-F",         nvidia_mcp_gpio2_raise},
+	{0x1106, 0x3099,      0,      0,  0x1106, 0x3074,      0,      0, NULL,           "shuttle",    "ak31",        "Shuttle",     "AK31",               w836xx_memw_enable_2e},
+	{0x1106, 0x3104, 0x1297, 0xa238,  0x1106, 0x3059, 0x1297, 0xc063, NULL,           NULL,         NULL,          "Shuttle",     "AK38N",              shuttle_ak38n},
+	{0x10DE, 0x0050, 0x1297, 0x5036,  0x1412, 0x1724, 0x1297, 0x5036, NULL,           NULL,         NULL,          "Shuttle",     "FN25",               board_shuttle_fn25},
+	{0x1106, 0x3038, 0x0925, 0x1234,  0x1106, 0x3058, 0x15DD, 0x7609, NULL,           NULL,         NULL,          "Soyo",        "SY-7VCA",            board_soyo_sy_7vca},
+	{0x8086, 0x1076, 0x8086, 0x1176,  0x1106, 0x3059, 0x10f1, 0x2498, NULL,           NULL,         NULL,          "Tyan",        "S2498 (Tomcat K7M)", w836xx_memw_enable_2e},
+	{0x1106, 0x3177, 0x1106, 0xAA01,  0x1106, 0x3123, 0x1106, 0xAA01, NULL,           NULL,         NULL,          "VIA",         "EPIA M/MII/...",     via_vt823x_gpio15_raise},
+	{0x1106, 0x0259, 0x1106, 0x3227,  0x1106, 0x3065, 0x1106, 0x3149, NULL,           NULL,         NULL,          "VIA",         "EPIA-N/NL",          via_vt823x_gpio9_raise},
+	{0x1106, 0x5337, 0x1458, 0xb003,  0x1106, 0x287e, 0x1106, 0x337e, NULL,           NULL,         NULL,          "VIA",         "PC3500G",            it87xx_probe_spi_flash},
 
-	{     0,      0,      0,      0,       0,      0,      0,      0, NULL,         NULL,          NULL,          NULL,                 NULL}, /* end marker */
+	{     0,      0,      0,      0,       0,      0,      0,      0, NULL,           NULL,         NULL,          NULL,          NULL,                 NULL}, /* end marker */
 };
 
 /**
@@ -1314,6 +1326,18 @@
 			}
 		}
 
+		if (board->dmi_pattern) {
+			if (!has_dmi_support) {
+				fprintf(stderr, "WARNING: Can't autodetect %s %s,"
+				       " DMI info unavailable.\n",
+				       board->vendor_name, board->board_name);
+				continue;
+			} else {
+				if (!dmi_match(board->dmi_pattern))
+					continue;
+			}
+		}
+
 		return board;
 	}
 





More information about the flashrom mailing list