Needed for the ALPS firmware detection

Signed-off-by: Peter Hutterer <[email protected]>
---
 src/quirks.c       | 22 +++++++++++++++++--
 test/test-quirks.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/src/quirks.c b/src/quirks.c
index 2fca275a..296b2730 100644
--- a/src/quirks.c
+++ b/src/quirks.c
@@ -85,8 +85,9 @@ enum match_flags {
        M_DMI           = (1 << 4),
        M_UDEV_TYPE     = (1 << 5),
        M_DT            = (1 << 6),
+       M_VERSION       = (1 << 7),
 
-       M_LAST          = M_DT,
+       M_LAST          = M_VERSION,
 };
 
 enum bustype {
@@ -121,6 +122,7 @@ struct match {
        enum bustype bus;
        uint32_t vendor;
        uint32_t product;
+       uint32_t version;
 
        char *dmi;      /* dmi modalias with preceding "dmi:" */
 
@@ -275,6 +277,7 @@ matchflagname(enum match_flags f)
        case M_BUS:             return "MatchBus";              break;
        case M_VID:             return "MatchVendor";           break;
        case M_PID:             return "MatchProduct";          break;
+       case M_VERSION:         return "MatchVersion";          break;
        case M_DMI:             return "MatchDMIModalias";      break;
        case M_UDEV_TYPE:       return "MatchUdevType";         break;
        case M_DT:              return "MatchDeviceTree";       break;
@@ -489,6 +492,16 @@ parse_match(struct quirks_context *ctx,
                        goto out;
 
                s->match.product = product;
+       } else if (streq(key, "MatchVersion")) {
+               unsigned int version;
+
+               check_set_bit(s, M_VERSION);
+               if (!strneq(value, "0x", 2) ||
+                   !safe_atou_base(value, &version, 16) ||
+                   version > 0xFFFF)
+                       goto out;
+
+               s->match.version = version;
        } else if (streq(key, "MatchDMIModalias")) {
                check_set_bit(s, M_DMI);
                if (!strneq(value, "dmi:", 4)) {
@@ -1147,7 +1160,8 @@ match_fill_bus_vid_pid(struct match *m,
 
        m->product = product;
        m->vendor = vendor;
-       m->bits |= M_PID|M_VID;
+       m->version = version;
+       m->bits |= M_PID|M_VID|M_VERSION;
        switch (bus) {
        case BUS_USB:
                m->bus = BT_USB;
@@ -1295,6 +1309,10 @@ quirk_match_section(struct quirks_context *ctx,
                        if (m->product == s->match.product)
                                matched_flags |= flag;
                        break;
+               case M_VERSION:
+                       if (m->version == s->match.version)
+                               matched_flags |= flag;
+                       break;
                case M_DMI:
                        if (fnmatch(s->match.dmi, m->dmi, 0) == 0)
                                matched_flags |= flag;
diff --git a/test/test-quirks.c b/test/test-quirks.c
index 16bbacf0..be488a7e 100644
--- a/test/test-quirks.c
+++ b/test/test-quirks.c
@@ -578,6 +578,67 @@ START_TEST(quirks_parse_product_invalid)
 }
 END_TEST
 
+START_TEST(quirks_parse_version)
+{
+       struct quirks_context *ctx;
+       const char quirks_file[] =
+       "[Section name]\n"
+       "MatchVersion=0x0000\n"
+       "ModelAppleTouchpad=1\n"
+       "\n"
+       "[Section name]\n"
+       "MatchVersion=0x0001\n"
+       "ModelAppleTouchpad=1\n"
+       "\n"
+       "[Section name]\n"
+       "MatchVersion=0x2343\n"
+       "ModelAppleTouchpad=1\n";
+       struct data_dir dd = make_data_dir(quirks_file);
+
+       ctx = quirks_init_subsystem(dd.dirname,
+                                   NULL,
+                                   log_handler,
+                                   NULL,
+                                   QLOG_CUSTOM_LOG_PRIORITIES);
+       ck_assert_notnull(ctx);
+       quirks_context_unref(ctx);
+       cleanup_data_dir(dd);
+}
+END_TEST
+
+START_TEST(quirks_parse_version_invalid)
+{
+       struct quirks_context *ctx;
+       const char *quirks_file[] = {
+       "[Section name]\n"
+       "MatchVersion=-1\n"
+       "ModelAppleTouchpad=1\n",
+       "[Section name]\n"
+       "MatchVersion=abc\n"
+       "ModelAppleTouchpad=1\n",
+       "[Section name]\n"
+       "MatchVersion=0xFFFFF\n"
+       "ModelAppleTouchpad=1\n",
+       "[Section name]\n"
+       "MatchVersion=123\n"
+       "ModelAppleTouchpad=1\n",
+       };
+       const char **qf;
+
+       ARRAY_FOR_EACH(quirks_file, qf) {
+               struct data_dir dd = make_data_dir(*qf);
+
+               ctx = quirks_init_subsystem(dd.dirname,
+                                           NULL,
+                                           log_handler,
+                                           NULL,
+                                           QLOG_CUSTOM_LOG_PRIORITIES);
+               ck_assert(ctx == NULL);
+               cleanup_data_dir(dd);
+       }
+}
+END_TEST
+
 START_TEST(quirks_parse_name)
 {
        struct quirks_context *ctx;
@@ -939,6 +1000,8 @@ TEST_COLLECTION(quirks)
        litest_add_for_device("quirks:parsing", quirks_parse_vendor_invalid, 
LITEST_MOUSE);
        litest_add_for_device("quirks:parsing", quirks_parse_product, 
LITEST_MOUSE);
        litest_add_for_device("quirks:parsing", quirks_parse_product_invalid, 
LITEST_MOUSE);
+       litest_add_for_device("quirks:parsing", quirks_parse_version, 
LITEST_MOUSE);
+       litest_add_for_device("quirks:parsing", quirks_parse_version_invalid, 
LITEST_MOUSE);
        litest_add_for_device("quirks:parsing", quirks_parse_name, 
LITEST_MOUSE);
        litest_add_for_device("quirks:parsing", quirks_parse_name_invalid, 
LITEST_MOUSE);
        litest_add_for_device("quirks:parsing", quirks_parse_udev, 
LITEST_MOUSE);
-- 
2.14.4

_______________________________________________
wayland-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to