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