dmi: add support for exact DMI matches in addition to substring matching
authorJani Nikula <jani.nikula@intel.com>
Wed, 3 Jul 2013 22:05:02 +0000 (15:05 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 29 Nov 2013 19:11:53 +0000 (11:11 -0800)
commit 5017b2851373ee15c7035151853bb1448800cae2 upstream.

dmi_match() considers a substring match to be a successful match.  This is
not always sufficient to distinguish between DMI data for different
systems.  Add support for exact string matching using strcmp() in addition
to the substring matching using strstr().

The specific use case in the i915 driver is to allow us to use an exact
match for D510MO, without also incorrectly matching D510MOV:

  {
.ident = "Intel D510MO",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Intel"),
DMI_EXACT_MATCH(DMI_BOARD_NAME, "D510MO"),
},
  }

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Cc: <annndddrr@gmail.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Cornel Panceac <cpanceac@gmail.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/firmware/dmi_scan.c
include/linux/mod_devicetable.h

index b95159b33c398bc3d6adb03b303eed0bde328c9a..eb760a218da4292f7c208ddc145deffb833df7ab 100644 (file)
@@ -551,9 +551,15 @@ static bool dmi_matches(const struct dmi_system_id *dmi)
                int s = dmi->matches[i].slot;
                if (s == DMI_NONE)
                        break;
-               if (dmi_ident[s]
-                   && strstr(dmi_ident[s], dmi->matches[i].substr))
-                       continue;
+               if (dmi_ident[s]) {
+                       if (!dmi->matches[i].exact_match &&
+                           strstr(dmi_ident[s], dmi->matches[i].substr))
+                               continue;
+                       else if (dmi->matches[i].exact_match &&
+                                !strcmp(dmi_ident[s], dmi->matches[i].substr))
+                               continue;
+               }
+
                /* No match */
                return false;
        }
index b508016fb76d3b912101695059044318d56150f4..b3bd7e737e8b847ebb356d1674047f3de33f3602 100644 (file)
@@ -456,7 +456,8 @@ enum dmi_field {
 };
 
 struct dmi_strmatch {
-       unsigned char slot;
+       unsigned char slot:7;
+       unsigned char exact_match:1;
        char substr[79];
 };
 
@@ -474,7 +475,8 @@ struct dmi_system_id {
  */
 #define dmi_device_id dmi_system_id
 
-#define DMI_MATCH(a, b)        { a, b }
+#define DMI_MATCH(a, b)        { .slot = a, .substr = b }
+#define DMI_EXACT_MATCH(a, b)  { .slot = a, .substr = b, .exact_match = 1 }
 
 #define PLATFORM_NAME_SIZE     20
 #define PLATFORM_MODULE_PREFIX "platform:"