1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // kselftest for the ALSA mixer API
4 //
5 // Original author: Mark Brown <broonie@kernel.org>
6 // Copyright (c) 2021-2 Arm Limited
7 
8 // This test will iterate over all cards detected in the system, exercising
9 // every mixer control it can find.  This may conflict with other system
10 // software if there is audio activity so is best run on a system with a
11 // minimal active userspace.
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <stdbool.h>
16 #include <limits.h>
17 #include <string.h>
18 #include <getopt.h>
19 #include <stdarg.h>
20 #include <ctype.h>
21 #include <math.h>
22 #include <errno.h>
23 #include <assert.h>
24 #include <alsa/asoundlib.h>
25 #include <poll.h>
26 #include <stdint.h>
27 
28 #include "../kselftest.h"
29 #include "alsa-local.h"
30 
31 #define TESTS_PER_CONTROL 7
32 
33 struct card_data {
34 	snd_ctl_t *handle;
35 	int card;
36 	struct pollfd pollfd;
37 	int num_ctls;
38 	snd_ctl_elem_list_t *ctls;
39 	struct card_data *next;
40 };
41 
42 struct ctl_data {
43 	const char *name;
44 	snd_ctl_elem_id_t *id;
45 	snd_ctl_elem_info_t *info;
46 	snd_ctl_elem_value_t *def_val;
47 	int elem;
48 	int event_missing;
49 	int event_spurious;
50 	struct card_data *card;
51 	struct ctl_data *next;
52 };
53 
54 int num_cards = 0;
55 int num_controls = 0;
56 struct card_data *card_list = NULL;
57 struct ctl_data *ctl_list = NULL;
58 
find_controls(void)59 static void find_controls(void)
60 {
61 	char name[32];
62 	int card, ctl, err;
63 	struct card_data *card_data;
64 	struct ctl_data *ctl_data;
65 	snd_config_t *config;
66 	char *card_name, *card_longname;
67 
68 	card = -1;
69 	if (snd_card_next(&card) < 0 || card < 0)
70 		return;
71 
72 	config = get_alsalib_config();
73 
74 	while (card >= 0) {
75 		sprintf(name, "hw:%d", card);
76 
77 		card_data = malloc(sizeof(*card_data));
78 		if (!card_data)
79 			ksft_exit_fail_msg("Out of memory\n");
80 
81 		err = snd_ctl_open_lconf(&card_data->handle, name, 0, config);
82 		if (err < 0) {
83 			ksft_print_msg("Failed to get hctl for card %d: %s\n",
84 				       card, snd_strerror(err));
85 			goto next_card;
86 		}
87 
88 		err = snd_card_get_name(card, &card_name);
89 		if (err != 0)
90 			card_name = "Unknown";
91 		err = snd_card_get_longname(card, &card_longname);
92 		if (err != 0)
93 			card_longname = "Unknown";
94 		ksft_print_msg("Card %d - %s (%s)\n", card,
95 			       card_name, card_longname);
96 
97 		/* Count controls */
98 		snd_ctl_elem_list_malloc(&card_data->ctls);
99 		snd_ctl_elem_list(card_data->handle, card_data->ctls);
100 		card_data->num_ctls = snd_ctl_elem_list_get_count(card_data->ctls);
101 
102 		/* Enumerate control information */
103 		snd_ctl_elem_list_alloc_space(card_data->ctls, card_data->num_ctls);
104 		snd_ctl_elem_list(card_data->handle, card_data->ctls);
105 
106 		card_data->card = num_cards++;
107 		card_data->next = card_list;
108 		card_list = card_data;
109 
110 		num_controls += card_data->num_ctls;
111 
112 		for (ctl = 0; ctl < card_data->num_ctls; ctl++) {
113 			ctl_data = malloc(sizeof(*ctl_data));
114 			if (!ctl_data)
115 				ksft_exit_fail_msg("Out of memory\n");
116 
117 			memset(ctl_data, 0, sizeof(*ctl_data));
118 			ctl_data->card = card_data;
119 			ctl_data->elem = ctl;
120 			ctl_data->name = snd_ctl_elem_list_get_name(card_data->ctls,
121 								    ctl);
122 
123 			err = snd_ctl_elem_id_malloc(&ctl_data->id);
124 			if (err < 0)
125 				ksft_exit_fail_msg("Out of memory\n");
126 
127 			err = snd_ctl_elem_info_malloc(&ctl_data->info);
128 			if (err < 0)
129 				ksft_exit_fail_msg("Out of memory\n");
130 
131 			err = snd_ctl_elem_value_malloc(&ctl_data->def_val);
132 			if (err < 0)
133 				ksft_exit_fail_msg("Out of memory\n");
134 
135 			snd_ctl_elem_list_get_id(card_data->ctls, ctl,
136 						 ctl_data->id);
137 			snd_ctl_elem_info_set_id(ctl_data->info, ctl_data->id);
138 			err = snd_ctl_elem_info(card_data->handle,
139 						ctl_data->info);
140 			if (err < 0) {
141 				ksft_print_msg("%s getting info for %s\n",
142 					       snd_strerror(err),
143 					       ctl_data->name);
144 			}
145 
146 			snd_ctl_elem_value_set_id(ctl_data->def_val,
147 						  ctl_data->id);
148 
149 			ctl_data->next = ctl_list;
150 			ctl_list = ctl_data;
151 		}
152 
153 		/* Set up for events */
154 		err = snd_ctl_subscribe_events(card_data->handle, true);
155 		if (err < 0) {
156 			ksft_exit_fail_msg("snd_ctl_subscribe_events() failed for card %d: %d\n",
157 					   card, err);
158 		}
159 
160 		err = snd_ctl_poll_descriptors_count(card_data->handle);
161 		if (err != 1) {
162 			ksft_exit_fail_msg("Unexpected descriptor count %d for card %d\n",
163 					   err, card);
164 		}
165 
166 		err = snd_ctl_poll_descriptors(card_data->handle,
167 					       &card_data->pollfd, 1);
168 		if (err != 1) {
169 			ksft_exit_fail_msg("snd_ctl_poll_descriptors() failed for card %d: %d\n",
170 				       card, err);
171 		}
172 
173 	next_card:
174 		if (snd_card_next(&card) < 0) {
175 			ksft_print_msg("snd_card_next");
176 			break;
177 		}
178 	}
179 
180 	snd_config_delete(config);
181 }
182 
183 /*
184  * Block for up to timeout ms for an event, returns a negative value
185  * on error, 0 for no event and 1 for an event.
186  */
wait_for_event(struct ctl_data * ctl,int timeout)187 static int wait_for_event(struct ctl_data *ctl, int timeout)
188 {
189 	unsigned short revents;
190 	snd_ctl_event_t *event;
191 	int err;
192 	unsigned int mask = 0;
193 	unsigned int ev_id;
194 
195 	snd_ctl_event_alloca(&event);
196 
197 	do {
198 		err = poll(&(ctl->card->pollfd), 1, timeout);
199 		if (err < 0) {
200 			ksft_print_msg("poll() failed for %s: %s (%d)\n",
201 				       ctl->name, strerror(errno), errno);
202 			return -1;
203 		}
204 		/* Timeout */
205 		if (err == 0)
206 			return 0;
207 
208 		err = snd_ctl_poll_descriptors_revents(ctl->card->handle,
209 						       &(ctl->card->pollfd),
210 						       1, &revents);
211 		if (err < 0) {
212 			ksft_print_msg("snd_ctl_poll_descriptors_revents() failed for %s: %d\n",
213 				       ctl->name, err);
214 			return err;
215 		}
216 		if (revents & POLLERR) {
217 			ksft_print_msg("snd_ctl_poll_descriptors_revents() reported POLLERR for %s\n",
218 				       ctl->name);
219 			return -1;
220 		}
221 		/* No read events */
222 		if (!(revents & POLLIN)) {
223 			ksft_print_msg("No POLLIN\n");
224 			continue;
225 		}
226 
227 		err = snd_ctl_read(ctl->card->handle, event);
228 		if (err < 0) {
229 			ksft_print_msg("snd_ctl_read() failed for %s: %d\n",
230 			       ctl->name, err);
231 			return err;
232 		}
233 
234 		if (snd_ctl_event_get_type(event) != SND_CTL_EVENT_ELEM)
235 			continue;
236 
237 		/* The ID returned from the event is 1 less than numid */
238 		mask = snd_ctl_event_elem_get_mask(event);
239 		ev_id = snd_ctl_event_elem_get_numid(event);
240 		if (ev_id != snd_ctl_elem_info_get_numid(ctl->info)) {
241 			ksft_print_msg("Event for unexpected ctl %s\n",
242 				       snd_ctl_event_elem_get_name(event));
243 			continue;
244 		}
245 
246 		if ((mask & SND_CTL_EVENT_MASK_REMOVE) == SND_CTL_EVENT_MASK_REMOVE) {
247 			ksft_print_msg("Removal event for %s\n",
248 				       ctl->name);
249 			return -1;
250 		}
251 	} while ((mask & SND_CTL_EVENT_MASK_VALUE) != SND_CTL_EVENT_MASK_VALUE);
252 
253 	return 1;
254 }
255 
ctl_value_index_valid(struct ctl_data * ctl,snd_ctl_elem_value_t * val,int index)256 static bool ctl_value_index_valid(struct ctl_data *ctl,
257 				  snd_ctl_elem_value_t *val,
258 				  int index)
259 {
260 	long int_val;
261 	long long int64_val;
262 
263 	switch (snd_ctl_elem_info_get_type(ctl->info)) {
264 	case SND_CTL_ELEM_TYPE_NONE:
265 		ksft_print_msg("%s.%d Invalid control type NONE\n",
266 			       ctl->name, index);
267 		return false;
268 
269 	case SND_CTL_ELEM_TYPE_BOOLEAN:
270 		int_val = snd_ctl_elem_value_get_boolean(val, index);
271 		switch (int_val) {
272 		case 0:
273 		case 1:
274 			break;
275 		default:
276 			ksft_print_msg("%s.%d Invalid boolean value %ld\n",
277 				       ctl->name, index, int_val);
278 			return false;
279 		}
280 		break;
281 
282 	case SND_CTL_ELEM_TYPE_INTEGER:
283 		int_val = snd_ctl_elem_value_get_integer(val, index);
284 
285 		if (int_val < snd_ctl_elem_info_get_min(ctl->info)) {
286 			ksft_print_msg("%s.%d value %ld less than minimum %ld\n",
287 				       ctl->name, index, int_val,
288 				       snd_ctl_elem_info_get_min(ctl->info));
289 			return false;
290 		}
291 
292 		if (int_val > snd_ctl_elem_info_get_max(ctl->info)) {
293 			ksft_print_msg("%s.%d value %ld more than maximum %ld\n",
294 				       ctl->name, index, int_val,
295 				       snd_ctl_elem_info_get_max(ctl->info));
296 			return false;
297 		}
298 
299 		/* Only check step size if there is one and we're in bounds */
300 		if (snd_ctl_elem_info_get_step(ctl->info) &&
301 		    (int_val - snd_ctl_elem_info_get_min(ctl->info) %
302 		     snd_ctl_elem_info_get_step(ctl->info))) {
303 			ksft_print_msg("%s.%d value %ld invalid for step %ld minimum %ld\n",
304 				       ctl->name, index, int_val,
305 				       snd_ctl_elem_info_get_step(ctl->info),
306 				       snd_ctl_elem_info_get_min(ctl->info));
307 			return false;
308 		}
309 		break;
310 
311 	case SND_CTL_ELEM_TYPE_INTEGER64:
312 		int64_val = snd_ctl_elem_value_get_integer64(val, index);
313 
314 		if (int64_val < snd_ctl_elem_info_get_min64(ctl->info)) {
315 			ksft_print_msg("%s.%d value %lld less than minimum %lld\n",
316 				       ctl->name, index, int64_val,
317 				       snd_ctl_elem_info_get_min64(ctl->info));
318 			return false;
319 		}
320 
321 		if (int64_val > snd_ctl_elem_info_get_max64(ctl->info)) {
322 			ksft_print_msg("%s.%d value %lld more than maximum %ld\n",
323 				       ctl->name, index, int64_val,
324 				       snd_ctl_elem_info_get_max(ctl->info));
325 			return false;
326 		}
327 
328 		/* Only check step size if there is one and we're in bounds */
329 		if (snd_ctl_elem_info_get_step64(ctl->info) &&
330 		    (int64_val - snd_ctl_elem_info_get_min64(ctl->info)) %
331 		    snd_ctl_elem_info_get_step64(ctl->info)) {
332 			ksft_print_msg("%s.%d value %lld invalid for step %lld minimum %lld\n",
333 				       ctl->name, index, int64_val,
334 				       snd_ctl_elem_info_get_step64(ctl->info),
335 				       snd_ctl_elem_info_get_min64(ctl->info));
336 			return false;
337 		}
338 		break;
339 
340 	case SND_CTL_ELEM_TYPE_ENUMERATED:
341 		int_val = snd_ctl_elem_value_get_enumerated(val, index);
342 
343 		if (int_val < 0) {
344 			ksft_print_msg("%s.%d negative value %ld for enumeration\n",
345 				       ctl->name, index, int_val);
346 			return false;
347 		}
348 
349 		if (int_val >= snd_ctl_elem_info_get_items(ctl->info)) {
350 			ksft_print_msg("%s.%d value %ld more than item count %ld\n",
351 				       ctl->name, index, int_val,
352 				       snd_ctl_elem_info_get_items(ctl->info));
353 			return false;
354 		}
355 		break;
356 
357 	default:
358 		/* No tests for other types */
359 		break;
360 	}
361 
362 	return true;
363 }
364 
365 /*
366  * Check that the provided value meets the constraints for the
367  * provided control.
368  */
ctl_value_valid(struct ctl_data * ctl,snd_ctl_elem_value_t * val)369 static bool ctl_value_valid(struct ctl_data *ctl, snd_ctl_elem_value_t *val)
370 {
371 	int i;
372 	bool valid = true;
373 
374 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++)
375 		if (!ctl_value_index_valid(ctl, val, i))
376 			valid = false;
377 
378 	return valid;
379 }
380 
381 /*
382  * Check that we can read the default value and it is valid. Write
383  * tests use the read value to restore the default.
384  */
test_ctl_get_value(struct ctl_data * ctl)385 static void test_ctl_get_value(struct ctl_data *ctl)
386 {
387 	int err;
388 
389 	/* If the control is turned off let's be polite */
390 	if (snd_ctl_elem_info_is_inactive(ctl->info)) {
391 		ksft_print_msg("%s is inactive\n", ctl->name);
392 		ksft_test_result_skip("get_value.%d.%d\n",
393 				      ctl->card->card, ctl->elem);
394 		return;
395 	}
396 
397 	/* Can't test reading on an unreadable control */
398 	if (!snd_ctl_elem_info_is_readable(ctl->info)) {
399 		ksft_print_msg("%s is not readable\n", ctl->name);
400 		ksft_test_result_skip("get_value.%d.%d\n",
401 				      ctl->card->card, ctl->elem);
402 		return;
403 	}
404 
405 	err = snd_ctl_elem_read(ctl->card->handle, ctl->def_val);
406 	if (err < 0) {
407 		ksft_print_msg("snd_ctl_elem_read() failed: %s\n",
408 			       snd_strerror(err));
409 		goto out;
410 	}
411 
412 	if (!ctl_value_valid(ctl, ctl->def_val))
413 		err = -EINVAL;
414 
415 out:
416 	ksft_test_result(err >= 0, "get_value.%d.%d\n",
417 			 ctl->card->card, ctl->elem);
418 }
419 
strend(const char * haystack,const char * needle)420 static bool strend(const char *haystack, const char *needle)
421 {
422 	size_t haystack_len = strlen(haystack);
423 	size_t needle_len = strlen(needle);
424 
425 	if (needle_len > haystack_len)
426 		return false;
427 	return strcmp(haystack + haystack_len - needle_len, needle) == 0;
428 }
429 
test_ctl_name(struct ctl_data * ctl)430 static void test_ctl_name(struct ctl_data *ctl)
431 {
432 	bool name_ok = true;
433 
434 	ksft_print_msg("%d.%d %s\n", ctl->card->card, ctl->elem,
435 		       ctl->name);
436 
437 	/* Only boolean controls should end in Switch */
438 	if (strend(ctl->name, " Switch")) {
439 		if (snd_ctl_elem_info_get_type(ctl->info) != SND_CTL_ELEM_TYPE_BOOLEAN) {
440 			ksft_print_msg("%d.%d %s ends in Switch but is not boolean\n",
441 				       ctl->card->card, ctl->elem, ctl->name);
442 			name_ok = false;
443 		}
444 	}
445 
446 	/* Writeable boolean controls should end in Switch */
447 	if (snd_ctl_elem_info_get_type(ctl->info) == SND_CTL_ELEM_TYPE_BOOLEAN &&
448 	    snd_ctl_elem_info_is_writable(ctl->info)) {
449 		if (!strend(ctl->name, " Switch")) {
450 			ksft_print_msg("%d.%d %s is a writeable boolean but not a Switch\n",
451 				       ctl->card->card, ctl->elem, ctl->name);
452 			name_ok = false;
453 		}
454 	}
455 
456 	ksft_test_result(name_ok, "name.%d.%d\n",
457 			 ctl->card->card, ctl->elem);
458 }
459 
show_values(struct ctl_data * ctl,snd_ctl_elem_value_t * orig_val,snd_ctl_elem_value_t * read_val)460 static void show_values(struct ctl_data *ctl, snd_ctl_elem_value_t *orig_val,
461 			snd_ctl_elem_value_t *read_val)
462 {
463 	long long orig_int, read_int;
464 	int i;
465 
466 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
467 		switch (snd_ctl_elem_info_get_type(ctl->info)) {
468 		case SND_CTL_ELEM_TYPE_BOOLEAN:
469 			orig_int = snd_ctl_elem_value_get_boolean(orig_val, i);
470 			read_int = snd_ctl_elem_value_get_boolean(read_val, i);
471 			break;
472 
473 		case SND_CTL_ELEM_TYPE_INTEGER:
474 			orig_int = snd_ctl_elem_value_get_integer(orig_val, i);
475 			read_int = snd_ctl_elem_value_get_integer(read_val, i);
476 			break;
477 
478 		case SND_CTL_ELEM_TYPE_INTEGER64:
479 			orig_int = snd_ctl_elem_value_get_integer64(orig_val,
480 								    i);
481 			read_int = snd_ctl_elem_value_get_integer64(read_val,
482 								    i);
483 			break;
484 
485 		case SND_CTL_ELEM_TYPE_ENUMERATED:
486 			orig_int = snd_ctl_elem_value_get_enumerated(orig_val,
487 								     i);
488 			read_int = snd_ctl_elem_value_get_enumerated(read_val,
489 								     i);
490 			break;
491 
492 		default:
493 			return;
494 		}
495 
496 		ksft_print_msg("%s.%d orig %lld read %lld, is_volatile %d\n",
497 			       ctl->name, i, orig_int, read_int,
498 			       snd_ctl_elem_info_is_volatile(ctl->info));
499 	}
500 }
501 
show_mismatch(struct ctl_data * ctl,int index,snd_ctl_elem_value_t * read_val,snd_ctl_elem_value_t * expected_val)502 static bool show_mismatch(struct ctl_data *ctl, int index,
503 			  snd_ctl_elem_value_t *read_val,
504 			  snd_ctl_elem_value_t *expected_val)
505 {
506 	long long expected_int, read_int;
507 
508 	/*
509 	 * We factor out the code to compare values representable as
510 	 * integers, ensure that check doesn't log otherwise.
511 	 */
512 	expected_int = 0;
513 	read_int = 0;
514 
515 	switch (snd_ctl_elem_info_get_type(ctl->info)) {
516 	case SND_CTL_ELEM_TYPE_BOOLEAN:
517 		expected_int = snd_ctl_elem_value_get_boolean(expected_val,
518 							      index);
519 		read_int = snd_ctl_elem_value_get_boolean(read_val, index);
520 		break;
521 
522 	case SND_CTL_ELEM_TYPE_INTEGER:
523 		expected_int = snd_ctl_elem_value_get_integer(expected_val,
524 							      index);
525 		read_int = snd_ctl_elem_value_get_integer(read_val, index);
526 		break;
527 
528 	case SND_CTL_ELEM_TYPE_INTEGER64:
529 		expected_int = snd_ctl_elem_value_get_integer64(expected_val,
530 								index);
531 		read_int = snd_ctl_elem_value_get_integer64(read_val,
532 							    index);
533 		break;
534 
535 	case SND_CTL_ELEM_TYPE_ENUMERATED:
536 		expected_int = snd_ctl_elem_value_get_enumerated(expected_val,
537 								 index);
538 		read_int = snd_ctl_elem_value_get_enumerated(read_val,
539 							     index);
540 		break;
541 
542 	default:
543 		break;
544 	}
545 
546 	if (expected_int != read_int) {
547 		/*
548 		 * NOTE: The volatile attribute means that the hardware
549 		 * can voluntarily change the state of control element
550 		 * independent of any operation by software.
551 		 */
552 		bool is_volatile = snd_ctl_elem_info_is_volatile(ctl->info);
553 		ksft_print_msg("%s.%d expected %lld but read %lld, is_volatile %d\n",
554 			       ctl->name, index, expected_int, read_int, is_volatile);
555 		return !is_volatile;
556 	} else {
557 		return false;
558 	}
559 }
560 
561 /*
562  * Write a value then if possible verify that we get the expected
563  * result.  An optional expected value can be provided if we expect
564  * the write to fail, for verifying that invalid writes don't corrupt
565  * anything.
566  */
write_and_verify(struct ctl_data * ctl,snd_ctl_elem_value_t * write_val,snd_ctl_elem_value_t * expected_val)567 static int write_and_verify(struct ctl_data *ctl,
568 			    snd_ctl_elem_value_t *write_val,
569 			    snd_ctl_elem_value_t *expected_val)
570 {
571 	int err, i;
572 	bool error_expected, mismatch_shown;
573 	snd_ctl_elem_value_t *initial_val, *read_val, *w_val;
574 	snd_ctl_elem_value_alloca(&initial_val);
575 	snd_ctl_elem_value_alloca(&read_val);
576 	snd_ctl_elem_value_alloca(&w_val);
577 
578 	/*
579 	 * We need to copy the write value since writing can modify
580 	 * the value which causes surprises, and allocate an expected
581 	 * value if we expect to read back what we wrote.
582 	 */
583 	snd_ctl_elem_value_copy(w_val, write_val);
584 	if (expected_val) {
585 		error_expected = true;
586 	} else {
587 		error_expected = false;
588 		snd_ctl_elem_value_alloca(&expected_val);
589 		snd_ctl_elem_value_copy(expected_val, write_val);
590 	}
591 
592 	/* Store the value before we write */
593 	if (snd_ctl_elem_info_is_readable(ctl->info)) {
594 		snd_ctl_elem_value_set_id(initial_val, ctl->id);
595 
596 		err = snd_ctl_elem_read(ctl->card->handle, initial_val);
597 		if (err < 0) {
598 			ksft_print_msg("snd_ctl_elem_read() failed: %s\n",
599 				       snd_strerror(err));
600 			return err;
601 		}
602 	}
603 
604 	/*
605 	 * Do the write, if we have an expected value ignore the error
606 	 * and carry on to validate the expected value.
607 	 */
608 	err = snd_ctl_elem_write(ctl->card->handle, w_val);
609 	if (err < 0 && !error_expected) {
610 		ksft_print_msg("snd_ctl_elem_write() failed: %s\n",
611 			       snd_strerror(err));
612 		return err;
613 	}
614 
615 	/* Can we do the verification part? */
616 	if (!snd_ctl_elem_info_is_readable(ctl->info))
617 		return err;
618 
619 	snd_ctl_elem_value_set_id(read_val, ctl->id);
620 
621 	err = snd_ctl_elem_read(ctl->card->handle, read_val);
622 	if (err < 0) {
623 		ksft_print_msg("snd_ctl_elem_read() failed: %s\n",
624 			       snd_strerror(err));
625 		return err;
626 	}
627 
628 	/*
629 	 * Check for an event if the value changed, or confirm that
630 	 * there was none if it didn't.  We rely on the kernel
631 	 * generating the notification before it returns from the
632 	 * write, this is currently true, should that ever change this
633 	 * will most likely break and need updating.
634 	 */
635 	if (!snd_ctl_elem_info_is_volatile(ctl->info)) {
636 		err = wait_for_event(ctl, 0);
637 		if (snd_ctl_elem_value_compare(initial_val, read_val)) {
638 			if (err < 1) {
639 				ksft_print_msg("No event generated for %s\n",
640 					       ctl->name);
641 				show_values(ctl, initial_val, read_val);
642 				ctl->event_missing++;
643 			}
644 		} else {
645 			if (err != 0) {
646 				ksft_print_msg("Spurious event generated for %s\n",
647 					       ctl->name);
648 				show_values(ctl, initial_val, read_val);
649 				ctl->event_spurious++;
650 			}
651 		}
652 	}
653 
654 	/*
655 	 * Use the libray to compare values, if there's a mismatch
656 	 * carry on and try to provide a more useful diagnostic than
657 	 * just "mismatch".
658 	 */
659 	if (!snd_ctl_elem_value_compare(expected_val, read_val))
660 		return 0;
661 
662 	mismatch_shown = false;
663 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++)
664 		if (show_mismatch(ctl, i, read_val, expected_val))
665 			mismatch_shown = true;
666 
667 	if (!mismatch_shown)
668 		ksft_print_msg("%s read and written values differ\n",
669 			       ctl->name);
670 
671 	return -1;
672 }
673 
674 /*
675  * Make sure we can write the default value back to the control, this
676  * should validate that at least some write works.
677  */
test_ctl_write_default(struct ctl_data * ctl)678 static void test_ctl_write_default(struct ctl_data *ctl)
679 {
680 	int err;
681 
682 	/* If the control is turned off let's be polite */
683 	if (snd_ctl_elem_info_is_inactive(ctl->info)) {
684 		ksft_print_msg("%s is inactive\n", ctl->name);
685 		ksft_test_result_skip("write_default.%d.%d\n",
686 				      ctl->card->card, ctl->elem);
687 		return;
688 	}
689 
690 	if (!snd_ctl_elem_info_is_writable(ctl->info)) {
691 		ksft_print_msg("%s is not writeable\n", ctl->name);
692 		ksft_test_result_skip("write_default.%d.%d\n",
693 				      ctl->card->card, ctl->elem);
694 		return;
695 	}
696 
697 	/* No idea what the default was for unreadable controls */
698 	if (!snd_ctl_elem_info_is_readable(ctl->info)) {
699 		ksft_print_msg("%s couldn't read default\n", ctl->name);
700 		ksft_test_result_skip("write_default.%d.%d\n",
701 				      ctl->card->card, ctl->elem);
702 		return;
703 	}
704 
705 	err = write_and_verify(ctl, ctl->def_val, NULL);
706 
707 	ksft_test_result(err >= 0, "write_default.%d.%d\n",
708 			 ctl->card->card, ctl->elem);
709 }
710 
test_ctl_write_valid_boolean(struct ctl_data * ctl)711 static bool test_ctl_write_valid_boolean(struct ctl_data *ctl)
712 {
713 	int err, i, j;
714 	bool fail = false;
715 	snd_ctl_elem_value_t *val;
716 	snd_ctl_elem_value_alloca(&val);
717 
718 	snd_ctl_elem_value_set_id(val, ctl->id);
719 
720 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
721 		for (j = 0; j < 2; j++) {
722 			snd_ctl_elem_value_set_boolean(val, i, j);
723 			err = write_and_verify(ctl, val, NULL);
724 			if (err != 0)
725 				fail = true;
726 		}
727 	}
728 
729 	return !fail;
730 }
731 
test_ctl_write_valid_integer(struct ctl_data * ctl)732 static bool test_ctl_write_valid_integer(struct ctl_data *ctl)
733 {
734 	int err;
735 	int i;
736 	long j, step;
737 	bool fail = false;
738 	snd_ctl_elem_value_t *val;
739 	snd_ctl_elem_value_alloca(&val);
740 
741 	snd_ctl_elem_value_set_id(val, ctl->id);
742 
743 	step = snd_ctl_elem_info_get_step(ctl->info);
744 	if (!step)
745 		step = 1;
746 
747 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
748 		for (j = snd_ctl_elem_info_get_min(ctl->info);
749 		     j <= snd_ctl_elem_info_get_max(ctl->info); j += step) {
750 
751 			snd_ctl_elem_value_set_integer(val, i, j);
752 			err = write_and_verify(ctl, val, NULL);
753 			if (err != 0)
754 				fail = true;
755 		}
756 	}
757 
758 
759 	return !fail;
760 }
761 
test_ctl_write_valid_integer64(struct ctl_data * ctl)762 static bool test_ctl_write_valid_integer64(struct ctl_data *ctl)
763 {
764 	int err, i;
765 	long long j, step;
766 	bool fail = false;
767 	snd_ctl_elem_value_t *val;
768 	snd_ctl_elem_value_alloca(&val);
769 
770 	snd_ctl_elem_value_set_id(val, ctl->id);
771 
772 	step = snd_ctl_elem_info_get_step64(ctl->info);
773 	if (!step)
774 		step = 1;
775 
776 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
777 		for (j = snd_ctl_elem_info_get_min64(ctl->info);
778 		     j <= snd_ctl_elem_info_get_max64(ctl->info); j += step) {
779 
780 			snd_ctl_elem_value_set_integer64(val, i, j);
781 			err = write_and_verify(ctl, val, NULL);
782 			if (err != 0)
783 				fail = true;
784 		}
785 	}
786 
787 	return !fail;
788 }
789 
test_ctl_write_valid_enumerated(struct ctl_data * ctl)790 static bool test_ctl_write_valid_enumerated(struct ctl_data *ctl)
791 {
792 	int err, i, j;
793 	bool fail = false;
794 	snd_ctl_elem_value_t *val;
795 	snd_ctl_elem_value_alloca(&val);
796 
797 	snd_ctl_elem_value_set_id(val, ctl->id);
798 
799 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
800 		for (j = 0; j < snd_ctl_elem_info_get_items(ctl->info); j++) {
801 			snd_ctl_elem_value_set_enumerated(val, i, j);
802 			err = write_and_verify(ctl, val, NULL);
803 			if (err != 0)
804 				fail = true;
805 		}
806 	}
807 
808 	return !fail;
809 }
810 
test_ctl_write_valid(struct ctl_data * ctl)811 static void test_ctl_write_valid(struct ctl_data *ctl)
812 {
813 	bool pass;
814 
815 	/* If the control is turned off let's be polite */
816 	if (snd_ctl_elem_info_is_inactive(ctl->info)) {
817 		ksft_print_msg("%s is inactive\n", ctl->name);
818 		ksft_test_result_skip("write_valid.%d.%d\n",
819 				      ctl->card->card, ctl->elem);
820 		return;
821 	}
822 
823 	if (!snd_ctl_elem_info_is_writable(ctl->info)) {
824 		ksft_print_msg("%s is not writeable\n", ctl->name);
825 		ksft_test_result_skip("write_valid.%d.%d\n",
826 				      ctl->card->card, ctl->elem);
827 		return;
828 	}
829 
830 	switch (snd_ctl_elem_info_get_type(ctl->info)) {
831 	case SND_CTL_ELEM_TYPE_BOOLEAN:
832 		pass = test_ctl_write_valid_boolean(ctl);
833 		break;
834 
835 	case SND_CTL_ELEM_TYPE_INTEGER:
836 		pass = test_ctl_write_valid_integer(ctl);
837 		break;
838 
839 	case SND_CTL_ELEM_TYPE_INTEGER64:
840 		pass = test_ctl_write_valid_integer64(ctl);
841 		break;
842 
843 	case SND_CTL_ELEM_TYPE_ENUMERATED:
844 		pass = test_ctl_write_valid_enumerated(ctl);
845 		break;
846 
847 	default:
848 		/* No tests for this yet */
849 		ksft_test_result_skip("write_valid.%d.%d\n",
850 				      ctl->card->card, ctl->elem);
851 		return;
852 	}
853 
854 	/* Restore the default value to minimise disruption */
855 	write_and_verify(ctl, ctl->def_val, NULL);
856 
857 	ksft_test_result(pass, "write_valid.%d.%d\n",
858 			 ctl->card->card, ctl->elem);
859 }
860 
test_ctl_write_invalid_value(struct ctl_data * ctl,snd_ctl_elem_value_t * val)861 static bool test_ctl_write_invalid_value(struct ctl_data *ctl,
862 					 snd_ctl_elem_value_t *val)
863 {
864 	int err;
865 
866 	/* Ideally this will fail... */
867 	err = snd_ctl_elem_write(ctl->card->handle, val);
868 	if (err < 0)
869 		return false;
870 
871 	/* ...but some devices will clamp to an in range value */
872 	err = snd_ctl_elem_read(ctl->card->handle, val);
873 	if (err < 0) {
874 		ksft_print_msg("%s failed to read: %s\n",
875 			       ctl->name, snd_strerror(err));
876 		return true;
877 	}
878 
879 	return !ctl_value_valid(ctl, val);
880 }
881 
test_ctl_write_invalid_boolean(struct ctl_data * ctl)882 static bool test_ctl_write_invalid_boolean(struct ctl_data *ctl)
883 {
884 	int i;
885 	bool fail = false;
886 	snd_ctl_elem_value_t *val;
887 	snd_ctl_elem_value_alloca(&val);
888 
889 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
890 		snd_ctl_elem_value_copy(val, ctl->def_val);
891 		snd_ctl_elem_value_set_boolean(val, i, 2);
892 
893 		if (test_ctl_write_invalid_value(ctl, val))
894 			fail = true;
895 	}
896 
897 	return !fail;
898 }
899 
test_ctl_write_invalid_integer(struct ctl_data * ctl)900 static bool test_ctl_write_invalid_integer(struct ctl_data *ctl)
901 {
902 	int i;
903 	bool fail = false;
904 	snd_ctl_elem_value_t *val;
905 	snd_ctl_elem_value_alloca(&val);
906 
907 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
908 		if (snd_ctl_elem_info_get_min(ctl->info) != LONG_MIN) {
909 			/* Just under range */
910 			snd_ctl_elem_value_copy(val, ctl->def_val);
911 			snd_ctl_elem_value_set_integer(val, i,
912 			       snd_ctl_elem_info_get_min(ctl->info) - 1);
913 
914 			if (test_ctl_write_invalid_value(ctl, val))
915 				fail = true;
916 
917 			/* Minimum representable value */
918 			snd_ctl_elem_value_copy(val, ctl->def_val);
919 			snd_ctl_elem_value_set_integer(val, i, LONG_MIN);
920 
921 			if (test_ctl_write_invalid_value(ctl, val))
922 				fail = true;
923 		}
924 
925 		if (snd_ctl_elem_info_get_max(ctl->info) != LONG_MAX) {
926 			/* Just over range */
927 			snd_ctl_elem_value_copy(val, ctl->def_val);
928 			snd_ctl_elem_value_set_integer(val, i,
929 			       snd_ctl_elem_info_get_max(ctl->info) + 1);
930 
931 			if (test_ctl_write_invalid_value(ctl, val))
932 				fail = true;
933 
934 			/* Maximum representable value */
935 			snd_ctl_elem_value_copy(val, ctl->def_val);
936 			snd_ctl_elem_value_set_integer(val, i, LONG_MAX);
937 
938 			if (test_ctl_write_invalid_value(ctl, val))
939 				fail = true;
940 		}
941 	}
942 
943 	return !fail;
944 }
945 
test_ctl_write_invalid_integer64(struct ctl_data * ctl)946 static bool test_ctl_write_invalid_integer64(struct ctl_data *ctl)
947 {
948 	int i;
949 	bool fail = false;
950 	snd_ctl_elem_value_t *val;
951 	snd_ctl_elem_value_alloca(&val);
952 
953 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
954 		if (snd_ctl_elem_info_get_min64(ctl->info) != LLONG_MIN) {
955 			/* Just under range */
956 			snd_ctl_elem_value_copy(val, ctl->def_val);
957 			snd_ctl_elem_value_set_integer64(val, i,
958 				snd_ctl_elem_info_get_min64(ctl->info) - 1);
959 
960 			if (test_ctl_write_invalid_value(ctl, val))
961 				fail = true;
962 
963 			/* Minimum representable value */
964 			snd_ctl_elem_value_copy(val, ctl->def_val);
965 			snd_ctl_elem_value_set_integer64(val, i, LLONG_MIN);
966 
967 			if (test_ctl_write_invalid_value(ctl, val))
968 				fail = true;
969 		}
970 
971 		if (snd_ctl_elem_info_get_max64(ctl->info) != LLONG_MAX) {
972 			/* Just over range */
973 			snd_ctl_elem_value_copy(val, ctl->def_val);
974 			snd_ctl_elem_value_set_integer64(val, i,
975 				snd_ctl_elem_info_get_max64(ctl->info) + 1);
976 
977 			if (test_ctl_write_invalid_value(ctl, val))
978 				fail = true;
979 
980 			/* Maximum representable value */
981 			snd_ctl_elem_value_copy(val, ctl->def_val);
982 			snd_ctl_elem_value_set_integer64(val, i, LLONG_MAX);
983 
984 			if (test_ctl_write_invalid_value(ctl, val))
985 				fail = true;
986 		}
987 	}
988 
989 	return !fail;
990 }
991 
test_ctl_write_invalid_enumerated(struct ctl_data * ctl)992 static bool test_ctl_write_invalid_enumerated(struct ctl_data *ctl)
993 {
994 	int i;
995 	bool fail = false;
996 	snd_ctl_elem_value_t *val;
997 	snd_ctl_elem_value_alloca(&val);
998 
999 	snd_ctl_elem_value_set_id(val, ctl->id);
1000 
1001 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
1002 		/* One beyond maximum */
1003 		snd_ctl_elem_value_copy(val, ctl->def_val);
1004 		snd_ctl_elem_value_set_enumerated(val, i,
1005 				  snd_ctl_elem_info_get_items(ctl->info));
1006 
1007 		if (test_ctl_write_invalid_value(ctl, val))
1008 			fail = true;
1009 
1010 		/* Maximum representable value */
1011 		snd_ctl_elem_value_copy(val, ctl->def_val);
1012 		snd_ctl_elem_value_set_enumerated(val, i, UINT_MAX);
1013 
1014 		if (test_ctl_write_invalid_value(ctl, val))
1015 			fail = true;
1016 
1017 	}
1018 
1019 	return !fail;
1020 }
1021 
1022 
test_ctl_write_invalid(struct ctl_data * ctl)1023 static void test_ctl_write_invalid(struct ctl_data *ctl)
1024 {
1025 	bool pass;
1026 
1027 	/* If the control is turned off let's be polite */
1028 	if (snd_ctl_elem_info_is_inactive(ctl->info)) {
1029 		ksft_print_msg("%s is inactive\n", ctl->name);
1030 		ksft_test_result_skip("write_invalid.%d.%d\n",
1031 				      ctl->card->card, ctl->elem);
1032 		return;
1033 	}
1034 
1035 	if (!snd_ctl_elem_info_is_writable(ctl->info)) {
1036 		ksft_print_msg("%s is not writeable\n", ctl->name);
1037 		ksft_test_result_skip("write_invalid.%d.%d\n",
1038 				      ctl->card->card, ctl->elem);
1039 		return;
1040 	}
1041 
1042 	switch (snd_ctl_elem_info_get_type(ctl->info)) {
1043 	case SND_CTL_ELEM_TYPE_BOOLEAN:
1044 		pass = test_ctl_write_invalid_boolean(ctl);
1045 		break;
1046 
1047 	case SND_CTL_ELEM_TYPE_INTEGER:
1048 		pass = test_ctl_write_invalid_integer(ctl);
1049 		break;
1050 
1051 	case SND_CTL_ELEM_TYPE_INTEGER64:
1052 		pass = test_ctl_write_invalid_integer64(ctl);
1053 		break;
1054 
1055 	case SND_CTL_ELEM_TYPE_ENUMERATED:
1056 		pass = test_ctl_write_invalid_enumerated(ctl);
1057 		break;
1058 
1059 	default:
1060 		/* No tests for this yet */
1061 		ksft_test_result_skip("write_invalid.%d.%d\n",
1062 				      ctl->card->card, ctl->elem);
1063 		return;
1064 	}
1065 
1066 	/* Restore the default value to minimise disruption */
1067 	write_and_verify(ctl, ctl->def_val, NULL);
1068 
1069 	ksft_test_result(pass, "write_invalid.%d.%d\n",
1070 			 ctl->card->card, ctl->elem);
1071 }
1072 
test_ctl_event_missing(struct ctl_data * ctl)1073 static void test_ctl_event_missing(struct ctl_data *ctl)
1074 {
1075 	ksft_test_result(!ctl->event_missing, "event_missing.%d.%d\n",
1076 			 ctl->card->card, ctl->elem);
1077 }
1078 
test_ctl_event_spurious(struct ctl_data * ctl)1079 static void test_ctl_event_spurious(struct ctl_data *ctl)
1080 {
1081 	ksft_test_result(!ctl->event_spurious, "event_spurious.%d.%d\n",
1082 			 ctl->card->card, ctl->elem);
1083 }
1084 
main(void)1085 int main(void)
1086 {
1087 	struct ctl_data *ctl;
1088 
1089 	ksft_print_header();
1090 
1091 	find_controls();
1092 
1093 	ksft_set_plan(num_controls * TESTS_PER_CONTROL);
1094 
1095 	for (ctl = ctl_list; ctl != NULL; ctl = ctl->next) {
1096 		/*
1097 		 * Must test get_value() before we write anything, the
1098 		 * test stores the default value for later cleanup.
1099 		 */
1100 		test_ctl_get_value(ctl);
1101 		test_ctl_name(ctl);
1102 		test_ctl_write_default(ctl);
1103 		test_ctl_write_valid(ctl);
1104 		test_ctl_write_invalid(ctl);
1105 		test_ctl_event_missing(ctl);
1106 		test_ctl_event_spurious(ctl);
1107 	}
1108 
1109 	ksft_exit_pass();
1110 
1111 	return 0;
1112 }
1113