quirks: add MatchVersion in addition to VID/PID

Needed for the ALPS firmware detection in #39

https://gitlab.freedesktop.org/libinput/libinput/issues/39

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2018-06-14 11:42:27 +10:00
parent cb7c9e596f
commit a57d35a1aa
2 changed files with 83 additions and 2 deletions

View file

@ -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;

View file

@ -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);