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 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 <string.h>
17 #include <getopt.h>
18 #include <stdarg.h>
19 #include <ctype.h>
20 #include <math.h>
21 #include <errno.h>
22 #include <assert.h>
23 #include <alsa/asoundlib.h>
24 #include <poll.h>
25 #include <stdint.h>
26 
27 #include "../kselftest.h"
28 
29 #define TESTS_PER_CONTROL 3
30 
31 struct card_data {
32 	snd_ctl_t *handle;
33 	int card;
34 	int num_ctls;
35 	snd_ctl_elem_list_t *ctls;
36 	struct card_data *next;
37 };
38 
39 struct ctl_data {
40 	const char *name;
41 	snd_ctl_elem_id_t *id;
42 	snd_ctl_elem_info_t *info;
43 	snd_ctl_elem_value_t *def_val;
44 	int elem;
45 	struct card_data *card;
46 	struct ctl_data *next;
47 };
48 
49 static const char *alsa_config =
50 "ctl.hw {\n"
51 "	@args [ CARD ]\n"
52 "	@args.CARD.type string\n"
53 "	type hw\n"
54 "	card $CARD\n"
55 "}\n"
56 ;
57 
58 int num_cards = 0;
59 int num_controls = 0;
60 struct card_data *card_list = NULL;
61 struct ctl_data *ctl_list = NULL;
62 
63 #ifdef SND_LIB_VER
64 #if SND_LIB_VERSION >= SND_LIB_VER(1, 2, 6)
65 #define LIB_HAS_LOAD_STRING
66 #endif
67 #endif
68 
69 #ifndef LIB_HAS_LOAD_STRING
70 int snd_config_load_string(snd_config_t **config, const char *s, size_t size)
71 {
72 	snd_input_t *input;
73 	snd_config_t *dst;
74 	int err;
75 
76 	assert(config && s);
77 	if (size == 0)
78 		size = strlen(s);
79 	err = snd_input_buffer_open(&input, s, size);
80 	if (err < 0)
81 		return err;
82 	err = snd_config_top(&dst);
83 	if (err < 0) {
84 		snd_input_close(input);
85 		return err;
86 	}
87 	err = snd_config_load(dst, input);
88 	snd_input_close(input);
89 	if (err < 0) {
90 		snd_config_delete(dst);
91 		return err;
92 	}
93 	*config = dst;
94 	return 0;
95 }
96 #endif
97 
98 void find_controls(void)
99 {
100 	char name[32];
101 	int card, ctl, err;
102 	struct card_data *card_data;
103 	struct ctl_data *ctl_data;
104 	snd_config_t *config;
105 
106 	card = -1;
107 	if (snd_card_next(&card) < 0 || card < 0)
108 		return;
109 
110 	err = snd_config_load_string(&config, alsa_config, strlen(alsa_config));
111 	if (err < 0) {
112 		ksft_print_msg("Unable to parse custom alsa-lib configuration: %s\n",
113 			       snd_strerror(err));
114 		ksft_exit_fail();
115 	}
116 
117 	while (card >= 0) {
118 		sprintf(name, "hw:%d", card);
119 
120 		card_data = malloc(sizeof(*card_data));
121 		if (!card_data)
122 			ksft_exit_fail_msg("Out of memory\n");
123 
124 		err = snd_ctl_open_lconf(&card_data->handle, name, 0, config);
125 		if (err < 0) {
126 			ksft_print_msg("Failed to get hctl for card %d: %s\n",
127 				       card, snd_strerror(err));
128 			goto next_card;
129 		}
130 
131 		/* Count controls */
132 		snd_ctl_elem_list_malloc(&card_data->ctls);
133 		snd_ctl_elem_list(card_data->handle, card_data->ctls);
134 		card_data->num_ctls = snd_ctl_elem_list_get_count(card_data->ctls);
135 
136 		/* Enumerate control information */
137 		snd_ctl_elem_list_alloc_space(card_data->ctls, card_data->num_ctls);
138 		snd_ctl_elem_list(card_data->handle, card_data->ctls);
139 
140 		card_data->card = num_cards++;
141 		card_data->next = card_list;
142 		card_list = card_data;
143 
144 		num_controls += card_data->num_ctls;
145 
146 		for (ctl = 0; ctl < card_data->num_ctls; ctl++) {
147 			ctl_data = malloc(sizeof(*ctl_data));
148 			if (!ctl_data)
149 				ksft_exit_fail_msg("Out of memory\n");
150 
151 			ctl_data->card = card_data;
152 			ctl_data->elem = ctl;
153 			ctl_data->name = snd_ctl_elem_list_get_name(card_data->ctls,
154 								    ctl);
155 
156 			err = snd_ctl_elem_id_malloc(&ctl_data->id);
157 			if (err < 0)
158 				ksft_exit_fail_msg("Out of memory\n");
159 
160 			err = snd_ctl_elem_info_malloc(&ctl_data->info);
161 			if (err < 0)
162 				ksft_exit_fail_msg("Out of memory\n");
163 
164 			err = snd_ctl_elem_value_malloc(&ctl_data->def_val);
165 			if (err < 0)
166 				ksft_exit_fail_msg("Out of memory\n");
167 
168 			snd_ctl_elem_list_get_id(card_data->ctls, ctl,
169 						 ctl_data->id);
170 			snd_ctl_elem_info_set_id(ctl_data->info, ctl_data->id);
171 			err = snd_ctl_elem_info(card_data->handle,
172 						ctl_data->info);
173 			if (err < 0) {
174 				ksft_print_msg("%s getting info for %d\n",
175 					       snd_strerror(err),
176 					       ctl_data->name);
177 			}
178 
179 			snd_ctl_elem_value_set_id(ctl_data->def_val,
180 						  ctl_data->id);
181 
182 			ctl_data->next = ctl_list;
183 			ctl_list = ctl_data;
184 		}
185 
186 	next_card:
187 		if (snd_card_next(&card) < 0) {
188 			ksft_print_msg("snd_card_next");
189 			break;
190 		}
191 	}
192 
193 	snd_config_delete(config);
194 }
195 
196 bool ctl_value_index_valid(struct ctl_data *ctl, snd_ctl_elem_value_t *val,
197 			   int index)
198 {
199 	long int_val;
200 	long long int64_val;
201 
202 	switch (snd_ctl_elem_info_get_type(ctl->info)) {
203 	case SND_CTL_ELEM_TYPE_NONE:
204 		ksft_print_msg("%s.%d Invalid control type NONE\n",
205 			       ctl->name, index);
206 		return false;
207 
208 	case SND_CTL_ELEM_TYPE_BOOLEAN:
209 		int_val = snd_ctl_elem_value_get_boolean(val, index);
210 		switch (int_val) {
211 		case 0:
212 		case 1:
213 			break;
214 		default:
215 			ksft_print_msg("%s.%d Invalid boolean value %ld\n",
216 				       ctl->name, index, int_val);
217 			return false;
218 		}
219 		break;
220 
221 	case SND_CTL_ELEM_TYPE_INTEGER:
222 		int_val = snd_ctl_elem_value_get_integer(val, index);
223 
224 		if (int_val < snd_ctl_elem_info_get_min(ctl->info)) {
225 			ksft_print_msg("%s.%d value %ld less than minimum %ld\n",
226 				       ctl->name, index, int_val,
227 				       snd_ctl_elem_info_get_min(ctl->info));
228 			return false;
229 		}
230 
231 		if (int_val > snd_ctl_elem_info_get_max(ctl->info)) {
232 			ksft_print_msg("%s.%d value %ld more than maximum %ld\n",
233 				       ctl->name, index, int_val,
234 				       snd_ctl_elem_info_get_max(ctl->info));
235 			return false;
236 		}
237 
238 		/* Only check step size if there is one and we're in bounds */
239 		if (snd_ctl_elem_info_get_step(ctl->info) &&
240 		    (int_val - snd_ctl_elem_info_get_min(ctl->info) %
241 		     snd_ctl_elem_info_get_step(ctl->info))) {
242 			ksft_print_msg("%s.%d value %ld invalid for step %ld minimum %ld\n",
243 				       ctl->name, index, int_val,
244 				       snd_ctl_elem_info_get_step(ctl->info),
245 				       snd_ctl_elem_info_get_min(ctl->info));
246 			return false;
247 		}
248 		break;
249 
250 	case SND_CTL_ELEM_TYPE_INTEGER64:
251 		int64_val = snd_ctl_elem_value_get_integer64(val, index);
252 
253 		if (int64_val < snd_ctl_elem_info_get_min64(ctl->info)) {
254 			ksft_print_msg("%s.%d value %lld less than minimum %lld\n",
255 				       ctl->name, index, int64_val,
256 				       snd_ctl_elem_info_get_min64(ctl->info));
257 			return false;
258 		}
259 
260 		if (int64_val > snd_ctl_elem_info_get_max64(ctl->info)) {
261 			ksft_print_msg("%s.%d value %lld more than maximum %lld\n",
262 				       ctl->name, index, int64_val,
263 				       snd_ctl_elem_info_get_max(ctl->info));
264 			return false;
265 		}
266 
267 		/* Only check step size if there is one and we're in bounds */
268 		if (snd_ctl_elem_info_get_step64(ctl->info) &&
269 		    (int64_val - snd_ctl_elem_info_get_min64(ctl->info)) %
270 		    snd_ctl_elem_info_get_step64(ctl->info)) {
271 			ksft_print_msg("%s.%d value %lld invalid for step %lld minimum %lld\n",
272 				       ctl->name, index, int64_val,
273 				       snd_ctl_elem_info_get_step64(ctl->info),
274 				       snd_ctl_elem_info_get_min64(ctl->info));
275 			return false;
276 		}
277 		break;
278 
279 	case SND_CTL_ELEM_TYPE_ENUMERATED:
280 		int_val = snd_ctl_elem_value_get_enumerated(val, index);
281 
282 		if (int_val < 0) {
283 			ksft_print_msg("%s.%d negative value %ld for enumeration\n",
284 				       ctl->name, index, int_val);
285 			return false;
286 		}
287 
288 		if (int_val >= snd_ctl_elem_info_get_items(ctl->info)) {
289 			ksft_print_msg("%s.%d value %ld more than item count %ld\n",
290 				       ctl->name, index, int_val,
291 				       snd_ctl_elem_info_get_items(ctl->info));
292 			return false;
293 		}
294 		break;
295 
296 	default:
297 		/* No tests for other types */
298 		break;
299 	}
300 
301 	return true;
302 }
303 
304 /*
305  * Check that the provided value meets the constraints for the
306  * provided control.
307  */
308 bool ctl_value_valid(struct ctl_data *ctl, snd_ctl_elem_value_t *val)
309 {
310 	int i;
311 	bool valid = true;
312 
313 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++)
314 		if (!ctl_value_index_valid(ctl, val, i))
315 			valid = false;
316 
317 	return valid;
318 }
319 
320 /*
321  * Check that we can read the default value and it is valid. Write
322  * tests use the read value to restore the default.
323  */
324 void test_ctl_get_value(struct ctl_data *ctl)
325 {
326 	int err;
327 
328 	/* If the control is turned off let's be polite */
329 	if (snd_ctl_elem_info_is_inactive(ctl->info)) {
330 		ksft_print_msg("%s is inactive\n", ctl->name);
331 		ksft_test_result_skip("get_value.%d.%d\n",
332 				      ctl->card->card, ctl->elem);
333 		return;
334 	}
335 
336 	/* Can't test reading on an unreadable control */
337 	if (!snd_ctl_elem_info_is_readable(ctl->info)) {
338 		ksft_print_msg("%s is not readable\n", ctl->name);
339 		ksft_test_result_skip("get_value.%d.%d\n",
340 				      ctl->card->card, ctl->elem);
341 		return;
342 	}
343 
344 	err = snd_ctl_elem_read(ctl->card->handle, ctl->def_val);
345 	if (err < 0) {
346 		ksft_print_msg("snd_ctl_elem_read() failed: %s\n",
347 			       snd_strerror(err));
348 		goto out;
349 	}
350 
351 	if (!ctl_value_valid(ctl, ctl->def_val))
352 		err = -EINVAL;
353 
354 out:
355 	ksft_test_result(err >= 0, "get_value.%d.%d\n",
356 			 ctl->card->card, ctl->elem);
357 }
358 
359 bool show_mismatch(struct ctl_data *ctl, int index,
360 		   snd_ctl_elem_value_t *read_val,
361 		   snd_ctl_elem_value_t *expected_val)
362 {
363 	long long expected_int, read_int;
364 
365 	/*
366 	 * We factor out the code to compare values representable as
367 	 * integers, ensure that check doesn't log otherwise.
368 	 */
369 	expected_int = 0;
370 	read_int = 0;
371 
372 	switch (snd_ctl_elem_info_get_type(ctl->info)) {
373 	case SND_CTL_ELEM_TYPE_BOOLEAN:
374 		expected_int = snd_ctl_elem_value_get_boolean(expected_val,
375 							      index);
376 		read_int = snd_ctl_elem_value_get_boolean(read_val, index);
377 		break;
378 
379 	case SND_CTL_ELEM_TYPE_INTEGER:
380 		expected_int = snd_ctl_elem_value_get_integer(expected_val,
381 							      index);
382 		read_int = snd_ctl_elem_value_get_integer(read_val, index);
383 		break;
384 
385 	case SND_CTL_ELEM_TYPE_INTEGER64:
386 		expected_int = snd_ctl_elem_value_get_integer64(expected_val,
387 								index);
388 		read_int = snd_ctl_elem_value_get_integer64(read_val,
389 							    index);
390 		break;
391 
392 	case SND_CTL_ELEM_TYPE_ENUMERATED:
393 		expected_int = snd_ctl_elem_value_get_enumerated(expected_val,
394 								 index);
395 		read_int = snd_ctl_elem_value_get_enumerated(read_val,
396 							     index);
397 		break;
398 
399 	default:
400 		break;
401 	}
402 
403 	if (expected_int != read_int) {
404 		/*
405 		 * NOTE: The volatile attribute means that the hardware
406 		 * can voluntarily change the state of control element
407 		 * independent of any operation by software.
408 		 */
409 		bool is_volatile = snd_ctl_elem_info_is_volatile(ctl->info);
410 		ksft_print_msg("%s.%d expected %lld but read %lld, is_volatile %d\n",
411 			       ctl->name, index, expected_int, read_int, is_volatile);
412 		return !is_volatile;
413 	} else {
414 		return false;
415 	}
416 }
417 
418 /*
419  * Write a value then if possible verify that we get the expected
420  * result.  An optional expected value can be provided if we expect
421  * the write to fail, for verifying that invalid writes don't corrupt
422  * anything.
423  */
424 int write_and_verify(struct ctl_data *ctl,
425 		     snd_ctl_elem_value_t *write_val,
426 		     snd_ctl_elem_value_t *expected_val)
427 {
428 	int err, i;
429 	bool error_expected, mismatch_shown;
430 	snd_ctl_elem_value_t *read_val, *w_val;
431 	snd_ctl_elem_value_alloca(&read_val);
432 	snd_ctl_elem_value_alloca(&w_val);
433 
434 	/*
435 	 * We need to copy the write value since writing can modify
436 	 * the value which causes surprises, and allocate an expected
437 	 * value if we expect to read back what we wrote.
438 	 */
439 	snd_ctl_elem_value_copy(w_val, write_val);
440 	if (expected_val) {
441 		error_expected = true;
442 	} else {
443 		error_expected = false;
444 		snd_ctl_elem_value_alloca(&expected_val);
445 		snd_ctl_elem_value_copy(expected_val, write_val);
446 	}
447 
448 	/*
449 	 * Do the write, if we have an expected value ignore the error
450 	 * and carry on to validate the expected value.
451 	 */
452 	err = snd_ctl_elem_write(ctl->card->handle, w_val);
453 	if (err < 0 && !error_expected) {
454 		ksft_print_msg("snd_ctl_elem_write() failed: %s\n",
455 			       snd_strerror(err));
456 		return err;
457 	}
458 
459 	/* Can we do the verification part? */
460 	if (!snd_ctl_elem_info_is_readable(ctl->info))
461 		return err;
462 
463 	snd_ctl_elem_value_set_id(read_val, ctl->id);
464 
465 	err = snd_ctl_elem_read(ctl->card->handle, read_val);
466 	if (err < 0) {
467 		ksft_print_msg("snd_ctl_elem_read() failed: %s\n",
468 			       snd_strerror(err));
469 		return err;
470 	}
471 
472 	/*
473 	 * Use the libray to compare values, if there's a mismatch
474 	 * carry on and try to provide a more useful diagnostic than
475 	 * just "mismatch".
476 	 */
477 	if (!snd_ctl_elem_value_compare(expected_val, read_val))
478 		return 0;
479 
480 	mismatch_shown = false;
481 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++)
482 		if (show_mismatch(ctl, i, read_val, expected_val))
483 			mismatch_shown = true;
484 
485 	if (!mismatch_shown)
486 		ksft_print_msg("%s read and written values differ\n",
487 			       ctl->name);
488 
489 	return -1;
490 }
491 
492 /*
493  * Make sure we can write the default value back to the control, this
494  * should validate that at least some write works.
495  */
496 void test_ctl_write_default(struct ctl_data *ctl)
497 {
498 	int err;
499 
500 	/* If the control is turned off let's be polite */
501 	if (snd_ctl_elem_info_is_inactive(ctl->info)) {
502 		ksft_print_msg("%s is inactive\n", ctl->name);
503 		ksft_test_result_skip("write_default.%d.%d\n",
504 				      ctl->card->card, ctl->elem);
505 		return;
506 	}
507 
508 	if (!snd_ctl_elem_info_is_writable(ctl->info)) {
509 		ksft_print_msg("%s is not writeable\n", ctl->name);
510 		ksft_test_result_skip("write_default.%d.%d\n",
511 				      ctl->card->card, ctl->elem);
512 		return;
513 	}
514 
515 	/* No idea what the default was for unreadable controls */
516 	if (!snd_ctl_elem_info_is_readable(ctl->info)) {
517 		ksft_print_msg("%s couldn't read default\n", ctl->name);
518 		ksft_test_result_skip("write_default.%d.%d\n",
519 				      ctl->card->card, ctl->elem);
520 		return;
521 	}
522 
523 	err = write_and_verify(ctl, ctl->def_val, NULL);
524 
525 	ksft_test_result(err >= 0, "write_default.%d.%d\n",
526 			 ctl->card->card, ctl->elem);
527 }
528 
529 bool test_ctl_write_valid_boolean(struct ctl_data *ctl)
530 {
531 	int err, i, j;
532 	bool fail = false;
533 	snd_ctl_elem_value_t *val;
534 	snd_ctl_elem_value_alloca(&val);
535 
536 	snd_ctl_elem_value_set_id(val, ctl->id);
537 
538 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
539 		for (j = 0; j < 2; j++) {
540 			snd_ctl_elem_value_set_boolean(val, i, j);
541 			err = write_and_verify(ctl, val, NULL);
542 			if (err != 0)
543 				fail = true;
544 		}
545 	}
546 
547 	return !fail;
548 }
549 
550 bool test_ctl_write_valid_integer(struct ctl_data *ctl)
551 {
552 	int err;
553 	int i;
554 	long j, step;
555 	bool fail = false;
556 	snd_ctl_elem_value_t *val;
557 	snd_ctl_elem_value_alloca(&val);
558 
559 	snd_ctl_elem_value_set_id(val, ctl->id);
560 
561 	step = snd_ctl_elem_info_get_step(ctl->info);
562 	if (!step)
563 		step = 1;
564 
565 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
566 		for (j = snd_ctl_elem_info_get_min(ctl->info);
567 		     j <= snd_ctl_elem_info_get_max(ctl->info); j += step) {
568 
569 			snd_ctl_elem_value_set_integer(val, i, j);
570 			err = write_and_verify(ctl, val, NULL);
571 			if (err != 0)
572 				fail = true;
573 		}
574 	}
575 
576 
577 	return !fail;
578 }
579 
580 bool test_ctl_write_valid_integer64(struct ctl_data *ctl)
581 {
582 	int err, i;
583 	long long j, step;
584 	bool fail = false;
585 	snd_ctl_elem_value_t *val;
586 	snd_ctl_elem_value_alloca(&val);
587 
588 	snd_ctl_elem_value_set_id(val, ctl->id);
589 
590 	step = snd_ctl_elem_info_get_step64(ctl->info);
591 	if (!step)
592 		step = 1;
593 
594 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
595 		for (j = snd_ctl_elem_info_get_min64(ctl->info);
596 		     j <= snd_ctl_elem_info_get_max64(ctl->info); j += step) {
597 
598 			snd_ctl_elem_value_set_integer64(val, i, j);
599 			err = write_and_verify(ctl, val, NULL);
600 			if (err != 0)
601 				fail = true;
602 		}
603 	}
604 
605 	return !fail;
606 }
607 
608 bool test_ctl_write_valid_enumerated(struct ctl_data *ctl)
609 {
610 	int err, i, j;
611 	bool fail = false;
612 	snd_ctl_elem_value_t *val;
613 	snd_ctl_elem_value_alloca(&val);
614 
615 	snd_ctl_elem_value_set_id(val, ctl->id);
616 
617 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
618 		for (j = 0; j < snd_ctl_elem_info_get_items(ctl->info); j++) {
619 			snd_ctl_elem_value_set_enumerated(val, i, j);
620 			err = write_and_verify(ctl, val, NULL);
621 			if (err != 0)
622 				fail = true;
623 		}
624 	}
625 
626 	return !fail;
627 }
628 
629 void test_ctl_write_valid(struct ctl_data *ctl)
630 {
631 	bool pass;
632 	int err;
633 
634 	/* If the control is turned off let's be polite */
635 	if (snd_ctl_elem_info_is_inactive(ctl->info)) {
636 		ksft_print_msg("%s is inactive\n", ctl->name);
637 		ksft_test_result_skip("write_valid.%d.%d\n",
638 				      ctl->card->card, ctl->elem);
639 		return;
640 	}
641 
642 	if (!snd_ctl_elem_info_is_writable(ctl->info)) {
643 		ksft_print_msg("%s is not writeable\n", ctl->name);
644 		ksft_test_result_skip("write_valid.%d.%d\n",
645 				      ctl->card->card, ctl->elem);
646 		return;
647 	}
648 
649 	switch (snd_ctl_elem_info_get_type(ctl->info)) {
650 	case SND_CTL_ELEM_TYPE_BOOLEAN:
651 		pass = test_ctl_write_valid_boolean(ctl);
652 		break;
653 
654 	case SND_CTL_ELEM_TYPE_INTEGER:
655 		pass = test_ctl_write_valid_integer(ctl);
656 		break;
657 
658 	case SND_CTL_ELEM_TYPE_INTEGER64:
659 		pass = test_ctl_write_valid_integer64(ctl);
660 		break;
661 
662 	case SND_CTL_ELEM_TYPE_ENUMERATED:
663 		pass = test_ctl_write_valid_enumerated(ctl);
664 		break;
665 
666 	default:
667 		/* No tests for this yet */
668 		ksft_test_result_skip("write_valid.%d.%d\n",
669 				      ctl->card->card, ctl->elem);
670 		return;
671 	}
672 
673 	/* Restore the default value to minimise disruption */
674 	err = write_and_verify(ctl, ctl->def_val, NULL);
675 	if (err < 0)
676 		pass = false;
677 
678 	ksft_test_result(pass, "write_valid.%d.%d\n",
679 			 ctl->card->card, ctl->elem);
680 }
681 
682 int main(void)
683 {
684 	struct ctl_data *ctl;
685 
686 	ksft_print_header();
687 
688 	find_controls();
689 
690 	ksft_set_plan(num_controls * TESTS_PER_CONTROL);
691 
692 	for (ctl = ctl_list; ctl != NULL; ctl = ctl->next) {
693 		/*
694 		 * Must test get_value() before we write anything, the
695 		 * test stores the default value for later cleanup.
696 		 */
697 		test_ctl_get_value(ctl);
698 		test_ctl_write_default(ctl);
699 		test_ctl_write_valid(ctl);
700 	}
701 
702 	ksft_exit_pass();
703 
704 	return 0;
705 }
706