powerpc/mm: Avoid calling arch_enter/leave_lazy_mmu() in set_ptes
[platform/kernel/linux-starfive.git] / tools / testing / selftests / alsa / mixer-test.c
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
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 %d\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 %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  */
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 count, 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
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 %lld\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  */
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  */
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
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
430 static void test_ctl_name(struct ctl_data *ctl)
431 {
432         bool name_ok = true;
433         bool check;
434
435         ksft_print_msg("%d.%d %s\n", ctl->card->card, ctl->elem,
436                        ctl->name);
437
438         /* Only boolean controls should end in Switch */
439         if (strend(ctl->name, " Switch")) {
440                 if (snd_ctl_elem_info_get_type(ctl->info) != SND_CTL_ELEM_TYPE_BOOLEAN) {
441                         ksft_print_msg("%d.%d %s ends in Switch but is not boolean\n",
442                                        ctl->card->card, ctl->elem, ctl->name);
443                         name_ok = false;
444                 }
445         }
446
447         /* Writeable boolean controls should end in Switch */
448         if (snd_ctl_elem_info_get_type(ctl->info) == SND_CTL_ELEM_TYPE_BOOLEAN &&
449             snd_ctl_elem_info_is_writable(ctl->info)) {
450                 if (!strend(ctl->name, " Switch")) {
451                         ksft_print_msg("%d.%d %s is a writeable boolean but not a Switch\n",
452                                        ctl->card->card, ctl->elem, ctl->name);
453                         name_ok = false;
454                 }
455         }
456
457         ksft_test_result(name_ok, "name.%d.%d\n",
458                          ctl->card->card, ctl->elem);
459 }
460
461 static void show_values(struct ctl_data *ctl, snd_ctl_elem_value_t *orig_val,
462                         snd_ctl_elem_value_t *read_val)
463 {
464         long long orig_int, read_int;
465         int i;
466
467         for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
468                 switch (snd_ctl_elem_info_get_type(ctl->info)) {
469                 case SND_CTL_ELEM_TYPE_BOOLEAN:
470                         orig_int = snd_ctl_elem_value_get_boolean(orig_val, i);
471                         read_int = snd_ctl_elem_value_get_boolean(read_val, i);
472                         break;
473
474                 case SND_CTL_ELEM_TYPE_INTEGER:
475                         orig_int = snd_ctl_elem_value_get_integer(orig_val, i);
476                         read_int = snd_ctl_elem_value_get_integer(read_val, i);
477                         break;
478
479                 case SND_CTL_ELEM_TYPE_INTEGER64:
480                         orig_int = snd_ctl_elem_value_get_integer64(orig_val,
481                                                                     i);
482                         read_int = snd_ctl_elem_value_get_integer64(read_val,
483                                                                     i);
484                         break;
485
486                 case SND_CTL_ELEM_TYPE_ENUMERATED:
487                         orig_int = snd_ctl_elem_value_get_enumerated(orig_val,
488                                                                      i);
489                         read_int = snd_ctl_elem_value_get_enumerated(read_val,
490                                                                      i);
491                         break;
492
493                 default:
494                         return;
495                 }
496
497                 ksft_print_msg("%s.%d orig %lld read %lld, is_volatile %d\n",
498                                ctl->name, i, orig_int, read_int,
499                                snd_ctl_elem_info_is_volatile(ctl->info));
500         }
501 }
502
503 static bool show_mismatch(struct ctl_data *ctl, int index,
504                           snd_ctl_elem_value_t *read_val,
505                           snd_ctl_elem_value_t *expected_val)
506 {
507         long long expected_int, read_int;
508
509         /*
510          * We factor out the code to compare values representable as
511          * integers, ensure that check doesn't log otherwise.
512          */
513         expected_int = 0;
514         read_int = 0;
515
516         switch (snd_ctl_elem_info_get_type(ctl->info)) {
517         case SND_CTL_ELEM_TYPE_BOOLEAN:
518                 expected_int = snd_ctl_elem_value_get_boolean(expected_val,
519                                                               index);
520                 read_int = snd_ctl_elem_value_get_boolean(read_val, index);
521                 break;
522
523         case SND_CTL_ELEM_TYPE_INTEGER:
524                 expected_int = snd_ctl_elem_value_get_integer(expected_val,
525                                                               index);
526                 read_int = snd_ctl_elem_value_get_integer(read_val, index);
527                 break;
528
529         case SND_CTL_ELEM_TYPE_INTEGER64:
530                 expected_int = snd_ctl_elem_value_get_integer64(expected_val,
531                                                                 index);
532                 read_int = snd_ctl_elem_value_get_integer64(read_val,
533                                                             index);
534                 break;
535
536         case SND_CTL_ELEM_TYPE_ENUMERATED:
537                 expected_int = snd_ctl_elem_value_get_enumerated(expected_val,
538                                                                  index);
539                 read_int = snd_ctl_elem_value_get_enumerated(read_val,
540                                                              index);
541                 break;
542
543         default:
544                 break;
545         }
546
547         if (expected_int != read_int) {
548                 /*
549                  * NOTE: The volatile attribute means that the hardware
550                  * can voluntarily change the state of control element
551                  * independent of any operation by software.  
552                  */
553                 bool is_volatile = snd_ctl_elem_info_is_volatile(ctl->info);
554                 ksft_print_msg("%s.%d expected %lld but read %lld, is_volatile %d\n",
555                                ctl->name, index, expected_int, read_int, is_volatile);
556                 return !is_volatile;
557         } else {
558                 return false;
559         }
560 }
561
562 /*
563  * Write a value then if possible verify that we get the expected
564  * result.  An optional expected value can be provided if we expect
565  * the write to fail, for verifying that invalid writes don't corrupt
566  * anything.
567  */
568 static int write_and_verify(struct ctl_data *ctl,
569                             snd_ctl_elem_value_t *write_val,
570                             snd_ctl_elem_value_t *expected_val)
571 {
572         int err, i;
573         bool error_expected, mismatch_shown;
574         snd_ctl_elem_value_t *initial_val, *read_val, *w_val;
575         snd_ctl_elem_value_alloca(&initial_val);
576         snd_ctl_elem_value_alloca(&read_val);
577         snd_ctl_elem_value_alloca(&w_val);
578
579         /*
580          * We need to copy the write value since writing can modify
581          * the value which causes surprises, and allocate an expected
582          * value if we expect to read back what we wrote.
583          */
584         snd_ctl_elem_value_copy(w_val, write_val);
585         if (expected_val) {
586                 error_expected = true;
587         } else {
588                 error_expected = false;
589                 snd_ctl_elem_value_alloca(&expected_val);
590                 snd_ctl_elem_value_copy(expected_val, write_val);
591         }
592
593         /* Store the value before we write */
594         if (snd_ctl_elem_info_is_readable(ctl->info)) {
595                 snd_ctl_elem_value_set_id(initial_val, ctl->id);
596
597                 err = snd_ctl_elem_read(ctl->card->handle, initial_val);
598                 if (err < 0) {
599                         ksft_print_msg("snd_ctl_elem_read() failed: %s\n",
600                                        snd_strerror(err));
601                         return err;
602                 }
603         }
604
605         /*
606          * Do the write, if we have an expected value ignore the error
607          * and carry on to validate the expected value.
608          */
609         err = snd_ctl_elem_write(ctl->card->handle, w_val);
610         if (err < 0 && !error_expected) {
611                 ksft_print_msg("snd_ctl_elem_write() failed: %s\n",
612                                snd_strerror(err));
613                 return err;
614         }
615
616         /* Can we do the verification part? */
617         if (!snd_ctl_elem_info_is_readable(ctl->info))
618                 return err;
619
620         snd_ctl_elem_value_set_id(read_val, ctl->id);
621
622         err = snd_ctl_elem_read(ctl->card->handle, read_val);
623         if (err < 0) {
624                 ksft_print_msg("snd_ctl_elem_read() failed: %s\n",
625                                snd_strerror(err));
626                 return err;
627         }
628
629         /*
630          * Check for an event if the value changed, or confirm that
631          * there was none if it didn't.  We rely on the kernel
632          * generating the notification before it returns from the
633          * write, this is currently true, should that ever change this
634          * will most likely break and need updating.
635          */
636         if (!snd_ctl_elem_info_is_volatile(ctl->info)) {
637                 err = wait_for_event(ctl, 0);
638                 if (snd_ctl_elem_value_compare(initial_val, read_val)) {
639                         if (err < 1) {
640                                 ksft_print_msg("No event generated for %s\n",
641                                                ctl->name);
642                                 show_values(ctl, initial_val, read_val);
643                                 ctl->event_missing++;
644                         }
645                 } else {
646                         if (err != 0) {
647                                 ksft_print_msg("Spurious event generated for %s\n",
648                                                ctl->name);
649                                 show_values(ctl, initial_val, read_val);
650                                 ctl->event_spurious++;
651                         }
652                 }
653         }
654
655         /*
656          * Use the libray to compare values, if there's a mismatch
657          * carry on and try to provide a more useful diagnostic than
658          * just "mismatch".
659          */
660         if (!snd_ctl_elem_value_compare(expected_val, read_val))
661                 return 0;
662
663         mismatch_shown = false;
664         for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++)
665                 if (show_mismatch(ctl, i, read_val, expected_val))
666                         mismatch_shown = true;
667
668         if (!mismatch_shown)
669                 ksft_print_msg("%s read and written values differ\n",
670                                ctl->name);
671
672         return -1;
673 }
674
675 /*
676  * Make sure we can write the default value back to the control, this
677  * should validate that at least some write works.
678  */
679 static void test_ctl_write_default(struct ctl_data *ctl)
680 {
681         int err;
682
683         /* If the control is turned off let's be polite */
684         if (snd_ctl_elem_info_is_inactive(ctl->info)) {
685                 ksft_print_msg("%s is inactive\n", ctl->name);
686                 ksft_test_result_skip("write_default.%d.%d\n",
687                                       ctl->card->card, ctl->elem);
688                 return;
689         }
690
691         if (!snd_ctl_elem_info_is_writable(ctl->info)) {
692                 ksft_print_msg("%s is not writeable\n", ctl->name);
693                 ksft_test_result_skip("write_default.%d.%d\n",
694                                       ctl->card->card, ctl->elem);
695                 return;
696         }
697
698         /* No idea what the default was for unreadable controls */
699         if (!snd_ctl_elem_info_is_readable(ctl->info)) {
700                 ksft_print_msg("%s couldn't read default\n", ctl->name);
701                 ksft_test_result_skip("write_default.%d.%d\n",
702                                       ctl->card->card, ctl->elem);
703                 return;
704         }
705
706         err = write_and_verify(ctl, ctl->def_val, NULL);
707
708         ksft_test_result(err >= 0, "write_default.%d.%d\n",
709                          ctl->card->card, ctl->elem);
710 }
711
712 static bool test_ctl_write_valid_boolean(struct ctl_data *ctl)
713 {
714         int err, i, j;
715         bool fail = false;
716         snd_ctl_elem_value_t *val;
717         snd_ctl_elem_value_alloca(&val);
718
719         snd_ctl_elem_value_set_id(val, ctl->id);
720
721         for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
722                 for (j = 0; j < 2; j++) {
723                         snd_ctl_elem_value_set_boolean(val, i, j);
724                         err = write_and_verify(ctl, val, NULL);
725                         if (err != 0)
726                                 fail = true;
727                 }
728         }
729
730         return !fail;
731 }
732
733 static bool test_ctl_write_valid_integer(struct ctl_data *ctl)
734 {
735         int err;
736         int i;
737         long j, step;
738         bool fail = false;
739         snd_ctl_elem_value_t *val;
740         snd_ctl_elem_value_alloca(&val);
741
742         snd_ctl_elem_value_set_id(val, ctl->id);
743
744         step = snd_ctl_elem_info_get_step(ctl->info);
745         if (!step)
746                 step = 1;
747
748         for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
749                 for (j = snd_ctl_elem_info_get_min(ctl->info);
750                      j <= snd_ctl_elem_info_get_max(ctl->info); j += step) {
751
752                         snd_ctl_elem_value_set_integer(val, i, j);
753                         err = write_and_verify(ctl, val, NULL);
754                         if (err != 0)
755                                 fail = true;
756                 }
757         }
758
759
760         return !fail;
761 }
762
763 static bool test_ctl_write_valid_integer64(struct ctl_data *ctl)
764 {
765         int err, i;
766         long long j, step;
767         bool fail = false;
768         snd_ctl_elem_value_t *val;
769         snd_ctl_elem_value_alloca(&val);
770
771         snd_ctl_elem_value_set_id(val, ctl->id);
772
773         step = snd_ctl_elem_info_get_step64(ctl->info);
774         if (!step)
775                 step = 1;
776
777         for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
778                 for (j = snd_ctl_elem_info_get_min64(ctl->info);
779                      j <= snd_ctl_elem_info_get_max64(ctl->info); j += step) {
780
781                         snd_ctl_elem_value_set_integer64(val, i, j);
782                         err = write_and_verify(ctl, val, NULL);
783                         if (err != 0)
784                                 fail = true;
785                 }
786         }
787
788         return !fail;
789 }
790
791 static bool test_ctl_write_valid_enumerated(struct ctl_data *ctl)
792 {
793         int err, i, j;
794         bool fail = false;
795         snd_ctl_elem_value_t *val;
796         snd_ctl_elem_value_alloca(&val);
797
798         snd_ctl_elem_value_set_id(val, ctl->id);
799
800         for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
801                 for (j = 0; j < snd_ctl_elem_info_get_items(ctl->info); j++) {
802                         snd_ctl_elem_value_set_enumerated(val, i, j);
803                         err = write_and_verify(ctl, val, NULL);
804                         if (err != 0)
805                                 fail = true;
806                 }
807         }
808
809         return !fail;
810 }
811
812 static void test_ctl_write_valid(struct ctl_data *ctl)
813 {
814         bool pass;
815
816         /* If the control is turned off let's be polite */
817         if (snd_ctl_elem_info_is_inactive(ctl->info)) {
818                 ksft_print_msg("%s is inactive\n", ctl->name);
819                 ksft_test_result_skip("write_valid.%d.%d\n",
820                                       ctl->card->card, ctl->elem);
821                 return;
822         }
823
824         if (!snd_ctl_elem_info_is_writable(ctl->info)) {
825                 ksft_print_msg("%s is not writeable\n", ctl->name);
826                 ksft_test_result_skip("write_valid.%d.%d\n",
827                                       ctl->card->card, ctl->elem);
828                 return;
829         }
830
831         switch (snd_ctl_elem_info_get_type(ctl->info)) {
832         case SND_CTL_ELEM_TYPE_BOOLEAN:
833                 pass = test_ctl_write_valid_boolean(ctl);
834                 break;
835
836         case SND_CTL_ELEM_TYPE_INTEGER:
837                 pass = test_ctl_write_valid_integer(ctl);
838                 break;
839
840         case SND_CTL_ELEM_TYPE_INTEGER64:
841                 pass = test_ctl_write_valid_integer64(ctl);
842                 break;
843
844         case SND_CTL_ELEM_TYPE_ENUMERATED:
845                 pass = test_ctl_write_valid_enumerated(ctl);
846                 break;
847
848         default:
849                 /* No tests for this yet */
850                 ksft_test_result_skip("write_valid.%d.%d\n",
851                                       ctl->card->card, ctl->elem);
852                 return;
853         }
854
855         /* Restore the default value to minimise disruption */
856         write_and_verify(ctl, ctl->def_val, NULL);
857
858         ksft_test_result(pass, "write_valid.%d.%d\n",
859                          ctl->card->card, ctl->elem);
860 }
861
862 static bool test_ctl_write_invalid_value(struct ctl_data *ctl,
863                                          snd_ctl_elem_value_t *val)
864 {
865         int err;
866         long val_read;
867
868         /* Ideally this will fail... */
869         err = snd_ctl_elem_write(ctl->card->handle, val);
870         if (err < 0)
871                 return false;
872
873         /* ...but some devices will clamp to an in range value */
874         err = snd_ctl_elem_read(ctl->card->handle, val);
875         if (err < 0) {
876                 ksft_print_msg("%s failed to read: %s\n",
877                                ctl->name, snd_strerror(err));
878                 return true;
879         }
880
881         return !ctl_value_valid(ctl, val);
882 }
883
884 static bool test_ctl_write_invalid_boolean(struct ctl_data *ctl)
885 {
886         int err, i;
887         long val_read;
888         bool fail = false;
889         snd_ctl_elem_value_t *val;
890         snd_ctl_elem_value_alloca(&val);
891
892         for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
893                 snd_ctl_elem_value_copy(val, ctl->def_val);
894                 snd_ctl_elem_value_set_boolean(val, i, 2);
895
896                 if (test_ctl_write_invalid_value(ctl, val))
897                         fail = true;
898         }
899
900         return !fail;
901 }
902
903 static bool test_ctl_write_invalid_integer(struct ctl_data *ctl)
904 {
905         int i;
906         bool fail = false;
907         snd_ctl_elem_value_t *val;
908         snd_ctl_elem_value_alloca(&val);
909
910         for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
911                 if (snd_ctl_elem_info_get_min(ctl->info) != LONG_MIN) {
912                         /* Just under range */
913                         snd_ctl_elem_value_copy(val, ctl->def_val);
914                         snd_ctl_elem_value_set_integer(val, i,
915                                snd_ctl_elem_info_get_min(ctl->info) - 1);
916
917                         if (test_ctl_write_invalid_value(ctl, val))
918                                 fail = true;
919
920                         /* Minimum representable value */
921                         snd_ctl_elem_value_copy(val, ctl->def_val);
922                         snd_ctl_elem_value_set_integer(val, i, LONG_MIN);
923
924                         if (test_ctl_write_invalid_value(ctl, val))
925                                 fail = true;
926                 }
927
928                 if (snd_ctl_elem_info_get_max(ctl->info) != LONG_MAX) {
929                         /* Just over range */
930                         snd_ctl_elem_value_copy(val, ctl->def_val);
931                         snd_ctl_elem_value_set_integer(val, i,
932                                snd_ctl_elem_info_get_max(ctl->info) + 1);
933
934                         if (test_ctl_write_invalid_value(ctl, val))
935                                 fail = true;
936
937                         /* Maximum representable value */
938                         snd_ctl_elem_value_copy(val, ctl->def_val);
939                         snd_ctl_elem_value_set_integer(val, i, LONG_MAX);
940
941                         if (test_ctl_write_invalid_value(ctl, val))
942                                 fail = true;
943                 }
944         }
945
946         return !fail;
947 }
948
949 static bool test_ctl_write_invalid_integer64(struct ctl_data *ctl)
950 {
951         int i;
952         bool fail = false;
953         snd_ctl_elem_value_t *val;
954         snd_ctl_elem_value_alloca(&val);
955
956         for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
957                 if (snd_ctl_elem_info_get_min64(ctl->info) != LLONG_MIN) {
958                         /* Just under range */
959                         snd_ctl_elem_value_copy(val, ctl->def_val);
960                         snd_ctl_elem_value_set_integer64(val, i,
961                                 snd_ctl_elem_info_get_min64(ctl->info) - 1);
962
963                         if (test_ctl_write_invalid_value(ctl, val))
964                                 fail = true;
965
966                         /* Minimum representable value */
967                         snd_ctl_elem_value_copy(val, ctl->def_val);
968                         snd_ctl_elem_value_set_integer64(val, i, LLONG_MIN);
969
970                         if (test_ctl_write_invalid_value(ctl, val))
971                                 fail = true;
972                 }
973
974                 if (snd_ctl_elem_info_get_max64(ctl->info) != LLONG_MAX) {
975                         /* Just over range */
976                         snd_ctl_elem_value_copy(val, ctl->def_val);
977                         snd_ctl_elem_value_set_integer64(val, i,
978                                 snd_ctl_elem_info_get_max64(ctl->info) + 1);
979
980                         if (test_ctl_write_invalid_value(ctl, val))
981                                 fail = true;
982
983                         /* Maximum representable value */
984                         snd_ctl_elem_value_copy(val, ctl->def_val);
985                         snd_ctl_elem_value_set_integer64(val, i, LLONG_MAX);
986
987                         if (test_ctl_write_invalid_value(ctl, val))
988                                 fail = true;
989                 }
990         }
991
992         return !fail;
993 }
994
995 static bool test_ctl_write_invalid_enumerated(struct ctl_data *ctl)
996 {
997         int err, i;
998         unsigned int val_read;
999         bool fail = false;
1000         snd_ctl_elem_value_t *val;
1001         snd_ctl_elem_value_alloca(&val);
1002
1003         snd_ctl_elem_value_set_id(val, ctl->id);
1004
1005         for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
1006                 /* One beyond maximum */
1007                 snd_ctl_elem_value_copy(val, ctl->def_val);
1008                 snd_ctl_elem_value_set_enumerated(val, i,
1009                                   snd_ctl_elem_info_get_items(ctl->info));
1010
1011                 if (test_ctl_write_invalid_value(ctl, val))
1012                         fail = true;
1013
1014                 /* Maximum representable value */
1015                 snd_ctl_elem_value_copy(val, ctl->def_val);
1016                 snd_ctl_elem_value_set_enumerated(val, i, UINT_MAX);
1017
1018                 if (test_ctl_write_invalid_value(ctl, val))
1019                         fail = true;
1020
1021         }
1022
1023         return !fail;
1024 }
1025
1026
1027 static void test_ctl_write_invalid(struct ctl_data *ctl)
1028 {
1029         bool pass;
1030         int err;
1031
1032         /* If the control is turned off let's be polite */
1033         if (snd_ctl_elem_info_is_inactive(ctl->info)) {
1034                 ksft_print_msg("%s is inactive\n", ctl->name);
1035                 ksft_test_result_skip("write_invalid.%d.%d\n",
1036                                       ctl->card->card, ctl->elem);
1037                 return;
1038         }
1039
1040         if (!snd_ctl_elem_info_is_writable(ctl->info)) {
1041                 ksft_print_msg("%s is not writeable\n", ctl->name);
1042                 ksft_test_result_skip("write_invalid.%d.%d\n",
1043                                       ctl->card->card, ctl->elem);
1044                 return;
1045         }
1046
1047         switch (snd_ctl_elem_info_get_type(ctl->info)) {
1048         case SND_CTL_ELEM_TYPE_BOOLEAN:
1049                 pass = test_ctl_write_invalid_boolean(ctl);
1050                 break;
1051
1052         case SND_CTL_ELEM_TYPE_INTEGER:
1053                 pass = test_ctl_write_invalid_integer(ctl);
1054                 break;
1055
1056         case SND_CTL_ELEM_TYPE_INTEGER64:
1057                 pass = test_ctl_write_invalid_integer64(ctl);
1058                 break;
1059
1060         case SND_CTL_ELEM_TYPE_ENUMERATED:
1061                 pass = test_ctl_write_invalid_enumerated(ctl);
1062                 break;
1063
1064         default:
1065                 /* No tests for this yet */
1066                 ksft_test_result_skip("write_invalid.%d.%d\n",
1067                                       ctl->card->card, ctl->elem);
1068                 return;
1069         }
1070
1071         /* Restore the default value to minimise disruption */
1072         write_and_verify(ctl, ctl->def_val, NULL);
1073
1074         ksft_test_result(pass, "write_invalid.%d.%d\n",
1075                          ctl->card->card, ctl->elem);
1076 }
1077
1078 static void test_ctl_event_missing(struct ctl_data *ctl)
1079 {
1080         ksft_test_result(!ctl->event_missing, "event_missing.%d.%d\n",
1081                          ctl->card->card, ctl->elem);
1082 }
1083
1084 static void test_ctl_event_spurious(struct ctl_data *ctl)
1085 {
1086         ksft_test_result(!ctl->event_spurious, "event_spurious.%d.%d\n",
1087                          ctl->card->card, ctl->elem);
1088 }
1089
1090 int main(void)
1091 {
1092         struct ctl_data *ctl;
1093
1094         ksft_print_header();
1095
1096         find_controls();
1097
1098         ksft_set_plan(num_controls * TESTS_PER_CONTROL);
1099
1100         for (ctl = ctl_list; ctl != NULL; ctl = ctl->next) {
1101                 /*
1102                  * Must test get_value() before we write anything, the
1103                  * test stores the default value for later cleanup.
1104                  */
1105                 test_ctl_get_value(ctl);
1106                 test_ctl_name(ctl);
1107                 test_ctl_write_default(ctl);
1108                 test_ctl_write_valid(ctl);
1109                 test_ctl_write_invalid(ctl);
1110                 test_ctl_event_missing(ctl);
1111                 test_ctl_event_spurious(ctl);
1112         }
1113
1114         ksft_exit_pass();
1115
1116         return 0;
1117 }