xref: /third_party/alsa-lib/src/ucm/main.c (revision d5ac70f0)
1/*
2 *  This library is free software; you can redistribute it and/or
3 *  modify it under the terms of the GNU Lesser General Public
4 *  License as published by the Free Software Foundation; either
5 *  version 2 of the License, or (at your option) any later version.
6 *
7 *  This library is distributed in the hope that it will be useful,
8 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10 *  Lesser General Public License for more details.
11 *
12 *  You should have received a copy of the GNU Lesser General Public
13 *  License along with this library; if not, write to the Free Software
14 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
15 *
16 *  Support for the verb/device/modifier core logic and API,
17 *  command line tool and file parser was kindly sponsored by
18 *  Texas Instruments Inc.
19 *  Support for multiple active modifiers and devices,
20 *  transition sequences, multiple client access and user defined use
21 *  cases was kindly sponsored by Wolfson Microelectronics PLC.
22 *
23 *  Copyright (C) 2008-2010 SlimLogic Ltd
24 *  Copyright (C) 2010 Wolfson Microelectronics PLC
25 *  Copyright (C) 2010 Texas Instruments Inc.
26 *  Copyright (C) 2010 Red Hat Inc.
27 *  Authors: Liam Girdwood <lrg@slimlogic.co.uk>
28 *	         Stefan Schmidt <stefan@slimlogic.co.uk>
29 *	         Justin Xu <justinx@slimlogic.co.uk>
30 *               Jaroslav Kysela <perex@perex.cz>
31 */
32
33#include "ucm_local.h"
34#include "../control/control_local.h"
35#include <stdbool.h>
36#include <ctype.h>
37#include <stdarg.h>
38#include <pthread.h>
39#include <sys/stat.h>
40#include <sys/wait.h>
41#include <limits.h>
42
43/*
44 * misc
45 */
46
47static int get_value(snd_use_case_mgr_t *uc_mgr,
48			const char *identifier,
49			char **value,
50			const char *mod_dev_name,
51			const char *verb_name,
52			int exact);
53static int get_value1(snd_use_case_mgr_t *uc_mgr, char **value,
54		      struct list_head *value_list, const char *identifier);
55static int get_value3(snd_use_case_mgr_t *uc_mgr,
56		      char **value,
57		      const char *identifier,
58		      struct list_head *value_list1,
59		      struct list_head *value_list2,
60		      struct list_head *value_list3);
61
62static int execute_sequence(snd_use_case_mgr_t *uc_mgr,
63			    struct use_case_verb *verb,
64			    struct list_head *seq,
65			    struct list_head *value_list1,
66			    struct list_head *value_list2,
67			    struct list_head *value_list3);
68
69static int execute_component_seq(snd_use_case_mgr_t *uc_mgr,
70				 struct component_sequence *cmpt_seq,
71				 struct list_head *value_list1,
72				 struct list_head *value_list2,
73				 struct list_head *value_list3,
74				 char *cdev);
75
76static inline struct use_case_device *
77	find_device(snd_use_case_mgr_t *uc_mgr, struct use_case_verb *verb,
78		    const char *device_name, int check_supported);
79
80static int check_identifier(const char *identifier, const char *prefix)
81{
82	int len;
83
84	len = strlen(prefix);
85	if (strncmp(identifier, prefix, len) != 0)
86		return 0;
87
88	if (identifier[len] == 0 || identifier[len] == '/')
89		return 1;
90
91	return 0;
92}
93
94static int list_count(struct list_head *list)
95{
96	struct list_head *pos;
97	int count = 0;
98
99	list_for_each(pos, list) {
100		count += 1;
101	}
102	return count;
103}
104
105static int alloc_str_list(struct list_head *list, int mult, char **result[])
106{
107	char **res;
108	int cnt;
109
110	cnt = list_count(list) * mult;
111	if (cnt == 0) {
112		*result = NULL;
113		return cnt;
114	}
115	res = calloc(mult, cnt * sizeof(char *));
116	if (res == NULL)
117		return -ENOMEM;
118	*result = res;
119	return cnt;
120}
121
122/**
123 * \brief Create an identifier
124 * \param fmt Format (sprintf like)
125 * \param ... Optional arguments for sprintf like format
126 * \return Allocated string identifier or NULL on error
127 */
128char *snd_use_case_identifier(const char *fmt, ...)
129{
130	char *str, *res;
131	int size = strlen(fmt) + 512;
132	va_list args;
133
134	str = malloc(size);
135	if (str == NULL)
136		return NULL;
137	va_start(args, fmt);
138	vsnprintf(str, size, fmt, args);
139	va_end(args);
140	str[size-1] = '\0';
141	res = realloc(str, strlen(str) + 1);
142	if (res)
143		return res;
144	return str;
145}
146
147/**
148 * \brief Free a string list
149 * \param list The string list to free
150 * \param items Count of strings
151 * \return Zero if success, otherwise a negative error code
152 */
153int snd_use_case_free_list(const char *list[], int items)
154{
155	int i;
156	if (list == NULL)
157		return 0;
158	for (i = 0; i < items; i++)
159		free((void *)list[i]);
160	free(list);
161	return 0;
162}
163
164static int read_tlv_file(unsigned int **res,
165			 const char *filepath)
166{
167	int err = 0;
168	int fd;
169	struct stat64 st;
170	size_t sz;
171	ssize_t sz_read;
172	struct snd_ctl_tlv *tlv;
173
174	fd = open(filepath, O_RDONLY);
175	if (fd < 0) {
176		err = -errno;
177		return err;
178	}
179	if (fstat64(fd, &st) == -1) {
180		err = -errno;
181		goto __fail;
182	}
183	sz = st.st_size;
184	if (sz > 16 * 1024 * 1024 || sz < 8 || sz % 4) {
185		uc_error("File size should be less than 16 MB "
186			 "and multiple of 4");
187		err = -EINVAL;
188		goto __fail;
189	}
190	*res = malloc(sz);
191	if (res == NULL) {
192		err = -ENOMEM;
193		goto __fail;
194	}
195	sz_read = read(fd, *res, sz);
196	if (sz_read < 0 || (size_t)sz_read != sz) {
197		err = -EIO;
198		free(*res);
199		*res = NULL;
200	}
201	/* Check if the tlv file specifies valid size. */
202	tlv = (struct snd_ctl_tlv *)(*res);
203	if (tlv->length + 2 * sizeof(unsigned int) != sz) {
204		uc_error("Invalid tlv size: %d", tlv->length);
205		err = -EINVAL;
206		free(*res);
207		*res = NULL;
208	}
209
210__fail:
211	close(fd);
212	return err;
213}
214
215static int binary_file_parse(snd_ctl_elem_value_t *dst,
216			      snd_ctl_elem_info_t *info,
217			      const char *filepath)
218{
219	int err = 0;
220	int fd;
221	struct stat64 st;
222	size_t sz;
223	ssize_t sz_read;
224	char *res;
225	snd_ctl_elem_type_t type;
226	unsigned int idx, count;
227
228	type = snd_ctl_elem_info_get_type(info);
229	if (type != SND_CTL_ELEM_TYPE_BYTES) {
230		uc_error("only support byte type!");
231		err = -EINVAL;
232		return err;
233	}
234	fd = open(filepath, O_RDONLY);
235	if (fd < 0) {
236		err = -errno;
237		return err;
238	}
239	if (stat64(filepath, &st) == -1) {
240		err = -errno;
241		goto __fail;
242	}
243	sz = st.st_size;
244	count = snd_ctl_elem_info_get_count(info);
245	if (sz != count || sz > sizeof(dst->value.bytes)) {
246		uc_error("invalid parameter size %d!", sz);
247		err = -EINVAL;
248		goto __fail;
249	}
250	res = malloc(sz);
251	if (res == NULL) {
252		err = -ENOMEM;
253		goto __fail;
254	}
255	sz_read = read(fd, res, sz);
256	if (sz_read < 0 || (size_t)sz_read != sz) {
257		err = -errno;
258		goto __fail_read;
259	}
260	for (idx = 0; idx < sz; idx++)
261		snd_ctl_elem_value_set_byte(dst, idx, *(res + idx));
262      __fail_read:
263	free(res);
264      __fail:
265	close(fd);
266	return err;
267}
268
269static const char *parse_type(const char *p, const char *prefix, size_t len,
270			      snd_ctl_elem_info_t *info)
271{
272	if (strncasecmp(p, prefix, len))
273		return p;
274	p += len;
275	if (info->type != SND_CTL_ELEM_TYPE_NONE)
276		return NULL;
277	if (strncasecmp(p, "bool", sizeof("bool") - 1) == 0)
278		info->type = SND_CTL_ELEM_TYPE_BOOLEAN;
279	else if (strncasecmp(p, "integer64", sizeof("integer64") - 1) == 0)
280		info->type = SND_CTL_ELEM_TYPE_INTEGER64;
281	else if (strncasecmp(p, "int64", sizeof("int64") - 1) == 0)
282		info->type = SND_CTL_ELEM_TYPE_INTEGER64;
283	else if (strncasecmp(p, "int", sizeof("int") - 1) == 0)
284		info->type = SND_CTL_ELEM_TYPE_INTEGER;
285	else if (strncasecmp(p, "enum", sizeof("enum") - 1) == 0)
286		info->type = SND_CTL_ELEM_TYPE_ENUMERATED;
287	else if (strncasecmp(p, "bytes", sizeof("bytes") - 1) == 0)
288		info->type = SND_CTL_ELEM_TYPE_BYTES;
289	else
290		return NULL;
291	while (isalpha(*p))
292		p++;
293	return p;
294}
295
296static const char *parse_uint(const char *p, const char *prefix, size_t len,
297			      unsigned int min, unsigned int max, unsigned int *rval)
298{
299	long v;
300	char *end;
301
302	if (strncasecmp(p, prefix, len))
303		return p;
304	p += len;
305	v = strtol(p, &end, 0);
306	if (*end != '\0' && *end != ' ' && *end != ',') {
307		uc_error("unable to parse '%s'", prefix);
308		return NULL;
309	}
310	if ((unsigned int)v < min || (unsigned int)v > max) {
311		uc_error("value '%s' out of range %u-%u %(%ld)", min, max, v);
312		return NULL;
313	}
314	*rval = v;
315	return end;
316}
317
318static const char *parse_labels(const char *p, const char *prefix, size_t len,
319				snd_ctl_elem_info_t *info)
320{
321	const char *s;
322	char *buf, *bp;
323	size_t l;
324	int c;
325
326	if (info->type != SND_CTL_ELEM_TYPE_ENUMERATED)
327		return NULL;
328	if (strncasecmp(p, prefix, len))
329		return p;
330	p += len;
331	s = p;
332	c = *s;
333	l = 0;
334	if (c == '\'' || c == '\"') {
335		s++;
336		while (*s && *s != c) {
337			s++, l++;
338		}
339		if (*s == c)
340			s++;
341	} else {
342		while (*s && *s != ',')
343			l++;
344	}
345	if (l == 0)
346		return NULL;
347	buf = malloc(l + 1);
348	if (buf == NULL)
349		return NULL;
350	memcpy(buf, p + ((c == '\'' || c == '\"') ? 1 : 0), l);
351	buf[l] = '\0';
352	info->value.enumerated.items = 1;
353	for (bp = buf; *bp; bp++) {
354		if (*bp == ';') {
355			if (bp == buf || bp[1] == ';') {
356				free(buf);
357				return NULL;
358			}
359			info->value.enumerated.items++;
360			*bp = '\0';
361		}
362	}
363	info->value.enumerated.names_ptr = (uintptr_t)buf;
364	info->value.enumerated.names_length = l + 1;
365	return s;
366}
367
368static int parse_cset_new_info(snd_ctl_elem_info_t *info, const char *s, const char **pos)
369{
370	const char *p = s, *op;
371
372	info->count = 1;
373	while (*s) {
374		op = p;
375		p = parse_type(p, "type=", sizeof("type=") - 1, info);
376		if (p != op)
377			goto next;
378		p = parse_uint(p, "elements=", sizeof("elements=") - 1, 1, 128, (unsigned int *)&info->owner);
379		if (p != op)
380			goto next;
381		p = parse_uint(p, "count=", sizeof("count=") - 1, 1, 128, &info->count);
382		if (p != op)
383			goto next;
384		p = parse_labels(p, "labels=", sizeof("labels=") - 1, info);
385next:
386		if (p == NULL)
387			goto er;
388		if (*p == ',')
389			p++;
390		if (isspace(*p))
391			break;
392		if (op == p)
393			goto er;
394	}
395	*pos = p;
396	return 0;
397er:
398	uc_error("unknown syntax '%s'", p);
399	return -EINVAL;
400}
401
402static int execute_cset(snd_ctl_t *ctl, const char *cset, unsigned int type)
403{
404	const char *pos;
405	int err;
406	snd_ctl_elem_id_t *id;
407	snd_ctl_elem_value_t *value;
408	snd_ctl_elem_info_t *info, *info2 = NULL;
409	unsigned int *res = NULL;
410
411	snd_ctl_elem_id_malloc(&id);
412	snd_ctl_elem_value_malloc(&value);
413	snd_ctl_elem_info_malloc(&info);
414
415	err = __snd_ctl_ascii_elem_id_parse(id, cset, &pos);
416	if (err < 0)
417		goto __fail;
418	while (*pos && isspace(*pos))
419		pos++;
420	if (type == SEQUENCE_ELEMENT_TYPE_CSET_NEW) {
421		snd_ctl_elem_info_malloc(&info2);
422		snd_ctl_elem_info_set_id(info2, id);
423		err = parse_cset_new_info(info2, pos, &pos);
424		if (err < 0 || !*pos) {
425			uc_error("undefined or wrong id config for cset-new", cset);
426			err = -EINVAL;
427			goto __fail;
428		}
429		while (*pos && isspace(*pos))
430			pos++;
431	}
432	if (!*pos) {
433		if (type != SEQUENCE_ELEMENT_TYPE_CTL_REMOVE) {
434			uc_error("undefined value for cset >%s<", cset);
435			err = -EINVAL;
436			goto __fail;
437		}
438	} else if (type == SEQUENCE_ELEMENT_TYPE_CTL_REMOVE) {
439		uc_error("extra value for ctl-remove >%s<", cset);
440		err = -EINVAL;
441		goto __fail;
442	}
443
444	snd_ctl_elem_info_set_id(info, id);
445	err = snd_ctl_elem_info(ctl, info);
446	if (type == SEQUENCE_ELEMENT_TYPE_CSET_NEW ||
447	    type == SEQUENCE_ELEMENT_TYPE_CTL_REMOVE) {
448		if (err >= 0) {
449			err = snd_ctl_elem_remove(ctl, id);
450			if (err < 0) {
451				uc_error("unable to remove control");
452				err = -EINVAL;
453				goto __fail;
454			}
455		}
456		if (type == SEQUENCE_ELEMENT_TYPE_CTL_REMOVE)
457			goto __ok;
458		err = __snd_ctl_add_elem_set(ctl, info2, info2->owner, info2->count);
459		if (err < 0) {
460			uc_error("unable to create new control");
461			goto __fail;
462		}
463		/* new id copy */
464		snd_ctl_elem_info_get_id(info2, id);
465		snd_ctl_elem_info_set_id(info, id);
466	} else if (err < 0)
467		goto __fail;
468	if (type == SEQUENCE_ELEMENT_TYPE_CSET_TLV) {
469		if (!snd_ctl_elem_info_is_tlv_writable(info)) {
470			err = -EINVAL;
471			goto __fail;
472		}
473		err = read_tlv_file(&res, pos);
474		if (err < 0)
475			goto __fail;
476		err = snd_ctl_elem_tlv_write(ctl, id, res);
477		if (err < 0)
478			goto __fail;
479	} else {
480		snd_ctl_elem_value_set_id(value, id);
481		err = snd_ctl_elem_read(ctl, value);
482		if (err < 0)
483			goto __fail;
484		if (type == SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE)
485			err = binary_file_parse(value, info, pos);
486		else
487			err = snd_ctl_ascii_value_parse(ctl, value, info, pos);
488		if (err < 0)
489			goto __fail;
490		err = snd_ctl_elem_write(ctl, value);
491		if (err < 0)
492			goto __fail;
493		if (type == SEQUENCE_ELEMENT_TYPE_CSET_NEW) {
494			unsigned int idx;
495			for (idx = 1; idx < (unsigned int)info2->owner; idx++) {
496				value->id.numid += 1;
497				err = snd_ctl_elem_write(ctl, value);
498				if (err < 0)
499					goto __fail;
500			}
501		}
502	}
503      __ok:
504	err = 0;
505      __fail:
506	free(id);
507	free(value);
508	if (info2) {
509		if (info2->type == SND_CTL_ELEM_TYPE_ENUMERATED)
510			free((void *)(size_t)info2->value.enumerated.names_ptr);
511		free(info2);
512	}
513	free(info);
514	free(res);
515
516	return err;
517}
518
519static int execute_sysw(const char *sysw)
520{
521	char path[PATH_MAX];
522	const char *e;
523	char *s, *value;
524	ssize_t wlen;
525	size_t len;
526	int fd, myerrno;
527	bool ignore_error = false;
528
529	if (sysw == NULL || *sysw == '\0')
530		return 0;
531
532	if (sysw[0] == '-') {
533		ignore_error = true;
534		sysw++;
535	}
536
537	if (sysw[0] == ':')
538		return -EINVAL;
539
540	s = strdup(sysw[0] != '/' ? sysw : sysw + 1);
541	if (s == NULL)
542		return -ENOMEM;
543
544	value = strchr(s, ':');
545	if (!value) {
546		free(s);
547		return -EINVAL;
548	}
549	*value = '\0';
550	value++;
551	len = strlen(value);
552	if (len < 1) {
553		free(s);
554		return -EINVAL;
555	}
556
557	e = uc_mgr_sysfs_root();
558	if (e == NULL) {
559		free(s);
560		return -EINVAL;
561	}
562	snprintf(path, sizeof(path), "%s/%s", e, s);
563
564	fd = open(path, O_WRONLY|O_CLOEXEC);
565	if (fd < 0) {
566		free(s);
567		if (ignore_error)
568			return 0;
569		uc_error("unable to open '%s' for write", path);
570		return -EINVAL;
571	}
572	wlen = write(fd, value, len);
573	myerrno = errno;
574	close(fd);
575
576	if (ignore_error)
577		goto __end;
578
579	if (wlen != (ssize_t)len) {
580		uc_error("unable to write '%s' to '%s': %s", value, path, strerror(myerrno));
581		free(s);
582		return -EINVAL;
583	}
584
585__end:
586	free(s);
587	return 0;
588}
589
590int _snd_config_save_node_value(snd_config_t *n, snd_output_t *out, unsigned int level);
591
592static int execute_cfgsave(snd_use_case_mgr_t *uc_mgr, const char *filename)
593{
594	snd_config_t *config = uc_mgr->local_config;
595	char *file, *root;
596	snd_output_t *out;
597	bool with_root = false;
598	int err = 0;
599
600	file = strdup(filename);
601	if (!file)
602		return -ENOMEM;
603	root = strchr(file, ':');
604	if (config && root) {
605		*root++ = '\0';
606		if (*root == '+') {
607			with_root = true;
608			root++;
609		}
610		err = snd_config_search(config, root, &config);
611		if (err < 0) {
612			uc_error("Unable to find subtree '%s'", root);
613			goto _err;
614		}
615	}
616
617	err = snd_output_stdio_open(&out, file, "w+");
618	if (err < 0) {
619		uc_error("unable to open file '%s': %s", file, snd_strerror(err));
620		goto _err;
621	}
622	if (!config || snd_config_is_empty(config)) {
623		snd_output_close(out);
624		goto _err;
625	}
626	if (with_root) {
627		snd_output_printf(out, "%s ", root);
628		err = _snd_config_save_node_value(config, out, 0);
629	} else {
630		err = snd_config_save(config, out);
631	}
632	snd_output_close(out);
633	if (err < 0) {
634		uc_error("unable to save configuration: %s", snd_strerror(err));
635		goto _err;
636	}
637_err:
638	free(file);
639	return err;
640}
641
642static int rewrite_device_value(snd_use_case_mgr_t *uc_mgr, const char *name, char **value)
643{
644	char *sval;
645	size_t l;
646	static const char **s, *_prefix[] = {
647		"PlaybackCTL",
648		"CaptureCTL",
649		"PlaybackMixer",
650		"CaptureMixer",
651		"PlaybackPCM",
652		"CapturePCM",
653		NULL
654	};
655
656	if (!uc_mgr_has_local_config(uc_mgr))
657		return 0;
658	for (s = _prefix; *s && *value; s++) {
659		if (strcmp(*s, name) != 0)
660			continue;
661		l = strlen(*value) + 9 + 1;
662		sval = malloc(l);
663		if (sval == NULL) {
664			free(*value);
665			*value = NULL;
666			return -ENOMEM;
667		}
668		snprintf(sval, l, "_ucm%04X.%s", uc_mgr->ucm_card_number, *value);
669		free(*value);
670		*value = sval;
671		break;
672	}
673	return 0;
674}
675
676static int run_device_sequence(snd_use_case_mgr_t *uc_mgr, struct use_case_verb *verb,
677			       const char *name, bool enable)
678{
679	struct use_case_device *device;
680
681	if (verb == NULL) {
682		uc_error("error: enadev2 / disdev2 must be executed inside the verb context");
683		return -ENOENT;
684	}
685
686	device = find_device(uc_mgr, verb, name, 0);
687	if (device == NULL) {
688		uc_error("error: unable to find device '%s'\n", name);
689		return -ENOENT;
690	}
691
692	return execute_sequence(uc_mgr, verb,
693				enable ? &device->enable_list : &device->disable_list,
694				&device->value_list,
695				&verb->value_list,
696				&uc_mgr->value_list);
697}
698
699static int run_device_all_sequence(snd_use_case_mgr_t *uc_mgr, struct use_case_verb *verb)
700{
701	struct use_case_device *device;
702	struct list_head *pos;
703	int err;
704
705	if (verb == NULL) {
706		uc_error("error: disdevall must be executed inside the verb context");
707		return -ENOENT;
708	}
709
710	list_for_each(pos, &verb->device_list) {
711		device = list_entry(pos, struct use_case_device, list);
712
713		err = execute_sequence(uc_mgr, verb,
714					&device->disable_list,
715					&device->value_list,
716					&verb->value_list,
717					&uc_mgr->value_list);
718		if (err < 0)
719			return err;
720	}
721	return 0;
722}
723
724/**
725 * \brief Execute the sequence
726 * \param uc_mgr Use case manager
727 * \param seq Sequence
728 * \return zero on success, otherwise a negative error code
729 */
730static int execute_sequence(snd_use_case_mgr_t *uc_mgr,
731			    struct use_case_verb *verb,
732			    struct list_head *seq,
733			    struct list_head *value_list1,
734			    struct list_head *value_list2,
735			    struct list_head *value_list3)
736{
737	struct list_head *pos;
738	struct sequence_element *s;
739	char *cdev = NULL;
740	snd_ctl_t *ctl = NULL;
741	struct ctl_list *ctl_list;
742	bool ignore_error;
743	int err = 0;
744
745	if (uc_mgr->sequence_hops > 100) {
746		uc_error("error: too many inner sequences!");
747		return -EINVAL;
748	}
749	uc_mgr->sequence_hops++;
750	list_for_each(pos, seq) {
751		s = list_entry(pos, struct sequence_element, list);
752		switch (s->type) {
753		case SEQUENCE_ELEMENT_TYPE_CDEV:
754			cdev = strdup(s->data.cdev);
755			if (cdev == NULL)
756				goto __fail_nomem;
757			if (rewrite_device_value(uc_mgr, "PlaybackCTL", &cdev))
758				goto __fail_nomem;
759			break;
760		case SEQUENCE_ELEMENT_TYPE_CSET:
761		case SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE:
762		case SEQUENCE_ELEMENT_TYPE_CSET_TLV:
763		case SEQUENCE_ELEMENT_TYPE_CSET_NEW:
764		case SEQUENCE_ELEMENT_TYPE_CTL_REMOVE:
765			if (cdev == NULL && uc_mgr->in_component_domain) {
766				/* For sequence of a component device, use
767				 * its parent's cdev stored by ucm manager.
768				 */
769				if (uc_mgr->cdev == NULL) {
770					uc_error("cdev is not defined!");
771					return err;
772				}
773
774				cdev = strndup(uc_mgr->cdev, PATH_MAX);
775				if (!cdev)
776					return -ENOMEM;
777			} else if (cdev == NULL) {
778				char *playback_ctl = NULL;
779				char *capture_ctl = NULL;
780
781				err = get_value3(uc_mgr, &playback_ctl, "PlaybackCTL",
782						 value_list1,
783						 value_list2,
784						 value_list3);
785				if (err < 0 && err != -ENOENT) {
786					uc_error("cdev is not defined!");
787					return err;
788				}
789				err = get_value3(uc_mgr, &capture_ctl, "CaptureCTL",
790						 value_list1,
791						 value_list2,
792						 value_list3);
793				if (err < 0 && err != -ENOENT) {
794					free(playback_ctl);
795					uc_error("cdev is not defined!");
796					return err;
797				}
798				if (playback_ctl == NULL &&
799				    capture_ctl == NULL) {
800					uc_error("cdev is not defined!");
801					return -EINVAL;
802				}
803				if (playback_ctl != NULL &&
804				    capture_ctl != NULL &&
805				    strcmp(playback_ctl, capture_ctl) != 0) {
806					free(playback_ctl);
807					free(capture_ctl);
808					uc_error("cdev is not equal for playback and capture!");
809					return -EINVAL;
810				}
811				if (playback_ctl != NULL) {
812					cdev = playback_ctl;
813					free(capture_ctl);
814				} else {
815					cdev = capture_ctl;
816				}
817			}
818			if (ctl == NULL) {
819				err = uc_mgr_open_ctl(uc_mgr, &ctl_list, cdev, 1);
820				if (err < 0) {
821					uc_error("unable to open ctl device '%s'", cdev);
822					goto __fail;
823				}
824				ctl = ctl_list->ctl;
825			}
826			err = execute_cset(ctl, s->data.cset, s->type);
827			if (err < 0) {
828				uc_error("unable to execute cset '%s'", s->data.cset);
829				goto __fail;
830			}
831			break;
832		case SEQUENCE_ELEMENT_TYPE_SYSSET:
833			err = execute_sysw(s->data.sysw);
834			if (err < 0)
835				goto __fail;
836			break;
837		case SEQUENCE_ELEMENT_TYPE_SLEEP:
838			usleep(s->data.sleep);
839			break;
840		case SEQUENCE_ELEMENT_TYPE_EXEC:
841			if (s->data.exec == NULL)
842				break;
843			ignore_error = s->data.exec[0] == '-';
844			err = uc_mgr_exec(s->data.exec + (ignore_error ? 1 : 0));
845			if (ignore_error == false && err != 0) {
846				uc_error("exec '%s' failed (exit code %d)", s->data.exec, err);
847				goto __fail;
848			}
849			break;
850		case SEQUENCE_ELEMENT_TYPE_SHELL:
851			if (s->data.exec == NULL)
852				break;
853			ignore_error = s->data.exec[0] == '-';
854shell_retry:
855			err = system(s->data.exec + (ignore_error ? 1 : 0));
856			if (WIFSIGNALED(err)) {
857				err = -EINTR;
858			} if (WIFEXITED(err)) {
859				if (ignore_error == false && WEXITSTATUS(err) != 0) {
860					uc_error("command '%s' failed (exit code %d)", s->data.exec, WEXITSTATUS(err));
861					err = -EINVAL;
862					goto __fail;
863				}
864			} else if (err < 0) {
865				if (errno == EAGAIN)
866					goto shell_retry;
867				err = -errno;
868				goto __fail;
869			}
870			break;
871		case SEQUENCE_ELEMENT_TYPE_CMPT_SEQ:
872			/* Execute enable or disable sequence of a component
873			 * device. Pass the cdev defined by the machine device.
874			 */
875			err = execute_component_seq(uc_mgr,
876						    &s->data.cmpt_seq,
877						    value_list1,
878						    value_list2,
879						    value_list3,
880						    cdev);
881			if (err < 0)
882				goto __fail;
883			break;
884		case SEQUENCE_ELEMENT_TYPE_CFGSAVE:
885			err = execute_cfgsave(uc_mgr, s->data.cfgsave);
886			if (err < 0)
887				goto __fail;
888			break;
889		case SEQUENCE_ELEMENT_TYPE_DEV_ENABLE_SEQ:
890		case SEQUENCE_ELEMENT_TYPE_DEV_DISABLE_SEQ:
891			err = run_device_sequence(uc_mgr, verb, s->data.device,
892							s->type == SEQUENCE_ELEMENT_TYPE_DEV_ENABLE_SEQ);
893			if (err < 0)
894				goto __fail;
895			break;
896		case SEQUENCE_ELEMENT_TYPE_DEV_DISABLE_ALL:
897			err = run_device_all_sequence(uc_mgr, verb);
898			if (err < 0)
899				goto __fail;
900			break;
901		default:
902			uc_error("unknown sequence command %i", s->type);
903			break;
904		}
905	}
906	free(cdev);
907	uc_mgr->sequence_hops--;
908	return 0;
909      __fail_nomem:
910	err = -ENOMEM;
911      __fail:
912	free(cdev);
913	uc_mgr->sequence_hops--;
914	return err;
915
916}
917
918/* Execute enable or disable sequence of a component device.
919 *
920 * For a component device (a codec or embedded DSP), its sequence doesn't
921 * specify the sound card device 'cdev', because a component can be reused
922 * by different sound cards (machines). So when executing its sequence, a
923 * parameter 'cdev' is used to pass cdev defined by the sequence of its
924 * parent, the machine device. UCM manger will store the cdev when entering
925 * the component domain.
926 */
927static int execute_component_seq(snd_use_case_mgr_t *uc_mgr,
928				 struct component_sequence *cmpt_seq,
929				 struct list_head *value_list1 ATTRIBUTE_UNUSED,
930				 struct list_head *value_list2 ATTRIBUTE_UNUSED,
931				 struct list_head *value_list3 ATTRIBUTE_UNUSED,
932				 char *cdev)
933{
934	struct use_case_device *device = cmpt_seq->device;
935	struct list_head *seq;
936	int err;
937
938	/* enter component domain and store cdev for the component */
939	uc_mgr->in_component_domain = 1;
940	uc_mgr->cdev = cdev;
941
942	/* choose enable or disable sequence of the component device */
943	if (cmpt_seq->enable)
944		seq = &device->enable_list;
945	else
946		seq = &device->disable_list;
947
948	/* excecute the sequence of the component dev */
949	err = execute_sequence(uc_mgr, uc_mgr->active_verb, seq,
950			       &device->value_list,
951			       &uc_mgr->active_verb->value_list,
952			       &uc_mgr->value_list);
953
954	/* exit component domain and clear cdev */
955	uc_mgr->in_component_domain = 0;
956	uc_mgr->cdev = NULL;
957
958	return err;
959}
960
961static int add_auto_value(snd_use_case_mgr_t *uc_mgr, const char *key, char *value)
962{
963	char *s;
964	int err;
965
966	err = get_value1(uc_mgr, &value, &uc_mgr->value_list, key);
967	if (err == -ENOENT) {
968		s = strdup(value);
969		if (s == NULL)
970			return -ENOMEM;
971		return uc_mgr_add_value(&uc_mgr->value_list, key, s);
972	} else if (err < 0) {
973		return err;
974	}
975	free(value);
976	return 0;
977}
978
979static int add_auto_values(snd_use_case_mgr_t *uc_mgr)
980{
981	struct ctl_list *ctl_list;
982	const char *id;
983	char buf[40];
984	int err;
985
986	ctl_list = uc_mgr_get_master_ctl(uc_mgr);
987	if (ctl_list) {
988		id = snd_ctl_card_info_get_id(ctl_list->ctl_info);
989		snprintf(buf, sizeof(buf), "hw:%s", id);
990		err = add_auto_value(uc_mgr, "PlaybackCTL", buf);
991		if (err < 0)
992			return err;
993		err = add_auto_value(uc_mgr, "CaptureCTL", buf);
994		if (err < 0)
995			return err;
996	}
997	return 0;
998}
999
1000/**
1001 * \brief execute default commands
1002 * \param uc_mgr Use case manager
1003 * \param force Force run
1004 * \return zero on success, otherwise a negative error code
1005 */
1006static int set_defaults(snd_use_case_mgr_t *uc_mgr, bool force)
1007{
1008	int err;
1009
1010	if (!force && uc_mgr->default_list_executed)
1011		return 0;
1012	err = execute_sequence(uc_mgr, NULL, &uc_mgr->default_list,
1013			       &uc_mgr->value_list, NULL, NULL);
1014	if (err < 0) {
1015		uc_error("Unable to execute default sequence");
1016		return err;
1017	}
1018	uc_mgr->default_list_executed = 1;
1019	return 0;
1020}
1021
1022/**
1023 * \brief Import master config and execute the default sequence
1024 * \param uc_mgr Use case manager
1025 * \return zero on success, otherwise a negative error code
1026 */
1027static int import_master_config(snd_use_case_mgr_t *uc_mgr)
1028{
1029	int err;
1030
1031	err = uc_mgr_import_master_config(uc_mgr);
1032	if (err < 0)
1033		return err;
1034	return add_auto_values(uc_mgr);
1035}
1036
1037/**
1038 * \brief Check, if the UCM configuration is empty
1039 * \param uc_mgr Use case Manager
1040 * \return zero on success, otherwise a negative error code
1041 */
1042static int check_empty_configuration(snd_use_case_mgr_t *uc_mgr)
1043{
1044	int err;
1045	char *value;
1046
1047	err = get_value(uc_mgr, "Linked", &value, NULL, NULL, 1);
1048	if (err >= 0) {
1049		err = strcasecmp(value, "true") == 0 ||
1050		      strcmp(value, "1") == 0;
1051		free(value);
1052		if (err)
1053			return 0;
1054	}
1055	if (!list_empty(&uc_mgr->verb_list))
1056		return 0;
1057	if (!list_empty(&uc_mgr->fixedboot_list))
1058		return 0;
1059	if (!list_empty(&uc_mgr->boot_list))
1060		return 0;
1061	return -ENXIO;
1062}
1063
1064/**
1065 * \brief Universal find - string in a list
1066 * \param list List of structures
1067 * \param offset Offset of list structure
1068 * \param soffset Offset of string structure
1069 * \param match String to match
1070 * \return structure on success, otherwise a NULL (not found)
1071 */
1072static void *find0(struct list_head *list,
1073		   unsigned long offset,
1074		   unsigned long soffset,
1075		   const char *match)
1076{
1077	struct list_head *pos;
1078	char *ptr, *str;
1079
1080	list_for_each(pos, list) {
1081		ptr = list_entry_offset(pos, char, offset);
1082		str = *((char **)(ptr + soffset));
1083		if (strcmp(str, match) == 0)
1084			return ptr;
1085	}
1086	return NULL;
1087}
1088
1089#define find(list, type, member, value, match) \
1090	find0(list, (unsigned long)(&((type *)0)->member), \
1091		    (unsigned long)(&((type *)0)->value), match)
1092
1093/**
1094 * \brief Universal string list
1095 * \param list List of structures
1096 * \param result Result list
1097 * \param offset Offset of list structure
1098 * \param s1offset Offset of string structure
1099 * \return count of items on success, otherwise a negative error code
1100 */
1101static int get_list0(struct list_head *list,
1102		     const char **result[],
1103		     unsigned long offset,
1104		     unsigned long s1offset)
1105{
1106	char **res;
1107	int cnt;
1108	struct list_head *pos;
1109	char *ptr, *str1;
1110
1111	cnt = alloc_str_list(list, 1, &res);
1112	if (cnt <= 0) {
1113		*result = NULL;
1114		return cnt;
1115	}
1116	*result = (const char **)res;
1117	list_for_each(pos, list) {
1118		ptr = list_entry_offset(pos, char, offset);
1119		str1 = *((char **)(ptr + s1offset));
1120		if (str1 != NULL) {
1121			*res = strdup(str1);
1122			if (*res == NULL)
1123				goto __fail;
1124		} else {
1125			*res = NULL;
1126		}
1127		res++;
1128	}
1129	return cnt;
1130      __fail:
1131	snd_use_case_free_list(*result, cnt);
1132	return -ENOMEM;
1133}
1134
1135#define get_list(list, result, type, member, s1) \
1136	get_list0(list, result, \
1137		    (unsigned long)(&((type *)0)->member), \
1138		    (unsigned long)(&((type *)0)->s1))
1139
1140/**
1141 * \brief Universal string list - pair of strings
1142 * \param list List of structures
1143 * \param result Result list
1144 * \param offset Offset of list structure
1145 * \param s1offset Offset of string structure
1146 * \param s1offset Offset of string structure
1147 * \return count of items on success, otherwise a negative error code
1148 */
1149static int get_list20(struct list_head *list,
1150		      const char **result[],
1151		      unsigned long offset,
1152		      unsigned long s1offset,
1153		      unsigned long s2offset)
1154{
1155	char **res;
1156	int cnt;
1157	struct list_head *pos;
1158	char *ptr, *str1, *str2;
1159
1160	cnt = alloc_str_list(list, 2, &res);
1161	if (cnt <= 0) {
1162		*result = NULL;
1163		return cnt;
1164	}
1165	*result = (const char **)res;
1166	list_for_each(pos, list) {
1167		ptr = list_entry_offset(pos, char, offset);
1168		str1 = *((char **)(ptr + s1offset));
1169		if (str1 != NULL) {
1170			*res = strdup(str1);
1171			if (*res == NULL)
1172				goto __fail;
1173		} else {
1174			*res = NULL;
1175		}
1176		res++;
1177		str2 = *((char **)(ptr + s2offset));
1178		if (str2 != NULL) {
1179			*res = strdup(str2);
1180			if (*res == NULL)
1181				goto __fail;
1182		} else {
1183			*res = NULL;
1184		}
1185		res++;
1186	}
1187	return cnt;
1188      __fail:
1189	snd_use_case_free_list(*result, cnt);
1190	return -ENOMEM;
1191}
1192
1193#define get_list2(list, result, type, member, s1, s2) \
1194	get_list20(list, result, \
1195		    (unsigned long)(&((type *)0)->member), \
1196		    (unsigned long)(&((type *)0)->s1), \
1197		    (unsigned long)(&((type *)0)->s2))
1198
1199/**
1200 * \brief Find verb
1201 * \param uc_mgr Use case manager
1202 * \param verb_name verb to find
1203 * \return structure on success, otherwise a NULL (not found)
1204 */
1205static inline struct use_case_verb *find_verb(snd_use_case_mgr_t *uc_mgr,
1206					      const char *verb_name)
1207{
1208	return find(&uc_mgr->verb_list,
1209		    struct use_case_verb, list, name,
1210		    verb_name);
1211}
1212
1213static int is_devlist_supported(snd_use_case_mgr_t *uc_mgr,
1214	struct dev_list *dev_list)
1215{
1216	struct dev_list_node *device;
1217	struct use_case_device *adev;
1218	struct list_head *pos, *pos1;
1219	int found_ret;
1220
1221	switch (dev_list->type) {
1222	case DEVLIST_NONE:
1223	default:
1224		return 1;
1225	case DEVLIST_SUPPORTED:
1226		found_ret = 1;
1227		break;
1228	case DEVLIST_CONFLICTING:
1229		found_ret = 0;
1230		break;
1231	}
1232
1233	list_for_each(pos, &dev_list->list) {
1234		device = list_entry(pos, struct dev_list_node, list);
1235
1236		list_for_each(pos1, &uc_mgr->active_devices) {
1237			adev = list_entry(pos1, struct use_case_device,
1238					    active_list);
1239			if (!strcmp(device->name, adev->name))
1240				return found_ret;
1241		}
1242	}
1243	return 1 - found_ret;
1244}
1245
1246static inline int is_modifier_supported(snd_use_case_mgr_t *uc_mgr,
1247	struct use_case_modifier *modifier)
1248{
1249	return is_devlist_supported(uc_mgr, &modifier->dev_list);
1250}
1251
1252static inline int is_device_supported(snd_use_case_mgr_t *uc_mgr,
1253	struct use_case_device *device)
1254{
1255	return is_devlist_supported(uc_mgr, &device->dev_list);
1256}
1257
1258/**
1259 * \brief Find device
1260 * \param verb Use case verb
1261 * \param device_name device to find
1262 * \return structure on success, otherwise a NULL (not found)
1263 */
1264static inline struct use_case_device *
1265	find_device(snd_use_case_mgr_t *uc_mgr, struct use_case_verb *verb,
1266		    const char *device_name, int check_supported)
1267{
1268	struct use_case_device *device;
1269	struct list_head *pos;
1270
1271	list_for_each(pos, &verb->device_list) {
1272		device = list_entry(pos, struct use_case_device, list);
1273
1274		if (strcmp(device_name, device->name))
1275			continue;
1276
1277		if (check_supported &&
1278		    !is_device_supported(uc_mgr, device))
1279			continue;
1280
1281		return device;
1282	}
1283	return NULL;
1284}
1285
1286/**
1287 * \brief Find modifier
1288 * \param verb Use case verb
1289 * \param modifier_name modifier to find
1290 * \return structure on success, otherwise a NULL (not found)
1291 */
1292static struct use_case_modifier *
1293	find_modifier(snd_use_case_mgr_t *uc_mgr, struct use_case_verb *verb,
1294		      const char *modifier_name, int check_supported)
1295{
1296	struct use_case_modifier *modifier;
1297	struct list_head *pos;
1298
1299	list_for_each(pos, &verb->modifier_list) {
1300		modifier = list_entry(pos, struct use_case_modifier, list);
1301
1302		if (strcmp(modifier->name, modifier_name))
1303			continue;
1304
1305		if (check_supported &&
1306		    !is_modifier_supported(uc_mgr, modifier))
1307			continue;
1308
1309		return modifier;
1310	}
1311	return NULL;
1312}
1313
1314long device_status(snd_use_case_mgr_t *uc_mgr,
1315		   const char *device_name)
1316{
1317	struct use_case_device *dev;
1318	struct list_head *pos;
1319
1320	list_for_each(pos, &uc_mgr->active_devices) {
1321		dev = list_entry(pos, struct use_case_device, active_list);
1322		if (strcmp(dev->name, device_name) == 0)
1323			return 1;
1324	}
1325	return 0;
1326}
1327
1328long modifier_status(snd_use_case_mgr_t *uc_mgr,
1329		     const char *modifier_name)
1330{
1331	struct use_case_modifier *mod;
1332	struct list_head *pos;
1333
1334	list_for_each(pos, &uc_mgr->active_modifiers) {
1335		mod = list_entry(pos, struct use_case_modifier, active_list);
1336		if (strcmp(mod->name, modifier_name) == 0)
1337			return 1;
1338	}
1339	return 0;
1340}
1341
1342/**
1343 * \brief Set verb
1344 * \param uc_mgr Use case manager
1345 * \param verb verb to set
1346 * \param enable nonzero = enable, zero = disable
1347 * \return zero on success, otherwise a negative error code
1348 */
1349static int set_verb(snd_use_case_mgr_t *uc_mgr,
1350		    struct use_case_verb *verb,
1351		    int enable)
1352{
1353	struct list_head *seq;
1354	int err;
1355
1356	if (enable) {
1357		err = set_defaults(uc_mgr, false);
1358		if (err < 0)
1359			return err;
1360		seq = &verb->enable_list;
1361	} else {
1362		seq = &verb->disable_list;
1363	}
1364	err = execute_sequence(uc_mgr, verb, seq,
1365			       &verb->value_list,
1366			       &uc_mgr->value_list,
1367			       NULL);
1368	if (enable && err >= 0)
1369		uc_mgr->active_verb = verb;
1370	return err;
1371}
1372
1373/**
1374 * \brief Set modifier
1375 * \param uc_mgr Use case manager
1376 * \param modifier modifier to set
1377 * \param enable nonzero = enable, zero = disable
1378 * \return zero on success, otherwise a negative error code
1379 */
1380static int set_modifier(snd_use_case_mgr_t *uc_mgr,
1381			struct use_case_modifier *modifier,
1382			int enable)
1383{
1384	struct list_head *seq;
1385	int err;
1386
1387	if (modifier_status(uc_mgr, modifier->name) == enable)
1388		return 0;
1389
1390	if (enable) {
1391		seq = &modifier->enable_list;
1392	} else {
1393		seq = &modifier->disable_list;
1394	}
1395	err = execute_sequence(uc_mgr, uc_mgr->active_verb, seq,
1396			       &modifier->value_list,
1397			       &uc_mgr->active_verb->value_list,
1398			       &uc_mgr->value_list);
1399	if (enable && err >= 0) {
1400		list_add_tail(&modifier->active_list, &uc_mgr->active_modifiers);
1401	} else if (!enable) {
1402		list_del(&modifier->active_list);
1403	}
1404	return err;
1405}
1406
1407/**
1408 * \brief Set device
1409 * \param uc_mgr Use case manager
1410 * \param device device to set
1411 * \param enable nonzero = enable, zero = disable
1412 * \return zero on success, otherwise a negative error code
1413 */
1414static int set_device(snd_use_case_mgr_t *uc_mgr,
1415		      struct use_case_device *device,
1416		      int enable)
1417{
1418	struct list_head *seq;
1419	int err;
1420
1421	if (device_status(uc_mgr, device->name) == enable)
1422		return 0;
1423
1424	if (enable) {
1425		seq = &device->enable_list;
1426	} else {
1427		seq = &device->disable_list;
1428	}
1429	err = execute_sequence(uc_mgr, uc_mgr->active_verb, seq,
1430			       &device->value_list,
1431			       &uc_mgr->active_verb->value_list,
1432			       &uc_mgr->value_list);
1433	if (enable && err >= 0) {
1434		list_add_tail(&device->active_list, &uc_mgr->active_devices);
1435	} else if (!enable) {
1436		list_del(&device->active_list);
1437	}
1438	return err;
1439}
1440
1441/**
1442 * \brief Do the full reset
1443 * \param uc_mgr Use case manager
1444 * \return zero on success, otherwise a negative error code
1445 */
1446static int do_reset(snd_use_case_mgr_t *uc_mgr)
1447{
1448	int err;
1449
1450	err = set_defaults(uc_mgr, true);
1451	INIT_LIST_HEAD(&uc_mgr->active_modifiers);
1452	INIT_LIST_HEAD(&uc_mgr->active_devices);
1453	uc_mgr->active_verb = NULL;
1454	return err;
1455}
1456
1457/**
1458 * \brief Parse open arguments
1459 * \param uc_mgr Use case manager
1460 * \param name name of card to open
1461 * \return the rest of the card name to open
1462 */
1463const char *parse_open_variables(snd_use_case_mgr_t *uc_mgr, const char *name)
1464{
1465	const char *end, *id;
1466	char *args, *var;
1467	snd_config_t *cfg, *n;
1468	snd_config_iterator_t i, next;
1469	char vname[128];
1470	size_t l;
1471	int err;
1472
1473	end = strstr(name, ">>>");
1474	if (end == NULL)
1475		return name;
1476	l = end - name - 3;
1477	args = alloca(l + 1);
1478	strncpy(args, name + 3, l);
1479	args[l] = '\0';
1480
1481	err = snd_config_load_string(&cfg, args, 0);
1482	if (err < 0) {
1483		uc_error("error: open arguments are not valid (%s)", args);
1484		goto skip;
1485	}
1486
1487	/* set arguments */
1488	snd_config_for_each(i, next, cfg) {
1489		n = snd_config_iterator_entry(i);
1490		err = snd_config_get_id(n, &id);
1491		if (err < 0)
1492			goto skip;
1493		err = snd_config_get_ascii(n, &var);
1494		if (err < 0)
1495			goto skip;
1496		snprintf(vname, sizeof(vname), "@%s", id);
1497		err = uc_mgr_set_variable(uc_mgr, vname, var);
1498		free(var);
1499		if (err < 0)
1500			goto skip;
1501	}
1502
1503skip:
1504	snd_config_delete(cfg);
1505	return end + 3;
1506}
1507
1508int snd_use_case_mgr_open(snd_use_case_mgr_t **uc_mgr,
1509			  const char *card_name)
1510{
1511	snd_use_case_mgr_t *mgr;
1512	int err;
1513
1514	/* create a new UCM */
1515	mgr = calloc(1, sizeof(snd_use_case_mgr_t));
1516	if (mgr == NULL)
1517		return -ENOMEM;
1518	INIT_LIST_HEAD(&mgr->verb_list);
1519	INIT_LIST_HEAD(&mgr->fixedboot_list);
1520	INIT_LIST_HEAD(&mgr->boot_list);
1521	INIT_LIST_HEAD(&mgr->default_list);
1522	INIT_LIST_HEAD(&mgr->value_list);
1523	INIT_LIST_HEAD(&mgr->active_modifiers);
1524	INIT_LIST_HEAD(&mgr->active_devices);
1525	INIT_LIST_HEAD(&mgr->ctl_list);
1526	INIT_LIST_HEAD(&mgr->variable_list);
1527	pthread_mutex_init(&mgr->mutex, NULL);
1528
1529	if (card_name && *card_name == '-') {
1530		card_name++;
1531		mgr->suppress_nodev_errors = 1;
1532	}
1533
1534	if (card_name && card_name[0] == '<' && card_name[1] == '<' && card_name[2] == '<')
1535		card_name = parse_open_variables(mgr, card_name);
1536
1537	err = uc_mgr_card_open(mgr);
1538	if (err < 0) {
1539		uc_mgr_free(mgr);
1540		return err;
1541	}
1542
1543	mgr->card_name = strdup(card_name);
1544	if (mgr->card_name == NULL) {
1545		err = -ENOMEM;
1546		goto _err;
1547	}
1548
1549	/* get info on use_cases and verify against card */
1550	err = import_master_config(mgr);
1551	if (err < 0) {
1552		if (err == -ENXIO && mgr->suppress_nodev_errors)
1553			goto _err;
1554		uc_error("error: failed to import %s use case configuration %d",
1555			 card_name, err);
1556		goto _err;
1557	}
1558
1559	err = check_empty_configuration(mgr);
1560	if (err < 0) {
1561		uc_error("error: failed to import %s (empty configuration)", card_name);
1562		goto _err;
1563	}
1564
1565	*uc_mgr = mgr;
1566	return 0;
1567
1568_err:
1569	uc_mgr_card_close(mgr);
1570	uc_mgr_free(mgr);
1571	return err;
1572}
1573
1574int snd_use_case_mgr_reload(snd_use_case_mgr_t *uc_mgr)
1575{
1576	int err;
1577
1578	pthread_mutex_lock(&uc_mgr->mutex);
1579
1580	do_reset(uc_mgr);
1581
1582	uc_mgr_free_verb(uc_mgr);
1583
1584	uc_mgr->default_list_executed = 0;
1585
1586	/* reload all use cases */
1587	err = import_master_config(uc_mgr);
1588	if (err < 0) {
1589		uc_error("error: failed to reload use cases");
1590		pthread_mutex_unlock(&uc_mgr->mutex);
1591		return -EINVAL;
1592	}
1593
1594	pthread_mutex_unlock(&uc_mgr->mutex);
1595	return err;
1596}
1597
1598int snd_use_case_mgr_close(snd_use_case_mgr_t *uc_mgr)
1599{
1600	uc_mgr_card_close(uc_mgr);
1601	uc_mgr_free(uc_mgr);
1602
1603	return 0;
1604}
1605
1606/*
1607 * Tear down current use case verb, device and modifier.
1608 */
1609static int dismantle_use_case(snd_use_case_mgr_t *uc_mgr)
1610{
1611	struct list_head *pos, *npos;
1612	struct use_case_modifier *modifier;
1613	struct use_case_device *device;
1614	int err;
1615
1616	list_for_each_safe(pos, npos, &uc_mgr->active_modifiers) {
1617		modifier = list_entry(pos, struct use_case_modifier,
1618				      active_list);
1619		err = set_modifier(uc_mgr, modifier, 0);
1620		if (err < 0)
1621			uc_error("Unable to disable modifier %s", modifier->name);
1622	}
1623	INIT_LIST_HEAD(&uc_mgr->active_modifiers);
1624
1625	list_for_each_safe(pos, npos, &uc_mgr->active_devices) {
1626		device = list_entry(pos, struct use_case_device,
1627				    active_list);
1628		err = set_device(uc_mgr, device, 0);
1629		if (err < 0)
1630			uc_error("Unable to disable device %s", device->name);
1631	}
1632	INIT_LIST_HEAD(&uc_mgr->active_devices);
1633
1634	err = set_verb(uc_mgr, uc_mgr->active_verb, 0);
1635	if (err < 0) {
1636		uc_error("Unable to disable verb %s", uc_mgr->active_verb->name);
1637		return err;
1638	}
1639	uc_mgr->active_verb = NULL;
1640
1641	err = set_defaults(uc_mgr, true);
1642
1643	return err;
1644}
1645
1646int snd_use_case_mgr_reset(snd_use_case_mgr_t *uc_mgr)
1647{
1648	int err;
1649
1650	pthread_mutex_lock(&uc_mgr->mutex);
1651	err = do_reset(uc_mgr);
1652	pthread_mutex_unlock(&uc_mgr->mutex);
1653	return err;
1654}
1655
1656/**
1657 * \brief Get list of verbs in pair verbname+comment
1658 * \param list Returned list
1659 * \return Number of list entries if success, otherwise a negative error code
1660 */
1661static int get_verb_list(snd_use_case_mgr_t *uc_mgr, const char **list[])
1662{
1663	return get_list2(&uc_mgr->verb_list, list,
1664			 struct use_case_verb, list,
1665			 name, comment);
1666}
1667
1668/**
1669 * \brief Get list of devices in pair devicename+comment
1670 * \param list Returned list
1671 * \param verbname For verb (NULL = current)
1672 * \return Number of list entries if success, otherwise a negative error code
1673 */
1674static int get_device_list(snd_use_case_mgr_t *uc_mgr, const char **list[],
1675			   char *verbname)
1676{
1677	struct use_case_verb *verb;
1678
1679	if (verbname) {
1680		verb = find_verb(uc_mgr, verbname);
1681	} else {
1682		verb = uc_mgr->active_verb;
1683	}
1684	if (verb == NULL)
1685		return -ENOENT;
1686	return get_list2(&verb->device_list, list,
1687			 struct use_case_device, list,
1688			 name, comment);
1689}
1690
1691/**
1692 * \brief Get list of modifiers in pair devicename+comment
1693 * \param list Returned list
1694 * \param verbname For verb (NULL = current)
1695 * \return Number of list entries if success, otherwise a negative error code
1696 */
1697static int get_modifier_list(snd_use_case_mgr_t *uc_mgr, const char **list[],
1698			     char *verbname)
1699{
1700	struct use_case_verb *verb;
1701	if (verbname) {
1702		verb = find_verb(uc_mgr, verbname);
1703	} else {
1704		verb = uc_mgr->active_verb;
1705	}
1706	if (verb == NULL)
1707		return -ENOENT;
1708	return get_list2(&verb->modifier_list, list,
1709			 struct use_case_modifier, list,
1710			 name, comment);
1711}
1712
1713/**
1714 * \brief Get list of supported/conflicting devices
1715 * \param list Returned list
1716 * \param name Name of modifier or verb to query
1717 * \param type Type of device list entries to return
1718 * \return Number of list entries if success, otherwise a negative error code
1719 */
1720static int get_supcon_device_list(snd_use_case_mgr_t *uc_mgr,
1721				  const char **list[], char *name,
1722				  enum dev_list_type type)
1723{
1724	char *str;
1725	struct use_case_verb *verb;
1726	struct use_case_modifier *modifier;
1727	struct use_case_device *device;
1728
1729	if (!name)
1730		return -ENOENT;
1731
1732	str = strchr(name, '/');
1733	if (str) {
1734		*str = '\0';
1735		verb = find_verb(uc_mgr, str + 1);
1736	}
1737	else {
1738		verb = uc_mgr->active_verb;
1739	}
1740	if (!verb)
1741		return -ENOENT;
1742
1743	modifier = find_modifier(uc_mgr, verb, name, 0);
1744	if (modifier) {
1745		if (modifier->dev_list.type != type) {
1746			*list = NULL;
1747			return 0;
1748		}
1749		return get_list(&modifier->dev_list.list, list,
1750				struct dev_list_node, list,
1751				name);
1752	}
1753
1754	device = find_device(uc_mgr, verb, name, 0);
1755	if (device) {
1756		if (device->dev_list.type != type) {
1757			*list = NULL;
1758			return 0;
1759		}
1760		return get_list(&device->dev_list.list, list,
1761				struct dev_list_node, list,
1762				name);
1763	}
1764
1765	return -ENOENT;
1766}
1767
1768/**
1769 * \brief Get list of supported devices
1770 * \param list Returned list
1771 * \param name Name of verb or modifier to query
1772 * \return Number of list entries if success, otherwise a negative error code
1773 */
1774static int get_supported_device_list(snd_use_case_mgr_t *uc_mgr,
1775				     const char **list[], char *name)
1776{
1777	return get_supcon_device_list(uc_mgr, list, name, DEVLIST_SUPPORTED);
1778}
1779
1780/**
1781 * \brief Get list of conflicting devices
1782 * \param list Returned list
1783 * \param name Name of verb or modifier to query
1784 * \return Number of list entries if success, otherwise a negative error code
1785 */
1786static int get_conflicting_device_list(snd_use_case_mgr_t *uc_mgr,
1787				       const char **list[], char *name)
1788{
1789	return get_supcon_device_list(uc_mgr, list, name, DEVLIST_CONFLICTING);
1790}
1791
1792#ifndef DOC_HIDDEN
1793struct myvalue {
1794	struct list_head list;
1795	const char *text;
1796};
1797#endif
1798
1799/**
1800 * \brief Convert myvalue list string list
1801 * \param list myvalue list
1802 * \param res string list
1803 * \retval Number of list entries if success, otherwise a negativer error code
1804 */
1805static int myvalue_to_str_list(struct list_head *list, char ***res)
1806{
1807	struct list_head *pos;
1808	struct myvalue *value;
1809	char **p;
1810	int cnt;
1811
1812	cnt = alloc_str_list(list, 1, res);
1813	if (cnt < 0)
1814		return cnt;
1815	p = *res;
1816	list_for_each(pos, list) {
1817		value = list_entry(pos, struct myvalue, list);
1818		*p = strdup(value->text);
1819		if (*p == NULL) {
1820			snd_use_case_free_list((const char **)p, cnt);
1821			return -ENOMEM;
1822		}
1823		p++;
1824	}
1825	return cnt;
1826}
1827
1828/**
1829 * \brief Free myvalue list
1830 * \param list myvalue list
1831 */
1832static void myvalue_list_free(struct list_head *list)
1833{
1834	struct list_head *pos, *npos;
1835	struct myvalue *value;
1836
1837	list_for_each_safe(pos, npos, list) {
1838		value = list_entry(pos, struct myvalue, list);
1839		list_del(&value->list);
1840		free(value);
1841	}
1842}
1843
1844/**
1845 * \brief Merge one value to the myvalue list
1846 * \param list The list with values
1847 * \param value The value to be merged (without duplicates)
1848 * \return 1 if dup, 0 if success, otherwise a negative error code
1849 */
1850static int merge_value(struct list_head *list, const char *text)
1851{
1852	struct list_head *pos;
1853	struct myvalue *value;
1854
1855	list_for_each(pos, list) {
1856		value = list_entry(pos, struct myvalue, list);
1857		if (strcmp(value->text, text) == 0)
1858			return 1;
1859	}
1860	value = malloc(sizeof(*value));
1861	if (value == NULL)
1862		return -ENOMEM;
1863	value->text = text;
1864	list_add_tail(&value->list, list);
1865	return 0;
1866}
1867
1868/**
1869 * \brief Find all values for given identifier
1870 * \param list Returned list
1871 * \param source Source list with ucm_value structures
1872 * \return Zero if success, otherwise a negative error code
1873 */
1874static int add_identifiers(struct list_head *list,
1875			   struct list_head *source)
1876{
1877	struct ucm_value *v;
1878	struct list_head *pos;
1879	int err;
1880
1881	list_for_each(pos, source) {
1882		v = list_entry(pos, struct ucm_value, list);
1883		err = merge_value(list, v->name);
1884		if (err < 0)
1885			return err;
1886	}
1887	return 0;
1888}
1889
1890/**
1891 * \brief Find all values for given identifier
1892 * \param list Returned list
1893 * \param identifier Identifier
1894 * \param source Source list with ucm_value structures
1895 */
1896static int add_values(struct list_head *list,
1897		      const char *identifier,
1898		      struct list_head *source)
1899{
1900	struct ucm_value *v;
1901	struct list_head *pos;
1902	int err;
1903
1904	list_for_each(pos, source) {
1905		v = list_entry(pos, struct ucm_value, list);
1906		if (check_identifier(identifier, v->name)) {
1907			err = merge_value(list, v->data);
1908			if (err < 0)
1909				return err;
1910		}
1911	}
1912	return 0;
1913}
1914
1915/**
1916 * \brief compare two identifiers
1917 */
1918static int identifier_cmp(const void *_a, const void *_b)
1919{
1920	const char * const *a = _a;
1921	const char * const *b = _b;
1922	return strcmp(*a, *b);
1923}
1924
1925/**
1926 * \brief Get list of available identifiers
1927 * \param list Returned list
1928 * \param name Name of verb or modifier to query
1929 * \return Number of list entries if success, otherwise a negative error code
1930 */
1931static int get_identifiers_list(snd_use_case_mgr_t *uc_mgr,
1932				const char **list[], char *name)
1933{
1934	struct use_case_verb *verb;
1935	struct use_case_modifier *modifier;
1936	struct use_case_device *device;
1937	struct list_head mylist;
1938	struct list_head *value_list;
1939	char *str, **res;
1940	int err;
1941
1942	if (!name)
1943		return -ENOENT;
1944
1945	str = strchr(name, '/');
1946	if (str) {
1947		*str = '\0';
1948		verb = find_verb(uc_mgr, str + 1);
1949	}
1950	else {
1951		verb = uc_mgr->active_verb;
1952	}
1953	if (!verb)
1954		return -ENOENT;
1955
1956	value_list = NULL;
1957	modifier = find_modifier(uc_mgr, verb, name, 0);
1958	if (modifier) {
1959		value_list = &modifier->value_list;
1960	} else {
1961		device = find_device(uc_mgr, verb, name, 0);
1962		if (device)
1963			value_list = &device->value_list;
1964	}
1965	if (value_list == NULL)
1966		return -ENOENT;
1967
1968	INIT_LIST_HEAD(&mylist);
1969	err = add_identifiers(&mylist, &uc_mgr->value_list);
1970	if (err < 0)
1971		goto __fail;
1972	err = add_identifiers(&mylist, &verb->value_list);
1973	if (err < 0)
1974		goto __fail;
1975	err = add_identifiers(&mylist, value_list);
1976	if (err < 0)
1977		goto __fail;
1978	err = myvalue_to_str_list(&mylist, &res);
1979	if (err > 0)
1980		*list = (const char **)res;
1981	else if (err == 0)
1982		*list = NULL;
1983__fail:
1984	myvalue_list_free(&mylist);
1985	if (err <= 0)
1986		return err;
1987	qsort(*list, err, sizeof(char *), identifier_cmp);
1988	return err;
1989}
1990
1991/**
1992 * \brief Get list of values
1993 * \param list Returned list
1994 * \param verbname For verb (NULL = current)
1995 * \return Number of list entries if success, otherwise a negative error code
1996 */
1997static int get_value_list(snd_use_case_mgr_t *uc_mgr,
1998			  const char *identifier,
1999			  const char **list[],
2000			  char *verbname)
2001{
2002	struct list_head mylist, *pos;
2003	struct use_case_verb *verb;
2004	struct use_case_device *dev;
2005	struct use_case_modifier *mod;
2006	char **res;
2007	int err;
2008
2009	if (verbname) {
2010		verb = find_verb(uc_mgr, verbname);
2011	} else {
2012		verb = uc_mgr->active_verb;
2013	}
2014	if (verb == NULL)
2015		return -ENOENT;
2016	INIT_LIST_HEAD(&mylist);
2017	err = add_values(&mylist, identifier, &uc_mgr->value_list);
2018	if (err < 0)
2019		goto __fail;
2020	err = add_values(&mylist, identifier, &verb->value_list);
2021	if (err < 0)
2022		goto __fail;
2023	list_for_each(pos, &verb->device_list) {
2024		dev = list_entry(pos, struct use_case_device, list);
2025		err = add_values(&mylist, identifier, &dev->value_list);
2026		if (err < 0)
2027			goto __fail;
2028	}
2029	list_for_each(pos, &verb->modifier_list) {
2030		mod = list_entry(pos, struct use_case_modifier, list);
2031		err = add_values(&mylist, identifier, &mod->value_list);
2032		if (err < 0)
2033			goto __fail;
2034	}
2035	err = myvalue_to_str_list(&mylist, &res);
2036	if (err > 0)
2037		*list = (const char **)res;
2038	else if (err == 0)
2039		*list = NULL;
2040      __fail:
2041	myvalue_list_free(&mylist);
2042	return err;
2043}
2044
2045/**
2046 * \brief Get list of enabled devices
2047 * \param list Returned list
2048 * \param verbname For verb (NULL = current)
2049 * \return Number of list entries if success, otherwise a negative error code
2050 */
2051static int get_enabled_device_list(snd_use_case_mgr_t *uc_mgr,
2052				   const char **list[])
2053{
2054	if (uc_mgr->active_verb == NULL)
2055		return -EINVAL;
2056	return get_list(&uc_mgr->active_devices, list,
2057			struct use_case_device, active_list,
2058			name);
2059}
2060
2061/**
2062 * \brief Get list of enabled modifiers
2063 * \param list Returned list
2064 * \param verbname For verb (NULL = current)
2065 * \return Number of list entries if success, otherwise a negative error code
2066 */
2067static int get_enabled_modifier_list(snd_use_case_mgr_t *uc_mgr,
2068				     const char **list[])
2069{
2070	if (uc_mgr->active_verb == NULL)
2071		return -EINVAL;
2072	return get_list(&uc_mgr->active_modifiers, list,
2073			struct use_case_modifier, active_list,
2074			name);
2075}
2076
2077int snd_use_case_get_list(snd_use_case_mgr_t *uc_mgr,
2078			  const char *identifier,
2079			  const char **list[])
2080{
2081	char *str, *str1;
2082	int err;
2083
2084	if (uc_mgr == NULL || identifier == NULL)
2085		return uc_mgr_scan_master_configs(list);
2086	pthread_mutex_lock(&uc_mgr->mutex);
2087	if (strcmp(identifier, "_verbs") == 0)
2088		err = get_verb_list(uc_mgr, list);
2089	else if (strcmp(identifier, "_enadevs") == 0)
2090		err = get_enabled_device_list(uc_mgr, list);
2091	else if (strcmp(identifier, "_enamods") == 0)
2092		err = get_enabled_modifier_list(uc_mgr, list);
2093	else {
2094		str1 = strchr(identifier, '/');
2095		if (str1) {
2096			str = strdup(str1 + 1);
2097			if (str == NULL) {
2098				err = -ENOMEM;
2099				goto __end;
2100			}
2101		} else {
2102			str = NULL;
2103		}
2104		if (check_identifier(identifier, "_devices"))
2105			err = get_device_list(uc_mgr, list, str);
2106		else if (check_identifier(identifier, "_modifiers"))
2107			err = get_modifier_list(uc_mgr, list, str);
2108		else if (check_identifier(identifier, "_identifiers"))
2109			err = get_identifiers_list(uc_mgr, list, str);
2110		else if (check_identifier(identifier, "_supporteddevs"))
2111			err = get_supported_device_list(uc_mgr, list, str);
2112		else if (check_identifier(identifier, "_conflictingdevs"))
2113			err = get_conflicting_device_list(uc_mgr, list, str);
2114		else if (identifier[0] == '_')
2115			err = -ENOENT;
2116		else
2117			err = get_value_list(uc_mgr, identifier, list, str);
2118		if (str)
2119			free(str);
2120	}
2121      __end:
2122	pthread_mutex_unlock(&uc_mgr->mutex);
2123	return err;
2124}
2125
2126static int get_value1(snd_use_case_mgr_t *uc_mgr, char **value,
2127		      struct list_head *value_list, const char *identifier)
2128{
2129	struct ucm_value *val;
2130	struct list_head *pos;
2131	int err;
2132
2133	if (!value_list)
2134		return -ENOENT;
2135
2136	list_for_each(pos, value_list) {
2137		val = list_entry(pos, struct ucm_value, list);
2138		if (check_identifier(identifier, val->name)) {
2139			if (uc_mgr->conf_format < 2) {
2140				*value = strdup(val->data);
2141				if (*value == NULL)
2142					return -ENOMEM;
2143				return 0;
2144			}
2145			err = uc_mgr_get_substituted_value(uc_mgr, value, val->data);
2146			if (err < 0)
2147				return err;
2148			return rewrite_device_value(uc_mgr, val->name, value);
2149		}
2150	}
2151	return -ENOENT;
2152}
2153
2154static int get_value3(snd_use_case_mgr_t *uc_mgr,
2155		      char **value,
2156		      const char *identifier,
2157		      struct list_head *value_list1,
2158		      struct list_head *value_list2,
2159		      struct list_head *value_list3)
2160{
2161	int err;
2162
2163	err = get_value1(uc_mgr, value, value_list1, identifier);
2164	if (err >= 0 || err != -ENOENT)
2165		return err;
2166	err = get_value1(uc_mgr, value, value_list2, identifier);
2167	if (err >= 0 || err != -ENOENT)
2168		return err;
2169	err = get_value1(uc_mgr, value, value_list3, identifier);
2170	if (err >= 0 || err != -ENOENT)
2171		return err;
2172	return -ENOENT;
2173}
2174
2175/**
2176 * \brief Get value
2177 * \param uc_mgr Use case manager
2178 * \param identifier Value identifier (string)
2179 * \param value Returned value string
2180 * \param item Modifier or Device name (string)
2181 * \return Zero on success (value is filled), otherwise a negative error code
2182 */
2183static int get_value(snd_use_case_mgr_t *uc_mgr,
2184			const char *identifier,
2185			char **value,
2186			const char *mod_dev_name,
2187			const char *verb_name,
2188			int exact)
2189{
2190	struct use_case_verb *verb;
2191	struct use_case_modifier *mod;
2192	struct use_case_device *dev;
2193	int err;
2194
2195	if (mod_dev_name || verb_name || !exact) {
2196		if (verb_name && strlen(verb_name)) {
2197			verb = find_verb(uc_mgr, verb_name);
2198		} else {
2199			verb = uc_mgr->active_verb;
2200		}
2201		if (verb) {
2202			if (mod_dev_name) {
2203				mod = find_modifier(uc_mgr, verb,
2204						    mod_dev_name, 0);
2205				if (mod) {
2206					err = get_value1(uc_mgr, value,
2207							 &mod->value_list,
2208							 identifier);
2209					if (err >= 0 || err != -ENOENT)
2210						return err;
2211				}
2212
2213				dev = find_device(uc_mgr, verb,
2214						  mod_dev_name, 0);
2215				if (dev) {
2216					err = get_value1(uc_mgr, value,
2217							 &dev->value_list,
2218							 identifier);
2219					if (err >= 0 || err != -ENOENT)
2220						return err;
2221				}
2222
2223				if (exact)
2224					return -ENOENT;
2225			}
2226
2227			err = get_value1(uc_mgr, value, &verb->value_list, identifier);
2228			if (err >= 0 || err != -ENOENT)
2229				return err;
2230		}
2231
2232		if (exact)
2233			return -ENOENT;
2234	}
2235
2236	err = get_value1(uc_mgr, value, &uc_mgr->value_list, identifier);
2237	if (err >= 0 || err != -ENOENT)
2238		return err;
2239
2240	return -ENOENT;
2241}
2242
2243/**
2244 * \brief Get private alsa-lib configuration (ASCII)
2245 * \param uc_mgr Use case manager
2246 * \param str Returned value string
2247 * \return Zero on success (value is filled), otherwise a negative error code
2248 */
2249static int get_alibcfg(snd_use_case_mgr_t *uc_mgr, char **str)
2250{
2251	snd_output_t *out;
2252	size_t size;
2253	int err;
2254
2255	err = snd_output_buffer_open(&out);
2256	if (err < 0)
2257		return err;
2258	err = snd_config_save(uc_mgr->local_config, out);
2259	if (err >= 0) {
2260		size = snd_output_buffer_steal(out, str);
2261		if (*str)
2262			(*str)[size] = '\0';
2263	}
2264	snd_output_close(out);
2265	return 0;
2266}
2267
2268/**
2269 * \brief Get device prefix for private alsa-lib configuration
2270 * \param uc_mgr Use case manager
2271 * \param str Returned value string
2272 * \return Zero on success (value is filled), otherwise a negative error code
2273 */
2274static int get_alibpref(snd_use_case_mgr_t *uc_mgr, char **str)
2275{
2276	const size_t l = 10;
2277	char *s;
2278
2279	s = malloc(l);
2280	if (s == NULL)
2281		return -ENOMEM;
2282	snprintf(s, l, "_ucm%04X.", uc_mgr->ucm_card_number);
2283	*str = s;
2284	return 0;
2285}
2286
2287int snd_use_case_get(snd_use_case_mgr_t *uc_mgr,
2288		     const char *identifier,
2289		     const char **value)
2290{
2291	const char *slash1, *slash2, *mod_dev_after;
2292	const char *ident, *mod_dev, *verb;
2293	int exact = 0;
2294	int err;
2295
2296	pthread_mutex_lock(&uc_mgr->mutex);
2297	if (identifier == NULL) {
2298		*value = strdup(uc_mgr->card_name);
2299		if (*value == NULL) {
2300			err = -ENOMEM;
2301			goto __end;
2302		}
2303		err = 0;
2304	} else if (strcmp(identifier, "_verb") == 0) {
2305		if (uc_mgr->active_verb == NULL) {
2306			err = -ENOENT;
2307			goto __end;
2308		}
2309		*value = strdup(uc_mgr->active_verb->name);
2310		if (*value == NULL) {
2311			err = -ENOMEM;
2312			goto __end;
2313		}
2314		err = 0;
2315	} else if (strcmp(identifier, "_file") == 0) {
2316		/* get the conf file name of the opened card */
2317		if ((uc_mgr->card_name == NULL) ||
2318		    (uc_mgr->conf_file_name == NULL) ||
2319		    (uc_mgr->conf_file_name[0] == '\0')) {
2320			err = -ENOENT;
2321			goto __end;
2322		}
2323		*value = strdup(uc_mgr->conf_file_name);
2324		if (*value == NULL) {
2325			err = -ENOMEM;
2326			goto __end;
2327		}
2328		err = 0;
2329
2330	} else if (strcmp(identifier, "_alibcfg") == 0) {
2331		err = get_alibcfg(uc_mgr, (char **)value);
2332	} else if (strcmp(identifier, "_alibpref") == 0) {
2333		err = get_alibpref(uc_mgr, (char **)value);
2334	} else if (identifier[0] == '_') {
2335		err = -ENOENT;
2336	} else {
2337		if (identifier[0] == '=') {
2338			exact = 1;
2339			identifier++;
2340		}
2341
2342		slash1 = strchr(identifier, '/');
2343		if (slash1) {
2344			ident = strndup(identifier, slash1 - identifier);
2345
2346			slash2 = strchr(slash1 + 1, '/');
2347			if (slash2) {
2348				mod_dev_after = slash2;
2349				verb = slash2 + 1;
2350			}
2351			else {
2352				mod_dev_after = slash1 + strlen(slash1);
2353				verb = NULL;
2354			}
2355
2356			if (mod_dev_after == slash1 + 1)
2357				mod_dev = NULL;
2358			else
2359				mod_dev = strndup(slash1 + 1,
2360						  mod_dev_after - (slash1 + 1));
2361		}
2362		else {
2363			ident = identifier;
2364			mod_dev = NULL;
2365			verb = NULL;
2366		}
2367
2368		err = get_value(uc_mgr, ident, (char **)value, mod_dev, verb,
2369				exact);
2370		if (ident != identifier)
2371			free((void *)ident);
2372		if (mod_dev)
2373			free((void *)mod_dev);
2374	}
2375      __end:
2376	pthread_mutex_unlock(&uc_mgr->mutex);
2377	return err;
2378}
2379
2380/*
2381 * a helper macro to obtain status and existence
2382 */
2383#define geti(uc_mgr, status, ifind, str, value) ({ \
2384	long val = -EINVAL; \
2385	if (str) { \
2386		val = (status)((uc_mgr), (str)); \
2387		if (val >= 0) { \
2388			if ((ifind)((uc_mgr), (uc_mgr)->active_verb, (str), 0)) { \
2389				*(value) = val; \
2390				val = 0; \
2391			} else { \
2392				val = -ENOENT; \
2393			} \
2394		} \
2395	} \
2396	; val; /* return value */ \
2397})
2398
2399int snd_use_case_geti(snd_use_case_mgr_t *uc_mgr,
2400		      const char *identifier,
2401		      long *value)
2402{
2403	char *str, *str1;
2404	int err;
2405
2406	pthread_mutex_lock(&uc_mgr->mutex);
2407	if (0) {
2408		/* nothing here - prepared for fixed identifiers */
2409	} else {
2410		str1 = strchr(identifier, '/');
2411		if (str1) {
2412			str = strdup(str1 + 1);
2413			if (str == NULL) {
2414				err = -ENOMEM;
2415				goto __end;
2416			}
2417		} else {
2418			str = NULL;
2419		}
2420		if (check_identifier(identifier, "_devstatus")) {
2421			err = geti(uc_mgr, device_status, find_device, str, value);
2422		} else if (check_identifier(identifier, "_modstatus")) {
2423			err = geti(uc_mgr, modifier_status, find_modifier, str, value);
2424#if 0
2425		/*
2426		 * enable this block if the else clause below is expanded to query
2427		 * user-supplied values
2428		 */
2429		} else if (identifier[0] == '_') {
2430			err = -ENOENT;
2431#endif
2432		} else
2433			err = -ENOENT;
2434		if (str)
2435			free(str);
2436	}
2437      __end:
2438	pthread_mutex_unlock(&uc_mgr->mutex);
2439	return err;
2440}
2441
2442static int set_fixedboot_user(snd_use_case_mgr_t *uc_mgr,
2443			      const char *value)
2444{
2445	int err;
2446
2447	if (value != NULL && *value) {
2448		uc_error("error: wrong value for _fboot (%s)", value);
2449		return -EINVAL;
2450	}
2451	if (list_empty(&uc_mgr->fixedboot_list))
2452		return -ENOENT;
2453	err = execute_sequence(uc_mgr, NULL, &uc_mgr->fixedboot_list,
2454			       &uc_mgr->value_list, NULL, NULL);
2455	if (err < 0) {
2456		uc_error("Unable to execute force boot sequence");
2457		return err;
2458	}
2459	return err;
2460}
2461
2462static int set_boot_user(snd_use_case_mgr_t *uc_mgr,
2463			 const char *value)
2464{
2465	int err;
2466
2467	if (value != NULL && *value) {
2468		uc_error("error: wrong value for _boot (%s)", value);
2469		return -EINVAL;
2470	}
2471	if (list_empty(&uc_mgr->boot_list))
2472		return -ENOENT;
2473	err = execute_sequence(uc_mgr, NULL, &uc_mgr->boot_list,
2474			       &uc_mgr->value_list, NULL, NULL);
2475	if (err < 0) {
2476		uc_error("Unable to execute boot sequence");
2477		return err;
2478	}
2479	return err;
2480}
2481
2482static int set_defaults_user(snd_use_case_mgr_t *uc_mgr,
2483			     const char *value)
2484{
2485	if (value != NULL && *value) {
2486		uc_error("error: wrong value for _defaults (%s)", value);
2487		return -EINVAL;
2488	}
2489	return set_defaults(uc_mgr, false);
2490}
2491
2492static int handle_transition_verb(snd_use_case_mgr_t *uc_mgr,
2493				  struct use_case_verb *new_verb)
2494{
2495	struct list_head *pos;
2496	struct transition_sequence *trans;
2497	int err;
2498
2499	list_for_each(pos, &uc_mgr->active_verb->transition_list) {
2500		trans = list_entry(pos, struct transition_sequence, list);
2501		if (strcmp(trans->name, new_verb->name) == 0) {
2502			err = execute_sequence(uc_mgr, uc_mgr->active_verb,
2503					       &trans->transition_list,
2504					       &uc_mgr->active_verb->value_list,
2505					       &uc_mgr->value_list,
2506					       NULL);
2507			if (err >= 0)
2508				return 1;
2509			return err;
2510		}
2511	}
2512	return 0;
2513}
2514
2515static int set_verb_user(snd_use_case_mgr_t *uc_mgr,
2516			 const char *verb_name)
2517{
2518	struct use_case_verb *verb;
2519	int err = 0;
2520
2521	if (uc_mgr->active_verb &&
2522	    strcmp(uc_mgr->active_verb->name, verb_name) == 0)
2523		return 0;
2524	if (strcmp(verb_name, SND_USE_CASE_VERB_INACTIVE) != 0) {
2525		verb = find_verb(uc_mgr, verb_name);
2526		if (verb == NULL)
2527			return -ENOENT;
2528	} else {
2529		verb = NULL;
2530	}
2531	if (uc_mgr->active_verb) {
2532		err = handle_transition_verb(uc_mgr, verb);
2533		if (err == 0) {
2534			err = dismantle_use_case(uc_mgr);
2535			if (err < 0)
2536				return err;
2537		} else if (err == 1) {
2538			uc_mgr->active_verb = verb;
2539			verb = NULL;
2540		} else {
2541			verb = NULL; /* show error */
2542		}
2543	}
2544	if (verb) {
2545		err = set_verb(uc_mgr, verb, 1);
2546		if (err < 0)
2547			uc_error("error: failed to initialize new use case: %s",
2548				 verb_name);
2549	}
2550	return err;
2551}
2552
2553
2554static int set_device_user(snd_use_case_mgr_t *uc_mgr,
2555			   const char *device_name,
2556			   int enable)
2557{
2558	struct use_case_device *device;
2559
2560	if (uc_mgr->active_verb == NULL)
2561		return -ENOENT;
2562	device = find_device(uc_mgr, uc_mgr->active_verb, device_name, 1);
2563	if (device == NULL)
2564		return -ENOENT;
2565	return set_device(uc_mgr, device, enable);
2566}
2567
2568static int set_modifier_user(snd_use_case_mgr_t *uc_mgr,
2569			     const char *modifier_name,
2570			     int enable)
2571{
2572	struct use_case_modifier *modifier;
2573
2574	if (uc_mgr->active_verb == NULL)
2575		return -ENOENT;
2576
2577	modifier = find_modifier(uc_mgr, uc_mgr->active_verb, modifier_name, 1);
2578	if (modifier == NULL)
2579		return -ENOENT;
2580	return set_modifier(uc_mgr, modifier, enable);
2581}
2582
2583static int switch_device(snd_use_case_mgr_t *uc_mgr,
2584			 const char *old_device,
2585			 const char *new_device)
2586{
2587	struct use_case_device *xold, *xnew;
2588	struct transition_sequence *trans;
2589	struct list_head *pos;
2590	int err, seq_found = 0;
2591
2592	if (uc_mgr->active_verb == NULL)
2593		return -ENOENT;
2594	if (device_status(uc_mgr, old_device) == 0) {
2595		uc_error("error: device %s not enabled", old_device);
2596		return -EINVAL;
2597	}
2598	if (device_status(uc_mgr, new_device) != 0) {
2599		uc_error("error: device %s already enabled", new_device);
2600		return -EINVAL;
2601	}
2602	xold = find_device(uc_mgr, uc_mgr->active_verb, old_device, 1);
2603	if (xold == NULL)
2604		return -ENOENT;
2605	list_del(&xold->active_list);
2606	xnew = find_device(uc_mgr, uc_mgr->active_verb, new_device, 1);
2607	list_add_tail(&xold->active_list, &uc_mgr->active_devices);
2608	if (xnew == NULL)
2609		return -ENOENT;
2610	err = 0;
2611	list_for_each(pos, &xold->transition_list) {
2612		trans = list_entry(pos, struct transition_sequence, list);
2613		if (strcmp(trans->name, new_device) == 0) {
2614			err = execute_sequence(uc_mgr, uc_mgr->active_verb,
2615					       &trans->transition_list,
2616					       &xold->value_list,
2617					       &uc_mgr->active_verb->value_list,
2618					       &uc_mgr->value_list);
2619			if (err >= 0) {
2620				list_del(&xold->active_list);
2621				list_add_tail(&xnew->active_list, &uc_mgr->active_devices);
2622			}
2623			seq_found = 1;
2624			break;
2625		}
2626	}
2627	if (!seq_found) {
2628		err = set_device(uc_mgr, xold, 0);
2629		if (err < 0)
2630			return err;
2631		err = set_device(uc_mgr, xnew, 1);
2632		if (err < 0)
2633			return err;
2634	}
2635	return err;
2636}
2637
2638static int switch_modifier(snd_use_case_mgr_t *uc_mgr,
2639			   const char *old_modifier,
2640			   const char *new_modifier)
2641{
2642	struct use_case_modifier *xold, *xnew;
2643	struct transition_sequence *trans;
2644	struct list_head *pos;
2645	int err, seq_found = 0;
2646
2647	if (uc_mgr->active_verb == NULL)
2648		return -ENOENT;
2649	if (modifier_status(uc_mgr, old_modifier) == 0) {
2650		uc_error("error: modifier %s not enabled", old_modifier);
2651		return -EINVAL;
2652	}
2653	if (modifier_status(uc_mgr, new_modifier) != 0) {
2654		uc_error("error: modifier %s already enabled", new_modifier);
2655		return -EINVAL;
2656	}
2657	xold = find_modifier(uc_mgr, uc_mgr->active_verb, old_modifier, 1);
2658	if (xold == NULL)
2659		return -ENOENT;
2660	xnew = find_modifier(uc_mgr, uc_mgr->active_verb, new_modifier, 1);
2661	if (xnew == NULL)
2662		return -ENOENT;
2663	err = 0;
2664	list_for_each(pos, &xold->transition_list) {
2665		trans = list_entry(pos, struct transition_sequence, list);
2666		if (strcmp(trans->name, new_modifier) == 0) {
2667			err = execute_sequence(uc_mgr, uc_mgr->active_verb,
2668					       &trans->transition_list,
2669					       &xold->value_list,
2670					       &uc_mgr->active_verb->value_list,
2671					       &uc_mgr->value_list);
2672			if (err >= 0) {
2673				list_del(&xold->active_list);
2674				list_add_tail(&xnew->active_list, &uc_mgr->active_modifiers);
2675			}
2676			seq_found = 1;
2677			break;
2678		}
2679	}
2680	if (!seq_found) {
2681		err = set_modifier(uc_mgr, xold, 0);
2682		if (err < 0)
2683			return err;
2684		err = set_modifier(uc_mgr, xnew, 1);
2685		if (err < 0)
2686			return err;
2687	}
2688	return err;
2689}
2690
2691int snd_use_case_set(snd_use_case_mgr_t *uc_mgr,
2692		     const char *identifier,
2693		     const char *value)
2694{
2695	char *str, *str1;
2696	int err = 0;
2697
2698	pthread_mutex_lock(&uc_mgr->mutex);
2699	if (strcmp(identifier, "_fboot") == 0)
2700		err = set_fixedboot_user(uc_mgr, value);
2701	else if (strcmp(identifier, "_boot") == 0)
2702		err = set_boot_user(uc_mgr, value);
2703	else if (strcmp(identifier, "_defaults") == 0)
2704		err = set_defaults_user(uc_mgr, value);
2705	else if (strcmp(identifier, "_verb") == 0)
2706		err = set_verb_user(uc_mgr, value);
2707	else if (strcmp(identifier, "_enadev") == 0)
2708		err = set_device_user(uc_mgr, value, 1);
2709	else if (strcmp(identifier, "_disdev") == 0)
2710		err = set_device_user(uc_mgr, value, 0);
2711	else if (strcmp(identifier, "_enamod") == 0)
2712		err = set_modifier_user(uc_mgr, value, 1);
2713	else if (strcmp(identifier, "_dismod") == 0)
2714		err = set_modifier_user(uc_mgr, value, 0);
2715	else {
2716		str1 = strchr(identifier, '/');
2717		if (str1) {
2718			str = strdup(str1 + 1);
2719			if (str == NULL) {
2720				err = -ENOMEM;
2721				goto __end;
2722			}
2723		} else {
2724			err = -EINVAL;
2725			goto __end;
2726		}
2727		if (check_identifier(identifier, "_swdev"))
2728			err = switch_device(uc_mgr, str, value);
2729		else if (check_identifier(identifier, "_swmod"))
2730			err = switch_modifier(uc_mgr, str, value);
2731		else
2732			err = -EINVAL;
2733		if (str)
2734			free(str);
2735	}
2736      __end:
2737	pthread_mutex_unlock(&uc_mgr->mutex);
2738	return err;
2739}
2740
2741/**
2742 * \brief Parse control element identifier
2743 * \param dst Element identifier
2744 * \param ucm_id Use case identifier
2745 * \param value String value to be parsed
2746 * \return Zero if success, otherwise a negative error code
2747 */
2748int snd_use_case_parse_ctl_elem_id(snd_ctl_elem_id_t *dst,
2749				   const char *ucm_id,
2750				   const char *value)
2751{
2752	snd_ctl_elem_iface_t iface;
2753	int jack_control;
2754
2755	jack_control = strcmp(ucm_id, "JackControl") == 0;
2756	if (!jack_control &&
2757	    strcmp(ucm_id, "PlaybackVolume") &&
2758	    strcmp(ucm_id, "PlaybackSwitch") &&
2759	    strcmp(ucm_id, "CaptureVolume") &&
2760	    strcmp(ucm_id, "CaptureSwitch"))
2761		return -EINVAL;
2762	snd_ctl_elem_id_clear(dst);
2763	if (strcasestr(value, "name="))
2764		return __snd_ctl_ascii_elem_id_parse(dst, value, NULL);
2765	iface = SND_CTL_ELEM_IFACE_MIXER;
2766	if (jack_control)
2767		iface = SND_CTL_ELEM_IFACE_CARD;
2768	snd_ctl_elem_id_set_interface(dst, iface);
2769	snd_ctl_elem_id_set_name(dst, value);
2770	return 0;
2771}
2772
2773/**
2774 * \brief Parse mixer element identifier
2775 * \param dst Simple mixer element identifier
2776 * \param ucm_id Use case identifier
2777 * \param value String value to be parsed
2778 * \return Zero if success, otherwise a negative error code
2779 */
2780int snd_use_case_parse_selem_id(snd_mixer_selem_id_t *dst,
2781				const char *ucm_id,
2782				const char *value)
2783{
2784#ifdef BUILD_MIXER
2785	if (strcmp(ucm_id, "PlaybackMixerId") == 0 ||
2786	    strcmp(ucm_id, "CaptureMixerId") == 0)
2787		return snd_mixer_selem_id_parse(dst, value);
2788#endif
2789	return -EINVAL;
2790}
2791