• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2018 Red Hat, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include "config.h"
25 
26 /* This has the hallmarks of a library to make it re-usable from the tests
27  * and from the list-quirks tool. It doesn't have all of the features from a
28  * library you'd expect though
29  */
30 
31 #undef NDEBUG /* You don't get to disable asserts here */
32 #include <assert.h>
33 #include <stdlib.h>
34 #include <libudev.h>
35 #include <dirent.h>
36 #include <fnmatch.h>
37 #include <libgen.h>
38 #ifdef __FreeBSD__
39 #include <kenv.h>
40 #endif
41 
42 #include "libinput-versionsort.h"
43 #include "libinput-util.h"
44 
45 #include "quirks.h"
46 
47 /* Custom logging so we can have detailed output for the tool but minimal
48  * logging for libinput itself. */
49 #define qlog_debug(ctx_, ...) quirk_log_msg((ctx_), QLOG_NOISE, __VA_ARGS__)
50 #define qlog_info(ctx_, ...) quirk_log_msg((ctx_),  QLOG_INFO, __VA_ARGS__)
51 #define qlog_error(ctx_, ...) quirk_log_msg((ctx_), QLOG_ERROR, __VA_ARGS__)
52 #define qlog_parser(ctx_, ...) quirk_log_msg((ctx_), QLOG_PARSER_ERROR, __VA_ARGS__)
53 
54 enum property_type {
55 	PT_UINT,
56 	PT_INT,
57 	PT_STRING,
58 	PT_BOOL,
59 	PT_DIMENSION,
60 	PT_RANGE,
61 	PT_DOUBLE,
62 	PT_TUPLES,
63 	PT_UINT_ARRAY,
64 };
65 
66 struct quirk_array {
67 	union {
68 		uint32_t u[32];
69 	} data;
70 	size_t nelements;
71 };
72 
73 /**
74  * Generic value holder for the property types we support. The type
75  * identifies which value in the union is defined and we expect callers to
76  * already know which type yields which value.
77  */
78 struct property {
79 	size_t refcount;
80 	struct list link; /* struct sections.properties */
81 
82 	enum quirk id;
83 	enum property_type type;
84 	union {
85 		bool b;
86 		uint32_t u;
87 		int32_t i;
88 		char *s;
89 		double d;
90 		struct quirk_dimensions dim;
91 		struct quirk_range range;
92 		struct quirk_tuples tuples;
93 		struct quirk_array array;
94 	} value;
95 };
96 
97 enum match_flags {
98 	M_NAME		= bit(0),
99 	M_BUS		= bit(1),
100 	M_VID		= bit(2),
101 	M_PID		= bit(3),
102 	M_DMI		= bit(4),
103 	M_UDEV_TYPE	= bit(5),
104 	M_DT		= bit(6),
105 	M_VERSION	= bit(7),
106 
107 	M_LAST		= M_VERSION,
108 };
109 
110 enum bustype {
111 	BT_UNKNOWN,
112 	BT_USB,
113 	BT_BLUETOOTH,
114 	BT_PS2,
115 	BT_RMI,
116 	BT_I2C,
117 	BT_SPI,
118 };
119 
120 enum udev_type {
121 	UDEV_MOUSE		= bit(1),
122 	UDEV_POINTINGSTICK	= bit(2),
123 	UDEV_TOUCHPAD		= bit(3),
124 	UDEV_TABLET		= bit(4),
125 	UDEV_TABLET_PAD		= bit(5),
126 	UDEV_JOYSTICK		= bit(6),
127 	UDEV_KEYBOARD		= bit(7),
128 };
129 
130 /**
131  * Contains the combined set of matches for one section or the values for
132  * one device.
133  *
134  * bits defines which fields are set, the rest is zero.
135  */
136 struct match {
137 	uint32_t bits;
138 
139 	char *name;
140 	enum bustype bus;
141 	uint32_t vendor;
142 	uint32_t product;
143 	uint32_t version;
144 
145 	char *dmi;	/* dmi modalias with preceding "dmi:" */
146 
147 	/* We can have more than one type set, so this is a bitfield */
148 	uint32_t udev_type;
149 
150 	char *dt;	/* device tree compatible (first) string */
151 };
152 
153 /**
154  * Represents one section in the .quirks file.
155  */
156 struct section {
157 	struct list link;
158 
159 	bool has_match;		/* to check for empty sections */
160 	bool has_property;	/* to check for empty sections */
161 
162 	char *name;		/* the [Section Name] */
163 	struct match match;
164 	struct list properties;
165 };
166 
167 /**
168  * The struct returned to the caller. It contains the
169  * properties for a given device.
170  */
171 struct quirks {
172 	size_t refcount;
173 	struct list link; /* struct quirks_context.quirks */
174 
175 	/* These are not ref'd, just a collection of pointers */
176 	struct property **properties;
177 	size_t nproperties;
178 };
179 
180 /**
181  * Quirk matching context, initialized once with quirks_init_subsystem()
182  */
183 struct quirks_context {
184 	size_t refcount;
185 
186 	libinput_log_handler log_handler;
187 	enum quirks_log_type log_type;
188 	struct libinput *libinput; /* for logging */
189 
190 	char *dmi;
191 	char *dt;
192 
193 	struct list sections;
194 
195 	/* list of quirks handed to libinput, just for bookkeeping */
196 	struct list quirks;
197 };
198 
199 LIBINPUT_ATTRIBUTE_PRINTF(3, 0)
200 static inline void
quirk_log_msg_va(struct quirks_context * ctx,enum quirks_log_priorities priority,const char * format,va_list args)201 quirk_log_msg_va(struct quirks_context *ctx,
202 		 enum quirks_log_priorities priority,
203 		 const char *format,
204 		 va_list args)
205 {
206 	switch (priority) {
207 	/* We don't use this if we're logging through libinput */
208 	default:
209 	case QLOG_NOISE:
210 	case QLOG_PARSER_ERROR:
211 		if (ctx->log_type == QLOG_LIBINPUT_LOGGING)
212 			return;
213 		break;
214 	case QLOG_DEBUG: /* These map straight to libinput priorities */
215 	case QLOG_INFO:
216 	case QLOG_ERROR:
217 		break;
218 	}
219 
220 	ctx->log_handler(ctx->libinput,
221 			 (enum libinput_log_priority)priority,
222 			 format,
223 			 args);
224 }
225 
226 LIBINPUT_ATTRIBUTE_PRINTF(3, 4)
227 static inline void
quirk_log_msg(struct quirks_context * ctx,enum quirks_log_priorities priority,const char * format,...)228 quirk_log_msg(struct quirks_context *ctx,
229 	      enum quirks_log_priorities priority,
230 	      const char *format,
231 	      ...)
232 {
233 	va_list args;
234 
235 	va_start(args, format);
236 	quirk_log_msg_va(ctx, priority, format, args);
237 	va_end(args);
238 
239 }
240 
241 const char *
quirk_get_name(enum quirk q)242 quirk_get_name(enum quirk q)
243 {
244 	switch(q) {
245 	case QUIRK_MODEL_ALPS_SERIAL_TOUCHPAD:		return "ModelALPSSerialTouchpad";
246 	case QUIRK_MODEL_APPLE_TOUCHPAD:		return "ModelAppleTouchpad";
247 	case QUIRK_MODEL_APPLE_TOUCHPAD_ONEBUTTON:	return "ModelAppleTouchpadOneButton";
248 	case QUIRK_MODEL_BOUNCING_KEYS:			return "ModelBouncingKeys";
249 	case QUIRK_MODEL_CHROMEBOOK:			return "ModelChromebook";
250 	case QUIRK_MODEL_CLEVO_W740SU:			return "ModelClevoW740SU";
251 	case QUIRK_MODEL_HP_PAVILION_DM4_TOUCHPAD:	return "ModelHPPavilionDM4Touchpad";
252 	case QUIRK_MODEL_HP_STREAM11_TOUCHPAD:		return "ModelHPStream11Touchpad";
253 	case QUIRK_MODEL_HP_ZBOOK_STUDIO_G3:		return "ModelHPZBookStudioG3";
254 	case QUIRK_MODEL_INVERT_HORIZONTAL_SCROLLING:	return "ModelInvertHorizontalScrolling";
255 	case QUIRK_MODEL_LENOVO_SCROLLPOINT:		return "ModelLenovoScrollPoint";
256 	case QUIRK_MODEL_LENOVO_T450_TOUCHPAD:		return "ModelLenovoT450Touchpad";
257 	case QUIRK_MODEL_LENOVO_TRACKPOINT_KEYBOARD_2:  return "ModelLenovoTrackpointKeyboard2";
258 	case QUIRK_MODEL_LENOVO_X1GEN6_TOUCHPAD:	return "ModelLenovoX1Gen6Touchpad";
259 	case QUIRK_MODEL_LENOVO_X230:			return "ModelLenovoX230";
260 	case QUIRK_MODEL_SYNAPTICS_SERIAL_TOUCHPAD:	return "ModelSynapticsSerialTouchpad";
261 	case QUIRK_MODEL_SYSTEM76_BONOBO:		return "ModelSystem76Bonobo";
262 	case QUIRK_MODEL_SYSTEM76_GALAGO:		return "ModelSystem76Galago";
263 	case QUIRK_MODEL_SYSTEM76_KUDU:			return "ModelSystem76Kudu";
264 	case QUIRK_MODEL_TABLET_MODE_NO_SUSPEND:	return "ModelTabletModeNoSuspend";
265 	case QUIRK_MODEL_TABLET_MODE_SWITCH_UNRELIABLE:	return "ModelTabletModeSwitchUnreliable";
266 	case QUIRK_MODEL_TOUCHPAD_VISIBLE_MARKER:	return "ModelTouchpadVisibleMarker";
267 	case QUIRK_MODEL_TRACKBALL:			return "ModelTrackball";
268 	case QUIRK_MODEL_WACOM_TOUCHPAD:		return "ModelWacomTouchpad";
269 	case QUIRK_MODEL_DELL_CANVAS_TOTEM:		return "ModelDellCanvasTotem";
270 
271 	case QUIRK_ATTR_SIZE_HINT:			return "AttrSizeHint";
272 	case QUIRK_ATTR_TOUCH_SIZE_RANGE:		return "AttrTouchSizeRange";
273 	case QUIRK_ATTR_PALM_SIZE_THRESHOLD:		return "AttrPalmSizeThreshold";
274 	case QUIRK_ATTR_LID_SWITCH_RELIABILITY:		return "AttrLidSwitchReliability";
275 	case QUIRK_ATTR_KEYBOARD_INTEGRATION:		return "AttrKeyboardIntegration";
276 	case QUIRK_ATTR_TRACKPOINT_INTEGRATION:		return "AttrPointingStickIntegration";
277 	case QUIRK_ATTR_TPKBCOMBO_LAYOUT:		return "AttrTPKComboLayout";
278 	case QUIRK_ATTR_PRESSURE_RANGE:			return "AttrPressureRange";
279 	case QUIRK_ATTR_PALM_PRESSURE_THRESHOLD:	return "AttrPalmPressureThreshold";
280 	case QUIRK_ATTR_RESOLUTION_HINT:		return "AttrResolutionHint";
281 	case QUIRK_ATTR_TRACKPOINT_MULTIPLIER:		return "AttrTrackpointMultiplier";
282 	case QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD:	return "AttrThumbPressureThreshold";
283 	case QUIRK_ATTR_USE_VELOCITY_AVERAGING:		return "AttrUseVelocityAveraging";
284 	case QUIRK_ATTR_TABLET_SMOOTHING:               return "AttrTabletSmoothing";
285 	case QUIRK_ATTR_THUMB_SIZE_THRESHOLD:		return "AttrThumbSizeThreshold";
286 	case QUIRK_ATTR_MSC_TIMESTAMP:			return "AttrMscTimestamp";
287 	case QUIRK_ATTR_EVENT_CODE_DISABLE:		return "AttrEventCodeDisable";
288 	case QUIRK_ATTR_EVENT_CODE_ENABLE:		return "AttrEventCodeEnable";
289 	case QUIRK_ATTR_INPUT_PROP_DISABLE:		return "AttrInputPropDisable";
290 	case QUIRK_ATTR_INPUT_PROP_ENABLE:		return "AttrInputPropEnable";
291 	default:
292 		abort();
293 	}
294 }
295 
296 static inline const char *
matchflagname(enum match_flags f)297 matchflagname(enum match_flags f)
298 {
299 	switch(f) {
300 	case M_NAME:		return "MatchName";		break;
301 	case M_BUS:		return "MatchBus";		break;
302 	case M_VID:		return "MatchVendor";		break;
303 	case M_PID:		return "MatchProduct";		break;
304 	case M_VERSION:		return "MatchVersion";		break;
305 	case M_DMI:		return "MatchDMIModalias";	break;
306 	case M_UDEV_TYPE:	return "MatchUdevType";		break;
307 	case M_DT:		return "MatchDeviceTree";	break;
308 	default:
309 		abort();
310 	}
311 }
312 
313 static inline struct property *
property_new(void)314 property_new(void)
315 {
316 	struct property *p;
317 
318 	p = zalloc(sizeof *p);
319 	p->refcount = 1;
320 	list_init(&p->link);
321 
322 	return p;
323 }
324 
325 static inline struct property *
property_ref(struct property * p)326 property_ref(struct property *p)
327 {
328 	assert(p->refcount > 0);
329 	p->refcount++;
330 	return p;
331 }
332 
333 static inline struct property *
property_unref(struct property * p)334 property_unref(struct property *p)
335 {
336 	/* Note: we don't cleanup here, that is a separate call so we
337 	   can abort if we haven't cleaned up correctly.  */
338 	assert(p->refcount > 0);
339 	p->refcount--;
340 
341 	return NULL;
342 }
343 
344 /* Separate call so we can verify that the caller unrefs the property
345  * before shutting down the subsystem.
346  */
347 static inline void
property_cleanup(struct property * p)348 property_cleanup(struct property *p)
349 {
350 	/* If we get here, the quirks must've been removed already */
351 	property_unref(p);
352 	assert(p->refcount == 0);
353 
354 	list_remove(&p->link);
355 	if (p->type == PT_STRING)
356 		free(p->value.s);
357 	free(p);
358 }
359 
360 /**
361  * Return the system DMI info in modalias format.
362  */
363 #ifdef __linux__
364 static inline char *
init_dmi_linux(void)365 init_dmi_linux(void)
366 {
367 	struct udev *udev;
368 	struct udev_device *udev_device;
369 	const char *modalias = NULL;
370 	char *copy = NULL;
371 	const char *syspath = "/sys/devices/virtual/dmi/id";
372 
373 	udev = udev_new();
374 	if (!udev)
375 		return NULL;
376 
377 	udev_device = udev_device_new_from_syspath(udev, syspath);
378 	if (udev_device)
379 		modalias = udev_device_get_property_value(udev_device,
380 							  "MODALIAS");
381 
382 	/* Not sure whether this could ever really fail, if so we should
383 	 * open the sysfs file directly. But then udev wouldn't have failed,
384 	 * so... */
385 	if (!modalias)
386 		modalias = "dmi:*";
387 
388 	copy = safe_strdup(modalias);
389 
390 	udev_device_unref(udev_device);
391 	udev_unref(udev);
392 
393 	return copy;
394 }
395 #endif
396 
397 #ifdef __FreeBSD__
398 static inline char *
init_dmi_freebsd(void)399 init_dmi_freebsd(void)
400 {
401 #define LEN (KENV_MVALLEN + 1)
402 	char *modalias;
403 	char bios_vendor[LEN], bios_version[LEN], bios_date[LEN];
404 	char sys_vendor[LEN], product_name[LEN], product_version[LEN];
405 	char board_vendor[LEN], board_name[LEN], board_version[LEN];
406 	char chassis_vendor[LEN], chassis_type[LEN], chassis_version[LEN];
407 	int chassis_type_num = 0x2;
408 
409 	kenv(KENV_GET, "smbios.bios.vendor", bios_vendor, LEN);
410 	kenv(KENV_GET, "smbios.bios.version", bios_version, LEN);
411 	kenv(KENV_GET, "smbios.bios.reldate", bios_date, LEN);
412 	kenv(KENV_GET, "smbios.system.maker", sys_vendor, LEN);
413 	kenv(KENV_GET, "smbios.system.product", product_name, LEN);
414 	kenv(KENV_GET, "smbios.system.version", product_version, LEN);
415 	kenv(KENV_GET, "smbios.planar.maker", board_vendor, LEN);
416 	kenv(KENV_GET, "smbios.planar.product", board_name, LEN);
417 	kenv(KENV_GET, "smbios.planar.version", board_version, LEN);
418 	kenv(KENV_GET, "smbios.chassis.vendor", chassis_vendor, LEN);
419 	kenv(KENV_GET, "smbios.chassis.type", chassis_type, LEN);
420 	kenv(KENV_GET, "smbios.chassis.version", chassis_version, LEN);
421 #undef LEN
422 
423 	if (strcmp(chassis_type, "Desktop") == 0)
424 		chassis_type_num = 0x3;
425 	else if (strcmp(chassis_type, "Portable") == 0)
426 		chassis_type_num = 0x8;
427 	else if (strcmp(chassis_type, "Laptop") == 0)
428 		chassis_type_num = 0x9;
429 	else if (strcmp(chassis_type, "Notebook") == 0)
430 		chassis_type_num = 0xA;
431 	else if (strcmp(chassis_type, "Tablet") == 0)
432 		chassis_type_num = 0x1E;
433 	else if (strcmp(chassis_type, "Convertible") == 0)
434 		chassis_type_num = 0x1F;
435 	else if (strcmp(chassis_type, "Detachable") == 0)
436 		chassis_type_num = 0x20;
437 
438 	xasprintf(&modalias,
439 		"dmi:bvn%s:bvr%s:bd%s:svn%s:pn%s:pvr%s:rvn%s:rn%s:rvr%s:cvn%s:ct%d:cvr%s:",
440 		bios_vendor, bios_version, bios_date, sys_vendor, product_name,
441 		product_version, board_vendor, board_name, board_version, chassis_vendor,
442 		chassis_type_num, chassis_version);
443 
444 	return modalias;
445 }
446 #endif
447 
448 static inline char *
init_dmi(void)449 init_dmi(void)
450 {
451 	if (getenv("LIBINPUT_RUNNING_TEST_SUITE"))
452 		return safe_strdup("dmi:");
453 
454 #if defined(__linux__)
455 	return init_dmi_linux();
456 #elif defined(__FreeBSD__)
457 	return init_dmi_freebsd();
458 #else
459 	return NULL;
460 #endif
461 }
462 
463 /**
464  * Return the dt compatible string
465  */
466 static inline char *
init_dt(void)467 init_dt(void)
468 {
469 	char compatible[1024];
470 	char *copy = NULL;
471 	const char *syspath = "/sys/firmware/devicetree/base/compatible";
472 	FILE *fp;
473 
474 	if (getenv("LIBINPUT_RUNNING_TEST_SUITE"))
475 		return safe_strdup("");
476 
477 	fp = fopen(syspath, "r");
478 	if (!fp)
479 		return NULL;
480 
481 	/* devicetree/base/compatible has multiple null-terminated entries
482 	   but we only care about the first one here, so strdup is enough */
483 	if (fgets(compatible, sizeof(compatible), fp)) {
484 		copy = safe_strdup(compatible);
485 	}
486 
487 	fclose(fp);
488 
489 	return copy;
490 }
491 
492 static inline struct section *
section_new(const char * path,const char * name)493 section_new(const char *path, const char *name)
494 {
495 	struct section *s = zalloc(sizeof(*s));
496 
497 	char *path_dup = safe_strdup(path);
498 	xasprintf(&s->name, "%s (%s)", name, basename(path_dup));
499 	free(path_dup);
500 	list_init(&s->link);
501 	list_init(&s->properties);
502 
503 	return s;
504 }
505 
506 static inline void
section_destroy(struct section * s)507 section_destroy(struct section *s)
508 {
509 	struct property *p;
510 
511 	free(s->name);
512 	free(s->match.name);
513 	free(s->match.dmi);
514 	free(s->match.dt);
515 
516 	list_for_each_safe(p, &s->properties, link)
517 		property_cleanup(p);
518 
519 	assert(list_empty(&s->properties));
520 
521 	list_remove(&s->link);
522 	free(s);
523 }
524 
525 static inline bool
parse_hex(const char * value,unsigned int * parsed)526 parse_hex(const char *value, unsigned int *parsed)
527 {
528 	return strneq(value, "0x", 2) &&
529 	       safe_atou_base(value, parsed, 16) &&
530 	       strspn(value, "0123456789xABCDEF") == strlen(value) &&
531 	       *parsed <= 0xFFFF;
532 }
533 
534 /**
535  * Parse a MatchFooBar=banana line.
536  *
537  * @param section The section struct to be filled in
538  * @param key The MatchFooBar part of the line
539  * @param value The banana part of the line.
540  *
541  * @return true on success, false otherwise.
542  */
543 static bool
parse_match(struct quirks_context * ctx,struct section * s,const char * key,const char * value)544 parse_match(struct quirks_context *ctx,
545 	    struct section *s,
546 	    const char *key,
547 	    const char *value)
548 {
549 	int rc = false;
550 
551 #define check_set_bit(s_, bit_) { \
552 		if ((s_)->match.bits & (bit_)) goto out; \
553 		(s_)->match.bits |= (bit_); \
554 	}
555 
556 	assert(strlen(value) >= 1);
557 
558 	if (streq(key, "MatchName")) {
559 		check_set_bit(s, M_NAME);
560 		s->match.name = safe_strdup(value);
561 	} else if (streq(key, "MatchBus")) {
562 		check_set_bit(s, M_BUS);
563 		if (streq(value, "usb"))
564 			s->match.bus = BT_USB;
565 		else if (streq(value, "bluetooth"))
566 			s->match.bus = BT_BLUETOOTH;
567 		else if (streq(value, "ps2"))
568 			s->match.bus = BT_PS2;
569 		else if (streq(value, "rmi"))
570 			s->match.bus = BT_RMI;
571 		else if (streq(value, "i2c"))
572 			s->match.bus = BT_I2C;
573 		else if (streq(value, "spi"))
574 			s->match.bus = BT_SPI;
575 		else
576 			goto out;
577 	} else if (streq(key, "MatchVendor")) {
578 		unsigned int vendor;
579 
580 		check_set_bit(s, M_VID);
581 		if (!parse_hex(value, &vendor))
582 			goto out;
583 
584 		s->match.vendor = vendor;
585 	} else if (streq(key, "MatchProduct")) {
586 		unsigned int product;
587 
588 		check_set_bit(s, M_PID);
589 		if (!parse_hex(value, &product))
590 			goto out;
591 
592 		s->match.product = product;
593 	} else if (streq(key, "MatchVersion")) {
594 		unsigned int version;
595 
596 		check_set_bit(s, M_VERSION);
597 		if (!parse_hex(value, &version))
598 			goto out;
599 
600 		s->match.version = version;
601 	} else if (streq(key, "MatchDMIModalias")) {
602 		check_set_bit(s, M_DMI);
603 		if (!strneq(value, "dmi:", 4)) {
604 			qlog_parser(ctx,
605 				    "%s: MatchDMIModalias must start with 'dmi:'\n",
606 				    s->name);
607 			goto out;
608 		}
609 		s->match.dmi = safe_strdup(value);
610 	} else if (streq(key, "MatchUdevType")) {
611 		check_set_bit(s, M_UDEV_TYPE);
612 		if (streq(value, "touchpad"))
613 			s->match.udev_type = UDEV_TOUCHPAD;
614 		else if (streq(value, "mouse"))
615 			s->match.udev_type = UDEV_MOUSE;
616 		else if (streq(value, "pointingstick"))
617 			s->match.udev_type = UDEV_POINTINGSTICK;
618 		else if (streq(value, "keyboard"))
619 			s->match.udev_type = UDEV_KEYBOARD;
620 		else if (streq(value, "joystick"))
621 			s->match.udev_type = UDEV_JOYSTICK;
622 		else if (streq(value, "tablet"))
623 			s->match.udev_type = UDEV_TABLET;
624 		else if (streq(value, "tablet-pad"))
625 			s->match.udev_type = UDEV_TABLET_PAD;
626 		else
627 			goto out;
628 	} else if (streq(key, "MatchDeviceTree")) {
629 		check_set_bit(s, M_DT);
630 		s->match.dt = safe_strdup(value);
631 	} else {
632 		qlog_error(ctx, "Unknown match key '%s'\n", key);
633 		goto out;
634 	}
635 
636 #undef check_set_bit
637 	s->has_match = true;
638 	rc = true;
639 out:
640 	return rc;
641 }
642 
643 /**
644  * Parse a ModelFooBar=1 line.
645  *
646  * @param section The section struct to be filled in
647  * @param key The ModelFooBar part of the line
648  * @param value The value after the =, must be 1 or 0.
649  *
650  * @return true on success, false otherwise.
651  */
652 static bool
parse_model(struct quirks_context * ctx,struct section * s,const char * key,const char * value)653 parse_model(struct quirks_context *ctx,
654 	    struct section *s,
655 	    const char *key,
656 	    const char *value)
657 {
658 	bool b;
659 	enum quirk q = QUIRK_MODEL_ALPS_SERIAL_TOUCHPAD;
660 
661 	assert(strneq(key, "Model", 5));
662 
663 	if (!parse_boolean_property(value, &b))
664 		return false;
665 
666 	do {
667 		if (streq(key, quirk_get_name(q))) {
668 			struct property *p = property_new();
669 			p->id = q,
670 			p->type = PT_BOOL;
671 			p->value.b = b;
672 			list_append(&s->properties, &p->link);
673 			s->has_property = true;
674 			return true;
675 		}
676 	} while (++q < _QUIRK_LAST_MODEL_QUIRK_);
677 
678 	qlog_error(ctx, "Unknown key %s in %s\n", key, s->name);
679 
680 	return false;
681 }
682 
683 /**
684  * Parse a AttrFooBar=banana line.
685  *
686  * @param section The section struct to be filled in
687  * @param key The AttrFooBar part of the line
688  * @param value The banana part of the line.
689  *
690  * Value parsing depends on the attribute type.
691  *
692  * @return true on success, false otherwise.
693  */
694 static inline bool
parse_attr(struct quirks_context * ctx,struct section * s,const char * key,const char * value)695 parse_attr(struct quirks_context *ctx,
696 	   struct section *s,
697 	   const char *key,
698 	   const char *value)
699 {
700 	struct property *p = property_new();
701 	bool rc = false;
702 	struct quirk_dimensions dim;
703 	struct quirk_range range;
704 	unsigned int v;
705 	bool b;
706 	double d;
707 
708 	if (streq(key, quirk_get_name(QUIRK_ATTR_SIZE_HINT))) {
709 		p->id = QUIRK_ATTR_SIZE_HINT;
710 		if (!parse_dimension_property(value, &dim.x, &dim.y))
711 			goto out;
712 		p->type = PT_DIMENSION;
713 		p->value.dim = dim;
714 		rc = true;
715 	} else if (streq(key, quirk_get_name(QUIRK_ATTR_TOUCH_SIZE_RANGE))) {
716 		p->id = QUIRK_ATTR_TOUCH_SIZE_RANGE;
717 		if (!parse_range_property(value, &range.upper, &range.lower))
718 			goto out;
719 		p->type = PT_RANGE;
720 		p->value.range = range;
721 		rc = true;
722 	} else if (streq(key, quirk_get_name(QUIRK_ATTR_PALM_SIZE_THRESHOLD))) {
723 		p->id = QUIRK_ATTR_PALM_SIZE_THRESHOLD;
724 		if (!safe_atou(value, &v))
725 			goto out;
726 		p->type = PT_UINT;
727 		p->value.u = v;
728 		rc = true;
729 	} else if (streq(key, quirk_get_name(QUIRK_ATTR_LID_SWITCH_RELIABILITY))) {
730 		p->id = QUIRK_ATTR_LID_SWITCH_RELIABILITY;
731 		if (!streq(value, "reliable") &&
732 		    !streq(value, "write_open"))
733 			goto out;
734 		p->type = PT_STRING;
735 		p->value.s = safe_strdup(value);
736 		rc = true;
737 	} else if (streq(key, quirk_get_name(QUIRK_ATTR_KEYBOARD_INTEGRATION))) {
738 		p->id = QUIRK_ATTR_KEYBOARD_INTEGRATION;
739 		if (!streq(value, "internal") && !streq(value, "external"))
740 			goto out;
741 		p->type = PT_STRING;
742 		p->value.s = safe_strdup(value);
743 		rc = true;
744 	} else if (streq(key, quirk_get_name(QUIRK_ATTR_TRACKPOINT_INTEGRATION))) {
745 		p->id = QUIRK_ATTR_TRACKPOINT_INTEGRATION;
746 		if (!streq(value, "internal") && !streq(value, "external"))
747 			goto out;
748 		p->type = PT_STRING;
749 		p->value.s = safe_strdup(value);
750 		rc = true;
751 	} else if (streq(key, quirk_get_name(QUIRK_ATTR_TPKBCOMBO_LAYOUT))) {
752 		p->id = QUIRK_ATTR_TPKBCOMBO_LAYOUT;
753 		if (!streq(value, "below"))
754 			goto out;
755 		p->type = PT_STRING;
756 		p->value.s = safe_strdup(value);
757 		rc = true;
758 	} else if (streq(key, quirk_get_name(QUIRK_ATTR_PRESSURE_RANGE))) {
759 		p->id = QUIRK_ATTR_PRESSURE_RANGE;
760 		if (!parse_range_property(value, &range.upper, &range.lower))
761 			goto out;
762 		p->type = PT_RANGE;
763 		p->value.range = range;
764 		rc = true;
765 	} else if (streq(key, quirk_get_name(QUIRK_ATTR_PALM_PRESSURE_THRESHOLD))) {
766 		p->id = QUIRK_ATTR_PALM_PRESSURE_THRESHOLD;
767 		if (!safe_atou(value, &v))
768 			goto out;
769 		p->type = PT_UINT;
770 		p->value.u = v;
771 		rc = true;
772 	} else if (streq(key, quirk_get_name(QUIRK_ATTR_RESOLUTION_HINT))) {
773 		p->id = QUIRK_ATTR_RESOLUTION_HINT;
774 		if (!parse_dimension_property(value, &dim.x, &dim.y))
775 			goto out;
776 		p->type = PT_DIMENSION;
777 		p->value.dim = dim;
778 		rc = true;
779 	} else if (streq(key, quirk_get_name(QUIRK_ATTR_TRACKPOINT_MULTIPLIER))) {
780 		p->id = QUIRK_ATTR_TRACKPOINT_MULTIPLIER;
781 		if (!safe_atod(value, &d))
782 			goto out;
783 		p->type = PT_DOUBLE;
784 		p->value.d = d;
785 		rc = true;
786 	} else if (streq(key, quirk_get_name(QUIRK_ATTR_USE_VELOCITY_AVERAGING))) {
787 		p->id = QUIRK_ATTR_USE_VELOCITY_AVERAGING;
788 		if (!parse_boolean_property(value, &b))
789 			goto out;
790 		p->type = PT_BOOL;
791 		p->value.b = b;
792 		rc = true;
793 	} else if (streq(key, quirk_get_name(QUIRK_ATTR_TABLET_SMOOTHING))) {
794 		p->id = QUIRK_ATTR_TABLET_SMOOTHING;
795 		if (!parse_boolean_property(value, &b))
796 			goto out;
797 		p->type = PT_BOOL;
798 		p->value.b = b;
799 		rc = true;
800 	} else if (streq(key, quirk_get_name(QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD))) {
801 		p->id = QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD;
802 		if (!safe_atou(value, &v))
803 			goto out;
804 		p->type = PT_UINT;
805 		p->value.u = v;
806 		rc = true;
807 	} else if (streq(key, quirk_get_name(QUIRK_ATTR_THUMB_SIZE_THRESHOLD))) {
808 		p->id = QUIRK_ATTR_THUMB_SIZE_THRESHOLD;
809 		if (!safe_atou(value, &v))
810 			goto out;
811 		p->type = PT_UINT;
812 		p->value.u = v;
813 		rc = true;
814 	} else if (streq(key, quirk_get_name(QUIRK_ATTR_MSC_TIMESTAMP))) {
815 		p->id = QUIRK_ATTR_MSC_TIMESTAMP;
816 		if (!streq(value, "watch"))
817 			goto out;
818 		p->type = PT_STRING;
819 		p->value.s = safe_strdup(value);
820 		rc = true;
821 	} else if (streq(key, quirk_get_name(QUIRK_ATTR_EVENT_CODE_DISABLE)) ||
822 		   streq(key, quirk_get_name(QUIRK_ATTR_EVENT_CODE_ENABLE))) {
823 		struct input_event events[32];
824 		size_t nevents = ARRAY_LENGTH(events);
825 		if (streq(key, quirk_get_name(QUIRK_ATTR_EVENT_CODE_DISABLE)))
826 		    p->id = QUIRK_ATTR_EVENT_CODE_DISABLE;
827 		else
828 		    p->id = QUIRK_ATTR_EVENT_CODE_ENABLE;
829 
830 		if (!parse_evcode_property(value, events, &nevents) ||
831 		    nevents == 0)
832 			goto out;
833 
834 		for (size_t i = 0; i < nevents; i++) {
835 			p->value.tuples.tuples[i].first = events[i].type;
836 			p->value.tuples.tuples[i].second = events[i].code;
837 		}
838 		p->value.tuples.ntuples = nevents;
839 		p->type = PT_TUPLES;
840 
841 		rc = true;
842 	} else if (streq(key, quirk_get_name(QUIRK_ATTR_INPUT_PROP_DISABLE)) ||
843 		   streq(key, quirk_get_name(QUIRK_ATTR_INPUT_PROP_ENABLE))) {
844 		unsigned int props[INPUT_PROP_CNT];
845 		size_t nprops = ARRAY_LENGTH(props);
846 		if (streq(key, quirk_get_name(QUIRK_ATTR_INPUT_PROP_DISABLE)))
847 			p->id = QUIRK_ATTR_INPUT_PROP_DISABLE;
848 		else
849 			p->id = QUIRK_ATTR_INPUT_PROP_ENABLE;
850 
851 		if (!parse_input_prop_property(value, props, &nprops) ||
852 		    nprops == 0)
853 			goto out;
854 
855 		memcpy(p->value.array.data.u, props, nprops * sizeof(unsigned int));
856 		p->value.array.nelements = nprops;
857 		p->type = PT_UINT_ARRAY;
858 
859 		rc = true;
860 	} else {
861 		qlog_error(ctx, "Unknown key %s in %s\n", key, s->name);
862 	}
863 out:
864 	if (rc) {
865 		list_append(&s->properties, &p->link);
866 		s->has_property = true;
867 	} else {
868 		property_cleanup(p);
869 	}
870 	return rc;
871 }
872 
873 /**
874  * Parse a single line, expected to be in the format Key=value. Anything
875  * else will be rejected with a failure.
876  *
877  * Our data files can only have Match, Model and Attr, so let's check for
878  * those too.
879  */
880 static bool
parse_value_line(struct quirks_context * ctx,struct section * s,const char * line)881 parse_value_line(struct quirks_context *ctx, struct section *s, const char *line)
882 {
883 	char **strv;
884 	const char *key, *value;
885 	bool rc = false;
886 
887 	strv = strv_from_string(line, "=");
888 	if (strv[0] == NULL || strv[1] == NULL || strv[2] != NULL) {
889 		goto out;
890 	}
891 
892 
893 	key = strv[0];
894 	value = strv[1];
895 	if (strlen(key) == 0 || strlen(value) == 0)
896 		goto out;
897 
898 	/* Whatever the value is, it's not supposed to be in quotes */
899 	if (value[0] == '"' || value[0] == '\'')
900 		goto out;
901 
902 	if (strneq(key, "Match", 5))
903 		rc = parse_match(ctx, s, key, value);
904 	else if (strneq(key, "Model", 5))
905 		rc = parse_model(ctx, s, key, value);
906 	else if (strneq(key, "Attr", 4))
907 		rc = parse_attr(ctx, s, key, value);
908 	else
909 		qlog_error(ctx, "Unknown value prefix %s\n", line);
910 out:
911 	strv_free(strv);
912 	return rc;
913 }
914 
915 static inline bool
parse_file(struct quirks_context * ctx,const char * path)916 parse_file(struct quirks_context *ctx, const char *path)
917 {
918 	enum state {
919 		STATE_SECTION,
920 		STATE_MATCH,
921 		STATE_MATCH_OR_VALUE,
922 		STATE_VALUE_OR_SECTION,
923 		STATE_ANY,
924 	};
925 	FILE *fp;
926 	char line[512];
927 	bool rc = false;
928 	enum state state = STATE_SECTION;
929 	struct section *section = NULL;
930 	int lineno = -1;
931 
932 	qlog_debug(ctx, "%s\n", path);
933 
934 	/* Not using open_restricted here, if we can't access
935 	 * our own data files, our installation is screwed up.
936 	 */
937 	fp = fopen(path, "r");
938 	if (!fp) {
939 		/* If the file doesn't exist that's fine. Only way this can
940 		 * happen is for the custom override file, all others are
941 		 * provided by scandir so they do exist. Short of races we
942 		 * don't care about. */
943 		if (errno == ENOENT)
944 			return true;
945 
946 		qlog_error(ctx, "%s: failed to open file\n", path);
947 		goto out;
948 	}
949 
950 	while (fgets(line, sizeof(line), fp)) {
951 		char *comment;
952 
953 		lineno++;
954 
955 		comment = strstr(line, "#");
956 		if (comment) {
957 			/* comment points to # but we need to remove the
958 			 * preceding whitespaces too */
959 			comment--;
960 			while (comment >= line) {
961 				if (*comment != ' ' && *comment != '\t')
962 					break;
963 				comment--;
964 			}
965 			*(comment + 1) = '\0';
966 		} else { /* strip the trailing newline */
967 			comment = strstr(line, "\n");
968 			if (comment)
969 				*comment = '\0';
970 		}
971 		if (strlen(line) == 0)
972 			continue;
973 
974 		/* We don't use quotes for strings, so we really don't want
975 		 * erroneous trailing whitespaces */
976 		switch (line[strlen(line) - 1]) {
977 		case ' ':
978 		case '\t':
979 			qlog_parser(ctx,
980 				    "%s:%d: Trailing whitespace '%s'\n",
981 				    path, lineno, line);
982 			goto out;
983 		}
984 
985 		switch (line[0]) {
986 		case '\0':
987 		case '\n':
988 		case '#':
989 			break;
990 		/* white space not allowed */
991 		case ' ':
992 		case '\t':
993 			qlog_parser(ctx, "%s:%d: Preceding whitespace '%s'\n",
994 					 path, lineno, line);
995 			goto out;
996 		/* section title */
997 		case '[':
998 			if (line[strlen(line) - 1] != ']') {
999 				qlog_parser(ctx, "%s:%d: Closing ] missing '%s'\n",
1000 					    path, lineno, line);
1001 				goto out;
1002 			}
1003 
1004 			if (state != STATE_SECTION &&
1005 			    state != STATE_VALUE_OR_SECTION) {
1006 				qlog_parser(ctx, "%s:%d: expected section before %s\n",
1007 					  path, lineno, line);
1008 				goto out;
1009 			}
1010 			if (section &&
1011 			    (!section->has_match || !section->has_property)) {
1012 				qlog_parser(ctx, "%s:%d: previous section %s was empty\n",
1013 					  path, lineno, section->name);
1014 				goto out; /* Previous section was empty */
1015 			}
1016 
1017 			state = STATE_MATCH;
1018 			section = section_new(path, line);
1019 			list_append(&ctx->sections, &section->link);
1020 			break;
1021 		default:
1022 			/* entries must start with A-Z */
1023 			if (line[0] < 'A' || line[0] > 'Z') {
1024 				qlog_parser(ctx, "%s:%d: Unexpected line %s\n",
1025 						 path, lineno, line);
1026 				goto out;
1027 			}
1028 			switch (state) {
1029 			case STATE_SECTION:
1030 				qlog_parser(ctx, "%s:%d: expected [Section], got %s\n",
1031 					  path, lineno, line);
1032 				goto out;
1033 			case STATE_MATCH:
1034 				if (!strneq(line, "Match", 5)) {
1035 					qlog_parser(ctx, "%s:%d: expected MatchFoo=bar, have %s\n",
1036 							 path, lineno, line);
1037 					goto out;
1038 				}
1039 				state = STATE_MATCH_OR_VALUE;
1040 				break;
1041 			case STATE_MATCH_OR_VALUE:
1042 				if (!strneq(line, "Match", 5))
1043 					state = STATE_VALUE_OR_SECTION;
1044 				break;
1045 			case STATE_VALUE_OR_SECTION:
1046 				if (strneq(line, "Match", 5)) {
1047 					qlog_parser(ctx, "%s:%d: expected value or [Section], have %s\n",
1048 							 path, lineno, line);
1049 					goto out;
1050 				}
1051 				break;
1052 			case STATE_ANY:
1053 				break;
1054 			}
1055 
1056 			if (!parse_value_line(ctx, section, line)) {
1057 				qlog_parser(ctx, "%s:%d: failed to parse %s\n",
1058 						 path, lineno, line);
1059 				goto out;
1060 			}
1061 			break;
1062 		}
1063 	}
1064 
1065 	if (!section) {
1066 		qlog_parser(ctx, "%s: is an empty file\n", path);
1067 		goto out;
1068 	}
1069 
1070 	if ((!section->has_match || !section->has_property)) {
1071 		qlog_parser(ctx, "%s:%d: previous section %s was empty\n",
1072 				 path, lineno, section->name);
1073 		goto out; /* Previous section was empty */
1074 	}
1075 
1076 	rc = true;
1077 out:
1078 	if (fp)
1079 		fclose(fp);
1080 
1081 	return rc;
1082 }
1083 
1084 static int
is_data_file(const struct dirent * dir)1085 is_data_file(const struct dirent *dir) {
1086 	return strendswith(dir->d_name, ".quirks");
1087 }
1088 
1089 static inline bool
parse_files(struct quirks_context * ctx,const char * data_path)1090 parse_files(struct quirks_context *ctx, const char *data_path)
1091 {
1092 	struct dirent **namelist;
1093 	int ndev = -1;
1094 	int idx = 0;
1095 
1096 	ndev = scandir(data_path, &namelist, is_data_file, versionsort);
1097 	if (ndev <= 0) {
1098 		qlog_error(ctx,
1099 			   "%s: failed to find data files\n",
1100 			   data_path);
1101 		return false;
1102 	}
1103 
1104 	for (idx = 0; idx < ndev; idx++) {
1105 		char path[PATH_MAX];
1106 
1107 		snprintf(path,
1108 			 sizeof(path),
1109 			 "%s/%s",
1110 			 data_path,
1111 			 namelist[idx]->d_name);
1112 
1113 		if (!parse_file(ctx, path))
1114 			break;
1115 	}
1116 
1117 	for (int i = 0; i < ndev; i++)
1118 		free(namelist[i]);
1119 	free(namelist);
1120 
1121 	return idx == ndev;
1122 }
1123 
1124 struct quirks_context *
quirks_init_subsystem(const char * data_path,const char * override_file,libinput_log_handler log_handler,struct libinput * libinput,enum quirks_log_type log_type)1125 quirks_init_subsystem(const char *data_path,
1126 		      const char *override_file,
1127 		      libinput_log_handler log_handler,
1128 		      struct libinput *libinput,
1129 		      enum quirks_log_type log_type)
1130 {
1131 	struct quirks_context *ctx = zalloc(sizeof *ctx);
1132 
1133 	assert(data_path);
1134 
1135 	ctx->refcount = 1;
1136 	ctx->log_handler = log_handler;
1137 	ctx->log_type = log_type;
1138 	ctx->libinput = libinput;
1139 	list_init(&ctx->quirks);
1140 	list_init(&ctx->sections);
1141 
1142 	qlog_debug(ctx, "%s is data root\n", data_path);
1143 
1144 	ctx->dmi = init_dmi();
1145 	ctx->dt = init_dt();
1146 	if (!ctx->dmi && !ctx->dt)
1147 		goto error;
1148 
1149 	if (!parse_files(ctx, data_path))
1150 		goto error;
1151 
1152 	if (override_file && !parse_file(ctx, override_file))
1153 		goto error;
1154 
1155 	return ctx;
1156 
1157 error:
1158 	quirks_context_unref(ctx);
1159 	return NULL;
1160 }
1161 
1162 struct quirks_context *
quirks_context_ref(struct quirks_context * ctx)1163 quirks_context_ref(struct quirks_context *ctx)
1164 {
1165 	assert(ctx->refcount > 0);
1166 	ctx->refcount++;
1167 
1168 	return ctx;
1169 }
1170 
1171 struct quirks_context *
quirks_context_unref(struct quirks_context * ctx)1172 quirks_context_unref(struct quirks_context *ctx)
1173 {
1174 	struct section *s;
1175 
1176 	if (!ctx)
1177 		return NULL;
1178 
1179 	assert(ctx->refcount >= 1);
1180 	ctx->refcount--;
1181 
1182 	if (ctx->refcount > 0)
1183 		return NULL;
1184 
1185 	/* Caller needs to clean up before calling this */
1186 	assert(list_empty(&ctx->quirks));
1187 
1188 	list_for_each_safe(s, &ctx->sections, link) {
1189 		section_destroy(s);
1190 	}
1191 
1192 	free(ctx->dmi);
1193 	free(ctx->dt);
1194 	free(ctx);
1195 
1196 	return NULL;
1197 }
1198 
1199 static struct quirks *
quirks_new(void)1200 quirks_new(void)
1201 {
1202 	struct quirks *q;
1203 
1204 	q = zalloc(sizeof *q);
1205 	q->refcount = 1;
1206 	q->nproperties = 0;
1207 	list_init(&q->link);
1208 
1209 	return q;
1210 }
1211 
1212 struct quirks *
quirks_unref(struct quirks * q)1213 quirks_unref(struct quirks *q)
1214 {
1215 	if (!q)
1216 		return NULL;
1217 
1218 	/* We don't really refcount, but might
1219 	 * as well have the API in place */
1220 	assert(q->refcount == 1);
1221 
1222 	for (size_t i = 0; i < q->nproperties; i++) {
1223 		property_unref(q->properties[i]);
1224 	}
1225 
1226 	list_remove(&q->link);
1227 	free(q->properties);
1228 	free(q);
1229 
1230 	return NULL;
1231 }
1232 
1233 /**
1234  * Searches for the udev property on this device and its parent devices.
1235  *
1236  * @return the value of the property or NULL
1237  */
1238 static const char *
udev_prop(struct udev_device * device,const char * prop)1239 udev_prop(struct udev_device *device, const char *prop)
1240 {
1241 	struct udev_device *d = device;
1242 	const char *value = NULL;
1243 
1244 	do {
1245 		value = udev_device_get_property_value(d, prop);
1246 		d = udev_device_get_parent(d);
1247 	} while (value == NULL && d != NULL);
1248 
1249 	return value;
1250 }
1251 
1252 static inline void
match_fill_name(struct match * m,struct udev_device * device)1253 match_fill_name(struct match *m,
1254 		struct udev_device *device)
1255 {
1256 	const char *str = udev_prop(device, "NAME");
1257 	size_t slen;
1258 
1259 	if (!str)
1260 		return;
1261 
1262 	/* udev NAME is in quotes, strip them */
1263 	if (str[0] == '"')
1264 		str++;
1265 
1266 	m->name = safe_strdup(str);
1267 	slen = strlen(m->name);
1268 	if (slen > 1 &&
1269 	    m->name[slen - 1] == '"')
1270 		m->name[slen - 1] = '\0';
1271 
1272 	m->bits |= M_NAME;
1273 }
1274 
1275 static inline void
match_fill_bus_vid_pid(struct match * m,struct udev_device * device)1276 match_fill_bus_vid_pid(struct match *m,
1277 		       struct udev_device *device)
1278 {
1279 	const char *str;
1280 	unsigned int product, vendor, bus, version;
1281 
1282 	str = udev_prop(device, "PRODUCT");
1283 	if (!str)
1284 		return;
1285 
1286 	/* ID_VENDOR_ID/ID_PRODUCT_ID/ID_BUS aren't filled in for virtual
1287 	 * devices so we have to resort to PRODUCT  */
1288 	if (sscanf(str, "%x/%x/%x/%x", &bus, &vendor, &product, &version) != 4)
1289 		return;
1290 
1291 	m->product = product;
1292 	m->vendor = vendor;
1293 	m->version = version;
1294 	m->bits |= M_PID|M_VID|M_VERSION;
1295 	switch (bus) {
1296 	case BUS_USB:
1297 		m->bus = BT_USB;
1298 		m->bits |= M_BUS;
1299 		break;
1300 	case BUS_BLUETOOTH:
1301 		m->bus = BT_BLUETOOTH;
1302 		m->bits |= M_BUS;
1303 		break;
1304 	case BUS_I8042:
1305 		m->bus = BT_PS2;
1306 		m->bits |= M_BUS;
1307 		break;
1308 	case BUS_RMI:
1309 		m->bus = BT_RMI;
1310 		m->bits |= M_BUS;
1311 		break;
1312 	case BUS_I2C:
1313 		m->bus = BT_I2C;
1314 		m->bits |= M_BUS;
1315 		break;
1316 	case BUS_SPI:
1317 		m->bus = BT_SPI;
1318 		m->bits |= M_BUS;
1319 		break;
1320 	default:
1321 		break;
1322 	}
1323 }
1324 
1325 static inline void
match_fill_udev_type(struct match * m,struct udev_device * device)1326 match_fill_udev_type(struct match *m,
1327 		     struct udev_device *device)
1328 {
1329 	struct ut_map {
1330 		const char *prop;
1331 		enum udev_type flag;
1332 	} mappings[] = {
1333 		{ "ID_INPUT_MOUSE", UDEV_MOUSE },
1334 		{ "ID_INPUT_POINTINGSTICK", UDEV_POINTINGSTICK },
1335 		{ "ID_INPUT_TOUCHPAD", UDEV_TOUCHPAD },
1336 		{ "ID_INPUT_TABLET", UDEV_TABLET },
1337 		{ "ID_INPUT_TABLET_PAD", UDEV_TABLET_PAD },
1338 		{ "ID_INPUT_JOYSTICK", UDEV_JOYSTICK },
1339 		{ "ID_INPUT_KEYBOARD", UDEV_KEYBOARD },
1340 		{ "ID_INPUT_KEY", UDEV_KEYBOARD },
1341 	};
1342 	struct ut_map *map;
1343 
1344 	ARRAY_FOR_EACH(mappings, map) {
1345 		if (udev_prop(device, map->prop))
1346 			m->udev_type |= map->flag;
1347 	}
1348 	m->bits |= M_UDEV_TYPE;
1349 }
1350 
1351 static inline void
match_fill_dmi_dt(struct match * m,char * dmi,char * dt)1352 match_fill_dmi_dt(struct match *m, char *dmi, char *dt)
1353 {
1354 	if (dmi) {
1355 		m->dmi = dmi;
1356 		m->bits |= M_DMI;
1357 	}
1358 
1359 	if (dt) {
1360 		m->dt = dt;
1361 		m->bits |= M_DT;
1362 	}
1363 }
1364 
1365 static struct match *
match_new(struct udev_device * device,char * dmi,char * dt)1366 match_new(struct udev_device *device,
1367 	  char *dmi, char *dt)
1368 {
1369 	struct match *m = zalloc(sizeof *m);
1370 
1371 	match_fill_name(m, device);
1372 	match_fill_bus_vid_pid(m, device);
1373 	match_fill_dmi_dt(m, dmi, dt);
1374 	match_fill_udev_type(m, device);
1375 	return m;
1376 }
1377 
1378 static void
match_free(struct match * m)1379 match_free(struct match *m)
1380 {
1381 	/* dmi and dt are global */
1382 	free(m->name);
1383 	free(m);
1384 }
1385 
1386 static void
quirk_apply_section(struct quirks_context * ctx,struct quirks * q,const struct section * s)1387 quirk_apply_section(struct quirks_context *ctx,
1388 		    struct quirks *q,
1389 		    const struct section *s)
1390 {
1391 	struct property *p;
1392 	size_t nprops = 0;
1393 	void *tmp;
1394 
1395 	list_for_each(p, &s->properties, link) {
1396 		nprops++;
1397 	}
1398 
1399 	nprops += q->nproperties;
1400 	tmp = realloc(q->properties, nprops * sizeof(p));
1401 	if (!tmp)
1402 		return;
1403 
1404 	q->properties = tmp;
1405 	list_for_each(p, &s->properties, link) {
1406 		qlog_debug(ctx, "property added: %s from %s\n",
1407 			   quirk_get_name(p->id), s->name);
1408 
1409 		q->properties[q->nproperties++] = property_ref(p);
1410 	}
1411 }
1412 
1413 static bool
quirk_match_section(struct quirks_context * ctx,struct quirks * q,struct section * s,struct match * m,struct udev_device * device)1414 quirk_match_section(struct quirks_context *ctx,
1415 		    struct quirks *q,
1416 		    struct section *s,
1417 		    struct match *m,
1418 		    struct udev_device *device)
1419 {
1420 	uint32_t matched_flags = 0x0;
1421 
1422 	for (uint32_t flag = 0x1; flag <= M_LAST; flag <<= 1) {
1423 		uint32_t prev_matched_flags = matched_flags;
1424 		/* section doesn't have this bit set, continue */
1425 		if ((s->match.bits & flag) == 0)
1426 			continue;
1427 
1428 		/* Couldn't fill in this bit for the match, so we
1429 		 * do not match on it */
1430 		if ((m->bits & flag) == 0) {
1431 			qlog_debug(ctx,
1432 				   "%s wants %s but we don't have that\n",
1433 				   s->name, matchflagname(flag));
1434 			continue;
1435 		}
1436 
1437 		/* now check the actual matching bit */
1438 		switch (flag) {
1439 		case M_NAME:
1440 			if (fnmatch(s->match.name, m->name, 0) == 0)
1441 				matched_flags |= flag;
1442 			break;
1443 		case M_BUS:
1444 			if (m->bus == s->match.bus)
1445 				matched_flags |= flag;
1446 			break;
1447 		case M_VID:
1448 			if (m->vendor == s->match.vendor)
1449 				matched_flags |= flag;
1450 			break;
1451 		case M_PID:
1452 			if (m->product == s->match.product)
1453 				matched_flags |= flag;
1454 			break;
1455 		case M_VERSION:
1456 			if (m->version == s->match.version)
1457 				matched_flags |= flag;
1458 			break;
1459 		case M_DMI:
1460 			if (fnmatch(s->match.dmi, m->dmi, 0) == 0)
1461 				matched_flags |= flag;
1462 			break;
1463 		case M_DT:
1464 			if (fnmatch(s->match.dt, m->dt, 0) == 0)
1465 				matched_flags |= flag;
1466 			break;
1467 		case M_UDEV_TYPE:
1468 			if (s->match.udev_type & m->udev_type)
1469 				matched_flags |= flag;
1470 			break;
1471 		default:
1472 			abort();
1473 		}
1474 
1475 		if (prev_matched_flags != matched_flags) {
1476 			qlog_debug(ctx,
1477 				   "%s matches for %s\n",
1478 				   s->name,
1479 				   matchflagname(flag));
1480 		}
1481 	}
1482 
1483 	if (s->match.bits == matched_flags) {
1484 		qlog_debug(ctx, "%s is full match\n", s->name);
1485 		quirk_apply_section(ctx, q, s);
1486 	}
1487 
1488 	return true;
1489 }
1490 
1491 struct quirks *
quirks_fetch_for_device(struct quirks_context * ctx,struct udev_device * udev_device)1492 quirks_fetch_for_device(struct quirks_context *ctx,
1493 			struct udev_device *udev_device)
1494 {
1495 	struct quirks *q = NULL;
1496 	struct section *s;
1497 	struct match *m;
1498 
1499 	if (!ctx)
1500 		return NULL;
1501 
1502 	qlog_debug(ctx, "%s: fetching quirks\n",
1503 		   udev_device_get_devnode(udev_device));
1504 
1505 	q = quirks_new();
1506 
1507 	m = match_new(udev_device, ctx->dmi, ctx->dt);
1508 
1509 	list_for_each(s, &ctx->sections, link) {
1510 		quirk_match_section(ctx, q, s, m, udev_device);
1511 	}
1512 
1513 	match_free(m);
1514 
1515 	if (q->nproperties == 0) {
1516 		quirks_unref(q);
1517 		return NULL;
1518 	}
1519 
1520 	list_insert(&ctx->quirks, &q->link);
1521 
1522 	return q;
1523 }
1524 
1525 
1526 static inline struct property *
quirk_find_prop(struct quirks * q,enum quirk which)1527 quirk_find_prop(struct quirks *q, enum quirk which)
1528 {
1529 	/* Run backwards to only handle the last one assigned */
1530 	for (ssize_t i = q->nproperties - 1; i >= 0; i--) {
1531 		struct property *p = q->properties[i];
1532 		if (p->id == which)
1533 			return p;
1534 	}
1535 
1536 	return NULL;
1537 }
1538 
1539 bool
quirks_has_quirk(struct quirks * q,enum quirk which)1540 quirks_has_quirk(struct quirks *q, enum quirk which)
1541 {
1542 	return quirk_find_prop(q, which) != NULL;
1543 }
1544 
1545 bool
quirks_get_int32(struct quirks * q,enum quirk which,int32_t * val)1546 quirks_get_int32(struct quirks *q, enum quirk which, int32_t *val)
1547 {
1548 	struct property *p;
1549 
1550 	if (!q)
1551 		return false;
1552 
1553 	p = quirk_find_prop(q, which);
1554 	if (!p)
1555 		return false;
1556 
1557 	assert(p->type == PT_INT);
1558 	*val = p->value.i;
1559 
1560 	return true;
1561 }
1562 
1563 bool
quirks_get_uint32(struct quirks * q,enum quirk which,uint32_t * val)1564 quirks_get_uint32(struct quirks *q, enum quirk which, uint32_t *val)
1565 {
1566 	struct property *p;
1567 
1568 	if (!q)
1569 		return false;
1570 
1571 	p = quirk_find_prop(q, which);
1572 	if (!p)
1573 		return false;
1574 
1575 	assert(p->type == PT_UINT);
1576 	*val = p->value.u;
1577 
1578 	return true;
1579 }
1580 
1581 bool
quirks_get_double(struct quirks * q,enum quirk which,double * val)1582 quirks_get_double(struct quirks *q, enum quirk which, double *val)
1583 {
1584 	struct property *p;
1585 
1586 	if (!q)
1587 		return false;
1588 
1589 	p = quirk_find_prop(q, which);
1590 	if (!p)
1591 		return false;
1592 
1593 	assert(p->type == PT_DOUBLE);
1594 	*val = p->value.d;
1595 
1596 	return true;
1597 }
1598 
1599 bool
quirks_get_string(struct quirks * q,enum quirk which,char ** val)1600 quirks_get_string(struct quirks *q, enum quirk which, char **val)
1601 {
1602 	struct property *p;
1603 
1604 	if (!q)
1605 		return false;
1606 
1607 	p = quirk_find_prop(q, which);
1608 	if (!p)
1609 		return false;
1610 
1611 	assert(p->type == PT_STRING);
1612 	*val = p->value.s;
1613 
1614 	return true;
1615 }
1616 
1617 bool
quirks_get_bool(struct quirks * q,enum quirk which,bool * val)1618 quirks_get_bool(struct quirks *q, enum quirk which, bool *val)
1619 {
1620 	struct property *p;
1621 
1622 	if (!q)
1623 		return false;
1624 
1625 	p = quirk_find_prop(q, which);
1626 	if (!p)
1627 		return false;
1628 
1629 	assert(p->type == PT_BOOL);
1630 	*val = p->value.b;
1631 
1632 	return true;
1633 }
1634 
1635 bool
quirks_get_dimensions(struct quirks * q,enum quirk which,struct quirk_dimensions * val)1636 quirks_get_dimensions(struct quirks *q,
1637 		      enum quirk which,
1638 		      struct quirk_dimensions *val)
1639 {
1640 	struct property *p;
1641 
1642 	if (!q)
1643 		return false;
1644 
1645 	p = quirk_find_prop(q, which);
1646 	if (!p)
1647 		return false;
1648 
1649 	assert(p->type == PT_DIMENSION);
1650 	*val = p->value.dim;
1651 
1652 	return true;
1653 }
1654 
1655 bool
quirks_get_range(struct quirks * q,enum quirk which,struct quirk_range * val)1656 quirks_get_range(struct quirks *q,
1657 		 enum quirk which,
1658 		 struct quirk_range *val)
1659 {
1660 	struct property *p;
1661 
1662 	if (!q)
1663 		return false;
1664 
1665 	p = quirk_find_prop(q, which);
1666 	if (!p)
1667 		return false;
1668 
1669 	assert(p->type == PT_RANGE);
1670 	*val = p->value.range;
1671 
1672 	return true;
1673 }
1674 
1675 bool
quirks_get_tuples(struct quirks * q,enum quirk which,const struct quirk_tuples ** tuples)1676 quirks_get_tuples(struct quirks *q,
1677 		  enum quirk which,
1678 		  const struct quirk_tuples **tuples)
1679 {
1680 	struct property *p;
1681 
1682 	if (!q)
1683 		return false;
1684 
1685 	p = quirk_find_prop(q, which);
1686 	if (!p)
1687 		return false;
1688 
1689 	assert(p->type == PT_TUPLES);
1690 	*tuples = &p->value.tuples;
1691 
1692 	return true;
1693 }
1694 
1695 bool
quirks_get_uint32_array(struct quirks * q,enum quirk which,const uint32_t ** array,size_t * nelements)1696 quirks_get_uint32_array(struct quirks *q,
1697 			enum quirk which,
1698 			const uint32_t **array,
1699 			size_t *nelements)
1700 {
1701 	struct property *p;
1702 
1703 	if (!q)
1704 		return false;
1705 
1706 	p = quirk_find_prop(q, which);
1707 	if (!p)
1708 		return false;
1709 
1710 	assert(p->type == PT_UINT_ARRAY);
1711 	*array = p->value.array.data.u;
1712 	*nelements = p->value.array.nelements;
1713 
1714 	return true;
1715 }
1716